From 629da8f8bf39da2e3a32f178954604a89de898d1 Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Wed, 2 May 2018 09:20:59 +0200 Subject: [PATCH 001/152] More changes for Android (#8421) --- .gitlab-ci.yml | 17 +++++++++++++++++ Cargo.lock | 22 +++++++++++----------- docker/android/Dockerfile | 2 ++ 3 files changed, 30 insertions(+), 11 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 2c216496f6..347b5a57ba 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -180,6 +180,23 @@ windows: paths: - parity.zip name: "x86_64-pc-windows-msvc_parity" +android-armv7: + stage: build + image: parity/parity-android:latest + only: + - beta + - tags + - stable + - triggers + script: + - cargo build --target=armv7-linux-androideabi + # TODO: check that `arm-linux-androideabi-objdump -x ./target/armv7-linux-androideabi/release/parity | grep c++_shared` is empty + tags: + - rust-arm + artifacts: + paths: + - parity.zip + name: "armv7-linux-androideabi_parity" docker-build: stage: build only: diff --git a/Cargo.lock b/Cargo.lock index 3176c3ab3d..741cc3832c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -70,7 +70,7 @@ name = "backtrace-sys" version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -184,7 +184,7 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "rayon 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -432,7 +432,7 @@ version = "0.5.7" source = "git+https://github.com/paritytech/rust-secp256k1#db81cfea59014b4d176f10f86ed52e1a130b6822" dependencies = [ "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "cc 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1203,7 +1203,7 @@ name = "hidapi" version = "0.3.1" source = "git+https://github.com/paritytech/hidapi-rs#70ec4bd1b755ec5dd32ad2be0c8345864147c8bc" dependencies = [ - "cc 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1436,7 +1436,7 @@ dependencies = [ name = "keccak-hash" version = "0.1.0" dependencies = [ - "cc 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", "ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "tiny-keccak 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1524,7 +1524,7 @@ name = "libusb-sys" version = "0.2.4" source = "git+https://github.com/paritytech/libusb-sys#14bdb698003731b6344a79e1d814704e44363e7c" dependencies = [ - "cc 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1678,7 +1678,7 @@ name = "miniz_oxide_c_api" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", "crc 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", "miniz_oxide 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2723,7 +2723,7 @@ name = "ring" version = "0.12.1" source = "git+https://github.com/paritytech/ring#b98d7f586c0467d68e9946a5f47b4a04b9a86b4a" dependencies = [ - "cc 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", "rayon 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2774,7 +2774,7 @@ name = "rocksdb-sys" version = "0.3.0" source = "git+https://github.com/paritytech/rust-rocksdb#ecf06adf3148ab10f6f7686b724498382ff4f36e" dependencies = [ - "cc 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", "local-encoding 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "snappy-sys 0.1.0 (git+https://github.com/paritytech/rust-snappy)", @@ -3010,7 +3010,7 @@ name = "snappy-sys" version = "0.1.0" source = "git+https://github.com/paritytech/rust-snappy#40ac9a0d9fd613e7f38df800a11a589b7296da73" dependencies = [ - "cc 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3782,7 +3782,7 @@ dependencies = [ "checksum build_const 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "39092a32794787acd8525ee150305ff051b0aa6cc2abaf193924f5ab05425f39" "checksum byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "652805b7e73fada9d85e9a6682a4abd490cb52d96aeecc12e33a0de34dfd0d23" "checksum bytes 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "1b7db437d718977f6dc9b2e3fd6fc343c02ac6b899b73fdd2179163447bd9ce9" -"checksum cc 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "2b4911e4bdcb4100c7680e7e854ff38e23f1b34d4d9e079efae3da2801341ffc" +"checksum cc 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)" = "8b9d2900f78631a5876dc5d6c9033ede027253efcd33dd36b1309fc6cab97ee0" "checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de" "checksum cid 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d85ee025368e69063c420cbb2ed9f852cb03a5e69b73be021e65726ce03585b6" "checksum clap 2.29.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8f4a2b3bb7ef3c672d7c13d15613211d5a6976b6892c598b0fcb5d40765f19c2" diff --git a/docker/android/Dockerfile b/docker/android/Dockerfile index 5769cd13bc..7783781b4c 100644 --- a/docker/android/Dockerfile +++ b/docker/android/Dockerfile @@ -75,3 +75,5 @@ ENV CFLAGS_arm_linux_androideabi -std=gnu11 -fPIC -D OS_ANDROID ENV CFLAGS_armv7_linux_androideabi -std=gnu11 -fPIC -D OS_ANDROID ENV CXXFLAGS_arm_linux_androideabi -std=gnu++11 -fPIC -fexceptions -frtti -static-libstdc++ -D OS_ANDROID ENV CXXFLAGS_armv7_linux_androideabi -std=gnu++11 -fPIC -fexceptions -frtti -static-libstdc++ -D OS_ANDROID +ENV CXXSTDLIB_arm_linux_androideabi "" +ENV CXXSTDLIB_armv7_linux_androideabi "" -- GitLab From 8e8679807dbb8df6456172fdfa1396b7f091d267 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Wed, 2 May 2018 09:31:06 +0200 Subject: [PATCH 002/152] Transaction Pool improvements (#8470) * Don't use ethereum_types in transaction pool. * Hide internal insertion_id. * Fix tests. * Review grumbles. --- miner/src/pool/mod.rs | 13 ++- miner/src/pool/queue.rs | 4 +- miner/src/pool/ready.rs | 12 +-- miner/src/pool/scoring.rs | 11 ++- transaction-pool/Cargo.toml | 2 + transaction-pool/src/error.rs | 16 ++-- transaction-pool/src/lib.rs | 23 +++-- transaction-pool/src/pool.rs | 113 +++++++++++++++-------- transaction-pool/src/ready.rs | 4 +- transaction-pool/src/scoring.rs | 34 ++++--- transaction-pool/src/tests/helpers.rs | 10 +- transaction-pool/src/tests/mod.rs | 13 +-- transaction-pool/src/tests/tx_builder.rs | 10 -- transaction-pool/src/transactions.rs | 46 +++++---- 14 files changed, 173 insertions(+), 138 deletions(-) diff --git a/miner/src/pool/mod.rs b/miner/src/pool/mod.rs index 7950510c6d..45d28f3c12 100644 --- a/miner/src/pool/mod.rs +++ b/miner/src/pool/mod.rs @@ -105,6 +105,11 @@ impl VerifiedTransaction { self.priority } + /// Gets transaction insertion id. + pub(crate) fn insertion_id(&self) -> usize { + self.insertion_id + } + /// Gets wrapped `SignedTransaction` pub fn signed(&self) -> &transaction::SignedTransaction { &self.transaction @@ -114,9 +119,13 @@ impl VerifiedTransaction { pub fn pending(&self) -> &transaction::PendingTransaction { &self.transaction } + } impl txpool::VerifiedTransaction for VerifiedTransaction { + type Hash = H256; + type Sender = Address; + fn hash(&self) -> &H256 { &self.hash } @@ -128,8 +137,4 @@ impl txpool::VerifiedTransaction for VerifiedTransaction { fn sender(&self) -> &Address { &self.sender } - - fn insertion_id(&self) -> u64 { - self.insertion_id as u64 - } } diff --git a/miner/src/pool/queue.rs b/miner/src/pool/queue.rs index edc092a119..8cf4534b76 100644 --- a/miner/src/pool/queue.rs +++ b/miner/src/pool/queue.rs @@ -282,11 +282,11 @@ impl TransactionQueue { // We want to clear stale transactions from the queue as well. // (Transactions that are occuping the queue for a long time without being included) let stale_id = { - let current_id = self.insertion_id.load(atomic::Ordering::Relaxed) as u64; + let current_id = self.insertion_id.load(atomic::Ordering::Relaxed); // wait at least for half of the queue to be replaced let gap = self.pool.read().options().max_count / 2; // but never less than 100 transactions - let gap = cmp::max(100, gap) as u64; + let gap = cmp::max(100, gap); current_id.checked_sub(gap) }; diff --git a/miner/src/pool/ready.rs b/miner/src/pool/ready.rs index 54b5aec3a9..c2829b34a9 100644 --- a/miner/src/pool/ready.rs +++ b/miner/src/pool/ready.rs @@ -54,14 +54,14 @@ pub struct State { nonces: HashMap, state: C, max_nonce: Option, - stale_id: Option, + stale_id: Option, } impl State { /// Create new State checker, given client interface. pub fn new( state: C, - stale_id: Option, + stale_id: Option, max_nonce: Option, ) -> Self { State { @@ -91,10 +91,10 @@ impl txpool::Ready for State { match tx.transaction.nonce.cmp(nonce) { // Before marking as future check for stale ids cmp::Ordering::Greater => match self.stale_id { - Some(id) if tx.insertion_id() < id => txpool::Readiness::Stalled, + Some(id) if tx.insertion_id() < id => txpool::Readiness::Stale, _ => txpool::Readiness::Future, }, - cmp::Ordering::Less => txpool::Readiness::Stalled, + cmp::Ordering::Less => txpool::Readiness::Stale, cmp::Ordering::Equal => { *nonce = *nonce + 1.into(); txpool::Readiness::Ready @@ -178,7 +178,7 @@ mod tests { let res = State::new(TestClient::new().with_nonce(125), None, None).is_ready(&tx); // then - assert_eq!(res, txpool::Readiness::Stalled); + assert_eq!(res, txpool::Readiness::Stale); } #[test] @@ -190,7 +190,7 @@ mod tests { let res = State::new(TestClient::new(), Some(1), None).is_ready(&tx); // then - assert_eq!(res, txpool::Readiness::Stalled); + assert_eq!(res, txpool::Readiness::Stale); } #[test] diff --git a/miner/src/pool/scoring.rs b/miner/src/pool/scoring.rs index b9f074ecb0..eaf0698332 100644 --- a/miner/src/pool/scoring.rs +++ b/miner/src/pool/scoring.rs @@ -28,7 +28,6 @@ //! from our local node (own transactions). use std::cmp; -use std::sync::Arc; use ethereum_types::U256; use txpool; @@ -69,7 +68,7 @@ impl txpool::Scoring for NonceAndGasPrice { } } - fn update_scores(&self, txs: &[Arc], scores: &mut [U256], change: txpool::scoring::Change) { + fn update_scores(&self, txs: &[txpool::Transaction], scores: &mut [U256], change: txpool::scoring::Change) { use self::txpool::scoring::Change; match change { @@ -79,7 +78,7 @@ impl txpool::Scoring for NonceAndGasPrice { assert!(i < txs.len()); assert!(i < scores.len()); - scores[i] = txs[i].transaction.gas_price; + scores[i] = txs[i].transaction.transaction.gas_price; let boost = match txs[i].priority() { super::Priority::Local => 15, super::Priority::Retracted => 10, @@ -116,6 +115,7 @@ impl txpool::Scoring for NonceAndGasPrice { mod tests { use super::*; + use std::sync::Arc; use pool::tests::tx::{Tx, TxExt}; use txpool::Scoring; @@ -131,7 +131,10 @@ mod tests { 1 => ::pool::Priority::Retracted, _ => ::pool::Priority::Regular, }; - Arc::new(verified) + txpool::Transaction { + insertion_id: 0, + transaction: Arc::new(verified), + } }).collect::>(); let initial_scores = vec![U256::from(0), 0.into(), 0.into()]; diff --git a/transaction-pool/Cargo.toml b/transaction-pool/Cargo.toml index b863078112..342c376f63 100644 --- a/transaction-pool/Cargo.toml +++ b/transaction-pool/Cargo.toml @@ -10,4 +10,6 @@ error-chain = "0.11" log = "0.3" smallvec = "0.4" trace-time = { path = "../util/trace-time" } + +[dev-dependencies] ethereum-types = "0.3" diff --git a/transaction-pool/src/error.rs b/transaction-pool/src/error.rs index 2e8ac73989..4cf221a71e 100644 --- a/transaction-pool/src/error.rs +++ b/transaction-pool/src/error.rs @@ -14,24 +14,26 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -use ethereum_types::H256; +/// Error chain doesn't let us have generic types. +/// So the hashes are converted to debug strings for easy display. +type Hash = String; error_chain! { errors { /// Transaction is already imported - AlreadyImported(hash: H256) { + AlreadyImported(hash: Hash) { description("transaction is already in the pool"), - display("[{:?}] already imported", hash) + display("[{}] already imported", hash) } /// Transaction is too cheap to enter the queue - TooCheapToEnter(hash: H256, min_score: String) { + TooCheapToEnter(hash: Hash, min_score: String) { description("the pool is full and transaction is too cheap to replace any transaction"), - display("[{:?}] too cheap to enter the pool. Min score: {}", hash, min_score) + display("[{}] too cheap to enter the pool. Min score: {}", hash, min_score) } /// Transaction is too cheap to replace existing transaction that occupies the same slot. - TooCheapToReplace(old_hash: H256, hash: H256) { + TooCheapToReplace(old_hash: Hash, hash: Hash) { description("transaction is too cheap to replace existing transaction in the pool"), - display("[{:?}] too cheap to replace: {:?}", hash, old_hash) + display("[{}] too cheap to replace: {}", hash, old_hash) } } } diff --git a/transaction-pool/src/lib.rs b/transaction-pool/src/lib.rs index 33d17f4b0f..4a1bdcde14 100644 --- a/transaction-pool/src/lib.rs +++ b/transaction-pool/src/lib.rs @@ -69,14 +69,15 @@ #![warn(missing_docs)] extern crate smallvec; -extern crate ethereum_types; +extern crate trace_time; #[macro_use] extern crate error_chain; #[macro_use] extern crate log; -extern crate trace_time; +#[cfg(test)] +extern crate ethereum_types; #[cfg(test)] mod tests; @@ -95,27 +96,29 @@ pub mod scoring; pub use self::error::{Error, ErrorKind}; pub use self::listener::{Listener, NoopListener}; pub use self::options::Options; -pub use self::pool::{Pool, PendingIterator}; +pub use self::pool::{Pool, PendingIterator, Transaction}; pub use self::ready::{Ready, Readiness}; pub use self::scoring::Scoring; pub use self::status::{LightStatus, Status}; pub use self::verifier::Verifier; use std::fmt; - -use ethereum_types::{H256, Address}; +use std::hash::Hash; /// Already verified transaction that can be safely queued. pub trait VerifiedTransaction: fmt::Debug { + /// Transaction hash type. + type Hash: fmt::Debug + fmt::LowerHex + Eq + Clone + Hash; + + /// Transaction sender type. + type Sender: fmt::Debug + Eq + Clone + Hash; + /// Transaction hash - fn hash(&self) -> &H256; + fn hash(&self) -> &Self::Hash; /// Memory usage fn mem_usage(&self) -> usize; /// Transaction sender - fn sender(&self) -> &Address; - - /// Unique index of insertion (lower = older). - fn insertion_id(&self) -> u64; + fn sender(&self) -> &Self::Sender; } diff --git a/transaction-pool/src/pool.rs b/transaction-pool/src/pool.rs index fa28cdcdfe..5cb6e479b8 100644 --- a/transaction-pool/src/pool.rs +++ b/transaction-pool/src/pool.rs @@ -17,8 +17,6 @@ use std::sync::Arc; use std::collections::{HashMap, BTreeSet}; -use ethereum_types::{H160, H256}; - use error; use listener::{Listener, NoopListener}; use options::Options; @@ -29,21 +27,51 @@ use transactions::{AddResult, Transactions}; use {VerifiedTransaction}; -type Sender = H160; +/// Internal representation of transaction. +/// +/// Includes unique insertion id that can be used for scoring explictly, +/// but internally is used to resolve conflicts in case of equal scoring +/// (newer transactionsa are preferred). +#[derive(Debug)] +pub struct Transaction { + /// Sequential id of the transaction + pub insertion_id: u64, + /// Shared transaction + pub transaction: Arc, +} + +impl Clone for Transaction { + fn clone(&self) -> Self { + Transaction { + insertion_id: self.insertion_id, + transaction: self.transaction.clone(), + } + } +} + +impl ::std::ops::Deref for Transaction { + type Target = Arc; + + fn deref(&self) -> &Self::Target { + &self.transaction + } +} /// A transaction pool. #[derive(Debug)] -pub struct Pool, L = NoopListener> { +pub struct Pool, L = NoopListener> { listener: L, scoring: S, options: Options, mem_usage: usize, - transactions: HashMap>, - by_hash: HashMap>, + transactions: HashMap>, + by_hash: HashMap>, best_transactions: BTreeSet>, worst_transactions: BTreeSet>, + + insertion_id: u64, } impl + Default> Default for Pool { @@ -89,6 +117,7 @@ impl Pool where by_hash, best_transactions: Default::default(), worst_transactions: Default::default(), + insertion_id: 0, } } @@ -104,10 +133,16 @@ impl Pool where /// If any limit is reached the transaction with the lowest `Score` is evicted to make room. /// /// The `Listener` will be informed on any drops or rejections. - pub fn import(&mut self, mut transaction: T) -> error::Result> { + pub fn import(&mut self, transaction: T) -> error::Result> { let mem_usage = transaction.mem_usage(); - ensure!(!self.by_hash.contains_key(transaction.hash()), error::ErrorKind::AlreadyImported(*transaction.hash())); + ensure!(!self.by_hash.contains_key(transaction.hash()), error::ErrorKind::AlreadyImported(format!("{:?}", transaction.hash()))); + + self.insertion_id += 1; + let mut transaction = Transaction { + insertion_id: self.insertion_id, + transaction: Arc::new(transaction), + }; // TODO [ToDr] Most likely move this after the transaction is inserted. // Avoid using should_replace, but rather use scoring for that. @@ -115,7 +150,7 @@ impl Pool where let remove_worst = |s: &mut Self, transaction| { match s.remove_worst(&transaction) { Err(err) => { - s.listener.rejected(&Arc::new(transaction), err.kind()); + s.listener.rejected(&transaction, err.kind()); Err(err) }, Ok(removed) => { @@ -138,7 +173,7 @@ impl Pool where } let (result, prev_state, current_state) = { - let transactions = self.transactions.entry(*transaction.sender()).or_insert_with(Transactions::default); + let transactions = self.transactions.entry(transaction.sender().clone()).or_insert_with(Transactions::default); // get worst and best transactions for comparison let prev = transactions.worst_and_best(); let result = transactions.add(transaction, &self.scoring, self.options.max_per_sender); @@ -153,31 +188,31 @@ impl Pool where AddResult::Ok(tx) => { self.listener.added(&tx, None); self.finalize_insert(&tx, None); - Ok(tx) + Ok(tx.transaction) }, AddResult::PushedOut { new, old } | AddResult::Replaced { new, old } => { self.listener.added(&new, Some(&old)); self.finalize_insert(&new, Some(&old)); - Ok(new) + Ok(new.transaction) }, AddResult::TooCheap { new, old } => { - let error = error::ErrorKind::TooCheapToReplace(*old.hash(), *new.hash()); - self.listener.rejected(&Arc::new(new), &error); + let error = error::ErrorKind::TooCheapToReplace(format!("{:x}", old.hash()), format!("{:x}", new.hash())); + self.listener.rejected(&new, &error); bail!(error) }, AddResult::TooCheapToEnter(new, score) => { - let error = error::ErrorKind::TooCheapToEnter(*new.hash(), format!("{:?}", score)); - self.listener.rejected(&Arc::new(new), &error); + let error = error::ErrorKind::TooCheapToEnter(format!("{:x}", new.hash()), format!("{:?}", score)); + self.listener.rejected(&new, &error); bail!(error) } } } /// Updates state of the pool statistics if the transaction was added to a set. - fn finalize_insert(&mut self, new: &Arc, old: Option<&Arc>) { + fn finalize_insert(&mut self, new: &Transaction, old: Option<&Transaction>) { self.mem_usage += new.mem_usage(); - self.by_hash.insert(*new.hash(), new.clone()); + self.by_hash.insert(new.hash().clone(), new.clone()); if let Some(old) = old { self.finalize_remove(old.hash()); @@ -185,23 +220,23 @@ impl Pool where } /// Updates the pool statistics if transaction was removed. - fn finalize_remove(&mut self, hash: &H256) -> Option> { + fn finalize_remove(&mut self, hash: &T::Hash) -> Option> { self.by_hash.remove(hash).map(|old| { - self.mem_usage -= old.mem_usage(); - old + self.mem_usage -= old.transaction.mem_usage(); + old.transaction }) } /// Updates best and worst transactions from a sender. fn update_senders_worst_and_best( &mut self, - previous: Option<((S::Score, Arc), (S::Score, Arc))>, - current: Option<((S::Score, Arc), (S::Score, Arc))>, + previous: Option<((S::Score, Transaction), (S::Score, Transaction))>, + current: Option<((S::Score, Transaction), (S::Score, Transaction))>, ) { let worst_collection = &mut self.worst_transactions; let best_collection = &mut self.best_transactions; - let is_same = |a: &(S::Score, Arc), b: &(S::Score, Arc)| { + let is_same = |a: &(S::Score, Transaction), b: &(S::Score, Transaction)| { a.0 == b.0 && a.1.hash() == b.1.hash() }; @@ -238,19 +273,19 @@ impl Pool where } /// Attempts to remove the worst transaction from the pool if it's worse than the given one. - fn remove_worst(&mut self, transaction: &T) -> error::Result> { + fn remove_worst(&mut self, transaction: &Transaction) -> error::Result> { let to_remove = match self.worst_transactions.iter().next_back() { // No elements to remove? and the pool is still full? None => { warn!("The pool is full but there are no transactions to remove."); - return Err(error::ErrorKind::TooCheapToEnter(*transaction.hash(), "unknown".into()).into()); + return Err(error::ErrorKind::TooCheapToEnter(format!("{:?}", transaction.hash()), "unknown".into()).into()); }, Some(old) => if self.scoring.should_replace(&old.transaction, transaction) { // New transaction is better than the worst one so we can replace it. old.clone() } else { // otherwise fail - return Err(error::ErrorKind::TooCheapToEnter(*transaction.hash(), format!("{:?}", old.score)).into()) + return Err(error::ErrorKind::TooCheapToEnter(format!("{:?}", transaction.hash()), format!("{:?}", old.score)).into()) }, }; @@ -263,7 +298,7 @@ impl Pool where } /// Removes transaction from sender's transaction `HashMap`. - fn remove_from_set, &S) -> R>(&mut self, sender: &Sender, f: F) -> Option { + fn remove_from_set, &S) -> R>(&mut self, sender: &T::Sender, f: F) -> Option { let (prev, next, result) = if let Some(set) = self.transactions.get_mut(sender) { let prev = set.worst_and_best(); let result = f(set, &self.scoring); @@ -286,14 +321,14 @@ impl Pool where self.worst_transactions.clear(); for (_hash, tx) in self.by_hash.drain() { - self.listener.dropped(&tx, None) + self.listener.dropped(&tx.transaction, None) } } /// Removes single transaction from the pool. /// Depending on the `is_invalid` flag the listener /// will either get a `cancelled` or `invalid` notification. - pub fn remove(&mut self, hash: &H256, is_invalid: bool) -> Option> { + pub fn remove(&mut self, hash: &T::Hash, is_invalid: bool) -> Option> { if let Some(tx) = self.finalize_remove(hash) { self.remove_from_set(tx.sender(), |set, scoring| { set.remove(&tx, scoring) @@ -310,7 +345,7 @@ impl Pool where } /// Removes all stalled transactions from given sender. - fn remove_stalled>(&mut self, sender: &Sender, ready: &mut R) -> usize { + fn remove_stalled>(&mut self, sender: &T::Sender, ready: &mut R) -> usize { let removed_from_set = self.remove_from_set(sender, |transactions, scoring| { transactions.cull(ready, scoring) }); @@ -329,7 +364,7 @@ impl Pool where } /// Removes all stalled transactions from given sender list (or from all senders). - pub fn cull>(&mut self, senders: Option<&[Sender]>, mut ready: R) -> usize { + pub fn cull>(&mut self, senders: Option<&[T::Sender]>, mut ready: R) -> usize { let mut removed = 0; match senders { Some(senders) => { @@ -349,13 +384,13 @@ impl Pool where } /// Returns a transaction if it's part of the pool or `None` otherwise. - pub fn find(&self, hash: &H256) -> Option> { - self.by_hash.get(hash).cloned() + pub fn find(&self, hash: &T::Hash) -> Option> { + self.by_hash.get(hash).map(|t| t.transaction.clone()) } /// Returns worst transaction in the queue (if any). pub fn worst_transaction(&self) -> Option> { - self.worst_transactions.iter().next().map(|x| x.transaction.clone()) + self.worst_transactions.iter().next().map(|x| x.transaction.transaction.clone()) } /// Returns an iterator of pending (ready) transactions. @@ -368,7 +403,7 @@ impl Pool where } /// Returns pending (ready) transactions from given sender. - pub fn pending_from_sender>(&self, ready: R, sender: &Sender) -> PendingIterator { + pub fn pending_from_sender>(&self, ready: R, sender: &T::Sender) -> PendingIterator { let best_transactions = self.transactions.get(sender) .and_then(|transactions| transactions.worst_and_best()) .map(|(_, best)| ScoreWithRef::new(best.0, best.1)) @@ -387,7 +422,7 @@ impl Pool where } /// Update score of transactions of a particular sender. - pub fn update_scores(&mut self, sender: &Sender, event: S::Event) { + pub fn update_scores(&mut self, sender: &T::Sender, event: S::Event) { let res = if let Some(set) = self.transactions.get_mut(sender) { let prev = set.worst_and_best(); set.update_scores(&self.scoring, event); @@ -410,7 +445,7 @@ impl Pool where let len = transactions.len(); for (idx, tx) in transactions.iter().enumerate() { match ready.is_ready(tx) { - Readiness::Stalled => status.stalled += 1, + Readiness::Stale => status.stalled += 1, Readiness::Ready => status.pending += 1, Readiness::Future => { status.future += len - idx; @@ -485,7 +520,7 @@ impl<'a, T, R, S, L> Iterator for PendingIterator<'a, T, R, S, L> where self.best_transactions.insert(ScoreWithRef::new(score, tx)); } - return Some(best.transaction) + return Some(best.transaction.transaction) }, state => trace!("[{:?}] Ignoring {:?} transaction.", best.transaction.hash(), state), } diff --git a/transaction-pool/src/ready.rs b/transaction-pool/src/ready.rs index 7352444322..aa913a9eb5 100644 --- a/transaction-pool/src/ready.rs +++ b/transaction-pool/src/ready.rs @@ -17,8 +17,8 @@ /// Transaction readiness. #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum Readiness { - /// The transaction is stalled (and should/will be removed from the pool). - Stalled, + /// The transaction is stale (and should/will be removed from the pool). + Stale, /// The transaction is ready to be included in pending set. Ready, /// The transaction is not yet ready. diff --git a/transaction-pool/src/scoring.rs b/transaction-pool/src/scoring.rs index 4e7a9833a1..2acfb33748 100644 --- a/transaction-pool/src/scoring.rs +++ b/transaction-pool/src/scoring.rs @@ -17,9 +17,7 @@ //! A transactions ordering abstraction. use std::{cmp, fmt}; -use std::sync::Arc; - -use {VerifiedTransaction}; +use pool::Transaction; /// Represents a decision what to do with /// a new transaction that tries to enter the pool. @@ -98,7 +96,7 @@ pub trait Scoring: fmt::Debug { /// Updates the transaction scores given a list of transactions and a change to previous scoring. /// NOTE: you can safely assume that both slices have the same length. /// (i.e. score at index `i` represents transaction at the same index) - fn update_scores(&self, txs: &[Arc], scores: &mut [Self::Score], change: Change); + fn update_scores(&self, txs: &[Transaction], scores: &mut [Self::Score], change: Change); /// Decides if `new` should push out `old` transaction from the pool. fn should_replace(&self, old: &T, new: &T) -> bool; @@ -110,7 +108,14 @@ pub struct ScoreWithRef { /// Score pub score: S, /// Shared transaction - pub transaction: Arc, + pub transaction: Transaction, +} + +impl ScoreWithRef { + /// Creates a new `ScoreWithRef` + pub fn new(score: S, transaction: Transaction) -> Self { + ScoreWithRef { score, transaction } + } } impl Clone for ScoreWithRef { @@ -122,30 +127,23 @@ impl Clone for ScoreWithRef { } } -impl ScoreWithRef { - /// Creates a new `ScoreWithRef` - pub fn new(score: S, transaction: Arc) -> Self { - ScoreWithRef { score, transaction } - } -} - -impl Ord for ScoreWithRef { +impl Ord for ScoreWithRef { fn cmp(&self, other: &Self) -> cmp::Ordering { other.score.cmp(&self.score) - .then(other.transaction.insertion_id().cmp(&self.transaction.insertion_id())) + .then(other.transaction.insertion_id.cmp(&self.transaction.insertion_id)) } } -impl PartialOrd for ScoreWithRef { +impl PartialOrd for ScoreWithRef { fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } } -impl PartialEq for ScoreWithRef { +impl PartialEq for ScoreWithRef { fn eq(&self, other: &Self) -> bool { - self.score == other.score && self.transaction.insertion_id() == other.transaction.insertion_id() + self.score == other.score && self.transaction.insertion_id == other.transaction.insertion_id } } -impl Eq for ScoreWithRef {} +impl Eq for ScoreWithRef {} diff --git a/transaction-pool/src/tests/helpers.rs b/transaction-pool/src/tests/helpers.rs index ab5b2a334b..cfc6641b5e 100644 --- a/transaction-pool/src/tests/helpers.rs +++ b/transaction-pool/src/tests/helpers.rs @@ -17,9 +17,9 @@ use std::cmp; use std::collections::HashMap; -use ethereum_types::U256; -use {scoring, Scoring, Ready, Readiness, Address as Sender}; -use super::{Transaction, SharedTransaction}; +use ethereum_types::{H160 as Sender, U256}; +use {pool, scoring, Scoring, Ready, Readiness}; +use super::Transaction; #[derive(Debug, Default)] pub struct DummyScoring; @@ -44,7 +44,7 @@ impl Scoring for DummyScoring { } } - fn update_scores(&self, txs: &[SharedTransaction], scores: &mut [Self::Score], change: scoring::Change) { + fn update_scores(&self, txs: &[pool::Transaction], scores: &mut [Self::Score], change: scoring::Change) { if let scoring::Change::Event(_) = change { // In case of event reset all scores to 0 for i in 0..txs.len() { @@ -84,7 +84,7 @@ impl Ready for NonceReady { *nonce = *nonce + 1.into(); Readiness::Ready }, - cmp::Ordering::Less => Readiness::Stalled, + cmp::Ordering::Less => Readiness::Stale, } } } diff --git a/transaction-pool/src/tests/mod.rs b/transaction-pool/src/tests/mod.rs index 5113a4663c..b21ea31807 100644 --- a/transaction-pool/src/tests/mod.rs +++ b/transaction-pool/src/tests/mod.rs @@ -32,15 +32,16 @@ pub struct Transaction { pub gas_price: U256, pub gas: U256, pub sender: Address, - pub insertion_id: u64, pub mem_usage: usize, } impl VerifiedTransaction for Transaction { + type Hash = H256; + type Sender = Address; + fn hash(&self) -> &H256 { &self.hash } fn mem_usage(&self) -> usize { self.mem_usage } fn sender(&self) -> &Address { &self.sender } - fn insertion_id(&self) -> u64 { self.insertion_id } } pub type SharedTransaction = Arc; @@ -123,7 +124,7 @@ fn should_reject_if_above_count() { // Reject second let tx1 = b.tx().nonce(0).new(); let tx2 = b.tx().nonce(1).new(); - let hash = *tx2.hash(); + let hash = format!("{:?}", tx2.hash()); txq.import(tx1).unwrap(); assert_eq!(txq.import(tx2).unwrap_err().kind(), &error::ErrorKind::TooCheapToEnter(hash, "0x0".into())); assert_eq!(txq.light_status().transaction_count, 1); @@ -149,7 +150,7 @@ fn should_reject_if_above_mem_usage() { // Reject second let tx1 = b.tx().nonce(1).mem_usage(1).new(); let tx2 = b.tx().nonce(2).mem_usage(2).new(); - let hash = *tx2.hash(); + let hash = format!("{:?}", tx2.hash()); txq.import(tx1).unwrap(); assert_eq!(txq.import(tx2).unwrap_err().kind(), &error::ErrorKind::TooCheapToEnter(hash, "0x0".into())); assert_eq!(txq.light_status().transaction_count, 1); @@ -175,7 +176,7 @@ fn should_reject_if_above_sender_count() { // Reject second let tx1 = b.tx().nonce(1).new(); let tx2 = b.tx().nonce(2).new(); - let hash = *tx2.hash(); + let hash = format!("{:x}", tx2.hash()); txq.import(tx1).unwrap(); assert_eq!(txq.import(tx2).unwrap_err().kind(), &error::ErrorKind::TooCheapToEnter(hash, "0x0".into())); assert_eq!(txq.light_status().transaction_count, 1); @@ -185,7 +186,7 @@ fn should_reject_if_above_sender_count() { // Replace first let tx1 = b.tx().nonce(1).new(); let tx2 = b.tx().nonce(2).gas_price(2).new(); - let hash = *tx2.hash(); + let hash = format!("{:x}", tx2.hash()); txq.import(tx1).unwrap(); // This results in error because we also compare nonces assert_eq!(txq.import(tx2).unwrap_err().kind(), &error::ErrorKind::TooCheapToEnter(hash, "0x0".into())); diff --git a/transaction-pool/src/tests/tx_builder.rs b/transaction-pool/src/tests/tx_builder.rs index e9c1c1d5fc..88a881aca8 100644 --- a/transaction-pool/src/tests/tx_builder.rs +++ b/transaction-pool/src/tests/tx_builder.rs @@ -14,9 +14,6 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -use std::rc::Rc; -use std::cell::Cell; - use super::{Transaction, U256, Address}; #[derive(Debug, Default, Clone)] @@ -26,7 +23,6 @@ pub struct TransactionBuilder { gas: U256, sender: Address, mem_usage: usize, - insertion_id: Rc>, } impl TransactionBuilder { @@ -55,11 +51,6 @@ impl TransactionBuilder { } pub fn new(self) -> Transaction { - let insertion_id = { - let id = self.insertion_id.get() + 1; - self.insertion_id.set(id); - id - }; let hash = self.nonce ^ (U256::from(100) * self.gas_price) ^ (U256::from(100_000) * U256::from(self.sender.low_u64())); Transaction { hash: hash.into(), @@ -67,7 +58,6 @@ impl TransactionBuilder { gas_price: self.gas_price, gas: 21_000.into(), sender: self.sender, - insertion_id, mem_usage: self.mem_usage, } } diff --git a/transaction-pool/src/transactions.rs b/transaction-pool/src/transactions.rs index c839d9e685..f1a91ff4f8 100644 --- a/transaction-pool/src/transactions.rs +++ b/transaction-pool/src/transactions.rs @@ -15,28 +15,28 @@ // along with Parity. If not, see . use std::{fmt, mem}; -use std::sync::Arc; use smallvec::SmallVec; use ready::{Ready, Readiness}; use scoring::{self, Scoring}; +use pool::Transaction; #[derive(Debug)] pub enum AddResult { - Ok(Arc), + Ok(T), TooCheapToEnter(T, S), TooCheap { - old: Arc, + old: T, new: T, }, Replaced { - old: Arc, - new: Arc, + old: T, + new: T, }, PushedOut { - old: Arc, - new: Arc, + old: T, + new: T, }, } @@ -45,7 +45,7 @@ const PER_SENDER: usize = 8; #[derive(Debug)] pub struct Transactions> { // TODO [ToDr] Consider using something that doesn't require shifting all records. - transactions: SmallVec<[Arc; PER_SENDER]>, + transactions: SmallVec<[Transaction; PER_SENDER]>, scores: SmallVec<[S::Score; PER_SENDER]>, } @@ -67,11 +67,11 @@ impl> Transactions { self.transactions.len() } - pub fn iter(&self) -> ::std::slice::Iter> { + pub fn iter(&self) -> ::std::slice::Iter> { self.transactions.iter() } - pub fn worst_and_best(&self) -> Option<((S::Score, Arc), (S::Score, Arc))> { + pub fn worst_and_best(&self) -> Option<((S::Score, Transaction), (S::Score, Transaction))> { let len = self.scores.len(); self.scores.get(0).cloned().map(|best| { let worst = self.scores[len - 1].clone(); @@ -82,7 +82,7 @@ impl> Transactions { }) } - pub fn find_next(&self, tx: &T, scoring: &S) -> Option<(S::Score, Arc)> { + pub fn find_next(&self, tx: &T, scoring: &S) -> Option<(S::Score, Transaction)> { self.transactions.binary_search_by(|old| scoring.compare(old, &tx)).ok().and_then(|index| { let index = index + 1; if index < self.scores.len() { @@ -93,18 +93,17 @@ impl> Transactions { }) } - fn push_cheapest_transaction(&mut self, tx: T, scoring: &S, max_count: usize) -> AddResult { + fn push_cheapest_transaction(&mut self, tx: Transaction, scoring: &S, max_count: usize) -> AddResult, S::Score> { let index = self.transactions.len(); if index == max_count { let min_score = self.scores[index - 1].clone(); AddResult::TooCheapToEnter(tx, min_score) } else { - let shared = Arc::new(tx); - self.transactions.push(shared.clone()); + self.transactions.push(tx.clone()); self.scores.push(Default::default()); scoring.update_scores(&self.transactions, &mut self.scores, scoring::Change::InsertedAt(index)); - AddResult::Ok(shared) + AddResult::Ok(tx) } } @@ -112,28 +111,26 @@ impl> Transactions { scoring.update_scores(&self.transactions, &mut self.scores, scoring::Change::Event(event)); } - pub fn add(&mut self, tx: T, scoring: &S, max_count: usize) -> AddResult { - let index = match self.transactions.binary_search_by(|old| scoring.compare(old, &tx)) { + pub fn add(&mut self, new: Transaction, scoring: &S, max_count: usize) -> AddResult, S::Score> { + let index = match self.transactions.binary_search_by(|old| scoring.compare(old, &new)) { Ok(index) => index, Err(index) => index, }; // Insert at the end. if index == self.transactions.len() { - return self.push_cheapest_transaction(tx, scoring, max_count) + return self.push_cheapest_transaction(new, scoring, max_count) } // Decide if the transaction should replace some other. - match scoring.choose(&self.transactions[index], &tx) { + match scoring.choose(&self.transactions[index], &new) { // New transaction should be rejected scoring::Choice::RejectNew => AddResult::TooCheap { old: self.transactions[index].clone(), - new: tx, + new, }, // New transaction should be kept along with old ones. scoring::Choice::InsertNew => { - let new = Arc::new(tx); - self.transactions.insert(index, new.clone()); self.scores.insert(index, Default::default()); scoring.update_scores(&self.transactions, &mut self.scores, scoring::Change::InsertedAt(index)); @@ -153,7 +150,6 @@ impl> Transactions { }, // New transaction is replacing some other transaction already in the queue. scoring::Choice::ReplaceOld => { - let new = Arc::new(tx); let old = mem::replace(&mut self.transactions[index], new.clone()); scoring.update_scores(&self.transactions, &mut self.scores, scoring::Change::ReplacedAt(index)); @@ -181,7 +177,7 @@ impl> Transactions { return true; } - pub fn cull>(&mut self, ready: &mut R, scoring: &S) -> SmallVec<[Arc; PER_SENDER]> { + pub fn cull>(&mut self, ready: &mut R, scoring: &S) -> SmallVec<[Transaction; PER_SENDER]> { let mut result = SmallVec::new(); if self.is_empty() { return result; @@ -190,7 +186,7 @@ impl> Transactions { let mut first_non_stalled = 0; for tx in &self.transactions { match ready.is_ready(tx) { - Readiness::Stalled => { + Readiness::Stale => { first_non_stalled += 1; }, Readiness::Ready | Readiness::Future => break, -- GitLab From b10094508f3a149830199ed35ea5ad7850a43603 Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Wed, 2 May 2018 15:40:27 +0800 Subject: [PATCH 003/152] Fetching logs by hash in blockchain database (#8463) * Fetch logs by hash in blockchain database * Fix tests * Add unit test for branch block logs fetching * Add docs that blocks must already be sorted * Handle branch block cases properly * typo: empty -> is_empty * Remove return_empty_if_none by using a closure * Use BTreeSet to avoid sorting again * Move is_canon to BlockChain * typo: pass value by reference * Use loop and wrap inside blocks to simplify the code Borrowed from https://github.com/paritytech/parity/pull/8463#discussion_r183453326 * typo: missed a comment --- ethcore/src/blockchain/blockchain.rs | 60 ++++++++++++++-- ethcore/src/client/client.rs | 91 +++++++++++++++++++----- ethcore/src/verification/verification.rs | 2 +- 3 files changed, 129 insertions(+), 24 deletions(-) diff --git a/ethcore/src/blockchain/blockchain.rs b/ethcore/src/blockchain/blockchain.rs index 6ad8bf8111..57bcdf2bc2 100644 --- a/ethcore/src/blockchain/blockchain.rs +++ b/ethcore/src/blockchain/blockchain.rs @@ -57,6 +57,12 @@ pub trait BlockProvider { /// (though not necessarily a part of the canon chain). fn is_known(&self, hash: &H256) -> bool; + /// Returns true if the given block is known and in the canon chain. + fn is_canon(&self, hash: &H256) -> bool { + let is_canon = || Some(hash == &self.block_hash(self.block_number(hash)?)?); + is_canon().unwrap_or(false) + } + /// Get the first block of the best part of the chain. /// Return `None` if there is no gap and the first block is the genesis. /// Any queries of blocks which precede this one are not guaranteed to @@ -148,7 +154,7 @@ pub trait BlockProvider { fn blocks_with_bloom(&self, bloom: &Bloom, from_block: BlockNumber, to_block: BlockNumber) -> Vec; /// Returns logs matching given filter. - fn logs(&self, blocks: Vec, matches: F, limit: Option) -> Vec + fn logs(&self, blocks: Vec, matches: F, limit: Option) -> Vec where F: Fn(&LogEntry) -> bool + Send + Sync, Self: Sized; } @@ -332,16 +338,18 @@ impl BlockProvider for BlockChain { .collect() } - fn logs(&self, mut blocks: Vec, matches: F, limit: Option) -> Vec + /// Returns logs matching given filter. The order of logs returned will be the same as the order of the blocks + /// provided. And it's the callers responsibility to sort blocks provided in advance. + fn logs(&self, mut blocks: Vec, matches: F, limit: Option) -> Vec where F: Fn(&LogEntry) -> bool + Send + Sync, Self: Sized { // sort in reverse order - blocks.sort_by(|a, b| b.cmp(a)); + blocks.reverse(); let mut logs = blocks .chunks(128) .flat_map(move |blocks_chunk| { blocks_chunk.into_par_iter() - .filter_map(|number| self.block_hash(*number).map(|hash| (*number, hash))) + .filter_map(|hash| self.block_number(&hash).map(|r| (r, hash))) .filter_map(|(number, hash)| self.block_receipts(&hash).map(|r| (number, hash, r.receipts))) .filter_map(|(number, hash, receipts)| self.block_body(&hash).map(|ref b| (number, hash, receipts, b.transaction_hashes()))) .flat_map(|(number, hash, mut receipts, mut hashes)| { @@ -368,7 +376,7 @@ impl BlockProvider for BlockChain { .enumerate() .map(move |(i, log)| LocalizedLogEntry { entry: log, - block_hash: hash, + block_hash: *hash, block_number: number, transaction_hash: tx_hash, // iterating in reverse order @@ -1933,17 +1941,33 @@ mod tests { value: 103.into(), data: "601080600c6000396000f3006000355415600957005b60203560003555".from_hex().unwrap(), }.sign(&secret(), None); + let t4 = Transaction { + nonce: 0.into(), + gas_price: 0.into(), + gas: 100_000.into(), + action: Action::Create, + value: 104.into(), + data: "601080600c6000396000f3006000355415600957005b60203560003555".from_hex().unwrap(), + }.sign(&secret(), None); let tx_hash1 = t1.hash(); let tx_hash2 = t2.hash(); let tx_hash3 = t3.hash(); + let tx_hash4 = t4.hash(); let genesis = BlockBuilder::genesis(); let b1 = genesis.add_block_with_transactions(vec![t1, t2]); let b2 = b1.add_block_with_transactions(iter::once(t3)); + let b3 = genesis.add_block_with(|| BlockOptions { + transactions: vec![t4.clone()], + difficulty: U256::from(9), + ..Default::default() + }); // Branch block let b1_hash = b1.last().hash(); let b1_number = b1.last().number(); let b2_hash = b2.last().hash(); let b2_number = b2.last().number(); + let b3_hash = b3.last().hash(); + let b3_number = b3.last().number(); let db = new_db(); let bc = new_chain(&genesis.last().encoded(), db.clone()); @@ -1974,10 +1998,21 @@ mod tests { ], } ]); + insert_block(&db, &bc, &b3.last().encoded(), vec![ + Receipt { + outcome: TransactionOutcome::StateRoot(H256::default()), + gas_used: 10_000.into(), + log_bloom: Default::default(), + logs: vec![ + LogEntry { address: Default::default(), topics: vec![], data: vec![5], }, + ], + } + ]); // when - let logs1 = bc.logs(vec![1, 2], |_| true, None); - let logs2 = bc.logs(vec![1, 2], |_| true, Some(1)); + let logs1 = bc.logs(vec![b1_hash, b2_hash], |_| true, None); + let logs2 = bc.logs(vec![b1_hash, b2_hash], |_| true, Some(1)); + let logs3 = bc.logs(vec![b3_hash], |_| true, None); // then assert_eq!(logs1, vec![ @@ -2029,6 +2064,17 @@ mod tests { log_index: 0, } ]); + assert_eq!(logs3, vec![ + LocalizedLogEntry { + entry: LogEntry { address: Default::default(), topics: vec![], data: vec![5] }, + block_hash: b3_hash, + block_number: b3_number, + transaction_hash: tx_hash4, + transaction_index: 0, + transaction_log_index: 0, + log_index: 0, + } + ]); } #[test] diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index bc20de3dd8..5efdef3a4d 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -14,7 +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, BTreeMap, VecDeque}; +use std::collections::{HashSet, HashMap, BTreeMap, BTreeSet, VecDeque}; use std::str::FromStr; use std::sync::{Arc, Weak}; use std::sync::atomic::{AtomicUsize, AtomicBool, Ordering as AtomicOrdering}; @@ -1848,23 +1848,82 @@ impl BlockChainClient for Client { } fn logs(&self, filter: Filter) -> Vec { - let (from, to) = match (self.block_number_ref(&filter.from_block), self.block_number_ref(&filter.to_block)) { - (Some(from), Some(to)) => (from, to), - _ => return Vec::new(), - }; + // Wrap the logic inside a closure so that we can take advantage of question mark syntax. + let fetch_logs = || { + let chain = self.chain.read(); - let chain = self.chain.read(); - let blocks = filter.bloom_possibilities().iter() - .map(move |bloom| { - chain.blocks_with_bloom(bloom, from, to) - }) - .flat_map(|m| m) - // remove duplicate elements - .collect::>() - .into_iter() - .collect::>(); + // First, check whether `filter.from_block` and `filter.to_block` is on the canon chain. If so, we can use the + // optimized version. + let is_canon = |id| { + match id { + // If it is referred by number, then it is always on the canon chain. + &BlockId::Earliest | &BlockId::Latest | &BlockId::Number(_) => true, + // If it is referred by hash, we see whether a hash -> number -> hash conversion gives us the same + // result. + &BlockId::Hash(ref hash) => chain.is_canon(hash), + } + }; + + let blocks = if is_canon(&filter.from_block) && is_canon(&filter.to_block) { + // If we are on the canon chain, use bloom filter to fetch required hashes. + let from = self.block_number_ref(&filter.from_block)?; + let to = self.block_number_ref(&filter.to_block)?; + + filter.bloom_possibilities().iter() + .map(|bloom| { + chain.blocks_with_bloom(bloom, from, to) + }) + .flat_map(|m| m) + // remove duplicate elements + .collect::>() + .into_iter() + .filter_map(|n| chain.block_hash(n)) + .collect::>() + + } else { + // Otherwise, we use a slower version that finds a link between from_block and to_block. + let from_hash = Self::block_hash(&chain, filter.from_block)?; + let from_number = chain.block_number(&from_hash)?; + let to_hash = Self::block_hash(&chain, filter.from_block)?; + + let blooms = filter.bloom_possibilities(); + let bloom_match = |header: &encoded::Header| { + blooms.iter().any(|bloom| header.log_bloom().contains_bloom(bloom)) + }; + + let (blocks, last_hash) = { + let mut blocks = Vec::new(); + let mut current_hash = to_hash; + + loop { + let header = chain.block_header_data(¤t_hash)?; + if bloom_match(&header) { + blocks.push(current_hash); + } + + // Stop if `from` block is reached. + if header.number() <= from_number { + break; + } + current_hash = header.parent_hash(); + } + + blocks.reverse(); + (blocks, current_hash) + }; + + // Check if we've actually reached the expected `from` block. + if last_hash != from_hash || blocks.is_empty() { + return None; + } + + blocks + }; + + Some(self.chain.read().logs(blocks, |entry| filter.matches(entry), filter.limit)) + }; - self.chain.read().logs(blocks, |entry| filter.matches(entry), filter.limit) + fetch_logs().unwrap_or_default() } fn filter_traces(&self, filter: TraceFilter) -> Option> { diff --git a/ethcore/src/verification/verification.rs b/ethcore/src/verification/verification.rs index 814a12aadf..92f3e77f90 100644 --- a/ethcore/src/verification/verification.rs +++ b/ethcore/src/verification/verification.rs @@ -476,7 +476,7 @@ mod tests { unimplemented!() } - fn logs(&self, _blocks: Vec, _matches: F, _limit: Option) -> Vec + fn logs(&self, _blocks: Vec, _matches: F, _limit: Option) -> Vec where F: Fn(&LogEntry) -> bool, Self: Sized { unimplemented!() } -- GitLab From eec7364760e760c798e744bba7c05f2ae9dd700a Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Wed, 2 May 2018 22:47:53 +0800 Subject: [PATCH 004/152] Pass on storage keys tracing to handle the case when it is not modified (#8491) * Pass on storage keys even if it is not modified * typo: account and storage query `to_pod_diff` builds both `touched_addresses` merge and storage keys merge. * Fix tests * Use state query directly because of suicided accounts * Fix a RefCell borrow issue * Add tests for unmodified storage trace * Address grumbles * typo: remove unwanted empty line * ensure_cached compiles with the original signature --- ethcore/src/state/mod.rs | 114 +++++++++++++++++++++++++++++---------- 1 file changed, 87 insertions(+), 27 deletions(-) diff --git a/ethcore/src/state/mod.rs b/ethcore/src/state/mod.rs index 9fd3fd8525..255dce5b5d 100644 --- a/ethcore/src/state/mod.rs +++ b/ethcore/src/state/mod.rs @@ -21,7 +21,7 @@ use std::cell::{RefCell, RefMut}; use std::collections::hash_map::Entry; -use std::collections::{HashMap, BTreeMap, HashSet}; +use std::collections::{HashMap, BTreeMap, BTreeSet, HashSet}; use std::fmt; use std::sync::Arc; use hash::{KECCAK_NULL_RLP, KECCAK_EMPTY}; @@ -862,40 +862,65 @@ impl State { })) } - // Return a list of all touched addresses in cache. - fn touched_addresses(&self) -> Vec
{ + /// Populate a PodAccount map from this state, with another state as the account and storage query. + pub fn to_pod_diff(&mut self, query: &State) -> trie::Result { assert!(self.checkpoints.borrow().is_empty()); - self.cache.borrow().iter().map(|(add, _)| *add).collect() - } - fn query_pod(&mut self, query: &PodState, touched_addresses: &[Address]) -> trie::Result<()> { - let pod = query.get(); + // Merge PodAccount::to_pod for cache of self and `query`. + let all_addresses = self.cache.borrow().keys().cloned() + .chain(query.cache.borrow().keys().cloned()) + .collect::>(); + + Ok(PodState::from(all_addresses.into_iter().fold(Ok(BTreeMap::new()), |m: trie::Result<_>, address| { + let mut m = m?; + + let account = self.ensure_cached(&address, RequireCache::Code, true, |acc| { + acc.map(|acc| { + // Merge all modified storage keys. + let all_keys = { + let self_keys = acc.storage_changes().keys().cloned() + .collect::>(); + + if let Some(ref query_storage) = query.cache.borrow().get(&address) + .and_then(|opt| { + Some(opt.account.as_ref()?.storage_changes().keys().cloned() + .collect::>()) + }) + { + self_keys.union(&query_storage).cloned().collect::>() + } else { + self_keys.into_iter().collect::>() + } + }; - for address in touched_addresses { - if !self.ensure_cached(address, RequireCache::Code, true, |a| a.is_some())? { - continue - } + // Storage must be fetched after ensure_cached to avoid borrow problem. + (*acc.balance(), *acc.nonce(), all_keys, acc.code().map(|x| x.to_vec())) + }) + })?; - if let Some(pod_account) = pod.get(address) { - // needs to be split into two parts for the refcell code here - // to work. - for key in pod_account.storage.keys() { - self.storage_at(address, key)?; - } + if let Some((balance, nonce, storage_keys, code)) = account { + let storage = storage_keys.into_iter().fold(Ok(BTreeMap::new()), |s: trie::Result<_>, key| { + let mut s = s?; + + s.insert(key, self.storage_at(&address, &key)?); + Ok(s) + })?; + + m.insert(address, PodAccount { + balance, nonce, storage, code + }); } - } - Ok(()) + Ok(m) + })?)) } /// Returns a `StateDiff` describing the difference from `orig` to `self`. /// Consumes self. - pub fn diff_from(&self, orig: State) -> trie::Result { - let addresses_post = self.touched_addresses(); + pub fn diff_from(&self, mut orig: State) -> trie::Result { let pod_state_post = self.to_pod(); - let mut state_pre = orig; - state_pre.query_pod(&pod_state_post, &addresses_post)?; - Ok(pod_state::diff_pod(&state_pre.to_pod(), &pod_state_post)) + let pod_state_pre = orig.to_pod_diff(self)?; + Ok(pod_state::diff_pod(&pod_state_pre, &pod_state_post)) } // load required account data from the databases. @@ -2243,9 +2268,6 @@ mod tests { let original = state.clone(); state.kill_account(&a); - assert_eq!(original.touched_addresses(), vec![]); - assert_eq!(state.touched_addresses(), vec![a]); - let diff = state.diff_from(original).unwrap(); let diff_map = diff.get(); assert_eq!(diff_map.len(), 1); @@ -2258,4 +2280,42 @@ mod tests { storage: Default::default() }), None).as_ref()); } + + #[test] + fn should_trace_diff_unmodified_storage() { + use pod_account; + + let a = 10.into(); + let db = get_temp_state_db(); + + let (root, db) = { + let mut state = State::new(db, U256::from(0), Default::default()); + state.set_storage(&a, H256::from(&U256::from(1u64)), H256::from(&U256::from(20u64))).unwrap(); + state.commit().unwrap(); + state.drop() + }; + + let mut state = State::from_existing(db, root, U256::from(0u8), Default::default()).unwrap(); + let original = state.clone(); + state.set_storage(&a, H256::from(&U256::from(1u64)), H256::from(&U256::from(100u64))).unwrap(); + + let diff = state.diff_from(original).unwrap(); + let diff_map = diff.get(); + assert_eq!(diff_map.len(), 1); + assert!(diff_map.get(&a).is_some()); + assert_eq!(diff_map.get(&a), + pod_account::diff_pod(Some(&PodAccount { + balance: U256::zero(), + nonce: U256::zero(), + code: Some(Default::default()), + storage: vec![(H256::from(&U256::from(1u64)), H256::from(&U256::from(20u64)))] + .into_iter().collect(), + }), Some(&PodAccount { + balance: U256::zero(), + nonce: U256::zero(), + code: Some(Default::default()), + storage: vec![(H256::from(&U256::from(1u64)), H256::from(&U256::from(100u64)))] + .into_iter().collect(), + })).as_ref()); + } } -- GitLab From 66c0638f3bddd262e4de19eb565413f82fda08fb Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Thu, 3 May 2018 08:01:13 +0100 Subject: [PATCH 005/152] Don't panic in import_block if invalid rlp (#8522) * Don't panic in import_block if invalid rlp * Remove redundant type annotation * Replace RLP header view usage with safe decoding Using the view will panic with invalid RLP. Here we use Rlp decoding directly which will return a `Result<_, DecoderError>`. While this path currently should not have any invalid RLP - it makes it safer if ever called with invalid RLP from other code paths. --- ethcore/src/client/client.rs | 14 ++++++-------- ethcore/src/error.rs | 2 ++ ethcore/src/tests/client.rs | 20 ++++++++++++++++++++ ethcore/src/verification/queue/kind.rs | 9 ++++----- ethcore/src/verification/queue/mod.rs | 23 ++++++++++++++--------- 5 files changed, 46 insertions(+), 22 deletions(-) diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index 5efdef3a4d..a37d62a591 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -447,9 +447,7 @@ impl Importer { /// /// The block is guaranteed to be the next best blocks in the /// first block sequence. Does no sealing or transaction validation. - fn import_old_block(&self, block_bytes: Bytes, receipts_bytes: Bytes, db: &KeyValueDB, chain: &BlockChain) -> Result { - let block = view!(BlockView, &block_bytes); - let header = block.header(); + fn import_old_block(&self, header: &Header, block_bytes: Bytes, receipts_bytes: Bytes, db: &KeyValueDB, chain: &BlockChain) -> Result { let receipts = ::rlp::decode_list(&receipts_bytes); let hash = header.hash(); let _import_lock = self.import_lock.lock(); @@ -1408,7 +1406,7 @@ impl ImportBlock for Client { use verification::queue::kind::blocks::Unverified; // create unverified block here so the `keccak` calculation can be cached. - let unverified = Unverified::new(bytes); + let unverified = Unverified::from_rlp(bytes)?; { if self.chain.read().is_known(&unverified.hash()) { @@ -1423,19 +1421,19 @@ impl ImportBlock for Client { } fn import_block_with_receipts(&self, block_bytes: Bytes, receipts_bytes: Bytes) -> Result { + let header: Header = ::rlp::Rlp::new(&block_bytes).val_at(0)?; { // check block order - let header = view!(BlockView, &block_bytes).header_view(); if self.chain.read().is_known(&header.hash()) { bail!(BlockImportErrorKind::Import(ImportErrorKind::AlreadyInChain)); } - let status = self.block_status(BlockId::Hash(header.parent_hash())); + let status = self.block_status(BlockId::Hash(*header.parent_hash())); if status == BlockStatus::Unknown || status == BlockStatus::Pending { - bail!(BlockImportErrorKind::Block(BlockError::UnknownParent(header.parent_hash()))); + bail!(BlockImportErrorKind::Block(BlockError::UnknownParent(*header.parent_hash()))); } } - self.importer.import_old_block(block_bytes, receipts_bytes, &**self.db.read(), &*self.chain.read()).map_err(Into::into) + self.importer.import_old_block(&header, block_bytes, receipts_bytes, &**self.db.read(), &*self.chain.read()).map_err(Into::into) } } diff --git a/ethcore/src/error.rs b/ethcore/src/error.rs index b68bf35534..561701e762 100644 --- a/ethcore/src/error.rs +++ b/ethcore/src/error.rs @@ -190,6 +190,7 @@ error_chain! { foreign_links { Block(BlockError) #[doc = "Block error"]; + Decoder(::rlp::DecoderError) #[doc = "Rlp decoding error"]; } errors { @@ -206,6 +207,7 @@ impl From for BlockImportError { match e { Error(ErrorKind::Block(block_error), _) => BlockImportErrorKind::Block(block_error).into(), Error(ErrorKind::Import(import_error), _) => BlockImportErrorKind::Import(import_error.into()).into(), + Error(ErrorKind::Util(util_error::ErrorKind::Decoder(decoder_err)), _) => BlockImportErrorKind::Decoder(decoder_err).into(), _ => BlockImportErrorKind::Other(format!("other block import error: {:?}", e)).into(), } } diff --git a/ethcore/src/tests/client.rs b/ethcore/src/tests/client.rs index 0b8200e938..6dcad9ba62 100644 --- a/ethcore/src/tests/client.rs +++ b/ethcore/src/tests/client.rs @@ -36,6 +36,7 @@ use views::BlockView; use ethkey::KeyPair; use transaction::{PendingTransaction, Transaction, Action, Condition}; use miner::MinerService; +use rlp::{RlpStream, EMPTY_LIST_RLP}; use tempdir::TempDir; #[test] @@ -111,6 +112,25 @@ fn imports_good_block() { assert!(!block.into_inner().is_empty()); } +#[test] +fn fails_to_import_block_with_invalid_rlp() { + use error::{BlockImportError, BlockImportErrorKind}; + + let client = generate_dummy_client(6); + let mut rlp = RlpStream::new_list(3); + rlp.append_raw(&EMPTY_LIST_RLP, 1); // empty header + rlp.append_raw(&EMPTY_LIST_RLP, 1); + rlp.append_raw(&EMPTY_LIST_RLP, 1); + let invalid_header_block = rlp.out(); + + match client.import_block(invalid_header_block) { + Err(BlockImportError(BlockImportErrorKind::Decoder(_), _)) => (), // all good + Err(_) => panic!("Should fail with a decoder error"), + Ok(_) => panic!("Should not import block with invalid header"), + } +} + + #[test] fn query_none_block() { let tempdir = TempDir::new("").unwrap(); diff --git a/ethcore/src/verification/queue/kind.rs b/ethcore/src/verification/queue/kind.rs index 7007da5be1..ce9bddf4ef 100644 --- a/ethcore/src/verification/queue/kind.rs +++ b/ethcore/src/verification/queue/kind.rs @@ -119,14 +119,13 @@ pub mod blocks { impl Unverified { /// Create an `Unverified` from raw bytes. - pub fn new(bytes: Bytes) -> Self { - use views::BlockView; + pub fn from_rlp(bytes: Bytes) -> Result { - let header = view!(BlockView, &bytes).header(); - Unverified { + let header = ::rlp::Rlp::new(&bytes).val_at(0)?; + Ok(Unverified { header: header, bytes: bytes, - } + }) } } diff --git a/ethcore/src/verification/queue/mod.rs b/ethcore/src/verification/queue/mod.rs index ca633b0f3d..f7a558f33d 100644 --- a/ethcore/src/verification/queue/mod.rs +++ b/ethcore/src/verification/queue/mod.rs @@ -734,6 +734,7 @@ mod tests { use test_helpers::{get_good_dummy_block_seq, get_good_dummy_block}; use error::*; use views::BlockView; + use bytes::Bytes; // create a test block queue. // auto_scaling enables verifier adjustment. @@ -746,6 +747,10 @@ mod tests { BlockQueue::new(config, engine, IoChannel::disconnected(), true) } + fn new_unverified(bytes: Bytes) -> Unverified { + Unverified::from_rlp(bytes).expect("Should be valid rlp") + } + #[test] fn can_be_created() { // TODO better test @@ -757,7 +762,7 @@ mod tests { #[test] fn can_import_blocks() { let queue = get_test_queue(false); - if let Err(e) = queue.import(Unverified::new(get_good_dummy_block())) { + if let Err(e) = queue.import(new_unverified(get_good_dummy_block())) { panic!("error importing block that is valid by definition({:?})", e); } } @@ -765,11 +770,11 @@ mod tests { #[test] fn returns_error_for_duplicates() { let queue = get_test_queue(false); - if let Err(e) = queue.import(Unverified::new(get_good_dummy_block())) { + if let Err(e) = queue.import(new_unverified(get_good_dummy_block())) { panic!("error importing block that is valid by definition({:?})", e); } - let duplicate_import = queue.import(Unverified::new(get_good_dummy_block())); + let duplicate_import = queue.import(new_unverified(get_good_dummy_block())); match duplicate_import { Err(e) => { match e { @@ -786,7 +791,7 @@ mod tests { let queue = get_test_queue(false); let block = get_good_dummy_block(); let hash = view!(BlockView, &block).header().hash().clone(); - if let Err(e) = queue.import(Unverified::new(block)) { + if let Err(e) = queue.import(new_unverified(block)) { panic!("error importing block that is valid by definition({:?})", e); } queue.flush(); @@ -802,14 +807,14 @@ mod tests { let queue = get_test_queue(false); let block = get_good_dummy_block(); let hash = view!(BlockView, &block).header().hash().clone(); - if let Err(e) = queue.import(Unverified::new(block)) { + if let Err(e) = queue.import(new_unverified(block)) { panic!("error importing block that is valid by definition({:?})", e); } queue.flush(); queue.drain(10); queue.mark_as_good(&[ hash ]); - if let Err(e) = queue.import(Unverified::new(get_good_dummy_block())) { + if let Err(e) = queue.import(new_unverified(get_good_dummy_block())) { panic!("error importing block that has already been drained ({:?})", e); } } @@ -817,7 +822,7 @@ mod tests { #[test] fn returns_empty_once_finished() { let queue = get_test_queue(false); - queue.import(Unverified::new(get_good_dummy_block())) + queue.import(new_unverified(get_good_dummy_block())) .expect("error importing block that is valid by definition"); queue.flush(); queue.drain(1); @@ -835,7 +840,7 @@ mod tests { assert!(!queue.queue_info().is_full()); let mut blocks = get_good_dummy_block_seq(50); for b in blocks.drain(..) { - queue.import(Unverified::new(b)).unwrap(); + queue.import(new_unverified(b)).unwrap(); } assert!(queue.queue_info().is_full()); } @@ -863,7 +868,7 @@ mod tests { *queue.state.0.lock() = State::Work(0); for block in get_good_dummy_block_seq(5000) { - queue.import(Unverified::new(block)).expect("Block good by definition; qed"); + queue.import(new_unverified(block)).expect("Block good by definition; qed"); } // almost all unverified == bump verifier count. -- GitLab From f0c6d17ad81636d3ca02e1694d5ffe39941ad425 Mon Sep 17 00:00:00 2001 From: David Date: Fri, 4 May 2018 10:06:54 +0200 Subject: [PATCH 006/152] Remove expect (#8536) * Remove expect and propagate rlp::DecoderErrors as TrieErrors --- util/patricia_trie/src/lib.rs | 8 ++++++++ util/patricia_trie/src/lookup.rs | 2 +- util/patricia_trie/src/triedb.rs | 27 +++++++++++++++++++++++++++ util/rlp/src/error.rs | 2 +- 4 files changed, 37 insertions(+), 2 deletions(-) diff --git a/util/patricia_trie/src/lib.rs b/util/patricia_trie/src/lib.rs index 3a1d683c26..d1563becff 100644 --- a/util/patricia_trie/src/lib.rs +++ b/util/patricia_trie/src/lib.rs @@ -67,6 +67,8 @@ pub enum TrieError { InvalidStateRoot(H256), /// Trie item not found in the database, IncompleteDatabase(H256), + /// Corrupt Trie item + DecoderError(rlp::DecoderError), } impl fmt::Display for TrieError { @@ -75,6 +77,7 @@ impl fmt::Display for TrieError { TrieError::InvalidStateRoot(ref root) => write!(f, "Invalid state root: {}", root), TrieError::IncompleteDatabase(ref missing) => write!(f, "Database missing expected key: {}", missing), + TrieError::DecoderError(ref err) => write!(f, "Decoding failed with {}", err), } } } @@ -84,10 +87,15 @@ impl error::Error for TrieError { match *self { TrieError::InvalidStateRoot(_) => "Invalid state root", TrieError::IncompleteDatabase(_) => "Incomplete database", + TrieError::DecoderError(ref e) => e.description(), } } } +impl From for Box { + fn from(e: rlp::DecoderError) -> Self { Box::new(TrieError::DecoderError(e)) } +} + /// Trie result type. Boxed to avoid copying around extra space for `H256`s on successful queries. pub type Result = ::std::result::Result>; diff --git a/util/patricia_trie/src/lookup.rs b/util/patricia_trie/src/lookup.rs index 88d2bc66e0..2d63f7d00e 100644 --- a/util/patricia_trie/src/lookup.rs +++ b/util/patricia_trie/src/lookup.rs @@ -55,7 +55,7 @@ impl<'a, Q: Query> Lookup<'a, Q> { // without incrementing the depth. let mut node_data = &node_data[..]; loop { - match Node::decoded(node_data).expect("rlp read from db; qed") { + match Node::decoded(node_data)? { Node::Leaf(slice, value) => { return Ok(match slice == key { true => Some(self.query.decode(value)), diff --git a/util/patricia_trie/src/triedb.rs b/util/patricia_trie/src/triedb.rs index 682f12467d..aed683117d 100644 --- a/util/patricia_trie/src/triedb.rs +++ b/util/patricia_trie/src/triedb.rs @@ -493,3 +493,30 @@ fn get_len() { assert_eq!(t.get_with(b"B", |x: &[u8]| x.len()), Ok(Some(5))); assert_eq!(t.get_with(b"C", |x: &[u8]| x.len()), Ok(None)); } + +// Test will work once https://github.com/paritytech/parity/pull/8527 is merged and rlp::decode returns Result instead of panicking +//#[test] +//fn test_lookup_with_corrupt_data_returns_decoder_error() { +// use memorydb::*; +// use super::TrieMut; +// use super::triedbmut::*; +// use rlp; +// use ethereum_types::H512; +// +// let mut memdb = MemoryDB::new(); +// let mut root = H256::new(); +// { +// let mut t = TrieDBMut::new(&mut memdb, &mut root); +// t.insert(b"A", b"ABC").unwrap(); +// t.insert(b"B", b"ABCBA").unwrap(); +// } +// +// let t = TrieDB::new(&memdb, &root).unwrap(); +// +// // query for an invalid data type to trigger an error +// let q = rlp::decode::; +// let lookup = Lookup{ db: t.db, query: q, hash: root }; +// let query_result = lookup.look_up(NibbleSlice::new(b"A")); +// let expected = Box::new(TrieError::DecoderError(::rlp::DecoderError::RlpIsTooShort)); +// assert_eq!(query_result.unwrap_err(), expected); +//} diff --git a/util/rlp/src/error.rs b/util/rlp/src/error.rs index 5113fdc17d..7aef6cfbf7 100644 --- a/util/rlp/src/error.rs +++ b/util/rlp/src/error.rs @@ -9,7 +9,7 @@ use std::fmt; use std::error::Error as StdError; -#[derive(Debug, PartialEq, Eq)] +#[derive(Debug, PartialEq, Eq, Clone)] /// Error concerning the RLP decoder. pub enum DecoderError { /// Data has additional bytes at the end of the valid RLP fragment. -- GitLab From a4c7843a073cceecf3d2adb8df26e96aa2e6bb6e Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Sat, 5 May 2018 16:23:50 +0800 Subject: [PATCH 007/152] EIP 145: Bitwise shifting instructions in EVM (#8451) * Add SHL, SHR, SAR opcodes * Add have_bitwise_shifting schedule flag * Add all EIP tests for SHL * Add SHR implementation and tests * Implement SAR and add tests * Add eip145transition config param * Change map_or to map_or_else when possible --- ethcore/evm/src/instructions.rs | 10 +- ethcore/evm/src/interpreter/mod.rs | 55 +++++- ethcore/evm/src/tests.rs | 268 ++++++++++++++++++++++++++++- ethcore/src/spec/spec.rs | 39 +++-- ethcore/vm/src/schedule.rs | 12 +- ethcore/vm/src/tests.rs | 7 + json/src/spec/params.rs | 3 + 7 files changed, 374 insertions(+), 20 deletions(-) diff --git a/ethcore/evm/src/instructions.rs b/ethcore/evm/src/instructions.rs index 3fb9fb9339..6ecfc7f673 100644 --- a/ethcore/evm/src/instructions.rs +++ b/ethcore/evm/src/instructions.rs @@ -187,6 +187,9 @@ lazy_static! { arr[OR as usize] = InstructionInfo::new("OR", 2, 1, GasPriceTier::VeryLow); arr[XOR as usize] = InstructionInfo::new("XOR", 2, 1, GasPriceTier::VeryLow); arr[BYTE as usize] = InstructionInfo::new("BYTE", 2, 1, GasPriceTier::VeryLow); + arr[SHL as usize] = InstructionInfo::new("SHL", 2, 1, GasPriceTier::VeryLow); + arr[SHR as usize] = InstructionInfo::new("SHR", 2, 1, GasPriceTier::VeryLow); + arr[SAR as usize] = InstructionInfo::new("SAR", 2, 1, GasPriceTier::VeryLow); arr[ADDMOD as usize] = InstructionInfo::new("ADDMOD", 3, 1, GasPriceTier::Mid); arr[MULMOD as usize] = InstructionInfo::new("MULMOD", 3, 1, GasPriceTier::Mid); arr[SIGNEXTEND as usize] = InstructionInfo::new("SIGNEXTEND", 2, 1, GasPriceTier::Low); @@ -354,6 +357,12 @@ pub const XOR: Instruction = 0x18; pub const NOT: Instruction = 0x19; /// retrieve single byte from word pub const BYTE: Instruction = 0x1a; +/// shift left operation +pub const SHL: Instruction = 0x1b; +/// logical shift right operation +pub const SHR: Instruction = 0x1c; +/// arithmetic shift right operation +pub const SAR: Instruction = 0x1d; /// compute SHA3-256 hash pub const SHA3: Instruction = 0x20; @@ -589,4 +598,3 @@ pub const REVERT: Instruction = 0xfd; pub const STATICCALL: Instruction = 0xfa; /// halt execution and register account for later deletion pub const SUICIDE: Instruction = 0xff; - diff --git a/ethcore/evm/src/interpreter/mod.rs b/ethcore/evm/src/interpreter/mod.rs index 05d1fb7885..160a2e5b1d 100644 --- a/ethcore/evm/src/interpreter/mod.rs +++ b/ethcore/evm/src/interpreter/mod.rs @@ -224,7 +224,8 @@ impl Interpreter { (instruction == instructions::CREATE2 && !schedule.have_create2) || (instruction == instructions::STATICCALL && !schedule.have_static_call) || ((instruction == instructions::RETURNDATACOPY || instruction == instructions::RETURNDATASIZE) && !schedule.have_return_data) || - (instruction == instructions::REVERT && !schedule.have_revert) { + (instruction == instructions::REVERT && !schedule.have_revert) || + ((instruction == instructions::SHL || instruction == instructions::SHR || instruction == instructions::SAR) && !schedule.have_bitwise_shifting) { return Err(vm::Error::BadInstruction { instruction: instruction @@ -871,6 +872,58 @@ impl Interpreter { }); } }, + instructions::SHL => { + const CONST_256: U256 = U256([256, 0, 0, 0]); + + let shift = stack.pop_back(); + let value = stack.pop_back(); + + let result = if shift >= CONST_256 { + U256::zero() + } else { + value << (shift.as_u32() as usize) + }; + stack.push(result); + }, + instructions::SHR => { + const CONST_256: U256 = U256([256, 0, 0, 0]); + + let shift = stack.pop_back(); + let value = stack.pop_back(); + + let result = if shift >= CONST_256 { + U256::zero() + } else { + value >> (shift.as_u32() as usize) + }; + stack.push(result); + }, + instructions::SAR => { + // We cannot use get_and_reset_sign/set_sign here, because the rounding looks different. + + const CONST_256: U256 = U256([256, 0, 0, 0]); + const CONST_HIBIT: U256 = U256([0, 0, 0, 0x8000000000000000]); + + let shift = stack.pop_back(); + let value = stack.pop_back(); + let sign = value & CONST_HIBIT != U256::zero(); + + let result = if shift >= CONST_256 { + if sign { + U256::max_value() + } else { + U256::zero() + } + } else { + let shift = shift.as_u32() as usize; + let mut shifted = value >> shift; + if sign { + shifted = shifted | (U256::max_value() << (256 - shift)); + } + shifted + }; + stack.push(result); + }, _ => { return Err(vm::Error::BadInstruction { instruction: instruction diff --git a/ethcore/evm/src/tests.rs b/ethcore/evm/src/tests.rs index 3758156e21..9058d073e8 100644 --- a/ethcore/evm/src/tests.rs +++ b/ethcore/evm/src/tests.rs @@ -787,6 +787,273 @@ fn test_create_in_staticcall(factory: super::Factory) { assert_eq!(ext.calls.len(), 0); } +evm_test!{test_shl: test_shl_int} +fn test_shl(factory: super::Factory) { + push_two_pop_one_constantinople_test( + &factory, + 0x1b, + "0000000000000000000000000000000000000000000000000000000000000001", + "00", + "0000000000000000000000000000000000000000000000000000000000000001"); + push_two_pop_one_constantinople_test( + &factory, + 0x1b, + "0000000000000000000000000000000000000000000000000000000000000001", + "01", + "0000000000000000000000000000000000000000000000000000000000000002"); + push_two_pop_one_constantinople_test( + &factory, + 0x1b, + "0000000000000000000000000000000000000000000000000000000000000001", + "ff", + "8000000000000000000000000000000000000000000000000000000000000000"); + push_two_pop_one_constantinople_test( + &factory, + 0x1b, + "0000000000000000000000000000000000000000000000000000000000000001", + "0100", + "0000000000000000000000000000000000000000000000000000000000000000"); + push_two_pop_one_constantinople_test( + &factory, + 0x1b, + "0000000000000000000000000000000000000000000000000000000000000001", + "0101", + "0000000000000000000000000000000000000000000000000000000000000000"); + push_two_pop_one_constantinople_test( + &factory, + 0x1b, + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "00", + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); + push_two_pop_one_constantinople_test( + &factory, + 0x1b, + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "01", + "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"); + push_two_pop_one_constantinople_test( + &factory, + 0x1b, + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "ff", + "8000000000000000000000000000000000000000000000000000000000000000"); + push_two_pop_one_constantinople_test( + &factory, + 0x1b, + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "0100", + "0000000000000000000000000000000000000000000000000000000000000000"); + push_two_pop_one_constantinople_test( + &factory, + 0x1b, + "0000000000000000000000000000000000000000000000000000000000000000", + "01", + "0000000000000000000000000000000000000000000000000000000000000000"); + push_two_pop_one_constantinople_test( + &factory, + 0x1b, + "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "01", + "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"); +} + +evm_test!{test_shr: test_shr_int} +fn test_shr(factory: super::Factory) { + push_two_pop_one_constantinople_test( + &factory, + 0x1c, + "0000000000000000000000000000000000000000000000000000000000000001", + "00", + "0000000000000000000000000000000000000000000000000000000000000001"); + push_two_pop_one_constantinople_test( + &factory, + 0x1c, + "0000000000000000000000000000000000000000000000000000000000000001", + "01", + "0000000000000000000000000000000000000000000000000000000000000000"); + push_two_pop_one_constantinople_test( + &factory, + 0x1c, + "8000000000000000000000000000000000000000000000000000000000000000", + "01", + "4000000000000000000000000000000000000000000000000000000000000000"); + push_two_pop_one_constantinople_test( + &factory, + 0x1c, + "8000000000000000000000000000000000000000000000000000000000000000", + "ff", + "0000000000000000000000000000000000000000000000000000000000000001"); + push_two_pop_one_constantinople_test( + &factory, + 0x1c, + "8000000000000000000000000000000000000000000000000000000000000000", + "0100", + "0000000000000000000000000000000000000000000000000000000000000000"); + push_two_pop_one_constantinople_test( + &factory, + 0x1c, + "8000000000000000000000000000000000000000000000000000000000000000", + "0101", + "0000000000000000000000000000000000000000000000000000000000000000"); + push_two_pop_one_constantinople_test( + &factory, + 0x1c, + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "00", + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); + push_two_pop_one_constantinople_test( + &factory, + 0x1c, + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "01", + "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); + push_two_pop_one_constantinople_test( + &factory, + 0x1c, + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "ff", + "0000000000000000000000000000000000000000000000000000000000000001"); + push_two_pop_one_constantinople_test( + &factory, + 0x1c, + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "0100", + "0000000000000000000000000000000000000000000000000000000000000000"); + push_two_pop_one_constantinople_test( + &factory, + 0x1c, + "0000000000000000000000000000000000000000000000000000000000000000", + "01", + "0000000000000000000000000000000000000000000000000000000000000000"); +} + +evm_test!{test_sar: test_sar_int} +fn test_sar(factory: super::Factory) { + push_two_pop_one_constantinople_test( + &factory, + 0x1d, + "0000000000000000000000000000000000000000000000000000000000000001", + "00", + "0000000000000000000000000000000000000000000000000000000000000001"); + push_two_pop_one_constantinople_test( + &factory, + 0x1d, + "0000000000000000000000000000000000000000000000000000000000000001", + "01", + "0000000000000000000000000000000000000000000000000000000000000000"); + push_two_pop_one_constantinople_test( + &factory, + 0x1d, + "8000000000000000000000000000000000000000000000000000000000000000", + "01", + "c000000000000000000000000000000000000000000000000000000000000000"); + push_two_pop_one_constantinople_test( + &factory, + 0x1d, + "8000000000000000000000000000000000000000000000000000000000000000", + "ff", + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); + push_two_pop_one_constantinople_test( + &factory, + 0x1d, + "8000000000000000000000000000000000000000000000000000000000000000", + "0100", + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); + push_two_pop_one_constantinople_test( + &factory, + 0x1d, + "8000000000000000000000000000000000000000000000000000000000000000", + "0101", + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); + push_two_pop_one_constantinople_test( + &factory, + 0x1d, + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "00", + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); + push_two_pop_one_constantinople_test( + &factory, + 0x1d, + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "01", + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); + push_two_pop_one_constantinople_test( + &factory, + 0x1d, + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "ff", + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); + push_two_pop_one_constantinople_test( + &factory, + 0x1d, + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "0100", + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); + push_two_pop_one_constantinople_test( + &factory, + 0x1d, + "0000000000000000000000000000000000000000000000000000000000000000", + "01", + "0000000000000000000000000000000000000000000000000000000000000000"); + push_two_pop_one_constantinople_test( + &factory, + 0x1d, + "4000000000000000000000000000000000000000000000000000000000000000", + "fe", + "0000000000000000000000000000000000000000000000000000000000000001"); + push_two_pop_one_constantinople_test( + &factory, + 0x1d, + "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "f8", + "000000000000000000000000000000000000000000000000000000000000007f"); + push_two_pop_one_constantinople_test( + &factory, + 0x1d, + "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "fe", + "0000000000000000000000000000000000000000000000000000000000000001"); + push_two_pop_one_constantinople_test( + &factory, + 0x1d, + "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "ff", + "0000000000000000000000000000000000000000000000000000000000000000"); + push_two_pop_one_constantinople_test( + &factory, + 0x1d, + "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "0100", + "0000000000000000000000000000000000000000000000000000000000000000"); +} + +fn push_two_pop_one_constantinople_test(factory: &super::Factory, opcode: u8, push1: &str, push2: &str, result: &str) { + let mut push1 = push1.from_hex().unwrap(); + let mut push2 = push2.from_hex().unwrap(); + assert!(push1.len() <= 32 && push1.len() != 0); + assert!(push2.len() <= 32 && push2.len() != 0); + + let mut code = Vec::new(); + code.push(0x60 + ((push1.len() - 1) as u8)); + code.append(&mut push1); + code.push(0x60 + ((push2.len() - 1) as u8)); + code.append(&mut push2); + code.push(opcode); + code.append(&mut vec![0x60, 0x00, 0x55]); + + let mut params = ActionParams::default(); + params.gas = U256::from(100_000); + params.code = Some(Arc::new(code)); + let mut ext = FakeExt::new_constantinople(); + + let _ = { + let mut vm = factory.create(¶ms.gas); + test_finalize(vm.exec(params, &mut ext)).unwrap() + }; + + assert_store(&ext, 0, result); +} + fn assert_set_contains(set: &HashSet, val: &T) { let contains = set.contains(val); if !contains { @@ -799,4 +1066,3 @@ fn assert_set_contains(set: &HashSet, val: fn assert_store(ext: &FakeExt, pos: u64, val: &str) { assert_eq!(ext.store.get(&H256::from(pos)).unwrap(), &H256::from_str(val).unwrap()); } - diff --git a/ethcore/src/spec/spec.rs b/ethcore/src/spec/spec.rs index 156ab8f15a..ef69f4847b 100644 --- a/ethcore/src/spec/spec.rs +++ b/ethcore/src/spec/spec.rs @@ -105,6 +105,8 @@ pub struct CommonParams { pub eip211_transition: BlockNumber, /// Number of first block where EIP-214 rules begin. pub eip214_transition: BlockNumber, + /// Number of first block where EIP-145 rules begin. + pub eip145_transition: BlockNumber, /// Number of first block where dust cleanup rules (EIP-168 and EIP169) begin. pub dust_protection_transition: BlockNumber, /// Nonce cap increase per block. Nonce cap is only checked if dust protection is enabled. @@ -152,6 +154,7 @@ impl CommonParams { schedule.have_revert = block_number >= self.eip140_transition; schedule.have_static_call = block_number >= self.eip214_transition; schedule.have_return_data = block_number >= self.eip211_transition; + schedule.have_bitwise_shifting = block_number >= self.eip145_transition; if block_number >= self.eip210_transition { schedule.blockhash_gas = 800; } @@ -198,16 +201,16 @@ impl From for CommonParams { eip155_transition: p.eip155_transition.map_or(0, Into::into), validate_receipts_transition: p.validate_receipts_transition.map_or(0, Into::into), validate_chain_id_transition: p.validate_chain_id_transition.map_or(0, Into::into), - eip86_transition: p.eip86_transition.map_or( - BlockNumber::max_value(), + eip86_transition: p.eip86_transition.map_or_else( + BlockNumber::max_value, Into::into, ), - eip140_transition: p.eip140_transition.map_or( - BlockNumber::max_value(), + eip140_transition: p.eip140_transition.map_or_else( + BlockNumber::max_value, Into::into, ), - eip210_transition: p.eip210_transition.map_or( - BlockNumber::max_value(), + eip210_transition: p.eip210_transition.map_or_else( + BlockNumber::max_value, Into::into, ), eip210_contract_address: p.eip210_contract_address.map_or(0xf0.into(), Into::into), @@ -220,20 +223,24 @@ impl From for CommonParams { Into::into, ), eip210_contract_gas: p.eip210_contract_gas.map_or(1000000.into(), Into::into), - eip211_transition: p.eip211_transition.map_or( - BlockNumber::max_value(), + eip211_transition: p.eip211_transition.map_or_else( + BlockNumber::max_value, Into::into, ), - eip214_transition: p.eip214_transition.map_or( - BlockNumber::max_value(), + eip145_transition: p.eip145_transition.map_or_else( + BlockNumber::max_value, Into::into, ), - eip658_transition: p.eip658_transition.map_or( - BlockNumber::max_value(), + eip214_transition: p.eip214_transition.map_or_else( + BlockNumber::max_value, Into::into, ), - dust_protection_transition: p.dust_protection_transition.map_or( - BlockNumber::max_value(), + eip658_transition: p.eip658_transition.map_or_else( + BlockNumber::max_value, + Into::into, + ), + dust_protection_transition: p.dust_protection_transition.map_or_else( + BlockNumber::max_value, Into::into, ), nonce_cap_increment: p.nonce_cap_increment.map_or(64, Into::into), @@ -245,8 +252,8 @@ impl From for CommonParams { max_transaction_size: p.max_transaction_size.map_or(MAX_TRANSACTION_SIZE, Into::into), max_code_size_transition: p.max_code_size_transition.map_or(0, Into::into), transaction_permission_contract: p.transaction_permission_contract.map(Into::into), - wasm_activation_transition: p.wasm_activation_transition.map_or( - BlockNumber::max_value(), + wasm_activation_transition: p.wasm_activation_transition.map_or_else( + BlockNumber::max_value, Into::into ), } diff --git a/ethcore/vm/src/schedule.rs b/ethcore/vm/src/schedule.rs index 6cfabed0df..a0085ef1ec 100644 --- a/ethcore/vm/src/schedule.rs +++ b/ethcore/vm/src/schedule.rs @@ -109,6 +109,8 @@ pub struct Schedule { pub have_static_call: bool, /// RETURNDATA and RETURNDATASIZE opcodes enabled. pub have_return_data: bool, + /// SHL, SHR, SAR opcodes enabled. + pub have_bitwise_shifting: bool, /// Kill basic accounts below this balance if touched. pub kill_dust: CleanDustMode, /// Enable EIP-86 rules @@ -194,6 +196,7 @@ impl Schedule { have_create2: false, have_revert: false, have_return_data: false, + have_bitwise_shifting: false, stack_limit: 1024, max_depth: 1024, tier_step_gas: [0, 2, 3, 5, 8, 10, 20, 0], @@ -250,6 +253,13 @@ impl Schedule { schedule } + /// Schedule for the Constantinople fork of the Ethereum main net. + pub fn new_constantinople() -> Schedule { + let mut schedule = Self::new_byzantium(); + schedule.have_bitwise_shifting = true; + schedule + } + fn new(efcd: bool, hdc: bool, tcg: usize) -> Schedule { Schedule { exceptional_failed_code_deposit: efcd, @@ -257,6 +267,7 @@ impl Schedule { have_create2: false, have_revert: false, have_return_data: false, + have_bitwise_shifting: false, stack_limit: 1024, max_depth: 1024, tier_step_gas: [0, 2, 3, 5, 8, 10, 20, 0], @@ -328,4 +339,3 @@ fn schedule_evm_assumptions() { assert_eq!(s1.quad_coeff_div, 512); assert_eq!(s2.quad_coeff_div, 512); } - diff --git a/ethcore/vm/src/tests.rs b/ethcore/vm/src/tests.rs index ce47121458..daf46be0f0 100644 --- a/ethcore/vm/src/tests.rs +++ b/ethcore/vm/src/tests.rs @@ -88,6 +88,13 @@ impl FakeExt { ext } + /// New fake externalities with constantinople schedule rules + pub fn new_constantinople() -> Self { + let mut ext = FakeExt::default(); + ext.schedule = Schedule::new_constantinople(); + ext + } + /// Alter fake externalities to allow wasm pub fn with_wasm(mut self) -> Self { self.schedule.wasm = Some(Default::default()); diff --git a/json/src/spec/params.rs b/json/src/spec/params.rs index ce47086df1..0addf52e4a 100644 --- a/json/src/spec/params.rs +++ b/json/src/spec/params.rs @@ -85,6 +85,9 @@ pub struct Params { #[serde(rename="eip211Transition")] pub eip211_transition: Option, /// See `CommonParams` docs. + #[serde(rename="eip145Transition")] + pub eip145_transition: Option, + /// See `CommonParams` docs. #[serde(rename="eip214Transition")] pub eip214_transition: Option, /// See `CommonParams` docs. -- GitLab From e30839e85ff74cd5eb087ef19a48d70afd1fd285 Mon Sep 17 00:00:00 2001 From: Toralf Wittner Date: Sat, 5 May 2018 11:02:33 +0200 Subject: [PATCH 008/152] Consolidate crypto functionality in `ethcore-crypto`. (#8432) * Consolidate crypto functionality in `ethcore-crypto`. - Move `ecdh`/`ecies` modules to `ethkey`. - Refactor `ethcore-crypto` to use file per module. - Replace `subtle` with `ethcore_crypto::is_equal`. - Add `aes_gcm` module to `ethcore-crypto`. * Rename `aes::{encrypt,decrypt,decrypt_cbc}` ... ... to `aes::{encrypt_128_ctr,decrypt_128_ctr,decrypt_128_cbc}`. --- Cargo.lock | 26 +- ethcore/Cargo.toml | 2 +- ethcore/benches/evm.rs | 9 +- ethcore/crypto/Cargo.toml | 10 +- ethcore/crypto/src/aes.rs | 54 ++++ ethcore/crypto/src/aes_gcm.rs | 199 ++++++++++++ ethcore/crypto/src/digest.rs | 109 +++++++ ethcore/crypto/src/error.rs | 83 +++++ ethcore/crypto/src/hmac.rs | 89 ++++++ ethcore/crypto/src/lib.rs | 299 +----------------- ethcore/crypto/src/pbkdf2.rs | 29 ++ ethcore/crypto/src/scrypt.rs | 39 +++ ethcore/private-tx/src/encryptor.rs | 7 +- ethcore/src/builtin.rs | 25 +- ethcore/src/lib.rs | 2 +- ethkey/Cargo.toml | 3 +- ethkey/src/crypto.rs | 189 +++++++++++ ethkey/src/extended.rs | 22 +- ethkey/src/lib.rs | 5 +- ethstore/Cargo.toml | 2 - ethstore/src/account/crypto.rs | 29 +- ethstore/src/account/safe_account.rs | 25 +- ethstore/src/accounts_dir/disk.rs | 6 +- ethstore/src/accounts_dir/vault.rs | 2 +- ethstore/src/error.rs | 25 +- ethstore/src/ethstore.rs | 2 +- ethstore/src/lib.rs | 2 - ethstore/src/presale.rs | 15 +- rpc/Cargo.toml | 1 - rpc/src/lib.rs | 1 - rpc/src/v1/helpers/ipfs.rs | 12 +- rpc/src/v1/helpers/secretstore.rs | 8 +- rpc/src/v1/impls/light/parity.rs | 4 +- rpc/src/v1/impls/parity.rs | 4 +- secret_store/src/key_server.rs | 35 +- .../client_sessions/decryption_session.rs | 4 +- .../src/key_server_cluster/io/handshake.rs | 2 +- .../src/key_server_cluster/io/message.rs | 4 +- .../key_server_cluster/jobs/decryption_job.rs | 2 +- secret_store/src/node_key_pair.rs | 5 +- secret_store/src/types/error.rs | 8 +- util/network-devp2p/src/connection.rs | 2 +- util/network-devp2p/src/handshake.rs | 2 +- util/network/src/error.rs | 16 +- whisper/Cargo.toml | 1 - whisper/src/lib.rs | 1 - whisper/src/rpc/crypto.rs | 109 ++----- whisper/src/rpc/filter.rs | 2 +- whisper/src/rpc/key_store.rs | 9 +- whisper/src/rpc/mod.rs | 4 +- 50 files changed, 1003 insertions(+), 542 deletions(-) create mode 100644 ethcore/crypto/src/aes.rs create mode 100644 ethcore/crypto/src/aes_gcm.rs create mode 100644 ethcore/crypto/src/digest.rs create mode 100644 ethcore/crypto/src/error.rs create mode 100644 ethcore/crypto/src/hmac.rs create mode 100644 ethcore/crypto/src/pbkdf2.rs create mode 100644 ethcore/crypto/src/scrypt.rs create mode 100644 ethkey/src/crypto.rs diff --git a/Cargo.lock b/Cargo.lock index 741cc3832c..ceb14ff277 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -509,6 +509,7 @@ dependencies = [ "ethash 1.12.0", "ethcore-bloom-journal 0.1.0", "ethcore-bytes 0.1.0", + "ethcore-crypto 0.1.0", "ethcore-io 1.12.0", "ethcore-logger 1.12.0", "ethcore-miner 1.12.0", @@ -545,7 +546,6 @@ dependencies = [ "rlp 0.2.1", "rlp_compress 0.1.0", "rlp_derive 0.1.0", - "rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "snappy 0.1.0 (git+https://github.com/paritytech/rust-snappy)", "stats 0.1.0", @@ -576,11 +576,10 @@ version = "0.1.0" name = "ethcore-crypto" version = "0.1.0" dependencies = [ - "eth-secp256k1 0.5.7 (git+https://github.com/paritytech/rust-secp256k1)", "ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "ethkey 0.3.0", + "quick-error 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ring 0.12.1 (git+https://github.com/paritytech/ring)", "rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", - "subtle 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "tiny-keccak 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -925,13 +924,14 @@ dependencies = [ "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "edit-distance 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "eth-secp256k1 0.5.7 (git+https://github.com/paritytech/rust-secp256k1)", + "ethcore-crypto 0.1.0", "ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "mem 0.1.0", "parity-wordlist 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "quick-error 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "tiny-keccak 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -966,13 +966,11 @@ dependencies = [ "parity-wordlist 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "subtle 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", "tiny-keccak 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2197,7 +2195,6 @@ dependencies = [ "pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "rlp 0.2.1", - "rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2362,7 +2359,6 @@ dependencies = [ "ordered-float 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "ring 0.12.1 (git+https://github.com/paritytech/ring)", "rlp 0.2.1", "serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2621,6 +2617,11 @@ dependencies = [ "quasi_codegen 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "quick-error" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "quote" version = "0.5.1" @@ -3035,11 +3036,6 @@ name = "strsim" version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "subtle" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "syn" version = "0.13.1" @@ -3927,6 +3923,7 @@ dependencies = [ "checksum quasi 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "18c45c4854d6d1cf5d531db97c75880feb91c958b0720f4ec1057135fec358b3" "checksum quasi_codegen 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "51b9e25fa23c044c1803f43ca59c98dac608976dd04ce799411edd58ece776d4" "checksum quasi_macros 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "29cec87bc2816766d7e4168302d505dd06b0a825aed41b00633d296e922e02dd" +"checksum quick-error 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eda5fe9b71976e62bc81b781206aaa076401769b2143379d3eb2118388babac4" "checksum quote 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7b0ff51282f28dc1b53fd154298feaa2e77c5ea0dba68e1fd8b03b72fbe13d2a" "checksum rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)" = "512870020642bb8c221bf68baa1b2573da814f6ccfe5c9699b1c303047abe9b1" "checksum rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5" @@ -3973,7 +3970,6 @@ dependencies = [ "checksum snappy-sys 0.1.0 (git+https://github.com/paritytech/rust-snappy)" = "" "checksum stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "15132e0e364248108c5e2c02e3ab539be8d6f5d52a01ca9bbf27ed657316f02b" "checksum strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694" -"checksum subtle 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dc7f6353c2ee5407358d063a14cccc1630804527090a6fb5a9489ce4924280fb" "checksum syn 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)" = "91b52877572087400e83d24b9178488541e3d535259e04ff17a63df1e5ceff59" "checksum syntex 0.58.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a8f5e3aaa79319573d19938ea38d068056b826db9883a5d47f86c1cecc688f0e" "checksum syntex_errors 0.58.1 (registry+https://github.com/rust-lang/crates.io-index)" = "867cc5c2d7140ae7eaad2ae9e8bf39cb18a67ca651b7834f88d46ca98faadb9c" diff --git a/ethcore/Cargo.toml b/ethcore/Cargo.toml index 147d9484c7..71c84a293f 100644 --- a/ethcore/Cargo.toml +++ b/ethcore/Cargo.toml @@ -20,6 +20,7 @@ fetch = { path = "../util/fetch" } hashdb = { path = "../util/hashdb" } memorydb = { path = "../util/memorydb" } patricia-trie = { path = "../util/patricia_trie" } +ethcore-crypto = { path = "crypto" } error-chain = { version = "0.11", default-features = false } ethcore-io = { path = "../util/io" } ethcore-logger = { path = "../logger" } @@ -56,7 +57,6 @@ util-error = { path = "../util/error" } snappy = { git = "https://github.com/paritytech/rust-snappy" } stop-guard = { path = "../util/stop-guard" } macros = { path = "../util/macros" } -rust-crypto = "0.2.34" rustc-hex = "1.0" stats = { path = "../util/stats" } trace-time = { path = "../util/trace-time" } diff --git a/ethcore/benches/evm.rs b/ethcore/benches/evm.rs index 324e3382e5..9fe2657d61 100644 --- a/ethcore/benches/evm.rs +++ b/ethcore/benches/evm.rs @@ -20,7 +20,7 @@ extern crate test; extern crate ethcore_util as util; extern crate rand; extern crate bn; -extern crate crypto; +extern crate ethcore_crypto; extern crate ethkey; extern crate rustc_hex; extern crate ethcore_bigint; @@ -61,16 +61,13 @@ fn bn_128_mul(b: &mut Bencher) { #[bench] fn sha256(b: &mut Bencher) { - use crypto::sha2::Sha256; - use crypto::digest::Digest; + use ethcore_crypto::digest::sha256; let mut input: [u8; 256] = [0; 256]; let mut out = [0; 32]; b.iter(|| { - let mut sha = Sha256::new(); - sha.input(&input); - sha.result(&mut input[0..32]); + sha256(&input); }); } diff --git a/ethcore/crypto/Cargo.toml b/ethcore/crypto/Cargo.toml index c3a2191b55..4fe023f25c 100644 --- a/ethcore/crypto/Cargo.toml +++ b/ethcore/crypto/Cargo.toml @@ -4,13 +4,9 @@ version = "0.1.0" authors = ["Parity Technologies "] [dependencies] +ethereum-types = "0.3" +quick-error = "1.2" +ring = "0.12" rust-crypto = "0.2.36" tiny-keccak = "1.3" -eth-secp256k1 = { git = "https://github.com/paritytech/rust-secp256k1", optional = true } -ethkey = { path = "../../ethkey", optional = true } -ethereum-types = "0.3" -subtle = "0.5" -[features] -default = ["secp256k1"] -secp256k1 = ["eth-secp256k1", "ethkey"] diff --git a/ethcore/crypto/src/aes.rs b/ethcore/crypto/src/aes.rs new file mode 100644 index 0000000000..79a8dcc86d --- /dev/null +++ b/ethcore/crypto/src/aes.rs @@ -0,0 +1,54 @@ +// 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 . + +use error::SymmError; +use rcrypto::blockmodes::{CtrMode, CbcDecryptor, PkcsPadding}; +use rcrypto::aessafe::{AesSafe128Encryptor, AesSafe128Decryptor}; +use rcrypto::symmetriccipher::{Encryptor, Decryptor}; +use rcrypto::buffer::{RefReadBuffer, RefWriteBuffer, WriteBuffer}; + +/// Encrypt a message (CTR mode). +/// +/// Key (`k`) length and initialisation vector (`iv`) length have to be 16 bytes each. +/// An error is returned if the input lengths are invalid. +pub fn encrypt_128_ctr(k: &[u8], iv: &[u8], plain: &[u8], dest: &mut [u8]) -> Result<(), SymmError> { + let mut encryptor = CtrMode::new(AesSafe128Encryptor::new(k), iv.to_vec()); + encryptor.encrypt(&mut RefReadBuffer::new(plain), &mut RefWriteBuffer::new(dest), true)?; + Ok(()) +} + +/// Decrypt a message (CTR mode). +/// +/// Key (`k`) length and initialisation vector (`iv`) length have to be 16 bytes each. +/// An error is returned if the input lengths are invalid. +pub fn decrypt_128_ctr(k: &[u8], iv: &[u8], encrypted: &[u8], dest: &mut [u8]) -> Result<(), SymmError> { + let mut encryptor = CtrMode::new(AesSafe128Encryptor::new(k), iv.to_vec()); + encryptor.decrypt(&mut RefReadBuffer::new(encrypted), &mut RefWriteBuffer::new(dest), true)?; + Ok(()) +} + +/// Decrypt a message (CBC mode). +/// +/// Key (`k`) length and initialisation vector (`iv`) length have to be 16 bytes each. +/// An error is returned if the input lengths are invalid. +pub fn decrypt_128_cbc(k: &[u8], iv: &[u8], encrypted: &[u8], dest: &mut [u8]) -> Result { + let mut encryptor = CbcDecryptor::new(AesSafe128Decryptor::new(k), PkcsPadding, iv.to_vec()); + let len = dest.len(); + let mut buffer = RefWriteBuffer::new(dest); + encryptor.decrypt(&mut RefReadBuffer::new(encrypted), &mut buffer, true)?; + Ok(len - buffer.remaining()) +} + diff --git a/ethcore/crypto/src/aes_gcm.rs b/ethcore/crypto/src/aes_gcm.rs new file mode 100644 index 0000000000..178b5d1e12 --- /dev/null +++ b/ethcore/crypto/src/aes_gcm.rs @@ -0,0 +1,199 @@ +// 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 . + +use error::SymmError; +use ring; + +enum Mode { Aes128Gcm, Aes256Gcm } + +/// AES GCM encryptor. +pub struct Encryptor<'a> { + mode: Mode, + key: ring::aead::SealingKey, + ad: &'a [u8], + offset: usize, +} + +impl<'a> Encryptor<'a> { + pub fn aes_128_gcm(key: &[u8; 16]) -> Result, SymmError> { + let sk = ring::aead::SealingKey::new(&ring::aead::AES_128_GCM, key)?; + Ok(Encryptor { + mode: Mode::Aes128Gcm, + key: sk, + ad: &[], + offset: 0, + }) + } + + pub fn aes_256_gcm(key: &[u8; 32]) -> Result, SymmError> { + let sk = ring::aead::SealingKey::new(&ring::aead::AES_256_GCM, key)?; + Ok(Encryptor { + mode: Mode::Aes256Gcm, + key: sk, + ad: &[], + offset: 0, + }) + } + + /// Optional associated data which is not encrypted but authenticated. + pub fn associate(&mut self, data: &'a [u8]) -> &mut Self { + self.ad = data; + self + } + + /// Optional offset value. Only the slice `[offset..]` will be encrypted. + pub fn offset(&mut self, off: usize) -> &mut Self { + self.offset = off; + self + } + + /// Please note that the pair (key, nonce) must never be reused. Using random nonces + /// limits the number of messages encrypted with the same key to 2^32 (cf. [[1]]) + /// + /// [1]: https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf + pub fn encrypt(&self, nonce: &[u8; 12], mut data: Vec) -> Result, SymmError> { + if self.offset > data.len() { + return Err(SymmError::offset_error(self.offset)) + } + let tag_len = match self.mode { + Mode::Aes128Gcm => ring::aead::AES_128_GCM.tag_len(), + Mode::Aes256Gcm => ring::aead::AES_256_GCM.tag_len(), + }; + data.extend(::std::iter::repeat(0).take(tag_len)); + let len = ring::aead::seal_in_place(&self.key, nonce, self.ad, &mut data[self.offset ..], tag_len)?; + data.truncate(self.offset + len); + Ok(data) + } +} + +/// AES GCM decryptor. +pub struct Decryptor<'a> { + key: ring::aead::OpeningKey, + ad: &'a [u8], + offset: usize, +} + +impl<'a> Decryptor<'a> { + pub fn aes_128_gcm(key: &[u8; 16]) -> Result, SymmError> { + let ok = ring::aead::OpeningKey::new(&ring::aead::AES_128_GCM, key)?; + Ok(Decryptor { + key: ok, + ad: &[], + offset: 0, + }) + } + + pub fn aes_256_gcm(key: &[u8; 32]) -> Result, SymmError> { + let ok = ring::aead::OpeningKey::new(&ring::aead::AES_256_GCM, key)?; + Ok(Decryptor { + key: ok, + ad: &[], + offset: 0, + }) + } + + /// Optional associated data which is not encrypted but authenticated. + pub fn associate(&mut self, data: &'a [u8]) -> &mut Self { + self.ad = data; + self + } + + /// Optional offset value. Only the slice `[offset..]` will be decrypted. + pub fn offset(&mut self, off: usize) -> &mut Self { + self.offset = off; + self + } + + pub fn decrypt(&self, nonce: &[u8; 12], mut data: Vec) -> Result, SymmError> { + if self.offset > data.len() { + return Err(SymmError::offset_error(self.offset)) + } + let len = ring::aead::open_in_place(&self.key, nonce, self.ad, 0, &mut data[self.offset ..])?.len(); + data.truncate(self.offset + len); + Ok(data) + } +} + +#[cfg(test)] +mod tests { + use super::{Encryptor, Decryptor}; + + #[test] + fn aes_gcm_128() { + let secret = b"1234567890123456"; + let nonce = b"123456789012"; + let message = b"So many books, so little time"; + + let ciphertext = Encryptor::aes_128_gcm(secret) + .unwrap() + .encrypt(nonce, message.to_vec()) + .unwrap(); + + assert!(ciphertext != message); + + let plaintext = Decryptor::aes_128_gcm(secret) + .unwrap() + .decrypt(nonce, ciphertext) + .unwrap(); + + assert_eq!(plaintext, message) + } + + #[test] + fn aes_gcm_256() { + let secret = b"12345678901234567890123456789012"; + let nonce = b"123456789012"; + let message = b"So many books, so little time"; + + let ciphertext = Encryptor::aes_256_gcm(secret) + .unwrap() + .encrypt(nonce, message.to_vec()) + .unwrap(); + + assert!(ciphertext != message); + + let plaintext = Decryptor::aes_256_gcm(secret) + .unwrap() + .decrypt(nonce, ciphertext) + .unwrap(); + + assert_eq!(plaintext, message) + } + + #[test] + fn aes_gcm_256_offset() { + let secret = b"12345678901234567890123456789012"; + let nonce = b"123456789012"; + let message = b"prefix data; So many books, so little time"; + + let ciphertext = Encryptor::aes_256_gcm(secret) + .unwrap() + .offset(13) // length of "prefix data; " + .encrypt(nonce, message.to_vec()) + .unwrap(); + + assert!(ciphertext != &message[..]); + + let plaintext = Decryptor::aes_256_gcm(secret) + .unwrap() + .offset(13) // length of "prefix data; " + .decrypt(nonce, ciphertext) + .unwrap(); + + assert_eq!(plaintext, &message[..]) + } +} + diff --git a/ethcore/crypto/src/digest.rs b/ethcore/crypto/src/digest.rs new file mode 100644 index 0000000000..095a8ca262 --- /dev/null +++ b/ethcore/crypto/src/digest.rs @@ -0,0 +1,109 @@ +// Copyright 2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +use rcrypto::ripemd160; +use ring::digest::{self, Context, SHA256, SHA512}; +use std::marker::PhantomData; +use std::ops::Deref; + +/// The message digest. +pub struct Digest(InnerDigest, PhantomData); + +enum InnerDigest { + Ring(digest::Digest), + Ripemd160([u8; 20]), +} + +impl Deref for Digest { + type Target = [u8]; + fn deref(&self) -> &Self::Target { + match self.0 { + InnerDigest::Ring(ref d) => d.as_ref(), + InnerDigest::Ripemd160(ref d) => &d[..] + } + } +} + +/// Single-step sha256 digest computation. +pub fn sha256(data: &[u8]) -> Digest { + Digest(InnerDigest::Ring(digest::digest(&SHA256, data)), PhantomData) +} + +/// Single-step sha512 digest computation. +pub fn sha512(data: &[u8]) -> Digest { + Digest(InnerDigest::Ring(digest::digest(&SHA512, data)), PhantomData) +} + +/// Single-step ripemd160 digest computation. +pub fn ripemd160(data: &[u8]) -> Digest { + let mut hasher = Hasher::ripemd160(); + hasher.update(data); + hasher.finish() +} + +pub enum Sha256 {} +pub enum Sha512 {} +pub enum Ripemd160 {} + +/// Stateful digest computation. +pub struct Hasher(Inner, PhantomData); + +enum Inner { + Ring(Context), + Ripemd160(ripemd160::Ripemd160) +} + +impl Hasher { + pub fn sha256() -> Hasher { + Hasher(Inner::Ring(Context::new(&SHA256)), PhantomData) + } +} + +impl Hasher { + pub fn sha512() -> Hasher { + Hasher(Inner::Ring(Context::new(&SHA512)), PhantomData) + } +} + +impl Hasher { + pub fn ripemd160() -> Hasher { + Hasher(Inner::Ripemd160(ripemd160::Ripemd160::new()), PhantomData) + } +} + +impl Hasher { + pub fn update(&mut self, data: &[u8]) { + match self.0 { + Inner::Ring(ref mut ctx) => ctx.update(data), + Inner::Ripemd160(ref mut ctx) => { + use rcrypto::digest::Digest; + ctx.input(data) + } + } + } + + pub fn finish(self) -> Digest { + match self.0 { + Inner::Ring(ctx) => Digest(InnerDigest::Ring(ctx.finish()), PhantomData), + Inner::Ripemd160(mut ctx) => { + use rcrypto::digest::Digest; + let mut d = [0; 20]; + ctx.result(&mut d); + Digest(InnerDigest::Ripemd160(d), PhantomData) + } + } + } +} diff --git a/ethcore/crypto/src/error.rs b/ethcore/crypto/src/error.rs new file mode 100644 index 0000000000..4de3b80036 --- /dev/null +++ b/ethcore/crypto/src/error.rs @@ -0,0 +1,83 @@ +// 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 . + +use rcrypto; +use ring; + +quick_error! { + #[derive(Debug)] + pub enum Error { + Scrypt(e: ScryptError) { + cause(e) + from() + } + Symm(e: SymmError) { + cause(e) + from() + } + } +} + +quick_error! { + #[derive(Debug)] + pub enum ScryptError { + // log(N) < r / 16 + InvalidN { + display("Invalid N argument of the scrypt encryption") + } + // p <= (2^31-1 * 32)/(128 * r) + InvalidP { + display("Invalid p argument of the scrypt encryption") + } + } +} + +quick_error! { + #[derive(Debug)] + pub enum SymmError wraps PrivSymmErr { + RustCrypto(e: rcrypto::symmetriccipher::SymmetricCipherError) { + display("symmetric crypto error") + from() + } + Ring(e: ring::error::Unspecified) { + display("symmetric crypto error") + cause(e) + from() + } + Offset(x: usize) { + display("offset {} greater than slice length", x) + } + } +} + +impl SymmError { + pub(crate) fn offset_error(x: usize) -> SymmError { + SymmError(PrivSymmErr::Offset(x)) + } +} + +impl From for SymmError { + fn from(e: ring::error::Unspecified) -> SymmError { + SymmError(PrivSymmErr::Ring(e)) + } +} + +impl From for SymmError { + fn from(e: rcrypto::symmetriccipher::SymmetricCipherError) -> SymmError { + SymmError(PrivSymmErr::RustCrypto(e)) + } +} + diff --git a/ethcore/crypto/src/hmac.rs b/ethcore/crypto/src/hmac.rs new file mode 100644 index 0000000000..7327250442 --- /dev/null +++ b/ethcore/crypto/src/hmac.rs @@ -0,0 +1,89 @@ +// Copyright 2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +use digest; +use ring::digest::{SHA256, SHA512}; +use ring::hmac::{self, SigningContext}; +use std::marker::PhantomData; +use std::ops::Deref; + +/// HMAC signature. +pub struct Signature(hmac::Signature, PhantomData); + +impl Deref for Signature { + type Target = [u8]; + fn deref(&self) -> &Self::Target { + self.0.as_ref() + } +} + +/// HMAC signing key. +pub struct SigKey(hmac::SigningKey, PhantomData); + +impl SigKey { + pub fn sha256(key: &[u8]) -> SigKey { + SigKey(hmac::SigningKey::new(&SHA256, key), PhantomData) + } +} + +impl SigKey { + pub fn sha512(key: &[u8]) -> SigKey { + SigKey(hmac::SigningKey::new(&SHA512, key), PhantomData) + } +} + +/// Compute HMAC signature of `data`. +pub fn sign(k: &SigKey, data: &[u8]) -> Signature { + Signature(hmac::sign(&k.0, data), PhantomData) +} + +/// Stateful HMAC computation. +pub struct Signer(SigningContext, PhantomData); + +impl Signer { + pub fn with(key: &SigKey) -> Signer { + Signer(hmac::SigningContext::with_key(&key.0), PhantomData) + } + + pub fn update(&mut self, data: &[u8]) { + self.0.update(data) + } + + pub fn sign(self) -> Signature { + Signature(self.0.sign(), PhantomData) + } +} + +/// HMAC signature verification key. +pub struct VerifyKey(hmac::VerificationKey, PhantomData); + +impl VerifyKey { + pub fn sha256(key: &[u8]) -> VerifyKey { + VerifyKey(hmac::VerificationKey::new(&SHA256, key), PhantomData) + } +} + +impl VerifyKey { + pub fn sha512(key: &[u8]) -> VerifyKey { + VerifyKey(hmac::VerificationKey::new(&SHA512, key), PhantomData) + } +} + +/// Verify HMAC signature of `data`. +pub fn verify(k: &VerifyKey, data: &[u8], sig: &[u8]) -> bool { + hmac::verify(&k.0, data, sig).is_ok() +} + diff --git a/ethcore/crypto/src/lib.rs b/ethcore/crypto/src/lib.rs index caa4cf77c4..0ee42e3599 100644 --- a/ethcore/crypto/src/lib.rs +++ b/ethcore/crypto/src/lib.rs @@ -18,23 +18,22 @@ extern crate crypto as rcrypto; extern crate ethereum_types; -extern crate subtle; +#[macro_use] +extern crate quick_error; +extern crate ring; extern crate tiny_keccak; -#[cfg(feature = "secp256k1")] -extern crate secp256k1; -#[cfg(feature = "secp256k1")] -extern crate ethkey; +pub mod aes; +pub mod aes_gcm; +pub mod error; +pub mod scrypt; +pub mod digest; +pub mod hmac; +pub mod pbkdf2; -use std::fmt; -use tiny_keccak::Keccak; -use rcrypto::pbkdf2::pbkdf2; -use rcrypto::scrypt::{scrypt, ScryptParams}; -use rcrypto::sha2::Sha256; -use rcrypto::hmac::Hmac; +pub use error::Error; -#[cfg(feature = "secp256k1")] -use secp256k1::Error as SecpError; +use tiny_keccak::Keccak; pub const KEY_LENGTH: usize = 32; pub const KEY_ITERATIONS: usize = 10240; @@ -43,65 +42,6 @@ pub const KEY_LENGTH_AES: usize = KEY_LENGTH / 2; /// Default authenticated data to use (in RPC). pub const DEFAULT_MAC: [u8; 2] = [0, 0]; -#[derive(PartialEq, Debug)] -pub enum ScryptError { - // log(N) < r / 16 - InvalidN, - // p <= (2^31-1 * 32)/(128 * r) - InvalidP, -} - -impl fmt::Display for ScryptError { - fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { - let s = match *self { - ScryptError::InvalidN => "Invalid N argument of the scrypt encryption" , - ScryptError::InvalidP => "Invalid p argument of the scrypt encryption", - }; - - write!(f, "{}", s) - } -} - -#[derive(PartialEq, Debug)] -pub enum Error { - #[cfg(feature = "secp256k1")] - Secp(SecpError), - Scrypt(ScryptError), - InvalidMessage, -} - -impl From for Error { - fn from(err: ScryptError) -> Self { - Error::Scrypt(err) - } -} - -impl fmt::Display for Error { - fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { - let s = match *self { - #[cfg(feature = "secp256k1")] - Error::Secp(ref err) => err.to_string(), - Error::Scrypt(ref err) => err.to_string(), - Error::InvalidMessage => "Invalid message".into(), - }; - - write!(f, "{}", s) - } -} - -impl Into for Error { - fn into(self) -> String { - format!("{}", self) - } -} - -#[cfg(feature = "secp256k1")] -impl From for Error { - fn from(e: SecpError) -> Self { - Error::Secp(e) - } -} - pub trait Keccak256 { fn keccak256(&self) -> T where T: Sized; } @@ -117,33 +57,13 @@ impl Keccak256<[u8; 32]> for T where T: AsRef<[u8]> { } pub fn derive_key_iterations(password: &str, salt: &[u8; 32], c: u32) -> (Vec, Vec) { - let mut h_mac = Hmac::new(Sha256::new(), password.as_bytes()); - let mut derived_key = vec![0u8; KEY_LENGTH]; - pbkdf2(&mut h_mac, salt, c, &mut derived_key); + let mut derived_key = [0u8; KEY_LENGTH]; + pbkdf2::sha256(c, pbkdf2::Salt(salt), pbkdf2::Secret(password.as_bytes()), &mut derived_key); let derived_right_bits = &derived_key[0..KEY_LENGTH_AES]; let derived_left_bits = &derived_key[KEY_LENGTH_AES..KEY_LENGTH]; (derived_right_bits.to_vec(), derived_left_bits.to_vec()) } -pub fn derive_key_scrypt(password: &str, salt: &[u8; 32], n: u32, p: u32, r: u32) -> Result<(Vec, Vec), Error> { - // sanity checks - let log_n = (32 - n.leading_zeros() - 1) as u8; - if log_n as u32 >= r * 16 { - return Err(Error::Scrypt(ScryptError::InvalidN)); - } - - if p as u64 > ((u32::max_value() as u64 - 1) * 32)/(128 * (r as u64)) { - return Err(Error::Scrypt(ScryptError::InvalidP)); - } - - let mut derived_key = vec![0u8; KEY_LENGTH]; - let scrypt_params = ScryptParams::new(log_n, r, p); - scrypt(password.as_bytes(), salt, &scrypt_params, &mut derived_key); - let derived_right_bits = &derived_key[0..KEY_LENGTH_AES]; - let derived_left_bits = &derived_key[KEY_LENGTH_AES..KEY_LENGTH]; - Ok((derived_right_bits.to_vec(), derived_left_bits.to_vec())) -} - pub fn derive_mac(derived_left_bits: &[u8], cipher_text: &[u8]) -> Vec { let mut mac = vec![0u8; KEY_LENGTH_AES + cipher_text.len()]; mac[0..KEY_LENGTH_AES].copy_from_slice(derived_left_bits); @@ -151,194 +71,7 @@ pub fn derive_mac(derived_left_bits: &[u8], cipher_text: &[u8]) -> Vec { mac } -/// AES encryption -pub mod aes { - use rcrypto::blockmodes::{CtrMode, CbcDecryptor, PkcsPadding}; - use rcrypto::aessafe::{AesSafe128Encryptor, AesSafe128Decryptor}; - use rcrypto::symmetriccipher::{Encryptor, Decryptor, SymmetricCipherError}; - use rcrypto::buffer::{RefReadBuffer, RefWriteBuffer, WriteBuffer}; - - /// Encrypt a message (CTR mode) - pub fn encrypt(k: &[u8], iv: &[u8], plain: &[u8], dest: &mut [u8]) { - let mut encryptor = CtrMode::new(AesSafe128Encryptor::new(k), iv.to_vec()); - encryptor.encrypt(&mut RefReadBuffer::new(plain), &mut RefWriteBuffer::new(dest), true).expect("Invalid length or padding"); - } - - /// Decrypt a message (CTR mode) - pub fn decrypt(k: &[u8], iv: &[u8], encrypted: &[u8], dest: &mut [u8]) { - let mut encryptor = CtrMode::new(AesSafe128Encryptor::new(k), iv.to_vec()); - encryptor.decrypt(&mut RefReadBuffer::new(encrypted), &mut RefWriteBuffer::new(dest), true).expect("Invalid length or padding"); - } - - - /// Decrypt a message using cbc mode - pub fn decrypt_cbc(k: &[u8], iv: &[u8], encrypted: &[u8], dest: &mut [u8]) -> Result { - let mut encryptor = CbcDecryptor::new(AesSafe128Decryptor::new(k), PkcsPadding, iv.to_vec()); - let len = dest.len(); - let mut buffer = RefWriteBuffer::new(dest); - encryptor.decrypt(&mut RefReadBuffer::new(encrypted), &mut buffer, true)?; - Ok(len - buffer.remaining()) - } -} - -/// ECDH functions -#[cfg(feature = "secp256k1")] -pub mod ecdh { - use secp256k1::{ecdh, key, Error as SecpError}; - use ethkey::{Secret, Public, SECP256K1}; - use Error; - - /// Agree on a shared secret - pub fn agree(secret: &Secret, public: &Public) -> Result { - let context = &SECP256K1; - let pdata = { - let mut temp = [4u8; 65]; - (&mut temp[1..65]).copy_from_slice(&public[0..64]); - temp - }; - - let publ = key::PublicKey::from_slice(context, &pdata)?; - let sec = key::SecretKey::from_slice(context, &secret)?; - let shared = ecdh::SharedSecret::new_raw(context, &publ, &sec); - - Secret::from_unsafe_slice(&shared[0..32]) - .map_err(|_| Error::Secp(SecpError::InvalidSecretKey)) - } -} - -/// ECIES function -#[cfg(feature = "secp256k1")] -pub mod ecies { - use rcrypto::digest::Digest; - use rcrypto::sha2::Sha256; - use rcrypto::hmac::Hmac; - use rcrypto::mac::Mac; - use ethereum_types::H128; - use ethkey::{Random, Generator, Public, Secret}; - use {Error, ecdh, aes}; - - /// Encrypt a message with a public key, writing an HMAC covering both - /// the plaintext and authenticated data. - /// - /// Authenticated data may be empty. - pub fn encrypt(public: &Public, auth_data: &[u8], plain: &[u8]) -> Result, Error> { - let r = Random.generate() - .expect("context known to have key-generation capabilities; qed"); - - let z = ecdh::agree(r.secret(), public)?; - let mut key = [0u8; 32]; - let mut mkey = [0u8; 32]; - kdf(&z, &[0u8; 0], &mut key); - let mut hasher = Sha256::new(); - let mkey_material = &key[16..32]; - hasher.input(mkey_material); - hasher.result(&mut mkey); - let ekey = &key[0..16]; - - let mut msg = vec![0u8; 1 + 64 + 16 + plain.len() + 32]; - msg[0] = 0x04u8; - { - let msgd = &mut msg[1..]; - msgd[0..64].copy_from_slice(r.public()); - let iv = H128::random(); - msgd[64..80].copy_from_slice(&iv); - { - let cipher = &mut msgd[(64 + 16)..(64 + 16 + plain.len())]; - aes::encrypt(ekey, &iv, plain, cipher); - } - let mut hmac = Hmac::new(Sha256::new(), &mkey); - { - let cipher_iv = &msgd[64..(64 + 16 + plain.len())]; - hmac.input(cipher_iv); - } - hmac.input(auth_data); - hmac.raw_result(&mut msgd[(64 + 16 + plain.len())..]); - } - Ok(msg) - } - - /// Decrypt a message with a secret key, checking HMAC for ciphertext - /// and authenticated data validity. - pub fn decrypt(secret: &Secret, auth_data: &[u8], encrypted: &[u8]) -> Result, Error> { - let meta_len = 1 + 64 + 16 + 32; - if encrypted.len() < meta_len || encrypted[0] < 2 || encrypted[0] > 4 { - return Err(Error::InvalidMessage); //invalid message: publickey - } - - let e = &encrypted[1..]; - let p = Public::from_slice(&e[0..64]); - let z = ecdh::agree(secret, &p)?; - let mut key = [0u8; 32]; - kdf(&z, &[0u8; 0], &mut key); - let ekey = &key[0..16]; - let mkey_material = &key[16..32]; - let mut hasher = Sha256::new(); - let mut mkey = [0u8; 32]; - hasher.input(mkey_material); - hasher.result(&mut mkey); - - let clen = encrypted.len() - meta_len; - let cipher_with_iv = &e[64..(64+16+clen)]; - let cipher_iv = &cipher_with_iv[0..16]; - let cipher_no_iv = &cipher_with_iv[16..]; - let msg_mac = &e[(64+16+clen)..]; - - // Verify tag - let mut hmac = Hmac::new(Sha256::new(), &mkey); - hmac.input(cipher_with_iv); - hmac.input(auth_data); - let mut mac = [0u8; 32]; - hmac.raw_result(&mut mac); - - // constant time compare to avoid timing attack. - if ::subtle::slices_equal(&mac[..], msg_mac) != 1 { - return Err(Error::InvalidMessage); - } - - let mut msg = vec![0u8; clen]; - aes::decrypt(ekey, cipher_iv, cipher_no_iv, &mut msg[..]); - Ok(msg) - } - - fn kdf(secret: &Secret, s1: &[u8], dest: &mut [u8]) { - let mut hasher = Sha256::new(); - // SEC/ISO/Shoup specify counter size SHOULD be equivalent - // to size of hash output, however, it also notes that - // the 4 bytes is okay. NIST specifies 4 bytes. - let mut ctr = 1u32; - let mut written = 0usize; - while written < dest.len() { - let ctrs = [(ctr >> 24) as u8, (ctr >> 16) as u8, (ctr >> 8) as u8, ctr as u8]; - hasher.input(&ctrs); - hasher.input(secret); - hasher.input(s1); - hasher.result(&mut dest[written..(written + 32)]); - hasher.reset(); - written += 32; - ctr += 1; - } - } -} - -#[cfg(test)] -mod tests { - use ethkey::{Random, Generator}; - use ecies; - - #[test] - fn ecies_shared() { - let kp = Random.generate().unwrap(); - let message = b"So many books, so little time"; - - let shared = b"shared"; - let wrong_shared = b"incorrect"; - let encrypted = ecies::encrypt(kp.public(), shared, message).unwrap(); - assert!(encrypted[..] != message[..]); - assert_eq!(encrypted[0], 0x04); - - assert!(ecies::decrypt(kp.secret(), wrong_shared, &encrypted).is_err()); - let decrypted = ecies::decrypt(kp.secret(), shared, &encrypted).unwrap(); - assert_eq!(decrypted[..message.len()], message[..]); - } +pub fn is_equal(a: &[u8], b: &[u8]) -> bool { + ring::constant_time::verify_slices_are_equal(a, b).is_ok() } diff --git a/ethcore/crypto/src/pbkdf2.rs b/ethcore/crypto/src/pbkdf2.rs new file mode 100644 index 0000000000..b4c993c513 --- /dev/null +++ b/ethcore/crypto/src/pbkdf2.rs @@ -0,0 +1,29 @@ +// Copyright 2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +use ring; + +pub struct Salt<'a>(pub &'a [u8]); +pub struct Secret<'a>(pub &'a [u8]); + +pub fn sha256(iter: u32, salt: Salt, sec: Secret, out: &mut [u8; 32]) { + ring::pbkdf2::derive(&ring::digest::SHA256, iter, salt.0, sec.0, &mut out[..]) +} + +pub fn sha512(iter: u32, salt: Salt, sec: Secret, out: &mut [u8; 64]) { + ring::pbkdf2::derive(&ring::digest::SHA512, iter, salt.0, sec.0, &mut out[..]) +} + diff --git a/ethcore/crypto/src/scrypt.rs b/ethcore/crypto/src/scrypt.rs new file mode 100644 index 0000000000..684ab2c572 --- /dev/null +++ b/ethcore/crypto/src/scrypt.rs @@ -0,0 +1,39 @@ +// 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 . + +use error::ScryptError; +use rcrypto::scrypt::{scrypt, ScryptParams}; +use super::{KEY_LENGTH_AES, KEY_LENGTH}; + +pub fn derive_key(pass: &str, salt: &[u8; 32], n: u32, p: u32, r: u32) -> Result<(Vec, Vec), ScryptError> { + // sanity checks + let log_n = (32 - n.leading_zeros() - 1) as u8; + if log_n as u32 >= r * 16 { + return Err(ScryptError::InvalidN); + } + + if p as u64 > ((u32::max_value() as u64 - 1) * 32)/(128 * (r as u64)) { + return Err(ScryptError::InvalidP); + } + + let mut derived_key = vec![0u8; KEY_LENGTH]; + let scrypt_params = ScryptParams::new(log_n, r, p); + scrypt(pass.as_bytes(), salt, &scrypt_params, &mut derived_key); + let derived_right_bits = &derived_key[0..KEY_LENGTH_AES]; + let derived_left_bits = &derived_key[KEY_LENGTH_AES..KEY_LENGTH]; + Ok((derived_right_bits.to_vec(), derived_left_bits.to_vec())) +} + diff --git a/ethcore/private-tx/src/encryptor.rs b/ethcore/private-tx/src/encryptor.rs index 5d592de603..b15acbee71 100644 --- a/ethcore/private-tx/src/encryptor.rs +++ b/ethcore/private-tx/src/encryptor.rs @@ -217,7 +217,8 @@ impl Encryptor for SecretStoreEncryptor { // encrypt data let mut cypher = Vec::with_capacity(plain_data.len() + initialisation_vector.len()); cypher.extend(repeat(0).take(plain_data.len())); - crypto::aes::encrypt(&key, initialisation_vector, plain_data, &mut cypher); + crypto::aes::encrypt_128_ctr(&key, initialisation_vector, plain_data, &mut cypher) + .map_err(|e| ErrorKind::Encrypt(e.to_string()))?; cypher.extend_from_slice(&initialisation_vector); Ok(cypher) @@ -243,8 +244,8 @@ impl Encryptor for SecretStoreEncryptor { let (cypher, iv) = cypher.split_at(cypher_len - INIT_VEC_LEN); let mut plain_data = Vec::with_capacity(cypher_len - INIT_VEC_LEN); plain_data.extend(repeat(0).take(cypher_len - INIT_VEC_LEN)); - crypto::aes::decrypt(&key, &iv, cypher, &mut plain_data); - + crypto::aes::decrypt_128_ctr(&key, &iv, cypher, &mut plain_data) + .map_err(|e| ErrorKind::Decrypt(e.to_string()))?; Ok(plain_data) } } diff --git a/ethcore/src/builtin.rs b/ethcore/src/builtin.rs index c18e1f3cd3..a0833cfb5e 100644 --- a/ethcore/src/builtin.rs +++ b/ethcore/src/builtin.rs @@ -18,9 +18,7 @@ use std::cmp::{max, min}; use std::io::{self, Read}; use byteorder::{ByteOrder, BigEndian}; -use crypto::sha2::Sha256 as Sha256Digest; -use crypto::ripemd160::Ripemd160 as Ripemd160Digest; -use crypto::digest::Digest; +use ethcore_crypto::digest; use num::{BigUint, Zero, One}; use hash::keccak; @@ -295,28 +293,17 @@ impl Impl for EcRecover { impl Impl for Sha256 { fn execute(&self, input: &[u8], output: &mut BytesRef) -> Result<(), Error> { - let mut sha = Sha256Digest::new(); - sha.input(input); - - let mut out = [0; 32]; - sha.result(&mut out); - - output.write(0, &out); - + let d = digest::sha256(input); + output.write(0, &*d); Ok(()) } } impl Impl for Ripemd160 { fn execute(&self, input: &[u8], output: &mut BytesRef) -> Result<(), Error> { - let mut sha = Ripemd160Digest::new(); - sha.input(input); - - let mut out = [0; 32]; - sha.result(&mut out[12..32]); - - output.write(0, &out); - + let hash = digest::ripemd160(input); + output.write(0, &[0; 12][..]); + output.write(12, &hash); Ok(()) } } diff --git a/ethcore/src/lib.rs b/ethcore/src/lib.rs index 9bb2e94c1c..b1782cb1d6 100644 --- a/ethcore/src/lib.rs +++ b/ethcore/src/lib.rs @@ -63,9 +63,9 @@ extern crate bn; extern crate byteorder; extern crate crossbeam; extern crate common_types as types; -extern crate crypto; extern crate ethash; extern crate ethcore_bloom_journal as bloom_journal; +extern crate ethcore_crypto; extern crate ethcore_io as io; extern crate ethcore_bytes as bytes; extern crate ethcore_logger; diff --git a/ethkey/Cargo.toml b/ethkey/Cargo.toml index 335f92fe15..d6698f86d9 100644 --- a/ethkey/Cargo.toml +++ b/ethkey/Cargo.toml @@ -6,13 +6,14 @@ authors = ["Parity Technologies "] [dependencies] byteorder = "1.0" edit-distance = "2.0" +ethcore-crypto = { path = "../ethcore/crypto" } eth-secp256k1 = { git = "https://github.com/paritytech/rust-secp256k1" } ethereum-types = "0.3" lazy_static = "1.0" log = "0.3" mem = { path = "../util/mem" } parity-wordlist = "1.2" +quick-error = "1.2" rand = "0.4" -rust-crypto = "0.2" rustc-hex = "1.0" tiny-keccak = "1.3" diff --git a/ethkey/src/crypto.rs b/ethkey/src/crypto.rs new file mode 100644 index 0000000000..739a463c07 --- /dev/null +++ b/ethkey/src/crypto.rs @@ -0,0 +1,189 @@ +// 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 . + +use secp256k1; +use std::io; +use ethcore_crypto::error::SymmError; + +quick_error! { + #[derive(Debug)] + pub enum Error { + Secp(e: secp256k1::Error) { + display("secp256k1 error: {}", e) + cause(e) + from() + } + Io(e: io::Error) { + display("i/o error: {}", e) + cause(e) + from() + } + InvalidMessage { + display("invalid message") + } + Symm(e: SymmError) { + cause(e) + from() + } + } +} + +/// ECDH functions +pub mod ecdh { + use secp256k1::{self, ecdh, key}; + use super::Error; + use {Secret, Public, SECP256K1}; + + /// Agree on a shared secret + pub fn agree(secret: &Secret, public: &Public) -> Result { + let context = &SECP256K1; + let pdata = { + let mut temp = [4u8; 65]; + (&mut temp[1..65]).copy_from_slice(&public[0..64]); + temp + }; + + let publ = key::PublicKey::from_slice(context, &pdata)?; + let sec = key::SecretKey::from_slice(context, &secret)?; + let shared = ecdh::SharedSecret::new_raw(context, &publ, &sec); + + Secret::from_unsafe_slice(&shared[0..32]) + .map_err(|_| Error::Secp(secp256k1::Error::InvalidSecretKey)) + } +} + +/// ECIES function +pub mod ecies { + use ethcore_crypto::{aes, digest, hmac, is_equal}; + use ethereum_types::H128; + use super::{ecdh, Error}; + use {Random, Generator, Public, Secret}; + + /// Encrypt a message with a public key, writing an HMAC covering both + /// the plaintext and authenticated data. + /// + /// Authenticated data may be empty. + pub fn encrypt(public: &Public, auth_data: &[u8], plain: &[u8]) -> Result, Error> { + let r = Random.generate()?; + let z = ecdh::agree(r.secret(), public)?; + let mut key = [0u8; 32]; + kdf(&z, &[0u8; 0], &mut key); + + let ekey = &key[0..16]; + let mkey = hmac::SigKey::sha256(&digest::sha256(&key[16..32])); + + let mut msg = vec![0u8; 1 + 64 + 16 + plain.len() + 32]; + msg[0] = 0x04u8; + { + let msgd = &mut msg[1..]; + msgd[0..64].copy_from_slice(r.public()); + let iv = H128::random(); + msgd[64..80].copy_from_slice(&iv); + { + let cipher = &mut msgd[(64 + 16)..(64 + 16 + plain.len())]; + aes::encrypt_128_ctr(ekey, &iv, plain, cipher)?; + } + let mut hmac = hmac::Signer::with(&mkey); + { + let cipher_iv = &msgd[64..(64 + 16 + plain.len())]; + hmac.update(cipher_iv); + } + hmac.update(auth_data); + let sig = hmac.sign(); + msgd[(64 + 16 + plain.len())..].copy_from_slice(&sig); + } + Ok(msg) + } + + /// Decrypt a message with a secret key, checking HMAC for ciphertext + /// and authenticated data validity. + pub fn decrypt(secret: &Secret, auth_data: &[u8], encrypted: &[u8]) -> Result, Error> { + let meta_len = 1 + 64 + 16 + 32; + if encrypted.len() < meta_len || encrypted[0] < 2 || encrypted[0] > 4 { + return Err(Error::InvalidMessage); //invalid message: publickey + } + + let e = &encrypted[1..]; + let p = Public::from_slice(&e[0..64]); + let z = ecdh::agree(secret, &p)?; + let mut key = [0u8; 32]; + kdf(&z, &[0u8; 0], &mut key); + + let ekey = &key[0..16]; + let mkey = hmac::SigKey::sha256(&digest::sha256(&key[16..32])); + + let clen = encrypted.len() - meta_len; + let cipher_with_iv = &e[64..(64+16+clen)]; + let cipher_iv = &cipher_with_iv[0..16]; + let cipher_no_iv = &cipher_with_iv[16..]; + let msg_mac = &e[(64+16+clen)..]; + + // Verify tag + let mut hmac = hmac::Signer::with(&mkey); + hmac.update(cipher_with_iv); + hmac.update(auth_data); + let mac = hmac.sign(); + + if !is_equal(&mac.as_ref()[..], msg_mac) { + return Err(Error::InvalidMessage); + } + + let mut msg = vec![0u8; clen]; + aes::decrypt_128_ctr(ekey, cipher_iv, cipher_no_iv, &mut msg[..])?; + Ok(msg) + } + + fn kdf(secret: &Secret, s1: &[u8], dest: &mut [u8]) { + // SEC/ISO/Shoup specify counter size SHOULD be equivalent + // to size of hash output, however, it also notes that + // the 4 bytes is okay. NIST specifies 4 bytes. + let mut ctr = 1u32; + let mut written = 0usize; + while written < dest.len() { + let mut hasher = digest::Hasher::sha256(); + let ctrs = [(ctr >> 24) as u8, (ctr >> 16) as u8, (ctr >> 8) as u8, ctr as u8]; + hasher.update(&ctrs); + hasher.update(secret); + hasher.update(s1); + let d = hasher.finish(); + &mut dest[written..(written + 32)].copy_from_slice(&d); + written += 32; + ctr += 1; + } + } +} + +#[cfg(test)] +mod tests { + use super::ecies; + use {Random, Generator}; + + #[test] + fn ecies_shared() { + let kp = Random.generate().unwrap(); + let message = b"So many books, so little time"; + + let shared = b"shared"; + let wrong_shared = b"incorrect"; + let encrypted = ecies::encrypt(kp.public(), shared, message).unwrap(); + assert!(encrypted[..] != message[..]); + assert_eq!(encrypted[0], 0x04); + + assert!(ecies::decrypt(kp.secret(), wrong_shared, &encrypted).is_err()); + let decrypted = ecies::decrypt(kp.secret(), shared, &encrypted).unwrap(); + assert_eq!(decrypted[..message.len()], message[..]); + } +} diff --git a/ethkey/src/extended.rs b/ethkey/src/extended.rs index 55bae62754..d41ae54c53 100644 --- a/ethkey/src/extended.rs +++ b/ethkey/src/extended.rs @@ -207,9 +207,7 @@ impl ExtendedKeyPair { // Work is based on BIP0032 // https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki mod derivation { - use rcrypto::hmac::Hmac; - use rcrypto::mac::Mac; - use rcrypto::sha2::Sha512; + use ethcore_crypto::hmac; use ethereum_types::{U256, U512, H512, H256}; use secp256k1::key::{SecretKey, PublicKey}; use SECP256K1; @@ -242,10 +240,8 @@ mod derivation { let private: U256 = private_key.into(); // produces 512-bit derived hmac (I) - let mut hmac = Hmac::new(Sha512::new(), &*chain_code); - let mut i_512 = [0u8; 64]; - hmac.input(&data[..]); - hmac.raw_result(&mut i_512); + let skey = hmac::SigKey::sha512(&*chain_code); + let i_512 = hmac::sign(&skey, &data[..]); // left most 256 bits are later added to original private key let hmac_key: U256 = H256::from_slice(&i_512[0..32]).into(); @@ -321,10 +317,8 @@ mod derivation { index.store(&mut data[33..(33 + T::len())]); // HMAC512SHA produces [derived private(256); new chain code(256)] - let mut hmac = Hmac::new(Sha512::new(), &*chain_code); - let mut i_512 = [0u8; 64]; - hmac.input(&data[..]); - hmac.raw_result(&mut i_512); + let skey = hmac::SigKey::sha512(&*chain_code); + let i_512 = hmac::sign(&skey, &data[..]); let new_private = H256::from(&i_512[0..32]); let new_chain_code = H256::from(&i_512[32..64]); @@ -369,10 +363,8 @@ mod derivation { } pub fn seed_pair(seed: &[u8]) -> (H256, H256) { - let mut hmac = Hmac::new(Sha512::new(), b"Bitcoin seed"); - let mut i_512 = [0u8; 64]; - hmac.input(seed); - hmac.raw_result(&mut i_512); + let skey = hmac::SigKey::sha512(b"Bitcoin seed"); + let i_512 = hmac::sign(&skey, seed); let master_key = H256::from_slice(&i_512[0..32]); let chain_code = H256::from_slice(&i_512[32..64]); diff --git a/ethkey/src/lib.rs b/ethkey/src/lib.rs index 951179771b..b5cf984530 100644 --- a/ethkey/src/lib.rs +++ b/ethkey/src/lib.rs @@ -17,11 +17,13 @@ // #![warn(missing_docs)] extern crate byteorder; -extern crate crypto as rcrypto; extern crate edit_distance; +extern crate ethcore_crypto; extern crate ethereum_types; extern crate mem; extern crate parity_wordlist; +#[macro_use] +extern crate quick_error; extern crate rand; extern crate rustc_hex; extern crate secp256k1; @@ -44,6 +46,7 @@ mod secret; mod extended; pub mod brain_recover; +pub mod crypto; pub mod math; pub use self::parity_wordlist::Error as WordlistError; diff --git a/ethstore/Cargo.toml b/ethstore/Cargo.toml index d0524baeaf..6330ce97ce 100644 --- a/ethstore/Cargo.toml +++ b/ethstore/Cargo.toml @@ -12,7 +12,6 @@ serde = "1.0" serde_json = "1.0" serde_derive = "1.0" rustc-hex = "1.0" -rust-crypto = "0.2.36" tiny-keccak = "1.3" time = "0.1.34" itertools = "0.5" @@ -22,7 +21,6 @@ ethereum-types = "0.3" dir = { path = "../util/dir" } smallvec = "0.4" parity-wordlist = "1.0" -subtle = "0.5" tempdir = "0.3" [dev-dependencies] diff --git a/ethstore/src/account/crypto.rs b/ethstore/src/account/crypto.rs index 967c92306a..bd65bc927b 100644 --- a/ethstore/src/account/crypto.rs +++ b/ethstore/src/account/crypto.rs @@ -21,7 +21,6 @@ use crypto::Keccak256; use random::Random; use smallvec::SmallVec; use account::{Cipher, Kdf, Aes128Ctr, Pbkdf2, Prf}; -use subtle; /// Encrypted data #[derive(Debug, PartialEq, Clone)] @@ -74,12 +73,12 @@ impl From for String { impl Crypto { /// Encrypt account secret - pub fn with_secret(secret: &Secret, password: &str, iterations: u32) -> Self { + pub fn with_secret(secret: &Secret, password: &str, iterations: u32) -> Result { Crypto::with_plain(&*secret, password, iterations) } /// Encrypt custom plain data - pub fn with_plain(plain: &[u8], password: &str, iterations: u32) -> Self { + pub fn with_plain(plain: &[u8], password: &str, iterations: u32) -> Result { let salt: [u8; 32] = Random::random(); let iv: [u8; 16] = Random::random(); @@ -93,12 +92,12 @@ impl Crypto { let mut ciphertext: SmallVec<[u8; 32]> = SmallVec::from_vec(vec![0; plain_len]); // aes-128-ctr with initial vector of iv - crypto::aes::encrypt(&derived_left_bits, &iv, plain, &mut *ciphertext); + crypto::aes::encrypt_128_ctr(&derived_left_bits, &iv, plain, &mut *ciphertext)?; // KECCAK(DK[16..31] ++ ), where DK[16..31] - derived_right_bits let mac = crypto::derive_mac(&derived_right_bits, &*ciphertext).keccak256(); - Crypto { + Ok(Crypto { cipher: Cipher::Aes128Ctr(Aes128Ctr { iv: iv, }), @@ -110,7 +109,7 @@ impl Crypto { prf: Prf::HmacSha256, }), mac: mac, - } + }) } /// Try to decrypt and convert result to account secret @@ -132,13 +131,13 @@ impl Crypto { fn do_decrypt(&self, password: &str, expected_len: usize) -> Result, Error> { let (derived_left_bits, derived_right_bits) = match self.kdf { Kdf::Pbkdf2(ref params) => crypto::derive_key_iterations(password, ¶ms.salt, params.c), - Kdf::Scrypt(ref params) => crypto::derive_key_scrypt(password, ¶ms.salt, params.n, params.p, params.r)?, + Kdf::Scrypt(ref params) => crypto::scrypt::derive_key(password, ¶ms.salt, params.n, params.p, params.r)?, }; let mac = crypto::derive_mac(&derived_right_bits, &self.ciphertext).keccak256(); - if subtle::slices_equal(&mac, &self.mac) == 0 { - return Err(Error::InvalidPassword); + if !crypto::is_equal(&mac, &self.mac) { + return Err(Error::InvalidPassword) } let mut plain: SmallVec<[u8; 32]> = SmallVec::from_vec(vec![0; expected_len]); @@ -149,7 +148,7 @@ impl Crypto { debug_assert!(expected_len >= self.ciphertext.len()); let from = expected_len - self.ciphertext.len(); - crypto::aes::decrypt(&derived_left_bits, ¶ms.iv, &self.ciphertext, &mut plain[from..]); + crypto::aes::decrypt_128_ctr(&derived_left_bits, ¶ms.iv, &self.ciphertext, &mut plain[from..])?; Ok(plain.into_iter().collect()) }, } @@ -164,7 +163,7 @@ mod tests { #[test] fn crypto_with_secret_create() { let keypair = Random.generate().unwrap(); - let crypto = Crypto::with_secret(keypair.secret(), "this is sparta", 10240); + let crypto = Crypto::with_secret(keypair.secret(), "this is sparta", 10240).unwrap(); let secret = crypto.secret("this is sparta").unwrap(); assert_eq!(keypair.secret(), &secret); } @@ -172,14 +171,14 @@ mod tests { #[test] fn crypto_with_secret_invalid_password() { let keypair = Random.generate().unwrap(); - let crypto = Crypto::with_secret(keypair.secret(), "this is sparta", 10240); + let crypto = Crypto::with_secret(keypair.secret(), "this is sparta", 10240).unwrap(); assert_matches!(crypto.secret("this is sparta!"), Err(Error::InvalidPassword)) } #[test] fn crypto_with_null_plain_data() { let original_data = b""; - let crypto = Crypto::with_plain(&original_data[..], "this is sparta", 10240); + let crypto = Crypto::with_plain(&original_data[..], "this is sparta", 10240).unwrap(); let decrypted_data = crypto.decrypt("this is sparta").unwrap(); assert_eq!(original_data[..], *decrypted_data); } @@ -187,7 +186,7 @@ mod tests { #[test] fn crypto_with_tiny_plain_data() { let original_data = b"{}"; - let crypto = Crypto::with_plain(&original_data[..], "this is sparta", 10240); + let crypto = Crypto::with_plain(&original_data[..], "this is sparta", 10240).unwrap(); let decrypted_data = crypto.decrypt("this is sparta").unwrap(); assert_eq!(original_data[..], *decrypted_data); } @@ -195,7 +194,7 @@ mod tests { #[test] fn crypto_with_huge_plain_data() { let original_data: Vec<_> = (1..65536).map(|i| (i % 256) as u8).collect(); - let crypto = Crypto::with_plain(&original_data, "this is sparta", 10240); + let crypto = Crypto::with_plain(&original_data, "this is sparta", 10240).unwrap(); let decrypted_data = crypto.decrypt("this is sparta").unwrap(); assert_eq!(&original_data, &decrypted_data); } diff --git a/ethstore/src/account/safe_account.rs b/ethstore/src/account/safe_account.rs index 478b796e64..069c997e10 100644 --- a/ethstore/src/account/safe_account.rs +++ b/ethstore/src/account/safe_account.rs @@ -14,10 +14,11 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -use ethkey::{KeyPair, sign, Address, Signature, Message, Public, Secret}; -use crypto::ecdh::agree; -use {json, Error, crypto}; +use ethkey::{self, KeyPair, sign, Address, Signature, Message, Public, Secret}; +use ethkey::crypto::ecdh::agree; +use {json, Error}; use account::Version; +use crypto; use super::crypto::Crypto; /// Account representation. @@ -61,16 +62,16 @@ impl SafeAccount { iterations: u32, name: String, meta: String - ) -> Self { - SafeAccount { + ) -> Result { + Ok(SafeAccount { id: id, version: Version::V3, - crypto: Crypto::with_secret(keypair.secret(), password, iterations), + crypto: Crypto::with_secret(keypair.secret(), password, iterations)?, address: keypair.address(), filename: None, name: name, meta: meta, - } + }) } /// Create a new `SafeAccount` from the given `json`; if it was read from a @@ -114,7 +115,7 @@ impl SafeAccount { meta: Some(self.meta), }; let meta_plain = meta_plain.write().map_err(|e| Error::Custom(format!("{:?}", e)))?; - let meta_crypto = Crypto::with_plain(&meta_plain, password, iterations); + let meta_crypto = Crypto::with_plain(&meta_plain, password, iterations)?; Ok(json::VaultKeyFile { id: self.id.into(), @@ -133,7 +134,7 @@ impl SafeAccount { /// Decrypt a message. pub fn decrypt(&self, password: &str, shared_mac: &[u8], message: &[u8]) -> Result, Error> { let secret = self.crypto.secret(password)?; - crypto::ecies::decrypt(&secret, shared_mac, message).map_err(From::from) + ethkey::crypto::ecies::decrypt(&secret, shared_mac, message).map_err(From::from) } /// Agree on shared key. @@ -154,7 +155,7 @@ impl SafeAccount { let result = SafeAccount { id: self.id.clone(), version: self.version.clone(), - crypto: Crypto::with_secret(&secret, new_password, iterations), + crypto: Crypto::with_secret(&secret, new_password, iterations)?, address: self.address.clone(), filename: self.filename.clone(), name: self.name.clone(), @@ -180,7 +181,7 @@ mod tests { let password = "hello world"; let message = Message::default(); let account = SafeAccount::create(&keypair, [0u8; 16], password, 10240, "Test".to_owned(), "{}".to_owned()); - let signature = account.sign(password, &message).unwrap(); + let signature = account.unwrap().sign(password, &message).unwrap(); assert!(verify_public(keypair.public(), &signature, &message).unwrap()); } @@ -191,7 +192,7 @@ mod tests { let sec_password = "this is sparta"; let i = 10240; let message = Message::default(); - let account = SafeAccount::create(&keypair, [0u8; 16], first_password, i, "Test".to_owned(), "{}".to_owned()); + let account = SafeAccount::create(&keypair, [0u8; 16], first_password, i, "Test".to_owned(), "{}".to_owned()).unwrap(); let new_account = account.change_password(first_password, sec_password, i).unwrap(); assert!(account.sign(first_password, &message).is_ok()); assert!(account.sign(sec_password, &message).is_err()); diff --git a/ethstore/src/accounts_dir/disk.rs b/ethstore/src/accounts_dir/disk.rs index 1446118440..29b7e52466 100644 --- a/ethstore/src/accounts_dir/disk.rs +++ b/ethstore/src/accounts_dir/disk.rs @@ -319,7 +319,7 @@ mod test { // when let account = SafeAccount::create(&keypair, [0u8; 16], password, 1024, "Test".to_owned(), "{}".to_owned()); - let res = directory.insert(account); + let res = directory.insert(account.unwrap()); // then assert!(res.is_ok(), "Should save account succesfuly."); @@ -339,7 +339,7 @@ mod test { let directory = RootDiskDirectory::create(dir.clone()).unwrap(); // when - let account = SafeAccount::create(&keypair, [0u8; 16], password, 1024, "Test".to_owned(), "{}".to_owned()); + let account = SafeAccount::create(&keypair, [0u8; 16], password, 1024, "Test".to_owned(), "{}".to_owned()).unwrap(); let filename = "test".to_string(); let dedup = true; @@ -424,7 +424,7 @@ mod test { let keypair = Random.generate().unwrap(); let password = "test pass"; let account = SafeAccount::create(&keypair, [0u8; 16], password, 1024, "Test".to_owned(), "{}".to_owned()); - directory.insert(account).expect("Account should be inserted ok"); + directory.insert(account.unwrap()).expect("Account should be inserted ok"); let new_hash = directory.files_hash().expect("New files hash should be calculated ok"); diff --git a/ethstore/src/accounts_dir/vault.rs b/ethstore/src/accounts_dir/vault.rs index 1ef85402a7..2705262666 100644 --- a/ethstore/src/accounts_dir/vault.rs +++ b/ethstore/src/accounts_dir/vault.rs @@ -235,7 +235,7 @@ fn check_vault_name(name: &str) -> bool { /// Vault can be empty, but still must be pluggable => we store vault password in separate file fn create_vault_file

(vault_dir_path: P, key: &VaultKey, meta: &str) -> Result<(), Error> where P: AsRef { let password_hash = key.password.keccak256(); - let crypto = Crypto::with_plain(&password_hash, &key.password, key.iterations); + let crypto = Crypto::with_plain(&password_hash, &key.password, key.iterations)?; let mut vault_file_path: PathBuf = vault_dir_path.as_ref().into(); vault_file_path.push(VAULT_FILE_NAME); diff --git a/ethstore/src/error.rs b/ethstore/src/error.rs index f7e0b0bfad..7c89473280 100644 --- a/ethstore/src/error.rs +++ b/ethstore/src/error.rs @@ -16,8 +16,8 @@ use std::fmt; use std::io::Error as IoError; -use ethkey::Error as EthKeyError; -use crypto::Error as EthCryptoError; +use ethkey::{self, Error as EthKeyError}; +use crypto::{self, Error as EthCryptoError}; use ethkey::DerivationError; /// Account-related errors. @@ -49,6 +49,8 @@ pub enum Error { CreationFailed, /// `EthKey` error EthKey(EthKeyError), + /// `ethkey::crypto::Error` + EthKeyCrypto(ethkey::crypto::Error), /// `EthCrypto` error EthCrypto(EthCryptoError), /// Derivation error @@ -73,6 +75,7 @@ impl fmt::Display for Error { Error::VaultNotFound => "Vault not found".into(), Error::CreationFailed => "Account creation failed".into(), Error::EthKey(ref err) => err.to_string(), + Error::EthKeyCrypto(ref err) => err.to_string(), Error::EthCrypto(ref err) => err.to_string(), Error::Derivation(ref err) => format!("Derivation error: {:?}", err), Error::Custom(ref s) => s.clone(), @@ -94,12 +97,30 @@ impl From for Error { } } +impl From for Error { + fn from(err: ethkey::crypto::Error) -> Self { + Error::EthKeyCrypto(err) + } +} + impl From for Error { fn from(err: EthCryptoError) -> Self { Error::EthCrypto(err) } } +impl From for Error { + fn from(err: crypto::error::ScryptError) -> Self { + Error::EthCrypto(err.into()) + } +} + +impl From for Error { + fn from(err: crypto::error::SymmError) -> Self { + Error::EthCrypto(err.into()) + } +} + impl From for Error { fn from(err: DerivationError) -> Self { Error::Derivation(err) diff --git a/ethstore/src/ethstore.rs b/ethstore/src/ethstore.rs index 40a687fc98..46c81153c7 100644 --- a/ethstore/src/ethstore.rs +++ b/ethstore/src/ethstore.rs @@ -458,7 +458,7 @@ impl SimpleSecretStore for EthMultiStore { fn insert_account(&self, vault: SecretVaultRef, secret: Secret, password: &str) -> Result { let keypair = KeyPair::from_secret(secret).map_err(|_| Error::CreationFailed)?; let id: [u8; 16] = Random::random(); - let account = SafeAccount::create(&keypair, id, password, self.iterations, "".to_owned(), "{}".to_owned()); + let account = SafeAccount::create(&keypair, id, password, self.iterations, "".to_owned(), "{}".to_owned())?; self.import(vault, account) } diff --git a/ethstore/src/lib.rs b/ethstore/src/lib.rs index 75df0953ce..b558126ada 100644 --- a/ethstore/src/lib.rs +++ b/ethstore/src/lib.rs @@ -18,7 +18,6 @@ #![warn(missing_docs)] -extern crate crypto as rcrypto; extern crate dir; extern crate itertools; extern crate libc; @@ -28,7 +27,6 @@ extern crate rustc_hex; extern crate serde; extern crate serde_json; extern crate smallvec; -extern crate subtle; extern crate time; extern crate tiny_keccak; extern crate tempdir; diff --git a/ethstore/src/presale.rs b/ethstore/src/presale.rs index 0c3e72e31b..555d00c1e9 100644 --- a/ethstore/src/presale.rs +++ b/ethstore/src/presale.rs @@ -1,11 +1,8 @@ use std::fs; use std::path::Path; -use rcrypto::pbkdf2::pbkdf2; -use rcrypto::sha2::Sha256; -use rcrypto::hmac::Hmac; use json; use ethkey::{Address, Secret, KeyPair}; -use crypto::Keccak256; +use crypto::{Keccak256, pbkdf2}; use {crypto, Error}; /// Pre-sale wallet. @@ -42,12 +39,14 @@ impl PresaleWallet { /// Decrypt the wallet. pub fn decrypt(&self, password: &str) -> Result { - let mut h_mac = Hmac::new(Sha256::new(), password.as_bytes()); - let mut derived_key = vec![0u8; 16]; - pbkdf2(&mut h_mac, password.as_bytes(), 2000, &mut derived_key); + let mut derived_key = [0u8; 32]; + let salt = pbkdf2::Salt(password.as_bytes()); + let sec = pbkdf2::Secret(password.as_bytes()); + pbkdf2::sha256(2000, salt, sec, &mut derived_key); let mut key = vec![0; self.ciphertext.len()]; - let len = crypto::aes::decrypt_cbc(&derived_key, &self.iv, &self.ciphertext, &mut key).map_err(|_| Error::InvalidPassword)?; + let len = crypto::aes::decrypt_128_cbc(&derived_key[0..16], &self.iv, &self.ciphertext, &mut key) + .map_err(|_| Error::InvalidPassword)?; let unpadded = &key[..len]; let secret = Secret::from_unsafe_slice(&unpadded.keccak256())?; diff --git a/rpc/Cargo.toml b/rpc/Cargo.toml index b8eb525462..731544a55f 100644 --- a/rpc/Cargo.toml +++ b/rpc/Cargo.toml @@ -17,7 +17,6 @@ multihash ="0.7" order-stat = "0.1" parking_lot = "0.5" rand = "0.4" -rust-crypto = "0.2" rustc-hex = "1.0" semver = "0.9" serde = "1.0" diff --git a/rpc/src/lib.rs b/rpc/src/lib.rs index 7b5cc36447..1fc3d0e242 100644 --- a/rpc/src/lib.rs +++ b/rpc/src/lib.rs @@ -23,7 +23,6 @@ extern crate futures; extern crate ansi_term; extern crate cid; -extern crate crypto as rust_crypto; extern crate futures_cpupool; extern crate itertools; extern crate multihash; diff --git a/rpc/src/v1/helpers/ipfs.rs b/rpc/src/v1/helpers/ipfs.rs index 80ad1c207b..da51f1fd54 100644 --- a/rpc/src/v1/helpers/ipfs.rs +++ b/rpc/src/v1/helpers/ipfs.rs @@ -18,21 +18,15 @@ use multihash; use cid::{Cid, Codec, Version}; -use rust_crypto::sha2::Sha256; -use rust_crypto::digest::Digest; +use crypto::digest; use jsonrpc_core::Error; use v1::types::Bytes; use super::errors; /// Compute CIDv0 from protobuf encoded bytes. pub fn cid(content: Bytes) -> Result { - let mut hasher = Sha256::new(); - hasher.input(&content.0); - let len = hasher.output_bytes(); - let mut buf = Vec::with_capacity(len); - buf.resize(len, 0); - hasher.result(&mut buf); - let mh = multihash::encode(multihash::Hash::SHA2256, &buf).map_err(errors::encoding)?; + let hash = digest::sha256(&content.0); + let mh = multihash::encode(multihash::Hash::SHA2256, &*hash).map_err(errors::encoding)?; let cid = Cid::new(Codec::DagProtobuf, Version::V0, &mh); Ok(cid.to_string().into()) } diff --git a/rpc/src/v1/helpers/secretstore.rs b/rpc/src/v1/helpers/secretstore.rs index fbcc167e23..019d2b1051 100644 --- a/rpc/src/v1/helpers/secretstore.rs +++ b/rpc/src/v1/helpers/secretstore.rs @@ -16,7 +16,7 @@ use std::collections::BTreeSet; use rand::{Rng, OsRng}; -use ethkey::{Public, Secret, Random, Generator, math}; +use ethkey::{self, Public, Secret, Random, Generator, math}; use crypto; use bytes::Bytes; use jsonrpc_core::Error; @@ -36,7 +36,7 @@ pub fn generate_document_key(account_public: Public, server_key_public: Public) let (common_point, encrypted_point) = encrypt_secret(document_key.public(), &server_key_public)?; // ..and now encrypt document key with account public - let encrypted_key = crypto::ecies::encrypt(&account_public, &crypto::DEFAULT_MAC, document_key.public()) + let encrypted_key = ethkey::crypto::ecies::encrypt(&account_public, &crypto::DEFAULT_MAC, document_key.public()) .map_err(errors::encryption)?; Ok(EncryptedDocumentKey { @@ -57,7 +57,7 @@ pub fn encrypt_document(key: Bytes, document: Bytes) -> Result { { let (mut encryption_buffer, iv_buffer) = encrypted_document.split_at_mut(document.len()); - crypto::aes::encrypt(&key, &iv, &document, &mut encryption_buffer); + crypto::aes::encrypt_128_ctr(&key, &iv, &document, &mut encryption_buffer).map_err(errors::encryption)?; iv_buffer.copy_from_slice(&iv); } @@ -78,7 +78,7 @@ pub fn decrypt_document(key: Bytes, mut encrypted_document: Bytes) -> Result = decrypted_secret.decrypt_shadows.unwrap().into_iter() .map(|c| Secret::from_slice(&decrypt(key_pair.secret(), &DEFAULT_MAC, &c).unwrap()).unwrap()) .collect(); @@ -1423,7 +1423,7 @@ mod tests { // 4 nodes must be able to recover original secret use crypto::DEFAULT_MAC; - use crypto::ecies::decrypt; + use ethkey::crypto::ecies::decrypt; let result = sessions[0].decrypted_secret().unwrap().unwrap(); assert_eq!(3, sessions.iter().skip(1).filter(|s| s.decrypted_secret() == Some(Ok(result.clone()))).count()); let decrypt_shadows: Vec<_> = result.decrypt_shadows.unwrap().into_iter() diff --git a/secret_store/src/key_server_cluster/io/handshake.rs b/secret_store/src/key_server_cluster/io/handshake.rs index 838e48e1f7..af64295632 100644 --- a/secret_store/src/key_server_cluster/io/handshake.rs +++ b/secret_store/src/key_server_cluster/io/handshake.rs @@ -37,7 +37,7 @@ use std::sync::Arc; use std::collections::BTreeSet; use futures::{Future, Poll, Async}; use tokio_io::{AsyncRead, AsyncWrite}; -use crypto::ecdh::agree; +use ethkey::crypto::ecdh::agree; use ethkey::{Random, Generator, KeyPair, Public, Signature, verify_public, sign, recover}; use ethereum_types::H256; use key_server_cluster::{NodeId, Error, NodeKeyPair}; diff --git a/secret_store/src/key_server_cluster/io/message.rs b/secret_store/src/key_server_cluster/io/message.rs index 784b0b2b6a..9925b789d2 100644 --- a/secret_store/src/key_server_cluster/io/message.rs +++ b/secret_store/src/key_server_cluster/io/message.rs @@ -19,7 +19,7 @@ use std::u16; use std::ops::Deref; use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt}; use serde_json; -use crypto::ecies; +use ethkey::crypto::ecies; use ethkey::{Secret, KeyPair}; use ethkey::math::curve_order; use ethereum_types::{H256, U256}; @@ -306,7 +306,7 @@ pub mod tests { use futures::Poll; use tokio_io::{AsyncRead, AsyncWrite}; use ethkey::{Random, Generator, KeyPair}; - use crypto::ecdh::agree; + use ethkey::crypto::ecdh::agree; use key_server_cluster::Error; use key_server_cluster::message::Message; use super::{MESSAGE_HEADER_SIZE, CURRENT_HEADER_VERSION, MessageHeader, fix_shared_key, encrypt_message, diff --git a/secret_store/src/key_server_cluster/jobs/decryption_job.rs b/secret_store/src/key_server_cluster/jobs/decryption_job.rs index 1f14a484da..2c11fe0ab3 100644 --- a/secret_store/src/key_server_cluster/jobs/decryption_job.rs +++ b/secret_store/src/key_server_cluster/jobs/decryption_job.rs @@ -17,8 +17,8 @@ use std::collections::{BTreeSet, BTreeMap}; use ethereum_types::H256; use ethkey::{Public, Secret}; -use crypto::ecies::encrypt; use crypto::DEFAULT_MAC; +use ethkey::crypto::ecies::encrypt; use key_server_cluster::{Error, NodeId, DocumentKeyShare, EncryptedDocumentKeyShadow}; use key_server_cluster::math; use key_server_cluster::jobs::job_session::{JobPartialRequestAction, JobPartialResponseAction, JobExecutor}; diff --git a/secret_store/src/node_key_pair.rs b/secret_store/src/node_key_pair.rs index 55c2a8a28a..428dba6c1a 100644 --- a/secret_store/src/node_key_pair.rs +++ b/secret_store/src/node_key_pair.rs @@ -15,7 +15,7 @@ // along with Parity. If not, see . use std::sync::Arc; -use crypto::ecdh::agree; +use ethkey::crypto::ecdh::agree; use ethkey::{KeyPair, Public, Signature, Error as EthKeyError, sign, public_to_address}; use ethcore::account_provider::AccountProvider; use ethereum_types::{H256, Address}; @@ -54,7 +54,8 @@ impl NodeKeyPair for PlainNodeKeyPair { } fn compute_shared_key(&self, peer_public: &Public) -> Result { - agree(self.key_pair.secret(), peer_public).map_err(|e| EthKeyError::Custom(e.into())) + agree(self.key_pair.secret(), peer_public) + .map_err(|e| EthKeyError::Custom(e.to_string())) .and_then(KeyPair::from_secret) } } diff --git a/secret_store/src/types/error.rs b/secret_store/src/types/error.rs index 6469585fac..1fceb120e8 100644 --- a/secret_store/src/types/error.rs +++ b/secret_store/src/types/error.rs @@ -168,6 +168,12 @@ impl From for Error { } } +impl From for Error { + fn from(err: ethkey::crypto::Error) -> Self { + Error::EthKey(err.to_string()) + } +} + impl From for Error { fn from(err: kvdb::Error) -> Self { Error::Database(err.to_string()) @@ -176,7 +182,7 @@ impl From for Error { impl From for Error { fn from(err: crypto::Error) -> Self { - Error::EthKey(err.into()) + Error::EthKey(err.to_string()) } } diff --git a/util/network-devp2p/src/connection.rs b/util/network-devp2p/src/connection.rs index 2b390baf75..5dbf71fa01 100644 --- a/util/network-devp2p/src/connection.rs +++ b/util/network-devp2p/src/connection.rs @@ -34,7 +34,7 @@ use rcrypto::symmetriccipher::*; use rcrypto::buffer::*; use tiny_keccak::Keccak; use bytes::{Buf, BufMut}; -use crypto; +use ethkey::crypto; use network::{Error, ErrorKind}; const ENCRYPTED_HEADER_LEN: usize = 32; diff --git a/util/network-devp2p/src/handshake.rs b/util/network-devp2p/src/handshake.rs index 37c39eb618..a203af5b4b 100644 --- a/util/network-devp2p/src/handshake.rs +++ b/util/network-devp2p/src/handshake.rs @@ -25,7 +25,7 @@ use connection::{Connection}; use node_table::NodeId; use io::{IoContext, StreamToken}; use ethkey::{KeyPair, Public, Secret, recover, sign, Generator, Random}; -use crypto::{ecdh, ecies}; +use ethkey::crypto::{ecdh, ecies}; use network::{Error, ErrorKind, HostInfo}; #[derive(PartialEq, Eq, Debug)] diff --git a/util/network/src/error.rs b/util/network/src/error.rs index 48bcf75965..6342bfe4ad 100644 --- a/util/network/src/error.rs +++ b/util/network/src/error.rs @@ -151,8 +151,14 @@ impl From for Error { } } -impl From for Error { - fn from(_err: crypto::Error) -> Self { +impl From for Error { + fn from(_err: ethkey::crypto::Error) -> Self { + ErrorKind::Auth.into() + } +} + +impl From for Error { + fn from(_err: crypto::error::SymmError) -> Self { ErrorKind::Auth.into() } } @@ -168,11 +174,11 @@ fn test_errors() { match *>::from(rlp::DecoderError::RlpIsTooBig).kind() { ErrorKind::Auth => {}, - _ => panic!("Unexpeceted error"), + _ => panic!("Unexpected error"), } - match *>::from(crypto::Error::InvalidMessage).kind() { + match *>::from(ethkey::crypto::Error::InvalidMessage).kind() { ErrorKind::Auth => {}, - _ => panic!("Unexpeceted error"), + _ => panic!("Unexpected error"), } } diff --git a/whisper/Cargo.toml b/whisper/Cargo.toml index bd1fc2dbb0..ed370e38a2 100644 --- a/whisper/Cargo.toml +++ b/whisper/Cargo.toml @@ -17,7 +17,6 @@ mem = { path = "../util/mem" } ordered-float = "0.5" parking_lot = "0.5" rand = "0.4" -ring = "0.12" rlp = { path = "../util/rlp" } serde = "1.0" serde_derive = "1.0" diff --git a/whisper/src/lib.rs b/whisper/src/lib.rs index 4aa1a99b9e..85ab55e0f4 100644 --- a/whisper/src/lib.rs +++ b/whisper/src/lib.rs @@ -28,7 +28,6 @@ extern crate ordered_float; extern crate parking_lot; extern crate rand; extern crate rlp; -extern crate ring; extern crate serde; extern crate slab; extern crate smallvec; diff --git a/whisper/src/rpc/crypto.rs b/whisper/src/rpc/crypto.rs index 8780045b47..667656d6bf 100644 --- a/whisper/src/rpc/crypto.rs +++ b/whisper/src/rpc/crypto.rs @@ -16,11 +16,11 @@ //! Encryption schemes supported by RPC layer. -use crypto; +use crypto::aes_gcm::{Encryptor, Decryptor}; +use ethkey::crypto::ecies; use ethereum_types::H256; use ethkey::{self, Public, Secret}; use mem::Memzero; -use ring::aead::{self, AES_256_GCM, SealingKey, OpeningKey}; /// Length of AES key pub const AES_KEY_LEN: usize = 32; @@ -72,38 +72,15 @@ impl EncryptionInstance { } /// Encrypt the supplied plaintext - pub fn encrypt(self, plain: &[u8]) -> Vec { + pub fn encrypt(self, plain: &[u8]) -> Option> { match self.0 { EncryptionInner::AES(key, nonce, encode) => { - let sealing_key = SealingKey::new(&AES_256_GCM, &*key) - .expect("key is of correct len; qed"); - - let encrypt_plain = move |buf: &mut Vec| { - let out_suffix_capacity = AES_256_GCM.tag_len(); - - let prepend_len = buf.len(); - buf.extend(plain); - - buf.resize(prepend_len + plain.len() + out_suffix_capacity, 0); - - let out_size = aead::seal_in_place( - &sealing_key, - &nonce, - &[], // no authenticated data. - &mut buf[prepend_len..], - out_suffix_capacity, - ).expect("key, nonce, buf are valid and out suffix large enough; qed"); - - // truncate to the output size and return. - buf.truncate(prepend_len + out_size); - }; - match encode { AesEncode::AppendedNonce => { - let mut buf = Vec::new(); - encrypt_plain(&mut buf); + let mut enc = Encryptor::aes_256_gcm(&*key).ok()?; + let mut buf = enc.encrypt(&nonce, plain.to_vec()).ok()?; buf.extend(&nonce[..]); - buf + Some(buf) } AesEncode::OnTopics(topics) => { let mut buf = Vec::new(); @@ -111,14 +88,16 @@ impl EncryptionInstance { xor(&mut t.0, &key); buf.extend(&t.0); } - encrypt_plain(&mut buf); - buf + let mut enc = Encryptor::aes_256_gcm(&*key).ok()?; + enc.offset(buf.len()); + buf.extend(plain); + let ciphertext = enc.encrypt(&nonce, buf).ok()?; + Some(ciphertext) } } } EncryptionInner::ECIES(valid_public) => { - crypto::ecies::encrypt(&valid_public, &[], plain) - .expect("validity of public key an invariant of the type; qed") + ecies::encrypt(&valid_public, &[], plain).ok() } } } @@ -169,58 +148,36 @@ impl DecryptionInstance { pub fn decrypt(self, ciphertext: &[u8]) -> Option> { match self.0 { DecryptionInner::AES(extract) => { - let decrypt = | - key: Memzero<[u8; AES_KEY_LEN]>, - nonce: [u8; AES_NONCE_LEN], - ciphertext: &[u8] - | { - if ciphertext.len() < AES_256_GCM.tag_len() { return None } - - let opening_key = OpeningKey::new(&AES_256_GCM, &*key) - .expect("key length is valid for mode; qed"); - - let mut buf = ciphertext.to_vec(); - - // decrypted plaintext always ends up at the - // front of the buffer. - let maybe_decrypted = aead::open_in_place( - &opening_key, - &nonce, - &[], // no authenticated data - 0, // no header. - &mut buf, - ).ok().map(|plain_slice| plain_slice.len()); - - maybe_decrypted.map(move |len| { buf.truncate(len); buf }) - }; - match extract { AesExtract::AppendedNonce(key) => { - if ciphertext.len() < AES_NONCE_LEN { return None } - + if ciphertext.len() < AES_NONCE_LEN { + return None + } // nonce is the suffix of ciphertext. let mut nonce = [0; AES_NONCE_LEN]; let nonce_offset = ciphertext.len() - AES_NONCE_LEN; - nonce.copy_from_slice(&ciphertext[nonce_offset..]); - decrypt(key, nonce, &ciphertext[..nonce_offset]) + Decryptor::aes_256_gcm(&*key).ok()? + .decrypt(&nonce, Vec::from(&ciphertext[..nonce_offset])) + .ok() } AesExtract::OnTopics(num_topics, known_index, known_topic) => { - if ciphertext.len() < num_topics * 32 { return None } - + if ciphertext.len() < num_topics * 32 { + return None + } let mut salted_topic = H256::new(); salted_topic.copy_from_slice(&ciphertext[(known_index * 32)..][..32]); - let key = Memzero::from((salted_topic ^ known_topic).0); - let offset = num_topics * 32; - decrypt(key, BROADCAST_IV, &ciphertext[offset..]) + Decryptor::aes_256_gcm(&*key).ok()? + .decrypt(&BROADCAST_IV, Vec::from(&ciphertext[offset..])) + .ok() } } } DecryptionInner::ECIES(secret) => { // secret is checked for validity, so only fails on invalid message. - crypto::ecies::decrypt(&secret, &[], ciphertext).ok() + ecies::decrypt(&secret, &[], ciphertext).ok() } } } @@ -230,16 +187,6 @@ impl DecryptionInstance { mod tests { use super::*; - #[test] - fn aes_key_len_should_be_equal_to_constant() { - assert_eq!(::ring::aead::AES_256_GCM.key_len(), AES_KEY_LEN); - } - - #[test] - fn aes_nonce_len_should_be_equal_to_constant() { - assert_eq!(::ring::aead::AES_256_GCM.nonce_len(), AES_NONCE_LEN); - } - #[test] fn encrypt_asymmetric() { use ethkey::{Generator, Random}; @@ -247,7 +194,7 @@ mod tests { let key_pair = Random.generate().unwrap(); let test_message = move |message: &[u8]| { let instance = EncryptionInstance::ecies(key_pair.public().clone()).unwrap(); - let ciphertext = instance.encrypt(&message); + let ciphertext = instance.encrypt(&message).unwrap(); if !message.is_empty() { assert!(&ciphertext[..message.len()] != message) @@ -273,7 +220,7 @@ mod tests { let key = Memzero::from(rng.gen::<[u8; 32]>()); let instance = EncryptionInstance::aes(key.clone(), rng.gen()); - let ciphertext = instance.encrypt(message); + let ciphertext = instance.encrypt(message).unwrap(); if !message.is_empty() { assert!(&ciphertext[..message.len()] != message) @@ -303,7 +250,7 @@ mod tests { let key = Memzero::from(rng.gen::<[u8; 32]>()); let instance = EncryptionInstance::broadcast(key, all_topics); - let ciphertext = instance.encrypt(message); + let ciphertext = instance.encrypt(message).unwrap(); if !message.is_empty() { assert!(&ciphertext[..message.len()] != message) diff --git a/whisper/src/rpc/filter.rs b/whisper/src/rpc/filter.rs index 5a192ac04c..8d125174ed 100644 --- a/whisper/src/rpc/filter.rs +++ b/whisper/src/rpc/filter.rs @@ -402,7 +402,7 @@ mod tests { sign_with: Some(signing_pair.secret().unwrap()) }).unwrap(); - let encrypted = encryption_instance.encrypt(&payload); + let encrypted = encryption_instance.encrypt(&payload).unwrap(); let message = Message::create(CreateParams { ttl: 100, diff --git a/whisper/src/rpc/key_store.rs b/whisper/src/rpc/key_store.rs index 02781e20ad..1fb4e264ac 100644 --- a/whisper/src/rpc/key_store.rs +++ b/whisper/src/rpc/key_store.rs @@ -25,7 +25,6 @@ use ethereum_types::H256; use ethkey::{KeyPair, Public, Secret}; use mem::Memzero; use rand::{Rng, OsRng}; -use ring::error::Unspecified; use rpc::crypto::{AES_KEY_LEN, EncryptionInstance, DecryptionInstance}; @@ -54,10 +53,8 @@ impl Key { } /// From secret asymmetric key. Fails if secret is invalid. - pub fn from_secret(secret: Secret) -> Result { - KeyPair::from_secret(secret) - .map(Key::Asymmetric) - .map_err(|_| Unspecified) + pub fn from_secret(secret: Secret) -> Option { + KeyPair::from_secret(secret).map(Key::Asymmetric).ok() } /// From raw symmetric key. @@ -179,7 +176,7 @@ mod tests { #[test] fn rejects_invalid_secret() { let bad_secret = ::ethkey::Secret::from([0xff; 32]); - assert!(Key::from_secret(bad_secret).is_err()); + assert!(Key::from_secret(bad_secret).is_none()); } #[test] diff --git a/whisper/src/rpc/mod.rs b/whisper/src/rpc/mod.rs index e9e6577085..7daa3f4559 100644 --- a/whisper/src/rpc/mod.rs +++ b/whisper/src/rpc/mod.rs @@ -226,7 +226,7 @@ impl Whisper for WhisperClien fn add_private_key(&self, private: types::Private) -> Result { let key_pair = Key::from_secret(private.into_inner().into()) - .map_err(|_| whisper_error("Invalid private key"))?; + .ok_or_else(|| whisper_error("Invalid private key"))?; Ok(HexEncode(self.store.write().insert(key_pair))) } @@ -317,7 +317,7 @@ impl Whisper for WhisperClien sign_with: sign_with.as_ref(), }).map_err(whisper_error)?; - encryption.encrypt(&payload) + encryption.encrypt(&payload).ok_or(whisper_error("encryption error"))? }; // mining the packet is the heaviest item of work by far. -- GitLab From 32c32ecfdac7787ab8d4271b5245661bf253d471 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Silva?= Date: Mon, 7 May 2018 11:57:03 +0100 Subject: [PATCH 009/152] ethcore, rpc, machine: refactor block reward application and tracing (#8490) --- ethcore/src/engines/authority_round/mod.rs | 9 ++++-- ethcore/src/engines/block_reward.rs | 34 +++++++++++++++++----- ethcore/src/engines/mod.rs | 2 +- ethcore/src/engines/null_engine.rs | 20 +++++-------- ethcore/src/engines/tendermint/mod.rs | 10 +++++-- ethcore/src/ethereum/ethash.rs | 25 ++++++++-------- ethcore/src/machine.rs | 24 ++++++++++----- ethcore/src/trace/types/trace.rs | 8 +++++ machine/src/lib.rs | 8 ----- rpc/src/v1/types/trace.rs | 8 +++++ 10 files changed, 93 insertions(+), 55 deletions(-) diff --git a/ethcore/src/engines/authority_round/mod.rs b/ethcore/src/engines/authority_round/mod.rs index 4807d6c3fb..c2aee7c6ef 100644 --- a/ethcore/src/engines/authority_round/mod.rs +++ b/ethcore/src/engines/authority_round/mod.rs @@ -1015,8 +1015,10 @@ impl Engine for AuthorityRound { let author = *block.header().author(); benefactors.push((author, RewardKind::Author)); - let rewards = match self.block_reward_contract { + let rewards: Vec<_> = match self.block_reward_contract { Some(ref c) if block.header().number() >= self.block_reward_contract_transition => { + // NOTE: this logic should be moved to a function when another + // engine needs support for block reward contract. let mut call = |to, data| { let result = self.machine.execute_as_system( block, @@ -1027,10 +1029,11 @@ impl Engine for AuthorityRound { result.map_err(|e| format!("{}", e)) }; - c.reward(&benefactors, &mut call)? + let rewards = c.reward(&benefactors, &mut call)?; + rewards.into_iter().map(|(author, amount)| (author, RewardKind::External, amount)).collect() }, _ => { - benefactors.into_iter().map(|(author, _)| (author, self.block_reward)).collect() + benefactors.into_iter().map(|(author, reward_kind)| (author, reward_kind, self.block_reward)).collect() }, }; diff --git a/ethcore/src/engines/block_reward.rs b/ethcore/src/engines/block_reward.rs index 510a5255f5..9a9d54e4af 100644 --- a/ethcore/src/engines/block_reward.rs +++ b/ethcore/src/engines/block_reward.rs @@ -14,13 +14,17 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . +//! A module with types for declaring block rewards and a client interface for interacting with a +//! block reward contract. + use ethabi; use ethabi::ParamType; use ethereum_types::{H160, Address, U256}; -use block::ExecutedBlock; use error::Error; -use machine::EthereumMachine; +use machine::WithRewards; +use parity_machine::{Machine, WithBalances}; +use trace; use super::SystemCall; use_contract!(block_reward_contract, "BlockReward", "res/contracts/block_reward.json"); @@ -37,6 +41,8 @@ pub enum RewardKind { Uncle = 1, /// Reward attributed to the author(s) of empty step(s) included in the block (AuthorityRound engine). EmptyStep = 2, + /// Reward attributed by an external protocol (e.g. block reward contract). + External = 3, } impl From for u16 { @@ -45,6 +51,17 @@ impl From for u16 { } } +impl Into for RewardKind { + fn into(self) -> trace::RewardType { + match self { + RewardKind::Author => trace::RewardType::Block, + RewardKind::Uncle => trace::RewardType::Uncle, + RewardKind::EmptyStep => trace::RewardType::EmptyStep, + RewardKind::External => trace::RewardType::External, + } + } +} + /// A client for the block reward contract. pub struct BlockRewardContract { /// Address of the contract. @@ -112,14 +129,17 @@ impl BlockRewardContract { /// Applies the given block rewards, i.e. adds the given balance to each benefactors' address. /// If tracing is enabled the operations are recorded. -pub fn apply_block_rewards(rewards: &[(Address, U256)], block: &mut ExecutedBlock, machine: &EthereumMachine) -> Result<(), Error> { - use parity_machine::WithBalances; - - for &(ref author, ref block_reward) in rewards { +pub fn apply_block_rewards( + rewards: &[(Address, RewardKind, U256)], + block: &mut M::LiveBlock, + machine: &M, +) -> Result<(), M::Error> { + for &(ref author, _, ref block_reward) in rewards { machine.add_balance(block, author, block_reward)?; } - machine.note_rewards(block, &rewards, &[]) + let rewards: Vec<_> = rewards.into_iter().map(|&(a, k, r)| (a, k.into(), r)).collect(); + machine.note_rewards(block, &rewards) } #[cfg(test)] diff --git a/ethcore/src/engines/mod.rs b/ethcore/src/engines/mod.rs index a17ae356e6..e019636f53 100644 --- a/ethcore/src/engines/mod.rs +++ b/ethcore/src/engines/mod.rs @@ -18,7 +18,6 @@ mod authority_round; mod basic_authority; -mod block_reward; mod instant_seal; mod null_engine; mod signer; @@ -27,6 +26,7 @@ mod transition; mod validator_set; mod vote_collector; +pub mod block_reward; pub mod epoch; pub use self::authority_round::AuthorityRound; diff --git a/ethcore/src/engines/null_engine.rs b/ethcore/src/engines/null_engine.rs index f20a9cdfd9..278eb037c0 100644 --- a/ethcore/src/engines/null_engine.rs +++ b/ethcore/src/engines/null_engine.rs @@ -16,7 +16,9 @@ use ethereum_types::U256; use engines::Engine; +use engines::block_reward::{self, RewardKind}; use header::BlockNumber; +use machine::WithRewards; use parity_machine::{Header, LiveBlock, WithBalances}; /// Params for a null engine. @@ -56,7 +58,7 @@ impl Default for NullEngine { } } -impl Engine for NullEngine { +impl Engine for NullEngine { fn name(&self) -> &str { "NullEngine" } @@ -74,26 +76,20 @@ impl Engine for NullEngine { let n_uncles = LiveBlock::uncles(&*block).len(); + let mut rewards = Vec::new(); + // Bestow block reward let result_block_reward = reward + reward.shr(5) * U256::from(n_uncles); - let mut uncle_rewards = Vec::with_capacity(n_uncles); - - self.machine.add_balance(block, &author, &result_block_reward)?; + rewards.push((author, RewardKind::Author, result_block_reward)); // bestow uncle rewards. for u in LiveBlock::uncles(&*block) { let uncle_author = u.author(); let result_uncle_reward = (reward * U256::from(8 + u.number() - number)).shr(3); - - uncle_rewards.push((*uncle_author, result_uncle_reward)); - } - - for &(ref a, ref reward) in &uncle_rewards { - self.machine.add_balance(block, a, reward)?; + rewards.push((*uncle_author, RewardKind::Uncle, result_uncle_reward)); } - // note and trace. - self.machine.note_rewards(block, &[(author, result_block_reward)], &uncle_rewards) + block_reward::apply_block_rewards(&rewards, block, &self.machine) } fn maximum_uncle_count(&self, _block: BlockNumber) -> usize { 2 } diff --git a/ethcore/src/engines/tendermint/mod.rs b/ethcore/src/engines/tendermint/mod.rs index 289beaad0c..d80a5e182f 100644 --- a/ethcore/src/engines/tendermint/mod.rs +++ b/ethcore/src/engines/tendermint/mod.rs @@ -41,6 +41,7 @@ use ethkey::{self, Message, Signature}; use account_provider::AccountProvider; use block::*; use engines::{Engine, Seal, EngineError, ConstructedVerifier}; +use engines::block_reward::{self, RewardKind}; use io::IoService; use super::signer::EngineSigner; use super::validator_set::{ValidatorSet, SimpleList}; @@ -550,10 +551,13 @@ impl Engine for Tendermint { /// Apply the block reward on finalisation of the block. fn on_close_block(&self, block: &mut ExecutedBlock) -> Result<(), Error>{ - use parity_machine::WithBalances; let author = *block.header().author(); - self.machine.add_balance(block, &author, &self.block_reward)?; - self.machine.note_rewards(block, &[(author, self.block_reward)], &[]) + + block_reward::apply_block_rewards( + &[(author, RewardKind::Author, self.block_reward)], + block, + &self.machine, + ) } fn verify_local_seal(&self, _header: &Header) -> Result<(), Error> { diff --git a/ethcore/src/ethereum/ethash.rs b/ethcore/src/ethereum/ethash.rs index 09e9caf727..09151415c8 100644 --- a/ethcore/src/ethereum/ethash.rs +++ b/ethcore/src/ethereum/ethash.rs @@ -19,6 +19,7 @@ use std::cmp; use std::collections::BTreeMap; use std::sync::Arc; use hash::{KECCAK_EMPTY_LIST_RLP}; +use engines::block_reward::{self, RewardKind}; use ethash::{quick_get_difficulty, slow_hash_block_number, EthashManager, OptimizeFor}; use ethereum_types::{H256, H64, U256, Address}; use unexpected::{OutOfBounds, Mismatch}; @@ -233,11 +234,13 @@ impl Engine for Arc { /// 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> { use std::ops::Shr; - use parity_machine::{LiveBlock, WithBalances}; + use parity_machine::LiveBlock; let author = *LiveBlock::header(&*block).author(); let number = LiveBlock::header(&*block).number(); + let mut rewards = Vec::new(); + // Applies EIP-649 reward. let reward = if number >= self.ethash_params.eip649_transition { self.ethash_params.eip649_reward.unwrap_or(self.ethash_params.block_reward) @@ -253,20 +256,21 @@ impl Engine for Arc { // Bestow block rewards. let mut result_block_reward = reward + reward.shr(5) * U256::from(n_uncles); - let mut uncle_rewards = Vec::with_capacity(n_uncles); if number >= self.ethash_params.mcip3_transition { result_block_reward = self.ethash_params.mcip3_miner_reward; + let ubi_contract = self.ethash_params.mcip3_ubi_contract; let ubi_reward = self.ethash_params.mcip3_ubi_reward; let dev_contract = self.ethash_params.mcip3_dev_contract; let dev_reward = self.ethash_params.mcip3_dev_reward; - self.machine.add_balance(block, &author, &result_block_reward)?; - self.machine.add_balance(block, &ubi_contract, &ubi_reward)?; - self.machine.add_balance(block, &dev_contract, &dev_reward)?; + rewards.push((author, RewardKind::Author, result_block_reward)); + rewards.push((ubi_contract, RewardKind::External, ubi_reward)); + rewards.push((dev_contract, RewardKind::External, dev_reward)); + } else { - self.machine.add_balance(block, &author, &result_block_reward)?; + rewards.push((author, RewardKind::Author, result_block_reward)); } // Bestow uncle rewards. @@ -278,15 +282,10 @@ impl Engine for Arc { reward.shr(5) }; - uncle_rewards.push((*uncle_author, result_uncle_reward)); - } - - for &(ref a, ref reward) in &uncle_rewards { - self.machine.add_balance(block, a, reward)?; + rewards.push((*uncle_author, RewardKind::Uncle, result_uncle_reward)); } - // Note and trace. - self.machine.note_rewards(block, &[(author, result_block_reward)], &uncle_rewards) + block_reward::apply_block_rewards(&rewards, block, &self.machine) } fn verify_local_seal(&self, header: &Header) -> Result<(), Error> { diff --git a/ethcore/src/machine.rs b/ethcore/src/machine.rs index e3bf7d340c..4aa72b50d9 100644 --- a/ethcore/src/machine.rs +++ b/ethcore/src/machine.rs @@ -437,22 +437,30 @@ impl ::parity_machine::WithBalances for EthereumMachine { fn add_balance(&self, live: &mut ExecutedBlock, address: &Address, amount: &U256) -> Result<(), Error> { live.state_mut().add_balance(address, amount, CleanupMode::NoEmpty).map_err(Into::into) } +} + +/// A state machine that uses block rewards. +pub trait WithRewards: ::parity_machine::Machine { + /// Note block rewards, traces each reward storing information about benefactor, amount and type + /// of reward. + fn note_rewards( + &self, + live: &mut Self::LiveBlock, + rewards: &[(Address, RewardType, U256)], + ) -> Result<(), Self::Error>; +} +impl WithRewards for EthereumMachine { fn note_rewards( &self, live: &mut Self::LiveBlock, - direct: &[(Address, U256)], - indirect: &[(Address, U256)], + rewards: &[(Address, RewardType, U256)], ) -> Result<(), Self::Error> { if let Tracing::Enabled(ref mut traces) = *live.traces_mut() { let mut tracer = ExecutiveTracer::default(); - for &(address, amount) in direct { - tracer.trace_reward(address, amount, RewardType::Block); - } - - for &(address, amount) in indirect { - tracer.trace_reward(address, amount, RewardType::Uncle); + for &(address, ref reward_type, amount) in rewards { + tracer.trace_reward(address, amount, reward_type.clone()); } traces.push(tracer.drain().into()); diff --git a/ethcore/src/trace/types/trace.rs b/ethcore/src/trace/types/trace.rs index 06f24efac3..cdb00a5229 100644 --- a/ethcore/src/trace/types/trace.rs +++ b/ethcore/src/trace/types/trace.rs @@ -141,6 +141,10 @@ pub enum RewardType { Block, /// Uncle Uncle, + /// Empty step (AuthorityRound) + EmptyStep, + /// A reward directly attributed by an external protocol (e.g. block reward contract) + External, } impl Encodable for RewardType { @@ -148,6 +152,8 @@ impl Encodable for RewardType { let v = match *self { RewardType::Block => 0u32, RewardType::Uncle => 1, + RewardType::EmptyStep => 2, + RewardType::External => 3, }; Encodable::rlp_append(&v, s); } @@ -158,6 +164,8 @@ impl Decodable for RewardType { rlp.as_val().and_then(|v| Ok(match v { 0u32 => RewardType::Block, 1 => RewardType::Uncle, + 2 => RewardType::EmptyStep, + 3 => RewardType::External, _ => return Err(DecoderError::Custom("Invalid value of RewardType item")), })) } diff --git a/machine/src/lib.rs b/machine/src/lib.rs index 3a45c38d2e..54ee403d95 100644 --- a/machine/src/lib.rs +++ b/machine/src/lib.rs @@ -106,12 +106,4 @@ pub trait WithBalances: Machine { /// Increment the balance of an account in the state of the live block. fn add_balance(&self, live: &mut Self::LiveBlock, address: &Address, amount: &U256) -> Result<(), Self::Error>; - - /// Note block rewards. "direct" rewards are for authors, "indirect" are for e.g. uncles. - fn note_rewards( - &self, - _live: &mut Self::LiveBlock, - _direct: &[(Address, U256)], - _indirect: &[(Address, U256)], - ) -> Result<(), Self::Error> { Ok(()) } } diff --git a/rpc/src/v1/types/trace.rs b/rpc/src/v1/types/trace.rs index a984c64ba8..6eb222f5e6 100644 --- a/rpc/src/v1/types/trace.rs +++ b/rpc/src/v1/types/trace.rs @@ -308,6 +308,12 @@ pub enum RewardType { /// Uncle #[serde(rename="uncle")] Uncle, + /// EmptyStep (AuthorityRound) + #[serde(rename="emptyStep")] + EmptyStep, + /// External (attributed as part of an external protocol) + #[serde(rename="external")] + External, } impl From for RewardType { @@ -315,6 +321,8 @@ impl From for RewardType { match c { trace::RewardType::Block => RewardType::Block, trace::RewardType::Uncle => RewardType::Uncle, + trace::RewardType::EmptyStep => RewardType::EmptyStep, + trace::RewardType::External => RewardType::External, } } } -- GitLab From 528497b86a93c64f317dd869da47010c2675e4ed Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Mon, 7 May 2018 18:58:25 +0800 Subject: [PATCH 010/152] Keep all enacted blocks notify in order (#8524) * Keep all enacted blocks notify in order * Collect is unnecessary * Update ChainNotify to use ChainRouteType * Fix all ethcore fn defs * Wrap the type within ChainRoute * Fix private-tx and sync api * Fix secret_store API * Fix updater API * Fix rpc api * Fix informant api * Eagerly cache enacted/retracted and remove contain_enacted/retracted * Fix indent * tests: should use full expr form for struct constructor * Use into_enacted_retracted to further avoid copy * typo: not a function * rpc/tests: ChainRoute -> ChainRoute::new --- ethcore/private-tx/src/lib.rs | 4 +- ethcore/src/blockchain/import_route.rs | 2 +- ethcore/src/client/chain_notify.rs | 88 ++++++++++++++++++- ethcore/src/client/client.rs | 49 +++-------- ethcore/src/client/mod.rs | 2 +- ethcore/src/snapshot/watcher.rs | 10 +-- ethcore/sync/src/api.rs | 9 +- ethcore/sync/src/tests/helpers.rs | 7 +- parity/informant.rs | 4 +- rpc/src/v1/impls/eth_pubsub.rs | 49 ++++++----- rpc/src/v1/tests/mocked/eth_pubsub.rs | 10 +-- secret_store/src/acl_storage.rs | 6 +- secret_store/src/key_server_set.rs | 6 +- .../src/listener/service_contract_listener.rs | 6 +- updater/src/updater.rs | 4 +- 15 files changed, 158 insertions(+), 98 deletions(-) diff --git a/ethcore/private-tx/src/lib.rs b/ethcore/private-tx/src/lib.rs index 26a31fc7ae..723d491829 100644 --- a/ethcore/private-tx/src/lib.rs +++ b/ethcore/private-tx/src/lib.rs @@ -79,7 +79,7 @@ use ethcore::executed::{Executed}; use transaction::{SignedTransaction, Transaction, Action, UnverifiedTransaction}; use ethcore::{contract_address as ethcore_contract_address}; use ethcore::client::{ - Client, ChainNotify, ChainMessageType, ClientIoMessage, BlockId, CallContract + Client, ChainNotify, ChainRoute, ChainMessageType, ClientIoMessage, BlockId, CallContract }; use ethcore::account_provider::AccountProvider; use ethcore::miner::{self, Miner, MinerService}; @@ -668,7 +668,7 @@ fn find_account_password(passwords: &Vec, account_provider: &AccountProv } impl ChainNotify for Provider { - fn new_blocks(&self, imported: Vec, _invalid: Vec, _enacted: Vec, _retracted: Vec, _sealed: Vec, _proposed: Vec, _duration: Duration) { + fn new_blocks(&self, imported: Vec, _invalid: Vec, _route: ChainRoute, _sealed: Vec, _proposed: Vec, _duration: Duration) { if !imported.is_empty() { trace!("New blocks imported, try to prune the queue"); if let Err(err) = self.process_queue() { diff --git a/ethcore/src/blockchain/import_route.rs b/ethcore/src/blockchain/import_route.rs index cf5d3ca1e7..080d3b0682 100644 --- a/ethcore/src/blockchain/import_route.rs +++ b/ethcore/src/blockchain/import_route.rs @@ -20,7 +20,7 @@ use ethereum_types::H256; use blockchain::block_info::{BlockInfo, BlockLocation}; /// Import route for newly inserted block. -#[derive(Debug, PartialEq)] +#[derive(Debug, PartialEq, Clone)] pub struct ImportRoute { /// Blocks that were invalidated by new block. pub retracted: Vec, diff --git a/ethcore/src/client/chain_notify.rs b/ethcore/src/client/chain_notify.rs index a1f84d2a13..8330fb40d9 100644 --- a/ethcore/src/client/chain_notify.rs +++ b/ethcore/src/client/chain_notify.rs @@ -17,7 +17,9 @@ use bytes::Bytes; use ethereum_types::H256; use transaction::UnverifiedTransaction; +use blockchain::ImportRoute; use std::time::Duration; +use std::collections::HashMap; /// Messages to broadcast via chain pub enum ChainMessageType { @@ -29,6 +31,89 @@ pub enum ChainMessageType { SignedPrivateTransaction(Vec), } +/// Route type to indicate whether it is enacted or retracted. +#[derive(Clone)] +pub enum ChainRouteType { + /// Enacted block + Enacted, + /// Retracted block + Retracted +} + +/// A complete chain enacted retracted route. +#[derive(Default, Clone)] +pub struct ChainRoute { + route: Vec<(H256, ChainRouteType)>, + enacted: Vec, + retracted: Vec, +} + +impl<'a> From<&'a [ImportRoute]> for ChainRoute { + fn from(import_results: &'a [ImportRoute]) -> ChainRoute { + ChainRoute::new(import_results.iter().flat_map(|route| { + route.retracted.iter().map(|h| (*h, ChainRouteType::Retracted)) + .chain(route.enacted.iter().map(|h| (*h, ChainRouteType::Enacted))) + }).collect()) + } +} + +impl ChainRoute { + /// Create a new ChainRoute based on block hash and route type pairs. + pub fn new(route: Vec<(H256, ChainRouteType)>) -> Self { + let (enacted, retracted) = Self::to_enacted_retracted(&route); + + Self { route, enacted, retracted } + } + + /// Gather all non-duplicate enacted and retracted blocks. + fn to_enacted_retracted(route: &[(H256, ChainRouteType)]) -> (Vec, Vec) { + fn map_to_vec(map: Vec<(H256, bool)>) -> Vec { + map.into_iter().map(|(k, _v)| k).collect() + } + + // Because we are doing multiple inserts some of the blocks that were enacted in import `k` + // could be retracted in import `k+1`. This is why to understand if after all inserts + // the block is enacted or retracted we iterate over all routes and at the end final state + // will be in the hashmap + let map = route.iter().fold(HashMap::new(), |mut map, route| { + match &route.1 { + &ChainRouteType::Enacted => { + map.insert(route.0, true); + }, + &ChainRouteType::Retracted => { + map.insert(route.0, false); + }, + } + map + }); + + // Split to enacted retracted (using hashmap value) + let (enacted, retracted) = map.into_iter().partition(|&(_k, v)| v); + // And convert tuples to keys + (map_to_vec(enacted), map_to_vec(retracted)) + } + + /// Consume route and return the enacted retracted form. + pub fn into_enacted_retracted(self) -> (Vec, Vec) { + (self.enacted, self.retracted) + } + + /// All non-duplicate enacted blocks. + pub fn enacted(&self) -> &[H256] { + &self.enacted + } + + /// All non-duplicate retracted blocks. + pub fn retracted(&self) -> &[H256] { + &self.retracted + } + + /// All blocks in the route. + pub fn route(&self) -> &[(H256, ChainRouteType)] { + &self.route + } +} + /// Represents what has to be handled by actor listening to chain events pub trait ChainNotify : Send + Sync { /// fires when chain has new blocks. @@ -36,8 +121,7 @@ pub trait ChainNotify : Send + Sync { &self, _imported: Vec, _invalid: Vec, - _enacted: Vec, - _retracted: Vec, + _route: ChainRoute, _sealed: Vec, // Block bytes. _proposed: Vec, diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index a37d62a591..8119ebd35f 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -14,7 +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, BTreeMap, BTreeSet, VecDeque}; +use std::collections::{HashSet, BTreeMap, BTreeSet, VecDeque}; use std::str::FromStr; use std::sync::{Arc, Weak}; use std::sync::atomic::{AtomicUsize, AtomicBool, Ordering as AtomicOrdering}; @@ -45,7 +45,7 @@ use client::{ use client::{ BlockId, TransactionId, UncleId, TraceId, ClientConfig, BlockChainClient, TraceFilter, CallAnalytics, BlockImportError, Mode, - ChainNotify, PruningInfo, ProvingBlockChainClient, EngineInfo, ChainMessageType + ChainNotify, ChainRoute, PruningInfo, ProvingBlockChainClient, EngineInfo, ChainMessageType }; use encoded; use engines::{EthEngine, EpochTransition}; @@ -245,32 +245,6 @@ impl Importer { }) } - fn calculate_enacted_retracted(&self, import_results: &[ImportRoute]) -> (Vec, Vec) { - fn map_to_vec(map: Vec<(H256, bool)>) -> Vec { - map.into_iter().map(|(k, _v)| k).collect() - } - - // In ImportRoute we get all the blocks that have been enacted and retracted by single insert. - // Because we are doing multiple inserts some of the blocks that were enacted in import `k` - // could be retracted in import `k+1`. This is why to understand if after all inserts - // the block is enacted or retracted we iterate over all routes and at the end final state - // will be in the hashmap - let map = import_results.iter().fold(HashMap::new(), |mut map, route| { - for hash in &route.enacted { - map.insert(hash.clone(), true); - } - for hash in &route.retracted { - map.insert(hash.clone(), false); - } - map - }); - - // Split to enacted retracted (using hashmap value) - let (enacted, retracted) = map.into_iter().partition(|&(_k, v)| v); - // And convert tuples to keys - (map_to_vec(enacted), map_to_vec(retracted)) - } - /// This is triggered by a message coming from a block queue when the block is ready for insertion pub fn import_verified_blocks(&self, client: &Client) -> usize { @@ -336,18 +310,17 @@ impl Importer { { if !imported_blocks.is_empty() && is_empty { - let (enacted, retracted) = self.calculate_enacted_retracted(&import_results); + let route = ChainRoute::from(import_results.as_ref()); if is_empty { - self.miner.chain_new_blocks(client, &imported_blocks, &invalid_blocks, &enacted, &retracted, false); + self.miner.chain_new_blocks(client, &imported_blocks, &invalid_blocks, route.enacted(), route.retracted(), false); } client.notify(|notify| { notify.new_blocks( imported_blocks.clone(), invalid_blocks.clone(), - enacted.clone(), - retracted.clone(), + route.clone(), Vec::new(), proposed_blocks.clone(), duration, @@ -1421,7 +1394,7 @@ impl ImportBlock for Client { } fn import_block_with_receipts(&self, block_bytes: Bytes, receipts_bytes: Bytes) -> Result { - let header: Header = ::rlp::Rlp::new(&block_bytes).val_at(0)?; + let header: Header = ::rlp::Rlp::new(&block_bytes).val_at(0)?; { // check block order if self.chain.read().is_known(&header.hash()) { @@ -2155,14 +2128,13 @@ impl ImportSealedBlock for Client { self.state_db.write().sync_cache(&route.enacted, &route.retracted, false); route }; - let (enacted, retracted) = self.importer.calculate_enacted_retracted(&[route]); - self.importer.miner.chain_new_blocks(self, &[h.clone()], &[], &enacted, &retracted, true); + let route = ChainRoute::from([route].as_ref()); + self.importer.miner.chain_new_blocks(self, &[h.clone()], &[], route.enacted(), route.retracted(), true); self.notify(|notify| { notify.new_blocks( vec![h.clone()], vec![], - enacted.clone(), - retracted.clone(), + route.clone(), vec![h.clone()], vec![], start.elapsed(), @@ -2180,8 +2152,7 @@ impl BroadcastProposalBlock for Client { notify.new_blocks( vec![], vec![], - vec![], - vec![], + ChainRoute::default(), vec![], vec![block.rlp_bytes()], DURATION_ZERO, diff --git a/ethcore/src/client/mod.rs b/ethcore/src/client/mod.rs index 1e4ccba585..05e2018258 100644 --- a/ethcore/src/client/mod.rs +++ b/ethcore/src/client/mod.rs @@ -31,7 +31,7 @@ pub use self::error::Error; pub use self::evm_test_client::{EvmTestClient, EvmTestError, TransactResult}; pub use self::io_message::ClientIoMessage; pub use self::test_client::{TestBlockChainClient, EachBlockWith}; -pub use self::chain_notify::{ChainNotify, ChainMessageType}; +pub use self::chain_notify::{ChainNotify, ChainRoute, ChainRouteType, ChainMessageType}; pub use self::traits::{ Nonce, Balance, ChainInfo, BlockInfo, ReopenBlock, PrepareOpenBlock, CallContract, TransactionInfo, RegistryInfo, ScheduleInfo, ImportSealedBlock, BroadcastProposalBlock, ImportBlock, StateOrBlock, StateClient, Call, EngineInfo, AccountData, BlockChain, BlockProducer, SealedBlockImporter diff --git a/ethcore/src/snapshot/watcher.rs b/ethcore/src/snapshot/watcher.rs index 936feaefba..6e04fe6d16 100644 --- a/ethcore/src/snapshot/watcher.rs +++ b/ethcore/src/snapshot/watcher.rs @@ -17,7 +17,7 @@ //! Watcher for snapshot-related chain events. use parking_lot::Mutex; -use client::{BlockInfo, Client, ChainNotify, ClientIoMessage}; +use client::{BlockInfo, Client, ChainNotify, ChainRoute, ClientIoMessage}; use ids::BlockId; use io::IoChannel; @@ -103,8 +103,7 @@ impl ChainNotify for Watcher { &self, imported: Vec, _: Vec, - _: Vec, - _: Vec, + _: ChainRoute, _: Vec, _: Vec, _duration: Duration) @@ -131,7 +130,7 @@ impl ChainNotify for Watcher { mod tests { use super::{Broadcast, Oracle, Watcher}; - use client::ChainNotify; + use client::{ChainNotify, ChainRoute}; use ethereum_types::{H256, U256}; @@ -174,8 +173,7 @@ mod tests { watcher.new_blocks( hashes, vec![], - vec![], - vec![], + ChainRoute::default(), vec![], vec![], DURATION_ZERO, diff --git a/ethcore/sync/src/api.rs b/ethcore/sync/src/api.rs index 5e96f11cf3..7690eeb864 100644 --- a/ethcore/sync/src/api.rs +++ b/ethcore/sync/src/api.rs @@ -25,7 +25,7 @@ use network::{NetworkProtocolHandler, NetworkContext, HostInfo, PeerId, Protocol use ethereum_types::{H256, H512, U256}; use io::{TimerToken}; use ethcore::ethstore::ethkey::Secret; -use ethcore::client::{BlockChainClient, ChainNotify, ChainMessageType}; +use ethcore::client::{BlockChainClient, ChainNotify, ChainRoute, ChainMessageType}; use ethcore::snapshot::SnapshotService; use ethcore::header::BlockNumber; use sync_io::NetSyncIo; @@ -409,8 +409,7 @@ impl ChainNotify for EthSync { fn new_blocks(&self, imported: Vec, invalid: Vec, - enacted: Vec, - retracted: Vec, + route: ChainRoute, sealed: Vec, proposed: Vec, _duration: Duration) @@ -424,8 +423,8 @@ impl ChainNotify for EthSync { &mut sync_io, &imported, &invalid, - &enacted, - &retracted, + route.enacted(), + route.retracted(), &sealed, &proposed); }); diff --git a/ethcore/sync/src/tests/helpers.rs b/ethcore/sync/src/tests/helpers.rs index 54467adb77..dc52fdd8b8 100644 --- a/ethcore/sync/src/tests/helpers.rs +++ b/ethcore/sync/src/tests/helpers.rs @@ -23,7 +23,7 @@ use bytes::Bytes; use network::{self, PeerId, ProtocolId, PacketId, SessionInfo}; use tests::snapshot::*; use ethcore::client::{TestBlockChainClient, BlockChainClient, Client as EthcoreClient, - ClientConfig, ChainNotify, ChainMessageType, ClientIoMessage}; + ClientConfig, ChainNotify, ChainRoute, ChainMessageType, ClientIoMessage}; use ethcore::header::BlockNumber; use ethcore::snapshot::SnapshotService; use ethcore::spec::Spec; @@ -535,12 +535,13 @@ impl ChainNotify for EthPeer { fn new_blocks(&self, imported: Vec, invalid: Vec, - enacted: Vec, - retracted: Vec, + route: ChainRoute, sealed: Vec, proposed: Vec, _duration: Duration) { + let (enacted, retracted) = route.into_enacted_retracted(); + self.new_blocks_queue.write().push_back(NewBlockMessage { imported, invalid, diff --git a/parity/informant.rs b/parity/informant.rs index 5c2e0ab89d..beeb258b52 100644 --- a/parity/informant.rs +++ b/parity/informant.rs @@ -25,7 +25,7 @@ use std::time::{Instant, Duration}; use atty; use ethcore::client::{ BlockId, BlockChainClient, ChainInfo, BlockInfo, BlockChainInfo, - BlockQueueInfo, ChainNotify, ClientReport, Client, ClientIoMessage + BlockQueueInfo, ChainNotify, ChainRoute, ClientReport, Client, ClientIoMessage }; use ethcore::header::BlockNumber; use ethcore::snapshot::{RestorationStatus, SnapshotService as SS}; @@ -351,7 +351,7 @@ impl Informant { } impl ChainNotify for Informant { - fn new_blocks(&self, imported: Vec, _invalid: Vec, _enacted: Vec, _retracted: Vec, _sealed: Vec, _proposed: Vec, duration: Duration) { + fn new_blocks(&self, imported: Vec, _invalid: Vec, _route: ChainRoute, _sealed: Vec, _proposed: Vec, duration: Duration) { let mut last_import = self.last_import.lock(); let client = &self.target.client; diff --git a/rpc/src/v1/impls/eth_pubsub.rs b/rpc/src/v1/impls/eth_pubsub.rs index 1a872f5600..3045959446 100644 --- a/rpc/src/v1/impls/eth_pubsub.rs +++ b/rpc/src/v1/impls/eth_pubsub.rs @@ -34,7 +34,7 @@ use v1::types::{pubsub, RichHeader, Log}; use ethcore::encoded; use ethcore::filter::Filter as EthFilter; -use ethcore::client::{BlockChainClient, ChainNotify, BlockId}; +use ethcore::client::{BlockChainClient, ChainNotify, ChainRoute, ChainRouteType, BlockId}; use sync::LightSync; use light::cache::Cache; use light::on_demand::OnDemand; @@ -141,19 +141,20 @@ impl ChainNotificationHandler { } } - fn notify_logs(&self, enacted: &[H256], logs: F) where - F: Fn(EthFilter) -> T, + fn notify_logs(&self, enacted: &[(H256, Ex)], logs: F) where + F: Fn(EthFilter, &Ex) -> T, + Ex: Send, T: IntoFuture, Error = Error>, T::Future: Send + 'static, { for &(ref subscriber, ref filter) in self.logs_subscribers.read().values() { let logs = futures::future::join_all(enacted .iter() - .map(|hash| { + .map(|&(hash, ref ex)| { let mut filter = filter.clone(); - filter.from_block = BlockId::Hash(*hash); + filter.from_block = BlockId::Hash(hash); filter.to_block = filter.from_block.clone(); - logs(filter).into_future() + logs(filter, ex).into_future() }) .collect::>() ); @@ -214,7 +215,7 @@ impl LightChainNotify for ChainNotificationHandler { .collect::>(); self.notify_heads(&headers); - self.notify_logs(&enacted, |filter| self.client.logs(filter)) + self.notify_logs(&enacted.iter().map(|h| (*h, ())).collect::>(), |filter, _| self.client.logs(filter)) } } @@ -223,17 +224,21 @@ impl ChainNotify for ChainNotificationHandler { &self, _imported: Vec, _invalid: Vec, - enacted: Vec, - retracted: Vec, + route: ChainRoute, _sealed: Vec, // Block bytes. _proposed: Vec, _duration: Duration, ) { const EXTRA_INFO_PROOF: &'static str = "Object exists in in blockchain (fetched earlier), extra_info is always available if object exists; qed"; - let headers = enacted + let headers = route.route() .iter() - .filter_map(|hash| self.client.block_header(BlockId::Hash(*hash))) + .filter_map(|&(hash, ref typ)| { + match typ { + &ChainRouteType::Retracted => None, + &ChainRouteType::Enacted => self.client.block_header(BlockId::Hash(hash)) + } + }) .map(|header| { let hash = header.hash(); (header, self.client.block_extra_info(BlockId::Hash(hash)).expect(EXTRA_INFO_PROOF)) @@ -243,17 +248,17 @@ impl ChainNotify for ChainNotificationHandler { // Headers self.notify_heads(&headers); - // Enacted logs - self.notify_logs(&enacted, |filter| { - Ok(self.client.logs(filter).into_iter().map(Into::into).collect()) - }); - - // Retracted logs - self.notify_logs(&retracted, |filter| { - Ok(self.client.logs(filter).into_iter().map(Into::into).map(|mut log: Log| { - log.log_type = "removed".into(); - log - }).collect()) + // We notify logs enacting and retracting as the order in route. + self.notify_logs(route.route(), |filter, ex| { + match ex { + &ChainRouteType::Enacted => + Ok(self.client.logs(filter).into_iter().map(Into::into).collect()), + &ChainRouteType::Retracted => + Ok(self.client.logs(filter).into_iter().map(Into::into).map(|mut log: Log| { + log.log_type = "removed".into(); + log + }).collect()), + } }); } } diff --git a/rpc/src/v1/tests/mocked/eth_pubsub.rs b/rpc/src/v1/tests/mocked/eth_pubsub.rs index fb28ba3127..936695a9a1 100644 --- a/rpc/src/v1/tests/mocked/eth_pubsub.rs +++ b/rpc/src/v1/tests/mocked/eth_pubsub.rs @@ -24,7 +24,7 @@ use std::time::Duration; use v1::{EthPubSub, EthPubSubClient, Metadata}; -use ethcore::client::{TestBlockChainClient, EachBlockWith, ChainNotify}; +use ethcore::client::{TestBlockChainClient, EachBlockWith, ChainNotify, ChainRoute, ChainRouteType}; use parity_reactor::EventLoop; const DURATION_ZERO: Duration = Duration::from_millis(0); @@ -57,13 +57,13 @@ fn should_subscribe_to_new_heads() { assert_eq!(io.handle_request_sync(request, metadata.clone()), Some(response.to_owned())); // Check notifications - handler.new_blocks(vec![], vec![], vec![h1], vec![], vec![], vec![], DURATION_ZERO); + handler.new_blocks(vec![], vec![], ChainRoute::new(vec![(h1, ChainRouteType::Enacted)]), vec![], vec![], DURATION_ZERO); let (res, receiver) = receiver.into_future().wait().unwrap(); let response = r#"{"jsonrpc":"2.0","method":"eth_subscription","params":{"result":{"author":"0x0000000000000000000000000000000000000000","difficulty":"0x1","extraData":"0x","gasLimit":"0xf4240","gasUsed":"0x0","hash":"0x3457d2fa2e3dd33c78ac681cf542e429becf718859053448748383af67e23218","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","miner":"0x0000000000000000000000000000000000000000","number":"0x1","parentHash":"0x0cd786a2425d16f152c658316c423e6ce1181e15c3295826d7c9904cba9ce303","receiptsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","sealFields":[],"sha3Uncles":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","size":"0x1c9","stateRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","timestamp":"0x0","transactionsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"},"subscription":"0x416d77337e24399d"}}"#; assert_eq!(res, Some(response.into())); // Notify about two blocks - handler.new_blocks(vec![], vec![], vec![h2, h3], vec![], vec![], vec![], DURATION_ZERO); + handler.new_blocks(vec![], vec![], ChainRoute::new(vec![(h2, ChainRouteType::Enacted), (h3, ChainRouteType::Enacted)]), vec![], vec![], DURATION_ZERO); // Receive both let (res, receiver) = receiver.into_future().wait().unwrap(); @@ -129,7 +129,7 @@ fn should_subscribe_to_logs() { assert_eq!(io.handle_request_sync(request, metadata.clone()), Some(response.to_owned())); // Check notifications (enacted) - handler.new_blocks(vec![], vec![], vec![h1], vec![], vec![], vec![], DURATION_ZERO); + handler.new_blocks(vec![], vec![], ChainRoute::new(vec![(h1, ChainRouteType::Enacted)]), vec![], vec![], DURATION_ZERO); let (res, receiver) = receiver.into_future().wait().unwrap(); let response = r#"{"jsonrpc":"2.0","method":"eth_subscription","params":{"result":{"address":"0x0000000000000000000000000000000000000005","blockHash":"0x3457d2fa2e3dd33c78ac681cf542e429becf718859053448748383af67e23218","blockNumber":"0x1","data":"0x","logIndex":"0x0","topics":["0x0000000000000000000000000000000000000000000000000000000000000001","0x0000000000000000000000000000000000000000000000000000000000000002","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000"],"transactionHash":""#.to_owned() + &format!("0x{:x}", tx_hash) @@ -137,7 +137,7 @@ fn should_subscribe_to_logs() { assert_eq!(res, Some(response.into())); // Check notifications (retracted) - handler.new_blocks(vec![], vec![], vec![], vec![h1], vec![], vec![], DURATION_ZERO); + handler.new_blocks(vec![], vec![], ChainRoute::new(vec![(h1, ChainRouteType::Retracted)]), vec![], vec![], DURATION_ZERO); let (res, receiver) = receiver.into_future().wait().unwrap(); let response = r#"{"jsonrpc":"2.0","method":"eth_subscription","params":{"result":{"address":"0x0000000000000000000000000000000000000005","blockHash":"0x3457d2fa2e3dd33c78ac681cf542e429becf718859053448748383af67e23218","blockNumber":"0x1","data":"0x","logIndex":"0x0","topics":["0x0000000000000000000000000000000000000000000000000000000000000001","0x0000000000000000000000000000000000000000000000000000000000000002","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000"],"transactionHash":""#.to_owned() + &format!("0x{:x}", tx_hash) diff --git a/secret_store/src/acl_storage.rs b/secret_store/src/acl_storage.rs index 50414eff26..b3427fa1b2 100644 --- a/secret_store/src/acl_storage.rs +++ b/secret_store/src/acl_storage.rs @@ -18,7 +18,7 @@ use std::sync::Arc; use std::collections::{HashMap, HashSet}; use std::time::Duration; use parking_lot::{Mutex, RwLock}; -use ethcore::client::{BlockId, ChainNotify, CallContract, RegistryInfo}; +use ethcore::client::{BlockId, ChainNotify, ChainRoute, CallContract, RegistryInfo}; use ethereum_types::{H256, Address}; use bytes::Bytes; use trusted_client::TrustedClient; @@ -76,8 +76,8 @@ impl AclStorage for OnChainAclStorage { } impl ChainNotify for OnChainAclStorage { - fn new_blocks(&self, _imported: Vec, _invalid: Vec, enacted: Vec, retracted: Vec, _sealed: Vec, _proposed: Vec, _duration: Duration) { - if !enacted.is_empty() || !retracted.is_empty() { + fn new_blocks(&self, _imported: Vec, _invalid: Vec, route: ChainRoute, _sealed: Vec, _proposed: Vec, _duration: Duration) { + if !route.enacted().is_empty() || !route.retracted().is_empty() { self.contract.lock().update() } } diff --git a/secret_store/src/key_server_set.rs b/secret_store/src/key_server_set.rs index 25651bb4ca..d13017261c 100644 --- a/secret_store/src/key_server_set.rs +++ b/secret_store/src/key_server_set.rs @@ -19,7 +19,7 @@ use std::net::SocketAddr; use std::collections::{BTreeMap, HashSet}; use std::time::Duration; use parking_lot::Mutex; -use ethcore::client::{Client, BlockChainClient, BlockId, ChainNotify, CallContract, RegistryInfo}; +use ethcore::client::{Client, BlockChainClient, BlockId, ChainNotify, ChainRoute, CallContract, RegistryInfo}; use ethcore::filter::Filter; use ethkey::public_to_address; use hash::keccak; @@ -163,7 +163,9 @@ impl KeyServerSet for OnChainKeyServerSet { } impl ChainNotify for OnChainKeyServerSet { - fn new_blocks(&self, _imported: Vec, _invalid: Vec, enacted: Vec, retracted: Vec, _sealed: Vec, _proposed: Vec, _duration: Duration) { + fn new_blocks(&self, _imported: Vec, _invalid: Vec, route: ChainRoute, _sealed: Vec, _proposed: Vec, _duration: Duration) { + let (enacted, retracted) = route.into_enacted_retracted(); + if !enacted.is_empty() || !retracted.is_empty() { self.contract.lock().update(enacted, retracted) } diff --git a/secret_store/src/listener/service_contract_listener.rs b/secret_store/src/listener/service_contract_listener.rs index 0e273b3eee..214235210f 100644 --- a/secret_store/src/listener/service_contract_listener.rs +++ b/secret_store/src/listener/service_contract_listener.rs @@ -20,7 +20,7 @@ use std::sync::atomic::{AtomicUsize, Ordering}; use std::time::Duration; use std::thread; use parking_lot::Mutex; -use ethcore::client::ChainNotify; +use ethcore::client::{ChainNotify, ChainRoute}; use ethkey::{Public, public_to_address}; use bytes::Bytes; use ethereum_types::{H256, U256, Address}; @@ -428,8 +428,8 @@ impl Drop for ServiceContractListener { } impl ChainNotify for ServiceContractListener { - fn new_blocks(&self, _imported: Vec, _invalid: Vec, enacted: Vec, _retracted: Vec, _sealed: Vec, _proposed: Vec, _duration: Duration) { - let enacted_len = enacted.len(); + fn new_blocks(&self, _imported: Vec, _invalid: Vec, route: ChainRoute, _sealed: Vec, _proposed: Vec, _duration: Duration) { + let enacted_len = route.enacted().len(); if enacted_len == 0 { return; } diff --git a/updater/src/updater.rs b/updater/src/updater.rs index c5f45c7658..f8a98f3b0f 100644 --- a/updater/src/updater.rs +++ b/updater/src/updater.rs @@ -28,7 +28,7 @@ use target_info::Target; use bytes::Bytes; use ethcore::BlockNumber; use ethcore::filter::Filter; -use ethcore::client::{BlockId, BlockChainClient, ChainNotify}; +use ethcore::client::{BlockId, BlockChainClient, ChainNotify, ChainRoute}; use ethereum_types::H256; use sync::{SyncProvider}; use hash_fetch::{self as fetch, HashFetch}; @@ -660,7 +660,7 @@ impl Updater, _invalid: Vec, _enacted: Vec, _retracted: Vec, _sealed: Vec, _proposed: Vec, _duration: Duration) { + fn new_blocks(&self, _imported: Vec, _invalid: Vec, _route: ChainRoute, _sealed: Vec, _proposed: Vec, _duration: Duration) { match (self.client.upgrade(), self.sync.as_ref().and_then(Weak::upgrade)) { (Some(ref c), Some(ref s)) if !s.status().is_syncing(c.queue_info()) => self.poll(), _ => {}, -- GitLab From a7a46f425369fd662042cb4a1c9ffc301b3b5b75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Silva?= Date: Mon, 7 May 2018 12:11:12 +0100 Subject: [PATCH 011/152] Node table sorting according to last contact data (#8541) * network-devp2p: sort nodes in node table using last contact data * network-devp2p: rename node contact types in node table json output * network-devp2p: fix node table tests * network-devp2p: note node failure when failed to establish connection * network-devp2p: handle UselessPeer error * network-devp2p: note failure when marking node as useless --- util/network-devp2p/src/host.rs | 28 +++- util/network-devp2p/src/node_table.rs | 230 +++++++++++++++++++------- 2 files changed, 188 insertions(+), 70 deletions(-) diff --git a/util/network-devp2p/src/host.rs b/util/network-devp2p/src/host.rs index 73ca2aca4b..2de9a1884c 100644 --- a/util/network-devp2p/src/host.rs +++ b/util/network-devp2p/src/host.rs @@ -105,10 +105,13 @@ pub struct NetworkContext<'s> { impl<'s> NetworkContext<'s> { /// Create a new network IO access point. Takes references to all the data that can be updated within the IO handler. - fn new(io: &'s IoContext, + fn new( + io: &'s IoContext, protocol: ProtocolId, - session: Option, sessions: Arc>>, - reserved_peers: &'s HashSet) -> NetworkContext<'s> { + session: Option, + sessions: Arc>>, + reserved_peers: &'s HashSet, + ) -> NetworkContext<'s> { let id = session.as_ref().map(|s| s.lock().token()); NetworkContext { io: io, @@ -585,10 +588,8 @@ impl Host { let address = { let mut nodes = self.nodes.write(); if let Some(node) = nodes.get_mut(id) { - node.attempts += 1; node.endpoint.address - } - else { + } else { debug!(target: "network", "Connection to expired node aborted"); return; } @@ -600,6 +601,7 @@ impl Host { }, Err(e) => { debug!(target: "network", "{}: Can't connect to address {:?}: {:?}", id, address, e); + self.nodes.write().note_failure(&id); return; } } @@ -685,10 +687,12 @@ impl Host { Err(e) => { let s = session.lock(); trace!(target: "network", "Session read error: {}:{:?} ({:?}) {:?}", token, s.id(), s.remote_addr(), e); - if let ErrorKind::Disconnect(DisconnectReason::IncompatibleProtocol) = *e.kind() { + if let ErrorKind::Disconnect(DisconnectReason::UselessPeer) = *e.kind() { if let Some(id) = s.id() { if !self.reserved_nodes.read().contains(id) { - self.nodes.write().mark_as_useless(id); + let mut nodes = self.nodes.write(); + nodes.note_failure(&id); + nodes.mark_as_useless(id); } } } @@ -754,6 +758,10 @@ impl Host { } } } + + // Note connection success + self.nodes.write().note_success(&id); + for (p, _) in self.handlers.read().iter() { if s.have_capability(*p) { ready_data.push(*p); @@ -1024,7 +1032,9 @@ impl IoHandler for Host { if let Some(session) = session { session.lock().disconnect(io, DisconnectReason::DisconnectRequested); if let Some(id) = session.lock().id() { - self.nodes.write().mark_as_useless(id) + let mut nodes = self.nodes.write(); + nodes.note_failure(&id); + nodes.mark_as_useless(id); } } trace!(target: "network", "Disabling peer {}", peer); diff --git a/util/network-devp2p/src/node_table.rs b/util/network-devp2p/src/node_table.rs index fd18c10a12..5079455866 100644 --- a/util/network-devp2p/src/node_table.rs +++ b/util/network-devp2p/src/node_table.rs @@ -21,6 +21,8 @@ use std::net::{SocketAddr, ToSocketAddrs, SocketAddrV4, SocketAddrV6, Ipv4Addr, use std::path::PathBuf; use std::str::FromStr; use std::{fs, mem, slice}; +use std::time::{self, Duration, SystemTime}; +use rand::{self, Rng}; use ethereum_types::H512; use rlp::{Rlp, RlpStream, DecoderError}; use network::{Error, ErrorKind, AllowIP, IpFilter}; @@ -128,40 +130,64 @@ impl FromStr for NodeEndpoint { } } -#[derive(PartialEq, Eq, Copy, Clone)] +#[derive(Debug, PartialEq, Eq, Copy, Clone)] pub enum PeerType { _Required, Optional } +/// A type for representing an interaction (contact) with a node at a given time +/// that was either a success or a failure. +#[derive(Clone, Copy, Debug)] +pub enum NodeContact { + Success(SystemTime), + Failure(SystemTime), +} + +impl NodeContact { + fn success() -> NodeContact { + NodeContact::Success(SystemTime::now()) + } + + fn failure() -> NodeContact { + NodeContact::Failure(SystemTime::now()) + } + + fn time(&self) -> SystemTime { + match *self { + NodeContact::Success(t) | NodeContact::Failure(t) => t + } + } + + /// Filters and old contact, returning `None` if it happened longer than a + /// week ago. + fn recent(&self) -> Option<&NodeContact> { + let t = self.time(); + if let Ok(d) = t.elapsed() { + if d < Duration::from_secs(60 * 60 * 24 * 7) { + return Some(self); + } + } + + None + } +} + +#[derive(Debug)] pub struct Node { pub id: NodeId, pub endpoint: NodeEndpoint, pub peer_type: PeerType, - pub attempts: u32, - pub failures: u32, + pub last_contact: Option, } -const DEFAULT_FAILURE_PERCENTAGE: usize = 50; - impl Node { pub fn new(id: NodeId, endpoint: NodeEndpoint) -> Node { Node { id: id, endpoint: endpoint, peer_type: PeerType::Optional, - attempts: 0, - failures: 0, - } - } - - /// Returns the node's failure percentage (0..100) in buckets of 5%. If there are 0 connection attempts for this - /// node the default failure percentage is returned (50%). - pub fn failure_percentage(&self) -> usize { - if self.attempts == 0 { - DEFAULT_FAILURE_PERCENTAGE - } else { - (self.failures * 100 / self.attempts / 5 * 5) as usize + last_contact: None, } } } @@ -191,8 +217,7 @@ impl FromStr for Node { id: id, endpoint: endpoint, peer_type: PeerType::Optional, - attempts: 0, - failures: 0, + last_contact: None, }) } } @@ -231,28 +256,61 @@ impl NodeTable { /// Add a node to table pub fn add_node(&mut self, mut node: Node) { - // preserve attempts and failure counter - let (attempts, failures) = - self.nodes.get(&node.id).map_or((0, 0), |n| (n.attempts, n.failures)); - - node.attempts = attempts; - node.failures = failures; - + // preserve node last_contact + node.last_contact = self.nodes.get(&node.id).and_then(|n| n.last_contact); self.nodes.insert(node.id.clone(), node); } + /// Returns a list of ordered nodes according to their most recent contact + /// and filtering useless nodes. The algorithm for creating the sorted nodes + /// is: + /// - Contacts that aren't recent (older than 1 week) are discarded + /// - (1) Nodes with a successful contact are ordered (most recent success first) + /// - (2) Nodes with unknown contact (older than 1 week or new nodes) are randomly shuffled + /// - (3) Nodes with a failed contact are ordered (oldest failure first) + /// - The final result is the concatenation of (1), (2) and (3) fn ordered_entries(&self) -> Vec<&Node> { - let mut refs: Vec<&Node> = self.nodes.values() - .filter(|n| !self.useless_nodes.contains(&n.id)) - .collect(); + let mut success = Vec::new(); + let mut failures = Vec::new(); + let mut unknown = Vec::new(); + + let nodes = self.nodes.values() + .filter(|n| !self.useless_nodes.contains(&n.id)); + + for node in nodes { + // discard contact points older that aren't recent + match node.last_contact.as_ref().and_then(|c| c.recent()) { + Some(&NodeContact::Success(_)) => { + success.push(node); + }, + Some(&NodeContact::Failure(_)) => { + failures.push(node); + }, + None => { + unknown.push(node); + }, + } + } - refs.sort_by(|a, b| { - a.failure_percentage().cmp(&b.failure_percentage()) - .then_with(|| a.failures.cmp(&b.failures)) - .then_with(|| b.attempts.cmp(&a.attempts)) // we use reverse ordering for number of attempts + success.sort_by(|a, b| { + let a = a.last_contact.expect("vector only contains values with defined last_contact; qed"); + let b = b.last_contact.expect("vector only contains values with defined last_contact; qed"); + // inverse ordering, most recent successes come first + b.time().cmp(&a.time()) }); - refs + failures.sort_by(|a, b| { + let a = a.last_contact.expect("vector only contains values with defined last_contact; qed"); + let b = b.last_contact.expect("vector only contains values with defined last_contact; qed"); + // normal ordering, most distant failures come first + a.time().cmp(&b.time()) + }); + + rand::thread_rng().shuffle(&mut unknown); + + success.append(&mut unknown); + success.append(&mut failures); + success } /// Returns node ids sorted by failure percentage, for nodes with the same failure percentage the absolute number of @@ -296,10 +354,17 @@ impl NodeTable { } } - /// Increase failure counte for a node + /// Set last contact as failure for a node pub fn note_failure(&mut self, id: &NodeId) { if let Some(node) = self.nodes.get_mut(id) { - node.failures += 1; + node.last_contact = Some(NodeContact::failure()); + } + } + + /// Set last contact as success for a node + pub fn note_success(&mut self, id: &NodeId) { + if let Some(node) = self.nodes.get_mut(id) { + node.last_contact = Some(NodeContact::success()); } } @@ -396,19 +461,38 @@ mod json { pub nodes: Vec, } + #[derive(Serialize, Deserialize)] + pub enum NodeContact { + #[serde(rename = "success")] + Success(u64), + #[serde(rename = "failure")] + Failure(u64), + } + + impl NodeContact { + pub fn into_node_contact(self) -> super::NodeContact { + match self { + NodeContact::Success(s) => super::NodeContact::Success( + time::UNIX_EPOCH + Duration::from_secs(s) + ), + NodeContact::Failure(s) => super::NodeContact::Failure( + time::UNIX_EPOCH + Duration::from_secs(s) + ), + } + } + } + #[derive(Serialize, Deserialize)] pub struct Node { pub url: String, - pub attempts: u32, - pub failures: u32, + pub last_contact: Option, } impl Node { pub fn into_node(self) -> Option { match super::Node::from_str(&self.url) { Ok(mut node) => { - node.attempts = self.attempts; - node.failures = self.failures; + node.last_contact = self.last_contact.map(|c| c.into_node_contact()); Some(node) }, _ => None, @@ -418,10 +502,18 @@ mod json { impl<'a> From<&'a super::Node> for Node { fn from(node: &'a super::Node) -> Self { + let last_contact = node.last_contact.and_then(|c| { + match c { + super::NodeContact::Success(t) => + t.duration_since(time::UNIX_EPOCH).ok().map(|d| NodeContact::Success(d.as_secs())), + super::NodeContact::Failure(t) => + t.duration_since(time::UNIX_EPOCH).ok().map(|d| NodeContact::Failure(d.as_secs())), + } + }); + Node { url: format!("{}", node), - attempts: node.attempts, - failures: node.failures, + last_contact } } } @@ -464,42 +556,54 @@ mod tests { } #[test] - fn table_failure_percentage_order() { + fn table_last_contact_order() { let node1 = Node::from_str("enode://a979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c@22.99.55.44:7770").unwrap(); let node2 = Node::from_str("enode://b979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c@22.99.55.44:7770").unwrap(); let node3 = Node::from_str("enode://c979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c@22.99.55.44:7770").unwrap(); let node4 = Node::from_str("enode://d979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c@22.99.55.44:7770").unwrap(); + let node5 = Node::from_str("enode://e979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c@22.99.55.44:7770").unwrap(); + let node6 = Node::from_str("enode://f979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c@22.99.55.44:7770").unwrap(); let id1 = H512::from_str("a979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c").unwrap(); let id2 = H512::from_str("b979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c").unwrap(); let id3 = H512::from_str("c979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c").unwrap(); let id4 = H512::from_str("d979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c").unwrap(); + let id5 = H512::from_str("e979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c").unwrap(); + let id6 = H512::from_str("f979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c").unwrap(); let mut table = NodeTable::new(None); table.add_node(node1); table.add_node(node2); table.add_node(node3); table.add_node(node4); + table.add_node(node5); + table.add_node(node6); - // node 1 - failure percentage 100% - table.get_mut(&id1).unwrap().attempts = 2; - table.note_failure(&id1); + // failures - nodes 1 & 2 table.note_failure(&id1); - - // node2 - failure percentage 33% - table.get_mut(&id2).unwrap().attempts = 3; table.note_failure(&id2); - // node3 - failure percentage 0% - table.get_mut(&id3).unwrap().attempts = 1; + // success - nodes 3 & 4 + table.note_success(&id3); + table.note_success(&id4); - // node4 - failure percentage 50% (default when no attempts) + // success - node 5 (old contact) + table.get_mut(&id5).unwrap().last_contact = Some(NodeContact::Success(time::UNIX_EPOCH)); + + // unknown - node 6 let r = table.nodes(IpFilter::default()); - assert_eq!(r[0][..], id3[..]); - assert_eq!(r[1][..], id2[..]); - assert_eq!(r[2][..], id4[..]); - assert_eq!(r[3][..], id1[..]); + assert_eq!(r[0][..], id4[..]); // most recent success + assert_eq!(r[1][..], id3[..]); + + // unknown (old contacts and new nodes), randomly shuffled + assert!( + r[2][..] == id5[..] && r[3][..] == id6[..] || + r[2][..] == id6[..] && r[3][..] == id5[..] + ); + + assert_eq!(r[4][..], id1[..]); // oldest failure + assert_eq!(r[5][..], id2[..]); } #[test] @@ -507,23 +611,27 @@ mod tests { let tempdir = TempDir::new("").unwrap(); let node1 = Node::from_str("enode://a979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c@22.99.55.44:7770").unwrap(); let node2 = Node::from_str("enode://b979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c@22.99.55.44:7770").unwrap(); + let node3 = Node::from_str("enode://c979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c@22.99.55.44:7770").unwrap(); let id1 = H512::from_str("a979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c").unwrap(); let id2 = H512::from_str("b979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c").unwrap(); + let id3 = H512::from_str("c979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c").unwrap(); + { let mut table = NodeTable::new(Some(tempdir.path().to_str().unwrap().to_owned())); table.add_node(node1); table.add_node(node2); + table.add_node(node3); - table.get_mut(&id1).unwrap().attempts = 1; - table.get_mut(&id2).unwrap().attempts = 1; - table.note_failure(&id2); + table.note_success(&id2); + table.note_failure(&id3); } { let table = NodeTable::new(Some(tempdir.path().to_str().unwrap().to_owned())); let r = table.nodes(IpFilter::default()); - assert_eq!(r[0][..], id1[..]); - assert_eq!(r[1][..], id2[..]); + assert_eq!(r[0][..], id2[..]); // latest success + assert_eq!(r[1][..], id1[..]); // unknown + assert_eq!(r[2][..], id3[..]); // oldest failure } } -- GitLab From 28c731881f2da0ceca4752dbcc1a8f9ad041f988 Mon Sep 17 00:00:00 2001 From: David Date: Tue, 8 May 2018 11:22:12 +0200 Subject: [PATCH 012/152] Rlp decode returns Result (#8527) rlp::decode returns Result Make a best effort to handle decoding errors gracefully throughout the code, using `expect` where the value is guaranteed to be valid (and in other places where it makes sense). --- ethcore/light/src/client/header_chain.rs | 27 +++++++++++++----------- ethcore/light/src/net/request_credits.rs | 2 +- ethcore/light/src/types/request/mod.rs | 2 +- ethcore/src/blockchain/blockchain.rs | 4 ++-- ethcore/src/db.rs | 13 +++++------- ethcore/src/encoded.rs | 11 +++++----- ethcore/src/engines/tendermint/mod.rs | 6 ++++-- ethcore/src/header.rs | 4 ++-- ethcore/src/snapshot/account.rs | 6 +++--- ethcore/src/snapshot/mod.rs | 6 +++--- ethcore/src/snapshot/tests/helpers.rs | 2 +- ethcore/src/snapshot/tests/state.rs | 2 +- ethcore/src/state/account.rs | 23 +++++++++++--------- ethcore/src/state/mod.rs | 17 ++++++++++----- ethcore/src/trace/types/flat.rs | 2 +- ethcore/transaction/src/transaction.rs | 5 +++-- ethcore/types/src/receipt.rs | 4 ++-- ethcore/vm/src/call_type.rs | 2 +- rpc/src/v1/tests/mocked/eth.rs | 3 ++- util/journaldb/src/archivedb.rs | 13 ++++++------ util/journaldb/src/earlymergedb.rs | 2 +- util/journaldb/src/overlaydb.rs | 2 +- util/journaldb/src/overlayrecentdb.rs | 4 ++-- util/journaldb/src/refcounteddb.rs | 15 +++++++------ util/rlp/src/lib.rs | 6 +++--- util/rlp/tests/tests.rs | 6 ++++-- util/rlp_derive/tests/rlp.rs | 4 ++-- whisper/src/message.rs | 4 ++-- 28 files changed, 107 insertions(+), 90 deletions(-) diff --git a/ethcore/light/src/client/header_chain.rs b/ethcore/light/src/client/header_chain.rs index abcb04c366..02a18a60df 100644 --- a/ethcore/light/src/client/header_chain.rs +++ b/ethcore/light/src/client/header_chain.rs @@ -228,7 +228,7 @@ impl HeaderChain { let decoded_header = spec.genesis_header(); let chain = if let Some(current) = db.get(col, CURRENT_KEY)? { - let curr : BestAndLatest = ::rlp::decode(¤t); + let curr : BestAndLatest = ::rlp::decode(¤t).expect("decoding db value failed"); let mut cur_number = curr.latest_num; let mut candidates = BTreeMap::new(); @@ -236,7 +236,7 @@ impl HeaderChain { // load all era entries, referenced headers within them, // and live epoch proofs. while let Some(entry) = db.get(col, era_key(cur_number).as_bytes())? { - let entry: Entry = ::rlp::decode(&entry); + let entry: Entry = ::rlp::decode(&entry).expect("decoding db value failed"); trace!(target: "chain", "loaded header chain entry for era {} with {} candidates", cur_number, entry.candidates.len()); @@ -524,7 +524,10 @@ impl HeaderChain { None } Ok(None) => panic!("stored candidates always have corresponding headers; qed"), - Ok(Some(header)) => Some((epoch_transition, ::rlp::decode(&header))), + Ok(Some(header)) => Some(( + epoch_transition, + ::rlp::decode(&header).expect("decoding value from db failed") + )), }; } } @@ -591,7 +594,7 @@ impl HeaderChain { in an inconsistent state", h_num); ErrorKind::Database(msg.into()) })?; - ::rlp::decode(&bytes) + ::rlp::decode(&bytes).expect("decoding db value failed") }; let total_difficulty = entry.candidates.iter() @@ -604,9 +607,9 @@ impl HeaderChain { .total_difficulty; break Ok(Some(SpecHardcodedSync { - header: header, - total_difficulty: total_difficulty, - chts: chts, + header, + total_difficulty, + chts, })); }, None => { @@ -742,7 +745,7 @@ impl HeaderChain { /// so including it within a CHT would be redundant. pub fn cht_root(&self, n: usize) -> Option { match self.db.get(self.col, cht_key(n as u64).as_bytes()) { - Ok(val) => val.map(|x| ::rlp::decode(&x)), + Ok(db_fetch) => db_fetch.map(|bytes| ::rlp::decode(&bytes).expect("decoding value from db failed")), Err(e) => { warn!(target: "chain", "Error reading from database: {}", e); None @@ -793,7 +796,7 @@ impl HeaderChain { pub fn pending_transition(&self, hash: H256) -> Option { let key = pending_transition_key(hash); match self.db.get(self.col, &*key) { - Ok(val) => val.map(|x| ::rlp::decode(&x)), + Ok(db_fetch) => db_fetch.map(|bytes| ::rlp::decode(&bytes).expect("decoding value from db failed")), Err(e) => { warn!(target: "chain", "Error reading from database: {}", e); None @@ -1192,7 +1195,7 @@ mod tests { let cache = Arc::new(Mutex::new(Cache::new(Default::default(), Duration::from_secs(6 * 3600)))); - let chain = HeaderChain::new(db.clone(), None, &spec, cache, HardcodedSync::Allow).unwrap(); + let chain = HeaderChain::new(db.clone(), None, &spec, cache, HardcodedSync::Allow).expect("failed to instantiate a new HeaderChain"); let mut parent_hash = genesis_header.hash(); let mut rolling_timestamp = genesis_header.timestamp(); @@ -1211,14 +1214,14 @@ mod tests { parent_hash = header.hash(); let mut tx = db.transaction(); - let pending = chain.insert(&mut tx, header, None).unwrap(); + let pending = chain.insert(&mut tx, header, None).expect("failed inserting a transaction"); db.write(tx).unwrap(); chain.apply_pending(pending); rolling_timestamp += 10; } - let hardcoded_sync = chain.read_hardcoded_sync().unwrap().unwrap(); + let hardcoded_sync = chain.read_hardcoded_sync().expect("failed reading hardcoded sync").expect("failed unwrapping hardcoded sync"); assert_eq!(hardcoded_sync.chts.len(), 3); assert_eq!(hardcoded_sync.total_difficulty, total_difficulty); let decoded: Header = hardcoded_sync.header.decode(); diff --git a/ethcore/light/src/net/request_credits.rs b/ethcore/light/src/net/request_credits.rs index abe609dabb..29570b613c 100644 --- a/ethcore/light/src/net/request_credits.rs +++ b/ethcore/light/src/net/request_credits.rs @@ -407,7 +407,7 @@ mod tests { let costs = CostTable::default(); let serialized = ::rlp::encode(&costs); - let new_costs: CostTable = ::rlp::decode(&*serialized); + let new_costs: CostTable = ::rlp::decode(&*serialized).unwrap(); assert_eq!(costs, new_costs); } diff --git a/ethcore/light/src/types/request/mod.rs b/ethcore/light/src/types/request/mod.rs index 8d911d3f55..bda992df97 100644 --- a/ethcore/light/src/types/request/mod.rs +++ b/ethcore/light/src/types/request/mod.rs @@ -1642,7 +1642,7 @@ mod tests { { // check as single value. let bytes = ::rlp::encode(&val); - let new_val: T = ::rlp::decode(&bytes); + let new_val: T = ::rlp::decode(&bytes).unwrap(); assert_eq!(val, new_val); // check as list containing single value. diff --git a/ethcore/src/blockchain/blockchain.rs b/ethcore/src/blockchain/blockchain.rs index 57bcdf2bc2..0e18c5f889 100644 --- a/ethcore/src/blockchain/blockchain.rs +++ b/ethcore/src/blockchain/blockchain.rs @@ -438,7 +438,7 @@ impl<'a> Iterator for EpochTransitionIter<'a> { return None } - let transitions: EpochTransitions = ::rlp::decode(&val[..]); + let transitions: EpochTransitions = ::rlp::decode(&val[..]).expect("decode error: the db is corrupted or the data structure has changed"); // if there are multiple candidates, at most one will be on the // canon chain. @@ -462,7 +462,7 @@ impl<'a> Iterator for EpochTransitionIter<'a> { impl BlockChain { /// Create new instance of blockchain from given Genesis. pub fn new(config: Config, genesis: &[u8], db: Arc) -> BlockChain { - // 400 is the avarage size of the key + // 400 is the average size of the key let cache_man = CacheManager::new(config.pref_cache_size, config.max_cache_size, 400); let mut bc = BlockChain { diff --git a/ethcore/src/db.rs b/ethcore/src/db.rs index d11adc7710..a1c7d6b0f5 100644 --- a/ethcore/src/db.rs +++ b/ethcore/src/db.rs @@ -218,15 +218,12 @@ impl Writable for DBTransaction { } impl Readable for KVDB { - fn read(&self, col: Option, key: &Key) -> Option where T: rlp::Decodable, R: Deref { - let result = self.get(col, &key.key()); + fn read(&self, col: Option, key: &Key) -> Option + where T: rlp::Decodable, R: Deref { + self.get(col, &key.key()) + .expect(&format!("db get failed, key: {:?}", &key.key() as &[u8])) + .map(|v| rlp::decode(&v).expect("decode db value failed") ) - match result { - Ok(option) => option.map(|v| rlp::decode(&v)), - Err(err) => { - panic!("db get failed, key: {:?}, err: {:?}", &key.key() as &[u8], err); - } - } } fn exists(&self, col: Option, key: &Key) -> bool where R: Deref { diff --git a/ethcore/src/encoded.rs b/ethcore/src/encoded.rs index 1f627666a9..01df386cc2 100644 --- a/ethcore/src/encoded.rs +++ b/ethcore/src/encoded.rs @@ -24,13 +24,12 @@ //! decoded object where parts like the hash can be saved. use block::Block as FullBlock; -use header::{BlockNumber, Header as FullHeader}; -use transaction::UnverifiedTransaction; - +use ethereum_types::{H256, Bloom, U256, Address}; use hash::keccak; +use header::{BlockNumber, Header as FullHeader}; use heapsize::HeapSizeOf; -use ethereum_types::{H256, Bloom, U256, Address}; use rlp::{Rlp, RlpStream}; +use transaction::UnverifiedTransaction; use views::{self, BlockView, HeaderView, BodyView}; /// Owning header view. @@ -48,7 +47,7 @@ impl Header { pub fn new(encoded: Vec) -> Self { Header(encoded) } /// Upgrade this encoded view to a fully owned `Header` object. - pub fn decode(&self) -> FullHeader { ::rlp::decode(&self.0) } + pub fn decode(&self) -> FullHeader { ::rlp::decode(&self.0).expect("decoding failure") } /// Get a borrowed header view onto the data. #[inline] @@ -205,7 +204,7 @@ impl Block { pub fn header_view(&self) -> HeaderView { self.view().header_view() } /// Decode to a full block. - pub fn decode(&self) -> FullBlock { ::rlp::decode(&self.0) } + pub fn decode(&self) -> FullBlock { ::rlp::decode(&self.0).expect("decoding failure") } /// Decode the header. pub fn decode_header(&self) -> FullHeader { self.view().rlp().val_at(0) } diff --git a/ethcore/src/engines/tendermint/mod.rs b/ethcore/src/engines/tendermint/mod.rs index d80a5e182f..93fc347e94 100644 --- a/ethcore/src/engines/tendermint/mod.rs +++ b/ethcore/src/engines/tendermint/mod.rs @@ -143,8 +143,10 @@ impl super::EpochVerifier for EpochVerifier } fn check_finality_proof(&self, proof: &[u8]) -> Option> { - let header: Header = ::rlp::decode(proof); - self.verify_light(&header).ok().map(|_| vec![header.hash()]) + match ::rlp::decode(proof) { + Ok(header) => self.verify_light(&header).ok().map(|_| vec![header.hash()]), + Err(_) => None // REVIEW: log perhaps? Not sure what the policy is. + } } } diff --git a/ethcore/src/header.rs b/ethcore/src/header.rs index a31aa029b3..ba71eb3049 100644 --- a/ethcore/src/header.rs +++ b/ethcore/src/header.rs @@ -398,7 +398,7 @@ mod tests { let nonce = "88ab4e252a7e8c2a23".from_hex().unwrap(); let nonce_decoded = "ab4e252a7e8c2a23".from_hex().unwrap(); - let header: Header = rlp::decode(&header_rlp); + let header: Header = rlp::decode(&header_rlp).expect("error decoding header"); let seal_fields = header.seal.clone(); assert_eq!(seal_fields.len(), 2); assert_eq!(seal_fields[0], mix_hash); @@ -415,7 +415,7 @@ mod tests { // that's rlp of block header created with ethash engine. let header_rlp = "f901f9a0d405da4e66f1445d455195229624e133f5baafe72b5cf7b3c36c12c8146e98b7a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a05fb2b4bfdef7b314451cb138a534d225c922fc0e5fbe25e451142732c3e25c25a088d2ec6b9860aae1a2c3b299f72b6a5d70d7f7ba4722c78f2c49ba96273c2158a007c6fdfa8eea7e86b81f5b0fc0f78f90cc19f4aa60d323151e0cac660199e9a1b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302008003832fefba82524d84568e932a80a0a0349d8c3df71f1a48a9df7d03fd5f14aeee7d91332c009ecaff0a71ead405bd88ab4e252a7e8c2a23".from_hex().unwrap(); - let header: Header = rlp::decode(&header_rlp); + let header: Header = rlp::decode(&header_rlp).expect("error decoding header"); let encoded_header = rlp::encode(&header).into_vec(); assert_eq!(header_rlp, encoded_header); diff --git a/ethcore/src/snapshot/account.rs b/ethcore/src/snapshot/account.rs index 6c9e0f3d6e..49f45136e9 100644 --- a/ethcore/src/snapshot/account.rs +++ b/ethcore/src/snapshot/account.rs @@ -236,7 +236,7 @@ mod tests { }; let thin_rlp = ::rlp::encode(&account); - assert_eq!(::rlp::decode::(&thin_rlp), account); + assert_eq!(::rlp::decode::(&thin_rlp).unwrap(), account); let fat_rlps = to_fat_rlps(&keccak(&addr), &account, &AccountDB::new(db.as_hashdb(), &addr), &mut Default::default(), usize::max_value(), usize::max_value()).unwrap(); let fat_rlp = Rlp::new(&fat_rlps[0]).at(1).unwrap(); @@ -261,7 +261,7 @@ mod tests { }; let thin_rlp = ::rlp::encode(&account); - assert_eq!(::rlp::decode::(&thin_rlp), account); + assert_eq!(::rlp::decode::(&thin_rlp).unwrap(), account); let fat_rlp = to_fat_rlps(&keccak(&addr), &account, &AccountDB::new(db.as_hashdb(), &addr), &mut Default::default(), usize::max_value(), usize::max_value()).unwrap(); let fat_rlp = Rlp::new(&fat_rlp[0]).at(1).unwrap(); @@ -286,7 +286,7 @@ mod tests { }; let thin_rlp = ::rlp::encode(&account); - assert_eq!(::rlp::decode::(&thin_rlp), account); + assert_eq!(::rlp::decode::(&thin_rlp).unwrap(), account); let fat_rlps = to_fat_rlps(&keccak(addr), &account, &AccountDB::new(db.as_hashdb(), &addr), &mut Default::default(), 500, 1000).unwrap(); let mut root = KECCAK_NULL_RLP; diff --git a/ethcore/src/snapshot/mod.rs b/ethcore/src/snapshot/mod.rs index fbf0c5ca5e..94236e9e95 100644 --- a/ethcore/src/snapshot/mod.rs +++ b/ethcore/src/snapshot/mod.rs @@ -281,7 +281,7 @@ pub fn chunk_state<'a>(db: &HashDB, root: &H256, writer: &Mutex(rlp).storage_root); + known_storage_roots.insert(*hash, ::rlp::decode::(rlp)?.storage_root); } if let Some(&(ref hash, ref rlp)) = out_chunk.iter().next() { - known_storage_roots.insert(*hash, ::rlp::decode::(rlp).storage_root); + known_storage_roots.insert(*hash, ::rlp::decode::(rlp)?.storage_root); } Ok(status) } diff --git a/ethcore/src/snapshot/tests/helpers.rs b/ethcore/src/snapshot/tests/helpers.rs index 51f417149b..067a3abab0 100644 --- a/ethcore/src/snapshot/tests/helpers.rs +++ b/ethcore/src/snapshot/tests/helpers.rs @@ -75,7 +75,7 @@ impl StateProducer { // sweep once to alter storage tries. for &mut (ref mut address_hash, ref mut account_data) in &mut accounts_to_modify { - let mut account: BasicAccount = ::rlp::decode(&*account_data); + let mut account: BasicAccount = ::rlp::decode(&*account_data).expect("error decoding basic account"); let acct_db = AccountDBMut::from_hash(db, *address_hash); fill_storage(acct_db, &mut account.storage_root, &mut self.storage_seed); *account_data = DBValue::from_vec(::rlp::encode(&account).into_vec()); diff --git a/ethcore/src/snapshot/tests/state.rs b/ethcore/src/snapshot/tests/state.rs index f17fa7dde5..05926a7e66 100644 --- a/ethcore/src/snapshot/tests/state.rs +++ b/ethcore/src/snapshot/tests/state.rs @@ -114,7 +114,7 @@ fn get_code_from_prev_chunk() { // first one will have code inlined, // second will just have its hash. let thin_rlp = acc_stream.out(); - let acc: BasicAccount = ::rlp::decode(&thin_rlp); + let acc: BasicAccount = ::rlp::decode(&thin_rlp).expect("error decoding basic account"); let mut make_chunk = |acc, hash| { let mut db = MemoryDB::new(); diff --git a/ethcore/src/state/account.rs b/ethcore/src/state/account.rs index f9c8f258e6..ff7d70bd3a 100644 --- a/ethcore/src/state/account.rs +++ b/ethcore/src/state/account.rs @@ -21,6 +21,7 @@ use std::sync::Arc; use std::collections::{HashMap, BTreeMap}; use hash::{KECCAK_EMPTY, KECCAK_NULL_RLP, keccak}; use ethereum_types::{H256, U256, Address}; +use error::Error; use hashdb::HashDB; use kvdb::DBValue; use bytes::{Bytes, ToPretty}; @@ -144,9 +145,10 @@ impl Account { } /// Create a new account from RLP. - pub fn from_rlp(rlp: &[u8]) -> Account { - let basic: BasicAccount = ::rlp::decode(rlp); - basic.into() + pub fn from_rlp(rlp: &[u8]) -> Result { + ::rlp::decode::(rlp) + .map(|ba| ba.into()) + .map_err(|e| e.into()) } /// Create a new contract account. @@ -202,8 +204,8 @@ impl Account { return Ok(value); } let db = SecTrieDB::new(db, &self.storage_root)?; - - let item: U256 = db.get_with(key, ::rlp::decode)?.unwrap_or_else(U256::zero); + let panicky_decoder = |bytes:&[u8]| ::rlp::decode(&bytes).expect("decoding db value failed"); + let item: U256 = db.get_with(key, panicky_decoder)?.unwrap_or_else(U256::zero); let value: H256 = item.into(); self.storage_cache.borrow_mut().insert(key.clone(), value.clone()); Ok(value) @@ -478,7 +480,8 @@ impl Account { let trie = TrieDB::new(db, &self.storage_root)?; let item: U256 = { - let query = (&mut recorder, ::rlp::decode); + let panicky_decoder = |bytes:&[u8]| ::rlp::decode(bytes).expect("decoding db value failed"); + let query = (&mut recorder, panicky_decoder); trie.get_with(&storage_key, query)?.unwrap_or_else(U256::zero) }; @@ -528,7 +531,7 @@ mod tests { a.rlp() }; - let a = Account::from_rlp(&rlp); + let a = Account::from_rlp(&rlp).expect("decoding db value failed"); assert_eq!(*a.storage_root().unwrap(), "c57e1afb758b07f8d2c8f13a3b6e44fa5ff94ab266facc5a4fd3f062426e50b2".into()); assert_eq!(a.storage_at(&db.immutable(), &0x00u64.into()).unwrap(), 0x1234u64.into()); assert_eq!(a.storage_at(&db.immutable(), &0x01u64.into()).unwrap(), H256::default()); @@ -546,10 +549,10 @@ mod tests { a.rlp() }; - let mut a = Account::from_rlp(&rlp); + let mut a = Account::from_rlp(&rlp).expect("decoding db value failed"); assert!(a.cache_code(&db.immutable()).is_some()); - let mut a = Account::from_rlp(&rlp); + let mut a = Account::from_rlp(&rlp).expect("decoding db value failed"); assert_eq!(a.note_code(vec![0x55, 0x44, 0xffu8]), Ok(())); } @@ -609,7 +612,7 @@ mod tests { #[test] fn rlpio() { let a = Account::new(69u8.into(), 0u8.into(), HashMap::new(), Bytes::new()); - let b = Account::from_rlp(&a.rlp()); + let b = Account::from_rlp(&a.rlp()).unwrap(); assert_eq!(a.balance(), b.balance()); assert_eq!(a.nonce(), b.nonce()); assert_eq!(a.code_hash(), b.code_hash()); diff --git a/ethcore/src/state/mod.rs b/ethcore/src/state/mod.rs index 255dce5b5d..20d564588c 100644 --- a/ethcore/src/state/mod.rs +++ b/ethcore/src/state/mod.rs @@ -605,7 +605,8 @@ impl State { // account is not found in the global cache, get from the DB and insert into local let db = self.factories.trie.readonly(self.db.as_hashdb(), &self.root).expect(SEC_TRIE_DB_UNWRAP_STR); - let maybe_acc = db.get_with(address, Account::from_rlp)?; + let from_rlp = |b: &[u8]| Account::from_rlp(b).expect("decoding db value failed"); + let maybe_acc = db.get_with(address, from_rlp)?; let r = maybe_acc.as_ref().map_or(Ok(H256::new()), |a| { let account_db = self.factories.accountdb.readonly(self.db.as_hashdb(), a.address_hash(address)); a.storage_at(account_db.as_hashdb(), key) @@ -983,7 +984,8 @@ impl State { // not found in the global cache, get from the DB and insert into local let db = self.factories.trie.readonly(self.db.as_hashdb(), &self.root)?; - let mut maybe_acc = db.get_with(a, Account::from_rlp)?; + let from_rlp = |b: &[u8]| Account::from_rlp(b).expect("decoding db value failed"); + let mut maybe_acc = db.get_with(a, from_rlp)?; if let Some(ref mut account) = maybe_acc.as_mut() { let accountdb = self.factories.accountdb.readonly(self.db.as_hashdb(), account.address_hash(a)); Self::update_account_cache(require, account, &self.db, accountdb.as_hashdb()); @@ -1012,7 +1014,8 @@ impl State { None => { let maybe_acc = if !self.db.is_known_null(a) { let db = self.factories.trie.readonly(self.db.as_hashdb(), &self.root)?; - AccountEntry::new_clean(db.get_with(a, Account::from_rlp)?) + let from_rlp = |b:&[u8]| { Account::from_rlp(b).expect("decoding db value failed") }; + AccountEntry::new_clean(db.get_with(a, from_rlp)?) } else { AccountEntry::new_clean(None) }; @@ -1064,7 +1067,10 @@ impl State { let mut recorder = Recorder::new(); let trie = TrieDB::new(self.db.as_hashdb(), &self.root)?; let maybe_account: Option = { - let query = (&mut recorder, ::rlp::decode); + let panicky_decoder = |bytes: &[u8]| { + ::rlp::decode(bytes).expect(&format!("prove_account, could not query trie for account key={}", &account_key)) + }; + let query = (&mut recorder, panicky_decoder); trie.get_with(&account_key, query)? }; let account = maybe_account.unwrap_or_else(|| BasicAccount { @@ -1086,7 +1092,8 @@ impl State { // TODO: probably could look into cache somehow but it's keyed by // address, not keccak(address). let trie = TrieDB::new(self.db.as_hashdb(), &self.root)?; - let acc = match trie.get_with(&account_key, Account::from_rlp)? { + let from_rlp = |b: &[u8]| Account::from_rlp(b).expect("decoding db value failed"); + let acc = match trie.get_with(&account_key, from_rlp)? { Some(acc) => acc, None => return Ok((Vec::new(), H256::new())), }; diff --git a/ethcore/src/trace/types/flat.rs b/ethcore/src/trace/types/flat.rs index e2746ca7f7..00cf517df8 100644 --- a/ethcore/src/trace/types/flat.rs +++ b/ethcore/src/trace/types/flat.rs @@ -244,7 +244,7 @@ mod tests { ]); let encoded = ::rlp::encode(&block_traces); - let decoded = ::rlp::decode(&encoded); + let decoded = ::rlp::decode(&encoded).expect("error decoding block traces"); assert_eq!(block_traces, decoded); } } diff --git a/ethcore/transaction/src/transaction.rs b/ethcore/transaction/src/transaction.rs index 571dec3fae..6152e61acb 100644 --- a/ethcore/transaction/src/transaction.rs +++ b/ethcore/transaction/src/transaction.rs @@ -576,7 +576,8 @@ mod tests { #[test] fn sender_test() { - let t: UnverifiedTransaction = rlp::decode(&::rustc_hex::FromHex::from_hex("f85f800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804").unwrap()); + let bytes = ::rustc_hex::FromHex::from_hex("f85f800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804").unwrap(); + let t: UnverifiedTransaction = rlp::decode(&bytes).expect("decoding UnverifiedTransaction failed"); assert_eq!(t.data, b""); assert_eq!(t.gas, U256::from(0x5208u64)); assert_eq!(t.gas_price, U256::from(0x01u64)); @@ -645,7 +646,7 @@ mod tests { use rustc_hex::FromHex; let test_vector = |tx_data: &str, address: &'static str| { - let signed = rlp::decode(&FromHex::from_hex(tx_data).unwrap()); + let signed = rlp::decode(&FromHex::from_hex(tx_data).unwrap()).expect("decoding tx data failed"); let signed = SignedTransaction::new(signed).unwrap(); assert_eq!(signed.sender(), address.into()); println!("chainid: {:?}", signed.chain_id()); diff --git a/ethcore/types/src/receipt.rs b/ethcore/types/src/receipt.rs index c1defbc151..8846d27c02 100644 --- a/ethcore/types/src/receipt.rs +++ b/ethcore/types/src/receipt.rs @@ -193,7 +193,7 @@ mod tests { ); let encoded = ::rlp::encode(&r); assert_eq!(&encoded[..], &expected[..]); - let decoded: Receipt = ::rlp::decode(&encoded); + let decoded: Receipt = ::rlp::decode(&encoded).expect("decoding receipt failed"); assert_eq!(decoded, r); } @@ -211,7 +211,7 @@ mod tests { ); let encoded = ::rlp::encode(&r); assert_eq!(&encoded[..], &expected[..]); - let decoded: Receipt = ::rlp::decode(&encoded); + let decoded: Receipt = ::rlp::decode(&encoded).expect("decoding receipt failed"); assert_eq!(decoded, r); } } diff --git a/ethcore/vm/src/call_type.rs b/ethcore/vm/src/call_type.rs index 83260825f3..dc00b2b839 100644 --- a/ethcore/vm/src/call_type.rs +++ b/ethcore/vm/src/call_type.rs @@ -64,7 +64,7 @@ mod tests { fn should_encode_and_decode_call_type() { let original = CallType::Call; let encoded = encode(&original); - let decoded = decode(&encoded); + let decoded = decode(&encoded).expect("failure decoding CallType"); assert_eq!(original, decoded); } } diff --git a/rpc/src/v1/tests/mocked/eth.rs b/rpc/src/v1/tests/mocked/eth.rs index badf5bff72..39a2e842db 100644 --- a/rpc/src/v1/tests/mocked/eth.rs +++ b/rpc/src/v1/tests/mocked/eth.rs @@ -566,7 +566,8 @@ fn rpc_eth_pending_transaction_by_hash() { let tester = EthTester::default(); { - let tx = rlp::decode(&FromHex::from_hex("f85f800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804").unwrap()); + let bytes = FromHex::from_hex("f85f800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804").unwrap(); + let tx = rlp::decode(&bytes).expect("decoding failure"); let tx = SignedTransaction::new(tx).unwrap(); tester.miner.pending_transactions.lock().insert(H256::zero(), tx); } diff --git a/util/journaldb/src/archivedb.rs b/util/journaldb/src/archivedb.rs index e00b37d3c4..b58558a332 100644 --- a/util/journaldb/src/archivedb.rs +++ b/util/journaldb/src/archivedb.rs @@ -45,14 +45,15 @@ pub struct ArchiveDB { impl ArchiveDB { /// Create a new instance from a key-value db. - pub fn new(backing: Arc, col: Option) -> ArchiveDB { - let latest_era = backing.get(col, &LATEST_ERA_KEY).expect("Low-level database error.") - .map(|val| decode::(&val)); + pub fn new(backing: Arc, column: Option) -> ArchiveDB { + let latest_era = backing.get(column, &LATEST_ERA_KEY) + .expect("Low-level database error.") + .map(|val| decode::(&val).expect("decoding db value failed")); ArchiveDB { overlay: MemoryDB::new(), - backing: backing, - latest_era: latest_era, - column: col, + backing, + latest_era, + column, } } diff --git a/util/journaldb/src/earlymergedb.rs b/util/journaldb/src/earlymergedb.rs index bb8e49d41e..e76cdcd313 100644 --- a/util/journaldb/src/earlymergedb.rs +++ b/util/journaldb/src/earlymergedb.rs @@ -263,7 +263,7 @@ impl EarlyMergeDB { let mut refs = HashMap::new(); let mut latest_era = None; if let Some(val) = db.get(col, &LATEST_ERA_KEY).expect("Low-level database error.") { - let mut era = decode::(&val); + let mut era = decode::(&val).expect("decoding db value failed"); latest_era = Some(era); loop { let mut db_key = DatabaseKey { diff --git a/util/journaldb/src/overlaydb.rs b/util/journaldb/src/overlaydb.rs index fa7ff04596..54d0bb12d7 100644 --- a/util/journaldb/src/overlaydb.rs +++ b/util/journaldb/src/overlaydb.rs @@ -137,7 +137,7 @@ impl OverlayDB { fn payload(&self, key: &H256) -> Option { self.backing.get(self.column, key) .expect("Low-level database error. Some issue with your hard disk?") - .map(|d| decode(&d)) + .map(|d| decode(&d).expect("decoding db value failed")) } /// Put the refs and value of the given key, possibly deleting it from the db. diff --git a/util/journaldb/src/overlayrecentdb.rs b/util/journaldb/src/overlayrecentdb.rs index fdc178350e..2c9ce5cb1d 100644 --- a/util/journaldb/src/overlayrecentdb.rs +++ b/util/journaldb/src/overlayrecentdb.rs @@ -186,7 +186,7 @@ impl OverlayRecentDB { let mut earliest_era = None; let mut cumulative_size = 0; if let Some(val) = db.get(col, &LATEST_ERA_KEY).expect("Low-level database error.") { - let mut era = decode::(&val); + let mut era = decode::(&val).expect("decoding db value failed"); latest_era = Some(era); loop { let mut db_key = DatabaseKey { @@ -195,7 +195,7 @@ impl OverlayRecentDB { }; while let Some(rlp_data) = db.get(col, &encode(&db_key)).expect("Low-level database error.") { trace!("read_overlay: era={}, index={}", era, db_key.index); - let value = decode::(&rlp_data); + let value = decode::(&rlp_data).expect(&format!("read_overlay: Error decoding DatabaseValue era={}, index{}", era, db_key.index)); count += value.inserts.len(); let mut inserted_keys = Vec::new(); for (k, v) in value.inserts { diff --git a/util/journaldb/src/refcounteddb.rs b/util/journaldb/src/refcounteddb.rs index bf366faf75..944d81d373 100644 --- a/util/journaldb/src/refcounteddb.rs +++ b/util/journaldb/src/refcounteddb.rs @@ -62,17 +62,18 @@ pub struct RefCountedDB { impl RefCountedDB { /// Create a new instance given a `backing` database. - pub fn new(backing: Arc, col: Option) -> RefCountedDB { - let latest_era = backing.get(col, &LATEST_ERA_KEY).expect("Low-level database error.") - .map(|val| decode::(&val)); + pub fn new(backing: Arc, column: Option) -> RefCountedDB { + let latest_era = backing.get(column, &LATEST_ERA_KEY) + .expect("Low-level database error.") + .map(|v| decode::(&v).expect("decoding db value failed")); RefCountedDB { - forward: OverlayDB::new(backing.clone(), col), - backing: backing, + forward: OverlayDB::new(backing.clone(), column), + backing, inserts: vec![], removes: vec![], - latest_era: latest_era, - column: col, + latest_era, + column, } } } diff --git a/util/rlp/src/lib.rs b/util/rlp/src/lib.rs index a6754e22de..b416b1c25b 100644 --- a/util/rlp/src/lib.rs +++ b/util/rlp/src/lib.rs @@ -63,13 +63,13 @@ pub const EMPTY_LIST_RLP: [u8; 1] = [0xC0; 1]; /// /// fn main () { /// let data = vec![0x83, b'c', b'a', b't']; -/// let animal: String = rlp::decode(&data); +/// let animal: String = rlp::decode(&data).expect("could not decode"); /// assert_eq!(animal, "cat".to_owned()); /// } /// ``` -pub fn decode(bytes: &[u8]) -> T where T: Decodable { +pub fn decode(bytes: &[u8]) -> Result where T: Decodable { let rlp = Rlp::new(bytes); - rlp.as_val().expect("trusted rlp should be valid") + rlp.as_val() } pub fn decode_list(bytes: &[u8]) -> Vec where T: Decodable { diff --git a/util/rlp/tests/tests.rs b/util/rlp/tests/tests.rs index 6ff426a773..041c267667 100644 --- a/util/rlp/tests/tests.rs +++ b/util/rlp/tests/tests.rs @@ -209,8 +209,10 @@ struct VDTestPair(Vec, Vec) where T: Decodable + fmt::Debug + cmp::Eq; fn run_decode_tests(tests: Vec>) where T: Decodable + fmt::Debug + cmp::Eq { for t in &tests { - let res: T = rlp::decode(&t.1); - assert_eq!(res, t.0); + let res : Result = rlp::decode(&t.1); + assert!(res.is_ok()); + let res = res.unwrap(); + assert_eq!(&res, &t.0); } } diff --git a/util/rlp_derive/tests/rlp.rs b/util/rlp_derive/tests/rlp.rs index c873805247..ba51309146 100644 --- a/util/rlp_derive/tests/rlp.rs +++ b/util/rlp_derive/tests/rlp.rs @@ -24,7 +24,7 @@ fn test_encode_foo() { let out = encode(&foo).into_vec(); assert_eq!(out, expected); - let decoded = decode(&expected); + let decoded = decode(&expected).expect("decode failure"); assert_eq!(foo, decoded); } @@ -38,7 +38,7 @@ fn test_encode_foo_wrapper() { let out = encode(&foo).into_vec(); assert_eq!(out, expected); - let decoded = decode(&expected); + let decoded = decode(&expected).expect("decode failure"); assert_eq!(foo, decoded); } diff --git a/whisper/src/message.rs b/whisper/src/message.rs index fbf2faf3fd..d0de9af4b5 100644 --- a/whisper/src/message.rs +++ b/whisper/src/message.rs @@ -446,7 +446,7 @@ mod tests { }; let encoded = ::rlp::encode(&envelope); - let decoded = ::rlp::decode(&encoded); + let decoded = ::rlp::decode(&encoded).expect("failure decoding Envelope"); assert_eq!(envelope, decoded) } @@ -462,7 +462,7 @@ mod tests { }; let encoded = ::rlp::encode(&envelope); - let decoded = ::rlp::decode(&encoded); + let decoded = ::rlp::decode(&encoded).expect("failure decoding Envelope"); assert_eq!(envelope, decoded) } -- GitLab From ac3de4c5fca0c0b469aa2198c42e92f04be18626 Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Wed, 9 May 2018 08:47:21 +0200 Subject: [PATCH 013/152] Parity as a library (#8412) * Parity as a library * Fix concerns * Allow using a null on_client_restart_cb * Fix more concerns * Test the C library in test.sh * Reduce CMake version to 3.5 * Move the clib test before cargo test * Add println in test --- Cargo.lock | 8 +- Cargo.toml | 5 +- parity-clib-example/CMakeLists.txt | 19 ++ parity-clib-example/main.cpp | 28 +++ parity-clib/Cargo.toml | 17 ++ parity-clib/parity.h | 93 ++++++++++ parity-clib/src/lib.rs | 133 ++++++++++++++ parity/blockchain.rs | 7 - parity/cli/usage.rs | 1 + parity/configuration.rs | 41 +++-- parity/lib.rs | 249 ++++++++++++++++++++++++++ parity/main.rs | 275 +++++++---------------------- parity/run.rs | 138 +++++---------- parity/snapshot.rs | 3 - parity/url.rs | 3 +- test.sh | 16 +- 16 files changed, 702 insertions(+), 334 deletions(-) create mode 100644 parity-clib-example/CMakeLists.txt create mode 100644 parity-clib-example/main.cpp create mode 100644 parity-clib/Cargo.toml create mode 100644 parity-clib/parity.h create mode 100644 parity-clib/src/lib.rs create mode 100644 parity/lib.rs diff --git a/Cargo.lock b/Cargo.lock index ceb14ff277..64e468e670 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1954,7 +1954,6 @@ dependencies = [ "ethcore-private-tx 1.0.0", "ethcore-secretstore 1.0.0", "ethcore-service 0.1.0", - "ethcore-stratum 1.12.0", "ethcore-sync 1.12.0", "ethcore-transaction 0.1.0", "ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2008,6 +2007,13 @@ dependencies = [ "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "parity-clib" +version = "1.12.0" +dependencies = [ + "parity 1.12.0", +] + [[package]] name = "parity-dapps" version = "1.12.0" diff --git a/Cargo.toml b/Cargo.toml index a611458e65..de1a78bf4f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -40,7 +40,6 @@ ethcore-miner = { path = "miner" } ethcore-network = { path = "util/network" } ethcore-private-tx = { path = "ethcore/private-tx" } ethcore-service = { path = "ethcore/service" } -ethcore-stratum = { path = "ethcore/stratum" } ethcore-sync = { path = "ethcore/sync" } ethcore-transaction = { path = "ethcore/transaction" } ethereum-types = "0.3" @@ -108,6 +107,9 @@ slow-blocks = ["ethcore/slow-blocks"] secretstore = ["ethcore-secretstore"] final = ["parity-version/final"] +[lib] +path = "parity/lib.rs" + [[bin]] path = "parity/main.rs" name = "parity" @@ -130,6 +132,7 @@ members = [ "ethstore/cli", "evmbin", "miner", + "parity-clib", "transaction-pool", "whisper", "whisper/cli", diff --git a/parity-clib-example/CMakeLists.txt b/parity-clib-example/CMakeLists.txt new file mode 100644 index 0000000000..143d014e32 --- /dev/null +++ b/parity-clib-example/CMakeLists.txt @@ -0,0 +1,19 @@ +cmake_minimum_required(VERSION 3.5) +include(ExternalProject) + +include_directories("${CMAKE_SOURCE_DIR}/../parity-clib") + +add_executable(parity-example main.cpp) + +ExternalProject_Add( + libparity + DOWNLOAD_COMMAND "" + CONFIGURE_COMMAND "" + BUILD_COMMAND "" + COMMAND cargo build -p parity-clib # Note: use --release in a real project + BINARY_DIR "${CMAKE_SOURCE_DIR}/../target" + INSTALL_COMMAND "" + LOG_BUILD ON) + +add_dependencies(parity-example libparity) +target_link_libraries(parity-example "${CMAKE_SOURCE_DIR}/../target/debug/libparity.so") diff --git a/parity-clib-example/main.cpp b/parity-clib-example/main.cpp new file mode 100644 index 0000000000..1fadf1b5b5 --- /dev/null +++ b/parity-clib-example/main.cpp @@ -0,0 +1,28 @@ +#include +#include +#include + +void on_restart(void*, const char*, size_t) {} + +int main() { + ParityParams cfg = { 0 }; + cfg.on_client_restart_cb = on_restart; + + const char* args[] = {"--light"}; + size_t str_lens[] = {7}; + if (parity_config_from_cli(args, str_lens, 1, &cfg.configuration) != 0) { + return 1; + } + + void* parity; + if (parity_start(&cfg, &parity) != 0) { + return 1; + } + + sleep(5); + if (parity != NULL) { + parity_destroy(parity); + } + + return 0; +} diff --git a/parity-clib/Cargo.toml b/parity-clib/Cargo.toml new file mode 100644 index 0000000000..001f954c21 --- /dev/null +++ b/parity-clib/Cargo.toml @@ -0,0 +1,17 @@ +[package] +description = "C bindings for the Parity Ethereum client" +name = "parity-clib" +version = "1.12.0" +license = "GPL-3.0" +authors = ["Parity Technologies "] + +[lib] +name = "parity" +crate-type = ["cdylib", "staticlib"] + +[dependencies] +parity = { path = "../", default-features = false } + +[features] +default = [] +final = ["parity/final"] diff --git a/parity-clib/parity.h b/parity-clib/parity.h new file mode 100644 index 0000000000..b61da8e458 --- /dev/null +++ b/parity-clib/parity.h @@ -0,0 +1,93 @@ +// Copyright 2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +#ifndef _PARITY_H_INCLUDED_ +#define _PARITY_H_INCLUDED_ + +#include + +/// Parameters to pass to `parity_start`. +struct ParityParams { + /// Configuration object, as handled by the `parity_config_*` functions. + /// Note that calling `parity_start` will destroy the configuration object (even on failure). + void *configuration; + + /// Callback function to call when the client receives an RPC request to change its chain spec. + /// + /// Will only be called if you enable the `--can-restart` flag. + /// + /// The first parameter of the callback is the value of `on_client_restart_cb_custom`. + /// The second and third parameters of the callback are the string pointer and length. + void (*on_client_restart_cb)(void* custom, const char* new_chain, size_t new_chain_len); + + /// Custom parameter passed to the `on_client_restart_cb` callback as first parameter. + void *on_client_restart_cb_custom; +}; + +#ifdef __cplusplus +extern "C" { +#endif + +/// Builds a new configuration object by parsing a list of CLI arguments. +/// +/// The first two parameters are string pointers and string lengths. They must have a length equal +/// to `len`. The strings don't need to be zero-terminated. +/// +/// On success, the produced object will be written to the `void*` pointed by `out`. +/// +/// Returns 0 on success, and non-zero on error. +/// +/// # Example +/// +/// ```no_run +/// void* cfg; +/// const char *args[] = {"--light", "--can-restart"}; +/// size_t str_lens[] = {7, 13}; +/// if (parity_config_from_cli(args, str_lens, 2, &cfg) != 0) { +/// return 1; +/// } +/// ``` +/// +int parity_config_from_cli(char const* const* args, size_t const* arg_lens, size_t len, void** out); + +/// Destroys a configuration object created earlier. +/// +/// **Important**: You probably don't need to call this function. Calling `parity_start` destroys +/// the configuration object as well (even on failure). +void parity_config_destroy(void* cfg); + +/// Starts the parity client in background threads. Returns a pointer to a struct that represents +/// the running client. Can also return NULL if the execution completes instantly. +/// +/// **Important**: The configuration object passed inside `cfg` is destroyed when you +/// call `parity_start` (even on failure). +/// +/// On success, the produced object will be written to the `void*` pointed by `out`. +/// +/// Returns 0 on success, and non-zero on error. +int parity_start(const ParityParams* params, void** out); + +/// Destroys the parity client created with `parity_start`. +/// +/// **Warning**: `parity_start` can return NULL if execution finished instantly, in which case you +/// must not call this function. +void parity_destroy(void* parity); + +#ifdef __cplusplus +} +#endif + +#endif // include guard diff --git a/parity-clib/src/lib.rs b/parity-clib/src/lib.rs new file mode 100644 index 0000000000..b08d6487d1 --- /dev/null +++ b/parity-clib/src/lib.rs @@ -0,0 +1,133 @@ +// Copyright 2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +//! Note that all the structs and functions here are documented in `parity.h`, to avoid +//! duplicating documentation. + +extern crate parity; + +use std::os::raw::{c_char, c_void, c_int}; +use std::panic; +use std::ptr; +use std::slice; + +#[repr(C)] +pub struct ParityParams { + pub configuration: *mut c_void, + pub on_client_restart_cb: Option, + pub on_client_restart_cb_custom: *mut c_void, +} + +#[no_mangle] +pub extern fn parity_config_from_cli(args: *const *const c_char, args_lens: *const usize, len: usize, output: *mut *mut c_void) -> c_int { + unsafe { + panic::catch_unwind(|| { + *output = ptr::null_mut(); + + let args = { + let arg_ptrs = slice::from_raw_parts(args, len); + let arg_lens = slice::from_raw_parts(args_lens, len); + + let mut args = Vec::with_capacity(len + 1); + args.push("parity".to_owned()); + + for (&arg, &len) in arg_ptrs.iter().zip(arg_lens.iter()) { + let string = slice::from_raw_parts(arg as *const u8, len); + match String::from_utf8(string.to_owned()) { + Ok(a) => args.push(a), + Err(_) => return 1, + }; + } + + args + }; + + match parity::Configuration::parse_cli(&args) { + Ok(mut cfg) => { + // Always disable the auto-updater when used as a library. + cfg.args.arg_auto_update = "none".to_owned(); + + let cfg = Box::into_raw(Box::new(cfg)); + *output = cfg as *mut _; + 0 + }, + Err(_) => { + 1 + }, + } + }).unwrap_or(1) + } +} + +#[no_mangle] +pub extern fn parity_config_destroy(cfg: *mut c_void) { + unsafe { + let _ = panic::catch_unwind(|| { + let _cfg = Box::from_raw(cfg as *mut parity::Configuration); + }); + } +} + +#[no_mangle] +pub extern fn parity_start(cfg: *const ParityParams, output: *mut *mut c_void) -> c_int { + unsafe { + panic::catch_unwind(|| { + *output = ptr::null_mut(); + let cfg: &ParityParams = &*cfg; + + let config = Box::from_raw(cfg.configuration as *mut parity::Configuration); + + let on_client_restart_cb = { + struct Cb(Option, *mut c_void); + unsafe impl Send for Cb {} + unsafe impl Sync for Cb {} + impl Cb { + fn call(&self, new_chain: String) { + if let Some(ref cb) = self.0 { + cb(self.1, new_chain.as_bytes().as_ptr() as *const _, new_chain.len()) + } + } + } + let cb = Cb(cfg.on_client_restart_cb, cfg.on_client_restart_cb_custom); + move |new_chain: String| { cb.call(new_chain); } + }; + + let action = match parity::start(*config, on_client_restart_cb, || {}) { + Ok(action) => action, + Err(_) => return 1, + }; + + match action { + parity::ExecutionAction::Instant(Some(s)) => { println!("{}", s); 0 }, + parity::ExecutionAction::Instant(None) => 0, + parity::ExecutionAction::Running(client) => { + *output = Box::into_raw(Box::::new(client)) as *mut c_void; + 0 + } + } + }).unwrap_or(1) + } +} + +#[no_mangle] +pub extern fn parity_destroy(client: *mut c_void) { + unsafe { + let _ = panic::catch_unwind(|| { + let client = Box::from_raw(client as *mut parity::RunningClient); + client.shutdown(); + }); + } +} diff --git a/parity/blockchain.rs b/parity/blockchain.rs index f9c2f8ba37..027814f245 100644 --- a/parity/blockchain.rs +++ b/parity/blockchain.rs @@ -37,7 +37,6 @@ use params::{SpecType, Pruning, Switch, tracing_switch_to_bool, fatdb_switch_to_ use helpers::{to_client_config, execute_upgrades}; use dir::Directories; use user_defaults::UserDefaults; -use fdlimit; use ethcore_private_tx; use db; @@ -178,8 +177,6 @@ fn execute_import_light(cmd: ImportBlockchain) -> Result<(), String> { // 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); @@ -327,8 +324,6 @@ fn execute_import(cmd: ImportBlockchain) -> Result<(), String> { // load user defaults let mut user_defaults = UserDefaults::load(&user_defaults_path)?; - fdlimit::raise_fd_limit(); - // select pruning algorithm let algorithm = cmd.pruning.to_algorithm(&user_defaults); @@ -518,8 +513,6 @@ fn start_client( // load user defaults let user_defaults = UserDefaults::load(&user_defaults_path)?; - fdlimit::raise_fd_limit(); - // select pruning algorithm let algorithm = pruning.to_algorithm(&user_defaults); diff --git a/parity/cli/usage.rs b/parity/cli/usage.rs index 2bdeaaed1a..ce138fdff3 100644 --- a/parity/cli/usage.rs +++ b/parity/cli/usage.rs @@ -198,6 +198,7 @@ macro_rules! usage { } } + /// Parsed command line arguments. #[derive(Debug, PartialEq)] pub struct Args { $( diff --git a/parity/configuration.rs b/parity/configuration.rs index 93cc9a4dd6..3151621801 100644 --- a/parity/configuration.rs +++ b/parity/configuration.rs @@ -92,23 +92,30 @@ pub struct Execute { pub cmd: Cmd, } +/// Configuration for the Parity client. #[derive(Debug, PartialEq)] pub struct Configuration { + /// Arguments to be interpreted. pub args: Args, } impl Configuration { - pub fn parse>(command: &[S]) -> Result { - let args = Args::parse(command)?; - + /// Parses a configuration from a list of command line arguments. + /// + /// # Example + /// + /// ``` + /// let _cfg = parity::Configuration::parse_cli(&["--light", "--chain", "koven"]).unwrap(); + /// ``` + pub fn parse_cli>(command: &[S]) -> Result { let config = Configuration { - args: args, + args: Args::parse(command)?, }; Ok(config) } - pub fn into_command(self) -> Result { + pub(crate) fn into_command(self) -> Result { let dirs = self.directories(); let pruning = self.args.arg_pruning.parse()?; let pruning_history = self.args.arg_pruning_history; @@ -1843,7 +1850,7 @@ mod tests { let filename = tempdir.path().join("peers"); File::create(&filename).unwrap().write_all(b" \n\t\n").unwrap(); let args = vec!["parity", "--reserved-peers", filename.to_str().unwrap()]; - let conf = Configuration::parse(&args).unwrap(); + let conf = Configuration::parse_cli(&args).unwrap(); assert!(conf.init_reserved_nodes().is_ok()); } @@ -1853,7 +1860,7 @@ mod tests { let filename = tempdir.path().join("peers_comments"); File::create(&filename).unwrap().write_all(b"# Sample comment\nenode://6f8a80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0@172.0.0.1:30303\n").unwrap(); let args = vec!["parity", "--reserved-peers", filename.to_str().unwrap()]; - let conf = Configuration::parse(&args).unwrap(); + let conf = Configuration::parse_cli(&args).unwrap(); let reserved_nodes = conf.init_reserved_nodes(); assert!(reserved_nodes.is_ok()); assert_eq!(reserved_nodes.unwrap().len(), 1); @@ -1862,7 +1869,7 @@ mod tests { #[test] fn test_dev_preset() { let args = vec!["parity", "--config", "dev"]; - let conf = Configuration::parse(&args).unwrap(); + let conf = Configuration::parse_cli(&args).unwrap(); match conf.into_command().unwrap().cmd { Cmd::Run(c) => { assert_eq!(c.net_settings.chain, "dev"); @@ -1876,7 +1883,7 @@ mod tests { #[test] fn test_mining_preset() { let args = vec!["parity", "--config", "mining"]; - let conf = Configuration::parse(&args).unwrap(); + let conf = Configuration::parse_cli(&args).unwrap(); match conf.into_command().unwrap().cmd { Cmd::Run(c) => { assert_eq!(c.net_conf.min_peers, 50); @@ -1898,7 +1905,7 @@ mod tests { #[test] fn test_non_standard_ports_preset() { let args = vec!["parity", "--config", "non-standard-ports"]; - let conf = Configuration::parse(&args).unwrap(); + let conf = Configuration::parse_cli(&args).unwrap(); match conf.into_command().unwrap().cmd { Cmd::Run(c) => { assert_eq!(c.net_settings.network_port, 30305); @@ -1911,7 +1918,7 @@ mod tests { #[test] fn test_insecure_preset() { let args = vec!["parity", "--config", "insecure"]; - let conf = Configuration::parse(&args).unwrap(); + let conf = Configuration::parse_cli(&args).unwrap(); match conf.into_command().unwrap().cmd { Cmd::Run(c) => { assert_eq!(c.update_policy.require_consensus, false); @@ -1931,7 +1938,7 @@ mod tests { #[test] fn test_dev_insecure_preset() { let args = vec!["parity", "--config", "dev-insecure"]; - let conf = Configuration::parse(&args).unwrap(); + let conf = Configuration::parse_cli(&args).unwrap(); match conf.into_command().unwrap().cmd { Cmd::Run(c) => { assert_eq!(c.net_settings.chain, "dev"); @@ -1954,7 +1961,7 @@ mod tests { #[test] fn test_override_preset() { let args = vec!["parity", "--config", "mining", "--min-peers=99"]; - let conf = Configuration::parse(&args).unwrap(); + let conf = Configuration::parse_cli(&args).unwrap(); match conf.into_command().unwrap().cmd { Cmd::Run(c) => { assert_eq!(c.net_conf.min_peers, 99); @@ -2077,7 +2084,7 @@ mod tests { #[test] fn should_respect_only_max_peers_and_default() { let args = vec!["parity", "--max-peers=50"]; - let conf = Configuration::parse(&args).unwrap(); + let conf = Configuration::parse_cli(&args).unwrap(); match conf.into_command().unwrap().cmd { Cmd::Run(c) => { assert_eq!(c.net_conf.min_peers, 25); @@ -2090,7 +2097,7 @@ mod tests { #[test] fn should_respect_only_max_peers_less_than_default() { let args = vec!["parity", "--max-peers=5"]; - let conf = Configuration::parse(&args).unwrap(); + let conf = Configuration::parse_cli(&args).unwrap(); match conf.into_command().unwrap().cmd { Cmd::Run(c) => { assert_eq!(c.net_conf.min_peers, 5); @@ -2103,7 +2110,7 @@ mod tests { #[test] fn should_respect_only_min_peers_and_default() { let args = vec!["parity", "--min-peers=5"]; - let conf = Configuration::parse(&args).unwrap(); + let conf = Configuration::parse_cli(&args).unwrap(); match conf.into_command().unwrap().cmd { Cmd::Run(c) => { assert_eq!(c.net_conf.min_peers, 5); @@ -2116,7 +2123,7 @@ mod tests { #[test] fn should_respect_only_min_peers_and_greater_than_default() { let args = vec!["parity", "--min-peers=500"]; - let conf = Configuration::parse(&args).unwrap(); + let conf = Configuration::parse_cli(&args).unwrap(); match conf.into_command().unwrap().cmd { Cmd::Run(c) => { assert_eq!(c.net_conf.min_peers, 500); diff --git a/parity/lib.rs b/parity/lib.rs new file mode 100644 index 0000000000..4d9d1a2c95 --- /dev/null +++ b/parity/lib.rs @@ -0,0 +1,249 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +//! Ethcore client application. + +#![warn(missing_docs)] + +extern crate ansi_term; +extern crate docopt; +#[macro_use] +extern crate clap; +extern crate dir; +extern crate env_logger; +extern crate futures; +extern crate futures_cpupool; +extern crate atty; +extern crate jsonrpc_core; +extern crate num_cpus; +extern crate number_prefix; +extern crate parking_lot; +extern crate regex; +extern crate rlp; +extern crate rpassword; +extern crate rustc_hex; +extern crate semver; +extern crate serde; +extern crate serde_json; +#[macro_use] +extern crate serde_derive; +extern crate toml; + +extern crate ethcore; +extern crate ethcore_bytes as bytes; +extern crate ethcore_io as io; +extern crate ethcore_light as light; +extern crate ethcore_logger; +extern crate ethcore_miner as miner; +extern crate ethcore_network as network; +extern crate ethcore_private_tx; +extern crate ethcore_service; +extern crate ethcore_sync as sync; +extern crate ethcore_transaction as transaction; +extern crate ethereum_types; +extern crate ethkey; +extern crate kvdb; +extern crate node_health; +extern crate panic_hook; +extern crate parity_hash_fetch as hash_fetch; +extern crate parity_ipfs_api; +extern crate parity_local_store as local_store; +extern crate parity_reactor; +extern crate parity_rpc; +extern crate parity_updater as updater; +extern crate parity_version; +extern crate parity_whisper; +extern crate path; +extern crate rpc_cli; +extern crate node_filter; +extern crate keccak_hash as hash; +extern crate journaldb; +extern crate registrar; + +#[macro_use] +extern crate log as rlog; + +#[cfg(feature="secretstore")] +extern crate ethcore_secretstore; + +#[cfg(feature = "dapps")] +extern crate parity_dapps; + +#[cfg(test)] +#[macro_use] +extern crate pretty_assertions; + +#[cfg(windows)] extern crate winapi; + +#[cfg(test)] +extern crate tempdir; + +mod account; +mod blockchain; +mod cache; +mod cli; +mod configuration; +mod dapps; +mod export_hardcoded_sync; +mod ipfs; +mod deprecated; +mod helpers; +mod informant; +mod light_helpers; +mod modules; +mod params; +mod presale; +mod rpc; +mod rpc_apis; +mod run; +mod secretstore; +mod signer; +mod snapshot; +mod upgrade; +mod url; +mod user_defaults; +mod whisper; +mod db; + +use std::net::{TcpListener}; +use std::io::BufReader; +use std::fs::File; +use ansi_term::Style; +use hash::keccak_buffer; +use cli::Args; +use configuration::{Cmd, Execute}; +use deprecated::find_deprecated; +use ethcore_logger::{Config as LogConfig, setup_log}; + +pub use self::configuration::Configuration; +pub use self::run::RunningClient; + +fn print_hash_of(maybe_file: Option) -> Result { + if let Some(file) = maybe_file { + let mut f = BufReader::new(File::open(&file).map_err(|_| "Unable to open file".to_owned())?); + let hash = keccak_buffer(&mut f).map_err(|_| "Unable to read from file".to_owned())?; + Ok(format!("{:x}", hash)) + } else { + Err("Streaming from standard input not yet supported. Specify a file.".to_owned()) + } +} + +/// Action that Parity performed when running `start`. +pub enum ExecutionAction { + /// The execution didn't require starting a node, and thus has finished. + /// Contains the string to print on stdout, if any. + Instant(Option), + + /// The client has started running and must be shut down manually by calling `shutdown`. + /// + /// If you don't call `shutdown()`, execution will continue in the background. + Running(RunningClient), +} + +fn execute(command: Execute, on_client_rq: Cr, on_updater_rq: Rr) -> Result + where Cr: Fn(String) + 'static + Send, + Rr: Fn() + 'static + Send +{ + // TODO: move this to `main()` and expose in the C API so that users can setup logging the way + // they want + let logger = setup_log(&command.logger).expect("Logger is initialized only once; qed"); + + match command.cmd { + Cmd::Run(run_cmd) => { + if run_cmd.ui_conf.enabled && !run_cmd.ui_conf.info_page_only { + warn!("{}", Style::new().bold().paint("Parity browser interface is deprecated. It's going to be removed in the next version, use standalone Parity UI instead.")); + warn!("{}", Style::new().bold().paint("Standalone Parity UI: https://github.com/Parity-JS/shell/releases")); + } + + if run_cmd.ui && run_cmd.dapps_conf.enabled { + // Check if Parity is already running + let addr = format!("{}:{}", run_cmd.ui_conf.interface, run_cmd.ui_conf.port); + if !TcpListener::bind(&addr as &str).is_ok() { + return open_ui(&run_cmd.ws_conf, &run_cmd.ui_conf, &run_cmd.logger_config).map(|_| ExecutionAction::Instant(None)); + } + } + + // start ui + if run_cmd.ui { + open_ui(&run_cmd.ws_conf, &run_cmd.ui_conf, &run_cmd.logger_config)?; + } + + if let Some(ref dapp) = run_cmd.dapp { + open_dapp(&run_cmd.dapps_conf, &run_cmd.http_conf, dapp)?; + } + + let outcome = run::execute(run_cmd, logger, on_client_rq, on_updater_rq)?; + Ok(ExecutionAction::Running(outcome)) + }, + Cmd::Version => Ok(ExecutionAction::Instant(Some(Args::print_version()))), + Cmd::Hash(maybe_file) => print_hash_of(maybe_file).map(|s| ExecutionAction::Instant(Some(s))), + Cmd::Account(account_cmd) => account::execute(account_cmd).map(|s| ExecutionAction::Instant(Some(s))), + Cmd::ImportPresaleWallet(presale_cmd) => presale::execute(presale_cmd).map(|s| ExecutionAction::Instant(Some(s))), + Cmd::Blockchain(blockchain_cmd) => blockchain::execute(blockchain_cmd).map(|_| ExecutionAction::Instant(None)), + Cmd::SignerToken(ws_conf, ui_conf, logger_config) => signer::execute(ws_conf, ui_conf, logger_config).map(|s| ExecutionAction::Instant(Some(s))), + Cmd::SignerSign { id, pwfile, port, authfile } => rpc_cli::signer_sign(id, pwfile, port, authfile).map(|s| ExecutionAction::Instant(Some(s))), + Cmd::SignerList { port, authfile } => rpc_cli::signer_list(port, authfile).map(|s| ExecutionAction::Instant(Some(s))), + Cmd::SignerReject { id, port, authfile } => rpc_cli::signer_reject(id, port, authfile).map(|s| ExecutionAction::Instant(Some(s))), + Cmd::Snapshot(snapshot_cmd) => snapshot::execute(snapshot_cmd).map(|s| ExecutionAction::Instant(Some(s))), + Cmd::ExportHardcodedSync(export_hs_cmd) => export_hardcoded_sync::execute(export_hs_cmd).map(|s| ExecutionAction::Instant(Some(s))), + } +} + +/// Starts the parity client. +/// +/// `on_client_rq` is the action to perform when the client receives an RPC request to be restarted +/// with a different chain. +/// +/// `on_updater_rq` is the action to perform when the updater has a new binary to execute. +/// +/// The first parameter is the command line arguments that you would pass when running the parity +/// binary. +/// +/// On error, returns what to print on stderr. +pub fn start(conf: Configuration, on_client_rq: Cr, on_updater_rq: Rr) -> Result + where Cr: Fn(String) + 'static + Send, + Rr: Fn() + 'static + Send +{ + let deprecated = find_deprecated(&conf.args); + for d in deprecated { + println!("{}", d); + } + + execute(conf.into_command()?, on_client_rq, on_updater_rq) +} + +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, logger_config)?; + // Open a browser + url::open(&token.url).map_err(|e| format!("{}", e))?; + // Print a message + println!("{}", token.message); + Ok(()) +} + +fn open_dapp(dapps_conf: &dapps::Configuration, rpc_conf: &rpc::HttpConfiguration, dapp: &str) -> Result<(), String> { + if !dapps_conf.enabled { + return Err("Cannot use DAPP command with Dapps turned off.".into()) + } + + let url = format!("http://{}:{}/{}/", rpc_conf.interface, rpc_conf.port, dapp); + url::open(&url).map_err(|e| format!("{}", e))?; + Ok(()) +} diff --git a/parity/main.rs b/parity/main.rs index 6774a83864..e489ad865e 100644 --- a/parity/main.rs +++ b/parity/main.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -18,187 +18,28 @@ #![warn(missing_docs)] -extern crate ansi_term; +extern crate parity; + extern crate ctrlc; -extern crate docopt; -#[macro_use] -extern crate clap; extern crate dir; -extern crate env_logger; extern crate fdlimit; -extern crate futures; -extern crate futures_cpupool; -extern crate atty; -extern crate jsonrpc_core; -extern crate num_cpus; -extern crate number_prefix; -extern crate parking_lot; -extern crate regex; -extern crate rlp; -extern crate rpassword; -extern crate rustc_hex; -extern crate semver; -extern crate serde; -extern crate serde_json; #[macro_use] -extern crate serde_derive; -extern crate toml; - -extern crate ethcore; -extern crate ethcore_bytes as bytes; -extern crate ethcore_io as io; -extern crate ethcore_light as light; -extern crate ethcore_logger; -extern crate ethcore_miner as miner; -extern crate ethcore_network as network; -extern crate ethcore_private_tx; -extern crate ethcore_service; -extern crate ethcore_sync as sync; -extern crate ethcore_transaction as transaction; -extern crate ethereum_types; -extern crate ethkey; -extern crate kvdb; -extern crate node_health; +extern crate log; extern crate panic_hook; -extern crate parity_hash_fetch as hash_fetch; -extern crate parity_ipfs_api; -extern crate parity_local_store as local_store; -extern crate parity_reactor; -extern crate parity_rpc; -extern crate parity_updater as updater; -extern crate parity_version; -extern crate parity_whisper; -extern crate path; -extern crate rpc_cli; -extern crate node_filter; -extern crate keccak_hash as hash; -extern crate journaldb; -extern crate registrar; - -#[macro_use] -extern crate log as rlog; - -#[cfg(feature="stratum")] -extern crate ethcore_stratum; - -#[cfg(feature="secretstore")] -extern crate ethcore_secretstore; - -#[cfg(feature = "dapps")] -extern crate parity_dapps; - -#[cfg(test)] -#[macro_use] -extern crate pretty_assertions; +extern crate parking_lot; #[cfg(windows)] extern crate winapi; -#[cfg(test)] -extern crate tempdir; - -mod account; -mod blockchain; -mod cache; -mod cli; -mod configuration; -mod dapps; -mod export_hardcoded_sync; -mod ipfs; -mod deprecated; -mod helpers; -mod informant; -mod light_helpers; -mod modules; -mod params; -mod presale; -mod rpc; -mod rpc_apis; -mod run; -mod secretstore; -mod signer; -mod snapshot; -mod upgrade; -mod url; -mod user_defaults; -mod whisper; -mod db; - -#[cfg(feature="stratum")] -mod stratum; - use std::{process, env}; -use std::collections::HashMap; -use std::io::{self as stdio, BufReader, Read, Write}; +use std::io::{self as stdio, Read, Write}; use std::fs::{remove_file, metadata, File, create_dir_all}; use std::path::PathBuf; -use hash::keccak_buffer; -use cli::Args; -use configuration::{Cmd, Execute, Configuration}; -use deprecated::find_deprecated; -use ethcore_logger::setup_log; +use std::sync::Arc; +use ctrlc::CtrlC; use dir::default_hypervisor_path; - -fn print_hash_of(maybe_file: Option) -> Result { - if let Some(file) = maybe_file { - let mut f = BufReader::new(File::open(&file).map_err(|_| "Unable to open file".to_owned())?); - let hash = keccak_buffer(&mut f).map_err(|_| "Unable to read from file".to_owned())?; - Ok(format!("{:x}", hash)) - } else { - Err("Streaming from standard input not yet supported. Specify a file.".to_owned()) - } -} - -enum PostExecutionAction { - Print(String), - Restart(Option), - Quit, -} - -fn execute(command: Execute, can_restart: bool) -> Result { - let logger = setup_log(&command.logger).expect("Logger is initialized only once; qed"); - - match command.cmd { - Cmd::Run(run_cmd) => { - let (restart, spec_name) = run::execute(run_cmd, can_restart, logger)?; - Ok(if restart { PostExecutionAction::Restart(spec_name) } else { PostExecutionAction::Quit }) - }, - Cmd::Version => Ok(PostExecutionAction::Print(Args::print_version())), - Cmd::Hash(maybe_file) => print_hash_of(maybe_file).map(|s| PostExecutionAction::Print(s)), - Cmd::Account(account_cmd) => 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, 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)), - Cmd::Snapshot(snapshot_cmd) => snapshot::execute(snapshot_cmd).map(|s| PostExecutionAction::Print(s)), - Cmd::ExportHardcodedSync(export_hs_cmd) => export_hardcoded_sync::execute(export_hs_cmd).map(|s| PostExecutionAction::Print(s)), - } -} - -fn start(mut args: Vec) -> Result { - args.insert(0, "parity".to_owned()); - let conf = Configuration::parse(&args).unwrap_or_else(|e| e.exit()); - let can_restart = conf.args.flag_can_restart; - - let deprecated = find_deprecated(&conf.args); - for d in deprecated { - println!("{}", d); - } - - let cmd = conf.into_command()?; - execute(cmd, can_restart) -} - -#[cfg(not(feature="stratum"))] -fn stratum_main(_: &mut HashMap) {} - -#[cfg(feature="stratum")] -fn stratum_main(alt_mains: &mut HashMap) { - alt_mains.insert("stratum".to_owned(), stratum::main); -} - -fn sync_main(_: &mut HashMap) {} +use fdlimit::raise_fd_limit; +use parity::{start, ExecutionAction}; +use parking_lot::{Condvar, Mutex}; fn updates_path(name: &str) -> PathBuf { let mut dest = PathBuf::from(default_hypervisor_path()); @@ -275,48 +116,68 @@ const PLEASE_RESTART_EXIT_CODE: i32 = 69; // Returns the exit error code. fn main_direct(force_can_restart: bool) -> i32 { global_init(); - let mut alt_mains = HashMap::new(); - sync_main(&mut alt_mains); - stratum_main(&mut alt_mains); - let res = if let Some(f) = std::env::args().nth(1).and_then(|arg| alt_mains.get(&arg.to_string())) { - f(); - 0 + + let mut conf = { + let args = std::env::args().collect::>(); + parity::Configuration::parse_cli(&args).unwrap_or_else(|e| e.exit()) + }; + + if let Some(spec_override) = take_spec_name_override() { + conf.args.flag_testnet = false; + conf.args.arg_chain = spec_override; + } + + let can_restart = force_can_restart || conf.args.flag_can_restart; + + // increase max number of open files + raise_fd_limit(); + + let exit = Arc::new((Mutex::new((false, None)), Condvar::new())); + + let exec = if can_restart { + let e1 = exit.clone(); + let e2 = exit.clone(); + start(conf, + move |new_chain: String| { *e1.0.lock() = (true, Some(new_chain)); e1.1.notify_all(); }, + move || { *e2.0.lock() = (true, None); e2.1.notify_all(); }) } else { - let mut args = std::env::args().skip(1).collect::>(); - if force_can_restart && !args.iter().any(|arg| arg == "--can-restart") { - args.push("--can-restart".to_owned()); - } + trace!(target: "mode", "Not hypervised: not setting exit handlers."); + start(conf, move |_| {}, move || {}) + }; - if let Some(spec_override) = take_spec_name_override() { - args.retain(|f| f != "--testnet"); - args.retain(|f| !f.starts_with("--chain=")); - while let Some(pos) = args.iter().position(|a| a == "--chain") { - if args.len() > pos + 1 { - args.remove(pos + 1); + let res = match exec { + Ok(result) => match result { + ExecutionAction::Instant(Some(s)) => { println!("{}", s); 0 }, + ExecutionAction::Instant(None) => 0, + ExecutionAction::Running(client) => { + CtrlC::set_handler({ + let e = exit.clone(); + move || { e.1.notify_all(); } + }); + + // Wait for signal + let mut lock = exit.0.lock(); + let _ = exit.1.wait(&mut lock); + + client.shutdown(); + + match &*lock { + &(true, ref spec_name_override) => { + if let &Some(ref spec_name) = spec_name_override { + set_spec_name_override(spec_name.clone()); + } + PLEASE_RESTART_EXIT_CODE + }, + _ => 0, } - args.remove(pos); - } - args.push("--chain".to_owned()); - args.push(spec_override); - } - - match start(args) { - Ok(result) => match result { - PostExecutionAction::Print(s) => { println!("{}", s); 0 }, - PostExecutionAction::Restart(spec_name_override) => { - if let Some(spec_name) = spec_name_override { - set_spec_name_override(spec_name); - } - PLEASE_RESTART_EXIT_CODE - }, - PostExecutionAction::Quit => 0, - }, - Err(err) => { - writeln!(&mut stdio::stderr(), "{}", err).expect("StdErr available; qed"); - 1 }, - } + }, + Err(err) => { + writeln!(&mut stdio::stderr(), "{}", err).expect("StdErr available; qed"); + 1 + }, }; + global_cleanup(); res } diff --git a/parity/run.rs b/parity/run.rs index fdb32293b9..73113055bb 100644 --- a/parity/run.rs +++ b/parity/run.rs @@ -19,10 +19,8 @@ use std::fmt; use std::sync::{Arc, Weak}; use std::time::{Duration, Instant}; use std::thread; -use std::net::{TcpListener}; -use ansi_term::{Colour, Style}; -use ctrlc::CtrlC; +use ansi_term::Colour; use ethcore::account_provider::{AccountProvider, AccountProviderSettings}; use ethcore::client::{Client, Mode, DatabaseCompactionProfile, VMType, BlockChainClient, BlockInfo}; use ethcore::ethstore::ethkey; @@ -34,7 +32,6 @@ use ethcore_logger::{Config as LogConfig, RotatingLogger}; use ethcore_service::ClientService; use sync::{self, SyncConfig}; use miner::work_notify::WorkPoster; -use fdlimit::raise_fd_limit; use futures_cpupool::CpuPool; use hash_fetch::{self, fetch}; use informant::{Informant, LightNodeInformantData, FullNodeInformantData}; @@ -45,7 +42,6 @@ use node_filter::NodeFilter; use node_health; use parity_reactor::EventLoop; use parity_rpc::{NetworkSettings, informant, is_major_importing}; -use parking_lot::{Condvar, Mutex}; use updater::{UpdatePolicy, Updater}; use parity_version::version; use ethcore_private_tx::{ProviderConfig, EncryptorConfig, SecretStoreEncryptor}; @@ -65,7 +61,6 @@ use rpc; use rpc_apis; use secretstore; use signer; -use url; use db; // how often to take periodic snapshots. @@ -138,28 +133,6 @@ pub struct RunCmd { pub no_hardcoded_sync: bool, } -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, logger_config)?; - // Open a browser - url::open(&token.url).map_err(|e| format!("{}", e))?; - // Print a message - println!("{}", token.message); - Ok(()) -} - -pub fn open_dapp(dapps_conf: &dapps::Configuration, rpc_conf: &rpc::HttpConfiguration, dapp: &str) -> Result<(), String> { - if !dapps_conf.enabled { - return Err("Cannot use DAPP command with Dapps turned off.".into()) - } - - let url = format!("http://{}:{}/{}/", rpc_conf.interface, rpc_conf.port, dapp); - url::open(&url).map_err(|e| format!("{}", e))?; - Ok(()) -} // node info fetcher for the local store. struct FullNodeInfo { miner: Option>, // TODO: only TXQ needed, just use that after decoupling. @@ -415,10 +388,12 @@ fn execute_light_impl(cmd: RunCmd, logger: Arc) -> Result(cmd: RunCmd, logger: Arc, on_client_rq: }, }; - // start ui - if cmd.ui { - open_ui(&cmd.ws_conf, &cmd.ui_conf, &cmd.logger_config)?; - } - - if let Some(dapp) = cmd.dapp { - open_dapp(&cmd.dapps_conf, &cmd.http_conf, &dapp)?; - } - client.set_exit_handler(on_client_rq); updater.set_exit_handler(on_updater_rq); - Ok(RunningClient::Full { - informant, - client, - keep_alive: Box::new((watcher, service, updater, ws_server, http_server, ipc_server, ui_server, secretstore_key_server, ipfs_server, event_loop)), + Ok(RunningClient { + inner: RunningClientInner::Full { + informant, + client, + keep_alive: Box::new((watcher, service, updater, ws_server, http_server, ipc_server, ui_server, secretstore_key_server, ipfs_server, event_loop)), + } }) } -enum RunningClient { +/// Parity client currently executing in background threads. +/// +/// Should be destroyed by calling `shutdown()`, otherwise execution will continue in the +/// background. +pub struct RunningClient { + inner: RunningClientInner +} + +enum RunningClientInner { Light { informant: Arc>, client: Arc, @@ -931,9 +907,10 @@ enum RunningClient { } impl RunningClient { - fn shutdown(self) { - match self { - RunningClient::Light { informant, client, keep_alive } => { + /// Shuts down the client. + pub fn shutdown(self) { + match self.inner { + RunningClientInner::Light { informant, client, keep_alive } => { // Create a weak reference to the client so that we can wait on shutdown // until it is dropped let weak_client = Arc::downgrade(&client); @@ -943,7 +920,7 @@ impl RunningClient { drop(client); wait_for_drop(weak_client); }, - RunningClient::Full { informant, client, keep_alive } => { + RunningClientInner::Full { informant, client, keep_alive } => { info!("Finishing work, please wait..."); // Create a weak reference to the client so that we can wait on shutdown // until it is dropped @@ -961,51 +938,24 @@ impl RunningClient { } } -pub fn execute(cmd: RunCmd, can_restart: bool, logger: Arc) -> Result<(bool, Option), String> { - if cmd.ui_conf.enabled && !cmd.ui_conf.info_page_only { - warn!("{}", Style::new().bold().paint("Parity browser interface is deprecated. It's going to be removed in the next version, use standalone Parity UI instead.")); - warn!("{}", Style::new().bold().paint("Standalone Parity UI: https://github.com/Parity-JS/shell/releases")); - } - - if cmd.ui && cmd.dapps_conf.enabled { - // 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, &cmd.logger_config).map(|_| (false, None)); - } - } - - // increase max number of open files - raise_fd_limit(); - - let exit = Arc::new((Mutex::new((false, None)), Condvar::new())); - - let running_client = if cmd.light { - execute_light_impl(cmd, logger)? - } else if can_restart { - let e1 = exit.clone(); - let e2 = exit.clone(); - execute_impl(cmd, logger, - move |new_chain: String| { *e1.0.lock() = (true, Some(new_chain)); e1.1.notify_all(); }, - move || { *e2.0.lock() = (true, None); e2.1.notify_all(); })? +/// Executes the given run command. +/// +/// `on_client_rq` is the action to perform when the client receives an RPC request to be restarted +/// with a different chain. +/// +/// `on_updater_rq` is the action to perform when the updater has a new binary to execute. +/// +/// On error, returns what to print on stderr. +pub fn execute(cmd: RunCmd, logger: Arc, + on_client_rq: Cr, on_updater_rq: Rr) -> Result + where Cr: Fn(String) + 'static + Send, + Rr: Fn() + 'static + Send +{ + if cmd.light { + execute_light_impl(cmd, logger) } else { - trace!(target: "mode", "Not hypervised: not setting exit handlers."); - execute_impl(cmd, logger, move |_| {}, move || {})? - }; - - // Handle possible exits - CtrlC::set_handler({ - let e = exit.clone(); - move || { e.1.notify_all(); } - }); - - // Wait for signal - let mut l = exit.0.lock(); - let _ = exit.1.wait(&mut l); - - running_client.shutdown(); - - Ok(l.clone()) + execute_impl(cmd, logger, on_client_rq, on_updater_rq) + } } #[cfg(not(windows))] diff --git a/parity/snapshot.rs b/parity/snapshot.rs index ad93801c0b..423864679a 100644 --- a/parity/snapshot.rs +++ b/parity/snapshot.rs @@ -35,7 +35,6 @@ use params::{SpecType, Pruning, Switch, tracing_switch_to_bool, fatdb_switch_to_ use helpers::{to_client_config, execute_upgrades}; use dir::Directories; use user_defaults::UserDefaults; -use fdlimit; use ethcore_private_tx; use db; @@ -149,8 +148,6 @@ impl SnapshotCommand { // load user defaults let user_defaults = UserDefaults::load(&user_defaults_path)?; - fdlimit::raise_fd_limit(); - // select pruning algorithm let algorithm = self.pruning.to_algorithm(&user_defaults); diff --git a/parity/url.rs b/parity/url.rs index 41c4e54583..4f547c28f0 100644 --- a/parity/url.rs +++ b/parity/url.rs @@ -80,8 +80,9 @@ pub fn open(url: &str) -> Result<(), Error> { } #[cfg(target_os="android")] -pub fn open(_url: &str) { +pub fn open(_url: &str) -> Result<(), Error> { // TODO: While it is generally always bad to leave a function implemented, there is not much // more we can do here. This function will eventually be removed when we compile Parity // as a library and not as a full binary. + Ok(()) } diff --git a/test.sh b/test.sh index 84940a6aca..6dcd258ea3 100755 --- a/test.sh +++ b/test.sh @@ -40,8 +40,18 @@ echo "________Validate chainspecs________" fi -# Running test's +# Running the C example +echo "________Running the C example________" +cd parity-clib-example && \ + mkdir -p build && \ + cd build && \ + cmake .. && \ + make && \ + ./parity-example && \ + cd .. && \ + rm -rf build && \ + cd .. + +# Running tests echo "________Running Parity Full Test Suite________" - cargo test -j 8 $OPTIONS --features "$FEATURES" --all $1 - -- GitLab From 7a00d97977f387e66793e6b31e0d739d3f5ff8c8 Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Wed, 9 May 2018 14:48:55 +0800 Subject: [PATCH 014/152] Trace precompiled contracts when the transfer value is not zero (#8486) * Trace precompiled contracts when the transfer value is not zero * Add tests for precompiled CALL tracing * Use byzantium test machine for the new test * Add notes in comments on why we don't trace all precompileds * Use is_transferred instead of transferred --- ethcore/src/executive.rs | 86 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 84 insertions(+), 2 deletions(-) diff --git a/ethcore/src/executive.rs b/ethcore/src/executive.rs index cded6358e8..e29da093c7 100644 --- a/ethcore/src/executive.rs +++ b/ethcore/src/executive.rs @@ -428,8 +428,14 @@ impl<'a, B: 'a + StateBackend> Executive<'a, B> { self.state.discard_checkpoint(); output.write(0, &builtin_out_buffer); - // trace only top level calls to builtins to avoid DDoS attacks - if self.depth == 0 { + // Trace only top level calls and calls with balance transfer to builtins. The reason why we don't + // trace all internal calls to builtin contracts is that memcpy (IDENTITY) is a heavily used + // function. + let is_transferred = match params.value { + ActionValue::Transfer(value) => value != U256::zero(), + ActionValue::Apparent(_) => false, + }; + if self.depth == 0 || is_transferred { let mut trace_output = tracer.prepare_trace_output(); if let Some(out) = trace_output.as_mut() { *out = output.to_owned(); @@ -722,6 +728,12 @@ mod tests { machine } + fn make_byzantium_machine(max_depth: usize) -> EthereumMachine { + let mut machine = ::ethereum::new_byzantium_test_machine(); + machine.set_schedule_creation_rules(Box::new(move |s, _| s.max_depth = max_depth)); + machine + } + #[test] fn test_contract_address() { let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap(); @@ -813,6 +825,76 @@ mod tests { assert_eq!(substate.contracts_created.len(), 0); } + #[test] + fn test_call_to_precompiled_tracing() { + // code: + // + // 60 00 - push 00 out size + // 60 00 - push 00 out offset + // 60 00 - push 00 in size + // 60 00 - push 00 in offset + // 60 01 - push 01 value + // 60 03 - push 03 to + // 61 ffff - push fff gas + // f1 - CALL + + let code = "60006000600060006001600361fffff1".from_hex().unwrap(); + let sender = Address::from_str("4444444444444444444444444444444444444444").unwrap(); + let address = Address::from_str("5555555555555555555555555555555555555555").unwrap(); + + let mut params = ActionParams::default(); + params.address = address.clone(); + params.code_address = address.clone(); + params.sender = sender.clone(); + params.origin = sender.clone(); + params.gas = U256::from(100_000); + params.code = Some(Arc::new(code)); + params.value = ActionValue::Transfer(U256::from(100)); + params.call_type = CallType::Call; + let mut state = get_temp_state(); + state.add_balance(&sender, &U256::from(100), CleanupMode::NoEmpty).unwrap(); + let info = EnvInfo::default(); + let machine = make_byzantium_machine(5); + let mut substate = Substate::new(); + let mut tracer = ExecutiveTracer::default(); + let mut vm_tracer = ExecutiveVMTracer::toplevel(); + + let mut ex = Executive::new(&mut state, &info, &machine); + let output = BytesRef::Fixed(&mut[0u8;0]); + ex.call(params, &mut substate, output, &mut tracer, &mut vm_tracer).unwrap(); + + assert_eq!(tracer.drain(), vec![FlatTrace { + action: trace::Action::Call(trace::Call { + from: "4444444444444444444444444444444444444444".into(), + to: "5555555555555555555555555555555555555555".into(), + value: 100.into(), + gas: 100_000.into(), + input: vec![], + call_type: CallType::Call + }), + result: trace::Res::Call(trace::CallResult { + gas_used: 33021.into(), + output: vec![] + }), + subtraces: 1, + trace_address: Default::default() + }, FlatTrace { + action: trace::Action::Call(trace::Call { + from: "5555555555555555555555555555555555555555".into(), + to: "0000000000000000000000000000000000000003".into(), + value: 1.into(), + gas: 66560.into(), + input: vec![], + call_type: CallType::Call + }), result: trace::Res::Call(trace::CallResult { + gas_used: 600.into(), + output: vec![] + }), + subtraces: 0, + trace_address: vec![0].into_iter().collect(), + }]); + } + #[test] // Tracing is not suported in JIT fn test_call_to_create() { -- GitLab From 24838bbcd3aa3eccde8bb0c24909172c06fdf58b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Wed, 9 May 2018 08:49:34 +0200 Subject: [PATCH 015/152] Don't block sync when importing old blocks (#8530) * Alter IO queueing. * Don't require IoMessages to be Clone * Ancient blocks imported via IoChannel. * Get rid of private transactions io message. * Get rid of deadlock and fix disconnected handler. * Revert to old disconnect condition. * Fix tests. * Fix deadlock. --- Cargo.lock | 2 + ethcore/private-tx/src/lib.rs | 250 +++++++++--------- ethcore/private-tx/tests/private_contract.rs | 2 +- ethcore/service/Cargo.toml | 1 + ethcore/service/src/lib.rs | 3 + ethcore/service/src/service.rs | 32 +-- ethcore/src/client/ancient_import.rs | 50 +++- ethcore/src/client/client.rs | 254 +++++++++++-------- ethcore/src/client/io_message.rs | 30 ++- ethcore/src/client/mod.rs | 3 +- ethcore/src/client/test_client.rs | 32 +-- ethcore/src/client/traits.rs | 24 +- ethcore/src/views/block.rs | 5 +- ethcore/sync/Cargo.toml | 1 + ethcore/sync/src/api.rs | 4 + ethcore/sync/src/block_sync.rs | 2 +- ethcore/sync/src/chain.rs | 5 +- ethcore/sync/src/lib.rs | 2 + ethcore/sync/src/tests/helpers.rs | 6 +- ethcore/sync/src/tests/private.rs | 9 +- util/io/src/lib.rs | 4 +- util/io/src/service.rs | 50 ++-- util/io/src/worker.rs | 10 +- 23 files changed, 452 insertions(+), 329 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 64e468e670..b02fcbd24e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -818,6 +818,7 @@ dependencies = [ "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "stop-guard 0.1.0", "tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "trace-time 0.1.0", ] [[package]] @@ -866,6 +867,7 @@ dependencies = [ "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "trace-time 0.1.0", "triehash 0.1.0", ] diff --git a/ethcore/private-tx/src/lib.rs b/ethcore/private-tx/src/lib.rs index 723d491829..7aca4c85dc 100644 --- a/ethcore/private-tx/src/lib.rs +++ b/ethcore/private-tx/src/lib.rs @@ -149,8 +149,8 @@ impl Provider where { encryptor: Box, config: ProviderConfig, channel: IoChannel, - ) -> Result { - Ok(Provider { + ) -> Self { + Provider { encryptor, validator_accounts: config.validator_accounts.into_iter().collect(), signer_account: config.signer_account, @@ -162,7 +162,7 @@ impl Provider where { miner, accounts, channel, - }) + } } // TODO [ToDr] Don't use `ChainNotify` here! @@ -243,50 +243,6 @@ impl Provider where { Ok(original_transaction) } - /// Process received private transaction - pub fn import_private_transaction(&self, rlp: &[u8]) -> Result<(), Error> { - trace!("Private transaction received"); - let private_tx: PrivateTransaction = Rlp::new(rlp).as_val()?; - let contract = private_tx.contract; - let contract_validators = self.get_validators(BlockId::Latest, &contract)?; - - let validation_account = contract_validators - .iter() - .find(|address| self.validator_accounts.contains(address)); - - match validation_account { - None => { - // TODO [ToDr] This still seems a bit invalid, imho we should still import the transaction to the pool. - // Importing to pool verifies correctness and nonce; here we are just blindly forwarding. - // - // Not for verification, broadcast further to peers - self.broadcast_private_transaction(rlp.into()); - return Ok(()); - }, - Some(&validation_account) => { - let hash = private_tx.hash(); - trace!("Private transaction taken for verification"); - let original_tx = self.extract_original_transaction(private_tx, &contract)?; - trace!("Validating transaction: {:?}", original_tx); - // Verify with the first account available - trace!("The following account will be used for verification: {:?}", validation_account); - let nonce_cache = Default::default(); - self.transactions_for_verification.lock().add_transaction( - original_tx, - contract, - validation_account, - hash, - self.pool_client(&nonce_cache), - )?; - // NOTE This will just fire `on_private_transaction_queued` but from a client thread. - // It seems that a lot of heavy work (verification) is done in this thread anyway - // it might actually make sense to decouple it from clientService and just use dedicated thread - // for both verification and execution. - self.channel.send(ClientIoMessage::NewPrivateTransaction).map_err(|_| ErrorKind::ClientIsMalformed.into()) - } - } - } - fn pool_client<'a>(&'a self, nonce_cache: &'a RwLock>) -> miner::pool_client::PoolClient<'a, Client> { let engine = self.client.engine(); let refuse_service_transactions = true; @@ -299,11 +255,6 @@ impl Provider where { ) } - /// Private transaction for validation added into queue - pub fn on_private_transaction_queued(&self) -> Result<(), Error> { - self.process_queue() - } - /// Retrieve and verify the first available private transaction for every sender /// /// TODO [ToDr] It seems that: @@ -347,73 +298,6 @@ impl Provider where { Ok(()) } - /// Add signed private transaction into the store - /// Creates corresponding public transaction if last required singature collected and sends it to the chain - pub fn import_signed_private_transaction(&self, rlp: &[u8]) -> Result<(), Error> { - let tx: SignedPrivateTransaction = Rlp::new(rlp).as_val()?; - trace!("Signature for private transaction received: {:?}", tx); - let private_hash = tx.private_transaction_hash(); - let desc = match self.transactions_for_signing.lock().get(&private_hash) { - None => { - // TODO [ToDr] Verification (we can't just blindly forward every transaction) - - // Not our transaction, broadcast further to peers - self.broadcast_signed_private_transaction(rlp.into()); - return Ok(()); - }, - Some(desc) => desc, - }; - - let last = self.last_required_signature(&desc, tx.signature())?; - - if last { - let mut signatures = desc.received_signatures.clone(); - signatures.push(tx.signature()); - let rsv: Vec = signatures.into_iter().map(|sign| sign.into_electrum().into()).collect(); - //Create public transaction - let public_tx = self.public_transaction( - desc.state.clone(), - &desc.original_transaction, - &rsv, - desc.original_transaction.nonce, - desc.original_transaction.gas_price - )?; - trace!("Last required signature received, public transaction created: {:?}", public_tx); - //Sign and add it to the queue - let chain_id = desc.original_transaction.chain_id(); - let hash = public_tx.hash(chain_id); - let signer_account = self.signer_account.ok_or_else(|| ErrorKind::SignerAccountNotSet)?; - let password = find_account_password(&self.passwords, &*self.accounts, &signer_account); - let signature = self.accounts.sign(signer_account, password, hash)?; - let signed = SignedTransaction::new(public_tx.with_signature(signature, chain_id))?; - match self.miner.import_own_transaction(&*self.client, signed.into()) { - Ok(_) => trace!("Public transaction added to queue"), - Err(err) => { - trace!("Failed to add transaction to queue, error: {:?}", err); - bail!(err); - } - } - //Remove from store for signing - match self.transactions_for_signing.lock().remove(&private_hash) { - Ok(_) => {} - Err(err) => { - trace!("Failed to remove transaction from signing store, error: {:?}", err); - bail!(err); - } - } - } else { - //Add signature to the store - match self.transactions_for_signing.lock().add_signature(&private_hash, tx.signature()) { - Ok(_) => trace!("Signature stored for private transaction"), - Err(err) => { - trace!("Failed to add signature to signing store, error: {:?}", err); - bail!(err); - } - } - } - Ok(()) - } - fn last_required_signature(&self, desc: &PrivateTransactionSigningDesc, sign: Signature) -> Result { if desc.received_signatures.contains(&sign) { return Ok(false); @@ -657,6 +541,134 @@ impl Provider where { } } +pub trait Importer { + /// Process received private transaction + fn import_private_transaction(&self, _rlp: &[u8]) -> Result<(), Error>; + + /// Add signed private transaction into the store + /// + /// Creates corresponding public transaction if last required signature collected and sends it to the chain + fn import_signed_private_transaction(&self, _rlp: &[u8]) -> Result<(), Error>; +} + +// TODO [ToDr] Offload more heavy stuff to the IoService thread. +// It seems that a lot of heavy work (verification) is done in this thread anyway +// it might actually make sense to decouple it from clientService and just use dedicated thread +// for both verification and execution. + +impl Importer for Arc { + fn import_private_transaction(&self, rlp: &[u8]) -> Result<(), Error> { + trace!("Private transaction received"); + let private_tx: PrivateTransaction = Rlp::new(rlp).as_val()?; + let contract = private_tx.contract; + let contract_validators = self.get_validators(BlockId::Latest, &contract)?; + + let validation_account = contract_validators + .iter() + .find(|address| self.validator_accounts.contains(address)); + + match validation_account { + None => { + // TODO [ToDr] This still seems a bit invalid, imho we should still import the transaction to the pool. + // Importing to pool verifies correctness and nonce; here we are just blindly forwarding. + // + // Not for verification, broadcast further to peers + self.broadcast_private_transaction(rlp.into()); + return Ok(()); + }, + Some(&validation_account) => { + let hash = private_tx.hash(); + trace!("Private transaction taken for verification"); + let original_tx = self.extract_original_transaction(private_tx, &contract)?; + trace!("Validating transaction: {:?}", original_tx); + // Verify with the first account available + trace!("The following account will be used for verification: {:?}", validation_account); + let nonce_cache = Default::default(); + self.transactions_for_verification.lock().add_transaction( + original_tx, + contract, + validation_account, + hash, + self.pool_client(&nonce_cache), + )?; + let provider = Arc::downgrade(self); + self.channel.send(ClientIoMessage::execute(move |_| { + if let Some(provider) = provider.upgrade() { + if let Err(e) = provider.process_queue() { + debug!("Unable to process the queue: {}", e); + } + } + })).map_err(|_| ErrorKind::ClientIsMalformed.into()) + } + } + } + + fn import_signed_private_transaction(&self, rlp: &[u8]) -> Result<(), Error> { + let tx: SignedPrivateTransaction = Rlp::new(rlp).as_val()?; + trace!("Signature for private transaction received: {:?}", tx); + let private_hash = tx.private_transaction_hash(); + let desc = match self.transactions_for_signing.lock().get(&private_hash) { + None => { + // TODO [ToDr] Verification (we can't just blindly forward every transaction) + + // Not our transaction, broadcast further to peers + self.broadcast_signed_private_transaction(rlp.into()); + return Ok(()); + }, + Some(desc) => desc, + }; + + let last = self.last_required_signature(&desc, tx.signature())?; + + if last { + let mut signatures = desc.received_signatures.clone(); + signatures.push(tx.signature()); + let rsv: Vec = signatures.into_iter().map(|sign| sign.into_electrum().into()).collect(); + //Create public transaction + let public_tx = self.public_transaction( + desc.state.clone(), + &desc.original_transaction, + &rsv, + desc.original_transaction.nonce, + desc.original_transaction.gas_price + )?; + trace!("Last required signature received, public transaction created: {:?}", public_tx); + //Sign and add it to the queue + let chain_id = desc.original_transaction.chain_id(); + let hash = public_tx.hash(chain_id); + let signer_account = self.signer_account.ok_or_else(|| ErrorKind::SignerAccountNotSet)?; + let password = find_account_password(&self.passwords, &*self.accounts, &signer_account); + let signature = self.accounts.sign(signer_account, password, hash)?; + let signed = SignedTransaction::new(public_tx.with_signature(signature, chain_id))?; + match self.miner.import_own_transaction(&*self.client, signed.into()) { + Ok(_) => trace!("Public transaction added to queue"), + Err(err) => { + trace!("Failed to add transaction to queue, error: {:?}", err); + bail!(err); + } + } + //Remove from store for signing + match self.transactions_for_signing.lock().remove(&private_hash) { + Ok(_) => {} + Err(err) => { + trace!("Failed to remove transaction from signing store, error: {:?}", err); + bail!(err); + } + } + } else { + //Add signature to the store + match self.transactions_for_signing.lock().add_signature(&private_hash, tx.signature()) { + Ok(_) => trace!("Signature stored for private transaction"), + Err(err) => { + trace!("Failed to add signature to signing store, error: {:?}", err); + bail!(err); + } + } + } + Ok(()) + } +} + /// Try to unlock account using stored password, return found password if any fn find_account_password(passwords: &Vec, account_provider: &AccountProvider, account: &Address) -> Option { for password in passwords { diff --git a/ethcore/private-tx/tests/private_contract.rs b/ethcore/private-tx/tests/private_contract.rs index e53ad5e5f6..e7e608c2b6 100644 --- a/ethcore/private-tx/tests/private_contract.rs +++ b/ethcore/private-tx/tests/private_contract.rs @@ -74,7 +74,7 @@ fn private_contract() { Box::new(NoopEncryptor::default()), config, io, - ).unwrap()); + )); let (address, _) = contract_address(CreateContractAddress::FromSenderAndNonce, &key1.address(), &0.into(), &[]); diff --git a/ethcore/service/Cargo.toml b/ethcore/service/Cargo.toml index b612baf566..3a10849b61 100644 --- a/ethcore/service/Cargo.toml +++ b/ethcore/service/Cargo.toml @@ -13,6 +13,7 @@ ethcore-sync = { path = "../sync" } kvdb = { path = "../../util/kvdb" } log = "0.3" stop-guard = { path = "../../util/stop-guard" } +trace-time = { path = "../../util/trace-time" } [dev-dependencies] tempdir = "0.3" diff --git a/ethcore/service/src/lib.rs b/ethcore/service/src/lib.rs index 1604e84b10..d85a377cde 100644 --- a/ethcore/service/src/lib.rs +++ b/ethcore/service/src/lib.rs @@ -28,6 +28,9 @@ extern crate error_chain; #[macro_use] extern crate log; +#[macro_use] +extern crate trace_time; + #[cfg(test)] extern crate tempdir; diff --git a/ethcore/service/src/service.rs b/ethcore/service/src/service.rs index b60d4194c9..5f46799796 100644 --- a/ethcore/service/src/service.rs +++ b/ethcore/service/src/service.rs @@ -33,7 +33,7 @@ use ethcore::snapshot::{RestorationStatus}; use ethcore::spec::Spec; use ethcore::account_provider::AccountProvider; -use ethcore_private_tx; +use ethcore_private_tx::{self, Importer}; use Error; pub struct PrivateTxService { @@ -112,14 +112,13 @@ impl ClientService { account_provider, encryptor, private_tx_conf, - io_service.channel())?, - ); + io_service.channel(), + )); let private_tx = Arc::new(PrivateTxService::new(provider)); let client_io = Arc::new(ClientIoHandler { client: client.clone(), snapshot: snapshot.clone(), - private_tx: private_tx.clone(), }); io_service.register_handler(client_io)?; @@ -175,7 +174,6 @@ impl ClientService { struct ClientIoHandler { client: Arc, snapshot: Arc, - private_tx: Arc, } const CLIENT_TICK_TIMER: TimerToken = 0; @@ -191,6 +189,7 @@ impl IoHandler for ClientIoHandler { } fn timeout(&self, _io: &IoContext, timer: TimerToken) { + trace_time!("service::read"); match timer { CLIENT_TICK_TIMER => { use ethcore::snapshot::SnapshotService; @@ -203,20 +202,24 @@ impl IoHandler for ClientIoHandler { } fn message(&self, _io: &IoContext, net_message: &ClientIoMessage) { + trace_time!("service::message"); use std::thread; match *net_message { - ClientIoMessage::BlockVerified => { self.client.import_verified_blocks(); } - ClientIoMessage::NewTransactions(ref transactions, peer_id) => { - self.client.import_queued_transactions(transactions, peer_id); + ClientIoMessage::BlockVerified => { + self.client.import_verified_blocks(); } ClientIoMessage::BeginRestoration(ref manifest) => { if let Err(e) = self.snapshot.init_restore(manifest.clone(), true) { warn!("Failed to initialize snapshot restoration: {}", e); } } - ClientIoMessage::FeedStateChunk(ref hash, ref chunk) => self.snapshot.feed_state_chunk(*hash, chunk), - ClientIoMessage::FeedBlockChunk(ref hash, ref chunk) => self.snapshot.feed_block_chunk(*hash, chunk), + ClientIoMessage::FeedStateChunk(ref hash, ref chunk) => { + self.snapshot.feed_state_chunk(*hash, chunk) + } + ClientIoMessage::FeedBlockChunk(ref hash, ref chunk) => { + self.snapshot.feed_block_chunk(*hash, chunk) + } ClientIoMessage::TakeSnapshot(num) => { let client = self.client.clone(); let snapshot = self.snapshot.clone(); @@ -231,12 +234,9 @@ impl IoHandler for ClientIoHandler { debug!(target: "snapshot", "Failed to initialize periodic snapshot thread: {:?}", e); } }, - ClientIoMessage::NewMessage(ref message) => if let Err(e) = self.client.engine().handle_message(message) { - trace!(target: "poa", "Invalid message received: {}", e); - }, - ClientIoMessage::NewPrivateTransaction => if let Err(e) = self.private_tx.provider.on_private_transaction_queued() { - warn!("Failed to handle private transaction {:?}", e); - }, + ClientIoMessage::Execute(ref exec) => { + (*exec.0)(&self.client); + } _ => {} // ignore other messages } } diff --git a/ethcore/src/client/ancient_import.rs b/ethcore/src/client/ancient_import.rs index 13699ea5a0..c2523a13a5 100644 --- a/ethcore/src/client/ancient_import.rs +++ b/ethcore/src/client/ancient_import.rs @@ -32,16 +32,16 @@ const HEAVY_VERIFY_RATE: f32 = 0.02; /// Ancient block verifier: import an ancient sequence of blocks in order from a starting /// epoch. pub struct AncientVerifier { - cur_verifier: RwLock>>, + cur_verifier: RwLock>>>, engine: Arc, } impl AncientVerifier { - /// Create a new ancient block verifier with the given engine and initial verifier. - pub fn new(engine: Arc, start_verifier: Box>) -> Self { + /// Create a new ancient block verifier with the given engine. + pub fn new(engine: Arc) -> Self { AncientVerifier { - cur_verifier: RwLock::new(start_verifier), - engine: engine, + cur_verifier: RwLock::new(None), + engine, } } @@ -53,17 +53,49 @@ impl AncientVerifier { header: &Header, chain: &BlockChain, ) -> Result<(), ::error::Error> { - match rng.gen::() <= HEAVY_VERIFY_RATE { - true => self.cur_verifier.read().verify_heavy(header)?, - false => self.cur_verifier.read().verify_light(header)?, + // perform verification + let verified = if let Some(ref cur_verifier) = *self.cur_verifier.read() { + match rng.gen::() <= HEAVY_VERIFY_RATE { + true => cur_verifier.verify_heavy(header)?, + false => cur_verifier.verify_light(header)?, + } + true + } else { + false + }; + + // when there is no verifier initialize it. + // We use a bool flag to avoid double locking in the happy case + if !verified { + { + let mut cur_verifier = self.cur_verifier.write(); + if cur_verifier.is_none() { + *cur_verifier = Some(self.initial_verifier(header, chain)?); + } + } + // Call again to verify. + return self.verify(rng, header, chain); } // ancient import will only use transitions obtained from the snapshot. if let Some(transition) = chain.epoch_transition(header.number(), header.hash()) { let v = self.engine.epoch_verifier(&header, &transition.proof).known_confirmed()?; - *self.cur_verifier.write() = v; + *self.cur_verifier.write() = Some(v); } Ok(()) } + + fn initial_verifier(&self, header: &Header, chain: &BlockChain) + -> Result>, ::error::Error> + { + trace!(target: "client", "Initializing ancient block restoration."); + let current_epoch_data = chain.epoch_transitions() + .take_while(|&(_, ref t)| t.block_number < header.number()) + .last() + .map(|(_, t)| t.proof) + .expect("At least one epoch entry (genesis) always stored; qed"); + + self.engine.epoch_verifier(&header, ¤t_epoch_data).known_confirmed() + } } diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index 8119ebd35f..bffa4e38ba 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -15,15 +15,16 @@ // along with Parity. If not, see . use std::collections::{HashSet, BTreeMap, BTreeSet, VecDeque}; +use std::fmt; use std::str::FromStr; -use std::sync::{Arc, Weak}; use std::sync::atomic::{AtomicUsize, AtomicBool, Ordering as AtomicOrdering}; +use std::sync::{Arc, Weak}; use std::time::{Instant, Duration}; -use itertools::Itertools; // util use hash::keccak; use bytes::Bytes; +use itertools::Itertools; use journaldb; use trie::{TrieSpec, TrieFactory, Trie}; use kvdb::{DBValue, KeyValueDB, DBTransaction}; @@ -45,7 +46,8 @@ use client::{ use client::{ BlockId, TransactionId, UncleId, TraceId, ClientConfig, BlockChainClient, TraceFilter, CallAnalytics, BlockImportError, Mode, - ChainNotify, ChainRoute, PruningInfo, ProvingBlockChainClient, EngineInfo, ChainMessageType + ChainNotify, ChainRoute, PruningInfo, ProvingBlockChainClient, EngineInfo, ChainMessageType, + IoClient, }; use encoded; use engines::{EthEngine, EpochTransition}; @@ -55,7 +57,7 @@ use evm::Schedule; use executive::{Executive, Executed, TransactOptions, contract_address}; use factory::{Factories, VmFactory}; use header::{BlockNumber, Header}; -use io::IoChannel; +use io::{IoChannel, IoError}; use log_entry::LocalizedLogEntry; use miner::{Miner, MinerService}; use ethcore_miner::pool::VerifiedTransaction; @@ -85,6 +87,7 @@ pub use verification::queue::QueueInfo as BlockQueueInfo; use_contract!(registry, "Registry", "res/contracts/registrar.json"); const MAX_TX_QUEUE_SIZE: usize = 4096; +const MAX_ANCIENT_BLOCKS_QUEUE_SIZE: usize = 4096; const MAX_QUEUE_SIZE_TO_SLEEP_ON: usize = 2; const MIN_HISTORY_SIZE: u64 = 8; @@ -154,10 +157,7 @@ struct Importer { pub miner: Arc, /// Ancient block verifier: import an ancient sequence of blocks in order from a starting epoch - pub ancient_verifier: Mutex>, - - /// Random number generator used by `AncientVerifier` - pub rng: Mutex, + pub ancient_verifier: AncientVerifier, /// Ethereum engine to be used during import pub engine: Arc, @@ -204,8 +204,13 @@ pub struct Client { /// List of actors to be notified on certain chain events notify: RwLock>>, - /// Count of pending transactions in the queue - queue_transactions: AtomicUsize, + /// Queued transactions from IO + queue_transactions: IoChannelQueue, + /// Ancient blocks import queue + queue_ancient_blocks: IoChannelQueue, + /// Consensus messages import queue + queue_consensus_message: IoChannelQueue, + last_hashes: RwLock>, factories: Factories, @@ -239,8 +244,7 @@ impl Importer { verifier: verification::new(config.verifier_type.clone()), block_queue, miner, - ancient_verifier: Mutex::new(None), - rng: Mutex::new(OsRng::new()?), + ancient_verifier: AncientVerifier::new(engine.clone()), engine, }) } @@ -416,55 +420,25 @@ impl Importer { Ok(locked_block) } + /// Import a block with transaction receipts. /// /// The block is guaranteed to be the next best blocks in the /// first block sequence. Does no sealing or transaction validation. - fn import_old_block(&self, header: &Header, block_bytes: Bytes, receipts_bytes: Bytes, db: &KeyValueDB, chain: &BlockChain) -> Result { - let receipts = ::rlp::decode_list(&receipts_bytes); + fn import_old_block(&self, header: &Header, block_bytes: &[u8], receipts_bytes: &[u8], db: &KeyValueDB, chain: &BlockChain) -> Result { + let receipts = ::rlp::decode_list(receipts_bytes); let hash = header.hash(); let _import_lock = self.import_lock.lock(); { trace_time!("import_old_block"); - let mut ancient_verifier = self.ancient_verifier.lock(); - - { - // closure for verifying a block. - let verify_with = |verifier: &AncientVerifier| -> Result<(), ::error::Error> { - // verify the block, passing the chain for updating the epoch - // verifier. - let mut rng = OsRng::new().map_err(UtilError::from)?; - verifier.verify(&mut rng, &header, &chain) - }; - - // initialize the ancient block verifier if we don't have one already. - match &mut *ancient_verifier { - &mut Some(ref verifier) => { - verify_with(verifier)? - } - x @ &mut None => { - // load most recent epoch. - trace!(target: "client", "Initializing ancient block restoration."); - let current_epoch_data = chain.epoch_transitions() - .take_while(|&(_, ref t)| t.block_number < header.number()) - .last() - .map(|(_, t)| t.proof) - .expect("At least one epoch entry (genesis) always stored; qed"); - - let current_verifier = self.engine.epoch_verifier(&header, ¤t_epoch_data) - .known_confirmed()?; - let current_verifier = AncientVerifier::new(self.engine.clone(), current_verifier); - - verify_with(¤t_verifier)?; - *x = Some(current_verifier); - } - } - } + // verify the block, passing the chain for updating the epoch verifier. + let mut rng = OsRng::new().map_err(UtilError::from)?; + self.ancient_verifier.verify(&mut rng, &header, &chain)?; // Commit results let mut batch = DBTransaction::new(); - chain.insert_unordered_block(&mut batch, &block_bytes, receipts, None, false, true); + chain.insert_unordered_block(&mut batch, block_bytes, receipts, None, false, true); // Final commit to the DB db.write_buffered(batch); chain.commit(); @@ -734,7 +708,9 @@ impl Client { report: RwLock::new(Default::default()), io_channel: Mutex::new(message_channel), notify: RwLock::new(Vec::new()), - queue_transactions: AtomicUsize::new(0), + queue_transactions: IoChannelQueue::new(MAX_TX_QUEUE_SIZE), + queue_ancient_blocks: IoChannelQueue::new(MAX_ANCIENT_BLOCKS_QUEUE_SIZE), + queue_consensus_message: IoChannelQueue::new(usize::max_value()), last_hashes: RwLock::new(VecDeque::new()), factories: factories, history: history, @@ -820,7 +796,7 @@ impl Client { } fn notify(&self, f: F) where F: Fn(&ChainNotify) { - for np in self.notify.read().iter() { + for np in &*self.notify.read() { if let Some(n) = np.upgrade() { f(&*n); } @@ -954,24 +930,6 @@ impl Client { } } - /// Import transactions from the IO queue - pub fn import_queued_transactions(&self, transactions: &[Bytes], peer_id: usize) -> usize { - trace_time!("import_queued_transactions"); - self.queue_transactions.fetch_sub(transactions.len(), AtomicOrdering::SeqCst); - - let txs: Vec = transactions - .iter() - .filter_map(|bytes| self.engine().decode_transaction(bytes).ok()) - .collect(); - - self.notify(|notify| { - notify.transactions_received(&txs, peer_id); - }); - - let results = self.importer.miner.import_external_transactions(self, txs); - results.len() - } - /// Get shared miner reference. #[cfg(test)] pub fn miner(&self) -> Arc { @@ -1392,22 +1350,6 @@ impl ImportBlock for Client { } Ok(self.importer.block_queue.import(unverified)?) } - - fn import_block_with_receipts(&self, block_bytes: Bytes, receipts_bytes: Bytes) -> Result { - let header: Header = ::rlp::Rlp::new(&block_bytes).val_at(0)?; - { - // check block order - if self.chain.read().is_known(&header.hash()) { - bail!(BlockImportErrorKind::Import(ImportErrorKind::AlreadyInChain)); - } - let status = self.block_status(BlockId::Hash(*header.parent_hash())); - if status == BlockStatus::Unknown || status == BlockStatus::Pending { - bail!(BlockImportErrorKind::Block(BlockError::UnknownParent(*header.parent_hash()))); - } - } - - self.importer.import_old_block(&header, block_bytes, receipts_bytes, &**self.db.read(), &*self.chain.read()).map_err(Into::into) - } } impl StateClient for Client { @@ -1958,35 +1900,10 @@ impl BlockChainClient for Client { (*self.build_last_hashes(&self.chain.read().best_block_hash())).clone() } - fn queue_transactions(&self, transactions: Vec, peer_id: usize) { - let queue_size = self.queue_transactions.load(AtomicOrdering::Relaxed); - trace!(target: "external_tx", "Queue size: {}", queue_size); - if queue_size > MAX_TX_QUEUE_SIZE { - debug!("Ignoring {} transactions: queue is full", transactions.len()); - } else { - let len = transactions.len(); - match self.io_channel.lock().send(ClientIoMessage::NewTransactions(transactions, peer_id)) { - Ok(_) => { - self.queue_transactions.fetch_add(len, AtomicOrdering::SeqCst); - } - Err(e) => { - debug!("Ignoring {} transactions: error queueing: {}", len, e); - } - } - } - } - fn ready_transactions(&self) -> Vec> { self.importer.miner.ready_transactions(self) } - fn queue_consensus_message(&self, message: Bytes) { - let channel = self.io_channel.lock().clone(); - if let Err(e) = channel.send(ClientIoMessage::NewMessage(message)) { - debug!("Ignoring the message, error queueing: {}", e); - } - } - fn signing_chain_id(&self) -> Option { self.engine.signing_chain_id(&self.latest_env_info()) } @@ -2034,6 +1951,72 @@ impl BlockChainClient for Client { } } +impl IoClient for Client { + fn queue_transactions(&self, transactions: Vec, peer_id: usize) { + let len = transactions.len(); + self.queue_transactions.queue(&mut self.io_channel.lock(), len, move |client| { + trace_time!("import_queued_transactions"); + + let txs: Vec = transactions + .iter() + .filter_map(|bytes| client.engine.decode_transaction(bytes).ok()) + .collect(); + + client.notify(|notify| { + notify.transactions_received(&txs, peer_id); + }); + + client.importer.miner.import_external_transactions(client, txs); + }).unwrap_or_else(|e| { + debug!(target: "client", "Ignoring {} transactions: {}", len, e); + }); + } + + fn queue_ancient_block(&self, block_bytes: Bytes, receipts_bytes: Bytes) -> Result { + let header: Header = ::rlp::Rlp::new(&block_bytes).val_at(0)?; + let hash = header.hash(); + + { + // check block order + if self.chain.read().is_known(&header.hash()) { + bail!(BlockImportErrorKind::Import(ImportErrorKind::AlreadyInChain)); + } + let status = self.block_status(BlockId::Hash(*header.parent_hash())); + if status == BlockStatus::Unknown || status == BlockStatus::Pending { + bail!(BlockImportErrorKind::Block(BlockError::UnknownParent(*header.parent_hash()))); + } + } + + match self.queue_ancient_blocks.queue(&mut self.io_channel.lock(), 1, move |client| { + client.importer.import_old_block( + &header, + &block_bytes, + &receipts_bytes, + &**client.db.read(), + &*client.chain.read() + ).map(|_| ()).unwrap_or_else(|e| { + error!(target: "client", "Error importing ancient block: {}", e); + }); + }) { + Ok(_) => Ok(hash), + Err(e) => bail!(BlockImportErrorKind::Other(format!("{}", e))), + } + } + + fn queue_consensus_message(&self, message: Bytes) { + match self.queue_consensus_message.queue(&mut self.io_channel.lock(), 1, move |client| { + if let Err(e) = client.engine().handle_message(&message) { + debug!(target: "poa", "Invalid message received: {}", e); + } + }) { + Ok(_) => (), + Err(e) => { + debug!(target: "poa", "Ignoring the message, error queueing: {}", e); + } + } + } +} + impl ReopenBlock for Client { fn reopen_block(&self, block: ClosedBlock) -> OpenBlock { let engine = &*self.engine; @@ -2409,3 +2392,54 @@ mod tests { }); } } + +#[derive(Debug)] +enum QueueError { + Channel(IoError), + Full(usize), +} + +impl fmt::Display for QueueError { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + match *self { + QueueError::Channel(ref c) => fmt::Display::fmt(c, fmt), + QueueError::Full(limit) => write!(fmt, "The queue is full ({})", limit), + } + } +} + +/// Queue some items to be processed by IO client. +struct IoChannelQueue { + currently_queued: Arc, + limit: usize, +} + +impl IoChannelQueue { + pub fn new(limit: usize) -> Self { + IoChannelQueue { + currently_queued: Default::default(), + limit, + } + } + + pub fn queue(&self, channel: &mut IoChannel, count: usize, fun: F) -> Result<(), QueueError> where + F: Fn(&Client) + Send + Sync + 'static, + { + let queue_size = self.currently_queued.load(AtomicOrdering::Relaxed); + ensure!(queue_size < self.limit, QueueError::Full(self.limit)); + + let currently_queued = self.currently_queued.clone(); + let result = channel.send(ClientIoMessage::execute(move |client| { + currently_queued.fetch_sub(count, AtomicOrdering::SeqCst); + fun(client); + })); + + match result { + Ok(_) => { + self.currently_queued.fetch_add(count, AtomicOrdering::SeqCst); + Ok(()) + }, + Err(e) => Err(QueueError::Channel(e)), + } + } +} diff --git a/ethcore/src/client/io_message.rs b/ethcore/src/client/io_message.rs index e19d3054fe..817c726020 100644 --- a/ethcore/src/client/io_message.rs +++ b/ethcore/src/client/io_message.rs @@ -14,19 +14,19 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -use ethereum_types::H256; +use std::fmt; use bytes::Bytes; +use client::Client; +use ethereum_types::H256; use snapshot::ManifestData; /// Message type for external and internal events -#[derive(Clone, PartialEq, Eq, Debug)] +#[derive(Debug)] pub enum ClientIoMessage { /// Best Block Hash in chain has been changed NewChainHead, /// A block is ready BlockVerified, - /// New transaction RLPs are ready to be imported - NewTransactions(Vec, usize), /// Begin snapshot restoration BeginRestoration(ManifestData), /// Feed a state chunk to the snapshot service @@ -35,9 +35,23 @@ pub enum ClientIoMessage { FeedBlockChunk(H256, Bytes), /// Take a snapshot for the block with given number. TakeSnapshot(u64), - /// New consensus message received. - NewMessage(Bytes), - /// New private transaction arrived - NewPrivateTransaction, + /// Execute wrapped closure + Execute(Callback), +} + +impl ClientIoMessage { + /// Create new `ClientIoMessage` that executes given procedure. + pub fn execute(fun: F) -> Self { + ClientIoMessage::Execute(Callback(Box::new(fun))) + } +} + +/// A function to invoke in the client thread. +pub struct Callback(pub Box); + +impl fmt::Debug for Callback { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + write!(fmt, "") + } } diff --git a/ethcore/src/client/mod.rs b/ethcore/src/client/mod.rs index 05e2018258..4c410d3011 100644 --- a/ethcore/src/client/mod.rs +++ b/ethcore/src/client/mod.rs @@ -36,9 +36,8 @@ pub use self::traits::{ Nonce, Balance, ChainInfo, BlockInfo, ReopenBlock, PrepareOpenBlock, CallContract, TransactionInfo, RegistryInfo, ScheduleInfo, ImportSealedBlock, BroadcastProposalBlock, ImportBlock, StateOrBlock, StateClient, Call, EngineInfo, AccountData, BlockChain, BlockProducer, SealedBlockImporter }; -//pub use self::private_notify::PrivateNotify; pub use state::StateInfo; -pub use self::traits::{BlockChainClient, EngineClient, ProvingBlockChainClient}; +pub use self::traits::{BlockChainClient, EngineClient, ProvingBlockChainClient, IoClient}; pub use types::ids::*; pub use types::trace_filter::Filter as TraceFilter; diff --git a/ethcore/src/client/test_client.rs b/ethcore/src/client/test_client.rs index c2e06009b6..b229159667 100644 --- a/ethcore/src/client/test_client.rs +++ b/ethcore/src/client/test_client.rs @@ -39,7 +39,7 @@ use client::{ PrepareOpenBlock, BlockChainClient, BlockChainInfo, BlockStatus, BlockId, TransactionId, UncleId, TraceId, TraceFilter, LastHashes, CallAnalytics, BlockImportError, ProvingBlockChainClient, ScheduleInfo, ImportSealedBlock, BroadcastProposalBlock, ImportBlock, StateOrBlock, - Call, StateClient, EngineInfo, AccountData, BlockChain, BlockProducer, SealedBlockImporter + Call, StateClient, EngineInfo, AccountData, BlockChain, BlockProducer, SealedBlockImporter, IoClient }; use db::{NUM_COLUMNS, COL_STATE}; use header::{Header as BlockHeader, BlockNumber}; @@ -556,10 +556,6 @@ impl ImportBlock for TestBlockChainClient { } Ok(h) } - - fn import_block_with_receipts(&self, b: Bytes, _r: Bytes) -> Result { - self.import_block(b) - } } impl Call for TestBlockChainClient { @@ -809,16 +805,6 @@ impl BlockChainClient for TestBlockChainClient { self.traces.read().clone() } - fn queue_transactions(&self, transactions: Vec, _peer_id: usize) { - // import right here - let txs = transactions.into_iter().filter_map(|bytes| Rlp::new(&bytes).as_val().ok()).collect(); - self.miner.import_external_transactions(self, txs); - } - - fn queue_consensus_message(&self, message: Bytes) { - self.spec.engine.handle_message(&message).unwrap(); - } - fn ready_transactions(&self) -> Vec> { self.miner.ready_transactions(self) } @@ -863,6 +849,22 @@ impl BlockChainClient for TestBlockChainClient { fn eip86_transition(&self) -> u64 { u64::max_value() } } +impl IoClient for TestBlockChainClient { + fn queue_transactions(&self, transactions: Vec, _peer_id: usize) { + // import right here + let txs = transactions.into_iter().filter_map(|bytes| Rlp::new(&bytes).as_val().ok()).collect(); + self.miner.import_external_transactions(self, txs); + } + + fn queue_ancient_block(&self, b: Bytes, _r: Bytes) -> Result { + self.import_block(b) + } + + fn queue_consensus_message(&self, message: Bytes) { + self.spec.engine.handle_message(&message).unwrap(); + } +} + impl ProvingBlockChainClient for TestBlockChainClient { fn prove_storage(&self, _: H256, _: H256, _: BlockId) -> Option<(Vec, H256)> { None diff --git a/ethcore/src/client/traits.rs b/ethcore/src/client/traits.rs index 7d4d5846c6..358e24fa90 100644 --- a/ethcore/src/client/traits.rs +++ b/ethcore/src/client/traits.rs @@ -168,9 +168,6 @@ pub trait RegistryInfo { pub trait ImportBlock { /// Import a block into the blockchain. fn import_block(&self, bytes: Bytes) -> Result; - - /// Import a block with transaction receipts. Does no sealing and transaction validation. - fn import_block_with_receipts(&self, block_bytes: Bytes, receipts_bytes: Bytes) -> Result; } /// Provides `call_contract` method @@ -201,8 +198,21 @@ pub trait EngineInfo { fn engine(&self) -> &EthEngine; } +/// IO operations that should off-load heavy work to another thread. +pub trait IoClient: Sync + Send { + /// Queue transactions for importing. + fn queue_transactions(&self, transactions: Vec, peer_id: usize); + + /// Queue block import with transaction receipts. Does no sealing and transaction validation. + fn queue_ancient_block(&self, block_bytes: Bytes, receipts_bytes: Bytes) -> Result; + + /// Queue conensus engine message. + fn queue_consensus_message(&self, message: Bytes); +} + /// Blockchain database client. Owns and manages a blockchain and a block queue. -pub trait BlockChainClient : Sync + Send + AccountData + BlockChain + CallContract + RegistryInfo + ImportBlock { +pub trait BlockChainClient : Sync + Send + AccountData + BlockChain + CallContract + RegistryInfo + ImportBlock ++ IoClient { /// Look up the block number for the given block ID. fn block_number(&self, id: BlockId) -> Option; @@ -310,12 +320,6 @@ pub trait BlockChainClient : Sync + Send + AccountData + BlockChain + CallContra /// Get last hashes starting from best block. fn last_hashes(&self) -> LastHashes; - /// Queue transactions for importing. - fn queue_transactions(&self, transactions: Vec, peer_id: usize); - - /// Queue conensus engine message. - fn queue_consensus_message(&self, message: Bytes); - /// List all transactions that are allowed into the next block. fn ready_transactions(&self) -> Vec>; diff --git a/ethcore/src/views/block.rs b/ethcore/src/views/block.rs index f610504d85..3bed1818f2 100644 --- a/ethcore/src/views/block.rs +++ b/ethcore/src/views/block.rs @@ -29,7 +29,6 @@ pub struct BlockView<'a> { rlp: ViewRlp<'a> } - impl<'a> BlockView<'a> { /// Creates new view onto block from rlp. /// Use the `view!` macro to create this view in order to capture debugging info. @@ -39,9 +38,9 @@ impl<'a> BlockView<'a> { /// ``` /// #[macro_use] /// extern crate ethcore; - /// + /// /// use ethcore::views::{BlockView}; - /// + /// /// fn main() { /// let bytes : &[u8] = &[]; /// let block_view = view!(BlockView, bytes); diff --git a/ethcore/sync/Cargo.toml b/ethcore/sync/Cargo.toml index d2d060e686..ba03075d0e 100644 --- a/ethcore/sync/Cargo.toml +++ b/ethcore/sync/Cargo.toml @@ -30,6 +30,7 @@ heapsize = "0.4" semver = "0.9" smallvec = { version = "0.4", features = ["heapsizeof"] } parking_lot = "0.5" +trace-time = { path = "../../util/trace-time" } ipnetwork = "0.12.6" [dev-dependencies] diff --git a/ethcore/sync/src/api.rs b/ethcore/sync/src/api.rs index 7690eeb864..4fd0cbb54d 100644 --- a/ethcore/sync/src/api.rs +++ b/ethcore/sync/src/api.rs @@ -379,10 +379,12 @@ impl NetworkProtocolHandler for SyncProtocolHandler { } fn read(&self, io: &NetworkContext, peer: &PeerId, packet_id: u8, data: &[u8]) { + trace_time!("sync::read"); ChainSync::dispatch_packet(&self.sync, &mut NetSyncIo::new(io, &*self.chain, &*self.snapshot_service, &self.overlay), *peer, packet_id, data); } fn connected(&self, io: &NetworkContext, peer: &PeerId) { + trace_time!("sync::connected"); // If warp protocol is supported only allow warp handshake let warp_protocol = io.protocol_version(WARP_SYNC_PROTOCOL_ID, *peer).unwrap_or(0) != 0; let warp_context = io.subprotocol_name() == WARP_SYNC_PROTOCOL_ID; @@ -392,12 +394,14 @@ impl NetworkProtocolHandler for SyncProtocolHandler { } fn disconnected(&self, io: &NetworkContext, peer: &PeerId) { + trace_time!("sync::disconnected"); if io.subprotocol_name() != WARP_SYNC_PROTOCOL_ID { self.sync.write().on_peer_aborting(&mut NetSyncIo::new(io, &*self.chain, &*self.snapshot_service, &self.overlay), *peer); } } fn timeout(&self, io: &NetworkContext, _timer: TimerToken) { + trace_time!("sync::timeout"); let mut io = NetSyncIo::new(io, &*self.chain, &*self.snapshot_service, &self.overlay); self.sync.write().maintain_peers(&mut io); self.sync.write().maintain_sync(&mut io); diff --git a/ethcore/sync/src/block_sync.rs b/ethcore/sync/src/block_sync.rs index 4a5acae526..7411fa30cc 100644 --- a/ethcore/sync/src/block_sync.rs +++ b/ethcore/sync/src/block_sync.rs @@ -496,7 +496,7 @@ impl BlockDownloader { } let result = if let Some(receipts) = receipts { - io.chain().import_block_with_receipts(block, receipts) + io.chain().queue_ancient_block(block, receipts) } else { io.chain().import_block(block) }; diff --git a/ethcore/sync/src/chain.rs b/ethcore/sync/src/chain.rs index 25d9a09f6b..1a6af10115 100644 --- a/ethcore/sync/src/chain.rs +++ b/ethcore/sync/src/chain.rs @@ -1789,10 +1789,13 @@ impl ChainSync { } pub fn on_packet(&mut self, io: &mut SyncIo, peer: PeerId, packet_id: u8, data: &[u8]) { + debug!(target: "sync", "{} -> Dispatching packet: {}", peer, packet_id); + if packet_id != STATUS_PACKET && !self.peers.contains_key(&peer) { debug!(target:"sync", "Unexpected packet {} from unregistered peer: {}:{}", packet_id, peer, io.peer_info(peer)); return; } + let rlp = Rlp::new(data); let result = match packet_id { STATUS_PACKET => self.on_peer_status(io, peer, &rlp), @@ -1831,7 +1834,7 @@ impl ChainSync { PeerAsking::SnapshotData => elapsed > SNAPSHOT_DATA_TIMEOUT, }; if timeout { - trace!(target:"sync", "Timeout {}", peer_id); + debug!(target:"sync", "Timeout {}", peer_id); io.disconnect_peer(*peer_id); aborting.push(*peer_id); } diff --git a/ethcore/sync/src/lib.rs b/ethcore/sync/src/lib.rs index a3e24bdb82..3eb2e8332b 100644 --- a/ethcore/sync/src/lib.rs +++ b/ethcore/sync/src/lib.rs @@ -54,6 +54,8 @@ extern crate macros; extern crate log; #[macro_use] extern crate heapsize; +#[macro_use] +extern crate trace_time; mod chain; mod blocks; diff --git a/ethcore/sync/src/tests/helpers.rs b/ethcore/sync/src/tests/helpers.rs index dc52fdd8b8..3a4697cc09 100644 --- a/ethcore/sync/src/tests/helpers.rs +++ b/ethcore/sync/src/tests/helpers.rs @@ -520,11 +520,9 @@ impl TestIoHandler { impl IoHandler for TestIoHandler { fn message(&self, _io: &IoContext, net_message: &ClientIoMessage) { match *net_message { - ClientIoMessage::NewMessage(ref message) => if let Err(e) = self.client.engine().handle_message(message) { - panic!("Invalid message received: {}", e); - }, - ClientIoMessage::NewPrivateTransaction => { + ClientIoMessage::Execute(ref exec) => { *self.private_tx_queued.lock() += 1; + (*exec.0)(&self.client); }, _ => {} // ignore other messages } diff --git a/ethcore/sync/src/tests/private.rs b/ethcore/sync/src/tests/private.rs index a9e8718e5e..b54240bfb8 100644 --- a/ethcore/sync/src/tests/private.rs +++ b/ethcore/sync/src/tests/private.rs @@ -24,7 +24,7 @@ use ethcore::CreateContractAddress; use transaction::{Transaction, Action}; use ethcore::executive::{contract_address}; use ethcore::test_helpers::{push_block_with_transactions}; -use ethcore_private_tx::{Provider, ProviderConfig, NoopEncryptor}; +use ethcore_private_tx::{Provider, ProviderConfig, NoopEncryptor, Importer}; use ethcore::account_provider::AccountProvider; use ethkey::{KeyPair}; use tests::helpers::{TestNet, TestIoHandler}; @@ -84,7 +84,7 @@ fn send_private_transaction() { Box::new(NoopEncryptor::default()), signer_config, IoChannel::to_handler(Arc::downgrade(&io_handler0)), - ).unwrap()); + )); pm0.add_notify(net.peers[0].clone()); let pm1 = Arc::new(Provider::new( @@ -94,7 +94,7 @@ fn send_private_transaction() { Box::new(NoopEncryptor::default()), validator_config, IoChannel::to_handler(Arc::downgrade(&io_handler1)), - ).unwrap()); + )); pm1.add_notify(net.peers[1].clone()); // Create and deploy contract @@ -133,7 +133,6 @@ fn send_private_transaction() { //process received private transaction message let private_transaction = received_private_transactions[0].clone(); assert!(pm1.import_private_transaction(&private_transaction).is_ok()); - assert!(pm1.on_private_transaction_queued().is_ok()); //send signed response net.sync(); @@ -147,4 +146,4 @@ fn send_private_transaction() { assert!(pm0.import_signed_private_transaction(&signed_private_transaction).is_ok()); let local_transactions = net.peer(0).miner.local_transactions(); assert_eq!(local_transactions.len(), 1); -} \ No newline at end of file +} diff --git a/util/io/src/lib.rs b/util/io/src/lib.rs index 20b908ac91..9232b2a909 100644 --- a/util/io/src/lib.rs +++ b/util/io/src/lib.rs @@ -106,7 +106,7 @@ impl From<::std::io::Error> for IoError { } } -impl From>> for IoError where Message: Send + Clone { +impl From>> for IoError where Message: Send { fn from(_err: NotifyError>) -> IoError { IoError::Mio(::std::io::Error::new(::std::io::ErrorKind::ConnectionAborted, "Network IO notification error")) } @@ -115,7 +115,7 @@ impl From>> for IoError where M /// Generic IO handler. /// All the handler function are called from within IO event loop. /// `Message` type is used as notification data -pub trait IoHandler: Send + Sync where Message: Send + Sync + Clone + 'static { +pub trait IoHandler: Send + Sync where Message: Send + Sync + 'static { /// Initialize the handler fn initialize(&self, _io: &IoContext) {} /// Timer function called after a timeout created with `HandlerIo::timeout`. diff --git a/util/io/src/service.rs b/util/io/src/service.rs index 19f2d4b3bb..0de674ae12 100644 --- a/util/io/src/service.rs +++ b/util/io/src/service.rs @@ -41,7 +41,7 @@ const MAX_HANDLERS: usize = 8; /// Messages used to communicate with the event loop from other threads. #[derive(Clone)] -pub enum IoMessage where Message: Send + Clone + Sized { +pub enum IoMessage where Message: Send + Sized { /// Shutdown the event loop Shutdown, /// Register a new protocol handler. @@ -74,16 +74,16 @@ pub enum IoMessage where Message: Send + Clone + Sized { token: StreamToken, }, /// Broadcast a message across all protocol handlers. - UserMessage(Message) + UserMessage(Arc) } /// IO access point. This is passed to all IO handlers and provides an interface to the IO subsystem. -pub struct IoContext where Message: Send + Clone + Sync + 'static { +pub struct IoContext where Message: Send + Sync + 'static { channel: IoChannel, handler: HandlerId, } -impl IoContext where Message: Send + Clone + Sync + 'static { +impl IoContext where Message: Send + Sync + 'static { /// Create a new IO access point. Takes references to all the data that can be updated within the IO handler. pub fn new(channel: IoChannel, handler: HandlerId) -> IoContext { IoContext { @@ -187,7 +187,7 @@ pub struct IoManager where Message: Send + Sync { work_ready: Arc, } -impl IoManager where Message: Send + Sync + Clone + 'static { +impl IoManager where Message: Send + Sync + 'static { /// Creates a new instance and registers it with the event loop. pub fn start( event_loop: &mut EventLoop>, @@ -219,7 +219,7 @@ impl IoManager where Message: Send + Sync + Clone + 'static { } } -impl Handler for IoManager where Message: Send + Clone + Sync + 'static { +impl Handler for IoManager where Message: Send + Sync + 'static { type Timeout = Token; type Message = IoMessage; @@ -317,7 +317,12 @@ impl Handler for IoManager where Message: Send + Clone + Sync for id in 0 .. MAX_HANDLERS { if let Some(h) = self.handlers.read().get(id) { let handler = h.clone(); - self.worker_channel.push(Work { work_type: WorkType::Message(data.clone()), token: 0, handler: handler, handler_id: id }); + self.worker_channel.push(Work { + work_type: WorkType::Message(data.clone()), + token: 0, + handler: handler, + handler_id: id + }); } } self.work_ready.notify_all(); @@ -326,21 +331,30 @@ impl Handler for IoManager where Message: Send + Clone + Sync } } -#[derive(Clone)] -enum Handlers where Message: Send + Clone { +enum Handlers where Message: Send { SharedCollection(Weak>, HandlerId>>>), Single(Weak>), } +impl Clone for Handlers { + fn clone(&self) -> Self { + use self::Handlers::*; + + match *self { + SharedCollection(ref w) => SharedCollection(w.clone()), + Single(ref w) => Single(w.clone()), + } + } +} + /// Allows sending messages into the event loop. All the IO handlers will get the message /// in the `message` callback. -pub struct IoChannel where Message: Send + Clone{ +pub struct IoChannel where Message: Send { channel: Option>>, handlers: Handlers, - } -impl Clone for IoChannel where Message: Send + Clone + Sync + 'static { +impl Clone for IoChannel where Message: Send + Sync + 'static { fn clone(&self) -> IoChannel { IoChannel { channel: self.channel.clone(), @@ -349,11 +363,11 @@ impl Clone for IoChannel where Message: Send + Clone + Sync + } } -impl IoChannel where Message: Send + Clone + Sync + 'static { +impl IoChannel where Message: Send + Sync + 'static { /// Send a message through the channel pub fn send(&self, message: Message) -> Result<(), IoError> { match self.channel { - Some(ref channel) => channel.send(IoMessage::UserMessage(message))?, + Some(ref channel) => channel.send(IoMessage::UserMessage(Arc::new(message)))?, None => self.send_sync(message)? } Ok(()) @@ -413,13 +427,13 @@ impl IoChannel where Message: Send + Clone + Sync + 'static { /// General IO Service. Starts an event loop and dispatches IO requests. /// 'Message' is a notification message type -pub struct IoService where Message: Send + Sync + Clone + 'static { +pub struct IoService where Message: Send + Sync + 'static { thread: Mutex>>, host_channel: Mutex>>, handlers: Arc>, HandlerId>>>, } -impl IoService where Message: Send + Sync + Clone + 'static { +impl IoService where Message: Send + Sync + 'static { /// Starts IO event loop pub fn start() -> Result, IoError> { let mut config = EventLoopBuilder::new(); @@ -462,7 +476,7 @@ impl IoService where Message: Send + Sync + Clone + 'static { /// Send a message over the network. Normaly `HostIo::send` should be used. This can be used from non-io threads. pub fn send_message(&self, message: Message) -> Result<(), IoError> { - self.host_channel.lock().send(IoMessage::UserMessage(message))?; + self.host_channel.lock().send(IoMessage::UserMessage(Arc::new(message)))?; Ok(()) } @@ -472,7 +486,7 @@ impl IoService where Message: Send + Sync + Clone + 'static { } } -impl Drop for IoService where Message: Send + Sync + Clone { +impl Drop for IoService where Message: Send + Sync { fn drop(&mut self) { self.stop() } diff --git a/util/io/src/worker.rs b/util/io/src/worker.rs index 79570d3612..0f0d448ecb 100644 --- a/util/io/src/worker.rs +++ b/util/io/src/worker.rs @@ -38,7 +38,7 @@ pub enum WorkType { Writable, Hup, Timeout, - Message(Message) + Message(Arc) } pub struct Work { @@ -65,7 +65,7 @@ impl Worker { wait: Arc, wait_mutex: Arc>, ) -> Worker - where Message: Send + Sync + Clone + 'static { + where Message: Send + Sync + 'static { let deleting = Arc::new(AtomicBool::new(false)); let mut worker = Worker { thread: None, @@ -86,7 +86,7 @@ impl Worker { channel: IoChannel, wait: Arc, wait_mutex: Arc>, deleting: Arc) - where Message: Send + Sync + Clone + 'static { + where Message: Send + Sync + 'static { loop { { let lock = wait_mutex.lock().expect("Poisoned work_loop mutex"); @@ -105,7 +105,7 @@ impl Worker { } } - fn do_work(work: Work, channel: IoChannel) where Message: Send + Sync + Clone + 'static { + fn do_work(work: Work, channel: IoChannel) where Message: Send + Sync + 'static { match work.work_type { WorkType::Readable => { work.handler.stream_readable(&IoContext::new(channel, work.handler_id), work.token); @@ -120,7 +120,7 @@ impl Worker { work.handler.timeout(&IoContext::new(channel, work.handler_id), work.token); } WorkType::Message(message) => { - work.handler.message(&IoContext::new(channel, work.handler_id), &message); + work.handler.message(&IoContext::new(channel, work.handler_id), &*message); } } } -- GitLab From f20f9f376ef6a713400e2ba18353268bd35129fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Wed, 9 May 2018 08:54:37 +0200 Subject: [PATCH 016/152] Make trace-time publishable. (#8568) --- transaction-pool/Cargo.toml | 2 +- util/trace-time/Cargo.toml | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/transaction-pool/Cargo.toml b/transaction-pool/Cargo.toml index 342c376f63..8965c8cee0 100644 --- a/transaction-pool/Cargo.toml +++ b/transaction-pool/Cargo.toml @@ -9,7 +9,7 @@ authors = ["Parity Technologies "] error-chain = "0.11" log = "0.3" smallvec = "0.4" -trace-time = { path = "../util/trace-time" } +trace-time = { path = "../util/trace-time", version = "0.1" } [dev-dependencies] ethereum-types = "0.3" diff --git a/util/trace-time/Cargo.toml b/util/trace-time/Cargo.toml index 00597ebfc4..288a2c4e47 100644 --- a/util/trace-time/Cargo.toml +++ b/util/trace-time/Cargo.toml @@ -1,7 +1,9 @@ [package] name = "trace-time" +description = "Easily trace time to execute a scope." version = "0.1.0" authors = ["Parity Technologies "] +license = "GPL-3.0" [dependencies] log = "0.3" -- GitLab From b84682168d46716f455c53ee35166ad7e8e6f7ce Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Wed, 9 May 2018 14:55:01 +0800 Subject: [PATCH 017/152] Remove State::replace_backend (#8569) --- ethcore/src/state/mod.rs | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/ethcore/src/state/mod.rs b/ethcore/src/state/mod.rs index 20d564588c..5b969bccb9 100644 --- a/ethcore/src/state/mod.rs +++ b/ethcore/src/state/mod.rs @@ -402,19 +402,6 @@ impl State { self.factories.vm.clone() } - /// Swap the current backend for another. - // TODO: [rob] find a less hacky way to avoid duplication of `Client::state_at`. - pub fn replace_backend(self, backend: T) -> State { - State { - db: backend, - root: self.root, - cache: self.cache, - checkpoints: self.checkpoints, - account_start_nonce: self.account_start_nonce, - factories: self.factories, - } - } - /// Create a recoverable checkpoint of this state. pub fn checkpoint(&mut self) { self.checkpoints.get_mut().push(HashMap::new()); -- GitLab From 8b0ba97cf2cec8c79b368e907d975484acaef504 Mon Sep 17 00:00:00 2001 From: Nicolas Gotchac Date: Wed, 9 May 2018 12:05:34 +0200 Subject: [PATCH 018/152] Refactoring `ethcore-sync` - Fixing warp-sync barrier (#8543) * Start dividing sync chain : first supplier method * WIP - updated chain sync supplier * Finish refactoring the Chain Sync Supplier * Create Chain Sync Requester * Add Propagator for Chain Sync * Add the Chain Sync Handler * Move tests from mod -> handler * Move tests to propagator * Refactor SyncRequester arguments * Refactoring peer fork header handler * Fix wrong highest block number in snapshot sync * Small refactor... * Address PR grumbles * Retry failed CI job * Fix tests * PR Grumbles --- ethcore/sync/src/chain.rs | 3112 -------------------------- ethcore/sync/src/chain/handler.rs | 828 +++++++ ethcore/sync/src/chain/mod.rs | 1379 ++++++++++++ ethcore/sync/src/chain/propagator.rs | 636 ++++++ ethcore/sync/src/chain/requester.rs | 154 ++ ethcore/sync/src/chain/supplier.rs | 446 ++++ ethcore/sync/src/tests/snapshot.rs | 12 +- 7 files changed, 3453 insertions(+), 3114 deletions(-) delete mode 100644 ethcore/sync/src/chain.rs create mode 100644 ethcore/sync/src/chain/handler.rs create mode 100644 ethcore/sync/src/chain/mod.rs create mode 100644 ethcore/sync/src/chain/propagator.rs create mode 100644 ethcore/sync/src/chain/requester.rs create mode 100644 ethcore/sync/src/chain/supplier.rs diff --git a/ethcore/sync/src/chain.rs b/ethcore/sync/src/chain.rs deleted file mode 100644 index 1a6af10115..0000000000 --- a/ethcore/sync/src/chain.rs +++ /dev/null @@ -1,3112 +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 . - -/// `BlockChain` synchronization strategy. -/// Syncs to peers and keeps up to date. -/// This implementation uses ethereum protocol v63 -/// -/// Syncing strategy summary. -/// Split the chain into ranges of N blocks each. Download ranges sequentially. Split each range into subchains of M blocks. Download subchains in parallel. -/// State. -/// Sync state consists of the following data: -/// - s: State enum which can be one of the following values: `ChainHead`, `Blocks`, `Idle` -/// - H: A set of downloaded block headers -/// - B: A set of downloaded block bodies -/// - S: Set of block subchain start block hashes to download. -/// - l: Last imported / common block hash -/// - P: A set of connected peers. For each peer we maintain its last known total difficulty and starting block hash being requested if any. -/// General behaviour. -/// We start with all sets empty, l is set to the best block in the block chain, s is set to `ChainHead`. -/// If at any moment a bad block is reported by the block queue, we set s to `ChainHead`, reset l to the best block in the block chain and clear H, B and S. -/// If at any moment P becomes empty, we set s to `ChainHead`, and clear H, B and S. -/// -/// Workflow for `ChainHead` state. -/// In this state we try to get subchain headers with a single `GetBlockHeaders` request. -/// On `NewPeer` / On `Restart`: -/// If peer's total difficulty is higher and there are less than 5 peers downloading, request N/M headers with interval M+1 starting from l -/// On `BlockHeaders(R)`: -/// If R is empty: -/// If l is equal to genesis block hash or l is more than 1000 blocks behind our best hash: -/// Remove current peer from P. set l to the best block in the block chain. Select peer with maximum total difficulty from P and restart. -/// Else -/// Set l to l’s parent and restart. -/// Else if we already have all the headers in the block chain or the block queue: -/// Set s to `Idle`, -/// Else -/// Set S to R, set s to `Blocks`. -/// -/// All other messages are ignored. -/// -/// Workflow for `Blocks` state. -/// In this state we download block headers and bodies from multiple peers. -/// On `NewPeer` / On `Restart`: -/// For all idle peers: -/// Find a set of 256 or less block hashes in H which are not in B and not being downloaded by other peers. If the set is not empty: -/// Request block bodies for the hashes in the set. -/// Else -/// Find an element in S which is not being downloaded by other peers. If found: Request M headers starting from the element. -/// -/// On `BlockHeaders(R)`: -/// If R is empty remove current peer from P and restart. -/// Validate received headers: -/// For each header find a parent in H or R or the blockchain. Restart if there is a block with unknown parent. -/// Find at least one header from the received list in S. Restart if there is none. -/// Go to `CollectBlocks`. -/// -/// On `BlockBodies(R)`: -/// If R is empty remove current peer from P and restart. -/// Add bodies with a matching header in H to B. -/// Go to `CollectBlocks`. -/// -/// `CollectBlocks`: -/// Find a chain of blocks C in H starting from h where h’s parent equals to l. The chain ends with the first block which does not have a body in B. -/// Add all blocks from the chain to the block queue. Remove them from H and B. Set l to the hash of the last block from C. -/// Update and merge subchain heads in S. For each h in S find a chain of blocks in B starting from h. Remove h from S. if the chain does not include an element from S add the end of the chain to S. -/// If H is empty and S contains a single element set s to `ChainHead`. -/// Restart. -/// -/// All other messages are ignored. -/// Workflow for Idle state. -/// On `NewBlock`: -/// Import the block. If the block is unknown set s to `ChainHead` and restart. -/// On `NewHashes`: -/// Set s to `ChainHead` and restart. -/// -/// All other messages are ignored. -/// - -use std::sync::Arc; -use std::collections::{HashSet, HashMap}; -use std::cmp; -use std::time::{Duration, Instant}; -use hash::keccak; -use heapsize::HeapSizeOf; -use ethereum_types::{H256, U256}; -use plain_hasher::H256FastMap; -use parking_lot::RwLock; -use bytes::Bytes; -use rlp::{Rlp, RlpStream, DecoderError, Encodable}; -use network::{self, PeerId, PacketId}; -use ethcore::header::{BlockNumber, Header as BlockHeader}; -use ethcore::client::{BlockChainClient, BlockStatus, BlockId, BlockChainInfo, BlockImportError, BlockImportErrorKind, BlockQueueInfo}; -use ethcore::error::*; -use ethcore::snapshot::{ManifestData, RestorationStatus}; -use transaction::SignedTransaction; -use sync_io::SyncIo; -use super::{WarpSync, SyncConfig}; -use block_sync::{BlockDownloader, BlockRequest, BlockDownloaderImportError as DownloaderImportError, DownloadAction}; -use rand::Rng; -use snapshot::{Snapshot, ChunkType}; -use api::{EthProtocolInfo as PeerInfoDigest, WARP_SYNC_PROTOCOL_ID}; -use private_tx::PrivateTxHandler; -use transactions_stats::{TransactionsStats, Stats as TransactionStats}; -use transaction::UnverifiedTransaction; - -known_heap_size!(0, PeerInfo); - -type PacketDecodeError = DecoderError; - -/// 63 version of Ethereum protocol. -pub const ETH_PROTOCOL_VERSION_63: u8 = 63; -/// 62 version of Ethereum protocol. -pub const ETH_PROTOCOL_VERSION_62: u8 = 62; -/// 1 version of Parity protocol. -pub const PAR_PROTOCOL_VERSION_1: u8 = 1; -/// 2 version of Parity protocol (consensus messages added). -pub const PAR_PROTOCOL_VERSION_2: u8 = 2; -/// 3 version of Parity protocol (private transactions messages added). -pub const PAR_PROTOCOL_VERSION_3: u8 = 3; - -const MAX_BODIES_TO_SEND: usize = 256; -const MAX_HEADERS_TO_SEND: usize = 512; -const MAX_NODE_DATA_TO_SEND: usize = 1024; -const MAX_RECEIPTS_TO_SEND: usize = 1024; -const MAX_RECEIPTS_HEADERS_TO_SEND: usize = 256; -const MIN_PEERS_PROPAGATION: usize = 4; -const MAX_PEERS_PROPAGATION: usize = 128; -const MAX_PEER_LAG_PROPAGATION: BlockNumber = 20; -const MAX_NEW_HASHES: usize = 64; -const MAX_NEW_BLOCK_AGE: BlockNumber = 20; -// maximal packet size with transactions (cannot be greater than 16MB - protocol limitation). -const MAX_TRANSACTION_PACKET_SIZE: usize = 8 * 1024 * 1024; -// Maximal number of transactions in sent in single packet. -const MAX_TRANSACTIONS_TO_PROPAGATE: usize = 64; -// Min number of blocks to be behind for a snapshot sync -const SNAPSHOT_RESTORE_THRESHOLD: BlockNumber = 30000; -const SNAPSHOT_MIN_PEERS: usize = 3; - -const STATUS_PACKET: u8 = 0x00; -const NEW_BLOCK_HASHES_PACKET: u8 = 0x01; -const TRANSACTIONS_PACKET: u8 = 0x02; -const GET_BLOCK_HEADERS_PACKET: u8 = 0x03; -const BLOCK_HEADERS_PACKET: u8 = 0x04; -const GET_BLOCK_BODIES_PACKET: u8 = 0x05; -const BLOCK_BODIES_PACKET: u8 = 0x06; -const NEW_BLOCK_PACKET: u8 = 0x07; - -const GET_NODE_DATA_PACKET: u8 = 0x0d; -const NODE_DATA_PACKET: u8 = 0x0e; -const GET_RECEIPTS_PACKET: u8 = 0x0f; -const RECEIPTS_PACKET: u8 = 0x10; - -pub const ETH_PACKET_COUNT: u8 = 0x11; - -const GET_SNAPSHOT_MANIFEST_PACKET: u8 = 0x11; -const SNAPSHOT_MANIFEST_PACKET: u8 = 0x12; -const GET_SNAPSHOT_DATA_PACKET: u8 = 0x13; -const SNAPSHOT_DATA_PACKET: u8 = 0x14; -const CONSENSUS_DATA_PACKET: u8 = 0x15; -const PRIVATE_TRANSACTION_PACKET: u8 = 0x16; -const SIGNED_PRIVATE_TRANSACTION_PACKET: u8 = 0x17; - -pub const SNAPSHOT_SYNC_PACKET_COUNT: u8 = 0x18; - -const MAX_SNAPSHOT_CHUNKS_DOWNLOAD_AHEAD: usize = 3; - -const WAIT_PEERS_TIMEOUT: Duration = Duration::from_secs(5); -const STATUS_TIMEOUT: Duration = Duration::from_secs(5); -const HEADERS_TIMEOUT: Duration = Duration::from_secs(15); -const BODIES_TIMEOUT: Duration = Duration::from_secs(20); -const RECEIPTS_TIMEOUT: Duration = Duration::from_secs(10); -const FORK_HEADER_TIMEOUT: Duration = Duration::from_secs(3); -const SNAPSHOT_MANIFEST_TIMEOUT: Duration = Duration::from_secs(5); -const SNAPSHOT_DATA_TIMEOUT: Duration = Duration::from_secs(120); - -#[derive(Copy, Clone, Eq, PartialEq, Debug)] -/// Sync state -pub enum SyncState { - /// Collecting enough peers to start syncing. - WaitingPeers, - /// Waiting for snapshot manifest download - SnapshotManifest, - /// Downloading snapshot data - SnapshotData, - /// Waiting for snapshot restoration progress. - SnapshotWaiting, - /// Downloading new blocks - Blocks, - /// Initial chain sync complete. Waiting for new packets - Idle, - /// Block downloading paused. Waiting for block queue to process blocks and free some space - Waiting, - /// Downloading blocks learned from `NewHashes` packet - NewBlocks, -} - -/// Syncing status and statistics -#[derive(Clone, Copy)] -pub struct SyncStatus { - /// State - pub state: SyncState, - /// Syncing protocol version. That's the maximum protocol version we connect to. - pub protocol_version: u8, - /// The underlying p2p network version. - pub network_id: u64, - /// `BlockChain` height for the moment the sync started. - pub start_block_number: BlockNumber, - /// Last fully downloaded and imported block number (if any). - pub last_imported_block_number: Option, - /// Highest block number in the download queue (if any). - pub highest_block_number: Option, - /// Total number of blocks for the sync process. - pub blocks_total: BlockNumber, - /// Number of blocks downloaded so far. - pub blocks_received: BlockNumber, - /// Total number of connected peers - pub num_peers: usize, - /// Total number of active peers. - pub num_active_peers: usize, - /// Heap memory used in bytes. - pub mem_used: usize, - /// Snapshot chunks - pub num_snapshot_chunks: usize, - /// Snapshot chunks downloaded - pub snapshot_chunks_done: usize, - /// Last fully downloaded and imported ancient block number (if any). - pub last_imported_old_block_number: Option, -} - -impl SyncStatus { - /// Indicates if snapshot download is in progress - pub fn is_snapshot_syncing(&self) -> bool { - self.state == SyncState::SnapshotManifest - || self.state == SyncState::SnapshotData - || self.state == SyncState::SnapshotWaiting - } - - /// Returns max no of peers to display in informants - pub fn current_max_peers(&self, min_peers: u32, max_peers: u32) -> u32 { - if self.num_peers as u32 > min_peers { - max_peers - } else { - min_peers - } - } - - /// Is it doing a major sync? - pub fn is_syncing(&self, queue_info: BlockQueueInfo) -> bool { - let is_syncing_state = match self.state { SyncState::Idle | SyncState::NewBlocks => false, _ => true }; - let is_verifying = queue_info.unverified_queue_size + queue_info.verified_queue_size > 3; - is_verifying || is_syncing_state - } -} - -#[derive(PartialEq, Eq, Debug, Clone)] -/// Peer data type requested -enum PeerAsking { - Nothing, - ForkHeader, - BlockHeaders, - BlockBodies, - BlockReceipts, - SnapshotManifest, - SnapshotData, -} - -#[derive(PartialEq, Eq, Debug, Clone, Copy)] -/// Block downloader channel. -enum BlockSet { - /// New blocks better than out best blocks - NewBlocks, - /// Missing old blocks - OldBlocks, -} -#[derive(Clone, Eq, PartialEq)] -enum ForkConfirmation { - /// Fork block confirmation pending. - Unconfirmed, - /// Peers chain is too short to confirm the fork. - TooShort, - /// Fork is confirmed. - Confirmed, -} - -#[derive(Clone)] -/// Syncing peer information -struct PeerInfo { - /// eth protocol version - protocol_version: u8, - /// Peer chain genesis hash - genesis: H256, - /// Peer network id - network_id: u64, - /// Peer best block hash - latest_hash: H256, - /// Peer total difficulty if known - difficulty: Option, - /// Type of data currenty being requested from peer. - asking: PeerAsking, - /// A set of block numbers being requested - asking_blocks: Vec, - /// Holds requested header hash if currently requesting block header by hash - asking_hash: Option, - /// Holds requested snapshot chunk hash if any. - asking_snapshot_data: Option, - /// Request timestamp - ask_time: Instant, - /// Holds a set of transactions recently sent to this peer to avoid spamming. - last_sent_transactions: HashSet, - /// Pending request is expired and result should be ignored - expired: bool, - /// Peer fork confirmation status - confirmation: ForkConfirmation, - /// Best snapshot hash - snapshot_hash: Option, - /// Best snapshot block number - snapshot_number: Option, - /// Block set requested - block_set: Option, -} - -impl PeerInfo { - fn can_sync(&self) -> bool { - self.confirmation == ForkConfirmation::Confirmed && !self.expired - } - - fn is_allowed(&self) -> bool { - self.confirmation != ForkConfirmation::Unconfirmed && !self.expired - } - - fn reset_asking(&mut self) { - self.asking_blocks.clear(); - self.asking_hash = None; - // mark any pending requests as expired - if self.asking != PeerAsking::Nothing && self.is_allowed() { - self.expired = true; - } - } -} - -#[cfg(not(test))] -mod random { - use rand; - pub fn new() -> rand::ThreadRng { rand::thread_rng() } -} -#[cfg(test)] -mod random { - use rand::{self, SeedableRng}; - pub fn new() -> rand::XorShiftRng { rand::XorShiftRng::from_seed([0, 1, 2, 3]) } -} - -/// Blockchain sync handler. -/// See module documentation for more details. -pub struct ChainSync { - /// Sync state - state: SyncState, - /// Last block number for the start of sync - starting_block: BlockNumber, - /// Highest block number seen - highest_block: Option, - /// All connected peers - peers: HashMap, - /// Peers active for current sync round - active_peers: HashSet, - /// Block download process for new blocks - new_blocks: BlockDownloader, - /// Block download process for ancient blocks - old_blocks: Option, - /// Last propagated block number - last_sent_block_number: BlockNumber, - /// Network ID - network_id: u64, - /// Optional fork block to check - fork_block: Option<(BlockNumber, H256)>, - /// Snapshot downloader. - snapshot: Snapshot, - /// Connected peers pending Status message. - /// Value is request timestamp. - handshaking_peers: HashMap, - /// Sync start timestamp. Measured when first peer is connected - sync_start_time: Option, - /// Transactions propagation statistics - transactions_stats: TransactionsStats, - /// Enable ancient block downloading - download_old_blocks: bool, - /// Shared private tx service. - private_tx_handler: Arc, - /// Enable warp sync. - warp_sync: WarpSync, -} - -type RlpResponseResult = Result, PacketDecodeError>; - -impl ChainSync { - /// Create a new instance of syncing strategy. - pub fn new(config: SyncConfig, chain: &BlockChainClient, private_tx_handler: Arc) -> ChainSync { - let chain_info = chain.chain_info(); - let best_block = chain.chain_info().best_block_number; - let state = match config.warp_sync { - WarpSync::Enabled => SyncState::WaitingPeers, - WarpSync::OnlyAndAfter(block) if block > best_block => SyncState::WaitingPeers, - _ => SyncState::Idle, - }; - - let mut sync = ChainSync { - state, - starting_block: best_block, - highest_block: None, - peers: HashMap::new(), - handshaking_peers: HashMap::new(), - active_peers: HashSet::new(), - new_blocks: BlockDownloader::new(false, &chain_info.best_block_hash, chain_info.best_block_number), - old_blocks: None, - last_sent_block_number: 0, - network_id: config.network_id, - fork_block: config.fork_block, - download_old_blocks: config.download_old_blocks, - snapshot: Snapshot::new(), - sync_start_time: None, - transactions_stats: TransactionsStats::default(), - private_tx_handler, - warp_sync: config.warp_sync, - }; - sync.update_targets(chain); - sync - } - - /// Returns synchonization status - pub fn status(&self) -> SyncStatus { - let last_imported_number = self.new_blocks.last_imported_block_number(); - SyncStatus { - state: self.state.clone(), - protocol_version: ETH_PROTOCOL_VERSION_63, - network_id: self.network_id, - 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| 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(), - num_active_peers: self.peers.values().filter(|p| p.is_allowed() && p.asking != PeerAsking::Nothing).count(), - num_snapshot_chunks: self.snapshot.total_chunks(), - snapshot_chunks_done: self.snapshot.done_chunks(), - mem_used: - self.new_blocks.heap_size() - + self.old_blocks.as_ref().map_or(0, |d| d.heap_size()) - + self.peers.heap_size_of_children(), - } - } - - /// Returns information on peers connections - pub fn peer_info(&self, peer_id: &PeerId) -> Option { - self.peers.get(peer_id).map(|peer_data| { - PeerInfoDigest { - version: peer_data.protocol_version as u32, - difficulty: peer_data.difficulty, - head: peer_data.latest_hash, - } - }) - } - - /// Returns transactions propagation statistics - pub fn transactions_stats(&self) -> &H256FastMap { - self.transactions_stats.stats() - } - - /// Updates transactions were received by a peer - pub fn transactions_received(&mut self, txs: &[UnverifiedTransaction], peer_id: PeerId) { - if let Some(peer_info) = self.peers.get_mut(&peer_id) { - peer_info.last_sent_transactions.extend(txs.iter().map(|tx| tx.hash())); - } - } - - /// Abort all sync activity - pub fn abort(&mut self, io: &mut SyncIo) { - self.reset_and_continue(io); - self.peers.clear(); - } - - /// Reset sync. Clear all downloaded data but keep the queue - fn reset(&mut self, io: &mut SyncIo) { - self.new_blocks.reset(); - let chain_info = io.chain().chain_info(); - for (_, ref mut p) in &mut self.peers { - if p.block_set != Some(BlockSet::OldBlocks) { - p.reset_asking(); - if p.difficulty.is_none() { - // assume peer has up to date difficulty - p.difficulty = Some(chain_info.pending_total_difficulty); - } - } - } - self.state = SyncState::Idle; - // Reactivate peers only if some progress has been made - // since the last sync round of if starting fresh. - self.active_peers = self.peers.keys().cloned().collect(); - } - - /// Restart sync - pub fn reset_and_continue(&mut self, io: &mut SyncIo) { - trace!(target: "sync", "Restarting"); - if self.state == SyncState::SnapshotData { - debug!(target:"sync", "Aborting snapshot restore"); - io.snapshot_service().abort_restore(); - } - self.snapshot.clear(); - self.reset(io); - self.continue_sync(io); - } - - /// Remove peer from active peer set. Peer will be reactivated on the next sync - /// round. - fn deactivate_peer(&mut self, _io: &mut SyncIo, peer_id: PeerId) { - trace!(target: "sync", "Deactivating peer {}", peer_id); - self.active_peers.remove(&peer_id); - } - - fn maybe_start_snapshot_sync(&mut self, io: &mut SyncIo) { - if !self.warp_sync.is_enabled() || io.snapshot_service().supported_versions().is_none() { - trace!(target: "sync", "Skipping warp sync. Disabled or not supported."); - return; - } - if self.state != SyncState::WaitingPeers && self.state != SyncState::Blocks && self.state != SyncState::Waiting { - trace!(target: "sync", "Skipping warp sync. State: {:?}", self.state); - return; - } - // Make sure the snapshot block is not too far away from best block and network best block and - // that it is higher than fork detection block - let our_best_block = io.chain().chain_info().best_block_number; - let fork_block = self.fork_block.as_ref().map(|&(n, _)| n).unwrap_or(0); - - let (best_hash, max_peers, snapshot_peers) = { - let expected_warp_block = match self.warp_sync { - WarpSync::OnlyAndAfter(block) => block, - _ => 0, - }; - //collect snapshot infos from peers - let snapshots = self.peers.iter() - .filter(|&(_, p)| p.is_allowed() && p.snapshot_number.map_or(false, |sn| - our_best_block < sn && (sn - our_best_block) > SNAPSHOT_RESTORE_THRESHOLD && - sn > fork_block && - sn > expected_warp_block && - self.highest_block.map_or(true, |highest| highest >= sn && (highest - sn) <= SNAPSHOT_RESTORE_THRESHOLD) - )) - .filter_map(|(p, peer)| peer.snapshot_hash.map(|hash| (p, hash.clone()))) - .filter(|&(_, ref hash)| !self.snapshot.is_known_bad(hash)); - - let mut snapshot_peers = HashMap::new(); - let mut max_peers: usize = 0; - let mut best_hash = None; - for (p, hash) in snapshots { - let peers = snapshot_peers.entry(hash).or_insert_with(Vec::new); - peers.push(*p); - if peers.len() > max_peers { - max_peers = peers.len(); - best_hash = Some(hash); - } - } - (best_hash, max_peers, snapshot_peers) - }; - - let timeout = (self.state == SyncState::WaitingPeers) && self.sync_start_time.map_or(false, |t| t.elapsed() > WAIT_PEERS_TIMEOUT); - - if let (Some(hash), Some(peers)) = (best_hash, best_hash.map_or(None, |h| snapshot_peers.get(&h))) { - if max_peers >= SNAPSHOT_MIN_PEERS { - trace!(target: "sync", "Starting confirmed snapshot sync {:?} with {:?}", hash, peers); - self.start_snapshot_sync(io, peers); - } else if timeout { - trace!(target: "sync", "Starting unconfirmed snapshot sync {:?} with {:?}", hash, peers); - self.start_snapshot_sync(io, peers); - } - } else if timeout && !self.warp_sync.is_warp_only() { - trace!(target: "sync", "No snapshots found, starting full sync"); - self.state = SyncState::Idle; - self.continue_sync(io); - } - } - - fn start_snapshot_sync(&mut self, io: &mut SyncIo, peers: &[PeerId]) { - if !self.snapshot.have_manifest() { - for p in peers { - if self.peers.get(p).map_or(false, |p| p.asking == PeerAsking::Nothing) { - self.request_snapshot_manifest(io, *p); - } - } - self.state = SyncState::SnapshotManifest; - trace!(target: "sync", "New snapshot sync with {:?}", peers); - } else { - self.state = SyncState::SnapshotData; - trace!(target: "sync", "Resumed snapshot sync with {:?}", peers); - } - } - - /// Restart sync disregarding the block queue status. May end up re-downloading up to QUEUE_SIZE blocks - pub fn restart(&mut self, io: &mut SyncIo) { - self.update_targets(io.chain()); - self.reset_and_continue(io); - } - - /// Update sync after the blockchain has been changed externally. - pub fn update_targets(&mut self, chain: &BlockChainClient) { - // Do not assume that the block queue/chain still has our last_imported_block - let chain = chain.chain_info(); - self.new_blocks = BlockDownloader::new(false, &chain.best_block_hash, chain.best_block_number); - self.old_blocks = None; - if self.download_old_blocks { - if let (Some(ancient_block_hash), Some(ancient_block_number)) = (chain.ancient_block_hash, chain.ancient_block_number) { - - trace!(target: "sync", "Downloading old blocks from {:?} (#{}) till {:?} (#{:?})", ancient_block_hash, ancient_block_number, chain.first_block_hash, chain.first_block_number); - let mut downloader = BlockDownloader::with_unlimited_reorg(true, &ancient_block_hash, ancient_block_number); - if let Some(hash) = chain.first_block_hash { - trace!(target: "sync", "Downloader target set to {:?}", hash); - downloader.set_target(&hash); - } - self.old_blocks = Some(downloader); - } - } - } - - /// Called by peer to report status - fn on_peer_status(&mut self, io: &mut SyncIo, peer_id: PeerId, r: &Rlp) -> Result<(), PacketDecodeError> { - self.handshaking_peers.remove(&peer_id); - let protocol_version: u8 = r.val_at(0)?; - let warp_protocol = io.protocol_version(&WARP_SYNC_PROTOCOL_ID, peer_id) != 0; - let peer = PeerInfo { - protocol_version: protocol_version, - network_id: r.val_at(1)?, - difficulty: Some(r.val_at(2)?), - latest_hash: r.val_at(3)?, - genesis: r.val_at(4)?, - asking: PeerAsking::Nothing, - asking_blocks: Vec::new(), - asking_hash: None, - ask_time: Instant::now(), - last_sent_transactions: HashSet::new(), - expired: false, - confirmation: if self.fork_block.is_none() { ForkConfirmation::Confirmed } else { ForkConfirmation::Unconfirmed }, - asking_snapshot_data: None, - snapshot_hash: if warp_protocol { Some(r.val_at(5)?) } else { None }, - snapshot_number: if warp_protocol { Some(r.val_at(6)?) } else { None }, - block_set: None, - }; - - trace!(target: "sync", "New peer {} (protocol: {}, network: {:?}, difficulty: {:?}, latest:{}, genesis:{}, snapshot:{:?})", - peer_id, peer.protocol_version, peer.network_id, peer.difficulty, peer.latest_hash, peer.genesis, peer.snapshot_number); - if io.is_expired() { - trace!(target: "sync", "Status packet from expired session {}:{}", peer_id, io.peer_info(peer_id)); - return Ok(()); - } - - if self.peers.contains_key(&peer_id) { - debug!(target: "sync", "Unexpected status packet from {}:{}", peer_id, io.peer_info(peer_id)); - return Ok(()); - } - let chain_info = io.chain().chain_info(); - if peer.genesis != chain_info.genesis_hash { - io.disable_peer(peer_id); - trace!(target: "sync", "Peer {} genesis hash mismatch (ours: {}, theirs: {})", peer_id, chain_info.genesis_hash, peer.genesis); - return Ok(()); - } - if peer.network_id != self.network_id { - io.disable_peer(peer_id); - trace!(target: "sync", "Peer {} network id mismatch (ours: {}, theirs: {})", peer_id, self.network_id, peer.network_id); - return Ok(()); - } - if (warp_protocol && peer.protocol_version != PAR_PROTOCOL_VERSION_1 && peer.protocol_version != PAR_PROTOCOL_VERSION_2 && peer.protocol_version != PAR_PROTOCOL_VERSION_3) - || (!warp_protocol && peer.protocol_version != ETH_PROTOCOL_VERSION_63 && peer.protocol_version != ETH_PROTOCOL_VERSION_62) { - io.disable_peer(peer_id); - trace!(target: "sync", "Peer {} unsupported eth protocol ({})", peer_id, peer.protocol_version); - return Ok(()); - } - - if self.sync_start_time.is_none() { - self.sync_start_time = Some(Instant::now()); - } - - self.peers.insert(peer_id.clone(), peer); - // Don't activate peer immediatelly when searching for common block. - // Let the current sync round complete first. - self.active_peers.insert(peer_id.clone()); - debug!(target: "sync", "Connected {}:{}", peer_id, io.peer_info(peer_id)); - if let Some((fork_block, _)) = self.fork_block { - self.request_fork_header_by_number(io, peer_id, fork_block); - } else { - self.sync_peer(io, peer_id, false); - } - Ok(()) - } - - /// Called by peer once it has new block headers during sync - fn on_peer_block_headers(&mut self, io: &mut SyncIo, peer_id: PeerId, r: &Rlp) -> Result<(), PacketDecodeError> { - let confirmed = match self.peers.get_mut(&peer_id) { - Some(ref mut peer) if peer.asking == PeerAsking::ForkHeader => { - peer.asking = PeerAsking::Nothing; - let item_count = r.item_count()?; - let (fork_number, fork_hash) = self.fork_block.expect("ForkHeader request is sent only fork block is Some; qed").clone(); - if item_count == 0 || item_count != 1 { - trace!(target: "sync", "{}: Chain is too short to confirm the block", peer_id); - peer.confirmation = ForkConfirmation::TooShort; - } else { - let header = r.at(0)?.as_raw(); - if keccak(&header) == fork_hash { - trace!(target: "sync", "{}: Confirmed peer", peer_id); - peer.confirmation = ForkConfirmation::Confirmed; - if !io.chain_overlay().read().contains_key(&fork_number) { - io.chain_overlay().write().insert(fork_number, header.to_vec()); - } - } else { - trace!(target: "sync", "{}: Fork mismatch", peer_id); - io.disable_peer(peer_id); - return Ok(()); - } - } - true - }, - _ => false, - }; - if confirmed { - self.sync_peer(io, peer_id, false); - return Ok(()); - } - - self.clear_peer_download(peer_id); - let expected_hash = self.peers.get(&peer_id).and_then(|p| p.asking_hash); - let allowed = self.peers.get(&peer_id).map(|p| p.is_allowed()).unwrap_or(false); - let block_set = self.peers.get(&peer_id).and_then(|p| p.block_set).unwrap_or(BlockSet::NewBlocks); - if !self.reset_peer_asking(peer_id, PeerAsking::BlockHeaders) || expected_hash.is_none() || !allowed { - trace!(target: "sync", "{}: Ignored unexpected headers, expected_hash = {:?}", peer_id, expected_hash); - self.continue_sync(io); - return Ok(()); - } - let item_count = r.item_count()?; - trace!(target: "sync", "{} -> BlockHeaders ({} entries), state = {:?}, set = {:?}", peer_id, item_count, self.state, block_set); - if (self.state == SyncState::Idle || self.state == SyncState::WaitingPeers) && self.old_blocks.is_none() { - trace!(target: "sync", "Ignored unexpected block headers"); - self.continue_sync(io); - return Ok(()); - } - if self.state == SyncState::Waiting { - trace!(target: "sync", "Ignored block headers while waiting"); - self.continue_sync(io); - return Ok(()); - } - - let result = { - let downloader = match block_set { - BlockSet::NewBlocks => &mut self.new_blocks, - BlockSet::OldBlocks => { - match self.old_blocks { - None => { - trace!(target: "sync", "Ignored block headers while block download is inactive"); - self.continue_sync(io); - return Ok(()); - }, - Some(ref mut blocks) => blocks, - } - } - }; - downloader.import_headers(io, r, expected_hash) - }; - - match result { - Err(DownloaderImportError::Useless) => { - self.deactivate_peer(io, peer_id); - }, - Err(DownloaderImportError::Invalid) => { - io.disable_peer(peer_id); - self.deactivate_peer(io, peer_id); - self.continue_sync(io); - return Ok(()); - }, - Ok(DownloadAction::Reset) => { - // mark all outstanding requests as expired - trace!("Resetting downloads for {:?}", block_set); - for (_, ref mut p) in self.peers.iter_mut().filter(|&(_, ref p)| p.block_set == Some(block_set)) { - p.reset_asking(); - } - - } - Ok(DownloadAction::None) => {}, - } - - self.collect_blocks(io, block_set); - // give a task to the same peer first if received valuable headers. - self.sync_peer(io, peer_id, false); - // give tasks to other peers - self.continue_sync(io); - Ok(()) - } - - /// Called by peer once it has new block bodies - fn on_peer_block_bodies(&mut self, io: &mut SyncIo, peer_id: PeerId, r: &Rlp) -> Result<(), PacketDecodeError> { - self.clear_peer_download(peer_id); - let block_set = self.peers.get(&peer_id).and_then(|p| p.block_set).unwrap_or(BlockSet::NewBlocks); - if !self.reset_peer_asking(peer_id, PeerAsking::BlockBodies) { - trace!(target: "sync", "{}: Ignored unexpected bodies", peer_id); - self.continue_sync(io); - return Ok(()); - } - let item_count = r.item_count()?; - trace!(target: "sync", "{} -> BlockBodies ({} entries), set = {:?}", peer_id, item_count, block_set); - if item_count == 0 { - self.deactivate_peer(io, peer_id); - } - else if self.state == SyncState::Waiting { - trace!(target: "sync", "Ignored block bodies while waiting"); - } - else - { - let result = { - let downloader = match block_set { - BlockSet::NewBlocks => &mut self.new_blocks, - BlockSet::OldBlocks => match self.old_blocks { - None => { - trace!(target: "sync", "Ignored block headers while block download is inactive"); - self.continue_sync(io); - return Ok(()); - }, - Some(ref mut blocks) => blocks, - } - }; - downloader.import_bodies(io, r) - }; - - match result { - Err(DownloaderImportError::Invalid) => { - io.disable_peer(peer_id); - self.deactivate_peer(io, peer_id); - self.continue_sync(io); - return Ok(()); - }, - Err(DownloaderImportError::Useless) => { - self.deactivate_peer(io, peer_id); - }, - Ok(()) => (), - } - - self.collect_blocks(io, block_set); - self.sync_peer(io, peer_id, false); - } - self.continue_sync(io); - Ok(()) - } - - /// Called by peer once it has new block receipts - fn on_peer_block_receipts(&mut self, io: &mut SyncIo, peer_id: PeerId, r: &Rlp) -> Result<(), PacketDecodeError> { - self.clear_peer_download(peer_id); - let block_set = self.peers.get(&peer_id).and_then(|p| p.block_set).unwrap_or(BlockSet::NewBlocks); - if !self.reset_peer_asking(peer_id, PeerAsking::BlockReceipts) { - trace!(target: "sync", "{}: Ignored unexpected receipts", peer_id); - self.continue_sync(io); - return Ok(()); - } - let item_count = r.item_count()?; - trace!(target: "sync", "{} -> BlockReceipts ({} entries)", peer_id, item_count); - if item_count == 0 { - self.deactivate_peer(io, peer_id); - } - else if self.state == SyncState::Waiting { - trace!(target: "sync", "Ignored block receipts while waiting"); - } - else - { - let result = { - let downloader = match block_set { - BlockSet::NewBlocks => &mut self.new_blocks, - BlockSet::OldBlocks => match self.old_blocks { - None => { - trace!(target: "sync", "Ignored block headers while block download is inactive"); - self.continue_sync(io); - return Ok(()); - }, - Some(ref mut blocks) => blocks, - } - }; - downloader.import_receipts(io, r) - }; - - match result { - Err(DownloaderImportError::Invalid) => { - io.disable_peer(peer_id); - self.deactivate_peer(io, peer_id); - self.continue_sync(io); - return Ok(()); - }, - Err(DownloaderImportError::Useless) => { - self.deactivate_peer(io, peer_id); - }, - Ok(()) => (), - } - - self.collect_blocks(io, block_set); - self.sync_peer(io, peer_id, false); - } - self.continue_sync(io); - Ok(()) - } - - /// Called by peer once it has new block bodies - fn on_peer_new_block(&mut self, io: &mut SyncIo, peer_id: PeerId, r: &Rlp) -> Result<(), PacketDecodeError> { - if !self.peers.get(&peer_id).map_or(false, |p| p.can_sync()) { - trace!(target: "sync", "Ignoring new block from unconfirmed peer {}", peer_id); - return Ok(()); - } - let difficulty: U256 = r.val_at(1)?; - if let Some(ref mut peer) = self.peers.get_mut(&peer_id) { - if peer.difficulty.map_or(true, |pd| difficulty > pd) { - peer.difficulty = Some(difficulty); - } - } - let block_rlp = r.at(0)?; - let header_rlp = block_rlp.at(0)?; - let h = keccak(&header_rlp.as_raw()); - trace!(target: "sync", "{} -> NewBlock ({})", peer_id, h); - let header: BlockHeader = header_rlp.as_val()?; - if header.number() > self.highest_block.unwrap_or(0) { - self.highest_block = Some(header.number()); - } - let mut unknown = false; - { - if let Some(ref mut peer) = self.peers.get_mut(&peer_id) { - peer.latest_hash = header.hash(); - } - } - let last_imported_number = self.new_blocks.last_imported_block_number(); - if last_imported_number > header.number() && last_imported_number - header.number() > MAX_NEW_BLOCK_AGE { - trace!(target: "sync", "Ignored ancient new block {:?}", h); - io.disable_peer(peer_id); - return Ok(()); - } - match io.chain().import_block(block_rlp.as_raw().to_vec()) { - Err(BlockImportError(BlockImportErrorKind::Import(ImportErrorKind::AlreadyInChain), _)) => { - trace!(target: "sync", "New block already in chain {:?}", h); - }, - Err(BlockImportError(BlockImportErrorKind::Import(ImportErrorKind::AlreadyQueued), _)) => { - trace!(target: "sync", "New block already queued {:?}", h); - }, - Ok(_) => { - // abort current download of the same block - self.complete_sync(io); - self.new_blocks.mark_as_known(&header.hash(), header.number()); - trace!(target: "sync", "New block queued {:?} ({})", h, header.number()); - }, - Err(BlockImportError(BlockImportErrorKind::Block(BlockError::UnknownParent(p)), _)) => { - unknown = true; - trace!(target: "sync", "New block with unknown parent ({:?}) {:?}", p, h); - }, - Err(e) => { - debug!(target: "sync", "Bad new block {:?} : {:?}", h, e); - io.disable_peer(peer_id); - } - }; - if unknown { - if self.state != SyncState::Idle { - trace!(target: "sync", "NewBlock ignored while seeking"); - } else { - trace!(target: "sync", "New unknown block {:?}", h); - //TODO: handle too many unknown blocks - self.sync_peer(io, peer_id, true); - } - } - self.continue_sync(io); - Ok(()) - } - - /// Handles `NewHashes` packet. Initiates headers download for any unknown hashes. - fn on_peer_new_hashes(&mut self, io: &mut SyncIo, peer_id: PeerId, r: &Rlp) -> Result<(), PacketDecodeError> { - if !self.peers.get(&peer_id).map_or(false, |p| p.can_sync()) { - trace!(target: "sync", "Ignoring new hashes from unconfirmed peer {}", peer_id); - return Ok(()); - } - let hashes: Vec<_> = r.iter().take(MAX_NEW_HASHES).map(|item| (item.val_at::(0), item.val_at::(1))).collect(); - if let Some(ref mut peer) = self.peers.get_mut(&peer_id) { - // Peer has new blocks with unknown difficulty - peer.difficulty = None; - if let Some(&(Ok(ref h), _)) = hashes.last() { - peer.latest_hash = h.clone(); - } - } - 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, cmp::max); - if max > self.highest_block.unwrap_or(0) { - self.highest_block = Some(max); - } - self.continue_sync(io); - return Ok(()); - } - trace!(target: "sync", "{} -> NewHashes ({} entries)", peer_id, r.item_count()?); - let mut max_height: BlockNumber = 0; - let mut new_hashes = Vec::new(); - let last_imported_number = self.new_blocks.last_imported_block_number(); - for (rh, rn) in hashes { - let hash = rh?; - let number = rn?; - if number > self.highest_block.unwrap_or(0) { - self.highest_block = Some(number); - } - if self.new_blocks.is_downloading(&hash) { - continue; - } - if last_imported_number > number && last_imported_number - number > MAX_NEW_BLOCK_AGE { - trace!(target: "sync", "Ignored ancient new block hash {:?}", hash); - io.disable_peer(peer_id); - continue; - } - match io.chain().block_status(BlockId::Hash(hash.clone())) { - BlockStatus::InChain => { - trace!(target: "sync", "New block hash already in chain {:?}", hash); - }, - BlockStatus::Queued => { - trace!(target: "sync", "New hash block already queued {:?}", hash); - }, - BlockStatus::Unknown | BlockStatus::Pending => { - new_hashes.push(hash.clone()); - if number > max_height { - trace!(target: "sync", "New unknown block hash {:?}", hash); - if let Some(ref mut peer) = self.peers.get_mut(&peer_id) { - peer.latest_hash = hash.clone(); - } - max_height = number; - } - }, - BlockStatus::Bad => { - debug!(target: "sync", "Bad new block hash {:?}", hash); - io.disable_peer(peer_id); - return Ok(()); - } - } - }; - if max_height != 0 { - trace!(target: "sync", "Downloading blocks for new hashes"); - self.new_blocks.reset_to(new_hashes); - self.state = SyncState::NewBlocks; - self.sync_peer(io, peer_id, true); - } - self.continue_sync(io); - Ok(()) - } - - /// Called when snapshot manifest is downloaded from a peer. - fn on_snapshot_manifest(&mut self, io: &mut SyncIo, peer_id: PeerId, r: &Rlp) -> Result<(), PacketDecodeError> { - if !self.peers.get(&peer_id).map_or(false, |p| p.can_sync()) { - trace!(target: "sync", "Ignoring snapshot manifest from unconfirmed peer {}", peer_id); - return Ok(()); - } - self.clear_peer_download(peer_id); - if !self.reset_peer_asking(peer_id, PeerAsking::SnapshotManifest) || self.state != SyncState::SnapshotManifest { - trace!(target: "sync", "{}: Ignored unexpected/expired manifest", peer_id); - self.continue_sync(io); - return Ok(()); - } - - let manifest_rlp = r.at(0)?; - let manifest = match ManifestData::from_rlp(manifest_rlp.as_raw()) { - Err(e) => { - trace!(target: "sync", "{}: Ignored bad manifest: {:?}", peer_id, e); - io.disable_peer(peer_id); - self.continue_sync(io); - return Ok(()); - } - Ok(manifest) => manifest, - }; - - let is_supported_version = io.snapshot_service().supported_versions() - .map_or(false, |(l, h)| manifest.version >= l && manifest.version <= h); - - if !is_supported_version { - trace!(target: "sync", "{}: Snapshot manifest version not supported: {}", peer_id, manifest.version); - io.disable_peer(peer_id); - self.continue_sync(io); - return Ok(()); - } - self.snapshot.reset_to(&manifest, &keccak(manifest_rlp.as_raw())); - io.snapshot_service().begin_restore(manifest); - self.state = SyncState::SnapshotData; - - // give a task to the same peer first. - self.sync_peer(io, peer_id, false); - // give tasks to other peers - self.continue_sync(io); - Ok(()) - } - - /// Called when snapshot data is downloaded from a peer. - fn on_snapshot_data(&mut self, io: &mut SyncIo, peer_id: PeerId, r: &Rlp) -> Result<(), PacketDecodeError> { - if !self.peers.get(&peer_id).map_or(false, |p| p.can_sync()) { - trace!(target: "sync", "Ignoring snapshot data from unconfirmed peer {}", peer_id); - return Ok(()); - } - self.clear_peer_download(peer_id); - if !self.reset_peer_asking(peer_id, PeerAsking::SnapshotData) || (self.state != SyncState::SnapshotData && self.state != SyncState::SnapshotWaiting) { - trace!(target: "sync", "{}: Ignored unexpected snapshot data", peer_id); - self.continue_sync(io); - return Ok(()); - } - - // check service status - let status = io.snapshot_service().status(); - match status { - RestorationStatus::Inactive | RestorationStatus::Failed => { - trace!(target: "sync", "{}: Snapshot restoration aborted", peer_id); - self.state = SyncState::WaitingPeers; - - // only note bad if restoration failed. - if let (Some(hash), RestorationStatus::Failed) = (self.snapshot.snapshot_hash(), status) { - trace!(target: "sync", "Noting snapshot hash {} as bad", hash); - self.snapshot.note_bad(hash); - } - - self.snapshot.clear(); - self.continue_sync(io); - return Ok(()); - }, - RestorationStatus::Ongoing { .. } => { - trace!(target: "sync", "{}: Snapshot restoration is ongoing", peer_id); - }, - } - - let snapshot_data: Bytes = r.val_at(0)?; - match self.snapshot.validate_chunk(&snapshot_data) { - Ok(ChunkType::Block(hash)) => { - trace!(target: "sync", "{}: Processing block chunk", peer_id); - io.snapshot_service().restore_block_chunk(hash, snapshot_data); - } - Ok(ChunkType::State(hash)) => { - trace!(target: "sync", "{}: Processing state chunk", peer_id); - io.snapshot_service().restore_state_chunk(hash, snapshot_data); - } - Err(()) => { - trace!(target: "sync", "{}: Got bad snapshot chunk", peer_id); - io.disconnect_peer(peer_id); - self.continue_sync(io); - return Ok(()); - } - } - - if self.snapshot.is_complete() { - // wait for snapshot restoration process to complete - self.state = SyncState::SnapshotWaiting; - } - // give a task to the same peer first. - self.sync_peer(io, peer_id, false); - // give tasks to other peers - self.continue_sync(io); - Ok(()) - } - - /// Called by peer when it is disconnecting - pub fn on_peer_aborting(&mut self, io: &mut SyncIo, peer: PeerId) { - trace!(target: "sync", "== Disconnecting {}: {}", peer, io.peer_info(peer)); - self.handshaking_peers.remove(&peer); - if self.peers.contains_key(&peer) { - debug!(target: "sync", "Disconnected {}", peer); - self.clear_peer_download(peer); - self.peers.remove(&peer); - self.active_peers.remove(&peer); - self.continue_sync(io); - } - } - - /// Called when a new peer is connected - pub fn on_peer_connected(&mut self, io: &mut SyncIo, peer: PeerId) { - trace!(target: "sync", "== Connected {}: {}", peer, io.peer_info(peer)); - if let Err(e) = self.send_status(io, peer) { - debug!(target:"sync", "Error sending status request: {:?}", e); - io.disconnect_peer(peer); - } else { - self.handshaking_peers.insert(peer, Instant::now()); - } - } - - /// Resume downloading - fn continue_sync(&mut self, io: &mut SyncIo) { - let mut peers: Vec<(PeerId, U256, u8)> = self.peers.iter().filter_map(|(k, p)| - if p.can_sync() { Some((*k, p.difficulty.unwrap_or_else(U256::zero), p.protocol_version)) } else { None }).collect(); - random::new().shuffle(&mut peers); //TODO: sort by rating - // prefer peers with higher protocol version - peers.sort_by(|&(_, _, ref v1), &(_, _, ref v2)| v1.cmp(v2)); - trace!(target: "sync", "Syncing with peers: {} active, {} confirmed, {} total", self.active_peers.len(), peers.len(), self.peers.len()); - for (p, _, _) in peers { - if self.active_peers.contains(&p) { - self.sync_peer(io, p, false); - } - } - - if - self.state != SyncState::WaitingPeers && - self.state != SyncState::SnapshotWaiting && - self.state != SyncState::Waiting && - self.state != SyncState::Idle && - !self.peers.values().any(|p| p.asking != PeerAsking::Nothing && p.block_set != Some(BlockSet::OldBlocks) && p.can_sync()) - { - self.complete_sync(io); - } - } - - /// Called after all blocks have been downloaded - fn complete_sync(&mut self, io: &mut SyncIo) { - trace!(target: "sync", "Sync complete"); - self.reset(io); - self.state = SyncState::Idle; - } - - /// Enter waiting state - fn pause_sync(&mut self) { - trace!(target: "sync", "Block queue full, pausing sync"); - self.state = SyncState::Waiting; - } - - /// Find something to do for a peer. Called for a new peer or when a peer is done with its task. - fn sync_peer(&mut self, io: &mut SyncIo, peer_id: PeerId, force: bool) { - if !self.active_peers.contains(&peer_id) { - trace!(target: "sync", "Skipping deactivated peer {}", peer_id); - return; - } - let (peer_latest, peer_difficulty, peer_snapshot_number, peer_snapshot_hash) = { - if let Some(peer) = self.peers.get_mut(&peer_id) { - if peer.asking != PeerAsking::Nothing || !peer.can_sync() { - trace!(target: "sync", "Skipping busy peer {}", peer_id); - return; - } - if self.state == SyncState::Waiting { - trace!(target: "sync", "Waiting for the block queue"); - return; - } - if self.state == SyncState::SnapshotWaiting { - trace!(target: "sync", "Waiting for the snapshot restoration"); - return; - } - (peer.latest_hash.clone(), peer.difficulty.clone(), peer.snapshot_number.as_ref().cloned().unwrap_or(0), peer.snapshot_hash.as_ref().cloned()) - } else { - return; - } - }; - let chain_info = io.chain().chain_info(); - let syncing_difficulty = chain_info.pending_total_difficulty; - let num_active_peers = self.peers.values().filter(|p| p.asking != PeerAsking::Nothing).count(); - - let higher_difficulty = peer_difficulty.map_or(true, |pd| pd > syncing_difficulty); - if force || higher_difficulty || self.old_blocks.is_some() { - match self.state { - SyncState::WaitingPeers => { - trace!( - target: "sync", - "Checking snapshot sync: {} vs {} (peer: {})", - peer_snapshot_number, - chain_info.best_block_number, - peer_id - ); - self.maybe_start_snapshot_sync(io); - }, - SyncState::Idle | SyncState::Blocks | SyncState::NewBlocks => { - if io.chain().queue_info().is_full() { - self.pause_sync(); - return; - } - - let have_latest = io.chain().block_status(BlockId::Hash(peer_latest)) != BlockStatus::Unknown; - trace!(target: "sync", "Considering peer {}, force={}, td={:?}, our td={}, latest={}, have_latest={}, state={:?}", peer_id, force, peer_difficulty, syncing_difficulty, peer_latest, have_latest, self.state); - if !have_latest && (higher_difficulty || force || self.state == SyncState::NewBlocks) { - // check if got new blocks to download - trace!(target: "sync", "Syncing with peer {}, force={}, td={:?}, our td={}, state={:?}", peer_id, force, peer_difficulty, syncing_difficulty, self.state); - if let Some(request) = self.new_blocks.request_blocks(io, num_active_peers) { - self.request_blocks(io, peer_id, request, BlockSet::NewBlocks); - if self.state == SyncState::Idle { - self.state = SyncState::Blocks; - } - return; - } - } - - if let Some(request) = self.old_blocks.as_mut().and_then(|d| d.request_blocks(io, num_active_peers)) { - self.request_blocks(io, peer_id, request, BlockSet::OldBlocks); - return; - } - }, - SyncState::SnapshotData => { - if let RestorationStatus::Ongoing { state_chunks_done, block_chunks_done, .. } = io.snapshot_service().status() { - if self.snapshot.done_chunks() - (state_chunks_done + block_chunks_done) as usize > MAX_SNAPSHOT_CHUNKS_DOWNLOAD_AHEAD { - trace!(target: "sync", "Snapshot queue full, pausing sync"); - self.state = SyncState::SnapshotWaiting; - return; - } - } - if peer_snapshot_hash.is_some() && peer_snapshot_hash == self.snapshot.snapshot_hash() { - self.request_snapshot_data(io, peer_id); - } - }, - SyncState::SnapshotManifest | //already downloading from other peer - SyncState::Waiting | SyncState::SnapshotWaiting => () - } - } else { - trace!(target: "sync", "Skipping peer {}, force={}, td={:?}, our td={}, state={:?}", peer_id, force, peer_difficulty, syncing_difficulty, self.state); - } - } - - /// Perofrm block download request` - fn request_blocks(&mut self, io: &mut SyncIo, peer_id: PeerId, request: BlockRequest, block_set: BlockSet) { - match request { - BlockRequest::Headers { start, count, skip } => { - self.request_headers_by_hash(io, peer_id, &start, count, skip, false, block_set); - }, - BlockRequest::Bodies { hashes } => { - self.request_bodies(io, peer_id, hashes, block_set); - }, - BlockRequest::Receipts { hashes } => { - self.request_receipts(io, peer_id, hashes, block_set); - }, - } - } - - /// Find some headers or blocks to download for a peer. - fn request_snapshot_data(&mut self, io: &mut SyncIo, peer_id: PeerId) { - self.clear_peer_download(peer_id); - // find chunk data to download - if let Some(hash) = self.snapshot.needed_chunk() { - if let Some(ref mut peer) = self.peers.get_mut(&peer_id) { - peer.asking_snapshot_data = Some(hash.clone()); - } - self.request_snapshot_chunk(io, peer_id, &hash); - } - } - - /// Clear all blocks/headers marked as being downloaded by a peer. - fn clear_peer_download(&mut self, peer_id: PeerId) { - if let Some(ref mut peer) = self.peers.get_mut(&peer_id) { - match peer.asking { - PeerAsking::BlockHeaders => { - if let Some(ref hash) = peer.asking_hash { - self.new_blocks.clear_header_download(hash); - if let Some(ref mut old) = self.old_blocks { - old.clear_header_download(hash); - } - } - }, - PeerAsking::BlockBodies => { - self.new_blocks.clear_body_download(&peer.asking_blocks); - if let Some(ref mut old) = self.old_blocks { - old.clear_body_download(&peer.asking_blocks); - } - }, - PeerAsking::BlockReceipts => { - self.new_blocks.clear_receipt_download(&peer.asking_blocks); - if let Some(ref mut old) = self.old_blocks { - old.clear_receipt_download(&peer.asking_blocks); - } - }, - PeerAsking::SnapshotData => { - if let Some(hash) = peer.asking_snapshot_data { - self.snapshot.clear_chunk_download(&hash); - } - }, - _ => (), - } - } - } - - /// Checks if there are blocks fully downloaded that can be imported into the blockchain and does the import. - fn collect_blocks(&mut self, io: &mut SyncIo, block_set: BlockSet) { - match block_set { - BlockSet::NewBlocks => { - if self.new_blocks.collect_blocks(io, self.state == SyncState::NewBlocks) == Err(DownloaderImportError::Invalid) { - self.restart(io); - } - }, - BlockSet::OldBlocks => { - if self.old_blocks.as_mut().map_or(false, |downloader| { downloader.collect_blocks(io, false) == Err(DownloaderImportError::Invalid) }) { - self.restart(io); - } else if self.old_blocks.as_ref().map_or(false, |downloader| { downloader.is_complete() }) { - trace!(target: "sync", "Background block download is complete"); - self.old_blocks = None; - } - } - } - } - - /// Request headers from a peer by block hash - fn request_headers_by_hash(&mut self, sync: &mut SyncIo, peer_id: PeerId, h: &H256, count: u64, skip: u64, reverse: bool, set: BlockSet) { - trace!(target: "sync", "{} <- GetBlockHeaders: {} entries starting from {}, set = {:?}", peer_id, count, h, set); - let mut rlp = RlpStream::new_list(4); - rlp.append(h); - rlp.append(&count); - rlp.append(&skip); - rlp.append(&if reverse {1u32} else {0u32}); - self.send_request(sync, peer_id, PeerAsking::BlockHeaders, GET_BLOCK_HEADERS_PACKET, rlp.out()); - let peer = self.peers.get_mut(&peer_id).expect("peer_id may originate either from on_packet, where it is already validated or from enumerating self.peers. qed"); - peer.asking_hash = Some(h.clone()); - peer.block_set = Some(set); - } - - /// Request headers from a peer by block number - fn request_fork_header_by_number(&mut self, sync: &mut SyncIo, peer_id: PeerId, n: BlockNumber) { - trace!(target: "sync", "{} <- GetForkHeader: at {}", peer_id, n); - let mut rlp = RlpStream::new_list(4); - rlp.append(&n); - rlp.append(&1u32); - rlp.append(&0u32); - rlp.append(&0u32); - self.send_request(sync, peer_id, PeerAsking::ForkHeader, GET_BLOCK_HEADERS_PACKET, rlp.out()); - } - - /// Request snapshot manifest from a peer. - fn request_snapshot_manifest(&mut self, sync: &mut SyncIo, peer_id: PeerId) { - trace!(target: "sync", "{} <- GetSnapshotManifest", peer_id); - let rlp = RlpStream::new_list(0); - self.send_request(sync, peer_id, PeerAsking::SnapshotManifest, GET_SNAPSHOT_MANIFEST_PACKET, rlp.out()); - } - - /// Request snapshot chunk from a peer. - fn request_snapshot_chunk(&mut self, sync: &mut SyncIo, peer_id: PeerId, chunk: &H256) { - trace!(target: "sync", "{} <- GetSnapshotData {:?}", peer_id, chunk); - let mut rlp = RlpStream::new_list(1); - rlp.append(chunk); - self.send_request(sync, peer_id, PeerAsking::SnapshotData, GET_SNAPSHOT_DATA_PACKET, rlp.out()); - } - - /// Request block bodies from a peer - fn request_bodies(&mut self, sync: &mut SyncIo, peer_id: PeerId, hashes: Vec, set: BlockSet) { - let mut rlp = RlpStream::new_list(hashes.len()); - trace!(target: "sync", "{} <- GetBlockBodies: {} entries starting from {:?}, set = {:?}", peer_id, hashes.len(), hashes.first(), set); - for h in &hashes { - rlp.append(&h.clone()); - } - self.send_request(sync, peer_id, PeerAsking::BlockBodies, GET_BLOCK_BODIES_PACKET, rlp.out()); - let peer = self.peers.get_mut(&peer_id).expect("peer_id may originate either from on_packet, where it is already validated or from enumerating self.peers. qed"); - peer.asking_blocks = hashes; - peer.block_set = Some(set); - } - - /// Request block receipts from a peer - fn request_receipts(&mut self, sync: &mut SyncIo, peer_id: PeerId, hashes: Vec, set: BlockSet) { - let mut rlp = RlpStream::new_list(hashes.len()); - trace!(target: "sync", "{} <- GetBlockReceipts: {} entries starting from {:?}, set = {:?}", peer_id, hashes.len(), hashes.first(), set); - for h in &hashes { - rlp.append(&h.clone()); - } - self.send_request(sync, peer_id, PeerAsking::BlockReceipts, GET_RECEIPTS_PACKET, rlp.out()); - let peer = self.peers.get_mut(&peer_id).expect("peer_id may originate either from on_packet, where it is already validated or from enumerating self.peers. qed"); - peer.asking_blocks = hashes; - peer.block_set = Some(set); - } - - /// Reset peer status after request is complete. - fn reset_peer_asking(&mut self, peer_id: PeerId, asking: PeerAsking) -> bool { - if let Some(ref mut peer) = self.peers.get_mut(&peer_id) { - peer.expired = false; - peer.block_set = None; - if peer.asking != asking { - trace!(target:"sync", "Asking {:?} while expected {:?}", peer.asking, asking); - peer.asking = PeerAsking::Nothing; - return false; - } else { - peer.asking = PeerAsking::Nothing; - return true; - } - } - false - } - - /// Generic request sender - fn send_request(&mut self, sync: &mut SyncIo, peer_id: PeerId, asking: PeerAsking, packet_id: PacketId, packet: Bytes) { - if let Some(ref mut peer) = self.peers.get_mut(&peer_id) { - if peer.asking != PeerAsking::Nothing { - warn!(target:"sync", "Asking {:?} while requesting {:?}", peer.asking, asking); - } - peer.asking = asking; - peer.ask_time = Instant::now(); - let result = if packet_id >= ETH_PACKET_COUNT { - sync.send_protocol(WARP_SYNC_PROTOCOL_ID, peer_id, packet_id, packet) - } else { - sync.send(peer_id, packet_id, packet) - }; - if let Err(e) = result { - debug!(target:"sync", "Error sending request: {:?}", e); - sync.disconnect_peer(peer_id); - } - } - } - - /// Generic packet sender - fn send_packet(&mut self, sync: &mut SyncIo, peer_id: PeerId, packet_id: PacketId, packet: Bytes) { - if let Err(e) = sync.send(peer_id, packet_id, packet) { - debug!(target:"sync", "Error sending packet: {:?}", e); - sync.disconnect_peer(peer_id); - } - } - - /// Called when peer sends us new transactions - fn on_peer_transactions(&mut self, io: &mut SyncIo, peer_id: PeerId, r: &Rlp) -> Result<(), PacketDecodeError> { - // Accept transactions only when fully synced - if !io.is_chain_queue_empty() || (self.state != SyncState::Idle && self.state != SyncState::NewBlocks) { - trace!(target: "sync", "{} Ignoring transactions while syncing", peer_id); - return Ok(()); - } - if !self.peers.get(&peer_id).map_or(false, |p| p.can_sync()) { - trace!(target: "sync", "{} Ignoring transactions from unconfirmed/unknown peer", peer_id); - return Ok(()); - } - - let item_count = r.item_count()?; - trace!(target: "sync", "{:02} -> Transactions ({} entries)", peer_id, item_count); - let mut transactions = Vec::with_capacity(item_count); - for i in 0 .. item_count { - let rlp = r.at(i)?; - let tx = rlp.as_raw().to_vec(); - transactions.push(tx); - } - io.chain().queue_transactions(transactions, peer_id); - Ok(()) - } - - /// Send Status message - fn send_status(&mut self, io: &mut SyncIo, peer: PeerId) -> Result<(), network::Error> { - let warp_protocol_version = io.protocol_version(&WARP_SYNC_PROTOCOL_ID, peer); - let warp_protocol = warp_protocol_version != 0; - let protocol = if warp_protocol { warp_protocol_version } else { ETH_PROTOCOL_VERSION_63 }; - trace!(target: "sync", "Sending status to {}, protocol version {}", peer, protocol); - let mut packet = RlpStream::new_list(if warp_protocol { 7 } else { 5 }); - let chain = io.chain().chain_info(); - packet.append(&(protocol as u32)); - packet.append(&self.network_id); - packet.append(&chain.total_difficulty); - packet.append(&chain.best_block_hash); - packet.append(&chain.genesis_hash); - if warp_protocol { - let manifest = match self.old_blocks.is_some() { - true => None, - false => io.snapshot_service().manifest(), - }; - let block_number = manifest.as_ref().map_or(0, |m| m.block_number); - let manifest_hash = manifest.map_or(H256::new(), |m| keccak(m.into_rlp())); - packet.append(&manifest_hash); - packet.append(&block_number); - } - io.respond(STATUS_PACKET, packet.out()) - } - - /// Respond to GetBlockHeaders request - fn return_block_headers(io: &SyncIo, r: &Rlp, peer_id: PeerId) -> RlpResponseResult { - // Packet layout: - // [ block: { P , B_32 }, maxHeaders: P, skip: P, reverse: P in { 0 , 1 } ] - let max_headers: usize = r.val_at(1)?; - let skip: usize = r.val_at(2)?; - let reverse: bool = r.val_at(3)?; - let last = io.chain().chain_info().best_block_number; - let number = if r.at(0)?.size() == 32 { - // id is a hash - let hash: H256 = r.val_at(0)?; - trace!(target: "sync", "{} -> GetBlockHeaders (hash: {}, max: {}, skip: {}, reverse:{})", peer_id, hash, max_headers, skip, reverse); - match io.chain().block_header(BlockId::Hash(hash)) { - Some(hdr) => { - let number = hdr.number().into(); - debug_assert_eq!(hdr.hash(), hash); - - if max_headers == 1 || io.chain().block_hash(BlockId::Number(number)) != Some(hash) { - // Non canonical header or single header requested - // TODO: handle single-step reverse hashchains of non-canon hashes - trace!(target:"sync", "Returning single header: {:?}", hash); - let mut rlp = RlpStream::new_list(1); - rlp.append_raw(&hdr.into_inner(), 1); - return Ok(Some((BLOCK_HEADERS_PACKET, rlp))); - } - number - } - None => return Ok(Some((BLOCK_HEADERS_PACKET, RlpStream::new_list(0)))) //no such header, return nothing - } - } else { - trace!(target: "sync", "{} -> GetBlockHeaders (number: {}, max: {}, skip: {}, reverse:{})", peer_id, r.val_at::(0)?, max_headers, skip, reverse); - r.val_at(0)? - }; - - let mut number = if reverse { - cmp::min(last, number) - } else { - cmp::max(0, number) - }; - 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; - let overlay = io.chain_overlay().read(); - - while number <= last && count < max_count { - if let Some(hdr) = overlay.get(&number) { - trace!(target: "sync", "{}: Returning cached fork header", peer_id); - data.extend_from_slice(hdr); - count += 1; - } else if let Some(hdr) = io.chain().block_header(BlockId::Number(number)) { - data.append(&mut hdr.into_inner()); - count += 1; - } else { - // No required block. - break; - } - if reverse { - if number <= inc || number == 0 { - break; - } - number -= inc; - } - else { - number += inc; - } - } - let mut rlp = RlpStream::new_list(count as usize); - rlp.append_raw(&data, count as usize); - trace!(target: "sync", "{} -> GetBlockHeaders: returned {} entries", peer_id, count); - Ok(Some((BLOCK_HEADERS_PACKET, rlp))) - } - - /// Respond to GetBlockBodies request - fn return_block_bodies(io: &SyncIo, r: &Rlp, peer_id: PeerId) -> RlpResponseResult { - let mut count = r.item_count().unwrap_or(0); - if count == 0 { - debug!(target: "sync", "Empty GetBlockBodies request, ignoring."); - return Ok(None); - } - count = cmp::min(count, MAX_BODIES_TO_SEND); - let mut added = 0usize; - let mut data = Bytes::new(); - for i in 0..count { - if let Some(body) = io.chain().block_body(BlockId::Hash(r.val_at::(i)?)) { - data.append(&mut body.into_inner()); - added += 1; - } - } - let mut rlp = RlpStream::new_list(added); - rlp.append_raw(&data, added); - trace!(target: "sync", "{} -> GetBlockBodies: returned {} entries", peer_id, added); - Ok(Some((BLOCK_BODIES_PACKET, rlp))) - } - - /// Respond to GetNodeData request - fn return_node_data(io: &SyncIo, r: &Rlp, peer_id: PeerId) -> RlpResponseResult { - let mut count = r.item_count().unwrap_or(0); - trace!(target: "sync", "{} -> GetNodeData: {} entries", peer_id, count); - if count == 0 { - debug!(target: "sync", "Empty GetNodeData request, ignoring."); - return Ok(None); - } - count = cmp::min(count, MAX_NODE_DATA_TO_SEND); - let mut added = 0usize; - let mut data = Vec::new(); - for i in 0..count { - if let Some(node) = io.chain().state_data(&r.val_at::(i)?) { - data.push(node); - added += 1; - } - } - trace!(target: "sync", "{} -> GetNodeData: return {} entries", peer_id, added); - let mut rlp = RlpStream::new_list(added); - for d in data { - rlp.append(&d); - } - Ok(Some((NODE_DATA_PACKET, rlp))) - } - - fn return_receipts(io: &SyncIo, rlp: &Rlp, peer_id: PeerId) -> RlpResponseResult { - let mut count = rlp.item_count().unwrap_or(0); - trace!(target: "sync", "{} -> GetReceipts: {} entries", peer_id, count); - if count == 0 { - debug!(target: "sync", "Empty GetReceipts request, ignoring."); - return Ok(None); - } - count = cmp::min(count, MAX_RECEIPTS_HEADERS_TO_SEND); - let mut added_headers = 0usize; - let mut added_receipts = 0usize; - let mut data = Bytes::new(); - for i in 0..count { - if let Some(mut receipts_bytes) = io.chain().block_receipts(&rlp.val_at::(i)?) { - data.append(&mut receipts_bytes); - added_receipts += receipts_bytes.len(); - added_headers += 1; - if added_receipts > MAX_RECEIPTS_TO_SEND { break; } - } - } - let mut rlp_result = RlpStream::new_list(added_headers); - rlp_result.append_raw(&data, added_headers); - Ok(Some((RECEIPTS_PACKET, rlp_result))) - } - - /// Respond to GetSnapshotManifest request - fn return_snapshot_manifest(io: &SyncIo, r: &Rlp, peer_id: PeerId) -> RlpResponseResult { - let count = r.item_count().unwrap_or(0); - trace!(target: "sync", "{} -> GetSnapshotManifest", peer_id); - if count != 0 { - debug!(target: "sync", "Invalid GetSnapshotManifest request, ignoring."); - return Ok(None); - } - let rlp = match io.snapshot_service().manifest() { - Some(manifest) => { - trace!(target: "sync", "{} <- SnapshotManifest", peer_id); - let mut rlp = RlpStream::new_list(1); - rlp.append_raw(&manifest.into_rlp(), 1); - rlp - }, - None => { - trace!(target: "sync", "{}: No manifest to return", peer_id); - RlpStream::new_list(0) - } - }; - Ok(Some((SNAPSHOT_MANIFEST_PACKET, rlp))) - } - - /// Respond to GetSnapshotData request - fn return_snapshot_data(io: &SyncIo, r: &Rlp, peer_id: PeerId) -> RlpResponseResult { - let hash: H256 = r.val_at(0)?; - trace!(target: "sync", "{} -> GetSnapshotData {:?}", peer_id, hash); - let rlp = match io.snapshot_service().chunk(hash) { - Some(data) => { - let mut rlp = RlpStream::new_list(1); - trace!(target: "sync", "{} <- SnapshotData", peer_id); - rlp.append(&data); - rlp - }, - None => { - RlpStream::new_list(0) - } - }; - Ok(Some((SNAPSHOT_DATA_PACKET, rlp))) - } - - fn return_rlp(io: &mut SyncIo, rlp: &Rlp, peer: PeerId, rlp_func: FRlp, error_func: FError) -> Result<(), PacketDecodeError> - where FRlp : Fn(&SyncIo, &Rlp, PeerId) -> RlpResponseResult, - FError : FnOnce(network::Error) -> String - { - let response = rlp_func(io, rlp, peer); - match response { - Err(e) => Err(e), - Ok(Some((packet_id, rlp_stream))) => { - io.respond(packet_id, rlp_stream.out()).unwrap_or_else( - |e| debug!(target: "sync", "{:?}", error_func(e))); - Ok(()) - } - _ => Ok(()) - } - } - - /// Dispatch incoming requests and responses - pub fn dispatch_packet(sync: &RwLock, io: &mut SyncIo, peer: PeerId, packet_id: u8, data: &[u8]) { - let rlp = Rlp::new(data); - let result = match packet_id { - GET_BLOCK_BODIES_PACKET => ChainSync::return_rlp(io, &rlp, peer, - ChainSync::return_block_bodies, - |e| format!("Error sending block bodies: {:?}", e)), - - GET_BLOCK_HEADERS_PACKET => ChainSync::return_rlp(io, &rlp, peer, - ChainSync::return_block_headers, - |e| format!("Error sending block headers: {:?}", e)), - - GET_RECEIPTS_PACKET => ChainSync::return_rlp(io, &rlp, peer, - ChainSync::return_receipts, - |e| format!("Error sending receipts: {:?}", e)), - - GET_NODE_DATA_PACKET => ChainSync::return_rlp(io, &rlp, peer, - ChainSync::return_node_data, - |e| format!("Error sending nodes: {:?}", e)), - - GET_SNAPSHOT_MANIFEST_PACKET => ChainSync::return_rlp(io, &rlp, peer, - ChainSync::return_snapshot_manifest, - |e| format!("Error sending snapshot manifest: {:?}", e)), - - GET_SNAPSHOT_DATA_PACKET => ChainSync::return_rlp(io, &rlp, peer, - ChainSync::return_snapshot_data, - |e| format!("Error sending snapshot data: {:?}", e)), - CONSENSUS_DATA_PACKET => ChainSync::on_consensus_packet(io, peer, &rlp), - _ => { - sync.write().on_packet(io, peer, packet_id, data); - Ok(()) - } - }; - result.unwrap_or_else(|e| { - debug!(target:"sync", "{} -> Malformed packet {} : {}", peer, packet_id, e); - }) - } - - pub fn on_packet(&mut self, io: &mut SyncIo, peer: PeerId, packet_id: u8, data: &[u8]) { - debug!(target: "sync", "{} -> Dispatching packet: {}", peer, packet_id); - - if packet_id != STATUS_PACKET && !self.peers.contains_key(&peer) { - debug!(target:"sync", "Unexpected packet {} from unregistered peer: {}:{}", packet_id, peer, io.peer_info(peer)); - return; - } - - let rlp = Rlp::new(data); - let result = match packet_id { - STATUS_PACKET => self.on_peer_status(io, peer, &rlp), - TRANSACTIONS_PACKET => self.on_peer_transactions(io, peer, &rlp), - BLOCK_HEADERS_PACKET => self.on_peer_block_headers(io, peer, &rlp), - BLOCK_BODIES_PACKET => self.on_peer_block_bodies(io, peer, &rlp), - RECEIPTS_PACKET => self.on_peer_block_receipts(io, peer, &rlp), - NEW_BLOCK_PACKET => self.on_peer_new_block(io, peer, &rlp), - NEW_BLOCK_HASHES_PACKET => self.on_peer_new_hashes(io, peer, &rlp), - SNAPSHOT_MANIFEST_PACKET => self.on_snapshot_manifest(io, peer, &rlp), - SNAPSHOT_DATA_PACKET => self.on_snapshot_data(io, peer, &rlp), - PRIVATE_TRANSACTION_PACKET => self.on_private_transaction(io, peer, &rlp), - SIGNED_PRIVATE_TRANSACTION_PACKET => self.on_signed_private_transaction(io, peer, &rlp), - _ => { - debug!(target: "sync", "{}: Unknown packet {}", peer, packet_id); - Ok(()) - } - }; - result.unwrap_or_else(|e| { - debug!(target:"sync", "{} -> Malformed packet {} : {}", peer, packet_id, e); - }) - } - - pub fn maintain_peers(&mut self, io: &mut SyncIo) { - let tick = Instant::now(); - let mut aborting = Vec::new(); - for (peer_id, peer) in &self.peers { - let elapsed = tick - peer.ask_time; - let timeout = match peer.asking { - PeerAsking::BlockHeaders => elapsed > HEADERS_TIMEOUT, - PeerAsking::BlockBodies => elapsed > BODIES_TIMEOUT, - PeerAsking::BlockReceipts => elapsed > RECEIPTS_TIMEOUT, - PeerAsking::Nothing => false, - PeerAsking::ForkHeader => elapsed > FORK_HEADER_TIMEOUT, - PeerAsking::SnapshotManifest => elapsed > SNAPSHOT_MANIFEST_TIMEOUT, - PeerAsking::SnapshotData => elapsed > SNAPSHOT_DATA_TIMEOUT, - }; - if timeout { - debug!(target:"sync", "Timeout {}", peer_id); - io.disconnect_peer(*peer_id); - aborting.push(*peer_id); - } - } - for p in aborting { - self.on_peer_aborting(io, p); - } - - // Check for handshake timeouts - for (peer, &ask_time) in &self.handshaking_peers { - let elapsed = (tick - ask_time) / 1_000_000_000; - if elapsed > STATUS_TIMEOUT { - trace!(target:"sync", "Status timeout {}", peer); - io.disconnect_peer(*peer); - } - } - } - - fn check_resume(&mut self, io: &mut SyncIo) { - if self.state == SyncState::Waiting && !io.chain().queue_info().is_full() && self.state == SyncState::Waiting { - self.state = SyncState::Blocks; - self.continue_sync(io); - } else if self.state == SyncState::SnapshotWaiting { - match io.snapshot_service().status() { - RestorationStatus::Inactive => { - trace!(target:"sync", "Snapshot restoration is complete"); - self.restart(io); - self.continue_sync(io); - }, - RestorationStatus::Ongoing { state_chunks_done, block_chunks_done, .. } => { - if !self.snapshot.is_complete() && self.snapshot.done_chunks() - (state_chunks_done + block_chunks_done) as usize <= MAX_SNAPSHOT_CHUNKS_DOWNLOAD_AHEAD { - trace!(target:"sync", "Resuming snapshot sync"); - self.state = SyncState::SnapshotData; - self.continue_sync(io); - } - }, - RestorationStatus::Failed => { - trace!(target: "sync", "Snapshot restoration aborted"); - self.state = SyncState::WaitingPeers; - self.snapshot.clear(); - self.continue_sync(io); - }, - } - } - } - - /// creates rlp to send for the tree defined by 'from' and 'to' hashes - fn create_new_hashes_rlp(chain: &BlockChainClient, from: &H256, to: &H256) -> Option { - match chain.tree_route(from, to) { - Some(route) => { - let uncles = chain.find_uncles(from).unwrap_or_else(Vec::new); - match route.blocks.len() { - 0 => None, - _ => { - let mut blocks = route.blocks; - blocks.extend(uncles); - let mut rlp_stream = RlpStream::new_list(blocks.len()); - for block_hash in blocks { - let mut hash_rlp = RlpStream::new_list(2); - let number = chain.block_header(BlockId::Hash(block_hash.clone())) - .expect("chain.tree_route and chain.find_uncles only return hahses of blocks that are in the blockchain. qed.").number(); - hash_rlp.append(&block_hash); - hash_rlp.append(&number); - rlp_stream.append_raw(hash_rlp.as_raw(), 1); - } - Some(rlp_stream.out()) - } - } - }, - None => None - } - } - - /// creates rlp from block bytes and total difficulty - fn create_block_rlp(bytes: &Bytes, total_difficulty: U256) -> Bytes { - let mut rlp_stream = RlpStream::new_list(2); - rlp_stream.append_raw(bytes, 1); - rlp_stream.append(&total_difficulty); - rlp_stream.out() - } - - /// creates latest block rlp for the given client - fn create_latest_block_rlp(chain: &BlockChainClient) -> Bytes { - ChainSync::create_block_rlp( - &chain.block(BlockId::Hash(chain.chain_info().best_block_hash)) - .expect("Best block always exists").into_inner(), - chain.chain_info().total_difficulty - ) - } - - /// creates given hash block rlp for the given client - fn create_new_block_rlp(chain: &BlockChainClient, hash: &H256) -> Bytes { - ChainSync::create_block_rlp( - &chain.block(BlockId::Hash(hash.clone())).expect("Block has just been sealed; qed").into_inner(), - chain.block_total_difficulty(BlockId::Hash(hash.clone())).expect("Block has just been sealed; qed.") - ) - } - - /// returns peer ids that have different blocks than our chain - fn get_lagging_peers(&mut self, chain_info: &BlockChainInfo) -> Vec { - let latest_hash = chain_info.best_block_hash; - self - .peers - .iter_mut() - .filter_map(|(&id, ref mut peer_info)| { - trace!(target: "sync", "Checking peer our best {} their best {}", latest_hash, peer_info.latest_hash); - if peer_info.latest_hash != latest_hash { - Some(id) - } else { - None - } - }) - .collect::>() - } - - fn select_random_peers(peers: &[PeerId]) -> Vec { - // take sqrt(x) peers - let mut peers = peers.to_vec(); - let mut count = (peers.len() as f64).powf(0.5).round() as usize; - count = cmp::min(count, MAX_PEERS_PROPAGATION); - count = cmp::max(count, MIN_PEERS_PROPAGATION); - random::new().shuffle(&mut peers); - peers.truncate(count); - peers - } - - fn get_consensus_peers(&self) -> Vec { - self.peers.iter().filter_map(|(id, p)| if p.protocol_version >= PAR_PROTOCOL_VERSION_2 { Some(*id) } else { None }).collect() - } - - fn get_private_transaction_peers(&self) -> Vec { - self.peers.iter().filter_map(|(id, p)| if p.protocol_version >= PAR_PROTOCOL_VERSION_3 { Some(*id) } else { None }).collect() - } - - /// propagates latest block to a set of peers - fn propagate_blocks(&mut self, chain_info: &BlockChainInfo, io: &mut SyncIo, blocks: &[H256], peers: &[PeerId]) -> usize { - trace!(target: "sync", "Sending NewBlocks to {:?}", peers); - let mut sent = 0; - for peer_id in peers { - if blocks.is_empty() { - let rlp = ChainSync::create_latest_block_rlp(io.chain()); - self.send_packet(io, *peer_id, NEW_BLOCK_PACKET, rlp); - } else { - for h in blocks { - let rlp = ChainSync::create_new_block_rlp(io.chain(), h); - self.send_packet(io, *peer_id, NEW_BLOCK_PACKET, rlp); - } - } - if let Some(ref mut peer) = self.peers.get_mut(peer_id) { - peer.latest_hash = chain_info.best_block_hash.clone(); - } - sent += 1; - } - sent - } - - /// propagates new known hashes to all peers - fn propagate_new_hashes(&mut self, chain_info: &BlockChainInfo, io: &mut SyncIo, peers: &[PeerId]) -> usize { - trace!(target: "sync", "Sending NewHashes to {:?}", peers); - let mut sent = 0; - let last_parent = *io.chain().best_block_header().parent_hash(); - for peer_id in peers { - sent += match ChainSync::create_new_hashes_rlp(io.chain(), &last_parent, &chain_info.best_block_hash) { - Some(rlp) => { - { - if let Some(ref mut peer) = self.peers.get_mut(peer_id) { - peer.latest_hash = chain_info.best_block_hash.clone(); - } - } - self.send_packet(io, *peer_id, NEW_BLOCK_HASHES_PACKET, rlp); - 1 - }, - None => 0 - } - } - sent - } - - /// propagates new transactions to all peers - pub fn propagate_new_transactions(&mut self, io: &mut SyncIo) -> usize { - // Early out if nobody to send to. - if self.peers.is_empty() { - return 0; - } - - let transactions = io.chain().ready_transactions(); - if transactions.is_empty() { - return 0; - } - - let (transactions, service_transactions): (Vec<_>, Vec<_>) = transactions.iter() - .map(|tx| tx.signed()) - .partition(|tx| !tx.gas_price.is_zero()); - - // usual transactions could be propagated to all peers - let mut affected_peers = HashSet::new(); - if !transactions.is_empty() { - let peers = self.select_peers_for_transactions(|_| true); - affected_peers = self.propagate_transactions_to_peers(io, peers, transactions); - } - - // most of times service_transactions will be empty - // => there's no need to merge packets - if !service_transactions.is_empty() { - let service_transactions_peers = self.select_peers_for_transactions(|peer_id| accepts_service_transaction(&io.peer_info(*peer_id))); - let service_transactions_affected_peers = self.propagate_transactions_to_peers(io, service_transactions_peers, service_transactions); - affected_peers.extend(&service_transactions_affected_peers); - } - - affected_peers.len() - } - - 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) * (u32::max_value() as f64).round()) as u32; - let small = self.peers.len() < MIN_PEERS_PROPAGATION; - - let mut random = random::new(); - self.peers.keys() - .cloned() - .filter(filter) - .filter(|_| small || random.next_u32() < fraction) - .take(MAX_PEERS_PROPAGATION) - .collect() - } - - fn propagate_transactions_to_peers(&mut self, io: &mut SyncIo, peers: Vec, transactions: Vec<&SignedTransaction>) -> HashSet { - let all_transactions_hashes = transactions.iter() - .map(|tx| tx.hash()) - .collect::>(); - let all_transactions_rlp = { - let mut packet = RlpStream::new_list(transactions.len()); - for tx in &transactions { packet.append(&**tx); } - packet.out() - }; - - // Clear old transactions from stats - self.transactions_stats.retain(&all_transactions_hashes); - - // sqrt(x)/x scaled to max u32 - let block_number = io.chain().chain_info().best_block_number; - - let lucky_peers = { - peers.into_iter() - .filter_map(|peer_id| { - let stats = &mut self.transactions_stats; - let peer_info = self.peers.get_mut(&peer_id) - .expect("peer_id is form peers; peers is result of select_peers_for_transactions; select_peers_for_transactions selects peers from self.peers; qed"); - - // Send all transactions - if peer_info.last_sent_transactions.is_empty() { - // update stats - for hash in &all_transactions_hashes { - let id = io.peer_session_info(peer_id).and_then(|info| info.id); - stats.propagated(hash, id, block_number); - } - peer_info.last_sent_transactions = all_transactions_hashes.clone(); - return Some((peer_id, all_transactions_hashes.len(), all_transactions_rlp.clone())); - } - - // Get hashes of all transactions to send to this peer - let to_send = all_transactions_hashes.difference(&peer_info.last_sent_transactions) - .take(MAX_TRANSACTIONS_TO_PROPAGATE) - .cloned() - .collect::>(); - if to_send.is_empty() { - return None; - } - - // Construct RLP - let (packet, to_send) = { - let mut to_send = to_send; - let mut packet = RlpStream::new(); - packet.begin_unbounded_list(); - let mut pushed = 0; - for tx in &transactions { - let hash = tx.hash(); - if to_send.contains(&hash) { - let mut transaction = RlpStream::new(); - tx.rlp_append(&mut transaction); - let appended = packet.append_raw_checked(&transaction.drain(), 1, MAX_TRANSACTION_PACKET_SIZE); - if !appended { - // Maximal packet size reached just proceed with sending - debug!("Transaction packet size limit reached. Sending incomplete set of {}/{} transactions.", pushed, to_send.len()); - to_send = to_send.into_iter().take(pushed).collect(); - break; - } - pushed += 1; - } - } - packet.complete_unbounded_list(); - (packet, to_send) - }; - - // Update stats - let id = io.peer_session_info(peer_id).and_then(|info| info.id); - for hash in &to_send { - // update stats - stats.propagated(hash, id, block_number); - } - - peer_info.last_sent_transactions = all_transactions_hashes - .intersection(&peer_info.last_sent_transactions) - .chain(&to_send) - .cloned() - .collect(); - Some((peer_id, to_send.len(), packet.out())) - }) - .collect::>() - }; - - // Send RLPs - let mut peers = HashSet::new(); - if lucky_peers.len() > 0 { - let mut max_sent = 0; - let lucky_peers_len = lucky_peers.len(); - for (peer_id, sent, rlp) in lucky_peers { - peers.insert(peer_id); - self.send_packet(io, peer_id, TRANSACTIONS_PACKET, rlp); - trace!(target: "sync", "{:02} <- Transactions ({} entries)", peer_id, sent); - max_sent = cmp::max(max_sent, sent); - } - debug!(target: "sync", "Sent up to {} transactions to {} peers.", max_sent, lucky_peers_len); - } - - peers - } - - fn propagate_latest_blocks(&mut self, io: &mut SyncIo, sealed: &[H256]) { - let chain_info = io.chain().chain_info(); - if (((chain_info.best_block_number as i64) - (self.last_sent_block_number as i64)).abs() as BlockNumber) < MAX_PEER_LAG_PROPAGATION { - let mut peers = self.get_lagging_peers(&chain_info); - if sealed.is_empty() { - let hashes = self.propagate_new_hashes(&chain_info, io, &peers); - peers = ChainSync::select_random_peers(&peers); - let blocks = self.propagate_blocks(&chain_info, io, sealed, &peers); - if blocks != 0 || hashes != 0 { - trace!(target: "sync", "Sent latest {} blocks and {} hashes to peers.", blocks, hashes); - } - } else { - self.propagate_blocks(&chain_info, io, sealed, &peers); - self.propagate_new_hashes(&chain_info, io, &peers); - trace!(target: "sync", "Sent sealed block to all peers"); - }; - } - self.last_sent_block_number = chain_info.best_block_number; - } - - /// Distribute valid proposed blocks to subset of current peers. - fn propagate_proposed_blocks(&mut self, io: &mut SyncIo, proposed: &[Bytes]) { - let peers = self.get_consensus_peers(); - trace!(target: "sync", "Sending proposed blocks to {:?}", peers); - for block in proposed { - let rlp = ChainSync::create_block_rlp( - block, - io.chain().chain_info().total_difficulty - ); - for peer_id in &peers { - self.send_packet(io, *peer_id, NEW_BLOCK_PACKET, rlp.clone()); - } - } - } - - /// Maintain other peers. Send out any new blocks and transactions - pub fn maintain_sync(&mut self, io: &mut SyncIo) { - self.maybe_start_snapshot_sync(io); - self.check_resume(io); - } - - /// called when block is imported to chain - propagates the blocks and updates transactions sent to peers - pub fn chain_new_blocks(&mut self, io: &mut SyncIo, _imported: &[H256], invalid: &[H256], enacted: &[H256], _retracted: &[H256], sealed: &[H256], proposed: &[Bytes]) { - let queue_info = io.chain().queue_info(); - let is_syncing = self.status().is_syncing(queue_info); - - if !is_syncing || !sealed.is_empty() || !proposed.is_empty() { - trace!(target: "sync", "Propagating blocks, state={:?}", self.state); - self.propagate_latest_blocks(io, sealed); - self.propagate_proposed_blocks(io, proposed); - } - if !invalid.is_empty() { - trace!(target: "sync", "Bad blocks in the queue, restarting"); - self.restart(io); - } - - if !is_syncing && !enacted.is_empty() && !self.peers.is_empty() { - // Select random peer to re-broadcast transactions to. - let peer = random::new().gen_range(0, self.peers.len()); - trace!(target: "sync", "Re-broadcasting transactions to a random peer."); - self.peers.values_mut().nth(peer).map(|peer_info| - peer_info.last_sent_transactions.clear() - ); - } - } - - /// Called when peer sends us new consensus packet - fn on_consensus_packet(io: &mut SyncIo, peer_id: PeerId, r: &Rlp) -> Result<(), PacketDecodeError> { - trace!(target: "sync", "Received consensus packet from {:?}", peer_id); - io.chain().queue_consensus_message(r.as_raw().to_vec()); - Ok(()) - } - - /// Broadcast consensus message to peers. - pub fn propagate_consensus_packet(&mut self, io: &mut SyncIo, packet: Bytes) { - let lucky_peers = ChainSync::select_random_peers(&self.get_consensus_peers()); - trace!(target: "sync", "Sending consensus packet to {:?}", lucky_peers); - for peer_id in lucky_peers { - self.send_packet(io, peer_id, CONSENSUS_DATA_PACKET, packet.clone()); - } - } - - /// Called when peer sends us new private transaction packet - fn on_private_transaction(&self, _io: &mut SyncIo, peer_id: PeerId, r: &Rlp) -> Result<(), PacketDecodeError> { - if !self.peers.get(&peer_id).map_or(false, |p| p.can_sync()) { - trace!(target: "sync", "{} Ignoring packet from unconfirmed/unknown peer", peer_id); - return Ok(()); - } - - trace!(target: "sync", "Received private transaction packet from {:?}", peer_id); - - if let Err(e) = self.private_tx_handler.import_private_transaction(r.as_raw()) { - trace!(target: "sync", "Ignoring the message, error queueing: {}", e); - } - Ok(()) - } - - /// Broadcast private transaction message to peers. - pub fn propagate_private_transaction(&mut self, io: &mut SyncIo, packet: Bytes) { - let lucky_peers = ChainSync::select_random_peers(&self.get_private_transaction_peers()); - trace!(target: "sync", "Sending private transaction packet to {:?}", lucky_peers); - for peer_id in lucky_peers { - self.send_packet(io, peer_id, PRIVATE_TRANSACTION_PACKET, packet.clone()); - } - } - - /// Called when peer sends us signed private transaction packet - fn on_signed_private_transaction(&self, _io: &mut SyncIo, peer_id: PeerId, r: &Rlp) -> Result<(), PacketDecodeError> { - if !self.peers.get(&peer_id).map_or(false, |p| p.can_sync()) { - trace!(target: "sync", "{} Ignoring packet from unconfirmed/unknown peer", peer_id); - return Ok(()); - } - - trace!(target: "sync", "Received signed private transaction packet from {:?}", peer_id); - if let Err(e) = self.private_tx_handler.import_signed_private_transaction(r.as_raw()) { - trace!(target: "sync", "Ignoring the message, error queueing: {}", e); - } - Ok(()) - } - - /// Broadcast signed private transaction message to peers. - pub fn propagate_signed_private_transaction(&mut self, io: &mut SyncIo, packet: Bytes) { - let lucky_peers = ChainSync::select_random_peers(&self.get_private_transaction_peers()); - trace!(target: "sync", "Sending signed private transaction packet to {:?}", lucky_peers); - for peer_id in lucky_peers { - self.send_packet(io, peer_id, SIGNED_PRIVATE_TRANSACTION_PACKET, packet.clone()); - } - } - -} - -/// Checks if peer is able to process service transactions -fn accepts_service_transaction(client_id: &str) -> bool { - // Parity versions starting from this will accept service-transactions - const SERVICE_TRANSACTIONS_VERSION: (u32, u32) = (1u32, 6u32); - // Parity client string prefix - const PARITY_CLIENT_ID_PREFIX: &'static str = "Parity/v"; - - if !client_id.starts_with(PARITY_CLIENT_ID_PREFIX) { - return false; - } - let ver: Vec = client_id[PARITY_CLIENT_ID_PREFIX.len()..].split('.') - .take(2) - .filter_map(|s| s.parse().ok()) - .collect(); - ver.len() == 2 && (ver[0] > SERVICE_TRANSACTIONS_VERSION.0 || (ver[0] == SERVICE_TRANSACTIONS_VERSION.0 && ver[1] >= SERVICE_TRANSACTIONS_VERSION.1)) -} - -#[cfg(test)] -mod tests { - use std::collections::{HashSet, VecDeque}; - use ethkey; - use network::PeerId; - use tests::helpers::{TestIo}; - use tests::snapshot::TestSnapshotService; - use ethereum_types::{H256, U256, Address}; - use parking_lot::RwLock; - use bytes::Bytes; - use rlp::{Rlp, RlpStream}; - use super::*; - use ::SyncConfig; - use super::{PeerInfo, PeerAsking}; - use ethcore::header::*; - use ethcore::client::{BlockChainClient, EachBlockWith, TestBlockChainClient, ChainInfo, BlockInfo}; - use ethcore::miner::MinerService; - use private_tx::NoopPrivateTxHandler; - - fn get_dummy_block(order: u32, parent_hash: H256) -> Bytes { - let mut header = Header::new(); - header.set_gas_limit(0.into()); - header.set_difficulty((order * 100).into()); - header.set_timestamp((order * 10) as u64); - header.set_number(order as u64); - header.set_parent_hash(parent_hash); - header.set_state_root(H256::zero()); - - let mut rlp = RlpStream::new_list(3); - rlp.append(&header); - rlp.append_raw(&::rlp::EMPTY_LIST_RLP, 1); - rlp.append_raw(&::rlp::EMPTY_LIST_RLP, 1); - rlp.out() - } - - fn get_dummy_blocks(order: u32, parent_hash: H256) -> Bytes { - let mut rlp = RlpStream::new_list(1); - rlp.append_raw(&get_dummy_block(order, parent_hash), 1); - let difficulty: U256 = (100 * order).into(); - rlp.append(&difficulty); - rlp.out() - } - - fn get_dummy_hashes() -> Bytes { - let mut rlp = RlpStream::new_list(5); - for _ in 0..5 { - let mut hash_d_rlp = RlpStream::new_list(2); - let hash: H256 = H256::from(0u64); - let diff: U256 = U256::from(1u64); - hash_d_rlp.append(&hash); - hash_d_rlp.append(&diff); - - rlp.append_raw(&hash_d_rlp.out(), 1); - } - - rlp.out() - } - - fn queue_info(unverified: usize, verified: usize) -> BlockQueueInfo { - BlockQueueInfo { - unverified_queue_size: unverified, - verified_queue_size: verified, - verifying_queue_size: 0, - max_queue_size: 1000, - max_mem_use: 1000, - mem_used: 500 - } - } - - fn sync_status(state: SyncState) -> SyncStatus { - SyncStatus { - state: state, - protocol_version: 0, - network_id: 0, - start_block_number: 0, - last_imported_block_number: None, - highest_block_number: None, - blocks_total: 0, - blocks_received: 0, - num_peers: 0, - num_active_peers: 0, - mem_used: 0, - num_snapshot_chunks: 0, - snapshot_chunks_done: 0, - last_imported_old_block_number: None, - } - } - - #[test] - fn is_still_verifying() { - assert!(!sync_status(SyncState::Idle).is_syncing(queue_info(2, 1))); - assert!(sync_status(SyncState::Idle).is_syncing(queue_info(2, 2))); - } - - #[test] - fn is_synced_state() { - assert!(sync_status(SyncState::Blocks).is_syncing(queue_info(0, 0))); - assert!(!sync_status(SyncState::Idle).is_syncing(queue_info(0, 0))); - } - - #[test] - fn return_receipts_empty() { - let mut client = TestBlockChainClient::new(); - let queue = RwLock::new(VecDeque::new()); - let ss = TestSnapshotService::new(); - let io = TestIo::new(&mut client, &ss, &queue, None); - - let result = ChainSync::return_receipts(&io, &Rlp::new(&[0xc0]), 0); - - assert!(result.is_ok()); - } - - #[test] - fn return_receipts() { - let mut client = TestBlockChainClient::new(); - let queue = RwLock::new(VecDeque::new()); - let sync = dummy_sync_with_peer(H256::new(), &client); - let ss = TestSnapshotService::new(); - let mut io = TestIo::new(&mut client, &ss, &queue, None); - - let mut receipt_list = RlpStream::new_list(4); - receipt_list.append(&H256::from("0000000000000000000000000000000000000000000000005555555555555555")); - receipt_list.append(&H256::from("ff00000000000000000000000000000000000000000000000000000000000000")); - receipt_list.append(&H256::from("fff0000000000000000000000000000000000000000000000000000000000000")); - receipt_list.append(&H256::from("aff0000000000000000000000000000000000000000000000000000000000000")); - - let receipts_request = receipt_list.out(); - // it returns rlp ONLY for hashes started with "f" - let result = ChainSync::return_receipts(&io, &Rlp::new(&receipts_request.clone()), 0); - - assert!(result.is_ok()); - let rlp_result = result.unwrap(); - assert!(rlp_result.is_some()); - - // the length of two rlp-encoded receipts - assert_eq!(603, rlp_result.unwrap().1.out().len()); - - io.sender = Some(2usize); - ChainSync::dispatch_packet(&RwLock::new(sync), &mut io, 0usize, super::GET_RECEIPTS_PACKET, &receipts_request); - assert_eq!(1, io.packets.len()); - } - - #[test] - fn return_block_headers() { - use ethcore::views::HeaderView; - fn make_hash_req(h: &H256, count: usize, skip: usize, reverse: bool) -> Bytes { - let mut rlp = RlpStream::new_list(4); - rlp.append(h); - rlp.append(&count); - rlp.append(&skip); - rlp.append(&if reverse {1u32} else {0u32}); - rlp.out() - } - - fn make_num_req(n: usize, count: usize, skip: usize, reverse: bool) -> Bytes { - let mut rlp = RlpStream::new_list(4); - rlp.append(&n); - rlp.append(&count); - rlp.append(&skip); - rlp.append(&if reverse {1u32} else {0u32}); - rlp.out() - } - fn to_header_vec(rlp: ::chain::RlpResponseResult) -> Vec { - Rlp::new(&rlp.unwrap().unwrap().1.out()).iter().map(|r| r.as_raw().to_vec()).collect() - } - - let mut client = TestBlockChainClient::new(); - client.add_blocks(100, EachBlockWith::Nothing); - let blocks: Vec<_> = (0 .. 100) - .map(|i| (&client as &BlockChainClient).block(BlockId::Number(i as BlockNumber)).map(|b| b.into_inner()).unwrap()).collect(); - let headers: Vec<_> = blocks.iter().map(|b| Rlp::new(b).at(0).unwrap().as_raw().to_vec()).collect(); - let hashes: Vec<_> = headers.iter().map(|h| view!(HeaderView, h).hash()).collect(); - - let queue = RwLock::new(VecDeque::new()); - let ss = TestSnapshotService::new(); - let io = TestIo::new(&mut client, &ss, &queue, None); - - let unknown: H256 = H256::new(); - let result = ChainSync::return_block_headers(&io, &Rlp::new(&make_hash_req(&unknown, 1, 0, false)), 0); - assert!(to_header_vec(result).is_empty()); - let result = ChainSync::return_block_headers(&io, &Rlp::new(&make_hash_req(&unknown, 1, 0, true)), 0); - assert!(to_header_vec(result).is_empty()); - - let result = ChainSync::return_block_headers(&io, &Rlp::new(&make_hash_req(&hashes[2], 1, 0, true)), 0); - assert_eq!(to_header_vec(result), vec![headers[2].clone()]); - - let result = ChainSync::return_block_headers(&io, &Rlp::new(&make_hash_req(&hashes[2], 1, 0, false)), 0); - assert_eq!(to_header_vec(result), vec![headers[2].clone()]); - - let result = ChainSync::return_block_headers(&io, &Rlp::new(&make_hash_req(&hashes[50], 3, 5, false)), 0); - assert_eq!(to_header_vec(result), vec![headers[50].clone(), headers[56].clone(), headers[62].clone()]); - - let result = ChainSync::return_block_headers(&io, &Rlp::new(&make_hash_req(&hashes[50], 3, 5, true)), 0); - assert_eq!(to_header_vec(result), vec![headers[50].clone(), headers[44].clone(), headers[38].clone()]); - - let result = ChainSync::return_block_headers(&io, &Rlp::new(&make_num_req(2, 1, 0, true)), 0); - assert_eq!(to_header_vec(result), vec![headers[2].clone()]); - - let result = ChainSync::return_block_headers(&io, &Rlp::new(&make_num_req(2, 1, 0, false)), 0); - assert_eq!(to_header_vec(result), vec![headers[2].clone()]); - - let result = ChainSync::return_block_headers(&io, &Rlp::new(&make_num_req(50, 3, 5, false)), 0); - assert_eq!(to_header_vec(result), vec![headers[50].clone(), headers[56].clone(), headers[62].clone()]); - - let result = ChainSync::return_block_headers(&io, &Rlp::new(&make_num_req(50, 3, 5, true)), 0); - assert_eq!(to_header_vec(result), vec![headers[50].clone(), headers[44].clone(), headers[38].clone()]); - } - - #[test] - fn return_nodes() { - let mut client = TestBlockChainClient::new(); - let queue = RwLock::new(VecDeque::new()); - let sync = dummy_sync_with_peer(H256::new(), &client); - let ss = TestSnapshotService::new(); - let mut io = TestIo::new(&mut client, &ss, &queue, None); - - let mut node_list = RlpStream::new_list(3); - node_list.append(&H256::from("0000000000000000000000000000000000000000000000005555555555555555")); - node_list.append(&H256::from("ffffffffffffffffffffffffffffffffffffffffffffaaaaaaaaaaaaaaaaaaaa")); - node_list.append(&H256::from("aff0000000000000000000000000000000000000000000000000000000000000")); - - let node_request = node_list.out(); - // it returns rlp ONLY for hashes started with "f" - let result = ChainSync::return_node_data(&io, &Rlp::new(&node_request.clone()), 0); - - assert!(result.is_ok()); - let rlp_result = result.unwrap(); - assert!(rlp_result.is_some()); - - // the length of one rlp-encoded hashe - let rlp = rlp_result.unwrap().1.out(); - let rlp = Rlp::new(&rlp); - assert_eq!(Ok(1), rlp.item_count()); - - io.sender = Some(2usize); - - ChainSync::dispatch_packet(&RwLock::new(sync), &mut io, 0usize, super::GET_NODE_DATA_PACKET, &node_request); - assert_eq!(1, io.packets.len()); - } - - fn dummy_sync_with_peer(peer_latest_hash: H256, client: &BlockChainClient) -> ChainSync { - let mut sync = ChainSync::new(SyncConfig::default(), client, Arc::new(NoopPrivateTxHandler)); - insert_dummy_peer(&mut sync, 0, peer_latest_hash); - sync - } - - fn insert_dummy_peer(sync: &mut ChainSync, peer_id: PeerId, peer_latest_hash: H256) { - sync.peers.insert(peer_id, - PeerInfo { - protocol_version: 0, - genesis: H256::zero(), - network_id: 0, - latest_hash: peer_latest_hash, - difficulty: None, - asking: PeerAsking::Nothing, - asking_blocks: Vec::new(), - asking_hash: None, - ask_time: Instant::now(), - last_sent_transactions: HashSet::new(), - expired: false, - confirmation: super::ForkConfirmation::Confirmed, - snapshot_number: None, - snapshot_hash: None, - asking_snapshot_data: None, - block_set: None, - }); - - } - - #[test] - fn finds_lagging_peers() { - let mut client = TestBlockChainClient::new(); - client.add_blocks(100, EachBlockWith::Uncle); - let mut sync = dummy_sync_with_peer(client.block_hash_delta_minus(10), &client); - let chain_info = client.chain_info(); - - let lagging_peers = sync.get_lagging_peers(&chain_info); - - assert_eq!(1, lagging_peers.len()); - } - - #[test] - fn calculates_tree_for_lagging_peer() { - let mut client = TestBlockChainClient::new(); - client.add_blocks(15, EachBlockWith::Uncle); - - let start = client.block_hash_delta_minus(4); - let end = client.block_hash_delta_minus(2); - - // wrong way end -> start, should be None - let rlp = ChainSync::create_new_hashes_rlp(&client, &end, &start); - assert!(rlp.is_none()); - - let rlp = ChainSync::create_new_hashes_rlp(&client, &start, &end).unwrap(); - // size of three rlp encoded hash-difficulty - assert_eq!(107, rlp.len()); - } - - #[test] - fn sends_new_hashes_to_lagging_peer() { - let mut client = TestBlockChainClient::new(); - client.add_blocks(100, EachBlockWith::Uncle); - let queue = RwLock::new(VecDeque::new()); - let mut sync = dummy_sync_with_peer(client.block_hash_delta_minus(5), &client); - let chain_info = client.chain_info(); - let ss = TestSnapshotService::new(); - let mut io = TestIo::new(&mut client, &ss, &queue, None); - - let peers = sync.get_lagging_peers(&chain_info); - let peer_count = sync.propagate_new_hashes(&chain_info, &mut io, &peers); - - // 1 message should be send - assert_eq!(1, io.packets.len()); - // 1 peer should be updated - assert_eq!(1, peer_count); - // NEW_BLOCK_HASHES_PACKET - assert_eq!(0x01, io.packets[0].packet_id); - } - - #[test] - fn sends_latest_block_to_lagging_peer() { - let mut client = TestBlockChainClient::new(); - client.add_blocks(100, EachBlockWith::Uncle); - let queue = RwLock::new(VecDeque::new()); - let mut sync = dummy_sync_with_peer(client.block_hash_delta_minus(5), &client); - let chain_info = client.chain_info(); - let ss = TestSnapshotService::new(); - let mut io = TestIo::new(&mut client, &ss, &queue, None); - let peers = sync.get_lagging_peers(&chain_info); - let peer_count = sync.propagate_blocks(&chain_info, &mut io, &[], &peers); - - // 1 message should be send - assert_eq!(1, io.packets.len()); - // 1 peer should be updated - assert_eq!(1, peer_count); - // NEW_BLOCK_PACKET - assert_eq!(0x07, io.packets[0].packet_id); - } - - #[test] - fn sends_sealed_block() { - let mut client = TestBlockChainClient::new(); - client.add_blocks(100, EachBlockWith::Uncle); - let queue = RwLock::new(VecDeque::new()); - let hash = client.block_hash(BlockId::Number(99)).unwrap(); - let mut sync = dummy_sync_with_peer(client.block_hash_delta_minus(5), &client); - let chain_info = client.chain_info(); - let ss = TestSnapshotService::new(); - let mut io = TestIo::new(&mut client, &ss, &queue, None); - let peers = sync.get_lagging_peers(&chain_info); - let peer_count = sync.propagate_blocks(&chain_info, &mut io, &[hash.clone()], &peers); - - // 1 message should be send - assert_eq!(1, io.packets.len()); - // 1 peer should be updated - assert_eq!(1, peer_count); - // NEW_BLOCK_PACKET - assert_eq!(0x07, io.packets[0].packet_id); - } - - #[test] - fn sends_proposed_block() { - let mut client = TestBlockChainClient::new(); - client.add_blocks(2, EachBlockWith::Uncle); - let queue = RwLock::new(VecDeque::new()); - let block = client.block(BlockId::Latest).unwrap().into_inner(); - let mut sync = ChainSync::new(SyncConfig::default(), &client, Arc::new(NoopPrivateTxHandler)); - sync.peers.insert(0, - PeerInfo { - // Messaging protocol - protocol_version: 2, - genesis: H256::zero(), - network_id: 0, - latest_hash: client.block_hash_delta_minus(1), - difficulty: None, - asking: PeerAsking::Nothing, - asking_blocks: Vec::new(), - asking_hash: None, - ask_time: Instant::now(), - last_sent_transactions: HashSet::new(), - expired: false, - confirmation: super::ForkConfirmation::Confirmed, - snapshot_number: None, - snapshot_hash: None, - asking_snapshot_data: None, - block_set: None, - }); - let ss = TestSnapshotService::new(); - let mut io = TestIo::new(&mut client, &ss, &queue, None); - sync.propagate_proposed_blocks(&mut io, &[block]); - - // 1 message should be sent - assert_eq!(1, io.packets.len()); - // NEW_BLOCK_PACKET - assert_eq!(0x07, io.packets[0].packet_id); - } - - #[test] - fn propagates_transactions() { - let mut client = TestBlockChainClient::new(); - client.add_blocks(100, EachBlockWith::Uncle); - client.insert_transaction_to_queue(); - let mut sync = dummy_sync_with_peer(client.block_hash_delta_minus(1), &client); - let queue = RwLock::new(VecDeque::new()); - let ss = TestSnapshotService::new(); - let mut io = TestIo::new(&mut client, &ss, &queue, None); - let peer_count = sync.propagate_new_transactions(&mut io); - // Try to propagate same transactions for the second time - let peer_count2 = sync.propagate_new_transactions(&mut io); - // Even after new block transactions should not be propagated twice - sync.chain_new_blocks(&mut io, &[], &[], &[], &[], &[], &[]); - // Try to propagate same transactions for the third time - let peer_count3 = sync.propagate_new_transactions(&mut io); - - // 1 message should be send - assert_eq!(1, io.packets.len()); - // 1 peer should be updated but only once - assert_eq!(1, peer_count); - assert_eq!(0, peer_count2); - assert_eq!(0, peer_count3); - // TRANSACTIONS_PACKET - assert_eq!(0x02, io.packets[0].packet_id); - } - - #[test] - fn does_not_propagate_new_transactions_after_new_block() { - let mut client = TestBlockChainClient::new(); - client.add_blocks(100, EachBlockWith::Uncle); - client.insert_transaction_to_queue(); - let mut sync = dummy_sync_with_peer(client.block_hash_delta_minus(1), &client); - let queue = RwLock::new(VecDeque::new()); - let ss = TestSnapshotService::new(); - let mut io = TestIo::new(&mut client, &ss, &queue, None); - let peer_count = sync.propagate_new_transactions(&mut io); - io.chain.insert_transaction_to_queue(); - // New block import should not trigger propagation. - // (we only propagate on timeout) - sync.chain_new_blocks(&mut io, &[], &[], &[], &[], &[], &[]); - - // 2 message should be send - assert_eq!(1, io.packets.len()); - // 1 peer should receive the message - assert_eq!(1, peer_count); - // TRANSACTIONS_PACKET - assert_eq!(0x02, io.packets[0].packet_id); - } - - #[test] - fn does_not_fail_for_no_peers() { - let mut client = TestBlockChainClient::new(); - client.add_blocks(100, EachBlockWith::Uncle); - client.insert_transaction_to_queue(); - // Sync with no peers - let mut sync = ChainSync::new(SyncConfig::default(), &client, Arc::new(NoopPrivateTxHandler)); - let queue = RwLock::new(VecDeque::new()); - let ss = TestSnapshotService::new(); - let mut io = TestIo::new(&mut client, &ss, &queue, None); - let peer_count = sync.propagate_new_transactions(&mut io); - sync.chain_new_blocks(&mut io, &[], &[], &[], &[], &[], &[]); - // Try to propagate same transactions for the second time - let peer_count2 = sync.propagate_new_transactions(&mut io); - - assert_eq!(0, io.packets.len()); - assert_eq!(0, peer_count); - assert_eq!(0, peer_count2); - } - - #[test] - fn propagates_transactions_without_alternating() { - let mut client = TestBlockChainClient::new(); - client.add_blocks(100, EachBlockWith::Uncle); - client.insert_transaction_to_queue(); - let mut sync = dummy_sync_with_peer(client.block_hash_delta_minus(1), &client); - let queue = RwLock::new(VecDeque::new()); - let ss = TestSnapshotService::new(); - // should sent some - { - let mut io = TestIo::new(&mut client, &ss, &queue, None); - let peer_count = sync.propagate_new_transactions(&mut io); - assert_eq!(1, io.packets.len()); - assert_eq!(1, peer_count); - } - // Insert some more - client.insert_transaction_to_queue(); - let (peer_count2, peer_count3) = { - let mut io = TestIo::new(&mut client, &ss, &queue, None); - // Propagate new transactions - let peer_count2 = sync.propagate_new_transactions(&mut io); - // And now the peer should have all transactions - let peer_count3 = sync.propagate_new_transactions(&mut io); - (peer_count2, peer_count3) - }; - - // 2 message should be send (in total) - assert_eq!(2, queue.read().len()); - // 1 peer should be updated but only once after inserting new transaction - assert_eq!(1, peer_count2); - assert_eq!(0, peer_count3); - // TRANSACTIONS_PACKET - assert_eq!(0x02, queue.read()[0].packet_id); - assert_eq!(0x02, queue.read()[1].packet_id); - } - - #[test] - fn should_maintain_transations_propagation_stats() { - let mut client = TestBlockChainClient::new(); - client.add_blocks(100, EachBlockWith::Uncle); - client.insert_transaction_to_queue(); - let mut sync = dummy_sync_with_peer(client.block_hash_delta_minus(1), &client); - let queue = RwLock::new(VecDeque::new()); - let ss = TestSnapshotService::new(); - let mut io = TestIo::new(&mut client, &ss, &queue, None); - sync.propagate_new_transactions(&mut io); - - let stats = sync.transactions_stats(); - assert_eq!(stats.len(), 1, "Should maintain stats for single transaction.") - } - - #[test] - fn should_propagate_service_transaction_to_selected_peers_only() { - let mut client = TestBlockChainClient::new(); - client.insert_transaction_with_gas_price_to_queue(U256::zero()); - let block_hash = client.block_hash_delta_minus(1); - let mut sync = ChainSync::new(SyncConfig::default(), &client, Arc::new(NoopPrivateTxHandler)); - let queue = RwLock::new(VecDeque::new()); - let ss = TestSnapshotService::new(); - let mut io = TestIo::new(&mut client, &ss, &queue, None); - - // when peer#1 is Geth - insert_dummy_peer(&mut sync, 1, block_hash); - io.peers_info.insert(1, "Geth".to_owned()); - // and peer#2 is Parity, accepting service transactions - insert_dummy_peer(&mut sync, 2, block_hash); - io.peers_info.insert(2, "Parity/v1.6".to_owned()); - // and peer#3 is Parity, discarding service transactions - insert_dummy_peer(&mut sync, 3, block_hash); - io.peers_info.insert(3, "Parity/v1.5".to_owned()); - // and peer#4 is Parity, accepting service transactions - insert_dummy_peer(&mut sync, 4, block_hash); - io.peers_info.insert(4, "Parity/v1.7.3-ABCDEFGH".to_owned()); - - // and new service transaction is propagated to peers - sync.propagate_new_transactions(&mut io); - - // peer#2 && peer#4 are receiving service transaction - assert!(io.packets.iter().any(|p| p.packet_id == 0x02 && p.recipient == 2)); // TRANSACTIONS_PACKET - assert!(io.packets.iter().any(|p| p.packet_id == 0x02 && p.recipient == 4)); // TRANSACTIONS_PACKET - assert_eq!(io.packets.len(), 2); - } - - #[test] - fn should_propagate_service_transaction_is_sent_as_separate_message() { - let mut client = TestBlockChainClient::new(); - let tx1_hash = client.insert_transaction_to_queue(); - let tx2_hash = client.insert_transaction_with_gas_price_to_queue(U256::zero()); - let block_hash = client.block_hash_delta_minus(1); - let mut sync = ChainSync::new(SyncConfig::default(), &client, Arc::new(NoopPrivateTxHandler)); - let queue = RwLock::new(VecDeque::new()); - let ss = TestSnapshotService::new(); - let mut io = TestIo::new(&mut client, &ss, &queue, None); - - // when peer#1 is Parity, accepting service transactions - insert_dummy_peer(&mut sync, 1, block_hash); - io.peers_info.insert(1, "Parity/v1.6".to_owned()); - - // and service + non-service transactions are propagated to peers - sync.propagate_new_transactions(&mut io); - - // two separate packets for peer are queued: - // 1) with non-service-transaction - // 2) with service transaction - let sent_transactions: Vec = io.packets.iter() - .filter_map(|p| { - if p.packet_id != 0x02 || p.recipient != 1 { // TRANSACTIONS_PACKET - return None; - } - - let rlp = Rlp::new(&*p.data); - let item_count = rlp.item_count().unwrap_or(0); - if item_count != 1 { - return None; - } - - rlp.at(0).ok().and_then(|r| r.as_val().ok()) - }) - .collect(); - assert_eq!(sent_transactions.len(), 2); - assert!(sent_transactions.iter().any(|tx| tx.hash() == tx1_hash)); - assert!(sent_transactions.iter().any(|tx| tx.hash() == tx2_hash)); - } - - #[test] - fn handles_peer_new_block_malformed() { - let mut client = TestBlockChainClient::new(); - client.add_blocks(10, EachBlockWith::Uncle); - - let block_data = get_dummy_block(11, client.chain_info().best_block_hash); - - let queue = RwLock::new(VecDeque::new()); - let mut sync = dummy_sync_with_peer(client.block_hash_delta_minus(5), &client); - //sync.have_common_block = true; - let ss = TestSnapshotService::new(); - let mut io = TestIo::new(&mut client, &ss, &queue, None); - - let block = Rlp::new(&block_data); - - let result = sync.on_peer_new_block(&mut io, 0, &block); - - assert!(result.is_err()); - } - - #[test] - fn handles_peer_new_block() { - let mut client = TestBlockChainClient::new(); - client.add_blocks(10, EachBlockWith::Uncle); - - let block_data = get_dummy_blocks(11, client.chain_info().best_block_hash); - - let queue = RwLock::new(VecDeque::new()); - let mut sync = dummy_sync_with_peer(client.block_hash_delta_minus(5), &client); - let ss = TestSnapshotService::new(); - let mut io = TestIo::new(&mut client, &ss, &queue, None); - - let block = Rlp::new(&block_data); - - let result = sync.on_peer_new_block(&mut io, 0, &block); - - assert!(result.is_ok()); - } - - #[test] - fn handles_peer_new_block_empty() { - let mut client = TestBlockChainClient::new(); - client.add_blocks(10, EachBlockWith::Uncle); - let queue = RwLock::new(VecDeque::new()); - let mut sync = dummy_sync_with_peer(client.block_hash_delta_minus(5), &client); - let ss = TestSnapshotService::new(); - let mut io = TestIo::new(&mut client, &ss, &queue, None); - - let empty_data = vec![]; - let block = Rlp::new(&empty_data); - - let result = sync.on_peer_new_block(&mut io, 0, &block); - - assert!(result.is_err()); - } - - #[test] - fn handles_peer_new_hashes() { - let mut client = TestBlockChainClient::new(); - client.add_blocks(10, EachBlockWith::Uncle); - let queue = RwLock::new(VecDeque::new()); - let mut sync = dummy_sync_with_peer(client.block_hash_delta_minus(5), &client); - let ss = TestSnapshotService::new(); - let mut io = TestIo::new(&mut client, &ss, &queue, None); - - let hashes_data = get_dummy_hashes(); - let hashes_rlp = Rlp::new(&hashes_data); - - let result = sync.on_peer_new_hashes(&mut io, 0, &hashes_rlp); - - assert!(result.is_ok()); - } - - #[test] - fn handles_peer_new_hashes_empty() { - let mut client = TestBlockChainClient::new(); - client.add_blocks(10, EachBlockWith::Uncle); - let queue = RwLock::new(VecDeque::new()); - let mut sync = dummy_sync_with_peer(client.block_hash_delta_minus(5), &client); - let ss = TestSnapshotService::new(); - let mut io = TestIo::new(&mut client, &ss, &queue, None); - - let empty_hashes_data = vec![]; - let hashes_rlp = Rlp::new(&empty_hashes_data); - - let result = sync.on_peer_new_hashes(&mut io, 0, &hashes_rlp); - - assert!(result.is_ok()); - } - - // idea is that what we produce when propagading latest hashes should be accepted in - // on_peer_new_hashes in our code as well - #[test] - fn hashes_rlp_mutually_acceptable() { - let mut client = TestBlockChainClient::new(); - client.add_blocks(100, EachBlockWith::Uncle); - let queue = RwLock::new(VecDeque::new()); - let mut sync = dummy_sync_with_peer(client.block_hash_delta_minus(5), &client); - let chain_info = client.chain_info(); - let ss = TestSnapshotService::new(); - let mut io = TestIo::new(&mut client, &ss, &queue, None); - - let peers = sync.get_lagging_peers(&chain_info); - sync.propagate_new_hashes(&chain_info, &mut io, &peers); - - let data = &io.packets[0].data.clone(); - let result = sync.on_peer_new_hashes(&mut io, 0, &Rlp::new(data)); - assert!(result.is_ok()); - } - - // idea is that what we produce when propagading latest block should be accepted in - // on_peer_new_block in our code as well - #[test] - fn block_rlp_mutually_acceptable() { - let mut client = TestBlockChainClient::new(); - client.add_blocks(100, EachBlockWith::Uncle); - let queue = RwLock::new(VecDeque::new()); - let mut sync = dummy_sync_with_peer(client.block_hash_delta_minus(5), &client); - let chain_info = client.chain_info(); - let ss = TestSnapshotService::new(); - let mut io = TestIo::new(&mut client, &ss, &queue, None); - - let peers = sync.get_lagging_peers(&chain_info); - sync.propagate_blocks(&chain_info, &mut io, &[], &peers); - - let data = &io.packets[0].data.clone(); - let result = sync.on_peer_new_block(&mut io, 0, &Rlp::new(data)); - assert!(result.is_ok()); - } - - #[test] - fn should_add_transactions_to_queue() { - fn sender(tx: &UnverifiedTransaction) -> Address { - ethkey::public_to_address(&tx.recover_public().unwrap()) - } - - // given - let mut client = TestBlockChainClient::new(); - client.add_blocks(98, EachBlockWith::Uncle); - client.add_blocks(1, EachBlockWith::UncleAndTransaction); - client.add_blocks(1, EachBlockWith::Transaction); - let mut sync = dummy_sync_with_peer(client.block_hash_delta_minus(5), &client); - - let good_blocks = vec![client.block_hash_delta_minus(2)]; - let retracted_blocks = vec![client.block_hash_delta_minus(1)]; - - // Add some balance to clients and reset nonces - for h in &[good_blocks[0], retracted_blocks[0]] { - let block = client.block(BlockId::Hash(*h)).unwrap(); - let sender = sender(&block.transactions()[0]);; - client.set_balance(sender, U256::from(10_000_000_000_000_000_000u64)); - client.set_nonce(sender, U256::from(0)); - } - - - // when - { - let queue = RwLock::new(VecDeque::new()); - let ss = TestSnapshotService::new(); - let mut io = TestIo::new(&mut client, &ss, &queue, None); - io.chain.miner.chain_new_blocks(io.chain, &[], &[], &[], &good_blocks, false); - sync.chain_new_blocks(&mut io, &[], &[], &[], &good_blocks, &[], &[]); - assert_eq!(io.chain.miner.ready_transactions(io.chain).len(), 1); - } - // We need to update nonce status (because we say that the block has been imported) - for h in &[good_blocks[0]] { - let block = client.block(BlockId::Hash(*h)).unwrap(); - client.set_nonce(sender(&block.transactions()[0]), U256::from(1)); - } - { - let queue = RwLock::new(VecDeque::new()); - let ss = TestSnapshotService::new(); - let mut io = TestIo::new(&client, &ss, &queue, None); - io.chain.miner.chain_new_blocks(io.chain, &[], &[], &good_blocks, &retracted_blocks, false); - sync.chain_new_blocks(&mut io, &[], &[], &good_blocks, &retracted_blocks, &[], &[]); - } - - // then - assert_eq!(client.miner.ready_transactions(&client).len(), 1); - } - - #[test] - fn should_not_add_transactions_to_queue_if_not_synced() { - // given - let mut client = TestBlockChainClient::new(); - client.add_blocks(98, EachBlockWith::Uncle); - client.add_blocks(1, EachBlockWith::UncleAndTransaction); - client.add_blocks(1, EachBlockWith::Transaction); - let mut sync = dummy_sync_with_peer(client.block_hash_delta_minus(5), &client); - - let good_blocks = vec![client.block_hash_delta_minus(2)]; - let retracted_blocks = vec![client.block_hash_delta_minus(1)]; - - let queue = RwLock::new(VecDeque::new()); - let ss = TestSnapshotService::new(); - let mut io = TestIo::new(&mut client, &ss, &queue, None); - - // when - sync.chain_new_blocks(&mut io, &[], &[], &[], &good_blocks, &[], &[]); - assert_eq!(io.chain.miner.queue_status().status.transaction_count, 0); - sync.chain_new_blocks(&mut io, &[], &[], &good_blocks, &retracted_blocks, &[], &[]); - - // then - let status = io.chain.miner.queue_status(); - assert_eq!(status.status.transaction_count, 0); - } -} diff --git a/ethcore/sync/src/chain/handler.rs b/ethcore/sync/src/chain/handler.rs new file mode 100644 index 0000000000..966b7ce20a --- /dev/null +++ b/ethcore/sync/src/chain/handler.rs @@ -0,0 +1,828 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +use api::WARP_SYNC_PROTOCOL_ID; +use block_sync::{BlockDownloaderImportError as DownloaderImportError, DownloadAction}; +use bytes::Bytes; +use ethcore::client::{BlockStatus, BlockId, BlockImportError, BlockImportErrorKind}; +use ethcore::error::*; +use ethcore::header::{BlockNumber, Header as BlockHeader}; +use ethcore::snapshot::{ManifestData, RestorationStatus}; +use ethereum_types::{H256, U256}; +use hash::keccak; +use network::PeerId; +use rlp::Rlp; +use snapshot::ChunkType; +use std::cmp; +use std::collections::HashSet; +use std::time::Instant; +use sync_io::SyncIo; + +use super::{ + BlockSet, + ChainSync, + ForkConfirmation, + PacketDecodeError, + PeerAsking, + PeerInfo, + SyncRequester, + SyncState, + ETH_PROTOCOL_VERSION_62, + ETH_PROTOCOL_VERSION_63, + MAX_NEW_BLOCK_AGE, + MAX_NEW_HASHES, + PAR_PROTOCOL_VERSION_1, + PAR_PROTOCOL_VERSION_2, + PAR_PROTOCOL_VERSION_3, + BLOCK_BODIES_PACKET, + BLOCK_HEADERS_PACKET, + NEW_BLOCK_HASHES_PACKET, + NEW_BLOCK_PACKET, + PRIVATE_TRANSACTION_PACKET, + RECEIPTS_PACKET, + SIGNED_PRIVATE_TRANSACTION_PACKET, + SNAPSHOT_DATA_PACKET, + SNAPSHOT_MANIFEST_PACKET, + STATUS_PACKET, + TRANSACTIONS_PACKET, +}; + +/// The Chain Sync Handler: handles responses from peers +pub struct SyncHandler; + +impl SyncHandler { + /// Handle incoming packet from peer + pub fn on_packet(sync: &mut ChainSync, io: &mut SyncIo, peer: PeerId, packet_id: u8, data: &[u8]) { + if packet_id != STATUS_PACKET && !sync.peers.contains_key(&peer) { + debug!(target:"sync", "Unexpected packet {} from unregistered peer: {}:{}", packet_id, peer, io.peer_info(peer)); + return; + } + let rlp = Rlp::new(data); + let result = match packet_id { + STATUS_PACKET => SyncHandler::on_peer_status(sync, io, peer, &rlp), + TRANSACTIONS_PACKET => SyncHandler::on_peer_transactions(sync, io, peer, &rlp), + BLOCK_HEADERS_PACKET => SyncHandler::on_peer_block_headers(sync, io, peer, &rlp), + BLOCK_BODIES_PACKET => SyncHandler::on_peer_block_bodies(sync, io, peer, &rlp), + RECEIPTS_PACKET => SyncHandler::on_peer_block_receipts(sync, io, peer, &rlp), + NEW_BLOCK_PACKET => SyncHandler::on_peer_new_block(sync, io, peer, &rlp), + NEW_BLOCK_HASHES_PACKET => SyncHandler::on_peer_new_hashes(sync, io, peer, &rlp), + SNAPSHOT_MANIFEST_PACKET => SyncHandler::on_snapshot_manifest(sync, io, peer, &rlp), + SNAPSHOT_DATA_PACKET => SyncHandler::on_snapshot_data(sync, io, peer, &rlp), + PRIVATE_TRANSACTION_PACKET => SyncHandler::on_private_transaction(sync, io, peer, &rlp), + SIGNED_PRIVATE_TRANSACTION_PACKET => SyncHandler::on_signed_private_transaction(sync, io, peer, &rlp), + _ => { + debug!(target: "sync", "{}: Unknown packet {}", peer, packet_id); + Ok(()) + } + }; + result.unwrap_or_else(|e| { + debug!(target:"sync", "{} -> Malformed packet {} : {}", peer, packet_id, e); + }) + } + + /// Called when peer sends us new consensus packet + pub fn on_consensus_packet(io: &mut SyncIo, peer_id: PeerId, r: &Rlp) -> Result<(), PacketDecodeError> { + trace!(target: "sync", "Received consensus packet from {:?}", peer_id); + io.chain().queue_consensus_message(r.as_raw().to_vec()); + Ok(()) + } + + /// Called by peer when it is disconnecting + pub fn on_peer_aborting(sync: &mut ChainSync, io: &mut SyncIo, peer: PeerId) { + trace!(target: "sync", "== Disconnecting {}: {}", peer, io.peer_info(peer)); + sync.handshaking_peers.remove(&peer); + if sync.peers.contains_key(&peer) { + debug!(target: "sync", "Disconnected {}", peer); + sync.clear_peer_download(peer); + sync.peers.remove(&peer); + sync.active_peers.remove(&peer); + sync.continue_sync(io); + } + } + + /// Called when a new peer is connected + pub fn on_peer_connected(sync: &mut ChainSync, io: &mut SyncIo, peer: PeerId) { + trace!(target: "sync", "== Connected {}: {}", peer, io.peer_info(peer)); + if let Err(e) = sync.send_status(io, peer) { + debug!(target:"sync", "Error sending status request: {:?}", e); + io.disconnect_peer(peer); + } else { + sync.handshaking_peers.insert(peer, Instant::now()); + } + } + + /// Called by peer once it has new block bodies + pub fn on_peer_new_block(sync: &mut ChainSync, io: &mut SyncIo, peer_id: PeerId, r: &Rlp) -> Result<(), PacketDecodeError> { + if !sync.peers.get(&peer_id).map_or(false, |p| p.can_sync()) { + trace!(target: "sync", "Ignoring new block from unconfirmed peer {}", peer_id); + return Ok(()); + } + let difficulty: U256 = r.val_at(1)?; + if let Some(ref mut peer) = sync.peers.get_mut(&peer_id) { + if peer.difficulty.map_or(true, |pd| difficulty > pd) { + peer.difficulty = Some(difficulty); + } + } + let block_rlp = r.at(0)?; + let header_rlp = block_rlp.at(0)?; + let h = keccak(&header_rlp.as_raw()); + trace!(target: "sync", "{} -> NewBlock ({})", peer_id, h); + let header: BlockHeader = header_rlp.as_val()?; + if header.number() > sync.highest_block.unwrap_or(0) { + sync.highest_block = Some(header.number()); + } + let mut unknown = false; + { + if let Some(ref mut peer) = sync.peers.get_mut(&peer_id) { + peer.latest_hash = header.hash(); + } + } + let last_imported_number = sync.new_blocks.last_imported_block_number(); + if last_imported_number > header.number() && last_imported_number - header.number() > MAX_NEW_BLOCK_AGE { + trace!(target: "sync", "Ignored ancient new block {:?}", h); + io.disable_peer(peer_id); + return Ok(()); + } + match io.chain().import_block(block_rlp.as_raw().to_vec()) { + Err(BlockImportError(BlockImportErrorKind::Import(ImportErrorKind::AlreadyInChain), _)) => { + trace!(target: "sync", "New block already in chain {:?}", h); + }, + Err(BlockImportError(BlockImportErrorKind::Import(ImportErrorKind::AlreadyQueued), _)) => { + trace!(target: "sync", "New block already queued {:?}", h); + }, + Ok(_) => { + // abort current download of the same block + sync.complete_sync(io); + sync.new_blocks.mark_as_known(&header.hash(), header.number()); + trace!(target: "sync", "New block queued {:?} ({})", h, header.number()); + }, + Err(BlockImportError(BlockImportErrorKind::Block(BlockError::UnknownParent(p)), _)) => { + unknown = true; + trace!(target: "sync", "New block with unknown parent ({:?}) {:?}", p, h); + }, + Err(e) => { + debug!(target: "sync", "Bad new block {:?} : {:?}", h, e); + io.disable_peer(peer_id); + } + }; + if unknown { + if sync.state != SyncState::Idle { + trace!(target: "sync", "NewBlock ignored while seeking"); + } else { + trace!(target: "sync", "New unknown block {:?}", h); + //TODO: handle too many unknown blocks + sync.sync_peer(io, peer_id, true); + } + } + sync.continue_sync(io); + Ok(()) + } + + /// Handles `NewHashes` packet. Initiates headers download for any unknown hashes. + pub fn on_peer_new_hashes(sync: &mut ChainSync, io: &mut SyncIo, peer_id: PeerId, r: &Rlp) -> Result<(), PacketDecodeError> { + if !sync.peers.get(&peer_id).map_or(false, |p| p.can_sync()) { + trace!(target: "sync", "Ignoring new hashes from unconfirmed peer {}", peer_id); + return Ok(()); + } + let hashes: Vec<_> = r.iter().take(MAX_NEW_HASHES).map(|item| (item.val_at::(0), item.val_at::(1))).collect(); + if let Some(ref mut peer) = sync.peers.get_mut(&peer_id) { + // Peer has new blocks with unknown difficulty + peer.difficulty = None; + if let Some(&(Ok(ref h), _)) = hashes.last() { + peer.latest_hash = h.clone(); + } + } + if sync.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, cmp::max); + if max > sync.highest_block.unwrap_or(0) { + sync.highest_block = Some(max); + } + sync.continue_sync(io); + return Ok(()); + } + trace!(target: "sync", "{} -> NewHashes ({} entries)", peer_id, r.item_count()?); + let mut max_height: BlockNumber = 0; + let mut new_hashes = Vec::new(); + let last_imported_number = sync.new_blocks.last_imported_block_number(); + for (rh, rn) in hashes { + let hash = rh?; + let number = rn?; + if number > sync.highest_block.unwrap_or(0) { + sync.highest_block = Some(number); + } + if sync.new_blocks.is_downloading(&hash) { + continue; + } + if last_imported_number > number && last_imported_number - number > MAX_NEW_BLOCK_AGE { + trace!(target: "sync", "Ignored ancient new block hash {:?}", hash); + io.disable_peer(peer_id); + continue; + } + match io.chain().block_status(BlockId::Hash(hash.clone())) { + BlockStatus::InChain => { + trace!(target: "sync", "New block hash already in chain {:?}", hash); + }, + BlockStatus::Queued => { + trace!(target: "sync", "New hash block already queued {:?}", hash); + }, + BlockStatus::Unknown | BlockStatus::Pending => { + new_hashes.push(hash.clone()); + if number > max_height { + trace!(target: "sync", "New unknown block hash {:?}", hash); + if let Some(ref mut peer) = sync.peers.get_mut(&peer_id) { + peer.latest_hash = hash.clone(); + } + max_height = number; + } + }, + BlockStatus::Bad => { + debug!(target: "sync", "Bad new block hash {:?}", hash); + io.disable_peer(peer_id); + return Ok(()); + } + } + }; + if max_height != 0 { + trace!(target: "sync", "Downloading blocks for new hashes"); + sync.new_blocks.reset_to(new_hashes); + sync.state = SyncState::NewBlocks; + sync.sync_peer(io, peer_id, true); + } + sync.continue_sync(io); + Ok(()) + } + + /// Called by peer once it has new block bodies + fn on_peer_block_bodies(sync: &mut ChainSync, io: &mut SyncIo, peer_id: PeerId, r: &Rlp) -> Result<(), PacketDecodeError> { + sync.clear_peer_download(peer_id); + let block_set = sync.peers.get(&peer_id).and_then(|p| p.block_set).unwrap_or(BlockSet::NewBlocks); + if !sync.reset_peer_asking(peer_id, PeerAsking::BlockBodies) { + trace!(target: "sync", "{}: Ignored unexpected bodies", peer_id); + sync.continue_sync(io); + return Ok(()); + } + let item_count = r.item_count()?; + trace!(target: "sync", "{} -> BlockBodies ({} entries), set = {:?}", peer_id, item_count, block_set); + if item_count == 0 { + sync.deactivate_peer(io, peer_id); + } + else if sync.state == SyncState::Waiting { + trace!(target: "sync", "Ignored block bodies while waiting"); + } + else + { + let result = { + let downloader = match block_set { + BlockSet::NewBlocks => &mut sync.new_blocks, + BlockSet::OldBlocks => match sync.old_blocks { + None => { + trace!(target: "sync", "Ignored block headers while block download is inactive"); + sync.continue_sync(io); + return Ok(()); + }, + Some(ref mut blocks) => blocks, + } + }; + downloader.import_bodies(io, r) + }; + + match result { + Err(DownloaderImportError::Invalid) => { + io.disable_peer(peer_id); + sync.deactivate_peer(io, peer_id); + sync.continue_sync(io); + return Ok(()); + }, + Err(DownloaderImportError::Useless) => { + sync.deactivate_peer(io, peer_id); + }, + Ok(()) => (), + } + + sync.collect_blocks(io, block_set); + sync.sync_peer(io, peer_id, false); + } + sync.continue_sync(io); + Ok(()) + } + + fn on_peer_confirmed(sync: &mut ChainSync, io: &mut SyncIo, peer_id: PeerId) { + sync.sync_peer(io, peer_id, false); + } + + fn on_peer_fork_header(sync: &mut ChainSync, io: &mut SyncIo, peer_id: PeerId, r: &Rlp) -> Result<(), PacketDecodeError> { + { + let peer = sync.peers.get_mut(&peer_id).expect("Is only called when peer is present in peers"); + peer.asking = PeerAsking::Nothing; + let item_count = r.item_count()?; + let (fork_number, fork_hash) = sync.fork_block.expect("ForkHeader request is sent only fork block is Some; qed").clone(); + + if item_count == 0 || item_count != 1 { + trace!(target: "sync", "{}: Chain is too short to confirm the block", peer_id); + io.disable_peer(peer_id); + return Ok(()); + } + + let header = r.at(0)?.as_raw(); + if keccak(&header) != fork_hash { + trace!(target: "sync", "{}: Fork mismatch", peer_id); + io.disable_peer(peer_id); + return Ok(()); + } + + trace!(target: "sync", "{}: Confirmed peer", peer_id); + peer.confirmation = ForkConfirmation::Confirmed; + if !io.chain_overlay().read().contains_key(&fork_number) { + io.chain_overlay().write().insert(fork_number, header.to_vec()); + } + } + SyncHandler::on_peer_confirmed(sync, io, peer_id); + return Ok(()); + } + + /// Called by peer once it has new block headers during sync + fn on_peer_block_headers(sync: &mut ChainSync, io: &mut SyncIo, peer_id: PeerId, r: &Rlp) -> Result<(), PacketDecodeError> { + let is_fork_header_request = match sync.peers.get(&peer_id) { + Some(peer) if peer.asking == PeerAsking::ForkHeader => true, + _ => false, + }; + + if is_fork_header_request { + return SyncHandler::on_peer_fork_header(sync, io, peer_id, r); + } + + sync.clear_peer_download(peer_id); + let expected_hash = sync.peers.get(&peer_id).and_then(|p| p.asking_hash); + let allowed = sync.peers.get(&peer_id).map(|p| p.is_allowed()).unwrap_or(false); + let block_set = sync.peers.get(&peer_id).and_then(|p| p.block_set).unwrap_or(BlockSet::NewBlocks); + if !sync.reset_peer_asking(peer_id, PeerAsking::BlockHeaders) || expected_hash.is_none() || !allowed { + trace!(target: "sync", "{}: Ignored unexpected headers, expected_hash = {:?}", peer_id, expected_hash); + sync.continue_sync(io); + return Ok(()); + } + let item_count = r.item_count()?; + trace!(target: "sync", "{} -> BlockHeaders ({} entries), state = {:?}, set = {:?}", peer_id, item_count, sync.state, block_set); + if (sync.state == SyncState::Idle || sync.state == SyncState::WaitingPeers) && sync.old_blocks.is_none() { + trace!(target: "sync", "Ignored unexpected block headers"); + sync.continue_sync(io); + return Ok(()); + } + if sync.state == SyncState::Waiting { + trace!(target: "sync", "Ignored block headers while waiting"); + sync.continue_sync(io); + return Ok(()); + } + + let result = { + let downloader = match block_set { + BlockSet::NewBlocks => &mut sync.new_blocks, + BlockSet::OldBlocks => { + match sync.old_blocks { + None => { + trace!(target: "sync", "Ignored block headers while block download is inactive"); + sync.continue_sync(io); + return Ok(()); + }, + Some(ref mut blocks) => blocks, + } + } + }; + downloader.import_headers(io, r, expected_hash) + }; + + match result { + Err(DownloaderImportError::Useless) => { + sync.deactivate_peer(io, peer_id); + }, + Err(DownloaderImportError::Invalid) => { + io.disable_peer(peer_id); + sync.deactivate_peer(io, peer_id); + sync.continue_sync(io); + return Ok(()); + }, + Ok(DownloadAction::Reset) => { + // mark all outstanding requests as expired + trace!("Resetting downloads for {:?}", block_set); + for (_, ref mut p) in sync.peers.iter_mut().filter(|&(_, ref p)| p.block_set == Some(block_set)) { + p.reset_asking(); + } + + } + Ok(DownloadAction::None) => {}, + } + + sync.collect_blocks(io, block_set); + // give a task to the same peer first if received valuable headers. + sync.sync_peer(io, peer_id, false); + // give tasks to other peers + sync.continue_sync(io); + Ok(()) + } + + /// Called by peer once it has new block receipts + fn on_peer_block_receipts(sync: &mut ChainSync, io: &mut SyncIo, peer_id: PeerId, r: &Rlp) -> Result<(), PacketDecodeError> { + sync.clear_peer_download(peer_id); + let block_set = sync.peers.get(&peer_id).and_then(|p| p.block_set).unwrap_or(BlockSet::NewBlocks); + if !sync.reset_peer_asking(peer_id, PeerAsking::BlockReceipts) { + trace!(target: "sync", "{}: Ignored unexpected receipts", peer_id); + sync.continue_sync(io); + return Ok(()); + } + let item_count = r.item_count()?; + trace!(target: "sync", "{} -> BlockReceipts ({} entries)", peer_id, item_count); + if item_count == 0 { + sync.deactivate_peer(io, peer_id); + } + else if sync.state == SyncState::Waiting { + trace!(target: "sync", "Ignored block receipts while waiting"); + } + else + { + let result = { + let downloader = match block_set { + BlockSet::NewBlocks => &mut sync.new_blocks, + BlockSet::OldBlocks => match sync.old_blocks { + None => { + trace!(target: "sync", "Ignored block headers while block download is inactive"); + sync.continue_sync(io); + return Ok(()); + }, + Some(ref mut blocks) => blocks, + } + }; + downloader.import_receipts(io, r) + }; + + match result { + Err(DownloaderImportError::Invalid) => { + io.disable_peer(peer_id); + sync.deactivate_peer(io, peer_id); + sync.continue_sync(io); + return Ok(()); + }, + Err(DownloaderImportError::Useless) => { + sync.deactivate_peer(io, peer_id); + }, + Ok(()) => (), + } + + sync.collect_blocks(io, block_set); + sync.sync_peer(io, peer_id, false); + } + sync.continue_sync(io); + Ok(()) + } + + /// Called when snapshot manifest is downloaded from a peer. + fn on_snapshot_manifest(sync: &mut ChainSync, io: &mut SyncIo, peer_id: PeerId, r: &Rlp) -> Result<(), PacketDecodeError> { + if !sync.peers.get(&peer_id).map_or(false, |p| p.can_sync()) { + trace!(target: "sync", "Ignoring snapshot manifest from unconfirmed peer {}", peer_id); + return Ok(()); + } + sync.clear_peer_download(peer_id); + if !sync.reset_peer_asking(peer_id, PeerAsking::SnapshotManifest) || sync.state != SyncState::SnapshotManifest { + trace!(target: "sync", "{}: Ignored unexpected/expired manifest", peer_id); + sync.continue_sync(io); + return Ok(()); + } + + let manifest_rlp = r.at(0)?; + let manifest = match ManifestData::from_rlp(manifest_rlp.as_raw()) { + Err(e) => { + trace!(target: "sync", "{}: Ignored bad manifest: {:?}", peer_id, e); + io.disable_peer(peer_id); + sync.continue_sync(io); + return Ok(()); + } + Ok(manifest) => manifest, + }; + + let is_supported_version = io.snapshot_service().supported_versions() + .map_or(false, |(l, h)| manifest.version >= l && manifest.version <= h); + + if !is_supported_version { + trace!(target: "sync", "{}: Snapshot manifest version not supported: {}", peer_id, manifest.version); + io.disable_peer(peer_id); + sync.continue_sync(io); + return Ok(()); + } + sync.snapshot.reset_to(&manifest, &keccak(manifest_rlp.as_raw())); + io.snapshot_service().begin_restore(manifest); + sync.state = SyncState::SnapshotData; + + // give a task to the same peer first. + sync.sync_peer(io, peer_id, false); + // give tasks to other peers + sync.continue_sync(io); + Ok(()) + } + + /// Called when snapshot data is downloaded from a peer. + fn on_snapshot_data(sync: &mut ChainSync, io: &mut SyncIo, peer_id: PeerId, r: &Rlp) -> Result<(), PacketDecodeError> { + if !sync.peers.get(&peer_id).map_or(false, |p| p.can_sync()) { + trace!(target: "sync", "Ignoring snapshot data from unconfirmed peer {}", peer_id); + return Ok(()); + } + sync.clear_peer_download(peer_id); + if !sync.reset_peer_asking(peer_id, PeerAsking::SnapshotData) || (sync.state != SyncState::SnapshotData && sync.state != SyncState::SnapshotWaiting) { + trace!(target: "sync", "{}: Ignored unexpected snapshot data", peer_id); + sync.continue_sync(io); + return Ok(()); + } + + // check service status + let status = io.snapshot_service().status(); + match status { + RestorationStatus::Inactive | RestorationStatus::Failed => { + trace!(target: "sync", "{}: Snapshot restoration aborted", peer_id); + sync.state = SyncState::WaitingPeers; + + // only note bad if restoration failed. + if let (Some(hash), RestorationStatus::Failed) = (sync.snapshot.snapshot_hash(), status) { + trace!(target: "sync", "Noting snapshot hash {} as bad", hash); + sync.snapshot.note_bad(hash); + } + + sync.snapshot.clear(); + sync.continue_sync(io); + return Ok(()); + }, + RestorationStatus::Ongoing { .. } => { + trace!(target: "sync", "{}: Snapshot restoration is ongoing", peer_id); + }, + } + + let snapshot_data: Bytes = r.val_at(0)?; + match sync.snapshot.validate_chunk(&snapshot_data) { + Ok(ChunkType::Block(hash)) => { + trace!(target: "sync", "{}: Processing block chunk", peer_id); + io.snapshot_service().restore_block_chunk(hash, snapshot_data); + } + Ok(ChunkType::State(hash)) => { + trace!(target: "sync", "{}: Processing state chunk", peer_id); + io.snapshot_service().restore_state_chunk(hash, snapshot_data); + } + Err(()) => { + trace!(target: "sync", "{}: Got bad snapshot chunk", peer_id); + io.disconnect_peer(peer_id); + sync.continue_sync(io); + return Ok(()); + } + } + + if sync.snapshot.is_complete() { + // wait for snapshot restoration process to complete + sync.state = SyncState::SnapshotWaiting; + } + // give a task to the same peer first. + sync.sync_peer(io, peer_id, false); + // give tasks to other peers + sync.continue_sync(io); + Ok(()) + } + + /// Called by peer to report status + fn on_peer_status(sync: &mut ChainSync, io: &mut SyncIo, peer_id: PeerId, r: &Rlp) -> Result<(), PacketDecodeError> { + sync.handshaking_peers.remove(&peer_id); + let protocol_version: u8 = r.val_at(0)?; + let warp_protocol = io.protocol_version(&WARP_SYNC_PROTOCOL_ID, peer_id) != 0; + let peer = PeerInfo { + protocol_version: protocol_version, + network_id: r.val_at(1)?, + difficulty: Some(r.val_at(2)?), + latest_hash: r.val_at(3)?, + genesis: r.val_at(4)?, + asking: PeerAsking::Nothing, + asking_blocks: Vec::new(), + asking_hash: None, + ask_time: Instant::now(), + last_sent_transactions: HashSet::new(), + expired: false, + confirmation: if sync.fork_block.is_none() { ForkConfirmation::Confirmed } else { ForkConfirmation::Unconfirmed }, + asking_snapshot_data: None, + snapshot_hash: if warp_protocol { Some(r.val_at(5)?) } else { None }, + snapshot_number: if warp_protocol { Some(r.val_at(6)?) } else { None }, + block_set: None, + }; + + trace!(target: "sync", "New peer {} (protocol: {}, network: {:?}, difficulty: {:?}, latest:{}, genesis:{}, snapshot:{:?})", + peer_id, peer.protocol_version, peer.network_id, peer.difficulty, peer.latest_hash, peer.genesis, peer.snapshot_number); + if io.is_expired() { + trace!(target: "sync", "Status packet from expired session {}:{}", peer_id, io.peer_info(peer_id)); + return Ok(()); + } + + if sync.peers.contains_key(&peer_id) { + debug!(target: "sync", "Unexpected status packet from {}:{}", peer_id, io.peer_info(peer_id)); + return Ok(()); + } + let chain_info = io.chain().chain_info(); + if peer.genesis != chain_info.genesis_hash { + io.disable_peer(peer_id); + trace!(target: "sync", "Peer {} genesis hash mismatch (ours: {}, theirs: {})", peer_id, chain_info.genesis_hash, peer.genesis); + return Ok(()); + } + if peer.network_id != sync.network_id { + io.disable_peer(peer_id); + trace!(target: "sync", "Peer {} network id mismatch (ours: {}, theirs: {})", peer_id, sync.network_id, peer.network_id); + return Ok(()); + } + if (warp_protocol && peer.protocol_version != PAR_PROTOCOL_VERSION_1 && peer.protocol_version != PAR_PROTOCOL_VERSION_2 && peer.protocol_version != PAR_PROTOCOL_VERSION_3) + || (!warp_protocol && peer.protocol_version != ETH_PROTOCOL_VERSION_63 && peer.protocol_version != ETH_PROTOCOL_VERSION_62) { + io.disable_peer(peer_id); + trace!(target: "sync", "Peer {} unsupported eth protocol ({})", peer_id, peer.protocol_version); + return Ok(()); + } + + if sync.sync_start_time.is_none() { + sync.sync_start_time = Some(Instant::now()); + } + + sync.peers.insert(peer_id.clone(), peer); + // Don't activate peer immediatelly when searching for common block. + // Let the current sync round complete first. + sync.active_peers.insert(peer_id.clone()); + debug!(target: "sync", "Connected {}:{}", peer_id, io.peer_info(peer_id)); + if let Some((fork_block, _)) = sync.fork_block { + SyncRequester::request_fork_header(sync, io, peer_id, fork_block); + } else { + SyncHandler::on_peer_confirmed(sync, io, peer_id); + } + Ok(()) + } + + /// Called when peer sends us new transactions + fn on_peer_transactions(sync: &mut ChainSync, io: &mut SyncIo, peer_id: PeerId, r: &Rlp) -> Result<(), PacketDecodeError> { + // Accept transactions only when fully synced + if !io.is_chain_queue_empty() || (sync.state != SyncState::Idle && sync.state != SyncState::NewBlocks) { + trace!(target: "sync", "{} Ignoring transactions while syncing", peer_id); + return Ok(()); + } + if !sync.peers.get(&peer_id).map_or(false, |p| p.can_sync()) { + trace!(target: "sync", "{} Ignoring transactions from unconfirmed/unknown peer", peer_id); + return Ok(()); + } + + let item_count = r.item_count()?; + trace!(target: "sync", "{:02} -> Transactions ({} entries)", peer_id, item_count); + let mut transactions = Vec::with_capacity(item_count); + for i in 0 .. item_count { + let rlp = r.at(i)?; + let tx = rlp.as_raw().to_vec(); + transactions.push(tx); + } + io.chain().queue_transactions(transactions, peer_id); + Ok(()) + } + + /// Called when peer sends us signed private transaction packet + fn on_signed_private_transaction(sync: &ChainSync, _io: &mut SyncIo, peer_id: PeerId, r: &Rlp) -> Result<(), PacketDecodeError> { + if !sync.peers.get(&peer_id).map_or(false, |p| p.can_sync()) { + trace!(target: "sync", "{} Ignoring packet from unconfirmed/unknown peer", peer_id); + return Ok(()); + } + + trace!(target: "sync", "Received signed private transaction packet from {:?}", peer_id); + if let Err(e) = sync.private_tx_handler.import_signed_private_transaction(r.as_raw()) { + trace!(target: "sync", "Ignoring the message, error queueing: {}", e); + } + Ok(()) + } + + /// Called when peer sends us new private transaction packet + fn on_private_transaction(sync: &ChainSync, _io: &mut SyncIo, peer_id: PeerId, r: &Rlp) -> Result<(), PacketDecodeError> { + if !sync.peers.get(&peer_id).map_or(false, |p| p.can_sync()) { + trace!(target: "sync", "{} Ignoring packet from unconfirmed/unknown peer", peer_id); + return Ok(()); + } + + trace!(target: "sync", "Received private transaction packet from {:?}", peer_id); + + if let Err(e) = sync.private_tx_handler.import_private_transaction(r.as_raw()) { + trace!(target: "sync", "Ignoring the message, error queueing: {}", e); + } + Ok(()) + } +} + +#[cfg(test)] +mod tests { + use ethcore::client::{ChainInfo, EachBlockWith, TestBlockChainClient}; + use parking_lot::RwLock; + use rlp::{Rlp}; + use std::collections::{VecDeque}; + use tests::helpers::{TestIo}; + use tests::snapshot::TestSnapshotService; + + use super::*; + use super::super::tests::{ + dummy_sync_with_peer, + get_dummy_block, + get_dummy_blocks, + get_dummy_hashes, + }; + + #[test] + fn handles_peer_new_hashes() { + let mut client = TestBlockChainClient::new(); + client.add_blocks(10, EachBlockWith::Uncle); + let queue = RwLock::new(VecDeque::new()); + let mut sync = dummy_sync_with_peer(client.block_hash_delta_minus(5), &client); + let ss = TestSnapshotService::new(); + let mut io = TestIo::new(&mut client, &ss, &queue, None); + + let hashes_data = get_dummy_hashes(); + let hashes_rlp = Rlp::new(&hashes_data); + + let result = SyncHandler::on_peer_new_hashes(&mut sync, &mut io, 0, &hashes_rlp); + + assert!(result.is_ok()); + } + + #[test] + fn handles_peer_new_block_malformed() { + let mut client = TestBlockChainClient::new(); + client.add_blocks(10, EachBlockWith::Uncle); + + let block_data = get_dummy_block(11, client.chain_info().best_block_hash); + + let queue = RwLock::new(VecDeque::new()); + let mut sync = dummy_sync_with_peer(client.block_hash_delta_minus(5), &client); + //sync.have_common_block = true; + let ss = TestSnapshotService::new(); + let mut io = TestIo::new(&mut client, &ss, &queue, None); + + let block = Rlp::new(&block_data); + + let result = SyncHandler::on_peer_new_block(&mut sync, &mut io, 0, &block); + + assert!(result.is_err()); + } + + #[test] + fn handles_peer_new_block() { + let mut client = TestBlockChainClient::new(); + client.add_blocks(10, EachBlockWith::Uncle); + + let block_data = get_dummy_blocks(11, client.chain_info().best_block_hash); + + let queue = RwLock::new(VecDeque::new()); + let mut sync = dummy_sync_with_peer(client.block_hash_delta_minus(5), &client); + let ss = TestSnapshotService::new(); + let mut io = TestIo::new(&mut client, &ss, &queue, None); + + let block = Rlp::new(&block_data); + + let result = SyncHandler::on_peer_new_block(&mut sync, &mut io, 0, &block); + + assert!(result.is_ok()); + } + + #[test] + fn handles_peer_new_block_empty() { + let mut client = TestBlockChainClient::new(); + client.add_blocks(10, EachBlockWith::Uncle); + let queue = RwLock::new(VecDeque::new()); + let mut sync = dummy_sync_with_peer(client.block_hash_delta_minus(5), &client); + let ss = TestSnapshotService::new(); + let mut io = TestIo::new(&mut client, &ss, &queue, None); + + let empty_data = vec![]; + let block = Rlp::new(&empty_data); + + let result = SyncHandler::on_peer_new_block(&mut sync, &mut io, 0, &block); + + assert!(result.is_err()); + } + + #[test] + fn handles_peer_new_hashes_empty() { + let mut client = TestBlockChainClient::new(); + client.add_blocks(10, EachBlockWith::Uncle); + let queue = RwLock::new(VecDeque::new()); + let mut sync = dummy_sync_with_peer(client.block_hash_delta_minus(5), &client); + let ss = TestSnapshotService::new(); + let mut io = TestIo::new(&mut client, &ss, &queue, None); + + let empty_hashes_data = vec![]; + let hashes_rlp = Rlp::new(&empty_hashes_data); + + let result = SyncHandler::on_peer_new_hashes(&mut sync, &mut io, 0, &hashes_rlp); + + assert!(result.is_ok()); + } +} diff --git a/ethcore/sync/src/chain/mod.rs b/ethcore/sync/src/chain/mod.rs new file mode 100644 index 0000000000..abab1da941 --- /dev/null +++ b/ethcore/sync/src/chain/mod.rs @@ -0,0 +1,1379 @@ +// 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 . + +//! `BlockChain` synchronization strategy. +//! Syncs to peers and keeps up to date. +//! This implementation uses ethereum protocol v63 +//! +//! Syncing strategy summary. +//! Split the chain into ranges of N blocks each. Download ranges sequentially. Split each range into subchains of M blocks. Download subchains in parallel. +//! State. +//! Sync state consists of the following data: +//! - s: State enum which can be one of the following values: `ChainHead`, `Blocks`, `Idle` +//! - H: A set of downloaded block headers +//! - B: A set of downloaded block bodies +//! - S: Set of block subchain start block hashes to download. +//! - l: Last imported / common block hash +//! - P: A set of connected peers. For each peer we maintain its last known total difficulty and starting block hash being requested if any. +//! General behaviour. +//! We start with all sets empty, l is set to the best block in the block chain, s is set to `ChainHead`. +//! If at any moment a bad block is reported by the block queue, we set s to `ChainHead`, reset l to the best block in the block chain and clear H, B and S. +//! If at any moment P becomes empty, we set s to `ChainHead`, and clear H, B and S. +//! +//! Workflow for `ChainHead` state. +//! In this state we try to get subchain headers with a single `GetBlockHeaders` request. +//! On `NewPeer` / On `Restart`: +//! If peer's total difficulty is higher and there are less than 5 peers downloading, request N/M headers with interval M+1 starting from l +//! On `BlockHeaders(R)`: +//! If R is empty: +//! If l is equal to genesis block hash or l is more than 1000 blocks behind our best hash: +//! Remove current peer from P. set l to the best block in the block chain. Select peer with maximum total difficulty from P and restart. +//! Else +//! Set l to l’s parent and restart. +//! Else if we already have all the headers in the block chain or the block queue: +//! Set s to `Idle`, +//! Else +//! Set S to R, set s to `Blocks`. +//! +//! All other messages are ignored. +//! +//! Workflow for `Blocks` state. +//! In this state we download block headers and bodies from multiple peers. +//! On `NewPeer` / On `Restart`: +//! For all idle peers: +//! Find a set of 256 or less block hashes in H which are not in B and not being downloaded by other peers. If the set is not empty: +//! Request block bodies for the hashes in the set. +//! Else +//! Find an element in S which is not being downloaded by other peers. If found: Request M headers starting from the element. +//! +//! On `BlockHeaders(R)`: +//! If R is empty remove current peer from P and restart. +//! Validate received headers: +//! For each header find a parent in H or R or the blockchain. Restart if there is a block with unknown parent. +//! Find at least one header from the received list in S. Restart if there is none. +//! Go to `CollectBlocks`. +//! +//! On `BlockBodies(R)`: +//! If R is empty remove current peer from P and restart. +//! Add bodies with a matching header in H to B. +//! Go to `CollectBlocks`. +//! +//! `CollectBlocks`: +//! Find a chain of blocks C in H starting from h where h’s parent equals to l. The chain ends with the first block which does not have a body in B. +//! Add all blocks from the chain to the block queue. Remove them from H and B. Set l to the hash of the last block from C. +//! Update and merge subchain heads in S. For each h in S find a chain of blocks in B starting from h. Remove h from S. if the chain does not include an element from S add the end of the chain to S. +//! If H is empty and S contains a single element set s to `ChainHead`. +//! Restart. +//! +//! All other messages are ignored. +//! Workflow for Idle state. +//! On `NewBlock`: +//! Import the block. If the block is unknown set s to `ChainHead` and restart. +//! On `NewHashes`: +//! Set s to `ChainHead` and restart. +//! +//! All other messages are ignored. + +mod handler; +mod propagator; +mod requester; +mod supplier; + +use std::sync::Arc; +use std::collections::{HashSet, HashMap}; +use std::cmp; +use std::time::{Duration, Instant}; +use hash::keccak; +use heapsize::HeapSizeOf; +use ethereum_types::{H256, U256}; +use plain_hasher::H256FastMap; +use parking_lot::RwLock; +use bytes::Bytes; +use rlp::{Rlp, RlpStream, DecoderError}; +use network::{self, PeerId, PacketId}; +use ethcore::header::{BlockNumber}; +use ethcore::client::{BlockChainClient, BlockStatus, BlockId, BlockChainInfo, BlockQueueInfo}; +use ethcore::snapshot::{RestorationStatus}; +use sync_io::SyncIo; +use super::{WarpSync, SyncConfig}; +use block_sync::{BlockDownloader, BlockDownloaderImportError as DownloaderImportError}; +use rand::Rng; +use snapshot::{Snapshot}; +use api::{EthProtocolInfo as PeerInfoDigest, WARP_SYNC_PROTOCOL_ID}; +use private_tx::PrivateTxHandler; +use transactions_stats::{TransactionsStats, Stats as TransactionStats}; +use transaction::UnverifiedTransaction; + +use self::handler::SyncHandler; +use self::propagator::SyncPropagator; +use self::requester::SyncRequester; +use self::supplier::SyncSupplier; + +known_heap_size!(0, PeerInfo); + +pub type PacketDecodeError = DecoderError; + +/// 63 version of Ethereum protocol. +pub const ETH_PROTOCOL_VERSION_63: u8 = 63; +/// 62 version of Ethereum protocol. +pub const ETH_PROTOCOL_VERSION_62: u8 = 62; +/// 1 version of Parity protocol. +pub const PAR_PROTOCOL_VERSION_1: u8 = 1; +/// 2 version of Parity protocol (consensus messages added). +pub const PAR_PROTOCOL_VERSION_2: u8 = 2; +/// 3 version of Parity protocol (private transactions messages added). +pub const PAR_PROTOCOL_VERSION_3: u8 = 3; + +pub const MAX_BODIES_TO_SEND: usize = 256; +pub const MAX_HEADERS_TO_SEND: usize = 512; +pub const MAX_NODE_DATA_TO_SEND: usize = 1024; +pub const MAX_RECEIPTS_TO_SEND: usize = 1024; +pub const MAX_RECEIPTS_HEADERS_TO_SEND: usize = 256; +const MIN_PEERS_PROPAGATION: usize = 4; +const MAX_PEERS_PROPAGATION: usize = 128; +const MAX_PEER_LAG_PROPAGATION: BlockNumber = 20; +const MAX_NEW_HASHES: usize = 64; +const MAX_NEW_BLOCK_AGE: BlockNumber = 20; +// maximal packet size with transactions (cannot be greater than 16MB - protocol limitation). +const MAX_TRANSACTION_PACKET_SIZE: usize = 8 * 1024 * 1024; +// Maximal number of transactions in sent in single packet. +const MAX_TRANSACTIONS_TO_PROPAGATE: usize = 64; +// Min number of blocks to be behind for a snapshot sync +const SNAPSHOT_RESTORE_THRESHOLD: BlockNumber = 30000; +const SNAPSHOT_MIN_PEERS: usize = 3; + +const STATUS_PACKET: u8 = 0x00; +const NEW_BLOCK_HASHES_PACKET: u8 = 0x01; +const TRANSACTIONS_PACKET: u8 = 0x02; +pub const GET_BLOCK_HEADERS_PACKET: u8 = 0x03; +pub const BLOCK_HEADERS_PACKET: u8 = 0x04; +pub const GET_BLOCK_BODIES_PACKET: u8 = 0x05; +const BLOCK_BODIES_PACKET: u8 = 0x06; +const NEW_BLOCK_PACKET: u8 = 0x07; + +pub const GET_NODE_DATA_PACKET: u8 = 0x0d; +pub const NODE_DATA_PACKET: u8 = 0x0e; +pub const GET_RECEIPTS_PACKET: u8 = 0x0f; +pub const RECEIPTS_PACKET: u8 = 0x10; + +pub const ETH_PACKET_COUNT: u8 = 0x11; + +pub const GET_SNAPSHOT_MANIFEST_PACKET: u8 = 0x11; +pub const SNAPSHOT_MANIFEST_PACKET: u8 = 0x12; +pub const GET_SNAPSHOT_DATA_PACKET: u8 = 0x13; +pub const SNAPSHOT_DATA_PACKET: u8 = 0x14; +pub const CONSENSUS_DATA_PACKET: u8 = 0x15; +const PRIVATE_TRANSACTION_PACKET: u8 = 0x16; +const SIGNED_PRIVATE_TRANSACTION_PACKET: u8 = 0x17; + +pub const SNAPSHOT_SYNC_PACKET_COUNT: u8 = 0x18; + +const MAX_SNAPSHOT_CHUNKS_DOWNLOAD_AHEAD: usize = 3; + +const WAIT_PEERS_TIMEOUT: Duration = Duration::from_secs(5); +const STATUS_TIMEOUT: Duration = Duration::from_secs(5); +const HEADERS_TIMEOUT: Duration = Duration::from_secs(15); +const BODIES_TIMEOUT: Duration = Duration::from_secs(20); +const RECEIPTS_TIMEOUT: Duration = Duration::from_secs(10); +const FORK_HEADER_TIMEOUT: Duration = Duration::from_secs(3); +const SNAPSHOT_MANIFEST_TIMEOUT: Duration = Duration::from_secs(5); +const SNAPSHOT_DATA_TIMEOUT: Duration = Duration::from_secs(120); + +#[derive(Copy, Clone, Eq, PartialEq, Debug)] +/// Sync state +pub enum SyncState { + /// Collecting enough peers to start syncing. + WaitingPeers, + /// Waiting for snapshot manifest download + SnapshotManifest, + /// Downloading snapshot data + SnapshotData, + /// Waiting for snapshot restoration progress. + SnapshotWaiting, + /// Downloading new blocks + Blocks, + /// Initial chain sync complete. Waiting for new packets + Idle, + /// Block downloading paused. Waiting for block queue to process blocks and free some space + Waiting, + /// Downloading blocks learned from `NewHashes` packet + NewBlocks, +} + +/// Syncing status and statistics +#[derive(Clone, Copy)] +pub struct SyncStatus { + /// State + pub state: SyncState, + /// Syncing protocol version. That's the maximum protocol version we connect to. + pub protocol_version: u8, + /// The underlying p2p network version. + pub network_id: u64, + /// `BlockChain` height for the moment the sync started. + pub start_block_number: BlockNumber, + /// Last fully downloaded and imported block number (if any). + pub last_imported_block_number: Option, + /// Highest block number in the download queue (if any). + pub highest_block_number: Option, + /// Total number of blocks for the sync process. + pub blocks_total: BlockNumber, + /// Number of blocks downloaded so far. + pub blocks_received: BlockNumber, + /// Total number of connected peers + pub num_peers: usize, + /// Total number of active peers. + pub num_active_peers: usize, + /// Heap memory used in bytes. + pub mem_used: usize, + /// Snapshot chunks + pub num_snapshot_chunks: usize, + /// Snapshot chunks downloaded + pub snapshot_chunks_done: usize, + /// Last fully downloaded and imported ancient block number (if any). + pub last_imported_old_block_number: Option, +} + +impl SyncStatus { + /// Indicates if snapshot download is in progress + pub fn is_snapshot_syncing(&self) -> bool { + self.state == SyncState::SnapshotManifest + || self.state == SyncState::SnapshotData + || self.state == SyncState::SnapshotWaiting + } + + /// Returns max no of peers to display in informants + pub fn current_max_peers(&self, min_peers: u32, max_peers: u32) -> u32 { + if self.num_peers as u32 > min_peers { + max_peers + } else { + min_peers + } + } + + /// Is it doing a major sync? + pub fn is_syncing(&self, queue_info: BlockQueueInfo) -> bool { + let is_syncing_state = match self.state { SyncState::Idle | SyncState::NewBlocks => false, _ => true }; + let is_verifying = queue_info.unverified_queue_size + queue_info.verified_queue_size > 3; + is_verifying || is_syncing_state + } +} + +#[derive(PartialEq, Eq, Debug, Clone)] +/// Peer data type requested +pub enum PeerAsking { + Nothing, + ForkHeader, + BlockHeaders, + BlockBodies, + BlockReceipts, + SnapshotManifest, + SnapshotData, +} + +#[derive(PartialEq, Eq, Debug, Clone, Copy)] +/// Block downloader channel. +pub enum BlockSet { + /// New blocks better than out best blocks + NewBlocks, + /// Missing old blocks + OldBlocks, +} +#[derive(Clone, Eq, PartialEq)] +pub enum ForkConfirmation { + /// Fork block confirmation pending. + Unconfirmed, + /// Fork is confirmed. + Confirmed, +} + +#[derive(Clone)] +/// Syncing peer information +pub struct PeerInfo { + /// eth protocol version + protocol_version: u8, + /// Peer chain genesis hash + genesis: H256, + /// Peer network id + network_id: u64, + /// Peer best block hash + latest_hash: H256, + /// Peer total difficulty if known + difficulty: Option, + /// Type of data currenty being requested from peer. + asking: PeerAsking, + /// A set of block numbers being requested + asking_blocks: Vec, + /// Holds requested header hash if currently requesting block header by hash + asking_hash: Option, + /// Holds requested snapshot chunk hash if any. + asking_snapshot_data: Option, + /// Request timestamp + ask_time: Instant, + /// Holds a set of transactions recently sent to this peer to avoid spamming. + last_sent_transactions: HashSet, + /// Pending request is expired and result should be ignored + expired: bool, + /// Peer fork confirmation status + confirmation: ForkConfirmation, + /// Best snapshot hash + snapshot_hash: Option, + /// Best snapshot block number + snapshot_number: Option, + /// Block set requested + block_set: Option, +} + +impl PeerInfo { + fn can_sync(&self) -> bool { + self.confirmation == ForkConfirmation::Confirmed && !self.expired + } + + fn is_allowed(&self) -> bool { + self.confirmation != ForkConfirmation::Unconfirmed && !self.expired + } + + fn reset_asking(&mut self) { + self.asking_blocks.clear(); + self.asking_hash = None; + // mark any pending requests as expired + if self.asking != PeerAsking::Nothing && self.is_allowed() { + self.expired = true; + } + } +} + +#[cfg(not(test))] +pub mod random { + use rand; + pub fn new() -> rand::ThreadRng { rand::thread_rng() } +} +#[cfg(test)] +pub mod random { + use rand::{self, SeedableRng}; + pub fn new() -> rand::XorShiftRng { rand::XorShiftRng::from_seed([0, 1, 2, 3]) } +} + +pub type RlpResponseResult = Result, PacketDecodeError>; +pub type Peers = HashMap; + +/// Blockchain sync handler. +/// See module documentation for more details. +pub struct ChainSync { + /// Sync state + state: SyncState, + /// Last block number for the start of sync + starting_block: BlockNumber, + /// Highest block number seen + highest_block: Option, + /// All connected peers + peers: Peers, + /// Peers active for current sync round + active_peers: HashSet, + /// Block download process for new blocks + new_blocks: BlockDownloader, + /// Block download process for ancient blocks + old_blocks: Option, + /// Last propagated block number + last_sent_block_number: BlockNumber, + /// Network ID + network_id: u64, + /// Optional fork block to check + fork_block: Option<(BlockNumber, H256)>, + /// Snapshot downloader. + snapshot: Snapshot, + /// Connected peers pending Status message. + /// Value is request timestamp. + handshaking_peers: HashMap, + /// Sync start timestamp. Measured when first peer is connected + sync_start_time: Option, + /// Transactions propagation statistics + transactions_stats: TransactionsStats, + /// Enable ancient block downloading + download_old_blocks: bool, + /// Shared private tx service. + private_tx_handler: Arc, + /// Enable warp sync. + warp_sync: WarpSync, +} + +impl ChainSync { + /// Create a new instance of syncing strategy. + pub fn new(config: SyncConfig, chain: &BlockChainClient, private_tx_handler: Arc) -> ChainSync { + let chain_info = chain.chain_info(); + let best_block = chain.chain_info().best_block_number; + let state = ChainSync::get_init_state(config.warp_sync, chain); + + let mut sync = ChainSync { + state, + starting_block: best_block, + highest_block: None, + peers: HashMap::new(), + handshaking_peers: HashMap::new(), + active_peers: HashSet::new(), + new_blocks: BlockDownloader::new(false, &chain_info.best_block_hash, chain_info.best_block_number), + old_blocks: None, + last_sent_block_number: 0, + network_id: config.network_id, + fork_block: config.fork_block, + download_old_blocks: config.download_old_blocks, + snapshot: Snapshot::new(), + sync_start_time: None, + transactions_stats: TransactionsStats::default(), + private_tx_handler, + warp_sync: config.warp_sync, + }; + sync.update_targets(chain); + sync + } + + fn get_init_state(warp_sync: WarpSync, chain: &BlockChainClient) -> SyncState { + let best_block = chain.chain_info().best_block_number; + match warp_sync { + WarpSync::Enabled => SyncState::WaitingPeers, + WarpSync::OnlyAndAfter(block) if block > best_block => SyncState::WaitingPeers, + _ => SyncState::Idle, + } + } + + /// Returns synchonization status + pub fn status(&self) -> SyncStatus { + let last_imported_number = self.new_blocks.last_imported_block_number(); + SyncStatus { + state: self.state.clone(), + protocol_version: ETH_PROTOCOL_VERSION_63, + network_id: self.network_id, + 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| 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(), + num_active_peers: self.peers.values().filter(|p| p.is_allowed() && p.asking != PeerAsking::Nothing).count(), + num_snapshot_chunks: self.snapshot.total_chunks(), + snapshot_chunks_done: self.snapshot.done_chunks(), + mem_used: + self.new_blocks.heap_size() + + self.old_blocks.as_ref().map_or(0, |d| d.heap_size()) + + self.peers.heap_size_of_children(), + } + } + + /// Returns information on peers connections + pub fn peer_info(&self, peer_id: &PeerId) -> Option { + self.peers.get(peer_id).map(|peer_data| { + PeerInfoDigest { + version: peer_data.protocol_version as u32, + difficulty: peer_data.difficulty, + head: peer_data.latest_hash, + } + }) + } + + /// Returns transactions propagation statistics + pub fn transactions_stats(&self) -> &H256FastMap { + self.transactions_stats.stats() + } + + /// Updates transactions were received by a peer + pub fn transactions_received(&mut self, txs: &[UnverifiedTransaction], peer_id: PeerId) { + if let Some(peer_info) = self.peers.get_mut(&peer_id) { + peer_info.last_sent_transactions.extend(txs.iter().map(|tx| tx.hash())); + } + } + + /// Abort all sync activity + pub fn abort(&mut self, io: &mut SyncIo) { + self.reset_and_continue(io); + self.peers.clear(); + } + + /// Reset sync. Clear all downloaded data but keep the queue + fn reset(&mut self, io: &mut SyncIo) { + self.new_blocks.reset(); + let chain_info = io.chain().chain_info(); + for (_, ref mut p) in &mut self.peers { + if p.block_set != Some(BlockSet::OldBlocks) { + p.reset_asking(); + if p.difficulty.is_none() { + // assume peer has up to date difficulty + p.difficulty = Some(chain_info.pending_total_difficulty); + } + } + } + self.state = ChainSync::get_init_state(self.warp_sync, io.chain()); + // Reactivate peers only if some progress has been made + // since the last sync round of if starting fresh. + self.active_peers = self.peers.keys().cloned().collect(); + } + + /// Restart sync + pub fn reset_and_continue(&mut self, io: &mut SyncIo) { + trace!(target: "sync", "Restarting"); + if self.state == SyncState::SnapshotData { + debug!(target:"sync", "Aborting snapshot restore"); + io.snapshot_service().abort_restore(); + } + self.snapshot.clear(); + self.reset(io); + self.continue_sync(io); + } + + /// Remove peer from active peer set. Peer will be reactivated on the next sync + /// round. + fn deactivate_peer(&mut self, _io: &mut SyncIo, peer_id: PeerId) { + trace!(target: "sync", "Deactivating peer {}", peer_id); + self.active_peers.remove(&peer_id); + } + + fn maybe_start_snapshot_sync(&mut self, io: &mut SyncIo) { + if !self.warp_sync.is_enabled() || io.snapshot_service().supported_versions().is_none() { + trace!(target: "sync", "Skipping warp sync. Disabled or not supported."); + return; + } + if self.state != SyncState::WaitingPeers && self.state != SyncState::Blocks && self.state != SyncState::Waiting { + trace!(target: "sync", "Skipping warp sync. State: {:?}", self.state); + return; + } + // Make sure the snapshot block is not too far away from best block and network best block and + // that it is higher than fork detection block + let our_best_block = io.chain().chain_info().best_block_number; + let fork_block = self.fork_block.map_or(0, |(n, _)| n); + + let (best_hash, max_peers, snapshot_peers) = { + let expected_warp_block = match self.warp_sync { + WarpSync::OnlyAndAfter(block) => block, + _ => 0, + }; + //collect snapshot infos from peers + let snapshots = self.peers.iter() + .filter(|&(_, p)| p.is_allowed() && p.snapshot_number.map_or(false, |sn| + // Snapshot must be old enough that it's usefull to sync with it + our_best_block < sn && (sn - our_best_block) > SNAPSHOT_RESTORE_THRESHOLD && + // Snapshot must have been taken after the Fork + sn > fork_block && + // Snapshot must be greater than the warp barrier if any + sn > expected_warp_block && + // If we know a highest block, snapshot must be recent enough + self.highest_block.map_or(true, |highest| { + highest < sn || (highest - sn) <= SNAPSHOT_RESTORE_THRESHOLD + }) + )) + .filter_map(|(p, peer)| peer.snapshot_hash.map(|hash| (p, hash.clone()))) + .filter(|&(_, ref hash)| !self.snapshot.is_known_bad(hash)); + + let mut snapshot_peers = HashMap::new(); + let mut max_peers: usize = 0; + let mut best_hash = None; + for (p, hash) in snapshots { + let peers = snapshot_peers.entry(hash).or_insert_with(Vec::new); + peers.push(*p); + if peers.len() > max_peers { + max_peers = peers.len(); + best_hash = Some(hash); + } + } + (best_hash, max_peers, snapshot_peers) + }; + + let timeout = (self.state == SyncState::WaitingPeers) && self.sync_start_time.map_or(false, |t| t.elapsed() > WAIT_PEERS_TIMEOUT); + + if let (Some(hash), Some(peers)) = (best_hash, best_hash.map_or(None, |h| snapshot_peers.get(&h))) { + if max_peers >= SNAPSHOT_MIN_PEERS { + trace!(target: "sync", "Starting confirmed snapshot sync {:?} with {:?}", hash, peers); + self.start_snapshot_sync(io, peers); + } else if timeout { + trace!(target: "sync", "Starting unconfirmed snapshot sync {:?} with {:?}", hash, peers); + self.start_snapshot_sync(io, peers); + } + } else if timeout && !self.warp_sync.is_warp_only() { + trace!(target: "sync", "No snapshots found, starting full sync"); + self.state = SyncState::Idle; + self.continue_sync(io); + } + } + + fn start_snapshot_sync(&mut self, io: &mut SyncIo, peers: &[PeerId]) { + if !self.snapshot.have_manifest() { + for p in peers { + if self.peers.get(p).map_or(false, |p| p.asking == PeerAsking::Nothing) { + SyncRequester::request_snapshot_manifest(self, io, *p); + } + } + self.state = SyncState::SnapshotManifest; + trace!(target: "sync", "New snapshot sync with {:?}", peers); + } else { + self.state = SyncState::SnapshotData; + trace!(target: "sync", "Resumed snapshot sync with {:?}", peers); + } + } + + /// Restart sync disregarding the block queue status. May end up re-downloading up to QUEUE_SIZE blocks + pub fn restart(&mut self, io: &mut SyncIo) { + self.update_targets(io.chain()); + self.reset_and_continue(io); + } + + /// Update sync after the blockchain has been changed externally. + pub fn update_targets(&mut self, chain: &BlockChainClient) { + // Do not assume that the block queue/chain still has our last_imported_block + let chain = chain.chain_info(); + self.new_blocks = BlockDownloader::new(false, &chain.best_block_hash, chain.best_block_number); + self.old_blocks = None; + if self.download_old_blocks { + if let (Some(ancient_block_hash), Some(ancient_block_number)) = (chain.ancient_block_hash, chain.ancient_block_number) { + + trace!(target: "sync", "Downloading old blocks from {:?} (#{}) till {:?} (#{:?})", ancient_block_hash, ancient_block_number, chain.first_block_hash, chain.first_block_number); + let mut downloader = BlockDownloader::with_unlimited_reorg(true, &ancient_block_hash, ancient_block_number); + if let Some(hash) = chain.first_block_hash { + trace!(target: "sync", "Downloader target set to {:?}", hash); + downloader.set_target(&hash); + } + self.old_blocks = Some(downloader); + } + } + } + + /// Resume downloading + fn continue_sync(&mut self, io: &mut SyncIo) { + // Collect active peers that can sync + let confirmed_peers: Vec<(PeerId, u8)> = self.peers.iter().filter_map(|(peer_id, peer)| + if peer.can_sync() { + Some((*peer_id, peer.protocol_version)) + } else { + None + } + ).collect(); + let mut peers: Vec<(PeerId, u8)> = confirmed_peers.iter().filter(|&&(peer_id, _)| + self.active_peers.contains(&peer_id) + ).map(|v| *v).collect(); + + random::new().shuffle(&mut peers); //TODO: sort by rating + // prefer peers with higher protocol version + peers.sort_by(|&(_, ref v1), &(_, ref v2)| v1.cmp(v2)); + trace!( + target: "sync", + "Syncing with peers: {} active, {} confirmed, {} total", + self.active_peers.len(), confirmed_peers.len(), self.peers.len() + ); + for (peer_id, _) in peers { + self.sync_peer(io, peer_id, false); + } + + if + (self.state == SyncState::Blocks || self.state == SyncState::NewBlocks) && + !self.peers.values().any(|p| p.asking != PeerAsking::Nothing && p.block_set != Some(BlockSet::OldBlocks) && p.can_sync()) + { + self.complete_sync(io); + } + } + + /// Called after all blocks have been downloaded + fn complete_sync(&mut self, io: &mut SyncIo) { + trace!(target: "sync", "Sync complete"); + self.reset(io); + } + + /// Enter waiting state + fn pause_sync(&mut self) { + trace!(target: "sync", "Block queue full, pausing sync"); + self.state = SyncState::Waiting; + } + + /// Find something to do for a peer. Called for a new peer or when a peer is done with its task. + fn sync_peer(&mut self, io: &mut SyncIo, peer_id: PeerId, force: bool) { + if !self.active_peers.contains(&peer_id) { + trace!(target: "sync", "Skipping deactivated peer {}", peer_id); + return; + } + let (peer_latest, peer_difficulty, peer_snapshot_number, peer_snapshot_hash) = { + if let Some(peer) = self.peers.get_mut(&peer_id) { + if peer.asking != PeerAsking::Nothing || !peer.can_sync() { + trace!(target: "sync", "Skipping busy peer {}", peer_id); + return; + } + if self.state == SyncState::Waiting { + trace!(target: "sync", "Waiting for the block queue"); + return; + } + if self.state == SyncState::SnapshotWaiting { + trace!(target: "sync", "Waiting for the snapshot restoration"); + return; + } + (peer.latest_hash.clone(), peer.difficulty.clone(), peer.snapshot_number.as_ref().cloned().unwrap_or(0), peer.snapshot_hash.as_ref().cloned()) + } else { + return; + } + }; + let chain_info = io.chain().chain_info(); + let syncing_difficulty = chain_info.pending_total_difficulty; + let num_active_peers = self.peers.values().filter(|p| p.asking != PeerAsking::Nothing).count(); + + let higher_difficulty = peer_difficulty.map_or(true, |pd| pd > syncing_difficulty); + if force || higher_difficulty || self.old_blocks.is_some() { + match self.state { + SyncState::WaitingPeers => { + trace!( + target: "sync", + "Checking snapshot sync: {} vs {} (peer: {})", + peer_snapshot_number, + chain_info.best_block_number, + peer_id + ); + self.maybe_start_snapshot_sync(io); + }, + SyncState::Idle | SyncState::Blocks | SyncState::NewBlocks => { + if io.chain().queue_info().is_full() { + self.pause_sync(); + return; + } + + let have_latest = io.chain().block_status(BlockId::Hash(peer_latest)) != BlockStatus::Unknown; + trace!(target: "sync", "Considering peer {}, force={}, td={:?}, our td={}, latest={}, have_latest={}, state={:?}", peer_id, force, peer_difficulty, syncing_difficulty, peer_latest, have_latest, self.state); + if !have_latest && (higher_difficulty || force || self.state == SyncState::NewBlocks) { + // check if got new blocks to download + trace!(target: "sync", "Syncing with peer {}, force={}, td={:?}, our td={}, state={:?}", peer_id, force, peer_difficulty, syncing_difficulty, self.state); + if let Some(request) = self.new_blocks.request_blocks(io, num_active_peers) { + SyncRequester::request_blocks(self, io, peer_id, request, BlockSet::NewBlocks); + if self.state == SyncState::Idle { + self.state = SyncState::Blocks; + } + return; + } + } + + if let Some(request) = self.old_blocks.as_mut().and_then(|d| d.request_blocks(io, num_active_peers)) { + SyncRequester::request_blocks(self, io, peer_id, request, BlockSet::OldBlocks); + return; + } + }, + SyncState::SnapshotData => { + if let RestorationStatus::Ongoing { state_chunks_done, block_chunks_done, .. } = io.snapshot_service().status() { + if self.snapshot.done_chunks() - (state_chunks_done + block_chunks_done) as usize > MAX_SNAPSHOT_CHUNKS_DOWNLOAD_AHEAD { + trace!(target: "sync", "Snapshot queue full, pausing sync"); + self.state = SyncState::SnapshotWaiting; + return; + } + } + if peer_snapshot_hash.is_some() && peer_snapshot_hash == self.snapshot.snapshot_hash() { + self.clear_peer_download(peer_id); + SyncRequester::request_snapshot_data(self, io, peer_id); + } + }, + SyncState::SnapshotManifest | //already downloading from other peer + SyncState::Waiting | SyncState::SnapshotWaiting => () + } + } else { + trace!(target: "sync", "Skipping peer {}, force={}, td={:?}, our td={}, state={:?}", peer_id, force, peer_difficulty, syncing_difficulty, self.state); + } + } + + /// Clear all blocks/headers marked as being downloaded by a peer. + fn clear_peer_download(&mut self, peer_id: PeerId) { + if let Some(ref peer) = self.peers.get(&peer_id) { + match peer.asking { + PeerAsking::BlockHeaders => { + if let Some(ref hash) = peer.asking_hash { + self.new_blocks.clear_header_download(hash); + if let Some(ref mut old) = self.old_blocks { + old.clear_header_download(hash); + } + } + }, + PeerAsking::BlockBodies => { + self.new_blocks.clear_body_download(&peer.asking_blocks); + if let Some(ref mut old) = self.old_blocks { + old.clear_body_download(&peer.asking_blocks); + } + }, + PeerAsking::BlockReceipts => { + self.new_blocks.clear_receipt_download(&peer.asking_blocks); + if let Some(ref mut old) = self.old_blocks { + old.clear_receipt_download(&peer.asking_blocks); + } + }, + PeerAsking::SnapshotData => { + if let Some(hash) = peer.asking_snapshot_data { + self.snapshot.clear_chunk_download(&hash); + } + }, + _ => (), + } + } + } + + /// Checks if there are blocks fully downloaded that can be imported into the blockchain and does the import. + fn collect_blocks(&mut self, io: &mut SyncIo, block_set: BlockSet) { + match block_set { + BlockSet::NewBlocks => { + if self.new_blocks.collect_blocks(io, self.state == SyncState::NewBlocks) == Err(DownloaderImportError::Invalid) { + self.restart(io); + } + }, + BlockSet::OldBlocks => { + if self.old_blocks.as_mut().map_or(false, |downloader| { downloader.collect_blocks(io, false) == Err(DownloaderImportError::Invalid) }) { + self.restart(io); + } else if self.old_blocks.as_ref().map_or(false, |downloader| { downloader.is_complete() }) { + trace!(target: "sync", "Background block download is complete"); + self.old_blocks = None; + } + } + } + } + + /// Reset peer status after request is complete. + fn reset_peer_asking(&mut self, peer_id: PeerId, asking: PeerAsking) -> bool { + if let Some(ref mut peer) = self.peers.get_mut(&peer_id) { + peer.expired = false; + peer.block_set = None; + if peer.asking != asking { + trace!(target:"sync", "Asking {:?} while expected {:?}", peer.asking, asking); + peer.asking = PeerAsking::Nothing; + return false; + } else { + peer.asking = PeerAsking::Nothing; + return true; + } + } + false + } + + /// Send Status message + fn send_status(&mut self, io: &mut SyncIo, peer: PeerId) -> Result<(), network::Error> { + let warp_protocol_version = io.protocol_version(&WARP_SYNC_PROTOCOL_ID, peer); + let warp_protocol = warp_protocol_version != 0; + let protocol = if warp_protocol { warp_protocol_version } else { ETH_PROTOCOL_VERSION_63 }; + trace!(target: "sync", "Sending status to {}, protocol version {}", peer, protocol); + let mut packet = RlpStream::new_list(if warp_protocol { 7 } else { 5 }); + let chain = io.chain().chain_info(); + packet.append(&(protocol as u32)); + packet.append(&self.network_id); + packet.append(&chain.total_difficulty); + packet.append(&chain.best_block_hash); + packet.append(&chain.genesis_hash); + if warp_protocol { + let manifest = match self.old_blocks.is_some() { + true => None, + false => io.snapshot_service().manifest(), + }; + let block_number = manifest.as_ref().map_or(0, |m| m.block_number); + let manifest_hash = manifest.map_or(H256::new(), |m| keccak(m.into_rlp())); + packet.append(&manifest_hash); + packet.append(&block_number); + } + io.respond(STATUS_PACKET, packet.out()) + } + + pub fn maintain_peers(&mut self, io: &mut SyncIo) { + let tick = Instant::now(); + let mut aborting = Vec::new(); + for (peer_id, peer) in &self.peers { + let elapsed = tick - peer.ask_time; + let timeout = match peer.asking { + PeerAsking::BlockHeaders => elapsed > HEADERS_TIMEOUT, + PeerAsking::BlockBodies => elapsed > BODIES_TIMEOUT, + PeerAsking::BlockReceipts => elapsed > RECEIPTS_TIMEOUT, + PeerAsking::Nothing => false, + PeerAsking::ForkHeader => elapsed > FORK_HEADER_TIMEOUT, + PeerAsking::SnapshotManifest => elapsed > SNAPSHOT_MANIFEST_TIMEOUT, + PeerAsking::SnapshotData => elapsed > SNAPSHOT_DATA_TIMEOUT, + }; + if timeout { + debug!(target:"sync", "Timeout {}", peer_id); + io.disconnect_peer(*peer_id); + aborting.push(*peer_id); + } + } + for p in aborting { + SyncHandler::on_peer_aborting(self, io, p); + } + + // Check for handshake timeouts + for (peer, &ask_time) in &self.handshaking_peers { + let elapsed = (tick - ask_time) / 1_000_000_000; + if elapsed > STATUS_TIMEOUT { + trace!(target:"sync", "Status timeout {}", peer); + io.disconnect_peer(*peer); + } + } + } + + fn check_resume(&mut self, io: &mut SyncIo) { + if self.state == SyncState::Waiting && !io.chain().queue_info().is_full() { + self.state = SyncState::Blocks; + self.continue_sync(io); + } else if self.state == SyncState::SnapshotWaiting { + match io.snapshot_service().status() { + RestorationStatus::Inactive => { + trace!(target:"sync", "Snapshot restoration is complete"); + self.restart(io); + }, + RestorationStatus::Ongoing { state_chunks_done, block_chunks_done, .. } => { + if !self.snapshot.is_complete() && self.snapshot.done_chunks() - (state_chunks_done + block_chunks_done) as usize <= MAX_SNAPSHOT_CHUNKS_DOWNLOAD_AHEAD { + trace!(target:"sync", "Resuming snapshot sync"); + self.state = SyncState::SnapshotData; + self.continue_sync(io); + } + }, + RestorationStatus::Failed => { + trace!(target: "sync", "Snapshot restoration aborted"); + self.state = SyncState::WaitingPeers; + self.snapshot.clear(); + self.continue_sync(io); + }, + } + } + } + + /// creates rlp to send for the tree defined by 'from' and 'to' hashes + fn create_new_hashes_rlp(chain: &BlockChainClient, from: &H256, to: &H256) -> Option { + match chain.tree_route(from, to) { + Some(route) => { + let uncles = chain.find_uncles(from).unwrap_or_else(Vec::new); + match route.blocks.len() { + 0 => None, + _ => { + let mut blocks = route.blocks; + blocks.extend(uncles); + let mut rlp_stream = RlpStream::new_list(blocks.len()); + for block_hash in blocks { + let mut hash_rlp = RlpStream::new_list(2); + let number = chain.block_header(BlockId::Hash(block_hash.clone())) + .expect("chain.tree_route and chain.find_uncles only return hahses of blocks that are in the blockchain. qed.").number(); + hash_rlp.append(&block_hash); + hash_rlp.append(&number); + rlp_stream.append_raw(hash_rlp.as_raw(), 1); + } + Some(rlp_stream.out()) + } + } + }, + None => None + } + } + + /// creates rlp from block bytes and total difficulty + fn create_block_rlp(bytes: &Bytes, total_difficulty: U256) -> Bytes { + let mut rlp_stream = RlpStream::new_list(2); + rlp_stream.append_raw(bytes, 1); + rlp_stream.append(&total_difficulty); + rlp_stream.out() + } + + /// creates latest block rlp for the given client + fn create_latest_block_rlp(chain: &BlockChainClient) -> Bytes { + ChainSync::create_block_rlp( + &chain.block(BlockId::Hash(chain.chain_info().best_block_hash)) + .expect("Best block always exists").into_inner(), + chain.chain_info().total_difficulty + ) + } + + /// creates given hash block rlp for the given client + fn create_new_block_rlp(chain: &BlockChainClient, hash: &H256) -> Bytes { + ChainSync::create_block_rlp( + &chain.block(BlockId::Hash(hash.clone())).expect("Block has just been sealed; qed").into_inner(), + chain.block_total_difficulty(BlockId::Hash(hash.clone())).expect("Block has just been sealed; qed.") + ) + } + + /// returns peer ids that have different blocks than our chain + fn get_lagging_peers(&mut self, chain_info: &BlockChainInfo) -> Vec { + let latest_hash = chain_info.best_block_hash; + self + .peers + .iter_mut() + .filter_map(|(&id, ref mut peer_info)| { + trace!(target: "sync", "Checking peer our best {} their best {}", latest_hash, peer_info.latest_hash); + if peer_info.latest_hash != latest_hash { + Some(id) + } else { + None + } + }) + .collect::>() + } + + fn select_random_peers(peers: &[PeerId]) -> Vec { + // take sqrt(x) peers + let mut peers = peers.to_vec(); + let mut count = (peers.len() as f64).powf(0.5).round() as usize; + count = cmp::min(count, MAX_PEERS_PROPAGATION); + count = cmp::max(count, MIN_PEERS_PROPAGATION); + random::new().shuffle(&mut peers); + peers.truncate(count); + peers + } + + fn get_consensus_peers(&self) -> Vec { + self.peers.iter().filter_map(|(id, p)| if p.protocol_version >= PAR_PROTOCOL_VERSION_2 { Some(*id) } else { None }).collect() + } + + fn get_private_transaction_peers(&self) -> Vec { + self.peers.iter().filter_map(|(id, p)| if p.protocol_version >= PAR_PROTOCOL_VERSION_3 { Some(*id) } else { None }).collect() + } + + /// Maintain other peers. Send out any new blocks and transactions + pub fn maintain_sync(&mut self, io: &mut SyncIo) { + self.maybe_start_snapshot_sync(io); + self.check_resume(io); + } + + /// called when block is imported to chain - propagates the blocks and updates transactions sent to peers + pub fn chain_new_blocks(&mut self, io: &mut SyncIo, _imported: &[H256], invalid: &[H256], enacted: &[H256], _retracted: &[H256], sealed: &[H256], proposed: &[Bytes]) { + let queue_info = io.chain().queue_info(); + let is_syncing = self.status().is_syncing(queue_info); + + if !is_syncing || !sealed.is_empty() || !proposed.is_empty() { + trace!(target: "sync", "Propagating blocks, state={:?}", self.state); + SyncPropagator::propagate_latest_blocks(self, io, sealed); + SyncPropagator::propagate_proposed_blocks(self, io, proposed); + } + if !invalid.is_empty() { + trace!(target: "sync", "Bad blocks in the queue, restarting"); + self.restart(io); + } + + if !is_syncing && !enacted.is_empty() && !self.peers.is_empty() { + // Select random peer to re-broadcast transactions to. + let peer = random::new().gen_range(0, self.peers.len()); + trace!(target: "sync", "Re-broadcasting transactions to a random peer."); + self.peers.values_mut().nth(peer).map(|peer_info| + peer_info.last_sent_transactions.clear() + ); + } + } + + /// Dispatch incoming requests and responses + pub fn dispatch_packet(sync: &RwLock, io: &mut SyncIo, peer: PeerId, packet_id: u8, data: &[u8]) { + SyncSupplier::dispatch_packet(sync, io, peer, packet_id, data) + } + + pub fn on_packet(&mut self, io: &mut SyncIo, peer: PeerId, packet_id: u8, data: &[u8]) { + debug!(target: "sync", "{} -> Dispatching packet: {}", peer, packet_id); + SyncHandler::on_packet(self, io, peer, packet_id, data); + } + + /// Called when peer sends us new consensus packet + pub fn on_consensus_packet(io: &mut SyncIo, peer_id: PeerId, r: &Rlp) -> Result<(), PacketDecodeError> { + SyncHandler::on_consensus_packet(io, peer_id, r) + } + + /// Called by peer when it is disconnecting + pub fn on_peer_aborting(&mut self, io: &mut SyncIo, peer: PeerId) { + SyncHandler::on_peer_aborting(self, io, peer); + } + + /// Called when a new peer is connected + pub fn on_peer_connected(&mut self, io: &mut SyncIo, peer: PeerId) { + SyncHandler::on_peer_connected(self, io, peer); + } + + /// propagates new transactions to all peers + pub fn propagate_new_transactions(&mut self, io: &mut SyncIo) -> usize { + SyncPropagator::propagate_new_transactions(self, io) + } + + /// Broadcast consensus message to peers. + pub fn propagate_consensus_packet(&mut self, io: &mut SyncIo, packet: Bytes) { + SyncPropagator::propagate_consensus_packet(self, io, packet); + } + + /// Broadcast private transaction message to peers. + pub fn propagate_private_transaction(&mut self, io: &mut SyncIo, packet: Bytes) { + SyncPropagator::propagate_private_transaction(self, io, packet); + } + + /// Broadcast signed private transaction message to peers. + pub fn propagate_signed_private_transaction(&mut self, io: &mut SyncIo, packet: Bytes) { + SyncPropagator::propagate_signed_private_transaction(self, io, packet); + } +} + +#[cfg(test)] +pub mod tests { + use std::collections::{HashSet, VecDeque}; + use ethkey; + use network::PeerId; + use tests::helpers::{TestIo}; + use tests::snapshot::TestSnapshotService; + use ethereum_types::{H256, U256, Address}; + use parking_lot::RwLock; + use bytes::Bytes; + use rlp::{Rlp, RlpStream}; + use super::*; + use ::SyncConfig; + use super::{PeerInfo, PeerAsking}; + use ethcore::header::*; + use ethcore::client::{BlockChainClient, EachBlockWith, TestBlockChainClient, ChainInfo, BlockInfo}; + use ethcore::miner::MinerService; + use private_tx::NoopPrivateTxHandler; + + pub fn get_dummy_block(order: u32, parent_hash: H256) -> Bytes { + let mut header = Header::new(); + header.set_gas_limit(0.into()); + header.set_difficulty((order * 100).into()); + header.set_timestamp((order * 10) as u64); + header.set_number(order as u64); + header.set_parent_hash(parent_hash); + header.set_state_root(H256::zero()); + + let mut rlp = RlpStream::new_list(3); + rlp.append(&header); + rlp.append_raw(&::rlp::EMPTY_LIST_RLP, 1); + rlp.append_raw(&::rlp::EMPTY_LIST_RLP, 1); + rlp.out() + } + + pub fn get_dummy_blocks(order: u32, parent_hash: H256) -> Bytes { + let mut rlp = RlpStream::new_list(1); + rlp.append_raw(&get_dummy_block(order, parent_hash), 1); + let difficulty: U256 = (100 * order).into(); + rlp.append(&difficulty); + rlp.out() + } + + pub fn get_dummy_hashes() -> Bytes { + let mut rlp = RlpStream::new_list(5); + for _ in 0..5 { + let mut hash_d_rlp = RlpStream::new_list(2); + let hash: H256 = H256::from(0u64); + let diff: U256 = U256::from(1u64); + hash_d_rlp.append(&hash); + hash_d_rlp.append(&diff); + + rlp.append_raw(&hash_d_rlp.out(), 1); + } + + rlp.out() + } + + fn queue_info(unverified: usize, verified: usize) -> BlockQueueInfo { + BlockQueueInfo { + unverified_queue_size: unverified, + verified_queue_size: verified, + verifying_queue_size: 0, + max_queue_size: 1000, + max_mem_use: 1000, + mem_used: 500 + } + } + + fn sync_status(state: SyncState) -> SyncStatus { + SyncStatus { + state: state, + protocol_version: 0, + network_id: 0, + start_block_number: 0, + last_imported_block_number: None, + highest_block_number: None, + blocks_total: 0, + blocks_received: 0, + num_peers: 0, + num_active_peers: 0, + mem_used: 0, + num_snapshot_chunks: 0, + snapshot_chunks_done: 0, + last_imported_old_block_number: None, + } + } + + #[test] + fn is_still_verifying() { + assert!(!sync_status(SyncState::Idle).is_syncing(queue_info(2, 1))); + assert!(sync_status(SyncState::Idle).is_syncing(queue_info(2, 2))); + } + + #[test] + fn is_synced_state() { + assert!(sync_status(SyncState::Blocks).is_syncing(queue_info(0, 0))); + assert!(!sync_status(SyncState::Idle).is_syncing(queue_info(0, 0))); + } + + pub fn dummy_sync_with_peer(peer_latest_hash: H256, client: &BlockChainClient) -> ChainSync { + let mut sync = ChainSync::new(SyncConfig::default(), client, Arc::new(NoopPrivateTxHandler)); + insert_dummy_peer(&mut sync, 0, peer_latest_hash); + sync + } + + pub fn insert_dummy_peer(sync: &mut ChainSync, peer_id: PeerId, peer_latest_hash: H256) { + sync.peers.insert(peer_id, + PeerInfo { + protocol_version: 0, + genesis: H256::zero(), + network_id: 0, + latest_hash: peer_latest_hash, + difficulty: None, + asking: PeerAsking::Nothing, + asking_blocks: Vec::new(), + asking_hash: None, + ask_time: Instant::now(), + last_sent_transactions: HashSet::new(), + expired: false, + confirmation: super::ForkConfirmation::Confirmed, + snapshot_number: None, + snapshot_hash: None, + asking_snapshot_data: None, + block_set: None, + }); + + } + + #[test] + fn finds_lagging_peers() { + let mut client = TestBlockChainClient::new(); + client.add_blocks(100, EachBlockWith::Uncle); + let mut sync = dummy_sync_with_peer(client.block_hash_delta_minus(10), &client); + let chain_info = client.chain_info(); + + let lagging_peers = sync.get_lagging_peers(&chain_info); + + assert_eq!(1, lagging_peers.len()); + } + + #[test] + fn calculates_tree_for_lagging_peer() { + let mut client = TestBlockChainClient::new(); + client.add_blocks(15, EachBlockWith::Uncle); + + let start = client.block_hash_delta_minus(4); + let end = client.block_hash_delta_minus(2); + + // wrong way end -> start, should be None + let rlp = ChainSync::create_new_hashes_rlp(&client, &end, &start); + assert!(rlp.is_none()); + + let rlp = ChainSync::create_new_hashes_rlp(&client, &start, &end).unwrap(); + // size of three rlp encoded hash-difficulty + assert_eq!(107, rlp.len()); + } + // idea is that what we produce when propagading latest hashes should be accepted in + // on_peer_new_hashes in our code as well + #[test] + fn hashes_rlp_mutually_acceptable() { + let mut client = TestBlockChainClient::new(); + client.add_blocks(100, EachBlockWith::Uncle); + let queue = RwLock::new(VecDeque::new()); + let mut sync = dummy_sync_with_peer(client.block_hash_delta_minus(5), &client); + let chain_info = client.chain_info(); + let ss = TestSnapshotService::new(); + let mut io = TestIo::new(&mut client, &ss, &queue, None); + + let peers = sync.get_lagging_peers(&chain_info); + SyncPropagator::propagate_new_hashes(&mut sync, &chain_info, &mut io, &peers); + + let data = &io.packets[0].data.clone(); + let result = SyncHandler::on_peer_new_hashes(&mut sync, &mut io, 0, &Rlp::new(data)); + assert!(result.is_ok()); + } + + // idea is that what we produce when propagading latest block should be accepted in + // on_peer_new_block in our code as well + #[test] + fn block_rlp_mutually_acceptable() { + let mut client = TestBlockChainClient::new(); + client.add_blocks(100, EachBlockWith::Uncle); + let queue = RwLock::new(VecDeque::new()); + let mut sync = dummy_sync_with_peer(client.block_hash_delta_minus(5), &client); + let chain_info = client.chain_info(); + let ss = TestSnapshotService::new(); + let mut io = TestIo::new(&mut client, &ss, &queue, None); + + let peers = sync.get_lagging_peers(&chain_info); + SyncPropagator::propagate_blocks(&mut sync, &chain_info, &mut io, &[], &peers); + + let data = &io.packets[0].data.clone(); + let result = SyncHandler::on_peer_new_block(&mut sync, &mut io, 0, &Rlp::new(data)); + assert!(result.is_ok()); + } + + #[test] + fn should_add_transactions_to_queue() { + fn sender(tx: &UnverifiedTransaction) -> Address { + ethkey::public_to_address(&tx.recover_public().unwrap()) + } + + // given + let mut client = TestBlockChainClient::new(); + client.add_blocks(98, EachBlockWith::Uncle); + client.add_blocks(1, EachBlockWith::UncleAndTransaction); + client.add_blocks(1, EachBlockWith::Transaction); + let mut sync = dummy_sync_with_peer(client.block_hash_delta_minus(5), &client); + + let good_blocks = vec![client.block_hash_delta_minus(2)]; + let retracted_blocks = vec![client.block_hash_delta_minus(1)]; + + // Add some balance to clients and reset nonces + for h in &[good_blocks[0], retracted_blocks[0]] { + let block = client.block(BlockId::Hash(*h)).unwrap(); + let sender = sender(&block.transactions()[0]);; + client.set_balance(sender, U256::from(10_000_000_000_000_000_000u64)); + client.set_nonce(sender, U256::from(0)); + } + + + // when + { + let queue = RwLock::new(VecDeque::new()); + let ss = TestSnapshotService::new(); + let mut io = TestIo::new(&mut client, &ss, &queue, None); + io.chain.miner.chain_new_blocks(io.chain, &[], &[], &[], &good_blocks, false); + sync.chain_new_blocks(&mut io, &[], &[], &[], &good_blocks, &[], &[]); + assert_eq!(io.chain.miner.ready_transactions(io.chain).len(), 1); + } + // We need to update nonce status (because we say that the block has been imported) + for h in &[good_blocks[0]] { + let block = client.block(BlockId::Hash(*h)).unwrap(); + client.set_nonce(sender(&block.transactions()[0]), U256::from(1)); + } + { + let queue = RwLock::new(VecDeque::new()); + let ss = TestSnapshotService::new(); + let mut io = TestIo::new(&client, &ss, &queue, None); + io.chain.miner.chain_new_blocks(io.chain, &[], &[], &good_blocks, &retracted_blocks, false); + sync.chain_new_blocks(&mut io, &[], &[], &good_blocks, &retracted_blocks, &[], &[]); + } + + // then + assert_eq!(client.miner.ready_transactions(&client).len(), 1); + } + + #[test] + fn should_not_add_transactions_to_queue_if_not_synced() { + // given + let mut client = TestBlockChainClient::new(); + client.add_blocks(98, EachBlockWith::Uncle); + client.add_blocks(1, EachBlockWith::UncleAndTransaction); + client.add_blocks(1, EachBlockWith::Transaction); + let mut sync = dummy_sync_with_peer(client.block_hash_delta_minus(5), &client); + + let good_blocks = vec![client.block_hash_delta_minus(2)]; + let retracted_blocks = vec![client.block_hash_delta_minus(1)]; + + let queue = RwLock::new(VecDeque::new()); + let ss = TestSnapshotService::new(); + let mut io = TestIo::new(&mut client, &ss, &queue, None); + + // when + sync.chain_new_blocks(&mut io, &[], &[], &[], &good_blocks, &[], &[]); + assert_eq!(io.chain.miner.queue_status().status.transaction_count, 0); + sync.chain_new_blocks(&mut io, &[], &[], &good_blocks, &retracted_blocks, &[], &[]); + + // then + let status = io.chain.miner.queue_status(); + assert_eq!(status.status.transaction_count, 0); + } +} diff --git a/ethcore/sync/src/chain/propagator.rs b/ethcore/sync/src/chain/propagator.rs new file mode 100644 index 0000000000..4ae0518a53 --- /dev/null +++ b/ethcore/sync/src/chain/propagator.rs @@ -0,0 +1,636 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +use bytes::Bytes; +use ethereum_types::H256; +use ethcore::client::BlockChainInfo; +use ethcore::header::BlockNumber; +use network::{PeerId, PacketId}; +use rand::Rng; +use rlp::{Encodable, RlpStream}; +use sync_io::SyncIo; +use std::cmp; +use std::collections::HashSet; +use transaction::SignedTransaction; + +use super::{ + random, + ChainSync, + MAX_PEER_LAG_PROPAGATION, + MAX_PEERS_PROPAGATION, + MAX_TRANSACTION_PACKET_SIZE, + MAX_TRANSACTIONS_TO_PROPAGATE, + MIN_PEERS_PROPAGATION, + CONSENSUS_DATA_PACKET, + NEW_BLOCK_HASHES_PACKET, + NEW_BLOCK_PACKET, + PRIVATE_TRANSACTION_PACKET, + SIGNED_PRIVATE_TRANSACTION_PACKET, + TRANSACTIONS_PACKET, +}; + +/// Checks if peer is able to process service transactions +fn accepts_service_transaction(client_id: &str) -> bool { + // Parity versions starting from this will accept service-transactions + const SERVICE_TRANSACTIONS_VERSION: (u32, u32) = (1u32, 6u32); + // Parity client string prefix + const PARITY_CLIENT_ID_PREFIX: &'static str = "Parity/v"; + + if !client_id.starts_with(PARITY_CLIENT_ID_PREFIX) { + return false; + } + let ver: Vec = client_id[PARITY_CLIENT_ID_PREFIX.len()..].split('.') + .take(2) + .filter_map(|s| s.parse().ok()) + .collect(); + ver.len() == 2 && (ver[0] > SERVICE_TRANSACTIONS_VERSION.0 || (ver[0] == SERVICE_TRANSACTIONS_VERSION.0 && ver[1] >= SERVICE_TRANSACTIONS_VERSION.1)) +} + +/// The Chain Sync Propagator: propagates data to peers +pub struct SyncPropagator; + +impl SyncPropagator { + /// propagates latest block to a set of peers + pub fn propagate_blocks(sync: &mut ChainSync, chain_info: &BlockChainInfo, io: &mut SyncIo, blocks: &[H256], peers: &[PeerId]) -> usize { + trace!(target: "sync", "Sending NewBlocks to {:?}", peers); + let mut sent = 0; + for peer_id in peers { + if blocks.is_empty() { + let rlp = ChainSync::create_latest_block_rlp(io.chain()); + SyncPropagator::send_packet(io, *peer_id, NEW_BLOCK_PACKET, rlp); + } else { + for h in blocks { + let rlp = ChainSync::create_new_block_rlp(io.chain(), h); + SyncPropagator::send_packet(io, *peer_id, NEW_BLOCK_PACKET, rlp); + } + } + if let Some(ref mut peer) = sync.peers.get_mut(peer_id) { + peer.latest_hash = chain_info.best_block_hash.clone(); + } + sent += 1; + } + sent + } + + /// propagates new known hashes to all peers + pub fn propagate_new_hashes(sync: &mut ChainSync, chain_info: &BlockChainInfo, io: &mut SyncIo, peers: &[PeerId]) -> usize { + trace!(target: "sync", "Sending NewHashes to {:?}", peers); + let mut sent = 0; + let last_parent = *io.chain().best_block_header().parent_hash(); + for peer_id in peers { + sent += match ChainSync::create_new_hashes_rlp(io.chain(), &last_parent, &chain_info.best_block_hash) { + Some(rlp) => { + { + if let Some(ref mut peer) = sync.peers.get_mut(peer_id) { + peer.latest_hash = chain_info.best_block_hash.clone(); + } + } + SyncPropagator::send_packet(io, *peer_id, NEW_BLOCK_HASHES_PACKET, rlp); + 1 + }, + None => 0 + } + } + sent + } + + /// propagates new transactions to all peers + pub fn propagate_new_transactions(sync: &mut ChainSync, io: &mut SyncIo) -> usize { + // Early out if nobody to send to. + if sync.peers.is_empty() { + return 0; + } + + let transactions = io.chain().ready_transactions(); + if transactions.is_empty() { + return 0; + } + + let (transactions, service_transactions): (Vec<_>, Vec<_>) = transactions.iter() + .map(|tx| tx.signed()) + .partition(|tx| !tx.gas_price.is_zero()); + + // usual transactions could be propagated to all peers + let mut affected_peers = HashSet::new(); + if !transactions.is_empty() { + let peers = SyncPropagator::select_peers_for_transactions(sync, |_| true); + affected_peers = SyncPropagator::propagate_transactions_to_peers(sync, io, peers, transactions); + } + + // most of times service_transactions will be empty + // => there's no need to merge packets + if !service_transactions.is_empty() { + let service_transactions_peers = SyncPropagator::select_peers_for_transactions(sync, |peer_id| accepts_service_transaction(&io.peer_info(*peer_id))); + let service_transactions_affected_peers = SyncPropagator::propagate_transactions_to_peers(sync, io, service_transactions_peers, service_transactions); + affected_peers.extend(&service_transactions_affected_peers); + } + + affected_peers.len() + } + + fn propagate_transactions_to_peers(sync: &mut ChainSync, io: &mut SyncIo, peers: Vec, transactions: Vec<&SignedTransaction>) -> HashSet { + let all_transactions_hashes = transactions.iter() + .map(|tx| tx.hash()) + .collect::>(); + let all_transactions_rlp = { + let mut packet = RlpStream::new_list(transactions.len()); + for tx in &transactions { packet.append(&**tx); } + packet.out() + }; + + // Clear old transactions from stats + sync.transactions_stats.retain(&all_transactions_hashes); + + // sqrt(x)/x scaled to max u32 + let block_number = io.chain().chain_info().best_block_number; + + let lucky_peers = { + peers.into_iter() + .filter_map(|peer_id| { + let stats = &mut sync.transactions_stats; + let peer_info = sync.peers.get_mut(&peer_id) + .expect("peer_id is form peers; peers is result of select_peers_for_transactions; select_peers_for_transactions selects peers from self.peers; qed"); + + // Send all transactions + if peer_info.last_sent_transactions.is_empty() { + // update stats + for hash in &all_transactions_hashes { + let id = io.peer_session_info(peer_id).and_then(|info| info.id); + stats.propagated(hash, id, block_number); + } + peer_info.last_sent_transactions = all_transactions_hashes.clone(); + return Some((peer_id, all_transactions_hashes.len(), all_transactions_rlp.clone())); + } + + // Get hashes of all transactions to send to this peer + let to_send = all_transactions_hashes.difference(&peer_info.last_sent_transactions) + .take(MAX_TRANSACTIONS_TO_PROPAGATE) + .cloned() + .collect::>(); + if to_send.is_empty() { + return None; + } + + // Construct RLP + let (packet, to_send) = { + let mut to_send = to_send; + let mut packet = RlpStream::new(); + packet.begin_unbounded_list(); + let mut pushed = 0; + for tx in &transactions { + let hash = tx.hash(); + if to_send.contains(&hash) { + let mut transaction = RlpStream::new(); + tx.rlp_append(&mut transaction); + let appended = packet.append_raw_checked(&transaction.drain(), 1, MAX_TRANSACTION_PACKET_SIZE); + if !appended { + // Maximal packet size reached just proceed with sending + debug!("Transaction packet size limit reached. Sending incomplete set of {}/{} transactions.", pushed, to_send.len()); + to_send = to_send.into_iter().take(pushed).collect(); + break; + } + pushed += 1; + } + } + packet.complete_unbounded_list(); + (packet, to_send) + }; + + // Update stats + let id = io.peer_session_info(peer_id).and_then(|info| info.id); + for hash in &to_send { + // update stats + stats.propagated(hash, id, block_number); + } + + peer_info.last_sent_transactions = all_transactions_hashes + .intersection(&peer_info.last_sent_transactions) + .chain(&to_send) + .cloned() + .collect(); + Some((peer_id, to_send.len(), packet.out())) + }) + .collect::>() + }; + + // Send RLPs + let mut peers = HashSet::new(); + if lucky_peers.len() > 0 { + let mut max_sent = 0; + let lucky_peers_len = lucky_peers.len(); + for (peer_id, sent, rlp) in lucky_peers { + peers.insert(peer_id); + SyncPropagator::send_packet(io, peer_id, TRANSACTIONS_PACKET, rlp); + trace!(target: "sync", "{:02} <- Transactions ({} entries)", peer_id, sent); + max_sent = cmp::max(max_sent, sent); + } + debug!(target: "sync", "Sent up to {} transactions to {} peers.", max_sent, lucky_peers_len); + } + + peers + } + + pub fn propagate_latest_blocks(sync: &mut ChainSync, io: &mut SyncIo, sealed: &[H256]) { + let chain_info = io.chain().chain_info(); + if (((chain_info.best_block_number as i64) - (sync.last_sent_block_number as i64)).abs() as BlockNumber) < MAX_PEER_LAG_PROPAGATION { + let mut peers = sync.get_lagging_peers(&chain_info); + if sealed.is_empty() { + let hashes = SyncPropagator::propagate_new_hashes(sync, &chain_info, io, &peers); + peers = ChainSync::select_random_peers(&peers); + let blocks = SyncPropagator::propagate_blocks(sync, &chain_info, io, sealed, &peers); + if blocks != 0 || hashes != 0 { + trace!(target: "sync", "Sent latest {} blocks and {} hashes to peers.", blocks, hashes); + } + } else { + SyncPropagator::propagate_blocks(sync, &chain_info, io, sealed, &peers); + SyncPropagator::propagate_new_hashes(sync, &chain_info, io, &peers); + trace!(target: "sync", "Sent sealed block to all peers"); + }; + } + sync.last_sent_block_number = chain_info.best_block_number; + } + + /// Distribute valid proposed blocks to subset of current peers. + pub fn propagate_proposed_blocks(sync: &mut ChainSync, io: &mut SyncIo, proposed: &[Bytes]) { + let peers = sync.get_consensus_peers(); + trace!(target: "sync", "Sending proposed blocks to {:?}", peers); + for block in proposed { + let rlp = ChainSync::create_block_rlp( + block, + io.chain().chain_info().total_difficulty + ); + for peer_id in &peers { + SyncPropagator::send_packet(io, *peer_id, NEW_BLOCK_PACKET, rlp.clone()); + } + } + } + + /// Broadcast consensus message to peers. + pub fn propagate_consensus_packet(sync: &mut ChainSync, io: &mut SyncIo, packet: Bytes) { + let lucky_peers = ChainSync::select_random_peers(&sync.get_consensus_peers()); + trace!(target: "sync", "Sending consensus packet to {:?}", lucky_peers); + for peer_id in lucky_peers { + SyncPropagator::send_packet(io, peer_id, CONSENSUS_DATA_PACKET, packet.clone()); + } + } + + /// Broadcast private transaction message to peers. + pub fn propagate_private_transaction(sync: &mut ChainSync, io: &mut SyncIo, packet: Bytes) { + let lucky_peers = ChainSync::select_random_peers(&sync.get_private_transaction_peers()); + trace!(target: "sync", "Sending private transaction packet to {:?}", lucky_peers); + for peer_id in lucky_peers { + SyncPropagator::send_packet(io, peer_id, PRIVATE_TRANSACTION_PACKET, packet.clone()); + } + } + + /// Broadcast signed private transaction message to peers. + pub fn propagate_signed_private_transaction(sync: &mut ChainSync, io: &mut SyncIo, packet: Bytes) { + let lucky_peers = ChainSync::select_random_peers(&sync.get_private_transaction_peers()); + trace!(target: "sync", "Sending signed private transaction packet to {:?}", lucky_peers); + for peer_id in lucky_peers { + SyncPropagator::send_packet(io, peer_id, SIGNED_PRIVATE_TRANSACTION_PACKET, packet.clone()); + } + } + + fn select_peers_for_transactions(sync: &ChainSync, filter: F) -> Vec + where F: Fn(&PeerId) -> bool { + // sqrt(x)/x scaled to max u32 + let fraction = ((sync.peers.len() as f64).powf(-0.5) * (u32::max_value() as f64).round()) as u32; + let small = sync.peers.len() < MIN_PEERS_PROPAGATION; + + let mut random = random::new(); + sync.peers.keys() + .cloned() + .filter(filter) + .filter(|_| small || random.next_u32() < fraction) + .take(MAX_PEERS_PROPAGATION) + .collect() + } + + /// Generic packet sender + fn send_packet(sync: &mut SyncIo, peer_id: PeerId, packet_id: PacketId, packet: Bytes) { + if let Err(e) = sync.send(peer_id, packet_id, packet) { + debug!(target:"sync", "Error sending packet: {:?}", e); + sync.disconnect_peer(peer_id); + } + } +} + +#[cfg(test)] +mod tests { + use ethcore::client::{BlockInfo, ChainInfo, EachBlockWith, TestBlockChainClient}; + use parking_lot::RwLock; + use private_tx::NoopPrivateTxHandler; + use rlp::{Rlp}; + use std::collections::{VecDeque}; + use tests::helpers::{TestIo}; + use tests::snapshot::TestSnapshotService; + + use super::{*, super::{*, tests::*}}; + + #[test] + fn sends_new_hashes_to_lagging_peer() { + let mut client = TestBlockChainClient::new(); + client.add_blocks(100, EachBlockWith::Uncle); + let queue = RwLock::new(VecDeque::new()); + let mut sync = dummy_sync_with_peer(client.block_hash_delta_minus(5), &client); + let chain_info = client.chain_info(); + let ss = TestSnapshotService::new(); + let mut io = TestIo::new(&mut client, &ss, &queue, None); + + let peers = sync.get_lagging_peers(&chain_info); + let peer_count = SyncPropagator::propagate_new_hashes(&mut sync, &chain_info, &mut io, &peers); + + // 1 message should be send + assert_eq!(1, io.packets.len()); + // 1 peer should be updated + assert_eq!(1, peer_count); + // NEW_BLOCK_HASHES_PACKET + assert_eq!(0x01, io.packets[0].packet_id); + } + + #[test] + fn sends_latest_block_to_lagging_peer() { + let mut client = TestBlockChainClient::new(); + client.add_blocks(100, EachBlockWith::Uncle); + let queue = RwLock::new(VecDeque::new()); + let mut sync = dummy_sync_with_peer(client.block_hash_delta_minus(5), &client); + let chain_info = client.chain_info(); + let ss = TestSnapshotService::new(); + let mut io = TestIo::new(&mut client, &ss, &queue, None); + let peers = sync.get_lagging_peers(&chain_info); + let peer_count = SyncPropagator::propagate_blocks(&mut sync, &chain_info, &mut io, &[], &peers); + + // 1 message should be send + assert_eq!(1, io.packets.len()); + // 1 peer should be updated + assert_eq!(1, peer_count); + // NEW_BLOCK_PACKET + assert_eq!(0x07, io.packets[0].packet_id); + } + + #[test] + fn sends_sealed_block() { + let mut client = TestBlockChainClient::new(); + client.add_blocks(100, EachBlockWith::Uncle); + let queue = RwLock::new(VecDeque::new()); + let hash = client.block_hash(BlockId::Number(99)).unwrap(); + let mut sync = dummy_sync_with_peer(client.block_hash_delta_minus(5), &client); + let chain_info = client.chain_info(); + let ss = TestSnapshotService::new(); + let mut io = TestIo::new(&mut client, &ss, &queue, None); + let peers = sync.get_lagging_peers(&chain_info); + let peer_count = SyncPropagator::propagate_blocks(&mut sync ,&chain_info, &mut io, &[hash.clone()], &peers); + + // 1 message should be send + assert_eq!(1, io.packets.len()); + // 1 peer should be updated + assert_eq!(1, peer_count); + // NEW_BLOCK_PACKET + assert_eq!(0x07, io.packets[0].packet_id); + } + + #[test] + fn sends_proposed_block() { + let mut client = TestBlockChainClient::new(); + client.add_blocks(2, EachBlockWith::Uncle); + let queue = RwLock::new(VecDeque::new()); + let block = client.block(BlockId::Latest).unwrap().into_inner(); + let mut sync = ChainSync::new(SyncConfig::default(), &client, Arc::new(NoopPrivateTxHandler)); + sync.peers.insert(0, + PeerInfo { + // Messaging protocol + protocol_version: 2, + genesis: H256::zero(), + network_id: 0, + latest_hash: client.block_hash_delta_minus(1), + difficulty: None, + asking: PeerAsking::Nothing, + asking_blocks: Vec::new(), + asking_hash: None, + ask_time: Instant::now(), + last_sent_transactions: HashSet::new(), + expired: false, + confirmation: ForkConfirmation::Confirmed, + snapshot_number: None, + snapshot_hash: None, + asking_snapshot_data: None, + block_set: None, + }); + let ss = TestSnapshotService::new(); + let mut io = TestIo::new(&mut client, &ss, &queue, None); + SyncPropagator::propagate_proposed_blocks(&mut sync, &mut io, &[block]); + + // 1 message should be sent + assert_eq!(1, io.packets.len()); + // NEW_BLOCK_PACKET + assert_eq!(0x07, io.packets[0].packet_id); + } + + #[test] + fn propagates_transactions() { + let mut client = TestBlockChainClient::new(); + client.add_blocks(100, EachBlockWith::Uncle); + client.insert_transaction_to_queue(); + let mut sync = dummy_sync_with_peer(client.block_hash_delta_minus(1), &client); + let queue = RwLock::new(VecDeque::new()); + let ss = TestSnapshotService::new(); + let mut io = TestIo::new(&mut client, &ss, &queue, None); + let peer_count = SyncPropagator::propagate_new_transactions(&mut sync, &mut io); + // Try to propagate same transactions for the second time + let peer_count2 = SyncPropagator::propagate_new_transactions(&mut sync, &mut io); + // Even after new block transactions should not be propagated twice + sync.chain_new_blocks(&mut io, &[], &[], &[], &[], &[], &[]); + // Try to propagate same transactions for the third time + let peer_count3 = SyncPropagator::propagate_new_transactions(&mut sync, &mut io); + + // 1 message should be send + assert_eq!(1, io.packets.len()); + // 1 peer should be updated but only once + assert_eq!(1, peer_count); + assert_eq!(0, peer_count2); + assert_eq!(0, peer_count3); + // TRANSACTIONS_PACKET + assert_eq!(0x02, io.packets[0].packet_id); + } + + #[test] + fn does_not_propagate_new_transactions_after_new_block() { + let mut client = TestBlockChainClient::new(); + client.add_blocks(100, EachBlockWith::Uncle); + client.insert_transaction_to_queue(); + let mut sync = dummy_sync_with_peer(client.block_hash_delta_minus(1), &client); + let queue = RwLock::new(VecDeque::new()); + let ss = TestSnapshotService::new(); + let mut io = TestIo::new(&mut client, &ss, &queue, None); + let peer_count = SyncPropagator::propagate_new_transactions(&mut sync, &mut io); + io.chain.insert_transaction_to_queue(); + // New block import should not trigger propagation. + // (we only propagate on timeout) + sync.chain_new_blocks(&mut io, &[], &[], &[], &[], &[], &[]); + + // 2 message should be send + assert_eq!(1, io.packets.len()); + // 1 peer should receive the message + assert_eq!(1, peer_count); + // TRANSACTIONS_PACKET + assert_eq!(0x02, io.packets[0].packet_id); + } + + #[test] + fn does_not_fail_for_no_peers() { + let mut client = TestBlockChainClient::new(); + client.add_blocks(100, EachBlockWith::Uncle); + client.insert_transaction_to_queue(); + // Sync with no peers + let mut sync = ChainSync::new(SyncConfig::default(), &client, Arc::new(NoopPrivateTxHandler)); + let queue = RwLock::new(VecDeque::new()); + let ss = TestSnapshotService::new(); + let mut io = TestIo::new(&mut client, &ss, &queue, None); + let peer_count = SyncPropagator::propagate_new_transactions(&mut sync, &mut io); + sync.chain_new_blocks(&mut io, &[], &[], &[], &[], &[], &[]); + // Try to propagate same transactions for the second time + let peer_count2 = SyncPropagator::propagate_new_transactions(&mut sync, &mut io); + + assert_eq!(0, io.packets.len()); + assert_eq!(0, peer_count); + assert_eq!(0, peer_count2); + } + + #[test] + fn propagates_transactions_without_alternating() { + let mut client = TestBlockChainClient::new(); + client.add_blocks(100, EachBlockWith::Uncle); + client.insert_transaction_to_queue(); + let mut sync = dummy_sync_with_peer(client.block_hash_delta_minus(1), &client); + let queue = RwLock::new(VecDeque::new()); + let ss = TestSnapshotService::new(); + // should sent some + { + let mut io = TestIo::new(&mut client, &ss, &queue, None); + let peer_count = SyncPropagator::propagate_new_transactions(&mut sync, &mut io); + assert_eq!(1, io.packets.len()); + assert_eq!(1, peer_count); + } + // Insert some more + client.insert_transaction_to_queue(); + let (peer_count2, peer_count3) = { + let mut io = TestIo::new(&mut client, &ss, &queue, None); + // Propagate new transactions + let peer_count2 = SyncPropagator::propagate_new_transactions(&mut sync, &mut io); + // And now the peer should have all transactions + let peer_count3 = SyncPropagator::propagate_new_transactions(&mut sync, &mut io); + (peer_count2, peer_count3) + }; + + // 2 message should be send (in total) + assert_eq!(2, queue.read().len()); + // 1 peer should be updated but only once after inserting new transaction + assert_eq!(1, peer_count2); + assert_eq!(0, peer_count3); + // TRANSACTIONS_PACKET + assert_eq!(0x02, queue.read()[0].packet_id); + assert_eq!(0x02, queue.read()[1].packet_id); + } + + #[test] + fn should_maintain_transations_propagation_stats() { + let mut client = TestBlockChainClient::new(); + client.add_blocks(100, EachBlockWith::Uncle); + client.insert_transaction_to_queue(); + let mut sync = dummy_sync_with_peer(client.block_hash_delta_minus(1), &client); + let queue = RwLock::new(VecDeque::new()); + let ss = TestSnapshotService::new(); + let mut io = TestIo::new(&mut client, &ss, &queue, None); + SyncPropagator::propagate_new_transactions(&mut sync, &mut io); + + let stats = sync.transactions_stats(); + assert_eq!(stats.len(), 1, "Should maintain stats for single transaction.") + } + + #[test] + fn should_propagate_service_transaction_to_selected_peers_only() { + let mut client = TestBlockChainClient::new(); + client.insert_transaction_with_gas_price_to_queue(U256::zero()); + let block_hash = client.block_hash_delta_minus(1); + let mut sync = ChainSync::new(SyncConfig::default(), &client, Arc::new(NoopPrivateTxHandler)); + let queue = RwLock::new(VecDeque::new()); + let ss = TestSnapshotService::new(); + let mut io = TestIo::new(&mut client, &ss, &queue, None); + + // when peer#1 is Geth + insert_dummy_peer(&mut sync, 1, block_hash); + io.peers_info.insert(1, "Geth".to_owned()); + // and peer#2 is Parity, accepting service transactions + insert_dummy_peer(&mut sync, 2, block_hash); + io.peers_info.insert(2, "Parity/v1.6".to_owned()); + // and peer#3 is Parity, discarding service transactions + insert_dummy_peer(&mut sync, 3, block_hash); + io.peers_info.insert(3, "Parity/v1.5".to_owned()); + // and peer#4 is Parity, accepting service transactions + insert_dummy_peer(&mut sync, 4, block_hash); + io.peers_info.insert(4, "Parity/v1.7.3-ABCDEFGH".to_owned()); + + // and new service transaction is propagated to peers + SyncPropagator::propagate_new_transactions(&mut sync, &mut io); + + // peer#2 && peer#4 are receiving service transaction + assert!(io.packets.iter().any(|p| p.packet_id == 0x02 && p.recipient == 2)); // TRANSACTIONS_PACKET + assert!(io.packets.iter().any(|p| p.packet_id == 0x02 && p.recipient == 4)); // TRANSACTIONS_PACKET + assert_eq!(io.packets.len(), 2); + } + + #[test] + fn should_propagate_service_transaction_is_sent_as_separate_message() { + let mut client = TestBlockChainClient::new(); + let tx1_hash = client.insert_transaction_to_queue(); + let tx2_hash = client.insert_transaction_with_gas_price_to_queue(U256::zero()); + let block_hash = client.block_hash_delta_minus(1); + let mut sync = ChainSync::new(SyncConfig::default(), &client, Arc::new(NoopPrivateTxHandler)); + let queue = RwLock::new(VecDeque::new()); + let ss = TestSnapshotService::new(); + let mut io = TestIo::new(&mut client, &ss, &queue, None); + + // when peer#1 is Parity, accepting service transactions + insert_dummy_peer(&mut sync, 1, block_hash); + io.peers_info.insert(1, "Parity/v1.6".to_owned()); + + // and service + non-service transactions are propagated to peers + SyncPropagator::propagate_new_transactions(&mut sync, &mut io); + + // two separate packets for peer are queued: + // 1) with non-service-transaction + // 2) with service transaction + let sent_transactions: Vec = io.packets.iter() + .filter_map(|p| { + if p.packet_id != 0x02 || p.recipient != 1 { // TRANSACTIONS_PACKET + return None; + } + + let rlp = Rlp::new(&*p.data); + let item_count = rlp.item_count().unwrap_or(0); + if item_count != 1 { + return None; + } + + rlp.at(0).ok().and_then(|r| r.as_val().ok()) + }) + .collect(); + assert_eq!(sent_transactions.len(), 2); + assert!(sent_transactions.iter().any(|tx| tx.hash() == tx1_hash)); + assert!(sent_transactions.iter().any(|tx| tx.hash() == tx2_hash)); + } +} diff --git a/ethcore/sync/src/chain/requester.rs b/ethcore/sync/src/chain/requester.rs new file mode 100644 index 0000000000..e6acf6bc53 --- /dev/null +++ b/ethcore/sync/src/chain/requester.rs @@ -0,0 +1,154 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +use api::WARP_SYNC_PROTOCOL_ID; +use block_sync::BlockRequest; +use bytes::Bytes; +use ethcore::header::BlockNumber; +use ethereum_types::H256; +use network::{PeerId, PacketId}; +use rlp::RlpStream; +use std::time::Instant; +use sync_io::SyncIo; + +use super::{ + BlockSet, + ChainSync, + PeerAsking, + ETH_PACKET_COUNT, + GET_BLOCK_BODIES_PACKET, + GET_BLOCK_HEADERS_PACKET, + GET_RECEIPTS_PACKET, + GET_SNAPSHOT_DATA_PACKET, + GET_SNAPSHOT_MANIFEST_PACKET, +}; + +/// The Chain Sync Requester: requesting data to other peers +pub struct SyncRequester; + +impl SyncRequester { + /// Perform block download request` + pub fn request_blocks(sync: &mut ChainSync, io: &mut SyncIo, peer_id: PeerId, request: BlockRequest, block_set: BlockSet) { + match request { + BlockRequest::Headers { start, count, skip } => { + SyncRequester::request_headers_by_hash(sync, io, peer_id, &start, count, skip, false, block_set); + }, + BlockRequest::Bodies { hashes } => { + SyncRequester::request_bodies(sync, io, peer_id, hashes, block_set); + }, + BlockRequest::Receipts { hashes } => { + SyncRequester::request_receipts(sync, io, peer_id, hashes, block_set); + }, + } + } + + /// Request block bodies from a peer + fn request_bodies(sync: &mut ChainSync, io: &mut SyncIo, peer_id: PeerId, hashes: Vec, set: BlockSet) { + let mut rlp = RlpStream::new_list(hashes.len()); + trace!(target: "sync", "{} <- GetBlockBodies: {} entries starting from {:?}, set = {:?}", peer_id, hashes.len(), hashes.first(), set); + for h in &hashes { + rlp.append(&h.clone()); + } + SyncRequester::send_request(sync, io, peer_id, PeerAsking::BlockBodies, GET_BLOCK_BODIES_PACKET, rlp.out()); + let peer = sync.peers.get_mut(&peer_id).expect("peer_id may originate either from on_packet, where it is already validated or from enumerating self.peers. qed"); + peer.asking_blocks = hashes; + peer.block_set = Some(set); + } + + /// Request headers from a peer by block number + pub fn request_fork_header(sync: &mut ChainSync, io: &mut SyncIo, peer_id: PeerId, n: BlockNumber) { + trace!(target: "sync", "{} <- GetForkHeader: at {}", peer_id, n); + let mut rlp = RlpStream::new_list(4); + rlp.append(&n); + rlp.append(&1u32); + rlp.append(&0u32); + rlp.append(&0u32); + SyncRequester::send_request(sync, io, peer_id, PeerAsking::ForkHeader, GET_BLOCK_HEADERS_PACKET, rlp.out()); + } + + /// Find some headers or blocks to download for a peer. + pub fn request_snapshot_data(sync: &mut ChainSync, io: &mut SyncIo, peer_id: PeerId) { + // find chunk data to download + if let Some(hash) = sync.snapshot.needed_chunk() { + if let Some(ref mut peer) = sync.peers.get_mut(&peer_id) { + peer.asking_snapshot_data = Some(hash.clone()); + } + SyncRequester::request_snapshot_chunk(sync, io, peer_id, &hash); + } + } + + /// Request snapshot manifest from a peer. + pub fn request_snapshot_manifest(sync: &mut ChainSync, io: &mut SyncIo, peer_id: PeerId) { + trace!(target: "sync", "{} <- GetSnapshotManifest", peer_id); + let rlp = RlpStream::new_list(0); + SyncRequester::send_request(sync, io, peer_id, PeerAsking::SnapshotManifest, GET_SNAPSHOT_MANIFEST_PACKET, rlp.out()); + } + + /// Request headers from a peer by block hash + fn request_headers_by_hash(sync: &mut ChainSync, io: &mut SyncIo, peer_id: PeerId, h: &H256, count: u64, skip: u64, reverse: bool, set: BlockSet) { + trace!(target: "sync", "{} <- GetBlockHeaders: {} entries starting from {}, set = {:?}", peer_id, count, h, set); + let mut rlp = RlpStream::new_list(4); + rlp.append(h); + rlp.append(&count); + rlp.append(&skip); + rlp.append(&if reverse {1u32} else {0u32}); + SyncRequester::send_request(sync, io, peer_id, PeerAsking::BlockHeaders, GET_BLOCK_HEADERS_PACKET, rlp.out()); + let peer = sync.peers.get_mut(&peer_id).expect("peer_id may originate either from on_packet, where it is already validated or from enumerating self.peers. qed"); + peer.asking_hash = Some(h.clone()); + peer.block_set = Some(set); + } + + /// Request block receipts from a peer + fn request_receipts(sync: &mut ChainSync, io: &mut SyncIo, peer_id: PeerId, hashes: Vec, set: BlockSet) { + let mut rlp = RlpStream::new_list(hashes.len()); + trace!(target: "sync", "{} <- GetBlockReceipts: {} entries starting from {:?}, set = {:?}", peer_id, hashes.len(), hashes.first(), set); + for h in &hashes { + rlp.append(&h.clone()); + } + SyncRequester::send_request(sync, io, peer_id, PeerAsking::BlockReceipts, GET_RECEIPTS_PACKET, rlp.out()); + let peer = sync.peers.get_mut(&peer_id).expect("peer_id may originate either from on_packet, where it is already validated or from enumerating self.peers. qed"); + peer.asking_blocks = hashes; + peer.block_set = Some(set); + } + + /// Request snapshot chunk from a peer. + fn request_snapshot_chunk(sync: &mut ChainSync, io: &mut SyncIo, peer_id: PeerId, chunk: &H256) { + trace!(target: "sync", "{} <- GetSnapshotData {:?}", peer_id, chunk); + let mut rlp = RlpStream::new_list(1); + rlp.append(chunk); + SyncRequester::send_request(sync, io, peer_id, PeerAsking::SnapshotData, GET_SNAPSHOT_DATA_PACKET, rlp.out()); + } + + /// Generic request sender + fn send_request(sync: &mut ChainSync, io: &mut SyncIo, peer_id: PeerId, asking: PeerAsking, packet_id: PacketId, packet: Bytes) { + if let Some(ref mut peer) = sync.peers.get_mut(&peer_id) { + if peer.asking != PeerAsking::Nothing { + warn!(target:"sync", "Asking {:?} while requesting {:?}", peer.asking, asking); + } + peer.asking = asking; + peer.ask_time = Instant::now(); + let result = if packet_id >= ETH_PACKET_COUNT { + io.send_protocol(WARP_SYNC_PROTOCOL_ID, peer_id, packet_id, packet) + } else { + io.send(peer_id, packet_id, packet) + }; + if let Err(e) = result { + debug!(target:"sync", "Error sending request: {:?}", e); + io.disconnect_peer(peer_id); + } + } + } +} diff --git a/ethcore/sync/src/chain/supplier.rs b/ethcore/sync/src/chain/supplier.rs new file mode 100644 index 0000000000..0bfb856982 --- /dev/null +++ b/ethcore/sync/src/chain/supplier.rs @@ -0,0 +1,446 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +use bytes::Bytes; +use ethcore::client::BlockId; +use ethcore::header::BlockNumber; +use ethereum_types::H256; +use network::{self, PeerId}; +use parking_lot::RwLock; +use rlp::{Rlp, RlpStream}; +use std::cmp; +use sync_io::SyncIo; + +use super::{ + ChainSync, + RlpResponseResult, + PacketDecodeError, + BLOCK_BODIES_PACKET, + BLOCK_HEADERS_PACKET, + CONSENSUS_DATA_PACKET, + GET_BLOCK_BODIES_PACKET, + GET_BLOCK_HEADERS_PACKET, + GET_NODE_DATA_PACKET, + GET_RECEIPTS_PACKET, + GET_SNAPSHOT_DATA_PACKET, + GET_SNAPSHOT_MANIFEST_PACKET, + MAX_BODIES_TO_SEND, + MAX_HEADERS_TO_SEND, + MAX_NODE_DATA_TO_SEND, + MAX_RECEIPTS_HEADERS_TO_SEND, + MAX_RECEIPTS_TO_SEND, + NODE_DATA_PACKET, + RECEIPTS_PACKET, + SNAPSHOT_DATA_PACKET, + SNAPSHOT_MANIFEST_PACKET, +}; + +/// The Chain Sync Supplier: answers requests from peers with available data +pub struct SyncSupplier; + +impl SyncSupplier { + /// Dispatch incoming requests and responses + pub fn dispatch_packet(sync: &RwLock, io: &mut SyncIo, peer: PeerId, packet_id: u8, data: &[u8]) { + let rlp = Rlp::new(data); + let result = match packet_id { + GET_BLOCK_BODIES_PACKET => SyncSupplier::return_rlp(io, &rlp, peer, + SyncSupplier::return_block_bodies, + |e| format!("Error sending block bodies: {:?}", e)), + + GET_BLOCK_HEADERS_PACKET => SyncSupplier::return_rlp(io, &rlp, peer, + SyncSupplier::return_block_headers, + |e| format!("Error sending block headers: {:?}", e)), + + GET_RECEIPTS_PACKET => SyncSupplier::return_rlp(io, &rlp, peer, + SyncSupplier::return_receipts, + |e| format!("Error sending receipts: {:?}", e)), + + GET_NODE_DATA_PACKET => SyncSupplier::return_rlp(io, &rlp, peer, + SyncSupplier::return_node_data, + |e| format!("Error sending nodes: {:?}", e)), + + GET_SNAPSHOT_MANIFEST_PACKET => SyncSupplier::return_rlp(io, &rlp, peer, + SyncSupplier::return_snapshot_manifest, + |e| format!("Error sending snapshot manifest: {:?}", e)), + + GET_SNAPSHOT_DATA_PACKET => SyncSupplier::return_rlp(io, &rlp, peer, + SyncSupplier::return_snapshot_data, + |e| format!("Error sending snapshot data: {:?}", e)), + CONSENSUS_DATA_PACKET => ChainSync::on_consensus_packet(io, peer, &rlp), + _ => { + sync.write().on_packet(io, peer, packet_id, data); + Ok(()) + } + }; + result.unwrap_or_else(|e| { + debug!(target:"sync", "{} -> Malformed packet {} : {}", peer, packet_id, e); + }) + } + + /// Respond to GetBlockHeaders request + fn return_block_headers(io: &SyncIo, r: &Rlp, peer_id: PeerId) -> RlpResponseResult { + // Packet layout: + // [ block: { P , B_32 }, maxHeaders: P, skip: P, reverse: P in { 0 , 1 } ] + let max_headers: usize = r.val_at(1)?; + let skip: usize = r.val_at(2)?; + let reverse: bool = r.val_at(3)?; + let last = io.chain().chain_info().best_block_number; + let number = if r.at(0)?.size() == 32 { + // id is a hash + let hash: H256 = r.val_at(0)?; + trace!(target: "sync", "{} -> GetBlockHeaders (hash: {}, max: {}, skip: {}, reverse:{})", peer_id, hash, max_headers, skip, reverse); + match io.chain().block_header(BlockId::Hash(hash)) { + Some(hdr) => { + let number = hdr.number().into(); + debug_assert_eq!(hdr.hash(), hash); + + if max_headers == 1 || io.chain().block_hash(BlockId::Number(number)) != Some(hash) { + // Non canonical header or single header requested + // TODO: handle single-step reverse hashchains of non-canon hashes + trace!(target:"sync", "Returning single header: {:?}", hash); + let mut rlp = RlpStream::new_list(1); + rlp.append_raw(&hdr.into_inner(), 1); + return Ok(Some((BLOCK_HEADERS_PACKET, rlp))); + } + number + } + None => return Ok(Some((BLOCK_HEADERS_PACKET, RlpStream::new_list(0)))) //no such header, return nothing + } + } else { + trace!(target: "sync", "{} -> GetBlockHeaders (number: {}, max: {}, skip: {}, reverse:{})", peer_id, r.val_at::(0)?, max_headers, skip, reverse); + r.val_at(0)? + }; + + let mut number = if reverse { + cmp::min(last, number) + } else { + cmp::max(0, number) + }; + 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; + let overlay = io.chain_overlay().read(); + + while number <= last && count < max_count { + if let Some(hdr) = overlay.get(&number) { + trace!(target: "sync", "{}: Returning cached fork header", peer_id); + data.extend_from_slice(hdr); + count += 1; + } else if let Some(hdr) = io.chain().block_header(BlockId::Number(number)) { + data.append(&mut hdr.into_inner()); + count += 1; + } else { + // No required block. + break; + } + if reverse { + if number <= inc || number == 0 { + break; + } + number -= inc; + } + else { + number += inc; + } + } + let mut rlp = RlpStream::new_list(count as usize); + rlp.append_raw(&data, count as usize); + trace!(target: "sync", "{} -> GetBlockHeaders: returned {} entries", peer_id, count); + Ok(Some((BLOCK_HEADERS_PACKET, rlp))) + } + + /// Respond to GetBlockBodies request + fn return_block_bodies(io: &SyncIo, r: &Rlp, peer_id: PeerId) -> RlpResponseResult { + let mut count = r.item_count().unwrap_or(0); + if count == 0 { + debug!(target: "sync", "Empty GetBlockBodies request, ignoring."); + return Ok(None); + } + count = cmp::min(count, MAX_BODIES_TO_SEND); + let mut added = 0usize; + let mut data = Bytes::new(); + for i in 0..count { + if let Some(body) = io.chain().block_body(BlockId::Hash(r.val_at::(i)?)) { + data.append(&mut body.into_inner()); + added += 1; + } + } + let mut rlp = RlpStream::new_list(added); + rlp.append_raw(&data, added); + trace!(target: "sync", "{} -> GetBlockBodies: returned {} entries", peer_id, added); + Ok(Some((BLOCK_BODIES_PACKET, rlp))) + } + + /// Respond to GetNodeData request + fn return_node_data(io: &SyncIo, r: &Rlp, peer_id: PeerId) -> RlpResponseResult { + let mut count = r.item_count().unwrap_or(0); + trace!(target: "sync", "{} -> GetNodeData: {} entries", peer_id, count); + if count == 0 { + debug!(target: "sync", "Empty GetNodeData request, ignoring."); + return Ok(None); + } + count = cmp::min(count, MAX_NODE_DATA_TO_SEND); + let mut added = 0usize; + let mut data = Vec::new(); + for i in 0..count { + if let Some(node) = io.chain().state_data(&r.val_at::(i)?) { + data.push(node); + added += 1; + } + } + trace!(target: "sync", "{} -> GetNodeData: return {} entries", peer_id, added); + let mut rlp = RlpStream::new_list(added); + for d in data { + rlp.append(&d); + } + Ok(Some((NODE_DATA_PACKET, rlp))) + } + + fn return_receipts(io: &SyncIo, rlp: &Rlp, peer_id: PeerId) -> RlpResponseResult { + let mut count = rlp.item_count().unwrap_or(0); + trace!(target: "sync", "{} -> GetReceipts: {} entries", peer_id, count); + if count == 0 { + debug!(target: "sync", "Empty GetReceipts request, ignoring."); + return Ok(None); + } + count = cmp::min(count, MAX_RECEIPTS_HEADERS_TO_SEND); + let mut added_headers = 0usize; + let mut added_receipts = 0usize; + let mut data = Bytes::new(); + for i in 0..count { + if let Some(mut receipts_bytes) = io.chain().block_receipts(&rlp.val_at::(i)?) { + data.append(&mut receipts_bytes); + added_receipts += receipts_bytes.len(); + added_headers += 1; + if added_receipts > MAX_RECEIPTS_TO_SEND { break; } + } + } + let mut rlp_result = RlpStream::new_list(added_headers); + rlp_result.append_raw(&data, added_headers); + Ok(Some((RECEIPTS_PACKET, rlp_result))) + } + + /// Respond to GetSnapshotManifest request + fn return_snapshot_manifest(io: &SyncIo, r: &Rlp, peer_id: PeerId) -> RlpResponseResult { + let count = r.item_count().unwrap_or(0); + trace!(target: "sync", "{} -> GetSnapshotManifest", peer_id); + if count != 0 { + debug!(target: "sync", "Invalid GetSnapshotManifest request, ignoring."); + return Ok(None); + } + let rlp = match io.snapshot_service().manifest() { + Some(manifest) => { + trace!(target: "sync", "{} <- SnapshotManifest", peer_id); + let mut rlp = RlpStream::new_list(1); + rlp.append_raw(&manifest.into_rlp(), 1); + rlp + }, + None => { + trace!(target: "sync", "{}: No manifest to return", peer_id); + RlpStream::new_list(0) + } + }; + Ok(Some((SNAPSHOT_MANIFEST_PACKET, rlp))) + } + + /// Respond to GetSnapshotData request + fn return_snapshot_data(io: &SyncIo, r: &Rlp, peer_id: PeerId) -> RlpResponseResult { + let hash: H256 = r.val_at(0)?; + trace!(target: "sync", "{} -> GetSnapshotData {:?}", peer_id, hash); + let rlp = match io.snapshot_service().chunk(hash) { + Some(data) => { + let mut rlp = RlpStream::new_list(1); + trace!(target: "sync", "{} <- SnapshotData", peer_id); + rlp.append(&data); + rlp + }, + None => { + RlpStream::new_list(0) + } + }; + Ok(Some((SNAPSHOT_DATA_PACKET, rlp))) + } + + fn return_rlp(io: &mut SyncIo, rlp: &Rlp, peer: PeerId, rlp_func: FRlp, error_func: FError) -> Result<(), PacketDecodeError> + where FRlp : Fn(&SyncIo, &Rlp, PeerId) -> RlpResponseResult, + FError : FnOnce(network::Error) -> String + { + let response = rlp_func(io, rlp, peer); + match response { + Err(e) => Err(e), + Ok(Some((packet_id, rlp_stream))) => { + io.respond(packet_id, rlp_stream.out()).unwrap_or_else( + |e| debug!(target: "sync", "{:?}", error_func(e))); + Ok(()) + } + _ => Ok(()) + } + } +} + +#[cfg(test)] +mod test { + use std::collections::{VecDeque}; + use tests::helpers::{TestIo}; + use tests::snapshot::TestSnapshotService; + use ethereum_types::{H256}; + use parking_lot::RwLock; + use bytes::Bytes; + use rlp::{Rlp, RlpStream}; + use super::{*, super::tests::*}; + use ethcore::client::{BlockChainClient, EachBlockWith, TestBlockChainClient}; + + #[test] + fn return_block_headers() { + use ethcore::views::HeaderView; + fn make_hash_req(h: &H256, count: usize, skip: usize, reverse: bool) -> Bytes { + let mut rlp = RlpStream::new_list(4); + rlp.append(h); + rlp.append(&count); + rlp.append(&skip); + rlp.append(&if reverse {1u32} else {0u32}); + rlp.out() + } + + fn make_num_req(n: usize, count: usize, skip: usize, reverse: bool) -> Bytes { + let mut rlp = RlpStream::new_list(4); + rlp.append(&n); + rlp.append(&count); + rlp.append(&skip); + rlp.append(&if reverse {1u32} else {0u32}); + rlp.out() + } + fn to_header_vec(rlp: ::chain::RlpResponseResult) -> Vec { + Rlp::new(&rlp.unwrap().unwrap().1.out()).iter().map(|r| r.as_raw().to_vec()).collect() + } + + let mut client = TestBlockChainClient::new(); + client.add_blocks(100, EachBlockWith::Nothing); + let blocks: Vec<_> = (0 .. 100) + .map(|i| (&client as &BlockChainClient).block(BlockId::Number(i as BlockNumber)).map(|b| b.into_inner()).unwrap()).collect(); + let headers: Vec<_> = blocks.iter().map(|b| Rlp::new(b).at(0).unwrap().as_raw().to_vec()).collect(); + let hashes: Vec<_> = headers.iter().map(|h| view!(HeaderView, h).hash()).collect(); + + let queue = RwLock::new(VecDeque::new()); + let ss = TestSnapshotService::new(); + let io = TestIo::new(&mut client, &ss, &queue, None); + + let unknown: H256 = H256::new(); + let result = SyncSupplier::return_block_headers(&io, &Rlp::new(&make_hash_req(&unknown, 1, 0, false)), 0); + assert!(to_header_vec(result).is_empty()); + let result = SyncSupplier::return_block_headers(&io, &Rlp::new(&make_hash_req(&unknown, 1, 0, true)), 0); + assert!(to_header_vec(result).is_empty()); + + let result = SyncSupplier::return_block_headers(&io, &Rlp::new(&make_hash_req(&hashes[2], 1, 0, true)), 0); + assert_eq!(to_header_vec(result), vec![headers[2].clone()]); + + let result = SyncSupplier::return_block_headers(&io, &Rlp::new(&make_hash_req(&hashes[2], 1, 0, false)), 0); + assert_eq!(to_header_vec(result), vec![headers[2].clone()]); + + let result = SyncSupplier::return_block_headers(&io, &Rlp::new(&make_hash_req(&hashes[50], 3, 5, false)), 0); + assert_eq!(to_header_vec(result), vec![headers[50].clone(), headers[56].clone(), headers[62].clone()]); + + let result = SyncSupplier::return_block_headers(&io, &Rlp::new(&make_hash_req(&hashes[50], 3, 5, true)), 0); + assert_eq!(to_header_vec(result), vec![headers[50].clone(), headers[44].clone(), headers[38].clone()]); + + let result = SyncSupplier::return_block_headers(&io, &Rlp::new(&make_num_req(2, 1, 0, true)), 0); + assert_eq!(to_header_vec(result), vec![headers[2].clone()]); + + let result = SyncSupplier::return_block_headers(&io, &Rlp::new(&make_num_req(2, 1, 0, false)), 0); + assert_eq!(to_header_vec(result), vec![headers[2].clone()]); + + let result = SyncSupplier::return_block_headers(&io, &Rlp::new(&make_num_req(50, 3, 5, false)), 0); + assert_eq!(to_header_vec(result), vec![headers[50].clone(), headers[56].clone(), headers[62].clone()]); + + let result = SyncSupplier::return_block_headers(&io, &Rlp::new(&make_num_req(50, 3, 5, true)), 0); + assert_eq!(to_header_vec(result), vec![headers[50].clone(), headers[44].clone(), headers[38].clone()]); + } + + #[test] + fn return_nodes() { + let mut client = TestBlockChainClient::new(); + let queue = RwLock::new(VecDeque::new()); + let sync = dummy_sync_with_peer(H256::new(), &client); + let ss = TestSnapshotService::new(); + let mut io = TestIo::new(&mut client, &ss, &queue, None); + + let mut node_list = RlpStream::new_list(3); + node_list.append(&H256::from("0000000000000000000000000000000000000000000000005555555555555555")); + node_list.append(&H256::from("ffffffffffffffffffffffffffffffffffffffffffffaaaaaaaaaaaaaaaaaaaa")); + node_list.append(&H256::from("aff0000000000000000000000000000000000000000000000000000000000000")); + + let node_request = node_list.out(); + // it returns rlp ONLY for hashes started with "f" + let result = SyncSupplier::return_node_data(&io, &Rlp::new(&node_request.clone()), 0); + + assert!(result.is_ok()); + let rlp_result = result.unwrap(); + assert!(rlp_result.is_some()); + + // the length of one rlp-encoded hashe + let rlp = rlp_result.unwrap().1.out(); + let rlp = Rlp::new(&rlp); + assert_eq!(Ok(1), rlp.item_count()); + + io.sender = Some(2usize); + + ChainSync::dispatch_packet(&RwLock::new(sync), &mut io, 0usize, GET_NODE_DATA_PACKET, &node_request); + assert_eq!(1, io.packets.len()); + } + + #[test] + fn return_receipts_empty() { + let mut client = TestBlockChainClient::new(); + let queue = RwLock::new(VecDeque::new()); + let ss = TestSnapshotService::new(); + let io = TestIo::new(&mut client, &ss, &queue, None); + + let result = SyncSupplier::return_receipts(&io, &Rlp::new(&[0xc0]), 0); + + assert!(result.is_ok()); + } + + #[test] + fn return_receipts() { + let mut client = TestBlockChainClient::new(); + let queue = RwLock::new(VecDeque::new()); + let sync = dummy_sync_with_peer(H256::new(), &client); + let ss = TestSnapshotService::new(); + let mut io = TestIo::new(&mut client, &ss, &queue, None); + + let mut receipt_list = RlpStream::new_list(4); + receipt_list.append(&H256::from("0000000000000000000000000000000000000000000000005555555555555555")); + receipt_list.append(&H256::from("ff00000000000000000000000000000000000000000000000000000000000000")); + receipt_list.append(&H256::from("fff0000000000000000000000000000000000000000000000000000000000000")); + receipt_list.append(&H256::from("aff0000000000000000000000000000000000000000000000000000000000000")); + + let receipts_request = receipt_list.out(); + // it returns rlp ONLY for hashes started with "f" + let result = SyncSupplier::return_receipts(&io, &Rlp::new(&receipts_request.clone()), 0); + + assert!(result.is_ok()); + let rlp_result = result.unwrap(); + assert!(rlp_result.is_some()); + + // the length of two rlp-encoded receipts + assert_eq!(603, rlp_result.unwrap().1.out().len()); + + io.sender = Some(2usize); + ChainSync::dispatch_packet(&RwLock::new(sync), &mut io, 0usize, GET_RECEIPTS_PACKET, &receipts_request); + assert_eq!(1, io.packets.len()); + } +} diff --git a/ethcore/sync/src/tests/snapshot.rs b/ethcore/sync/src/tests/snapshot.rs index 2f6441f4f2..804ebe9c53 100644 --- a/ethcore/sync/src/tests/snapshot.rs +++ b/ethcore/sync/src/tests/snapshot.rs @@ -22,7 +22,7 @@ use parking_lot::Mutex; use bytes::Bytes; use ethcore::snapshot::{SnapshotService, ManifestData, RestorationStatus}; use ethcore::header::BlockNumber; -use ethcore::client::{EachBlockWith}; +use ethcore::client::EachBlockWith; use super::helpers::*; use {SyncConfig, WarpSync}; @@ -99,7 +99,15 @@ impl SnapshotService for TestSnapshotService { } fn begin_restore(&self, manifest: ManifestData) { - *self.restoration_manifest.lock() = Some(manifest); + let mut restoration_manifest = self.restoration_manifest.lock(); + + if let Some(ref c_manifest) = *restoration_manifest { + if c_manifest.state_root == manifest.state_root { + return; + } + } + + *restoration_manifest = Some(manifest); self.state_restoration_chunks.lock().clear(); self.block_restoration_chunks.lock().clear(); } -- GitLab From 842b75c0e63f76e1b77d75529c7f6c3f4969d8d7 Mon Sep 17 00:00:00 2001 From: David Date: Wed, 9 May 2018 12:05:56 +0200 Subject: [PATCH 019/152] Decoding headers can fail (#8570) * rlp::decode returns Result * Fix journaldb to handle rlp::decode Result * Fix ethcore to work with rlp::decode returning Result * Light client handles rlp::decode returning Result * Fix tests in rlp_derive * Fix tests * Cleanup * cleanup * Allow panic rather than breaking out of iterator * Let decoding failures when reading from disk blow up * syntax * Fix the trivial grumbles * Fix failing tests * Make Account::from_rlp return Result * Syntx, sigh * Temp-fix for decoding failures * Header::decode returns Result Handle new return type throughout the code base. * Do not continue reading from the DB when a value could not be read * Fix tests * Handle header decoding in light_sync * Handling header decoding errors * Let the DecodeError bubble up unchanged * Remove redundant error conversion --- ethcore/light/src/client/header_chain.rs | 10 ++++--- ethcore/light/src/client/mod.rs | 12 ++++++-- ethcore/src/client/client.rs | 14 ++++++---- ethcore/src/client/test_client.rs | 5 ++-- ethcore/src/encoded.rs | 6 ++-- ethcore/src/engines/authority_round/mod.rs | 2 +- ethcore/src/error.rs | 10 +++++-- ethcore/src/miner/miner.rs | 11 ++++++-- ethcore/src/snapshot/mod.rs | 2 +- ethcore/src/verification/verification.rs | 5 ++-- ethcore/sync/src/light_sync/response.rs | 32 ++++++++++++---------- ethcore/sync/src/light_sync/tests/mod.rs | 2 +- rpc/src/v1/helpers/errors.rs | 13 +++++++++ rpc/src/v1/impls/eth.rs | 13 +++++---- rpc/src/v1/impls/light/eth.rs | 2 +- rpc/src/v1/impls/light/parity.rs | 2 +- rpc/src/v1/impls/parity.rs | 4 +-- rpc/src/v1/impls/traces.rs | 6 ++-- 18 files changed, 98 insertions(+), 53 deletions(-) diff --git a/ethcore/light/src/client/header_chain.rs b/ethcore/light/src/client/header_chain.rs index 02a18a60df..b85091e53b 100644 --- a/ethcore/light/src/client/header_chain.rs +++ b/ethcore/light/src/client/header_chain.rs @@ -305,7 +305,7 @@ impl HeaderChain { batch.put(col, cht_key(cht_num as u64).as_bytes(), &::rlp::encode(cht_root)); } - let decoded_header = hardcoded_sync.header.decode(); + let decoded_header = hardcoded_sync.header.decode()?; let decoded_header_num = decoded_header.number(); // write the block in the DB. @@ -585,7 +585,7 @@ impl HeaderChain { bail!(ErrorKind::Database(msg.into())); }; - let decoded = header.decode(); + let decoded = header.decode().expect("decoding db value failed"); let entry: Entry = { let bytes = self.db.get(self.col, era_key(h_num).as_bytes())? @@ -815,7 +815,9 @@ impl HeaderChain { for hdr in self.ancestry_iter(BlockId::Hash(parent_hash)) { if let Some(transition) = live_proofs.get(&hdr.hash()).cloned() { - return Some((hdr.decode(), transition.proof)) + return hdr.decode().map(|decoded_hdr| { + (decoded_hdr, transition.proof) + }).ok(); } } @@ -1224,7 +1226,7 @@ mod tests { let hardcoded_sync = chain.read_hardcoded_sync().expect("failed reading hardcoded sync").expect("failed unwrapping hardcoded sync"); assert_eq!(hardcoded_sync.chts.len(), 3); assert_eq!(hardcoded_sync.total_difficulty, total_difficulty); - let decoded: Header = hardcoded_sync.header.decode(); + let decoded: Header = hardcoded_sync.header.decode().expect("decoding failed"); assert_eq!(decoded.number(), h_num); } } diff --git a/ethcore/light/src/client/mod.rs b/ethcore/light/src/client/mod.rs index cf603d853f..82b424cc83 100644 --- a/ethcore/light/src/client/mod.rs +++ b/ethcore/light/src/client/mod.rs @@ -318,7 +318,7 @@ impl Client { let epoch_proof = self.engine.is_epoch_end( &verified_header, - &|h| self.chain.block_header(BlockId::Hash(h)).map(|hdr| hdr.decode()), + &|h| self.chain.block_header(BlockId::Hash(h)).and_then(|hdr| hdr.decode().ok()), &|h| self.chain.pending_transition(h), ); @@ -426,7 +426,15 @@ impl Client { }; // Verify Block Family - let verify_family_result = self.engine.verify_block_family(&verified_header, &parent_header.decode()); + + let verify_family_result = { + parent_header.decode() + .map_err(|dec_err| dec_err.into()) + .and_then(|decoded| { + self.engine.verify_block_family(&verified_header, &decoded) + }) + + }; if let Err(e) = verify_family_result { warn!(target: "client", "Stage 3 block verification failed for #{} ({})\nError: {:?}", verified_header.number(), verified_header.hash(), e); diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index bffa4e38ba..76d78e3df6 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -1219,8 +1219,7 @@ impl Client { => Some(self.chain.read().best_block_header()), BlockId::Number(number) if number == self.chain.read().best_block_number() => Some(self.chain.read().best_block_header()), - _ - => self.block_header(id).map(|h| h.decode()), + _ => self.block_header(id).and_then(|h| h.decode().ok()) } } } @@ -1915,7 +1914,11 @@ impl BlockChainClient for Client { fn uncle_extra_info(&self, id: UncleId) -> Option> { self.uncle(id) - .map(|header| self.engine.extra_info(&header.decode())) + .and_then(|h| { + h.decode().map(|dh| { + self.engine.extra_info(&dh) + }).ok() + }) } fn pruning_info(&self) -> PruningInfo { @@ -2033,7 +2036,8 @@ impl ReopenBlock for Client { for h in uncles { if !block.uncles().iter().any(|header| header.hash() == h) { let uncle = chain.block_header_data(&h).expect("find_uncle_hashes only returns hashes for existing headers; qed"); - block.push_uncle(uncle.decode()).expect("pushing up to maximum_uncle_count; + let uncle = uncle.decode().expect("decoding failure"); + block.push_uncle(uncle).expect("pushing up to maximum_uncle_count; push_uncle is not ok only if more than maximum_uncle_count is pushed; so all push_uncle are Ok; qed"); @@ -2074,7 +2078,7 @@ impl PrepareOpenBlock for Client { .into_iter() .take(engine.maximum_uncle_count(open_block.header().number())) .foreach(|h| { - open_block.push_uncle(h.decode()).expect("pushing maximum_uncle_count; + open_block.push_uncle(h.decode().expect("decoding failure")).expect("pushing maximum_uncle_count; open_block was just created; push_uncle is not ok only if more than maximum_uncle_count is pushed; so all push_uncle are Ok; diff --git a/ethcore/src/client/test_client.rs b/ethcore/src/client/test_client.rs index b229159667..6a3166f7c0 100644 --- a/ethcore/src/client/test_client.rs +++ b/ethcore/src/client/test_client.rs @@ -289,7 +289,7 @@ impl TestBlockChainClient { /// Make a bad block by setting invalid extra data. pub fn corrupt_block(&self, n: BlockNumber) { let hash = self.block_hash(BlockId::Number(n)).unwrap(); - let mut header: BlockHeader = self.block_header(BlockId::Number(n)).unwrap().decode(); + let mut header: BlockHeader = self.block_header(BlockId::Number(n)).unwrap().decode().expect("decoding failed"); header.set_extra_data(b"This extra data is way too long to be considered valid".to_vec()); let mut rlp = RlpStream::new_list(3); rlp.append(&header); @@ -301,7 +301,7 @@ impl TestBlockChainClient { /// Make a bad block by setting invalid parent hash. pub fn corrupt_block_parent(&self, n: BlockNumber) { let hash = self.block_hash(BlockId::Number(n)).unwrap(); - let mut header: BlockHeader = self.block_header(BlockId::Number(n)).unwrap().decode(); + let mut header: BlockHeader = self.block_header(BlockId::Number(n)).unwrap().decode().expect("decoding failed"); header.set_parent_hash(H256::from(42)); let mut rlp = RlpStream::new_list(3); rlp.append(&header); @@ -479,6 +479,7 @@ impl BlockInfo for TestBlockChainClient { self.block_header(BlockId::Hash(self.chain_info().best_block_hash)) .expect("Best block always has header.") .decode() + .expect("decoding failed") } fn block(&self, id: BlockId) -> Option { diff --git a/ethcore/src/encoded.rs b/ethcore/src/encoded.rs index 01df386cc2..c436607f8c 100644 --- a/ethcore/src/encoded.rs +++ b/ethcore/src/encoded.rs @@ -28,7 +28,7 @@ use ethereum_types::{H256, Bloom, U256, Address}; use hash::keccak; use header::{BlockNumber, Header as FullHeader}; use heapsize::HeapSizeOf; -use rlp::{Rlp, RlpStream}; +use rlp::{self, Rlp, RlpStream}; use transaction::UnverifiedTransaction; use views::{self, BlockView, HeaderView, BodyView}; @@ -47,7 +47,9 @@ impl Header { pub fn new(encoded: Vec) -> Self { Header(encoded) } /// Upgrade this encoded view to a fully owned `Header` object. - pub fn decode(&self) -> FullHeader { ::rlp::decode(&self.0).expect("decoding failure") } + pub fn decode(&self) -> Result { + rlp::decode(&self.0) + } /// Get a borrowed header view onto the data. #[inline] diff --git a/ethcore/src/engines/authority_round/mod.rs b/ethcore/src/engines/authority_round/mod.rs index c2aee7c6ef..ed9a9a4f25 100644 --- a/ethcore/src/engines/authority_round/mod.rs +++ b/ethcore/src/engines/authority_round/mod.rs @@ -996,7 +996,7 @@ impl Engine for AuthorityRound { let parent = client.block_header(::client::BlockId::Hash(*block.header().parent_hash())) .expect("hash is from parent; parent header must exist; qed") - .decode(); + .decode()?; let parent_step = header_step(&parent, self.empty_steps_transition)?; let current_step = self.step.load(); diff --git a/ethcore/src/error.rs b/ethcore/src/error.rs index 561701e762..bec749297c 100644 --- a/ethcore/src/error.rs +++ b/ethcore/src/error.rs @@ -290,6 +290,12 @@ error_chain! { description("Unknown engine name") display("Unknown engine name ({})", name) } + + #[doc = "RLP decoding errors"] + Decoder(err: ::rlp::DecoderError) { + description("decoding value failed") + display("decoding value failed with error: {}", err) + } } } @@ -310,11 +316,11 @@ impl From for Error { fn from(err: AccountsError) -> Error { ErrorKind::AccountProvider(err).into() } -} +} impl From<::rlp::DecoderError> for Error { fn from(err: ::rlp::DecoderError) -> Error { - UtilError::from(err).into() + ErrorKind::Decoder(err).into() } } diff --git a/ethcore/src/miner/miner.rs b/ethcore/src/miner/miner.rs index 76a011343f..3168ff1a84 100644 --- a/ethcore/src/miner/miner.rs +++ b/ethcore/src/miner/miner.rs @@ -528,8 +528,8 @@ impl Miner { } /// Attempts to perform internal sealing (one that does not require work) and handles the result depending on the type of Seal. - fn seal_and_import_block_internally(&self, chain: &C, block: ClosedBlock) -> bool where - C: BlockChain + SealedBlockImporter, + fn seal_and_import_block_internally(&self, chain: &C, block: ClosedBlock) -> bool + where C: BlockChain + SealedBlockImporter, { { let sealing = self.sealing.lock(); @@ -544,7 +544,12 @@ impl Miner { trace!(target: "miner", "seal_block_internally: attempting internal seal."); let parent_header = match chain.block_header(BlockId::Hash(*block.header().parent_hash())) { - Some(hdr) => hdr.decode(), + Some(h) => { + match h.decode() { + Ok(decoded_hdr) => decoded_hdr, + Err(_) => return false + } + } None => return false, }; diff --git a/ethcore/src/snapshot/mod.rs b/ethcore/src/snapshot/mod.rs index 94236e9e95..8871ced26f 100644 --- a/ethcore/src/snapshot/mod.rs +++ b/ethcore/src/snapshot/mod.rs @@ -487,7 +487,7 @@ pub fn verify_old_block(rng: &mut OsRng, header: &Header, engine: &EthEngine, ch if always || rng.gen::() <= POW_VERIFY_RATE { engine.verify_block_unordered(header)?; match chain.block_header_data(header.parent_hash()) { - Some(parent) => engine.verify_block_family(header, &parent.decode()), + Some(parent) => engine.verify_block_family(header, &parent.decode()?), None => Ok(()), } } else { diff --git a/ethcore/src/verification/verification.rs b/ethcore/src/verification/verification.rs index 92f3e77f90..03a6d6f8d4 100644 --- a/ethcore/src/verification/verification.rs +++ b/ethcore/src/verification/verification.rs @@ -224,7 +224,7 @@ fn verify_uncles(header: &Header, bytes: &[u8], bc: &BlockProvider, engine: &Eth return Err(From::from(BlockError::UncleParentNotInChain(uncle_parent.hash()))); } - let uncle_parent = uncle_parent.decode(); + let uncle_parent = uncle_parent.decode()?; verify_parent(&uncle, &uncle_parent, engine)?; engine.verify_block_family(&uncle, &uncle_parent)?; verified.insert(uncle.hash()); @@ -500,10 +500,9 @@ mod tests { // no existing tests need access to test, so having this not function // is fine. let client = ::client::TestBlockChainClient::default(); - let parent = bc.block_header_data(header.parent_hash()) .ok_or(BlockError::UnknownParent(header.parent_hash().clone()))? - .decode(); + .decode()?; let full_params = FullFamilyParams { block_bytes: bytes, diff --git a/ethcore/sync/src/light_sync/response.rs b/ethcore/sync/src/light_sync/response.rs index 4dfb383d46..74665118b7 100644 --- a/ethcore/sync/src/light_sync/response.rs +++ b/ethcore/sync/src/light_sync/response.rs @@ -16,13 +16,11 @@ //! Helpers for decoding and verifying responses for headers. -use std::fmt; - -use ethcore::encoded; -use ethcore::header::Header; +use ethcore::{self, encoded, header::Header}; +use ethereum_types::H256; use light::request::{HashOrNumber, CompleteHeadersRequest as HeadersRequest}; use rlp::DecoderError; -use ethereum_types::H256; +use std::fmt; /// Errors found when decoding headers and verifying with basic constraints. #[derive(Debug, PartialEq)] @@ -74,19 +72,23 @@ pub trait Constraint { /// Do basic verification of provided headers against a request. pub fn verify(headers: &[encoded::Header], request: &HeadersRequest) -> Result, BasicError> { - let headers: Vec<_> = headers.iter().map(|h| h.decode()).collect(); + let headers: Result, _> = headers.iter().map(|h| h.decode() ).collect(); + match headers { + Ok(headers) => { + let reverse = request.reverse; + + Max(request.max as usize).verify(&headers, reverse)?; + match request.start { + HashOrNumber::Number(ref num) => StartsAtNumber(*num).verify(&headers, reverse)?, + HashOrNumber::Hash(ref hash) => StartsAtHash(*hash).verify(&headers, reverse)?, + } - let reverse = request.reverse; + SkipsBetween(request.skip).verify(&headers, reverse)?; - Max(request.max as usize).verify(&headers, reverse)?; - match request.start { - HashOrNumber::Number(ref num) => StartsAtNumber(*num).verify(&headers, reverse)?, - HashOrNumber::Hash(ref hash) => StartsAtHash(*hash).verify(&headers, reverse)?, + Ok(headers) + }, + Err(e) => Err(e.into()) } - - SkipsBetween(request.skip).verify(&headers, reverse)?; - - Ok(headers) } struct StartsAtNumber(u64); diff --git a/ethcore/sync/src/light_sync/tests/mod.rs b/ethcore/sync/src/light_sync/tests/mod.rs index 9fd270838b..3fee1c7170 100644 --- a/ethcore/sync/src/light_sync/tests/mod.rs +++ b/ethcore/sync/src/light_sync/tests/mod.rs @@ -45,7 +45,7 @@ fn fork_post_cht() { for id in (0..CHAIN_LENGTH).map(|x| x + 1).map(BlockId::Number) { let (light_peer, full_peer) = (net.peer(0), net.peer(1)); let light_chain = light_peer.light_chain(); - let header = full_peer.chain().block_header(id).unwrap().decode(); + let header = full_peer.chain().block_header(id).unwrap().decode().expect("decoding failure"); let _ = light_chain.import_header(header); light_chain.flush_queue(); light_chain.import_verified(); diff --git a/rpc/src/v1/helpers/errors.rs b/rpc/src/v1/helpers/errors.rs index 4f3289a116..c85beef7d5 100644 --- a/rpc/src/v1/helpers/errors.rs +++ b/rpc/src/v1/helpers/errors.rs @@ -360,6 +360,19 @@ pub fn transaction>(error: T) -> Error { } } +pub fn decode>(error: T) -> Error { + let error = error.into(); + match *error.kind() { + ErrorKind::Decoder(ref dec_err) => rlp(dec_err.clone()), + _ => Error { + code: ErrorCode::InternalError, + message: "decoding error".into(), + data: None, + } + + } +} + pub fn rlp(error: DecoderError) -> Error { Error { code: ErrorCode::InvalidParams, diff --git a/rpc/src/v1/impls/eth.rs b/rpc/src/v1/impls/eth.rs index a7ff4916de..389805c176 100644 --- a/rpc/src/v1/impls/eth.rs +++ b/rpc/src/v1/impls/eth.rs @@ -343,7 +343,10 @@ impl EthClient hdr.decode(), + Some(hdr) => match hdr.decode() { + Ok(h) => h, + Err(e) => return Err(errors::decode(e)) + }, None => { return Ok(None); } }; @@ -851,9 +854,9 @@ impl Eth for EthClient< }; let state = try_bf!(self.client.state_at(id).ok_or(errors::state_pruned())); - let header = try_bf!(self.client.block_header(id).ok_or(errors::state_pruned())); + let header = try_bf!(self.client.block_header(id).ok_or(errors::state_pruned()).and_then(|h| h.decode().map_err(errors::decode))); - (state, header.decode()) + (state, header) }; let result = self.client.call(&signed, Default::default(), &mut state, &header); @@ -890,9 +893,9 @@ impl Eth for EthClient< }; let state = try_bf!(self.client.state_at(id).ok_or(errors::state_pruned())); - let header = try_bf!(self.client.block_header(id).ok_or(errors::state_pruned())); + let header = try_bf!(self.client.block_header(id).ok_or(errors::state_pruned()).and_then(|h| h.decode().map_err(errors::decode))); - (state, header.decode()) + (state, header) }; Box::new(future::done(self.client.estimate_gas(&signed, &state, &header) diff --git a/rpc/src/v1/impls/light/eth.rs b/rpc/src/v1/impls/light/eth.rs index eeef12da6e..35f7792b52 100644 --- a/rpc/src/v1/impls/light/eth.rs +++ b/rpc/src/v1/impls/light/eth.rs @@ -371,7 +371,7 @@ impl Eth for EthClient { } fn send_raw_transaction(&self, raw: Bytes) -> Result { - let best_header = self.client.best_block_header().decode(); + let best_header = self.client.best_block_header().decode().map_err(errors::decode)?; Rlp::new(&raw.into_vec()).as_val() .map_err(errors::rlp) diff --git a/rpc/src/v1/impls/light/parity.rs b/rpc/src/v1/impls/light/parity.rs index 3d31d9e676..982c7ff363 100644 --- a/rpc/src/v1/impls/light/parity.rs +++ b/rpc/src/v1/impls/light/parity.rs @@ -395,7 +395,7 @@ impl Parity for ParityClient { let engine = self.light_dispatch.client.engine().clone(); let from_encoded = move |encoded: encoded::Header| { - let header = encoded.decode(); + let header = encoded.decode().expect("decoding error"); // REVIEW: not sure what to do here; what is a decent return value for the error case here? let extra_info = engine.extra_info(&header); RichHeader { inner: Header { diff --git a/rpc/src/v1/impls/parity.rs b/rpc/src/v1/impls/parity.rs index db66bddc7e..08d5147202 100644 --- a/rpc/src/v1/impls/parity.rs +++ b/rpc/src/v1/impls/parity.rs @@ -487,9 +487,9 @@ impl Parity for ParityClient where }; let state = self.client.state_at(id).ok_or(errors::state_pruned())?; - let header = self.client.block_header(id).ok_or(errors::state_pruned())?; + let header = self.client.block_header(id).ok_or(errors::state_pruned())?.decode().map_err(errors::decode)?; - (state, header.decode()) + (state, header) }; self.client.call_many(&requests, &mut state, &header) diff --git a/rpc/src/v1/impls/traces.rs b/rpc/src/v1/impls/traces.rs index bf4dc83beb..0130b3b9c1 100644 --- a/rpc/src/v1/impls/traces.rs +++ b/rpc/src/v1/impls/traces.rs @@ -104,7 +104,7 @@ impl Traces for TracesClient where let mut state = self.client.state_at(id).ok_or(errors::state_pruned())?; let header = self.client.block_header(id).ok_or(errors::state_pruned())?; - self.client.call(&signed, to_call_analytics(flags), &mut state, &header.decode()) + self.client.call(&signed, to_call_analytics(flags), &mut state, &header.decode().map_err(errors::decode)?) .map(TraceResults::from) .map_err(errors::call) } @@ -131,7 +131,7 @@ impl Traces for TracesClient where let mut state = self.client.state_at(id).ok_or(errors::state_pruned())?; let header = self.client.block_header(id).ok_or(errors::state_pruned())?; - self.client.call_many(&requests, &mut state, &header.decode()) + self.client.call_many(&requests, &mut state, &header.decode().map_err(errors::decode)?) .map(|results| results.into_iter().map(TraceResults::from).collect()) .map_err(errors::call) } @@ -153,7 +153,7 @@ impl Traces for TracesClient where let mut state = self.client.state_at(id).ok_or(errors::state_pruned())?; let header = self.client.block_header(id).ok_or(errors::state_pruned())?; - self.client.call(&signed, to_call_analytics(flags), &mut state, &header.decode()) + self.client.call(&signed, to_call_analytics(flags), &mut state, &header.decode().map_err(errors::decode)?) .map(TraceResults::from) .map_err(errors::call) } -- GitLab From 25536c5ffb42136291a371efe0998c1b21354b47 Mon Sep 17 00:00:00 2001 From: Afri Schoedon <5chdn@users.noreply.github.com> Date: Wed, 9 May 2018 14:11:36 +0200 Subject: [PATCH 020/152] Update CHANGELOG for 1.9, 1.10, and 1.11 (#8556) * Move changelog for 1.10.x * Mark 1.9 EOL * Prepare changelog for 1.10.3 stable * Prepare changelog for 1.11.0 stable * Update changelogs * Update CHANGELOG for 1.10.3 beta * Update CHANGELOG for 1.11.0 beta * Update CHANGELOG for 1.11.0 beta * Update CHANGELOG for 1.11.0 beta * Format changelog --- CHANGELOG.md | 530 +++++++++++++++++++++-------------------- docs/CHANGELOG-1.10.md | 325 +++++++++++++++++++++++++ docs/CHANGELOG-1.9.md | 2 + 3 files changed, 594 insertions(+), 263 deletions(-) create mode 100644 docs/CHANGELOG-1.10.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 6272c32a7e..0c7dcf878b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,272 +1,276 @@ -## Parity [v1.10.2](https://github.com/paritytech/parity/releases/tag/v1.10.2) (2018-04-24) - -Parity 1.10.2 is a bug-fix release to improve performance and stability. - -The full list of included changes: - -- Update Parity beta to 1.10.2 + Backports ([#8455](https://github.com/paritytech/parity/pull/8455)) - - Update Parity beta to 1.10.2 - - Allow 32-bit pipelines to fail ([#8454](https://github.com/paritytech/parity/pull/8454)) - - Disable 32-bit targets for Gitlab - - Rename Linux pipelines - - Update wasmi ([#8452](https://github.com/paritytech/parity/pull/8452)) - - Fix Cargo.lock -- Backports ([#8450](https://github.com/paritytech/parity/pull/8450)) - - Use forked app_dirs crate for reverted Windows dir behavior ([#8438](https://github.com/paritytech/parity/pull/8438)) - - Remove unused app_dirs dependency in CLI - - Use forked app_dirs crate for reverted Windows dir behavior - - Remove Tendermint extra_info due to seal inconsistencies ([#8367](https://github.com/paritytech/parity/pull/8367)) - - Handle queue import errors a bit more gracefully ([#8385](https://github.com/paritytech/parity/pull/8385)) - - Improve VM executor stack size estimation rules ([#8439](https://github.com/paritytech/parity/pull/8439)) - - Improve VM executor stack size estimation rules - - Typo: docs add "(Debug build)" comment - - Fix an off by one typo and set minimal stack size - - Use saturating_sub to avoid potential overflow - -## Parity [v1.10.1](https://github.com/paritytech/parity/releases/tag/v1.10.1) (2018-04-17) - -Parity 1.10.1 is a bug-fix release to improve performance and stability. Among other changes, you can now use `--warp-barrier [BLOCK]` to specify a minimum block number to `--warp` to. This is useful in cases where clients restore to outdated snapshots far behind the latest chain head. - -The full list of included changes: - -- Bump beta to 1.10.1 ([#8350](https://github.com/paritytech/parity/pull/8350)) - - Bump beta to 1.10.1 - - Unflag critical release -- Backports ([#8346](https://github.com/paritytech/parity/pull/8346)) - - Warp-only sync with warp-barrier [blocknumber] flag. ([#8228](https://github.com/paritytech/parity/pull/8228)) - - Warp-only sync with warp-after [blocknumber] flag. - - Fix tests. - - Fix configuration tests. - - Rename to warp barrier. - - Allow unsafe js eval on Parity Wallet. ([#8204](https://github.com/paritytech/parity/pull/8204)) - - Update musicoin spec in line with gmc v2.6.2 ([#8242](https://github.com/paritytech/parity/pull/8242)) - - Supress TemporaryInvalid verification failures. ([#8256](https://github.com/paritytech/parity/pull/8256)) - - Include suicided accounts in state diff ([#8297](https://github.com/paritytech/parity/pull/8297)) - - Include suicided accounts in state diff - - Shorten form match -> if let - - Test suicide trace diff in State - - Replace_home for password_files, reserved_peers and log_file ([#8324](https://github.com/paritytech/parity/pull/8324)) - - Replace_home for password_files, reserved_peers and log_file - - Typo: arg_log_file is Option - - Enable UI by default, but only display info page. - - Fix test. - - Fix naming and remove old todo. - - Change "wallet" with "browser UI" -- Change name Wallet -> UI ([#8164](https://github.com/paritytech/parity/pull/8164)) ([#8205](https://github.com/paritytech/parity/pull/8205)) - - Change name Wallet -> UI - - Make warning bold -- Backport [#8099](https://github.com/paritytech/parity/pull/8099) ([#8132](https://github.com/paritytech/parity/pull/8132)) -- WASM libs ([#8220](https://github.com/paritytech/parity/pull/8220)) - - Bump wasm libs ([#8171](https://github.com/paritytech/parity/pull/8171)) - - Bump wasmi version ([#8209](https://github.com/paritytech/parity/pull/8209)) -- Update hyper to 0.11.24 ([#8203](https://github.com/paritytech/parity/pull/8203)) -- Updated jsonrpc to include latest backports (beta) ([#8181](https://github.com/paritytech/parity/pull/8181)) - - Updated jsonrpc to include latest backports - - Update dependencies. - -## Parity [v1.10.0](https://github.com/paritytech/parity/releases/tag/v1.10.0) (2018-03-22) - -This is the Parity 1.10.0-beta release! Cool! - -### Disabling the Parity Wallet - -The **Parity Wallet (a.k.a. "UI") is now disabled by default**. We are preparing to split the wallet from the core client. - -To reactivate the parity wallet, you have to run Parity either with `parity --force-ui` (not recommended) or `parity ui` (deprecated) from the command line. Or, if you feel super fancy and want to test our pre-releases of the stand-alone electron wallet, head over to the [Parity-JS repositories and check the releases](https://github.com/Parity-JS/shell/releases). - -Further reading: - -- [Docs: Parity Wallet](https://wiki.parity.io/Parity-Wallet) -- [Docs: How to customize Parity UI?](https://wiki.parity.io/FAQ-Customize-Parity-UI.html) -- [Github: Parity-JS](https://github.com/parity-js) - -### Introducing the Wasm VM - -We are excited to announce support for **Wasm Smart Contracts on Kovan network**. The hard-fork to activate the Wasm-VM will take place on block `6_600_000`. - -To enable Wasm contracts on your custom network, just schedule a `wasmActivationTransition` at your favorite block number (e.g., `42`, `666`, or `0xbada55`). To hack your first Wasm smart contracts in Rust, have a look at the [Parity Wasm Tutorials](https://github.com/paritytech/pwasm-tutorial). - -Further reading: - -- [Docs: WebAssembly (wasm)](https://wiki.parity.io/WebAssembly-Home) -- [Docs: Wasm VM Design](https://wiki.parity.io/WebAssembly-Design) -- [Docs: Wasm tutorials and examples](https://wiki.parity.io/WebAssembly-Links) - -### Empty step messages in PoA - -To **reduce blockchain bloat, proof-of-authority networks can now enable _empty step messages_ which replace empty blocks**. Each step message will be signed and broadcasted by the issuing authorities, and included and rewarded in the next non-empty block. - -To enable empty step messages, set the `emptyStepsTransition` to your favorite block number. You can also specify a maximum number of empty steps with `maximumEmptySteps` in your chain spec. - -### Other noteworthy changes - -We removed the old database migrations from 2016. In case you upgrade Parity from a really, really old version, you will have to reset your database manually first with `parity db kill`. - -We fixed DELEGATECALL `from` and `to` fields, see [#7166](https://github.com/paritytech/parity/issues/7166). - -We reduced the default USD per transaction value to 0.0001. Thanks, @MysticRyuujin! - -The Musicoin chain is now enabled with Byzantium features starting at block `2_222_222`. - -### Overview of all changes included +## Parity [v1.11.0](https://github.com/paritytech/parity/releases/tag/v1.10.0) (2018-05-09) + +This is the Parity 1.11.0-beta release! Hurray! + +Notable changes in reversed alphabetical order: + +- TOOLING: **Whisper CLI** [#8201](https://github.com/paritytech/parity/pull/8201) + - `whisper-cli` is a standalone tool to communicate with the Whisper protocol. + - It provides functionality to specify `whisper-pool-size`, `port` and `address` to use. + - All whisper RPC APIs are enabled and can be directly acessed. +I'm not used to writing these changelogs but I guess that would explain it +- JSON-RPC API: **Return error in case eth_call returns VM errors** [#8448](https://github.com/paritytech/parity/pull/8448) + - This changes the behaviors of `eth_call` to respect VM errors if any. + - In case of `REVERT`, it will also return the reverted return data in hex format. +- ENGINES: **Block reward contract** [#8419](https://github.com/paritytech/parity/pull/8419) + - The _AuRa_ PoA engine has now support for having a contract to calculate the block rewards. + - The engine passes a list of benefactors and reward types to the contract which then returns a list of addresses and respective rewards. +- CORE: **Private transactions integration pr** [#6422](https://github.com/paritytech/parity/pull/6422) + - Parity now provides a private transactions system. + - Please, check out our wiki to get and [overview and setup instructions](https://wiki.parity.io/Private-Transactions.html). +- CORE: **New Transaction Queue implementation** [#8074](https://github.com/paritytech/parity/pull/8074) + - Verification is now done in parallel. + - Previous queue had `O(1)` time to get pending set, but `O(n^2)` insertion time. And obviously insertion/removal happens much more often than retrieving the pending set (only for propagation and pending block building) Currently we have `O(n * log(senders))` pending set time (with cache) and `O(tx_per_sender)` (usually within `log(tx_per_sender)`) insertion time. + - `Scoring` and `Readiness` are separated from the pool, so it's easier to customize them or introduce different definitions (for instance for [EIP-859](https://github.com/ethereum/EIPs/issues/859) or private transactions, etc). + - Banning removed, soft-penalization introduced instead: if transaction exceeds the limit other transactions from that sender get lower priority. + - There is no explicit distinction between current and future transactions in the pool - `Readiness` determines that. Because of this we additionally remove `future` transactions that occupy the pool for long time. +- CONFIGURATION: **Warp-only sync with --warp-barrier [block-number] flag.** [#8228](https://github.com/paritytech/parity/pull/8228) + - Enables warp-only sync in case `--warp-barrier [block-number]` is provided. + - This avoids clients to warp to outdated snapshots that are too far away from the best block. + - This avoids clients to fall back to normal sync if there are no recent snapshots available currently. +- CONFIGURATION: **Disable UI by default.** [#8105](https://github.com/paritytech/parity/pull/8105) + - The user interface is now disabled by default. It still can be activated with the `--force-ui` flag. + - To get the stand-alone Parity UI, please check the dedicated [releases page](https://github.com/parity-js/shell/releases). +- CONFIGURATION: **Auto-updater improvements** [#8078](https://github.com/paritytech/parity/pull/8078) + - Added `--auto-update-delay` to randomly delay updates by `n` blocks. This takes into account the number of the block of the update release (old updates aren't delayed). + - Added `--auto-update-check-frequency` to define the periodicity of auto-update checks in number of blocks. + - This is an important improvement to ensure the network does not update all clients at the same time. +- CHAIN SPECS: **Enable WebAssembly and Byzantium for Ellaism** [#8520](https://github.com/paritytech/parity/pull/8520) + - This activates the Ellaism Byzantium hardfork ([2018-0004-byzantium](https://github.com/ellaism/specs/blob/master/specs/2018-0004-byzantium.md)) at block `2_000_000`. + - This enables the Wasm VM on Ellaism ([2018-0003-wasm-hardfork](https://github.com/ellaism/specs/blob/master/specs/2018-0003-wasm-hardfork.md)) at block `2_000_000`. + - Please, upgrade your clients if you run an Ellaism configuration. +- CHAIN SPECS: **Dev chain - increase gasLimit to 8_000_000** [#8362](https://github.com/paritytech/parity/pull/8362) + - This increases the default block gas limit on development chains to `8_000_000`. + - Please note, this makes previous dev chain configurations incompatible. +- CHAIN SPECS: **Add MCIP-6 Byzyantium transition to Musicoin spec** [#7841](https://github.com/paritytech/parity/pull/7841) + - This activates the Musicoin Byzantium hardfork ([MCIP-6](https://github.com/Musicoin/MCIPs/blob/master/MCIPS/mcip-6.md)) at block `2_222_222`. + - Please, upgrade your clients if you run a Musicoin configuration. The full list of included changes: -- Re-enable signer, even with no UI. ([#8167](https://github.com/paritytech/parity/pull/8167)) ([#8168](https://github.com/paritytech/parity/pull/8168)) - - Re-enable signer, even with no UI. - - Fix message. -- Beta Backports ([#8136](https://github.com/paritytech/parity/pull/8136)) - - Support parity protocol. ([#8035](https://github.com/paritytech/parity/pull/8035)) - - updater: apply exponential backoff after download failure ([#8059](https://github.com/paritytech/parity/pull/8059)) - - updater: apply exponential backoff after download failure - - updater: reset backoff on new release - - Max code size on Kovan ([#8067](https://github.com/paritytech/parity/pull/8067)) - - Enable code size limit on kovan - - Fix formatting. - - Limit incoming connections. ([#8060](https://github.com/paritytech/parity/pull/8060)) - - Limit ingress connections - - Optimized handshakes logging - - WASM libraries bump ([#7970](https://github.com/paritytech/parity/pull/7970)) - - update wasmi, parity-wasm, wasm-utils to latest version - - Update to new wasmi & error handling - - also utilize new stack limiter - - fix typo - - replace dependency url - - Cargo.lock update - - add some dos protection ([#8084](https://github.com/paritytech/parity/pull/8084)) - - revert removing blooms ([#8066](https://github.com/paritytech/parity/pull/8066)) - - Revert "fix traces, removed bloomchain crate, closes [#7228](https://github.com/paritytech/parity/issues/7228), closes [#7167](https://github.com/paritytech/parity/issues/7167)" - - Revert "fixed broken logs ([#7934](https://github.com/paritytech/parity/pull/7934))" - - fixed broken logs - - bring back old lock order - - remove migration v13 - - revert CURRENT_VERSION to 12 in migration.rs - - more dos protection ([#8104](https://github.com/paritytech/parity/pull/8104)) - - Const time comparison ([#8113](https://github.com/paritytech/parity/pull/8113)) - - Use `subtle::slices_equal` for constant time comparison. - - Also update the existing version of subtle in `ethcrypto` from 0.1 to 0.5 - - Test specifically for InvalidPassword error. - - fix trace filter returning returning unrelated reward calls, closes #8070 ([#8098](https://github.com/paritytech/parity/pull/8098)) - - network: init discovery using healthy nodes ([#8061](https://github.com/paritytech/parity/pull/8061)) - - network: init discovery using healthy nodes - - network: fix style grumble - - network: fix typo - - Postpone Kovan hard fork ([#8137](https://github.com/paritytech/parity/pull/8137)) - - ethcore: postpone Kovan hard fork - - util: update version fork metadata - - Disable UI by default. ([#8105](https://github.com/paritytech/parity/pull/8105)) - - dapps: update parity-ui dependencies ([#8160](https://github.com/paritytech/parity/pull/8160)) -- Probe changes one step deeper ([#8134](https://github.com/paritytech/parity/pull/8134)) ([#8135](https://github.com/paritytech/parity/pull/8135)) -- Beta backports ([#8053](https://github.com/paritytech/parity/pull/8053)) - - CI: Fix cargo cache ([#7968](https://github.com/paritytech/parity/pull/7968)) - - Fix cache - - Only clean locked cargo cache on windows - - fixed ethstore sign ([#8026](https://github.com/paritytech/parity/pull/8026)) - - fixed parsing ethash seals and verify_block_undordered ([#8031](https://github.com/paritytech/parity/pull/8031)) - - fix for verify_block_basic crashing on invalid transaction rlp ([#8032](https://github.com/paritytech/parity/pull/8032)) - - fix cache & snapcraft CI build ([#8052](https://github.com/paritytech/parity/pull/8052)) - - Add MCIP-6 Byzyantium transition to Musicoin spec ([#7841](https://github.com/paritytech/parity/pull/7841)) - - Add test chain spec for musicoin byzantium testnet - - Add MCIP-6 Byzyantium transition to Musicoin spec - - Update mcip6_byz.json - - ethcore: update musicoin byzantium block number - - ethcore: update musicoin bootnodes - - Update musicoin.json - - More bootnodes. -- Make 1.10 beta ([#8022](https://github.com/paritytech/parity/pull/8022)) - - Make 1.10 beta - - Fix gitlab builds -- SecretStore: secretstore_generateDocumentKey RPC ([#7864](https://github.com/paritytech/parity/pull/7864)) -- SecretStore: ECDSA session for cases when 2*t < N ([#7739](https://github.com/paritytech/parity/pull/7739)) -- bump tiny-keccak ([#8019](https://github.com/paritytech/parity/pull/8019)) -- Remove un-necessary comment ([#8014](https://github.com/paritytech/parity/pull/8014)) -- clean up account fmt::Debug ([#7983](https://github.com/paritytech/parity/pull/7983)) -- improve quality of vote_collector module ([#7984](https://github.com/paritytech/parity/pull/7984)) -- ExecutedBlock cleanup ([#7991](https://github.com/paritytech/parity/pull/7991)) -- Hardware-wallet/usb-subscribe-refactor ([#7860](https://github.com/paritytech/parity/pull/7860)) -- remove wildcard imports from views, make tests more idiomatic ([#7986](https://github.com/paritytech/parity/pull/7986)) -- moved PerfTimer to a separate crate - "trace-time" ([#7985](https://github.com/paritytech/parity/pull/7985)) -- clean up ethcore::spec module imports ([#7990](https://github.com/paritytech/parity/pull/7990)) -- rpc: don't include current block in new_block_filter ([#7982](https://github.com/paritytech/parity/pull/7982)) -- fix traces, removed bloomchain crate ([#7979](https://github.com/paritytech/parity/pull/7979)) -- simplify compression and move it out of rlp crate ([#7957](https://github.com/paritytech/parity/pull/7957)) -- removed old migrations ([#7974](https://github.com/paritytech/parity/pull/7974)) -- Reject too large packets in snapshot sync. ([#7977](https://github.com/paritytech/parity/pull/7977)) -- fixed broken logs ([#7934](https://github.com/paritytech/parity/pull/7934)) -- Increase max download limit to 128MB ([#7965](https://github.com/paritytech/parity/pull/7965)) -- Calculate proper keccak256/sha3 using parity. ([#7953](https://github.com/paritytech/parity/pull/7953)) -- Add changelog for 1.8.10 stable and 1.9.3 beta ([#7947](https://github.com/paritytech/parity/pull/7947)) -- kvdb-rocksdb: remove buffered operations when committing transaction ([#7950](https://github.com/paritytech/parity/pull/7950)) -- Bump WebSockets ([#7952](https://github.com/paritytech/parity/pull/7952)) -- removed redundant Bloom conversions ([#7932](https://github.com/paritytech/parity/pull/7932)) -- simplify RefInfo fmt ([#7929](https://github.com/paritytech/parity/pull/7929)) -- Kovan WASM fork code ([#7849](https://github.com/paritytech/parity/pull/7849)) -- bring back trie and triehash benches ([#7926](https://github.com/paritytech/parity/pull/7926)) -- removed redundant PodAccount::new method ([#7928](https://github.com/paritytech/parity/pull/7928)) -- removed dummy wrapper structure - LogGroupPosition ([#7922](https://github.com/paritytech/parity/pull/7922)) -- spec: Validate required divisor fields are not 0 ([#7933](https://github.com/paritytech/parity/pull/7933)) -- simplify Client::filter_traces method ([#7936](https://github.com/paritytech/parity/pull/7936)) -- gitlab cache ([#7921](https://github.com/paritytech/parity/pull/7921)) -- Fix a division by zero in light client RPC handler ([#7917](https://github.com/paritytech/parity/pull/7917)) -- triehash optimisations ([#7920](https://github.com/paritytech/parity/pull/7920)) -- removed redundant Blockchain::db method ([#7919](https://github.com/paritytech/parity/pull/7919)) -- removed redundant Blockchain::rewind method ([#7918](https://github.com/paritytech/parity/pull/7918)) -- Pending transactions subscription ([#7906](https://github.com/paritytech/parity/pull/7906)) -- removed redundant otry! macro from ethcore ([#7916](https://github.com/paritytech/parity/pull/7916)) -- Make block generator easier to use ([#7888](https://github.com/paritytech/parity/pull/7888)) -- ECIP 1041 - Remove Difficulty Bomb ([#7905](https://github.com/paritytech/parity/pull/7905)) -- Fix CSP for dapps that require eval. ([#7867](https://github.com/paritytech/parity/pull/7867)) -- Fix gitlab ([#7901](https://github.com/paritytech/parity/pull/7901)) -- Gitlb snap master patch ([#7900](https://github.com/paritytech/parity/pull/7900)) -- fix snap build master ([#7896](https://github.com/paritytech/parity/pull/7896)) -- Fix wallet import ([#7873](https://github.com/paritytech/parity/pull/7873)) -- Fix snapcraft nightly ([#7884](https://github.com/paritytech/parity/pull/7884)) -- Add a timeout for light client sync requests ([#7848](https://github.com/paritytech/parity/pull/7848)) -- SecretStore: fixed test ([#7878](https://github.com/paritytech/parity/pull/7878)) -- Fix checksums and auto-update push ([#7846](https://github.com/paritytech/parity/pull/7846)) -- Forward-port snap fixes ([#7831](https://github.com/paritytech/parity/pull/7831)) -- Update gitlab-test.sh ([#7883](https://github.com/paritytech/parity/pull/7883)) -- Fix installer binary names for macos and windows ([#7881](https://github.com/paritytech/parity/pull/7881)) -- Fix string typo: "develoopment" -> "development" ([#7874](https://github.com/paritytech/parity/pull/7874)) -- Update the instructions to install the stable snap ([#7876](https://github.com/paritytech/parity/pull/7876)) -- SecretStore: 'broadcast' decryption session ([#7843](https://github.com/paritytech/parity/pull/7843)) -- Flush keyfiles. Resolves #7632 ([#7868](https://github.com/paritytech/parity/pull/7868)) -- Read registry_address from given block ([#7866](https://github.com/paritytech/parity/pull/7866)) -- Clean up docs formatting for Wasm runtime ([#7869](https://github.com/paritytech/parity/pull/7869)) -- WASM: Disable internal memory ([#7842](https://github.com/paritytech/parity/pull/7842)) -- Update gitlab-build.sh ([#7855](https://github.com/paritytech/parity/pull/7855)) -- ethabi version 5 ([#7723](https://github.com/paritytech/parity/pull/7723)) -- Light client: randomize the peer we dispatch requests to ([#7844](https://github.com/paritytech/parity/pull/7844)) -- Store updater metadata in a single place ([#7832](https://github.com/paritytech/parity/pull/7832)) -- Add new EF ropstens nodes. ([#7824](https://github.com/paritytech/parity/pull/7824)) -- refactor stratum to remove retain cycle ([#7827](https://github.com/paritytech/parity/pull/7827)) -- Bump jsonrpc. ([#7828](https://github.com/paritytech/parity/pull/7828)) -- Add binary identifiers and sha256sum to builds ([#7830](https://github.com/paritytech/parity/pull/7830)) -- Update references to UI shell & wallet ([#7808](https://github.com/paritytech/parity/pull/7808)) -- Adjust storage update evm-style ([#7812](https://github.com/paritytech/parity/pull/7812)) -- Updated WASM Runtime & new interpreter (wasmi) ([#7796](https://github.com/paritytech/parity/pull/7796)) -- SecretStore: ignore removed authorities when running auto-migration ([#7674](https://github.com/paritytech/parity/pull/7674)) -- Fix build ([#7807](https://github.com/paritytech/parity/pull/7807)) -- Move js & js-old code to github.com/parity-js ([#7685](https://github.com/paritytech/parity/pull/7685)) -- More changelogs :) ([#7782](https://github.com/paritytech/parity/pull/7782)) -- Actualized API set in help ([#7790](https://github.com/paritytech/parity/pull/7790)) -- Removed obsolete file ([#7788](https://github.com/paritytech/parity/pull/7788)) -- Update ropsten bootnodes ([#7776](https://github.com/paritytech/parity/pull/7776)) -- CHANGELOG for 1.9.1 and 1.8.8 ([#7775](https://github.com/paritytech/parity/pull/7775)) -- Enable byzantium features on non-ethash chains ([#7753](https://github.com/paritytech/parity/pull/7753)) -- Fix client not being dropped on shutdown ([#7695](https://github.com/paritytech/parity/pull/7695)) -- Filter-out nodes.json ([#7716](https://github.com/paritytech/parity/pull/7716)) -- Removes redundant parentheses ([#7721](https://github.com/paritytech/parity/pull/7721)) -- Transaction-pool fixes ([#7741](https://github.com/paritytech/parity/pull/7741)) -- More visible download link in README.md ([#7707](https://github.com/paritytech/parity/pull/7707)) -- Changelog for 1.9.0 ([#7664](https://github.com/paritytech/parity/pull/7664)) -- Add scroll when too many accounts ([#7677](https://github.com/paritytech/parity/pull/7677)) -- SecretStore: return HTTP 403 (access denied) if consensus is unreachable ([#7656](https://github.com/paritytech/parity/pull/7656)) -- Moved StopGaurd to it's own crate ([#7635](https://github.com/paritytech/parity/pull/7635)) +- Backports ([#8558](https://github.com/paritytech/parity/pull/8558)) + - Fetching logs by hash in blockchain database ([#8463](https://github.com/paritytech/parity/pull/8463)) + - Fetch logs by hash in blockchain database + - Fix tests + - Add unit test for branch block logs fetching + - Add docs that blocks must already be sorted + - Handle branch block cases properly + - typo: empty -> is_empty + - Remove return_empty_if_none by using a closure + - Use BTreeSet to avoid sorting again + - Move is_canon to BlockChain + - typo: pass value by reference + - Use loop and wrap inside blocks to simplify the code + - typo: missed a comment + - Pass on storage keys tracing to handle the case when it is not modified ([#8491](https://github.com/paritytech/parity/pull/8491)) + - Pass on storage keys even if it is not modified + - typo: account and storage query + - Fix tests + - Use state query directly because of suicided accounts + - Fix a RefCell borrow issue + - Add tests for unmodified storage trace + - Address grumbles + - typo: remove unwanted empty line + - ensure_cached compiles with the original signature + - Update wasmi and pwasm-utils ([#8493](https://github.com/paritytech/parity/pull/8493)) + - Update wasmi to 0.2 + - Update pwasm-utils to 0.1.5 + - Show imported messages for light client ([#8517](https://github.com/paritytech/parity/pull/8517)) + - Enable WebAssembly and Byzantium for Ellaism ([#8520](https://github.com/paritytech/parity/pull/8520)) + - Enable WebAssembly and Byzantium for Ellaism + - Fix indentation + - Remove empty lines + - Don't panic in import_block if invalid rlp ([#8522](https://github.com/paritytech/parity/pull/8522)) + - Don't panic in import_block if invalid rlp + - Remove redundant type annotation + - Replace RLP header view usage with safe decoding + - Node table sorting according to last contact data ([#8541](https://github.com/paritytech/parity/pull/8541)) + - network-devp2p: sort nodes in node table using last contact data + - network-devp2p: rename node contact types in node table json output + - network-devp2p: fix node table tests + - network-devp2p: note node failure when failed to establish connection + - network-devp2p: handle UselessPeer error + - network-devp2p: note failure when marking node as useless +- Betalize 1.11 :) ([#8475](https://github.com/paritytech/parity/pull/8475)) + - Betalize 1.11 :) + - Update Gitlab scripts + - Use master as gitlab latest + - Fix snap builds ([#8483](https://github.com/paritytech/parity/pull/8483)) + - Update hardcodedSync for Ethereum, Kovan, and Ropsten ([#8489](https://github.com/paritytech/parity/pull/8489)) +- Fix typos in vm description comment ([#8446](https://github.com/paritytech/parity/pull/8446)) +- Add changelog for 1.9.7 and 1.10.2 ([#8460](https://github.com/paritytech/parity/pull/8460)) +- Fix docker build ([#8462](https://github.com/paritytech/parity/pull/8462)) +- Parityshell::open `Return result` ([#8377](https://github.com/paritytech/parity/pull/8377)) +- Return error in case eth_call returns VM errors ([#8448](https://github.com/paritytech/parity/pull/8448)) +- Update wasmi ([#8452](https://github.com/paritytech/parity/pull/8452)) +- Allow 32 bit pipelines to fail ([#8454](https://github.com/paritytech/parity/pull/8454)) +- Update Cargo hidapi-rs dependency ([#8447](https://github.com/paritytech/parity/pull/8447)) +- Private transactions processing error handling ([#8431](https://github.com/paritytech/parity/pull/8431)) +- Improve VM executor stack size estimation rules ([#8439](https://github.com/paritytech/parity/pull/8439)) +- Block reward contract ([#8419](https://github.com/paritytech/parity/pull/8419)) +- Permission fix ([#8441](https://github.com/paritytech/parity/pull/8441)) +- Use forked app_dirs crate for reverted Windows dir behavior ([#8438](https://github.com/paritytech/parity/pull/8438)) +- Remove From::from. ([#8390](https://github.com/paritytech/parity/pull/8390)) +- Move ethcore::Error to error_chain ([#8386](https://github.com/paritytech/parity/pull/8386)) +- Changelogs for 1.9.6 and 1.10.1 ([#8411](https://github.com/paritytech/parity/pull/8411)) +- Fix receipts stripping. ([#8414](https://github.com/paritytech/parity/pull/8414)) +- Typo, docs parity_chainId: empty string -> None ([#8434](https://github.com/paritytech/parity/pull/8434)) +- Update zip to 0.3 ([#8381](https://github.com/paritytech/parity/pull/8381)) +- Fix TODO comments ([#8413](https://github.com/paritytech/parity/pull/8413)) +- Replace legacy Rlp with UntrustedRlp and use in ethcore rlp views ([#8316](https://github.com/paritytech/parity/pull/8316)) +- Tokio-core v0.1.16 -> v0.1.17 ([#8408](https://github.com/paritytech/parity/pull/8408)) +- More code refactoring to integrate Duration ([#8322](https://github.com/paritytech/parity/pull/8322)) +- Remove Tendermint extra_info due to seal inconsistencies ([#8367](https://github.com/paritytech/parity/pull/8367)) +- Use tokio::spawn in secret_store listener and fix Uri ([#8373](https://github.com/paritytech/parity/pull/8373)) +- Unify and limit rocksdb dependency places ([#8371](https://github.com/paritytech/parity/pull/8371)) +- Clarify that windows need perl and yasm ([#8402](https://github.com/paritytech/parity/pull/8402)) +- New Transaction Queue implementation ([#8074](https://github.com/paritytech/parity/pull/8074)) +- Some tweaks to main.rs for parity as a library ([#8370](https://github.com/paritytech/parity/pull/8370)) +- Handle queue import errors a bit more gracefully ([#8385](https://github.com/paritytech/parity/pull/8385)) +- Ci: fix change detection in master builds ([#8382](https://github.com/paritytech/parity/pull/8382)) +- Fix config test by adding no-hardcodec-sync ([#8380](https://github.com/paritytech/parity/pull/8380)) +- Fixed unsafe shell call on windows ([#8372](https://github.com/paritytech/parity/pull/8372)) +- Parity uses winapi 0.3.4 ([#8366](https://github.com/paritytech/parity/pull/8366)) +- No hardcoded client name ([#8368](https://github.com/paritytech/parity/pull/8368)) +- Add `util/mem` to zero out memory on drop. ([#8356](https://github.com/paritytech/parity/pull/8356)) +- Use atty instead of isatty ([#8365](https://github.com/paritytech/parity/pull/8365)) +- Increase gasLimit to 8'000'000 ([#8362](https://github.com/paritytech/parity/pull/8362)) +- Util `fake-fetch` ([#8363](https://github.com/paritytech/parity/pull/8363)) +- Bump snappy and ring, use single rayon version, closes [#8296](https://github.com/paritytech/parity/issues/8296) ([#8364](https://github.com/paritytech/parity/pull/8364)) +- Use async hyper server in secret_store and upgrade igd ([#8359](https://github.com/paritytech/parity/pull/8359)) +- Enable UI by default, but only display deprecation notice ([#8262](https://github.com/paritytech/parity/pull/8262)) +- Ethcrypto renamed to ethcore-crypto and moved to ethcore dir ([#8340](https://github.com/paritytech/parity/pull/8340)) +- Use hyper 0.11 in ethcore-miner and improvements in parity-reactor ([#8335](https://github.com/paritytech/parity/pull/8335)) +- Ethcore-sync ([#8347](https://github.com/paritytech/parity/pull/8347)) +- Rpc, eth_filter: return error if the filter id does not exist ([#8341](https://github.com/paritytech/parity/pull/8341)) +- Ethcore-stratum crate moved to ethcore directory ([#8338](https://github.com/paritytech/parity/pull/8338)) +- Secretstore: get rid of engine.signer dependency ([#8173](https://github.com/paritytech/parity/pull/8173)) +- Whisper cli ([#8201](https://github.com/paritytech/parity/pull/8201)) +- Replace_home for password_files, reserved_peers and log_file ([#8324](https://github.com/paritytech/parity/pull/8324)) +- Add Ethereum Social support ([#8325](https://github.com/paritytech/parity/pull/8325)) +- Private transactions integration pr ([#6422](https://github.com/paritytech/parity/pull/6422)) +- Decouple rocksdb dependency from ethcore ([#8320](https://github.com/paritytech/parity/pull/8320)) +- Remove the clone operation of code_cache ([#8334](https://github.com/paritytech/parity/pull/8334)) +- Fix the JSONRPC API not running with the light client ([#8326](https://github.com/paritytech/parity/pull/8326)) +- Read registry_address from block with REQUEST_CONFIRMATIONS_REQUIRED ([#8309](https://github.com/paritytech/parity/pull/8309)) +- Tweaks and add a Dockerfile for Android ([#8036](https://github.com/paritytech/parity/pull/8036)) +- Use associated type M::Error instead of Error ([#8308](https://github.com/paritytech/parity/pull/8308)) +- Remove InvalidParentHash in favor of assert! ([#8300](https://github.com/paritytech/parity/pull/8300)) +- Bump proc macro deps ([#8310](https://github.com/paritytech/parity/pull/8310)) +- Decouple timestamp open-block-assignment/verification to Engine ([#8305](https://github.com/paritytech/parity/pull/8305)) +- Validate if gas limit is not zero ([#8307](https://github.com/paritytech/parity/pull/8307)) +- Implement Easthub chain spec ([#8295](https://github.com/paritytech/parity/pull/8295)) +- Update some dependencies ([#8285](https://github.com/paritytech/parity/pull/8285)) +- Ethcore now uses Rayon 1.0 as a dependency ([#8296](https://github.com/paritytech/parity/pull/8296)) ([#8304](https://github.com/paritytech/parity/pull/8304)) +- Upgrader `remove raw unwrap` and bump semver ([#8251](https://github.com/paritytech/parity/pull/8251)) +- Cleaner binary shutdown system ([#8284](https://github.com/paritytech/parity/pull/8284)) +- Ethcore now uses rayon to 0.9 as a dependency ([#8296](https://github.com/paritytech/parity/pull/8296)) ([#8302](https://github.com/paritytech/parity/pull/8302)) +- Include suicided accounts in state diff ([#8297](https://github.com/paritytech/parity/pull/8297)) +- Remove evmjit ([#8229](https://github.com/paritytech/parity/pull/8229)) +- Build: fix updater rand dependency in Cargo.lock ([#8298](https://github.com/paritytech/parity/pull/8298)) +- Honor --max-peers if --min-peers is not specified ([#8087](https://github.com/paritytech/parity/pull/8087)) +- Auto-updater improvements ([#8078](https://github.com/paritytech/parity/pull/8078)) +- Dapps-fetcher: calculate keccak in-flight while reading the response ([#8294](https://github.com/paritytech/parity/pull/8294)) +- Cleanup Ellaism bootnodes ([#8276](https://github.com/paritytech/parity/pull/8276)) +- Allow unsafe js eval on Parity Wallet. ([#8204](https://github.com/paritytech/parity/pull/8204)) +- Remove RefCell from Header ([#8227](https://github.com/paritytech/parity/pull/8227)) +- Typo fix: todo with no content ([#8292](https://github.com/paritytech/parity/pull/8292)) +- Revert "ci: disable link-dead-code in coverage build ([#8118](https://github.com/paritytech/parity/pull/8118))" ([#8287](https://github.com/paritytech/parity/pull/8287)) +- Bump ethabi & ethereum-types. ([#8258](https://github.com/paritytech/parity/pull/8258)) +- Allow customization of max WS connections. ([#8257](https://github.com/paritytech/parity/pull/8257)) +- Supress TemporaryInvalid verification failures. ([#8256](https://github.com/paritytech/parity/pull/8256)) +- Return null number for pending block in eth_getBlockByNumber ([#8281](https://github.com/paritytech/parity/pull/8281)) +- Use constant durations ([#8278](https://github.com/paritytech/parity/pull/8278)) +- Typo fix: Mode doc - RLP should be client ([#8283](https://github.com/paritytech/parity/pull/8283)) +- Eth_uninstallfilter should return false for non-existent filter ([#8280](https://github.com/paritytech/parity/pull/8280)) +- Update `app_dirs` to 1.2.1 ([#8268](https://github.com/paritytech/parity/pull/8268)) +- Add missing license header for runtime.rs ([#8252](https://github.com/paritytech/parity/pull/8252)) +- Warp-only sync with warp-barrier [blocknumber] flag. ([#8228](https://github.com/paritytech/parity/pull/8228)) +- Replace all Rlp usages with UntrustedRlp except for ethcore views ([#8233](https://github.com/paritytech/parity/pull/8233)) +- Add test for ethstore-cli, fixes [#8027](https://github.com/paritytech/parity/issues/8027) ([#8187](https://github.com/paritytech/parity/pull/8187)) +- Update musicoin spec in line with gmc v2.6.2 ([#8242](https://github.com/paritytech/parity/pull/8242)) +- Fixed ethcore tx_filter ([#8200](https://github.com/paritytech/parity/pull/8200)) +- Update CLI help for jsonrpc-apis, ws-apis and ipc-apis ([#8234](https://github.com/paritytech/parity/pull/8234)) +- Remove network stats ([#8225](https://github.com/paritytech/parity/pull/8225)) +- Node-filter does not use ChainNotify ([#8231](https://github.com/paritytech/parity/pull/8231)) +- Implement hardcoded sync in the light client ([#8075](https://github.com/paritytech/parity/pull/8075)) +- Update some of the dependencies for WASM ([#8223](https://github.com/paritytech/parity/pull/8223)) +- Bump wasmi version ([#8209](https://github.com/paritytech/parity/pull/8209)) +- Updated jsonrpc to point to the 1.11 branch ([#8180](https://github.com/paritytech/parity/pull/8180)) +- Change name Wallet -> UI ([#8164](https://github.com/paritytech/parity/pull/8164)) +- Introduce Parity UI ([#8202](https://github.com/paritytech/parity/pull/8202)) +- Update Changelogs ([#8175](https://github.com/paritytech/parity/pull/8175)) +- Returns number of topcis to take fr.. ([#8199](https://github.com/paritytech/parity/pull/8199)) +- Make docopt usage non-const ([#8189](https://github.com/paritytech/parity/pull/8189)) +- Avoid allocations when computing triehash. ([#8176](https://github.com/paritytech/parity/pull/8176)) +- Handle rlp decoding Result in patricia trie ([#8166](https://github.com/paritytech/parity/pull/8166)) +- Bump wasm libs ([#8171](https://github.com/paritytech/parity/pull/8171)) +- Re-enable signer, even with no UI. ([#8167](https://github.com/paritytech/parity/pull/8167)) +- Update daemonize ([#8165](https://github.com/paritytech/parity/pull/8165)) +- Some tiny modifications. ([#8163](https://github.com/paritytech/parity/pull/8163)) +- Secretstore: store key author address in db ([#7887](https://github.com/paritytech/parity/pull/7887)) +- Rename DatabaseValueView::new to from_rlp ([#8159](https://github.com/paritytech/parity/pull/8159)) +- Dapps: update parity-ui dependencies ([#8160](https://github.com/paritytech/parity/pull/8160)) +- Disable UI by default. ([#8105](https://github.com/paritytech/parity/pull/8105)) +- Fix wasmi x32 builds ([#8155](https://github.com/paritytech/parity/pull/8155)) +- Postpone Kovan hard fork ([#8137](https://github.com/paritytech/parity/pull/8137)) +- Secretstore: ability to identify requester via Public/Address ([#7886](https://github.com/paritytech/parity/pull/7886)) +- Optional dependency on secp256k1 for ethcrypto ([#8109](https://github.com/paritytech/parity/pull/8109)) +- Network: init discovery using healthy nodes ([#8061](https://github.com/paritytech/parity/pull/8061)) +- Check one step deeper if we're on release track branches ([#8134](https://github.com/paritytech/parity/pull/8134)) +- Explicitly mention pruning_history uses RAM ([#8130](https://github.com/paritytech/parity/pull/8130)) +- Remove `ethcrypto::{en,de}crypt_single_message`. ([#8126](https://github.com/paritytech/parity/pull/8126)) +- Fix typo ([#8124](https://github.com/paritytech/parity/pull/8124)) +- Secret_store: use `ecies::encrypt`/`ecies::decrypt`. ([#8125](https://github.com/paritytech/parity/pull/8125)) +- Fix comment for fn gas() in wasm/runtime ([#8122](https://github.com/paritytech/parity/pull/8122)) +- Structured rlp encoding in journaldb ([#8047](https://github.com/paritytech/parity/pull/8047)) +- Ci: disable link-dead-code in coverage build ([#8118](https://github.com/paritytech/parity/pull/8118)) +- Fix trace filter returning returning unrelated reward calls, closes [#8070](https://github.com/paritytech/parity/issues/8070) ([#8098](https://github.com/paritytech/parity/pull/8098)) +- Const time comparison ([#8113](https://github.com/paritytech/parity/pull/8113)) +- Replace reqwest with hyper ([#8099](https://github.com/paritytech/parity/pull/8099)) +- More dos protection ([#8104](https://github.com/paritytech/parity/pull/8104)) +- Remove the time dependency where possible ([#8100](https://github.com/paritytech/parity/pull/8100)) +- Fix comment for gas extern in Wasm runtime ([#8101](https://github.com/paritytech/parity/pull/8101)) +- Replace std::env::temp_dir with tempdir in tests ([#8103](https://github.com/paritytech/parity/pull/8103)) +- Fix Cargo.lock not parsable ([#8102](https://github.com/paritytech/parity/pull/8102)) +- Additional data in EVMTestClient ([#7964](https://github.com/paritytech/parity/pull/7964)) +- Update serde, serde-derive, ethabi-derive, syn, quote and rlp_derive ([#8085](https://github.com/paritytech/parity/pull/8085)) +- Ethcore-service ([#8089](https://github.com/paritytech/parity/pull/8089)) +- [contract-client] refactor ([#7978](https://github.com/paritytech/parity/pull/7978)) +- Revert removing blooms ([#8066](https://github.com/paritytech/parity/pull/8066)) +- Ethcore test::helpers cleanup ([#8086](https://github.com/paritytech/parity/pull/8086)) +- Add some dos protection ([#8084](https://github.com/paritytech/parity/pull/8084)) +- Wasm libraries bump ([#7970](https://github.com/paritytech/parity/pull/7970)) +- Echo back the message hash of a ping in the pong request ([#8042](https://github.com/paritytech/parity/pull/8042)) +- Add Kovan WASM activation blocknumber ([#8057](https://github.com/paritytech/parity/pull/8057)) +- [ethkey] Unify debug/display for Address/Public/Secret ([#8076](https://github.com/paritytech/parity/pull/8076)) +- Limit incoming connections. ([#8060](https://github.com/paritytech/parity/pull/8060)) +- Max code size on Kovan ([#8067](https://github.com/paritytech/parity/pull/8067)) +- Updater: apply exponential backoff after download failure ([#8059](https://github.com/paritytech/parity/pull/8059)) +- Make blockchain functions more idiomatic, avoid needless writes to cache_man ([#8054](https://github.com/paritytech/parity/pull/8054)) +- Make patricia-trie more idiomatic and remove redundant code ([#8056](https://github.com/paritytech/parity/pull/8056)) +- Abstract devp2p ([#8048](https://github.com/paritytech/parity/pull/8048)) +- Update refs to shell ([#8051](https://github.com/paritytech/parity/pull/8051)) +- Fix cache & snapcraft CI build ([#8052](https://github.com/paritytech/parity/pull/8052)) +- Prelude to the block module cleanup ([#8025](https://github.com/paritytech/parity/pull/8025)) +- Add MCIP-6 Byzyantium transition to Musicoin spec ([#7841](https://github.com/paritytech/parity/pull/7841)) +- Bump master to 1.11.0 ([#8021](https://github.com/paritytech/parity/pull/8021)) +- `client` refactoring ([#7038](https://github.com/paritytech/parity/pull/7038)) +- [hardware wallet] sleeping -> pollling ([#8018](https://github.com/paritytech/parity/pull/8018)) +- Fixed broken link in README ([#8012](https://github.com/paritytech/parity/pull/8012)) +- Support parity protocol. ([#8035](https://github.com/paritytech/parity/pull/8035)) +- Add changelog for 1.8.11 stable and 1.9.4 beta ([#8017](https://github.com/paritytech/parity/pull/8017)) +- Fix for verify_block_basic crashing on invalid transaction rlp ([#8032](https://github.com/paritytech/parity/pull/8032)) +- Extract the hard dependency on rocksdb from the light client ([#8034](https://github.com/paritytech/parity/pull/8034)) +- Fixed parsing ethash seals and verify_block_undordered ([#8031](https://github.com/paritytech/parity/pull/8031)) +- Fixed ethstore sign ([#8026](https://github.com/paritytech/parity/pull/8026)) +- Ci: Fix cargo cache ([#7968](https://github.com/paritytech/parity/pull/7968)) +- Update ref to new shell ([#8024](https://github.com/paritytech/parity/pull/8024)) ## Previous releases -- [CHANGELOG-1.9](docs/CHANGELOG-1.9.md) (_stable_) +- [CHANGELOG-1.10](docs/CHANGELOG-1.10.md) (_stable_) +- [CHANGELOG-1.9](docs/CHANGELOG-1.9.md) (EOL: 2018-05-09) - [CHANGELOG-1.8](docs/CHANGELOG-1.8.md) (EOL: 2018-03-22) - [CHANGELOG-1.7](docs/CHANGELOG-1.7.md) (EOL: 2018-01-25) - [CHANGELOG-1.6](docs/CHANGELOG-1.6.md) (EOL: 2017-10-15) diff --git a/docs/CHANGELOG-1.10.md b/docs/CHANGELOG-1.10.md new file mode 100644 index 0000000000..4db8f32bb6 --- /dev/null +++ b/docs/CHANGELOG-1.10.md @@ -0,0 +1,325 @@ +## Parity [v1.10.3](https://github.com/paritytech/parity/releases/tag/v1.10.3) (2018-05-08) + +Parity 1.10.3 marks the first stable release on the 1.10 track. Among others, it improves performance and stability. + +The full list of included changes: + +- Backports ([#8557](https://github.com/paritytech/parity/pull/8557)) + - Update wasmi and pwasm-utils ([#8493](https://github.com/paritytech/parity/pull/8493)) + - Update wasmi to 0.2 + - Update pwasm-utils to 0.1.5 + - Fetching logs by hash in blockchain database ([#8463](https://github.com/paritytech/parity/pull/8463)) + - Fetch logs by hash in blockchain database + - Fix tests + - Add unit test for branch block logs fetching + - Add docs that blocks must already be sorted + - Handle branch block cases properly + - typo: empty -> is_empty + - Remove return_empty_if_none by using a closure + - Use BTreeSet to avoid sorting again + - Move is_canon to BlockChain + - typo: pass value by reference + - Use loop and wrap inside blocks to simplify the code + - typo: missed a comment + - Pass on storage keys tracing to handle the case when it is not modified ([#8491](https://github.com/paritytech/parity/pull/8491)) + - Pass on storage keys even if it is not modified + - typo: account and storage query `to_pod_diff` builds both `touched_addresses` merge and storage keys merge. + - Fix tests + - Use state query directly because of suicided accounts + - Fix a RefCell borrow issue + - Add tests for unmodified storage trace + - Address grumbles + - typo: remove unwanted empty line + - ensure_cached compiles with the original signature + - Enable WebAssembly and Byzantium for Ellaism ([#8520](https://github.com/paritytech/parity/pull/8520)) + - Enable WebAssembly and Byzantium for Ellaism + - Fix indentation + - Remove empty lines + - Fix compilation. +- Stabilize 1.10.3 ([#8474](https://github.com/paritytech/parity/pull/8474)) + - Stabelize 1.10 + - Bump stable to 1.10.3 + - Update Gitlab scripts + - Fix snap builds ([#8483](https://github.com/paritytech/parity/pull/8483)) + - Fix docker build ([#8462](https://github.com/paritytech/parity/pull/8462)) + - Use `master` as Docker's `latest` (`beta-release` is not used anymore) + +## Parity [v1.10.2](https://github.com/paritytech/parity/releases/tag/v1.10.2) (2018-04-24) + +Parity 1.10.2 is a bug-fix release to improve performance and stability. + +The full list of included changes: + +- Update Parity beta to 1.10.2 + Backports ([#8455](https://github.com/paritytech/parity/pull/8455)) + - Update Parity beta to 1.10.2 + - Allow 32-bit pipelines to fail ([#8454](https://github.com/paritytech/parity/pull/8454)) + - Disable 32-bit targets for Gitlab + - Rename Linux pipelines + - Update wasmi ([#8452](https://github.com/paritytech/parity/pull/8452)) + - Fix Cargo.lock +- Backports ([#8450](https://github.com/paritytech/parity/pull/8450)) + - Use forked app_dirs crate for reverted Windows dir behavior ([#8438](https://github.com/paritytech/parity/pull/8438)) + - Remove unused app_dirs dependency in CLI + - Use forked app_dirs crate for reverted Windows dir behavior + - Remove Tendermint extra_info due to seal inconsistencies ([#8367](https://github.com/paritytech/parity/pull/8367)) + - Handle queue import errors a bit more gracefully ([#8385](https://github.com/paritytech/parity/pull/8385)) + - Improve VM executor stack size estimation rules ([#8439](https://github.com/paritytech/parity/pull/8439)) + - Improve VM executor stack size estimation rules + - Typo: docs add "(Debug build)" comment + - Fix an off by one typo and set minimal stack size + - Use saturating_sub to avoid potential overflow + +## Parity [v1.10.1](https://github.com/paritytech/parity/releases/tag/v1.10.1) (2018-04-17) + +Parity 1.10.1 is a bug-fix release to improve performance and stability. Among other changes, you can now use `--warp-barrier [BLOCK]` to specify a minimum block number to `--warp` to. This is useful in cases where clients restore to outdated snapshots far behind the latest chain head. + +The full list of included changes: + +- Bump beta to 1.10.1 ([#8350](https://github.com/paritytech/parity/pull/8350)) + - Bump beta to 1.10.1 + - Unflag critical release +- Backports ([#8346](https://github.com/paritytech/parity/pull/8346)) + - Warp-only sync with warp-barrier [blocknumber] flag. ([#8228](https://github.com/paritytech/parity/pull/8228)) + - Warp-only sync with warp-after [blocknumber] flag. + - Fix tests. + - Fix configuration tests. + - Rename to warp barrier. + - Allow unsafe js eval on Parity Wallet. ([#8204](https://github.com/paritytech/parity/pull/8204)) + - Update musicoin spec in line with gmc v2.6.2 ([#8242](https://github.com/paritytech/parity/pull/8242)) + - Supress TemporaryInvalid verification failures. ([#8256](https://github.com/paritytech/parity/pull/8256)) + - Include suicided accounts in state diff ([#8297](https://github.com/paritytech/parity/pull/8297)) + - Include suicided accounts in state diff + - Shorten form match -> if let + - Test suicide trace diff in State + - Replace_home for password_files, reserved_peers and log_file ([#8324](https://github.com/paritytech/parity/pull/8324)) + - Replace_home for password_files, reserved_peers and log_file + - Typo: arg_log_file is Option + - Enable UI by default, but only display info page. + - Fix test. + - Fix naming and remove old todo. + - Change "wallet" with "browser UI" +- Change name Wallet -> UI ([#8164](https://github.com/paritytech/parity/pull/8164)) ([#8205](https://github.com/paritytech/parity/pull/8205)) + - Change name Wallet -> UI + - Make warning bold +- Backport [#8099](https://github.com/paritytech/parity/pull/8099) ([#8132](https://github.com/paritytech/parity/pull/8132)) +- WASM libs ([#8220](https://github.com/paritytech/parity/pull/8220)) + - Bump wasm libs ([#8171](https://github.com/paritytech/parity/pull/8171)) + - Bump wasmi version ([#8209](https://github.com/paritytech/parity/pull/8209)) +- Update hyper to 0.11.24 ([#8203](https://github.com/paritytech/parity/pull/8203)) +- Updated jsonrpc to include latest backports (beta) ([#8181](https://github.com/paritytech/parity/pull/8181)) + - Updated jsonrpc to include latest backports + - Update dependencies. + +## Parity [v1.10.0](https://github.com/paritytech/parity/releases/tag/v1.10.0) (2018-03-22) + +This is the Parity 1.10.0-beta release! Cool! + +### Disabling the Parity Wallet + +The **Parity Wallet (a.k.a. "UI") is now disabled by default**. We are preparing to split the wallet from the core client. + +To reactivate the parity wallet, you have to run Parity either with `parity --force-ui` (not recommended) or `parity ui` (deprecated) from the command line. Or, if you feel super fancy and want to test our pre-releases of the stand-alone electron wallet, head over to the [Parity-JS repositories and check the releases](https://github.com/Parity-JS/shell/releases). + +Further reading: + +- [Docs: Parity Wallet](https://wiki.parity.io/Parity-Wallet) +- [Docs: How to customize Parity UI?](https://wiki.parity.io/FAQ-Customize-Parity-UI.html) +- [Github: Parity-JS](https://github.com/parity-js) + +### Introducing the Wasm VM + +We are excited to announce support for **Wasm Smart Contracts on Kovan network**. The hard-fork to activate the Wasm-VM will take place on block `6_600_000`. + +To enable Wasm contracts on your custom network, just schedule a `wasmActivationTransition` at your favorite block number (e.g., `42`, `666`, or `0xbada55`). To hack your first Wasm smart contracts in Rust, have a look at the [Parity Wasm Tutorials](https://github.com/paritytech/pwasm-tutorial). + +Further reading: + +- [Docs: WebAssembly (wasm)](https://wiki.parity.io/WebAssembly-Home) +- [Docs: Wasm VM Design](https://wiki.parity.io/WebAssembly-Design) +- [Docs: Wasm tutorials and examples](https://wiki.parity.io/WebAssembly-Links) + +### Empty step messages in PoA + +To **reduce blockchain bloat, proof-of-authority networks can now enable _empty step messages_ which replace empty blocks**. Each step message will be signed and broadcasted by the issuing authorities, and included and rewarded in the next non-empty block. + +To enable empty step messages, set the `emptyStepsTransition` to your favorite block number. You can also specify a maximum number of empty steps with `maximumEmptySteps` in your chain spec. + +### Other noteworthy changes + +We removed the old database migrations from 2016. In case you upgrade Parity from a really, really old version, you will have to reset your database manually first with `parity db kill`. + +We fixed DELEGATECALL `from` and `to` fields, see [#7166](https://github.com/paritytech/parity/issues/7166). + +We reduced the default USD per transaction value to 0.0001. Thanks, @MysticRyuujin! + +The Musicoin chain is now enabled with Byzantium features starting at block `2_222_222`. + +### Overview of all changes included + +The full list of included changes: + +- Re-enable signer, even with no UI. ([#8167](https://github.com/paritytech/parity/pull/8167)) ([#8168](https://github.com/paritytech/parity/pull/8168)) + - Re-enable signer, even with no UI. + - Fix message. +- Beta Backports ([#8136](https://github.com/paritytech/parity/pull/8136)) + - Support parity protocol. ([#8035](https://github.com/paritytech/parity/pull/8035)) + - updater: apply exponential backoff after download failure ([#8059](https://github.com/paritytech/parity/pull/8059)) + - updater: apply exponential backoff after download failure + - updater: reset backoff on new release + - Max code size on Kovan ([#8067](https://github.com/paritytech/parity/pull/8067)) + - Enable code size limit on kovan + - Fix formatting. + - Limit incoming connections. ([#8060](https://github.com/paritytech/parity/pull/8060)) + - Limit ingress connections + - Optimized handshakes logging + - WASM libraries bump ([#7970](https://github.com/paritytech/parity/pull/7970)) + - update wasmi, parity-wasm, wasm-utils to latest version + - Update to new wasmi & error handling + - also utilize new stack limiter + - fix typo + - replace dependency url + - Cargo.lock update + - add some dos protection ([#8084](https://github.com/paritytech/parity/pull/8084)) + - revert removing blooms ([#8066](https://github.com/paritytech/parity/pull/8066)) + - Revert "fix traces, removed bloomchain crate, closes [#7228](https://github.com/paritytech/parity/issues/7228), closes [#7167](https://github.com/paritytech/parity/issues/7167)" + - Revert "fixed broken logs ([#7934](https://github.com/paritytech/parity/pull/7934))" + - fixed broken logs + - bring back old lock order + - remove migration v13 + - revert CURRENT_VERSION to 12 in migration.rs + - more dos protection ([#8104](https://github.com/paritytech/parity/pull/8104)) + - Const time comparison ([#8113](https://github.com/paritytech/parity/pull/8113)) + - Use `subtle::slices_equal` for constant time comparison. + - Also update the existing version of subtle in `ethcrypto` from 0.1 to 0.5 + - Test specifically for InvalidPassword error. + - fix trace filter returning returning unrelated reward calls, closes #8070 ([#8098](https://github.com/paritytech/parity/pull/8098)) + - network: init discovery using healthy nodes ([#8061](https://github.com/paritytech/parity/pull/8061)) + - network: init discovery using healthy nodes + - network: fix style grumble + - network: fix typo + - Postpone Kovan hard fork ([#8137](https://github.com/paritytech/parity/pull/8137)) + - ethcore: postpone Kovan hard fork + - util: update version fork metadata + - Disable UI by default. ([#8105](https://github.com/paritytech/parity/pull/8105)) + - dapps: update parity-ui dependencies ([#8160](https://github.com/paritytech/parity/pull/8160)) +- Probe changes one step deeper ([#8134](https://github.com/paritytech/parity/pull/8134)) ([#8135](https://github.com/paritytech/parity/pull/8135)) +- Beta backports ([#8053](https://github.com/paritytech/parity/pull/8053)) + - CI: Fix cargo cache ([#7968](https://github.com/paritytech/parity/pull/7968)) + - Fix cache + - Only clean locked cargo cache on windows + - fixed ethstore sign ([#8026](https://github.com/paritytech/parity/pull/8026)) + - fixed parsing ethash seals and verify_block_undordered ([#8031](https://github.com/paritytech/parity/pull/8031)) + - fix for verify_block_basic crashing on invalid transaction rlp ([#8032](https://github.com/paritytech/parity/pull/8032)) + - fix cache & snapcraft CI build ([#8052](https://github.com/paritytech/parity/pull/8052)) + - Add MCIP-6 Byzyantium transition to Musicoin spec ([#7841](https://github.com/paritytech/parity/pull/7841)) + - Add test chain spec for musicoin byzantium testnet + - Add MCIP-6 Byzyantium transition to Musicoin spec + - Update mcip6_byz.json + - ethcore: update musicoin byzantium block number + - ethcore: update musicoin bootnodes + - Update musicoin.json + - More bootnodes. +- Make 1.10 beta ([#8022](https://github.com/paritytech/parity/pull/8022)) + - Make 1.10 beta + - Fix gitlab builds +- SecretStore: secretstore_generateDocumentKey RPC ([#7864](https://github.com/paritytech/parity/pull/7864)) +- SecretStore: ECDSA session for cases when 2*t < N ([#7739](https://github.com/paritytech/parity/pull/7739)) +- bump tiny-keccak ([#8019](https://github.com/paritytech/parity/pull/8019)) +- Remove un-necessary comment ([#8014](https://github.com/paritytech/parity/pull/8014)) +- clean up account fmt::Debug ([#7983](https://github.com/paritytech/parity/pull/7983)) +- improve quality of vote_collector module ([#7984](https://github.com/paritytech/parity/pull/7984)) +- ExecutedBlock cleanup ([#7991](https://github.com/paritytech/parity/pull/7991)) +- Hardware-wallet/usb-subscribe-refactor ([#7860](https://github.com/paritytech/parity/pull/7860)) +- remove wildcard imports from views, make tests more idiomatic ([#7986](https://github.com/paritytech/parity/pull/7986)) +- moved PerfTimer to a separate crate - "trace-time" ([#7985](https://github.com/paritytech/parity/pull/7985)) +- clean up ethcore::spec module imports ([#7990](https://github.com/paritytech/parity/pull/7990)) +- rpc: don't include current block in new_block_filter ([#7982](https://github.com/paritytech/parity/pull/7982)) +- fix traces, removed bloomchain crate ([#7979](https://github.com/paritytech/parity/pull/7979)) +- simplify compression and move it out of rlp crate ([#7957](https://github.com/paritytech/parity/pull/7957)) +- removed old migrations ([#7974](https://github.com/paritytech/parity/pull/7974)) +- Reject too large packets in snapshot sync. ([#7977](https://github.com/paritytech/parity/pull/7977)) +- fixed broken logs ([#7934](https://github.com/paritytech/parity/pull/7934)) +- Increase max download limit to 128MB ([#7965](https://github.com/paritytech/parity/pull/7965)) +- Calculate proper keccak256/sha3 using parity. ([#7953](https://github.com/paritytech/parity/pull/7953)) +- Add changelog for 1.8.10 stable and 1.9.3 beta ([#7947](https://github.com/paritytech/parity/pull/7947)) +- kvdb-rocksdb: remove buffered operations when committing transaction ([#7950](https://github.com/paritytech/parity/pull/7950)) +- Bump WebSockets ([#7952](https://github.com/paritytech/parity/pull/7952)) +- removed redundant Bloom conversions ([#7932](https://github.com/paritytech/parity/pull/7932)) +- simplify RefInfo fmt ([#7929](https://github.com/paritytech/parity/pull/7929)) +- Kovan WASM fork code ([#7849](https://github.com/paritytech/parity/pull/7849)) +- bring back trie and triehash benches ([#7926](https://github.com/paritytech/parity/pull/7926)) +- removed redundant PodAccount::new method ([#7928](https://github.com/paritytech/parity/pull/7928)) +- removed dummy wrapper structure - LogGroupPosition ([#7922](https://github.com/paritytech/parity/pull/7922)) +- spec: Validate required divisor fields are not 0 ([#7933](https://github.com/paritytech/parity/pull/7933)) +- simplify Client::filter_traces method ([#7936](https://github.com/paritytech/parity/pull/7936)) +- gitlab cache ([#7921](https://github.com/paritytech/parity/pull/7921)) +- Fix a division by zero in light client RPC handler ([#7917](https://github.com/paritytech/parity/pull/7917)) +- triehash optimisations ([#7920](https://github.com/paritytech/parity/pull/7920)) +- removed redundant Blockchain::db method ([#7919](https://github.com/paritytech/parity/pull/7919)) +- removed redundant Blockchain::rewind method ([#7918](https://github.com/paritytech/parity/pull/7918)) +- Pending transactions subscription ([#7906](https://github.com/paritytech/parity/pull/7906)) +- removed redundant otry! macro from ethcore ([#7916](https://github.com/paritytech/parity/pull/7916)) +- Make block generator easier to use ([#7888](https://github.com/paritytech/parity/pull/7888)) +- ECIP 1041 - Remove Difficulty Bomb ([#7905](https://github.com/paritytech/parity/pull/7905)) +- Fix CSP for dapps that require eval. ([#7867](https://github.com/paritytech/parity/pull/7867)) +- Fix gitlab ([#7901](https://github.com/paritytech/parity/pull/7901)) +- Gitlb snap master patch ([#7900](https://github.com/paritytech/parity/pull/7900)) +- fix snap build master ([#7896](https://github.com/paritytech/parity/pull/7896)) +- Fix wallet import ([#7873](https://github.com/paritytech/parity/pull/7873)) +- Fix snapcraft nightly ([#7884](https://github.com/paritytech/parity/pull/7884)) +- Add a timeout for light client sync requests ([#7848](https://github.com/paritytech/parity/pull/7848)) +- SecretStore: fixed test ([#7878](https://github.com/paritytech/parity/pull/7878)) +- Fix checksums and auto-update push ([#7846](https://github.com/paritytech/parity/pull/7846)) +- Forward-port snap fixes ([#7831](https://github.com/paritytech/parity/pull/7831)) +- Update gitlab-test.sh ([#7883](https://github.com/paritytech/parity/pull/7883)) +- Fix installer binary names for macos and windows ([#7881](https://github.com/paritytech/parity/pull/7881)) +- Fix string typo: "develoopment" -> "development" ([#7874](https://github.com/paritytech/parity/pull/7874)) +- Update the instructions to install the stable snap ([#7876](https://github.com/paritytech/parity/pull/7876)) +- SecretStore: 'broadcast' decryption session ([#7843](https://github.com/paritytech/parity/pull/7843)) +- Flush keyfiles. Resolves #7632 ([#7868](https://github.com/paritytech/parity/pull/7868)) +- Read registry_address from given block ([#7866](https://github.com/paritytech/parity/pull/7866)) +- Clean up docs formatting for Wasm runtime ([#7869](https://github.com/paritytech/parity/pull/7869)) +- WASM: Disable internal memory ([#7842](https://github.com/paritytech/parity/pull/7842)) +- Update gitlab-build.sh ([#7855](https://github.com/paritytech/parity/pull/7855)) +- ethabi version 5 ([#7723](https://github.com/paritytech/parity/pull/7723)) +- Light client: randomize the peer we dispatch requests to ([#7844](https://github.com/paritytech/parity/pull/7844)) +- Store updater metadata in a single place ([#7832](https://github.com/paritytech/parity/pull/7832)) +- Add new EF ropstens nodes. ([#7824](https://github.com/paritytech/parity/pull/7824)) +- refactor stratum to remove retain cycle ([#7827](https://github.com/paritytech/parity/pull/7827)) +- Bump jsonrpc. ([#7828](https://github.com/paritytech/parity/pull/7828)) +- Add binary identifiers and sha256sum to builds ([#7830](https://github.com/paritytech/parity/pull/7830)) +- Update references to UI shell & wallet ([#7808](https://github.com/paritytech/parity/pull/7808)) +- Adjust storage update evm-style ([#7812](https://github.com/paritytech/parity/pull/7812)) +- Updated WASM Runtime & new interpreter (wasmi) ([#7796](https://github.com/paritytech/parity/pull/7796)) +- SecretStore: ignore removed authorities when running auto-migration ([#7674](https://github.com/paritytech/parity/pull/7674)) +- Fix build ([#7807](https://github.com/paritytech/parity/pull/7807)) +- Move js & js-old code to github.com/parity-js ([#7685](https://github.com/paritytech/parity/pull/7685)) +- More changelogs :) ([#7782](https://github.com/paritytech/parity/pull/7782)) +- Actualized API set in help ([#7790](https://github.com/paritytech/parity/pull/7790)) +- Removed obsolete file ([#7788](https://github.com/paritytech/parity/pull/7788)) +- Update ropsten bootnodes ([#7776](https://github.com/paritytech/parity/pull/7776)) +- CHANGELOG for 1.9.1 and 1.8.8 ([#7775](https://github.com/paritytech/parity/pull/7775)) +- Enable byzantium features on non-ethash chains ([#7753](https://github.com/paritytech/parity/pull/7753)) +- Fix client not being dropped on shutdown ([#7695](https://github.com/paritytech/parity/pull/7695)) +- Filter-out nodes.json ([#7716](https://github.com/paritytech/parity/pull/7716)) +- Removes redundant parentheses ([#7721](https://github.com/paritytech/parity/pull/7721)) +- Transaction-pool fixes ([#7741](https://github.com/paritytech/parity/pull/7741)) +- More visible download link in README.md ([#7707](https://github.com/paritytech/parity/pull/7707)) +- Changelog for 1.9.0 ([#7664](https://github.com/paritytech/parity/pull/7664)) +- Add scroll when too many accounts ([#7677](https://github.com/paritytech/parity/pull/7677)) +- SecretStore: return HTTP 403 (access denied) if consensus is unreachable ([#7656](https://github.com/paritytech/parity/pull/7656)) +- Moved StopGaurd to it's own crate ([#7635](https://github.com/paritytech/parity/pull/7635)) + +## Previous releases + +- [CHANGELOG-1.9](docs/CHANGELOG-1.9.md) (_stable_) +- [CHANGELOG-1.8](docs/CHANGELOG-1.8.md) (EOL: 2018-03-22) +- [CHANGELOG-1.7](docs/CHANGELOG-1.7.md) (EOL: 2018-01-25) +- [CHANGELOG-1.6](docs/CHANGELOG-1.6.md) (EOL: 2017-10-15) +- [CHANGELOG-1.5](docs/CHANGELOG-1.5.md) (EOL: 2017-07-28) +- [CHANGELOG-1.4](docs/CHANGELOG-1.4.md) (EOL: 2017-03-13) +- [CHANGELOG-1.3](docs/CHANGELOG-1.3.md) (EOL: 2017-01-19) +- [CHANGELOG-1.2](docs/CHANGELOG-1.2.md) (EOL: 2016-11-07) +- [CHANGELOG-1.1](docs/CHANGELOG-1.1.md) (EOL: 2016-08-12) +- [CHANGELOG-1.0](docs/CHANGELOG-1.0.md) (EOL: 2016-06-24) +- [CHANGELOG-0.9](docs/CHANGELOG-0.9.md) (EOL: 2016-05-02) diff --git a/docs/CHANGELOG-1.9.md b/docs/CHANGELOG-1.9.md index 133c93c477..2be3fcf27b 100644 --- a/docs/CHANGELOG-1.9.md +++ b/docs/CHANGELOG-1.9.md @@ -1,3 +1,5 @@ +Note: Parity 1.9 reached End-of-Life on 2018-05-09 (EOL). + ## Parity [v1.9.7](https://github.com/paritytech/parity/releases/tag/v1.9.7) (2018-04-23) Parity 1.9.7 is a bug-fix release to improve performance and stability. -- GitLab From cb7ad2366dc2b62ac95e844287e516ebf6024772 Mon Sep 17 00:00:00 2001 From: David Date: Wed, 9 May 2018 15:58:02 +0200 Subject: [PATCH 021/152] Handle socket address parsing errors (#8545) Unpack errors and check for io::ErrorKind::InvalidInput and return our own AddressParse error. Remove the foreign link to std::net::AddrParseError and add an `impl From` for that error. Test parsing properly. --- Cargo.lock | 7 ++++ util/network-devp2p/Cargo.toml | 1 + util/network-devp2p/src/lib.rs | 2 ++ util/network-devp2p/src/node_table.rs | 52 ++++++++++++++++++++++----- util/network/src/error.rs | 11 +++++- 5 files changed, 63 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b02fcbd24e..edd76f9f4d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -35,6 +35,11 @@ dependencies = [ "nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "assert_matches" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "aster" version = "0.41.0" @@ -699,6 +704,7 @@ name = "ethcore-network-devp2p" version = "1.12.0" dependencies = [ "ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", + "assert_matches 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore-bytes 0.1.0", @@ -3767,6 +3773,7 @@ dependencies = [ "checksum ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6b3568b48b7cefa6b8ce125f9bb4989e52fbcc29ebea88df04cc7c5f12f70455" "checksum app_dirs 1.2.1 (git+https://github.com/paritytech/app-dirs-rs)" = "" "checksum arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef" +"checksum assert_matches 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "664470abf00fae0f31c0eb6e1ca12d82961b2a2541ef898bc9dd51a9254d218b" "checksum aster 0.41.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4ccfdf7355d9db158df68f976ed030ab0f6578af811f5a7bb6dcf221ec24e0e0" "checksum atty 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "af80143d6f7608d746df1520709e5d141c96f240b0e62b0aa41bdfb53374d9d4" "checksum backtrace 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ebbbf59b1c43eefa8c3ede390fcc36820b4999f7914104015be25025e0d62af2" diff --git a/util/network-devp2p/Cargo.toml b/util/network-devp2p/Cargo.toml index a8207ca615..3ec9684393 100644 --- a/util/network-devp2p/Cargo.toml +++ b/util/network-devp2p/Cargo.toml @@ -38,6 +38,7 @@ error-chain = { version = "0.11", default-features = false } [dev-dependencies] tempdir = "0.3" +assert_matches = "1.2" [features] default = [] diff --git a/util/network-devp2p/src/lib.rs b/util/network-devp2p/src/lib.rs index 8faf21e465..239763cbe1 100644 --- a/util/network-devp2p/src/lib.rs +++ b/util/network-devp2p/src/lib.rs @@ -95,6 +95,8 @@ extern crate serde_derive; #[cfg(test)] extern crate tempdir; +#[cfg(test)] #[macro_use] +extern crate assert_matches; mod host; mod connection; diff --git a/util/network-devp2p/src/node_table.rs b/util/network-devp2p/src/node_table.rs index 5079455866..8640901cd0 100644 --- a/util/network-devp2p/src/node_table.rs +++ b/util/network-devp2p/src/node_table.rs @@ -14,6 +14,12 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . +use discovery::{TableUpdates, NodeEntry}; +use ethereum_types::H512; +use ip_utils::*; +use network::{Error, ErrorKind, AllowIP, IpFilter}; +use rlp::{Rlp, RlpStream, DecoderError}; +use serde_json; use std::collections::{HashMap, HashSet}; use std::fmt::{self, Display, Formatter}; use std::hash::{Hash, Hasher}; @@ -23,12 +29,6 @@ use std::str::FromStr; use std::{fs, mem, slice}; use std::time::{self, Duration, SystemTime}; use rand::{self, Rng}; -use ethereum_types::H512; -use rlp::{Rlp, RlpStream, DecoderError}; -use network::{Error, ErrorKind, AllowIP, IpFilter}; -use discovery::{TableUpdates, NodeEntry}; -use ip_utils::*; -use serde_json; /// Node public key pub type NodeId = H512; @@ -124,8 +124,8 @@ impl FromStr for NodeEndpoint { address: a, udp_port: a.port() }), - Ok(_) => Err(ErrorKind::AddressResolve(None).into()), - Err(e) => Err(ErrorKind::AddressResolve(Some(e)).into()) + Ok(None) => bail!(ErrorKind::AddressResolve(None)), + Err(_) => Err(ErrorKind::AddressParse.into()) // always an io::Error of InvalidInput kind } } } @@ -534,11 +534,34 @@ mod tests { assert!(endpoint.is_ok()); let v4 = match endpoint.unwrap().address { SocketAddr::V4(v4address) => v4address, - _ => panic!("should ve v4 address") + _ => panic!("should be v4 address") }; assert_eq!(SocketAddrV4::new(Ipv4Addr::new(123, 99, 55, 44), 7770), v4); } + #[test] + fn endpoint_parse_empty_ip_string_returns_error() { + let endpoint = NodeEndpoint::from_str(""); + assert!(endpoint.is_err()); + assert_matches!(endpoint.unwrap_err().kind(), &ErrorKind::AddressParse); + } + + #[test] + fn endpoint_parse_invalid_ip_string_returns_error() { + let endpoint = NodeEndpoint::from_str("beef"); + assert!(endpoint.is_err()); + assert_matches!(endpoint.unwrap_err().kind(), &ErrorKind::AddressParse); + } + + #[test] + fn endpoint_parse_valid_ip_without_port_returns_error() { + let endpoint = NodeEndpoint::from_str("123.123.123.123"); + assert!(endpoint.is_err()); + assert_matches!(endpoint.unwrap_err().kind(), &ErrorKind::AddressParse); + let endpoint = NodeEndpoint::from_str("123.123.123.123:123"); + assert!(endpoint.is_ok()) + } + #[test] fn node_parse() { assert!(validate_node_url("enode://a979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c@22.99.55.44:7770").is_none()); @@ -555,6 +578,17 @@ mod tests { node.id); } + #[test] + fn node_parse_fails_for_invalid_urls() { + let node = Node::from_str("foo"); + assert!(node.is_err()); + assert_matches!(node.unwrap_err().kind(), &ErrorKind::AddressParse); + + let node = Node::from_str("enode://foo@bar"); + assert!(node.is_err()); + assert_matches!(node.unwrap_err().kind(), &ErrorKind::AddressParse); + } + #[test] fn table_last_contact_order() { let node1 = Node::from_str("enode://a979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c@22.99.55.44:7770").unwrap(); diff --git a/util/network/src/error.rs b/util/network/src/error.rs index 6342bfe4ad..6104486696 100644 --- a/util/network/src/error.rs +++ b/util/network/src/error.rs @@ -84,11 +84,16 @@ error_chain! { foreign_links { SocketIo(IoError) #[doc = "Socket IO error."]; Io(io::Error) #[doc = "Error concerning the Rust standard library's IO subsystem."]; - AddressParse(net::AddrParseError) #[doc = "Error concerning the network address parsing subsystem."]; Decompression(snappy::InvalidInput) #[doc = "Decompression error."]; } errors { + #[doc = "Error concerning the network address parsing subsystem."] + AddressParse { + description("Failed to parse network address"), + display("Failed to parse network address"), + } + #[doc = "Error concerning the network address resolution subsystem."] AddressResolve(err: Option) { description("Failed to resolve network address"), @@ -163,6 +168,10 @@ impl From for Error { } } +impl From for Error { + fn from(_err: net::AddrParseError) -> Self { ErrorKind::AddressParse.into() } +} + #[test] fn test_errors() { assert_eq!(DisconnectReason::ClientQuit, DisconnectReason::from_u8(8)); -- GitLab From cddc33bb24edf5e8b5d9052338965247829c5f4b Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Thu, 10 May 2018 00:41:56 +0800 Subject: [PATCH 022/152] Remove unnecessary cloning in overwrite_with (#8580) * Remove unnecessary cloning in overwrite_with * Remove into_iter --- ethcore/src/state/account.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ethcore/src/state/account.rs b/ethcore/src/state/account.rs index ff7d70bd3a..5c1dd40396 100644 --- a/ethcore/src/state/account.rs +++ b/ethcore/src/state/account.rs @@ -460,7 +460,7 @@ impl Account { self.address_hash = other.address_hash; let mut cache = self.storage_cache.borrow_mut(); for (k, v) in other.storage_cache.into_inner() { - cache.insert(k.clone() , v.clone()); //TODO: cloning should not be required here + cache.insert(k, v); } self.storage_changes = other.storage_changes; } -- GitLab From 1d42b7f0d1f44a3495f973704be494fd52644285 Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Wed, 9 May 2018 23:21:16 +0200 Subject: [PATCH 023/152] changelog nit (#8585) --- CHANGELOG.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0c7dcf878b..f839802e7c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,6 @@ Notable changes in reversed alphabetical order: - `whisper-cli` is a standalone tool to communicate with the Whisper protocol. - It provides functionality to specify `whisper-pool-size`, `port` and `address` to use. - All whisper RPC APIs are enabled and can be directly acessed. -I'm not used to writing these changelogs but I guess that would explain it - JSON-RPC API: **Return error in case eth_call returns VM errors** [#8448](https://github.com/paritytech/parity/pull/8448) - This changes the behaviors of `eth_call` to respect VM errors if any. - In case of `REVERT`, it will also return the reverted return data in hex format. -- GitLab From 21dad1d41ec3d1336a9a6a7c7e8eb4c9194dc2bd Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Wed, 9 May 2018 23:25:58 +0200 Subject: [PATCH 024/152] Rename `whisper-cli binary` to `whisper` (#8579) * rename whisper-cli binary to whisper * fix tests --- whisper/cli/Cargo.toml | 4 +++- whisper/cli/src/main.rs | 12 ++++++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/whisper/cli/Cargo.toml b/whisper/cli/Cargo.toml index 363471a1a3..9aea1a8776 100644 --- a/whisper/cli/Cargo.toml +++ b/whisper/cli/Cargo.toml @@ -1,7 +1,9 @@ [package] name = "whisper-cli" +description = "Whisper command line interface" version = "0.1.0" authors = ["Parity Technologies "] +license = "GPL-3.0" [dependencies] ethcore-network-devp2p = { path = "../../util/network-devp2p" } @@ -18,5 +20,5 @@ jsonrpc-http-server = { git = "https://github.com/paritytech/jsonrpc.git", branc log = "0.3" [[bin]] -name = "whisper-cli" +name = "whisper" path = "src/main.rs" diff --git a/whisper/cli/src/main.rs b/whisper/cli/src/main.rs index d0866cd66a..f9211b993b 100644 --- a/whisper/cli/src/main.rs +++ b/whisper/cli/src/main.rs @@ -46,7 +46,7 @@ use jsonrpc_http_server::{AccessControlAllowOrigin, DomainsValidation}; const POOL_UNIT: usize = 1024 * 1024; const USAGE: &'static str = r#" Whisper CLI. - Copyright 2017 Parity Technologies (UK) Ltd + Copyright 2018 Parity Technologies (UK) Ltd Usage: whisper [options] @@ -56,7 +56,7 @@ Options: --whisper-pool-size SIZE Specify Whisper pool size [default: 10]. -p, --port PORT Specify which RPC port to use [default: 8545]. -a, --address ADDRESS Specify which address to use [default: 127.0.0.1]. - -l, --log LEVEL Specify the logging level. Must conform to the same format as RUST_LOG [default: Error]. + -l, --log LEVEL Specify the logging level. Must conform to the same format as RUST_LOG [default: Error]. -h, --help Display this message and exit. "#; @@ -259,7 +259,7 @@ mod tests { #[test] fn invalid_argument() { - let command = vec!["whisper-cli", "--foo=12"] + let command = vec!["whisper", "--foo=12"] .into_iter() .map(Into::into) .collect::>(); @@ -270,7 +270,7 @@ mod tests { #[test] #[ignore] fn privileged_port() { - let command = vec!["whisper-cli", "--port=3"] + let command = vec!["whisper", "--port=3"] .into_iter() .map(Into::into) .collect::>(); @@ -280,7 +280,7 @@ mod tests { #[test] fn invalid_ip_address() { - let command = vec!["whisper-cli", "--address=x.x.x.x"] + let command = vec!["whisper", "--address=x.x.x.x"] .into_iter() .map(Into::into) .collect::>(); @@ -290,7 +290,7 @@ mod tests { #[test] fn invalid_whisper_pool_size() { - let command = vec!["whisper-cli", "--whisper-pool-size=-100000000000000000000000000000000000000"] + let command = vec!["whisper", "--whisper-pool-size=-100000000000000000000000000000000000000"] .into_iter() .map(Into::into) .collect::>(); -- GitLab From b2cc1c54f891c35364627757280ee33e836987ef Mon Sep 17 00:00:00 2001 From: Afri Schoedon <5chdn@users.noreply.github.com> Date: Wed, 9 May 2018 23:26:30 +0200 Subject: [PATCH 025/152] Add whisper CLI to the pipelines (#8578) * Add whisper CLI to the pipelines * Address todo, ref #8579 --- scripts/gitlab-build.sh | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/scripts/gitlab-build.sh b/scripts/gitlab-build.sh index 89fa2a0854..2f1b7b8d08 100755 --- a/scripts/gitlab-build.sh +++ b/scripts/gitlab-build.sh @@ -62,13 +62,16 @@ build () { cargo build --target $PLATFORM --release -p ethstore-cli echo "Build ethkey-cli:" cargo build --target $PLATFORM --release -p ethkey-cli + echo "Build whisper-cli:" + cargo build --target $PLATFORM --release -p whisper-cli } strip_binaries () { echo "Strip binaries:" $STRIP_BIN -v target/$PLATFORM/release/parity $STRIP_BIN -v target/$PLATFORM/release/parity-evm $STRIP_BIN -v target/$PLATFORM/release/ethstore - $STRIP_BIN -v target/$PLATFORM/release/ethkey; + $STRIP_BIN -v target/$PLATFORM/release/ethkey + $STRIP_BIN -v target/$PLATFORM/release/whisper; } calculate_checksums () { echo "Checksum calculation:" @@ -89,6 +92,8 @@ calculate_checksums () { $SHA256_BIN target/$PLATFORM/release/ethstore$S3WIN > ethstore$S3WIN.sha256 $MD5_BIN target/$PLATFORM/release/ethkey$S3WIN > ethkey$S3WIN.md5 $SHA256_BIN target/$PLATFORM/release/ethkey$S3WIN > ethkey$S3WIN.sha256 + $MD5_BIN target/$PLATFORM/release/whisper$S3WIN > whisper$S3WIN.md5 + $SHA256_BIN target/$PLATFORM/release/whisper$S3WIN > whisper$S3WIN.sha256 } make_deb () { rm -rf deb @@ -122,6 +127,7 @@ make_deb () { cp target/$PLATFORM/release/parity-evm deb/usr/bin/parity-evm cp target/$PLATFORM/release/ethstore deb/usr/bin/ethstore cp target/$PLATFORM/release/ethkey deb/usr/bin/ethkey + cp target/$PLATFORM/release/whisper deb/usr/bin/whisper dpkg-deb -b deb "parity_"$VER"_"$IDENT"_"$ARC".deb" $MD5_BIN "parity_"$VER"_"$IDENT"_"$ARC".deb" > "parity_"$VER"_"$IDENT"_"$ARC".deb.md5" $SHA256_BIN "parity_"$VER"_"$IDENT"_"$ARC".deb" > "parity_"$VER"_"$IDENT"_"$ARC".deb.sha256" @@ -133,6 +139,7 @@ make_rpm () { cp target/$PLATFORM/release/parity-evm /install/usr/bin/parity-evm cp target/$PLATFORM/release/ethstore /install/usr/bin/ethstore cp target/$PLATFORM/release/ethkey /install/usr/bin/ethkey + cp target/$PLATFORM/release/whisper /install/usr/bin/whisper rm -rf "parity-"$VER"-1."$ARC".rpm" || true fpm -s dir -t rpm -n parity -v $VER --epoch 1 --license GPLv3 -d openssl --provides parity --url https://parity.io --vendor "Parity Technologies" -a x86_64 -m "" --description "Ethereum network client by Parity Technologies" -C /install/ @@ -146,6 +153,7 @@ make_pkg () { cp target/$PLATFORM/release/parity-evm target/release/parity-evm cp target/$PLATFORM/release/ethstore target/release/ethstore cp target/$PLATFORM/release/ethkey target/release/ethkey + cp target/$PLATFORM/release/whisper target/release/whisper cd mac xcodebuild -configuration Release cd .. @@ -194,6 +202,9 @@ push_binaries () { aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/$BUILD_PLATFORM/ethkey$S3WIN --body target/$PLATFORM/release/ethkey$S3WIN aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/$BUILD_PLATFORM/ethkey$S3WIN.md5 --body ethkey$S3WIN.md5 aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/$BUILD_PLATFORM/ethkey$S3WIN.sha256 --body ethkey$S3WIN.sha256 + aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/$BUILD_PLATFORM/whisper$S3WIN --body target/$PLATFORM/release/whisper$S3WIN + aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/$BUILD_PLATFORM/whisper$S3WIN.md5 --body whisper$S3WIN.md5 + aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/$BUILD_PLATFORM/whisper$S3WIN.sha256 --body whisper$S3WIN.sha256 aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/$BUILD_PLATFORM/"parity_"$VER"_"$IDENT"_"$ARC"."$EXT --body "parity_"$VER"_"$IDENT"_"$ARC"."$EXT aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/$BUILD_PLATFORM/"parity_"$VER"_"$IDENT"_"$ARC"."$EXT".md5" --body "parity_"$VER"_"$IDENT"_"$ARC"."$EXT".md5" aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/$BUILD_PLATFORM/"parity_"$VER"_"$IDENT"_"$ARC"."$EXT".sha256" --body "parity_"$VER"_"$IDENT"_"$ARC"."$EXT".sha256" @@ -201,7 +212,7 @@ push_binaries () { make_archive () { echo "add artifacts to archive" rm -rf parity.zip - zip -r parity.zip target/$PLATFORM/release/parity$S3WIN target/$PLATFORM/release/parity-evm$S3WIN target/$PLATFORM/release/ethstore$S3WIN target/$PLATFORM/release/ethkey$S3WIN parity$S3WIN.md5 parity-evm$S3WIN.md5 ethstore$S3WIN.md5 ethkey$S3WIN.md5 parity$S3WIN.sha256 parity-evm$S3WIN.sha256 ethstore$S3WIN.sha256 ethkey$S3WIN.sha256 + zip -r parity.zip target/$PLATFORM/release/parity$S3WIN target/$PLATFORM/release/parity-evm$S3WIN target/$PLATFORM/release/ethstore$S3WIN target/$PLATFORM/release/ethkey$S3WIN target/$PLATFORM/release/whisper$S3WIN parity$S3WIN.md5 parity-evm$S3WIN.md5 ethstore$S3WIN.md5 ethkey$S3WIN.md5 whisper$S3WIN.md5 parity$S3WIN.sha256 parity-evm$S3WIN.sha256 ethstore$S3WIN.sha256 ethkey$S3WIN.sha256 whisper$S3WIN.sha256 } updater_push_release () { -- GitLab From a57c45bb1c79799a5ec68dd30eedb755545809bc Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Wed, 9 May 2018 23:28:16 +0200 Subject: [PATCH 026/152] Added Dockerfile for alpine linux by @andresilva, closes #3565 (#8587) --- docker/alpine/Dockerfile | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 docker/alpine/Dockerfile diff --git a/docker/alpine/Dockerfile b/docker/alpine/Dockerfile new file mode 100644 index 0000000000..ad8879ecf7 --- /dev/null +++ b/docker/alpine/Dockerfile @@ -0,0 +1,29 @@ +FROM alpine:3.7 + +WORKDIR /build + +# install tools and dependencies +RUN apk add --no-cache gcc musl-dev openssl-dev pkgconfig g++ make curl \ + eudev-dev rust cargo git file binutils libusb-dev \ + linux-headers + +# show backtraces +ENV RUST_BACKTRACE 1 + +# show tools +RUN rustc -vV && \ +cargo -V && \ +gcc -v &&\ +g++ -v + +# build parity +ADD . /build/parity +RUN cd parity && \ + cargo build --release --verbose && \ + ls /build/parity/target/release/parity && \ + strip /build/parity/target/release/parity + +RUN file /build/parity/target/release/parity + +EXPOSE 8080 8545 8180 +ENTRYPOINT ["/build/parity/target/release/parity"] -- GitLab From fb0e6cf0d0759bf0f0657f9995b666e1d9ec3e7b Mon Sep 17 00:00:00 2001 From: Afri Schoedon <5chdn@users.noreply.github.com> Date: Thu, 10 May 2018 12:33:40 +0200 Subject: [PATCH 027/152] Changelog and Readme (#8591) * Move changelog for 1.10.x * Mark 1.9 EOL * Prepare changelog for 1.10.3 stable * Prepare changelog for 1.11.0 stable * Update changelogs * Update CHANGELOG for 1.10.3 beta * Update CHANGELOG for 1.11.0 beta * Update CHANGELOG for 1.11.0 beta * Update CHANGELOG for 1.11.0 beta * Format changelog * Update README for 1.11 * Fix typo --- README.md | 29 ++++++----------------------- 1 file changed, 6 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index bfa7bde7bf..36e855fe42 100644 --- a/README.md +++ b/README.md @@ -19,9 +19,7 @@ Get in touch with us on Gitter: Or join our community on Matrix: [![Riot: +Parity](https://img.shields.io/badge/riot-%2Bparity%3Amatrix.parity.io-orange.svg)](https://riot.im/app/#/group/+parity:matrix.parity.io) -Official website: https://parity.io - -Be sure to check out [our wiki](https://wiki.parity.io) for more information. +Official website: https://parity.io | Be sure to check out [our wiki](https://wiki.parity.io) for more information. ---- @@ -29,28 +27,19 @@ Be sure to check out [our wiki](https://wiki.parity.io) for more information. Parity's goal is to be the fastest, lightest, and most secure Ethereum client. We are developing Parity using the sophisticated and cutting-edge Rust programming language. Parity is licensed under the GPLv3, and can be used for all your Ethereum needs. -Parity comes with a built-in wallet, to install it please follow [these instructions](https://wiki.parity.io/Parity-Wallet). It includes various functionality allowing you to: - -- create and manage your Ethereum accounts; -- manage your Ether and any Ethereum tokens; -- create and register your own tokens; -- and much more. - -From Parity Ethereum client version >=1.10, the User Interface (UI) is accessible in a separate application called Parity UI. To keep using the UI in the browser (deprecated), [follow these steps](https://wiki.parity.io/FAQ-Basic-Operations,-Configuration,-and-Synchronization.md#the-parity-ui-application-isnt-working-the-way-i-want). +From Parity Ethereum client version 1.10.0, the User Interface (UI) is accessible in a separate application called Parity UI. To keep using the UI in the browser (deprecated), [follow these steps](https://wiki.parity.io/FAQ-Basic-Operations,-Configuration,-and-Synchronization.md#the-parity-ui-application-isnt-working-the-way-i-want). By default, Parity will also run a JSONRPC server on `127.0.0.1:8545` and a websockets server on `127.0.0.1:8546`. This is fully configurable and supports a number of APIs. -If you run into an issue while using Parity, feel free to file one in this repository or hop on our [Gitter](https://gitter.im/paritytech/parity) or [Riot](https://riot.im/app/#/group/+parity:matrix.parity.io) chat room to ask a question. We are glad to help! - -**For security-critical issues**, please refer to the security policy outlined in [SECURITY.MD](SECURITY.md). +If you run into an issue while using Parity, feel free to file one in this repository or hop on our [Gitter](https://gitter.im/paritytech/parity) or [Riot](https://riot.im/app/#/group/+parity:matrix.parity.io) chat room to ask a question. We are glad to help! **For security-critical issues**, please refer to the security policy outlined in [SECURITY.MD](SECURITY.md). -Parity's current release is 1.9. You can download it at https://github.com/paritytech/parity/releases or follow the instructions below to build from source. +Parity's current beta-release is 1.11. You can download it at https://github.com/paritytech/parity/releases or follow the instructions below to build from source. ---- ## Build dependencies -**Parity requires Rust version 1.23.0 to build** +**Parity requires Rust version 1.26.0 to build** We recommend installing Rust through [rustup](https://www.rustup.rs/). If you don't already have rustup, you can install it like this: @@ -124,13 +113,7 @@ Note: if cargo fails to parse manifest try: $ ~/.cargo/bin/cargo build --release ``` -Note: When compiling a crate and you receive the following error: - -``` -error: the crate is compiled with the panic strategy `abort` which is incompatible with this crate's strategy of `unwind` -``` - -Cleaning the repository will most likely solve the issue, try: +Note, when compiling a crate and you receive errors, it's in most cases your outdated version of Rust, or some of your crates have to be recompiled. Cleaning the repository will most likely solve the issue if you are on the latest stable version of Rust, try: ```bash $ cargo clean -- GitLab From 6e2e08628a91ae248729030e3ece3b8e926c805f Mon Sep 17 00:00:00 2001 From: David Date: Thu, 10 May 2018 12:33:56 +0200 Subject: [PATCH 028/152] Attempt to fix intermittent test failures (#8584) Occasionally should_return_correct_nonces_when_dropped_because_of_limit fails, possibly because of multiple threads competing to finish. See CI logs here for an example: https://gitlab.parity.io/parity/parity/-/jobs/86738 --- miner/src/pool/tests/mod.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/miner/src/pool/tests/mod.rs b/miner/src/pool/tests/mod.rs index 0d8e38a6e1..5d80c2d5bf 100644 --- a/miner/src/pool/tests/mod.rs +++ b/miner/src/pool/tests/mod.rs @@ -63,8 +63,10 @@ fn should_return_correct_nonces_when_dropped_because_of_limit() { let nonce = tx1.nonce; // when - let result = txq.import(TestClient::new(), vec![tx1, tx2].local()); - assert_eq!(result, vec![Ok(()), Err(transaction::Error::LimitReached)]); + let r1= txq.import(TestClient::new(), vec![tx1].local()); + let r2= txq.import(TestClient::new(), vec![tx2].local()); + assert_eq!(r1, vec![Ok(())]); + assert_eq!(r2, vec![Err(transaction::Error::LimitReached)]); assert_eq!(txq.status().status.transaction_count, 1); // then -- GitLab From 1b8f299df2e6a29738a090c47911cc218db49b8d Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Thu, 10 May 2018 12:34:36 +0200 Subject: [PATCH 029/152] Make mio optional in ethcore-io (#8537) * Make mio optional in ethcore-io * Add some annotations, plus a check for features * Increase timer for test --- Cargo.lock | 46 ++- ethcore/sync/Cargo.toml | 1 + test.sh | 2 + util/io/Cargo.toml | 9 +- util/io/src/lib.rs | 145 +++++++-- util/io/src/{service.rs => service_mio.rs} | 16 +- util/io/src/service_non_mio.rs | 334 +++++++++++++++++++++ util/io/src/worker.rs | 11 +- util/network-devp2p/Cargo.toml | 2 +- 9 files changed, 508 insertions(+), 58 deletions(-) rename util/io/src/{service.rs => service_mio.rs} (97%) create mode 100644 util/io/src/service_non_mio.rs diff --git a/Cargo.lock b/Cargo.lock index edd76f9f4d..b4d6bd315f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -209,6 +209,16 @@ dependencies = [ "serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "chrono" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num-integer 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "cid" version = "0.2.3" @@ -542,7 +552,7 @@ dependencies = [ "memory-cache 0.1.0", "memorydb 0.1.1", "num 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-machine 0.1.0", "parking_lot 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "patricia-trie 0.1.0", @@ -597,10 +607,14 @@ name = "ethcore-io" version = "1.12.0" dependencies = [ "crossbeam 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", + "timer 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -991,7 +1005,7 @@ dependencies = [ "dir 0.1.0", "docopt 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)", "ethstore 0.2.0", - "num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "panic_hook 0.1.0", "parking_lot 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1117,7 +1131,7 @@ version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1483,7 +1497,7 @@ dependencies = [ "interleaved-ordered 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb 0.1.0", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "regex 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", "rocksdb 0.4.5 (git+https://github.com/paritytech/rust-rocksdb)", @@ -1888,7 +1902,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "num_cpus" -version = "1.7.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1981,7 +1995,7 @@ dependencies = [ "migration-rocksdb 0.1.0", "node-filter 1.12.0", "node-health 0.1.0", - "num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "number_prefix 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", "panic_hook 0.1.0", "parity-dapps 1.12.0", @@ -2680,7 +2694,7 @@ dependencies = [ "crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3183,7 +3197,7 @@ name = "threadpool" version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3197,6 +3211,14 @@ dependencies = [ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "timer" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "chrono 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "tiny-keccak" version = "1.4.1" @@ -3350,7 +3372,7 @@ dependencies = [ "crossbeam-deque 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-executor 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3795,6 +3817,7 @@ dependencies = [ "checksum bytes 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "1b7db437d718977f6dc9b2e3fd6fc343c02ac6b899b73fdd2179163447bd9ce9" "checksum cc 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)" = "8b9d2900f78631a5876dc5d6c9033ede027253efcd33dd36b1309fc6cab97ee0" "checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de" +"checksum chrono 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1cce36c92cb605414e9b824f866f5babe0a0368e39ea07393b9b63cf3844c0e6" "checksum cid 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d85ee025368e69063c420cbb2ed9f852cb03a5e69b73be021e65726ce03585b6" "checksum clap 2.29.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8f4a2b3bb7ef3c672d7c13d15613211d5a6976b6892c598b0fcb5d40765f19c2" "checksum conv 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "78ff10625fd0ac447827aa30ea8b861fead473bb60aeb73af6c1c58caf0d1299" @@ -3903,7 +3926,7 @@ dependencies = [ "checksum num-iter 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "4b226df12c5a59b63569dd57fafb926d91b385dfce33d8074a412411b689d593" "checksum num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31" "checksum num-traits 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dee092fcdf725aee04dd7da1d21debff559237d49ef1cb3e69bcb8ece44c7364" -"checksum num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "514f0d73e64be53ff320680ca671b64fe3fb91da01e1ae2ddc99eb51d453b20d" +"checksum num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c51a3322e4bca9d212ad9a158a02abc6934d005490c054a2778df73a70aa0a30" "checksum number_prefix 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "59a14be9c211cb9c602bad35ac99f41e9a84b44d71b8cbd3040e3bd02a214902" "checksum ole32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5d2c49021782e5233cd243168edfa8037574afed4eba4bbaf538b3d8d1789d8c" "checksum order-stat 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "efa535d5117d3661134dbf1719b6f0ffe06f2375843b13935db186cd094105eb" @@ -4001,6 +4024,7 @@ dependencies = [ "checksum thread_local 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1697c4b57aeeb7a536b647165a2825faddffb1d3bad386d507709bd51a90bb14" "checksum threadpool 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e2f0c90a5f3459330ac8bc0d2f879c693bb7a2f59689c1083fc4ef83834da865" "checksum time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)" = "d5d788d3aa77bc0ef3e9621256885555368b47bd495c13dd2e7413c89f845520" +"checksum timer 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "31d42176308937165701f50638db1c31586f183f1aab416268216577aec7306b" "checksum tiny-keccak 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "58911ed5eb275a8fd2f1f0418ed360a42f59329864b64e1e95377a9024498c01" "checksum tokio 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "be15ef40f675c9fe66e354d74c73f3ed012ca1aa14d65846a33ee48f1ae8d922" "checksum tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "aeeffbbb94209023feaef3c196a41cbcdafa06b4a6f893f68779bb5e53796f71" diff --git a/ethcore/sync/Cargo.toml b/ethcore/sync/Cargo.toml index ba03075d0e..cf163cc7bd 100644 --- a/ethcore/sync/Cargo.toml +++ b/ethcore/sync/Cargo.toml @@ -34,6 +34,7 @@ trace-time = { path = "../../util/trace-time" } ipnetwork = "0.12.6" [dev-dependencies] +ethcore-io = { path = "../../util/io", features = ["mio"] } ethkey = { path = "../../ethkey" } kvdb-memorydb = { path = "../../util/kvdb-memorydb" } ethcore-private-tx = { path = "../private-tx" } diff --git a/test.sh b/test.sh index 6dcd258ea3..9bb527b708 100755 --- a/test.sh +++ b/test.sh @@ -33,6 +33,8 @@ if [ "$VALIDATE" -eq "1" ]; then # Validate --no-default-features build echo "________Validate build________" cargo check --no-default-features +cargo check --manifest-path util/io/Cargo.toml --no-default-features +cargo check --manifest-path util/io/Cargo.toml --features "mio" # Validate chainspecs echo "________Validate chainspecs________" diff --git a/util/io/Cargo.toml b/util/io/Cargo.toml index 8538863d03..7168866160 100644 --- a/util/io/Cargo.toml +++ b/util/io/Cargo.toml @@ -7,9 +7,12 @@ version = "1.12.0" authors = ["Parity Technologies "] [dependencies] -mio = "0.6.8" +fnv = "1.0" +mio = { version = "0.6.8", optional = true } crossbeam = "0.3" parking_lot = "0.5" log = "0.3" -slab = "0.2" - +slab = "0.4" +num_cpus = "1.8" +timer = "0.2" +time = "0.1" diff --git a/util/io/src/lib.rs b/util/io/src/lib.rs index 9232b2a909..ef8c3adc7e 100644 --- a/util/io/src/lib.rs +++ b/util/io/src/lib.rs @@ -54,30 +54,59 @@ //! // Drop the service //! } //! ``` +//! +//! # Mio vs non-mio +//! +//! This library has two modes: mio and not mio. The `mio` feature can be activated or deactivated +//! when compiling or depending on the library. +//! +//! Without mio, only timers and message-passing are available. With mio, you can also use +//! low-level sockets provided by mio. +//! +//! The non-mio mode exists because the `mio` library doesn't compile on platforms such as +//! emscripten. //TODO: use Poll from mio #![allow(deprecated)] +#[cfg(feature = "mio")] extern crate mio; #[macro_use] extern crate log as rlog; extern crate slab; extern crate crossbeam; extern crate parking_lot; +extern crate num_cpus; +extern crate timer; +extern crate fnv; +extern crate time; -mod service; +#[cfg(feature = "mio")] +mod service_mio; +#[cfg(not(feature = "mio"))] +mod service_non_mio; +#[cfg(feature = "mio")] mod worker; +use std::cell::Cell; use std::{fmt, error}; +#[cfg(feature = "mio")] use mio::deprecated::{EventLoop, NotifyError}; +#[cfg(feature = "mio")] use mio::Token; -pub use worker::LOCAL_STACK_SIZE; +thread_local! { + /// Stack size + /// Should be modified if it is changed in Rust since it is no way + /// to know or get it + pub static LOCAL_STACK_SIZE: Cell = Cell::new(::std::env::var("RUST_MIN_STACK").ok().and_then(|s| s.parse().ok()).unwrap_or(2 * 1024 * 1024)); +} #[derive(Debug)] /// IO Error pub enum IoError { /// Low level error from mio crate + #[cfg(feature = "mio")] Mio(::std::io::Error), /// Error concerning the Rust standard library's IO subsystem. StdIo(::std::io::Error), @@ -88,6 +117,7 @@ impl fmt::Display for IoError { // just defer to the std implementation for now. // we can refine the formatting when more variants are added. match *self { + #[cfg(feature = "mio")] IoError::Mio(ref std_err) => std_err.fmt(f), IoError::StdIo(ref std_err) => std_err.fmt(f), } @@ -106,8 +136,9 @@ impl From<::std::io::Error> for IoError { } } -impl From>> for IoError where Message: Send { - fn from(_err: NotifyError>) -> IoError { +#[cfg(feature = "mio")] +impl From>> for IoError where Message: Send { + fn from(_err: NotifyError>) -> IoError { IoError::Mio(::std::io::Error::new(::std::io::ErrorKind::ConnectionAborted, "Network IO notification error")) } } @@ -123,58 +154,120 @@ pub trait IoHandler: Send + Sync where Message: Send + Sync + 'static { /// Called when a broadcasted message is received. The message can only be sent from a different IO handler. fn message(&self, _io: &IoContext, _message: &Message) {} /// Called when an IO stream gets closed + #[cfg(feature = "mio")] fn stream_hup(&self, _io: &IoContext, _stream: StreamToken) {} /// Called when an IO stream can be read from + #[cfg(feature = "mio")] fn stream_readable(&self, _io: &IoContext, _stream: StreamToken) {} /// Called when an IO stream can be written to + #[cfg(feature = "mio")] fn stream_writable(&self, _io: &IoContext, _stream: StreamToken) {} /// Register a new stream with the event loop + #[cfg(feature = "mio")] fn register_stream(&self, _stream: StreamToken, _reg: Token, _event_loop: &mut EventLoop>) {} /// Re-register a stream with the event loop + #[cfg(feature = "mio")] fn update_stream(&self, _stream: StreamToken, _reg: Token, _event_loop: &mut EventLoop>) {} /// Deregister a stream. Called whenstream is removed from event loop + #[cfg(feature = "mio")] fn deregister_stream(&self, _stream: StreamToken, _event_loop: &mut EventLoop>) {} } -pub use service::TimerToken; -pub use service::StreamToken; -pub use service::IoContext; -pub use service::IoService; -pub use service::IoChannel; -pub use service::IoManager; -pub use service::TOKENS_PER_HANDLER; +#[cfg(feature = "mio")] +pub use service_mio::{TimerToken, StreamToken, IoContext, IoService, IoChannel, IoManager, TOKENS_PER_HANDLER}; +#[cfg(not(feature = "mio"))] +pub use service_non_mio::{TimerToken, IoContext, IoService, IoChannel, TOKENS_PER_HANDLER}; #[cfg(test)] mod tests { - use std::sync::Arc; + use std::sync::atomic; + use std::thread; use std::time::Duration; use super::*; - struct MyHandler; + #[test] + fn send_message_to_handler() { + struct MyHandler(atomic::AtomicBool); - #[derive(Clone)] - struct MyMessage { - data: u32 - } + #[derive(Clone)] + struct MyMessage { + data: u32 + } - impl IoHandler for MyHandler { - fn initialize(&self, io: &IoContext) { - io.register_timer(0, Duration::from_secs(1)).unwrap(); + impl IoHandler for MyHandler { + fn message(&self, _io: &IoContext, message: &MyMessage) { + assert_eq!(message.data, 5); + self.0.store(true, atomic::Ordering::SeqCst); + } } - fn timeout(&self, _io: &IoContext, timer: TimerToken) { - println!("Timeout {}", timer); + let handler = Arc::new(MyHandler(atomic::AtomicBool::new(false))); + + let service = IoService::::start().expect("Error creating network service"); + service.register_handler(handler.clone()).unwrap(); + + service.send_message(MyMessage { data: 5 }).unwrap(); + + thread::sleep(Duration::from_secs(5)); + assert!(handler.0.load(atomic::Ordering::SeqCst)); + } + + #[test] + fn timeout_working() { + struct MyHandler(atomic::AtomicBool); + + #[derive(Clone)] + struct MyMessage { + data: u32 } - fn message(&self, _io: &IoContext, message: &MyMessage) { - println!("Message {}", message.data); + impl IoHandler for MyHandler { + fn initialize(&self, io: &IoContext) { + io.register_timer_once(1234, Duration::from_millis(500)).unwrap(); + } + + fn timeout(&self, _io: &IoContext, timer: TimerToken) { + assert_eq!(timer, 1234); + assert!(!self.0.swap(true, atomic::Ordering::SeqCst)); + } } + + let handler = Arc::new(MyHandler(atomic::AtomicBool::new(false))); + + let service = IoService::::start().expect("Error creating network service"); + service.register_handler(handler.clone()).unwrap(); + + thread::sleep(Duration::from_secs(2)); + assert!(handler.0.load(atomic::Ordering::SeqCst)); } #[test] - fn test_service_register_handler () { + fn multi_timeout_working() { + struct MyHandler(atomic::AtomicUsize); + + #[derive(Clone)] + struct MyMessage { + data: u32 + } + + impl IoHandler for MyHandler { + fn initialize(&self, io: &IoContext) { + io.register_timer(1234, Duration::from_millis(500)).unwrap(); + } + + fn timeout(&self, _io: &IoContext, timer: TimerToken) { + assert_eq!(timer, 1234); + self.0.fetch_add(1, atomic::Ordering::SeqCst); + } + } + + let handler = Arc::new(MyHandler(atomic::AtomicUsize::new(0))); + let service = IoService::::start().expect("Error creating network service"); - service.register_handler(Arc::new(MyHandler)).unwrap(); + service.register_handler(handler.clone()).unwrap(); + + thread::sleep(Duration::from_secs(2)); + assert!(handler.0.load(atomic::Ordering::SeqCst) >= 2); } } diff --git a/util/io/src/service.rs b/util/io/src/service_mio.rs similarity index 97% rename from util/io/src/service.rs rename to util/io/src/service_mio.rs index 0de674ae12..f7c9f1976c 100644 --- a/util/io/src/service.rs +++ b/util/io/src/service_mio.rs @@ -181,7 +181,7 @@ struct UserTimer { /// Root IO handler. Manages user handlers, messages and IO timers. pub struct IoManager where Message: Send + Sync { timers: Arc>>, - handlers: Arc>, HandlerId>>>, + handlers: Arc>>>>, workers: Vec, worker_channel: chase_lev::Worker>, work_ready: Arc, @@ -191,7 +191,7 @@ impl IoManager where Message: Send + Sync + 'static { /// Creates a new instance and registers it with the event loop. pub fn start( event_loop: &mut EventLoop>, - handlers: Arc>, HandlerId>>> + handlers: Arc>>>> ) -> Result<(), IoError> { let (worker, stealer) = chase_lev::deque(); let num_workers = 4; @@ -267,7 +267,8 @@ impl Handler for IoManager where Message: Send + Sync + 'stati event_loop.shutdown(); }, IoMessage::AddHandler { handler } => { - let handler_id = self.handlers.write().insert(handler.clone()).unwrap_or_else(|_| panic!("Too many handlers registered")); + let handler_id = self.handlers.write().insert(handler.clone()); + assert!(handler_id <= MAX_HANDLERS, "Too many handlers registered"); handler.initialize(&IoContext::new(IoChannel::new(event_loop.channel(), Arc::downgrade(&self.handlers)), handler_id)); }, IoMessage::RemoveHandler { handler_id } => { @@ -332,7 +333,7 @@ impl Handler for IoManager where Message: Send + Sync + 'stati } enum Handlers where Message: Send { - SharedCollection(Weak>, HandlerId>>>), + SharedCollection(Weak>>>>), Single(Weak>), } @@ -417,7 +418,7 @@ impl IoChannel where Message: Send + Sync + 'static { handlers: Handlers::Single(handler), } } - fn new(channel: Sender>, handlers: Weak>, HandlerId>>>) -> IoChannel { + fn new(channel: Sender>, handlers: Weak>>>>) -> IoChannel { IoChannel { channel: Some(channel), handlers: Handlers::SharedCollection(handlers), @@ -430,7 +431,7 @@ impl IoChannel where Message: Send + Sync + 'static { pub struct IoService where Message: Send + Sync + 'static { thread: Mutex>>, host_channel: Mutex>>, - handlers: Arc>, HandlerId>>>, + handlers: Arc>>>>, } impl IoService where Message: Send + Sync + 'static { @@ -440,7 +441,7 @@ impl IoService where Message: Send + Sync + 'static { config.messages_per_tick(1024); let mut event_loop = config.build().expect("Error creating event loop"); let channel = event_loop.channel(); - let handlers = Arc::new(RwLock::new(Slab::new(MAX_HANDLERS))); + let handlers = Arc::new(RwLock::new(Slab::with_capacity(MAX_HANDLERS))); let h = handlers.clone(); let thread = thread::spawn(move || { IoManager::::start(&mut event_loop, h).expect("Error starting IO service"); @@ -491,4 +492,3 @@ impl Drop for IoService where Message: Send + Sync { self.stop() } } - diff --git a/util/io/src/service_non_mio.rs b/util/io/src/service_non_mio.rs new file mode 100644 index 0000000000..22a795e4e8 --- /dev/null +++ b/util/io/src/service_non_mio.rs @@ -0,0 +1,334 @@ +// 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 . + +use std::sync::{Arc, Weak}; +use std::thread; +use crossbeam::sync::chase_lev; +use slab::Slab; +use fnv::FnvHashMap; +use {IoError, IoHandler}; +use parking_lot::{RwLock, Mutex}; +use num_cpus; +use std::time::Duration; +use timer::{Timer, Guard as TimerGuard}; +use time::Duration as TimeDuration; + +/// Timer ID +pub type TimerToken = usize; +/// IO Handler ID +pub type HandlerId = usize; + +/// Maximum number of tokens a handler can use +pub const TOKENS_PER_HANDLER: usize = 16384; +const MAX_HANDLERS: usize = 8; + +/// IO access point. This is passed to all IO handlers and provides an interface to the IO subsystem. +pub struct IoContext where Message: Send + Sync + 'static { + handler: HandlerId, + shared: Arc>, +} + +impl IoContext where Message: Send + Sync + 'static { + /// Register a new recurring IO timer. 'IoHandler::timeout' will be called with the token. + pub fn register_timer(&self, token: TimerToken, delay: Duration) -> Result<(), IoError> { + let channel = self.channel(); + + let msg = WorkTask::TimerTrigger { + handler_id: self.handler, + token: token, + }; + + let delay = TimeDuration::from_std(delay) + .map_err(|e| ::std::io::Error::new(::std::io::ErrorKind::Other, e))?; + let guard = self.shared.timer.lock().schedule_repeating(delay, move || { + channel.send_raw(msg.clone()); + }); + + self.shared.timers.lock().insert(token, guard); + + Ok(()) + } + + /// Register a new IO timer once. 'IoHandler::timeout' will be called with the token. + pub fn register_timer_once(&self, token: TimerToken, delay: Duration) -> Result<(), IoError> { + let channel = self.channel(); + + let msg = WorkTask::TimerTrigger { + handler_id: self.handler, + token: token, + }; + + let delay = TimeDuration::from_std(delay) + .map_err(|e| ::std::io::Error::new(::std::io::ErrorKind::Other, e))?; + let guard = self.shared.timer.lock().schedule_with_delay(delay, move || { + channel.send_raw(msg.clone()); + }); + + self.shared.timers.lock().insert(token, guard); + + Ok(()) + } + + /// Delete a timer. + pub fn clear_timer(&self, token: TimerToken) -> Result<(), IoError> { + self.shared.timers.lock().remove(&token); + Ok(()) + } + + /// Broadcast a message to other IO clients + pub fn message(&self, message: Message) -> Result<(), IoError> { + if let Some(ref channel) = *self.shared.channel.lock() { + channel.push(WorkTask::UserMessage(Arc::new(message))); + } + for thread in self.shared.threads.read().iter() { + thread.unpark(); + } + + Ok(()) + } + + /// Get message channel + pub fn channel(&self) -> IoChannel { + IoChannel { shared: Arc::downgrade(&self.shared) } + } + + /// Unregister current IO handler. + pub fn unregister_handler(&self) -> Result<(), IoError> { + self.shared.handlers.write().remove(self.handler); + Ok(()) + } +} + +/// Allows sending messages into the event loop. All the IO handlers will get the message +/// in the `message` callback. +pub struct IoChannel where Message: Send + Sync + 'static { + shared: Weak>, +} + +impl Clone for IoChannel where Message: Send + Sync + 'static { + fn clone(&self) -> IoChannel { + IoChannel { + shared: self.shared.clone(), + } + } +} + +impl IoChannel where Message: Send + Sync + 'static { + /// Send a message through the channel + pub fn send(&self, message: Message) -> Result<(), IoError> { + if let Some(shared) = self.shared.upgrade() { + match *shared.channel.lock() { + Some(ref channel) => channel.push(WorkTask::UserMessage(Arc::new(message))), + None => self.send_sync(message)? + }; + + for thread in shared.threads.read().iter() { + thread.unpark(); + } + } + + Ok(()) + } + + /// Send a message through the channel and handle it synchronously + pub fn send_sync(&self, message: Message) -> Result<(), IoError> { + if let Some(shared) = self.shared.upgrade() { + for id in 0 .. MAX_HANDLERS { + if let Some(h) = shared.handlers.read().get(id) { + let handler = h.clone(); + let ctxt = IoContext { handler: id, shared: shared.clone() }; + handler.message(&ctxt, &message); + } + } + } + + Ok(()) + } + + // Send low level io message + fn send_raw(&self, message: WorkTask) { + if let Some(shared) = self.shared.upgrade() { + if let Some(ref channel) = *shared.channel.lock() { + channel.push(message); + } + + for thread in shared.threads.read().iter() { + thread.unpark(); + } + } + } + + /// Create a new channel disconnected from an event loop. + pub fn disconnected() -> IoChannel { + IoChannel { + shared: Weak::default(), + } + } +} + +/// General IO Service. Starts an event loop and dispatches IO requests. +/// 'Message' is a notification message type +pub struct IoService where Message: Send + Sync + 'static { + thread_joins: Mutex>>, + shared: Arc>, +} + +// Struct shared throughout the whole implementation. +struct Shared where Message: Send + Sync + 'static { + // All the I/O handlers that have been registered. + handlers: RwLock>>>, + // All the background threads, so that we can unpark them. + threads: RwLock>, + // Used to create timeouts. + timer: Mutex, + // List of created timers. We need to keep them in a data struct so that we can cancel them if + // necessary. + timers: Mutex>, + // Channel used to send work to the worker threads. + channel: Mutex>>>, +} + +// Messages used to communicate with the event loop from other threads. +enum WorkTask where Message: Send + Sized { + Shutdown, + TimerTrigger { + handler_id: HandlerId, + token: TimerToken, + }, + UserMessage(Arc) +} + +impl Clone for WorkTask where Message: Send + Sized { + fn clone(&self) -> WorkTask { + match *self { + WorkTask::Shutdown => WorkTask::Shutdown, + WorkTask::TimerTrigger { handler_id, token } => WorkTask::TimerTrigger { handler_id, token }, + WorkTask::UserMessage(ref msg) => WorkTask::UserMessage(msg.clone()), + } + } +} + +impl IoService where Message: Send + Sync + 'static { + /// Starts IO event loop + pub fn start() -> Result, IoError> { + let (tx, rx) = chase_lev::deque(); + + let shared = Arc::new(Shared { + handlers: RwLock::new(Slab::with_capacity(MAX_HANDLERS)), + threads: RwLock::new(Vec::new()), + timer: Mutex::new(Timer::new()), + timers: Mutex::new(FnvHashMap::default()), + channel: Mutex::new(Some(tx)), + }); + + let thread_joins = (0 .. num_cpus::get()).map(|_| { + let rx = rx.clone(); + let shared = shared.clone(); + thread::spawn(move || { + do_work(&shared, rx) + }) + }).collect::>(); + + *shared.threads.write() = thread_joins.iter().map(|t| t.thread().clone()).collect(); + + Ok(IoService { + thread_joins: Mutex::new(thread_joins), + shared, + }) + } + + /// Stops the IO service. + pub fn stop(&self) { + trace!(target: "shutdown", "[IoService] Closing..."); + // Clear handlers so that shared pointers are not stuck on stack + // in Channel::send_sync + self.shared.handlers.write().clear(); + let channel = self.shared.channel.lock().take(); + let mut thread_joins = self.thread_joins.lock(); + if let Some(channel) = channel { + for _ in 0 .. thread_joins.len() { + channel.push(WorkTask::Shutdown); + } + } + for thread in thread_joins.drain(..) { + thread.thread().unpark(); + thread.join().unwrap_or_else(|e| { + debug!(target: "shutdown", "Error joining IO service worker thread: {:?}", e); + }); + } + trace!(target: "shutdown", "[IoService] Closed."); + } + + /// Register an IO handler with the event loop. + pub fn register_handler(&self, handler: Arc+Send>) -> Result<(), IoError> { + let id = self.shared.handlers.write().insert(handler.clone()); + assert!(id <= MAX_HANDLERS, "Too many handlers registered"); + let ctxt = IoContext { handler: id, shared: self.shared.clone() }; + handler.initialize(&ctxt); + Ok(()) + } + + /// Send a message over the network. Normaly `HostIo::send` should be used. This can be used from non-io threads. + pub fn send_message(&self, message: Message) -> Result<(), IoError> { + if let Some(ref channel) = *self.shared.channel.lock() { + channel.push(WorkTask::UserMessage(Arc::new(message))); + } + for thread in self.shared.threads.read().iter() { + thread.unpark(); + } + Ok(()) + } + + /// Create a new message channel + #[inline] + pub fn channel(&self) -> IoChannel { + IoChannel { + shared: Arc::downgrade(&self.shared) + } + } +} + +impl Drop for IoService where Message: Send + Sync { + fn drop(&mut self) { + self.stop() + } +} + +fn do_work(shared: &Arc>, rx: chase_lev::Stealer>) + where Message: Send + Sync + 'static +{ + loop { + match rx.steal() { + chase_lev::Steal::Abort => continue, + chase_lev::Steal::Empty => thread::park(), + chase_lev::Steal::Data(WorkTask::Shutdown) => break, + chase_lev::Steal::Data(WorkTask::UserMessage(message)) => { + for id in 0 .. MAX_HANDLERS { + if let Some(handler) = shared.handlers.read().get(id) { + let ctxt = IoContext { handler: id, shared: shared.clone() }; + handler.message(&ctxt, &message); + } + } + }, + chase_lev::Steal::Data(WorkTask::TimerTrigger { handler_id, token }) => { + if let Some(handler) = shared.handlers.read().get(handler_id) { + let ctxt = IoContext { handler: handler_id, shared: shared.clone() }; + handler.timeout(&ctxt, token); + } + }, + } + } +} diff --git a/util/io/src/worker.rs b/util/io/src/worker.rs index 0f0d448ecb..89657810dc 100644 --- a/util/io/src/worker.rs +++ b/util/io/src/worker.rs @@ -18,21 +18,14 @@ use std::sync::Arc; use std::thread::{JoinHandle, self}; use std::sync::atomic::{AtomicBool, Ordering as AtomicOrdering}; use crossbeam::sync::chase_lev; -use service::{HandlerId, IoChannel, IoContext}; +use service_mio::{HandlerId, IoChannel, IoContext}; use IoHandler; -use std::cell::Cell; +use LOCAL_STACK_SIZE; use std::sync::{Condvar as SCondvar, Mutex as SMutex}; const STACK_SIZE: usize = 16*1024*1024; -thread_local! { - /// Stack size - /// Should be modified if it is changed in Rust since it is no way - /// to know or get it - pub static LOCAL_STACK_SIZE: Cell = Cell::new(::std::env::var("RUST_MIN_STACK").ok().and_then(|s| s.parse().ok()).unwrap_or(2 * 1024 * 1024)); -} - pub enum WorkType { Readable, Writable, diff --git a/util/network-devp2p/Cargo.toml b/util/network-devp2p/Cargo.toml index 3ec9684393..f4889fe26d 100644 --- a/util/network-devp2p/Cargo.toml +++ b/util/network-devp2p/Cargo.toml @@ -19,7 +19,7 @@ libc = "0.2.7" parking_lot = "0.5" ansi_term = "0.10" rustc-hex = "1.0" -ethcore-io = { path = "../io" } +ethcore-io = { path = "../io", features = ["mio"] } ethcore-bytes = { path = "../bytes" } ethcore-crypto = { path = "../../ethcore/crypto" } ethcore-logger = { path ="../../logger" } -- GitLab From aea26dcc640696a712befd5339ab3186bcc3426b Mon Sep 17 00:00:00 2001 From: Thibaut S <33178835+Tbaut@users.noreply.github.com> Date: Fri, 11 May 2018 08:04:04 +0100 Subject: [PATCH 030/152] Fix Parity UI link (#8600) Fix link https://github.com/paritytech/parity/issues/8599 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 36e855fe42..9255d014b6 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ Official website: https://parity.io | Be sure to check out [our wiki](https://wi Parity's goal is to be the fastest, lightest, and most secure Ethereum client. We are developing Parity using the sophisticated and cutting-edge Rust programming language. Parity is licensed under the GPLv3, and can be used for all your Ethereum needs. -From Parity Ethereum client version 1.10.0, the User Interface (UI) is accessible in a separate application called Parity UI. To keep using the UI in the browser (deprecated), [follow these steps](https://wiki.parity.io/FAQ-Basic-Operations,-Configuration,-and-Synchronization.md#the-parity-ui-application-isnt-working-the-way-i-want). +From Parity Ethereum client version 1.10.0, the User Interface (UI) is accessible in a separate application called Parity UI. To keep using the UI in the browser (deprecated), [follow these steps](https://wiki.parity.io/FAQ-Basic-Operations,-Configuration,-and-Synchronization#the-parity-ui-application-isnt-working-the-way-i-want). By default, Parity will also run a JSONRPC server on `127.0.0.1:8545` and a websockets server on `127.0.0.1:8546`. This is fully configurable and supports a number of APIs. -- GitLab From ecd7caa93d803d1f07b4f6888e5f13de6d189fb8 Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Fri, 11 May 2018 11:23:19 +0200 Subject: [PATCH 031/152] fix compiler warning (#8590) --- ethcore/sync/src/light_sync/response.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ethcore/sync/src/light_sync/response.rs b/ethcore/sync/src/light_sync/response.rs index 74665118b7..3629613224 100644 --- a/ethcore/sync/src/light_sync/response.rs +++ b/ethcore/sync/src/light_sync/response.rs @@ -16,7 +16,7 @@ //! Helpers for decoding and verifying responses for headers. -use ethcore::{self, encoded, header::Header}; +use ethcore::{encoded, header::Header}; use ethereum_types::H256; use light::request::{HashOrNumber, CompleteHeadersRequest as HeadersRequest}; use rlp::DecoderError; -- GitLab From 61ec02248aa4acb21ff35999dd2c8945478eeb32 Mon Sep 17 00:00:00 2001 From: David Date: Fri, 11 May 2018 11:33:13 +0200 Subject: [PATCH 032/152] Block::decode() returns Result (#8586) --- ethcore/src/encoded.rs | 2 +- ethcore/src/snapshot/consensus/authority.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ethcore/src/encoded.rs b/ethcore/src/encoded.rs index c436607f8c..5a2d376a2a 100644 --- a/ethcore/src/encoded.rs +++ b/ethcore/src/encoded.rs @@ -206,7 +206,7 @@ impl Block { pub fn header_view(&self) -> HeaderView { self.view().header_view() } /// Decode to a full block. - pub fn decode(&self) -> FullBlock { ::rlp::decode(&self.0).expect("decoding failure") } + pub fn decode(&self) -> Result { rlp::decode(&self.0) } /// Decode the header. pub fn decode_header(&self) -> FullHeader { self.view().rlp().val_at(0) } diff --git a/ethcore/src/snapshot/consensus/authority.rs b/ethcore/src/snapshot/consensus/authority.rs index 474f5d350c..38d2c184ca 100644 --- a/ethcore/src/snapshot/consensus/authority.rs +++ b/ethcore/src/snapshot/consensus/authority.rs @@ -100,7 +100,7 @@ impl SnapshotComponents for PoaSnapshot { let (block, receipts) = chain.block(&block_at) .and_then(|b| chain.block_receipts(&block_at).map(|r| (b, r))) .ok_or(Error::BlockNotFound(block_at))?; - let block = block.decode(); + let block = block.decode()?; let parent_td = chain.block_details(block.header.parent_hash()) .map(|d| d.total_difficulty) -- GitLab From 25dc1c2155c8e84f2263e46b830f24f51a6e5195 Mon Sep 17 00:00:00 2001 From: David Date: Fri, 11 May 2018 11:34:07 +0200 Subject: [PATCH 033/152] block_header can fail so return Result (#8581) * block_header can fail so return Result * Restore previous return type based on feedback * Fix failing doc tests running on non-code --- rpc/src/v1/impls/light/parity.rs | 9 ++++----- util/journaldb/src/earlymergedb.rs | 6 +++--- util/journaldb/src/refcounteddb.rs | 2 +- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/rpc/src/v1/impls/light/parity.rs b/rpc/src/v1/impls/light/parity.rs index 982c7ff363..025538fc42 100644 --- a/rpc/src/v1/impls/light/parity.rs +++ b/rpc/src/v1/impls/light/parity.rs @@ -395,9 +395,9 @@ impl Parity for ParityClient { let engine = self.light_dispatch.client.engine().clone(); let from_encoded = move |encoded: encoded::Header| { - let header = encoded.decode().expect("decoding error"); // REVIEW: not sure what to do here; what is a decent return value for the error case here? + let header = encoded.decode().map_err(errors::decode)?; let extra_info = engine.extra_info(&header); - RichHeader { + Ok(RichHeader { inner: Header { hash: Some(header.hash().into()), size: Some(encoded.rlp().as_raw().len().into()), @@ -418,9 +418,8 @@ impl Parity for ParityClient { extra_data: Bytes::new(header.extra_data().clone()), }, extra_info: extra_info, - } + }) }; - // Note: Here we treat `Pending` as `Latest`. // Since light clients don't produce pending blocks // (they don't have state) we can safely fallback to `Latest`. @@ -430,7 +429,7 @@ impl Parity for ParityClient { BlockNumber::Latest | BlockNumber::Pending => BlockId::Latest, }; - Box::new(self.fetcher().header(id).map(from_encoded)) + Box::new(self.fetcher().header(id).and_then(from_encoded)) } fn ipfs_cid(&self, content: Bytes) -> Result { diff --git a/util/journaldb/src/earlymergedb.rs b/util/journaldb/src/earlymergedb.rs index e76cdcd313..c26a67e0ad 100644 --- a/util/journaldb/src/earlymergedb.rs +++ b/util/journaldb/src/earlymergedb.rs @@ -57,7 +57,7 @@ enum RemoveFrom { /// the removals actually take effect. /// /// journal format: -/// ``` +/// ```text /// [era, 0] => [ id, [insert_0, ...], [remove_0, ...] ] /// [era, 1] => [ id, [insert_0, ...], [remove_0, ...] ] /// [era, n] => [ ... ] @@ -76,7 +76,7 @@ enum RemoveFrom { /// which includes an original key, if any. /// /// The semantics of the `counter` are: -/// ``` +/// ```text /// insert key k: /// counter already contains k: count += 1 /// counter doesn't contain k: @@ -92,7 +92,7 @@ enum RemoveFrom { /// /// Practically, this means that for each commit block turning from recent to ancient we do the /// following: -/// ``` +/// ```text /// is_canonical: /// inserts: Ignored (left alone in the backing database). /// deletes: Enacted; however, recent history queue is checked for ongoing references. This is diff --git a/util/journaldb/src/refcounteddb.rs b/util/journaldb/src/refcounteddb.rs index 944d81d373..d182d5cf80 100644 --- a/util/journaldb/src/refcounteddb.rs +++ b/util/journaldb/src/refcounteddb.rs @@ -40,7 +40,7 @@ use util::{DatabaseKey, DatabaseValueView, DatabaseValueRef}; /// the removals actually take effect. /// /// journal format: -/// ``` +/// ```text /// [era, 0] => [ id, [insert_0, ...], [remove_0, ...] ] /// [era, 1] => [ id, [insert_0, ...], [remove_0, ...] ] /// [era, n] => [ ... ] -- GitLab From 1fa95ac236ab280afc9eccb4d6ea51b494f11422 Mon Sep 17 00:00:00 2001 From: Axel Chalon Date: Fri, 11 May 2018 12:09:42 +0200 Subject: [PATCH 034/152] Remove inject.js server-side injection for dapps (#8539) * Remove inject.js server-side injection for dapps * Remove dapps test `should_inject_js` Parity doesn't inject a "#, - apps::UTILS_PATH, - ); - - content.as_bytes().to_vec() - } else { - Vec::new() - }; - - let (reader, body) = Reader::pair(file.into_reader(), initial_content); + let (reader, body) = Reader::pair(file.into_reader(), Vec::new()); res.set_body(body); (Some(reader), res) } diff --git a/dapps/src/tests/home.rs b/dapps/src/tests/home.rs index 0ee0653648..fa5c5b4c46 100644 --- a/dapps/src/tests/home.rs +++ b/dapps/src/tests/home.rs @@ -60,32 +60,3 @@ fn should_serve_home() { response.assert_header("Content-Type", "text/html"); assert_security_headers(&response.headers); } - - -#[test] -fn should_inject_js() { - // given - let server = serve_ui(); - - // when - let response = request(server, - "\ - GET / HTTP/1.1\r\n\ - Host: 127.0.0.1:8080\r\n\ - Connection: close\r\n\ - \r\n\ - {} - " - ); - - // then - response.assert_status("HTTP/1.1 200 OK"); - response.assert_header("Content-Type", "text/html"); - assert_eq!( - response.body.contains(r#"/inject.js">"#), - true, - "Expected inject script tag in: {}", - response.body - ); - assert_security_headers(&response.headers); -} -- GitLab From 57d1f2b4d35d79a69aabe4d4460463a8e2569ad3 Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Fri, 11 May 2018 13:45:07 +0200 Subject: [PATCH 035/152] Fix the mio test again (#8602) --- util/io/src/lib.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/util/io/src/lib.rs b/util/io/src/lib.rs index ef8c3adc7e..cd635121ff 100644 --- a/util/io/src/lib.rs +++ b/util/io/src/lib.rs @@ -186,7 +186,12 @@ mod tests { use std::time::Duration; use super::*; + // Mio's behaviour is too unstable for this test. Sometimes we have to wait a few milliseconds, + // sometimes more than 5 seconds for the message to arrive. + // Therefore we ignore this test in order to not have spurious failure when running continuous + // integration. #[test] + #[cfg_attr(feature = "mio", ignore)] fn send_message_to_handler() { struct MyHandler(atomic::AtomicBool); @@ -209,7 +214,7 @@ mod tests { service.send_message(MyMessage { data: 5 }).unwrap(); - thread::sleep(Duration::from_secs(5)); + thread::sleep(Duration::from_secs(1)); assert!(handler.0.load(atomic::Ordering::SeqCst)); } -- GitLab From 979af3d3143a4219f8d7428f969d7c1b221d0133 Mon Sep 17 00:00:00 2001 From: lihuafeng <31607114+EighteenZi@users.noreply.github.com> Date: Sun, 13 May 2018 04:46:08 +0800 Subject: [PATCH 036/152] 2 tiny modification on snapshot (#8601) * Some tiny modifications. 1. fix some typo in the comment. 2. sort the order of methods in 'impl state::Backend for StateDB` * Remove the clone of code_cache, as it has been done in clone_basic. * remove From::from. It seems not necessary. * change mode: remove rust files' executable mode. * 2 tiny modifications on snapshot. --- ethcore/src/snapshot/consensus/work.rs | 2 +- ethcore/src/snapshot/service.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ethcore/src/snapshot/consensus/work.rs b/ethcore/src/snapshot/consensus/work.rs index 5414ed5963..b71f7b9d1d 100644 --- a/ethcore/src/snapshot/consensus/work.rs +++ b/ethcore/src/snapshot/consensus/work.rs @@ -229,7 +229,7 @@ impl Rebuilder for PowRebuilder { let item_count = rlp.item_count()?; let num_blocks = (item_count - 3) as u64; - trace!(target: "snapshot", "restoring block chunk with {} blocks.", item_count - 3); + trace!(target: "snapshot", "restoring block chunk with {} blocks.", num_blocks); if self.fed_blocks + num_blocks > self.snapshot_blocks { return Err(Error::TooManyBlocks(self.snapshot_blocks, self.fed_blocks + num_blocks).into()) diff --git a/ethcore/src/snapshot/service.rs b/ethcore/src/snapshot/service.rs index 9cfb2eb63f..c5b9123e10 100644 --- a/ethcore/src/snapshot/service.rs +++ b/ethcore/src/snapshot/service.rs @@ -176,7 +176,7 @@ impl Restoration { // verify final state root. let root = self.state.state_root(); if root != self.final_state_root { - warn!("Final restored state has wrong state root: expected {:?}, got {:?}", root, self.final_state_root); + warn!("Final restored state has wrong state root: expected {:?}, got {:?}", self.final_state_root, root); return Err(TrieError::InvalidStateRoot(root).into()); } -- GitLab From 981554cf74980c9470abf23039ad39e75246eef8 Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Mon, 14 May 2018 15:22:59 +0800 Subject: [PATCH 037/152] Use full qualified syntax for itertools::Itertools::flatten (#8606) --- ethstore/src/accounts_dir/memory.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ethstore/src/accounts_dir/memory.rs b/ethstore/src/accounts_dir/memory.rs index bd162b5ef0..5cfdba0e5c 100644 --- a/ethstore/src/accounts_dir/memory.rs +++ b/ethstore/src/accounts_dir/memory.rs @@ -16,7 +16,7 @@ use std::collections::HashMap; use parking_lot::RwLock; -use itertools::Itertools; +use itertools; use ethkey::Address; use {SafeAccount, Error}; @@ -30,7 +30,7 @@ pub struct MemoryDirectory { impl KeyDirectory for MemoryDirectory { fn load(&self) -> Result, Error> { - Ok(self.accounts.read().values().cloned().flatten().collect()) + Ok(itertools::Itertools::flatten(self.accounts.read().values().cloned()).collect()) } fn update(&self, account: SafeAccount) -> Result { -- GitLab From 08abf67a5118ad7846eb0a438cca5b0d54fb9666 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Mon, 14 May 2018 10:09:05 +0200 Subject: [PATCH 038/152] Fix packet count when talking with PAR2 peers (#8555) * Support diferent packet counts in different protocol versions. * Fix light timeouts and eclipse protection. * Fix devp2p tests. * Fix whisper-cli compilation. * Fix compilation. * Fix ethcore-sync tests. * Revert "Fix light timeouts and eclipse protection." This reverts commit 06285ea8c1d9d184d809f64b5507aece633da6cc. * Increase timeouts. --- ethcore/light/src/net/mod.rs | 17 ++++++++++------- ethcore/sync/src/api.rs | 17 +++++++---------- ethcore/sync/src/chain/handler.rs | 8 +++++--- ethcore/sync/src/chain/mod.rs | 24 ++++++++++-------------- ethcore/sync/src/chain/requester.rs | 5 +++-- ethcore/sync/src/tests/helpers.rs | 4 ++-- parity/whisper.rs | 2 -- util/network-devp2p/src/host.rs | 13 +++++++++---- util/network-devp2p/src/lib.rs | 2 +- util/network-devp2p/src/service.rs | 13 +++++++++---- util/network-devp2p/tests/tests.rs | 4 ++-- util/network/src/lib.rs | 6 ++---- whisper/cli/src/main.rs | 4 ++-- whisper/src/net/mod.rs | 10 ++++++---- 14 files changed, 68 insertions(+), 61 deletions(-) diff --git a/ethcore/light/src/net/mod.rs b/ethcore/light/src/net/mod.rs index d58d90fac4..27d5c12a5f 100644 --- a/ethcore/light/src/net/mod.rs +++ b/ethcore/light/src/net/mod.rs @@ -75,14 +75,17 @@ const RECALCULATE_COSTS_INTERVAL: Duration = Duration::from_secs(60 * 60); // minimum interval between updates. const UPDATE_INTERVAL: Duration = Duration::from_millis(5000); +/// Packet count for PIP. +const PACKET_COUNT_V1: u8 = 9; + /// Supported protocol versions. -pub const PROTOCOL_VERSIONS: &'static [u8] = &[1]; +pub const PROTOCOL_VERSIONS: &'static [(u8, u8)] = &[ + (1, PACKET_COUNT_V1), +]; /// Max protocol version. pub const MAX_PROTOCOL_VERSION: u8 = 1; -/// Packet count for PIP. -pub const PACKET_COUNT: u8 = 9; // packet ID definitions. mod packet { @@ -111,9 +114,9 @@ mod packet { mod timeout { use std::time::Duration; - pub const HANDSHAKE: Duration = Duration::from_millis(2500); - pub const ACKNOWLEDGE_UPDATE: Duration = Duration::from_millis(5000); - pub const BASE: u64 = 1500; // base timeout for packet. + pub const HANDSHAKE: Duration = Duration::from_millis(4_000); + pub const ACKNOWLEDGE_UPDATE: Duration = Duration::from_millis(5_000); + pub const BASE: u64 = 2_500; // base timeout for packet. // timeouts per request within packet. pub const HEADERS: u64 = 250; // per header? @@ -688,7 +691,7 @@ impl LightProtocol { Err(e) => { punish(*peer, io, e); return } }; - if PROTOCOL_VERSIONS.iter().find(|x| **x == proto_version).is_none() { + if PROTOCOL_VERSIONS.iter().find(|x| x.0 == proto_version).is_none() { punish(*peer, io, Error::UnsupportedProtocolVersion(proto_version)); return; } diff --git a/ethcore/sync/src/api.rs b/ethcore/sync/src/api.rs index 4fd0cbb54d..e901528e41 100644 --- a/ethcore/sync/src/api.rs +++ b/ethcore/sync/src/api.rs @@ -33,7 +33,7 @@ use chain::{ChainSync, SyncStatus as EthSyncStatus}; use std::net::{SocketAddr, AddrParseError}; use std::str::FromStr; use parking_lot::RwLock; -use chain::{ETH_PACKET_COUNT, SNAPSHOT_SYNC_PACKET_COUNT, ETH_PROTOCOL_VERSION_63, ETH_PROTOCOL_VERSION_62, +use chain::{ETH_PROTOCOL_VERSION_63, ETH_PROTOCOL_VERSION_62, PAR_PROTOCOL_VERSION_1, PAR_PROTOCOL_VERSION_2, PAR_PROTOCOL_VERSION_3}; use light::client::AsLightClient; use light::Provider; @@ -202,10 +202,8 @@ pub struct AttachedProtocol { pub handler: Arc, /// 3-character ID for the protocol. pub protocol_id: ProtocolId, - /// Packet count. - pub packet_count: u8, - /// Supported versions. - pub versions: &'static [u8], + /// Supported versions and their packet counts. + pub versions: &'static [(u8, u8)], } impl AttachedProtocol { @@ -213,7 +211,6 @@ impl AttachedProtocol { let res = network.register_protocol( self.handler.clone(), self.protocol_id, - self.packet_count, self.versions ); @@ -459,15 +456,15 @@ impl ChainNotify for EthSync { Err(err) => warn!("Error starting network: {}", err), _ => {}, } - self.network.register_protocol(self.eth_handler.clone(), self.subprotocol_name, ETH_PACKET_COUNT, &[ETH_PROTOCOL_VERSION_62, ETH_PROTOCOL_VERSION_63]) + self.network.register_protocol(self.eth_handler.clone(), self.subprotocol_name, &[ETH_PROTOCOL_VERSION_62, ETH_PROTOCOL_VERSION_63]) .unwrap_or_else(|e| warn!("Error registering ethereum protocol: {:?}", e)); // register the warp sync subprotocol - self.network.register_protocol(self.eth_handler.clone(), WARP_SYNC_PROTOCOL_ID, SNAPSHOT_SYNC_PACKET_COUNT, &[PAR_PROTOCOL_VERSION_1, PAR_PROTOCOL_VERSION_2, PAR_PROTOCOL_VERSION_3]) + self.network.register_protocol(self.eth_handler.clone(), WARP_SYNC_PROTOCOL_ID, &[PAR_PROTOCOL_VERSION_1, PAR_PROTOCOL_VERSION_2, PAR_PROTOCOL_VERSION_3]) .unwrap_or_else(|e| warn!("Error registering snapshot sync protocol: {:?}", e)); // register the light protocol. if let Some(light_proto) = self.light_proto.as_ref().map(|x| x.clone()) { - self.network.register_protocol(light_proto, self.light_subprotocol_name, ::light::net::PACKET_COUNT, ::light::net::PROTOCOL_VERSIONS) + self.network.register_protocol(light_proto, self.light_subprotocol_name, ::light::net::PROTOCOL_VERSIONS) .unwrap_or_else(|e| warn!("Error registering light client protocol: {:?}", e)); } @@ -827,7 +824,7 @@ impl ManageNetwork for LightSync { let light_proto = self.proto.clone(); - self.network.register_protocol(light_proto, self.subprotocol_name, ::light::net::PACKET_COUNT, ::light::net::PROTOCOL_VERSIONS) + self.network.register_protocol(light_proto, self.subprotocol_name, ::light::net::PROTOCOL_VERSIONS) .unwrap_or_else(|e| warn!("Error registering light client protocol: {:?}", e)); for proto in &self.attached_protos { proto.register(&self.network) } diff --git a/ethcore/sync/src/chain/handler.rs b/ethcore/sync/src/chain/handler.rs index 966b7ce20a..a55c0319b3 100644 --- a/ethcore/sync/src/chain/handler.rs +++ b/ethcore/sync/src/chain/handler.rs @@ -45,7 +45,6 @@ use super::{ MAX_NEW_BLOCK_AGE, MAX_NEW_HASHES, PAR_PROTOCOL_VERSION_1, - PAR_PROTOCOL_VERSION_2, PAR_PROTOCOL_VERSION_3, BLOCK_BODIES_PACKET, BLOCK_HEADERS_PACKET, @@ -641,8 +640,11 @@ impl SyncHandler { trace!(target: "sync", "Peer {} network id mismatch (ours: {}, theirs: {})", peer_id, sync.network_id, peer.network_id); return Ok(()); } - if (warp_protocol && peer.protocol_version != PAR_PROTOCOL_VERSION_1 && peer.protocol_version != PAR_PROTOCOL_VERSION_2 && peer.protocol_version != PAR_PROTOCOL_VERSION_3) - || (!warp_protocol && peer.protocol_version != ETH_PROTOCOL_VERSION_63 && peer.protocol_version != ETH_PROTOCOL_VERSION_62) { + + if false + || (warp_protocol && (peer.protocol_version < PAR_PROTOCOL_VERSION_1.0 || peer.protocol_version > PAR_PROTOCOL_VERSION_3.0)) + || (!warp_protocol && (peer.protocol_version < ETH_PROTOCOL_VERSION_62.0 || peer.protocol_version > ETH_PROTOCOL_VERSION_63.0)) + { io.disable_peer(peer_id); trace!(target: "sync", "Peer {} unsupported eth protocol ({})", peer_id, peer.protocol_version); return Ok(()); diff --git a/ethcore/sync/src/chain/mod.rs b/ethcore/sync/src/chain/mod.rs index abab1da941..381936949b 100644 --- a/ethcore/sync/src/chain/mod.rs +++ b/ethcore/sync/src/chain/mod.rs @@ -127,15 +127,15 @@ known_heap_size!(0, PeerInfo); pub type PacketDecodeError = DecoderError; /// 63 version of Ethereum protocol. -pub const ETH_PROTOCOL_VERSION_63: u8 = 63; +pub const ETH_PROTOCOL_VERSION_63: (u8, u8) = (63, 0x11); /// 62 version of Ethereum protocol. -pub const ETH_PROTOCOL_VERSION_62: u8 = 62; -/// 1 version of Parity protocol. -pub const PAR_PROTOCOL_VERSION_1: u8 = 1; +pub const ETH_PROTOCOL_VERSION_62: (u8, u8) = (62, 0x11); +/// 1 version of Parity protocol and the packet count. +pub const PAR_PROTOCOL_VERSION_1: (u8, u8) = (1, 0x15); /// 2 version of Parity protocol (consensus messages added). -pub const PAR_PROTOCOL_VERSION_2: u8 = 2; +pub const PAR_PROTOCOL_VERSION_2: (u8, u8) = (2, 0x16); /// 3 version of Parity protocol (private transactions messages added). -pub const PAR_PROTOCOL_VERSION_3: u8 = 3; +pub const PAR_PROTOCOL_VERSION_3: (u8, u8) = (3, 0x18); pub const MAX_BODIES_TO_SEND: usize = 256; pub const MAX_HEADERS_TO_SEND: usize = 512; @@ -169,8 +169,6 @@ pub const NODE_DATA_PACKET: u8 = 0x0e; pub const GET_RECEIPTS_PACKET: u8 = 0x0f; pub const RECEIPTS_PACKET: u8 = 0x10; -pub const ETH_PACKET_COUNT: u8 = 0x11; - pub const GET_SNAPSHOT_MANIFEST_PACKET: u8 = 0x11; pub const SNAPSHOT_MANIFEST_PACKET: u8 = 0x12; pub const GET_SNAPSHOT_DATA_PACKET: u8 = 0x13; @@ -179,8 +177,6 @@ pub const CONSENSUS_DATA_PACKET: u8 = 0x15; const PRIVATE_TRANSACTION_PACKET: u8 = 0x16; const SIGNED_PRIVATE_TRANSACTION_PACKET: u8 = 0x17; -pub const SNAPSHOT_SYNC_PACKET_COUNT: u8 = 0x18; - const MAX_SNAPSHOT_CHUNKS_DOWNLOAD_AHEAD: usize = 3; const WAIT_PEERS_TIMEOUT: Duration = Duration::from_secs(5); @@ -453,7 +449,7 @@ impl ChainSync { let last_imported_number = self.new_blocks.last_imported_block_number(); SyncStatus { state: self.state.clone(), - protocol_version: ETH_PROTOCOL_VERSION_63, + protocol_version: ETH_PROTOCOL_VERSION_63.0, network_id: self.network_id, start_block_number: self.starting_block, last_imported_block_number: Some(last_imported_number), @@ -855,7 +851,7 @@ impl ChainSync { fn send_status(&mut self, io: &mut SyncIo, peer: PeerId) -> Result<(), network::Error> { let warp_protocol_version = io.protocol_version(&WARP_SYNC_PROTOCOL_ID, peer); let warp_protocol = warp_protocol_version != 0; - let protocol = if warp_protocol { warp_protocol_version } else { ETH_PROTOCOL_VERSION_63 }; + let protocol = if warp_protocol { warp_protocol_version } else { ETH_PROTOCOL_VERSION_63.0 }; trace!(target: "sync", "Sending status to {}, protocol version {}", peer, protocol); let mut packet = RlpStream::new_list(if warp_protocol { 7 } else { 5 }); let chain = io.chain().chain_info(); @@ -1019,11 +1015,11 @@ impl ChainSync { } fn get_consensus_peers(&self) -> Vec { - self.peers.iter().filter_map(|(id, p)| if p.protocol_version >= PAR_PROTOCOL_VERSION_2 { Some(*id) } else { None }).collect() + self.peers.iter().filter_map(|(id, p)| if p.protocol_version >= PAR_PROTOCOL_VERSION_2.0 { Some(*id) } else { None }).collect() } fn get_private_transaction_peers(&self) -> Vec { - self.peers.iter().filter_map(|(id, p)| if p.protocol_version >= PAR_PROTOCOL_VERSION_3 { Some(*id) } else { None }).collect() + self.peers.iter().filter_map(|(id, p)| if p.protocol_version >= PAR_PROTOCOL_VERSION_3.0 { Some(*id) } else { None }).collect() } /// Maintain other peers. Send out any new blocks and transactions diff --git a/ethcore/sync/src/chain/requester.rs b/ethcore/sync/src/chain/requester.rs index e6acf6bc53..a85874d292 100644 --- a/ethcore/sync/src/chain/requester.rs +++ b/ethcore/sync/src/chain/requester.rs @@ -28,7 +28,7 @@ use super::{ BlockSet, ChainSync, PeerAsking, - ETH_PACKET_COUNT, + ETH_PROTOCOL_VERSION_63, GET_BLOCK_BODIES_PACKET, GET_BLOCK_HEADERS_PACKET, GET_RECEIPTS_PACKET, @@ -140,7 +140,8 @@ impl SyncRequester { } peer.asking = asking; peer.ask_time = Instant::now(); - let result = if packet_id >= ETH_PACKET_COUNT { + // TODO [ToDr] This seems quite fragile. Be careful when protocol is updated. + let result = if packet_id >= ETH_PROTOCOL_VERSION_63.1 { io.send_protocol(WARP_SYNC_PROTOCOL_ID, peer_id, packet_id, packet) } else { io.send(peer_id, packet_id, packet) diff --git a/ethcore/sync/src/tests/helpers.rs b/ethcore/sync/src/tests/helpers.rs index 3a4697cc09..407f699e0e 100644 --- a/ethcore/sync/src/tests/helpers.rs +++ b/ethcore/sync/src/tests/helpers.rs @@ -134,11 +134,11 @@ impl<'p, C> SyncIo for TestIo<'p, C> where C: FlushingBlockChainClient, C: 'p { } fn eth_protocol_version(&self, _peer: PeerId) -> u8 { - ETH_PROTOCOL_VERSION_63 + ETH_PROTOCOL_VERSION_63.0 } fn protocol_version(&self, protocol: &ProtocolId, peer_id: PeerId) -> u8 { - if protocol == &WARP_SYNC_PROTOCOL_ID { PAR_PROTOCOL_VERSION_3 } else { self.eth_protocol_version(peer_id) } + if protocol == &WARP_SYNC_PROTOCOL_ID { PAR_PROTOCOL_VERSION_3.0 } else { self.eth_protocol_version(peer_id) } } fn chain_overlay(&self) -> &RwLock> { diff --git a/parity/whisper.rs b/parity/whisper.rs index c7acd8f9d6..bb9aebf0b9 100644 --- a/parity/whisper.rs +++ b/parity/whisper.rs @@ -89,7 +89,6 @@ pub fn setup(target_pool_size: usize, protos: &mut Vec) protos.push(AttachedProtocol { handler: net.clone() as Arc<_>, - packet_count: whisper_net::PACKET_COUNT, versions: whisper_net::SUPPORTED_VERSIONS, protocol_id: whisper_net::PROTOCOL_ID, }); @@ -97,7 +96,6 @@ pub fn setup(target_pool_size: usize, protos: &mut Vec) // parity-only extensions to whisper. protos.push(AttachedProtocol { handler: Arc::new(whisper_net::ParityExtensions), - packet_count: whisper_net::PACKET_COUNT, versions: whisper_net::SUPPORTED_VERSIONS, protocol_id: whisper_net::PARITY_PROTOCOL_ID, }); diff --git a/util/network-devp2p/src/host.rs b/util/network-devp2p/src/host.rs index 2de9a1884c..3c8643fe62 100644 --- a/util/network-devp2p/src/host.rs +++ b/util/network-devp2p/src/host.rs @@ -79,7 +79,9 @@ const NODE_TABLE_TIMEOUT: Duration = Duration::from_secs(300); #[derive(Debug, PartialEq, Eq)] /// Protocol info pub struct CapabilityInfo { + /// Protocol ID pub protocol: ProtocolId, + /// Protocol version pub version: u8, /// Total number of packet IDs this protocol support. pub packet_count: u8, @@ -687,7 +689,7 @@ impl Host { Err(e) => { let s = session.lock(); trace!(target: "network", "Session read error: {}:{:?} ({:?}) {:?}", token, s.id(), s.remote_addr(), e); - if let ErrorKind::Disconnect(DisconnectReason::UselessPeer) = *e.kind() { + if let ErrorKind::Disconnect(DisconnectReason::IncompatibleProtocol) = *e.kind() { if let Some(id) = s.id() { if !self.reserved_nodes.read().contains(id) { let mut nodes = self.nodes.write(); @@ -990,7 +992,6 @@ impl IoHandler for Host { ref handler, ref protocol, ref versions, - ref packet_count, } => { let h = handler.clone(); let reserved = self.reserved_nodes.read(); @@ -1000,8 +1001,12 @@ impl IoHandler for Host { ); self.handlers.write().insert(*protocol, h); let mut info = self.info.write(); - for v in versions { - info.capabilities.push(CapabilityInfo { protocol: *protocol, version: *v, packet_count: *packet_count }); + for &(version, packet_count) in versions { + info.capabilities.push(CapabilityInfo { + protocol: *protocol, + version, + packet_count, + }); } }, NetworkIoMessage::AddTimer { diff --git a/util/network-devp2p/src/lib.rs b/util/network-devp2p/src/lib.rs index 239763cbe1..e5bb95f220 100644 --- a/util/network-devp2p/src/lib.rs +++ b/util/network-devp2p/src/lib.rs @@ -49,7 +49,7 @@ //! fn main () { //! let mut service = NetworkService::new(NetworkConfiguration::new_local(), None).expect("Error creating network service"); //! service.start().expect("Error starting service"); -//! service.register_protocol(Arc::new(MyHandler), *b"myp", 1, &[1u8]); +//! service.register_protocol(Arc::new(MyHandler), *b"myp", &[(1u8, 1u8)]); //! //! // Wait for quit condition //! // ... diff --git a/util/network-devp2p/src/service.rs b/util/network-devp2p/src/service.rs index 711ee95cf3..10a1e9abc8 100644 --- a/util/network-devp2p/src/service.rs +++ b/util/network-devp2p/src/service.rs @@ -67,12 +67,17 @@ impl NetworkService { } /// Regiter a new protocol handler with the event loop. - pub fn register_protocol(&self, handler: Arc, protocol: ProtocolId, packet_count: u8, versions: &[u8]) -> Result<(), Error> { + pub fn register_protocol( + &self, + handler: Arc, + protocol: ProtocolId, + // version id + packet count + versions: &[(u8, u8)] + ) -> Result<(), Error> { self.io_service.send_message(NetworkIoMessage::AddHandler { - handler: handler, - protocol: protocol, + handler, + protocol, versions: versions.to_vec(), - packet_count: packet_count, })?; Ok(()) } diff --git a/util/network-devp2p/tests/tests.rs b/util/network-devp2p/tests/tests.rs index 4788e0d442..e8c8eddde4 100644 --- a/util/network-devp2p/tests/tests.rs +++ b/util/network-devp2p/tests/tests.rs @@ -52,7 +52,7 @@ impl TestProtocol { /// Creates and register protocol with the network service pub fn register(service: &mut NetworkService, drop_session: bool) -> Arc { let handler = Arc::new(TestProtocol::new(drop_session)); - service.register_protocol(handler.clone(), *b"tst", 1, &[42u8, 43u8]).expect("Error registering test protocol handler"); + service.register_protocol(handler.clone(), *b"tst", &[(42u8, 1u8), (43u8, 1u8)]).expect("Error registering test protocol handler"); handler } @@ -104,7 +104,7 @@ impl NetworkProtocolHandler for TestProtocol { fn net_service() { let service = NetworkService::new(NetworkConfiguration::new_local(), None).expect("Error creating network service"); service.start().unwrap(); - service.register_protocol(Arc::new(TestProtocol::new(false)), *b"myp", 1, &[1u8]).unwrap(); + service.register_protocol(Arc::new(TestProtocol::new(false)), *b"myp", &[(1u8, 1u8)]).unwrap(); } #[test] diff --git a/util/network/src/lib.rs b/util/network/src/lib.rs index 5077a953d4..673e4dab35 100644 --- a/util/network/src/lib.rs +++ b/util/network/src/lib.rs @@ -64,10 +64,8 @@ pub enum NetworkIoMessage { handler: Arc, /// Protocol Id. protocol: ProtocolId, - /// Supported protocol versions. - versions: Vec, - /// Number of packet IDs reserved by the protocol. - packet_count: u8, + /// Supported protocol versions and number of packet IDs reserved by the protocol (packet count). + versions: Vec<(u8, u8)>, }, /// Register a new protocol timer AddTimer { diff --git a/whisper/cli/src/main.rs b/whisper/cli/src/main.rs index f9211b993b..c3a4dc8c3a 100644 --- a/whisper/cli/src/main.rs +++ b/whisper/cli/src/main.rs @@ -218,10 +218,10 @@ fn execute(command: I) -> Result<(), Error> where I: IntoIterator, network.start()?; // Attach whisper protocol to the network service - network.register_protocol(whisper_network_handler.clone(), whisper::net::PROTOCOL_ID, whisper::net::PACKET_COUNT, + network.register_protocol(whisper_network_handler.clone(), whisper::net::PROTOCOL_ID, whisper::net::SUPPORTED_VERSIONS)?; network.register_protocol(Arc::new(whisper::net::ParityExtensions), whisper::net::PARITY_PROTOCOL_ID, - whisper::net::PACKET_COUNT, whisper::net::SUPPORTED_VERSIONS)?; + whisper::net::SUPPORTED_VERSIONS)?; // Request handler let mut io = MetaIoHandler::default(); diff --git a/whisper/src/net/mod.rs b/whisper/src/net/mod.rs index fc6138cf1d..c462baa9d7 100644 --- a/whisper/src/net/mod.rs +++ b/whisper/src/net/mod.rs @@ -41,15 +41,17 @@ const RALLY_TIMEOUT: Duration = Duration::from_millis(2500); /// Current protocol version. pub const PROTOCOL_VERSION: usize = 6; +/// Number of packets. A bunch are reserved. +const PACKET_COUNT: u8 = 128; + /// Supported protocol versions. -pub const SUPPORTED_VERSIONS: &'static [u8] = &[PROTOCOL_VERSION as u8]; +pub const SUPPORTED_VERSIONS: &'static [(u8, u8)] = &[ + (PROTOCOL_VERSION as u8, PACKET_COUNT) +]; // maximum tolerated delay between messages packets. const MAX_TOLERATED_DELAY: Duration = Duration::from_millis(5000); -/// Number of packets. A bunch are reserved. -pub const PACKET_COUNT: u8 = 128; - /// Whisper protocol ID pub const PROTOCOL_ID: ::network::ProtocolId = *b"shh"; -- GitLab From cfd50538bb5daa2a1ca2e097f08a6c6ce73af65e Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Mon, 14 May 2018 16:10:11 +0800 Subject: [PATCH 039/152] typo: wrong indentation in kovan config (#8610) --- ethcore/res/ethereum/kovan.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ethcore/res/ethereum/kovan.json b/ethcore/res/ethereum/kovan.json index 1cd74d973c..02d22bb419 100644 --- a/ethcore/res/ethereum/kovan.json +++ b/ethcore/res/ethereum/kovan.json @@ -4,8 +4,8 @@ "engine": { "authorityRound": { "params": { - "stepDuration": "4", - "blockReward": "0x4563918244F40000", + "stepDuration": "4", + "blockReward": "0x4563918244F40000", "validators" : { "list": [ "0x00D6Cc1BA9cf89BD2e58009741f4F7325BAdc0ED", -- GitLab From 272ebc1ef7ff2f6fab76d0e1999eebd899e23485 Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Mon, 14 May 2018 16:10:28 +0800 Subject: [PATCH 040/152] Fix account list double 0x display (#8596) * Remove unused self import * Fix account list double 0x display --- parity/account.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/parity/account.rs b/parity/account.rs index 3db1844a1b..676cf93e73 100644 --- a/parity/account.rs +++ b/parity/account.rs @@ -94,7 +94,7 @@ fn new(n: NewAccount) -> Result { let secret_store = Box::new(secret_store(dir, Some(n.iterations))?); let acc_provider = AccountProvider::new(secret_store, AccountProviderSettings::default()); let new_account = acc_provider.new_account(&password).map_err(|e| format!("Could not create new account: {}", e))?; - Ok(format!("0x{:?}", new_account)) + Ok(format!("0x{:x}", new_account)) } fn list(list_cmd: ListAccounts) -> Result { @@ -103,7 +103,7 @@ fn list(list_cmd: ListAccounts) -> Result { let acc_provider = AccountProvider::new(secret_store, AccountProviderSettings::default()); let accounts = acc_provider.accounts().map_err(|e| format!("{}", e))?; let result = accounts.into_iter() - .map(|a| format!("0x{:?}", a)) + .map(|a| format!("0x{:x}", a)) .collect::>() .join("\n"); -- GitLab From 1b95af18ff4f5898786fcd044d3c42fe6f5fcd4a Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Mon, 14 May 2018 10:11:10 +0200 Subject: [PATCH 041/152] Remove manually added text to the errors (#8595) These messages were confusing for the users especially the help message. --- whisper/cli/src/main.rs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/whisper/cli/src/main.rs b/whisper/cli/src/main.rs index c3a4dc8c3a..f245e99e48 100644 --- a/whisper/cli/src/main.rs +++ b/whisper/cli/src/main.rs @@ -170,12 +170,12 @@ impl From for Error { impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { match *self { - Error::SockAddr(ref e) => write!(f, "SockAddrError: {}", e), - Error::Docopt(ref e) => write!(f, "DocoptError: {}", e), - Error::Io(ref e) => write!(f, "IoError: {}", e), - Error::JsonRpc(ref e) => write!(f, "JsonRpcError: {:?}", e), - Error::Network(ref e) => write!(f, "NetworkError: {}", e), - Error::Logger(ref e) => write!(f, "LoggerError: {}", e), + Error::SockAddr(ref e) => write!(f, "{}", e), + Error::Docopt(ref e) => write!(f, "{}", e), + Error::Io(ref e) => write!(f, "{}", e), + Error::JsonRpc(ref e) => write!(f, "{:?}", e), + Error::Network(ref e) => write!(f, "{}", e), + Error::Logger(ref e) => write!(f, "{}", e), } } } @@ -252,7 +252,6 @@ fn initialize_logger(log_level: String) -> Result<(), String> { Ok(()) } - #[cfg(test)] mod tests { use super::execute; -- GitLab From 938c3707fc63c5d37bb7a16a9f0c39742d841ad5 Mon Sep 17 00:00:00 2001 From: Afri Schoedon <5chdn@users.noreply.github.com> Date: Mon, 14 May 2018 11:28:41 +0200 Subject: [PATCH 042/152] Gitlab test script fixes (#8573) * Exclude /docs from modified files. * Ensure all references in the working tree are available * Remove duplicated line from test script --- scripts/gitlab-test.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/gitlab-test.sh b/scripts/gitlab-test.sh index a617f68e22..57cf7c6b6c 100755 --- a/scripts/gitlab-test.sh +++ b/scripts/gitlab-test.sh @@ -7,8 +7,8 @@ if [[ "$CI_COMMIT_REF_NAME" = "master" || "$CI_COMMIT_REF_NAME" = "beta" || "$CI else export GIT_COMPARE=master; fi -export RUST_FILES_MODIFIED="$(git --no-pager diff --name-only $GIT_COMPARE...$CI_COMMIT_SHA | grep -v -e ^\\. -e ^LICENSE -e ^README.md -e ^test.sh -e ^windows/ -e ^scripts/ -e ^mac/ -e ^nsis/ | wc -l)" -echo "RUST_FILES_MODIFIED: $RUST_FILES_MODIFIED" +git fetch -a +export RUST_FILES_MODIFIED="$(git --no-pager diff --name-only $GIT_COMPARE...$CI_COMMIT_SHA | grep -v -e ^\\. -e ^LICENSE -e ^README.md -e ^test.sh -e ^windows/ -e ^scripts/ -e ^mac/ -e ^nsis/ -e ^docs/ | wc -l)" echo "RUST_FILES_MODIFIED: $RUST_FILES_MODIFIED" TEST_SWITCH=$1 rust_test () { -- GitLab From af90fbfb3344fdc2447d97d4c48dcdfd69899a4f Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Mon, 14 May 2018 22:26:18 +0800 Subject: [PATCH 043/152] Fix BlockReward contract "arithmetic operation overflow" (#8611) * Fix BlockReward contract "arithmetic operation overflow" * Add docs on how execute_as_system works * Fix typo --- ethcore/src/machine.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/ethcore/src/machine.rs b/ethcore/src/machine.rs index 4aa72b50d9..d0d434b1de 100644 --- a/ethcore/src/machine.rs +++ b/ethcore/src/machine.rs @@ -122,7 +122,13 @@ impl EthereumMachine { } impl EthereumMachine { - /// Execute a call as the system address. + /// Execute a call as the system address. Block environment information passed to the + /// VM is modified to have its gas limit bounded at the upper limit of possible used + /// gases including this system call, capped at the maximum value able to be + /// represented by U256. This system call modifies the block state, but discards other + /// information. If suicides, logs or refunds happen within the system call, they + /// will not be executed or recorded. Gas used by this system call will not be counted + /// on the block. pub fn execute_as_system( &self, block: &mut ExecutedBlock, @@ -132,7 +138,7 @@ impl EthereumMachine { ) -> Result, Error> { let env_info = { let mut env_info = block.env_info(); - env_info.gas_limit = env_info.gas_used + gas; + env_info.gas_limit = env_info.gas_used.saturating_add(gas); env_info }; -- GitLab From 8f56606cac19d7a55735e214c8c96fc7cebb49f1 Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Tue, 15 May 2018 07:46:37 +0200 Subject: [PATCH 044/152] =?UTF-8?q?=C2=B4main.rs=C2=B4=20typo=20(#8629)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Typo * Update main.rs --- parity/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/parity/main.rs b/parity/main.rs index e489ad865e..03b04a8c82 100644 --- a/parity/main.rs +++ b/parity/main.rs @@ -71,7 +71,7 @@ fn take_spec_name_override() -> Option { #[cfg(windows)] fn global_cleanup() { - // We need to cleanup all sockets before spawning another Parity process. This makes shure everything is cleaned up. + // We need to cleanup all sockets before spawning another Parity process. This makes sure everything is cleaned up. // The loop is required because of internal reference counter for winsock dll. We don't know how many crates we use do // initialize it. There's at least 2 now. for _ in 0.. 10 { -- GitLab From e4614e49ae532bbef239f9eb3cf1741a2bdc7093 Mon Sep 17 00:00:00 2001 From: David Date: Tue, 15 May 2018 12:57:32 +0200 Subject: [PATCH 045/152] Store morden db and keys in "path/to/parity/data/Morden" (ropsten uses "test", like before) (#8621) * Store morden db and keys in "path/to/parity/data/morden" (ropsten uses "test", like before) --- .gitignore | 2 +- ethcore/res/ethereum/morden.json | 2 +- util/dir/src/lib.rs | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index 0675bc41eb..3bc041c908 100644 --- a/.gitignore +++ b/.gitignore @@ -40,5 +40,5 @@ node_modules out/ .vscode - +rls/ /parity.* diff --git a/ethcore/res/ethereum/morden.json b/ethcore/res/ethereum/morden.json index 04c5a12444..bca9919903 100644 --- a/ethcore/res/ethereum/morden.json +++ b/ethcore/res/ethereum/morden.json @@ -1,6 +1,6 @@ { "name": "Morden", - "dataDir": "test", + "dataDir": "morden", "engine": { "Ethash": { "params": { diff --git a/util/dir/src/lib.rs b/util/dir/src/lib.rs index b2ffed329c..bb36a46a83 100644 --- a/util/dir/src/lib.rs +++ b/util/dir/src/lib.rs @@ -104,9 +104,9 @@ impl Directories { DatabaseDirectories { path: self.db.clone(), legacy_path: self.base.clone(), - genesis_hash: genesis_hash, - fork_name: fork_name, - spec_name: spec_name, + genesis_hash, + fork_name, + spec_name, } } -- GitLab From 0c4d2fbc703608c05b17b0bc5b97a38ea76e7525 Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Tue, 15 May 2018 15:35:52 +0200 Subject: [PATCH 046/152] Fix light sync with initial validator-set contract (#8528) * Fix #8468 * Use U256::max_value() instead * Fix again * Also change initial transaction gas --- ethcore/src/spec/spec.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ethcore/src/spec/spec.rs b/ethcore/src/spec/spec.rs index ef69f4847b..1ee8cf7032 100644 --- a/ethcore/src/spec/spec.rs +++ b/ethcore/src/spec/spec.rs @@ -783,7 +783,7 @@ impl Spec { author: *genesis.author(), timestamp: genesis.timestamp(), difficulty: *genesis.difficulty(), - gas_limit: *genesis.gas_limit(), + gas_limit: U256::max_value(), last_hashes: Arc::new(Vec::new()), gas_used: 0.into(), }; @@ -792,7 +792,7 @@ impl Spec { let tx = Transaction { nonce: self.engine.account_start_nonce(0), action: Action::Call(a), - gas: U256::from(50_000_000), // TODO: share with client. + gas: U256::max_value(), gas_price: U256::default(), value: U256::default(), data: d, -- GitLab From 8e078b1d83bf708ef29bbbb166ab5c6edfdaa7b3 Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Tue, 15 May 2018 17:03:09 +0200 Subject: [PATCH 047/152] Remove NetworkContext::io_channel() (#8625) * Remove io_channel() * Fix warning --- util/network-devp2p/src/host.rs | 4 ---- util/network/src/lib.rs | 8 -------- 2 files changed, 12 deletions(-) diff --git a/util/network-devp2p/src/host.rs b/util/network-devp2p/src/host.rs index 3c8643fe62..4cca2e6e5a 100644 --- a/util/network-devp2p/src/host.rs +++ b/util/network-devp2p/src/host.rs @@ -153,10 +153,6 @@ impl<'s> NetworkContextTrait for NetworkContext<'s> { self.session_id.map_or_else(|| Err(ErrorKind::Expired.into()), |id| self.send(id, packet_id, data)) } - fn io_channel(&self) -> IoChannel { - self.io.channel() - } - fn disable_peer(&self, peer: PeerId) { self.io.message(NetworkIoMessage::DisablePeer(peer)) .unwrap_or_else(|e| warn!("Error sending network IO message: {:?}", e)); diff --git a/util/network/src/lib.rs b/util/network/src/lib.rs index 673e4dab35..1327a9ad59 100644 --- a/util/network/src/lib.rs +++ b/util/network/src/lib.rs @@ -39,7 +39,6 @@ use std::str::{self, FromStr}; use std::sync::Arc; use std::time::Duration; use ipnetwork::{IpNetwork, IpNetworkError}; -use io::IoChannel; use ethkey::Secret; use ethereum_types::{H256, H512}; use rlp::{Decodable, DecoderError, Rlp}; @@ -257,9 +256,6 @@ pub trait NetworkContext { /// Respond to a current network message. Panics if no there is no packet in the context. If the session is expired returns nothing. fn respond(&self, packet_id: PacketId, data: Vec) -> Result<(), Error>; - /// Get an IoChannel. - fn io_channel(&self) -> IoChannel; - /// Disconnect a peer and prevent it from connecting again. fn disable_peer(&self, peer: PeerId); @@ -298,10 +294,6 @@ impl<'a, T> NetworkContext for &'a T where T: ?Sized + NetworkContext { (**self).respond(packet_id, data) } - fn io_channel(&self) -> IoChannel { - (**self).io_channel() - } - fn disable_peer(&self, peer: PeerId) { (**self).disable_peer(peer) } -- GitLab From 3bb5ad7204dcdabf841910799814bccc5019729e Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Tue, 15 May 2018 23:11:14 +0200 Subject: [PATCH 048/152] Check that the Android build doesn't dep on c++_shared (#8538) --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 347b5a57ba..95a7ebcb5e 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -190,7 +190,7 @@ android-armv7: - triggers script: - cargo build --target=armv7-linux-androideabi - # TODO: check that `arm-linux-androideabi-objdump -x ./target/armv7-linux-androideabi/release/parity | grep c++_shared` is empty + - if [ $(arm-linux-androideabi-objdump -x ./target/armv7-linux-androideabi/debug/parity | grep -i 'c++_shared' | wc -l) -ne 0]; then echo "FAIL!!" fi tags: - rust-arm artifacts: -- GitLab From 0ecbb3ec02a5b36c95f09a20d5958a374c32511f Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Wed, 16 May 2018 14:58:01 +0800 Subject: [PATCH 049/152] Fork choice and metadata framework for Engine (#8401) * Add light client TODO item * Move existing total-difficulty-based fork choice check to Engine * Abstract total difficulty and block provider as Machine::BlockMetadata and Machine::BlockProvider * Decouple "generate_metadata" logic to Engine * Use fixed BlockMetadata and BlockProvider type for null and instantseal In this way they can use total difficulty fork choice check * Extend blockdetails with metadatas and finalized info * Extra data update: mark_finalized and update_metadatas * Check finalized block in Blockchain * Fix a test constructor in verification mod * Add total difficulty trait * Fix type import * Db migration to V13 with metadata column * Address grumbles * metadatas -> metadata * Use generic type for update_metadata to avoid passing HashMap all around * Remove metadata in blockdetails * [WIP] Implement a generic metadata architecture * [WIP] Metadata insertion logic in BlockChain * typo: Value -> Self::Value * [WIP] Temporarily remove Engine::is_new_best interface So that we don't have too many type errors. * [WIP] Fix more type errors * [WIP] ExtendedHeader::PartialEq * [WIP] Change metadata type Option> to Vec * [WIP] Remove Metadata Error * [WIP] Clean up error conversion * [WIP] finalized -> is_finalized * [WIP] Mark all fields in ExtrasInsert as pub * [WIP] Remove unused import * [WIP] Keep only local metadata info * Mark metadata as optional * [WIP] Revert metadata db change in BlockChain * [WIP] Put finalization in unclosed state * Use metadata interface in BlockDetail * [WIP] Fix current build failures * [WIP] Remove unused blockmetadata struct * Remove DB migration info * [WIP] Typo * Use ExtendedHeader to implement fork choice check * Implement is_new_best using Ancestry iterator * Use expect instead of panic * [WIP] Add ancestry Engine support via on_new_block * Fix tests * Emission of ancestry actions * use_short_version should take account of metadata * Engine::is_new_best -> Engine::fork_choice * Use proper expect format as defined in #1026 * panic -> expect * ancestry_header -> ancestry_with_metadata * Boxed iterator -> &mut iterator * Fix tests * is_new_best -> primitive_fork_choice * Document how fork_choice works * Engine::fork_choice -> Engine::primitive_fork_choice * comment: clarify types of finalization where Engine::primitive_fork_choice works * Expose FinalizationInfo to Engine * Fix tests due to merging * Remove TotalDifficulty trait * Do not pass FinalizationInfo to Engine If there's finalized blocks in from route, choose the old branch without calling `Engine::fork_choice`. * Fix compile * Fix unused import * Remove is_to_route_finalized When no block reorg passes a finalized block, this variable is always false. * Address format grumbles * Fix docs: mark_finalized returns None if block hash is not found `blockchain` mod does not yet have an Error type, so we still temporarily use None here. * Fix inaccurate tree_route None expect description --- ethcore/light/src/client/header_chain.rs | 1 + ethcore/src/block.rs | 51 +++- ethcore/src/blockchain/blockchain.rs | 258 ++++++++++++++------ ethcore/src/blockchain/extras.rs | 54 +++- ethcore/src/blockchain/mod.rs | 1 + ethcore/src/blockchain/update.rs | 10 + ethcore/src/client/client.rs | 67 ++++- ethcore/src/client/test_client.rs | 4 +- ethcore/src/engines/authority_round/mod.rs | 33 ++- ethcore/src/engines/basic_authority.rs | 8 +- ethcore/src/engines/instant_seal.rs | 12 +- ethcore/src/engines/mod.rs | 31 ++- ethcore/src/engines/null_engine.rs | 11 +- ethcore/src/engines/tendermint/mod.rs | 10 +- ethcore/src/ethereum/ethash.rs | 20 +- ethcore/src/header.rs | 48 +++- ethcore/src/machine.rs | 4 +- ethcore/src/snapshot/tests/proof_of_work.rs | 8 +- ethcore/src/test_helpers.rs | 17 +- ethcore/src/tests/trace.rs | 5 +- ethcore/src/verification/verification.rs | 2 + ethcore/types/src/ancestry_action.rs | 27 ++ ethcore/types/src/lib.rs | 1 + ethcore/types/src/tree_route.rs | 2 + machine/src/lib.rs | 48 +++- 25 files changed, 592 insertions(+), 141 deletions(-) create mode 100644 ethcore/types/src/ancestry_action.rs diff --git a/ethcore/light/src/client/header_chain.rs b/ethcore/light/src/client/header_chain.rs index b85091e53b..60c7d288a7 100644 --- a/ethcore/light/src/client/header_chain.rs +++ b/ethcore/light/src/client/header_chain.rs @@ -445,6 +445,7 @@ impl HeaderChain { let raw = header.encoded().into_inner(); transaction.put_vec(self.col, &hash[..], raw); + // TODO: For engines when required, use cryptoeconomic guarantees. let (best_num, is_new_best) = { let cur_best = self.best_block.read(); if cur_best.total_difficulty < total_difficulty { diff --git a/ethcore/src/block.rs b/ethcore/src/block.rs index d9f3d27afb..4c47089677 100644 --- a/ethcore/src/block.rs +++ b/ethcore/src/block.rs @@ -31,7 +31,7 @@ use vm::{EnvInfo, LastHashes}; use engines::EthEngine; use error::{Error, BlockError}; use factory::Factories; -use header::Header; +use header::{Header, ExtendedHeader}; use receipt::{Receipt, TransactionOutcome}; use state::State; use state_db::StateDB; @@ -94,6 +94,8 @@ pub struct ExecutedBlock { state: State, traces: Tracing, last_hashes: Arc, + is_finalized: bool, + metadata: Option>, } impl ExecutedBlock { @@ -112,6 +114,8 @@ impl ExecutedBlock { Tracing::Disabled }, last_hashes: last_hashes, + is_finalized: false, + metadata: None, } } @@ -206,6 +210,26 @@ impl ::parity_machine::Transactions for ExecutedBlock { } } +impl ::parity_machine::Finalizable for ExecutedBlock { + fn is_finalized(&self) -> bool { + self.is_finalized + } + + fn mark_finalized(&mut self) { + self.is_finalized = true; + } +} + +impl ::parity_machine::WithMetadata for ExecutedBlock { + fn metadata(&self) -> Option<&[u8]> { + self.metadata.as_ref().map(|v| v.as_ref()) + } + + fn set_metadata(&mut self, value: Option>) { + self.metadata = value; + } +} + /// Block that is ready for transactions to be added. /// /// It's a bit like a Vec, except that whenever a transaction is pushed, we execute it and @@ -224,6 +248,8 @@ pub struct ClosedBlock { block: ExecutedBlock, uncle_bytes: Bytes, unclosed_state: State, + unclosed_finalization_state: bool, + unclosed_metadata: Option>, } /// Just like `ClosedBlock` except that we can't reopen it and it's faster. @@ -245,7 +271,7 @@ pub struct SealedBlock { impl<'x> OpenBlock<'x> { /// Create a new `OpenBlock` ready for transaction pushing. - pub fn new( + pub fn new<'a>( engine: &'x EthEngine, factories: Factories, tracing: bool, @@ -256,6 +282,7 @@ impl<'x> OpenBlock<'x> { gas_range_target: (U256, U256), extra_data: Bytes, is_epoch_begin: bool, + ancestry: &mut Iterator, ) -> Result { let number = parent.number() + 1; let state = State::from_existing(db, parent.state_root().clone(), engine.account_start_nonce(number), factories)?; @@ -277,7 +304,7 @@ impl<'x> OpenBlock<'x> { engine.populate_from_parent(&mut r.block.header, parent); engine.machine().on_new_block(&mut r.block)?; - engine.on_new_block(&mut r.block, is_epoch_begin)?; + engine.on_new_block(&mut r.block, is_epoch_begin, ancestry)?; Ok(r) } @@ -387,6 +414,8 @@ impl<'x> OpenBlock<'x> { let mut s = self; let unclosed_state = s.block.state.clone(); + let unclosed_metadata = s.block.metadata.clone(); + let unclosed_finalization_state = s.block.is_finalized; if let Err(e) = s.engine.on_close_block(&mut s.block) { warn!("Encountered error on closing the block: {}", e); @@ -410,6 +439,8 @@ impl<'x> OpenBlock<'x> { block: s.block, uncle_bytes, unclosed_state, + unclosed_metadata, + unclosed_finalization_state, } } @@ -483,6 +514,8 @@ impl ClosedBlock { // revert rewards (i.e. set state back at last transaction's state). let mut block = self.block; block.state = self.unclosed_state; + block.metadata = self.unclosed_metadata; + block.is_finalized = self.unclosed_finalization_state; OpenBlock { block: block, engine: engine, @@ -588,6 +621,7 @@ fn enact( last_hashes: Arc, factories: Factories, is_epoch_begin: bool, + ancestry: &mut Iterator, ) -> Result { { if ::log::max_log_level() >= ::log::LogLevel::Trace { @@ -608,6 +642,7 @@ fn enact( (3141562.into(), 31415620.into()), vec![], is_epoch_begin, + ancestry, )?; b.populate_from(&header); @@ -630,6 +665,7 @@ pub fn enact_verified( last_hashes: Arc, factories: Factories, is_epoch_begin: bool, + ancestry: &mut Iterator, ) -> Result { let view = view!(BlockView, &block.bytes); @@ -644,6 +680,7 @@ pub fn enact_verified( last_hashes, factories, is_epoch_begin, + ancestry, ) } @@ -701,6 +738,7 @@ mod tests { (3141562.into(), 31415620.into()), vec![], false, + &mut Vec::new().into_iter(), )?; b.populate_from(&header); @@ -734,7 +772,7 @@ mod tests { let genesis_header = spec.genesis_header(); let db = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap(); let last_hashes = Arc::new(vec![genesis_header.hash()]); - let b = OpenBlock::new(&*spec.engine, Default::default(), false, db, &genesis_header, last_hashes, Address::zero(), (3141562.into(), 31415620.into()), vec![], false).unwrap(); + let b = OpenBlock::new(&*spec.engine, Default::default(), false, db, &genesis_header, last_hashes, Address::zero(), (3141562.into(), 31415620.into()), vec![], false, &mut Vec::new().into_iter()).unwrap(); let b = b.close_and_lock(); let _ = b.seal(&*spec.engine, vec![]); } @@ -748,7 +786,7 @@ mod tests { let db = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap(); let last_hashes = Arc::new(vec![genesis_header.hash()]); - let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes.clone(), Address::zero(), (3141562.into(), 31415620.into()), vec![], false).unwrap() + let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes.clone(), Address::zero(), (3141562.into(), 31415620.into()), vec![], false, &mut Vec::new().into_iter()).unwrap() .close_and_lock().seal(engine, vec![]).unwrap(); let orig_bytes = b.rlp_bytes(); let orig_db = b.drain(); @@ -772,7 +810,7 @@ mod tests { let db = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap(); let last_hashes = Arc::new(vec![genesis_header.hash()]); - let mut open_block = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes.clone(), Address::zero(), (3141562.into(), 31415620.into()), vec![], false).unwrap(); + let mut open_block = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes.clone(), Address::zero(), (3141562.into(), 31415620.into()), vec![], false, &mut Vec::new().into_iter()).unwrap(); let mut uncle1_header = Header::new(); uncle1_header.set_extra_data(b"uncle1".to_vec()); let mut uncle2_header = Header::new(); @@ -797,4 +835,3 @@ mod tests { assert!(orig_db.journal_db().keys().iter().filter(|k| orig_db.journal_db().get(k.0) != db.journal_db().get(k.0)).next() == None); } } - diff --git a/ethcore/src/blockchain/blockchain.rs b/ethcore/src/blockchain/blockchain.rs index 0e18c5f889..f2621d00e1 100644 --- a/ethcore/src/blockchain/blockchain.rs +++ b/ethcore/src/blockchain/blockchain.rs @@ -38,11 +38,12 @@ use blockchain::block_info::{BlockInfo, BlockLocation, BranchBecomingCanonChainD use blockchain::extras::{BlockReceipts, BlockDetails, TransactionAddress, EPOCH_KEY_PREFIX, EpochTransitions}; use types::blockchain_info::BlockChainInfo; use types::tree_route::TreeRoute; -use blockchain::update::ExtrasUpdate; +use blockchain::update::{ExtrasUpdate, ExtrasInsert}; use blockchain::{CacheSize, ImportRoute, Config}; use db::{self, Writable, Readable, CacheUpdatePolicy}; use cache_manager::CacheManager; use encoded; +use engines::ForkChoice; use engines::epoch::{Transition as EpochTransition, PendingTransition as PendingEpochTransition}; use rayon::prelude::*; use ansi_term::Colour; @@ -417,6 +418,42 @@ impl<'a> Iterator for AncestryIter<'a> { } } +/// An iterator which walks the blockchain towards the genesis, with metadata information. +pub struct AncestryWithMetadataIter<'a> { + current: H256, + chain: &'a BlockChain, +} + +impl<'a> Iterator for AncestryWithMetadataIter<'a> { + type Item = ExtendedHeader; + fn next(&mut self) -> Option { + if self.current.is_zero() { + None + } else { + let details = self.chain.block_details(&self.current); + let header = self.chain.block_header_data(&self.current) + .map(|h| h.decode().expect("Stored block header data is valid RLP; qed")); + + match (details, header) { + (Some(details), Some(header)) => { + self.current = details.parent; + Some(ExtendedHeader { + parent_total_difficulty: details.total_difficulty - *header.difficulty(), + is_finalized: details.is_finalized, + metadata: details.metadata, + + header: header, + }) + }, + _ => { + self.current = H256::default(); + None + }, + } + } + } +} + /// An iterator which walks all epoch transitions. /// Returns epoch transitions. pub struct EpochTransitionIter<'a> { @@ -510,6 +547,8 @@ impl BlockChain { total_difficulty: header.difficulty(), parent: header.parent_hash(), children: vec![], + is_finalized: false, + metadata: None, }; let mut batch = DBTransaction::new(); @@ -649,6 +688,7 @@ impl BlockChain { /// `None` is returned. pub fn tree_route(&self, from: H256, to: H256) -> Option { let mut from_branch = vec![]; + let mut is_from_route_finalized = false; let mut to_branch = vec![]; let mut from_details = self.block_details(&from)?; @@ -661,6 +701,7 @@ impl BlockChain { from_branch.push(current_from); current_from = from_details.parent.clone(); from_details = self.block_details(&from_details.parent)?; + is_from_route_finalized = is_from_route_finalized || from_details.is_finalized; } while to_details.number > from_details.number { @@ -676,6 +717,7 @@ impl BlockChain { from_branch.push(current_from); current_from = from_details.parent.clone(); from_details = self.block_details(&from_details.parent)?; + is_from_route_finalized = is_from_route_finalized || from_details.is_finalized; to_branch.push(current_to); current_to = to_details.parent.clone(); @@ -689,7 +731,8 @@ impl BlockChain { Some(TreeRoute { blocks: from_branch, ancestor: current_from, - index: index + index: index, + is_from_route_finalized: is_from_route_finalized, }) } @@ -733,7 +776,7 @@ impl BlockChain { self.prepare_update(batch, ExtrasUpdate { block_hashes: self.prepare_block_hashes_update(bytes, &info), - block_details: self.prepare_block_details_update(bytes, &info), + block_details: self.prepare_block_details_update(bytes, &info, false, None), block_receipts: self.prepare_block_receipts_update(receipts, &info), blocks_blooms: self.prepare_block_blooms_update(bytes, &info), transactions_addresses: self.prepare_transaction_addresses_update(bytes, &info), @@ -769,11 +812,14 @@ impl BlockChain { location: BlockLocation::CanonChain, }; + // TODO [sorpaas] support warp sync insertion of finalization and metadata. let block_details = BlockDetails { number: header.number(), total_difficulty: info.total_difficulty, parent: header.parent_hash(), children: Vec::new(), + is_finalized: false, + metadata: None, }; let mut update = HashMap::new(); @@ -898,7 +944,22 @@ impl BlockChain { /// Inserts the block into backing cache database. /// Expects the block to be valid and already verified. /// If the block is already known, does nothing. - pub fn insert_block(&self, batch: &mut DBTransaction, bytes: &[u8], receipts: Vec) -> ImportRoute { + pub fn insert_block(&self, batch: &mut DBTransaction, bytes: &[u8], receipts: Vec, extras: ExtrasInsert) -> ImportRoute { + let block = view!(BlockView, bytes); + let header = block.header_view(); + + let parent_hash = header.parent_hash(); + let best_hash = self.best_block_hash(); + + let route = self.tree_route(best_hash, parent_hash).expect("forks are only kept when it has common ancestors; tree route from best to prospective's parent always exists; qed"); + + self.insert_block_with_route(batch, bytes, receipts, route, extras) + } + + /// Inserts the block into backing cache database with already generated route information. + /// Expects the block to be valid and already verified and route is tree route information from current best block to new block's parent. + /// If the block is already known, does nothing. + pub fn insert_block_with_route(&self, batch: &mut DBTransaction, bytes: &[u8], receipts: Vec, route: TreeRoute, extras: ExtrasInsert) -> ImportRoute { // create views onto rlp let block = view!(BlockView, bytes); let header = block.header_view(); @@ -917,7 +978,7 @@ impl BlockChain { batch.put(db::COL_HEADERS, &hash, &compressed_header); batch.put(db::COL_BODIES, &hash, &compressed_body); - let info = self.block_info(&header); + let info = self.block_info(&header, route, &extras); if let BlockLocation::BranchBecomingCanonChain(ref d) = info.location { info!(target: "reorg", "Reorg to {} ({} {} {})", @@ -930,7 +991,7 @@ impl BlockChain { self.prepare_update(batch, ExtrasUpdate { block_hashes: self.prepare_block_hashes_update(bytes, &info), - block_details: self.prepare_block_details_update(bytes, &info), + block_details: self.prepare_block_details_update(bytes, &info, extras.is_finalized, extras.metadata), block_receipts: self.prepare_block_receipts_update(receipts, &info), blocks_blooms: self.prepare_block_blooms_update(bytes, &info), transactions_addresses: self.prepare_transaction_addresses_update(bytes, &info), @@ -942,45 +1003,59 @@ impl BlockChain { } /// Get inserted block info which is critical to prepare extras updates. - fn block_info(&self, header: &HeaderView) -> BlockInfo { + fn block_info(&self, header: &HeaderView, route: TreeRoute, extras: &ExtrasInsert) -> BlockInfo { let hash = header.hash(); let number = header.number(); let parent_hash = header.parent_hash(); let parent_details = self.block_details(&parent_hash).unwrap_or_else(|| panic!("Invalid parent hash: {:?}", parent_hash)); - let is_new_best = parent_details.total_difficulty + header.difficulty() > self.best_block_total_difficulty(); BlockInfo { hash: hash, number: number, total_difficulty: parent_details.total_difficulty + header.difficulty(), - location: if is_new_best { - // on new best block we need to make sure that all ancestors - // are moved to "canon chain" - // find the route between old best block and the new one - let best_hash = self.best_block_hash(); - let route = self.tree_route(best_hash, parent_hash) - .expect("blocks being imported always within recent history; qed"); - - assert_eq!(number, parent_details.number + 1); - - match route.blocks.len() { - 0 => BlockLocation::CanonChain, - _ => { - let retracted = route.blocks.iter().take(route.index).cloned().collect::>().into_iter().collect::>(); - let enacted = route.blocks.into_iter().skip(route.index).collect::>(); - BlockLocation::BranchBecomingCanonChain(BranchBecomingCanonChainData { - ancestor: route.ancestor, - enacted: enacted, - retracted: retracted, - }) + location: match extras.fork_choice { + ForkChoice::New => { + // On new best block we need to make sure that all ancestors + // are moved to "canon chain" + // find the route between old best block and the new one + match route.blocks.len() { + 0 => BlockLocation::CanonChain, + _ => { + let retracted = route.blocks.iter().take(route.index).cloned().collect::>().into_iter().collect::>(); + let enacted = route.blocks.into_iter().skip(route.index).collect::>(); + BlockLocation::BranchBecomingCanonChain(BranchBecomingCanonChainData { + ancestor: route.ancestor, + enacted: enacted, + retracted: retracted, + }) + } } - } - } else { - BlockLocation::Branch - } + }, + ForkChoice::Old => BlockLocation::Branch, + }, } } + /// Mark a block to be considered finalized. Returns `Some(())` if the operation succeeds, and `None` if the block + /// hash is not found. + pub fn mark_finalized(&self, batch: &mut DBTransaction, block_hash: H256) -> Option<()> { + let mut block_details = self.block_details(&block_hash)?; + block_details.is_finalized = true; + + self.update_block_details(batch, block_hash, block_details); + Some(()) + } + + /// Prepares extras block detail update. + fn update_block_details(&self, batch: &mut DBTransaction, block_hash: H256, block_details: BlockDetails) { + let mut details_map = HashMap::new(); + details_map.insert(block_hash, block_details); + + // We're only updating one existing value. So it shouldn't suffer from cache decoherence problem. + let mut write_details = self.pending_block_details.write(); + batch.extend_with_cache(db::COL_EXTRA, &mut *write_details, details_map, CacheUpdatePolicy::Overwrite); + } + /// Prepares extras update. fn prepare_update(&self, batch: &mut DBTransaction, update: ExtrasUpdate, is_best: bool) { @@ -1101,6 +1176,18 @@ impl BlockChain { } } + /// Iterator that lists `first` and then all of `first`'s ancestors, by extended header. + pub fn ancestry_with_metadata_iter<'a>(&'a self, first: H256) -> AncestryWithMetadataIter { + AncestryWithMetadataIter { + current: if self.is_known(&first) { + first + } else { + H256::default() // zero hash + }, + chain: self + } + } + /// Given a block's `parent`, find every block header which represents a valid possible uncle. pub fn find_uncle_headers(&self, parent: &H256, uncle_generations: usize) -> Option> { self.find_uncle_hashes(parent, uncle_generations) @@ -1166,7 +1253,7 @@ impl BlockChain { /// This function returns modified block details. /// Uses the given parent details or attempts to load them from the database. - fn prepare_block_details_update(&self, block_bytes: &[u8], info: &BlockInfo) -> HashMap { + fn prepare_block_details_update(&self, block_bytes: &[u8], info: &BlockInfo, is_finalized: bool, metadata: Option>) -> HashMap { let block = view!(BlockView, block_bytes); let header = block.header_view(); let parent_hash = header.parent_hash(); @@ -1181,6 +1268,8 @@ impl BlockChain { total_difficulty: info.total_difficulty, parent: parent_hash, children: vec![], + is_finalized: is_finalized, + metadata: metadata, }; // write to batch @@ -1418,7 +1507,7 @@ mod tests { use std::sync::Arc; use rustc_hex::FromHex; use hash::keccak; - use kvdb::KeyValueDB; + use kvdb::{KeyValueDB, DBTransaction}; use kvdb_memorydb; use ethereum_types::*; use receipt::{Receipt, TransactionOutcome}; @@ -1441,6 +1530,42 @@ mod tests { BlockChain::new(Config::default(), genesis, db) } + fn insert_block(db: &Arc, bc: &BlockChain, bytes: &[u8], receipts: Vec) -> ImportRoute { + insert_block_commit(db, bc, bytes, receipts, true) + } + + fn insert_block_commit(db: &Arc, bc: &BlockChain, bytes: &[u8], receipts: Vec, commit: bool) -> ImportRoute { + let mut batch = db.transaction(); + let res = insert_block_batch(&mut batch, bc, bytes, receipts); + db.write(batch).unwrap(); + if commit { + bc.commit(); + } + res + } + + fn insert_block_batch(batch: &mut DBTransaction, bc: &BlockChain, bytes: &[u8], receipts: Vec) -> ImportRoute { + use views::BlockView; + use blockchain::ExtrasInsert; + + let block = view!(BlockView, bytes); + let header = block.header_view(); + let parent_hash = header.parent_hash(); + let parent_details = bc.block_details(&parent_hash).unwrap_or_else(|| panic!("Invalid parent hash: {:?}", parent_hash)); + let block_total_difficulty = parent_details.total_difficulty + header.difficulty(); + let fork_choice = if block_total_difficulty > bc.best_block_total_difficulty() { + ::engines::ForkChoice::New + } else { + ::engines::ForkChoice::Old + }; + + bc.insert_block(batch, bytes, receipts, ExtrasInsert { + fork_choice: fork_choice, + is_finalized: false, + metadata: None + }) + } + #[test] fn should_cache_best_block() { // given @@ -1452,8 +1577,7 @@ mod tests { assert_eq!(bc.best_block_number(), 0); // when - let mut batch = db.transaction(); - bc.insert_block(&mut batch, &first.last().encoded(), vec![]); + insert_block_commit(&db, &bc, &first.last().encoded(), vec![], false); assert_eq!(bc.best_block_number(), 0); bc.commit(); // NOTE no db.write here (we want to check if best block is cached) @@ -1483,7 +1607,7 @@ mod tests { assert_eq!(bc.block_details(&genesis_hash).unwrap().children, vec![]); let mut batch = db.transaction(); - bc.insert_block(&mut batch, &first.encoded(), vec![]); + insert_block_batch(&mut batch, &bc, &first.encoded(), vec![]); db.write(batch).unwrap(); bc.commit(); @@ -1509,7 +1633,7 @@ mod tests { let mut batch = db.transaction(); for block in generator { block_hashes.push(block.hash()); - bc.insert_block(&mut batch, &block.encoded(), vec![]); + insert_block_batch(&mut batch, &bc, &block.encoded(), vec![]); bc.commit(); } db.write(batch).unwrap(); @@ -1549,14 +1673,10 @@ mod tests { let db = new_db(); let bc = new_chain(&genesis.last().encoded(), db.clone()); - let mut batch = db.transaction(); for b in generator { - bc.insert_block(&mut batch, &b.encoded(), vec![]); - bc.commit(); + insert_block(&db, &bc, &b.encoded(), vec![]); } - db.write(batch).unwrap(); - assert_eq!(uncle_headers, bc.find_uncle_headers(&b4a_hash, 3).unwrap()); // TODO: insert block that already includes one of them as an uncle to check it's not allowed. } @@ -1590,9 +1710,9 @@ mod tests { let bc = new_chain(&genesis.last().encoded(), db.clone()); let mut batch = db.transaction(); - let _ = bc.insert_block(&mut batch, &b1a.last().encoded(), vec![]); + let _ = insert_block_batch(&mut batch, &bc, &b1a.last().encoded(), vec![]); bc.commit(); - let _ = bc.insert_block(&mut batch, &b1b.last().encoded(), vec![]); + let _ = insert_block_batch(&mut batch, &bc, &b1b.last().encoded(), vec![]); bc.commit(); db.write(batch).unwrap(); @@ -1604,7 +1724,7 @@ mod tests { // now let's make forked chain the canon chain let mut batch = db.transaction(); - let _ = bc.insert_block(&mut batch, &b2.last().encoded(), vec![]); + let _ = insert_block_batch(&mut batch, &bc, &b2.last().encoded(), vec![]); bc.commit(); db.write(batch).unwrap(); @@ -1665,9 +1785,9 @@ mod tests { let bc = new_chain(&genesis.last().encoded(), db.clone()); let mut batch = db.transaction(); - let _ = bc.insert_block(&mut batch, &b1a.last().encoded(), vec![]); + let _ = insert_block_batch(&mut batch, &bc, &b1a.last().encoded(), vec![]); bc.commit(); - let _ = bc.insert_block(&mut batch, &b1b.last().encoded(), vec![]); + let _ = insert_block_batch(&mut batch, &bc, &b1b.last().encoded(), vec![]); bc.commit(); db.write(batch).unwrap(); @@ -1683,7 +1803,7 @@ mod tests { // now let's make forked chain the canon chain let mut batch = db.transaction(); - let _ = bc.insert_block(&mut batch, &b2.last().encoded(), vec![]); + let _ = insert_block_batch(&mut batch, &bc, &b2.last().encoded(), vec![]); bc.commit(); db.write(batch).unwrap(); @@ -1723,16 +1843,16 @@ mod tests { let bc = new_chain(&genesis.last().encoded(), db.clone()); let mut batch = db.transaction(); - let ir1 = bc.insert_block(&mut batch, &b1.last().encoded(), vec![]); + let ir1 = insert_block_batch(&mut batch, &bc, &b1.last().encoded(), vec![]); bc.commit(); - let ir2 = bc.insert_block(&mut batch, &b2.last().encoded(), vec![]); + let ir2 = insert_block_batch(&mut batch, &bc, &b2.last().encoded(), vec![]); bc.commit(); - let ir3b = bc.insert_block(&mut batch, &b3b.last().encoded(), vec![]); + let ir3b = insert_block_batch(&mut batch, &bc, &b3b.last().encoded(), vec![]); bc.commit(); db.write(batch).unwrap(); assert_eq!(bc.block_hash(3).unwrap(), b3b_hash); let mut batch = db.transaction(); - let ir3a = bc.insert_block(&mut batch, &b3a.last().encoded(), vec![]); + let ir3a = insert_block_batch(&mut batch, &bc, &b3a.last().encoded(), vec![]); bc.commit(); db.write(batch).unwrap(); @@ -1837,7 +1957,7 @@ mod tests { let bc = new_chain(&genesis.last().encoded(), db.clone()); assert_eq!(bc.best_block_hash(), genesis_hash); let mut batch = db.transaction(); - bc.insert_block(&mut batch, &first.last().encoded(), vec![]); + insert_block_batch(&mut batch, &bc, &first.last().encoded(), vec![]); db.write(batch).unwrap(); bc.commit(); assert_eq!(bc.best_block_hash(), first_hash); @@ -1896,7 +2016,7 @@ mod tests { let db = new_db(); let bc = new_chain(&genesis, db.clone()); let mut batch =db.transaction(); - bc.insert_block(&mut batch, &b1, vec![]); + insert_block_batch(&mut batch, &bc, &b1, vec![]); db.write(batch).unwrap(); bc.commit(); @@ -1907,14 +2027,6 @@ mod tests { } } - fn insert_block(db: &Arc, bc: &BlockChain, bytes: &[u8], receipts: Vec) -> ImportRoute { - let mut batch = db.transaction(); - let res = bc.insert_block(&mut batch, bytes, receipts); - db.write(batch).unwrap(); - bc.commit(); - res - } - #[test] fn test_logs() { let t1 = Transaction { @@ -2198,12 +2310,12 @@ mod tests { let mut batch = db.transaction(); // create a longer fork for block in generator { - bc.insert_block(&mut batch, &block.encoded(), vec![]); + insert_block_batch(&mut batch, &bc, &block.encoded(), vec![]); bc.commit(); } assert_eq!(bc.best_block_number(), 5); - bc.insert_block(&mut batch, &uncle.last().encoded(), vec![]); + insert_block_batch(&mut batch, &bc, &uncle.last().encoded(), vec![]); db.write(batch).unwrap(); bc.commit(); } @@ -2230,7 +2342,7 @@ mod tests { // create a longer fork for (i, block) in generator.into_iter().enumerate() { - bc.insert_block(&mut batch, &block.encoded(), vec![]); + insert_block_batch(&mut batch, &bc, &block.encoded(), vec![]); bc.insert_epoch_transition(&mut batch, i as u64, EpochTransition { block_hash: block.hash(), block_number: i as u64 + 1, @@ -2241,7 +2353,7 @@ mod tests { assert_eq!(bc.best_block_number(), 5); - bc.insert_block(&mut batch, &uncle.last().encoded(), vec![]); + insert_block_batch(&mut batch, &bc, &uncle.last().encoded(), vec![]); bc.insert_epoch_transition(&mut batch, 999, EpochTransition { block_hash: uncle.last().hash(), block_number: 1, @@ -2291,11 +2403,7 @@ mod tests { // and a non-canonical fork of 8 from genesis. let fork_hash = { for block in fork_generator { - let mut batch = db.transaction(); - - bc.insert_block(&mut batch, &block.encoded(), vec![]); - bc.commit(); - db.write(batch).unwrap(); + insert_block(&db, &bc, &block.encoded(), vec![]); } assert_eq!(bc.best_block_number(), 7); @@ -2303,11 +2411,7 @@ mod tests { }; for block in next_generator { - let mut batch = db.transaction(); - bc.insert_block(&mut batch, &block.encoded(), vec![]); - bc.commit(); - - db.write(batch).unwrap(); + insert_block(&db, &bc, &block.encoded(), vec![]); } assert_eq!(bc.best_block_number(), 10); diff --git a/ethcore/src/blockchain/extras.rs b/ethcore/src/blockchain/extras.rs index 97583a693a..3fb25e7b1b 100644 --- a/ethcore/src/blockchain/extras.rs +++ b/ethcore/src/blockchain/extras.rs @@ -23,6 +23,7 @@ use db::Key; use engines::epoch::{Transition as EpochTransition}; use header::BlockNumber; use receipt::Receipt; +use rlp; use heapsize::HeapSizeOf; use ethereum_types::{H256, H264, U256}; @@ -167,7 +168,7 @@ impl Key for u64 { } /// Familial details concerning a block -#[derive(Debug, Clone, RlpEncodable, RlpDecodable)] +#[derive(Debug, Clone)] pub struct BlockDetails { /// Block number pub number: BlockNumber, @@ -177,6 +178,57 @@ pub struct BlockDetails { pub parent: H256, /// List of children block hashes pub children: Vec, + /// Whether the block is considered finalized + pub is_finalized: bool, + /// Additional block metadata + pub metadata: Option>, +} + +impl rlp::Encodable for BlockDetails { + fn rlp_append(&self, stream: &mut rlp::RlpStream) { + let use_short_version = self.metadata.is_none() && !self.is_finalized; + + match use_short_version { + true => { stream.begin_list(4); }, + false => { stream.begin_list(6); }, + } + + stream.append(&self.number); + stream.append(&self.total_difficulty); + stream.append(&self.parent); + stream.append_list(&self.children); + if !use_short_version { + stream.append(&self.is_finalized); + stream.append(&self.metadata); + } + } +} + +impl rlp::Decodable for BlockDetails { + fn decode(rlp: &rlp::Rlp) -> Result { + let use_short_version = match rlp.item_count()? { + 4 => true, + 6 => false, + _ => return Err(rlp::DecoderError::RlpIncorrectListLen), + }; + + Ok(BlockDetails { + number: rlp.val_at(0)?, + total_difficulty: rlp.val_at(1)?, + parent: rlp.val_at(2)?, + children: rlp.list_at(3)?, + is_finalized: if use_short_version { + false + } else { + rlp.val_at(4)? + }, + metadata: if use_short_version { + None + } else { + rlp.val_at(5)? + }, + }) + } } impl HeapSizeOf for BlockDetails { diff --git a/ethcore/src/blockchain/mod.rs b/ethcore/src/blockchain/mod.rs index 062068c704..f991692ded 100644 --- a/ethcore/src/blockchain/mod.rs +++ b/ethcore/src/blockchain/mod.rs @@ -33,4 +33,5 @@ pub use self::cache::CacheSize; pub use self::config::Config; pub use self::extras::{BlockReceipts, BlockDetails, TransactionAddress}; pub use self::import_route::ImportRoute; +pub use self::update::ExtrasInsert; pub use types::tree_route::TreeRoute; diff --git a/ethcore/src/blockchain/update.rs b/ethcore/src/blockchain/update.rs index a5251c1ed8..b695b9236b 100644 --- a/ethcore/src/blockchain/update.rs +++ b/ethcore/src/blockchain/update.rs @@ -22,3 +22,13 @@ pub struct ExtrasUpdate<'a> { /// Modified transaction addresses (None signifies removed transactions). pub transactions_addresses: HashMap>, } + +/// Extra information in block insertion. +pub struct ExtrasInsert { + /// The primitive fork choice before applying finalization rules. + pub fork_choice: ::engines::ForkChoice, + /// Is the inserted block considered finalized. + pub is_finalized: bool, + /// New block local metadata. + pub metadata: Option>, +} diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index 76d78e3df6..993ecdda21 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -33,7 +33,7 @@ use util_error::UtilError; // other use ethereum_types::{H256, Address, U256}; use block::{IsBlock, LockedBlock, Drain, ClosedBlock, OpenBlock, enact_verified, SealedBlock}; -use blockchain::{BlockChain, BlockProvider, TreeRoute, ImportRoute, TransactionAddress}; +use blockchain::{BlockChain, BlockProvider, TreeRoute, ImportRoute, TransactionAddress, ExtrasInsert}; use client::ancient_import::AncientVerifier; use client::Error as ClientError; use client::{ @@ -50,13 +50,13 @@ use client::{ IoClient, }; use encoded; -use engines::{EthEngine, EpochTransition}; +use engines::{EthEngine, EpochTransition, ForkChoice}; use error::{ImportErrorKind, BlockImportErrorKind, ExecutionError, CallError, BlockError, ImportResult, Error as EthcoreError}; use vm::{EnvInfo, LastHashes}; use evm::Schedule; use executive::{Executive, Executed, TransactOptions, contract_address}; use factory::{Factories, VmFactory}; -use header::{BlockNumber, Header}; +use header::{BlockNumber, Header, ExtendedHeader}; use io::{IoChannel, IoError}; use log_entry::LocalizedLogEntry; use miner::{Miner, MinerService}; @@ -73,10 +73,12 @@ use trace::{TraceDB, ImportRequest as TraceImportRequest, LocalizedTrace, Databa use transaction::{self, LocalizedTransaction, UnverifiedTransaction, SignedTransaction, Transaction, Action}; use types::filter::Filter; use types::mode::Mode as IpcMode; +use types::ancestry_action::AncestryAction; use verification; use verification::{PreverifiedBlock, Verifier}; use verification::queue::BlockQueue; use views::BlockView; +use parity_machine::{Finalizable, WithMetadata}; // re-export pub use types::blockchain_info::BlockChainInfo; @@ -396,6 +398,7 @@ impl Importer { last_hashes, client.factories.clone(), is_epoch_begin, + &mut chain.ancestry_with_metadata_iter(*header.parent_hash()), ); let mut locked_block = enact_result.map_err(|e| { @@ -467,6 +470,44 @@ impl Importer { let mut batch = DBTransaction::new(); + let ancestry_actions = self.engine.ancestry_actions(block.block(), &mut chain.ancestry_with_metadata_iter(*parent)); + + let best_hash = chain.best_block_hash(); + let metadata = block.block().metadata().map(Into::into); + let is_finalized = block.block().is_finalized(); + + let new = ExtendedHeader { + header: header.clone(), + is_finalized: is_finalized, + metadata: metadata, + parent_total_difficulty: chain.block_details(&parent).expect("Parent block is in the database; qed").total_difficulty + }; + + let best = { + let hash = best_hash; + let header = chain.block_header_data(&hash) + .expect("Best block is in the database; qed") + .decode() + .expect("Stored block header is valid RLP; qed"); + let details = chain.block_details(&hash) + .expect("Best block is in the database; qed"); + + ExtendedHeader { + parent_total_difficulty: details.total_difficulty - *header.difficulty(), + is_finalized: details.is_finalized, + metadata: details.metadata, + + header: header, + } + }; + + let route = chain.tree_route(best_hash, *parent).expect("forks are only kept when it has common ancestors; tree route from best to prospective's parent always exists; qed"); + let fork_choice = if route.is_from_route_finalized { + ForkChoice::Old + } else { + self.engine.fork_choice(&new, &best) + }; + // CHECK! I *think* this is fine, even if the state_root is equal to another // already-imported block of the same number. // TODO: Prove it with a test. @@ -485,7 +526,17 @@ impl Importer { ); state.journal_under(&mut batch, number, hash).expect("DB commit failed"); - let route = chain.insert_block(&mut batch, block_data, receipts.clone()); + + for ancestry_action in ancestry_actions { + let AncestryAction::MarkFinalized(ancestry) = ancestry_action; + chain.mark_finalized(&mut batch, ancestry).expect("Engine's ancestry action must be known blocks; qed"); + } + + let route = chain.insert_block(&mut batch, block_data, receipts.clone(), ExtrasInsert { + fork_choice: fork_choice, + is_finalized: is_finalized, + metadata: new.metadata, + }); client.tracedb.read().import(&mut batch, TraceImportRequest { traces: traces.into(), @@ -2069,6 +2120,7 @@ impl PrepareOpenBlock for Client { gas_range_target, extra_data, is_epoch_begin, + &mut chain.ancestry_with_metadata_iter(best_header.hash()), ).expect("OpenBlock::new only fails if parent state root invalid; state root of best block's header is never invalid; qed"); // Add uncles @@ -2284,6 +2336,7 @@ mod tests { use std::sync::Arc; use std::sync::atomic::{AtomicBool, Ordering}; use kvdb::DBTransaction; + use blockchain::ExtrasInsert; let client = generate_dummy_client(0); let genesis = client.chain_info().best_block_hash; @@ -2296,7 +2349,11 @@ mod tests { let another_client = client.clone(); thread::spawn(move || { let mut batch = DBTransaction::new(); - another_client.chain.read().insert_block(&mut batch, &new_block, Vec::new()); + another_client.chain.read().insert_block(&mut batch, &new_block, Vec::new(), ExtrasInsert { + fork_choice: ::engines::ForkChoice::New, + is_finalized: false, + metadata: None, + }); go_thread.store(true, Ordering::SeqCst); }); go diff --git a/ethcore/src/client/test_client.rs b/ethcore/src/client/test_client.rs index 6a3166f7c0..fab3234657 100644 --- a/ethcore/src/client/test_client.rs +++ b/ethcore/src/client/test_client.rs @@ -392,6 +392,7 @@ impl PrepareOpenBlock for TestBlockChainClient { gas_range_target, extra_data, false, + &mut Vec::new().into_iter(), ).expect("Opening block for tests will not fail."); // TODO [todr] Override timestamp for predictability open_block.set_timestamp(*self.latest_block_timestamp.read()); @@ -739,7 +740,8 @@ impl BlockChainClient for TestBlockChainClient { } } if adding { Vec::new() } else { blocks } - } + }, + is_from_route_finalized: false, }) } diff --git a/ethcore/src/engines/authority_round/mod.rs b/ethcore/src/engines/authority_round/mod.rs index ed9a9a4f25..02bb88c51f 100644 --- a/ethcore/src/engines/authority_round/mod.rs +++ b/ethcore/src/engines/authority_round/mod.rs @@ -33,7 +33,7 @@ use error::{Error, BlockError}; use ethjson; use machine::{AuxiliaryData, Call, EthereumMachine}; use hash::keccak; -use header::{Header, BlockNumber}; +use header::{Header, BlockNumber, ExtendedHeader}; use super::signer::EngineSigner; use super::validator_set::{ValidatorSet, SimpleList, new_validator_set}; @@ -957,6 +957,7 @@ impl Engine for AuthorityRound { &self, block: &mut ExecutedBlock, epoch_begin: bool, + _ancestry: &mut Iterator, ) -> Result<(), Error> { // with immediate transitions, we don't use the epoch mechanism anyway. // the genesis is always considered an epoch, but we ignore it intentionally. @@ -1348,6 +1349,10 @@ impl Engine for AuthorityRound { Some(Box::new(::snapshot::PoaSnapshot)) } } + + fn fork_choice(&self, new: &ExtendedHeader, current: &ExtendedHeader) -> super::ForkChoice { + super::total_difficulty_fork_choice(new, current) + } } #[cfg(test)] @@ -1407,9 +1412,9 @@ mod tests { let db1 = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap(); let db2 = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap(); let last_hashes = Arc::new(vec![genesis_header.hash()]); - let b1 = OpenBlock::new(engine, Default::default(), false, db1, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![], false).unwrap(); + let b1 = OpenBlock::new(engine, Default::default(), false, db1, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![], false, &mut Vec::new().into_iter()).unwrap(); let b1 = b1.close_and_lock(); - let b2 = OpenBlock::new(engine, Default::default(), false, db2, &genesis_header, last_hashes, addr2, (3141562.into(), 31415620.into()), vec![], false).unwrap(); + let b2 = OpenBlock::new(engine, Default::default(), false, db2, &genesis_header, last_hashes, addr2, (3141562.into(), 31415620.into()), vec![], false, &mut Vec::new().into_iter()).unwrap(); let b2 = b2.close_and_lock(); engine.set_signer(tap.clone(), addr1, "1".into()); @@ -1441,9 +1446,9 @@ mod tests { let db2 = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap(); let last_hashes = Arc::new(vec![genesis_header.hash()]); - let b1 = OpenBlock::new(engine, Default::default(), false, db1, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![], false).unwrap(); + let b1 = OpenBlock::new(engine, Default::default(), false, db1, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![], false, &mut Vec::new().into_iter()).unwrap(); let b1 = b1.close_and_lock(); - let b2 = OpenBlock::new(engine, Default::default(), false, db2, &genesis_header, last_hashes, addr2, (3141562.into(), 31415620.into()), vec![], false).unwrap(); + let b2 = OpenBlock::new(engine, Default::default(), false, db2, &genesis_header, last_hashes, addr2, (3141562.into(), 31415620.into()), vec![], false, &mut Vec::new().into_iter()).unwrap(); let b2 = b2.close_and_lock(); engine.set_signer(tap.clone(), addr1, "1".into()); @@ -1696,7 +1701,7 @@ mod tests { let db1 = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap(); let last_hashes = Arc::new(vec![genesis_header.hash()]); - let b1 = OpenBlock::new(engine, Default::default(), false, db1, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![], false).unwrap(); + let b1 = OpenBlock::new(engine, Default::default(), false, db1, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![], false, &mut Vec::new().into_iter()).unwrap(); let b1 = b1.close_and_lock(); let client = generate_dummy_client(0); @@ -1731,7 +1736,7 @@ mod tests { let last_hashes = Arc::new(vec![genesis_header.hash()]); // step 2 - let b1 = OpenBlock::new(engine, Default::default(), false, db1, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![], false).unwrap(); + let b1 = OpenBlock::new(engine, Default::default(), false, db1, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![], false, &mut Vec::new().into_iter()).unwrap(); let b1 = b1.close_and_lock(); // since the block is empty it isn't sealed and we generate empty steps @@ -1740,7 +1745,7 @@ mod tests { engine.step(); // step 3 - let mut b2 = OpenBlock::new(engine, Default::default(), false, db2, &genesis_header, last_hashes.clone(), addr2, (3141562.into(), 31415620.into()), vec![], false).unwrap(); + let mut b2 = OpenBlock::new(engine, Default::default(), false, db2, &genesis_header, last_hashes.clone(), addr2, (3141562.into(), 31415620.into()), vec![], false, &mut Vec::new().into_iter()).unwrap(); b2.push_transaction(Transaction { action: Action::Create, nonce: U256::from(0), @@ -1779,7 +1784,7 @@ mod tests { let last_hashes = Arc::new(vec![genesis_header.hash()]); // step 2 - let b1 = OpenBlock::new(engine, Default::default(), false, db1, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![], false).unwrap(); + let b1 = OpenBlock::new(engine, Default::default(), false, db1, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![], false, &mut Vec::new().into_iter()).unwrap(); let b1 = b1.close_and_lock(); // since the block is empty it isn't sealed and we generate empty steps @@ -1788,7 +1793,7 @@ mod tests { engine.step(); // step 3 - let b2 = OpenBlock::new(engine, Default::default(), false, db2, &genesis_header, last_hashes.clone(), addr2, (3141562.into(), 31415620.into()), vec![], false).unwrap(); + let b2 = OpenBlock::new(engine, Default::default(), false, db2, &genesis_header, last_hashes.clone(), addr2, (3141562.into(), 31415620.into()), vec![], false, &mut Vec::new().into_iter()).unwrap(); let b2 = b2.close_and_lock(); engine.set_signer(tap.clone(), addr2, "0".into()); assert_eq!(engine.generate_seal(b2.block(), &genesis_header), Seal::None); @@ -1796,7 +1801,7 @@ mod tests { // step 4 // the spec sets the maximum_empty_steps to 2 so we will now seal an empty block and include the empty step messages - let b3 = OpenBlock::new(engine, Default::default(), false, db3, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![], false).unwrap(); + let b3 = OpenBlock::new(engine, Default::default(), false, db3, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![], false, &mut Vec::new().into_iter()).unwrap(); let b3 = b3.close_and_lock(); engine.set_signer(tap.clone(), addr1, "1".into()); @@ -1829,7 +1834,7 @@ mod tests { engine.register_client(Arc::downgrade(&client) as _); // step 2 - let b1 = OpenBlock::new(engine, Default::default(), false, db1, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![], false).unwrap(); + let b1 = OpenBlock::new(engine, Default::default(), false, db1, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![], false, &mut Vec::new().into_iter()).unwrap(); let b1 = b1.close_and_lock(); // since the block is empty it isn't sealed and we generate empty steps @@ -1839,7 +1844,7 @@ mod tests { // step 3 // the signer of the accumulated empty step message should be rewarded - let b2 = OpenBlock::new(engine, Default::default(), false, db2, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![], false).unwrap(); + let b2 = OpenBlock::new(engine, Default::default(), false, db2, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![], false, &mut Vec::new().into_iter()).unwrap(); let addr1_balance = b2.block().state().balance(&addr1).unwrap(); // after closing the block `addr1` should be reward twice, one for the included empty step message and another for block creation @@ -1962,6 +1967,7 @@ mod tests { (3141562.into(), 31415620.into()), vec![], false, + &mut Vec::new().into_iter(), ).unwrap(); let b1 = b1.close_and_lock(); @@ -1983,6 +1989,7 @@ mod tests { (3141562.into(), 31415620.into()), vec![], false, + &mut Vec::new().into_iter(), ).unwrap(); let addr1_balance = b2.block().state().balance(&addr1).unwrap(); diff --git a/ethcore/src/engines/basic_authority.rs b/ethcore/src/engines/basic_authority.rs index bbefddccb7..e99fd88dcb 100644 --- a/ethcore/src/engines/basic_authority.rs +++ b/ethcore/src/engines/basic_authority.rs @@ -25,7 +25,7 @@ use block::*; use engines::{Engine, Seal, ConstructedVerifier, EngineError}; use error::{BlockError, Error}; use ethjson; -use header::Header; +use header::{Header, ExtendedHeader}; use client::EngineClient; use machine::{AuxiliaryData, Call, EthereumMachine}; use super::signer::EngineSigner; @@ -191,6 +191,10 @@ impl Engine for BasicAuthority { fn snapshot_components(&self) -> Option> { None } + + fn fork_choice(&self, new: &ExtendedHeader, current: &ExtendedHeader) -> super::ForkChoice { + super::total_difficulty_fork_choice(new, current) + } } #[cfg(test)] @@ -247,7 +251,7 @@ mod tests { let genesis_header = spec.genesis_header(); let db = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap(); let last_hashes = Arc::new(vec![genesis_header.hash()]); - let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, addr, (3141562.into(), 31415620.into()), vec![], false).unwrap(); + let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, addr, (3141562.into(), 31415620.into()), vec![], false, &mut Vec::new().into_iter()).unwrap(); let b = b.close_and_lock(); if let Seal::Regular(seal) = engine.generate_seal(b.block(), &genesis_header) { assert!(b.try_seal(engine, seal).is_ok()); diff --git a/ethcore/src/engines/instant_seal.rs b/ethcore/src/engines/instant_seal.rs index 40a96e2b71..c16203f105 100644 --- a/ethcore/src/engines/instant_seal.rs +++ b/ethcore/src/engines/instant_seal.rs @@ -15,7 +15,7 @@ // along with Parity. If not, see . use engines::{Engine, Seal}; -use parity_machine::{Machine, Transactions}; +use parity_machine::{Machine, Transactions, TotalScoredHeader}; /// An engine which does not provide any consensus mechanism, just seals blocks internally. /// Only seals blocks which have transactions. @@ -33,7 +33,9 @@ impl InstantSeal { } impl Engine for InstantSeal - where M::LiveBlock: Transactions + where M::LiveBlock: Transactions, + M::ExtendedHeader: TotalScoredHeader, + ::Value: Ord { fn name(&self) -> &str { "InstantSeal" @@ -61,6 +63,10 @@ impl Engine for InstantSeal fn is_timestamp_valid(&self, header_timestamp: u64, parent_timestamp: u64) -> bool { header_timestamp >= parent_timestamp } + + fn fork_choice(&self, new: &M::ExtendedHeader, current: &M::ExtendedHeader) -> super::ForkChoice { + super::total_difficulty_fork_choice(new, current) + } } #[cfg(test)] @@ -80,7 +86,7 @@ mod tests { let db = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap(); let genesis_header = spec.genesis_header(); let last_hashes = Arc::new(vec![genesis_header.hash()]); - let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, Address::default(), (3141562.into(), 31415620.into()), vec![], false).unwrap(); + let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, Address::default(), (3141562.into(), 31415620.into()), vec![], false, &mut Vec::new().into_iter()).unwrap(); let b = b.close_and_lock(); if let Seal::Regular(seal) = engine.generate_seal(b.block(), &genesis_header) { assert!(b.try_seal(engine, seal).is_ok()); diff --git a/ethcore/src/engines/mod.rs b/ethcore/src/engines/mod.rs index e019636f53..0878b4595f 100644 --- a/ethcore/src/engines/mod.rs +++ b/ethcore/src/engines/mod.rs @@ -52,15 +52,25 @@ use spec::CommonParams; use transaction::{self, UnverifiedTransaction, SignedTransaction}; use ethkey::Signature; -use parity_machine::{Machine, LocalizedMachine as Localized}; +use parity_machine::{Machine, LocalizedMachine as Localized, TotalScoredHeader}; use ethereum_types::{H256, U256, Address}; use unexpected::{Mismatch, OutOfBounds}; use bytes::Bytes; +use types::ancestry_action::AncestryAction; /// Default EIP-210 contract code. /// As defined in https://github.com/ethereum/EIPs/pull/210 pub const DEFAULT_BLOCKHASH_CONTRACT: &'static str = "73fffffffffffffffffffffffffffffffffffffffe33141561006a5760014303600035610100820755610100810715156100455760003561010061010083050761010001555b6201000081071515610064576000356101006201000083050761020001555b5061013e565b4360003512151561008457600060405260206040f361013d565b61010060003543031315156100a857610100600035075460605260206060f361013c565b6101006000350715156100c55762010000600035430313156100c8565b60005b156100ea576101006101006000350507610100015460805260206080f361013b565b620100006000350715156101095763010000006000354303131561010c565b60005b1561012f57610100620100006000350507610200015460a052602060a0f361013a565b600060c052602060c0f35b5b5b5b5b"; +/// Fork choice. +#[derive(Debug, PartialEq, Eq)] +pub enum ForkChoice { + /// Choose the new block. + New, + /// Choose the current best block. + Old, +} + /// Voting errors. #[derive(Debug)] pub enum EngineError { @@ -208,6 +218,7 @@ pub trait Engine: Sync + Send { &self, _block: &mut M::LiveBlock, _epoch_begin: bool, + _ancestry: &mut Iterator, ) -> Result<(), M::Error> { Ok(()) } @@ -348,6 +359,24 @@ pub trait Engine: Sync + Send { fn is_timestamp_valid(&self, header_timestamp: u64, parent_timestamp: u64) -> bool { header_timestamp > parent_timestamp } + + /// Gather all ancestry actions. Called at the last stage when a block is committed. The Engine must guarantee that + /// the ancestry exists. + fn ancestry_actions(&self, _block: &M::LiveBlock, _ancestry: &mut Iterator) -> Vec { + Vec::new() + } + + /// Check whether the given new block is the best block, after finalization check. + fn fork_choice(&self, new: &M::ExtendedHeader, best: &M::ExtendedHeader) -> ForkChoice; +} + +/// Check whether a given block is the best block based on the default total difficulty rule. +pub fn total_difficulty_fork_choice(new: &T, best: &T) -> ForkChoice where ::Value: Ord { + if new.total_score() > best.total_score() { + ForkChoice::New + } else { + ForkChoice::Old + } } /// Common type alias for an engine coupled with an Ethereum-like state machine. diff --git a/ethcore/src/engines/null_engine.rs b/ethcore/src/engines/null_engine.rs index 278eb037c0..c6025e6247 100644 --- a/ethcore/src/engines/null_engine.rs +++ b/ethcore/src/engines/null_engine.rs @@ -19,7 +19,7 @@ use engines::Engine; use engines::block_reward::{self, RewardKind}; use header::BlockNumber; use machine::WithRewards; -use parity_machine::{Header, LiveBlock, WithBalances}; +use parity_machine::{Header, LiveBlock, WithBalances, TotalScoredHeader}; /// Params for a null engine. #[derive(Clone, Default)] @@ -58,7 +58,10 @@ impl Default for NullEngine { } } -impl Engine for NullEngine { +impl Engine for NullEngine + where M::ExtendedHeader: TotalScoredHeader, + ::Value: Ord +{ fn name(&self) -> &str { "NullEngine" } @@ -101,4 +104,8 @@ impl Engine for NullEngine { fn snapshot_components(&self) -> Option> { Some(Box::new(::snapshot::PowSnapshot::new(10000, 10000))) } + + fn fork_choice(&self, new: &M::ExtendedHeader, current: &M::ExtendedHeader) -> super::ForkChoice { + super::total_difficulty_fork_choice(new, current) + } } diff --git a/ethcore/src/engines/tendermint/mod.rs b/ethcore/src/engines/tendermint/mod.rs index 93fc347e94..52bf5ff67b 100644 --- a/ethcore/src/engines/tendermint/mod.rs +++ b/ethcore/src/engines/tendermint/mod.rs @@ -35,7 +35,7 @@ use unexpected::{OutOfBounds, Mismatch}; use client::EngineClient; use bytes::Bytes; use error::{Error, BlockError}; -use header::{Header, BlockNumber}; +use header::{Header, BlockNumber, ExtendedHeader}; use rlp::Rlp; use ethkey::{self, Message, Signature}; use account_provider::AccountProvider; @@ -530,7 +530,7 @@ impl Engine for Tendermint { Ok(()) } - fn on_new_block(&self, block: &mut ExecutedBlock, epoch_begin: bool) -> Result<(), Error> { + fn on_new_block(&self, block: &mut ExecutedBlock, epoch_begin: bool, _ancestry: &mut Iterator) -> Result<(), Error> { if !epoch_begin { return Ok(()) } // genesis is never a new block, but might as well check. @@ -765,6 +765,10 @@ impl Engine for Tendermint { *self.client.write() = Some(client.clone()); self.validators.register_client(client); } + + fn fork_choice(&self, new: &ExtendedHeader, current: &ExtendedHeader) -> super::ForkChoice { + super::total_difficulty_fork_choice(new, current) + } } #[cfg(test)] @@ -800,7 +804,7 @@ mod tests { let db = spec.ensure_db_good(db, &Default::default()).unwrap(); let genesis_header = spec.genesis_header(); let last_hashes = Arc::new(vec![genesis_header.hash()]); - let b = OpenBlock::new(spec.engine.as_ref(), Default::default(), false, db.boxed_clone(), &genesis_header, last_hashes, proposer, (3141562.into(), 31415620.into()), vec![], false).unwrap(); + let b = OpenBlock::new(spec.engine.as_ref(), Default::default(), false, db.boxed_clone(), &genesis_header, last_hashes, proposer, (3141562.into(), 31415620.into()), vec![], false, &mut Vec::new().into_iter()).unwrap(); let b = b.close(); if let Seal::Proposal(seal) = spec.engine.generate_seal(b.block(), &genesis_header) { (b, seal) diff --git a/ethcore/src/ethereum/ethash.rs b/ethcore/src/ethereum/ethash.rs index 09151415c8..9b3945e38b 100644 --- a/ethcore/src/ethereum/ethash.rs +++ b/ethcore/src/ethereum/ethash.rs @@ -25,7 +25,7 @@ use ethereum_types::{H256, H64, U256, Address}; use unexpected::{OutOfBounds, Mismatch}; use block::*; use error::{BlockError, Error}; -use header::{Header, BlockNumber}; +use header::{Header, BlockNumber, ExtendedHeader}; use engines::{self, Engine}; use ethjson; use rlp::Rlp; @@ -222,14 +222,6 @@ impl Engine for Arc { header.set_difficulty(difficulty); } - fn on_new_block( - &self, - _block: &mut ExecutedBlock, - _begins_epoch: bool, - ) -> Result<(), Error> { - Ok(()) - } - /// 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> { @@ -364,6 +356,10 @@ impl Engine for Arc { fn snapshot_components(&self) -> Option> { Some(Box::new(::snapshot::PowSnapshot::new(SNAPSHOT_BLOCKS, MAX_SNAPSHOT_BLOCKS))) } + + fn fork_choice(&self, new: &ExtendedHeader, current: &ExtendedHeader) -> engines::ForkChoice { + engines::total_difficulty_fork_choice(new, current) + } } impl Ethash { @@ -538,7 +534,7 @@ mod tests { let genesis_header = spec.genesis_header(); let db = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap(); let last_hashes = Arc::new(vec![genesis_header.hash()]); - let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, Address::zero(), (3141562.into(), 31415620.into()), vec![], false).unwrap(); + let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, Address::zero(), (3141562.into(), 31415620.into()), vec![], false, &mut Vec::new().into_iter()).unwrap(); let b = b.close(); assert_eq!(b.state().balance(&Address::zero()).unwrap(), U256::from_str("4563918244f40000").unwrap()); } @@ -587,7 +583,7 @@ mod tests { let genesis_header = spec.genesis_header(); let db = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap(); let last_hashes = Arc::new(vec![genesis_header.hash()]); - let mut b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, Address::zero(), (3141562.into(), 31415620.into()), vec![], false).unwrap(); + let mut b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, Address::zero(), (3141562.into(), 31415620.into()), vec![], false, &mut Vec::new().into_iter()).unwrap(); let mut uncle = Header::new(); let uncle_author: Address = "ef2d6d194084c2de36e0dabfce45d046b37d1106".into(); uncle.set_author(uncle_author); @@ -605,7 +601,7 @@ mod tests { let genesis_header = spec.genesis_header(); let db = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap(); let last_hashes = Arc::new(vec![genesis_header.hash()]); - let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, Address::zero(), (3141562.into(), 31415620.into()), vec![], false).unwrap(); + let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, Address::zero(), (3141562.into(), 31415620.into()), vec![], false, &mut Vec::new().into_iter()).unwrap(); let b = b.close(); let ubi_contract: Address = "00efdd5883ec628983e9063c7d969fe268bbf310".into(); diff --git a/ethcore/src/header.rs b/ethcore/src/header.rs index ba71eb3049..3e9675aa35 100644 --- a/ethcore/src/header.rs +++ b/ethcore/src/header.rs @@ -34,6 +34,19 @@ enum Seal { Without, } +/// Extended block header, wrapping `Header` with finalized and total difficulty information. +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct ExtendedHeader { + /// The actual header. + pub header: Header, + /// Whether the block underlying this header is considered finalized. + pub is_finalized: bool, + /// The parent block difficulty. + pub parent_total_difficulty: U256, + /// The block metadata information. + pub metadata: Option>, +} + /// A block header. /// /// Reflects the specific RLP fields of a block in the chain with additional room for the seal @@ -368,21 +381,48 @@ impl HeapSizeOf for Header { impl ::parity_machine::Header for Header { fn bare_hash(&self) -> H256 { Header::bare_hash(self) } - fn hash(&self) -> H256 { Header::hash(self) } - fn seal(&self) -> &[Vec] { Header::seal(self) } - fn author(&self) -> &Address { Header::author(self) } - fn number(&self) -> BlockNumber { Header::number(self) } } impl ::parity_machine::ScoredHeader for Header { + type Value = U256; + fn score(&self) -> &U256 { self.difficulty() } fn set_score(&mut self, score: U256) { self.set_difficulty(score) } } +impl ::parity_machine::Header for ExtendedHeader { + fn bare_hash(&self) -> H256 { self.header.bare_hash() } + fn hash(&self) -> H256 { self.header.hash() } + fn seal(&self) -> &[Vec] { self.header.seal() } + fn author(&self) -> &Address { self.header.author() } + fn number(&self) -> BlockNumber { self.header.number() } +} + +impl ::parity_machine::ScoredHeader for ExtendedHeader { + type Value = U256; + + fn score(&self) -> &U256 { self.header.difficulty() } + fn set_score(&mut self, score: U256) { self.header.set_difficulty(score) } +} + +impl ::parity_machine::TotalScoredHeader for ExtendedHeader { + type Value = U256; + + fn total_score(&self) -> U256 { self.parent_total_difficulty + *self.header.difficulty() } +} + +impl ::parity_machine::FinalizableHeader for ExtendedHeader { + fn is_finalized(&self) -> bool { self.is_finalized } +} + +impl ::parity_machine::WithMetadataHeader for ExtendedHeader { + fn metadata(&self) -> Option<&[u8]> { self.metadata.as_ref().map(|v| v.as_ref()) } +} + #[cfg(test)] mod tests { use rustc_hex::FromHex; diff --git a/ethcore/src/machine.rs b/ethcore/src/machine.rs index d0d434b1de..1bd3805ef3 100644 --- a/ethcore/src/machine.rs +++ b/ethcore/src/machine.rs @@ -25,7 +25,7 @@ use builtin::Builtin; use client::{BlockInfo, CallContract}; use error::Error; use executive::Executive; -use header::{BlockNumber, Header}; +use header::{BlockNumber, Header, ExtendedHeader}; use spec::CommonParams; use state::{CleanupMode, Substate}; use trace::{NoopTracer, NoopVMTracer, Tracer, ExecutiveTracer, RewardType, Tracing}; @@ -422,10 +422,12 @@ pub enum AuxiliaryRequest { impl ::parity_machine::Machine for EthereumMachine { type Header = Header; + type ExtendedHeader = ExtendedHeader; type LiveBlock = ExecutedBlock; type EngineClient = ::client::EngineClient; type AuxiliaryRequest = AuxiliaryRequest; + type AncestryAction = ::types::ancestry_action::AncestryAction; type Error = Error; } diff --git a/ethcore/src/snapshot/tests/proof_of_work.rs b/ethcore/src/snapshot/tests/proof_of_work.rs index ae1805e85b..3c3b47ce9c 100644 --- a/ethcore/src/snapshot/tests/proof_of_work.rs +++ b/ethcore/src/snapshot/tests/proof_of_work.rs @@ -22,7 +22,7 @@ use tempdir::TempDir; use error::{Error, ErrorKind}; use blockchain::generator::{BlockGenerator, BlockBuilder}; -use blockchain::BlockChain; +use blockchain::{BlockChain, ExtrasInsert}; use snapshot::{chunk_secondary, Error as SnapshotError, Progress, SnapshotComponents}; use snapshot::io::{PackedReader, PackedWriter, SnapshotReader, SnapshotWriter}; @@ -49,7 +49,11 @@ fn chunk_and_restore(amount: u64) { // build the blockchain. let mut batch = DBTransaction::new(); for block in generator { - bc.insert_block(&mut batch, &block.encoded(), vec![]); + bc.insert_block(&mut batch, &block.encoded(), vec![], ExtrasInsert { + fork_choice: ::engines::ForkChoice::New, + is_finalized: false, + metadata: None, + }); bc.commit(); } diff --git a/ethcore/src/test_helpers.rs b/ethcore/src/test_helpers.rs index 32b8beab83..e57d16a654 100644 --- a/ethcore/src/test_helpers.rs +++ b/ethcore/src/test_helpers.rs @@ -19,7 +19,7 @@ use account_provider::AccountProvider; use ethereum_types::{H256, U256, Address}; use block::{OpenBlock, Drain}; -use blockchain::{BlockChain, Config as BlockChainConfig}; +use blockchain::{BlockChain, Config as BlockChainConfig, ExtrasInsert}; use bytes::Bytes; use client::{Client, ClientConfig, ChainInfo, ImportBlock, ChainNotify, ChainMessageType, PrepareOpenBlock}; use ethkey::KeyPair; @@ -148,6 +148,7 @@ pub fn generate_dummy_client_with_spec_accounts_and_data(test_spec: F, accoun (3141562.into(), 31415620.into()), vec![], false, + &mut Vec::new().into_iter(), ).unwrap(); rolling_timestamp += 10; b.set_timestamp(rolling_timestamp); @@ -265,7 +266,12 @@ pub fn generate_dummy_blockchain(block_number: u32) -> BlockChain { let mut batch = db.transaction(); for block_order in 1..block_number { - bc.insert_block(&mut batch, &create_unverifiable_block(block_order, bc.best_block_hash()), vec![]); + // Total difficulty is always 0 here. + bc.insert_block(&mut batch, &create_unverifiable_block(block_order, bc.best_block_hash()), vec![], ExtrasInsert { + fork_choice: ::engines::ForkChoice::New, + is_finalized: false, + metadata: None, + }); bc.commit(); } db.write(batch).unwrap(); @@ -280,7 +286,12 @@ pub fn generate_dummy_blockchain_with_extra(block_number: u32) -> BlockChain { let mut batch = db.transaction(); for block_order in 1..block_number { - bc.insert_block(&mut batch, &create_unverifiable_block_with_extra(block_order, bc.best_block_hash(), None), vec![]); + // Total difficulty is always 0 here. + bc.insert_block(&mut batch, &create_unverifiable_block_with_extra(block_order, bc.best_block_hash(), None), vec![], ExtrasInsert { + fork_choice: ::engines::ForkChoice::New, + is_finalized: false, + metadata: None, + }); bc.commit(); } db.write(batch).unwrap(); diff --git a/ethcore/src/tests/trace.rs b/ethcore/src/tests/trace.rs index 72d0d47371..a98667b142 100644 --- a/ethcore/src/tests/trace.rs +++ b/ethcore/src/tests/trace.rs @@ -87,6 +87,7 @@ fn can_trace_block_and_uncle_reward() { (3141562.into(), 31415620.into()), vec![], false, + &mut Vec::new().into_iter(), ).unwrap(); rolling_timestamp += 10; root_block.set_timestamp(rolling_timestamp); @@ -115,6 +116,7 @@ fn can_trace_block_and_uncle_reward() { (3141562.into(), 31415620.into()), vec![], false, + &mut Vec::new().into_iter(), ).unwrap(); rolling_timestamp += 10; parent_block.set_timestamp(rolling_timestamp); @@ -141,7 +143,8 @@ fn can_trace_block_and_uncle_reward() { author.clone(), (3141562.into(), 31415620.into()), vec![], - false + false, + &mut Vec::new().into_iter(), ).unwrap(); rolling_timestamp += 10; block.set_timestamp(rolling_timestamp); diff --git a/ethcore/src/verification/verification.rs b/ethcore/src/verification/verification.rs index 03a6d6f8d4..de2f6c7195 100644 --- a/ethcore/src/verification/verification.rs +++ b/ethcore/src/verification/verification.rs @@ -455,6 +455,8 @@ mod tests { total_difficulty: header.difficulty().clone(), parent: header.parent_hash().clone(), children: Vec::new(), + is_finalized: false, + metadata: None, } }) } diff --git a/ethcore/types/src/ancestry_action.rs b/ethcore/types/src/ancestry_action.rs new file mode 100644 index 0000000000..d9915cfee4 --- /dev/null +++ b/ethcore/types/src/ancestry_action.rs @@ -0,0 +1,27 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +//! Actions on ancestry blocks when working on a new block. + +use ethereum_types::H256; + +#[derive(Debug, PartialEq, Eq, Clone)] +/// Actions on a live block's parent block. Only committed when the live block is committed. Those actions here must +/// respect the normal blockchain reorganization rules. +pub enum AncestryAction { + /// Mark an ancestry block as finalized. + MarkFinalized(H256), +} diff --git a/ethcore/types/src/lib.rs b/ethcore/types/src/lib.rs index 83a1cc6557..18e0dde86a 100644 --- a/ethcore/types/src/lib.rs +++ b/ethcore/types/src/lib.rs @@ -46,6 +46,7 @@ pub mod state_diff; pub mod trace_filter; pub mod tree_route; pub mod verification_queue_info; +pub mod ancestry_action; /// Type for block number. pub type BlockNumber = u64; diff --git a/ethcore/types/src/tree_route.rs b/ethcore/types/src/tree_route.rs index b3fe431ab9..5d1bddd87b 100644 --- a/ethcore/types/src/tree_route.rs +++ b/ethcore/types/src/tree_route.rs @@ -27,4 +27,6 @@ pub struct TreeRoute { pub ancestor: H256, /// An index where best common ancestor would be. pub index: usize, + /// Whether it has finalized blocks from `from` (inclusive) to `ancestor` (exclusive). + pub is_from_route_finalized: bool, } diff --git a/machine/src/lib.rs b/machine/src/lib.rs index 54ee403d95..075a42d731 100644 --- a/machine/src/lib.rs +++ b/machine/src/lib.rs @@ -40,13 +40,35 @@ pub trait Header { fn number(&self) -> u64; } -/// a header with an associated score (difficulty in PoW terms) +/// A header with an associated score (difficulty in PoW terms) pub trait ScoredHeader: Header { + type Value; + /// Get the score of this header. - fn score(&self) -> &U256; + fn score(&self) -> &Self::Value; /// Set the score of this header. - fn set_score(&mut self, score: U256); + fn set_score(&mut self, score: Self::Value); +} + +/// A header with associated total score. +pub trait TotalScoredHeader: Header { + type Value; + + /// Get the total score of this header. + fn total_score(&self) -> Self::Value; +} + +/// A header with finalized information. +pub trait FinalizableHeader: Header { + /// Get whether this header is considered finalized, so that it will never be replaced in reorganization. + fn is_finalized(&self) -> bool; +} + +/// A header with metadata information. +pub trait WithMetadataHeader: Header { + /// Get the current header metadata. + fn metadata(&self) -> Option<&[u8]>; } /// A "live" block is one which is in the process of the transition. @@ -73,16 +95,36 @@ pub trait Transactions: LiveBlock { fn transactions(&self) -> &[Self::Transaction]; } +/// Trait for blocks which have finalized information. +pub trait Finalizable: LiveBlock { + /// Get whether the block is finalized. + fn is_finalized(&self) -> bool; + /// Mark the block as finalized. + fn mark_finalized(&mut self); +} + +/// A state machine with block metadata. +pub trait WithMetadata: LiveBlock { + /// Get the current live block metadata. + fn metadata(&self) -> Option<&[u8]>; + /// Set the current live block metadata. + fn set_metadata(&mut self, value: Option>); +} + /// Generalization of types surrounding blockchain-suitable state machines. pub trait Machine: for<'a> LocalizedMachine<'a> { /// The block header type. type Header: Header; /// The live block type. type LiveBlock: LiveBlock; + /// Block header with metadata information. + type ExtendedHeader: Header; /// A handle to a blockchain client for this machine. type EngineClient: ?Sized; /// A description of needed auxiliary data. type AuxiliaryRequest; + /// Actions taken on ancestry blocks when commiting a new block. + type AncestryAction; /// Errors which can occur when querying or interacting with the machine. type Error; -- GitLab From f9e64e0965febd95de513b1508f75fffc76169bf Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Wed, 16 May 2018 20:09:59 +0200 Subject: [PATCH 050/152] typo (#8640) --- parity/main.rs | 6 +++--- secret_store/src/acl_storage.rs | 2 +- secret_store/src/key_server_set.rs | 10 +++++----- secret_store/src/key_storage.rs | 2 +- secret_store/src/serialization.rs | 2 +- secret_store/src/traits.rs | 2 +- secret_store/src/types/all.rs | 2 +- secret_store/src/types/error.rs | 8 ++++---- 8 files changed, 17 insertions(+), 17 deletions(-) diff --git a/parity/main.rs b/parity/main.rs index 03b04a8c82..06671cbfeb 100644 --- a/parity/main.rs +++ b/parity/main.rs @@ -54,15 +54,15 @@ fn latest_exe_path() -> Option { fn set_spec_name_override(spec_name: String) { if let Err(e) = create_dir_all(default_hypervisor_path()) - .and_then(|_| File::create(updates_path("spec_name_overide")) + .and_then(|_| File::create(updates_path("spec_name_override")) .and_then(|mut f| f.write_all(spec_name.as_bytes()))) { - warn!("Couldn't override chain spec: {} at {:?}", e, updates_path("spec_name_overide")); + warn!("Couldn't override chain spec: {} at {:?}", e, updates_path("spec_name_override")); } } fn take_spec_name_override() -> Option { - let p = updates_path("spec_name_overide"); + let p = updates_path("spec_name_override"); let r = File::open(p.clone()).ok() .and_then(|mut f| { let mut spec_name = String::new(); f.read_to_string(&mut spec_name).ok().map(|_| spec_name) }); let _ = remove_file(p); diff --git a/secret_store/src/acl_storage.rs b/secret_store/src/acl_storage.rs index b3427fa1b2..bc75cfec44 100644 --- a/secret_store/src/acl_storage.rs +++ b/secret_store/src/acl_storage.rs @@ -106,7 +106,7 @@ impl CachedContract { pub fn check(&mut self, requester: Address, document: &ServerKeyId) -> Result { if let Some(client) = self.client.get() { - // call contract to check accesss + // call contract to check access match self.contract_addr { Some(contract_address) => { let do_call = |data| client.call_contract(BlockId::Latest, contract_address, data); diff --git a/secret_store/src/key_server_set.rs b/secret_store/src/key_server_set.rs index d13017261c..8a0d786af9 100644 --- a/secret_store/src/key_server_set.rs +++ b/secret_store/src/key_server_set.rs @@ -271,7 +271,7 @@ impl CachedContract { pub fn update(&mut self, enacted: Vec, retracted: Vec) { if let Some(client) = self.client.get() { - // read new snapshot from reqistry (if something has chnaged) + // read new snapshot from registry (if something has changed) self.read_from_registry_if_required(&*client, enacted, retracted); // update number of confirmations (if there's future new set) @@ -371,7 +371,7 @@ impl CachedContract { None => { // no contract installed => empty snapshot // WARNING: after restart current_set will be reset to the set from configuration file - // even though we have reset to empty set here. We are not considerning this as an issue + // even though we have reset to empty set here. We are not considering this as an issue // because it is actually the issue of administrator. self.snapshot = Default::default(); self.future_new_set = None; @@ -540,7 +540,7 @@ fn update_number_of_confirmations H256, F2: Fn(H256) -> Option> // not enough confirmations => do nothing Some(_) => return, // if number of confirmations is None, then reorg has happened && we need to reset block - // (some more intelligent startegy is possible, but let's stick to simplest one) + // (some more intelligent strategy is possible, but let's stick to simplest one) None => { future_new_set.block = latest_block(); return; @@ -556,9 +556,9 @@ fn update_number_of_confirmations H256, F2: Fn(H256) -> Option> fn update_last_transaction_block(client: &Client, migration_id: &H256, previous_transaction: &mut Option) -> bool { let last_block = client.block_number(BlockId::Latest).unwrap_or_default(); match previous_transaction.as_ref() { - // no previous transaction => send immideately + // no previous transaction => send immediately None => (), - // previous transaction has been sent for other migration process => send immideately + // previous transaction has been sent for other migration process => send immediately Some(tx) if tx.migration_id != *migration_id => (), // if we have sent the same type of transaction recently => do nothing (hope it will be mined eventually) // if we have sent the same transaction some time ago => diff --git a/secret_store/src/key_storage.rs b/secret_store/src/key_storage.rs index 4f78bc338c..848e6bf2a5 100644 --- a/secret_store/src/key_storage.rs +++ b/secret_store/src/key_storage.rs @@ -108,7 +108,7 @@ pub struct SerializableDocumentKeyShareV0 { /// V1 of encrypted key share, as it is stored by key storage on the single key server. #[derive(Serialize, Deserialize)] struct SerializableDocumentKeyShareV1 { - /// Authore of the entry. + /// Author of the entry. pub author: SerializablePublic, /// Decryption threshold (at least threshold + 1 nodes are required to decrypt data). pub threshold: usize, diff --git a/secret_store/src/serialization.rs b/secret_store/src/serialization.rs index 42209e0de4..f3e9aa1d76 100644 --- a/secret_store/src/serialization.rs +++ b/secret_store/src/serialization.rs @@ -117,7 +117,7 @@ impl_bytes!(SerializableSignature, Signature, false, ()); /// Serializable shadow decryption result. #[derive(Clone, Debug, Serialize, Deserialize)] pub struct SerializableEncryptedDocumentKeyShadow { - /// Decrypted secret point. It is partially decrypted if shadow decrpytion was requested. + /// Decrypted secret point. It is partially decrypted if shadow decryption was requested. pub decrypted_secret: SerializablePublic, /// Shared common point. pub common_point: SerializablePublic, diff --git a/secret_store/src/traits.rs b/secret_store/src/traits.rs index 04f2fa1294..704be1c254 100644 --- a/secret_store/src/traits.rs +++ b/secret_store/src/traits.rs @@ -94,7 +94,7 @@ pub trait MessageSigner: ServerKeyGenerator { /// Administrative sessions server. pub trait AdminSessionsServer { /// Change servers set so that nodes in new_servers_set became owners of shares for all keys. - /// And old nodes (i.e. cluste nodes except new_servers_set) have clear databases. + /// And old nodes (i.e. cluster nodes except new_servers_set) have clear databases. /// WARNING: newly generated keys will be distributed among all cluster nodes. So this session /// must be followed with cluster nodes change (either via contract, or config files). fn change_servers_set(&self, old_set_signature: RequestSignature, new_set_signature: RequestSignature, new_servers_set: BTreeSet) -> Result<(), Error>; diff --git a/secret_store/src/types/all.rs b/secret_store/src/types/all.rs index bfc58779a6..ab0aea1b13 100644 --- a/secret_store/src/types/all.rs +++ b/secret_store/src/types/all.rs @@ -94,7 +94,7 @@ pub struct ClusterConfiguration { /// Shadow decryption result. #[derive(Clone, Debug, PartialEq)] pub struct EncryptedDocumentKeyShadow { - /// Decrypted secret point. It is partially decrypted if shadow decrpytion was requested. + /// Decrypted secret point. It is partially decrypted if shadow decryption was requested. pub decrypted_secret: ethkey::Public, /// Shared common point. pub common_point: Option, diff --git a/secret_store/src/types/error.rs b/secret_store/src/types/error.rs index 1fceb120e8..eae914ec86 100644 --- a/secret_store/src/types/error.rs +++ b/secret_store/src/types/error.rs @@ -60,7 +60,7 @@ pub enum Error { /// Document key with this ID is not yet stored. DocumentKeyIsNotFound, /// Consensus is temporary unreachable. Means that something is currently blocking us from either forming - /// consensus group (like disconnecting from too many nodes, which are AGREE to partticipate in consensus) + /// consensus group (like disconnecting from too many nodes, which are AGREE to participate in consensus) /// or from rejecting request (disconnecting from AccessDenied-nodes). ConsensusTemporaryUnreachable, /// Consensus is unreachable. It doesn't mean that it will ALWAYS remain unreachable, but right NOW we have @@ -78,9 +78,9 @@ pub enum Error { InsufficientRequesterData(String), /// Cryptographic error. EthKey(String), - /// I/O error has occured. + /// I/O error has occurred. Io(String), - /// Deserialization error has occured. + /// Deserialization error has occurred. Serde(String), /// Hyper error. Hyper(String), @@ -148,7 +148,7 @@ impl fmt::Display for Error { Error::DocumentKeyIsNotFound => write!(f, "Document key with this ID is not found"), Error::ConsensusUnreachable => write!(f, "Consensus unreachable"), Error::ConsensusTemporaryUnreachable => write!(f, "Consensus temporary unreachable"), - Error::AccessDenied => write!(f, "Access dened"), + Error::AccessDenied => write!(f, "Access denied"), Error::ExclusiveSessionActive => write!(f, "Exclusive session active"), Error::HasActiveSessions => write!(f, "Unable to start exclusive session"), Error::InsufficientRequesterData(ref e) => write!(f, "Insufficient requester data: {}", e), -- GitLab From 30ecd045fa2a1b7f001ca387965d5a296af61d7d Mon Sep 17 00:00:00 2001 From: Afri Schoedon <5chdn@users.noreply.github.com> Date: Wed, 16 May 2018 22:00:33 +0200 Subject: [PATCH 051/152] Changelog for 1.10.4-stable and 1.11.1-beta (#8637) * Add changelog for 1.10.4 * Add changelog for 1.11.1 * Fix Typos --- CHANGELOG.md | 119 ++++++++++++++++++++++++++++++++++++++--- docs/CHANGELOG-1.10.md | 23 ++++++++ 2 files changed, 136 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f839802e7c..ee66149ed0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,22 +1,22 @@ -## Parity [v1.11.0](https://github.com/paritytech/parity/releases/tag/v1.10.0) (2018-05-09) +## Parity [v1.11.1](https://github.com/paritytech/parity/releases/tag/v1.11.1) (2018-05-15) -This is the Parity 1.11.0-beta release! Hurray! +This is the Parity 1.11.1-beta release! Hurray! Notable changes in reversed alphabetical order: - TOOLING: **Whisper CLI** [#8201](https://github.com/paritytech/parity/pull/8201) - `whisper-cli` is a standalone tool to communicate with the Whisper protocol. - It provides functionality to specify `whisper-pool-size`, `port` and `address` to use. - - All whisper RPC APIs are enabled and can be directly acessed. + - All whisper RPC APIs are enabled and can be directly accessed. - JSON-RPC API: **Return error in case eth_call returns VM errors** [#8448](https://github.com/paritytech/parity/pull/8448) - This changes the behaviors of `eth_call` to respect VM errors if any. - In case of `REVERT`, it will also return the reverted return data in hex format. -- ENGINES: **Block reward contract** [#8419](https://github.com/paritytech/parity/pull/8419) +- ENGINES: **Block Reward Contract** [#8419](https://github.com/paritytech/parity/pull/8419) - The _AuRa_ PoA engine has now support for having a contract to calculate the block rewards. - The engine passes a list of benefactors and reward types to the contract which then returns a list of addresses and respective rewards. -- CORE: **Private transactions integration pr** [#6422](https://github.com/paritytech/parity/pull/6422) +- CORE: **Private Transactions** [#6422](https://github.com/paritytech/parity/pull/6422) - Parity now provides a private transactions system. - - Please, check out our wiki to get and [overview and setup instructions](https://wiki.parity.io/Private-Transactions.html). + - Please, check out our wiki to get an [overview and setup instructions](https://wiki.parity.io/Private-Transactions.html). - CORE: **New Transaction Queue implementation** [#8074](https://github.com/paritytech/parity/pull/8074) - Verification is now done in parallel. - Previous queue had `O(1)` time to get pending set, but `O(n^2)` insertion time. And obviously insertion/removal happens much more often than retrieving the pending set (only for propagation and pending block building) Currently we have `O(n * log(senders))` pending set time (with cache) and `O(tx_per_sender)` (usually within `log(tx_per_sender)`) insertion time. @@ -47,6 +47,113 @@ Notable changes in reversed alphabetical order: The full list of included changes: +- Backports ([#8624](https://github.com/paritytech/parity/pull/8624)) + - Trace precompiled contracts when the transfer value is not zero ([#8486](https://github.com/paritytech/parity/pull/8486)) + - Trace precompiled contracts when the transfer value is not zero + - Add tests for precompiled CALL tracing + - Use byzantium test machine for the new test + - Add notes in comments on why we don't trace all precompiles + - Use is_transferred instead of transferred + - Return error if RLP size of transaction exceeds the limit ([#8473](https://github.com/paritytech/parity/pull/8473)) + - Return error if RLP size of transaction exceeds the limit + - Review comments fixed + - RLP check moved to verifier, corresponding pool test added + - Don't block sync when importing old blocks ([#8530](https://github.com/paritytech/parity/pull/8530)) + - Alter IO queueing. + - Don't require IoMessages to be Clone + - Ancient blocks imported via IoChannel. + - Get rid of private transactions io message. + - Get rid of deadlock and fix disconnected handler. + - Revert to old disconnect condition. + - Fix tests. + - Fix deadlock. + - Refactoring `ethcore-sync` - Fixing warp-sync barrier ([#8543](https://github.com/paritytech/parity/pull/8543)) + - Start dividing sync chain : first supplier method + - WIP - updated chain sync supplier + - Finish refactoring the Chain Sync Supplier + - Create Chain Sync Requester + - Add Propagator for Chain Sync + - Add the Chain Sync Handler + - Move tests from mod -> handler + - Move tests to propagator + - Refactor SyncRequester arguments + - Refactoring peer fork header handler + - Fix wrong highest block number in snapshot sync + - Small refactor... + - Address PR grumbles + - Retry failed CI job + - Fix tests + - PR Grumbles + - Handle socket address parsing errors ([#8545](https://github.com/paritytech/parity/pull/8545)) + - Fix packet count when talking with PAR2 peers ([#8555](https://github.com/paritytech/parity/pull/8555)) + - Support diferent packet counts in different protocol versions. + - Fix light timeouts and eclipse protection. + - Fix devp2p tests. + - Fix whisper-cli compilation. + - Fix compilation. + - Fix ethcore-sync tests. + - Revert "Fix light timeouts and eclipse protection." + - Increase timeouts. + - Add whisper CLI to the pipelines ([#8578](https://github.com/paritytech/parity/pull/8578)) + - Add whisper CLI to the pipelines + - Address todo, ref [#8579](https://github.com/paritytech/parity/pull/8579) + - Rename `whisper-cli binary` to `whisper` ([#8579](https://github.com/paritytech/parity/pull/8579)) + - Rename whisper-cli binary to whisper + - Fix tests + - Remove manually added text to the errors ([#8595](https://github.com/paritytech/parity/pull/8595)) + - Fix account list double 0x display ([#8596](https://github.com/paritytech/parity/pull/8596)) + - Remove unused self import + - Fix account list double 0x display + - Fix BlockReward contract "arithmetic operation overflow" ([#8611](https://github.com/paritytech/parity/pull/8611)) + - Fix BlockReward contract "arithmetic operation overflow" + - Add docs on how execute_as_system works + - Fix typo + - Rlp decode returns Result ([#8527](https://github.com/paritytech/parity/pull/8527)) + - Remove expect ([#8536](https://github.com/paritytech/parity/pull/8536)) + - Remove expect and propagate rlp::DecoderErrors as TrieErrors + - Decoding headers can fail ([#8570](https://github.com/paritytech/parity/pull/8570)) + - Rlp::decode returns Result + - Fix journaldb to handle rlp::decode Result + - Fix ethcore to work with rlp::decode returning Result + - Light client handles rlp::decode returning Result + - Fix tests in rlp_derive + - Fix tests + - Cleanup + - Cleanup + - Allow panic rather than breaking out of iterator + - Let decoding failures when reading from disk blow up + - Syntax + - Fix the trivial grumbles + - Fix failing tests + - Make Account::from_rlp return Result + - Syntx, sigh + - Temp-fix for decoding failures + - Header::decode returns Result + - Do not continue reading from the DB when a value could not be read + - Fix tests + - Handle header decoding in light_sync + - Handling header decoding errors + - Let the DecodeError bubble up unchanged + - Remove redundant error conversion + - Fix compiler warning ([#8590](https://github.com/paritytech/parity/pull/8590)) + - Attempt to fix intermittent test failures ([#8584](https://github.com/paritytech/parity/pull/8584)) + - Block_header can fail so return Result ([#8581](https://github.com/paritytech/parity/pull/8581)) + - Block_header can fail so return Result + - Restore previous return type based on feedback + - Fix failing doc tests running on non-code + - Block::decode() returns Result ([#8586](https://github.com/paritytech/parity/pull/8586)) + - Gitlab test script fixes ([#8573](https://github.com/paritytech/parity/pull/8573)) + - Exclude /docs from modified files. + - Ensure all references in the working tree are available + - Remove duplicated line from test script +- Bump beta to 1.11.1 ([#8627](https://github.com/paritytech/parity/pull/8627)) + +## Parity [v1.11.0](https://github.com/paritytech/parity/releases/tag/v1.11.0) (2018-05-09) + +This is the Parity 1.11.0-beta release! ~~Hurray!~~ This release has been pulled due to peering issues, please use 1.11.1-beta. + +The full list of included changes: + - Backports ([#8558](https://github.com/paritytech/parity/pull/8558)) - Fetching logs by hash in blockchain database ([#8463](https://github.com/paritytech/parity/pull/8463)) - Fetch logs by hash in blockchain database diff --git a/docs/CHANGELOG-1.10.md b/docs/CHANGELOG-1.10.md index 4db8f32bb6..a8c7ad20a7 100644 --- a/docs/CHANGELOG-1.10.md +++ b/docs/CHANGELOG-1.10.md @@ -1,3 +1,26 @@ +## Parity [v1.10.4](https://github.com/paritytech/parity/releases/tag/v1.10.4) (2018-05-15) + +Parity 1.10.4 is a bug-fix release to improve performance and stability. + +The full list of included changes: + +- Backports ([#8623](https://github.com/paritytech/parity/pull/8623)) + - Fix account list double 0x display ([#8596](https://github.com/paritytech/parity/pull/8596)) + - Remove unused self import + - Fix account list double 0x display + - Trace precompiled contracts when the transfer value is not zero ([#8486](https://github.com/paritytech/parity/pull/8486)) + - Trace precompiled contracts when the transfer value is not zero + - Add tests for precompiled CALL tracing + - Use byzantium test machine for the new test + - Add notes in comments on why we don't trace all precompileds + - Use is_transferred instead of transferred + - Gitlab test script fixes ([#8573](https://github.com/paritytech/parity/pull/8573)) + - Exclude /docs from modified files. + - Ensure all references in the working tree are available + - Remove duplicated line from test script +- Bump stable to 1.10.4 ([#8626](https://github.com/paritytech/parity/pull/8626)) +- Allow stable snaps to be stable. ([#8582](https://github.com/paritytech/parity/pull/8582)) + ## Parity [v1.10.3](https://github.com/paritytech/parity/releases/tag/v1.10.3) (2018-05-08) Parity 1.10.3 marks the first stable release on the 1.10 track. Among others, it improves performance and stability. -- GitLab From 6ecc855c3433403e5d54910cdc6c44700d7b4ab7 Mon Sep 17 00:00:00 2001 From: Benjamin Kampmann Date: Wed, 16 May 2018 22:01:11 +0200 Subject: [PATCH 052/152] Don't open Browser post-install on Mac (#8641) Since we start parity with the UI disabled per default now, opening the browser post installation will show an annoying error message, confusing the user. This patch removes opening the browser to prevent that annoyance. fixes #8194 --- mac/post-install.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/mac/post-install.sh b/mac/post-install.sh index a364878d88..fc71ee1de6 100755 --- a/mac/post-install.sh +++ b/mac/post-install.sh @@ -3,6 +3,4 @@ test -f /usr/local/libexec/uninstall-parity.sh && /usr/local/libexec/uninstall-parity.sh || true killall -9 parity && sleep 5 su $USER -c "open /Applications/Parity\ Ethereum.app" -sleep 5 -su $USER -c "open http://127.0.0.1:8180/" exit 0 -- GitLab From cdbcfaa7de55731f4e1eb2613f72c980fba1e0f7 Mon Sep 17 00:00:00 2001 From: Nicolas Gotchac Date: Wed, 16 May 2018 22:01:55 +0200 Subject: [PATCH 053/152] Resumable warp-sync / Seed downloaded snapshots (#8544) * Start dividing sync chain : first supplier method * WIP - updated chain sync supplier * Finish refactoring the Chain Sync Supplier * Create Chain Sync Requester * Add Propagator for Chain Sync * Add the Chain Sync Handler * Move tests from mod -> handler * Move tests to propagator * Refactor SyncRequester arguments * Refactoring peer fork header handler * Fix wrong highest block number in snapshot sync * Small refactor... * Resume warp-sync downloaded chunks * Add comments * Refactoring the previous chunks import * Fix tests * Address PR grumbles * Fix not seeding current snapshot * Address PR Grumbles * Address PR grumble * Retry failed CI job * Update SnapshotService readiness check Fix restoration locking issue for previous chunks restoration * Fix tests * Fix tests * Fix test * Early abort importing previous chunks * PR Grumbles * Update Gitlab CI config * SyncState back to Waiting when Manifest peers disconnect * Move fix * Better fix * Revert GitLab CI changes * Fix Warning * Refactor resuming snapshots * Fix string construction * Revert "Refactor resuming snapshots" This reverts commit 75fd4b553a38e4a49dc5d6a878c70e830ff382eb. * Update informant log * Fix string construction * Refactor resuming snapshots * Fix informant * PR Grumbles * Update informant message : show chunks done * PR Grumbles * Fix * Fix Warning * PR Grumbles --- ethcore/src/snapshot/service.rs | 165 ++++++++++++++++--- ethcore/src/snapshot/tests/service.rs | 8 +- ethcore/src/snapshot/traits.rs | 3 + ethcore/sync/src/chain/handler.rs | 52 ++++-- ethcore/sync/src/chain/mod.rs | 104 +++++++----- ethcore/sync/src/chain/supplier.rs | 26 +-- ethcore/sync/src/snapshot.rs | 71 ++++++-- ethcore/sync/src/tests/snapshot.rs | 4 + ethcore/types/src/restoration_status.rs | 5 + parity/informant.rs | 23 ++- parity/snapshot.rs | 1 + rpc/src/v1/tests/helpers/snapshot_service.rs | 1 + 12 files changed, 361 insertions(+), 102 deletions(-) diff --git a/ethcore/src/snapshot/service.rs b/ethcore/src/snapshot/service.rs index c5b9123e10..17c362e044 100644 --- a/ethcore/src/snapshot/service.rs +++ b/ethcore/src/snapshot/service.rs @@ -17,8 +17,8 @@ //! Snapshot network service implementation. use std::collections::HashSet; -use std::io::ErrorKind; -use std::fs; +use std::io::{self, Read, ErrorKind}; +use std::fs::{self, File}; use std::path::PathBuf; use std::sync::Arc; use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering}; @@ -30,6 +30,7 @@ use blockchain::BlockChain; use client::{Client, ChainInfo, ClientIoMessage}; use engines::EthEngine; use error::Error; +use hash::keccak; use ids::BlockId; use io::IoChannel; @@ -270,8 +271,8 @@ impl Service { } } - // delete the temporary restoration dir if it does exist. - if let Err(e) = fs::remove_dir_all(service.restoration_dir()) { + // delete the temporary restoration DB dir if it does exist. + if let Err(e) = fs::remove_dir_all(service.restoration_db()) { if e.kind() != ErrorKind::NotFound { return Err(e.into()) } @@ -325,6 +326,13 @@ impl Service { dir } + // previous snapshot chunks path. + fn prev_chunks_dir(&self) -> PathBuf { + let mut dir = self.snapshot_root.clone(); + dir.push("prev_chunks"); + dir + } + // replace one the client's database with our own. fn replace_client_db(&self) -> Result<(), Error> { let our_db = self.restoration_db(); @@ -406,9 +414,26 @@ impl Service { /// Initialize the restoration synchronously. /// The recover flag indicates whether to recover the restored snapshot. pub fn init_restore(&self, manifest: ManifestData, recover: bool) -> Result<(), Error> { + let mut res = self.restoration.lock(); + let rest_dir = self.restoration_dir(); + let rest_db = self.restoration_db(); + let recovery_temp = self.temp_recovery_dir(); + let prev_chunks = self.prev_chunks_dir(); - let mut res = self.restoration.lock(); + // delete and restore the restoration dir. + if let Err(e) = fs::remove_dir_all(&prev_chunks) { + match e.kind() { + ErrorKind::NotFound => {}, + _ => return Err(e.into()), + } + } + + // Move the previous recovery temp directory + // to `prev_chunks` to be able to restart restoring + // with previously downloaded blocks + // This step is optional, so don't fail on error + fs::rename(&recovery_temp, &prev_chunks).ok(); self.state_chunks.store(0, Ordering::SeqCst); self.block_chunks.store(0, Ordering::SeqCst); @@ -424,29 +449,38 @@ impl Service { } } + *self.status.lock() = RestorationStatus::Initializing { + chunks_done: 0, + }; + fs::create_dir_all(&rest_dir)?; // make new restoration. let writer = match recover { - true => Some(LooseWriter::new(self.temp_recovery_dir())?), + true => Some(LooseWriter::new(recovery_temp)?), false => None }; let params = RestorationParams { - manifest: manifest, + manifest: manifest.clone(), pruning: self.pruning, - db: self.restoration_db_handler.open(&self.restoration_db())?, + db: self.restoration_db_handler.open(&rest_db)?, writer: writer, genesis: &self.genesis_block, - guard: Guard::new(rest_dir), + guard: Guard::new(rest_db), engine: &*self.engine, }; - let state_chunks = params.manifest.state_hashes.len(); - let block_chunks = params.manifest.block_hashes.len(); + let state_chunks = manifest.state_hashes.len(); + let block_chunks = manifest.block_hashes.len(); *res = Some(Restoration::new(params)?); + self.restoring_snapshot.store(true, Ordering::SeqCst); + + // Import previous chunks, continue if it fails + self.import_prev_chunks(&mut res, manifest).ok(); + *self.status.lock() = RestorationStatus::Ongoing { state_chunks: state_chunks as u32, block_chunks: block_chunks as u32, @@ -454,10 +488,65 @@ impl Service { block_chunks_done: self.block_chunks.load(Ordering::SeqCst) as u32, }; - self.restoring_snapshot.store(true, Ordering::SeqCst); Ok(()) } + /// Import the previous chunks into the current restoration + fn import_prev_chunks(&self, restoration: &mut Option, manifest: ManifestData) -> Result<(), Error> { + let prev_chunks = self.prev_chunks_dir(); + + // Restore previous snapshot chunks + let files = fs::read_dir(prev_chunks.as_path())?; + let mut num_temp_chunks = 0; + + for prev_chunk_file in files { + // Don't go over all the files if the restoration has been aborted + if !self.restoring_snapshot.load(Ordering::SeqCst) { + trace!(target:"snapshot", "Aborting importing previous chunks"); + return Ok(()); + } + // Import the chunk, don't fail and continue if one fails + match self.import_prev_chunk(restoration, &manifest, prev_chunk_file) { + Ok(true) => num_temp_chunks += 1, + Err(e) => trace!(target: "snapshot", "Error importing chunk: {:?}", e), + _ => (), + } + } + + trace!(target:"snapshot", "Imported {} previous chunks", num_temp_chunks); + + // Remove the prev temp directory + fs::remove_dir_all(&prev_chunks)?; + + Ok(()) + } + + /// Import a previous chunk at the given path. Returns whether the block was imported or not + fn import_prev_chunk(&self, restoration: &mut Option, manifest: &ManifestData, file: io::Result) -> Result { + let file = file?; + let path = file.path(); + + let mut file = File::open(path.clone())?; + let mut buffer = Vec::new(); + file.read_to_end(&mut buffer)?; + + let hash = keccak(&buffer); + + let is_state = if manifest.block_hashes.contains(&hash) { + false + } else if manifest.state_hashes.contains(&hash) { + true + } else { + return Ok(false); + }; + + self.feed_chunk_with_restoration(restoration, hash, &buffer, is_state)?; + + trace!(target: "snapshot", "Fed chunk {:?}", hash); + + Ok(true) + } + // finalize the restoration. this accepts an already-locked // restoration as an argument -- so acquiring it again _will_ // lead to deadlock. @@ -499,12 +588,19 @@ impl Service { /// Feed a chunk of either kind. no-op if no restoration or status is wrong. fn feed_chunk(&self, hash: H256, chunk: &[u8], is_state: bool) -> Result<(), Error> { // TODO: be able to process block chunks and state chunks at same time? - let (result, db) = { - let mut restoration = self.restoration.lock(); + let mut restoration = self.restoration.lock(); + self.feed_chunk_with_restoration(&mut restoration, hash, chunk, is_state) + } + /// Feed a chunk with the Restoration + fn feed_chunk_with_restoration(&self, restoration: &mut Option, hash: H256, chunk: &[u8], is_state: bool) -> Result<(), Error> { + let (result, db) = { match self.status() { - RestorationStatus::Inactive | RestorationStatus::Failed => return Ok(()), - RestorationStatus::Ongoing { .. } => { + RestorationStatus::Inactive | RestorationStatus::Failed => { + trace!(target: "snapshot", "Tried to restore chunk {:x} while inactive or failed", hash); + return Ok(()); + }, + RestorationStatus::Ongoing { .. } | RestorationStatus::Initializing { .. } => { let (res, db) = { let rest = match *restoration { Some(ref mut r) => r, @@ -583,11 +679,41 @@ impl SnapshotService for Service { self.reader.read().as_ref().and_then(|r| r.chunk(hash).ok()) } + fn completed_chunks(&self) -> Option> { + let restoration = self.restoration.lock(); + + match *restoration { + Some(ref restoration) => { + let completed_chunks = restoration.manifest.block_hashes + .iter() + .filter(|h| !restoration.block_chunks_left.contains(h)) + .chain( + restoration.manifest.state_hashes + .iter() + .filter(|h| !restoration.state_chunks_left.contains(h)) + ) + .map(|h| *h) + .collect(); + + Some(completed_chunks) + }, + None => None, + } + } + fn status(&self) -> RestorationStatus { let mut cur_status = self.status.lock(); - if let RestorationStatus::Ongoing { ref mut state_chunks_done, ref mut block_chunks_done, .. } = *cur_status { - *state_chunks_done = self.state_chunks.load(Ordering::SeqCst) as u32; - *block_chunks_done = self.block_chunks.load(Ordering::SeqCst) as u32; + + match *cur_status { + RestorationStatus::Initializing { ref mut chunks_done } => { + *chunks_done = self.state_chunks.load(Ordering::SeqCst) as u32 + + self.block_chunks.load(Ordering::SeqCst) as u32; + } + RestorationStatus::Ongoing { ref mut state_chunks_done, ref mut block_chunks_done, .. } => { + *state_chunks_done = self.state_chunks.load(Ordering::SeqCst) as u32; + *block_chunks_done = self.block_chunks.load(Ordering::SeqCst) as u32; + }, + _ => (), } cur_status.clone() @@ -600,6 +726,7 @@ impl SnapshotService for Service { } fn abort_restore(&self) { + trace!(target: "snapshot", "Aborting restore"); self.restoring_snapshot.store(false, Ordering::SeqCst); *self.restoration.lock() = None; *self.status.lock() = RestorationStatus::Inactive; diff --git a/ethcore/src/snapshot/tests/service.rs b/ethcore/src/snapshot/tests/service.rs index 3e3087f2bf..3fcb0addfa 100644 --- a/ethcore/src/snapshot/tests/service.rs +++ b/ethcore/src/snapshot/tests/service.rs @@ -130,12 +130,16 @@ fn guards_delete_folders() { service.init_restore(manifest.clone(), true).unwrap(); assert!(path.exists()); + // The `db` folder should have been deleted, + // while the `temp` one kept service.abort_restore(); - assert!(!path.exists()); + assert!(!path.join("db").exists()); + assert!(path.join("temp").exists()); service.init_restore(manifest.clone(), true).unwrap(); assert!(path.exists()); drop(service); - assert!(!path.exists()); + assert!(!path.join("db").exists()); + assert!(path.join("temp").exists()); } diff --git a/ethcore/src/snapshot/traits.rs b/ethcore/src/snapshot/traits.rs index a81c14f08d..2b6ee9df9f 100644 --- a/ethcore/src/snapshot/traits.rs +++ b/ethcore/src/snapshot/traits.rs @@ -30,6 +30,9 @@ pub trait SnapshotService : Sync + Send { /// `None` indicates warp sync isn't supported by the consensus engine. fn supported_versions(&self) -> Option<(u64, u64)>; + /// Returns a list of the completed chunks + fn completed_chunks(&self) -> Option>; + /// Get raw chunk for a given hash. fn chunk(&self, hash: H256) -> Option; diff --git a/ethcore/sync/src/chain/handler.rs b/ethcore/sync/src/chain/handler.rs index a55c0319b3..7668a64594 100644 --- a/ethcore/sync/src/chain/handler.rs +++ b/ethcore/sync/src/chain/handler.rs @@ -100,14 +100,27 @@ impl SyncHandler { } /// Called by peer when it is disconnecting - pub fn on_peer_aborting(sync: &mut ChainSync, io: &mut SyncIo, peer: PeerId) { - trace!(target: "sync", "== Disconnecting {}: {}", peer, io.peer_info(peer)); - sync.handshaking_peers.remove(&peer); - if sync.peers.contains_key(&peer) { - debug!(target: "sync", "Disconnected {}", peer); - sync.clear_peer_download(peer); - sync.peers.remove(&peer); - sync.active_peers.remove(&peer); + pub fn on_peer_aborting(sync: &mut ChainSync, io: &mut SyncIo, peer_id: PeerId) { + trace!(target: "sync", "== Disconnecting {}: {}", peer_id, io.peer_info(peer_id)); + sync.handshaking_peers.remove(&peer_id); + if sync.peers.contains_key(&peer_id) { + debug!(target: "sync", "Disconnected {}", peer_id); + sync.clear_peer_download(peer_id); + sync.peers.remove(&peer_id); + sync.active_peers.remove(&peer_id); + + if sync.state == SyncState::SnapshotManifest { + // Check if we are asking other peers for + // the snapshot manifest as well. + // If not, return to initial state + let still_asking_manifest = sync.peers.iter() + .filter(|&(id, p)| sync.active_peers.contains(id) && p.asking == PeerAsking::SnapshotManifest) + .next().is_none(); + + if still_asking_manifest { + sync.state = ChainSync::get_init_state(sync.warp_sync, io.chain()); + } + } sync.continue_sync(io); } } @@ -320,6 +333,10 @@ impl SyncHandler { } fn on_peer_confirmed(sync: &mut ChainSync, io: &mut SyncIo, peer_id: PeerId) { + { + let peer = sync.peers.get_mut(&peer_id).expect("Is only called when peer is present in peers"); + peer.confirmation = ForkConfirmation::Confirmed; + } sync.sync_peer(io, peer_id, false); } @@ -344,8 +361,8 @@ impl SyncHandler { } trace!(target: "sync", "{}: Confirmed peer", peer_id); - peer.confirmation = ForkConfirmation::Confirmed; if !io.chain_overlay().read().contains_key(&fork_number) { + trace!(target: "sync", "Inserting (fork) block {} header", fork_number); io.chain_overlay().write().insert(fork_number, header.to_vec()); } } @@ -560,6 +577,10 @@ impl SyncHandler { sync.continue_sync(io); return Ok(()); }, + RestorationStatus::Initializing { .. } => { + trace!(target: "warp", "{}: Snapshot restoration is initializing", peer_id); + return Ok(()); + } RestorationStatus::Ongoing { .. } => { trace!(target: "sync", "{}: Snapshot restoration is ongoing", peer_id); }, @@ -659,11 +680,16 @@ impl SyncHandler { // Let the current sync round complete first. sync.active_peers.insert(peer_id.clone()); debug!(target: "sync", "Connected {}:{}", peer_id, io.peer_info(peer_id)); - if let Some((fork_block, _)) = sync.fork_block { - SyncRequester::request_fork_header(sync, io, peer_id, fork_block); - } else { - SyncHandler::on_peer_confirmed(sync, io, peer_id); + + match sync.fork_block { + Some((fork_block, _)) => { + SyncRequester::request_fork_header(sync, io, peer_id, fork_block); + }, + _ => { + SyncHandler::on_peer_confirmed(sync, io, peer_id); + } } + Ok(()) } diff --git a/ethcore/sync/src/chain/mod.rs b/ethcore/sync/src/chain/mod.rs index 381936949b..5af2892549 100644 --- a/ethcore/sync/src/chain/mod.rs +++ b/ethcore/sync/src/chain/mod.rs @@ -245,9 +245,12 @@ pub struct SyncStatus { impl SyncStatus { /// Indicates if snapshot download is in progress pub fn is_snapshot_syncing(&self) -> bool { - self.state == SyncState::SnapshotManifest - || self.state == SyncState::SnapshotData - || self.state == SyncState::SnapshotWaiting + match self.state { + SyncState::SnapshotManifest | + SyncState::SnapshotData | + SyncState::SnapshotWaiting => true, + _ => false, + } } /// Returns max no of peers to display in informants @@ -643,7 +646,7 @@ impl ChainSync { } } - /// Resume downloading + /// Resume downloading fn continue_sync(&mut self, io: &mut SyncIo) { // Collect active peers that can sync let confirmed_peers: Vec<(PeerId, u8)> = self.peers.iter().filter_map(|(peer_id, peer)| @@ -751,26 +754,45 @@ impl ChainSync { } } - if let Some(request) = self.old_blocks.as_mut().and_then(|d| d.request_blocks(io, num_active_peers)) { - SyncRequester::request_blocks(self, io, peer_id, request, BlockSet::OldBlocks); - return; + // Only ask for old blocks if the peer has a higher difficulty + if force || higher_difficulty { + if let Some(request) = self.old_blocks.as_mut().and_then(|d| d.request_blocks(io, num_active_peers)) { + SyncRequester::request_blocks(self, io, peer_id, request, BlockSet::OldBlocks); + return; + } + } else { + trace!(target: "sync", "peer {} is not suitable for asking old blocks", peer_id); + self.deactivate_peer(io, peer_id); } }, SyncState::SnapshotData => { - if let RestorationStatus::Ongoing { state_chunks_done, block_chunks_done, .. } = io.snapshot_service().status() { - if self.snapshot.done_chunks() - (state_chunks_done + block_chunks_done) as usize > MAX_SNAPSHOT_CHUNKS_DOWNLOAD_AHEAD { - trace!(target: "sync", "Snapshot queue full, pausing sync"); - self.state = SyncState::SnapshotWaiting; + match io.snapshot_service().status() { + RestorationStatus::Ongoing { state_chunks_done, block_chunks_done, .. } => { + // Initialize the snapshot if not already done + self.snapshot.initialize(io.snapshot_service()); + if self.snapshot.done_chunks() - (state_chunks_done + block_chunks_done) as usize > MAX_SNAPSHOT_CHUNKS_DOWNLOAD_AHEAD { + trace!(target: "sync", "Snapshot queue full, pausing sync"); + self.state = SyncState::SnapshotWaiting; + return; + } + }, + RestorationStatus::Initializing { .. } => { + trace!(target: "warp", "Snapshot is stil initializing."); return; - } + }, + _ => { + return; + }, } + if peer_snapshot_hash.is_some() && peer_snapshot_hash == self.snapshot.snapshot_hash() { self.clear_peer_download(peer_id); SyncRequester::request_snapshot_data(self, io, peer_id); } }, SyncState::SnapshotManifest | //already downloading from other peer - SyncState::Waiting | SyncState::SnapshotWaiting => () + SyncState::Waiting | + SyncState::SnapshotWaiting => () } } else { trace!(target: "sync", "Skipping peer {}, force={}, td={:?}, our td={}, state={:?}", peer_id, force, peer_difficulty, syncing_difficulty, self.state); @@ -861,10 +883,7 @@ impl ChainSync { packet.append(&chain.best_block_hash); packet.append(&chain.genesis_hash); if warp_protocol { - let manifest = match self.old_blocks.is_some() { - true => None, - false => io.snapshot_service().manifest(), - }; + let manifest = io.snapshot_service().manifest(); let block_number = manifest.as_ref().map_or(0, |m| m.block_number); let manifest_hash = manifest.map_or(H256::new(), |m| keccak(m.into_rlp())); packet.append(&manifest_hash); @@ -908,29 +927,36 @@ impl ChainSync { } fn check_resume(&mut self, io: &mut SyncIo) { - if self.state == SyncState::Waiting && !io.chain().queue_info().is_full() { - self.state = SyncState::Blocks; - self.continue_sync(io); - } else if self.state == SyncState::SnapshotWaiting { - match io.snapshot_service().status() { - RestorationStatus::Inactive => { - trace!(target:"sync", "Snapshot restoration is complete"); - self.restart(io); - }, - RestorationStatus::Ongoing { state_chunks_done, block_chunks_done, .. } => { - if !self.snapshot.is_complete() && self.snapshot.done_chunks() - (state_chunks_done + block_chunks_done) as usize <= MAX_SNAPSHOT_CHUNKS_DOWNLOAD_AHEAD { - trace!(target:"sync", "Resuming snapshot sync"); - self.state = SyncState::SnapshotData; + match self.state { + SyncState::Waiting if !io.chain().queue_info().is_full() => { + self.state = SyncState::Blocks; + self.continue_sync(io); + }, + SyncState::SnapshotWaiting => { + match io.snapshot_service().status() { + RestorationStatus::Inactive => { + trace!(target:"sync", "Snapshot restoration is complete"); + self.restart(io); + }, + RestorationStatus::Initializing { .. } => { + trace!(target:"sync", "Snapshot restoration is initializing"); + }, + RestorationStatus::Ongoing { state_chunks_done, block_chunks_done, .. } => { + if !self.snapshot.is_complete() && self.snapshot.done_chunks() - (state_chunks_done + block_chunks_done) as usize <= MAX_SNAPSHOT_CHUNKS_DOWNLOAD_AHEAD { + trace!(target:"sync", "Resuming snapshot sync"); + self.state = SyncState::SnapshotData; + self.continue_sync(io); + } + }, + RestorationStatus::Failed => { + trace!(target: "sync", "Snapshot restoration aborted"); + self.state = SyncState::WaitingPeers; + self.snapshot.clear(); self.continue_sync(io); - } - }, - RestorationStatus::Failed => { - trace!(target: "sync", "Snapshot restoration aborted"); - self.state = SyncState::WaitingPeers; - self.snapshot.clear(); - self.continue_sync(io); - }, - } + }, + } + }, + _ => (), } } diff --git a/ethcore/sync/src/chain/supplier.rs b/ethcore/sync/src/chain/supplier.rs index 0bfb856982..e0245fdbcd 100644 --- a/ethcore/sync/src/chain/supplier.rs +++ b/ethcore/sync/src/chain/supplier.rs @@ -120,8 +120,9 @@ impl SyncSupplier { None => return Ok(Some((BLOCK_HEADERS_PACKET, RlpStream::new_list(0)))) //no such header, return nothing } } else { - trace!(target: "sync", "{} -> GetBlockHeaders (number: {}, max: {}, skip: {}, reverse:{})", peer_id, r.val_at::(0)?, max_headers, skip, reverse); - r.val_at(0)? + let number = r.val_at::(0)?; + trace!(target: "sync", "{} -> GetBlockHeaders (number: {}, max: {}, skip: {}, reverse:{})", peer_id, number, max_headers, skip, reverse); + number }; let mut number = if reverse { @@ -135,7 +136,10 @@ impl SyncSupplier { let inc = (skip + 1) as BlockNumber; let overlay = io.chain_overlay().read(); - while number <= last && count < max_count { + // We are checking the `overlay` as well since it's where the ForkBlock + // header is cached : so peers can confirm we are on the right fork, + // even if we are not synced until the fork block + while (number <= last || overlay.contains_key(&number)) && count < max_count { if let Some(hdr) = overlay.get(&number) { trace!(target: "sync", "{}: Returning cached fork header", peer_id); data.extend_from_slice(hdr); @@ -152,8 +156,7 @@ impl SyncSupplier { break; } number -= inc; - } - else { + } else { number += inc; } } @@ -237,20 +240,20 @@ impl SyncSupplier { /// Respond to GetSnapshotManifest request fn return_snapshot_manifest(io: &SyncIo, r: &Rlp, peer_id: PeerId) -> RlpResponseResult { let count = r.item_count().unwrap_or(0); - trace!(target: "sync", "{} -> GetSnapshotManifest", peer_id); + trace!(target: "warp", "{} -> GetSnapshotManifest", peer_id); if count != 0 { - debug!(target: "sync", "Invalid GetSnapshotManifest request, ignoring."); + debug!(target: "warp", "Invalid GetSnapshotManifest request, ignoring."); return Ok(None); } let rlp = match io.snapshot_service().manifest() { Some(manifest) => { - trace!(target: "sync", "{} <- SnapshotManifest", peer_id); + trace!(target: "warp", "{} <- SnapshotManifest", peer_id); let mut rlp = RlpStream::new_list(1); rlp.append_raw(&manifest.into_rlp(), 1); rlp }, None => { - trace!(target: "sync", "{}: No manifest to return", peer_id); + trace!(target: "warp", "{}: No snapshot manifest to return", peer_id); RlpStream::new_list(0) } }; @@ -260,15 +263,16 @@ impl SyncSupplier { /// Respond to GetSnapshotData request fn return_snapshot_data(io: &SyncIo, r: &Rlp, peer_id: PeerId) -> RlpResponseResult { let hash: H256 = r.val_at(0)?; - trace!(target: "sync", "{} -> GetSnapshotData {:?}", peer_id, hash); + trace!(target: "warp", "{} -> GetSnapshotData {:?}", peer_id, hash); let rlp = match io.snapshot_service().chunk(hash) { Some(data) => { let mut rlp = RlpStream::new_list(1); - trace!(target: "sync", "{} <- SnapshotData", peer_id); + trace!(target: "warp", "{} <- SnapshotData", peer_id); rlp.append(&data); rlp }, None => { + trace!(target: "warp", "{}: No snapshot data to return", peer_id); RlpStream::new_list(0) } }; diff --git a/ethcore/sync/src/snapshot.rs b/ethcore/sync/src/snapshot.rs index 917e84c884..b603a2a007 100644 --- a/ethcore/sync/src/snapshot.rs +++ b/ethcore/sync/src/snapshot.rs @@ -14,10 +14,13 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -use hash::keccak; +use ethcore::snapshot::{ManifestData, SnapshotService}; use ethereum_types::H256; +use hash::keccak; +use rand::{thread_rng, Rng}; + use std::collections::HashSet; -use ethcore::snapshot::ManifestData; +use std::iter::FromIterator; #[derive(PartialEq, Eq, Debug)] pub enum ChunkType { @@ -32,6 +35,7 @@ pub struct Snapshot { completed_chunks: HashSet, snapshot_hash: Option, bad_hashes: HashSet, + initialized: bool, } impl Snapshot { @@ -44,7 +48,27 @@ impl Snapshot { completed_chunks: HashSet::new(), snapshot_hash: None, bad_hashes: HashSet::new(), + initialized: false, + } + } + + /// Sync the Snapshot completed chunks with the Snapshot Service + pub fn initialize(&mut self, snapshot_service: &SnapshotService) { + if self.initialized { + return; + } + + if let Some(completed_chunks) = snapshot_service.completed_chunks() { + self.completed_chunks = HashSet::from_iter(completed_chunks); } + + trace!( + target: "snapshot", + "Snapshot is now initialized with {} completed chunks.", + self.completed_chunks.len(), + ); + + self.initialized = true; } /// Clear everything. @@ -54,6 +78,7 @@ impl Snapshot { self.downloading_chunks.clear(); self.completed_chunks.clear(); self.snapshot_hash = None; + self.initialized = false; } /// Check if currently downloading a snapshot. @@ -89,18 +114,35 @@ impl Snapshot { Err(()) } - /// Find a chunk to download + /// Find a random chunk to download pub fn needed_chunk(&mut self) -> Option { - // check state chunks first - let chunk = self.pending_state_chunks.iter() - .chain(self.pending_block_chunks.iter()) - .find(|&h| !self.downloading_chunks.contains(h) && !self.completed_chunks.contains(h)) - .cloned(); + // Find all random chunks: first blocks, then state + let needed_chunks = { + let chunk_filter = |h| !self.downloading_chunks.contains(h) && !self.completed_chunks.contains(h); + + let needed_block_chunks = self.pending_block_chunks.iter() + .filter(|&h| chunk_filter(h)) + .map(|h| *h) + .collect::>(); + + // If no block chunks to download, get the state chunks + if needed_block_chunks.len() == 0 { + self.pending_state_chunks.iter() + .filter(|&h| chunk_filter(h)) + .map(|h| *h) + .collect::>() + } else { + needed_block_chunks + } + }; + + // Get a random chunk + let chunk = thread_rng().choose(&needed_chunks); if let Some(hash) = chunk { self.downloading_chunks.insert(hash.clone()); } - chunk + chunk.map(|h| *h) } pub fn clear_chunk_download(&mut self, hash: &H256) { @@ -185,8 +227,15 @@ mod test { let requested: Vec = (0..40).map(|_| snapshot.needed_chunk().unwrap()).collect(); assert!(snapshot.needed_chunk().is_none()); - assert_eq!(&requested[0..20], &manifest.state_hashes[..]); - assert_eq!(&requested[20..40], &manifest.block_hashes[..]); + + let requested_all_block_chunks = manifest.block_hashes.iter() + .all(|h| requested.iter().any(|rh| rh == h)); + assert!(requested_all_block_chunks); + + let requested_all_state_chunks = manifest.state_hashes.iter() + .all(|h| requested.iter().any(|rh| rh == h)); + assert!(requested_all_state_chunks); + assert_eq!(snapshot.downloading_chunks.len(), 40); assert_eq!(snapshot.validate_chunk(&state_chunks[4]), Ok(ChunkType::State(manifest.state_hashes[4].clone()))); diff --git a/ethcore/sync/src/tests/snapshot.rs b/ethcore/sync/src/tests/snapshot.rs index 804ebe9c53..864f3d4dc6 100644 --- a/ethcore/sync/src/tests/snapshot.rs +++ b/ethcore/sync/src/tests/snapshot.rs @@ -80,6 +80,10 @@ impl SnapshotService for TestSnapshotService { Some((1, 2)) } + fn completed_chunks(&self) -> Option> { + Some(vec![]) + } + fn chunk(&self, hash: H256) -> Option { self.chunks.get(&hash).cloned() } diff --git a/ethcore/types/src/restoration_status.rs b/ethcore/types/src/restoration_status.rs index 0cc7fccc08..51f5b8aa0a 100644 --- a/ethcore/types/src/restoration_status.rs +++ b/ethcore/types/src/restoration_status.rs @@ -21,6 +21,11 @@ pub enum RestorationStatus { /// No restoration. Inactive, + /// Restoration is initalizing + Initializing { + /// Number of chunks done/imported + chunks_done: u32, + }, /// Ongoing restoration. Ongoing { /// Total number of state chunks. diff --git a/parity/informant.rs b/parity/informant.rs index beeb258b52..a4d2727c35 100644 --- a/parity/informant.rs +++ b/parity/informant.rs @@ -278,15 +278,12 @@ impl Informant { } = full_report; let rpc_stats = self.rpc_stats.as_ref(); - - let (snapshot_sync, snapshot_current, snapshot_total) = self.snapshot.as_ref().map_or((false, 0, 0), |s| + let snapshot_sync = sync_info.as_ref().map_or(false, |s| s.snapshot_sync) && self.snapshot.as_ref().map_or(false, |s| match s.status() { - RestorationStatus::Ongoing { state_chunks, block_chunks, state_chunks_done, block_chunks_done } => - (true, state_chunks_done + block_chunks_done, state_chunks + block_chunks), - _ => (false, 0, 0), + RestorationStatus::Ongoing { .. } | RestorationStatus::Initializing { .. } => true, + _ => false, } ); - let snapshot_sync = snapshot_sync && sync_info.as_ref().map_or(false, |s| s.snapshot_sync); if !importing && !snapshot_sync && elapsed < Duration::from_secs(30) { return; } @@ -318,7 +315,19 @@ impl Informant { paint(Green.bold(), format!("{:5}", queue_info.unverified_queue_size)), paint(Green.bold(), format!("{:5}", queue_info.verified_queue_size)) ), - true => format!("Syncing snapshot {}/{}", snapshot_current, snapshot_total), + true => { + self.snapshot.as_ref().map_or(String::new(), |s| + match s.status() { + RestorationStatus::Ongoing { state_chunks, block_chunks, state_chunks_done, block_chunks_done } => { + format!("Syncing snapshot {}/{}", state_chunks_done + block_chunks_done, state_chunks + block_chunks) + }, + RestorationStatus::Initializing { chunks_done } => { + format!("Snapshot initializing ({} chunks restored)", chunks_done) + }, + _ => String::new(), + } + ) + }, }, false => String::new(), }, diff --git a/parity/snapshot.rs b/parity/snapshot.rs index 423864679a..3c0dadedaa 100644 --- a/parity/snapshot.rs +++ b/parity/snapshot.rs @@ -122,6 +122,7 @@ fn restore_using(snapshot: Arc, reader: &R, match snapshot.status() { RestorationStatus::Ongoing { .. } => Err("Snapshot file is incomplete and missing chunks.".into()), + RestorationStatus::Initializing { .. } => Err("Snapshot restoration is still initializing.".into()), RestorationStatus::Failed => Err("Snapshot restoration failed.".into()), RestorationStatus::Inactive => { info!("Restoration complete."); diff --git a/rpc/src/v1/tests/helpers/snapshot_service.rs b/rpc/src/v1/tests/helpers/snapshot_service.rs index 25abab578e..099773ab52 100644 --- a/rpc/src/v1/tests/helpers/snapshot_service.rs +++ b/rpc/src/v1/tests/helpers/snapshot_service.rs @@ -43,6 +43,7 @@ impl TestSnapshotService { impl SnapshotService for TestSnapshotService { fn manifest(&self) -> Option { None } fn supported_versions(&self) -> Option<(u64, u64)> { None } + fn completed_chunks(&self) -> Option> { Some(vec![]) } fn chunk(&self, _hash: H256) -> Option { None } fn status(&self) -> RestorationStatus { self.status.lock().clone() } fn begin_restore(&self, _manifest: ManifestData) { } -- GitLab From d1934363e7c2c953f17cd451bea8476f46f52b82 Mon Sep 17 00:00:00 2001 From: Nicolas Gotchac Date: Thu, 17 May 2018 10:58:35 +0200 Subject: [PATCH 054/152] Fix not downloading old blocks (#8642) --- ethcore/src/client/client.rs | 62 +++++++++++++++++++++++------------- ethcore/sync/src/blocks.rs | 2 +- 2 files changed, 40 insertions(+), 24 deletions(-) diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index 993ecdda21..5cfe8fce82 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -17,7 +17,7 @@ use std::collections::{HashSet, BTreeMap, BTreeSet, VecDeque}; use std::fmt; use std::str::FromStr; -use std::sync::atomic::{AtomicUsize, AtomicBool, Ordering as AtomicOrdering}; +use std::sync::atomic::{AtomicBool, Ordering as AtomicOrdering}; use std::sync::{Arc, Weak}; use std::time::{Instant, Duration}; @@ -210,6 +210,8 @@ pub struct Client { queue_transactions: IoChannelQueue, /// Ancient blocks import queue queue_ancient_blocks: IoChannelQueue, + /// Hashes of pending ancient block wainting to be included + pending_ancient_blocks: RwLock>, /// Consensus messages import queue queue_consensus_message: IoChannelQueue, @@ -433,6 +435,7 @@ impl Importer { let hash = header.hash(); let _import_lock = self.import_lock.lock(); + trace!(target: "client", "Trying to import old block #{}", header.number()); { trace_time!("import_old_block"); // verify the block, passing the chain for updating the epoch verifier. @@ -761,6 +764,7 @@ impl Client { notify: RwLock::new(Vec::new()), queue_transactions: IoChannelQueue::new(MAX_TX_QUEUE_SIZE), queue_ancient_blocks: IoChannelQueue::new(MAX_ANCIENT_BLOCKS_QUEUE_SIZE), + pending_ancient_blocks: RwLock::new(HashSet::new()), queue_consensus_message: IoChannelQueue::new(usize::max_value()), last_hashes: RwLock::new(VecDeque::new()), factories: factories, @@ -2008,7 +2012,7 @@ impl BlockChainClient for Client { impl IoClient for Client { fn queue_transactions(&self, transactions: Vec, peer_id: usize) { let len = transactions.len(); - self.queue_transactions.queue(&mut self.io_channel.lock(), len, move |client| { + self.queue_transactions.queue(&mut self.io_channel.lock(), move |client| { trace_time!("import_queued_transactions"); let txs: Vec = transactions @@ -2032,23 +2036,32 @@ impl IoClient for Client { { // check block order - if self.chain.read().is_known(&header.hash()) { + if self.chain.read().is_known(&hash) { bail!(BlockImportErrorKind::Import(ImportErrorKind::AlreadyInChain)); } - let status = self.block_status(BlockId::Hash(*header.parent_hash())); - if status == BlockStatus::Unknown || status == BlockStatus::Pending { - bail!(BlockImportErrorKind::Block(BlockError::UnknownParent(*header.parent_hash()))); + + let parent_hash = *header.parent_hash(); + let parent_pending = self.pending_ancient_blocks.read().contains(&parent_hash); + let status = self.block_status(BlockId::Hash(parent_hash)); + if !parent_pending && (status == BlockStatus::Unknown || status == BlockStatus::Pending) { + bail!(BlockImportErrorKind::Block(BlockError::UnknownParent(parent_hash))); } } - match self.queue_ancient_blocks.queue(&mut self.io_channel.lock(), 1, move |client| { - client.importer.import_old_block( + self.pending_ancient_blocks.write().insert(hash); + + trace!(target: "client", "Queuing old block #{}", header.number()); + match self.queue_ancient_blocks.queue(&mut self.io_channel.lock(), move |client| { + let result = client.importer.import_old_block( &header, &block_bytes, &receipts_bytes, &**client.db.read(), &*client.chain.read() - ).map(|_| ()).unwrap_or_else(|e| { + ); + + client.pending_ancient_blocks.write().remove(&hash); + result.map(|_| ()).unwrap_or_else(|e| { error!(target: "client", "Error importing ancient block: {}", e); }); }) { @@ -2058,7 +2071,7 @@ impl IoClient for Client { } fn queue_consensus_message(&self, message: Bytes) { - match self.queue_consensus_message.queue(&mut self.io_channel.lock(), 1, move |client| { + match self.queue_consensus_message.queue(&mut self.io_channel.lock(), move |client| { if let Err(e) = client.engine().handle_message(&message) { debug!(target: "poa", "Invalid message received: {}", e); } @@ -2471,35 +2484,38 @@ impl fmt::Display for QueueError { /// Queue some items to be processed by IO client. struct IoChannelQueue { - currently_queued: Arc, + queue: Arc>>>, limit: usize, } impl IoChannelQueue { pub fn new(limit: usize) -> Self { IoChannelQueue { - currently_queued: Default::default(), + queue: Default::default(), limit, } } - pub fn queue(&self, channel: &mut IoChannel, count: usize, fun: F) -> Result<(), QueueError> where - F: Fn(&Client) + Send + Sync + 'static, + pub fn queue(&self, channel: &mut IoChannel, fun: F) -> Result<(), QueueError> + where F: Fn(&Client) + Send + Sync + 'static { - let queue_size = self.currently_queued.load(AtomicOrdering::Relaxed); - ensure!(queue_size < self.limit, QueueError::Full(self.limit)); + { + let mut queue = self.queue.lock(); + let queue_size = queue.len(); + ensure!(queue_size < self.limit, QueueError::Full(self.limit)); - let currently_queued = self.currently_queued.clone(); + queue.push_back(Box::new(fun)); + } + + let queue = self.queue.clone(); let result = channel.send(ClientIoMessage::execute(move |client| { - currently_queued.fetch_sub(count, AtomicOrdering::SeqCst); - fun(client); + while let Some(fun) = queue.lock().pop_front() { + fun(client); + } })); match result { - Ok(_) => { - self.currently_queued.fetch_add(count, AtomicOrdering::SeqCst); - Ok(()) - }, + Ok(_) => Ok(()), Err(e) => Err(QueueError::Channel(e)), } } diff --git a/ethcore/sync/src/blocks.rs b/ethcore/sync/src/blocks.rs index 321c783b4d..283f4ed610 100644 --- a/ethcore/sync/src/blocks.rs +++ b/ethcore/sync/src/blocks.rs @@ -266,7 +266,7 @@ impl BlockCollection { } } - /// Get a valid chain of blocks ordered in descending order and ready for importing into blockchain. + /// Get a valid chain of blocks ordered in ascending order and ready for importing into blockchain. pub fn drain(&mut self) -> Vec { if self.blocks.is_empty() || self.head.is_none() { return Vec::new(); -- GitLab From 6552256981589a3a80a1c6c253fb8418f9ded0e8 Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Fri, 18 May 2018 08:04:25 +0200 Subject: [PATCH 055/152] Remove HostInfo::next_nonce (#8644) --- util/network-devp2p/src/host.rs | 12 +++++++----- util/network/src/lib.rs | 2 -- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/util/network-devp2p/src/host.rs b/util/network-devp2p/src/host.rs index 4cca2e6e5a..f3446845fb 100644 --- a/util/network-devp2p/src/host.rs +++ b/util/network-devp2p/src/host.rs @@ -210,6 +210,13 @@ pub struct HostInfo { pub public_endpoint: Option, } +impl HostInfo { + fn next_nonce(&mut self) -> H256 { + self.nonce = keccak(&self.nonce); + self.nonce + } +} + impl HostInfoTrait for HostInfo { fn id(&self) -> &NodeId { self.keys.public() @@ -219,11 +226,6 @@ impl HostInfoTrait for HostInfo { self.keys.secret() } - fn next_nonce(&mut self) -> H256 { - self.nonce = keccak(&self.nonce); - self.nonce - } - fn client_version(&self) -> &str { &self.config.client_version } diff --git a/util/network/src/lib.rs b/util/network/src/lib.rs index 1327a9ad59..0137543fdd 100644 --- a/util/network/src/lib.rs +++ b/util/network/src/lib.rs @@ -332,8 +332,6 @@ pub trait HostInfo { fn id(&self) -> &NodeId; /// Returns secret key fn secret(&self) -> &Secret; - /// Increments and returns connection nonce. - fn next_nonce(&mut self) -> H256; /// Returns the client version. fn client_version(&self) -> &str; } -- GitLab From 9e719f088f37ec9af7a24403cbd7e8cbfd9a134e Mon Sep 17 00:00:00 2001 From: David Date: Sun, 20 May 2018 06:27:59 +0200 Subject: [PATCH 056/152] Remove the Keccak C library and use the pure Rust impl (#8657) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add license and readme * Use pure rust implementation * Bump version to 0.1.1 * Don't use C, prefer the pure Rust implementation * Add test for `write_keccak` * Bump version * Add benchmarks * Add benchmarks * Add keccak_256, keccak_512, keccak_256_unchecked and keccak_512_unchecked – mostly for compatibility with ethash * Remove failed git merge attempt from external git repo Cargo.lock updates * whitespace * Mark unsafe function unsafe * Unsafe calls in unsafe block * Document unsafety invariants * Revert unintended changes to Cargo.lock --- Cargo.lock | 53 +++++----- ethash/src/keccak.rs | 20 ++-- util/hash/Cargo.toml | 11 +- util/hash/benches/keccak_256.rs | 36 +++++++ util/hash/build.rs | 26 ----- util/hash/src/lib.rs | 55 +++++++--- util/hash/src/tinykeccak.c | 177 -------------------------------- 7 files changed, 119 insertions(+), 259 deletions(-) create mode 100644 util/hash/benches/keccak_256.rs delete mode 100644 util/hash/build.rs delete mode 100644 util/hash/src/tinykeccak.c diff --git a/Cargo.lock b/Cargo.lock index b4d6bd315f..e4c80310c1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -251,7 +251,7 @@ dependencies = [ "ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "ethjson 0.1.0", "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "keccak-hash 0.1.0", + "keccak-hash 0.1.2", "rlp 0.2.1", "rlp_derive 0.1.0", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -487,7 +487,7 @@ version = "1.12.0" dependencies = [ "crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "either 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "keccak-hash 0.1.0", + "keccak-hash 0.1.2", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -541,7 +541,7 @@ dependencies = [ "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", "journaldb 0.1.0", - "keccak-hash 0.1.0", + "keccak-hash 0.1.2", "kvdb 0.1.0", "kvdb-memorydb 0.1.0", "kvdb-rocksdb 0.1.0", @@ -633,7 +633,7 @@ dependencies = [ "hashdb 0.1.1", "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", - "keccak-hash 0.1.0", + "keccak-hash 0.1.2", "kvdb 0.1.0", "kvdb-memorydb 0.1.0", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -685,7 +685,7 @@ dependencies = [ "futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.11.24 (registry+https://github.com/rust-lang/crates.io-index)", - "keccak-hash 0.1.0", + "keccak-hash 0.1.2", "linked-hash-map 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "parity-reactor 0.1.0", @@ -730,7 +730,7 @@ dependencies = [ "ethkey 0.3.0", "igd 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "ipnetwork 0.12.7 (registry+https://github.com/rust-lang/crates.io-index)", - "keccak-hash 0.1.0", + "keccak-hash 0.1.2", "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)", @@ -769,7 +769,7 @@ dependencies = [ "ethkey 0.3.0", "fetch 0.1.0", "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", - "keccak-hash 0.1.0", + "keccak-hash 0.1.2", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "patricia-trie 0.1.0", @@ -803,7 +803,7 @@ dependencies = [ "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", "futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.11.24 (registry+https://github.com/rust-lang/crates.io-index)", - "keccak-hash 0.1.0", + "keccak-hash 0.1.2", "kvdb 0.1.0", "kvdb-rocksdb 0.1.0", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -851,7 +851,7 @@ dependencies = [ "jsonrpc-core 8.0.1 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.11)", "jsonrpc-macros 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.11)", "jsonrpc-tcp-server 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.11)", - "keccak-hash 0.1.0", + "keccak-hash 0.1.2", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", @@ -875,7 +875,7 @@ dependencies = [ "ethkey 0.3.0", "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "ipnetwork 0.12.7 (registry+https://github.com/rust-lang/crates.io-index)", - "keccak-hash 0.1.0", + "keccak-hash 0.1.2", "kvdb 0.1.0", "kvdb-memorydb 0.1.0", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -900,7 +900,7 @@ dependencies = [ "ethkey 0.3.0", "evm 0.1.0", "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "keccak-hash 0.1.0", + "keccak-hash 0.1.2", "rlp 0.2.1", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "unexpected 0.1.0", @@ -1021,7 +1021,7 @@ dependencies = [ "bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "keccak-hash 0.1.0", + "keccak-hash 0.1.2", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "memory-cache 0.1.0", @@ -1345,7 +1345,7 @@ dependencies = [ "ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "hashdb 0.1.1", "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "keccak-hash 0.1.0", + "keccak-hash 0.1.2", "kvdb 0.1.0", "kvdb-memorydb 0.1.0", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1454,9 +1454,8 @@ dependencies = [ [[package]] name = "keccak-hash" -version = "0.1.0" +version = "0.1.2" dependencies = [ - "cc 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", "ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "tiny-keccak 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1648,7 +1647,7 @@ dependencies = [ "ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "hashdb 0.1.1", "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "keccak-hash 0.1.0", + "keccak-hash 0.1.2", "plain_hasher 0.1.0", "rlp 0.2.1", ] @@ -1987,7 +1986,7 @@ dependencies = [ "ipnetwork 0.12.7 (registry+https://github.com/rust-lang/crates.io-index)", "journaldb 0.1.0", "jsonrpc-core 8.0.1 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.11)", - "keccak-hash 0.1.0", + "keccak-hash 0.1.2", "kvdb 0.1.0", "kvdb-rocksdb 0.1.0", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2051,7 +2050,7 @@ dependencies = [ "itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core 8.0.1 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.11)", "jsonrpc-http-server 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.11)", - "keccak-hash 0.1.0", + "keccak-hash 0.1.2", "linked-hash-map 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "mime_guess 2.0.0-alpha.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2115,7 +2114,7 @@ dependencies = [ "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", "futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.11.24 (registry+https://github.com/rust-lang/crates.io-index)", - "keccak-hash 0.1.0", + "keccak-hash 0.1.2", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "mime 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "mime_guess 2.0.0-alpha.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2208,7 +2207,7 @@ dependencies = [ "jsonrpc-macros 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.11)", "jsonrpc-pubsub 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.11)", "jsonrpc-ws-server 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.11)", - "keccak-hash 0.1.0", + "keccak-hash 0.1.2", "kvdb-memorydb 0.1.0", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "macros 0.1.0", @@ -2244,7 +2243,7 @@ dependencies = [ "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core 8.0.1 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.11)", "jsonrpc-ws-server 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.11)", - "keccak-hash 0.1.0", + "keccak-hash 0.1.2", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "parity-rpc 1.12.0", @@ -2332,7 +2331,7 @@ dependencies = [ "ethcore-bytes 0.1.0", "ethcore-sync 1.12.0", "ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "keccak-hash 0.1.0", + "keccak-hash 0.1.2", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2440,7 +2439,7 @@ dependencies = [ "ethcore-logger 1.12.0", "ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "hashdb 0.1.1", - "keccak-hash 0.1.0", + "keccak-hash 0.1.2", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "memorydb 0.1.1", "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2736,7 +2735,7 @@ dependencies = [ "ethabi-contract 5.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethabi-derive 5.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", - "keccak-hash 0.1.0", + "keccak-hash 0.1.2", ] [[package]] @@ -3472,7 +3471,7 @@ version = "0.1.0" dependencies = [ "ethcore-bytes 0.1.0", "ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "keccak-hash 0.1.0", + "keccak-hash 0.1.2", "rlp 0.2.1", ] @@ -3482,7 +3481,7 @@ version = "0.1.0" dependencies = [ "elastic-array 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "keccak-hash 0.1.0", + "keccak-hash 0.1.2", "rlp 0.2.1", "trie-standardmap 0.1.0", ] @@ -3630,7 +3629,7 @@ dependencies = [ "ethcore-bytes 0.1.0", "ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "ethjson 0.1.0", - "keccak-hash 0.1.0", + "keccak-hash 0.1.2", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "patricia-trie 0.1.0", "rlp 0.2.1", diff --git a/ethash/src/keccak.rs b/ethash/src/keccak.rs index 8ca4f54384..36fb173547 100644 --- a/ethash/src/keccak.rs +++ b/ethash/src/keccak.rs @@ -21,32 +21,36 @@ pub type H256 = [u8; 32]; pub mod keccak_512 { use super::hash; - pub use self::hash::keccak_512 as unchecked; + pub use self::hash::keccak_512_unchecked as unchecked; pub fn write(input: &[u8], output: &mut [u8]) { - unsafe { hash::keccak_512(output.as_mut_ptr(), output.len(), input.as_ptr(), input.len()) }; + hash::keccak_512(input, output); } pub fn inplace(input: &mut [u8]) { - // This is safe since `sha3_*` uses an internal buffer and copies the result to the output. This + // This is safe since `keccak_*` 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 { hash::keccak_512(input.as_mut_ptr(), input.len(), input.as_ptr(), input.len()) }; + unsafe { + hash::keccak_512_unchecked(input.as_mut_ptr(), input.len(), input.as_ptr(), input.len()); + } } } pub mod keccak_256 { use super::hash; - pub use self::hash::keccak_256 as unchecked; + pub use self::hash::keccak_256_unchecked as unchecked; #[allow(dead_code)] pub fn write(input: &[u8], output: &mut [u8]) { - unsafe { hash::keccak_256(output.as_mut_ptr(), output.len(), input.as_ptr(), input.len()) }; + hash::keccak_256(input, output); } pub fn inplace(input: &mut [u8]) { - // This is safe since `sha3_*` uses an internal buffer and copies the result to the output. This + // This is safe since `keccak_*` 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 { hash::keccak_256(input.as_mut_ptr(), input.len(), input.as_ptr(), input.len()) }; + unsafe { + hash::keccak_256_unchecked(input.as_mut_ptr(), input.len(), input.as_ptr(), input.len()); + } } } diff --git a/util/hash/Cargo.toml b/util/hash/Cargo.toml index da91cd733c..e136ada305 100644 --- a/util/hash/Cargo.toml +++ b/util/hash/Cargo.toml @@ -1,18 +1,15 @@ [package] description = "Rust bindings for tinykeccak C library" -homepage = "http://parity.io" +homepage = "https://github.com/paritytech/keccak-hash" +readme = "README.md" license = "GPL-3.0" name = "keccak-hash" -version = "0.1.0" +version = "0.1.2" authors = ["Parity Technologies "] -build = "build.rs" [dependencies] ethereum-types = "0.3" -tiny-keccak = "1.3" - -[build-dependencies] -cc = "1.0" +tiny-keccak = "1.4.1" [dev-dependencies] tempdir = "0.3" diff --git a/util/hash/benches/keccak_256.rs b/util/hash/benches/keccak_256.rs new file mode 100644 index 0000000000..8b398417d8 --- /dev/null +++ b/util/hash/benches/keccak_256.rs @@ -0,0 +1,36 @@ +#![feature(test)] + +extern crate test; +extern crate ethereum_types; +extern crate keccak_hash; + +use keccak_hash::{keccak, write_keccak}; +use test::Bencher; + +#[bench] +fn bench_keccak_256_with_empty_input(b: &mut Bencher) { + let empty = [0u8;0]; + b.bytes = empty.len() as u64; + b.iter(|| { + let _out = keccak(empty); + }) +} + +#[bench] +fn bench_keccak_256_with_typical_input(b: &mut Bencher) { + let data: Vec = From::from("some medum length string with important information"); + b.bytes = data.len() as u64; + b.iter(|| { + let _out = keccak(&data); + }) +} + +#[bench] +fn bench_keccak_256_with_large_input(b: &mut Bencher) { + // 4096 chars + let data: Vec = From::from("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"); + b.bytes = data.len() as u64; + b.iter(|| { + let _out = keccak(&data); + }) +} \ No newline at end of file diff --git a/util/hash/build.rs b/util/hash/build.rs deleted file mode 100644 index eecb804f90..0000000000 --- a/util/hash/build.rs +++ /dev/null @@ -1,26 +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 . - - // build.rs - -// Bring in a dependency on an externally maintained `cc` package which manages -// invoking the C compiler. -extern crate cc; - -fn main() { - cc::Build::new().file("src/tinykeccak.c").compile("libtinykeccak.a"); -} - diff --git a/util/hash/src/lib.rs b/util/hash/src/lib.rs index 526d22aeda..b75e095a68 100644 --- a/util/hash/src/lib.rs +++ b/util/hash/src/lib.rs @@ -18,7 +18,9 @@ extern crate ethereum_types; extern crate tiny_keccak; use std::io; +use std::slice; use tiny_keccak::Keccak; + pub use ethereum_types::H256; /// Get the KECCAK (i.e. Keccak) hash of the empty bytes string. @@ -30,12 +32,6 @@ pub const KECCAK_NULL_RLP: H256 = H256( [0x56, 0xe8, 0x1f, 0x17, 0x1b, 0xcc, 0x5 /// The KECCAK of the RLP encoding of empty list. pub const KECCAK_EMPTY_LIST_RLP: H256 = H256( [0x1d, 0xcc, 0x4d, 0xe8, 0xde, 0xc7, 0x5d, 0x7a, 0xab, 0x85, 0xb5, 0x67, 0xb6, 0xcc, 0xd4, 0x1a, 0xd3, 0x12, 0x45, 0x1b, 0x94, 0x8a, 0x74, 0x13, 0xf0, 0xa1, 0x42, 0xfd, 0x40, 0xd4, 0x93, 0x47] ); -extern { - /// Hashes input. Returns -1 if either out or input does not exist. Otherwise returns 0. - pub fn keccak_256(out: *mut u8, outlen: usize, input: *const u8, inputlen: usize) -> i32; - /// Hashes input. Returns -1 if either out or input does not exist. Otherwise returns 0. - pub fn keccak_512(out: *mut u8, outlen: usize, input: *const u8, inputlen: usize) -> i32; -} pub fn keccak>(s: T) -> H256 { let mut result = [0u8; 32]; @@ -43,15 +39,30 @@ pub fn keccak>(s: T) -> H256 { H256(result) } -pub fn write_keccak>(s: T, dest: &mut [u8]) { - let input = s.as_ref(); - unsafe { - // we can safely ignore keccak_256 output, cause we know that both input - // and dest are properly allocated - keccak_256(dest.as_mut_ptr(), dest.len(), input.as_ptr(), input.len()); - } +pub unsafe fn keccak_256_unchecked(out: *mut u8, outlen: usize, input: *const u8, inputlen: usize) { + // This is safe since `keccak_*` 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. + Keccak::keccak256( + slice::from_raw_parts(input, inputlen), + slice::from_raw_parts_mut(out, outlen) + ); } +pub unsafe fn keccak_512_unchecked(out: *mut u8, outlen: usize, input: *const u8, inputlen: usize) { + // This is safe since `keccak_*` 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. + Keccak::keccak512( + slice::from_raw_parts(input, inputlen), + slice::from_raw_parts_mut(out, outlen) + ); +} + +pub fn keccak_256(input: &[u8], mut output: &mut [u8]) { Keccak::keccak256(input, &mut output); } + +pub fn keccak_512(input: &[u8], mut output: &mut [u8]) { Keccak::keccak512(input, &mut output); } + +pub fn write_keccak>(s: T, dest: &mut [u8]) { Keccak::keccak256(s.as_ref(), dest); } + pub fn keccak_pipe(r: &mut io::BufRead, w: &mut io::Write) -> Result { let mut output = [0u8; 32]; let mut input = [0u8; 1024]; @@ -82,17 +93,33 @@ mod tests { use std::fs; use std::io::{Write, BufReader}; use self::tempdir::TempDir; - use super::{keccak, keccak_buffer, KECCAK_EMPTY}; + use super::{keccak, write_keccak, keccak_buffer, KECCAK_EMPTY}; #[test] fn keccak_empty() { assert_eq!(keccak([0u8; 0]), KECCAK_EMPTY); } + #[test] fn keccak_as() { assert_eq!(keccak([0x41u8; 32]), From::from("59cad5948673622c1d64e2322488bf01619f7ff45789741b15a9f782ce9290a8")); } + #[test] + fn write_keccak_with_content() { + let data: Vec = From::from("hello world"); + let expected = vec![ + 0x47, 0x17, 0x32, 0x85, 0xa8, 0xd7, 0x34, 0x1e, + 0x5e, 0x97, 0x2f, 0xc6, 0x77, 0x28, 0x63, 0x84, + 0xf8, 0x02, 0xf8, 0xef, 0x42, 0xa5, 0xec, 0x5f, + 0x03, 0xbb, 0xfa, 0x25, 0x4c, 0xb0, 0x1f, 0xad + ]; + let mut dest = [0u8;32]; + write_keccak(data, &mut dest); + + assert_eq!(dest, expected.as_ref()); + } + #[test] fn should_keccak_a_file() { // given diff --git a/util/hash/src/tinykeccak.c b/util/hash/src/tinykeccak.c deleted file mode 100644 index bfe172e5f6..0000000000 --- a/util/hash/src/tinykeccak.c +++ /dev/null @@ -1,177 +0,0 @@ -#include -#include - -/** libkeccak-tiny - * - * A single-file implementation of SHA-3 and SHAKE. - * - * Implementor: David Leon Gil - * License: CC0, attribution kindly requested. Blame taken too, - * but not liability. - */ - -#define decshake(bits) \ - int shake##bits(uint8_t*, size_t, const uint8_t*, size_t); - -#define deckeccak(bits) \ - int keccak_##bits(uint8_t*, size_t, const uint8_t*, size_t); - -decshake(128) -decshake(256) -deckeccak(224) -deckeccak(256) -deckeccak(384) -deckeccak(512) - -/******** The Keccak-f[1600] permutation ********/ - -/*** Constants. ***/ -static const uint8_t rho[24] = \ - { 1, 3, 6, 10, 15, 21, - 28, 36, 45, 55, 2, 14, - 27, 41, 56, 8, 25, 43, - 62, 18, 39, 61, 20, 44}; -static const uint8_t pi[24] = \ - {10, 7, 11, 17, 18, 3, - 5, 16, 8, 21, 24, 4, - 15, 23, 19, 13, 12, 2, - 20, 14, 22, 9, 6, 1}; -static const uint64_t RC[24] = \ - {1ULL, 0x8082ULL, 0x800000000000808aULL, 0x8000000080008000ULL, - 0x808bULL, 0x80000001ULL, 0x8000000080008081ULL, 0x8000000000008009ULL, - 0x8aULL, 0x88ULL, 0x80008009ULL, 0x8000000aULL, - 0x8000808bULL, 0x800000000000008bULL, 0x8000000000008089ULL, 0x8000000000008003ULL, - 0x8000000000008002ULL, 0x8000000000000080ULL, 0x800aULL, 0x800000008000000aULL, - 0x8000000080008081ULL, 0x8000000000008080ULL, 0x80000001ULL, 0x8000000080008008ULL}; - -/*** Helper macros to unroll the permutation. ***/ -#define rol(x, s) (((x) << s) | ((x) >> (64 - s))) -#define REPEAT6(e) e e e e e e -#define REPEAT24(e) REPEAT6(e e e e) -#define REPEAT5(e) e e e e e -#define FOR5(v, s, e) \ - v = 0; \ - REPEAT5(e; v += s;) - -/*** Keccak-f[1600] ***/ -static inline void keccakf(void* state) { - uint64_t* a = (uint64_t*)state; - uint64_t b[5] = {0}; - uint64_t t = 0; - uint8_t x, y; - int i; - - for (i = 0; i < 24; i++) { - // Theta - FOR5(x, 1, - b[x] = 0; - FOR5(y, 5, - b[x] ^= a[x + y]; )) - FOR5(x, 1, - FOR5(y, 5, - a[y + x] ^= b[(x + 4) % 5] ^ rol(b[(x + 1) % 5], 1); )) - // Rho and pi - t = a[1]; - x = 0; - REPEAT24(b[0] = a[pi[x]]; - a[pi[x]] = rol(t, rho[x]); - t = b[0]; - x++; ) - // Chi - FOR5(y, - 5, - FOR5(x, 1, - b[x] = a[y + x];) - FOR5(x, 1, - a[y + x] = b[x] ^ ((~b[(x + 1) % 5]) & b[(x + 2) % 5]); )) - // Iota - a[0] ^= RC[i]; - } -} - -/******** The FIPS202-defined functions. ********/ - -/*** Some helper macros. ***/ - -#define _(S) do { S } while (0) -#define FOR(i, ST, L, S) \ - _({size_t i; for (i = 0; i < L; i += ST) { S; }}) -#define mkapply_ds(NAME, S) \ - static inline void NAME(uint8_t* dst, \ - const uint8_t* src, \ - size_t len) { \ - FOR(i, 1, len, S); \ - } -#define mkapply_sd(NAME, S) \ - static inline void NAME(const uint8_t* src, \ - uint8_t* dst, \ - size_t len) { \ - FOR(i, 1, len, S); \ - } - -mkapply_ds(xorin, dst[i] ^= src[i]) // xorin -mkapply_sd(setout, dst[i] = src[i]) // setout - -#define P keccakf -#define Plen 200 - -// Fold P*F over the full blocks of an input. -#define foldP(I, L, F) \ - while (L >= rate) { \ - F(a, I, rate); \ - P(a); \ - I += rate; \ - L -= rate; \ - } - -/** The sponge-based hash construction. **/ -static inline int hash(uint8_t* out, size_t outlen, - const uint8_t* in, size_t inlen, - size_t rate, uint8_t delim) { - if ((out == NULL) || ((in == NULL) && inlen != 0) || (rate >= Plen)) { - return -1; - } - uint8_t a[Plen] = {0}; - // Absorb input. - foldP(in, inlen, xorin); - // Xor in the DS and pad frame. - a[inlen] ^= delim; - a[rate - 1] ^= 0x80; - // Xor in the last block. - xorin(a, in, inlen); - // Apply P - P(a); - // Squeeze output. - foldP(out, outlen, setout); - setout(a, out, outlen); - memset(a, 0, 200); - return 0; -} - -/*** Helper macros to define SHA3 and SHAKE instances. ***/ -#define defshake(bits) \ - int shake##bits(uint8_t* out, size_t outlen, \ - const uint8_t* in, size_t inlen) { \ - return hash(out, outlen, in, inlen, 200 - (bits / 4), 0x1f); \ - } -#define defkeccak(bits) \ - int keccak_##bits(uint8_t* out, size_t outlen, \ - const uint8_t* in, size_t inlen) { \ - if (outlen > (bits/8)) { \ - return -1; \ - } \ - return hash(out, outlen, in, inlen, 200 - (bits / 4), 0x01); \ - } - -/*** FIPS202 SHAKE VOFs ***/ -defshake(128) -defshake(256) - -/*** FIPS202 SHA3 FOFs ***/ -defkeccak(224) -defkeccak(256) -defkeccak(384) -defkeccak(512) - - - -- GitLab From 52f10242e2419cc31096904578e6c92e0e54e503 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Mon, 21 May 2018 15:33:47 +0800 Subject: [PATCH 057/152] updated tiny-keccak to 1.4.2 (#8669) --- Cargo.lock | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e4c80310c1..e2fa0a9db8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -462,7 +462,7 @@ dependencies = [ "serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", - "tiny-keccak 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -504,7 +504,7 @@ dependencies = [ "ethereum-types-serialize 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "fixed-hash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)", - "tiny-keccak 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -595,7 +595,7 @@ dependencies = [ "quick-error 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "ring 0.12.1 (git+https://github.com/paritytech/ring)", "rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", - "tiny-keccak 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -746,7 +746,7 @@ dependencies = [ "slab 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "snappy 0.1.0 (git+https://github.com/paritytech/rust-snappy)", "tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "tiny-keccak 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -780,7 +780,7 @@ dependencies = [ "serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", - "tiny-keccak 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -814,7 +814,7 @@ dependencies = [ "serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "tiny-keccak 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -955,7 +955,7 @@ dependencies = [ "quick-error 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tiny-keccak 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -995,7 +995,7 @@ dependencies = [ "smallvec 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", - "tiny-keccak 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1458,7 +1458,7 @@ version = "0.1.2" dependencies = [ "ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "tiny-keccak 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1776,7 +1776,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "ring 0.12.1 (git+https://github.com/paritytech/ring)", - "tiny-keccak 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2229,7 +2229,7 @@ dependencies = [ "serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "stats 0.1.0", "tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "tiny-keccak 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-timer 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "transaction-pool 1.12.0", "transient-hashmap 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2392,7 +2392,7 @@ dependencies = [ "serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "tiny-keccak 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3220,7 +3220,7 @@ dependencies = [ [[package]] name = "tiny-keccak" -version = "1.4.1" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4024,7 +4024,7 @@ dependencies = [ "checksum threadpool 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e2f0c90a5f3459330ac8bc0d2f879c693bb7a2f59689c1083fc4ef83834da865" "checksum time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)" = "d5d788d3aa77bc0ef3e9621256885555368b47bd495c13dd2e7413c89f845520" "checksum timer 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "31d42176308937165701f50638db1c31586f183f1aab416268216577aec7306b" -"checksum tiny-keccak 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "58911ed5eb275a8fd2f1f0418ed360a42f59329864b64e1e95377a9024498c01" +"checksum tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e9175261fbdb60781fcd388a4d6cc7e14764a2b629a7ad94abb439aed223a44f" "checksum tokio 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "be15ef40f675c9fe66e354d74c73f3ed012ca1aa14d65846a33ee48f1ae8d922" "checksum tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "aeeffbbb94209023feaef3c196a41cbcdafa06b4a6f893f68779bb5e53796f71" "checksum tokio-executor 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8cac2a7883ff3567e9d66bb09100d09b33d90311feca0206c7ca034bc0c55113" -- GitLab From 3c2f13f88b5fee3d485e91130d6b1a8bf1f66f52 Mon Sep 17 00:00:00 2001 From: Afri Schoedon <5chdn@users.noreply.github.com> Date: Tue, 22 May 2018 04:19:00 +0200 Subject: [PATCH 058/152] parity: improve cli help and logging (#8665) * parity: indicate disabling ancient blocks is not recommended * parity: display decimals for stats in informant --- parity/cli/mod.rs | 6 +++--- parity/informant.rs | 14 +++++++------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/parity/cli/mod.rs b/parity/cli/mod.rs index c7c484e2bd..34e3bf03a1 100644 --- a/parity/cli/mod.rs +++ b/parity/cli/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -424,7 +424,7 @@ usage! { FLAG flag_no_ancient_blocks: (bool) = false, or |_| None, "--no-ancient-blocks", - "Disable downloading old blocks after snapshot restoration or warp sync.", + "Disable downloading old blocks after snapshot restoration or warp sync. Not recommended.", FLAG flag_no_serve_light: (bool) = false, or |c: &Config| c.network.as_ref()?.no_serve_light.clone(), "--no-serve-light", @@ -894,7 +894,7 @@ usage! { ["Legacy options"] FLAG flag_warp: (bool) = false, or |_| None, "--warp", - "Does nothing; warp sync is enabled by default.", + "Does nothing; warp sync is enabled by default. Use --no-warp to disable.", FLAG flag_dapps_apis_all: (bool) = false, or |_| None, "--dapps-apis-all", diff --git a/parity/informant.rs b/parity/informant.rs index a4d2727c35..e2f3960b67 100644 --- a/parity/informant.rs +++ b/parity/informant.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -303,13 +303,13 @@ impl Informant { paint(White.bold(), format!("{}", chain_info.best_block_hash)), if self.target.executes_transactions() { format!("{} blk/s {} tx/s {} Mgas/s", - paint(Yellow.bold(), format!("{:4}", (client_report.blocks_imported * 1000) as u64 / elapsed.as_milliseconds())), - paint(Yellow.bold(), format!("{:4}", (client_report.transactions_applied * 1000) as u64 / elapsed.as_milliseconds())), - paint(Yellow.bold(), format!("{:3}", (client_report.gas_processed / From::from(elapsed.as_milliseconds() * 1000)).low_u64())) + paint(Yellow.bold(), format!("{:5.2}", (client_report.blocks_imported * 1000) as f64 / elapsed.as_milliseconds() as f64)), + paint(Yellow.bold(), format!("{:6.1}", (client_report.transactions_applied * 1000) as f64 / elapsed.as_milliseconds() as f64)), + paint(Yellow.bold(), format!("{:4}", (client_report.gas_processed / From::from(elapsed.as_milliseconds() * 1000)).low_u64())) ) } else { format!("{} hdr/s", - paint(Yellow.bold(), format!("{:4}", (client_report.blocks_imported * 1000) as u64 / elapsed.as_milliseconds())) + paint(Yellow.bold(), format!("{:6.1}", (client_report.blocks_imported * 1000) as f64 / elapsed.as_milliseconds() as f64)) ) }, paint(Green.bold(), format!("{:5}", queue_info.unverified_queue_size)), @@ -350,8 +350,8 @@ impl Informant { Some(ref rpc_stats) => format!( "RPC: {} conn, {} req/s, {} µs", paint(Blue.bold(), format!("{:2}", rpc_stats.sessions())), - paint(Blue.bold(), format!("{:2}", rpc_stats.requests_rate())), - paint(Blue.bold(), format!("{:3}", rpc_stats.approximated_roundtrip())), + paint(Blue.bold(), format!("{:4}", rpc_stats.requests_rate())), + paint(Blue.bold(), format!("{:4}", rpc_stats.approximated_roundtrip())), ), _ => String::new(), }, -- GitLab From 3fde07b2e18f20453970ed2ab9c6f2df6cc717b1 Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Tue, 22 May 2018 12:24:09 +0800 Subject: [PATCH 059/152] Refactor EIP150, EIP160 and EIP161 forks to be specified in CommonParams (#8614) * Allow post-homestead forks to be specified in CommonParams * Fix all json configs * Fix test in json crate * Fix test in ethcore * Fix all chain configs to use tabs Given we use tabs in .editorconfig and the majority of chain configs. This change is done in Emacs using `mark-whole-buffer` and `indent-region`. --- ...authority_round_block_reward_contract.json | 112 +- ethcore/res/ethereum/byzantium_test.json | 8 +- ethcore/res/ethereum/classic.json | 8 +- ethcore/res/ethereum/constantinople_test.json | 8 +- ethcore/res/ethereum/easthub.json | 174 +- ethcore/res/ethereum/eip150_test.json | 10 +- ethcore/res/ethereum/eip161_test.json | 10 +- ethcore/res/ethereum/ellaism.json | 144 +- ethcore/res/ethereum/expanse.json | 8 +- ethcore/res/ethereum/foundation.json | 8 +- ethcore/res/ethereum/frontier_like_test.json | 10 +- ethcore/res/ethereum/frontier_test.json | 10 +- ethcore/res/ethereum/homestead_test.json | 12 +- ethcore/res/ethereum/mcip3_test.json | 332 +- ethcore/res/ethereum/mcip6_byz.json | 318 +- ethcore/res/ethereum/morden.json | 8 +- ethcore/res/ethereum/musicoin.json | 324 +- ethcore/res/ethereum/olympic.json | 10 +- ethcore/res/ethereum/ropsten.json | 8 +- ethcore/res/ethereum/social.json | 17710 ++++++++-------- ethcore/res/ethereum/transition_test.json | 8 +- ethcore/src/machine.rs | 29 +- ethcore/src/spec/spec.rs | 29 +- json/src/spec/ethash.rs | 29 +- json/src/spec/params.rs | 15 + 25 files changed, 9663 insertions(+), 9679 deletions(-) diff --git a/ethcore/res/authority_round_block_reward_contract.json b/ethcore/res/authority_round_block_reward_contract.json index e008de117f..3195773123 100644 --- a/ethcore/res/authority_round_block_reward_contract.json +++ b/ethcore/res/authority_round_block_reward_contract.json @@ -1,61 +1,61 @@ { - "name": "TestAuthorityRoundBlockRewardContract", - "engine": { - "authorityRound": { - "params": { - "stepDuration": 1, - "startStep": 2, - "validators": { - "list": [ - "0x7d577a597b2742b498cb5cf0c26cdcd726d39e6e", - "0x82a978b3f5962a5b0957d9ee9eef472ee55b42f1" - ] + "name": "TestAuthorityRoundBlockRewardContract", + "engine": { + "authorityRound": { + "params": { + "stepDuration": 1, + "startStep": 2, + "validators": { + "list": [ + "0x7d577a597b2742b498cb5cf0c26cdcd726d39e6e", + "0x82a978b3f5962a5b0957d9ee9eef472ee55b42f1" + ] + }, + "immediateTransitions": true, + "emptyStepsTransition": "1", + "maximumEmptySteps": "2", + "blockRewardContractAddress": "0x0000000000000000000000000000000000000042" + } + } + }, + "params": { + "gasLimitBoundDivisor": "0x0400", + "accountStartNonce": "0x0", + "maximumExtraDataSize": "0x20", + "minGasLimit": "0x1388", + "networkID" : "0x69", + "eip140Transition": "0x0", + "eip211Transition": "0x0", + "eip214Transition": "0x0", + "eip658Transition": "0x0" + }, + "genesis": { + "seal": { + "authorityRound": { + "step": "0x0", + "signature": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + } }, - "immediateTransitions": true, - "emptyStepsTransition": "1", - "maximumEmptySteps": "2", - "blockRewardContractAddress": "0x0000000000000000000000000000000000000042" - } - } - }, - "params": { - "gasLimitBoundDivisor": "0x0400", - "accountStartNonce": "0x0", - "maximumExtraDataSize": "0x20", - "minGasLimit": "0x1388", - "networkID" : "0x69", - "eip140Transition": "0x0", - "eip211Transition": "0x0", - "eip214Transition": "0x0", - "eip658Transition": "0x0" - }, - "genesis": { - "seal": { - "authorityRound": { - "step": "0x0", - "signature": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - } + "difficulty": "0x20000", + "author": "0x0000000000000000000000000000000000000000", + "timestamp": "0x00", + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "extraData": "0x", + "gasLimit": "0x222222" }, - "difficulty": "0x20000", - "author": "0x0000000000000000000000000000000000000000", - "timestamp": "0x00", - "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "extraData": "0x", - "gasLimit": "0x222222" - }, - "accounts": { - "0000000000000000000000000000000000000001": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } }, - "0000000000000000000000000000000000000002": { "balance": "1", "nonce": "1048576", "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } }, - "0000000000000000000000000000000000000003": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } }, - "0000000000000000000000000000000000000004": { "balance": "1", "nonce": "1048576", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } }, - "0000000000000000000000000000000000000005": { "balance": "1", "builtin": { "name": "modexp", "activate_at": 0, "pricing": { "modexp": { "divisor": 20 } } } }, - "0000000000000000000000000000000000000006": { "balance": "1", "builtin": { "name": "alt_bn128_add", "activate_at": 0, "pricing": { "linear": { "base": 500, "word": 0 } } } }, - "0000000000000000000000000000000000000007": { "balance": "1", "builtin": { "name": "alt_bn128_mul", "activate_at": 0, "pricing": { "linear": { "base": 40000, "word": 0 } } } }, - "0000000000000000000000000000000000000008": { "balance": "1", "builtin": { "name": "alt_bn128_pairing", "activate_at": 0, "pricing": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 } } } }, - "9cce34f7ab185c7aba1b7c8140d620b4bda941d6": { "balance": "1606938044258990275541962092341162602522202993782792835301376", "nonce": "1048576" }, - "0000000000000000000000000000000000000042": { - "balance": "1", - "constructor": "6060604052341561000f57600080fd5b6102b88061001e6000396000f300606060405260043610610041576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063f91c289814610046575b600080fd5b341561005157600080fd5b610086600480803590602001908201803590602001919091929080359060200190820180359060200191909192905050610125565b604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b838110156100cd5780820151818401526020810190506100b2565b50505050905001838103825284818151815260200191508051906020019060200280838360005b8381101561010f5780820151818401526020810190506100f4565b5050505090500194505050505060405180910390f35b61012d610264565b610135610278565b61013d610278565b600073fffffffffffffffffffffffffffffffffffffffe73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561018d57600080fd5b85859050888890501415156101a157600080fd5b878790506040518059106101b25750595b90808252806020026020018201604052509150600090505b815181101561021d5785858281811015156101e157fe5b9050602002013561ffff166103e80161ffff16828281518110151561020257fe5b906020019060200201818152505080806001019150506101ca565b878783828280806020026020016040519081016040528093929190818152602001838360200280828437820191505050505050915090915093509350505094509492505050565b602060405190810160405280600081525090565b6020604051908101604052806000815250905600a165627a7a723058201da0f164e75517fb8baf51f030b904032cb748334938e7386f63025bfb23f3de0029" + "accounts": { + "0000000000000000000000000000000000000001": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } }, + "0000000000000000000000000000000000000002": { "balance": "1", "nonce": "1048576", "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } }, + "0000000000000000000000000000000000000003": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } }, + "0000000000000000000000000000000000000004": { "balance": "1", "nonce": "1048576", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } }, + "0000000000000000000000000000000000000005": { "balance": "1", "builtin": { "name": "modexp", "activate_at": 0, "pricing": { "modexp": { "divisor": 20 } } } }, + "0000000000000000000000000000000000000006": { "balance": "1", "builtin": { "name": "alt_bn128_add", "activate_at": 0, "pricing": { "linear": { "base": 500, "word": 0 } } } }, + "0000000000000000000000000000000000000007": { "balance": "1", "builtin": { "name": "alt_bn128_mul", "activate_at": 0, "pricing": { "linear": { "base": 40000, "word": 0 } } } }, + "0000000000000000000000000000000000000008": { "balance": "1", "builtin": { "name": "alt_bn128_pairing", "activate_at": 0, "pricing": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 } } } }, + "9cce34f7ab185c7aba1b7c8140d620b4bda941d6": { "balance": "1606938044258990275541962092341162602522202993782792835301376", "nonce": "1048576" }, + "0000000000000000000000000000000000000042": { + "balance": "1", + "constructor": "6060604052341561000f57600080fd5b6102b88061001e6000396000f300606060405260043610610041576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063f91c289814610046575b600080fd5b341561005157600080fd5b610086600480803590602001908201803590602001919091929080359060200190820180359060200191909192905050610125565b604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b838110156100cd5780820151818401526020810190506100b2565b50505050905001838103825284818151815260200191508051906020019060200280838360005b8381101561010f5780820151818401526020810190506100f4565b5050505090500194505050505060405180910390f35b61012d610264565b610135610278565b61013d610278565b600073fffffffffffffffffffffffffffffffffffffffe73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561018d57600080fd5b85859050888890501415156101a157600080fd5b878790506040518059106101b25750595b90808252806020026020018201604052509150600090505b815181101561021d5785858281811015156101e157fe5b9050602002013561ffff166103e80161ffff16828281518110151561020257fe5b906020019060200201818152505080806001019150506101ca565b878783828280806020026020016040519081016040528093929190818152602001838360200280828437820191505050505050915090915093509350505094509492505050565b602060405190810160405280600081525090565b6020604051908101604052806000815250905600a165627a7a723058201da0f164e75517fb8baf51f030b904032cb748334938e7386f63025bfb23f3de0029" + } } - } } diff --git a/ethcore/res/ethereum/byzantium_test.json b/ethcore/res/ethereum/byzantium_test.json index 40c7e46599..90c92bbff5 100644 --- a/ethcore/res/ethereum/byzantium_test.json +++ b/ethcore/res/ethereum/byzantium_test.json @@ -8,10 +8,6 @@ "durationLimit": "0x0d", "blockReward": "0x4563918244F40000", "homesteadTransition": "0x0", - "eip150Transition": "0x0", - "eip160Transition": "0x0", - "eip161abcTransition": "0x0", - "eip161dTransition": "0x0", "eip649Reward": "0x29A2241AF62C0000", "eip100bTransition": "0x0", "eip649Transition": "0x0" @@ -27,6 +23,10 @@ "networkID" : "0x1", "maxCodeSize": 24576, "maxCodeSizeTransition": "0x0", + "eip150Transition": "0x0", + "eip160Transition": "0x0", + "eip161abcTransition": "0x0", + "eip161dTransition": "0x0", "eip98Transition": "0xffffffffffffffff", "eip140Transition": "0x0", "eip211Transition": "0x0", diff --git a/ethcore/res/ethereum/classic.json b/ethcore/res/ethereum/classic.json index a4c6fe9f22..928c056d66 100644 --- a/ethcore/res/ethereum/classic.json +++ b/ethcore/res/ethereum/classic.json @@ -9,13 +9,9 @@ "durationLimit": "0x0d", "blockReward": "0x4563918244F40000", "homesteadTransition": 1150000, - "eip150Transition": 2500000, - "eip160Transition": 3000000, "ecip1010PauseTransition": 3000000, "ecip1010ContinueTransition": 5000000, "ecip1017EraRounds": 5000000, - "eip161abcTransition": "0x7fffffffffffffff", - "eip161dTransition": "0x7fffffffffffffff", "bombDefuseTransition": 5900000 } } @@ -30,6 +26,10 @@ "chainID": "0x3d", "forkBlock": "0x1d4c00", "forkCanonHash": "0x94365e3a8c0b35089c1d1195081fe7489b528a84b22199c916180db8b28ade7f", + "eip150Transition": 2500000, + "eip160Transition": 3000000, + "eip161abcTransition": "0x7fffffffffffffff", + "eip161dTransition": "0x7fffffffffffffff", "eip155Transition": 3000000, "eip98Transition": "0x7fffffffffffff", "eip86Transition": "0x7fffffffffffff" diff --git a/ethcore/res/ethereum/constantinople_test.json b/ethcore/res/ethereum/constantinople_test.json index 7b137e86fa..155b06507d 100644 --- a/ethcore/res/ethereum/constantinople_test.json +++ b/ethcore/res/ethereum/constantinople_test.json @@ -8,10 +8,6 @@ "durationLimit": "0x0d", "blockReward": "0x4563918244F40000", "homesteadTransition": "0x0", - "eip150Transition": "0x0", - "eip160Transition": "0x0", - "eip161abcTransition": "0x0", - "eip161dTransition": "0x0", "eip649Reward": "0x29A2241AF62C0000", "eip100bTransition": "0x0", "eip649Transition": "0x0" @@ -28,6 +24,10 @@ "maxCodeSize": 24576, "maxCodeSizeTransition": "0x0", "eip98Transition": "0xffffffffffffffff", + "eip150Transition": "0x0", + "eip160Transition": "0x0", + "eip161abcTransition": "0x0", + "eip161dTransition": "0x0", "eip140Transition": "0x0", "eip210Transition": "0x0", "eip211Transition": "0x0", diff --git a/ethcore/res/ethereum/easthub.json b/ethcore/res/ethereum/easthub.json index ddc170d8a6..e7e1a6e708 100644 --- a/ethcore/res/ethereum/easthub.json +++ b/ethcore/res/ethereum/easthub.json @@ -1,89 +1,89 @@ { - "name": "Easthub", - "dataDir": "easthub", - "engine": { - "Ethash": { - "params": { - "minimumDifficulty": "0x020000", - "difficultyBoundDivisor": "0x0800", - "durationLimit": "0x0d", - "blockReward": "0x2B5E3AF16B1880000", - "homesteadTransition": "0x0", - "bombDefuseTransition": "0x0", - "eip150Transition": "0x0", - "eip160Transition": "0x0", - "ecip1017EraRounds": 5000000, - "eip161abcTransition": "0x7fffffffffffffff", - "eip161dTransition": "0x7fffffffffffffff" - } - } - }, - "params": { - "gasLimitBoundDivisor": "0x0400", - "registrar": "0x0000000000000000000000000000000000000000", - "accountStartNonce": "0x00", - "maximumExtraDataSize": "0x20", - "minGasLimit": "0x1388", - "networkID": "0x7", - "chainID": "0x7", - "eip155Transition": "0x0", - "eip98Transition": "0x7fffffffffffff", - "eip86Transition": "0x7fffffffffffff" - }, - "genesis": { - "seal": { - "ethereum": { - "nonce": "0x0000000000000042", - "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - }, - "difficulty": "0x0400000000", - "author": "0x0000000000000000000000000000000000000000", - "timestamp": "0x00", - "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "extraData": "0x323031382045617374636f696e2050726f6a656374", - "gasLimit": "0x1388" - }, - "nodes": [ - "enode://ca57e40edb95a08a81b85a91e91099a0aaab777ad329ea7f3f772bc0fd511a276a5d84944725d181ff80f8c7dc1034814bff25b9723b03363d48617fed4b15f0@13.125.109.174:30303", - "enode://57254e23a7e5fe1e081ee5d1b236e37735a120660daeb4bf1fec6943a82c915c5b6fad23eeb1a43a27c23f236e084e8051aaa28f7d4139149f844747facb62bb@18.217.39.51:30303", - "enode://ef248f327c73c0318f4d51a62270b0612f3c4a4fd04b77d04854dc355980e137708d1e48811bc91387b0d7eb85cf447d8bbc095404f39bb7064e76751bda9cd4@52.221.160.236:30303", - "enode://bf6f0e37dd733cf04f2b079c753d2dea7cc7c59d8637eff9a8e63e17d08e2bfc91229fbb2dff08fe6ee12e51c1b6f8ed969d7042b89d77029e7ea02b05e17be3@18.197.47.177:30303" - ], - "accounts": { - "0000000000000000000000000000000000000001": { "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } }, - "0000000000000000000000000000000000000002": { "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } }, - "0000000000000000000000000000000000000003": { "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } }, - "0000000000000000000000000000000000000004": { "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } }, - "20c1252a8cb33a7a9a257b2a4cfeed8daf87c847": { - "balance": "100000000000000000000000000" - }, - "9dcd37c8e5aea3a0d37c5d0a2db683362d81febd": { - "balance": "100000000000000000000000000" - }, - "9eff080302333f44a60bfd8c33bd63015c6d921b": { - "balance": "100000000000000000000000000" - }, - "c1df2e5de98d5c41fec0642dc302971f5d3500bd": { - "balance": "100000000000000000000000000" - }, - "2e0fb67cd1d029cbaea4b74c361efcc06b3105fd": { - "balance": "100000000000000000000000000" - }, - "2b6425cc3cd90654f077889ef7262ac2f5846460": { - "balance": "100000000000000000000000000" - }, - "28562041230c6d575e233e4ed1b35c514884d964": { - "balance": "100000000000000000000000000" - }, - "16eb6896a5a83d39ac762d79d21f825f5f980d12": { - "balance": "100000000000000000000000000" - }, - "f09e3f1de27dd03a1ac0a021b2d9e45bde1b360c": { - "balance": "100000000000000000000000000" - }, - "2d87547819c6433f208ee3096161cdb2835a2333": { - "balance": "100000000000000000000000000" - } - } + "name": "Easthub", + "dataDir": "easthub", + "engine": { + "Ethash": { + "params": { + "minimumDifficulty": "0x020000", + "difficultyBoundDivisor": "0x0800", + "durationLimit": "0x0d", + "blockReward": "0x2B5E3AF16B1880000", + "homesteadTransition": "0x0", + "bombDefuseTransition": "0x0", + "ecip1017EraRounds": 5000000 + } + } + }, + "params": { + "gasLimitBoundDivisor": "0x0400", + "registrar": "0x0000000000000000000000000000000000000000", + "accountStartNonce": "0x00", + "maximumExtraDataSize": "0x20", + "minGasLimit": "0x1388", + "networkID": "0x7", + "chainID": "0x7", + "eip150Transition": "0x0", + "eip160Transition": "0x0", + "eip155Transition": "0x0", + "eip161abcTransition": "0x7fffffffffffffff", + "eip161dTransition": "0x7fffffffffffffff", + "eip98Transition": "0x7fffffffffffff", + "eip86Transition": "0x7fffffffffffff" + }, + "genesis": { + "seal": { + "ethereum": { + "nonce": "0x0000000000000042", + "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + }, + "difficulty": "0x0400000000", + "author": "0x0000000000000000000000000000000000000000", + "timestamp": "0x00", + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "extraData": "0x323031382045617374636f696e2050726f6a656374", + "gasLimit": "0x1388" + }, + "nodes": [ + "enode://ca57e40edb95a08a81b85a91e91099a0aaab777ad329ea7f3f772bc0fd511a276a5d84944725d181ff80f8c7dc1034814bff25b9723b03363d48617fed4b15f0@13.125.109.174:30303", + "enode://57254e23a7e5fe1e081ee5d1b236e37735a120660daeb4bf1fec6943a82c915c5b6fad23eeb1a43a27c23f236e084e8051aaa28f7d4139149f844747facb62bb@18.217.39.51:30303", + "enode://ef248f327c73c0318f4d51a62270b0612f3c4a4fd04b77d04854dc355980e137708d1e48811bc91387b0d7eb85cf447d8bbc095404f39bb7064e76751bda9cd4@52.221.160.236:30303", + "enode://bf6f0e37dd733cf04f2b079c753d2dea7cc7c59d8637eff9a8e63e17d08e2bfc91229fbb2dff08fe6ee12e51c1b6f8ed969d7042b89d77029e7ea02b05e17be3@18.197.47.177:30303" + ], + "accounts": { + "0000000000000000000000000000000000000001": { "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } }, + "0000000000000000000000000000000000000002": { "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } }, + "0000000000000000000000000000000000000003": { "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } }, + "0000000000000000000000000000000000000004": { "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } }, + "20c1252a8cb33a7a9a257b2a4cfeed8daf87c847": { + "balance": "100000000000000000000000000" + }, + "9dcd37c8e5aea3a0d37c5d0a2db683362d81febd": { + "balance": "100000000000000000000000000" + }, + "9eff080302333f44a60bfd8c33bd63015c6d921b": { + "balance": "100000000000000000000000000" + }, + "c1df2e5de98d5c41fec0642dc302971f5d3500bd": { + "balance": "100000000000000000000000000" + }, + "2e0fb67cd1d029cbaea4b74c361efcc06b3105fd": { + "balance": "100000000000000000000000000" + }, + "2b6425cc3cd90654f077889ef7262ac2f5846460": { + "balance": "100000000000000000000000000" + }, + "28562041230c6d575e233e4ed1b35c514884d964": { + "balance": "100000000000000000000000000" + }, + "16eb6896a5a83d39ac762d79d21f825f5f980d12": { + "balance": "100000000000000000000000000" + }, + "f09e3f1de27dd03a1ac0a021b2d9e45bde1b360c": { + "balance": "100000000000000000000000000" + }, + "2d87547819c6433f208ee3096161cdb2835a2333": { + "balance": "100000000000000000000000000" + } + } } diff --git a/ethcore/res/ethereum/eip150_test.json b/ethcore/res/ethereum/eip150_test.json index 60157c5716..baf9c1b7bf 100644 --- a/ethcore/res/ethereum/eip150_test.json +++ b/ethcore/res/ethereum/eip150_test.json @@ -7,11 +7,7 @@ "difficultyBoundDivisor": "0x0800", "durationLimit": "0x0d", "blockReward": "0x4563918244F40000", - "homesteadTransition": "0x0", - "eip150Transition": "0x0", - "eip160Transition": "0x7fffffffffffffff", - "eip161abcTransition": "0x7fffffffffffffff", - "eip161dTransition": "0x7fffffffffffffff" + "homesteadTransition": "0x0" } } }, @@ -22,6 +18,10 @@ "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", "networkID" : "0x1", + "eip150Transition": "0x0", + "eip160Transition": "0x7fffffffffffffff", + "eip161abcTransition": "0x7fffffffffffffff", + "eip161dTransition": "0x7fffffffffffffff", "eip98Transition": "0x7fffffffffffffff", "eip86Transition": "0x7fffffffffffffff", "eip155Transition": "0x7fffffffffffffff", diff --git a/ethcore/res/ethereum/eip161_test.json b/ethcore/res/ethereum/eip161_test.json index ac1c0a5d1e..079ce7d55a 100644 --- a/ethcore/res/ethereum/eip161_test.json +++ b/ethcore/res/ethereum/eip161_test.json @@ -7,11 +7,7 @@ "difficultyBoundDivisor": "0x0800", "durationLimit": "0x0d", "blockReward": "0x4563918244F40000", - "homesteadTransition": "0x0", - "eip150Transition": "0x0", - "eip160Transition": "0x0", - "eip161abcTransition": "0x0", - "eip161dTransition": "0x0" + "homesteadTransition": "0x0" } } }, @@ -22,6 +18,10 @@ "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", "networkID" : "0x1", + "eip150Transition": "0x0", + "eip160Transition": "0x0", + "eip161abcTransition": "0x0", + "eip161dTransition": "0x0", "eip98Transition": "0x7fffffffffffffff", "eip86Transition": "0x7fffffffffffffff", "eip155Transition": "0x7fffffffffffffff", diff --git a/ethcore/res/ethereum/ellaism.json b/ethcore/res/ethereum/ellaism.json index 96c2016e55..c3107bbe46 100644 --- a/ethcore/res/ethereum/ellaism.json +++ b/ethcore/res/ethereum/ellaism.json @@ -1,74 +1,74 @@ { - "name": "Ellaism", - "dataDir": "ellaism", - "engine": { - "Ethash": { - "params": { - "minimumDifficulty": "0x020000", - "difficultyBoundDivisor": "0x0800", - "durationLimit": "0x0d", - "blockReward": "0x4563918244F40000", - "homesteadTransition": "0x0", - "bombDefuseTransition": "0x0", - "eip150Transition": "0x0", - "eip160Transition": "0x0", - "ecip1017EraRounds": 10000000, - "eip161abcTransition": "0x7fffffffffffffff", - "eip161dTransition": "0x7fffffffffffffff", - "eip100bTransition": 2000000 - } - } - }, - "params": { - "gasLimitBoundDivisor": "0x0400", - "registrar": "0x3bb2bb5c6c9c9b7f4EF430b47Dc7e026310042ea", - "accountStartNonce": "0x00", - "maximumExtraDataSize": "0x20", - "minGasLimit": "0x1388", - "networkID": "0x40", - "chainID": "0x40", - "eip155Transition": "0x0", - "eip98Transition": "0x7fffffffffffff", - "eip86Transition": "0x7fffffffffffff", - "wasmActivationTransition": 2000000, - "eip140Transition": 2000000, - "eip211Transition": 2000000, - "eip214Transition": 2000000, - "eip658Transition": 2000000 - }, - "genesis": { - "seal": { - "ethereum": { - "nonce": "0x0000000000000040", - "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - }, - "difficulty": "0x40000000", - "author": "0x0000000000000000000000000000000000000000", - "timestamp": "0x00", - "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "extraData": "0x0000000000000000000000000000000000000000000000000000000000000000", - "gasLimit": "0x1388" - }, - "nodes": [ - "enode://0d88e242aa0b01ee306ca43e956174677c96ec8eba4197f4d8be6fd7d4f2e57731e95d533b88229b66eb1a44399d870e99b7a4fe6547c8c80cdf00407a986e14@94.130.237.158:30303", - "enode://4be9e419d3efb0214faf3ef1794a0c33ebbd7633ece734a0a956faa166fefc496b2692a2a485adc66af805e461ba3e12f8d3941ec207e56bb9f3d3626787a705@94.130.237.158:60606", - "enode://834246cc2a7584df29ccdcf3b5366f118a0e291264980376769e809665a02c4caf0d68c43eecf8390dbeaf861823b05583807af0a62542a1f3f717046b958a76@45.77.106.33:30303", - "enode://d8059dcb137cb52b8960ca82613eeba1d121105572decd8f1d3ea22b09070645eeab548d2a3cd2914f206e1331c7870bd2bd5a231ebac6b3d4886ec3b8e627e5@173.212.216.105:30303", - "enode://9215ad77bd081e35013cb42a8ceadff9d8e94a78fcc680dff1752a54e7484badff0904e331c4b40a68be593782e55acfd800f076d22f9d2832e8483733ade149@213.14.82.125:30303", - "enode://5dd35866da95aea15211fb1f98684f6e8c4e355e6aa3cc17585680ed53fa164477b8c52cb6ca4b24ec4d80f3d48ff9212b53feb131d825c7945a3abaaf02d24d@178.79.189.58:60606", - "enode://6c585c18024eb902ca093278af73b04863ac904caabc39ac2920c23532307c572ad92afd828a990c980d272b1f26307f2409cc97aec3ff9fe866732cae49a8c2@144.217.163.224:31337", - "enode://edd90c4cc64528802ad52fd127d80b641ff80fd43fa5292fb111c8bd2914482dffee288fd1b0d26440c6b2c669b10a53cbcd37c895ba0d6194110e100a965b2d@188.166.179.159:30303", - "enode://9d960373335c1cc38ca696dea8f2893e2a071c8f21524f21e8aae22be032acc3b67797b1d21e866f9d832943ae7d9555b8466c6ab34f473d21e547114952df37@213.32.53.183:30303" - ], - "accounts": { - "0000000000000000000000000000000000000001": { "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } }, - "0000000000000000000000000000000000000002": { "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } }, - "0000000000000000000000000000000000000003": { "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } }, - "0000000000000000000000000000000000000004": { "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } }, - "0000000000000000000000000000000000000005": { "builtin": { "name": "modexp", "activate_at": 2000000, "pricing": { "modexp": { "divisor": 20 } } } }, - "0000000000000000000000000000000000000006": { "builtin": { "name": "alt_bn128_add", "activate_at": 2000000, "pricing": { "linear": { "base": 500, "word": 0 } } } }, - "0000000000000000000000000000000000000007": { "builtin": { "name": "alt_bn128_mul", "activate_at": 2000000, "pricing": { "linear": { "base": 40000, "word": 0 } } } }, - "0000000000000000000000000000000000000008": { "builtin": { "name": "alt_bn128_pairing", "activate_at": 2000000, "pricing": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 } } } } - } + "name": "Ellaism", + "dataDir": "ellaism", + "engine": { + "Ethash": { + "params": { + "minimumDifficulty": "0x020000", + "difficultyBoundDivisor": "0x0800", + "durationLimit": "0x0d", + "blockReward": "0x4563918244F40000", + "homesteadTransition": "0x0", + "bombDefuseTransition": "0x0", + "ecip1017EraRounds": 10000000, + "eip100bTransition": 2000000 + } + } + }, + "params": { + "gasLimitBoundDivisor": "0x0400", + "registrar": "0x3bb2bb5c6c9c9b7f4EF430b47Dc7e026310042ea", + "accountStartNonce": "0x00", + "maximumExtraDataSize": "0x20", + "minGasLimit": "0x1388", + "networkID": "0x40", + "chainID": "0x40", + "eip150Transition": "0x0", + "eip160Transition": "0x0", + "eip161abcTransition": "0x7fffffffffffffff", + "eip161dTransition": "0x7fffffffffffffff", + "eip155Transition": "0x0", + "eip98Transition": "0x7fffffffffffff", + "eip86Transition": "0x7fffffffffffff", + "wasmActivationTransition": 2000000, + "eip140Transition": 2000000, + "eip211Transition": 2000000, + "eip214Transition": 2000000, + "eip658Transition": 2000000 + }, + "genesis": { + "seal": { + "ethereum": { + "nonce": "0x0000000000000040", + "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + }, + "difficulty": "0x40000000", + "author": "0x0000000000000000000000000000000000000000", + "timestamp": "0x00", + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "extraData": "0x0000000000000000000000000000000000000000000000000000000000000000", + "gasLimit": "0x1388" + }, + "nodes": [ + "enode://0d88e242aa0b01ee306ca43e956174677c96ec8eba4197f4d8be6fd7d4f2e57731e95d533b88229b66eb1a44399d870e99b7a4fe6547c8c80cdf00407a986e14@94.130.237.158:30303", + "enode://4be9e419d3efb0214faf3ef1794a0c33ebbd7633ece734a0a956faa166fefc496b2692a2a485adc66af805e461ba3e12f8d3941ec207e56bb9f3d3626787a705@94.130.237.158:60606", + "enode://834246cc2a7584df29ccdcf3b5366f118a0e291264980376769e809665a02c4caf0d68c43eecf8390dbeaf861823b05583807af0a62542a1f3f717046b958a76@45.77.106.33:30303", + "enode://d8059dcb137cb52b8960ca82613eeba1d121105572decd8f1d3ea22b09070645eeab548d2a3cd2914f206e1331c7870bd2bd5a231ebac6b3d4886ec3b8e627e5@173.212.216.105:30303", + "enode://9215ad77bd081e35013cb42a8ceadff9d8e94a78fcc680dff1752a54e7484badff0904e331c4b40a68be593782e55acfd800f076d22f9d2832e8483733ade149@213.14.82.125:30303", + "enode://5dd35866da95aea15211fb1f98684f6e8c4e355e6aa3cc17585680ed53fa164477b8c52cb6ca4b24ec4d80f3d48ff9212b53feb131d825c7945a3abaaf02d24d@178.79.189.58:60606", + "enode://6c585c18024eb902ca093278af73b04863ac904caabc39ac2920c23532307c572ad92afd828a990c980d272b1f26307f2409cc97aec3ff9fe866732cae49a8c2@144.217.163.224:31337", + "enode://edd90c4cc64528802ad52fd127d80b641ff80fd43fa5292fb111c8bd2914482dffee288fd1b0d26440c6b2c669b10a53cbcd37c895ba0d6194110e100a965b2d@188.166.179.159:30303", + "enode://9d960373335c1cc38ca696dea8f2893e2a071c8f21524f21e8aae22be032acc3b67797b1d21e866f9d832943ae7d9555b8466c6ab34f473d21e547114952df37@213.32.53.183:30303" + ], + "accounts": { + "0000000000000000000000000000000000000001": { "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } }, + "0000000000000000000000000000000000000002": { "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } }, + "0000000000000000000000000000000000000003": { "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } }, + "0000000000000000000000000000000000000004": { "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } }, + "0000000000000000000000000000000000000005": { "builtin": { "name": "modexp", "activate_at": 2000000, "pricing": { "modexp": { "divisor": 20 } } } }, + "0000000000000000000000000000000000000006": { "builtin": { "name": "alt_bn128_add", "activate_at": 2000000, "pricing": { "linear": { "base": 500, "word": 0 } } } }, + "0000000000000000000000000000000000000007": { "builtin": { "name": "alt_bn128_mul", "activate_at": 2000000, "pricing": { "linear": { "base": 40000, "word": 0 } } } }, + "0000000000000000000000000000000000000008": { "builtin": { "name": "alt_bn128_pairing", "activate_at": 2000000, "pricing": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 } } } } + } } diff --git a/ethcore/res/ethereum/expanse.json b/ethcore/res/ethereum/expanse.json index b9b734e313..2061231c60 100644 --- a/ethcore/res/ethereum/expanse.json +++ b/ethcore/res/ethereum/expanse.json @@ -13,10 +13,6 @@ "difficultyHardforkTransition": "0x59d9", "difficultyHardforkBoundDivisor": "0x0200", "bombDefuseTransition": "0x30d40", - "eip150Transition": "0x927C0", - "eip160Transition": "0x927C0", - "eip161abcTransition": "0x927C0", - "eip161dTransition": "0x927C0", "eip100bTransition": "0xC3500", "metropolisDifficultyIncrementDivisor": "0x1E", "eip649Transition": "0xC3500", @@ -37,6 +33,10 @@ "forkBlock": "0xDBBA0", "forkCanonHash": "0x8e7bed51e24f5174090408664ac476b90b5e1199a947af7442f1ac88263fc8c7", "subprotocolName": "exp", + "eip150Transition": "0x927C0", + "eip160Transition": "0x927C0", + "eip161abcTransition": "0x927C0", + "eip161dTransition": "0x927C0", "eip98Transition": "0x7fffffffffffff", "eip86Transition": "0x7fffffffffffff", "eip155Transition": "0x927C0", diff --git a/ethcore/res/ethereum/foundation.json b/ethcore/res/ethereum/foundation.json index 6658b5e522..b725c9f7c0 100644 --- a/ethcore/res/ethereum/foundation.json +++ b/ethcore/res/ethereum/foundation.json @@ -129,10 +129,6 @@ "0xbb9bc244d798123fde783fcc1c72d3bb8c189413", "0x807640a13483f8ac783c557fcdf27be11ea4ac7a" ], - "eip150Transition": "0x259518", - "eip160Transition": 2675000, - "eip161abcTransition": 2675000, - "eip161dTransition": 2675000, "eip649Reward": "0x29A2241AF62C0000", "eip100bTransition": 4370000, "eip649Transition": 4370000 @@ -148,6 +144,10 @@ "networkID" : "0x1", "forkBlock": "0x1d4c00", "forkCanonHash": "0x4985f5ca3d2afbec36529aa96f74de3cc10a2a4a6c44f2157a57d2c6059a11bb", + "eip150Transition": "0x259518", + "eip160Transition": 2675000, + "eip161abcTransition": 2675000, + "eip161dTransition": 2675000, "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 6d2ea3693d..7eac5acbd0 100644 --- a/ethcore/res/ethereum/frontier_like_test.json +++ b/ethcore/res/ethereum/frontier_like_test.json @@ -127,11 +127,7 @@ "0x7602b46df5390e432ef1c307d4f2c9ff6d65cc97", "0xbb9bc244d798123fde783fcc1c72d3bb8c189413", "0x807640a13483f8ac783c557fcdf27be11ea4ac7a" - ], - "eip150Transition": "0x7fffffffffffffff", - "eip160Transition": "0x7fffffffffffffff", - "eip161abcTransition": "0x7fffffffffffffff", - "eip161dTransition": "0x7fffffffffffffff" + ] } } }, @@ -142,6 +138,10 @@ "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", "networkID" : "0x1", + "eip150Transition": "0x7fffffffffffffff", + "eip160Transition": "0x7fffffffffffffff", + "eip161abcTransition": "0x7fffffffffffffff", + "eip161dTransition": "0x7fffffffffffffff", "eip98Transition": "0x7fffffffffffff", "eip86Transition": "0x7fffffffffffff", "eip155Transition": "0x7fffffffffffffff" diff --git a/ethcore/res/ethereum/frontier_test.json b/ethcore/res/ethereum/frontier_test.json index aae59cb071..7e52f6ecf9 100644 --- a/ethcore/res/ethereum/frontier_test.json +++ b/ethcore/res/ethereum/frontier_test.json @@ -7,11 +7,7 @@ "difficultyBoundDivisor": "0x0800", "durationLimit": "0x0d", "blockReward": "0x4563918244F40000", - "homesteadTransition": "0x7fffffffffffffff", - "eip150Transition": "0x7fffffffffffffff", - "eip160Transition": "0x7fffffffffffffff", - "eip161abcTransition": "0x7fffffffffffffff", - "eip161dTransition": "0x7fffffffffffffff" + "homesteadTransition": "0x7fffffffffffffff" } } }, @@ -22,6 +18,10 @@ "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", "networkID" : "0x1", + "eip150Transition": "0x7fffffffffffffff", + "eip160Transition": "0x7fffffffffffffff", + "eip161abcTransition": "0x7fffffffffffffff", + "eip161dTransition": "0x7fffffffffffffff", "eip98Transition": "0x7fffffffffffff", "eip86Transition": "0x7fffffffffffff", "eip155Transition": "0x7fffffffffffffff" diff --git a/ethcore/res/ethereum/homestead_test.json b/ethcore/res/ethereum/homestead_test.json index c6d49b5455..817bf5ff57 100644 --- a/ethcore/res/ethereum/homestead_test.json +++ b/ethcore/res/ethereum/homestead_test.json @@ -7,11 +7,7 @@ "difficultyBoundDivisor": "0x0800", "durationLimit": "0x0d", "blockReward": "0x4563918244F40000", - "homesteadTransition": "0x0", - "eip150Transition": "0x7fffffffffffffff", - "eip160Transition": "0x7fffffffffffffff", - "eip161abcTransition": "0x7fffffffffffffff", - "eip161dTransition": "0x7fffffffffffffff" + "homesteadTransition": "0x0" } } }, @@ -24,7 +20,11 @@ "networkID" : "0x1", "eip98Transition": "0x7fffffffffffff", "eip86Transition": "0x7fffffffffffff", - "eip155Transition": "0x7fffffffffffffff" + "eip155Transition": "0x7fffffffffffffff", + "eip150Transition": "0x7fffffffffffffff", + "eip160Transition": "0x7fffffffffffffff", + "eip161abcTransition": "0x7fffffffffffffff", + "eip161dTransition": "0x7fffffffffffffff" }, "genesis": { "seal": { diff --git a/ethcore/res/ethereum/mcip3_test.json b/ethcore/res/ethereum/mcip3_test.json index d2e5ec8b6b..391a625730 100644 --- a/ethcore/res/ethereum/mcip3_test.json +++ b/ethcore/res/ethereum/mcip3_test.json @@ -1,168 +1,168 @@ { - "name":"MCIP3 Test", - "dataDir":"mcip3test", - "engine":{ - "Ethash":{ - "params":{ - "minimumDifficulty":"0x020000", - "difficultyBoundDivisor":"0x0800", - "durationLimit":"0x0d", - "homesteadTransition":"0x118c30", - "eip100bTransition":"0x7fffffffffffff", - "eip150Transition":"0x7fffffffffffff", - "eip160Transition":"0x7fffffffffffff", - "eip161abcTransition":"0x7fffffffffffff", - "eip161dTransition":"0x7fffffffffffff", - "eip649Transition":"0x7fffffffffffff", - "blockReward":"0x1105a0185b50a80000", - "mcip3Transition":"0x00", - "mcip3MinerReward":"0xd8d726b7177a80000", - "mcip3UbiReward":"0x2b5e3af16b1880000", - "mcip3UbiContract":"0x00efdd5883ec628983e9063c7d969fe268bbf310", - "mcip3DevReward":"0xc249fdd327780000", - "mcip3DevContract":"0x00756cf8159095948496617f5fb17ed95059f536" - } - } - }, - "params":{ - "gasLimitBoundDivisor":"0x0400", - "registrar":"0x5C271c4C9A67E7D73b7b3669d47504741354f21D", - "accountStartNonce":"0x00", - "maximumExtraDataSize":"0x20", - "minGasLimit":"0x1388", - "networkID":"0x76740b", - "forkBlock":"0x5b6", - "forkCanonHash":"0xa5e88ad9e34d113e264e307bc27e8471452c8fc13780324bb3abb96fd0558343", - "eip86Transition":"0x7fffffffffffff", - "eip98Transition":"0x7fffffffffffff", - "eip140Transition":"0x7fffffffffffff", - "eip155Transition":"0x7fffffffffffff", - "eip211Transition":"0x7fffffffffffff", - "eip214Transition":"0x7fffffffffffff", - "eip658Transition":"0x7fffffffffffff", - "maxCodeSize":"0x6000", - "maxCodeSizeTransition": "0x7fffffffffffff" - }, - "genesis":{ - "seal":{ - "ethereum":{ - "nonce":"0x000000000000002a", - "mixHash":"0x00000000000000000000000000000000000000647572616c65787365646c6578" - } - }, - "difficulty":"0x3d0900", - "author":"0x0000000000000000000000000000000000000000", - "timestamp":"0x00", - "parentHash":"0x0000000000000000000000000000000000000000000000000000000000000000", - "extraData":"", - "gasLimit":"0x7a1200" - }, - "nodes":[ - "enode://a979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c@52.16.188.185:30303", - "enode://3f1d12044546b76342d59d4a05532c14b85aa669704bfe1f864fe079415aa2c02d743e03218e57a33fb94523adb54032871a6c51b2cc5514cb7c7e35b3ed0a99@13.93.211.84:30303", - "enode://78de8a0916848093c73790ead81d1928bec737d565119932b98c6b100d944b7a95e94f847f689fc723399d2e31129d182f7ef3863f2b4c820abbf3ab2722344d@191.235.84.50:30303", - "enode://158f8aab45f6d19c6cbf4a089c2670541a8da11978a2f90dbf6a502a4a3bab80d288afdbeb7ec0ef6d92de563767f3b1ea9e8e334ca711e9f8e2df5a0385e8e6@13.75.154.138:30303", - "enode://1118980bf48b0a3640bdba04e0fe78b1add18e1cd99bf22d53daac1fd9972ad650df52176e7c7d89d1114cfef2bc23a2959aa54998a46afcf7d91809f0855082@52.74.57.123:30303", - "enode://979b7fa28feeb35a4741660a16076f1943202cb72b6af70d327f053e248bab9ba81760f39d0701ef1d8f89cc1fbd2cacba0710a12cd5314d5e0c9021aa3637f9@5.1.83.226:30303", - "enode://d302f52c8789ad87ee528f1431a67f1aa646c9bec17babb4665dfb3d61de5b9119a70aa77b2147a5f28854092ba09769323c1c552a6ac6f6a34cbcf767e2d2fe@158.69.248.48:30303", - "enode://c72564bce8331ae298fb8ece113a456e3927d7e5989c2be3e445678b3600579f722410ef9bbfe339335d676af77343cb21b5b1703b7bebc32be85fce937a2220@191.252.185.71:30303", - "enode://e3ae4d25ee64791ff98bf17c37acf90933359f2505c00f65c84f6863231a32a94153cadb0a462e428f18f35ded6bd91cd91033d26576a28558c22678be9cfaee@5.63.158.137:35555" - ], - "accounts":{ - "0000000000000000000000000000000000000001":{ - "balance":"1", - "builtin":{ - "name":"ecrecover", - "pricing":{ - "linear":{ - "base":3000, - "word":0 - } - } - } - }, - "0000000000000000000000000000000000000002":{ - "balance":"1", - "builtin":{ - "name":"sha256", - "pricing":{ - "linear":{ - "base":60, - "word":12 - } - } - } - }, - "0000000000000000000000000000000000000003":{ - "balance":"1", - "builtin":{ - "name":"ripemd160", - "pricing":{ - "linear":{ - "base":600, - "word":120 - } - } - } - }, - "0000000000000000000000000000000000000004":{ - "balance":"1", - "builtin":{ - "name":"identity", - "pricing":{ - "linear":{ - "base":15, - "word":3 - } - } - } - }, - "0000000000000000000000000000000000000005":{ - "builtin":{ - "name":"modexp", - "activate_at":"0x7fffffffffffff", - "pricing":{ - "modexp":{ - "divisor":20 - } - } - } - }, - "0000000000000000000000000000000000000006":{ - "builtin":{ - "name":"alt_bn128_add", - "activate_at":"0x7fffffffffffff", - "pricing":{ - "linear":{ - "base":500, - "word":0 - } - } - } - }, - "0000000000000000000000000000000000000007":{ - "builtin":{ - "name":"alt_bn128_mul", - "activate_at":"0x7fffffffffffff", - "pricing":{ - "linear":{ - "base":40000, - "word":0 - } - } - } - }, - "0000000000000000000000000000000000000008":{ - "builtin":{ - "name":"alt_bn128_pairing", - "activate_at":"0x7fffffffffffff", - "pricing":{ - "alt_bn128_pairing":{ - "base":100000, - "pair":80000 - } - } - } - } - } + "name":"MCIP3 Test", + "dataDir":"mcip3test", + "engine":{ + "Ethash":{ + "params":{ + "minimumDifficulty":"0x020000", + "difficultyBoundDivisor":"0x0800", + "durationLimit":"0x0d", + "homesteadTransition":"0x118c30", + "eip100bTransition":"0x7fffffffffffff", + "eip649Transition":"0x7fffffffffffff", + "blockReward":"0x1105a0185b50a80000", + "mcip3Transition":"0x00", + "mcip3MinerReward":"0xd8d726b7177a80000", + "mcip3UbiReward":"0x2b5e3af16b1880000", + "mcip3UbiContract":"0x00efdd5883ec628983e9063c7d969fe268bbf310", + "mcip3DevReward":"0xc249fdd327780000", + "mcip3DevContract":"0x00756cf8159095948496617f5fb17ed95059f536" + } + } + }, + "params":{ + "gasLimitBoundDivisor":"0x0400", + "registrar":"0x5C271c4C9A67E7D73b7b3669d47504741354f21D", + "accountStartNonce":"0x00", + "maximumExtraDataSize":"0x20", + "minGasLimit":"0x1388", + "networkID":"0x76740b", + "forkBlock":"0x5b6", + "forkCanonHash":"0xa5e88ad9e34d113e264e307bc27e8471452c8fc13780324bb3abb96fd0558343", + "eip150Transition":"0x7fffffffffffff", + "eip160Transition":"0x7fffffffffffff", + "eip161abcTransition":"0x7fffffffffffff", + "eip161dTransition":"0x7fffffffffffff", + "eip86Transition":"0x7fffffffffffff", + "eip98Transition":"0x7fffffffffffff", + "eip140Transition":"0x7fffffffffffff", + "eip155Transition":"0x7fffffffffffff", + "eip211Transition":"0x7fffffffffffff", + "eip214Transition":"0x7fffffffffffff", + "eip658Transition":"0x7fffffffffffff", + "maxCodeSize":"0x6000", + "maxCodeSizeTransition": "0x7fffffffffffff" + }, + "genesis":{ + "seal":{ + "ethereum":{ + "nonce":"0x000000000000002a", + "mixHash":"0x00000000000000000000000000000000000000647572616c65787365646c6578" + } + }, + "difficulty":"0x3d0900", + "author":"0x0000000000000000000000000000000000000000", + "timestamp":"0x00", + "parentHash":"0x0000000000000000000000000000000000000000000000000000000000000000", + "extraData":"", + "gasLimit":"0x7a1200" + }, + "nodes":[ + "enode://a979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c@52.16.188.185:30303", + "enode://3f1d12044546b76342d59d4a05532c14b85aa669704bfe1f864fe079415aa2c02d743e03218e57a33fb94523adb54032871a6c51b2cc5514cb7c7e35b3ed0a99@13.93.211.84:30303", + "enode://78de8a0916848093c73790ead81d1928bec737d565119932b98c6b100d944b7a95e94f847f689fc723399d2e31129d182f7ef3863f2b4c820abbf3ab2722344d@191.235.84.50:30303", + "enode://158f8aab45f6d19c6cbf4a089c2670541a8da11978a2f90dbf6a502a4a3bab80d288afdbeb7ec0ef6d92de563767f3b1ea9e8e334ca711e9f8e2df5a0385e8e6@13.75.154.138:30303", + "enode://1118980bf48b0a3640bdba04e0fe78b1add18e1cd99bf22d53daac1fd9972ad650df52176e7c7d89d1114cfef2bc23a2959aa54998a46afcf7d91809f0855082@52.74.57.123:30303", + "enode://979b7fa28feeb35a4741660a16076f1943202cb72b6af70d327f053e248bab9ba81760f39d0701ef1d8f89cc1fbd2cacba0710a12cd5314d5e0c9021aa3637f9@5.1.83.226:30303", + "enode://d302f52c8789ad87ee528f1431a67f1aa646c9bec17babb4665dfb3d61de5b9119a70aa77b2147a5f28854092ba09769323c1c552a6ac6f6a34cbcf767e2d2fe@158.69.248.48:30303", + "enode://c72564bce8331ae298fb8ece113a456e3927d7e5989c2be3e445678b3600579f722410ef9bbfe339335d676af77343cb21b5b1703b7bebc32be85fce937a2220@191.252.185.71:30303", + "enode://e3ae4d25ee64791ff98bf17c37acf90933359f2505c00f65c84f6863231a32a94153cadb0a462e428f18f35ded6bd91cd91033d26576a28558c22678be9cfaee@5.63.158.137:35555" + ], + "accounts":{ + "0000000000000000000000000000000000000001":{ + "balance":"1", + "builtin":{ + "name":"ecrecover", + "pricing":{ + "linear":{ + "base":3000, + "word":0 + } + } + } + }, + "0000000000000000000000000000000000000002":{ + "balance":"1", + "builtin":{ + "name":"sha256", + "pricing":{ + "linear":{ + "base":60, + "word":12 + } + } + } + }, + "0000000000000000000000000000000000000003":{ + "balance":"1", + "builtin":{ + "name":"ripemd160", + "pricing":{ + "linear":{ + "base":600, + "word":120 + } + } + } + }, + "0000000000000000000000000000000000000004":{ + "balance":"1", + "builtin":{ + "name":"identity", + "pricing":{ + "linear":{ + "base":15, + "word":3 + } + } + } + }, + "0000000000000000000000000000000000000005":{ + "builtin":{ + "name":"modexp", + "activate_at":"0x7fffffffffffff", + "pricing":{ + "modexp":{ + "divisor":20 + } + } + } + }, + "0000000000000000000000000000000000000006":{ + "builtin":{ + "name":"alt_bn128_add", + "activate_at":"0x7fffffffffffff", + "pricing":{ + "linear":{ + "base":500, + "word":0 + } + } + } + }, + "0000000000000000000000000000000000000007":{ + "builtin":{ + "name":"alt_bn128_mul", + "activate_at":"0x7fffffffffffff", + "pricing":{ + "linear":{ + "base":40000, + "word":0 + } + } + } + }, + "0000000000000000000000000000000000000008":{ + "builtin":{ + "name":"alt_bn128_pairing", + "activate_at":"0x7fffffffffffff", + "pricing":{ + "alt_bn128_pairing":{ + "base":100000, + "pair":80000 + } + } + } + } + } } diff --git a/ethcore/res/ethereum/mcip6_byz.json b/ethcore/res/ethereum/mcip6_byz.json index 8028e6b1bb..a12df7c711 100644 --- a/ethcore/res/ethereum/mcip6_byz.json +++ b/ethcore/res/ethereum/mcip6_byz.json @@ -1,161 +1,161 @@ { - "name":"Musicoin Byzantium Test", - "dataDir":"mcip6test", - "engine":{ - "Ethash":{ - "params":{ - "minimumDifficulty":"0x020000", - "difficultyBoundDivisor":"0x0800", - "durationLimit":"0x0d", - "homesteadTransition":"0x17", - "eip100bTransition":"0x2a", - "eip150Transition":"0x2a", - "eip160Transition":"0x7fffffffffffff", - "eip161abcTransition":"0x7fffffffffffff", - "eip161dTransition":"0x7fffffffffffff", - "eip649Transition":"0x2a", - "blockReward":"0x1105a0185b50a80000", - "mcip3Transition":"0x17", - "mcip3MinerReward":"0xd8d726b7177a80000", - "mcip3UbiReward":"0x2b5e3af16b1880000", - "mcip3UbiContract":"0x00efdd5883ec628983e9063c7d969fe268bbf310", - "mcip3DevReward":"0xc249fdd327780000", - "mcip3DevContract":"0x00756cf8159095948496617f5fb17ed95059f536" - } - } - }, - "params":{ - "gasLimitBoundDivisor":"0x0400", - "registrar":"0x5C271c4C9A67E7D73b7b3669d47504741354f21D", - "accountStartNonce":"0x00", - "maximumExtraDataSize":"0x20", - "minGasLimit":"0x1388", - "networkID":"0x76740c", - "forkBlock":"0x2b", - "forkCanonHash":"0x23c3171e864a5d513a3ef85e4cf86dac4cc36b89e5b8e63bf0ebcca68b9e43c9", - "eip86Transition":"0x7fffffffffffff", - "eip98Transition":"0x7fffffffffffff", - "eip140Transition":"0x2a", - "eip155Transition":"0x2a", - "eip211Transition":"0x2a", - "eip214Transition":"0x2a", - "eip658Transition":"0x2a", - "maxCodeSize":"0x6000", - "maxCodeSizeTransition": "0x7fffffffffffff" - }, - "genesis":{ - "seal":{ - "ethereum":{ - "nonce":"0x000000000000002a", - "mixHash":"0x00000000000000000000000000000000000000647572616c65787365646c6578" - } - }, - "difficulty":"0x3d0900", - "author":"0x0000000000000000000000000000000000000000", - "timestamp":"0x00", - "parentHash":"0x0000000000000000000000000000000000000000000000000000000000000000", - "extraData":"", - "gasLimit":"0x7a1200" - }, - "nodes":[ - "enode://5ddc110733f6d34101973cdef3f9b43484159acf6f816d3b1ee92bc3c98ea453e857bb1207edf0ec0242008ab3a0f9f05eeaee99d47bd414c08a5bdf4847de13@176.9.3.148:30303", - "enode://38f074f4db8e64dfbaf87984bf290eef67772a901a7113d1b62f36216be152b8450c393d6fc562a5e38f04f99bc8f439a99010a230b1d92dc1df43bf0bd00615@176.9.3.148:30403" - ], - "accounts":{ - "0000000000000000000000000000000000000001":{ - "balance":"1", - "builtin":{ - "name":"ecrecover", - "pricing":{ - "linear":{ - "base":3000, - "word":0 - } - } - } - }, - "0000000000000000000000000000000000000002":{ - "balance":"1", - "builtin":{ - "name":"sha256", - "pricing":{ - "linear":{ - "base":60, - "word":12 - } - } - } - }, - "0000000000000000000000000000000000000003":{ - "balance":"1", - "builtin":{ - "name":"ripemd160", - "pricing":{ - "linear":{ - "base":600, - "word":120 - } - } - } - }, - "0000000000000000000000000000000000000004":{ - "balance":"1", - "builtin":{ - "name":"identity", - "pricing":{ - "linear":{ - "base":15, - "word":3 - } - } - } - }, - "0000000000000000000000000000000000000005":{ - "builtin":{ - "name":"modexp", - "activate_at":"0x2a", - "pricing":{ - "modexp":{ - "divisor":20 - } - } - } - }, - "0000000000000000000000000000000000000006":{ - "builtin":{ - "name":"alt_bn128_add", - "activate_at":"0x2a", - "pricing":{ - "linear":{ - "base":500, - "word":0 - } - } - } - }, - "0000000000000000000000000000000000000007":{ - "builtin":{ - "name":"alt_bn128_mul", - "activate_at":"0x2a", - "pricing":{ - "linear":{ - "base":40000, - "word":0 - } - } - } - }, - "0000000000000000000000000000000000000008":{ - "builtin":{ - "name":"alt_bn128_pairing", - "activate_at":"0x2a", - "pricing":{ - "alt_bn128_pairing":{ - "base":100000, - "pair":80000 - } - } - } - } - } + "name":"Musicoin Byzantium Test", + "dataDir":"mcip6test", + "engine":{ + "Ethash":{ + "params":{ + "minimumDifficulty":"0x020000", + "difficultyBoundDivisor":"0x0800", + "durationLimit":"0x0d", + "homesteadTransition":"0x17", + "eip100bTransition":"0x2a", + "eip649Transition":"0x2a", + "blockReward":"0x1105a0185b50a80000", + "mcip3Transition":"0x17", + "mcip3MinerReward":"0xd8d726b7177a80000", + "mcip3UbiReward":"0x2b5e3af16b1880000", + "mcip3UbiContract":"0x00efdd5883ec628983e9063c7d969fe268bbf310", + "mcip3DevReward":"0xc249fdd327780000", + "mcip3DevContract":"0x00756cf8159095948496617f5fb17ed95059f536" + } + } + }, + "params":{ + "gasLimitBoundDivisor":"0x0400", + "registrar":"0x5C271c4C9A67E7D73b7b3669d47504741354f21D", + "accountStartNonce":"0x00", + "maximumExtraDataSize":"0x20", + "minGasLimit":"0x1388", + "networkID":"0x76740c", + "forkBlock":"0x2b", + "forkCanonHash":"0x23c3171e864a5d513a3ef85e4cf86dac4cc36b89e5b8e63bf0ebcca68b9e43c9", + "eip150Transition":"0x2a", + "eip160Transition":"0x7fffffffffffff", + "eip161abcTransition":"0x7fffffffffffff", + "eip161dTransition":"0x7fffffffffffff", + "eip86Transition":"0x7fffffffffffff", + "eip98Transition":"0x7fffffffffffff", + "eip140Transition":"0x2a", + "eip155Transition":"0x2a", + "eip211Transition":"0x2a", + "eip214Transition":"0x2a", + "eip658Transition":"0x2a", + "maxCodeSize":"0x6000", + "maxCodeSizeTransition": "0x7fffffffffffff" + }, + "genesis":{ + "seal":{ + "ethereum":{ + "nonce":"0x000000000000002a", + "mixHash":"0x00000000000000000000000000000000000000647572616c65787365646c6578" + } + }, + "difficulty":"0x3d0900", + "author":"0x0000000000000000000000000000000000000000", + "timestamp":"0x00", + "parentHash":"0x0000000000000000000000000000000000000000000000000000000000000000", + "extraData":"", + "gasLimit":"0x7a1200" + }, + "nodes":[ + "enode://5ddc110733f6d34101973cdef3f9b43484159acf6f816d3b1ee92bc3c98ea453e857bb1207edf0ec0242008ab3a0f9f05eeaee99d47bd414c08a5bdf4847de13@176.9.3.148:30303", + "enode://38f074f4db8e64dfbaf87984bf290eef67772a901a7113d1b62f36216be152b8450c393d6fc562a5e38f04f99bc8f439a99010a230b1d92dc1df43bf0bd00615@176.9.3.148:30403" + ], + "accounts":{ + "0000000000000000000000000000000000000001":{ + "balance":"1", + "builtin":{ + "name":"ecrecover", + "pricing":{ + "linear":{ + "base":3000, + "word":0 + } + } + } + }, + "0000000000000000000000000000000000000002":{ + "balance":"1", + "builtin":{ + "name":"sha256", + "pricing":{ + "linear":{ + "base":60, + "word":12 + } + } + } + }, + "0000000000000000000000000000000000000003":{ + "balance":"1", + "builtin":{ + "name":"ripemd160", + "pricing":{ + "linear":{ + "base":600, + "word":120 + } + } + } + }, + "0000000000000000000000000000000000000004":{ + "balance":"1", + "builtin":{ + "name":"identity", + "pricing":{ + "linear":{ + "base":15, + "word":3 + } + } + } + }, + "0000000000000000000000000000000000000005":{ + "builtin":{ + "name":"modexp", + "activate_at":"0x2a", + "pricing":{ + "modexp":{ + "divisor":20 + } + } + } + }, + "0000000000000000000000000000000000000006":{ + "builtin":{ + "name":"alt_bn128_add", + "activate_at":"0x2a", + "pricing":{ + "linear":{ + "base":500, + "word":0 + } + } + } + }, + "0000000000000000000000000000000000000007":{ + "builtin":{ + "name":"alt_bn128_mul", + "activate_at":"0x2a", + "pricing":{ + "linear":{ + "base":40000, + "word":0 + } + } + } + }, + "0000000000000000000000000000000000000008":{ + "builtin":{ + "name":"alt_bn128_pairing", + "activate_at":"0x2a", + "pricing":{ + "alt_bn128_pairing":{ + "base":100000, + "pair":80000 + } + } + } + } + } } diff --git a/ethcore/res/ethereum/morden.json b/ethcore/res/ethereum/morden.json index bca9919903..b61799c0c9 100644 --- a/ethcore/res/ethereum/morden.json +++ b/ethcore/res/ethereum/morden.json @@ -9,13 +9,9 @@ "durationLimit": "0x0d", "blockReward": "0x4563918244F40000", "homesteadTransition": 494000, - "eip150Transition": 1783000, - "eip160Transition": 1915000, "ecip1010PauseTransition": 1915000, "ecip1010ContinueTransition": 3415000, "ecip1017EraRounds": 2000000, - "eip161abcTransition": "0x7fffffffffffffff", - "eip161dTransition": "0x7fffffffffffffff", "bombDefuseTransition": 2300000 } } @@ -30,6 +26,10 @@ "chainID": "0x3e", "forkBlock": "0x1b34d8", "forkCanonHash": "0xf376243aeff1f256d970714c3de9fd78fa4e63cf63e32a51fe1169e375d98145", + "eip150Transition": 1783000, + "eip160Transition": 1915000, + "eip161abcTransition": "0x7fffffffffffffff", + "eip161dTransition": "0x7fffffffffffffff", "eip155Transition": 1915000, "eip98Transition": "0x7fffffffffffff", "eip86Transition": "0x7fffffffffffff" diff --git a/ethcore/res/ethereum/musicoin.json b/ethcore/res/ethereum/musicoin.json index 6d5f6835bd..724f11478b 100644 --- a/ethcore/res/ethereum/musicoin.json +++ b/ethcore/res/ethereum/musicoin.json @@ -1,164 +1,164 @@ { - "name":"Musicoin", - "dataDir":"musicoin", - "engine":{ - "Ethash":{ - "params":{ - "minimumDifficulty":"0x020000", - "difficultyBoundDivisor":"0x0800", - "durationLimit":"0x0d", - "homesteadTransition":"0x118c30", - "eip100bTransition":"0x21e88e", - "eip150Transition":"0x21e88e", - "eip160Transition":"0x21e88e", - "eip161abcTransition":"0x21e88e", - "eip161dTransition":"0x21e88e", - "eip649Transition":"0x21e88e", - "blockReward":"0x1105a0185b50a80000", - "mcip3Transition":"0x124f81", - "mcip3MinerReward":"0xd8d726b7177a80000", - "mcip3UbiReward":"0x2b5e3af16b1880000", - "mcip3UbiContract":"0x00efdd5883ec628983e9063c7d969fe268bbf310", - "mcip3DevReward":"0xc249fdd327780000", - "mcip3DevContract":"0x00756cf8159095948496617f5fb17ed95059f536" - } - } - }, - "params":{ - "gasLimitBoundDivisor":"0x0400", - "registrar":"0x5C271c4C9A67E7D73b7b3669d47504741354f21D", - "accountStartNonce":"0x00", - "maximumExtraDataSize":"0x20", - "minGasLimit":"0x1388", - "networkID":"0x76740f", - "forkBlock":"0x1d8015", - "forkCanonHash":"0x380602acf82b629a0be6b5adb2b4a801e960a07dc8261bf196d21befdbb8f2f9", - "eip86Transition":"0x7fffffffffffff", - "eip98Transition":"0x7fffffffffffff", - "eip140Transition":"0x21e88e", - "eip155Transition":"0x21e88e", - "eip211Transition":"0x21e88e", - "eip214Transition":"0x21e88e", - "eip658Transition":"0x21e88e", - "maxCodeSize":"0x6000" - }, - "genesis":{ - "seal":{ - "ethereum":{ - "nonce":"0x000000000000002a", - "mixHash":"0x00000000000000000000000000000000000000647572616c65787365646c6578" - } - }, - "difficulty":"0x3d0900", - "author":"0x0000000000000000000000000000000000000000", - "timestamp":"0x00", - "parentHash":"0x0000000000000000000000000000000000000000000000000000000000000000", - "extraData":"", - "gasLimit":"0x7a1200" - }, - "nodes":[ - "enode://09fcd36d553044c8b499b9b9e13a228ffd99572c513f77073d41f009717c464cd4399c0e665d6aff1590324254ee4e698b2b2533b1998dd04d896b9d6aff7895@35.185.67.35:30303", - "enode://89e51a34770a0badf8ea18c4c4d2c361cde707abd60031d99b1ab3010363e1898230a516ddb37d974af8d8db1b322779d7fe0caae0617bed4924d1b4968cf92b@35.231.48.142:30303", - "enode://b58c0c71f08864c0cf7fa9dea2c4cbefae5ae7a36cc30d286603b24982d25f3ccc056b589119324c51768fc2054b8c529ecf682e06e1e9980170b93ff194ed7a@132.148.132.9:30303", - "enode://d302f52c8789ad87ee528f1431a67f1aa646c9bec17babb4665dfb3d61de5b9119a70aa77b2147a5f28854092ba09769323c1c552a6ac6f6a34cbcf767e2d2fe@158.69.248.48:30303", - "enode://c72564bce8331ae298fb8ece113a456e3927d7e5989c2be3e445678b3600579f722410ef9bbfe339335d676af77343cb21b5b1703b7bebc32be85fce937a2220@191.252.185.71:30303", - "enode://e3ae4d25ee64791ff98bf17c37acf90933359f2505c00f65c84f6863231a32a94153cadb0a462e428f18f35ded6bd91cd91033d26576a28558c22678be9cfaee@5.63.158.137:35555" - ], - "accounts":{ - "0000000000000000000000000000000000000001":{ - "balance":"1", - "builtin":{ - "name":"ecrecover", - "pricing":{ - "linear":{ - "base":3000, - "word":0 - } - } - } - }, - "0000000000000000000000000000000000000002":{ - "balance":"1", - "builtin":{ - "name":"sha256", - "pricing":{ - "linear":{ - "base":60, - "word":12 - } - } - } - }, - "0000000000000000000000000000000000000003":{ - "balance":"1", - "builtin":{ - "name":"ripemd160", - "pricing":{ - "linear":{ - "base":600, - "word":120 - } - } - } - }, - "0000000000000000000000000000000000000004":{ - "balance":"1", - "builtin":{ - "name":"identity", - "pricing":{ - "linear":{ - "base":15, - "word":3 - } - } - } - }, - "0000000000000000000000000000000000000005":{ - "builtin":{ - "name":"modexp", - "activate_at":"0x21e88e", - "pricing":{ - "modexp":{ - "divisor":20 - } - } - } - }, - "0000000000000000000000000000000000000006":{ - "builtin":{ - "name":"alt_bn128_add", - "activate_at":"0x21e88e", - "pricing":{ - "linear":{ - "base":500, - "word":0 - } - } - } - }, - "0000000000000000000000000000000000000007":{ - "builtin":{ - "name":"alt_bn128_mul", - "activate_at":"0x21e88e", - "pricing":{ - "linear":{ - "base":40000, - "word":0 - } - } - } - }, - "0000000000000000000000000000000000000008":{ - "builtin":{ - "name":"alt_bn128_pairing", - "activate_at":"0x21e88e", - "pricing":{ - "alt_bn128_pairing":{ - "base":100000, - "pair":80000 - } - } - } - } - } + "name":"Musicoin", + "dataDir":"musicoin", + "engine":{ + "Ethash":{ + "params":{ + "minimumDifficulty":"0x020000", + "difficultyBoundDivisor":"0x0800", + "durationLimit":"0x0d", + "homesteadTransition":"0x118c30", + "eip100bTransition":"0x21e88e", + "eip649Transition":"0x21e88e", + "blockReward":"0x1105a0185b50a80000", + "mcip3Transition":"0x124f81", + "mcip3MinerReward":"0xd8d726b7177a80000", + "mcip3UbiReward":"0x2b5e3af16b1880000", + "mcip3UbiContract":"0x00efdd5883ec628983e9063c7d969fe268bbf310", + "mcip3DevReward":"0xc249fdd327780000", + "mcip3DevContract":"0x00756cf8159095948496617f5fb17ed95059f536" + } + } + }, + "params":{ + "gasLimitBoundDivisor":"0x0400", + "registrar":"0x5C271c4C9A67E7D73b7b3669d47504741354f21D", + "accountStartNonce":"0x00", + "maximumExtraDataSize":"0x20", + "minGasLimit":"0x1388", + "networkID":"0x76740f", + "forkBlock":"0x1d8015", + "forkCanonHash":"0x380602acf82b629a0be6b5adb2b4a801e960a07dc8261bf196d21befdbb8f2f9", + "eip150Transition":"0x21e88e", + "eip160Transition":"0x21e88e", + "eip161abcTransition":"0x21e88e", + "eip161dTransition":"0x21e88e", + "eip86Transition":"0x7fffffffffffff", + "eip98Transition":"0x7fffffffffffff", + "eip140Transition":"0x21e88e", + "eip155Transition":"0x21e88e", + "eip211Transition":"0x21e88e", + "eip214Transition":"0x21e88e", + "eip658Transition":"0x21e88e", + "maxCodeSize":"0x6000" + }, + "genesis":{ + "seal":{ + "ethereum":{ + "nonce":"0x000000000000002a", + "mixHash":"0x00000000000000000000000000000000000000647572616c65787365646c6578" + } + }, + "difficulty":"0x3d0900", + "author":"0x0000000000000000000000000000000000000000", + "timestamp":"0x00", + "parentHash":"0x0000000000000000000000000000000000000000000000000000000000000000", + "extraData":"", + "gasLimit":"0x7a1200" + }, + "nodes":[ + "enode://09fcd36d553044c8b499b9b9e13a228ffd99572c513f77073d41f009717c464cd4399c0e665d6aff1590324254ee4e698b2b2533b1998dd04d896b9d6aff7895@35.185.67.35:30303", + "enode://89e51a34770a0badf8ea18c4c4d2c361cde707abd60031d99b1ab3010363e1898230a516ddb37d974af8d8db1b322779d7fe0caae0617bed4924d1b4968cf92b@35.231.48.142:30303", + "enode://b58c0c71f08864c0cf7fa9dea2c4cbefae5ae7a36cc30d286603b24982d25f3ccc056b589119324c51768fc2054b8c529ecf682e06e1e9980170b93ff194ed7a@132.148.132.9:30303", + "enode://d302f52c8789ad87ee528f1431a67f1aa646c9bec17babb4665dfb3d61de5b9119a70aa77b2147a5f28854092ba09769323c1c552a6ac6f6a34cbcf767e2d2fe@158.69.248.48:30303", + "enode://c72564bce8331ae298fb8ece113a456e3927d7e5989c2be3e445678b3600579f722410ef9bbfe339335d676af77343cb21b5b1703b7bebc32be85fce937a2220@191.252.185.71:30303", + "enode://e3ae4d25ee64791ff98bf17c37acf90933359f2505c00f65c84f6863231a32a94153cadb0a462e428f18f35ded6bd91cd91033d26576a28558c22678be9cfaee@5.63.158.137:35555" + ], + "accounts":{ + "0000000000000000000000000000000000000001":{ + "balance":"1", + "builtin":{ + "name":"ecrecover", + "pricing":{ + "linear":{ + "base":3000, + "word":0 + } + } + } + }, + "0000000000000000000000000000000000000002":{ + "balance":"1", + "builtin":{ + "name":"sha256", + "pricing":{ + "linear":{ + "base":60, + "word":12 + } + } + } + }, + "0000000000000000000000000000000000000003":{ + "balance":"1", + "builtin":{ + "name":"ripemd160", + "pricing":{ + "linear":{ + "base":600, + "word":120 + } + } + } + }, + "0000000000000000000000000000000000000004":{ + "balance":"1", + "builtin":{ + "name":"identity", + "pricing":{ + "linear":{ + "base":15, + "word":3 + } + } + } + }, + "0000000000000000000000000000000000000005":{ + "builtin":{ + "name":"modexp", + "activate_at":"0x21e88e", + "pricing":{ + "modexp":{ + "divisor":20 + } + } + } + }, + "0000000000000000000000000000000000000006":{ + "builtin":{ + "name":"alt_bn128_add", + "activate_at":"0x21e88e", + "pricing":{ + "linear":{ + "base":500, + "word":0 + } + } + } + }, + "0000000000000000000000000000000000000007":{ + "builtin":{ + "name":"alt_bn128_mul", + "activate_at":"0x21e88e", + "pricing":{ + "linear":{ + "base":40000, + "word":0 + } + } + } + }, + "0000000000000000000000000000000000000008":{ + "builtin":{ + "name":"alt_bn128_pairing", + "activate_at":"0x21e88e", + "pricing":{ + "alt_bn128_pairing":{ + "base":100000, + "pair":80000 + } + } + } + } + } } diff --git a/ethcore/res/ethereum/olympic.json b/ethcore/res/ethereum/olympic.json index 6854f2b78a..3ae9baddf2 100644 --- a/ethcore/res/ethereum/olympic.json +++ b/ethcore/res/ethereum/olympic.json @@ -7,11 +7,7 @@ "difficultyBoundDivisor": "0x0800", "durationLimit": "0x08", "blockReward": "0x14D1120D7B160000", - "homesteadTransition": "0x7fffffffffffffff", - "eip150Transition": "0x7fffffffffffffff", - "eip160Transition": "0x7fffffffffffffff", - "eip161abcTransition": "0x7fffffffffffffff", - "eip161dTransition": "0x7fffffffffffffff" + "homesteadTransition": "0x7fffffffffffffff" } } }, @@ -22,6 +18,10 @@ "maximumExtraDataSize": "0x0400", "minGasLimit": "125000", "networkID" : "0x0", + "eip150Transition": "0x7fffffffffffffff", + "eip160Transition": "0x7fffffffffffffff", + "eip161abcTransition": "0x7fffffffffffffff", + "eip161dTransition": "0x7fffffffffffffff", "eip98Transition": "0x7fffffffffffff", "eip86Transition": "0x7fffffffffffff", "eip155Transition": "0x7fffffffffffffff" diff --git a/ethcore/res/ethereum/ropsten.json b/ethcore/res/ethereum/ropsten.json index 065e336443..bddf5c0084 100644 --- a/ethcore/res/ethereum/ropsten.json +++ b/ethcore/res/ethereum/ropsten.json @@ -9,10 +9,6 @@ "durationLimit": "0x0d", "blockReward": "0x4563918244F40000", "homesteadTransition": 0, - "eip150Transition": 0, - "eip160Transition": 10, - "eip161abcTransition": 10, - "eip161dTransition": 10, "eip649Reward": "0x29A2241AF62C0000", "eip100bTransition": 1700000, "eip649Transition": 1700000 @@ -30,6 +26,10 @@ "forkCanonHash": "0x8033403e9fe5811a7b6d6b469905915de1c59207ce2172cbcf5d6ff14fa6a2eb", "maxCodeSize": 24576, "maxCodeSizeTransition": 10, + "eip150Transition": 0, + "eip160Transition": 10, + "eip161abcTransition": 10, + "eip161dTransition": 10, "eip155Transition": 10, "eip98Transition": "0x7fffffffffffff", "eip86Transition": "0x7fffffffffffff", diff --git a/ethcore/res/ethereum/social.json b/ethcore/res/ethereum/social.json index 87d1f2e4b1..52b442d088 100644 --- a/ethcore/res/ethereum/social.json +++ b/ethcore/res/ethereum/social.json @@ -1,8857 +1,8857 @@ { - "name": "Ethereum Social", - "dataDir": "social", - "engine": { - "Ethash": { - "params": { - "minimumDifficulty": "0x020000", - "difficultyBoundDivisor": "0x0800", - "durationLimit": "0x0d", - "blockReward": "0x2B5E3AF16B1880000", - "homesteadTransition": "0x0", - "bombDefuseTransition": "0x0", - "eip150Transition": "0x0", - "eip160Transition": "0x0", - "ecip1017EraRounds": 5000000, - "eip161abcTransition": "0x7fffffffffffffff", - "eip161dTransition": "0x7fffffffffffffff" - } - } - }, - "params": { - "gasLimitBoundDivisor": "0x0400", - "registrar": "0x0000000000000000000000000000000000000000", - "accountStartNonce": "0x00", - "maximumExtraDataSize": "0x20", - "minGasLimit": "0x1388", - "networkID": "0x1C", - "chainID": "0x1C", - "eip155Transition": "0x0", - "eip98Transition": "0x7fffffffffffff", - "eip86Transition": "0x7fffffffffffff" - }, - "genesis": { - "seal": { - "ethereum": { - "nonce": "0x0000000000000042", - "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - }, - "difficulty": "0x0400000000", - "author": "0x0000000000000000000000000000000000000000", - "timestamp": "0x00", - "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "extraData": "0x3230313820457468657265756d20536f6369616c2050726f6a656374", - "gasLimit": "0x1388" - }, - "nodes": [ - "enode://54d0824a268747046b6cabc7ee3afda48edba319f0d175e9e505aa9d425a1872b8b6f9ebf8f3b0a10dc7611a4c44ddec0fc691e5a5cde23e06fc4e4b3ff9dbef@13.125.185.147:30303", - "enode://7e150d47637177f675e20d663fc2500987f2149332caf23da522d92363be8a7880ef9150a6183e9031288a441e0457239474967a111eafce17e19a4288076ea9@18.219.40.235:30303", - "enode://6244c9d9cd288015d7ff165e90f3bb5649e34467e095a47c6d3c56e8fb8c849b3b4db683ff3c7ae8a654bbdc07ef12ee2fd7d72831ac213723281c1b0cc90599@13.250.220.98:30303", - "enode://e39f162b9f4b6ed6f098550f7867c2fb068fc66f362b3db0f45124c43ea18508f5ceef4e0e4de53d301e14a6f1683226aeb931d7401b4e83b5a583153ffdd7fd@52.57.98.157:30303", - "enode://54b4a117d66dc3aa93358dec1b31d4f38e72e4381b3e28a65ac6f1aaac3b304ebbe41d32cc864fa69a9a6815c34cf9b8965690dc174a5f72af14547b601b7924@222.239.255.71:30303", - "enode://851f14c5cc86cbc0a81acfcbe5dd99ad5c823435357219df736932c5f89ad4318f6973a553857a32d97a71793f5a35c062d46320be282aa0a80b06b9c6b624e4@13.125.232.71:30303" - ], - "accounts": { - "0000000000000000000000000000000000000001": { "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } }, - "0000000000000000000000000000000000000002": { "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } }, - "0000000000000000000000000000000000000003": { "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } }, - "0000000000000000000000000000000000000004": { "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } }, - "ceed1c8254abaf069669fc6045e90482543d1f2e": { - "balance": "38000000000000000000000000" - }, - "6f22d7f8c38e0135e36be87e77fc8d4ae4b3d965": { - "balance": "38000000000000000000000000" - }, - "d016e982b7886302428d7c741392c658337513d2": { - "balance": "38000000000000000000000000" - }, - "defa96db5c8a41772bc56f68f95e307ff71a2c60": { - "balance": "38000000000000000000000000" - }, - "951ffd4253ffcf31b2895dd3f7f2a8a9bb2933e5": { - "balance": "38000000000000000000000000" - }, - "b7071dba21cfbe1b70abd7ddfd2f0f83d5d19a61": { - "balance": "38000000000000000000000000" - }, - "6ca420cd8d5407c61a9b14adcb38bee0f26e2848": { - "balance": "38000000000000000000000000" - }, - "b50d185b6cd04499a38afc0fcfcb59eaa74d0956": { - "balance": "38000000000000000000000000" - }, - "7ba8c49a444c117f2d2a50650b3f700d4ee659fe": { - "balance": "38000000000000000000000000" - }, - "83f9959ecc532dce071fcd0c62dc23cd571b689b": { - "balance": "38000000000000000000000000" - }, - "001327afce7ebb623a7d0f17b2ffc358fb863b5a": { - "balance": "9844198127334000000000" - }, - "0015ac7f8bb2a2c7d954fc2dbd4e20c0db5942a5": { - "balance": "1000000000000000000000000" - }, - "0021e69c041be2d28744b69361105ff51295da59": { - "balance": "1379639894000000000" - }, - "002cfd27bbb8164681b8762e71b2891beb127fdd": { - "balance": "25105286685000000000" - }, - "0033cf217bc765ccfc338869451588ce448fde65": { - "balance": "23425485280069000000000" - }, - "0048f1d1735979cd8ac9c0886088336b2d4a43a6": { - "balance": "10000000000000000000" - }, - "006a79cc154917cf204d8097728f290e29716d43": { - "balance": "20000000000000000000000" - }, - "007c8db36e4f649b14516dd78202670b671ba753": { - "balance": "1000000000000000000" - }, - "007d131b58388f251075a3c61020ce301106c5cf": { - "balance": "381079535880476000000000" - }, - "008e8fbffc2fdbefaa7e3be4f4a9160db826d05f": { - "balance": "10000000000000000000000" - }, - "0126d86b9814b0e78c4e01a3916bee6a7778145b": { - "balance": "10000000000000000000000" - }, - "012cb961297c837630251a173b7861e77724856d": { - "balance": "494562376059000000000" - }, - "0145886dfab5ef4f2def50a56b4a074cf5b18acf": { - "balance": "680585022951000000000" - }, - "0167918bab62aa2118cfa4d3eb80da0e71c71d8b": { - "balance": "122395119468000000000" - }, - "0182f7286ae9d4d6bc514d5175d14685d520bde7": { - "balance": "10000000000000000000000" - }, - "0184e9c8fe99d85100fe28a0e8877b14768b372a": { - "balance": "193295614762000000000" - }, - "019eff7dce7f31c2d4f7318da71d212cbf89d36e": { - "balance": "64004138198000000000" - }, - "01f3351ea66c352346244dbb79189066bed62fc5": { - "balance": "937056266523000000000" - }, - "0202ddd7f4f32bc575f7df24612f8aa9f9a7ae42": { - "balance": "106905151080000000000" - }, - "022b8c65e959cab71f56688b7073257b58bbef4a": { - "balance": "9682681149566000000000" - }, - "0245ff6382eb93ab1e8ed2e3c0bce7a1b9a9713d": { - "balance": "289000000000000000000" - }, - "025e117a69ca9244ed430732c11e550e3ee67577": { - "balance": "1861905310567000000000" - }, - "026e7457eeaeaec7898fdee1ad39be89e92733b3": { - "balance": "7529030978000000000" - }, - "028d2def8c54fcc77bf0191b183c0bc4570ec1c5": { - "balance": "9056720934000000000" - }, - "0291a087605b516e465134797b5459436d320e6a": { - "balance": "481100929805000000000" - }, - "02a4b18b3e13ec79307e712fba1867cbf7fb6155": { - "balance": "9000000000000000000" - }, - "02a812d4cebcac1a92ae470ade92fde7bead127d": { - "balance": "66793603497000000000" - }, - "02f718c94b2c8e8d62752f8632443504c1e4b6e2": { - "balance": "1000000000000000000000000" - }, - "030dab52b47b37505b72e5ca0985f65ead590816": { - "balance": "1376851176362000000000" - }, - "031c59846f75de1aefb0e8a95e0fb822fd06555b": { - "balance": "140978338628000000000" - }, - "031ee87c672d83ec73059c86a312a9e972142054": { - "balance": "96406273341000000000" - }, - "033182e860564cf695cb403c8c0f078053368d7d": { - "balance": "1504349255824000000000" - }, - "03788dc6528fa33a90e90e03295ae4b792d56644": { - "balance": "24356250426000000000" - }, - "037aae119047028157c5b3bc9d3d202b02cbce42": { - "balance": "105627739575000000000" - }, - "037d45b323cbc5cbac999c5001169646e690b94c": { - "balance": "2000000000000000000" - }, - "0390ba35c454a24519d845405a7e24df71250748": { - "balance": "1872501898509000000000" - }, - "03ab8c1e7f904db62437b16d28aeb539b2dee55e": { - "balance": "55000000000000000000000000" - }, - "03af4c69728a888fa26b1aefa439005989771fdf": { - "balance": "27704588237757000000000" - }, - "03b33fb19d165e5e33bcfbbfc009f418d71f30fb": { - "balance": "1999139000000000000" - }, - "03b34c79f8167a4e8be0f6133254d2b50cbd878d": { - "balance": "111065050160000000000" - }, - "03d7e8638b74ae44a2770287285489a95fa1ea11": { - "balance": "20000000000000000000000" - }, - "03d870bf719f03250c0dc5156a36751b3aa21f18": { - "balance": "981119649953000000000" - }, - "03de52c12b05fb8bcba3a1cfe02a0ad1bc9761d3": { - "balance": "362007990932000000000" - }, - "03e516db27b1abe008ffc57ced48f72f872d8b08": { - "balance": "3389116345657000000000" - }, - "03ef5ff863ee5f1167f38cdf316e4d52a242b750": { - "balance": "12395856876000000000" - }, - "03f27766760f2bd1cae1cb85ddf43ab59c871e47": { - "balance": "49000000000000000000" - }, - "03f4e1a8fb4eedc776f4835fcc85d0f236612f9c": { - "balance": "27210590272692000000000" - }, - "0404936ee04cc79cbb3aedfa33a53f94940f772c": { - "balance": "29919204637416000000000" - }, - "040501ffde9649be794b7d41643273ed6285ab39": { - "balance": "686000000000000000000" - }, - "040e449de680f69614120f0a2e894cde36e4adf1": { - "balance": "81993180085000000000" - }, - "041531e906dbdc70d89f5e255151d9865a059308": { - "balance": "2163418749315000000000" - }, - "041ad9f6bf970541e4ea8a14dde1e789d0fe4367": { - "balance": "44999979000000000000" - }, - "0446420c07cf73d2b3741b945c1cc8444b4ba6b6": { - "balance": "138749371512564000000000" - }, - "044c1a540b8ab286c218c2fa9d5bfbc2761e7626": { - "balance": "1" - }, - "04526b2c62911e78a939816aa4575fe30baa06c7": { - "balance": "2983093150081000000000" - }, - "04adf59f8a0ad3820a7972c6243202b3b0617fcf": { - "balance": "50000000000000000000" - }, - "04bbb42882a475eed58aae47fe530ed19c1cedaa": { - "balance": "278038763863000000000" - }, - "04cff7a7c2b9b0bf31c5ad4a5de8b0eade70aafc": { - "balance": "515406205244000000000" - }, - "04dcd325dc1fd37ff3c87da3b21c47ddfcc37cc2": { - "balance": "5831887315000000000" - }, - "04ec8d0b5157370f5a2671a2aa68ae486b7a7842": { - "balance": "10000000000000000000000" - }, - "04f50f2a6e89ee497a64c11baa90759a10a1247a": { - "balance": "25443071621949000000000" - }, - "0513a769ebef58ad3a4fd7011ddbe19799ff5600": { - "balance": "64369494797000000000" - }, - "0514c1151f356070ace281435f25c86b58280715": { - "balance": "38967380881301000000000" - }, - "052fda414fe1279c6276a237b07e1b4148a8cc77": { - "balance": "10000000000000000000000" - }, - "05431089cc62a987d0e99847e10a006233146f6d": { - "balance": "268977485219000000000" - }, - "054ed2f55028257212b996f9a3d34758d1d4ffd1": { - "balance": "100000000000000000000000" - }, - "05a68cc758560addde302baf814f2fdbe0ef2c2b": { - "balance": "10000000000000000000" - }, - "05c669d9ded79fe9e4e3718052bc7ca18a3205ab": { - "balance": "7347158140000000000" - }, - "05d77ce5c87477b05e90e829dafd8eb3a8c87823": { - "balance": "21191998933000000000" - }, - "05ef2894a2a1c6eb6c0a768d04ef5b573f357712": { - "balance": "20000000000000000000000" - }, - "0601011f80279190b96f641205c6a524a8ad5a28": { - "balance": "12025716447696000000000" - }, - "061a8acdb1a340ba7c550814831e27262708fc98": { - "balance": "234029764576000000000" - }, - "06219483e217c9ad479f76a95426f689ef4d5951": { - "balance": "1509408723551000000000" - }, - "062d0db8a650f2241f8a4295326a2570a7c771bb": { - "balance": "717459720227000000000" - }, - "0633ba746235d8fc8243751b1aa31646c299f262": { - "balance": "49000000000000000000" - }, - "06b6a5cadfe1fdc88015512e835d840e58ae4123": { - "balance": "1000000000000000000" - }, - "06d08fcbe96791514d900d2cb6c0f029d8d791d0": { - "balance": "19196168602258000000000" - }, - "06e5c0bad43a7011878b12a682abf01ccdfaa151": { - "balance": "30000000000000000000" - }, - "070656bb11ec36074d47c791c0b306394b703401": { - "balance": "1245216075291000000000" - }, - "070d84c938217163b60ed38e4937eea7158c03d9": { - "balance": "27507979787000000000" - }, - "07428c95ef3862026e54d3a963911cdc673dbcd9": { - "balance": "13792309994528000000000" - }, - "0781cb21df142ec5f67b956bf995f02f6f24985f": { - "balance": "224940990659000000000" - }, - "078c38c153b414cc4c12818fce2ea7ba09a34e51": { - "balance": "1410646136000000000" - }, - "07bfd0de7a9a1c927446aaf2d7ede55b471daa87": { - "balance": "77778844734000000000" - }, - "07d1ac83140188b8d7f4c8c607d0da22c5ba523f": { - "balance": "7713686418107000000000" - }, - "07d8ef8fc6dcde319a5af5b6cea18983bdc4c8fe": { - "balance": "3801361173000000000" - }, - "07dfab72dd3e44fcbb1ced625899bf20e0c52ffc": { - "balance": "154177778806000000000" - }, - "0817ce33d943e84c7b3261cc3e37b86b5d6d76ae": { - "balance": "90753785862000000000" - }, - "081be00a2ff62cbcb95a8eb020ac0efa33f93a42": { - "balance": "1027889807304000000000" - }, - "085ffdc6043b04653e51b1a34af20b609d158607": { - "balance": "3314058000000000" - }, - "0882c2228f5df24064bc37e8b7199199de308bb8": { - "balance": "98420617420000000000" - }, - "08918776e9a7136cedad5d0cee52f5d9dd833ece": { - "balance": "1263170315026000000000" - }, - "08bdbcff16919abc5e15fa68ece56eceef33f48d": { - "balance": "2552990000000000" - }, - "08fc8c7bd03fe1249266b233edfcf830693d0e10": { - "balance": "283490111768000000000" - }, - "090f79a4178b5180150444805f62c26cd21be897": { - "balance": "884195010282000000000" - }, - "0914a9dfc9d6ecc063a55e5320050112f305fe17": { - "balance": "15373898854941000000000" - }, - "091791ab5f8ab86f1d8f566ed221b268cbc55347": { - "balance": "2207516004000000000" - }, - "09529f8b1633ce4375451bb44b1025f6e5f9facd": { - "balance": "151697652792000000000" - }, - "09600bbb9d9b23661d269dbe1ed066d8e573b5e1": { - "balance": "802935104935000000000" - }, - "0964d2af1d5883fc0e0a77459f6a141824de7356": { - "balance": "9610980935058000000000" - }, - "097c731d1fc6792ac0f0ff92be4403c3749cc1dd": { - "balance": "165134479709000000000" - }, - "097f152b3f837d38ab1e8c0683d62f5a01d67902": { - "balance": "20000000000000000000000" - }, - "09a6772629ef0bf402ae6d27cd32e6eefb220a12": { - "balance": "20000000000000000000000" - }, - "09addb954d4e4b4e95e0c66d324115d609df5a99": { - "balance": "8435321515000000000" - }, - "09b2eb03e0fa321102196578eb40dcba3a46ec9c": { - "balance": "12723517962933000000000" - }, - "09ba0ed4dce470ba0bcb4d46b507c3b024b83070": { - "balance": "99999979000000000000" - }, - "09efbd6dfea375065be1b3a8f4541f024da21a34": { - "balance": "5870833623000000000" - }, - "0a24d4ae66edc7723bbb314e9b96dc7b9a31e813": { - "balance": "70000000000000000000" - }, - "0a3ee710909382f762648deff8ac7c8b30e2ce10": { - "balance": "407656462445000000000" - }, - "0a42b3145257154e76a97db8147c93be4cffd97b": { - "balance": "10000000000000000000000" - }, - "0a7cb6037f1eba5d19fe781335ecd37b7229c5f7": { - "balance": "74113322448000000000" - }, - "0a85d1bec4d44e309068b115abd517d3733fc56e": { - "balance": "14836218750000000000000" - }, - "0a891ba9ca7b99ecd815b1dcec9243dd4deff866": { - "balance": "178004857988000000000" - }, - "0ab69370b537d4ff5b45704fed293e46e3464f87": { - "balance": "1258876668246000000000" - }, - "0ab77a2e8ab9a3b659d1f1d37956c3607a0f9a60": { - "balance": "6283300817712000000000" - }, - "0abc7e8d52f5b0dcf1d4713e5fa4909102251dfb": { - "balance": "39307290577000000000" - }, - "0af2c0471c802d2e2b20aadf9dd4ec842d313ab0": { - "balance": "1529468143183000000000" - }, - "0b08c717bb3982fc8b92d5b3d30e5b41265a0d0f": { - "balance": "1184600154874000000000" - }, - "0b3f2aa9dc5b57b0469398d62f60a13774ec0e87": { - "balance": "132187640280004000000000" - }, - "0b3ffe85aa89e71a6e51e938c7265d2a7173061b": { - "balance": "2106793086824000000000" - }, - "0b468562e712d22b37e1a65f54b1fa825beebd1b": { - "balance": "15130906006000000000" - }, - "0b5333eb668dee29ebc0e335d74f33ffeaae9ac5": { - "balance": "125953133109000000000" - }, - "0b59a20107495e951b509187307782ca9dfa441f": { - "balance": "25000000000000000000" - }, - "0b8b7fb066601ea7744b81f6e1a21b8e489359cf": { - "balance": "101782000000000000000" - }, - "0bd7791097f79066d71ac0a2c94bce6628a63373": { - "balance": "44389955028000000000" - }, - "0be541af06e167206b5d1cbe08e8fb2b5ebc82cb": { - "balance": "9000000000000000000" - }, - "0bf178bba463f4f6c33e3d81b1a78d220f7b5d4b": { - "balance": "111784804790646000000000" - }, - "0c1f000249b1f1ac9e43c4f10e2da1cc2adf886f": { - "balance": "91251997635000000000" - }, - "0c74e46b115e19726997dd559d2b6ff1bfb79af6": { - "balance": "879229287149000000000" - }, - "0c7c1ec152c920a068c25626c22c4fae7f435536": { - "balance": "39849464104000000000" - }, - "0c85fbd7492d1ae87bf3d286c4750a34f1fd3121": { - "balance": "20000000000000000000000" - }, - "0c9fd6123e313f7d1f0cb25d99839102da08b2c5": { - "balance": "10000000000000000000000" - }, - "0cb051e3bdd9d96e667fbcc00a766d4f149f89e4": { - "balance": "1000000000000000000000" - }, - "0ce32bf6c433cbd26c6f09a1214db0374002784e": { - "balance": "3293279842000000000" - }, - "0ce6374ff04430e34edec8b6323feab2bccab92d": { - "balance": "93983447000000000" - }, - "0ce646412a1524c3f73edfd753c0ba3ee7338275": { - "balance": "10000000000000000000000" - }, - "0ced803e56eac3c99269ff7409d2d200d62d7c25": { - "balance": "49539379000000000" - }, - "0d1dc2be9f78ce2b2591e7f5b8af9dc778499bd5": { - "balance": "2235348003595000000000" - }, - "0d235583458a168e810275f907b5f87bebb2d1cf": { - "balance": "83106439283110000000000" - }, - "0d28fe6e8b7d4b8c90ef7c52b9656511ce5867f1": { - "balance": "1347248794799000000000" - }, - "0d5cbe0da660cbca831787efc45fecb20e06e02b": { - "balance": "297528508941000000000" - }, - "0d7a24f324176f6d793c3a2eb6c54d6ee47eca79": { - "balance": "25637813467000000000" - }, - "0da26a24e3650e84c52fedb36ef76225a8d9d259": { - "balance": "15467820321000000000" - }, - "0db7eaceaf3df21ebb49c56fa2d2e2c8e85dec52": { - "balance": "196000000000000000000" - }, - "0dde52823bd8fb2cb179e6d417c07ff285c31775": { - "balance": "347321514878000000000" - }, - "0df9585f1aa83189e0a813f5eac6e6e0b2bbb8d8": { - "balance": "2891430551000000000" - }, - "0e09af9368f05b476164953b7b9db60ac95248f0": { - "balance": "573644391203000000000" - }, - "0e18315dd2b663ce4859b5bed854403191452c2f": { - "balance": "24174325261000000000" - }, - "0e29bef5f4f66c38a0f05cca1e4938d57ff09c70": { - "balance": "10000000000000000000000" - }, - "0e443353b42e042ff5168e9b3c6de37070368223": { - "balance": "20000000000000000000000" - }, - "0e8cb6e439516b312158f169b546937b715db3f2": { - "balance": "8049136367000000000" - }, - "0e980fab23be601f3abec7b9a24e1335a5e765c8": { - "balance": "8301885845897000000000" - }, - "0ea63fef218ebf570a4ee62ef6ed712dbe623c44": { - "balance": "10000000000000000000000" - }, - "0eb60e3512336e4447ceeb8664ce0ecaa3eb0bdc": { - "balance": "41401696400000000000" - }, - "0edafc1058879a9568e711445b18ec4da31d2480": { - "balance": "10000000000000000000000" - }, - "0efce4565062b23b43dbc1e261463e363e4a5b4c": { - "balance": "10000000000000000000000" - }, - "0f08782c04bf7249ab08f4e251abc60aee792a96": { - "balance": "1380257622493000000000" - }, - "0f19bfe1eb24def828bf1be69791c63ba1de1263": { - "balance": "2223687184885000000000" - }, - "0f2171161eb9674218add261be61d18d86b846a6": { - "balance": "121000000000000000000" - }, - "0f42ef6c5690b6c95f8b8c9dbdc16f717c04852e": { - "balance": "81000000000000000000" - }, - "0f47f5063d321b34a0d800951bcdc3f53c07e32c": { - "balance": "5288516165000000000" - }, - "0f529a9beedb2c2a087a220f0013cea4f8454bfc": { - "balance": "114585457979000000000" - }, - "0f6751d10aaf855454a6e9e4241cfcae3b0ed732": { - "balance": "94160300063000000000" - }, - "0f6ed5a4c3ec100afcd59e9066ba7fcb63cfa6dc": { - "balance": "1000000000000000000" - }, - "0f77025519cc76c38e1cf0bd8721f4a5b9c814d4": { - "balance": "834620571043000000000" - }, - "0f773db2a1a96b775e4481575704f5f087b067e0": { - "balance": "554268361745000000000" - }, - "0fa0f73adbe82f8e09f8adbce15b051971e289c3": { - "balance": "11329911975000000000" - }, - "0fa6397d747d88a25d0c755b3be4eee0e3f68912": { - "balance": "31394936138000000000" - }, - "0fac8635a61bf7652d86725cc75c307949bd4f2a": { - "balance": "49000000000000000000" - }, - "0fb0ce787306ce13dcd614ab3d0e15d9772106ac": { - "balance": "50000000000000000000000" - }, - "0fb1d306d240360056f60f197dc7f68f732ac515": { - "balance": "20000000000000000000000" - }, - "0fe3571f498a6d945e123ac8ff6e3fed348d9432": { - "balance": "20000000000000000000000" - }, - "0ffd6b01ea9a7bd2576fe4a5838fe09e44c1639e": { - "balance": "100000000000000000000" - }, - "100bde3d73fda700369e78229127b58d2ade9177": { - "balance": "10000000000000000000000" - }, - "102028c7626970a28677bbdc7733484c8b14c2d2": { - "balance": "500000000000000000000000" - }, - "10245044be6a46ad41d4559129cb59e843379cf8": { - "balance": "857437279765000000000" - }, - "10417d0ff25c115b25915dd10ca57b16be497bf6": { - "balance": "10000000000000000000000" - }, - "10579870e6685ed7e97dd2c79a6dc3528bae968e": { - "balance": "5187866041491000000000" - }, - "109736465b4bbe31ea65ad01fc98f04498271e6c": { - "balance": "20000000000000000000000" - }, - "109c0535a4a86244c5094e99167d312a77657dd5": { - "balance": "138277702073000000000" - }, - "10aa08064689ee97d5f030a537f3cd4d8bbdaf74": { - "balance": "10000000000000000000000" - }, - "10d8bc8c3d3e2010e83009290586ad85b73321d1": { - "balance": "25000000000000000000" - }, - "10f22b82460252345753875555de2cebebe63a93": { - "balance": "765947730644000000000" - }, - "11111c3a2cfa55e52d6aacf533e1d412f8c8c01c": { - "balance": "4827254128275000000000" - }, - "11386103a0bf199db9504b617ccb3bbd780eb9fe": { - "balance": "10000000000000" - }, - "1156a129183e5bdfdf2bf7a70963285a979363a0": { - "balance": "10000000000000000000000" - }, - "11589cf70a6a4fbaac25224e2ddab222333f78e6": { - "balance": "49000000000000000000" - }, - "1162fabeb3eb1e4124179b00c4a1e01503023f54": { - "balance": "817145350625000000000" - }, - "116a7d140f4b7f9b4689063a8417ac07a32bae00": { - "balance": "106088220142108000000000" - }, - "116dc38ddb4b138b19ce6a51e5922c287da5c86b": { - "balance": "100000000000000000000" - }, - "1175f84f835a5ae40d49b8ca17e3e474c1eceef7": { - "balance": "1698584794716000000000" - }, - "119f822a796fee9c41a488949fcb14b589ffa628": { - "balance": "20000000000000000000000" - }, - "11a99f6019b6a53f5dc8cbd0c34f1ee75ced33b8": { - "balance": "102126982156000000000" - }, - "11b9324406068e8bf598d3a9ea59ef31c52f51fa": { - "balance": "6525925895203000000000" - }, - "11cb7be6869a10f5f9e8a47c6c92f729b083084b": { - "balance": "182959434323344000000000" - }, - "11d96a76166ec579e2b6cfa903f66da4af669351": { - "balance": "1000000000000000000000000" - }, - "11fcee55f78278df60f50096d45da1aafe72722d": { - "balance": "222859488179000000000" - }, - "120a1fc914718acd85bf92d9492330165d78075a": { - "balance": "3736627235906000000000" - }, - "12366136d83c77befdc30e04d4f5d808419f504f": { - "balance": "88008649003000000000" - }, - "12435af3f2f92ec43e8f2894be9c72fa932880fe": { - "balance": "1590548436852000000000" - }, - "124ff67125a00aed24e58b6d64ffa887a59b48a4": { - "balance": "20613022349070000000000" - }, - "1296f04910ebc89556ec7ab1b178fdbf14d0295c": { - "balance": "36000000000000000000" - }, - "1299f180e42bfaa1162d36110d29ab062e43e1c8": { - "balance": "321570118362000000000" - }, - "12abac62150c526866ec958cd0e3721b2c78d550": { - "balance": "51898545633262000000000" - }, - "12b345087cee385b9adccaaaa6741b767c82d7ea": { - "balance": "36000000000000000000" - }, - "12cd5e8c0c93f8e34b589b95954b719f54d1515b": { - "balance": "1000000000000000000" - }, - "12d262cdd25edc39b6fd9ae78184eb548e513927": { - "balance": "500976168000000000" - }, - "12d933448218629702c48547b3446b629ec65883": { - "balance": "2168010577395000000000" - }, - "13054aa42d3e119220ac359641c15f8b54bfffef": { - "balance": "24986834005530000000000" - }, - "130bda09f463a982199849ae617062a1d68f3a85": { - "balance": "154504844790000000000" - }, - "131a5da679863c05dc627d53634f2925ba0ce731": { - "balance": "10000000000000000000000" - }, - "1334f2752b5c21f681ba9e23a9fe95a85f8e05f1": { - "balance": "121000000000000000000" - }, - "13634512e2ae79fe3febb9e55e03b47bc350d7ba": { - "balance": "338331304738000000000" - }, - "136fae842aab625768bef9079ee1711e8c007d8f": { - "balance": "2759741687626000000000" - }, - "139fa969e8b74bee1f6113a362f15060ea998b15": { - "balance": "10000000000000000000000" - }, - "13c7e1d694bde6f8f6a31eb6c99f38dc739d61fe": { - "balance": "10901074773586000000000" - }, - "13c849944ad6ad12a46c46973d562bee8284f46d": { - "balance": "35114615504000000000" - }, - "13ec3aa8f4a427ecdecc7901060ccac9bea7a61e": { - "balance": "10000000000000000000000" - }, - "13f478c74acfd6897d13e602a8d362893f4fd038": { - "balance": "3521111850000000000" - }, - "14403970d0784a6458a7bf2584a53d14234e8860": { - "balance": "25000000000000000000" - }, - "14440bb7410337e34a064a92206075575f5362ee": { - "balance": "14918844868393000000000" - }, - "144a88e7a8af70b8bef5c4b70ee0cff771d0c252": { - "balance": "67961927542000000000" - }, - "146b79f474176a4b0069199b03669ab6467a4787": { - "balance": "122518123211000000000" - }, - "148893e7811c36c6bd1ada367681ab8327b3b2fa": { - "balance": "1313118418375000000000" - }, - "14900a17784e3b4d89d98b6cb31c74c685418b89": { - "balance": "131112181597000000000" - }, - "149a483758a98ffe28f7f25cfa17d7433f852ebe": { - "balance": "10000000000000000000000" - }, - "14a03c8e84f07c5596687a98d1e0b1859e9b34ac": { - "balance": "55000000000000000000000000" - }, - "14c7899cb34b5447d6363d4e8355113ebf4bcc66": { - "balance": "197554844582000000000" - }, - "14efa63ee285277c0f8e0d5cc22193e17984e11b": { - "balance": "106221254735000000000" - }, - "151c6099b3fb5b18e0e36a3335dff186dcd2904d": { - "balance": "4304311254087000000000" - }, - "1525dce233a971eb1387f130fdf0e5bf3455723b": { - "balance": "45004174531000000000" - }, - "15271904676f2bc2511294e500152d05ea9acc85": { - "balance": "9300898622566000000000" - }, - "1556ba42ea69d72c1d0faf802906645268e36aac": { - "balance": "171939212653000000000" - }, - "156558fb71ff986953d899c9916a121fd047675c": { - "balance": "290926338537000000000" - }, - "156fbf32614aac2cf462952ec1a3f141f797316e": { - "balance": "6084388860000000000" - }, - "15b9497d6bde8017baf3c29e12430e05a47efbf4": { - "balance": "206126229839000000000" - }, - "15d532e828bdcaf1246696d679a2eb66a154db5d": { - "balance": "69656571015000000000" - }, - "15e26a60cfaf23dfd9bbb999a30904d11b6ddd05": { - "balance": "9839303178835000000000" - }, - "15f3be2f11ee3b19472cc3d171931f050d8629a2": { - "balance": "13572825921000000000" - }, - "16254bed335420e5f793de2295b0081ac41a08d1": { - "balance": "144000000000000000000" - }, - "163aa91bc2ad588116141d48fcbd943985455cac": { - "balance": "618250979557000000000" - }, - "164cff4b9341d536b8aaf2d1dd0e3ed35ecb1db7": { - "balance": "671554639913000000000" - }, - "164d2a9a63868ac25bfe26ecba446d7ce256c351": { - "balance": "7233638188261000000000" - }, - "164e759b64d3ee0a23ec3030f50a1b454a6ec15b": { - "balance": "12281161499000000000" - }, - "165d4a0f23c016b8064adf0dcf7e31bc06350777": { - "balance": "256757922324741000000000" - }, - "166b862954dacddc3333aba4edbe523d693df858": { - "balance": "123677971414000000000" - }, - "16858eb1a6f0e7ff01b91aa9c92d0a433a5f767c": { - "balance": "500000000000000000000000" - }, - "168909a1c2a43cff1fe4faeac32a609c25fbd1e8": { - "balance": "62258808044224000000000" - }, - "16987ad8e10dda7f9e5d95c0f0ee36f46b10e168": { - "balance": "10000000000000000000000" - }, - "16b5dffce79573300a6514ace5f2e844d26fc64e": { - "balance": "5576805697087000000000" - }, - "16e01370a93befe24f6ae6076cd04c84cd3515b1": { - "balance": "1922179181578000000000" - }, - "16fbafd4fc871c7589e63062133793ab244c2019": { - "balance": "2865030627000000000" - }, - "16fdf76180796c6e4335eaa2842775b2e4a22e0b": { - "balance": "20000000000000000000000" - }, - "17081d4d6ebb9f4b163e181a59c2102c99fce6bd": { - "balance": "490625378000000000000" - }, - "17218ff455aa87b29ad4c4f7ba21e9c6f74fc97a": { - "balance": "1607392037652000000000" - }, - "1725bce47f3700f4646efb343f950e2e8ba66607": { - "balance": "58472967071000000000" - }, - "172c5f71aabf072507664471ebaa435779d74a32": { - "balance": "16000000000000000000" - }, - "173a065f351ee0513cfebfe9b950fd2c641fc8cc": { - "balance": "25000000000000000000" - }, - "174e1793c96cefb584ae0a67fff85c65065dafc5": { - "balance": "50221000010000000000" - }, - "1794bc4d622d514f95da5404358ed404b3f59aa3": { - "balance": "36000000000000000000" - }, - "179839d61e7c7a0382fe08e0573bcfbe42a108ca": { - "balance": "203299791419000000000" - }, - "179eb30b5b28a961eac70a919d26ca96e6472166": { - "balance": "55000000000000000000000000" - }, - "17be72168606fb5d27761157e48fc14789f84634": { - "balance": "311205588354000000000" - }, - "17cefb6611033759b8755197b983de2d7e98315e": { - "balance": "10000000000000000000000" - }, - "17e07cc7d89bcd1708b1f05ab6e1252c629d71cc": { - "balance": "903234908997000000000" - }, - "1811be559b657685c2f163122479101c404325b0": { - "balance": "10060694170000000000" - }, - "181417a4883c429ef26a4baeb48e70d4f00278b4": { - "balance": "4621446218088000000000" - }, - "181d345cd6b5f518bdab8d40f5d4896a725b3f3d": { - "balance": "114349561983000000000" - }, - "184625e544aa31552d2911023a892f739df84be7": { - "balance": "5303698708000000000" - }, - "185e4f6eee203ca3c089baa1e643ff1aab7cc8f4": { - "balance": "33969718257699000000000" - }, - "188e4a1a7b23ff35ec90b7bf7561db9e3c0f53bb": { - "balance": "394325508701000000000" - }, - "18a4dbf513be132f9ecfd69e3eb683d710e28c4b": { - "balance": "5997985132329000000000" - }, - "18c9298f62635ef47d0ef215b8a693af60829c27": { - "balance": "100000000000000000000" - }, - "18e7e2ee0c86bc1ba3595fee3d40257776fe8172": { - "balance": "185584626033000000000" - }, - "196575e74499b741877793f8c8facf2f3b1ddb8f": { - "balance": "30318381929000000000" - }, - "196df33f2d3ed473e6e07650419969f4a39fd03b": { - "balance": "15442864665000000000" - }, - "1975c5293ec9c72a28e6cc74173cdfd8de682fea": { - "balance": "103624886552134000000000" - }, - "19832cd1b2fc4138c8d9291a0f404d3c4326b48f": { - "balance": "4732362673000000000" - }, - "198705f46f31c7ca22f5b88fab210bc5b0c7647c": { - "balance": "548940869737000000000" - }, - "19a5a213e6abfee29f17e871222cbe9ac45322c8": { - "balance": "10000000000000000000000" - }, - "19ab9a7a4e9f9c08c9b4295c406b78389a864ba7": { - "balance": "369299839157000000000" - }, - "19f19f5f01b3f6a1c4f645dc7e3992b1196ccb7a": { - "balance": "97759406000000000000" - }, - "1a11a0b0081522e60e16f154e093ac2e005d24ee": { - "balance": "88024675252000000000" - }, - "1a27309b0c09be2234fd64afdbcfb099f8e2e7cd": { - "balance": "10000000000000000000000" - }, - "1a3d61754974bea23503a61ef0fe584b7b6e6cf3": { - "balance": "326950210355000000000" - }, - "1a49bbde1457a8d4c247606b206ac8d4d389da5a": { - "balance": "402438941516000000000" - }, - "1a7a4b41be64fff3a31eb6166db59741e073d0f7": { - "balance": "250000000000000000000" - }, - "1a8d282e82c606e992f69ce618ba634d98bf2683": { - "balance": "20000000000000000000000" - }, - "1aa0ba27662816e5e3d79e223cc18f5dfef089cf": { - "balance": "187581622694000000000" - }, - "1acab416a1d3e8caa65faca378c79aaf2065b851": { - "balance": "1000000000000000000" - }, - "1acd37af3f87da1dff743dfcb97038d178b1dc4f": { - "balance": "708034481300000000000" - }, - "1ad8f036022c3e5258455d6aa05fb4be5dd121b1": { - "balance": "42957064709000000000" - }, - "1aee811e06c579c21fbcc3b53d2dcf9d5f24808e": { - "balance": "52480060284048000000000" - }, - "1b03b7a4e9908c3531618f49f8d050ba6afb4de6": { - "balance": "28410489187000000000" - }, - "1b073d026e93de51db34d5a8e19047784c277ea1": { - "balance": "20579129628026000000000" - }, - "1b0b87e414bc8fe4920fe104b6de7d17db3a1a19": { - "balance": "10720000000000000000" - }, - "1b411c692c80948e59cd805a0f8574dd67519288": { - "balance": "5416615538000000000" - }, - "1b8d57e995749618c7bb3e60194ac6fc57e9b3eb": { - "balance": "10000000000000000000000" - }, - "1b913efde1255516346b40ae2a48ebf62251682d": { - "balance": "100000000000000000000" - }, - "1ba7276c133f93d43db2f2caddec08e0167eaf15": { - "balance": "82559173174000000000" - }, - "1ba919f7742160cabf2756eb6eae67b92530f3f3": { - "balance": "1102304139883000000000" - }, - "1bb20857de494694fe15bd11f8cac1218435fbc0": { - "balance": "10221322567000000000" - }, - "1bb5c5e81d451f03e899852edc8556a9f7aac5df": { - "balance": "18781017696028000000000" - }, - "1be3507349ed07d3e7902951d490f560a75e96be": { - "balance": "660691718918000000000" - }, - "1bf1c0b2e6f64b612f35f2bf98d894b13dda9bf7": { - "balance": "3050161851140000000000" - }, - "1bfd3c2ba6a537e97cedd542cd554a5050963d54": { - "balance": "20000000000000000000000" - }, - "1c4af5003f9e7223f4141107d21640e4a85a4827": { - "balance": "612390629874000000000" - }, - "1c6a94810bd0afcf79ceea11afe86c34f6813211": { - "balance": "10000000000000000000000" - }, - "1c7e277460191c886cb1647173d27122c2146252": { - "balance": "209062806527000000000" - }, - "1c818ffa9caa61d512fa5d7d6e566f3ae37d5434": { - "balance": "454897845316000000000" - }, - "1c9599d5f8e5eaf8f68d35d52132e15a153f6d3c": { - "balance": "36000000000000000000" - }, - "1c95ab5229fd08c638a1728c022f09291b8dc55d": { - "balance": "20000000000000000000000" - }, - "1c962808c175ee5e5e365483d066c8ea95993700": { - "balance": "1362779746855000000000" - }, - "1cafad295b2188f10192c8a32440931f7e3554e4": { - "balance": "36000000000000000000" - }, - "1cdc2899ec563d79569d1ba776bc03cff331e786": { - "balance": "572163587827000000000" - }, - "1ce0042e7b4f13589f5f8490836dc63e0ca60c3c": { - "balance": "25000000000000000000" - }, - "1ce62051fd7801d294bf31a7b44cd87510e8b545": { - "balance": "2008112411284000000000" - }, - "1cf20f30cd901b2e5fef3f948289dafaaabaa77d": { - "balance": "1444000000000000000000" - }, - "1d449764d38b7a4ac848f49e2dc99df02dfd8a53": { - "balance": "48215693645000000000" - }, - "1d635125c494b1137ca5f15ac95dd6d93c3a9546": { - "balance": "10000000000000000000000" - }, - "1d85a61353c3e0b6d34e105e35c8c7833b6a1e35": { - "balance": "16000000000000000000" - }, - "1d969134ee156c41c98c3721c5dbb092c0b581a6": { - "balance": "64000000000000000000" - }, - "1da12434596a9c318dab854f06d404fe61f0a69d": { - "balance": "16675185416000000000" - }, - "1db0d23fb63681958a66e716e99df3e0b848fd12": { - "balance": "1103581911968000000000" - }, - "1dc628820da657f07ab5eb887d5f512378b5b61f": { - "balance": "6272287019755000000000" - }, - "1e05cba75b0dd379037940352e0073564957b7d9": { - "balance": "12453446342664000000000" - }, - "1e13f037a92ab6f19c4484ae3301b3ac6f48575d": { - "balance": "106244918916000000000" - }, - "1e167bc07f094915c00e7aa4c43b607ed2c998b9": { - "balance": "1000000000000000000" - }, - "1e1f9409bf92c3ef59aa2fd82dce55cd90e23f19": { - "balance": "99139000000000000" - }, - "1e4dfea7871d941e72a161022b62fdb01818c86d": { - "balance": "81000000000000000000" - }, - "1e5d0b525228167334e94314a201388bba08153b": { - "balance": "1138044078759000000000" - }, - "1e6633290c9898abf5fcac54396de770164edc5a": { - "balance": "25052055674000000000" - }, - "1e76296584058670ea80fe9a39d8f457c03747c5": { - "balance": "10000000000000000000000" - }, - "1e88b2c8dcd289929e51a15c636d0b0f3b035569": { - "balance": "87357600832000000000" - }, - "1eb59a1732a159a91a9371650943840e0eb61174": { - "balance": "20542821429000000000" - }, - "1ee077bdef6d45d491602342cee008cd1e2912e3": { - "balance": "10000000000000000000000" - }, - "1f1ebf2f80afced68424cb7b0b966fdf42d508a4": { - "balance": "1460082126494000000000" - }, - "1f3d4a903bd32a537efae19592f5516698c95a20": { - "balance": "10000000000000000000000" - }, - "1f6431696efc6f1ab98dcc2ef0e8553da697e6f1": { - "balance": "20000000000000000000000" - }, - "1f657552b745acbdf731f2ad107d6362480abc88": { - "balance": "162042599568000000000" - }, - "1f699a7682c1266291a3f49e19cac0846470abf5": { - "balance": "712268213248000000000" - }, - "1f7a332dabb00851705274c59187817d859cb9a4": { - "balance": "199999999160000000000000" - }, - "1f7c333047e168f5d3408c42a4919bd44b8f7961": { - "balance": "3918096658000000000" - }, - "1f8226f7a4525b9f3cd4da3acc1bb34529f8d28a": { - "balance": "3530829464000000000" - }, - "1f8b6fcea9e0991ad0b0b25dc65748518a28713f": { - "balance": "142069368416000000000" - }, - "1fa3de6913e4de78cc4828e246554785950c3c8e": { - "balance": "178437291360000000000" - }, - "1faa75d57fd597d2b58d2ac6f65bc2bd5946911f": { - "balance": "13092024644362000000000" - }, - "1faf1721dba3266cde1e04a7e9c789bdabdd930d": { - "balance": "862698523071976000000000" - }, - "1fb861559361701fca1df6ab4ef4d2fb9d2d7e13": { - "balance": "100000000000000000000" - }, - "20154d678cdde9ca1c0acb94726f26617a4da0d8": { - "balance": "2288800561677000000000" - }, - "202484a46ca9d54d0d456bc38e2a74ec5f469349": { - "balance": "50178714107336000000000" - }, - "20324278018b4d8e0c49e0fd1be35d3494079165": { - "balance": "484082383314000000000" - }, - "2033ef68ef6297e9229bb73e6486330543aa3eb7": { - "balance": "51260669473000000000" - }, - "20b1e0ab7b9d62a314946b55a5775f24ae3cfa00": { - "balance": "1540424185584000000000" - }, - "20b61f2eb5e18b1e8568d18235918f9e2f596c32": { - "balance": "10000000000000000000000" - }, - "20ed8ca39dd148edf22e03b8021af32cecadd42a": { - "balance": "20000000000000000000000" - }, - "20fd5feb799fbb021ba262d28332b4dda8f44a2c": { - "balance": "7607475714434000000000" - }, - "215ab8aad1c8960838225294d086f0786c2dd796": { - "balance": "19929201327000000000" - }, - "21681cda53aa1a4cfb3e3ea645c8eeaecfc3ba4f": { - "balance": "10000000000000000000000" - }, - "217b75eaf2c0be12108120ba56ddb709e1885324": { - "balance": "36000000000000000000" - }, - "21be1d75b93e96017f088f1ca64ba7076c8edf07": { - "balance": "150798073752000000000" - }, - "21ccdbe0216b486cb39c94ed13767aa061c75ce9": { - "balance": "11070639373000000000" - }, - "21f2289f2d274bddd7928622fffdf3850d42d383": { - "balance": "268859368544000000000" - }, - "21f54f92a7d9a91915e1751ceb02cb8e3ed3d622": { - "balance": "10000000000000000000000" - }, - "2202c70ec23f4605394d69944edd9f90e488eb61": { - "balance": "9000000000000000000" - }, - "220e2253e1ab9ec348cc28d38bae4cb2d5d9cf8f": { - "balance": "116100821631000000000" - }, - "22328e434957107884854999e666ad0710187e3b": { - "balance": "233364805270000000000" - }, - "22851c0487d119ee3f150010515358d6ff14807a": { - "balance": "104464221701684000000000" - }, - "22a38000f5eca29001e387b52c18fb6030683fac": { - "balance": "55000000000000000000000000" - }, - "22b655a19810307750ed1b6b093da10a863d4fe2": { - "balance": "11840799203605000000000" - }, - "22cc48cf48e8ee207bc08411240f913a4e594529": { - "balance": "10000000000000000000000" - }, - "22d6ea6cb8a9206285ccddd3b6d0d1471ba66f17": { - "balance": "64000000000000000000" - }, - "22e2f41b31a0c69472a1a02d419886539b7b6197": { - "balance": "39885451304000000000" - }, - "22e962f91d01480d027ee0060030f529a7a64c8f": { - "balance": "93285203531000000000" - }, - "22f169328fb1104b386ad7fa69f0c7bf3e9a7d3b": { - "balance": "63366769386000000000" - }, - "22f35f5e0e7a8405714de66a5875c7ef84ec4891": { - "balance": "60944382032000000000" - }, - "23041bdc8d371dc29ffc890f19317dabeef12634": { - "balance": "402327389857000000000" - }, - "230eff5e8595f418686737ae671f1f1d225080a5": { - "balance": "114574598112000000000" - }, - "2331e1756d9800800fc9b54ee6e43e1150b6e58b": { - "balance": "44594796226000000000" - }, - "233a72b132e4ab1d3884274d4402d1a2a6399f0b": { - "balance": "1372148909093000000000" - }, - "2369d9dbbfd0f8aa8a3d84d8f2aea840a0cdf760": { - "balance": "500000000000000000000000" - }, - "23754e5cef31ab60aa97a0c8f9ccb4f2969f2d6c": { - "balance": "24764775861000000000" - }, - "2387973589fb07a8c1ec92492c0b8ba9ab5e52a2": { - "balance": "11642113696681000000000" - }, - "23950cd6f23912758ebe9d412166e27994fe6ec2": { - "balance": "100000000000000000000" - }, - "23b383e11573f3ca9be84e1e11694f58a432324b": { - "balance": "206558238838000000000" - }, - "23c329bb641fa51122ea476e3bc614f5d4f9cf00": { - "balance": "35908627324000000000" - }, - "23cb9f997c39853486adfc1a8b029874d1a6af15": { - "balance": "1400984459856000000000" - }, - "23ee14215c531f6ff1baef2c74b1754306f4532d": { - "balance": "10000000000000000000000" - }, - "23f641f765cf15665b6c28d77229d3b2a58fd857": { - "balance": "266570948120000000000" - }, - "23febb49d9541360b9d099377df16b5630dfbb52": { - "balance": "228513797641000000000" - }, - "24082040652a09cbed6504f3dd6491e0ee9d2bff": { - "balance": "91160839809000000000" - }, - "240d3edf4aaf42e99d366ca36d82c370271b8e8d": { - "balance": "65535355843947000000000" - }, - "242b63ebf47678f17c176d5d4a670e46e66a823c": { - "balance": "469668185647000000000" - }, - "2433612fb939236a87a97261ff7b3bc7b754afb1": { - "balance": "20000000000000000000000" - }, - "246bb03a3fab572b3c64fc23b03dfda42b7ea34c": { - "balance": "936364046000000000" - }, - "246c510dfaf5b49bc0fe01c8256d3879c1b5f89a": { - "balance": "100000000000000000000000" - }, - "24bf4d255bd3db4e33bff1effd73b5aa61ae1ac2": { - "balance": "302436106595000000000" - }, - "24c0378e1a02113c6f0c9f0f2f68167051735111": { - "balance": "36000000000000000000" - }, - "24cf04b7450a0fac4283fa6fcfef6215274b273e": { - "balance": "83714002622000000000" - }, - "24f5f8e7d6a23b55c95fcdc1300de05f9d2abd83": { - "balance": "20000000000000000000000" - }, - "25204bfb27a08dbdee826ad6d9c3398ec6d14fe1": { - "balance": "5929256591480000000000" - }, - "253d95911b4174805d13706b449879413b1672be": { - "balance": "37012901440000000000" - }, - "256065f7e919c508b68957b1d2c9120d29181e12": { - "balance": "25000000000000000000" - }, - "25624542c14c2ecb9a0fe7daec9ac5af16868ee7": { - "balance": "16000000000000000000" - }, - "256d05b6de445179e504a6c94ce1253ae159e19a": { - "balance": "12048598744001000000000" - }, - "256d37fc8980a969063b1f7e7fda8b87d4210da6": { - "balance": "107293553721000000000" - }, - "2588af91a0e8f3ba3ab636781bb84e263acd1f52": { - "balance": "8910000000000000000" - }, - "259774584d4fcae1d84f5997c00beee8a380e46c": { - "balance": "1140713354605000000000" - }, - "25bda1418853a22eb6a5380e8a2862d2a74949bc": { - "balance": "10000000000000000000000" - }, - "25cafdab7f79f7b95d55b4c2dda1f4080aa74d64": { - "balance": "2525573681000000000" - }, - "25cca69b41bb51c51b387c47ece83f30b9a78daa": { - "balance": "163449631440000000000" - }, - "25ce9dabd0a72b02e0056931155ba99c94cbc837": { - "balance": "230073284349000000000" - }, - "25d9d1785c96acddd926b3ed52987ff74f9083f6": { - "balance": "780460361789000000000" - }, - "25e56bd3e1461f27db4eb0cce8bb5ca1574401f8": { - "balance": "1001937531200000000000" - }, - "25fa2162d5c86cda10e4be42c14a24329e455ad8": { - "balance": "50000000000000000000000" - }, - "260a932a23b344056acb8e676714ffac0a13ad2b": { - "balance": "2000000000000000" - }, - "2622efe8836095fcf48d9c8019f48c8320d6e0f2": { - "balance": "5451866545636000000000" - }, - "262447c4d8826ed23ea25e9703a11b4ad3ae9388": { - "balance": "33992454005000000000" - }, - "263eee3badb9b0dd13579c09361806503705a1de": { - "balance": "1134831344000000000" - }, - "266f4c232ebc946c46979cd90d70868380e186d8": { - "balance": "20000000000000000000000" - }, - "267dfe6fa918686942f5e1d19d5fa615f6f2086d": { - "balance": "3569373363935000000000" - }, - "268ad2272c2b71243a7391020a600fd8dfa42d45": { - "balance": "122768017414906000000000" - }, - "269e4f43be9865f05a277933c2fbb466659ada7f": { - "balance": "22064992930948000000000" - }, - "26ae161c20acb26a320fbfbd60c97335cda28bca": { - "balance": "170710653621000000000" - }, - "26b4da905780fb0c5c3e7e5315989fed3aeef135": { - "balance": "20000000000000000000000" - }, - "2704312aa5a4202f14fa3b08e587e4f0ef13accf": { - "balance": "124259630994000000000" - }, - "2704e4b0e8df0c1f298843109ae3bb26c29a22c4": { - "balance": "3155521256785000000000" - }, - "2709347d12251c01aac6455108c6bebe72f0af2d": { - "balance": "220898650215000000000" - }, - "270a32b41dde877463d2106ea4f4529557a5e1d3": { - "balance": "10000000000000000000000" - }, - "2738b3746d6bda9bd72858eaa76f8b5ce7a88c8c": { - "balance": "10000000000000000000000" - }, - "27593d2271aced83e81034e8dd603d098238320c": { - "balance": "20000000000000000000000" - }, - "2771ba4b5944bb12d74b1888255c60e0db215fd2": { - "balance": "412946979808000000000" - }, - "27780086136ea3e97d264584d819dcb2176d7544": { - "balance": "292224348060000000000" - }, - "278936fff8afb553043f038c39fe93906bdb1f4f": { - "balance": "1448466441752000000000" - }, - "27aa0d45d3506f8446816e0e2e9675d46285f6e0": { - "balance": "20000000000000000000000" - }, - "27e655dcc5728b97b3b03fb2796c561090dced1a": { - "balance": "9841344000000000" - }, - "27eb0529279f7a71e50efb70bb1767cbe1ffa4ce": { - "balance": "10000000000000000000000" - }, - "27f564956c837d7949739f419d6ac99deb33d790": { - "balance": "1505247707018000000000" - }, - "280f5618a23c41ac8c60d8bef585aa1cc628a67d": { - "balance": "1316618646306000000000" - }, - "28167a591d66ae52ab22a990954a46e1555c8098": { - "balance": "1000000000000000000000000" - }, - "28257eeb8d20f2fe5f73b0ff2eca3214e30ece4f": { - "balance": "95924728584000000000" - }, - "2827abfc49828db0370b0e3f79de448d46af534e": { - "balance": "769862008499000000000" - }, - "2832b92434e3c922206c2408442bc8274606cbd9": { - "balance": "103421320914027000000000" - }, - "2854f190a38e9b9c04cf499259c6577a68b0b5ed": { - "balance": "144000000000000000000" - }, - "288923bd91be164496e5378ee484f0e4c6c16ed6": { - "balance": "10137243270703000000000" - }, - "2897ff80794153edb721801fb91c6d8373c965f4": { - "balance": "10000000000000000000000" - }, - "28aa06e2290010374097aa2f87a67556d8d68083": { - "balance": "84783245638916000000000" - }, - "28b04ec8eb18b0c6a384f9d92cfb44d1d43ecb51": { - "balance": "14364248730194000000000" - }, - "28db0c000cad3a524bb68dfdd74ffd47b42fb13a": { - "balance": "43586590410000000000" - }, - "28ecd4c5fe98cff66a5b8423f4a27cba9634e2d0": { - "balance": "56106658052000000000" - }, - "2930822031420731f09dce572554a8b8c1eaa09b": { - "balance": "1170839742000000000" - }, - "295154c4522d7bcb2e24b7de9c543dcd1c5f51d9": { - "balance": "179028680906000000000" - }, - "296be4ef7402b00d7af673c1770a50162d7ab602": { - "balance": "8206640005889000000000" - }, - "297b84150756fa89101dd59750a7beb36fb8785c": { - "balance": "1168894124400000000000" - }, - "297cfb72cd1b8b2808fd1b25cdcf7d8de279ad96": { - "balance": "500000000000000000000000" - }, - "29cec0eca9f8508a1ba192a90bb6dee18c40745a": { - "balance": "260217025084000000000" - }, - "29d8f7e72bfa297f17fdce9cf8f4a398f547e200": { - "balance": "307787433251000000000" - }, - "29e14b01c59ba894dd090382fb193ea441164b90": { - "balance": "229028661439000000000" - }, - "29ed634e165084b720e446d28893dbeecd6a7018": { - "balance": "226530464200000000000" - }, - "2a0f8136d43248233f652fe579ef3bd2281dde24": { - "balance": "4007544428000000000" - }, - "2a10204a0c7c9f7701e33c1b71c9427ea16e2e45": { - "balance": "50000000000000000000000" - }, - "2a319ee7a9dbe5b832beae324290f7df6d66f516": { - "balance": "28127560161000000000" - }, - "2a50bfda2b06a9fb28c73f14aaff4f7ef865db65": { - "balance": "10483823413828000000000" - }, - "2a7b7feb145c331cb385b9fcb9555859c16820f6": { - "balance": "1017182951264000000000" - }, - "2ae076c36b18a60f1e3c05d434276a1e16f3f838": { - "balance": "10000000000000000000000" - }, - "2ae2e51ea2ee6a848acde342db2bf6eac927e5af": { - "balance": "494279795271000000000" - }, - "2afd69fac54c167e7ca9d8198a8de386f3acee50": { - "balance": "227162683047000000000" - }, - "2b08018d6e65a7b74ddb5ce1af99976a484b9f50": { - "balance": "16000000000000000000" - }, - "2b0c1d629ad2958ab91e31f351a91219fdbca39e": { - "balance": "113239399820000000000" - }, - "2b2bb67fe9e44165d2108676579a9437c760da30": { - "balance": "20000000000000000000000" - }, - "2b2c99e88e938d1f1416a408a7d0041a605bce16": { - "balance": "6118539729000000000" - }, - "2b5c97b6402ac189e14bbca3e7759319ca8a9222": { - "balance": "10000000000000000000000" - }, - "2b813339c7f818f578b45f17c41c7e931c7828e2": { - "balance": "842834712955000000000" - }, - "2ba6fc21f743968d51f80113aadfc0fdfe8499ed": { - "balance": "309973507270000000000" - }, - "2bb75b272b279cb54498f12b6805261af643c8b1": { - "balance": "1426727673809000000000" - }, - "2bdac062364abd9cf67ba7de214a2cceb0511033": { - "balance": "1090525272063000000000" - }, - "2bea658caa805241aa921f48c8f10cb49e16ffae": { - "balance": "1295499213027000000000" - }, - "2befe7e34299a7c1ad53fc9988ce77e2d9fab20b": { - "balance": "4326342236300000000000" - }, - "2bf466a83cd44aaf0f627606a1c954fd31deb782": { - "balance": "1388986370166000000000" - }, - "2c016a23890e9633fc17b0a8d328ec1ec7ee0113": { - "balance": "92483174342000000000" - }, - "2c45a87a63cc5c8c102d12b83bd9a3501ee41995": { - "balance": "394657687589000000000" - }, - "2c600a596368405e584f3b869f7fabef4ce54aa4": { - "balance": "9879984853585000000000" - }, - "2c7032da8b7816e16095735aee43d1c3f1c43acb": { - "balance": "10000000000000000000" - }, - "2c7275511fe06ee86663b3a618497168b35b0cdf": { - "balance": "10000000000000000000000" - }, - "2ca4074843e9519265447c0dd9ac84ddc2033c1a": { - "balance": "179612279567000000000" - }, - "2cac03ba2c45a6c8186bdceb095b7c5feced3114": { - "balance": "2022060470376000000000" - }, - "2cb8c2cd506b2d7b4cac88ce63230022d412c62d": { - "balance": "211378154058000000000" - }, - "2cd27561cf37ec229982dd592c71d1aab9c2d7d8": { - "balance": "42189968284000000000" - }, - "2cd2e85310a4fbb7f296c3d0d1cee07b191239eb": { - "balance": "1940327317417000000000" - }, - "2ceca4501c5f2194518b411def28985e84d42913": { - "balance": "25000000000000000000" - }, - "2cf7abd42394634689aa2a36d263a6345116b7df": { - "balance": "3553167226295000000000" - }, - "2cf88f29356c166df8383d3312cea10397e25150": { - "balance": "76961677759000000000" - }, - "2d0b62fe49592752cfebaa19003a60b8b39b1cb9": { - "balance": "10277397502735000000000" - }, - "2d2051887107bbd8ed45b405b9be6974a13172d9": { - "balance": "1928781992000000000" - }, - "2d2c9525e2811f4d1016c042f476faf23274aa31": { - "balance": "1000000000000000000000000" - }, - "2d2ef9e1c7a6b66d9a2994adb3ac4a9921408e69": { - "balance": "10000000000000000000" - }, - "2d3bcd18e5c97ddbf1cd28ab37eabe070e9a04d1": { - "balance": "323879852538000000000" - }, - "2d3e60496d0092a4efc665389a916be1a9f8b378": { - "balance": "161958437779000000000" - }, - "2d3fb0ae9b17d3a57d23549ae5500fbb163de25d": { - "balance": "25000000000000000000" - }, - "2d8106dbee6f728c0ff11887690a6370a7d9f5a5": { - "balance": "3102418708000000000" - }, - "2da48eeb788686811ac8270ef3baf0159fc47446": { - "balance": "252187695395000000000" - }, - "2da9d2a6f0b92651a36b05c5e9d2a717c6e166de": { - "balance": "500000000000000000000000" - }, - "2dad81b23d8447190259119019c04a4ef61ab91f": { - "balance": "53428719965000000000" - }, - "2db1faf35901e272aee74a2469a278fdaa6e6e18": { - "balance": "100000000000000000000000" - }, - "2dbae8e1ad37384ca5ff0b4470d3dbc73559841c": { - "balance": "10000000000000000000000" - }, - "2ddf9e23945c181b8592d7965e782068b4c38b37": { - "balance": "100000000000000000" - }, - "2def05d1f2abbaa193a219b87e5319c7ecd48dea": { - "balance": "51359946957000000000" - }, - "2dfd221f96a21e41ffe4dca67b15cd352fe9637e": { - "balance": "36000000000000000000" - }, - "2e1371fcfea9d8dc8e692897a91753400caa9c3a": { - "balance": "5199902650733000000000" - }, - "2e2e04945adbfaeec698ea0f5275f1ad5ffd3d5b": { - "balance": "42034514567000000000" - }, - "2e41f865cfbcf8b89f848405e04de9114087f4ff": { - "balance": "44875730962000000000" - }, - "2e530254768ce94db0ef1204ede0e12b3558e7eb": { - "balance": "14319506377747000000000" - }, - "2e5c43868f45de268967fb22f3f4107da401510d": { - "balance": "20000000000000000000000" - }, - "2e5d2e117d2ba9af9697ec023a4d10b5a2436902": { - "balance": "16000000000000000000" - }, - "2e6000778fb225ddb3e1a2f297d56774e85d9c9d": { - "balance": "10000000000000000000000" - }, - "2eb64b8ab13f0d7823158217d15ba310ed3d0e58": { - "balance": "58724606000000000" - }, - "2ec3973ff33a06d355ad4e8f73b657af8a5ed8e9": { - "balance": "1165606294808000000000" - }, - "2ed4362ea5edf510e210af733089b294f87e8f67": { - "balance": "427561040806000000000" - }, - "2ed8788f1c31b508e37079098a7337bff77b49cc": { - "balance": "10000000000000000000000" - }, - "2edbbe1e2ea482920c76a4ff4c14602b4d37c955": { - "balance": "294409476945451000000000" - }, - "2edcba2bd76128750c8aa00f832c62db30aa7868": { - "balance": "25000000000000000000" - }, - "2ee5abcc0d0d51d4b18947b5aaaa95d037be4e2c": { - "balance": "20000000000000000000000" - }, - "2f058187ef141c06c7c87da86cc1953d2fcf70fa": { - "balance": "9000000000000000000" - }, - "2f16b101da9986a18f4b0d30a26557860338c4e0": { - "balance": "254907899725000000000" - }, - "2f4363df2c61273d230071286bb0157dfefee2cc": { - "balance": "64000000000000000000" - }, - "2f6099a8cb7bc3713b87dab20994d8dc09342003": { - "balance": "1902400000000000000000" - }, - "2f7b3902ce56f74adb0f83cc7d3a99df440cca1c": { - "balance": "825246221388000000000" - }, - "2f7d0298ff6a363375b7eecfe754fca0963c8a1b": { - "balance": "101000000000000000000" - }, - "2fb7c16232b3b1f2e3a676d6d5c93ae6fe5cb14e": { - "balance": "1000000000000000000" - }, - "2fbd5ccc716d2f510d10ec84def3fa69e49f46ca": { - "balance": "1000000000000000000" - }, - "2fd84376be11772e5d072cd74c96b0d9a49c27fb": { - "balance": "1000000000000000000" - }, - "2fdab070e20e2c8923a24c196bec72c33ff0f220": { - "balance": "64000000000000000000" - }, - "3003e6007f69902a0f5e4b4e6d0468277897fc70": { - "balance": "1501210602075000000000" - }, - "30095e6a4ccd1ac2014c3d1d98dce003d775708e": { - "balance": "500000000000000000000000" - }, - "300e47e0fa556371f6c882eb98423be44de7c239": { - "balance": "9108837665958000000000" - }, - "3011231224920b62bcfcbf0aed4fde35dd0a4bdb": { - "balance": "374689586073000000000" - }, - "304be24debce62e70943efddd20457d34e85ab40": { - "balance": "81000000000000000000" - }, - "30912555bb14023e9b7c90aa2314721918cdf1f9": { - "balance": "10000000000000000000000" - }, - "309a94ca7b44bc84a7909ee2b93ed1c94eaf75a1": { - "balance": "39000000000000" - }, - "30bcc93965fa36bbaabcd781326e42227c4e1a51": { - "balance": "10000000000000000000000" - }, - "30c71fed91d24bff69f286ff8f0c6c02a21736a8": { - "balance": "409782329653000000000" - }, - "30cbaf4103757013fd8fb71c44a985939e212b86": { - "balance": "7424807960947000000000" - }, - "30dd59e66093d0bfd87b09c5f6588b9857e9a6f7": { - "balance": "26123006239871345154" - }, - "30f692235f254b02f583d5b515f4701a35c7f692": { - "balance": "148184457997000000000" - }, - "310763019a24a927ce42b00604ee664ca53ff6d0": { - "balance": "393757908273000000000" - }, - "3118a5d4d06ca8b7c8835f4860e6973228000ee2": { - "balance": "56188713212579000000000" - }, - "311adec5bfcaed44680691cc644ee120a484aa05": { - "balance": "169000000000000000000" - }, - "3124e387aa7023995643344c782dac84b9d8c7d4": { - "balance": "1393596696367000000000" - }, - "31379702391cb5a737db3f3ffc336bd03aaa181f": { - "balance": "10000000000000000000000" - }, - "3145606c3ccbaf337610185ffac14ac4f0583c0b": { - "balance": "196454968572000000000" - }, - "315e11501d2c57a62af1631fc2662d4d8745401e": { - "balance": "225000000000000000000" - }, - "31a785ad3eea177c59fb575cad0b44f9a48a12e9": { - "balance": "38039017162416000000000" - }, - "31ae64035e95c1205bf957afb5e1636df00dea3d": { - "balance": "1718600907000000000" - }, - "31c0bb22fd2e9d22984f248a16ec3ed9ad834517": { - "balance": "5982762676000000000" - }, - "31e73a3b5451ebe1163571e9e0567c425bbbfb83": { - "balance": "10000000000000000000000" - }, - "322543c74039ef61fd051021b5e6f16b54bc7c1c": { - "balance": "101346282441000000000" - }, - "3233c7ed11c25bfc41d506c3ae0daf5a3c7c1278": { - "balance": "20000000000000000000" - }, - "325dae17b5225f6734a02c677d43fd126bea89b7": { - "balance": "365067246683000000000" - }, - "326ce8166a4094b93c15557f50f2b1d47811e72c": { - "balance": "16641460224765000000000" - }, - "32cf76046ae48b609524b1a6203eb6296d04853d": { - "balance": "1094839482061000000000" - }, - "33456a28f36aa240262cf95b78b4ac2cd8aa77f6": { - "balance": "3077123488326000000000" - }, - "3348bce2ef90ffd6a59ef5079e1af84b2dd604a7": { - "balance": "9000000000000000000" - }, - "334e5f0ae77dcd3d32dfc2c4ec6ab5e2826dc4b1": { - "balance": "3176777762079000000000" - }, - "335775e19200cd0305e529bc4cdf7295a47cb2d3": { - "balance": "2945631571804000000000" - }, - "336ba81ea6ec4f0da38c1a1761ed3d97fd3ca28c": { - "balance": "3587379203826000000000" - }, - "339191e03e9d5a08ae7b58f4c860235a0721b5a1": { - "balance": "2732237722000000000" - }, - "3399bf9f94c5488c89450257b39fdf3ec8c7f413": { - "balance": "477423805836000000000" - }, - "33cb8556a6c6c867e1be7de591cb22c1b7e9824e": { - "balance": "62293494164000000000" - }, - "33ed633804f39367078e830328dd223254be3366": { - "balance": "22842013797896000000000" - }, - "3409025dce86ad441a5a80f30ce03768d37e40bc": { - "balance": "1381667933000000000" - }, - "34153174cd4d3f1eaed7438638d302f6414d5965": { - "balance": "50000000000000000000000" - }, - "343c6b82b13f0dc82d4269e2c806d2d58e6dde35": { - "balance": "9546969736042000000000" - }, - "346089ea81f7dcb79caf2444df34bd6ee78be4bb": { - "balance": "4344080889000000000" - }, - "34984a8f96dbbfd1f977826a4c2187482559a2e4": { - "balance": "25000000000000000000" - }, - "34a5cce96d2211feb04472260c4cd368bda8432e": { - "balance": "1240050112677000000000" - }, - "34c026a39e44955d1051e8669f9cc58a027455c1": { - "balance": "20000000000000000000000" - }, - "34d730652f4aa002a9f39a47212ca3bc47506b8b": { - "balance": "418050617956000000000" - }, - "34e1d8c8a32ce0f6378abb9bd05ea1f9bfdc5782": { - "balance": "20000000000000000000000" - }, - "350b228870445141f4417ea5dba4f009d693b96c": { - "balance": "76995849736776000000000" - }, - "350eaec708d5d862831aa31be2c37b2fdcef97c6": { - "balance": "258753545822704000000000" - }, - "351fc1f25e88b4ccf090266ebb408593418d8fde": { - "balance": "10000000000000000000000" - }, - "3523ac7a6e79162bb8400bf161cb59389432aa51": { - "balance": "436606776923000000000" - }, - "354d490095e79a29bda2fa11823328450f14333b": { - "balance": "50000000000000000000" - }, - "355a555a36e319e76042e62875a15e1db3012b86": { - "balance": "20000000000000000000000" - }, - "3568840d0a26f39248ab088653ede831f150ce29": { - "balance": "16000000000000000000" - }, - "357096b9c1c7c8d51b682ed3c43d150f55629ff2": { - "balance": "900090781248000000000" - }, - "3588c47ba9204b672c456ee9b5c1ae70f3c738ac": { - "balance": "10000000000000000000000" - }, - "3591edeb9c036e871b4fc6fb3ae6d42e0c0d7203": { - "balance": "1000000000000000000" - }, - "359d92e3e8757a4a97187a96d408c0c11f5c7eb9": { - "balance": "22330509101591000000000" - }, - "35aac2a948f316ba93ed111ac127e29ee9a3adb0": { - "balance": "364387817746000000000" - }, - "35b20459a7daa5f44ae423fd4a1b451ea5090b09": { - "balance": "20000000000000000000000" - }, - "35cdaa84c1f3bc2673bc0c60222c133bae0d3db1": { - "balance": "15234182435000000000" - }, - "35d554233ca690130aaa43501e121a208c657226": { - "balance": "10000000000000000000000" - }, - "35ed399940ece44d01ac873b9c0d3212e659a97e": { - "balance": "55000000000000000000000000" - }, - "35f164612afc2d678bb770f317085ae68cce19bc": { - "balance": "693763596328000000000" - }, - "3601b36cb475101d0d0976a8de9d38e5f3483a08": { - "balance": "1000021000000000000" - }, - "361368bc42c8daf365bce9f9ff3b611373d7b690": { - "balance": "21658400518000000000" - }, - "361bc43be077a269e3e37c11e91479017c47f847": { - "balance": "268900383140000000000" - }, - "363c7a2203f6f93287de091bde3c87eb6800e7a7": { - "balance": "20874859005000000000" - }, - "365dc06856dc6ef35b75b1d4eabb00a7220f4fb5": { - "balance": "30000000000000000000" - }, - "3660e246bce68e2b6e4a802681f188587d2c1c99": { - "balance": "55000000000000000000000000" - }, - "366868ef8e193d7e649ee970d476e6774d5ff1ac": { - "balance": "2544456626840000000000" - }, - "366f7f762887cfb2d09cefa4a5108cf390bdeb41": { - "balance": "26837527714000000000" - }, - "36759f9c92a016b940424404de6548632c8721b1": { - "balance": "1033159825798000000000" - }, - "36a939be88508646709d36841110015bf7cedd90": { - "balance": "144000000000000000000" - }, - "36adca6635db6b00d28a250228532fe560127efb": { - "balance": "3370820618318000000000" - }, - "36bfaed8099ee9f216193ade26d21656c98ce4b5": { - "balance": "1353728563832000000000" - }, - "36df854d0123e271529a8767d1cded4e7b5f31d6": { - "balance": "10000000000000000000000" - }, - "36f59989a902cd10725ff7fe2cab1689aa4e9326": { - "balance": "20000000000000000000000" - }, - "370d6999ae70e781c81d12dc259ea304183b01eb": { - "balance": "45563989086590000000000" - }, - "370e8af59a64a3171b422913921a1e2f982dd512": { - "balance": "170263356254000000000" - }, - "372e01083072214134018f50bde3c8ac4f6e071d": { - "balance": "1400474252324000000000" - }, - "37410fda52f94185d824258ad5f3c9ad9a331257": { - "balance": "11830521097085000000000" - }, - "3752b7e1628275522cd693307787b9564501d959": { - "balance": "67839627078000000000" - }, - "3776f82701c384ce6cbf6a8fea40772cb882b66d": { - "balance": "50000000000000000000000" - }, - "379f63e538168925ba6313f9a6a3b6e7f0e8ed52": { - "balance": "292876625446000000000" - }, - "37a24c1a8080ab429a136c5582782b276eaa931f": { - "balance": "6099055841000000000" - }, - "37abbeaf24b5e6264c87633734852e243d377010": { - "balance": "1051360014489000000000" - }, - "37c50cecab8fe9dcd81aaede95050d27c53f4d45": { - "balance": "106051638566000000000" - }, - "37f82962c3097f0cd9ff605db66e792025a540cb": { - "balance": "10000000000000000000000" - }, - "382ba1e6c53cd7b9c360ef894962d281d557561f": { - "balance": "216789631461000000000" - }, - "38309b458993916efc1ac8b0b5d41302fec21095": { - "balance": "999139000000000000" - }, - "3847f25956a97a32caac059fd9e4cdc105756e25": { - "balance": "876497264905000000000" - }, - "384fe5f399638d277d4fb93f26d527497939287a": { - "balance": "280035151914000000000" - }, - "388335d8b92b445b1b19a3107547bb6ca7c0763c": { - "balance": "167140942784000000000" - }, - "3894a1e65973a542101caa4dc01e9553a5521d63": { - "balance": "34262479791000000000" - }, - "38a0e019c6120a19acaf0e651dd8338982cdaab1": { - "balance": "153843170492000000000" - }, - "38d4bdb10819a7d4ae9a32f4abb82402dff319b5": { - "balance": "1471131830647000000000" - }, - "38e56a55e2ac8320a480562f4a7cea9220306ee3": { - "balance": "907464312139000000000" - }, - "38f18123f3643e03d24ad759afbefc90ed923a2a": { - "balance": "943729130798000000000" - }, - "38f764c861def6d5d65e5ec099536f4cfcc3af55": { - "balance": "20000000000000000000000" - }, - "391e12b51fc85fb879a72fa746ca06c7a5659e6c": { - "balance": "9000000000000000000" - }, - "392342dc7b475c3975877a41622be0fed8e386be": { - "balance": "218719857770000000000" - }, - "3944cc960b8f1993ad841629a79e53d0535a88c8": { - "balance": "210571656485000000000" - }, - "396219864b8cfb0ffb3c675690ccd7026424ad4b": { - "balance": "138984508746000000000" - }, - "396403f26b388150b4876485b124a49845101464": { - "balance": "10000000000000000000000" - }, - "396f1e0f9e7ee86d1b2159ab8f9353677d12d340": { - "balance": "121000000000000000000" - }, - "397cc9f6254d56c721c767e41628a9078bea878c": { - "balance": "225000000000000000000" - }, - "39878b0c7049fb179aba0015279eff6cc3136816": { - "balance": "33962071375000000000" - }, - "3a06b58d0cceee5b091fe6aeb0fc0db5774e9395": { - "balance": "272033811720000000000" - }, - "3a3330e0152d86c5aa1d9bdfe9e1697645d3377e": { - "balance": "2165107207206000000000" - }, - "3a3bb8ed3130e09fbdfc21db3571d4711fc92d60": { - "balance": "885484658836000000000" - }, - "3a4ac96c489c864765cb1997a0084ba745b67a87": { - "balance": "1257436384863000000000" - }, - "3a69e1c351978ced418cea6cee019f220bcb065f": { - "balance": "579242822216000000000" - }, - "3a76a23d81929bed05ef7e1982d32b456e62aa7c": { - "balance": "1027078338792000000000" - }, - "3a7beadd1e11d0e3326c0dcd0f670530612931a5": { - "balance": "20633069818937000000000" - }, - "3a867c44d0dd06517a82ad467d0aefd7f11ce729": { - "balance": "12323708574000000000" - }, - "3a969ae486215e24c7ab89e38929562e2f85d923": { - "balance": "18955477335000000000" - }, - "3ab81366d898a8b798afb08a4b722ab0eb883652": { - "balance": "1220090012596000000000" - }, - "3ac1e14ed5929d382f6488c5444e717373ed29ba": { - "balance": "2030543873000000000" - }, - "3accf4b8ef20e4fea983f13f99ab257a5f9e988d": { - "balance": "156030342415000000000" - }, - "3ad38fa6e3c078025794e213d9dcc5aa397050c2": { - "balance": "36561766773000000000" - }, - "3adef81b2c861ae39c418d55be99aee2306e29fc": { - "balance": "15752410974000000000" - }, - "3b21ff4d5801d3976643899f195fbfd1b72a50b3": { - "balance": "8971221745646000000000" - }, - "3b2f2635dd428ac0b5873088a9a81800f09d6e02": { - "balance": "56922872447000000000" - }, - "3b39919c7bc8d0afec792288c56ab7f4934dc7d2": { - "balance": "1678237240464000000000" - }, - "3b468d9d5546810aa837c29ccb8349548b0e8170": { - "balance": "1100000000000000000" - }, - "3b83d1b651f117f1559a19b04ef408619c2dc4a7": { - "balance": "53628552066000000000" - }, - "3b9a72201bb1e8e678e36129cb1570e3ac99270e": { - "balance": "25000000000000000000" - }, - "3bcab1535b04a0a3fbb673bc41fedaa80bf7901c": { - "balance": "1526488015042000000000" - }, - "3bed42c3d0c49ffac87b9d482f6338fdc9e3880e": { - "balance": "26189771073000000000" - }, - "3bf736b57f0ae47f3714a6bb852090a543b9d367": { - "balance": "652395174320000000000" - }, - "3bfd481651956105ed909eeb98be404ec5ae77e9": { - "balance": "177520143473000000000" - }, - "3c0a12a327545b5f8b7b5c1f7a1ec6a341ec9578": { - "balance": "4184342789398000000000" - }, - "3c132698d59927fe08cba433a41d08acc96c0edd": { - "balance": "151913899135971000000000" - }, - "3c27bd92c4be1a19974ec773bd20b13afe582c9f": { - "balance": "10000000000000000000000" - }, - "3c2ad171573a608286f1fa3f5ef9e6099823983e": { - "balance": "3240802189194000000000" - }, - "3c4b5e808b9fb8baab1144b981b6cd53e216fcdd": { - "balance": "61214114118619000000000" - }, - "3c4cfc6ead044819ceb41c1c64ceda1a228af801": { - "balance": "9000000000000000000" - }, - "3c553afd45535f7c2a70c701d00890e607b96ffe": { - "balance": "2678827200938000000000" - }, - "3c620d55268c55b6deea3b7dc7f59dbe93b6e141": { - "balance": "55494311990000000000" - }, - "3c9b204db23b902d4295e6aba3405917efd59449": { - "balance": "55543672571000000000" - }, - "3cf233b7730a175d05a861318b7bb917bb5bee06": { - "balance": "1867187351033000000000" - }, - "3d292272992397ed5f27d5202da693128d023d35": { - "balance": "79770828413000000000" - }, - "3d353cfe84e9a93aef90547fbeb6e4b4bef83069": { - "balance": "36000000000000000000" - }, - "3d54da4ddd0621822a114581ecd15572e6488be9": { - "balance": "1623867132383000000000" - }, - "3d62ddc67d366fb055eaf92c936a6e7df5085454": { - "balance": "124933526793000000000" - }, - "3d754df1151b9b62a6ed48b477225121c29af063": { - "balance": "50000000000000000000000" - }, - "3d79d1ebd5224ffdc13e27924ab7f9f8e3452ec9": { - "balance": "520163228474000000000" - }, - "3d84fd9785a6bd3148847038c6f1e135042a892e": { - "balance": "10000000000000000000000" - }, - "3d9574c3860f30bcb42523a0cbb08aa7dd83e733": { - "balance": "15259904884000000000" - }, - "3da809a5911ccc77f892034049a97a9022c35e7d": { - "balance": "1415009021101000000000" - }, - "3db9a6c6ab3d0cf6d3bd7e04bdad39b4d419ab13": { - "balance": "9999781764000000000" - }, - "3dc7367c3218f88de8867c425f89102d2f2056f4": { - "balance": "10000000000000000000000" - }, - "3dd273dedb28824d1309c7d60a0744a6b6353e79": { - "balance": "9000000000000000000" - }, - "3dd6b25eb91dd2f3468e0786e8beb465abe7f515": { - "balance": "275172962210000000000" - }, - "3e0d14f83b304136311a33bbac2720c0cd66f117": { - "balance": "3390479675000000000" - }, - "3e15e947ee76f52f0f2a7d84da7c4ab060eb5cbf": { - "balance": "6751398714759000000000" - }, - "3e1b5469e1da4ec27537513f4df3f1a338a7dc2d": { - "balance": "161899580000000000000" - }, - "3e3329bcc90e47e4dabb5c93572b18b5e0efa024": { - "balance": "10000000000000000000000" - }, - "3e5a585ad0f34d78899433edaed574af052616f0": { - "balance": "910225655353000000000" - }, - "3e6be9615713bb06198bf354ef434a9db649699b": { - "balance": "783525278181000000000" - }, - "3e7c7c082f2f99b1ad579400a2e93586a24ed992": { - "balance": "159035553843000000000" - }, - "3e86ea5713f90022c0914fcc25e97c39487eb957": { - "balance": "101867287023438000000000" - }, - "3e9dabab6e50a696edfba6bcd44230d087c8d04c": { - "balance": "3315882414579000000000" - }, - "3ed956f86fe78223c86e164e4f372c9a0bf4a279": { - "balance": "119959915220000000000" - }, - "3ee87e776fb12e9c894e36fd5a61daa984e8a5cb": { - "balance": "50000000000000000000" - }, - "3ef1c8f294443f776a794563ce7569a8fe4d5d20": { - "balance": "25000000000000000000" - }, - "3ef6a396d6611df6c79ec1e6ad6bbd253917fbe9": { - "balance": "10000000000000000000000" - }, - "3ef727346fc631ae6473e9a36e2e5e54df696195": { - "balance": "121000000000000000000" - }, - "3efdcf2c0998637cb82d2b5fc24f27162578d207": { - "balance": "1054861112990000000000" - }, - "3f2cb2335e2bc07744175c497e2f437e87c2a146": { - "balance": "48999979000000000000" - }, - "3f4d16663a4f76ade93eb8bd6ca8fe2158e24322": { - "balance": "237117597268000000000" - }, - "3f7c5e6aea7f3f74d764df50f0fc1aa758fc99a7": { - "balance": "63372222562060000000000" - }, - "3f92239fdb41c6ec228252248c2db3f23675e275": { - "balance": "28538064487000000000" - }, - "3f9610454b621c04f00f01f4d54046502edb21fb": { - "balance": "16000000000000000000" - }, - "3fcfb30cbfe53c0c43f58c28386d9a6e5b49f7cd": { - "balance": "79080579219000000000" - }, - "3fda0c9a3d3f0000635376f064481d05d1b930bb": { - "balance": "10599947385000000000" - }, - "3ffce0475430de0bd9b09a412e404bc63aa28eea": { - "balance": "10000000000000000000000" - }, - "3ffe7583b568448ded5183e1544bca0d283680d2": { - "balance": "1076944549283000000000" - }, - "4003a137e577351a4ad7e42d1fc2d2cf1f906b6f": { - "balance": "25000000000000000000" - }, - "40215fc4c6300d8d8179383d9028fd2d909c6cc4": { - "balance": "3941346079000000000" - }, - "4027d7bbfa5d12c1ab9d08933a1659ae8dd023ee": { - "balance": "1156537386462000000000" - }, - "4039439c960070394dbda457726d97121c7b3669": { - "balance": "4444061364102000000000" - }, - "405978c24a12d930ada6163a44fc4a70c16569e1": { - "balance": "707298643296000000000" - }, - "405d2c1b55ba3f67c8634456b99c19092b407a10": { - "balance": "1462185951849000000000" - }, - "405ddfcf45005cf5a0ee1bfa605a7346a0167945": { - "balance": "88775535985000000000" - }, - "405f72a6940acf5d36a29498075f2d0d7a75bc22": { - "balance": "402796678569000000000" - }, - "407253b005ae97857f812fc60d441e5367b4bac8": { - "balance": "1484147810895000000000" - }, - "4091e1fb1c7af51a64c201d6a0c8f0183dfb7ca5": { - "balance": "10000000000000000000000" - }, - "40950bad9580d4b111955da7d3f9ada26dd9f05a": { - "balance": "500000000000000000000000" - }, - "409a28106192cae7a76c6aa8add0f73dcd63d2c0": { - "balance": "214832616721000000000" - }, - "409d5b872b059aea9a773e854f9a17ed2d5c2ef3": { - "balance": "64000000000000000000" - }, - "40a6e3c753b04c42fcf89cc30df8f50418caecb8": { - "balance": "754228409494000000000" - }, - "40e5ce1e18c78d6c792f46ed6246bfb31bcdb6af": { - "balance": "500000000000000000000000" - }, - "4121692a14554ddca1ca662fb577d7152d4fa7d0": { - "balance": "49000000000000000000" - }, - "412acb10c8ca937ddd64cf0d413b1dd34760f72b": { - "balance": "6073360870000000000" - }, - "4166a5c94d5ae48ced410f950d40656182bf8990": { - "balance": "55000000000000000000000000" - }, - "41752b7d0d3ee58a6b69d8ba721c0894ff701237": { - "balance": "585556720807000000000" - }, - "417c86d6bf734e99892a15294230771bbfd7e1e1": { - "balance": "38233258264000000000" - }, - "418414498f7361b29428c54732e1f49fb394f813": { - "balance": "2063786326155000000000" - }, - "41a424dcbff6bf31686f5c936e00d21e8a4e0f78": { - "balance": "33554754580438000000000" - }, - "41a893429d5f8487c1866b87779155d4bfe33198": { - "balance": "20000000000000000000000" - }, - "41bbedd607fa576d130305486824cd2871bf6b05": { - "balance": "649728993301000000000" - }, - "41ee42c1fb1bcdc9c7a97a199fdcf9b63623521a": { - "balance": "7906012418597000000000" - }, - "41feffaf56d1712af6965fa6eee1b06bd624e7b8": { - "balance": "49000000000000000000" - }, - "42107e765e77ea76b3d6069d3775bc3aef7d692c": { - "balance": "25320783684183000000000" - }, - "421f4dab3240e15a1c78e3ce8642de9b578b8e4a": { - "balance": "832511242936000000000" - }, - "4246c52c3601541a873d4bbaafedf28b9bad5b73": { - "balance": "10000000000000000000" - }, - "424efe1ba28bb1aeedc38a3a5135547d0fe80751": { - "balance": "25622294162729000000000" - }, - "424fb0a3ec325bf42e7edbef7e450f2ffd1cf318": { - "balance": "20000000000000000000000" - }, - "42714c04d17f6c29029daf7f50d1cbad6590cfad": { - "balance": "271755674161000000000" - }, - "42b66e9123d304b70fef3dbcfe8587fd6189b5c4": { - "balance": "1030481609000000000" - }, - "42dacbc412b829cb304ffbc316b3f81b379bfc80": { - "balance": "304208485736000000000" - }, - "42e3d9832c8b6cdea39c97525570391803dee276": { - "balance": "2581020833000000000" - }, - "42f757898f95c1b46f64a4a6b7f86ab03022d672": { - "balance": "100000000000000000000" - }, - "42f7956fd659e00d3be2f3d1d4f3ed187aef04d6": { - "balance": "50000000000000000000000" - }, - "43160b2bc00f7f8f7fc806e2f6e2ffdc62b3a651": { - "balance": "1000000000000000000000000" - }, - "431b77cdd067003eeed26c1aee32f67fb94f7092": { - "balance": "902514849986000000000" - }, - "434e44583786e354731bca250d94ef0d8860a538": { - "balance": "1187789683866000000000" - }, - "434f1b9b193c88bf58685124aac0167fe69f9014": { - "balance": "500000000000000000000000" - }, - "43535982688844fa703cb9bd5723790cab364049": { - "balance": "100000000000000000000000" - }, - "43559f405590592c254e427fa25f03e774d8defd": { - "balance": "6913200000000000000" - }, - "435c08c481d59308a64afec0d6f936321bb120bf": { - "balance": "9005920819593000000000" - }, - "43629748a92b846f21f637aac5103412fbabb9a6": { - "balance": "1177513692845000000000" - }, - "43650b37552882d225ccc977aa2b7a86a4ca9bb1": { - "balance": "16000000000000000000" - }, - "4385de394371d26a45f18e8b3842effd015027bf": { - "balance": "187331693412000000000" - }, - "4386ff9648fe420503c9a36fe7b97c079de3b770": { - "balance": "2714401478778000000000" - }, - "43b370c4457cf39a3be86cc00c2b27614ca6e638": { - "balance": "8316429850934000000000" - }, - "43c464ea740172fe6f4f09974106fd24029837b9": { - "balance": "129643160399000000000" - }, - "43ddd2d33dcb7e578f4e59ad6b9c61a24c793aa8": { - "balance": "500000000000000000000000" - }, - "43e0f8065eb7faf3bbd13bc7c5d5d8f5ff1bdac3": { - "balance": "4454324716300000000000" - }, - "43e96cd065d7934b246d0fec8cd2dc6b36d56d7a": { - "balance": "81721481452000000000" - }, - "43e99acabfbdc6cafee3afb12fa7ed1345370b2d": { - "balance": "4595292398872000000000" - }, - "43fae764c7555b859b93d2126edfa59cfbf298b5": { - "balance": "105746805109558000000000" - }, - "44052eb938c02776b5240f38ec99f5ef51ef0d87": { - "balance": "38446396949881000000000" - }, - "440fc7621cc17f121f0bdf2a68c5be2c3af4fd3b": { - "balance": "1026958147051000000000" - }, - "4440ccbc77249a4d891d9ab5a5f2026b17aff7c7": { - "balance": "10000000000000000000000" - }, - "447f3f702c13a3fbdc8675c6285702b5aa2b66bc": { - "balance": "1089533398014000000000" - }, - "448f152be153fdb0497403f70e37d876946a5021": { - "balance": "614429461682000000000" - }, - "44a1e3a044f5d1fb00f4beb3772a3ee08d8b7093": { - "balance": "1000000000000000000" - }, - "4515edc7154bedd7143b69a04c4e738f8aa4ab18": { - "balance": "10000000000000000000000" - }, - "4572148fe5ea9d4795e1f1ed93097aac1d70991c": { - "balance": "2873782218000000000" - }, - "457581f223b8eacd757abb292613e317d6f59305": { - "balance": "3582446780073000000000" - }, - "45b450961882850f7038d5cdcd2a8fa2dc4b5469": { - "balance": "20000000000000000000000" - }, - "45bdfdf3840d4341503cd7fc87e4b66f6179e5fe": { - "balance": "10000000000000000000000" - }, - "45dd9baa87b3c94df66308d8ed4f3a5bb65c3dcb": { - "balance": "25000000000000000000" - }, - "45de332b8ee95d886cf11b99291b46f46c1ddd45": { - "balance": "36000000000000000000" - }, - "45e06afdbc70288a2cc55bccc4fb2d8195aea028": { - "balance": "790360485306000000000" - }, - "45fce5fd1acb2bc5507723c897cb340437e39735": { - "balance": "100000000000000000000" - }, - "46045cddd940d80596826ce5354489b3047663bb": { - "balance": "100000000000000000000000" - }, - "4610286f8a2649dcfbc6d91735745f418a6abc75": { - "balance": "10000000000000000000000" - }, - "4615905ecc6f7df0ccb7b86a3e1d3770adb2f874": { - "balance": "1000000000000000" - }, - "46256e00ff927d54b0ca139ddccac2148784273b": { - "balance": "10000000000000000000000" - }, - "465e40e7d129ad310fc60ff0f17c0f968611118f": { - "balance": "677971225649000000000" - }, - "4664a920f7fe9b0d78a665e1a4aeb95f287d6059": { - "balance": "20000000000000000000000" - }, - "46679de1c6143138fd9c44ff05853a52371915ff": { - "balance": "363627463229000000000" - }, - "467cdc210ae48ba99740d37ee79fa57c4216bc81": { - "balance": "10000000000000000000000" - }, - "468053d193debb88735571acb24b764f2676272e": { - "balance": "49000000000000000000" - }, - "46826d1f1418abbe4e7b9236d643e5b57a0f0208": { - "balance": "37752144164916000000000" - }, - "468df2ea57972ddeb88d470a5f3c2c0e2284ac17": { - "balance": "757320434551000000000" - }, - "4695ad5b686520ee8426d24b50ff7a5f0d703443": { - "balance": "2851082366000000000" - }, - "46a149bc8ec2b85fdf938f753a6c53777dcca2b1": { - "balance": "10123698633000000000" - }, - "46c081440f760a21b74c2499bdda13aef8245930": { - "balance": "180752319265000000000" - }, - "46e615324f6e4fb242f9bfecffc0c802ba7733c9": { - "balance": "10000000000000000000000" - }, - "46eb54f09dbdaaf3b97a1f79a3d82ee2e902b3b8": { - "balance": "3430510380318000000000" - }, - "46ebb24b04919ec0164f0bafcebca2309f2d3035": { - "balance": "129155832233000000000" - }, - "4701f9fe78111011f820fe28c47522e601655678": { - "balance": "9000000000000000000" - }, - "473f44e2c1d5d7aa53cf7041d7ad19a0d9eaf1d8": { - "balance": "162679637505000000000" - }, - "474f8bf4d03a7efa4d190905ce062eea7c75118c": { - "balance": "1259904506149000000000" - }, - "47598330e862a4f7cbda8be74ac10cd5d370a55e": { - "balance": "291763101699000000000" - }, - "476455d48fc858a06bd7854fcf1bd60bcfde9ed3": { - "balance": "10000000000000000000000" - }, - "476826d58192ad822f4686311d6c6d4d4f66ee5f": { - "balance": "453184657722000000000" - }, - "47a231eb3fdbc24f2d008f06228624b2a45ae5fa": { - "balance": "1000000000000000000" - }, - "4805f4c0eb1c83c436118ec9148019e5fc1962e3": { - "balance": "1311161626928000000000" - }, - "4809f373cdd56c8481ba3bce5a401d55a7e50a50": { - "balance": "2284845194349000000000" - }, - "4839bf9ad56873abd5695057bf71972806cde827": { - "balance": "42264923611000000000" - }, - "486dba2a47decabc9a85d1d64d74687983ab273b": { - "balance": "49000000000000000000" - }, - "4877993f5ecf02451f8d4591594cb2f30dcf9f26": { - "balance": "100000000000000000000" - }, - "489723e325f609e27be14528c4111fb3eec13f7c": { - "balance": "2489030141000000000" - }, - "48b710d16e9da736b773453089d69cc6ede116b5": { - "balance": "26651593216000000000" - }, - "491088e1e4b5c3d65870f2deef9be6ec3dc6c7c7": { - "balance": "1446809481953000000000" - }, - "49174451320ad2e14cb2b05ecdd251b75ace3038": { - "balance": "15533380764616000000000" - }, - "4956ead915594b621131b2fc2dbbb49ba43c5559": { - "balance": "1175638488000000000" - }, - "4973a0d32147ba89f525a18f989518dcfce93b0e": { - "balance": "522848489444000000000" - }, - "498c6f9063705054fae07260d4176c3d55a97650": { - "balance": "732941433000000000" - }, - "49991f68f2a76bd1cffa3e9721be36f3fd8351b8": { - "balance": "17742568700019000000000" - }, - "499a8af194e0040f349e893937fe3858f8267fca": { - "balance": "80704784160862000000000" - }, - "49bcbb7b263febf54f8ff498525bac8e7241f966": { - "balance": "603044032468000000000" - }, - "49bd72773656c4e1a4d16284aea2fb05546d2b31": { - "balance": "1896607093054000000000" - }, - "49bf80fcdefebe8cd4830ba09e46ccd7231c8e6f": { - "balance": "10000000000000000000" - }, - "49c9d82dea78f14b1c52efc0196b67f508f7859b": { - "balance": "2313040051399000000000" - }, - "4a2daeacf0468d137e3bc464d6d5fa3893a9136b": { - "balance": "10000000000000000000000" - }, - "4a6c428f245e8d9115b34764bab17eb86ac472be": { - "balance": "10000000000000000000000" - }, - "4a6e8d037acf1960dbbf14e7a02fec0ac656f9c1": { - "balance": "6516295825438000000000" - }, - "4a7e7fc3c72f2f9b92bf0dcd5297cfb19f077d7c": { - "balance": "99426213999999999" - }, - "4aaa6817a5000bb7596e000135b3051c5931e7c5": { - "balance": "102884105546478000000000" - }, - "4abcdc3d7d3d314a163da92aee53a56b87313a2e": { - "balance": "44402243657000000000" - }, - "4ac9385ade2377b061f4211b392ed6a6e7fb83cc": { - "balance": "1000000000000000000" - }, - "4ac96e1e26cb66ff788ed8c62db811d7b4fdbc74": { - "balance": "68476115774000000000" - }, - "4b10c247caf33fb872d9bf86572424410aa86752": { - "balance": "337915294240000000000" - }, - "4b23ffff1894df49005c7afc0828880924571299": { - "balance": "169848767272000000000" - }, - "4b486895caf3a0b5afa198df744de7082eec8666": { - "balance": "1672587376054000000000" - }, - "4b98fc960610573be456c0e1e319f4f863bf9095": { - "balance": "259382246718303000000000" - }, - "4bc0cc483be20223f40ed6deef63dd9645c216c4": { - "balance": "4322684620000000000" - }, - "4bf4a046afdd4ec9d0e50730ff6ded5ef2327442": { - "balance": "70601389160000000000" - }, - "4c0149058e2e74f7c900e6d6e5fa12eea882c5e0": { - "balance": "2017399852886000000000" - }, - "4c17a3997fb70599794d01a33a27a6d5b52b6f01": { - "balance": "469002093209000000000" - }, - "4c4559e7b32340dce112cf7a021ced1b113f6dd9": { - "balance": "25000000000000000000" - }, - "4c4f02b3f232b8ce8485d425639271510cd0486f": { - "balance": "68828038140000000000" - }, - "4c52ec56142bb6e8c8830e5c17b01b5165915f3c": { - "balance": "321766233041000000000" - }, - "4c58defa57875e709ca039a54a2be5aed6672f6d": { - "balance": "121000000000000000000" - }, - "4c5a886ab90b6bac68677a7eb92a06bf33ff2930": { - "balance": "236899852150000000000" - }, - "4c60539363edbd812334a54543c40ecab8af2ac8": { - "balance": "3281904094699000000000" - }, - "4c76897d0d5d39195354194710c5e7f99bef63d1": { - "balance": "10232271258305000000000" - }, - "4ca3c03780c20a64f3b5ebb75669982a71ee8a71": { - "balance": "377172198976000000000" - }, - "4caf77eefe062a6f053a464171bc75254b47f52b": { - "balance": "20000000000000000000000" - }, - "4cb7d7ce805e56f6e47e94cd755b6d97f8f996a0": { - "balance": "120998866000000000000" - }, - "4cd34f8f3299d3b7aaee180baa0b432369e1b3d6": { - "balance": "197088135242000000000" - }, - "4cd7aaa5415d809f405f520e4c0319a6029b981b": { - "balance": "686627368232000000000" - }, - "4d01067555f1ef63883f25c562b07168f79fa80d": { - "balance": "17547055698000000000" - }, - "4d2cb4c1da53e227b08c0a269402e9243a13f08d": { - "balance": "324000000000000000000" - }, - "4d38bb5f48ec37b751d16de32a4896fbda479ce1": { - "balance": "802530078718000000000" - }, - "4db3e76e2f68896cecc9826e10a5e09df0352c28": { - "balance": "555180306924000000000" - }, - "4dc8730d9f032d33dc493bcd3c6375b38f41afff": { - "balance": "5726933881000000000" - }, - "4ddde96556f5185a13617f01ebd9102800bc9e9c": { - "balance": "1181822708402000000000" - }, - "4df9359cb204bf649668ff8086a7f5e24709083c": { - "balance": "262998978400000000000" - }, - "4e0a1a3dff0d33c418758263664b490140da9e01": { - "balance": "100000000000000000000" - }, - "4e0dd6d8de5caa3a3bf9fdd6f2d7b30618623cc0": { - "balance": "10000000000000000000" - }, - "4e11af85d184b7f5e56d6b54a99198e4a5594b38": { - "balance": "76658631121000000000" - }, - "4e314349abc52c686d47dc771ebc8040966be386": { - "balance": "632341985941000000000" - }, - "4e3fb09c35375106bece137dbe0e5491e872871b": { - "balance": "153648535396000000000" - }, - "4e4f0d606f7065bfb1545e60b5e684ae1934e055": { - "balance": "48998635468000000000" - }, - "4e50957aa6c91c548075add8ec625b74c0973abd": { - "balance": "1000000000000000000" - }, - "4e5c6efa76493f0e9422582016aac50539ae60d9": { - "balance": "2078967343000000000" - }, - "4e70bbcb50c4e875fd573dcb694908abf3b30b37": { - "balance": "20000000000000000000000" - }, - "4e7f5670a7dd168a0803e53b8bf72f4db280e3ae": { - "balance": "1658463113665000000000" - }, - "4edaf859990a10977bf378df45b32f93422c84b4": { - "balance": "121000000000000000000" - }, - "4ef41923a1a426772832d3c267adbd84e5994edd": { - "balance": "5432615017384000000000" - }, - "4f11a70d80f36f46ed0c2a5fff1a39b711f3bae5": { - "balance": "8415785077000000000" - }, - "4f159095afcc75b8f5cfc90c9d07a0d77ac8ed69": { - "balance": "25000000000000000000" - }, - "4f2652322736cc18b24af582d4022fe329a9dfb7": { - "balance": "9000000000000000000" - }, - "4f328173f352f3dfdca0ff5e3185f26de77c6f75": { - "balance": "10722917874680000000000" - }, - "4f47a62aba6ea049fc0e92d8afbe1682472d98bf": { - "balance": "10000000000000000000000" - }, - "4f4c3e89f1474fe0f20125fae97db0054e9e14e0": { - "balance": "50203638983000000000" - }, - "4f5ac8dfe79c366010eb340c6135fbee56f781d8": { - "balance": "50000000000000000000000" - }, - "4f672cbd373183d77d8bd791096c6ebb82fa9a2a": { - "balance": "978111227765000000000" - }, - "4fb179c9c88decaa9b21d8fc165889b8b5c56706": { - "balance": "24750205150000000000" - }, - "4fbcf391c765b244b321875d6ab4381c44d0747a": { - "balance": "99999580000000000000" - }, - "4fc979b38b981fca67dfa96c6a38a17816d00013": { - "balance": "1088876196468000000000" - }, - "4fdfdd1832b114b4404aae23305c346beee14e1d": { - "balance": "278724179057000000000" - }, - "4feffb1836029cd0e9b8f4aa94b35ae3982fa770": { - "balance": "1674590934924000000000" - }, - "50045745a859f8fce8a2becf2c2b883b3723b2c8": { - "balance": "169000000000000000000" - }, - "5028bde29fe88e03e3de069b3907fa9df551c379": { - "balance": "196000000000000000000" - }, - "507096ed771fa8a1d004ee5377c01506df461b32": { - "balance": "2669205000000000" - }, - "50788574a0967580fdaddc4758f834d8978455f6": { - "balance": "1648581593000000000" - }, - "508d8e8f338ca98d3c09f0f15fd9e7baa80701e8": { - "balance": "16000000000000000000" - }, - "50a4dc916845172b83764a6c8b4b00d6d02d41d3": { - "balance": "3020744393592000000000" - }, - "50da06418780c220ced4898af0b1fca533f73cca": { - "balance": "36486700700823000000000" - }, - "50fb6fd8432a66219e754234e9eea1dabcc07676": { - "balance": "489500000000000000" - }, - "5104bb1b831902333732dd25209afee810dfb4fe": { - "balance": "1333614132000000000" - }, - "513963743ec6ec9dc91abf356b807ebad64df221": { - "balance": "1508002412172000000000" - }, - "51397ca69d36e515a58882a04266179843727304": { - "balance": "941648956414000000000" - }, - "514a58f2b36c2cf1b6293c36360cf658d8af30ed": { - "balance": "1233397704089000000000" - }, - "514fe0cdb3de692cab9f2ef2fd774244df71be66": { - "balance": "9670444445882000000000" - }, - "51583128081fd800d9550144afebdf3fe88149cb": { - "balance": "231190355520000000000" - }, - "517384fe92391187d0e65747a17bfaadf967c331": { - "balance": "1943121865489000000000" - }, - "51aebfaa26a54071cfe6c2d8f81157ec313984ad": { - "balance": "1422225031261000000000" - }, - "51d4f1205b272e491e94fe21f0341465f14141fc": { - "balance": "552384783614000000000" - }, - "51de598faa85276bb26a68b135028755304b6700": { - "balance": "2068484560002000000000" - }, - "51e08e0304f08ef768c80ca149da4721fcf482b0": { - "balance": "194629207228000000000" - }, - "51fa3da695e24f602952a71966f37ac3596a94a4": { - "balance": "17008166261720000000000" - }, - "520b22776b1befd3064636da0dd251afe569ef13": { - "balance": "18538137781909000000000" - }, - "52219a1e1aa82b78b971088c30583a3bbe675c8e": { - "balance": "411959222637000000000" - }, - "5252b8a0688096523498cb5c1f42bcd1f61923d7": { - "balance": "1863936864000000000" - }, - "5259154e1a5a809b2e3dab80372124cebbfd56e2": { - "balance": "110000000000000" - }, - "5264f2de516835e549710bfe34ef03b08b8557dd": { - "balance": "1216000000000000000000" - }, - "52b17fae7e9cac447f026db71dba4034a1d53174": { - "balance": "99001631977000000000" - }, - "52b3363ae882a99354faeb76733d0fa2cbb89787": { - "balance": "102517584327000000000" - }, - "52bee7fb24a7fc1f34cf0874ec2f06c5fe847cb1": { - "balance": "54443400591000000000" - }, - "52d1f12d391c7a2f3b52939a61a20da5f85eecc3": { - "balance": "2707175772061000000000" - }, - "52f27099483589e883e7eb789896de39c61e46da": { - "balance": "358944977251000000000" - }, - "52f3b715b678de95d1befb292de14c70f89f5e03": { - "balance": "2989868434000000000" - }, - "53259780569f6dd6753c1da1d53d0b155c5b30d2": { - "balance": "200489122590000000000" - }, - "532e4908e8297c90d75d2280b432b469aaafa2ac": { - "balance": "20000000000000000" - }, - "5334d1e399feacabc9648cebcd93172db95d43be": { - "balance": "25000000000000000000" - }, - "5341665addfb5e367f7a7d35de95b87a0cceb3a9": { - "balance": "60544291695000000000" - }, - "535a39a854ed1c2f0afbc5944f1ee0e2e68cf65a": { - "balance": "2141913781000000000" - }, - "536515c0c08988ee69da1d75f18c706f6b9bf7a3": { - "balance": "169000000000000000000" - }, - "5387a1ce4cd2ef4f90075c15dc3c0744948ec356": { - "balance": "50000000000000000000000" - }, - "539a30ee5724978010990718bb8b0dd25f89fd15": { - "balance": "1306896514000000000" - }, - "53a5f87dfb17149b8c2934a2a9d519ace4ac9724": { - "balance": "4569449510000000000" - }, - "53b24fb36e72c22eb830dc93857a8188b03397a9": { - "balance": "64000000000000000000" - }, - "53cc35b3daf4b8e1982e0e63d0bc68d7252e7fcc": { - "balance": "68213426853658000000000" - }, - "53e1f85147e000ae1ff6a5910407395e388c683c": { - "balance": "20000000000000000000000" - }, - "541f43ff66ed5eb1a1ea0ae3f86355ecff665274": { - "balance": "49562725831000000000" - }, - "5428a31f736c0d2b3c4e80baefb75a76ed44d3f7": { - "balance": "10000000000000000000000" - }, - "542f732aec0873bf531f6941828b6f0ed0611106": { - "balance": "8407722276000000000" - }, - "54300b6a77b95545373b2bba73e60f37c31eb1c6": { - "balance": "1581215621996000000000" - }, - "5434bd65a492a4d14d3b97eb49f6e491350ef73c": { - "balance": "484000000000000000000" - }, - "5444a1735913eeac177d947ef38de7cd6bdfc0a6": { - "balance": "1000000000000000000000000" - }, - "544ffeab53bdc59ef8edaff0042b03c2ea123615": { - "balance": "10000000000000000000000" - }, - "54613713df6c5b89c3012a7835651f25cdac8331": { - "balance": "98684037547000000000" - }, - "5471fb39b4e48c118f855492830ad9e2eaa68179": { - "balance": "91791250228000000000" - }, - "5472591efd048dd60a4d6afdb549e95a65578b0a": { - "balance": "50000000000000000000000" - }, - "547b4c1ae70567fd77a896dc05eb536f502ac8a4": { - "balance": "14037444012000000000" - }, - "547fa9f6f86a2939f9144aacb74e0af60d434535": { - "balance": "428416957729000000000" - }, - "54841d6a478cb9b6e717a9de35577a1a4a504b0d": { - "balance": "144000000000000000000" - }, - "549157e5b1c92a88a0eef335b1bcf4d162482017": { - "balance": "21019502942000000000" - }, - "5492757c55c72ac5946b21514ee16c5065ecde7b": { - "balance": "10446737491000000000" - }, - "54984a41eeaa8e710e4e5b8a7f68c96057b7df3a": { - "balance": "10000000000000000000000" - }, - "549a3717a1bca3f38d24655197c3ccef1e8c273e": { - "balance": "4416133255000000000" - }, - "54b047fbe004191cd02f31163d29bd61ccfaadf7": { - "balance": "52649445905000000000" - }, - "54b125d8b260386633b756056b7d7e78e7071715": { - "balance": "10000000000000000000000" - }, - "54ffad1ae76ab45c4218ced27e49bf2745b2a2e7": { - "balance": "1426474871178000000000" - }, - "550b28968bae36f4e99780c6d7deb54c158be6d8": { - "balance": "10000000000000000000" - }, - "55117923e8393dbf233c0f10819e7de75569962c": { - "balance": "470094520022000000000" - }, - "554a2471e6ecf2320da545d559c40b8b622465ab": { - "balance": "4052895973949000000000" - }, - "55607b39da9480ed8f54d74d0818ab8798136589": { - "balance": "13704276648975000000000" - }, - "5561cbe99fd775f5d0f05903fd62ba4877b3319d": { - "balance": "1007596371374000000000" - }, - "559ba7ab58670d4a0b118bbf6aed7f6fdb276594": { - "balance": "3127762973000000000" - }, - "55b0bc444f2a5952a98f216f61cf07382da1e156": { - "balance": "18683409750727000000000" - }, - "55c0a02dc68123aca7ee0c9cd073ead50b16406e": { - "balance": "99999999580000000000000" - }, - "55c47d593952afd637050c5758a921a204f23fc6": { - "balance": "1615608723958000000000" - }, - "55c6855b3970e5a550f0c75d5727329476406d91": { - "balance": "600705012673000000000" - }, - "55eadbe33899f53138d0fb204f42e272f447cfd6": { - "balance": "1671128311341000000000" - }, - "55fa59fa0fbba06b7184ea78868d438176eb96eb": { - "balance": "1553000000000000000000" - }, - "560a11493b5a0ec28589e80276fe975ee26c6a3e": { - "balance": "10000000000000000000000" - }, - "560fbb31d83bf6dc49e5fb15bd582d70c49fd273": { - "balance": "46015432815000000000" - }, - "5620e17ccf094b1be1a93f6f3388fb96e3a90165": { - "balance": "484000000000000000000" - }, - "5633512298cf74f4d2b8663e6f291e9e25436e7f": { - "balance": "10026444446000000000" - }, - "564423f92b8841b3b1f8bdba443067b580916e65": { - "balance": "465451550122000000000" - }, - "56730e1d11a84970355c43ac7659f2f4786dadcd": { - "balance": "20000000000000000000000" - }, - "5678851984add045f3d054623c198dfd4665d54e": { - "balance": "227651903234000000000" - }, - "569cf18b4bcb99e3f3d27235f2c4c0d8d160af03": { - "balance": "4124979731000000000" - }, - "56ac5f2c3486a9ce744a71599ab89a606e7464a7": { - "balance": "9000000000000000000" - }, - "56bc5936a6ea37c1d0839bf64bcec0d366840ace": { - "balance": "14741201469670000000000" - }, - "56bf62e0135e903525cc46b0a3cce33f4a16880a": { - "balance": "534970476270000000000" - }, - "56da0781a80a0abf5dcda4da35861e9de601bfbb": { - "balance": "166898390441000000000" - }, - "56db15729e52d615a744a04f8a59d63e3b9f735b": { - "balance": "10000000000000000000000" - }, - "56e32ed78e7f5be6b00c28847efe7b3589cdae1a": { - "balance": "1046236086484000000000" - }, - "570f7a08150e0088178276f8116bc4103f885903": { - "balance": "1124393518440000000000" - }, - "57147fdd9b52ef53b4ebd4b5712d29da83f99374": { - "balance": "39000000000000" - }, - "57395fb355fe51f1b32c1baa4e9ee0fc2b8fe05c": { - "balance": "7701013675397000000000" - }, - "5752f0f11ed12bb1d5041b0cee4ddd500cd8806f": { - "balance": "151337200533000000000" - }, - "575907d73ad5ad4980a2037efbd20860afc67ad9": { - "balance": "3568754158000000000000" - }, - "576acb4c0bccc89903ad285ac08c70fde514aaf2": { - "balance": "25000000000000000000" - }, - "5784cb8a17cfb5392c4aeec2edbd173849ca6ee3": { - "balance": "15804767597000000000" - }, - "579234645eb857a3ca51230b3a02b964f8efa2f6": { - "balance": "20576922380000000000" - }, - "57989f9fa52b4c0502e7d0c3caac0c37a0b20516": { - "balance": "462711082812000000000" - }, - "57a55c376ea03c22e21c797d83e2fb039508ad3c": { - "balance": "10000000000000000000" - }, - "57d1612ea1fddacf088b62f625ad8cd49d7517cd": { - "balance": "18001023230648000000000" - }, - "5811590907050746b897efe65fea7b65710e1a2c": { - "balance": "310984892882000000000" - }, - "582ffd8c43966aa8ad3c6cecdfc18eddc56fe5c0": { - "balance": "69136214255000000000" - }, - "583b90b3c4d00b9ddf101efbce75bb811d969fe2": { - "balance": "7839200298177000000000" - }, - "5841fee8b1965141e51b8c146b6af00f6a879a8c": { - "balance": "1210322907244000000000" - }, - "5847a576f7799ba1a35e36906b2c2a5aadeb99b1": { - "balance": "183765768447000000000" - }, - "586dea7ada0a54150f5afcf54198db473ed046a2": { - "balance": "7123598380000000000" - }, - "586f545062ec7dc0ffc213eacd59af80660df570": { - "balance": "10000000000000000000000" - }, - "587187488758f67912bd5bb8a5be787a73d97ee3": { - "balance": "702757402654000000000" - }, - "58be0a3482dc3411571f047f4128387049cb9798": { - "balance": "1000000000000000000" - }, - "58d546e2ae82efc4d8efc887ac6fd30f7eb5dac6": { - "balance": "1486717153455000000000" - }, - "58e7010e6b8d97a556c0e7f0d90151224ebf674e": { - "balance": "20000000000000000000000" - }, - "58f991b3b12d29f09ff4cc2c6e83d576e95b1f59": { - "balance": "25000000000000000000" - }, - "5923a65a796934e69081715657e8dfec8874e40d": { - "balance": "10000000000000000000000" - }, - "593b7c43073b8954355ed76020ff3780dd6ae783": { - "balance": "1403468567787000000000" - }, - "5947f1dbd79a622bcc3fa64b19f9b6eda164dcce": { - "balance": "50000000000000000000" - }, - "596311e2fc09ae1eaee57900f2ca188afd5e68a6": { - "balance": "448723397560091000000000" - }, - "597a3adac4607d457c90817220f67eb4abcf129f": { - "balance": "18000240000000000000" - }, - "598201a9bcff0a773e9323338a8a094e9d9b3999": { - "balance": "74904485722481000000000" - }, - "599e93031704c2ce36308f44d4ff8166e71ae516": { - "balance": "100000000000000000000" - }, - "59af0178699f9f3d8f0ea645dda75356119a6e2e": { - "balance": "152462578058000000000" - }, - "59b0c06e40475cd75728797add9c69c3fdb17b4e": { - "balance": "23147237210000000000" - }, - "59b79577f183b9d39c2b458646a26b2fd6ed806e": { - "balance": "4244859516807000000000" - }, - "5a03b51d67a9c660258ebc030120d5d1d4f687c5": { - "balance": "4451691855300000000000" - }, - "5a0d03dff6754963c757eb15a3339ac6c4ba6196": { - "balance": "215126489934000000000" - }, - "5a34ab3937854e407a8739fa14574d3d20e30d6f": { - "balance": "1375979293937000000000" - }, - "5a352fbeb2fd78bbe0268b0efd34f68d401e2769": { - "balance": "27929247671418000000000" - }, - "5a47c2ca4c0fad7e2fc7bbdf5f2356d68843c564": { - "balance": "3218227936000000000" - }, - "5a538adb2c7f6a80634b0ec20ec5152ff6bb4d5f": { - "balance": "10000000000000000000000" - }, - "5a8fe770c221072a7cba79ae7759cae0185adde7": { - "balance": "11913943233694000000000" - }, - "5aafe1efac688583d7facb09d3e569d58fb5a357": { - "balance": "4713219466825000000000" - }, - "5ab68d762750d5185138187db7751c9f71db5836": { - "balance": "500000000000000000000000" - }, - "5acab69851959dd5a6f0673ef757009ed36dfa3b": { - "balance": "974443209942000000000" - }, - "5ad9f2ab11b5e59b756404395f350aad6019d7a7": { - "balance": "54151179981663000000000" - }, - "5b1dc013ba1a28235cc70e785a00eff8808faef6": { - "balance": "516289257133000000000" - }, - "5b1eeb44ef61c7f35482503b7041162bec9b1e32": { - "balance": "125493885394000000000" - }, - "5b3db31996bca4625d22330686128ec234270206": { - "balance": "362316593128000000000" - }, - "5b401fc9ff3be7cdf5f0df870843bbef94f43285": { - "balance": "1373804724122000000000" - }, - "5b47ba296069041f25768e61be14437b8a469e81": { - "balance": "3152706392234000000000" - }, - "5b5030b5057c0457c190489c5d709d7dbdddee8f": { - "balance": "1154404278000000000" - }, - "5b5a4a782d37154a307868cd79bec9cb2a8f0161": { - "balance": "100277816425153000000000" - }, - "5b5e0b6b7cc27b06456ba4c7816ac4e89e1e26a3": { - "balance": "1023749119000000000" - }, - "5b638e4b6dfdb6928b07586e63d5879dce69a1f8": { - "balance": "1000000000000000000000000" - }, - "5b7be81d6ff5228a2b8c2913deea3f86823f1dee": { - "balance": "36000000000000000000" - }, - "5b7c4804bc2b8c72f3112b73d44b59c0711f83cf": { - "balance": "6803857604000000000" - }, - "5ba26d941544d07100744d8ffd6595a8eb7770bc": { - "balance": "583051897662000000000" - }, - "5bd58fc88733632b63d4f26893bc5c08fb60e2ad": { - "balance": "3480620567502000000000" - }, - "5bd85b5f0ecad08133fceb486c43998e537b3451": { - "balance": "484263880245000000000" - }, - "5c12639a5ab107f9e580cbd2278568dde10758d6": { - "balance": "101293252434000000000" - }, - "5c5522df05d6c6d960394c4762599e74247ab102": { - "balance": "149088856773000000000" - }, - "5c722f3ac94421f95389756af9cd97d0eaa6b696": { - "balance": "1435349483553000000000" - }, - "5c7b14ce51abf629bb0953ee4e2d9d87fc86eb4d": { - "balance": "10000000000000000000000" - }, - "5c8b215403da4e7912c1a1704a949087e091b111": { - "balance": "1440961256910000000000" - }, - "5cab313964f6730888e4158234bbd4806db0286e": { - "balance": "32284637230203000000000" - }, - "5cd736bf65c99469490d0523b10a658178cab10b": { - "balance": "99740204082000000000" - }, - "5ce91ef7ae254b2bd6d910cbf0d380814200811b": { - "balance": "50000000000000000000000" - }, - "5d15fc3a0ba8b3d87b80f9bbf972320112c644f9": { - "balance": "64000000000000000000" - }, - "5d2ccc795b19df400f21f24c0dca4d0e9e898093": { - "balance": "10000000000000000000000" - }, - "5d879b8b31af1e400cf53eb7170f82583190b96f": { - "balance": "93765337844000000000" - }, - "5d8dd54178b68bb36e1963d47d29c123864fd0ef": { - "balance": "20000000000000000000000" - }, - "5da1653bbe8353134edfff6158211ad7ee21dbef": { - "balance": "1491149937915000000000" - }, - "5da733ef41a7bdc0cf7975f83ed24604fbb4d40b": { - "balance": "10343699901151000000000" - }, - "5ddf5d7306f7c603b8d3ff993f03906dca14cd8b": { - "balance": "862558469755000000000" - }, - "5de87ec54e2160c7c2a8eff2d859414737501ae2": { - "balance": "21579321171000000000" - }, - "5df1b805b1361c1f39ca844aebe5ecee8a8d06b2": { - "balance": "411820472746000000000" - }, - "5df86b0a183b5e7f702e4da582ce9a8116a05f61": { - "balance": "256000000000000000000" - }, - "5e22359e20dc14be6930c6c1ce5a0c81c039cac7": { - "balance": "10000000000000000000" - }, - "5e2d38a06f33c784303abf2012f9af12622d9e5a": { - "balance": "10000000000000000000000" - }, - "5e479e616585e7fa84bd6f7465d394a1c0302be7": { - "balance": "10000000000000000000000" - }, - "5e4a55027a0d372f6da042b7f73720b143347d9c": { - "balance": "16175516772000000000" - }, - "5e52e86eda3e05f96e353d7e3f0ee90f08864f84": { - "balance": "21255916842000000000" - }, - "5e91c4d3a21c9dfac2c0994ed8890c78d58626d5": { - "balance": "325349462011000000000" - }, - "5ea797b18caba45d5504e57b80b12f5f5ae630aa": { - "balance": "7805696321000000000" - }, - "5eaec8815e859c34dba88cfe7b7fe28572c964ba": { - "balance": "145852682588000000000" - }, - "5eb974b5716fc4712d431bec7fbb2c49057a7b84": { - "balance": "4890681156035000000000" - }, - "5ee5f8407dedbac839f509419051106219458006": { - "balance": "3042761975468000000000" - }, - "5ef782abb28d1ca889ceb3039eef98713effbf32": { - "balance": "40915083108000000000" - }, - "5f23b88f06430c42570ac3fa33b1c7503b388a3c": { - "balance": "2376070180325000000000" - }, - "5f2b1641c0f2605b090039851aacf297e35632ef": { - "balance": "141615261000000000" - }, - "5f44cc8083340e644d19d3debc84dc14a0cbc53f": { - "balance": "291829106275000000000" - }, - "5f633f89adcc70e9da0b66611a5da108b4b221cd": { - "balance": "50835573000000000" - }, - "5f94ef8e9612b03a5c6ffcf423ada9a19a40818f": { - "balance": "102566595099430000000000" - }, - "5fae1977b76a5e899b384f572e4d94855f9cb52f": { - "balance": "773616125740000000000" - }, - "5fbd22cb3de462c794e523fd1ce36f230cc84b83": { - "balance": "1009995132839000000000" - }, - "5fd91676bc95bd6b5e69db8b9216dc83ed9dddaa": { - "balance": "1000000000000000000" - }, - "5fdda8f5271a08cf1b830faa497019d75fa9d231": { - "balance": "4149626365000000000" - }, - "5fdea351c5eccedf2394fb54437b149ae423ecf3": { - "balance": "100000000000000000000000" - }, - "5fe70ee123cb2e03c768138b2f71c1e1ea75ad17": { - "balance": "1074496282650000000000" - }, - "5fec9df797214459f85a040a559b186ee9161c88": { - "balance": "205282872821268000000000" - }, - "60037df7e4092466656a6b9571437fc4600c66e3": { - "balance": "1000000000000000000000000" - }, - "6009a0bcf531640a5a7f1664a69fe0f64b564ede": { - "balance": "50170000000000000000" - }, - "601668d8b678c95ec5ef98d9d2624decbdd52e9b": { - "balance": "23592727870000000000" - }, - "6027bafcd0ade24fda8c345dcbc812d59df74bf7": { - "balance": "10000000000000000000000" - }, - "6029514f24825c1fadc68cf8614951de5d53268f": { - "balance": "1389262963614000000000" - }, - "606de6db14272a314d778cf0e67913b7fabea45c": { - "balance": "144000000000000000000" - }, - "6074f20675f975ae2c081930cae8f299710f0bba": { - "balance": "10000000000000000000000" - }, - "60850fa9e09d414af3690e4b5daefb1b906b0d20": { - "balance": "10000000000000000000000" - }, - "60ad0b6239dda5df7ac0f0ca941684cf20ae0fd8": { - "balance": "81000000000000000000" - }, - "60d6136e6db631be45fefb9667c3dfa69e9d6054": { - "balance": "651902184266000000000" - }, - "60d733dedec6886908520ba57cab8c9d5c2d7f7a": { - "balance": "555461746642000000000" - }, - "61202238aea4010d115c5c64322ad790576cee43": { - "balance": "10465801848035000000000" - }, - "6142d92b61111657de4b2d65698a3621411e3adc": { - "balance": "100000000000000000000" - }, - "61879bc1a022d9cac8b7d57c8f528065beb10bb2": { - "balance": "72766025231000000000" - }, - "618b15c9a60ad89e7fc28afc79bbf7f28d4998cf": { - "balance": "444855210015000000000" - }, - "61c1169e8ba43ee6b919e5be2eac19542eb913b4": { - "balance": "500000000000000000000000" - }, - "61f1cd6efce17f5458325f022f363fd9772d8f20": { - "balance": "19704989598372000000000" - }, - "61f7d39211a0af2e226d8cbc95fb673168653b0a": { - "balance": "484884476279000000000" - }, - "621aa67f09e6506efb2fd141f080fb1d96693a57": { - "balance": "1694451603196000000000" - }, - "62332fa5127b98bd2a627a0ac22d3a1bdb418efd": { - "balance": "926882233406000000000" - }, - "624a465696ad409586a2e67d84750ba50a971fee": { - "balance": "25000000000000000000" - }, - "624d866f0d61bdefc3ec2210bfe36b6d51018f9c": { - "balance": "199592183194000000000" - }, - "6255d6d3b49443891661b209056d530ecd63bcca": { - "balance": "10000000000000000000000" - }, - "626c484055e6739d46e2ff25190c8b3a4af3fe0f": { - "balance": "1485276462321000000000" - }, - "62865e637d723393ab9654d6439db7fb5abf8803": { - "balance": "10000000000000000000000" - }, - "628a47761d5ce755de88444aaf6d7736b911672f": { - "balance": "18625552918216000000000" - }, - "62df6a38e8b15a1c4f4a7aa7c1736c612f54a0e4": { - "balance": "16468111299582000000000" - }, - "631d7916ddbb5f7c469f8ba07cd48e377560319d": { - "balance": "2493487426430000000000" - }, - "632754f5afcae7dc36d9286cfcd91c14abf0f7bd": { - "balance": "1424933496931000000000" - }, - "635788343997ea9f145c508b0cd2ed36e180f46d": { - "balance": "143040938538000000000" - }, - "636973e7dbda9e3042a8c03e25696d0faf27f025": { - "balance": "5491869128148000000000" - }, - "63707efa26d34d7ceadf4e6439324e7bde0ebc3f": { - "balance": "1000000000000000000" - }, - "637d92494f7872d397340c9b5183dce354c8c43b": { - "balance": "724687404033000000000" - }, - "63b9c2e6762a431752f7669b8bbedae9f37120b3": { - "balance": "1360967549741000000000" - }, - "63bd281d8c4d1279519237a2b68f2a73c228f7e1": { - "balance": "217457311664000000000" - }, - "63c0eb8c9a0019e36ec9a731b4bd947271a5bed0": { - "balance": "36693488147419103230" - }, - "63c6362eff56de328a29b7e9d32ced28f3602b6b": { - "balance": "148335309448000000000" - }, - "63c979c787a7b037693cadfeda738ae33178c009": { - "balance": "81000000000000000000" - }, - "63d4621d91906215d32f6fbcee1ac48bd773f630": { - "balance": "1006939236069000000000" - }, - "63ff99fec1cbd2f6e83c0e6de3c0ea4b7c7e1398": { - "balance": "1201300688980000000000" - }, - "640ffd856e48528b05d5ef1e60348048ce291960": { - "balance": "20000000000000000000000" - }, - "641c25f7c380e2745c81a268384a029b2e2be0cf": { - "balance": "635133477665000000000" - }, - "6427792a164bbeab45f6c3acf17c76f721b90e81": { - "balance": "10000000000000000000000" - }, - "6437986b4c545af9c4a5ee96371a5807275e9221": { - "balance": "2951152516627000000000" - }, - "64460d09d1bc5c425d62bef5969eb0c5916963c3": { - "balance": "1680000000000000000" - }, - "646381f92216b97abbd86ca100a773eebdf7545b": { - "balance": "211234535515000000000" - }, - "649f73d1cafeb3ab0631432f04c9d08b9f438c22": { - "balance": "248900746448000000000" - }, - "64a239be45a92df83bb85b25f8ed7de5d82313b9": { - "balance": "100000000000000000000000" - }, - "64a3d97f82e3d42eea78bbcee31a95d33767b055": { - "balance": "2511466286000000000" - }, - "64ad579975888f455217e0f801e371900d9814c9": { - "balance": "7118859416319000000000" - }, - "64af5edbfec8adea679951662c08a781175688bb": { - "balance": "822966999709000000000" - }, - "64b7f2c22c20a59c07cb0dd7f8f692153c68f3f8": { - "balance": "20000000000000000000000" - }, - "64bc17e28d468b7b8368ee8a8375710d21c3ac5d": { - "balance": "875002262415000000000" - }, - "64d17aa662e56061cebb3c2e2421e637163e8dd3": { - "balance": "363241251465000000000" - }, - "64d714ec3145308e8f939bab7591b0773038b886": { - "balance": "338231954012000000000" - }, - "65199fc9ba95434382c108b44ac553534a9a3670": { - "balance": "2537340957145000000000" - }, - "6527c67c29e47833dc2440570596023318a7bd99": { - "balance": "555434226832000000000" - }, - "654b9d299077c90768c5ca6635e5802e8099f51a": { - "balance": "119004827465000000000" - }, - "655908513607cc38de35351ff3738b201bbf39d4": { - "balance": "652902936029000000000" - }, - "656ad16063b2d397788c231e537384ece94eb0d2": { - "balance": "63116382606000000000" - }, - "656e622970b8829a7cfe24f5b82696c7777683ba": { - "balance": "20390269890405000000000" - }, - "6583a6ff4dfcf447e3b163a61b0d5cb84ceee375": { - "balance": "3858529344000000000" - }, - "658d2b7e8a6517256efafd74321757d5c384a2b9": { - "balance": "221114751567000000000" - }, - "65920758857ee5b27b0f31487ccc3c5d6986df3a": { - "balance": "16272975796000000000" - }, - "659d60d67a07774ecc5cfea9e56809bec024d639": { - "balance": "20000000000000000000000" - }, - "65a1a3f968bab5fc1f097b8e297099a3d34ef45a": { - "balance": "16000000000000000000" - }, - "65b5e3163d20b2a6fc75c0219b7f97d83479a26d": { - "balance": "1716459529041000000000" - }, - "65c9bc3b8b0ce7c4d16b35abe1a5c285a59f672e": { - "balance": "20000000000000000000000" - }, - "65d5b458d9b1a9659c1125d20d970d5e6c29dc3e": { - "balance": "20000000000000000000000" - }, - "65e75bb8ade25eb7975ea12b9afdb17ac21063b3": { - "balance": "2270407774714000000000" - }, - "65ed78d0c4ef1150e8765b24b210f056e079cd59": { - "balance": "500000000000000000000000" - }, - "664ee5e334b8378928becfbf5d5e51daaf001125": { - "balance": "860160259186000000000" - }, - "6679bdb26adc179d046607d49f4b10c65d8a40d1": { - "balance": "436794739763000000000" - }, - "6680fe9d6eda3ab9fc4ac1ac933339b533eb682b": { - "balance": "551296206326000000000" - }, - "66a1249501cc5076b040bbb165ce032ace216ea2": { - "balance": "36000000000000000000" - }, - "66a475d014c2f976704bfb93ce78dbabbfc5e072": { - "balance": "1140135640169000000000" - }, - "66ae43d92e8fb2231fee8c72d720ff90cdd267ff": { - "balance": "796696150339000000000" - }, - "66b7e0c810d6959afa8210f6ca67e3e40bd24eb9": { - "balance": "16000000000000000000" - }, - "66bf8be16f33b111b2a425743bb7ebcdfbb35034": { - "balance": "538590591000000000" - }, - "66d2eaf7fe10900d93eab17823ebfde5486aa2b7": { - "balance": "121000000000000000000" - }, - "66e525bb01b3ede1a4a105bb6087ec8a76200616": { - "balance": "1506610219207000000000" - }, - "67291e0df83d6e9f1386e87a1792d7d147341df9": { - "balance": "272330177662000000000" - }, - "6730b27b62e064b9d63df3bcbb8c4bbb0e500afe": { - "balance": "331282968154000000000" - }, - "67318617bfe19b739fac9a126fd129223db52498": { - "balance": "12699924981000000000" - }, - "674dd0b036c91f3a83288af44897b4ceb2e15a12": { - "balance": "4352791270187000000000" - }, - "6751bffd04be55c86692994fed06694cb78b62ff": { - "balance": "26049487516000000000" - }, - "6768d99a0cdcd7bb7c7d0aeee466d6bdc7208bbc": { - "balance": "309909685000000000000" - }, - "677ba2de3e5c68a4c354c9e3129ed1c41025312b": { - "balance": "127426274611000000000" - }, - "67b83745856551f1878027843be20e1473191944": { - "balance": "185757248875000000000" - }, - "68170edcfaf2c6df4e6542b2856ad33e9e2d6623": { - "balance": "4003453949471000000000" - }, - "684ae403d9a08e4f4f971cfedf81094074daa77f": { - "balance": "25139713925794000000000" - }, - "684f3b8a749c002aa434bad6af7a3e2579c69315": { - "balance": "16000000000000000000" - }, - "68538a9e8246be5a5c5ea315cb325344062cf8c4": { - "balance": "14009193210480000000000" - }, - "68935ff3a3a3b6ef16ae7df58cee50b157658dd2": { - "balance": "20000000000000000000000" - }, - "689f508256ea64f5dbd6bb77f1ce1bdaf36d7152": { - "balance": "10000000000000000000000" - }, - "68a3e6e7c191a8c1add988bfbbb9b51d4f36f521": { - "balance": "10000000000000000000000" - }, - "68a74ff2a5577321f854b56d3834a55d3c41bd94": { - "balance": "88873831171000000000" - }, - "68e6da521bde13cf4e4f423a78fda2f69b3d1c2a": { - "balance": "538392460838000000000" - }, - "68ecd5cf8cf8d9704fafc36d8da53930afeb0553": { - "balance": "1090923641219767000000000" - }, - "68fd0b8e000bd2788be6cb10fc0496fe2cbe155d": { - "balance": "32853847745000000000" - }, - "6904045feb5ef94e096894b863d314ff8a0f206b": { - "balance": "9892165615000000000" - }, - "690fbae5153849bb20797af7b8dea66a728a06c3": { - "balance": "6082107223716000000000" - }, - "693d909842877d017e0f102e37a55024517dd0ae": { - "balance": "20000000000000000000000" - }, - "694cd00fac9cded484ef2cfcd44faf161354f288": { - "balance": "3049716150137000000000" - }, - "6964c3c2c7bc719ec94a51bc4bf412e137d2b4e9": { - "balance": "1000000000000000000000000" - }, - "69a5c692516940bebad8efaa2243a8fbdf2ade62": { - "balance": "2803346939929000000000" - }, - "69f566c44802b0140f5e1c9234f46006773c03d4": { - "balance": "20000000000000000000000" - }, - "6a17eef3a6bd407260f52067592226448182cdc3": { - "balance": "1116509364305000000000" - }, - "6a200e99a0f50aab32fa7373c7880817c81f472a": { - "balance": "1836680122795000000000" - }, - "6a2a29f5f441876816dd17856051040787f48a64": { - "balance": "1131603204000000000" - }, - "6a3f855c7dceb75d0de7fa18fbc2f40c81b76756": { - "balance": "32267494586000000000" - }, - "6a46af653b938643e781cc4a0edcf5357852fd21": { - "balance": "1140718780752000000000" - }, - "6a4b2e5b45da0d70621ce71f165a11078a1745e2": { - "balance": "3768326643000000000" - }, - "6a530c813595a5b7776cced05a865dedcb110d94": { - "balance": "270559347097000000000" - }, - "6a6e3e82f98ce891f47721770301dbe2652a9e25": { - "balance": "10000000000000000000000" - }, - "6a828d6f2f7f68bde4a12608024020e593540010": { - "balance": "7531817000000000" - }, - "6aaddd1f4ff6b4d414c87271619b826ead27f09f": { - "balance": "64000000000000000000" - }, - "6ae6bce1e2865ade0d02eff9899ea3767b5511cd": { - "balance": "6893781798524000000000" - }, - "6b04e7c6a837d218fd3322b87a267fdd979358ef": { - "balance": "302679180175000000000" - }, - "6b2210b8536803b134e69c5046904acafef48cdd": { - "balance": "47823456459000000000" - }, - "6b2da6f36c2e7f61cabd7580480065360c995c93": { - "balance": "55000000000000000000000000" - }, - "6b3401986f2be7ae5a4ec160b8f96b2a651fce73": { - "balance": "16000000000000000000" - }, - "6b3847774e99dec307dcf5bf5adba49df4a9f145": { - "balance": "43276069579000000000" - }, - "6b57f2d9d95cac67fd2f70c0911d48c7f09de072": { - "balance": "1000000000000000000" - }, - "6b65d736a8ca89ec8508b52e4aca5166f9703732": { - "balance": "766421968820000000000" - }, - "6bcc55d897829e98fc3f3ac8beb331e59c33b942": { - "balance": "318115956882000000000" - }, - "6bd76e7af1775b88743d5f53ede0ce846d3d7ced": { - "balance": "139548017482371000000000" - }, - "6bd7cca99acf6eed5842417c2327c642df5473fd": { - "balance": "3321731000000000" - }, - "6bf72c4d39d6700181954a8d386c3df216634412": { - "balance": "12742769034078000000000" - }, - "6bfd3aedeac7c6ec086c0a4ec29d2d0f5bd69bc5": { - "balance": "50000000000000000000000" - }, - "6c025962810a6fb8374af5e07d7fcd631d10b1ce": { - "balance": "674126722005000000000" - }, - "6c1b72df836f410038af9e020fa2ff2ead398ef4": { - "balance": "1851293017364000000000" - }, - "6c1fddb4254ff46b3750de322ebb7d6238c0a606": { - "balance": "9977629348276000000000" - }, - "6c37069a361c5c72355bb5a56879dd0a9735a237": { - "balance": "1062230154063000000000" - }, - "6cb166eeca248a234c971b2a864a7b3fdbe5a737": { - "balance": "390222992865000000000" - }, - "6cb797289059cadcfa77eab0365e6bf1ae12df46": { - "balance": "100000000000000000000" - }, - "6cc787e6bb4f484828b080330667b93953e7a3c9": { - "balance": "16106440380234000000000" - }, - "6cdf7b334fb2ef8115198d475d431eeb7d88df77": { - "balance": "1940904395351000000000" - }, - "6ced85b035b787e9e427d0904aaf96e011417310": { - "balance": "103417697874000000000" - }, - "6d6e09acc07f388cbab99e53959f75e9ad8f07bc": { - "balance": "1305917678000000000" - }, - "6da91b02f512f412d374392247a9aaa853e9dd59": { - "balance": "2300525907893000000000" - }, - "6de5d70481cd40db468f64227228cdd362ad9980": { - "balance": "10447389944082000000000" - }, - "6dea87255c9ebfa63f017209046e894ecbbc03b7": { - "balance": "1527216854064000000000" - }, - "6df6f6b9953c2f2a8ce5985e19dd6835ae2c566c": { - "balance": "6539856530000000000" - }, - "6e013c83cac111a38fbbf8d47778fda0d3af25d5": { - "balance": "12139181929380000000000" - }, - "6e18a484f402fd433a5ac4dee5a4b8bf6f22db47": { - "balance": "23215906572368000000000" - }, - "6e4fd058e4dcd502c2015f83f3677f680ec58110": { - "balance": "480059342014000000000" - }, - "6e501ac7357fc758caf5dff6c29a995c806a1a7f": { - "balance": "1573491311733000000000" - }, - "6e6912f9fc21dfba736055e6ccef074dd62dcc59": { - "balance": "256000000000000000000" - }, - "6e869c68511c1458f4fbed9a4c5296fe961eb47e": { - "balance": "68488423994541000000000" - }, - "6ea6827b377b3d3ecf7c7628ed8daad7fd8eab1e": { - "balance": "188825714738000000000" - }, - "6eb9237738339fcaad3763466509f23efd0c5054": { - "balance": "48417242786000000000" - }, - "6eb92a61390f9d9ecdac80a8833aa801c3926b13": { - "balance": "1412936326723000000000" - }, - "6ecb93f18153ef2d2a552286ea3b7436f1f8168c": { - "balance": "20272577229669000000000" - }, - "6ee087c04cf16f4768c783a548686448fd125914": { - "balance": "1397039628538000000000" - }, - "6efbae7a34c71233329d0bb4cbec45274824ebf4": { - "balance": "8910000000000000000" - }, - "6efcd6776f287c25a6eb3cf71018adc282eeab6d": { - "balance": "1310659853178000000000" - }, - "6f9ca805ddaaea5205e85778dedb2eff4a5aaa75": { - "balance": "2585733757016000000000" - }, - "6fbbea927469f4d18942ce0aade164828fe23a2a": { - "balance": "4671857880000000000" - }, - "6fbe9df6c42151c453502960d99170445dd3ac0a": { - "balance": "20060296562115000000000" - }, - "6fed121fb310431f1659e637f35f4c878a7256c7": { - "balance": "55170085399000000000" - }, - "6ff2dd5373bd72966ef48d3183c60d74a6549cb9": { - "balance": "24103445361000000000" - }, - "703a490c4783776da244384c964897491aed3711": { - "balance": "2001677632732000000000" - }, - "704dcd2d9f75f0bbfb73f2fe58bcbf4508374381": { - "balance": "439603954369000000000" - }, - "70859a14f33b8ab873fa5781a4af1ce40dff65c0": { - "balance": "10000000000000000000000" - }, - "70b9cdfa5f6d41c60e1c0d3f544f569c9b340ea2": { - "balance": "198355566698000000000" - }, - "70d0ee793e28e320b34267ef2df69050fca0a9e0": { - "balance": "8010660534227000000000" - }, - "70dc7e5951752c22a0e3c50e8e7b1f7af4971d51": { - "balance": "3991137321749000000000" - }, - "71057f5afbed7d82c92d50790e3797fd7395d036": { - "balance": "49000000000000000000" - }, - "7109a3b3d5d6af49693549728691099d696ce016": { - "balance": "4119694297000000000" - }, - "712231a5161745fa1b33c7b0f6e8c767e1de4f81": { - "balance": "1353809351914000000000" - }, - "712aa38999c0be211654e5c84f59e3b2e018f597": { - "balance": "160199774000000000000" - }, - "713229fc94a86b71a5bd1ea6498b9373e3f3c549": { - "balance": "98289185940000000000" - }, - "715de29a0b6f467b94d4a90dc767ad52d0fb3b9e": { - "balance": "948824982990000000000" - }, - "71776853ac97ce04b008c9a7b64156a3cafc52a4": { - "balance": "608309596513759000000000" - }, - "7189f6dcfe64e1ddbfb5e51fd5f3174bc636dd0e": { - "balance": "5674608906899000000000" - }, - "718a4da87464caf6e83ca374d5ef9255b8f7cc3e": { - "balance": "761891873568000000000" - }, - "71bc447761cdb68915cc2288b4929fdc0adce02d": { - "balance": "10000000000000000000" - }, - "71d78531896642069b725bf82fc385789c63217c": { - "balance": "33103960195000000000" - }, - "71e328deeafbb1724051d1062609c43eef56ecdf": { - "balance": "493550967964000000000" - }, - "71ed0310fb51b86a61794aea17a3c792dd301e3c": { - "balance": "3234918634449000000000" - }, - "71fa264f58041e41cfe36e8f8d4e0cb22ab71925": { - "balance": "5558941960000000000" - }, - "72059c57d0fc05bc02ba54ebea6cefd1efbeadf1": { - "balance": "4458278271443000000000" - }, - "720847a28916a532bcab33e1fcbde5d1c4d820bc": { - "balance": "1392418942284000000000" - }, - "723cd2b5b836b0ee8481d37b9c51b5f3f1beddd2": { - "balance": "1856420455522000000000" - }, - "72430c6664d23c7051b0e99912fa54dfadcfdeff": { - "balance": "102078926010505000000000" - }, - "72652c4320dda25348f15c0ecfeb4b3b3ceeb7c8": { - "balance": "307639955659000000000" - }, - "7288bd1b9f4c068dd5df9bcd6fec1ccecd240195": { - "balance": "80161087899000000000" - }, - "7299cb8a288abe8e1a22c11b53a903acb7db5827": { - "balance": "752198565719000000000" - }, - "72f6bc0c3ae437756c099e02e9c084febedc5569": { - "balance": "696294297587000000000" - }, - "730e5907b344c80e0a6115723a90a23e3635192f": { - "balance": "6056082041729000000000" - }, - "732e97b992e4f8a53034cf29cf11aacba7452261": { - "balance": "100000000000000000000000" - }, - "7339df65ce293b3d501647a04c83819099f0bd38": { - "balance": "706500983417000000000" - }, - "73482f8135ca2231db5e0e034a235a9d244a8656": { - "balance": "1143989148865000000000" - }, - "73769e43058d30a530048e5a2bea7e9333534e93": { - "balance": "113542901996000000000" - }, - "73bb9e6f1709fbb7964df7b3cc0f9170c3152f38": { - "balance": "1639793026701000000000" - }, - "73e261da7978764044ee916f88bf66680952607f": { - "balance": "100000000000000000000" - }, - "740154120c4f41c50b0aaa0636a2000ff1e870ad": { - "balance": "10000000000000000000000" - }, - "741fe2a1537284b70e97e3ff659eedfd7fc5b1b6": { - "balance": "75911502037000000000" - }, - "7420bb277d834763e4429db9bf37f053f71ab769": { - "balance": "3100160195046000000000" - }, - "74281371c3b569c774da6bab686e7d7a45d4dc4c": { - "balance": "25666397941223000000000" - }, - "7428d261b5418652c5ab248d6abc3d2af25d904a": { - "balance": "56252809397000000000" - }, - "742c876433297f5a8fd4a25f75ee9a607726bd3c": { - "balance": "4132793019677000000000" - }, - "74302036cf52e11aa3f32a371bb4992e2bdc3f39": { - "balance": "19557661364000000000" - }, - "7445c657c24d014f3a9dddc3e446868bc2dbd13e": { - "balance": "10000000000000000000000" - }, - "744b8fa69d2542be3557267edaeaf2cfa8a9e991": { - "balance": "16000000000000000000" - }, - "74728999963524e7cc1736abcb4deac630142c44": { - "balance": "37000250991000000000" - }, - "74926cbdacd0e871cad0d926c8e17cb2c00475b9": { - "balance": "20000000000000000000000" - }, - "749e115a9e675bb15af5e1c04f81fede07c40120": { - "balance": "440913547154000000000" - }, - "74b7e01acf825898544d6c1b61e53356be759c56": { - "balance": "25000000000000000000" - }, - "74c5fcf875e2e9b726a7cf6e176dc2f7eb84c200": { - "balance": "59208835472000000000" - }, - "74f44579859e4a7944dda7bd810088e116ae9910": { - "balance": "1038454108527000000000" - }, - "750b1e2955ba05c1fc8a1f9dbb1624ed11587edd": { - "balance": "9545712605000000000" - }, - "75375129cff2a051f656b91f868325c3b35ee1ae": { - "balance": "25000000000000000000" - }, - "753ca28fbd89081382a996fe938da7e6c3ae6cfd": { - "balance": "156582454263000000000" - }, - "753d91c04e554680cc32a97c1abc96280e8263ee": { - "balance": "725101425969000000000" - }, - "754e5b5d64c267e83fd4804d112725531cf5abe9": { - "balance": "83276113115000000000" - }, - "7588a96a2bc65569a6c124c4a4acc55863a8ab78": { - "balance": "24062602342000000000" - }, - "759075dc3a6b9d2499a74bc57e346c9ed7ff834e": { - "balance": "225000000000000000000" - }, - "7591d6fa043801fe12462e11d9e33a53f438c073": { - "balance": "1863874274000000000" - }, - "75bda5bdf6aa749bbd62b6107941a7dd9ce3880a": { - "balance": "36000000000000000000" - }, - "75c2d3a99f144c4b9962b49be9d0a81b203906e8": { - "balance": "9000000000000000000" - }, - "75f587a69a97eb4d1c4c4078418d5fa85dff6f94": { - "balance": "10000000000000000000000" - }, - "75f67649605f49d98d866102ea2d6881ead9bea0": { - "balance": "814929108418000000000" - }, - "7602abce0f510b6ca471fd8d734e21a2591886f6": { - "balance": "50000000001006000000000" - }, - "7629b788160531b0be28bf445bf305fbe2c514d2": { - "balance": "23022256366212000000000" - }, - "762aed2e3aa2293e69dc2110b1fc6c806ae799a5": { - "balance": "10000000000000000000000" - }, - "7637b89130bc3f87e90c618fd02d6dd27179101d": { - "balance": "77765738300000000000" - }, - "765136022facade53e7a95c0c7aa510787e674d5": { - "balance": "1478178932688000000000" - }, - "765274015a308a9e6b1f264e5bac592d267f2f7b": { - "balance": "3058788819393000000000" - }, - "765cbc0a89fd727a2c1a6b055139faee53f11330": { - "balance": "500000000000000000000000" - }, - "768bb6d4b190c18a0946d92073ee446d68d98a6f": { - "balance": "144000000000000000000" - }, - "76ae8079894c760f2850c02cf5a0d7bb41e5864d": { - "balance": "156059816821000000000" - }, - "76af4103a231b1302d314c486a0ba524d0427899": { - "balance": "10000000000000000000000" - }, - "76b6394cd02ddf761e981b6a6ce1654c0e575443": { - "balance": "1078304803757000000000" - }, - "76db33eafeaf965dcf15d5460b64a48b37285259": { - "balance": "1000000000000000000" - }, - "76e5721c0a39d41274f84cb572039967a07e9beb": { - "balance": "156298167226000000000" - }, - "76e6ca6ef145d2711ab27f82376a065cc6f62a29": { - "balance": "100000000000000000" - }, - "7705d637cf9f6ceaa452deaca7ccc581beb5fa34": { - "balance": "36254762908065000000000" - }, - "7706c80af4eb372e168501eedfe7bda6dc942243": { - "balance": "50000000000000000000000" - }, - "771493da92c9fc6c6b39a4071ae70d99f6a588d3": { - "balance": "2000677471360000000000" - }, - "7719206286f26144c0f20b5e1c35cf4495271152": { - "balance": "1380480863056000000000" - }, - "771adcba1409fa2df6db19d9f784abc81a7bbf36": { - "balance": "15416381820915000000000" - }, - "772f7baa80a852e05b2fb3903a36061da132b2d8": { - "balance": "121000000000000000000" - }, - "7731a4175eee5077e2ede48878e6e2a18fce0f9e": { - "balance": "10000000000000000000000" - }, - "77385deeba01e3cd7a63e13d6048011020f56724": { - "balance": "57204247488000000000" - }, - "776808e7688432755b9e91a838410d29e532c624": { - "balance": "120318608715941000000000" - }, - "776d1b406f63082b80e250c4a0073fa0d83b9090": { - "balance": "243779839900000000000" - }, - "779848a59036ee3cd23b93ff6d53620d874f0bee": { - "balance": "82228810849000000000" - }, - "77d02a031274bd4ed2a16f3cc29d94e755142036": { - "balance": "408567696646000000000" - }, - "77d609a407aa0d126d58090b8d635f5ab7a02d6d": { - "balance": "776754055755000000000" - }, - "77dec41e116301dbd6e542f139816bfd9bf6d154": { - "balance": "16335989583000000000" - }, - "780398b42f81167731a8ef6a8bd1d14942b83267": { - "balance": "25000000000000000000" - }, - "780a645d59027e7b0670d9565898dc00704cbe5f": { - "balance": "20000000000000000000000" - }, - "78182a7711c773f306ec42ce6da3e983cd49b00b": { - "balance": "580861257254000000000" - }, - "7822622f07fec12995c4bb8eb32d62aa7f00be05": { - "balance": "5018461926846000000000" - }, - "786410c679101c0ebf06fb4f36102368121f3c8b": { - "balance": "16098386724761000000000" - }, - "787d5476038ab0a09b846645285ada23ffd7318c": { - "balance": "492047430907000000000" - }, - "788e9e27ed979d1e7aefadda798f69df1de1d1bd": { - "balance": "30965301214000000000" - }, - "78ab2d2dfaf5d2580ed89c970e771572bc91d3be": { - "balance": "36000000000000000000" - }, - "78ab7ac6f379ff084a7acf4a1a31fe2e5a6834c0": { - "balance": "107332516726000000000" - }, - "78aba95da37385c736ef93d0ca8318baf6c5ff3e": { - "balance": "9000000000000000000" - }, - "78cecbd82229dc91a530bd555c9e45125e2a6bc7": { - "balance": "28474069251604000000000" - }, - "78d4df90990248f3ac67e492a0a1e3f4ee455507": { - "balance": "10000000000000000000" - }, - "78f6de3768abc604c49b10d798e0656948cd334e": { - "balance": "9000000000000000000" - }, - "7909aca95ed899743de222e56c231f9bed1b518a": { - "balance": "5355599376491000000000" - }, - "79193e660b4431e8aca9c821b7daa88064e33750": { - "balance": "100000000000000000000000" - }, - "792487caa23b0d9b9998002810cf29439f7190bb": { - "balance": "4828579961131000000000" - }, - "793f56adea51063243a9633ecc1d1e620a91f327": { - "balance": "926742377449000000000" - }, - "796d187077c1d7591583436ae64d10a641490ca5": { - "balance": "242664407084091000000000" - }, - "79a6b7fad3b5a655679450ca82818ec2d6f58688": { - "balance": "1400472715109000000000" - }, - "79acf627e67cedf48297c26fd135973bff6c57da": { - "balance": "444598475759000000000" - }, - "79ae0dda1964ff0191b98d28c9b52a79dc9ab078": { - "balance": "325908985422000000000" - }, - "79e71dcc52fa1b28226c519f715faa3cf63cfb09": { - "balance": "497898493594000000000" - }, - "79e98193ff8770f26af824734bbb1c2ce8197b6f": { - "balance": "10000000000000000000000" - }, - "79ff3d790d52c58b7317a415278e9058915d5241": { - "balance": "48502649691864000000000" - }, - "7a0b02d16d26e8f31e57106bbdad308f513d436c": { - "balance": "841000000000000000000" - }, - "7a1d422352ec7e6ca46131728e4b71f20ed84e2f": { - "balance": "50496873413000000000" - }, - "7a2a3fbe27e33df867ba8800788995d7662c046b": { - "balance": "100000000000000000000000" - }, - "7a629c4783079cd55633661d2b02e6706b45cf8e": { - "balance": "50000000000000000000000" - }, - "7a62d8875f53e54b775ee2f67f7e2ec137bf724f": { - "balance": "25000000000000000000" - }, - "7a67285fd883d36ea3107aa3fe7727c68a99eb2d": { - "balance": "254787158217000000000" - }, - "7a90fbec48492473d54b0fad128ceda94ea66100": { - "balance": "313715004199000000000" - }, - "7a9e11463d84a08140d698972e32e66bacf7a7c9": { - "balance": "3602603216258000000000" - }, - "7ac4f33e1b93ef0f9c15014e06da24904ef4419e": { - "balance": "101000000000000000" - }, - "7ae082ad247275fd5a9e77b127cee5693784e9e1": { - "balance": "1921957343533000000000" - }, - "7b27e070ca4158d13f8333b34842d4c28b678c92": { - "balance": "10000000000000000000000" - }, - "7b2e34374921e4dc10fd9cfc670a40f5d092da1b": { - "balance": "2098457950503000000000" - }, - "7b54c6c8041c8b09240de1ff06e0d3d2d8d877e0": { - "balance": "944752036841000000000" - }, - "7b5aecb798d8f4f5a04bdaef909e09a35bde8d47": { - "balance": "21975115049000000000" - }, - "7b88a7ef9201966bd1ca634779c3b7f40c22f0d7": { - "balance": "64344833519732000000000" - }, - "7b8c22ddc5c7e59e571587d7c776fa50e65f4845": { - "balance": "225108110445000000000" - }, - "7bb4d8a169f72432494ac362eeab005ce1e02d81": { - "balance": "2098993419448000000000" - }, - "7bbaaa6690698e749d095447bdd27207c0caee43": { - "balance": "490069993631000000000" - }, - "7bbf27f92f9f726381d4f68b21ed86af8f792d04": { - "balance": "806346082666000000000" - }, - "7bc6f172fd78953c3456c571ac8394756715d5fd": { - "balance": "81000000000000000000" - }, - "7bcca29b477730ee8f219a5d1bca24415c7a4625": { - "balance": "36273885000000000000" - }, - "7bd296e1cb29ad87ed28b0ed18440ee686b157e0": { - "balance": "35964679698000000000" - }, - "7bde6d49a1af34a5a9dac0b9007e9a5583c65ebd": { - "balance": "1041474566346000000000" - }, - "7bea6240f245e649563253fa4c1da39b12625da7": { - "balance": "100000000000000000000" - }, - "7bf096396c56f27f9c39c4056ee6cfcb0db44bc6": { - "balance": "407261849111000000000" - }, - "7c3b58d3ba283bd9b1580832e9d014eff48bff7f": { - "balance": "7074518779349000000000" - }, - "7c5a56c45f23c353ff9f6f71ec86c9a6a1a0ca67": { - "balance": "11277879639596900000000" - }, - "7c783ac9b07bc6576835635f37e7e3c137055c8c": { - "balance": "16253676225000000000" - }, - "7ca2fbc0a0d1370e95048a21a300eac4d6056df3": { - "balance": "2772084065617000000000" - }, - "7cbe95802a20eb765f9fcff0a068859cc35d2660": { - "balance": "255153842674000000000" - }, - "7d004fb3a6a81c00fd2872e8079ad2912841b0e0": { - "balance": "642630220843000000000" - }, - "7d30c788d4ea18849ebae1173373c8915ffd7a35": { - "balance": "61062263242000000000" - }, - "7d39324f5ff62e849b0f0f46ab8ee396fbd85581": { - "balance": "100000000000000000000000" - }, - "7db0ce6c04537417dca1dd3415a5bf213edc2028": { - "balance": "30393443462000000000" - }, - "7dcfaa795586c92f1ce7d5c7b10608fe6a773fe4": { - "balance": "183173395920000000000" - }, - "7ddd111cfdc3133f59b82568e3deefc3cf10b0d0": { - "balance": "5622149283840000000000" - }, - "7de81daaa7ed5cbf4d379cdd26ae353cbd5a2489": { - "balance": "10000000000000000000000" - }, - "7e0a11af993a41626c5564f719442c0dfd608ec5": { - "balance": "1532083534600000000000" - }, - "7e34971b187047e7f7980650630b936eedc11023": { - "balance": "10000000000000000000000" - }, - "7e5214e16851b33c4a4d29e5a06929461d3d9555": { - "balance": "371790231197000000000" - }, - "7e52ae9c7e4b888015a3a5af7a91444510aa18e2": { - "balance": "109879329128000000000" - }, - "7e69b383671f96b7abc2d1fed8b61477b87a58dd": { - "balance": "10000000000000000000000" - }, - "7e733b1fcadc9a20dc038fba74e236af0b5a39b3": { - "balance": "43583614302000000000" - }, - "7eadcf955c90040668fb0f75a61f687e4e41f314": { - "balance": "332201682206000000000" - }, - "7eb51f3ead1dd0f5384c199ad5518ec55f77d35c": { - "balance": "38487884822000000000" - }, - "7ee73c0d64caf46f47f439969060092ecafdecd9": { - "balance": "15063618320000000000" - }, - "7ee8e4c6742a4c6d8efbfacc4d56119bc6c74ea4": { - "balance": "31882319329000000000" - }, - "7f16d981521c06347db8324da38b25eab3cee23c": { - "balance": "400000000000000" - }, - "7f6ff7db81a26fe78dd80636f0b178c669344393": { - "balance": "10000000000000000" - }, - "7f792b094c0b96d6819823cf21bc0c402fc27bf9": { - "balance": "50000000000000000000000" - }, - "7f84ae97c21cc45a7e56603ddf97449d803fb246": { - "balance": "81000000000000000000" - }, - "7f89c2b9daba034841f19ae843cfb6cd6f75b1d7": { - "balance": "20000000000000000000000" - }, - "7fb18f8b0e1fd1ed8c863a66226082bdc0429ee6": { - "balance": "11465417544634000000000" - }, - "7fb4e30579c64efe981d0057204e5bd8770a1f87": { - "balance": "249801873762000000000" - }, - "7fcc4de10e837d98691acc52732e1568c890304a": { - "balance": "1000000000000000000" - }, - "7fcc77798cd50345b2784a78b81a25dd4c1e64ab": { - "balance": "2676882485895000000000" - }, - "7fe33e773a02b995278ff595d55a0741813b19d4": { - "balance": "5788279057355000000000" - }, - "7ff32b13d531ceef500ca6c6806ffc0773639264": { - "balance": "1000000000000000" - }, - "801380158ef8f24316bdceaa00eb89c3d886707e": { - "balance": "35627521347898000000000" - }, - "804fdccdc8603858d15dec88666437505b2a106a": { - "balance": "14607090269617000000000" - }, - "807915567eed99bb9146354a32409812b9490d70": { - "balance": "1083142734057000000000" - }, - "8092ceeb2be5b271f4c156d85fe14977e919c7e0": { - "balance": "761607160308000000000" - }, - "80962bf961d0d713395dbe00379a6e207b425a76": { - "balance": "524215754483000000000" - }, - "80a9787124075c8cd44b9c8674967a54445e2354": { - "balance": "7600078997429000000000" - }, - "80aacd59dd76bf443c47ca02976178af8453f23a": { - "balance": "411856023767000000000" - }, - "80db788f7fbd7613f0fff66c21389eedbbd4bd35": { - "balance": "956888725645000000000" - }, - "80e449a70e3c7707d6441ae8863a44aee2d7f3f2": { - "balance": "16260784762856000000000" - }, - "811a2c3d0ba4e1c36a848495585da824ec3a7620": { - "balance": "36000000000000000000" - }, - "812a3c55234d5849a854ad76891c34ee90c8a0e3": { - "balance": "703378980438000000000" - }, - "814b4b5eb67afb8d1a60e3d240fe804bb752f632": { - "balance": "17578964576000000000" - }, - "817025619f37838470b90d0a25af2c02de80dae6": { - "balance": "96000000000000000000" - }, - "817233a104d87cac34d9c90243aebd7f68e0a9ea": { - "balance": "510051038684000000000" - }, - "818be95c0c13c3018b4084ea177556705e84c1f5": { - "balance": "332239667000000000" - }, - "819618c19a4a490b821f8156c5633749ea782ca2": { - "balance": "10000000000000000000000" - }, - "81a80d26b70626e07e8747bc1569dd2855834f7c": { - "balance": "521696417321000000000" - }, - "81b2fb0db882bf2538cf8788bae1ad850cef3bab": { - "balance": "102457067052000000000" - }, - "81d4c3bf72837b21203b2a4f90bf42fda10acf48": { - "balance": "10000000000000000000000" - }, - "81df59e5d7b9a2db5463b53be83b4d7c7673d163": { - "balance": "887372337013000000000" - }, - "81ef38d074e0aa9ad618deaab01bcd135301fb67": { - "balance": "24072930558567000000000" - }, - "81f3a4c5291f13f8f97a067a6ed744a686331eaf": { - "balance": "56612148225000000000" - }, - "820610d0ddd3e9f3893f7cc13f32b1ad0d169f81": { - "balance": "50000000000000000000" - }, - "822d6388145e96cdeb2900420a0e0436e940b670": { - "balance": "20000000000000000000000" - }, - "82323b748fdee9f18e34aefc4ddebd4993ac6293": { - "balance": "112752706047881000000000" - }, - "82324995b36f4ff15be3559ccee14742d5b4c75a": { - "balance": "1184047304377000000000" - }, - "8235bfba0bf0fb664271ebe534616456a78852ce": { - "balance": "6804584686000000000" - }, - "824df7b17a61392f88f7e3067f8c261abb48806b": { - "balance": "144857897574000000000" - }, - "82555a7aebfc95a01a3773aa5370394cadef0302": { - "balance": "40069354268401000000000" - }, - "82831d451b8f92fbf6a763adb708010a3e66bb60": { - "balance": "8750983992240000000000" - }, - "8294176178418f46bb18440cc87a07cf40c1669d": { - "balance": "4439783816461000000000" - }, - "82a1c733c3c937ba0a1a49481e4d1f6226157d2a": { - "balance": "50000000000000000000000" - }, - "82ad0b5dc23bc763da0352f5983efceeaee6ea08": { - "balance": "171723633433000000000" - }, - "82b4a3d16655fd71f4020e6a562592a621ff6e1c": { - "balance": "190211621484000000000" - }, - "8357d5a016a00aa5e3ef05d3ce210826adf4c501": { - "balance": "10000000000000000" - }, - "836c41d7f9e72131eff839b7d510fd0ed412f939": { - "balance": "15575572364757000000000" - }, - "8377fff2b0eb03393543ddf5ffae90b3311af5d3": { - "balance": "2058810049054000000000" - }, - "838859e6fd751539a88d00581b0e19bc98c37e47": { - "balance": "338264241636000000000" - }, - "838da0414211392b644e73541e51e9f0fba26615": { - "balance": "20000000000000000000000" - }, - "83958896a43d23ef4ba01bdf6757c36105985096": { - "balance": "9000000000000000000" - }, - "83b88314b606df40d5e716df488980bc64125b46": { - "balance": "10985538717083000000000" - }, - "83bf53fa162e1d85751be0bc6f46e8ec881392e2": { - "balance": "1497107276676000000000" - }, - "83d7c52608b445e18fb1e28dc6198908d66bb6d8": { - "balance": "265446362740000000000" - }, - "83ee8ebaed62092d2116de6b4e90778454e8dfc4": { - "balance": "1000000000000000000000000" - }, - "8402fe573658250f50fbe111596ce35ea9ec01ca": { - "balance": "3479737676000000000" - }, - "8412b877e708a7d5db2a38d9b0f4f23d12231f63": { - "balance": "9225027744855000000000" - }, - "8418dcc09fe052febf2946ee22bcc8c53d548eb6": { - "balance": "3000000000000000" - }, - "84199f54ef96bda5e14f60aa1723e811f755d3bb": { - "balance": "129197612052433000000000" - }, - "841b1400f97ecd2ca008e7b4f5a95274bc3e99dc": { - "balance": "2095180906854000000000" - }, - "844177191a120d2dc4be9169ddbc3b5430e9e238": { - "balance": "3620793599287000000000" - }, - "84578fcffc73be7d65bfa81b0cdafd26885bafbc": { - "balance": "37592478429000000000" - }, - "8460acb05c6c476ca26495aec7224c2bf90996fc": { - "balance": "8999580000000000000" - }, - "84696cdb9f018d3e7bf453efdc174e1a586e9c25": { - "balance": "118007806297016000000000" - }, - "846a8a91d2890000d1e995fc1663cf5b7c22211c": { - "balance": "27266838638307000000000" - }, - "846b5ef52d5f7ccc17d9c7e5f49db807908c63f3": { - "balance": "375423381758000000000" - }, - "847409e5d6ed2c4e54ff97f2ed58217ac5fc3d68": { - "balance": "23972870617025000000000" - }, - "84bf432c967540caafb8bf49cdc9983e8953a18a": { - "balance": "453476687224000000000" - }, - "84eba1bb76f7a3f6d2b9052d068cc6c48d449d76": { - "balance": "17655334922000000000" - }, - "851245ef1637a07578241b3c35acf215908e1898": { - "balance": "1269389304110000000000" - }, - "853708e974fd4810655d9cd19fc8dbfd3d5e1e36": { - "balance": "18000534000000000000" - }, - "8547989af8c99a3432038a03d3fb30a054d90413": { - "balance": "10000000000000000000000" - }, - "854ba39bac4c7bf619804b6773fe43bc71f3255d": { - "balance": "15999580000000000000" - }, - "85636f3e113cbe1d1bbd1b3a23e9e98edbcb94f2": { - "balance": "1199038399611000000000" - }, - "857167896b859394babf897c4c6fa57b3a057117": { - "balance": "921057404898000000000" - }, - "85799226a1474371ca76f05597a1e3835c17e7d7": { - "balance": "562141544946000000000" - }, - "85a2221cbbb47e8b74fc2617d6087a98f47e2738": { - "balance": "10000000000000000000000" - }, - "85be0bd55fb9143ff17387914a82d0a2650224c4": { - "balance": "4038654147145000000000" - }, - "85c5ff0e4956ef0fb662a2cbf6a86325a53dac8a": { - "balance": "28690160424000000000" - }, - "85caff4ec0e1719ad963e97c1c02828683070370": { - "balance": "2022427900763000000000" - }, - "8630cc2780fee566f172ed0437264c45421ce675": { - "balance": "669721278148000000000" - }, - "8633d245c5f1b63403e3d7828dc197ce1cfafc0f": { - "balance": "10000000000000000000000" - }, - "867ccceae3192a27751d870ae13b1d3d2c3584dc": { - "balance": "1491436265909000000000" - }, - "868bed241f77983ff4a7a8d0bf121299b6b2248b": { - "balance": "5600000000000000000" - }, - "868ddd283a76a26c8bbb9761df3ca647bea267e2": { - "balance": "9000000000000000000" - }, - "8696e546f96f6e51f405905e095902db8bb90118": { - "balance": "533558981421000000000" - }, - "86ac0eae4e4c20cb7019325f4dbebad053f92213": { - "balance": "697960117764000000000" - }, - "86bef47f9d2cd7526495454eb4d1737510696a5f": { - "balance": "2938307902381000000000" - }, - "86ddd4e3f444b395be8b2b2b75c35c78877fefb7": { - "balance": "15615434748526000000000" - }, - "86f115ed19a32aba4f98270b8ad45820abbc4653": { - "balance": "151868798605000000000" - }, - "870f19e7ee358de61ad0fd3c7710441156d68f66": { - "balance": "674715936435000000000" - }, - "87141a2d3857fb8a328ef8e7b503ed965294c85d": { - "balance": "1609607183158000000000" - }, - "87257783d866af25a7a71b46ea6c2bd1e9ab9596": { - "balance": "64000000000000000000" - }, - "87298979a9a0dbc272b0e15b7e5f2e42639c9912": { - "balance": "722087160930000000000" - }, - "8757b784015f88d072229176cabefa358a0e95a4": { - "balance": "204003337866000000000" - }, - "8760e60a56c5b8b61276634a571400023f08e3ac": { - "balance": "1000000000000000000" - }, - "877e54ea7e8ab03bb8e2b842dadab16bf4ae0a4c": { - "balance": "341020957932000000000" - }, - "87919285fc5d98169bbd073cebb1b3a564264dd8": { - "balance": "579080463078000000000" - }, - "87c39cfaa9c82d84119f306e6a233a3abfbb0ad1": { - "balance": "121753433796000000000" - }, - "87d479659a472af7c8ea78a3c658605f8c40bec6": { - "balance": "20000000000000000000000" - }, - "87d933ad6fba603950da9d245b9387880e6d9def": { - "balance": "1087642723520000000000" - }, - "87ec448309024bb1b756116b81652ea518cf353d": { - "balance": "344562808694000000000" - }, - "87fbbe010837f8907cc01a5bbd967f402a216488": { - "balance": "185411503628000000000" - }, - "8805a3c529bef4d19a6491f3b7d7b1b7232bb93d": { - "balance": "264150205918000000000" - }, - "880ec9548864fcd51f711ab731d847260ed0e3d5": { - "balance": "723225945994000000000" - }, - "8818d160b56b18e196871a6c7ccf02112dc13342": { - "balance": "2857439182291000000000" - }, - "8836e25baa08c19a9b0155c57072582b49f7dbef": { - "balance": "5468425690148000000000" - }, - "885b6303d06142accf2ddddbbdd4a9379d1cd124": { - "balance": "11853214736000000000" - }, - "88656958d9cd758d71546ba52c4ea646b658c84c": { - "balance": "10000000000000000000000" - }, - "88740acdf9ab5711d015391fe8cf4a7c70a0bc86": { - "balance": "510027156671000000000" - }, - "8874966976d776c3154261afa802692afedf3d3d": { - "balance": "305634301700000000000" - }, - "88aea53c727d7a5dd8a416e49faba1c4f741f01a": { - "balance": "15358334295959000000000" - }, - "88b67d05997ae3852259ca638a00ce9b9e7e4a61": { - "balance": "278125551806452000000000" - }, - "88d730e074a102048008de81d3adcba831335736": { - "balance": "5984576042159000000000" - }, - "88da27b1f0a604a87fdedd9ea51087a331179cb4": { - "balance": "10000000000000000000000" - }, - "88efaa91dab9671f5c903e69aa6ca4d9a04b5ddb": { - "balance": "1996126782729000000000" - }, - "89a9d702f64f14fae4d1a69717744dd700208d9a": { - "balance": "251686323241000000000" - }, - "89ac81571265bebbf9d3c09e9459fd1ba7fb1297": { - "balance": "162368080974000000000" - }, - "89c75c4f0ce41d283587beba1a3e3efab05ca6ad": { - "balance": "16000000000000000000" - }, - "89d44cb81cc5a1bdf4d573c4954ee641f3cb91d1": { - "balance": "97965629614355000000000" - }, - "89e2fef4f7b7c255b36afa81cf4033b22de3db25": { - "balance": "7278615226888000000000" - }, - "89fe5d3cb5283c7b87daf6103bb568f92a230631": { - "balance": "64000000000000000000" - }, - "8a07242231f4a654aeea65b857d1519385a18065": { - "balance": "20000000000000000000000" - }, - "8a5a415f0fe2a8329e14628493d11ca20d4e482a": { - "balance": "157274758238000000000" - }, - "8a6ce9f270fe3ec33a013be9e5b1ef823c0dab53": { - "balance": "20672772672000000000" - }, - "8a6fe4fa2f86f879ec9b2bf643beeb0876da46d4": { - "balance": "1041983771868000000000" - }, - "8a765ff2b429dcdf59b65a34c4bb41798dfb5886": { - "balance": "355487172996000000000" - }, - "8a9b9b65a3d443a6e4dcf696a64983f3b625774f": { - "balance": "3185351572575000000000" - }, - "8ab1f5443cf9149773b9ddb69de3e6ea047ae38f": { - "balance": "161619949415000000000" - }, - "8abeacee0078e07fb417277e8bf15dcc2cdb9fa7": { - "balance": "144000000000000000000" - }, - "8ac0d9e0e77aa4ada4080604f2118b3a5a0f8102": { - "balance": "100000000000000000" - }, - "8adae0dc99300f60d31bfa619ec83d45b48ea22b": { - "balance": "697262590215000000000" - }, - "8aef59e59a27a8662043f1a4abcaf945a5e3fafc": { - "balance": "26780431538000000000" - }, - "8b3386f32e2d77526c223ee8bb95b7dd111ced92": { - "balance": "2179932854210000000000" - }, - "8b34d5e457ef6451bb7f5ecc93c80678a30e3194": { - "balance": "31492358338840000000000" - }, - "8b47e07f192c33bd7d298bae717dfcd68a8097ae": { - "balance": "1000000000000000000000000" - }, - "8b55bff4b281f6a24ab428d66b91f9bab06f7b96": { - "balance": "1596248680941000000000" - }, - "8b576b1e2391f22193bb4f91bec5f2a8aec02af7": { - "balance": "29660301836269000000000" - }, - "8b9097b762c7bc38a487974f3551fea697087553": { - "balance": "260887123991000000000" - }, - "8b92c50e1c39466f900a578edb20a49356c4fe24": { - "balance": "35654824979000000000" - }, - "8ba3933337108841a997accf0b5735e005373f53": { - "balance": "574965182000000000" - }, - "8ba3eeb2d1b27e021ed6bf5827280807f32c7897": { - "balance": "64000000000000000000" - }, - "8bb23a5b8c48ec5bde84f39b463559b7c048c853": { - "balance": "16186405874000000000" - }, - "8be0b6ab14e15b46905335d07df03726fb1df0e8": { - "balance": "500000000000000000000000" - }, - "8bfc53af1ae6931f47ad7f7ed2f807f70fddb24e": { - "balance": "20000000000000000000" - }, - "8c0599df87df142d3aea37d50c975c1813ecb642": { - "balance": "871085782287000000000" - }, - "8c2deeeaf095be075a2646ed7b8764d3665acf14": { - "balance": "10000000000000000000000" - }, - "8c3e7381b0598356ff81e860faf25390ae7de9d9": { - "balance": "36000000000000000000" - }, - "8c5671a6f4610ddbd05a5139659c7190f54117b5": { - "balance": "50000000000000000000000" - }, - "8c60582c4e4e60da665b4a5a2d18f514ded6c49d": { - "balance": "16806447782991000000000" - }, - "8c8464ea6b17687eec36ef04966d59c7c91fa092": { - "balance": "1872124465602000000000" - }, - "8c85c5a318cc0227576adba3e91dce6adc73f6a2": { - "balance": "52479305517000000000" - }, - "8c8f3796a2942a2298d14ff1a9e3264e9f63f2bd": { - "balance": "10000000000000000000000" - }, - "8cec1886f2cc71b09ca32a1cf77a280ae3a6a9fe": { - "balance": "500000000000000000000000" - }, - "8d0b26d57eb52a62814d7876d64c8274f4371464": { - "balance": "20794037603000000000" - }, - "8d40b92e41f3cfec06e767d64b4dafc5612133b6": { - "balance": "25000000000000000000" - }, - "8d41ea1cfb70d0ef1f6572fd72a6b417739ac7dc": { - "balance": "738777348304000000000" - }, - "8d4eb54646f9d14882fc8ebb0ef15f6056d1afbb": { - "balance": "1003867239086000000000" - }, - "8d51ab29ccd190bfe12bcd94a651e9f49a003253": { - "balance": "442251355663000000000" - }, - "8d6c0c8e4ca47626115433b39feb939014b8738f": { - "balance": "119828137027000000000" - }, - "8d7acd92d664a485625bb9884e7cac9cc6077f41": { - "balance": "1381910232084000000000" - }, - "8d7ee7a9c1c263ba8061f54dcf62d9f8420e2008": { - "balance": "20000000000000000000000" - }, - "8d941c5d0c6e2b8e2934c9f80f8a63e2fb5868ef": { - "balance": "116443644149000000000" - }, - "8da0dc43ed3ccefb18f21aa13f3fa42c13e540a6": { - "balance": "516000000000000000000" - }, - "8dab4500316475e8fc3bb6494be09f549dedf026": { - "balance": "2736245677000000000" - }, - "8db39a95f4e63bde0bd8c02e386122ce2c57a30f": { - "balance": "12577347153000000000" - }, - "8dc718b49fb68584d9472490743f9be1b0ad683b": { - "balance": "50000000000000000000000" - }, - "8dd05e26224aa8a6deb0904b6d3bbb34d268e901": { - "balance": "613146658282863000000000" - }, - "8dda0e7ddde515480ef08cf90a1eb4e78f50a2c4": { - "balance": "19265526663314000000000" - }, - "8dedad1511c11798c338334dde7be967de96e9b2": { - "balance": "50000000000000000000000" - }, - "8df63c04f18a854d7bb397bca3e2ba19202e9da1": { - "balance": "1479940547081000000000" - }, - "8dfd7edb7d28e8b3df1faab70a8ef9e3b923d998": { - "balance": "10000000000000000000000" - }, - "8e2c3af057e931b5f82e83873b336a7f68e7eb03": { - "balance": "27138009123000000000" - }, - "8e2f4eaddd60468bdc09d47f65839b96f50596ef": { - "balance": "970529157231000000000" - }, - "8e750010c88ba99d75b0b5943c716d6fc0d01802": { - "balance": "42271114987000000000" - }, - "8e889d47f3307a18490e53f2108dc31b14d6300e": { - "balance": "115722965933000000000" - }, - "8e9e1953c82217ba56365e7a9c54b1ded73914bd": { - "balance": "6248835752208000000000" - }, - "8ec980d3066cb6afa793577cf88ccb46ce8d13f2": { - "balance": "100000000000000000000000" - }, - "8ef324c861de7e042c445776bcc8ac026533bc15": { - "balance": "1869634994148000000000" - }, - "8efd14464465e50af087a80a5fbe652445de373d": { - "balance": "1157403424927000000000" - }, - "8f1b57304406fd8b2eb5dabcbd322e326dd873f5": { - "balance": "194188733254000000000" - }, - "8f36ffd921e12083e374335d3cc43fcfeeadfa46": { - "balance": "100000000000000000000000" - }, - "8f813b88e6e125eab71a63455f326322ef505501": { - "balance": "19087691927734000000000" - }, - "8f83892d4d2892cd57828fde2318610a54b14498": { - "balance": "22833507983000000000" - }, - "8f89c1bcba85757cf1718d5b9eb007e27e5195ab": { - "balance": "2241600478705000000000" - }, - "8f927ab63df4c2ce46f1ea35bc875a0c006d2d4f": { - "balance": "327487123409000000000" - }, - "8fc3c231df0f93a84bbe348aff12ab576284d70f": { - "balance": "25000000000000000000" - }, - "8ffa089b07ed1388a5d1a428daf54d9591e734e6": { - "balance": "1347580402248000000000" - }, - "90040e00f585f8be44c82597037fde452472e741": { - "balance": "2746884591879000000000" - }, - "9034eb46aad2a76bdb812c981565d4701dc10718": { - "balance": "10000000000000000000" - }, - "904ca1ac2381702bd18472b175262a8928cde5f1": { - "balance": "304421909590000000000" - }, - "90502c1123692c3b86e99b328d07fae473d4a283": { - "balance": "227491252462000000000" - }, - "9052ca7e9623c1bbe3568668673d6d252b56a764": { - "balance": "35268091378000000000" - }, - "9093d12d8410193293e1fda0cca98a43b85b91a8": { - "balance": "6829489147119000000000" - }, - "909ba8cdc707c12ba577dcd8ed1df1c02a7ce2ef": { - "balance": "60524108169000000000" - }, - "90a2cc3aa73495531691e027a8c02783cea7941d": { - "balance": "65263780625000000000" - }, - "90d7c82615f151953a8d71a68096cee4d428619c": { - "balance": "298774379499000000000" - }, - "90e02deb31d98b9c85fcaa7876eb5ec51d721dd4": { - "balance": "2000000000000000000" - }, - "90e538746bbfc6181514338a608181a3c4286d1d": { - "balance": "6069511690189000000000" - }, - "9106dddc1b693e7dcb85f1dc13563d6c7c9d8a6e": { - "balance": "1977000091291000000000" - }, - "910d1e0d3f71054835ee0d4cd87054dd7add3e38": { - "balance": "40104690362000000000" - }, - "912e2349b791fe702692a6c1ccbf6f0f06b826db": { - "balance": "6305336897000000000" - }, - "9144cc61c01eb819e654b46730620c230da9e936": { - "balance": "144000000000000000000" - }, - "91478d4c15d9ba02816456030915be08fa3aa208": { - "balance": "200078339107000000000" - }, - "9160c466b5f9020b0ab1c0ff497bf0345598ec90": { - "balance": "17705350930000000000" - }, - "919025625787101c572d8340ead1444a96593424": { - "balance": "2418027749789000000000" - }, - "91926323868c65f91b6d74c85c07279610651ede": { - "balance": "538073886450000000000" - }, - "91950cd6e2dd99e024854b65c09c5a7476777a21": { - "balance": "11629505934425000000000" - }, - "91ae8d74c26d3dcc291db208fc0783347fcc197f": { - "balance": "7604593786920000000000" - }, - "91b9ac26869abc9eb3090f1d8140eabe97f41001": { - "balance": "25000000000000000000" - }, - "91c349651afb604f9b00a08e097e02c0964e148a": { - "balance": "117290771022000000000" - }, - "91ddc95cadeb6dcf6ebbdb3300a29699ac8ded39": { - "balance": "20000000000000000000000" - }, - "91ebbd36714cc069f8ce46f3e0eda5504fdd3aa2": { - "balance": "203944728497000000000" - }, - "91f2765125b84923bd506a719d72b0c1de030e32": { - "balance": "452269960816000000000" - }, - "91f2e54a9d61ef52a33d150da50d5a8f2ebcd6bf": { - "balance": "242321058694000000000" - }, - "920dc90d11e087a0d8912c1d43db102e9ba4f43e": { - "balance": "20000000000000000000000" - }, - "922ff522cf7f3ce0bab9312132df51704caa755b": { - "balance": "1414824682473000000000" - }, - "9251449b0f757ef62f63c2774eb63ba15bf3712b": { - "balance": "102688517037000000000" - }, - "926255c17386720fdc1701747a2f024475063d4a": { - "balance": "25000000000000000000" - }, - "92808a38ffc5a339b1ab6b0b472f9975718d4a07": { - "balance": "500000000000000000000000" - }, - "9286c4497e820845341e3b9127813c1b7c884830": { - "balance": "101241387488275000000000" - }, - "9298e1df6730e91e9892d19f7ce18a3db9b5d2a1": { - "balance": "169000000000000000000" - }, - "92d98aed335c29402a43ba96c610251bed97308b": { - "balance": "3032350763000000000" - }, - "9319153f24814a81d920c60cbee9b5f2f275fac0": { - "balance": "56619610984000000000" - }, - "9347532d6396bc0b86bcd34eb80facd4c3690684": { - "balance": "258912194626000000000" - }, - "93487691d71e6248d88f06b1fbaee58b6fe34615": { - "balance": "1593901704394000000000" - }, - "9375154a7f19783b26ae1c9e48f114e1cfd1307a": { - "balance": "9000000000000000000" - }, - "9377947e0db688bb09c9ca3838ca2197fb262a1e": { - "balance": "323993393587000000000" - }, - "939ca9030b28d356dc1b071169f98b0728a9aef3": { - "balance": "218900305967000000000" - }, - "93b71636b8332515c2af031aac7a8805de716a62": { - "balance": "1640174743698000000000" - }, - "93bca153afd427b0c3c1de4a5584610e4a6595b7": { - "balance": "654782426410000000000" - }, - "93cb3b73fee80cedacf5197f8b4ac8f18f0d0184": { - "balance": "100000000000000000000" - }, - "940fcd215bab373d1b736e354f2def501244885a": { - "balance": "13133641534585000000000" - }, - "943f4bc76f20580b6546b6aff2800448f82cfdc0": { - "balance": "1927982550280000000000" - }, - "946ddb5c46fb13010b9c7ec56e4055b4f3e24b4a": { - "balance": "1410000000000000000" - }, - "947961dc367226f78d722361d5821cced52db01b": { - "balance": "115598797369000000000" - }, - "948eab3ffe44d5f1f381de2c8cadcb311c25df2a": { - "balance": "870664355820000000000" - }, - "94bf674593378243fb6b811f331f77561efb4106": { - "balance": "226539311455000000000" - }, - "94ce082887dd6324d7dcfa6cae17b653be021b25": { - "balance": "420000000000000000000" - }, - "94e2aaa4b5e2b36a12f866c96e3382a1150a97b4": { - "balance": "7344059136611000000000" - }, - "94ea5b1cdceb3f1a9d5ecacb6ac8dd2db9a461d7": { - "balance": "1951787237292000000000" - }, - "95218633176c0fe2f32fb55ad3df9f387e63aed1": { - "balance": "99999999580000000000000" - }, - "9543cb22853a46cce3aadc60e46cbddbd3fcf593": { - "balance": "2806074281914000000000" - }, - "958842c5389656d156aab05ac1731a20656716ff": { - "balance": "391064461038000000000" - }, - "958fd9bbc96531a00adc5c484d06dc61ccd717b6": { - "balance": "8021794447667000000000" - }, - "9593ce72919cb0648ddacc58af233d942963e2e6": { - "balance": "32322940730755000000000" - }, - "95a8e371af9128c97c9d4d7c4d58f5f75f2d07d4": { - "balance": "49000000000000000000" - }, - "95b9a9ad563a4c1ff7b6ebcf5fabcf5dbdb4a6a3": { - "balance": "10000000000000000000000" - }, - "95ef5fac6aa3ab1b4a87246fa800cfceff43dec7": { - "balance": "119666779022000000000" - }, - "961a3aa8015cd520de43bd47d81f5194ee4dfdc2": { - "balance": "248589901007000000000" - }, - "962bad39df25d64ee1c6b4ae9c14a18d316bfc06": { - "balance": "2404608291000000000" - }, - "96392119198c4b644c64284c9a75f61210a6292d": { - "balance": "1000000000000000000" - }, - "963c82319380587eeba0bd7b07eb63ea7042984b": { - "balance": "1480123630618000000000" - }, - "963e05fb6245ec11d67ed80e9feba6e2c0a8b4ae": { - "balance": "276053287417000000000" - }, - "964452b86b0d1d4b34aa881509a99e7b631d4a85": { - "balance": "64000000000000000000" - }, - "9644a2af2ff70eb43584a4351bfbe027c42ba3f9": { - "balance": "500000000000000000000000" - }, - "96572a017489450f2dfc0e31928576acd3bc6808": { - "balance": "1140183097730000000000" - }, - "9686bfcc0dc3de20604eb77787d0dba818cc5016": { - "balance": "10593448987804000000000" - }, - "96879780764b4433589d26573fc221f5218f1877": { - "balance": "154136576560000000000" - }, - "96ac1e62c95e33dbbd4f6ed389007e16c00b205e": { - "balance": "4130528000000000" - }, - "96ba703df3a8a6dc3c5d6be02cbf6a4afa2d1650": { - "balance": "2885298549532000000000" - }, - "96d516ded110f1d7e0290716689fd1b7964d9d42": { - "balance": "40665675241000000000" - }, - "96d75950c9354cec6084ba11058dd52d00fdb1f2": { - "balance": "903158106646000000000" - }, - "96f362c59c72fa1d39ae3ec37a7b715d2dd23679": { - "balance": "110000000000000000" - }, - "97115f7544cb05009b3fad2f0c2817f3ee77dd4d": { - "balance": "10000000000000000000000" - }, - "971cbaeafd4b0fdbad24fab946051b8949efaebf": { - "balance": "8462381628000000000" - }, - "971e195e980b4fd4db8d279c80968ca1bd390edd": { - "balance": "10000000000000000000" - }, - "9722648970c455929d621546fddbff27c49acd3c": { - "balance": "70337427969000000000" - }, - "9772027a4ea991eb9eb5ae6b8f34d750a917538b": { - "balance": "148918416138000000000" - }, - "97797e3919aa35567b9eb1224be87f96c6c2e1b4": { - "balance": "973342196399000000000" - }, - "9780a9c86160e27f627179535c3d3f23b6b29917": { - "balance": "10000000000000000000000" - }, - "97a85f4e3f53aa066825de15f1d0e25d4189b037": { - "balance": "2435764858719000000000" - }, - "97f46465e99910539bd3593c16a572e159bac87d": { - "balance": "25000000000000000000" - }, - "9882505fcb54ca2d2f4f79b03f0a5ead61936979": { - "balance": "249999580000000000000" - }, - "9898e969629502a891b758efecc9fdc5ada7d32c": { - "balance": "20000000000000000000000" - }, - "98a52d325e28ca9b4474846c7e4c07a223440fab": { - "balance": "418260286015000000000" - }, - "98a9b2f7d1ba7838e3242b5e4cbf1f2897aa4bc5": { - "balance": "500000000000000000000000" - }, - "98b8308c37a2f6cc1bb382dba2ba95a3c5ca2834": { - "balance": "10000000000000000000000" - }, - "98bf0170a61f98ab0710a68810bf152b7f6c56fd": { - "balance": "2279761566089000000000" - }, - "98c8a323a0022bd147a466fa1ac867977e12eb92": { - "balance": "10000000000000000000000" - }, - "98cd102caf0866ba0a74604b01f54049503905d6": { - "balance": "34739921273310000000000" - }, - "98d7e89c2765aaac224d4015aa277fef208953c3": { - "balance": "1291811952000000000" - }, - "98fe96bfd1e10fb60b343e512b15e955aefc0778": { - "balance": "464922897623000000000" - }, - "99064a57d693e45559a1a910c9ef7d46cce0e703": { - "balance": "8969733492948000000000" - }, - "991ea5429b91a8bfc4352a1d93304dc463be5b90": { - "balance": "149367286734000000000" - }, - "9921d405fada890fee6bf76acc39141fd34e5d2b": { - "balance": "5021308706457000000000" - }, - "9938d357d3d5dcc6f6fc7fb47a98405c0ab6830e": { - "balance": "516293591974000000000" - }, - "994f4e6521a3a5752359308b9f6b2722922c60b1": { - "balance": "23993133615000000000" - }, - "995a6a1c38f037b3a9f0a2e915b8fc0efdea082a": { - "balance": "1403498530728000000000" - }, - "99709e57748a7da6556b1670ba4f15c45aef4689": { - "balance": "36000000000000000000" - }, - "99789f65655c6f917d575169f4ba8192440e659a": { - "balance": "393071814319000000000" - }, - "998f66cbde2693603fa109ad7aaa8bc42a8765a9": { - "balance": "49000000000000000000" - }, - "99afd42a58af31daa54ad9ba35b06954330107ba": { - "balance": "25000000000000000000" - }, - "99b6a9ff2b2ac9ac0361af007aba107695ff5fad": { - "balance": "12860157225353000000000" - }, - "99d16a5955d43723ed8e2b1a642f8f1195f38b64": { - "balance": "62907829047000000000" - }, - "99df609926ca536ed3be80e35dbaecc42ae67f2f": { - "balance": "316809833612000000000" - }, - "99f3faf97a36fabea7306979b30b08fa70110e29": { - "balance": "173292373556000000000" - }, - "9a26110067b473e3bdc0fc32951b39596c967a56": { - "balance": "78192198764000000000" - }, - "9a3a8eff6fb82377da6c17ba658dca87ca0dfe26": { - "balance": "50000000000000000000000" - }, - "9a3b06257088ef8c17410a8f2d63392edb9b55ce": { - "balance": "239567000000000" - }, - "9a426842301802866cca0ef89794d928d3e8f843": { - "balance": "776173297821000000000" - }, - "9a5f2c0a6d41131d9aacdb4f8c274958cbdd377e": { - "balance": "441954000000000000000" - }, - "9a6893023ac6f34b493d33e4dc63ef697169a58d": { - "balance": "439689418527000000000" - }, - "9a86eefd848acafcbd9960003e90b22162b15ef9": { - "balance": "294190908093575000000000" - }, - "9aa711f3e4eb67d2f6405b5ee6290a014d203a72": { - "balance": "9101556549634000000000" - }, - "9abf9ccf6abb8d55ede458d2d12a279d0a823944": { - "balance": "17609693072000000000" - }, - "9ac1909b983c754f0800559174025c0f0baa9d31": { - "balance": "80921948093000000000" - }, - "9ad62cd855d629e1ddab632874a6dc2b812f2348": { - "balance": "2068118534000000000" - }, - "9afc2c33aa2c9a42600abb18aedaefa433326122": { - "balance": "2485353229354000000000" - }, - "9b18d230b221a99c74877d4a1dbdee2214c7d60c": { - "balance": "4024172228743000000000" - }, - "9b18e27788c9d59053072032a480569e142595a0": { - "balance": "110789164888000000000" - }, - "9b4535b23af0b8e5f488a6f318ff6badf71d16c1": { - "balance": "84756740661000000000" - }, - "9b5e7cf43aece7b38ea2af6d08bebe2d3b926840": { - "balance": "262771268227000000000" - }, - "9b77dac92fedd0ad3eb4326d4fafe0f4315a8844": { - "balance": "3616321626000000000" - }, - "9b8f6f223641f9b1bab319dd1e88c49fd411a765": { - "balance": "2054417462086000000000" - }, - "9b9f94861d80365464912e5c7213403405a6cd8d": { - "balance": "2367093088000000000" - }, - "9ba24397002929e6239848596b67b18a8dea1eef": { - "balance": "5000000000000000000" - }, - "9ba99736c5ac468d6b644e39b8d515c39151f51d": { - "balance": "311900650761999999999" - }, - "9bf2d4ff366e1bb2313ae9a93ccca75d6bc0d232": { - "balance": "764870206925000000000" - }, - "9bfce7dbfc9ae62d450e862261d1e21e68bac92c": { - "balance": "1000000000000000000000" - }, - "9c003e74b62f192a864045d678639580c672fc22": { - "balance": "50000000000000000000000" - }, - "9c128bd2c0c96b896db6c0f398e908c98302809e": { - "balance": "3251059363800000000000" - }, - "9c255daa89ee16f32fc0ab1ed8e22db39342e6ca": { - "balance": "37695843594589000000000" - }, - "9c32e714bcb601a56a8a4e6b3f7bcd9e1c7a1b54": { - "balance": "50000000000000000000" - }, - "9c503e087b04a540ed87056c9371d591afa72df2": { - "balance": "64229084991000000000" - }, - "9c54297dd3527cbbb8ca8c305291b89bfb7ab39d": { - "balance": "61682466962052000000000" - }, - "9c55bb1db3b2bb06e605a66ced9ea2ac95718205": { - "balance": "16512365324000000000" - }, - "9c59dbc48b9cf53fe668784e89d30493da9995b3": { - "balance": "50000000000000000000000" - }, - "9c61b58aa760265f7fd1b9e749df70122ea81175": { - "balance": "50590272373000000000" - }, - "9c6c7eaf4bec0566a7bf8acd30e10311a963267c": { - "balance": "999999999580000000000000" - }, - "9c91dd4006f9d01d8caf5f5fb4f2c4f35ee63ffc": { - "balance": "175730980227000000000" - }, - "9c99275f5dee14b426302b1a47a8488c16432f2b": { - "balance": "2000000000000000000" - }, - "9ccf7b23528d062da63f6af3e26531b775c83c52": { - "balance": "928373869120000000000" - }, - "9cd21c30ccbc1087c9b351395fdea17ad669cc2e": { - "balance": "529762292313000000000" - }, - "9cfee47d6f24880af7b281cc00e1fc58e0a4a718": { - "balance": "198888257958000000000" - }, - "9d08251f7d4cfd66d15c17e1ea6bae5c795e290b": { - "balance": "813841349140000000000" - }, - "9d5411490ce89359bfbacf9f9957ebfbbc18debb": { - "balance": "22263187467000000000" - }, - "9d61e1dfaa7d0e0c5f5d733a24a1883c4e201f3d": { - "balance": "144000000000000000000" - }, - "9d754d94a15ab6d738e511fe4c775ee6d20a53ee": { - "balance": "20000000000000000000000" - }, - "9daccedf104fdcc3c39f2961ddfa1c64eb632476": { - "balance": "1237093270947000000000" - }, - "9dad4968c0e44aa729fc5732f3ee903c6799637b": { - "balance": "838788687517000000000" - }, - "9db73ca677bacbb622f44fe90b53ee1d9f0c2009": { - "balance": "472858335000000000" - }, - "9dbcb5026e0f444a33197da240856f108db14ff0": { - "balance": "10000000000000000000000" - }, - "9dc46cf729187ceed8001c4ab14fa4fc21c35f32": { - "balance": "3320792646995000000000" - }, - "9dd895c1bdac2ed9864134aaa8c543473ee5f19b": { - "balance": "1430620966869000000000" - }, - "9de2687242cbf9fb94fee0ad873acc7494ebd2bf": { - "balance": "20000000000000000000000" - }, - "9deec036282717aac93ad5cc1b6d4a5354e85c2e": { - "balance": "2048627955362000000000" - }, - "9df8dc66395aeae9b4c831b4d63bdf48db08811a": { - "balance": "215874670561486000000000" - }, - "9e1fe68a70abd8ab517878b03961da8564b43eb5": { - "balance": "67908329894526000000000" - }, - "9e33293006982abc668e199aab20260b9b754463": { - "balance": "49000000000000000000" - }, - "9e65616282a0baf89469a58915fd8fdbed210e3f": { - "balance": "829209872657000000000" - }, - "9e7b7b522834dd7e83ff2bb6b6e4cd2972330899": { - "balance": "500000000000000000000000" - }, - "9ed134b3a8feccb4056b2e511cea9a8ec58a3e77": { - "balance": "18787546978390000000000" - }, - "9edcf477687a9dee79341ed5d89d576c9a854c2d": { - "balance": "500449025554000000000" - }, - "9eeb06d4b532118afa013a01c9e89216fe0475ae": { - "balance": "1823939486758000000000" - }, - "9ef20a338e85044922f08f3648355e834874d551": { - "balance": "50000000000000000000000" - }, - "9f0855f9cc429fd3590c6ad05bb66a9e038efdca": { - "balance": "8017999878252000000000" - }, - "9f3befcc1884d16b65ae429228d26fffc146c8dc": { - "balance": "1016482445089000000000" - }, - "9f4571748463eee19e59ff9bd734a62a66613850": { - "balance": "20000000000000000000000" - }, - "9f51de282745f77b8e531e1de0b7c14e3369ba54": { - "balance": "1010657089383000000000" - }, - "9f6527175a2b581cc79f2a68c35202e0a7f2af20": { - "balance": "216495522463000000000" - }, - "9f70204d1194f539c042a8b0f9a88b0a03bbcd8b": { - "balance": "10000000000000000000000" - }, - "9f70e44704049633110ecd444f9540e241b50783": { - "balance": "9139000000000000" - }, - "9f73fea741e8506ba7acb477745dab1cfab8366e": { - "balance": "4461472359634000000000" - }, - "9f88d33d26c90e74c39c9676b8b580d21bbad124": { - "balance": "54437240781000000000" - }, - "9fa47455be14ad2eecce495281ed0eea926ec6a6": { - "balance": "10000000000000000000000" - }, - "9fbb15b595d154754a2ae77c77283db9d4e9f27b": { - "balance": "6195722646556000000000" - }, - "9fc480ab1823a59fd6130c3948980f95ac99f1d2": { - "balance": "24101151540000000000" - }, - "9fe5f054165fbf1943b1b02c01063f04e0c3890b": { - "balance": "1000000000000000000" - }, - "9fe7d3d5976e7b8b5ad6baa15ceae96c43c60fea": { - "balance": "55000000000000000000000000" - }, - "9ff116ea0e219814970cf0030932f5ce2cd9a56f": { - "balance": "36000000000000000000" - }, - "a01f6c36193839bc3a31e6d0792324771040fc05": { - "balance": "48298750000000000000" - }, - "a0264706d668522b737bbdbe949ce3e5a60fe314": { - "balance": "1423066922869000000000" - }, - "a02b13bb3b13027045ffb9b44bc7380a942e8ebb": { - "balance": "86845430807181000000000" - }, - "a03d246a931c3d422e5d2bf90f64975923a93643": { - "balance": "5834171660287000000000" - }, - "a046caaee59425ea1040867c62a6fcda11652a23": { - "balance": "83087966538000000000" - }, - "a04b57b2dd8b2082c53517d956f5909d25e14b69": { - "balance": "4518538234851000000000" - }, - "a074ef9e0ffe15619103e3de490f5813be53dcbb": { - "balance": "4568113810000000000" - }, - "a07bae42b44c085067de16e7d9846db529059acf": { - "balance": "4000000000000000000" - }, - "a08530e5fb7e569102b2c226aa5e53dc74483e4e": { - "balance": "2325665286793000000000" - }, - "a095a2c666f4f3203a2714fb04867c13c2add4be": { - "balance": "14768043990000000000" - }, - "a0a967418a3fcb3ee3827a08efa851347c528a60": { - "balance": "20000000000000000000000" - }, - "a0bb293071e07418ecb2fefc073136569ebd1736": { - "balance": "25871128320000000000" - }, - "a0c6c220a53b7dc790f7a5b462a106245c761f70": { - "balance": "1000000000000000000000000" - }, - "a0f06c86c49b248f4835bff405b620d12ec80d07": { - "balance": "484572382390000000000" - }, - "a10bc9f4d05678b26c4ffd2d92ab358163020b61": { - "balance": "10000000000000000000000" - }, - "a10c1197f7bc96639d01a652df73e49c669165dc": { - "balance": "1205859101575000000000" - }, - "a1221b2001f85f71e0655551e300ce115284b8dd": { - "balance": "1376698025177000000000" - }, - "a13fce836d65124fe5bcfa2d817ab2a043acbcf8": { - "balance": "55000000000000000000000000" - }, - "a15f1f609f7464906e0eb9d5e1d26468b90d9198": { - "balance": "16000000000000000000" - }, - "a1617dcf3acda60737e5ca9e4d0ecd82a98ef667": { - "balance": "500000000000000000000000" - }, - "a165c5f151d0daab905ba4a6d1fe5d5114fd7686": { - "balance": "41039049526000000000" - }, - "a17d5bed36c1059561e184a8a90a38ce955b92e4": { - "balance": "10000000000000000000000" - }, - "a18efb4e0950e7ac95970cd4591dacc286241246": { - "balance": "12403188476000000000" - }, - "a191fa6be64f2f6d2b4a7fb5a586416a605552c6": { - "balance": "60340281461000000000" - }, - "a194c15518cefbe94edbef3a2421586b51f7e1f6": { - "balance": "4153525550636000000000" - }, - "a1d0e41aacf83fc62fbecf35f8e873f8d734ecaf": { - "balance": "9000000000000000000" - }, - "a1ddd1f615ed483ef895e341f3266b6891f9b59c": { - "balance": "180411786335000000000" - }, - "a1f4d1e03114707a56ef9069bc20c6094e810d34": { - "balance": "51949145435222000000000" - }, - "a1fe101a65616cd03e3af03092be63434b7bf203": { - "balance": "1005401878265000000000" - }, - "a25a8225ce67c54048737601eac5e0d063c2fa17": { - "balance": "272038848571000000000" - }, - "a2714999233bcaff7294fa3e3b64c63ad45a928b": { - "balance": "14560781294000000000" - }, - "a28db3f7fb1771a3d77dfb19b54f88fd55b15c8c": { - "balance": "8000940572576000000000" - }, - "a290101bfe5fbc73146c4ec3ab5266c043eb701c": { - "balance": "1397563244603000000000" - }, - "a2924cfbcd37d0b321d6abbe57c645f9ce32340e": { - "balance": "200000000000000000" - }, - "a2a26c34f3d950c795fc965f6b1df3990e111403": { - "balance": "34525064429023000000000" - }, - "a2a2855851711bfc051c1f298821ae89e4c872c5": { - "balance": "491025000000000" - }, - "a2b956dd6f1934a4a44a026a18ac345ddabe42d5": { - "balance": "20096625821563000000000" - }, - "a2b9a118a79be81711d95485aa12e3efe78ca256": { - "balance": "10451051632647000000000" - }, - "a2bcf08ddd1778b30ea7882518148edfba2d9b20": { - "balance": "347033754668000000000" - }, - "a2bd489ec4790f4145f8a9a95c9c829c5c020146": { - "balance": "100311110878000000000" - }, - "a2ee35300ddf6a2491ec0e1848f8b56defafd7fe": { - "balance": "500000000000000000000000" - }, - "a31adf082ffd212df18d5a84b105a937e83b1b1a": { - "balance": "7124891785000000000" - }, - "a32c944e6c5fe186794b88d6bcbf51c47bea55ab": { - "balance": "732129357042000000000" - }, - "a33105d543f5d2b1220d4e1ecfdcf85699324dad": { - "balance": "74798779358000000000" - }, - "a3330c73e2d79355a14e570da1ec2e80f8048c69": { - "balance": "10000000000000000000000" - }, - "a3580034590e3052b9de5abd635e514ec5ba8694": { - "balance": "10000000000000000000000" - }, - "a360d8e2519dc6d7793cc371d91ad6add75e3314": { - "balance": "192622260840000000000" - }, - "a36b9b8b2adb20fb4a84d3025bf2e35baa8b7fef": { - "balance": "20000000000000000000000" - }, - "a3771b191237bef48339aa77ad5357f6227b358c": { - "balance": "512633055119000000000" - }, - "a3892bfd25705387cfb4eeb6d21089753c22e3e2": { - "balance": "258136912825000000000" - }, - "a38c793775ebfc7330b4331fe2dc848abb862b73": { - "balance": "1193250172232000000000" - }, - "a39417002ab94845541aded4a614a5a04af8187b": { - "balance": "1185722898000000000" - }, - "a3a79a9f929b54075de43689adb665ef914812ca": { - "balance": "100000000000000000000" - }, - "a3b59ea3d366f818ca09980846ac533d4685c121": { - "balance": "59734700360000000000" - }, - "a3c7b7c594a64225922e02039669e4d0b43fc458": { - "balance": "11779233750000000000" - }, - "a3cc39a68184e51f6445d3ba681a55f4157d4383": { - "balance": "10000000000000000000" - }, - "a3d414d9f210f7b77f90790ce09f6128abe50adc": { - "balance": "10000000000000000000000" - }, - "a3dfda16e5ae534ac100f56741b77b6f86786615": { - "balance": "9000000000000000000" - }, - "a3f79b9d1fc9d6dbaaef49d48fa9c9fb5a822536": { - "balance": "108910000000000000000" - }, - "a3f87414bc9e6f01c2fbde966fc8fb6edbf58c29": { - "balance": "441000000000000000000" - }, - "a3fa3f58c802d9a9690de760716275f14449045a": { - "balance": "437227558095000000000" - }, - "a417ec5a9749064a6521ca2bf9d05f208eeaed54": { - "balance": "959205202638000000000" - }, - "a484d5b883d2b99b81b7bef27e307957ecb64b15": { - "balance": "126491152120000000000" - }, - "a488cd48258e57d66f44e73a60c121f963cb29f5": { - "balance": "20000000000000000000000" - }, - "a488e3b5096e964b21cdeba12ab423f391765b6d": { - "balance": "1712050478592000000000" - }, - "a49dba65f28909e9bd2ce5675bd091f498c6c5db": { - "balance": "216802821062000000000" - }, - "a49eb6a791022c1324facc23d8813f9954d1c639": { - "balance": "287438914902000000000" - }, - "a4cc080a5c4649f511b5844a8e0b031927e13a87": { - "balance": "20333578449000000000" - }, - "a4d2624ac5e027f72edaa625ef22134217203b5d": { - "balance": "1000000000000000000" - }, - "a4d30e35c9617eafeda82866c96c3ce6bf14400e": { - "balance": "1223254927978000000000" - }, - "a4deae7355bd2e1d57eefa56600601b8b475a501": { - "balance": "36000000000000000000" - }, - "a4ff3b5abfe4e50adad16d01aaf62c3d4cdb5260": { - "balance": "20000000000000000000000" - }, - "a502b109869ef07451576bf0e13ab294e1f236b9": { - "balance": "94843398055000000000" - }, - "a517a3b5e4324197902e16f8a29e47335cf39c11": { - "balance": "100000000000000000000" - }, - "a51e101088da23c82907e3e2c65a058f0454b131": { - "balance": "196000000000000000000" - }, - "a52bcff6a7e2e70cd714058bc30a16138fe39899": { - "balance": "30429750204000000000" - }, - "a544e84c2bc4b17859d06f136b6e377e4e398b22": { - "balance": "143977568178000000000" - }, - "a54ddacbc17a98b9fb6292aab3d92f4c5753fd0a": { - "balance": "100583192014000000000" - }, - "a557754f6637a19c1a48cb9bf58c1fe897acf434": { - "balance": "2087038692036000000000" - }, - "a56649205d9ea247b49e03dacbed6c78c21beb4a": { - "balance": "5046177099585000000000" - }, - "a568136446ee6b3bf62a20238db3b11397a065f2": { - "balance": "11652249158033000000000" - }, - "a56a7865b526e315a9eb41f4847485c7e0c952fd": { - "balance": "50000000000000000000000" - }, - "a56bab2a9aac9d08a7bc9265864a80089b68570d": { - "balance": "37138466291329000000000" - }, - "a5965a601c5df7765cd70e5dad27dd23da67ac99": { - "balance": "10000000000000000" - }, - "a5a3161c44c34c441784b7df795067760b0ee569": { - "balance": "35053289069000000000" - }, - "a5c245cf843e691956007b94e259b437a4e6b7e3": { - "balance": "18749166170000000000" - }, - "a5d7de961c3b991dc78f2d6c0448fa6225116d3f": { - "balance": "1574510758868000000000" - }, - "a5f47d2081ef728808786128549a28a5662e92a8": { - "balance": "1750000000000000000" - }, - "a610c90f5b7e5f33044956ba431a3887de1c969f": { - "balance": "25000000000000000000" - }, - "a61c1919bc3f3181dc94e2230d35574cfc972d78": { - "balance": "8990565120000000000" - }, - "a62f1aabd91cbc0112e796d1ec3727fcd26fa293": { - "balance": "1311277302001000000000" - }, - "a64fff0bb32e32f81a541c393982bc59fa183b1e": { - "balance": "8291357610655000000000" - }, - "a673dae555d367b8d4a784274577a1884615b9d9": { - "balance": "27416452091330000000000" - }, - "a6c780b585355d84d9d3c13be5bd05374588e240": { - "balance": "913657165911000000000" - }, - "a6cc1f6f51862c2798adaa1d266988022005a71a": { - "balance": "284500645805000000000" - }, - "a6d9c82784fa20dcf28266d047db441cfeb8855b": { - "balance": "10000000000000000000000" - }, - "a6dae08f99e4fb57b066a645a259d8e4f7ac2bc8": { - "balance": "9044922773690000000000" - }, - "a6f49f36f8d10a796bc2afc9e069cb0c76004ddd": { - "balance": "128555691078000000000" - }, - "a721ce1c294a0f1957ebf9be20b0fffcf90111ad": { - "balance": "3392103457630000000000" - }, - "a72b82c33bd3d6060e8a04392d236775d48ec3ae": { - "balance": "1434465940701000000000" - }, - "a7344654f2a1a44b3774e236f130dff8a4721e82": { - "balance": "100000000000000000000000" - }, - "a748cced92a87066db8b29f931fb92e827488a9e": { - "balance": "5487679824758000000000" - }, - "a78dcb2bcbec2d0a60661e1715c9a95c9d573a68": { - "balance": "346798292989000000000" - }, - "a7a6c0505e7090e0b2c21394877f91c50be6b45f": { - "balance": "4125233658872000000000" - }, - "a7dcdd9b9785a44a2dd4c5eeeb863ac1feae0f66": { - "balance": "10000000000000000000000" - }, - "a8013e9dca1bd38975748de2fb6cb3af5cae74d9": { - "balance": "10000000000000000000000" - }, - "a807bf78b15c15cd9e8edcf586849db716fedbb1": { - "balance": "1458293606310000000000" - }, - "a83410ff00fb4b913dd0ea2003b38c5c3247350a": { - "balance": "2876442029807000000000" - }, - "a848f61298a409e77a03900712017572f35a3319": { - "balance": "2783106133600000000000" - }, - "a85bb81d0dc57f824a763814759fd93fe3020569": { - "balance": "4558027813744000000000" - }, - "a860611cd098ce98974313030d9f6f462bb274d4": { - "balance": "961594154368000000000" - }, - "a8799eeff72929ee6cbfb5b0c02985cd4841be3c": { - "balance": "500000000000000000000000" - }, - "a8c29b9b1349fac0be9a65873e1911b7439c9a63": { - "balance": "1264035560749000000000" - }, - "a8c321024a3c015d881efca33bd1b2c1788b379e": { - "balance": "528752788000000000" - }, - "a8d02e8925ed48f4274d8bee62253dc0d4f2989c": { - "balance": "209083880937000000000" - }, - "a8d2bde2ccd6bad67ee1b9550c9310accb37cd79": { - "balance": "49000000000000000000" - }, - "a8d61abc6a403adc183aeb74c83e4221fd28ee1e": { - "balance": "50000000000000000000" - }, - "a8eb6aa5a0c5b6d9260a202dc76ab674d9a5f3b9": { - "balance": "1041257515142000000000" - }, - "a8efc57efc776dcaaf4003a8cfa63f215ab0284d": { - "balance": "166144142685000000000" - }, - "a8faba86d87678294e311cfa7f8cbeb6f9d8a499": { - "balance": "124541781000000000" - }, - "a912e02f8eab0cb620316129875f919455201117": { - "balance": "6454482105955000000000" - }, - "a929ac95281d1a77a3eda3b5ac90a761ef03ff16": { - "balance": "1074305309650000000000" - }, - "a92a4e40519003813f5574397ce328d046f75802": { - "balance": "9188437500000000000" - }, - "a93850ba8fff3bd18ab259f87c58bbce84165fff": { - "balance": "39018890852058000000000" - }, - "a9843660a17c2d972246028cb8045472abdd346d": { - "balance": "1052681604185000000000" - }, - "a9866c6271733971e46df3c9bb27b3d3c513c166": { - "balance": "200000000000000000000" - }, - "a9b1299c0c064e766f9f29f4301a78c6e4931fcd": { - "balance": "267785134400000000000" - }, - "a9bc33b9c99dd5a3967387c1e99766f9bc74d591": { - "balance": "65356157048000000000" - }, - "a9ccf1cd2f816b15182997e3207d9a681bf21b06": { - "balance": "17521053440000000000" - }, - "a9e54bd9826f853f65e0be1ec0bb9c28f95e0eea": { - "balance": "6260000000000000000000" - }, - "a9ef563c872342f49817a903a5725b504d455ea9": { - "balance": "50134015139000000000000" - }, - "aa0d69c7e1382cd16c527a3fee48db19c38e1398": { - "balance": "142562301500000000000" - }, - "aa12abcc3ab373d07bf560fd200652c8580fd967": { - "balance": "5509242259903000000000" - }, - "aa1d6b968b3f8046a94f128864bfc612fc2e2700": { - "balance": "489179780895000000000" - }, - "aa20b8559d6dd1543e8c528775ae4b04c6242471": { - "balance": "169000000000000000000" - }, - "aa227e9d6074a60ecd43e1cc24092ee58560374c": { - "balance": "596190898010000000000" - }, - "aa7b660fec7b05968ba656eae9a8aaef4481720e": { - "balance": "674642002744000000000" - }, - "aa9e04077d44d288978a3a3ab0d7c251c0447a4c": { - "balance": "10000000000000000000000" - }, - "aaaac1e72955e9d67625cf8bed73fa643fb1cc1a": { - "balance": "9781187987000000000" - }, - "aab46c0c2db4e330834081f97678906252746f97": { - "balance": "16440184245000000000" - }, - "aade5358c52b8aa5ad8ff285c6b297e86f49fa0f": { - "balance": "982846000000000" - }, - "aaedb3fa2cf0ebca0ef4a121a28a406264ccc900": { - "balance": "100000000000000000000000" - }, - "aaf30bf76362a03450aefaf5bd68d28b84eb4962": { - "balance": "509106199370000000000" - }, - "aafbaaa6b6369e986ba72b196bd5f08cc458e344": { - "balance": "216372214000000000" - }, - "abb03c888d61c9102827a1dc0950145beb9d96b3": { - "balance": "144000000000000000000" - }, - "abc6dc937d7703a6b0c83659a328cde0d5008e32": { - "balance": "4052429106341000000000" - }, - "abd3910139a97cb92dc09a8a0352575bcc9ebed3": { - "balance": "24028359215749000000000" - }, - "abdc3953ef293c98989802063f8cb55e0e506432": { - "balance": "64000000000000000000" - }, - "abf1a47c582bc87d36e47cfce24e0ad249f42e73": { - "balance": "71947491720909000000000" - }, - "ac0b6e7aadfb5ffafd5cb3ef3620ebb0691cc3fe": { - "balance": "10000000000000000000000" - }, - "ac1a182607046b56e7a4bbab87cc1182874f79ef": { - "balance": "453499500178000000000" - }, - "ac251b311f781ad7a43d01b0b4b20fe891004e7e": { - "balance": "304621378298000000000" - }, - "ac258cec5ef49f96612d659f66dd4e6ea88e3c87": { - "balance": "255185373455000000000" - }, - "ac4000d9ad080740ef4a2ebe4a3075877bea277e": { - "balance": "10000000000000000000000" - }, - "ac7445c09372f15259fd852cc458783d6140c0db": { - "balance": "10000000000000000000000" - }, - "ac8d29dc05ea6c2f5409a76abe04321bf9381f32": { - "balance": "22464474197854000000000" - }, - "accd52b63822d8cb5117d9deb56596e072462614": { - "balance": "20000000000000000000000" - }, - "ace63a86a2ddfc79f677344e93dc0c4750b8fdcf": { - "balance": "1355066360964000000000" - }, - "ace83deb83fa8d319979658592b75ed13bdf97c7": { - "balance": "20000000000000000000000" - }, - "acf91515df16b21f1e5f5474dbefe596e4929b96": { - "balance": "1153047238967000000000" - }, - "ad04381f7ba89220e8fcd7e200f98a476683a904": { - "balance": "2000000000000000000" - }, - "ad22225bf225d8f705f93bdcda8d301180ea28dd": { - "balance": "1272512717188000000000" - }, - "ad3f74034ff5ca89f97b2585edf12376820307ab": { - "balance": "12303261515593000000000" - }, - "ad43a3527ad2b9445417cb73cbcb42965a5f469c": { - "balance": "67607364133000000000" - }, - "ad61cf9bf560bd5da75d55738477bd9aa25fb0b8": { - "balance": "4358939446693000000000" - }, - "ad649e8a3e1436e0604b0b8c9b1a5f1c09e06d7c": { - "balance": "344000000000000000000" - }, - "ad6b584813814db4c72c4c7eb31447d224074b46": { - "balance": "18445595367000000000" - }, - "ad7d404afc67c0e457fd3ce142cd30b506408683": { - "balance": "48218702840000000000" - }, - "adaf4d39b6806d132128ac438c2862c0a1650cff": { - "balance": "500000000000000000000000" - }, - "adda124baed2e1fdc1acc7b4a048eab0cd249212": { - "balance": "1074765673925000000000" - }, - "adef437c429d90a350b99750d4b72bc8538c5f98": { - "balance": "931901903135000000000" - }, - "adf826a0ea7dc4322d26e9d8c54c4180c1827216": { - "balance": "323567723315099000000000" - }, - "ae01d8b1668f8bfe6e225bd9bc746f7e839ac0d8": { - "balance": "321211880744000000000" - }, - "ae17de3ae6127022e53ebcf9e08457174cdee0e9": { - "balance": "3817903000000000" - }, - "ae243b0186793eddc6ebbb1a2c1f0b1cd574b07c": { - "balance": "9000000000000000000" - }, - "ae3ae1d41dfb16e19a1817b3639cd4300fd166c1": { - "balance": "55437674845679000000000" - }, - "ae506999882d4c6f05cc7979c342c0ce559a8df0": { - "balance": "1391755905401000000000" - }, - "ae524cee5aa23025d6ad185ccab75a6974335d53": { - "balance": "797132751509000000000" - }, - "ae5a55075d0541f179b085152bfc8c72c74abe23": { - "balance": "589408139567000000000" - }, - "ae63d02b18b464f0bbab4de943766bdc7ba2926d": { - "balance": "300261019201000000000" - }, - "aed8ffb86a49c09ae3a83e93d9045851434a9f0c": { - "balance": "1031991707237000000000" - }, - "aee18a9a2ccdf6025d61005827753ce4f510f7e8": { - "balance": "1818639022863000000000" - }, - "aee67910c514fa63a228769d5e15ca40bc4b26c2": { - "balance": "5688989238568000000000" - }, - "aef744eb2ec682dca128dc3149afcf881e367121": { - "balance": "818801643225000000000" - }, - "af04430b3e40e746127623532353a0f177a88fe3": { - "balance": "100000000000000000000000" - }, - "af181833edb15c9b2ee2329dcf1845b977361b7d": { - "balance": "93228805338000000000" - }, - "af30db29765b4fda6f075af96e8acd5046b099c4": { - "balance": "1000000000000000000" - }, - "af31fd30cfb10f1b0a12c2e7dd7ca56bdf517745": { - "balance": "36000000000000000000" - }, - "af70d6820e1d26194b0a9965b55254a287b162f3": { - "balance": "87593999609754000000000" - }, - "af96a573fa86c07389a71db797bea689419b23ca": { - "balance": "36000000000000000000" - }, - "afa4c5b674934e31a9aa5e3e723d85060d51c4d0": { - "balance": "10000000000000000000000" - }, - "afa6e4b4060c2e5969c2329d13cc42924412efde": { - "balance": "127502378589556000000000" - }, - "aff2308ac607f85392f4c8a6a043af67b7b849cd": { - "balance": "11130371831000000000" - }, - "b00ea9c459105b650def1e8569c85fa01837454d": { - "balance": "94928352162000000000" - }, - "b02a7d16ea8663c88416e6f64eaf57787d230be3": { - "balance": "17215604601000000000" - }, - "b03f4e9aa5c352cb1cec953d1123c2f22cd94b5b": { - "balance": "206022552274000000000" - }, - "b051459b91d253c5e8251a5a68282c291833466a": { - "balance": "297127749975000000000" - }, - "b055bdc874ca5a7d2f4bcbc51f1cfc3671b55f72": { - "balance": "1421913523478000000000" - }, - "b06156b99b891b756262c5b40db9bbe39fddc77f": { - "balance": "49000000000000000000" - }, - "b076893b9841d2775ec8883f05b74f1e5aec327c": { - "balance": "22591055478000000000" - }, - "b095de644af3c9f960f67502da6ac5eb050a158e": { - "balance": "4958067562725000000000" - }, - "b0a1f794cf70422395f74395abc9a7d0b271846c": { - "balance": "812057322000000000" - }, - "b0d36e0f426a99416425689c657fc6d64ad698ca": { - "balance": "1157727077158000000000" - }, - "b0f35fa554d6ed657bf3996cc027d045c3971fcc": { - "balance": "64000000000000000000" - }, - "b0f76b4c9afdfe35c41d588265642da60f1b97d1": { - "balance": "1000000000000000000000000" - }, - "b0f76b4c9afdfe35c41d588265b42da60f1b97d1": { - "balance": "2028311808491377000000000" - }, - "b1445842d56c56bc532d2f33ab9b93509c732a3b": { - "balance": "13522982470164000000000" - }, - "b156bafe05973bc839c4f115be847bbde8a67cb1": { - "balance": "10000000000000000000000" - }, - "b182e4d318893dc1c4c585195dbde52a84ed4ffd": { - "balance": "329498977335000000000" - }, - "b18f506e77df4db80ca57cefeaca4f1010f78f50": { - "balance": "956339304078000000000" - }, - "b1b6f617b110dd79c8fd77e729584d1fdfa9aa09": { - "balance": "16000000000000000000" - }, - "b1bba36e2d9e272e0131f4bae09bcfd92e0a63db": { - "balance": "64000000000000000000" - }, - "b2285651e57ae0ff27c619207cceacd20884d152": { - "balance": "1345938295122000000000" - }, - "b2419a93732d0d324daf7707fac3782a77b0dff8": { - "balance": "625000000000000000000" - }, - "b27206e9f2ac430841fb8da69b49d505f1558b8b": { - "balance": "29507819229000000000" - }, - "b2801fe902c7bbc987ba12ecae98765c99980fef": { - "balance": "240016083000000000" - }, - "b2843d5215ceb761e78f281402a1660c3abadf5b": { - "balance": "3335539720927000000000" - }, - "b2a22e6a04a2ce3287da3b8b6eed4ea1f18f05dd": { - "balance": "99999978999999999999" - }, - "b2d55a061fc6f90d2a05e0cbd26ffe0a1c3321c2": { - "balance": "1000000000000000000" - }, - "b326aec1cd523948ffec2fd1e8f21bd2b4308f40": { - "balance": "913000000000000000" - }, - "b32abc82b251e2d310ea7588cae4ad4acb657cd9": { - "balance": "26946233911000000000" - }, - "b36924d578973aec05ce7ab556d7ed00004949ca": { - "balance": "393041705867000000000" - }, - "b37482114c83e857c730588d7d959d300b8142da": { - "balance": "29429544454000000000" - }, - "b39998bade135ac6ccadff41cd709e161d01aa60": { - "balance": "26272579375000000000" - }, - "b3a995ee94f1d63d12f10cea5ab3d596c7c6f284": { - "balance": "64000000000000000000" - }, - "b3bf35e936fdbb7d0bbeeb1cf076f243855ed477": { - "balance": "754081187934000000000" - }, - "b3c2ac85b99abed4a2a52b5f96a2c98040d16022": { - "balance": "50000000000000000000000" - }, - "b3d1a2c0ab2d8987446d74f49e357adf5bf15986": { - "balance": "10000000000000000000000" - }, - "b3fbcd24c8394a5d2b7fe877f18681a109a404e5": { - "balance": "2558689648423000000000" - }, - "b4110f4e38405adfc054e55ff73c55842db8e2cd": { - "balance": "129000000000000000000" - }, - "b417f4681fdd4e53cfdf8550e3d326dbb0a557ec": { - "balance": "1000000000000000000" - }, - "b422970fb8799d83642b7ff715fc941d69e86053": { - "balance": "81000000000000000000" - }, - "b4237be71920497715826eae8d85c26cb3c111a8": { - "balance": "10499979000000000000" - }, - "b431839de4b21dfb44150cfc6ed00ea430a81687": { - "balance": "26839560174813000000000" - }, - "b43a0d6399c7d1be943c4b45838156a47c88f909": { - "balance": "10000000000000000000" - }, - "b44ec608b95d0d51105ce5f4b48de5dd72f346fd": { - "balance": "448125120000000000" - }, - "b47f63e14f6de6c3413b2be95a725e367ac18fb6": { - "balance": "500000000000000000000000" - }, - "b48071cd1b15f45028e9dec2237f14f10b7aedf9": { - "balance": "38042711385000000000" - }, - "b4b874b323b560aa0e4811ca574bd48b65b3fc72": { - "balance": "18063913676592000000000" - }, - "b4e4d4af0667f8158cf817bf1bc3eada08a551ca": { - "balance": "2149067370317000000000" - }, - "b4ecd625ffe470ee1fa1d97832e42ddf3f9ddf6a": { - "balance": "1181738860120000000000" - }, - "b53f380ce92787c1db461524290e8fcede552fe7": { - "balance": "12640674931821000000000" - }, - "b547e04ab8a44d3cae38704356f1f59408457b67": { - "balance": "286604155735000000000" - }, - "b562e4010a0a5fd0906a4cd9f47fc28f6f51e210": { - "balance": "1000000000000000000000000" - }, - "b584de7b38a2a2e3d9ff9c055b309ca56e5da5a9": { - "balance": "237896887904000000000" - }, - "b5c1129961c4a43673324aaedb8296f5ade82516": { - "balance": "4213058948283000000000" - }, - "b5da6711c72bf27c87923aed4a39349b4192e6b4": { - "balance": "55180742586465000000000" - }, - "b5eac5e7e03b9d31e40393e16e956cd588cb7566": { - "balance": "4508019435556000000000" - }, - "b5fd46ee4e02946dca3485439f98bdab290c82b7": { - "balance": "108321600045000000000" - }, - "b5ff2a3caef6ec30365f4f0ecbecbdeec1cacbba": { - "balance": "979696597242000000000" - }, - "b609d05242f7c13a4ae4036f6da9c0bae18dd70c": { - "balance": "229121731278000000000" - }, - "b611156a2f87fb45c431a5cf5740ded90c2dc542": { - "balance": "401783365700000000000" - }, - "b61c7623144afbd0f6cf44c951e4219ef8096119": { - "balance": "36000000000000000000" - }, - "b61cbe0e58ff6fa4c810ad03c759c79d9ff052a5": { - "balance": "1034495371371000000000" - }, - "b622bb67e95a03f58dc9aecf82c217e86f2cf7c3": { - "balance": "500000000000000000000000" - }, - "b62a50be3ce0e7cf8f61991daf8fa7e23775141e": { - "balance": "1000000000000000000" - }, - "b63cbff6b1747ad5cda101d5f919ce81dd67e363": { - "balance": "2570089937000000000000" - }, - "b65e80551a8687c9cef2d852949177c0e3b56e51": { - "balance": "100000000000000000000" - }, - "b68126ebbcb5ab9b0371b62597a38d5c1685b0df": { - "balance": "671140851028000000000" - }, - "b69f5830c371cad5a74ae823eb8892d153ef3c23": { - "balance": "18446744063709551616" - }, - "b6b4468c4db64e0b85cddc251d02f32fffcd1f7c": { - "balance": "10308006217291000000000" - }, - "b6c129312505e571148dbe69833d30550efc12c9": { - "balance": "5105834767567000000000" - }, - "b6cee8ef00b8674a9a96447e4511b30d6564ff67": { - "balance": "667754569888000000000" - }, - "b70f805aeba260d44f0730f0a9dec60f2b4f54a1": { - "balance": "2751303297000000000" - }, - "b71a901dc4b6c6463f7d221f868677bcadbcc680": { - "balance": "169000000000000000000" - }, - "b7385bd8f8257331f4c7a87c7a23724f615cff8e": { - "balance": "196000000000000000000" - }, - "b755692bc027e30730dc1d0e0b2a883830a84115": { - "balance": "30713083153428000000000" - }, - "b765305dda3c1e069a7a022ec127ff2140d0a820": { - "balance": "603122990932000000000" - }, - "b77403a4c56ffc7715b4bfdfe4b054336aeca466": { - "balance": "130840969728386000000000" - }, - "b78b2f6dc731d7d84b7eea151805f9208a1d0cf0": { - "balance": "142084687500000000000" - }, - "b792a0fd762c002a7585cfdefd36cf7ffb42fc05": { - "balance": "10000000000000000000000" - }, - "b7ccd7164aa7fb871726d9d043a8f8f890068c0f": { - "balance": "1170997140237000000000" - }, - "b801f49018317caf30f310dbe116f4e876184874": { - "balance": "50000000000000000000000" - }, - "b81ca2bc63cb4008cebdda3ce8f4eaba322efca6": { - "balance": "4678481047354000000000" - }, - "b82e3d50bf8c5b471c525ec8dd37b06688ed6178": { - "balance": "1202448975553000000000" - }, - "b841162a7a8876296f10794d8847d8095426aa54": { - "balance": "73500210754000000000" - }, - "b8421d375c3f954e22b6fd304235dd7c43b68bd0": { - "balance": "6499782706009000000000" - }, - "b859b76d77eb604728093c61fcabe6f9d22433b0": { - "balance": "196000000000000000000" - }, - "b86536268ace9be93a1db2012d6e3e59023ef2cb": { - "balance": "52878034904067000000000" - }, - "b87e1ac4fc423ab37e10ffd221df8056537b1d03": { - "balance": "119159824674000000000" - }, - "b8825a99806c5a968423e69d22f2b61a2f0ae9e4": { - "balance": "999999999580000000000000" - }, - "b8835acaf63e0e5d41fb743eb0f954040a38d381": { - "balance": "64000000000000000000" - }, - "b8844c74b227781d4b3fafd32e39ff6fa9857f77": { - "balance": "490694157000000000" - }, - "b8962e8bcbcf0f69144f8fcd2ec3ae8e54c05034": { - "balance": "1425313342735000000000" - }, - "b898b4ece8e0eea375f6eb85615652cc5c221593": { - "balance": "2284038029169000000000" - }, - "b8a949bfd9751c29c4cd547cca2e584d8dac4e12": { - "balance": "50000000000000000000000" - }, - "b8ad5ce2ae781e2d245919c15bbbc992185e5ada": { - "balance": "733786526623000000000" - }, - "b8cb6a9bc5a52b9cfce26869e627b2af0ff5ed4a": { - "balance": "98364826821577000000000" - }, - "b8cf6aac7b9028649f0d55a57b61640d70cef120": { - "balance": "104799890645000000000" - }, - "b8e827b5d1e10a3944039adb1a3dd7ff6949145c": { - "balance": "172413427060000000000" - }, - "b8f6d7f33ee5755ba56647ab8fc9ca27b8aba677": { - "balance": "1430769696978000000000" - }, - "b9221177e2b09725bc95f08c72c17c42887eea62": { - "balance": "1212779749827000000000" - }, - "b936e0d83cde9bb810b85ad58eb5ff0fa9c11654": { - "balance": "4999580000000000000" - }, - "b961d435c457e205fdbed5442c8614ecfd59616c": { - "balance": "27847452621284000000000" - }, - "b969e9d89f32002cd4f90ef5907bebbbdca6fe6a": { - "balance": "12455448454838000000000" - }, - "b981c9137cfca5389f0123927852278d2d7ff618": { - "balance": "92180707865000000000" - }, - "b98abf0fe91b0d3a16c6ed37aea446baea33fd23": { - "balance": "560454425563614000000000" - }, - "b99ab4e6ae277b9fb04537adbb781e8390b490ad": { - "balance": "32814665223319000000000" - }, - "b99d0a433d7994743dd675894c18ed03164436e1": { - "balance": "16000000000000000000" - }, - "b9d8b6f0a505d217709bb9327f3b9b3f84813e00": { - "balance": "81000000000000000000" - }, - "b9dbd64e3c8e6ad84c9c67c66e678c06ea7bcb91": { - "balance": "1161140466507000000000" - }, - "ba361f7a6dff16a96f957c63e08267dec8f9ecf7": { - "balance": "2170060167590000000000" - }, - "ba47f4136f74b566f62ba373651332b59e74e1db": { - "balance": "906249296535000000000" - }, - "ba5287cf15de91daeaea2465da4d4c1a14dea716": { - "balance": "98978398162000000000" - }, - "ba77d056d52f84e740579aa527792f826591c858": { - "balance": "50000000000000000000000" - }, - "ba895406774ced5fd2e759b58f9ffaed5e04fb14": { - "balance": "10000000000000000000000" - }, - "ba96fab21a4926fd1137558ae996b52ec14538a6": { - "balance": "10000000000000000000000" - }, - "baacc247801eddbf152fd6ec39d659f265935743": { - "balance": "2661902597584000000000" - }, - "bab2eb9fab8e699a958699b15ddc7ada5428d33a": { - "balance": "27006404153000000000" - }, - "babeacd7933c817472875c86bf126e6d11886f8c": { - "balance": "2461234517292000000000" - }, - "baf7021d4d754d4478d3c3624c2376e3f1d4ee5e": { - "balance": "1352066301857000000000" - }, - "bb0760bd1da973d8f70dd0caa6cadfcfd8199231": { - "balance": "177674700430000000000" - }, - "bb278c6a52eebd0b8950e9b78ba211453ccb1b6a": { - "balance": "25000000000000000000" - }, - "bb327e5f260b2dfe25fb180c2d3f4b63211c1dee": { - "balance": "7694972715000000000" - }, - "bb643e768ab20c135e7df3f400284cf04c40a6f7": { - "balance": "385756449779000000000" - }, - "bb73d1d1c289b4953d0033b52d9d2d0d92573d22": { - "balance": "11000000000000000000" - }, - "bb89936d562b19e4c599826ce7cd0c60cb02b512": { - "balance": "725910446589000000000" - }, - "bbc509b7999b0e94534477b98ec8927cba879677": { - "balance": "20000000000000000000000" - }, - "bbcfa9ab62f4eab14d6a1b09c1aa554dae113183": { - "balance": "589417352665000000000" - }, - "bbe78301134249b52b74d73ee3855e7e3d288a40": { - "balance": "4456159000000000" - }, - "bbe7bb4c4f1b506b58f7e3334e6c89011cf2d6a7": { - "balance": "3889127030000000000" - }, - "bc016690596e077273465d1728d18553b185654c": { - "balance": "185932953686000000000" - }, - "bc16b2ab9c7ab309249f93b496b75c6a7392cb10": { - "balance": "5000000000000000000" - }, - "bc254e5405b154b98abb5fe5508d3e7c98663f4e": { - "balance": "144000000000000000000" - }, - "bc258aeb0f18150d3ca253c6bb04f63d657d99ac": { - "balance": "6011905701701000000000" - }, - "bc2620b5ebac12a88b287b625fa5b336568e7869": { - "balance": "534886892259000000000" - }, - "bc318687cfaae2be4c5ece4a18bb9252486a19d0": { - "balance": "147226513970000000000" - }, - "bc32dd123fcc2ef0dc36484c3ab1bae5d9890761": { - "balance": "16000000000000000000" - }, - "bc5c5151be06aaf6180bc9c1058b181a5a30366e": { - "balance": "113865120384000000000" - }, - "bc66241ca430dc31a3e2f44dedba868e16b9a6a1": { - "balance": "50000000000000000000000" - }, - "bc7c371af0688b1c409f4b07662609a1c9efd120": { - "balance": "20000000000000000000000" - }, - "bc9454f7efc86e25d18a8e8b6e230de42a51d967": { - "balance": "148103676062000000000" - }, - "bc9d5456b975bf0b95c161c3355e4ceb28898fd9": { - "balance": "28083912047000000000" - }, - "bce0b47bf13e4517c53bbbe6e51544b99f3147f6": { - "balance": "919711480389000000000" - }, - "bce2d1ec7c41b426f72b352f5f2b7da3edac4157": { - "balance": "908085365725000000000" - }, - "bcf0756789a57f16206dd78bf6e1322ba9b9b85b": { - "balance": "110888224252000000000" - }, - "bd0bc4a0730f9f55a2f65f62662c7553db52238e": { - "balance": "8440290043000000000" - }, - "bd29fda37c2581a3f040c77eead3143cff24a346": { - "balance": "126022762542000000000" - }, - "bd4c1270322a26a1b825040b239008a447c31918": { - "balance": "727012140904000000000" - }, - "bd6a3da2db66dc9fa26fa2b63b14003d26ef91d0": { - "balance": "5492112771780000000000" - }, - "bd80fcccac60078fcf09f5bddd8a25a92fb9cfdf": { - "balance": "10000000000000000000" - }, - "bd92dc94b6e81a3da5dc3ae6bd80782622658196": { - "balance": "10000000000000000000000" - }, - "bdb35c2c595fe7a2864ebe20dd56d6ddaf9d447c": { - "balance": "4346566125000000000" - }, - "bded4718cbad2150c9b6df9ee7356e0f5c713cea": { - "balance": "311694803600000000000" - }, - "be1804630ecd95ac411b935566cecc5a24c6f18a": { - "balance": "85033246331000000000" - }, - "be2318ad50b0a85b95870a81dce5c31029636159": { - "balance": "5185298019030000000000" - }, - "be3de52fc1119f02f4707f353c040b7c4222d847": { - "balance": "25267399461000000000" - }, - "be4feae01d429c872601ae84dfae8fddc3372686": { - "balance": "20000000000000000000000" - }, - "be7c09d704d16e4b2c9e19cc8c07808bb335f926": { - "balance": "25000000000000000000" - }, - "be873a9525899bdad5e4376b0115950e534dea2f": { - "balance": "404116929377000000000" - }, - "be891b1680ad835aab1ac05a30c0813306cf20f2": { - "balance": "144000000000000000000" - }, - "be8ed2d85a5e3f83c6105db1a1f304e9f174bfce": { - "balance": "50000000000000000000" - }, - "beb1cd80c2f8fabc27ee3a3b2a15e35fa52e7879": { - "balance": "11539095431000000000" - }, - "beb67375e46950830906bf281209be133075452f": { - "balance": "1305262446956000000000" - }, - "bebe54437722c6000bc6a8843f159538a2abf613": { - "balance": "41042548942568000000000" - }, - "bef2a05e283ae948efa9b0e3a6ab5d26a57f1de0": { - "balance": "180614450853000000000" - }, - "bf03950f265a4182b4402703723a0311158eef4f": { - "balance": "158997402149000000000" - }, - "bf06393654baa1ad15c2e717e06dbaa61834c214": { - "balance": "34409427774000000000" - }, - "bf2b867313a44bd04aceaa644771d1e95317c881": { - "balance": "10000000000000000000000" - }, - "bf350ccad91a2a2aff4cf27a291323a297a78009": { - "balance": "124593326152000000000" - }, - "bf3d86edfcf52733e91a9c59be606a95bd921885": { - "balance": "20000000000000000000000" - }, - "bf5b21d5e339752b33b180064d0e6047338650a5": { - "balance": "1000000000000000000" - }, - "bf64c2715db8f353600a45b9264e1f22a40ef8c1": { - "balance": "2952972677360000000000" - }, - "bfaff32c8b04a61658ff94f94e4687232b8d2d7a": { - "balance": "1117691379350000000000" - }, - "bfb00182321502e0729d9a0862ec1df1b3e2208e": { - "balance": "500000000000000000000000" - }, - "bfcdfc9f60610f0ca279ca2c89b9af831332aece": { - "balance": "1431082635308000000000" - }, - "bfe14356e86f6b2ad470bc77d250517c8dc03d15": { - "balance": "310115085185000000000" - }, - "c008bd3fb881da9dca4cadcc56b1d99c56db9abd": { - "balance": "12899598792000000000" - }, - "c01efea456d30360a78ee10c790d46bcb889ee61": { - "balance": "103203021492000000000" - }, - "c03d622627bba7d5db1a9f699924e9d5ff5640f2": { - "balance": "95102233308870000000000" - }, - "c0465ed806ce7ee730e5b6eb7b86a754bfd196a9": { - "balance": "1654379359619000000000" - }, - "c061c5b0d0ce7af95ded1805abb23f743e13c455": { - "balance": "500000000000000000000000" - }, - "c074f2024f79cf8d7aab2d858dd110fc2ee89d41": { - "balance": "18382732686000000000" - }, - "c085147a76d0336b4bd6e7d5b60d394bfd3c6f42": { - "balance": "3236912707535000000000" - }, - "c089416d2d679cb2abf44251de227d0a08fa1206": { - "balance": "497124416350000000000" - }, - "c09d8cfd85989397dc723f2df821dbfb2c0c39b3": { - "balance": "833485701262000000000" - }, - "c0aaf130e3b67250d9775d62e7cd3963daf0a627": { - "balance": "1249947125780000000000" - }, - "c0aebdb5c2e8c5ff9870535c738bfe892c9365dd": { - "balance": "360097616959000000000" - }, - "c0db5680ba88052652bfd5a617c4e8a5be188077": { - "balance": "509051625766000000000" - }, - "c0ee350e5e09a2daeff332a66a6e117fad102112": { - "balance": "10000000000000000000000" - }, - "c12c0a3fd42501f8772e4ad5d262eef3f0bc4701": { - "balance": "120398848512531000000000" - }, - "c135b48c7fd11670bbfba923b28767d21d7923ea": { - "balance": "20000000000000000000" - }, - "c1397c66b7f150c0062b0e87c981c107d771b109": { - "balance": "87751498250000000000" - }, - "c1507ee435cf506fc5d8e4cb62515f2ea0f3a7ae": { - "balance": "4935384099000000000" - }, - "c150d185e2cf203054a6e328b72d8c35bfbbcc33": { - "balance": "21044148271000000000" - }, - "c163098f8b8f0736862274860b3842cf14bd2288": { - "balance": "119025568966000000000" - }, - "c1687fbbc7d504b73fe3e71af440b3dec0da88b2": { - "balance": "229520711528000000000" - }, - "c172bf224080d448261b3b66453074b28628daf7": { - "balance": "7903438287958000000000" - }, - "c18e9bc05dfee2a39fe2b6778a24a48d5bf0f141": { - "balance": "500000000000000000000000" - }, - "c198fec4069c95300d34b9c7109d7441b8e62745": { - "balance": "50000000000000000" - }, - "c1b4134f4757d19a687d05bd7087872b5625405f": { - "balance": "20000000000000000000000" - }, - "c1b43ca2af534ac6bcad8f23c30c07ba07e7e8fb": { - "balance": "194999622000000000000" - }, - "c1c2249507d2dcaf4a9103fcea2cfb47aa4957f7": { - "balance": "571416394325000000000" - }, - "c1e90af40fb64427aeb79a13607debbae9270b52": { - "balance": "50000000000000000000" - }, - "c1ffc8938f3412d19d428b8450f17fd394ae539a": { - "balance": "36000000000000000000" - }, - "c20013e25ae53d0d41bf365aa767822bbbe70936": { - "balance": "10000000000000000000000" - }, - "c20e9eadffa5529ce58a39f5898f39906dcd4b78": { - "balance": "757301065305000000000" - }, - "c211fc2623d51846d26952628d140643efa5156c": { - "balance": "865384323985000000000" - }, - "c2546c312570b30ad2ed05edb13b6469494c5b92": { - "balance": "5000000000000000000" - }, - "c25b2280ed0f835538f8ffd9dfc08a3b853f1ccf": { - "balance": "1000000000000000000" - }, - "c260e43b89a7a4e84bcc4c21dc43d4b5e6923f3a": { - "balance": "1000000000000000000" - }, - "c26aeef0e1f382c88bbdb1eb8c01afa7f58218ce": { - "balance": "79774757760000000000" - }, - "c27dd2645254bc30b6cf7bf418803b02ac808b5e": { - "balance": "4419594173874000000000" - }, - "c2b4f6cf92d6d63a20034e409a358df1803159b8": { - "balance": "1630820442000000000" - }, - "c2ba4a7ea6ca2d17231fb17ebd5dd2dfc0964de4": { - "balance": "221662324727000000000" - }, - "c2bc18f24b8097208a8b2418c444ea58beb94281": { - "balance": "1766754009521000000000" - }, - "c2c028dd17f8a89b9131b7daaeae9cb1dddf86e7": { - "balance": "10000000000000000000000" - }, - "c2ed78a0cb850c12ce8e6ff3873e8c18ffc9f4b9": { - "balance": "1017518755567000000000" - }, - "c2fd7296210b7013d476205d2517d51b21c9e76c": { - "balance": "500000000000000000000000" - }, - "c3041d3d650ff6ac3e35b60371b6798360727651": { - "balance": "1011071365226000000000" - }, - "c328ab9ce1fddd5623e0383828714a7e3ff12eff": { - "balance": "285042661579000000000" - }, - "c34ab008ddddf376dd866cccae4a4d6eb88403e2": { - "balance": "2798642711076000000000" - }, - "c3511391c4515cf8f27e9bc0f777a02a4125c8b1": { - "balance": "20000000000000000000000" - }, - "c36916a9fdf656bb1a8c2f7fb752a3489020f6ff": { - "balance": "689483152953000000000" - }, - "c37598a388d6f4e8e046923265ee9256456e40ab": { - "balance": "62865106394696000000000" - }, - "c38813db256eb221a7142d042b81ba2babab2c31": { - "balance": "98477603778000000000" - }, - "c3acd30f0bc3146fc2cab8d54904f98289021374": { - "balance": "17820000000000000000" - }, - "c3ede34dc1cd995fda1c5cb6e9ffd0c0da080587": { - "balance": "1080428143758000000000" - }, - "c3f04dffe2be55a1d6cdaa78e5c09a79d0477e7b": { - "balance": "59747493842929000000000" - }, - "c3f09f681cfb57d3cabc547dc32a71d2a6585c1a": { - "balance": "1757648436173000000000" - }, - "c3f3bb6444d853614f18c04a3c81f7d26e62e96a": { - "balance": "9022830778000000000" - }, - "c3fe4534327a2fc4144e2d3d3392f7b78d2aabc5": { - "balance": "1759225739027000000000" - }, - "c424f5be9490ec7f0f1e2debc3f72bd83e35f587": { - "balance": "1774372626989000000000" - }, - "c434f64eb937207f80e9a02d2f77ca34bfc63aa2": { - "balance": "960850858644000000000" - }, - "c438b6fa5801a4b8dea450530d975f174cdd47ef": { - "balance": "64000000000000000000" - }, - "c446effb984ff3e5ed92280e7b3dcdb1284230b3": { - "balance": "503490303680000000000" - }, - "c453ae9f94253ebdb871e9dac19056b13d1747a3": { - "balance": "1621494076559000000000" - }, - "c4a473b5e3a6bfb51f963d4dcf109bddedf4fb43": { - "balance": "104273242373000000000" - }, - "c4b8058e9e5416e526ea16e37f29dc221d28a003": { - "balance": "1833513486496000000000" - }, - "c4c09f4bbae0ee06f2a52ff0ef0de1978b5305e9": { - "balance": "20000000000000000000000" - }, - "c4c5981f5ac0a9a3701663b887c4aaac3a3a4d1d": { - "balance": "1411640000000000" - }, - "c4f7a493d16aab4d18e88e530e75e3095a3439ee": { - "balance": "191606419322000000000" - }, - "c5259c18bbd8b0485ca83d069d5ac235b28f24ea": { - "balance": "1276479076242000000000" - }, - "c526ef1124c7d0549b117e7b7463539a24209290": { - "balance": "9106523141000000000" - }, - "c5278b9eeff2221604f30f002c307ca2882fba97": { - "balance": "20875716591000000000" - }, - "c527ca73562846de9fca1649fe5144e5068a2f6e": { - "balance": "25000000000000000000" - }, - "c52a960c5df55169ed5d5cb0109a576321ab82fa": { - "balance": "1097338876493000000000" - }, - "c533ab799e5a04e0ba4e4780d632e0044262d216": { - "balance": "200529941482000000000" - }, - "c5389e3ee2f043ac2b6481f254440a97a9cf3bdb": { - "balance": "84047554571000000000" - }, - "c5594292b324c1d63f797c588a589c895c680ed0": { - "balance": "334298857161000000000" - }, - "c55d7ae4f29d857182d5f1ac2a78cbf35a694dc2": { - "balance": "500000000000000000000000" - }, - "c55ead0ece8fcfbecc573666c0170228e089aefb": { - "balance": "438775082956000000000" - }, - "c55f7d73491cdba391b631581029de32755a09b8": { - "balance": "1340000000000000000" - }, - "c56cb4e8308d6462eded0bbc74965ee135e23e11": { - "balance": "568187503785000000000" - }, - "c5b0c5f840f579536d5977a77262458d72ef1490": { - "balance": "5880686297881000000000" - }, - "c5b129c764daac8bfbf023646b9306d817a8ebdd": { - "balance": "10000000000000000000000" - }, - "c5bba43db949e2ed3de3036caf7a6e42558b1ef2": { - "balance": "763947031151000000000" - }, - "c5d57171e5b9cbafaba7d2c13cca3ec9d81bda49": { - "balance": "25000000000000000000" - }, - "c604e6c539c857ae9e60ca20d1906308ba431892": { - "balance": "100000000000000000000" - }, - "c607bdc5ad2f189e9356edb4d7975c7ba9300836": { - "balance": "55828814399000000000" - }, - "c60b0d2341ecada6c3faf1efcc9027125d99e17a": { - "balance": "121000000000000000000" - }, - "c61e1b993c3fd91a1023ba5b92d06a0aa539d92c": { - "balance": "23863993763643000000000" - }, - "c624656ee5298786cb3d0de045b0ac089c5341d6": { - "balance": "2210389938000000000" - }, - "c6573a023d6f4b5e151f266af4ec0045df0d1518": { - "balance": "52505006485983000000000" - }, - "c66b1d84c42018b16dbc4777409bf50a49febba9": { - "balance": "9078953000000000" - }, - "c69e4de93457f251b1e0879b5250b26e57839fec": { - "balance": "500000000000000000000000" - }, - "c6c51205c9f0bcaea05dce8e47e91d94a3f63c2a": { - "balance": "2720612321571000000000" - }, - "c6d237e0936c4714e701823aadb368fdc471451d": { - "balance": "541700595551000000000" - }, - "c6dcac15739872089cb3d23287e8cd546487ecf2": { - "balance": "1023857245227000000000" - }, - "c6f40b81a5860dece34305f53570be61cdf9a8fa": { - "balance": "20000000000000000000000" - }, - "c7147a95cc4f6bedce6292e8f95539caf550e9d6": { - "balance": "20000000000000000000000" - }, - "c7185b1a680d8b0893065d8213de54375d086420": { - "balance": "11564622085000000000" - }, - "c71b3876613c928197aadf3dd7888db3665f28f0": { - "balance": "112276274428000000000" - }, - "c72200bb380db62a3fd741713d332be77bc1a4ed": { - "balance": "6962060809000000000" - }, - "c7345cd5a7eafc9d7ebdc17d674f83e23336538c": { - "balance": "4425703195684000000000" - }, - "c734f9dc3ee2d857ac826b101129eb77a4a22256": { - "balance": "100000000000000000000" - }, - "c736fa9550b73f4a4ca0ac1cd94bf6f42ccbb11b": { - "balance": "449139000000000000" - }, - "c74128ea37f5d1ee016086a38e470bb332eb5270": { - "balance": "40479951869000000000" - }, - "c7647ec91e823cfe57e8a3433ddafd7b4f675b80": { - "balance": "307102062000000000000" - }, - "c76d49334ce25f5fc62841e5a87d4e03ab3edd9f": { - "balance": "109999979000000000000" - }, - "c771093ed5c4df518536b76e013e8142ecc3f9ed": { - "balance": "5247752820195000000000" - }, - "c780dfb4cdcba4dc89245a8be8a93de1a3e82d3c": { - "balance": "205580199482642000000000" - }, - "c79c6c3a0a46052f723a26b1f107a332474df3a1": { - "balance": "50370325181000000000" - }, - "c7a4e02d2c0f00fa56662cc9f323cabeff82759f": { - "balance": "1163435680762000000000" - }, - "c7c0632cff11812130c30163c83746839a625f95": { - "balance": "10000000000000000000000" - }, - "c82238664bedfa8ded51e91969a39f13a8262a37": { - "balance": "10000000000000000000000" - }, - "c877d228c350ec0d8d97802e7d874d3130171813": { - "balance": "199845203467946000000000" - }, - "c88b8a2e498fee366a1290a575a7f09da12ea8b2": { - "balance": "50895598476000000000" - }, - "c8bbd0e52b11ae6a20adc5f6bbe4d34d7440e8ca": { - "balance": "114566193776000000000" - }, - "c8ca2bd1bef02b505f0333996bcb6bf730648390": { - "balance": "1177250974576000000000" - }, - "c92c3358910418fdb3950e1a378af7246553ae38": { - "balance": "81000000000000000000" - }, - "c9325c9b6d2af226bc5ae1cc975e00cc11274cd1": { - "balance": "2927587698197000000000" - }, - "c95ae8dbc8bb075e7dcb2b2c6d9411bedf26244e": { - "balance": "931878010706000000000" - }, - "c98fc33c1d980052d75fee8b34d08796734b6a4d": { - "balance": "8671327034000000000" - }, - "c99fba8321d16cb19c55703b407c54ed106dcdc4": { - "balance": "20000000000000000000000" - }, - "c9a0da2a3be799e751738e61b9cc376eb06e2b00": { - "balance": "50000000000000000000000" - }, - "c9afc551058c32e89bc2d6704d0d00e92f5ef6d7": { - "balance": "11135553563900000000000" - }, - "c9bfa2ad4b3e9c624255c6ede116421b04487d65": { - "balance": "105514983171000000000" - }, - "c9e4b61d8ddeee339e31ba088efb5d608c3464a5": { - "balance": "20000000000000000000000" - }, - "c9e9090d9f95f401c87c7240f3bf88ca9b540f8b": { - "balance": "553735838243000000000" - }, - "c9fd40bb35284e3d7f0dd3b43a1d9e958f7c86e0": { - "balance": "50480449695128000000000" - }, - "ca038c7c9e66531ad79e4d67b42d7920b7f05c26": { - "balance": "64000000000000000000" - }, - "ca0d08f6019884f94f2b5b191ac9bb247150cd13": { - "balance": "25078089364984000000000" - }, - "ca2c6e6ed3d6a1d030807f91e1fd5c79d36af86f": { - "balance": "849454139892000000000" - }, - "ca7c7bbc24cac0f3aabfdccc77df21004672e634": { - "balance": "6952718700000000000" - }, - "ca998c74383b55c8dcddd46b49f95456fb056b7a": { - "balance": "2000000000000000000000" - }, - "caa989e6a1e934532aaae6cad282c18b1a0b9fd6": { - "balance": "2335540529729000000000" - }, - "cab32ee5cce74e0ee88bbd4b505aa587ef2e4bbf": { - "balance": "75914058971000000000" - }, - "cabe9f0d0a18de8d3495dd063b04c6a33584a8c1": { - "balance": "116083536145000000000" - }, - "cacde94daeafc06e46c86b1e20387a23d909ace8": { - "balance": "1521003430346000000000" - }, - "cafbad01b81ad6cc401883773994a9dd6e6ed913": { - "balance": "10000000000000000000" - }, - "cb343b882cfe866f73cd5f0f31fc68cebaddd882": { - "balance": "221801563082000000000" - }, - "cb3a7aa2e97517b6ea8d9ed0ac270a6a9cc6e079": { - "balance": "958830201738000000000" - }, - "cbd2c4916211ab2c234bc8a51e6f680b59aff782": { - "balance": "24279462419000000000" - }, - "cbea4ed5e8d2ffad442e482fa5f8d551ef2a58e6": { - "balance": "26730000000000000000" - }, - "cc001ce4f4417505116486bed9fdf04bf97ca246": { - "balance": "31740534557000000000" - }, - "cc0b53b26b6dee9f8226f25b834085bde13f5eb5": { - "balance": "132440104515963000000000" - }, - "cc174862456f02f349303d1b8328495de8ccd789": { - "balance": "155951512603000000000" - }, - "cc2af3921727d6d2de31d5f656f837a5475de6cf": { - "balance": "10000000000000000000000" - }, - "cc3201749f55f0d7b450110bc11f65b1ce165d2a": { - "balance": "123428947550000000000" - }, - "cc3f37ad6b449e39c544e26bbdf4d7be66b9dab0": { - "balance": "348574664284000000000" - }, - "cc5b36c9ecea12ebfd0721a58ac11b0c340a3f44": { - "balance": "384197170701000000000" - }, - "cc5b410c7797faa05ac4233eb31b468ee4bf279f": { - "balance": "10000000000000000" - }, - "cc60b223554cc6425374c5e2424df7007621368a": { - "balance": "1128118098000000000" - }, - "cc7027381d98c2e883c82bb9c2f85b985e1e7b4c": { - "balance": "1370000000000000000000" - }, - "cca378f16e07258b9c15921233110fb4729645d2": { - "balance": "151974946930000000000" - }, - "cca781d996c3ef985bf7d2b4d68d55f52efe1905": { - "balance": "2217463190039000000000" - }, - "ccd0b9f6ffb0383553c355c6a14be1200966d47d": { - "balance": "12917165349191000000000" - }, - "ccfa4594129bbb9d07cb4ae8dc2b1c8f3bf98508": { - "balance": "524845286088000000000" - }, - "cd19c879df458106d179bbb5b7f44609d68e6e5f": { - "balance": "8601633489844000000000" - }, - "cd1c55037a0570e8f9aaa95ef157ae81a1969250": { - "balance": "10000000000000000000" - }, - "cd1e47695b0fc93b82cffd0326852dc04d8441f0": { - "balance": "144000000000000000000" - }, - "cd1f90c388d76b3aeaf77850f2191f12a2311f51": { - "balance": "1728456799866000000000" - }, - "cd3aecd58de07f80b64044875fa6ad4f18f72789": { - "balance": "2648597880142000000000" - }, - "cd4f39123ece1e0ab52cfa2a5d059b49c4d63c3f": { - "balance": "1661718859439000000000" - }, - "cd6ed2f7ab49515f8fd70aeb4d72bfae8956b5f1": { - "balance": "183807926254000000000" - }, - "cd9d9d07fcf476a8ee7240324a602449606d75f4": { - "balance": "100000000000000000000000" - }, - "cda66d375a10a22f13dff8a9c40b63461daddab3": { - "balance": "1116940051064000000000" - }, - "cdb0832ee5b26da24b1775c4cf0dfd669b94ce00": { - "balance": "23919219542965000000000" - }, - "cdba5805f17df1f3e47647464de978944ed36b62": { - "balance": "4204539000000000" - }, - "cdd1df8bd54941e26ea26eebbd537e751f64f5f7": { - "balance": "5000000000000000000000" - }, - "cddf5b34342200c37ba96eb0dd662ca4c29f89f8": { - "balance": "10000000000000000000000" - }, - "cdf6c838980afd91a600e3fff755a4848d138568": { - "balance": "25000000000000000000" - }, - "cdf7f55a5a16572d2f2bbf7faeffe3c4d64f86ab": { - "balance": "3115969322502000000000" - }, - "ce0f1dbbfa3490a21ee4b28232db612f44bb7bf1": { - "balance": "9227310122000000000" - }, - "ce33184573c33dd859450304984fa63ea4f2b62d": { - "balance": "7055925237496000000000" - }, - "ce33a3db107f01c51d30b24a8db80faf05308bb7": { - "balance": "10996113113089000000000" - }, - "ce4922b3daef62914f0580a55c524e6a02e31d83": { - "balance": "5541295938315000000000" - }, - "ce4ce8a8540678dda16380c211482dd8c8b71092": { - "balance": "6224176337062000000000" - }, - "ce62cfd71abb9979a0acc398c17dbb5cb6da4721": { - "balance": "13448605175000000000" - }, - "ce724bb30c7821a9c847e0a3e9c12843c3471f9d": { - "balance": "252657175031000000000" - }, - "ce8af01494c2c5b4e74bb02dc6de982e7234fed2": { - "balance": "77349533545000000000" - }, - "ce8c774b7f92045faec43e9cc1711224a3b32435": { - "balance": "370287579971000000000" - }, - "ce8c9ed5018559f36ec72e5a9b0701724e498b51": { - "balance": "142866501748000000000" - }, - "ce995c13568a8b1521d4c9721cfc11da4891860b": { - "balance": "1000000000000000000" - }, - "ceab9dddc767a9651e98527fcf51f6e85c9ae402": { - "balance": "5251411770975000000000" - }, - "ceace25f8c7cf853500a461df007f9c9703ac4a5": { - "balance": "1428847332255000000000" - }, - "ceb0c49dad36f6169ec82a2f0d80da36c87e4209": { - "balance": "459821324064000000000" - }, - "cee8083233bcb4d50ddbf2121c90b5c2019ca58d": { - "balance": "557985245088000000000" - }, - "cf0c6bcc66eb75899bc7f8ed4b8d2b29437bfe85": { - "balance": "3252418478000000000" - }, - "cf32c5bf1d7ef0cb0f2f190f8468b01a4f2d93e2": { - "balance": "6593164924646000000000" - }, - "cf6e47463382153fcf0ec6738880925dbc08116a": { - "balance": "1091910654350000000000" - }, - "cf7539096fd0cd97cd316efcfe9d3c87a101a74c": { - "balance": "741847588809000000000" - }, - "cf9439bf2fbab65cecd783e135a37127f585f1e5": { - "balance": "50100000000000000000" - }, - "cf9bdc902604fab070c611ebf6a989ac4a785c82": { - "balance": "1501000000000000000000" - }, - "cfbbefc0e6013fa2caeabc54ac05f45dbf17ca13": { - "balance": "230809632301000000000" - }, - "cfd53f18ac7d94cadd032a0f4cdbdffaf4765d6e": { - "balance": "64000000000000000000" - }, - "cfe66dc4aa9ac9c9f87fdd05c1b2b95da5211703": { - "balance": "1656993051100000000000" - }, - "cff376eef4d69c4a47d6c7916583228fab3b5967": { - "balance": "5904462494391000000000" - }, - "cfffcb819302d05ed763026bdf84b48818938fb0": { - "balance": "289619807900000000000" - }, - "d000aa72a77d55911a5e66c2906da9206db86633": { - "balance": "3008989624945000000000" - }, - "d02d7b42213e873f91e789cbaffc734ffabd1087": { - "balance": "144960809826000000000" - }, - "d02db5279e918b3e93ff81d00d4025cc71dccaf6": { - "balance": "2386625717975000000000" - }, - "d0802cbcca2bb516f251b873eb20bb5e94af7f37": { - "balance": "9287997718210000000000" - }, - "d0c07380308972a36f57d1cd9081d7389d0421cb": { - "balance": "1280367167470000000000" - }, - "d0c131c1b60891b91e58fbed787ee4567e3f2038": { - "balance": "6360752089492000000000" - }, - "d0c71159d46c4d2af7699f682a055c79a1a68a0d": { - "balance": "1527974433762000000000" - }, - "d0d5d9f242f2613079b3b443c359c2e18ed5faab": { - "balance": "637334647476000000000" - }, - "d0dd208ce92da02eee3ee3de335e67f819581a33": { - "balance": "100000000000000000000" - }, - "d0e55ec0ad0f8986dd9fa9d738007c5bdc22f840": { - "balance": "53012893797000000000" - }, - "d0f222cec657ee444e284c07228d585155b82c0a": { - "balance": "7368748129592000000000" - }, - "d11efb07887d8b5b87a77d8fd388190614e8c077": { - "balance": "4703283503278000000000" - }, - "d129f1b89045ebfb4d1df1d9077e9359fd2990f7": { - "balance": "14496053137000000000" - }, - "d15a509424c4e04868bdcf59cbee09882ba04c8d": { - "balance": "65042393236903000000000" - }, - "d162416912b03fa65f3972a63e357ceaa3b621f7": { - "balance": "325650177224000000000" - }, - "d166183164b81bd049b2146a3ccfcc78cc6a0bdd": { - "balance": "1000000000000000000" - }, - "d173d759f0916e61400d56ca690cbf1743fe27b0": { - "balance": "53550838679000000000" - }, - "d18dc883e3881bf4c7db2afaa097bc2d33656724": { - "balance": "5000000000000000000" - }, - "d19dc9b5ae689dea1ccbfea8b44ec6034559e326": { - "balance": "135552499885000000000" - }, - "d1c79160d0b8c1a1546b86db5123e87645a45d13": { - "balance": "10000000000000000000000" - }, - "d1cccaa22259c547993df3c147d5b545f003adb8": { - "balance": "10000000000000000000000" - }, - "d209c9f32f3292ac4d15ef353fbe6f6efcd4e49d": { - "balance": "81000000000000000000" - }, - "d21ac89a20d67e309f96f64adf05fc48f55918a9": { - "balance": "500000000000000000000000" - }, - "d21f6e7adbf480600295af683091f9b9833f5330": { - "balance": "1229445878922000000000" - }, - "d22700a47a0edb137d2f0348aa0f8d4b6dbc5850": { - "balance": "21301422923000000000" - }, - "d258ddc9372e3b70ff53da171252239655ca9886": { - "balance": "16000000000000000000" - }, - "d274c69317dd836df48562455e8f5a7bd2e47d19": { - "balance": "156091832558000000000" - }, - "d286b68a358fcf8a6cec70b83467079664632ae9": { - "balance": "90377010699000000000" - }, - "d29284915d9b924ae5673e8a4a557478f68a7471": { - "balance": "324678197320000000000" - }, - "d297e64ac2bd8e98e6d276d6fe080679c398a26a": { - "balance": "3401930527000000000" - }, - "d2a1e7b51f6b5930a0d9e2ee55736f3d83a1b323": { - "balance": "44578900750000000000" - }, - "d2c9b0b0bbe61de504e4f210c168fa5999c9c23d": { - "balance": "76537483113000000000" - }, - "d2d49f650d222ec3e2cecba163ee92f0e934ca14": { - "balance": "3312486482635000000000" - }, - "d2d803bf10ba18adef5716b4056c1b1d61c45abf": { - "balance": "964679698000000000" - }, - "d2f673b589df7ef5cb32fdeef842d48d66130567": { - "balance": "1079010447581000000000" - }, - "d2ffaceef1af3f1c3e3f35e4062cd9f9abd1da59": { - "balance": "3041453068594000000000" - }, - "d30a74f5041ec6e73d066a375a105116699ce177": { - "balance": "21814020745000000000" - }, - "d30d849a2d8ff5041304014ecf6752dc769bf004": { - "balance": "1247532881540000000000" - }, - "d3113f558c6376321691931c9b21205e31f4a56e": { - "balance": "572224428451000000000" - }, - "d314bac1bf85eedeac0b359dd2106dbae8fc6947": { - "balance": "20000000000000000000000" - }, - "d3283e17112028b324327ef64a238183ba189207": { - "balance": "136000000000000000000" - }, - "d33ce3c3b64d1b3d399651432c15ecb943d16c70": { - "balance": "10000000000000000000000" - }, - "d33e1e4b10a98e82810f6d161df5d35e5677e35f": { - "balance": "10169656674000000000" - }, - "d34699fd152fe38caacd3c096f6abb1cd79e88b2": { - "balance": "25056644550000000000" - }, - "d369c0e01b9a9d519b3b099a98fead19867c019c": { - "balance": "100000000000000000000000" - }, - "d388dcfe55a9b710d05c686f033fdbdd7861ab71": { - "balance": "1439589263065000000000" - }, - "d391a7d45c7b454b743bd867f8f62f56894f9b65": { - "balance": "484904747488000000000" - }, - "d39a75b4831543e1bc99e7a5ca8875c4f69da45b": { - "balance": "10000000000000000000000" - }, - "d39ed6978b6a90fea29e735f8ea3f1d20e0fbd15": { - "balance": "144000000000000000000" - }, - "d3a0a1a00dcbd6bc44c9803ce351a4b36a69c929": { - "balance": "191222401916000000000" - }, - "d3bf1c0a6b0470c30fc49d995025af5e6b639e61": { - "balance": "10000000000000000000000" - }, - "d3cda762bafaf204469f85e6896ec64147a3452c": { - "balance": "468094119213000000000" - }, - "d3d04d78c1ab9e6887a9467b8b1e31b5c9910e5c": { - "balance": "81000000000000000000" - }, - "d3e1bfdd9396aba00d3e78646ddcdaf139a967c0": { - "balance": "833333174120000000000" - }, - "d3e502c42ff0274da12ba87ffd45fa593bba052a": { - "balance": "100409899947269000000000" - }, - "d3e76066c2e32d9a693161de07f2d3b7e6ea07eb": { - "balance": "10000000000000000000000" - }, - "d3e8d577323d97407246b198c4c61f7943c468cd": { - "balance": "10000000000000000000000" - }, - "d3fd4d1b0edbc314b103d350fff023ab75b7d7cd": { - "balance": "84129547428000000000" - }, - "d40087fca8feb72d130bbc9622575d4987f12895": { - "balance": "1000000000000000000" - }, - "d407d4126cbf3619a422c532ccf20c3da1495dbd": { - "balance": "99622000000000000" - }, - "d41a28761c8e5de8c803813667f1dc0918a105be": { - "balance": "157507410260000000000" - }, - "d46ed38228a3c3d78065b2d8b71b325bf0f0e685": { - "balance": "6787045850000000000" - }, - "d4a7463d202e804b39a93bccd77491d8791baf58": { - "balance": "171694163573000000000" - }, - "d4c20716ff7288d811d05fd6f0696a9f5627a11d": { - "balance": "100000000000000000000" - }, - "d4d95059c808cf41e64f7f353246ffae635419d4": { - "balance": "10000000000000000000000" - }, - "d4ef925157c6d0e2d649332f44416b85f8abe69e": { - "balance": "1392945162611000000000" - }, - "d4f0cb25801794f6d803306878763e08209d19f4": { - "balance": "64000000000000000000" - }, - "d55fbebc4dcf2de6341c2325448e9c198f0f06a3": { - "balance": "14206622892000000000" - }, - "d566968c40211fb25114105e36b5a7219cde9d5f": { - "balance": "4898442964000000000" - }, - "d5817b95c6b504a6d07f64faccc9aedf408b0ac4": { - "balance": "54387832478000000000" - }, - "d59679fc40a71897065bf1b3a73f331226cdae72": { - "balance": "20000000000000000000000" - }, - "d5a7deec4a5898f094e1600f9b15768d8aada258": { - "balance": "100000000000000000000000" - }, - "d5b91c29bf772ad3ba04033dfb86b672b245ad77": { - "balance": "100500000000000000000" - }, - "d5c1a9bcc5e68b7547354178fefb3d870572fd67": { - "balance": "2252066779089000000000" - }, - "d5da2a826f5909a221bfd8561dbd7dbf4aca4c35": { - "balance": "13839784966766000000000" - }, - "d5dcc82fa169b4677a3fc26d78f38e27dcc763f3": { - "balance": "10000000000000000000000" - }, - "d5f344ee8a1b954ae5fd8fc7ac702174749bc8a4": { - "balance": "1398836216771000000000" - }, - "d61cd03afbfc1bea186e5a3a51347c2c4ee3a2c3": { - "balance": "109879472702000000000" - }, - "d647fd7ca17203a0049c28ec6759612d767cfcce": { - "balance": "162681136487000000000" - }, - "d656d14acfb2f0fbde2ed2a137a52d852bb6288b": { - "balance": "20000000000000000000000" - }, - "d68130b421b19c193d03a9017b2dc687c7307d26": { - "balance": "128569735484000000000" - }, - "d69a41f7ca76b40ee94b0d04a3780a00c6c651ba": { - "balance": "2801054372864000000000" - }, - "d69af2a796a737a103f12d2f0bcc563a13900e6f": { - "balance": "7412286547000000000" - }, - "d6a5a7e149cbccb72a50b0a3ae00e6756b0a7eda": { - "balance": "1075352201657000000000" - }, - "d6aa9957f141f0dfed77e943c39aeed978834fdf": { - "balance": "20920740110000000000" - }, - "d6e99ccb72d24e8a60f24d47afd4074b1d1fd336": { - "balance": "15415994387186000000000" - }, - "d6ea4a9dda8d5bc832229c916fa45f05f99c093a": { - "balance": "27075799893190000000000" - }, - "d71de419d746ac277baa955761cced4b34c376ec": { - "balance": "1388473506822000000000" - }, - "d71ec6b5e5d4c604f741bafde0974eca49c56156": { - "balance": "61938809628000000000" - }, - "d72f90d9879f6d2d407b4fdf5d128b98d518f1a5": { - "balance": "10000000000000000000000" - }, - "d743d7925a0cfd08150814cce8cd5d3f7099e1c9": { - "balance": "25681376856000000000" - }, - "d7575a09e7498f21cda3e9e7266b7fde91dfe19b": { - "balance": "9841565066000000000" - }, - "d75c2eb5e0a2b2ee72ef4fa7249c1a1ce03f333d": { - "balance": "134491489751000000000" - }, - "d77088329ec1e280ea7a087ad20c5e965721ff4d": { - "balance": "3949070941222000000000" - }, - "d78d564bb79ea19e4a93975a38fe0882018f177c": { - "balance": "992717434142000000000" - }, - "d78efb176b252ce67b5648e04088d12c4668aad1": { - "balance": "10070463674000000000" - }, - "d7a25e43d7d4e23744f0b10e2b4f2911fd3b3bc1": { - "balance": "1000000000000000000" - }, - "d7a941cd82f8aa63c55baa81db44bcb347b8e529": { - "balance": "49000000000000000000" - }, - "d7b34387880daede6cbdad11bb3db67daf942975": { - "balance": "20000000000000000000000" - }, - "d7bca0770e2f890c1e93c3595641241454a31045": { - "balance": "2000000000000000000" - }, - "d7cb675cea1c0dafded44f611c9c344e2a5e053c": { - "balance": "25000000000000000000" - }, - "d7e53a2d8eaefd18e02bbadb7e64906ca8613151": { - "balance": "166599594268000000000" - }, - "d8076b9db0b7496efbd198b73c4bfcf51ac080fd": { - "balance": "210272077089000000000" - }, - "d81dcf5756da397ff1f783ffe5391d1ffd4ff227": { - "balance": "500000000000000000000000" - }, - "d833c6d08f5fff8f77628ab1e86584d052976d1f": { - "balance": "10000000000000000000000" - }, - "d835732e85953baf2af9e49f770bac1caa1dac23": { - "balance": "152211441541000000000" - }, - "d84005fea447e8c6aa0b5436ad79654a75348456": { - "balance": "22563694224690000000000" - }, - "d84d9c59a445911922e88c0f22cc6534f33ca3de": { - "balance": "3054115413381000000000" - }, - "d84e69926216065749e624d87783e90ce3015b82": { - "balance": "1420803164313000000000" - }, - "d884bdbdb7e13cc523e7f192310230c7bdbb4a07": { - "balance": "10000000000000000000000" - }, - "d88eedca1dd9249702f5ffc807c1e439eee1c5e5": { - "balance": "36000000000000000000" - }, - "d8a23fd234bada1c726622925ade62d3021e0037": { - "balance": "1567046607931000000000" - }, - "d8b1aee24264efebd1c677fcab6ada6e0f000cc5": { - "balance": "20000000000000000000000" - }, - "d8ba7afbb8bf2910b983a114aedec626eb7426c1": { - "balance": "275491152435000000000" - }, - "d8c8af55ebf116ba3c3904f8ac39d3a7d31aadc5": { - "balance": "1499999998278000000000000" - }, - "d8d97645f5f62aa89bf0046362dd0f45d40f821f": { - "balance": "25000000000000000000" - }, - "d8ea0e24a7e28285c4454f54181d581324da2583": { - "balance": "53039425000000000" - }, - "d8f5d258164747ccf790f5ed358162c756de49db": { - "balance": "323009990690000000000" - }, - "d9477bb62d3eb668a83a9679f3a7ef43f17c9e4d": { - "balance": "14045557127869000000000" - }, - "d9585e1b03fc86636dde1e64aed3cad77868549a": { - "balance": "1000000000000000000000" - }, - "d975f9ce3fe773fac3f8338a034a757c58f6e11f": { - "balance": "25000000000000000000" - }, - "d97e490faf19de612fb49c041d3f9e7877d3c0bb": { - "balance": "65766847746000000000" - }, - "d98117b74b2f2888d7078d3116d5758e2d09bfca": { - "balance": "1749157484422000000000" - }, - "d990b3f69ec700bdc095c184b3804551c832d612": { - "balance": "509385034698000000000" - }, - "d99b35298e709e5f54e6a5c612a326a83f4268c4": { - "balance": "71963571266000000000" - }, - "d99d9ec76005da26ccc721ec26be4ed9b3b1c586": { - "balance": "469607736824000000000" - }, - "d9bc61075c3201351584a026e5bdfb7cf9a7b6ab": { - "balance": "200000000000000000000" - }, - "d9d07b72f83491b6db26602f6b7039aeebfe6b61": { - "balance": "144000000000000000000" - }, - "d9f6f1ddf03e836b3744d008b62a6424544c67a5": { - "balance": "74347470143000000000" - }, - "d9fceff07ad69bf3b4aef54a7eee541368980cf6": { - "balance": "1143407707495000000000" - }, - "da0285fb7e37fd4be66fb862b248cea94ea8f6db": { - "balance": "80770216661309000000000" - }, - "da05c7aa330fcc5834e19deeb0a808e9ab7f3d99": { - "balance": "169000000000000000000" - }, - "da129e4481bd25450e6c7b42fe417c87ee2ce7a7": { - "balance": "256000000000000000000" - }, - "da32e3ec421993db088c71e256263158f7855b61": { - "balance": "18540215888567000000000" - }, - "da3c99669acd202ccbe6f80902c807588eca0880": { - "balance": "1000000000000000" - }, - "da72a7bec114d43aee6449db830d2d3f16e4d9b6": { - "balance": "744534872932000000000" - }, - "da72ec2cd7b8e3924f8baaea75d5ed23ef39394c": { - "balance": "38646377617204000000000" - }, - "da73078957f491827d62cb3ca0c484c2d1004ba7": { - "balance": "891774109242000000000" - }, - "da828e50c7c8580c6ce81718f11fbd43b2b0541f": { - "balance": "66094097819000000000" - }, - "da91483db6a6a034e068e69a6b46674838c5bc80": { - "balance": "4000000000000000000000" - }, - "da9551b635c3619f81641571e267755b89f7fe1e": { - "balance": "670841942250000000000" - }, - "da9b43a9c1c574580ec43da9f6acb687fc2f8c68": { - "balance": "761695404114000000000" - }, - "daa7f446923f7481115ad285ca468c865147e563": { - "balance": "10000000000000000000000" - }, - "dac6bfd15954efa4c9254e24e5831ab1884f8d67": { - "balance": "960042043423000000000" - }, - "dad85d0b8bb5ebf6ef811d0d35c89f9f343c833c": { - "balance": "37664599958479000000000" - }, - "dad9b01652de5d50bf30f9bcb0c6edc6315139e3": { - "balance": "21500996724000000000" - }, - "dae9c7d6bb0efe3f7ea20442b184f6d99b2a2c12": { - "balance": "937830189066000000000" - }, - "db0d6c28e9b913f611accaab15cc887f9b770f58": { - "balance": "20000000000000000000000" - }, - "db0e5341d64817885721c5abff04c30bd38df40f": { - "balance": "62600679700000000000" - }, - "db387dd404d14478babb60bad2391720d68b92ed": { - "balance": "115096708329000000000" - }, - "db3fb19e8a4a6ace4d8c6c02085d4cbba528b532": { - "balance": "1000000000000000000" - }, - "db4f05a66c0ccf0532ea1ecb931e05a400a6f4a7": { - "balance": "20000000000000000000000" - }, - "db571f1cdf8e83fbff6fb48cc0c81ef95ede12a0": { - "balance": "118317387393000000000" - }, - "db6a6a6db2aef3f43afbfe23027b670ebb3d33bf": { - "balance": "9960755220000000000" - }, - "db8bed34f8f34f45cb83ab19ed33fad76437d217": { - "balance": "21003651205000000000" - }, - "dbeba6a2a7f66c20c6db7b9270a5aee74de3f441": { - "balance": "4086905723945000000000" - }, - "dc04efeac13b2dab3d07833a7e7fa728fc23d18a": { - "balance": "1161834099120000000000" - }, - "dc092386c3a3e28b6b2d7d70db8f3d11e79ef5df": { - "balance": "124362293793000000000" - }, - "dc10be66aa11acbd42a2b1953714f09b5281681b": { - "balance": "20000000000000000000000" - }, - "dc2d58a383ce0bd40bed859ec2f25412b68eca0a": { - "balance": "104917823922000000000" - }, - "dc2e38183dceb2bc82b23e8ccf48dd96ea1c97b6": { - "balance": "2847787376064000000000" - }, - "dc5d9d94530d88451cf081fe7f2ac33667af9d8f": { - "balance": "65321904051000000000000" - }, - "dc993112a8d89136e0e73d67e2f26191583a50ec": { - "balance": "1000000000000000000" - }, - "dc9bb69b295945589a41feb794406558ce65dedc": { - "balance": "104077637254454000000000" - }, - "dcb0109d4fca2dace08ddca5d989a09d470161a0": { - "balance": "28897833222000000000" - }, - "dcce3a4ec516d833f5a9790c40ad0334b0d2dd01": { - "balance": "25000000000000000000" - }, - "dcdb21cc811ab733c2a80a2d5c8e5bb49cb2ddc4": { - "balance": "16000000000000000000" - }, - "dcdf8dd3ce03a2fe0d72835dbbd58725e1ed2c57": { - "balance": "113330414284000000000" - }, - "dd2165839ab95d6b24591307adcde9ee1819927a": { - "balance": "20260199589072000000000" - }, - "dd3015a5fdef66e749a000585d5574f975e3432d": { - "balance": "85465001652000000000" - }, - "dd37c478727f44943c5fd79ace30f21fae5a589a": { - "balance": "108577233510000000000" - }, - "dd3fb5810c31d37652bd17b92497ed479faf123d": { - "balance": "669996966072000000000" - }, - "ddc3bda30f7cf36bd535de4e20c9becb78d159f4": { - "balance": "99998278000000000000" - }, - "ddcce2d2431b67d4157c7ac4bd77f20c24831de6": { - "balance": "36160893899000000000" - }, - "dddcebe609f8b4354a1f27ab1915135e25800344": { - "balance": "1457846339959000000000" - }, - "dde223eb48f81748abde6cbc08cf1e6b0e8e4e5a": { - "balance": "1501921107087000000000" - }, - "ddf4ba402007060d9940a96f8e7c39f0a2c6108a": { - "balance": "377268151287000000000" - }, - "de05d9ada6626a8492acd137c7c7f7080a987cd1": { - "balance": "222144234923000000000" - }, - "de0fab89f79c4edf9766c3b7b1f508cb43c5495e": { - "balance": "8278000000000000" - }, - "de1070f3ff6c47237768fbdead88b2d5184fbe2f": { - "balance": "1000000000000000000" - }, - "de2b16d7f36f630329287822f550ec19415acb3a": { - "balance": "25000000000000000000" - }, - "de3faf6884337a99e54ac5d3f08b34be51b0755b": { - "balance": "51926806905184000000000" - }, - "de4614fd632ddac888d177de0858e62bbbf7dc11": { - "balance": "52506376589000000000" - }, - "de54cabb241dc5def530191f948f67db942a85b0": { - "balance": "9691177060000000000" - }, - "de81e488284acc4f8f6061d3a73bad112efa7a40": { - "balance": "14654060992000000000" - }, - "dea86ac3a661272691c877c1bad8355789382b69": { - "balance": "903877103000000000" - }, - "deadfc79f2a722dbf1c1a92f2824da8874189fea": { - "balance": "98905944986000000000" - }, - "decf1af47e153f6f3749a1b7abadefdcf1607a0f": { - "balance": "529000000000000000000" - }, - "dede5fa984f0def639d5b633f54c60fc5aaa272a": { - "balance": "8193771708654000000000" - }, - "df23607c63b3fd4b5fde6aab093c0c56d1188f95": { - "balance": "14687379916000000000" - }, - "df5b74bf02902e4c466821de798406b663d4d73e": { - "balance": "9000000000000000000" - }, - "df6402ee3f37389e7f65720561b54e26e5f1cbaf": { - "balance": "358266132937000000000" - }, - "df83ea5b770d5abeccac7f0cae803e8bd7b9831d": { - "balance": "25000000000000000000" - }, - "df92802ffe9892c7704875755bdec648914430e6": { - "balance": "20000000000000000000000" - }, - "dfa108bcd80e824a255679a38b2450d428e2f939": { - "balance": "489209553654000000000" - }, - "dfa9f18e859353796afe384d05353dc80b3ffc43": { - "balance": "121000000000000000000" - }, - "dfb0d6580f011e68a39d7727818b0890e70f3036": { - "balance": "537675412560000000000" - }, - "dfdf006abf2293aadc58feea6af6b35db428675e": { - "balance": "9000000000000000000" - }, - "dfdf2ba93bd47d7243b7419413458a947effcf67": { - "balance": "45080282196110000000000" - }, - "dff01277ac23a8cf93383595a80a7c070eafe5c6": { - "balance": "312778552103000000000" - }, - "e0450154c441e52c5e507e8316d4e9376c59c12b": { - "balance": "170163401434000000000" - }, - "e059374d6a7e6c63e609b65642272869fa3b2b3c": { - "balance": "300122497803000000000" - }, - "e0c0d8e739a2f274a43f019a07f7f61d7d8e11a7": { - "balance": "2630310240000000000" - }, - "e0e779e4e3573ea77096daec252ac2b3f1c0013a": { - "balance": "10000000000000000000000" - }, - "e1325eb586180a67873718a2016172afeb03c6a5": { - "balance": "531691399657000000000" - }, - "e13958af480da6443b9ec1067f0f33440634a282": { - "balance": "10000000000000000000000" - }, - "e142daac753b2c4d215372797999e9c88b65dfc9": { - "balance": "585813299366000000000" - }, - "e142ea343bc36ec49989fd43ad5c403c70a40dbe": { - "balance": "656734902975000000000" - }, - "e14d0a3d259db6bfec2fc4ef6e18729e4d93b007": { - "balance": "210234446279000000000" - }, - "e16a5316e3a113f27bafdf3d4fe44fe30ae9c210": { - "balance": "16000000000000000000" - }, - "e1770944aec145a96c9491497eacf7f3fb03c1b2": { - "balance": "335417250470000000000" - }, - "e199ac237661dcac0a4cfab404876abde72ee209": { - "balance": "340000000000000000000" - }, - "e1ad427471023f38cbdf07fdca3728ec343810c4": { - "balance": "343957267368000000000" - }, - "e1ae0223cecd738c8e530a0007ef05e8f3b33769": { - "balance": "950528515289000000000" - }, - "e1d2d4ef39f01a60c3bb5d671af91c5298d87711": { - "balance": "121000000000000000000" - }, - "e1d4a8888cbb383f3671ca96e7b55310b59a2541": { - "balance": "242387826125000000000" - }, - "e1da9039ddfe117e6a0b484fd3962426c112871c": { - "balance": "3710499693813000000000" - }, - "e1da9f16d57c601af8b6d102323c20408af8531a": { - "balance": "3135322588771000000000" - }, - "e1e1c163f391ffad2d0be68641253b0860485a95": { - "balance": "10000000000000000000000" - }, - "e1ec6361df67ad915df9e9661cd0932186db034a": { - "balance": "4279936304854000000000" - }, - "e224050bcd723e63f1fc0567a86942546aaf8d13": { - "balance": "12007628539000000000" - }, - "e2342c7f411d7ca3a86484af59a9c3f3180e2f0f": { - "balance": "16000000000000000000" - }, - "e26f2b026a258ce5801c90bb8fd6f7a152b8d267": { - "balance": "304593714834000000000" - }, - "e2717eb5fd0a1da51272b50ca8d12858009c7016": { - "balance": "506943817535000000000" - }, - "e27546d5620e6398829260e58e8cf4a3a03f4164": { - "balance": "3000000000000000000000" - }, - "e2762bb64e0606a5d635032e15164b01f612a74f": { - "balance": "884716158811000000000" - }, - "e2882066ed0a3c041d09c00c8532850fc42eac06": { - "balance": "42441412728970000000000" - }, - "e294c5d64daf7b7c0994aa9d03669c4b2658c9cf": { - "balance": "6996693830997000000000" - }, - "e2b179f0ed6870a6268aea64b0c7b39d98d97fcf": { - "balance": "334205318353000000000" - }, - "e2d1f6f7e3128340b789565b527bb91de96d54bf": { - "balance": "100000000000000000000" - }, - "e2f136d3693aa0b2346a968a22aca6707fc1d0e5": { - "balance": "10000000000000000000000" - }, - "e2f229054293e32cf3e83f9bb88d9cf1d6acd66b": { - "balance": "20000000000000000000000" - }, - "e33b8f4c9a49554c8b134861f88c8fffc399e456": { - "balance": "83552502198000000000" - }, - "e33cfc7727b1460324b34277dde14cc49bcb273d": { - "balance": "100000000000000000" - }, - "e36af9bfed4f912cae21f3d899f7354e1c902601": { - "balance": "31474316356000000000" - }, - "e36eff7c061dec48446d47675f176b4da3c2e950": { - "balance": "10000000000000000000000" - }, - "e383f3cf431f3cf645f26c7d5e5e2f77348ede6f": { - "balance": "776224304171000000000" - }, - "e398b9f004a4f891cf871a57d9124a97b56e89e9": { - "balance": "84846187740000000000" - }, - "e39ab2415144b46db522e92ed51b8089a5ec01fd": { - "balance": "4158925896363000000000" - }, - "e3aa7ac7e15e9a8a6f54565067234a9d4bf7b569": { - "balance": "1080385576951000000000" - }, - "e3ec5ebd3e822c972d802a0ee4e0ec080b8237ba": { - "balance": "2129139289000000000" - }, - "e3f1fbff8686af23ab95eeeee6a6a03782d72416": { - "balance": "401776848194000000000" - }, - "e4001b830fbd86df257ebab54aec0c66314ef9aa": { - "balance": "518220809325000000000" - }, - "e40790bff894f0b3e534942b5ad6f6592cd6e896": { - "balance": "25000000000000000000" - }, - "e409170a296e46fc96d85a2395e4324212a470ee": { - "balance": "1072528749756000000000" - }, - "e41546f68bbe1771febbdac2a4a5999eef50edf3": { - "balance": "1000000000000000000000000" - }, - "e425d63d711a9996c09d928ba8df94c88163aea9": { - "balance": "10000000000000000000000" - }, - "e4432ff1aee13f97f73a8407e4c7d6e768b8040b": { - "balance": "700508995102000000000" - }, - "e4690f5d024a395355a7cb5238fb7e0dc921b1e8": { - "balance": "1000000000000000000000000" - }, - "e4829684fb36f054766a61fb2a8f6ecdf27c9e87": { - "balance": "73885178137000000000" - }, - "e48a68e1ac007e14ac08c1b3b0df2b5602081ec2": { - "balance": "1389262869176000000000" - }, - "e4d699b3f4117eba7ed27b323048c9ffcb46ed42": { - "balance": "183131036697000000000" - }, - "e4db688c29fdf9a1c16114f99797d8409545955f": { - "balance": "16000000000000000000" - }, - "e535b94d370190d1e0955d3c0d12480e558f00dd": { - "balance": "20000000000000000000000" - }, - "e53966d4bb17fa9b50d29b44ddf3951c9ca67caa": { - "balance": "6400630678000000000" - }, - "e56f2656fdd1a5f7d3716e65dd89a37dd6e42dcc": { - "balance": "1000000000000000000" - }, - "e5a364113076273352e0c31bf505028e0b7edbaa": { - "balance": "10000000000000000000000" - }, - "e5a3c80518fab6a0a721ccbdc3e673680a65f6de": { - "balance": "171727917465000000000" - }, - "e5c71c7170e5c9b07e62cc307d81a4a3053ed64c": { - "balance": "10000000000000000000000" - }, - "e5fb6408db128c55cfb3e7fa1942d6347e34932c": { - "balance": "10000000000000000000" - }, - "e606883236f8b2045393c574153a100675cd4b90": { - "balance": "14005226900000000000" - }, - "e61869d1cf72f25e195898217f5bf5bcec9c9038": { - "balance": "50000000000000000000000" - }, - "e61e2e29c0719457ab1bf7d6d9fe442bd6107b07": { - "balance": "30943034333100000000000" - }, - "e61eb97093e9ee609647bd55f434a27bb30a9401": { - "balance": "200951434577471000000000" - }, - "e62812ad5834747f17c92435d863639e84d132fc": { - "balance": "3017271391299000000000" - }, - "e630b92aa8443eb077e1f6990a2e194d99cf53ec": { - "balance": "1000000000000000000000000" - }, - "e656fd1641c15e1a4b753be41bc4aa438b44b42c": { - "balance": "26972744083000000000" - }, - "e663f0257b98dfa80602a2af1bea1f901c4a7612": { - "balance": "97075813547000000000" - }, - "e66e411a8a9d019b53bf2e0a7e44703e1aa93ac1": { - "balance": "25000000000000000000" - }, - "e6712675d13fff27af43bb1cb3f2f283755bacf5": { - "balance": "227572496234000000000" - }, - "e68e8f04b2cff484da2d41dd639ae8880920f781": { - "balance": "20000000000000000000000" - }, - "e6972b5d7e0fe8c722dec9146b92f89291a0207a": { - "balance": "2115924954211000000000" - }, - "e698b491330cb55ecc4cc4b74015cd94eb927fc4": { - "balance": "1038111785278000000000" - }, - "e6c411e67b90109dbb0fa75f0f07ae8a504e9637": { - "balance": "123792105420000000000" - }, - "e6fb1dabc624edb45b040ad66f30dae010a6b634": { - "balance": "16076893670852000000000" - }, - "e71dac161206e7d3686d13b98fd922ab73587988": { - "balance": "500000000000000000000000" - }, - "e773f9be9b3f4b35ac149b4d759b9e47c8000bdb": { - "balance": "329623043336000000000" - }, - "e781cbbd2dccfdf68595d54fa44104a80d52dd22": { - "balance": "188679476509000000000" - }, - "e793666c7850a409b1d5494f576d122e85cfed9c": { - "balance": "1141845197779000000000" - }, - "e7a5527c6deb922e9f84309c502048f49f0c8f14": { - "balance": "81415566708000000000" - }, - "e7b0f75f9c69ae464b1b63cf295555d0815fc532": { - "balance": "10000000000000000000000" - }, - "e7b43cc673e321e607190a6fde996b71508f4d81": { - "balance": "103958781426000000000" - }, - "e7bfcf3125e37755e57804dfe4479657b212a8ca": { - "balance": "10000000000000000000000" - }, - "e7d33cbbd4eb38365c5be04ce32658a5ac741cfa": { - "balance": "1545192252109000000000" - }, - "e84cfbd7844f6aa3e830258a6b1069b6a7ff5b7e": { - "balance": "543989509107945000000000" - }, - "e8aa0cbc5c1f59fadf3ec122fa8a59ebfc60b5b6": { - "balance": "61271973066000000000" - }, - "e8adb5303c30a8ee044dc09c49818c02a16f4254": { - "balance": "737375689166000000000" - }, - "e8aeef5114e19d467c3064938c5965d04830f2ae": { - "balance": "51130466380000000000" - }, - "e8b5a83497198a513fb2e244bcf05f9d4cf09d62": { - "balance": "10000000000000000000000" - }, - "e8b6818cf0d24bd0e7ded854b3d368662a150dab": { - "balance": "63697741112000000000" - }, - "e8b68b9cb24169fd688db7a626d79d0363777c75": { - "balance": "427222669643000000000" - }, - "e8b8b57b23ea953943da3ef7efaefced9cdbb44c": { - "balance": "16000000000000000000" - }, - "e8f85dca364d26c2149b767904c6c06249c3d88a": { - "balance": "199342917246000000000" - }, - "e916c7801cdcf1b6cf640fcd9dcc1e3148c80105": { - "balance": "9000756000000000000" - }, - "e93cbef13277324caae7816c3d601e2f6bb42589": { - "balance": "121000000000000000000" - }, - "e9415fedcdf8939b551999900128530195a2a5f0": { - "balance": "85165078941891000000000" - }, - "e9a79ade714ce48a07fe88532a20d8f8ed27bac9": { - "balance": "30768493367842000000000" - }, - "e9b35c7ca775661bbd3a4844e2c6bc5effcdea58": { - "balance": "134719523000000000" - }, - "e9b819dffb600373bfd1b1608fc9744cc9167855": { - "balance": "1537634693002000000000" - }, - "e9c5ef50d4a194e53928659b4486a1c456df9e56": { - "balance": "50000000000000000000000" - }, - "e9e21f4523b11567516f6fc525e8967ac707f988": { - "balance": "2498740681000000000" - }, - "ea02821d6c730e061a9947b75188eb8bc0bbf9f1": { - "balance": "12822292582000000000" - }, - "ea3bca3a17c7e724ac0e15acab6442f222cd8688": { - "balance": "2789689549000000000" - }, - "ea4f7923d7045a148d50153f5f4620dbd31a74da": { - "balance": "113595858930000000000" - }, - "ea6d4cbae3cfe49ffd36653bb0d64c01b2bbc0b8": { - "balance": "49325017701000000000" - }, - "ea76cd4cff825301932a5c1d3a1de55a0ff00797": { - "balance": "1282028021000000000" - }, - "ea8e4c8c6500856777e2b41832ff00443db291ce": { - "balance": "553674550359000000000" - }, - "eab52191e5afc804b8685fe13d7ad6f5dc64fc12": { - "balance": "244412435341000000000" - }, - "eac1b0868b710e40d6d5c66a461dfc8f78abbaa9": { - "balance": "10000000000000000000000" - }, - "eacac2c75920b8f6e65f37ad81deb113d526d031": { - "balance": "53028042076000000000" - }, - "eacc9ef8b534143560f420031a8a7f030ff1a36e": { - "balance": "381111853842000000000" - }, - "eaf2cc9fdfe6272de269f32486b2d4c248a05afe": { - "balance": "2793234915237000000000" - }, - "eb0220406832a8a5d4f242538e82c80bd83d0ac6": { - "balance": "10000000000000000000000" - }, - "eb20efc0e0af48c8e6da4b21efa9c9f02d92d29f": { - "balance": "152958793764000000000" - }, - "eb41bce8e3aac2bcf662854a3151e3c83d98c6f3": { - "balance": "219455327737000000000" - }, - "eb44c591306972c29a7084079720d8ee5fb9b0a1": { - "balance": "49000000000000000000" - }, - "eb4b26ab55dc35df2e78d47a90fc43148a6de881": { - "balance": "12139574483030000000000" - }, - "eb4f53510db5edcaad6ea169e521bd094e8da4b1": { - "balance": "100000000000000000" - }, - "eb4fbfb7c0082aa0e7edaed934c5166fee955e5b": { - "balance": "299713748180000000000" - }, - "eb6067ab544af6289a73111e7693dc449d5c2134": { - "balance": "20000000000000000000" - }, - "eb86fea82d10d309b1365237e4855a48684e0e49": { - "balance": "81510415589000000000" - }, - "eb8abbcadeb6e19ab4392cded7a407c8d5df2d5c": { - "balance": "25000000000000000000" - }, - "eba44ca2d6f36df8221a2021bf0644cf6cb59452": { - "balance": "500000000000000000000000" - }, - "ebacbc0eace170f66415df48f74d98eb31828d15": { - "balance": "19046465915296000000000" - }, - "ebc72fb8a1029139d8abdc08da23dc559f87e1a8": { - "balance": "24177703742991000000000" - }, - "ebd561bb9001991cb6b02c8ff9e7ece8a3d73dde": { - "balance": "6684606759000000000" - }, - "ebe1dc3ee857ae4add6fa6636b678af8451d1701": { - "balance": "1485349608007000000000" - }, - "ebe68dc904c737be83aa2ee7f613dd51a6d436e4": { - "balance": "11206782120918000000000" - }, - "ebecf4db55a99f018bf136173ae823528f211380": { - "balance": "191817711082000000000" - }, - "ec15ad0aafe0c0f18089de50b2397509e15a20de": { - "balance": "20000000000000000000000" - }, - "ec2e56973a6cbd8b37d0294b16ef806ab5943ec7": { - "balance": "12031630315394000000000" - }, - "ec432a6a4685ebf6c1e872001d1de246140c8d98": { - "balance": "280056522277000000000" - }, - "ec866ba1bdadb91ca25f5ae035b0f69421ed4377": { - "balance": "431849961155000000000" - }, - "ec9be854224d3d371b79ffc1230fe704ba03be2b": { - "balance": "3692428502391000000000" - }, - "ecc2d6e129c7daa37a93f559c6d4f575171d8386": { - "balance": "20000000000000000000000" - }, - "ecc3aca2a21cb317c5b9debdcb2090f3931d5cd7": { - "balance": "100000000000000000000000" - }, - "eccc9a49ff40aa4b07aa0e1271cfb6713de683dd": { - "balance": "617207728367000000000" - }, - "ecccf24530629033fd6234ae32bde2052ebaa640": { - "balance": "16000000000000000000" - }, - "ed16770d5a56dced87224d4ff68a361a2285fef2": { - "balance": "10000000000000000000000" - }, - "ed23b8e782d5ddf203f9b80e5df83ec32e484fc6": { - "balance": "5000000000000000000" - }, - "ed3244e4168e669ae9d54175173c3f0f0e7c4c7a": { - "balance": "803397672115000000000" - }, - "ed48f39d3f022b321c0864d4955e1cdc8cf54834": { - "balance": "64000000000000000000" - }, - "ed4cb42fa6737cbbbf095f181e1425b3bc3ab4f6": { - "balance": "8974148344000000000" - }, - "ed560f7d83c27a26965f84dcface3930bc447fc5": { - "balance": "2092287996000000000" - }, - "ed6ace91369ec3b06cce474e67d1ce4aba6475a6": { - "balance": "1227081000000000000" - }, - "ed8249dd4a91f70176ffff310e5546e7e0c30b91": { - "balance": "813069034369000000000" - }, - "ed8987fa3d4d42bb8f009c99cda5868633d94f5a": { - "balance": "174952234860000000000" - }, - "ed99b72a58a519ca7aa8f46b8d254c3f1eeea0d6": { - "balance": "10000000000000000000000" - }, - "edb720c9bde4801e204e90282de2a6cf1c44c4ad": { - "balance": "10000000000000000000000" - }, - "edbea23cd0cfde3705d83aada88e78b9f4bb1a50": { - "balance": "4000000000000000000000" - }, - "edc1f174655205bb961ddf94a997cdfd24f1c2ed": { - "balance": "65211537189000000000" - }, - "edd1d2dcba881202bc546943194d64e59bf74bfd": { - "balance": "10000000000000000000000" - }, - "eded28fbd959f2351b4252abc71f0e809562fd4c": { - "balance": "1000000000000000000" - }, - "edfe4d4c83c7db76e5e8a9ccafa34d9841669dac": { - "balance": "2578239411258000000000" - }, - "ee1ef79de869b89334d883ba766e65150f3f6cf5": { - "balance": "779780646165000000000" - }, - "ee27b2da240e862f0848d31116a7b4ed91835c8d": { - "balance": "111637484977461000000000" - }, - "ee3195bdb69e97796911c63fdd3fcebad61ffe9b": { - "balance": "214483035823000000000" - }, - "ee43306530c21793c4fd6039b51cf54fbc912bf0": { - "balance": "374531713769000000000" - }, - "ee4515e30ee1b8dba4779ef213d89e8dfff26ea6": { - "balance": "1166743135013000000000" - }, - "ee591e9ca7948b8485eb210e2a3f706b97e6f9e2": { - "balance": "27793157052774000000000" - }, - "ee5ba6c854d633a04f7656d311817e5104c6de14": { - "balance": "289361919166000000000" - }, - "ee909db4ee48bff3adb9e43db940245a8e5e094d": { - "balance": "582143490064000000000" - }, - "ee94d1afa82de70eb65aad0662f48ef3170495cb": { - "balance": "242490158636000000000" - }, - "ee97e18e09bbb16137a7b4aaae464e97d70e6606": { - "balance": "442709862861000000000" - }, - "eebe957af00050c2841f3ef8768c6a77a5394012": { - "balance": "9000000000000000000" - }, - "eec052f4e2902f7cc496162ca6525997d2b3ede4": { - "balance": "69349303517000000000" - }, - "eed30e1a939d5f0b4a39598967a5f149a7b7cb8c": { - "balance": "1637195595000000000" - }, - "eed7bf1ba39bfdad0ce1b6b8d4c9bb31dc1a9843": { - "balance": "203331701702000000000" - }, - "eee276140ea24e36eccb4fd748f675df1acd3b73": { - "balance": "1000000000000000000000000" - }, - "eefb33b290741c4cded862cea777efe4b14a76da": { - "balance": "64000000000000000000" - }, - "ef17a60d15ecf68a62b4bfd5e3acd6201e1931af": { - "balance": "113292502078000000000" - }, - "ef3f4df42127d3e94b4b5883ca97ee63f90b68b5": { - "balance": "17819622000000000000" - }, - "ef4aa6833a69cf72fbf3eaac57da236970aa4241": { - "balance": "1638520372091000000000" - }, - "ef958a1db06e5b8e12547148f3b01da9a8841aad": { - "balance": "12847752197000000000" - }, - "ef9fa861eefe12a3b4c161a47db5d94b1fa873a9": { - "balance": "49000000000000000000" - }, - "efd9b1ce6bc3932961e41e875edaaa367d318b36": { - "balance": "1626378762077000000000" - }, - "efdce7f577c77f0dac6afc78dcbf5ebadc1c3a73": { - "balance": "627500067619000000000" - }, - "eff3f26bc45638d89f28b3ea7a5471af0b680b72": { - "balance": "1650959950189000000000" - }, - "eff6d78814ddae79d6d09d830dd44de55f3f919d": { - "balance": "44409266093000000000" - }, - "eff739e22b9aeb3781dc301da70761fdd178f08f": { - "balance": "574842224234000000000" - }, - "f0059b3c8a32d3d012b4fcb993431a484b67762f": { - "balance": "516933429840000000000" - }, - "f06747d8e2c76b8827bbd0bf4ea3a68d390ee8f3": { - "balance": "8124594790100000000000" - }, - "f0e29fc0aecc36d1bdd818148878ea7d01957476": { - "balance": "79821431871000000000" - }, - "f0e42acf4e027aa61ac2f56e3d2c171ec0fd6ebf": { - "balance": "672499252575000000000" - }, - "f14338307bc5e6ab71fa202447ce240947568b3c": { - "balance": "13990001528784000000000" - }, - "f14f9a1206eb436a3d2e4ba9b3976137f67a6596": { - "balance": "1086707451000000000" - }, - "f15fcf1772fa5b2a578ce4f9270996430d533000": { - "balance": "496026996898000000000" - }, - "f18c691a5827ff1fdc44b54bd9a64fabd53c1cf4": { - "balance": "3112912699000000000000" - }, - "f1960640b52af75fc71101aec2611499c17cd9c6": { - "balance": "195957678178000000000" - }, - "f1abf01ddd474949713bd7fa67ec81d6b56c87b7": { - "balance": "121000000000000000000" - }, - "f1b93a6cfd4b1c7e0e89ebed119c5fe55af2035e": { - "balance": "1000000000000000000000000" - }, - "f1d14c7659a10ff38f4ea74ff5b07ac035984b6a": { - "balance": "9986323720000000000" - }, - "f1dbf37470a2c4fef98b1023026870ae8f7df2c0": { - "balance": "132757602000000000000" - }, - "f220b958b619d5d848597dd00824ab8b1401ebd2": { - "balance": "1461699635849000000000" - }, - "f2484911e0aa707f88d9dd970db21e8f24b9de2f": { - "balance": "20000000000000000000000" - }, - "f264c15790fd7a36d9ce7a454f6bfbe878708a50": { - "balance": "64000000000000000000" - }, - "f2662356cb3ae7b82efd6c82c3591ee40854892b": { - "balance": "50000000000000000000000" - }, - "f27ae5783b96ef637bde4179080a8f5af63ae692": { - "balance": "784985848611000000000" - }, - "f2a62fc212717e411f72f9a694e30b8da21bb31b": { - "balance": "614971541702000000000" - }, - "f2d0a9594231efb87ac833c365b80944251f29d7": { - "balance": "478622654587000000000" - }, - "f2df99a3df0b9b448d0ea48b9fd5cb1ce9ce50cf": { - "balance": "851116673037000000000" - }, - "f2dff0ae1f5f74808624e4f26fa814e4e19c216a": { - "balance": "404457730686000000000" - }, - "f2ea1ac6282364ad5904c6f058827a4382111d94": { - "balance": "5502482915000000000" - }, - "f2fafdcdb2d887eb13b5362eb76be2a682868643": { - "balance": "6174264174000000000" - }, - "f314adfc2fbf632a6e5d8a261385b6054aca31b6": { - "balance": "1267558242119000000000" - }, - "f31a66a88394ed7dd6609aff07dd26a60a219bd8": { - "balance": "346102834465000000000" - }, - "f3535f2b42d8613363e6d9717cc21a8ec3a74fe0": { - "balance": "35723093185103000000000" - }, - "f36a149466982c030ce3b9717f34b593613804d5": { - "balance": "10000000000000000000000" - }, - "f3828b0eaba4acfbbcf3c58277ceb4616a34b630": { - "balance": "633998941064000000000" - }, - "f38f767eeb8002ef051b32fe2f40193bf0751d92": { - "balance": "50000000000000000000000" - }, - "f39bce177817a7338b1adaf713222e515c0d762b": { - "balance": "1128231726329000000000" - }, - "f3ac7ea27a1cefc7787e5ba54dacfd8385ee4afc": { - "balance": "11364602682758000000000" - }, - "f3d9ea511335ed418b1837766da11832aedf5578": { - "balance": "29188596603509000000000" - }, - "f3ef05ccd19df167e06797d962f6afe16037e134": { - "balance": "144000000000000000000" - }, - "f3f630148eccea0ad7bd67bb806bd5676a4ea4cb": { - "balance": "87187208643000000000" - }, - "f3ff31784e0b8c3cd2f7e18cfd07c682a42d1c8d": { - "balance": "10515373125000000000" - }, - "f40b976e8519a2c97f64783bca495ed3f2e4a7c0": { - "balance": "780184503985000000000" - }, - "f416a3af7f3181ad9c8a916989949d35b0b636ec": { - "balance": "16114504005275000000000" - }, - "f419759927eea6afe77701c4cf4a98791a709ad1": { - "balance": "1032589347112000000000" - }, - "f4368f9c9ad8236b56413f174562d6b6fef21d1c": { - "balance": "5447645343000000000" - }, - "f43c57f984b0e2b7ce4d703e82f41195585504a4": { - "balance": "1135809111749000000000" - }, - "f4449f52895de96a4638c927dc389f010bbd530c": { - "balance": "693196063498000000000" - }, - "f449bd417a674c8bfa1db3a3e09c2b03da0f0c04": { - "balance": "106343287319000000000" - }, - "f44dec8340986c06d64dc98d78772a8a9cdc41ec": { - "balance": "1379381904815000000000" - }, - "f4642be1a7685aea0dc7b362d36f58f15d806b72": { - "balance": "4717509847323000000000" - }, - "f4712925f57391043e0cc2e671f33124a0bc8613": { - "balance": "419736833200000000000" - }, - "f47317fba5927dd8dffc4049d4f3277fcef503d6": { - "balance": "149279442682000000000" - }, - "f47ce4c5aaef82692e47f7a810ba38d1faec0eea": { - "balance": "10000000000000000000000" - }, - "f491ffc412bf142788bb82d48bd4eccbe9e0a286": { - "balance": "77276422315000000000" - }, - "f4a1e27e669c29f15b9f89ac15f702340a135743": { - "balance": "324000000000000000000" - }, - "f4b5cbfa50a6c4f5f7db7a93fa565362cc7aceac": { - "balance": "195951823248000000000" - }, - "f4b949c6e10615b651675016f0d7d6ff64e31aee": { - "balance": "35516207325223000000000" - }, - "f4c5e2f043ef3548a2c1c27d968087bec65e2f7d": { - "balance": "100000000000000000000000" - }, - "f4c79ea9c6f7297e016c39296d86f0304070c31d": { - "balance": "71036374423000000000" - }, - "f4dde3733a72872a7efc095cb412672c50928f1b": { - "balance": "129914864759880000000000" - }, - "f4ed736a413464eb93f8a430e093a64f0bd4222d": { - "balance": "10000000000000000000000" - }, - "f4f07e45560fb63d5207ed7e8d7cf4fe29e06d18": { - "balance": "293103814503448000000000" - }, - "f50eac35eef0a1bfa23ba31020ef60e89bf8e9df": { - "balance": "10000000000000000000000" - }, - "f51236dfd888929ccb2fe1f1fc5554abc5df4ce2": { - "balance": "25000000000000000000" - }, - "f521eb42e9092350f2ad4391ddb42bfe7abb4db9": { - "balance": "217462745186000000000" - }, - "f54e7062b6a9a8b283acf00fcbad58aca0737676": { - "balance": "7327357122437000000000" - }, - "f553301efd81629d0856d9c95c70f4a962e602ed": { - "balance": "1500355826530000000000" - }, - "f55c555b0991b2413f2f2764d8ed6a0d77825965": { - "balance": "1174679810163000000000" - }, - "f56ff110d521ceaec29dbf2842f1e78b24463cea": { - "balance": "20000000000000000000000" - }, - "f573fec366236ab87ba041f7dc6a88d92b1fc9b7": { - "balance": "4659857040000000000" - }, - "f59987743b239379aac9353e17e0e4442aa2c684": { - "balance": "25000000000000000000" - }, - "f5a9ca298e88c5492dd44a66d815b649c2f01d39": { - "balance": "95879585325000000000" - }, - "f5b4933164c55b5ba99db906ecaa52bba4f95164": { - "balance": "25663623936000000000" - }, - "f5d20af68c6fed98144718b6beab82fde00dfedc": { - "balance": "16000000000000000000" - }, - "f5e49ce72be9b17ff39688860e5cf6fd500a886c": { - "balance": "106142276914000000000" - }, - "f5f472405a4530075805fbc11928544770fd61fe": { - "balance": "64000000000000000000" - }, - "f62096c7305eb97b221bb637f4269246fe59262b": { - "balance": "855993602798000000000" - }, - "f622bf9b8f7be2f75d5ed73d318a0e7fa62a587f": { - "balance": "20000000000000000000000" - }, - "f6231f31d524ccc444bd046123ba33bc224bdd52": { - "balance": "97550810879000000000" - }, - "f641b4a721dcefa497274fd06888eb998b9bc038": { - "balance": "39401014566340000000000" - }, - "f64f0c5172c99d74b2450a4685c3ec715b379922": { - "balance": "28337413668000000000" - }, - "f65841061cd55cbf20843d9594bce9ee133aa644": { - "balance": "9064540188290000000000" - }, - "f65f0106f3d148d0660547f0683ded4dffc12fe9": { - "balance": "87334071785367000000000" - }, - "f677961296ed933db9e1dd887711387540c0436d": { - "balance": "3982789899000000000" - }, - "f68ba7530f423b8df1625cee36f8df2363a57c49": { - "balance": "5000000000000000000000" - }, - "f69c6eaf077b795f19a9590ee8b578543558e4c4": { - "balance": "10000000000000000000000" - }, - "f69dfe3f0f76e50e2850e44e9e36b6966e277eaa": { - "balance": "288231750575462000000000" - }, - "f6a73c4b958b4d6044f3f4da7147d0fa80e2ea31": { - "balance": "50000000000000000000000" - }, - "f6b0864be5f7bbc4210a3420aa3ead614a8fe7e2": { - "balance": "880968828000000000" - }, - "f6f43a6d9517471436d2ce5047a2b707580e7149": { - "balance": "20000000000000000000000" - }, - "f6fb414d1ca7c29be35b5f97096c817bbf70b070": { - "balance": "15156317416682000000000" - }, - "f707b491ac27b2d2e5e1f9d4123635ee0af92c5c": { - "balance": "500000000000000000000000" - }, - "f71179583a471767a1b399842d7d29caefe57a5e": { - "balance": "429648186876000000000" - }, - "f71ed909eca6bfd574cd670389bc9250493d686d": { - "balance": "38189267531000000000" - }, - "f72ccdc70b7878cdb94f42ee72ca5b4b35a46238": { - "balance": "86065647347000000000" - }, - "f74035e85dbfdb961037bf689ee7dfdcfaf32d64": { - "balance": "398451682882000000000" - }, - "f77668db085a87b0a0405a275e1c2516d3e02b66": { - "balance": "10000000000000000000000" - }, - "f78990d9e50876b49f933e9d74bda44197e9aa7d": { - "balance": "51984216556000000000" - }, - "f79b9df28b7d94d1b4491fca1cbe50bd36aedb3a": { - "balance": "11546152485156000000000" - }, - "f7c773b89be413848dc4a96f064693a0c3a2eab0": { - "balance": "7084247258755000000000" - }, - "f7e29c20bb0023e9ae079da589346fdfd960dae3": { - "balance": "93132014782000000000" - }, - "f8124428ea619d30a335ecc4c2f64e36500abdcb": { - "balance": "8838170798391000000000" - }, - "f843c9d70226e6c2c8cd4cef78e2db66a8eac027": { - "balance": "498377670361000000000" - }, - "f84bb3c0d872dcdbe99d6abcc57c6b5c2b2e35ad": { - "balance": "1405105232436000000000" - }, - "f8679b915ae94e4668f2e27d1094cbb2d97cf428": { - "balance": "1000000000000000000" - }, - "f86dbb82c634cdfa818e4d0dbcfcc9a5c47a9ddb": { - "balance": "196000000000000000000" - }, - "f88bad7726aa66bc1d0ca5824044072f3551fd15": { - "balance": "37432374800000000000" - }, - "f8ab07d0751a2c283ebe2a7e28c5b6e57867e1d1": { - "balance": "25000000000000000000" - }, - "f8afb4f5684c56ff7ce71b4e4cf7e42062470e08": { - "balance": "10000000000000000000000" - }, - "f8c28df0d1a0982289ddfa2a6d562e5c75a5dd01": { - "balance": "1447386977682000000000" - }, - "f8cca137f9c12b48eafd43f038e55e2d3c481919": { - "balance": "35370515421000000000" - }, - "f8e50d1816a5e5c649756ae208209b03b1ece0c3": { - "balance": "48449640035000000000" - }, - "f8fb33ba1d93112d9c3672806e0939083f09a88e": { - "balance": "419743187776000000000" - }, - "f903bebfcc6a7050fc2c5bd14248af9b300f1600": { - "balance": "473363252199000000000" - }, - "f90ab9078f26dd881fb054b4b6e3b3e17fa94718": { - "balance": "156449634345000000000" - }, - "f93e3f392efc057f0af3a91416858a515c1ed996": { - "balance": "1147663044625000000000" - }, - "f94eac538ca66931869c312acb67721c4337842f": { - "balance": "368103335377000000000" - }, - "f94fda503c3f792491fa77b3702fd465f028810d": { - "balance": "317241487661000000000" - }, - "f95dcedbefee8ed01086c91d91a4c115ad8fc947": { - "balance": "147059838786000000000" - }, - "f961a293bbce366a6fcc98d2ba0342e2ef3c5519": { - "balance": "10000000000000000000000" - }, - "f966fdbc4a42f055f8f52d31c23ad7b6a07a5e22": { - "balance": "10000000000000000000000" - }, - "f9a3a61a2f1469835240bb0641eae40c07451e30": { - "balance": "218000000000000" - }, - "f9adcf232180378b08a46d6c8d9d97f01802e01b": { - "balance": "15658216517944000000000" - }, - "f9c68991ff7ac307e41ea1c673f8ebb1a6afbd99": { - "balance": "10000000000000000000000" - }, - "f9cc0c60431d7bdb0c7581a9ae7f011b0abefeb1": { - "balance": "16000000000000000000" - }, - "f9d43c329b61ca2169600e45c8fad3c94226adb8": { - "balance": "120128558137000000000" - }, - "f9ef5d4e2ca8888216b939d3d938438a34dd9da2": { - "balance": "144000000000000000000" - }, - "f9f3d14cd3bd09e2c4c89035b4f50e93f6175cef": { - "balance": "725000000000000000000" - }, - "fa0f5a03601bd1fc76865cdd69d9671ba6073592": { - "balance": "225298289139000000000" - }, - "fa12f10db0eb552b719194becef20af9f45de8db": { - "balance": "1012484659496000000000" - }, - "fa146c58a0709951bc2e9bccddcd002c5a0bb7dd": { - "balance": "199563276701000000000" - }, - "fa159185c156f35fa450b77c48846c2dab6349b7": { - "balance": "100660066567000000000" - }, - "fa193312655f79c7b0ee7d7ef904486836180026": { - "balance": "48141690266000000000" - }, - "fa2484de744918bd8c91350fbabc0dab8b8a44f0": { - "balance": "36000000000000000000" - }, - "fa36dc463b026d8edfeb8ac4acac43a51d643457": { - "balance": "9608761064478000000000" - }, - "fa84199010be2bf53e803c23771e0d15fd025386": { - "balance": "1474902394742000000000" - }, - "fa958bbfa367a745bcd0904db2c4e30445edaefb": { - "balance": "175679888121000000000" - }, - "fa98bcaeb55285ad7ead12ccaa15cf488f567ede": { - "balance": "136105143781000000000" - }, - "faa1be631da42b41a026774f4166c1b831ef41e9": { - "balance": "86358861589000000000" - }, - "faaa857e7f149968434f313ab8db596e1b0ae75d": { - "balance": "36000000000000000000" - }, - "fac2b85ab274055cf1415d57394e8aca4541857d": { - "balance": "289000000000000000000" - }, - "fb23a508ccdb4e91b252f5c06c465c55ed59b1db": { - "balance": "14698710175236000000000" - }, - "fb24d4e47ba70aa4b984372b4852ad3d082daa24": { - "balance": "4526648424830000000000" - }, - "fb27a7e8b8b4ae43c69ce025b46187e538608769": { - "balance": "121000000000000000000" - }, - "fb2cdb5e85872f52c99985f219b8fb4125c6a8b7": { - "balance": "8568367153000000000" - }, - "fb3d76c8165bcb3c93fd3b2b10c20588d0fa97aa": { - "balance": "500000000000000000000000" - }, - "fb5161b2cc9d48a53f47d66002905f0458e3cd9e": { - "balance": "225000000000000000000" - }, - "fb72756c4845f18ab35d29f632b662c0c0d4b94f": { - "balance": "883095068524000000000" - }, - "fb8b7efb02ea5292304c0f0abc8c555684653587": { - "balance": "10000000000000000000000" - }, - "fb9ee61e337a5c7b57c5140e84919101570e2cb7": { - "balance": "16000000000000000000" - }, - "fbae69f44b116c186a86cb0de79323ca3d6b99eb": { - "balance": "1359504686067000000000" - }, - "fbbd399eb9e5d3dd67efc48927973601dcd84321": { - "balance": "2049018637367000000000" - }, - "fbc9a3c3c429990cc306710b3dd44174dcc72ad4": { - "balance": "55507457947000000000" - }, - "fbce66a6898ecd70893db6b4b8c3d00afef8e20b": { - "balance": "20857164902458000000000" - }, - "fbe8fe04084fc93dff8228861fe100bfeeb057b6": { - "balance": "10000000000000000000000" - }, - "fbfb717f902ad79ef63565f9ab57f041ff5f7626": { - "balance": "16000000000000000000" - }, - "fc0b6c8c6be79bf0c9554f7855dc8c4a617d02c9": { - "balance": "17347593956000000000" - }, - "fc17518d05e605807847bbf6f407da89037bca00": { - "balance": "1796383702108000000000" - }, - "fc2793424c809cc80938a1be1292813adbc8ac8c": { - "balance": "10000000000000000000" - }, - "fc35930abb108ae6cae33fd065dfb799808ea326": { - "balance": "912737460000000000000" - }, - "fc5a9209799e563ae8d958774dc86345a3bc7ed2": { - "balance": "29049176573000000000" - }, - "fc8011850c09c9288e737ea58ca5c15cded6dc8d": { - "balance": "10000000000000000000000" - }, - "fc9183ed137be071ad183d025395a0ebe2674654": { - "balance": "500000000000000000000000" - }, - "fc98c9d88b1fbbb68dbdd6448aa6a32e8282800d": { - "balance": "900000000000000000000" - }, - "fc9f4b9da7a46c2bfcd50cafe1f892b9984be0ee": { - "balance": "21577116424370000000000" - }, - "fca525b732a673b953f1c23083c276cc8cbcb86c": { - "balance": "77653618624000000000" - }, - "fca57b6a4798f33478b6e23622173cda3fe1b9a0": { - "balance": "793368066098000000000" - }, - "fca79b446c513a7bed643603c42f35ff0fa89f49": { - "balance": "998082799053000000000" - }, - "fcab42f7f07735a7b09074c1f1769287069c88c8": { - "balance": "94824830574000000000" - }, - "fcacbbc6810c586522012ad32c3dfac80eb563b4": { - "balance": "10000000000000000000000" - }, - "fcb38809b63810b6673dcb4c947e01f7b49fb1b3": { - "balance": "725937240372000000000" - }, - "fcc0e531d9f6265672aa885af361534464a11015": { - "balance": "22121462657000000000" - }, - "fcc49c62d7738fa1b92aa6a69a12b671e4c7c8d9": { - "balance": "50000000000000000000000" - }, - "fcc95394fd796ca5bd8f3814883b1150d74dd9a5": { - "balance": "144000000000000000000" - }, - "fccdb068dfd599d7d5c290a6ae65eba9151d5b29": { - "balance": "5369426564000000000" - }, - "fcde41ae28bdf9084a28f47a9348d8aac5b3dd43": { - "balance": "409599263197000000000" - }, - "fce5816f066ca32d1fa02e9e8b5eb8a7fa3e4dea": { - "balance": "1193272309645000000000" - }, - "fcf9fb8996d6d9175ade6d6063be0742de20ea1f": { - "balance": "16852526239339000000000" - }, - "fd10488d55e6861cb67f7f50950d78892e7032ad": { - "balance": "165069902909000000000" - }, - "fd23e8263d89256add0dfe93da153d305ad917c7": { - "balance": "26633825496000000000" - }, - "fd3a98cc3b3f1439af35f806de2fb05fef98f279": { - "balance": "1043321187464000000000" - }, - "fd3d79185a91984a117ee6f9fd304725875094e2": { - "balance": "2349991833898000000000" - }, - "fd5e6ac22634f04ec4ace5da8996c2b7b70b22f4": { - "balance": "10000000000000000" - }, - "fd62ed1cf7a535c989fbd742b1660205a2f69dd0": { - "balance": "49000000000000000000" - }, - "fd645043bd4d7b71e63e30409b91e9fdda3a86c0": { - "balance": "362957768837969000000000" - }, - "fd7014fc1c70af482115247ff94ff6bdbd3d364d": { - "balance": "743383172317000000000" - }, - "fda0cfe95df9021497752b04863c3ec44d13e853": { - "balance": "15586809617955000000000" - }, - "fdb5b964808bcb974d3e888cbb45bcd57e57c907": { - "balance": "5549247772273000000000" - }, - "fdbaaa865ec38da13e80554b6d0abc437f60d8a5": { - "balance": "3736861227131000000000" - }, - "fdbb8693b3c20c0eac5fb585e2347d41debbffce": { - "balance": "100000000000000000" - }, - "fdbdaec57829f25ad48e18d94e0b8533f2801818": { - "balance": "6934630922926000000000" - }, - "fdc318ba5b1f8ad33e00528828b93a840592e2fb": { - "balance": "10000000000000000000000" - }, - "fdcf6a997bb10806e4d87eb4222e9f93b4202179": { - "balance": "1000000000000000000" - }, - "fde5a9911a10770d733db4d32ca9a5493478399c": { - "balance": "20000000000000000000000" - }, - "fe39185a6b84378820ee215f630533e658731ca9": { - "balance": "17022202932000000000" - }, - "fe3b1032e524674cba5f329f940c837850fa53ed": { - "balance": "50000000000000000000000" - }, - "fe3bc4ff2c3b66bc582558314b80030407e7de96": { - "balance": "1669870860988000000000" - }, - "fe668dbb1f3de744d16e13e0ed6f5708c2c15d1f": { - "balance": "39974355655263000000000" - }, - "fe95bfb97fa60341f8af2ad621e606b85e3c2e57": { - "balance": "528601649597478000000000" - }, - "fe99cf2a1fbbe7c46e4235b2d135a3a093fcf16c": { - "balance": "7271022106877000000000" - }, - "fec1f6ed4b3ff01e7ebe13fb53f60ee5a3b9e191": { - "balance": "1316316072034000000000" - }, - "fed9bec1b2145452ed5535e4ba29fafac6c35fbb": { - "balance": "10799354586000000000" - }, - "fedced7aa1cf3f3a7eec321cc0274759b154ea8e": { - "balance": "11740927210323000000000" - }, - "fef5063701a93ad02676fe0b99d0f4d2da0ccd67": { - "balance": "10178531012000000000" - }, - "fefd5627a408ca099587892ee2a46fa8cc89be19": { - "balance": "458504035686000000000" - }, - "ff1fc0f6f26188cbe18cf65d8a344d3775aecc6d": { - "balance": "81000000000000000000" - }, - "ff4fe483b3c04ebc8d6705c699ecee3e92071715": { - "balance": "1000000000000000000" - }, - "ff51bfe823394b2bce05947a6068bd5158d4af0e": { - "balance": "692533626783000000000" - }, - "ff6652e4e45f6b0f95ad4c9ec2bc80476e3f7fc6": { - "balance": "46457898024000000000" - }, - "ff68246ac7640091e5e58345736b249e036364fc": { - "balance": "2626125272000000000" - }, - "ff6d4b8a8393a503047ff829dbf2bf8e9172dc6d": { - "balance": "2865001878255000000000" - }, - "ff6fe19e056a7211b7e484c2c540d5aa5f1d83e5": { - "balance": "36000000000000000000" - }, - "ff7fa33529e1781c1b2951e57581780b229e3fda": { - "balance": "10000000000000000000" - }, - "ff82d1052538539d07cf3955476cc9a5027d8e4e": { - "balance": "83572023121000000000" - }, - "ff8acfe75afcc1efb1bc44be9f9bb242a94f73f7": { - "balance": "7556034521000000000" - }, - "ffa2b5f1685de9fcf1af4653cd3a584db1beed64": { - "balance": "114892199805000000000" - }, - "ffb1e9be68ae8be8d7d066c473589921e68825a2": { - "balance": "484660652980000000000" - }, - "ffbf91a9d1a6377b7435e3e734132e7b34188dac": { - "balance": "20000000000000000000000" - }, - "ffbff1fab9f2bc2f387d0cc9cc28f6aac533c813": { - "balance": "10000000000000000000000" - }, - "ffc4ff6433ea35544e7a07fda170e62c451301df": { - "balance": "29238210920000000000" - }, - "ffc7534b64a8fe8760e931a710883119d28ae106": { - "balance": "500000000000000000000000" - }, - "ffda6b8e3de72d7f7c18b892e6a8b80b886d5fa5": { - "balance": "214366938289000000000" - }, - "ffddb1fb7521c9772ea4886aaf022c4375ef904d": { - "balance": "554864446437000000000" - } - } + "name": "Ethereum Social", + "dataDir": "social", + "engine": { + "Ethash": { + "params": { + "minimumDifficulty": "0x020000", + "difficultyBoundDivisor": "0x0800", + "durationLimit": "0x0d", + "blockReward": "0x2B5E3AF16B1880000", + "homesteadTransition": "0x0", + "bombDefuseTransition": "0x0", + "ecip1017EraRounds": 5000000 + } + } + }, + "params": { + "gasLimitBoundDivisor": "0x0400", + "registrar": "0x0000000000000000000000000000000000000000", + "accountStartNonce": "0x00", + "maximumExtraDataSize": "0x20", + "minGasLimit": "0x1388", + "networkID": "0x1C", + "chainID": "0x1C", + "eip150Transition": "0x0", + "eip160Transition": "0x0", + "eip161abcTransition": "0x7fffffffffffffff", + "eip161dTransition": "0x7fffffffffffffff", + "eip155Transition": "0x0", + "eip98Transition": "0x7fffffffffffff", + "eip86Transition": "0x7fffffffffffff" + }, + "genesis": { + "seal": { + "ethereum": { + "nonce": "0x0000000000000042", + "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + }, + "difficulty": "0x0400000000", + "author": "0x0000000000000000000000000000000000000000", + "timestamp": "0x00", + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "extraData": "0x3230313820457468657265756d20536f6369616c2050726f6a656374", + "gasLimit": "0x1388" + }, + "nodes": [ + "enode://54d0824a268747046b6cabc7ee3afda48edba319f0d175e9e505aa9d425a1872b8b6f9ebf8f3b0a10dc7611a4c44ddec0fc691e5a5cde23e06fc4e4b3ff9dbef@13.125.185.147:30303", + "enode://7e150d47637177f675e20d663fc2500987f2149332caf23da522d92363be8a7880ef9150a6183e9031288a441e0457239474967a111eafce17e19a4288076ea9@18.219.40.235:30303", + "enode://6244c9d9cd288015d7ff165e90f3bb5649e34467e095a47c6d3c56e8fb8c849b3b4db683ff3c7ae8a654bbdc07ef12ee2fd7d72831ac213723281c1b0cc90599@13.250.220.98:30303", + "enode://e39f162b9f4b6ed6f098550f7867c2fb068fc66f362b3db0f45124c43ea18508f5ceef4e0e4de53d301e14a6f1683226aeb931d7401b4e83b5a583153ffdd7fd@52.57.98.157:30303", + "enode://54b4a117d66dc3aa93358dec1b31d4f38e72e4381b3e28a65ac6f1aaac3b304ebbe41d32cc864fa69a9a6815c34cf9b8965690dc174a5f72af14547b601b7924@222.239.255.71:30303", + "enode://851f14c5cc86cbc0a81acfcbe5dd99ad5c823435357219df736932c5f89ad4318f6973a553857a32d97a71793f5a35c062d46320be282aa0a80b06b9c6b624e4@13.125.232.71:30303" + ], + "accounts": { + "0000000000000000000000000000000000000001": { "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } }, + "0000000000000000000000000000000000000002": { "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } }, + "0000000000000000000000000000000000000003": { "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } }, + "0000000000000000000000000000000000000004": { "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } }, + "ceed1c8254abaf069669fc6045e90482543d1f2e": { + "balance": "38000000000000000000000000" + }, + "6f22d7f8c38e0135e36be87e77fc8d4ae4b3d965": { + "balance": "38000000000000000000000000" + }, + "d016e982b7886302428d7c741392c658337513d2": { + "balance": "38000000000000000000000000" + }, + "defa96db5c8a41772bc56f68f95e307ff71a2c60": { + "balance": "38000000000000000000000000" + }, + "951ffd4253ffcf31b2895dd3f7f2a8a9bb2933e5": { + "balance": "38000000000000000000000000" + }, + "b7071dba21cfbe1b70abd7ddfd2f0f83d5d19a61": { + "balance": "38000000000000000000000000" + }, + "6ca420cd8d5407c61a9b14adcb38bee0f26e2848": { + "balance": "38000000000000000000000000" + }, + "b50d185b6cd04499a38afc0fcfcb59eaa74d0956": { + "balance": "38000000000000000000000000" + }, + "7ba8c49a444c117f2d2a50650b3f700d4ee659fe": { + "balance": "38000000000000000000000000" + }, + "83f9959ecc532dce071fcd0c62dc23cd571b689b": { + "balance": "38000000000000000000000000" + }, + "001327afce7ebb623a7d0f17b2ffc358fb863b5a": { + "balance": "9844198127334000000000" + }, + "0015ac7f8bb2a2c7d954fc2dbd4e20c0db5942a5": { + "balance": "1000000000000000000000000" + }, + "0021e69c041be2d28744b69361105ff51295da59": { + "balance": "1379639894000000000" + }, + "002cfd27bbb8164681b8762e71b2891beb127fdd": { + "balance": "25105286685000000000" + }, + "0033cf217bc765ccfc338869451588ce448fde65": { + "balance": "23425485280069000000000" + }, + "0048f1d1735979cd8ac9c0886088336b2d4a43a6": { + "balance": "10000000000000000000" + }, + "006a79cc154917cf204d8097728f290e29716d43": { + "balance": "20000000000000000000000" + }, + "007c8db36e4f649b14516dd78202670b671ba753": { + "balance": "1000000000000000000" + }, + "007d131b58388f251075a3c61020ce301106c5cf": { + "balance": "381079535880476000000000" + }, + "008e8fbffc2fdbefaa7e3be4f4a9160db826d05f": { + "balance": "10000000000000000000000" + }, + "0126d86b9814b0e78c4e01a3916bee6a7778145b": { + "balance": "10000000000000000000000" + }, + "012cb961297c837630251a173b7861e77724856d": { + "balance": "494562376059000000000" + }, + "0145886dfab5ef4f2def50a56b4a074cf5b18acf": { + "balance": "680585022951000000000" + }, + "0167918bab62aa2118cfa4d3eb80da0e71c71d8b": { + "balance": "122395119468000000000" + }, + "0182f7286ae9d4d6bc514d5175d14685d520bde7": { + "balance": "10000000000000000000000" + }, + "0184e9c8fe99d85100fe28a0e8877b14768b372a": { + "balance": "193295614762000000000" + }, + "019eff7dce7f31c2d4f7318da71d212cbf89d36e": { + "balance": "64004138198000000000" + }, + "01f3351ea66c352346244dbb79189066bed62fc5": { + "balance": "937056266523000000000" + }, + "0202ddd7f4f32bc575f7df24612f8aa9f9a7ae42": { + "balance": "106905151080000000000" + }, + "022b8c65e959cab71f56688b7073257b58bbef4a": { + "balance": "9682681149566000000000" + }, + "0245ff6382eb93ab1e8ed2e3c0bce7a1b9a9713d": { + "balance": "289000000000000000000" + }, + "025e117a69ca9244ed430732c11e550e3ee67577": { + "balance": "1861905310567000000000" + }, + "026e7457eeaeaec7898fdee1ad39be89e92733b3": { + "balance": "7529030978000000000" + }, + "028d2def8c54fcc77bf0191b183c0bc4570ec1c5": { + "balance": "9056720934000000000" + }, + "0291a087605b516e465134797b5459436d320e6a": { + "balance": "481100929805000000000" + }, + "02a4b18b3e13ec79307e712fba1867cbf7fb6155": { + "balance": "9000000000000000000" + }, + "02a812d4cebcac1a92ae470ade92fde7bead127d": { + "balance": "66793603497000000000" + }, + "02f718c94b2c8e8d62752f8632443504c1e4b6e2": { + "balance": "1000000000000000000000000" + }, + "030dab52b47b37505b72e5ca0985f65ead590816": { + "balance": "1376851176362000000000" + }, + "031c59846f75de1aefb0e8a95e0fb822fd06555b": { + "balance": "140978338628000000000" + }, + "031ee87c672d83ec73059c86a312a9e972142054": { + "balance": "96406273341000000000" + }, + "033182e860564cf695cb403c8c0f078053368d7d": { + "balance": "1504349255824000000000" + }, + "03788dc6528fa33a90e90e03295ae4b792d56644": { + "balance": "24356250426000000000" + }, + "037aae119047028157c5b3bc9d3d202b02cbce42": { + "balance": "105627739575000000000" + }, + "037d45b323cbc5cbac999c5001169646e690b94c": { + "balance": "2000000000000000000" + }, + "0390ba35c454a24519d845405a7e24df71250748": { + "balance": "1872501898509000000000" + }, + "03ab8c1e7f904db62437b16d28aeb539b2dee55e": { + "balance": "55000000000000000000000000" + }, + "03af4c69728a888fa26b1aefa439005989771fdf": { + "balance": "27704588237757000000000" + }, + "03b33fb19d165e5e33bcfbbfc009f418d71f30fb": { + "balance": "1999139000000000000" + }, + "03b34c79f8167a4e8be0f6133254d2b50cbd878d": { + "balance": "111065050160000000000" + }, + "03d7e8638b74ae44a2770287285489a95fa1ea11": { + "balance": "20000000000000000000000" + }, + "03d870bf719f03250c0dc5156a36751b3aa21f18": { + "balance": "981119649953000000000" + }, + "03de52c12b05fb8bcba3a1cfe02a0ad1bc9761d3": { + "balance": "362007990932000000000" + }, + "03e516db27b1abe008ffc57ced48f72f872d8b08": { + "balance": "3389116345657000000000" + }, + "03ef5ff863ee5f1167f38cdf316e4d52a242b750": { + "balance": "12395856876000000000" + }, + "03f27766760f2bd1cae1cb85ddf43ab59c871e47": { + "balance": "49000000000000000000" + }, + "03f4e1a8fb4eedc776f4835fcc85d0f236612f9c": { + "balance": "27210590272692000000000" + }, + "0404936ee04cc79cbb3aedfa33a53f94940f772c": { + "balance": "29919204637416000000000" + }, + "040501ffde9649be794b7d41643273ed6285ab39": { + "balance": "686000000000000000000" + }, + "040e449de680f69614120f0a2e894cde36e4adf1": { + "balance": "81993180085000000000" + }, + "041531e906dbdc70d89f5e255151d9865a059308": { + "balance": "2163418749315000000000" + }, + "041ad9f6bf970541e4ea8a14dde1e789d0fe4367": { + "balance": "44999979000000000000" + }, + "0446420c07cf73d2b3741b945c1cc8444b4ba6b6": { + "balance": "138749371512564000000000" + }, + "044c1a540b8ab286c218c2fa9d5bfbc2761e7626": { + "balance": "1" + }, + "04526b2c62911e78a939816aa4575fe30baa06c7": { + "balance": "2983093150081000000000" + }, + "04adf59f8a0ad3820a7972c6243202b3b0617fcf": { + "balance": "50000000000000000000" + }, + "04bbb42882a475eed58aae47fe530ed19c1cedaa": { + "balance": "278038763863000000000" + }, + "04cff7a7c2b9b0bf31c5ad4a5de8b0eade70aafc": { + "balance": "515406205244000000000" + }, + "04dcd325dc1fd37ff3c87da3b21c47ddfcc37cc2": { + "balance": "5831887315000000000" + }, + "04ec8d0b5157370f5a2671a2aa68ae486b7a7842": { + "balance": "10000000000000000000000" + }, + "04f50f2a6e89ee497a64c11baa90759a10a1247a": { + "balance": "25443071621949000000000" + }, + "0513a769ebef58ad3a4fd7011ddbe19799ff5600": { + "balance": "64369494797000000000" + }, + "0514c1151f356070ace281435f25c86b58280715": { + "balance": "38967380881301000000000" + }, + "052fda414fe1279c6276a237b07e1b4148a8cc77": { + "balance": "10000000000000000000000" + }, + "05431089cc62a987d0e99847e10a006233146f6d": { + "balance": "268977485219000000000" + }, + "054ed2f55028257212b996f9a3d34758d1d4ffd1": { + "balance": "100000000000000000000000" + }, + "05a68cc758560addde302baf814f2fdbe0ef2c2b": { + "balance": "10000000000000000000" + }, + "05c669d9ded79fe9e4e3718052bc7ca18a3205ab": { + "balance": "7347158140000000000" + }, + "05d77ce5c87477b05e90e829dafd8eb3a8c87823": { + "balance": "21191998933000000000" + }, + "05ef2894a2a1c6eb6c0a768d04ef5b573f357712": { + "balance": "20000000000000000000000" + }, + "0601011f80279190b96f641205c6a524a8ad5a28": { + "balance": "12025716447696000000000" + }, + "061a8acdb1a340ba7c550814831e27262708fc98": { + "balance": "234029764576000000000" + }, + "06219483e217c9ad479f76a95426f689ef4d5951": { + "balance": "1509408723551000000000" + }, + "062d0db8a650f2241f8a4295326a2570a7c771bb": { + "balance": "717459720227000000000" + }, + "0633ba746235d8fc8243751b1aa31646c299f262": { + "balance": "49000000000000000000" + }, + "06b6a5cadfe1fdc88015512e835d840e58ae4123": { + "balance": "1000000000000000000" + }, + "06d08fcbe96791514d900d2cb6c0f029d8d791d0": { + "balance": "19196168602258000000000" + }, + "06e5c0bad43a7011878b12a682abf01ccdfaa151": { + "balance": "30000000000000000000" + }, + "070656bb11ec36074d47c791c0b306394b703401": { + "balance": "1245216075291000000000" + }, + "070d84c938217163b60ed38e4937eea7158c03d9": { + "balance": "27507979787000000000" + }, + "07428c95ef3862026e54d3a963911cdc673dbcd9": { + "balance": "13792309994528000000000" + }, + "0781cb21df142ec5f67b956bf995f02f6f24985f": { + "balance": "224940990659000000000" + }, + "078c38c153b414cc4c12818fce2ea7ba09a34e51": { + "balance": "1410646136000000000" + }, + "07bfd0de7a9a1c927446aaf2d7ede55b471daa87": { + "balance": "77778844734000000000" + }, + "07d1ac83140188b8d7f4c8c607d0da22c5ba523f": { + "balance": "7713686418107000000000" + }, + "07d8ef8fc6dcde319a5af5b6cea18983bdc4c8fe": { + "balance": "3801361173000000000" + }, + "07dfab72dd3e44fcbb1ced625899bf20e0c52ffc": { + "balance": "154177778806000000000" + }, + "0817ce33d943e84c7b3261cc3e37b86b5d6d76ae": { + "balance": "90753785862000000000" + }, + "081be00a2ff62cbcb95a8eb020ac0efa33f93a42": { + "balance": "1027889807304000000000" + }, + "085ffdc6043b04653e51b1a34af20b609d158607": { + "balance": "3314058000000000" + }, + "0882c2228f5df24064bc37e8b7199199de308bb8": { + "balance": "98420617420000000000" + }, + "08918776e9a7136cedad5d0cee52f5d9dd833ece": { + "balance": "1263170315026000000000" + }, + "08bdbcff16919abc5e15fa68ece56eceef33f48d": { + "balance": "2552990000000000" + }, + "08fc8c7bd03fe1249266b233edfcf830693d0e10": { + "balance": "283490111768000000000" + }, + "090f79a4178b5180150444805f62c26cd21be897": { + "balance": "884195010282000000000" + }, + "0914a9dfc9d6ecc063a55e5320050112f305fe17": { + "balance": "15373898854941000000000" + }, + "091791ab5f8ab86f1d8f566ed221b268cbc55347": { + "balance": "2207516004000000000" + }, + "09529f8b1633ce4375451bb44b1025f6e5f9facd": { + "balance": "151697652792000000000" + }, + "09600bbb9d9b23661d269dbe1ed066d8e573b5e1": { + "balance": "802935104935000000000" + }, + "0964d2af1d5883fc0e0a77459f6a141824de7356": { + "balance": "9610980935058000000000" + }, + "097c731d1fc6792ac0f0ff92be4403c3749cc1dd": { + "balance": "165134479709000000000" + }, + "097f152b3f837d38ab1e8c0683d62f5a01d67902": { + "balance": "20000000000000000000000" + }, + "09a6772629ef0bf402ae6d27cd32e6eefb220a12": { + "balance": "20000000000000000000000" + }, + "09addb954d4e4b4e95e0c66d324115d609df5a99": { + "balance": "8435321515000000000" + }, + "09b2eb03e0fa321102196578eb40dcba3a46ec9c": { + "balance": "12723517962933000000000" + }, + "09ba0ed4dce470ba0bcb4d46b507c3b024b83070": { + "balance": "99999979000000000000" + }, + "09efbd6dfea375065be1b3a8f4541f024da21a34": { + "balance": "5870833623000000000" + }, + "0a24d4ae66edc7723bbb314e9b96dc7b9a31e813": { + "balance": "70000000000000000000" + }, + "0a3ee710909382f762648deff8ac7c8b30e2ce10": { + "balance": "407656462445000000000" + }, + "0a42b3145257154e76a97db8147c93be4cffd97b": { + "balance": "10000000000000000000000" + }, + "0a7cb6037f1eba5d19fe781335ecd37b7229c5f7": { + "balance": "74113322448000000000" + }, + "0a85d1bec4d44e309068b115abd517d3733fc56e": { + "balance": "14836218750000000000000" + }, + "0a891ba9ca7b99ecd815b1dcec9243dd4deff866": { + "balance": "178004857988000000000" + }, + "0ab69370b537d4ff5b45704fed293e46e3464f87": { + "balance": "1258876668246000000000" + }, + "0ab77a2e8ab9a3b659d1f1d37956c3607a0f9a60": { + "balance": "6283300817712000000000" + }, + "0abc7e8d52f5b0dcf1d4713e5fa4909102251dfb": { + "balance": "39307290577000000000" + }, + "0af2c0471c802d2e2b20aadf9dd4ec842d313ab0": { + "balance": "1529468143183000000000" + }, + "0b08c717bb3982fc8b92d5b3d30e5b41265a0d0f": { + "balance": "1184600154874000000000" + }, + "0b3f2aa9dc5b57b0469398d62f60a13774ec0e87": { + "balance": "132187640280004000000000" + }, + "0b3ffe85aa89e71a6e51e938c7265d2a7173061b": { + "balance": "2106793086824000000000" + }, + "0b468562e712d22b37e1a65f54b1fa825beebd1b": { + "balance": "15130906006000000000" + }, + "0b5333eb668dee29ebc0e335d74f33ffeaae9ac5": { + "balance": "125953133109000000000" + }, + "0b59a20107495e951b509187307782ca9dfa441f": { + "balance": "25000000000000000000" + }, + "0b8b7fb066601ea7744b81f6e1a21b8e489359cf": { + "balance": "101782000000000000000" + }, + "0bd7791097f79066d71ac0a2c94bce6628a63373": { + "balance": "44389955028000000000" + }, + "0be541af06e167206b5d1cbe08e8fb2b5ebc82cb": { + "balance": "9000000000000000000" + }, + "0bf178bba463f4f6c33e3d81b1a78d220f7b5d4b": { + "balance": "111784804790646000000000" + }, + "0c1f000249b1f1ac9e43c4f10e2da1cc2adf886f": { + "balance": "91251997635000000000" + }, + "0c74e46b115e19726997dd559d2b6ff1bfb79af6": { + "balance": "879229287149000000000" + }, + "0c7c1ec152c920a068c25626c22c4fae7f435536": { + "balance": "39849464104000000000" + }, + "0c85fbd7492d1ae87bf3d286c4750a34f1fd3121": { + "balance": "20000000000000000000000" + }, + "0c9fd6123e313f7d1f0cb25d99839102da08b2c5": { + "balance": "10000000000000000000000" + }, + "0cb051e3bdd9d96e667fbcc00a766d4f149f89e4": { + "balance": "1000000000000000000000" + }, + "0ce32bf6c433cbd26c6f09a1214db0374002784e": { + "balance": "3293279842000000000" + }, + "0ce6374ff04430e34edec8b6323feab2bccab92d": { + "balance": "93983447000000000" + }, + "0ce646412a1524c3f73edfd753c0ba3ee7338275": { + "balance": "10000000000000000000000" + }, + "0ced803e56eac3c99269ff7409d2d200d62d7c25": { + "balance": "49539379000000000" + }, + "0d1dc2be9f78ce2b2591e7f5b8af9dc778499bd5": { + "balance": "2235348003595000000000" + }, + "0d235583458a168e810275f907b5f87bebb2d1cf": { + "balance": "83106439283110000000000" + }, + "0d28fe6e8b7d4b8c90ef7c52b9656511ce5867f1": { + "balance": "1347248794799000000000" + }, + "0d5cbe0da660cbca831787efc45fecb20e06e02b": { + "balance": "297528508941000000000" + }, + "0d7a24f324176f6d793c3a2eb6c54d6ee47eca79": { + "balance": "25637813467000000000" + }, + "0da26a24e3650e84c52fedb36ef76225a8d9d259": { + "balance": "15467820321000000000" + }, + "0db7eaceaf3df21ebb49c56fa2d2e2c8e85dec52": { + "balance": "196000000000000000000" + }, + "0dde52823bd8fb2cb179e6d417c07ff285c31775": { + "balance": "347321514878000000000" + }, + "0df9585f1aa83189e0a813f5eac6e6e0b2bbb8d8": { + "balance": "2891430551000000000" + }, + "0e09af9368f05b476164953b7b9db60ac95248f0": { + "balance": "573644391203000000000" + }, + "0e18315dd2b663ce4859b5bed854403191452c2f": { + "balance": "24174325261000000000" + }, + "0e29bef5f4f66c38a0f05cca1e4938d57ff09c70": { + "balance": "10000000000000000000000" + }, + "0e443353b42e042ff5168e9b3c6de37070368223": { + "balance": "20000000000000000000000" + }, + "0e8cb6e439516b312158f169b546937b715db3f2": { + "balance": "8049136367000000000" + }, + "0e980fab23be601f3abec7b9a24e1335a5e765c8": { + "balance": "8301885845897000000000" + }, + "0ea63fef218ebf570a4ee62ef6ed712dbe623c44": { + "balance": "10000000000000000000000" + }, + "0eb60e3512336e4447ceeb8664ce0ecaa3eb0bdc": { + "balance": "41401696400000000000" + }, + "0edafc1058879a9568e711445b18ec4da31d2480": { + "balance": "10000000000000000000000" + }, + "0efce4565062b23b43dbc1e261463e363e4a5b4c": { + "balance": "10000000000000000000000" + }, + "0f08782c04bf7249ab08f4e251abc60aee792a96": { + "balance": "1380257622493000000000" + }, + "0f19bfe1eb24def828bf1be69791c63ba1de1263": { + "balance": "2223687184885000000000" + }, + "0f2171161eb9674218add261be61d18d86b846a6": { + "balance": "121000000000000000000" + }, + "0f42ef6c5690b6c95f8b8c9dbdc16f717c04852e": { + "balance": "81000000000000000000" + }, + "0f47f5063d321b34a0d800951bcdc3f53c07e32c": { + "balance": "5288516165000000000" + }, + "0f529a9beedb2c2a087a220f0013cea4f8454bfc": { + "balance": "114585457979000000000" + }, + "0f6751d10aaf855454a6e9e4241cfcae3b0ed732": { + "balance": "94160300063000000000" + }, + "0f6ed5a4c3ec100afcd59e9066ba7fcb63cfa6dc": { + "balance": "1000000000000000000" + }, + "0f77025519cc76c38e1cf0bd8721f4a5b9c814d4": { + "balance": "834620571043000000000" + }, + "0f773db2a1a96b775e4481575704f5f087b067e0": { + "balance": "554268361745000000000" + }, + "0fa0f73adbe82f8e09f8adbce15b051971e289c3": { + "balance": "11329911975000000000" + }, + "0fa6397d747d88a25d0c755b3be4eee0e3f68912": { + "balance": "31394936138000000000" + }, + "0fac8635a61bf7652d86725cc75c307949bd4f2a": { + "balance": "49000000000000000000" + }, + "0fb0ce787306ce13dcd614ab3d0e15d9772106ac": { + "balance": "50000000000000000000000" + }, + "0fb1d306d240360056f60f197dc7f68f732ac515": { + "balance": "20000000000000000000000" + }, + "0fe3571f498a6d945e123ac8ff6e3fed348d9432": { + "balance": "20000000000000000000000" + }, + "0ffd6b01ea9a7bd2576fe4a5838fe09e44c1639e": { + "balance": "100000000000000000000" + }, + "100bde3d73fda700369e78229127b58d2ade9177": { + "balance": "10000000000000000000000" + }, + "102028c7626970a28677bbdc7733484c8b14c2d2": { + "balance": "500000000000000000000000" + }, + "10245044be6a46ad41d4559129cb59e843379cf8": { + "balance": "857437279765000000000" + }, + "10417d0ff25c115b25915dd10ca57b16be497bf6": { + "balance": "10000000000000000000000" + }, + "10579870e6685ed7e97dd2c79a6dc3528bae968e": { + "balance": "5187866041491000000000" + }, + "109736465b4bbe31ea65ad01fc98f04498271e6c": { + "balance": "20000000000000000000000" + }, + "109c0535a4a86244c5094e99167d312a77657dd5": { + "balance": "138277702073000000000" + }, + "10aa08064689ee97d5f030a537f3cd4d8bbdaf74": { + "balance": "10000000000000000000000" + }, + "10d8bc8c3d3e2010e83009290586ad85b73321d1": { + "balance": "25000000000000000000" + }, + "10f22b82460252345753875555de2cebebe63a93": { + "balance": "765947730644000000000" + }, + "11111c3a2cfa55e52d6aacf533e1d412f8c8c01c": { + "balance": "4827254128275000000000" + }, + "11386103a0bf199db9504b617ccb3bbd780eb9fe": { + "balance": "10000000000000" + }, + "1156a129183e5bdfdf2bf7a70963285a979363a0": { + "balance": "10000000000000000000000" + }, + "11589cf70a6a4fbaac25224e2ddab222333f78e6": { + "balance": "49000000000000000000" + }, + "1162fabeb3eb1e4124179b00c4a1e01503023f54": { + "balance": "817145350625000000000" + }, + "116a7d140f4b7f9b4689063a8417ac07a32bae00": { + "balance": "106088220142108000000000" + }, + "116dc38ddb4b138b19ce6a51e5922c287da5c86b": { + "balance": "100000000000000000000" + }, + "1175f84f835a5ae40d49b8ca17e3e474c1eceef7": { + "balance": "1698584794716000000000" + }, + "119f822a796fee9c41a488949fcb14b589ffa628": { + "balance": "20000000000000000000000" + }, + "11a99f6019b6a53f5dc8cbd0c34f1ee75ced33b8": { + "balance": "102126982156000000000" + }, + "11b9324406068e8bf598d3a9ea59ef31c52f51fa": { + "balance": "6525925895203000000000" + }, + "11cb7be6869a10f5f9e8a47c6c92f729b083084b": { + "balance": "182959434323344000000000" + }, + "11d96a76166ec579e2b6cfa903f66da4af669351": { + "balance": "1000000000000000000000000" + }, + "11fcee55f78278df60f50096d45da1aafe72722d": { + "balance": "222859488179000000000" + }, + "120a1fc914718acd85bf92d9492330165d78075a": { + "balance": "3736627235906000000000" + }, + "12366136d83c77befdc30e04d4f5d808419f504f": { + "balance": "88008649003000000000" + }, + "12435af3f2f92ec43e8f2894be9c72fa932880fe": { + "balance": "1590548436852000000000" + }, + "124ff67125a00aed24e58b6d64ffa887a59b48a4": { + "balance": "20613022349070000000000" + }, + "1296f04910ebc89556ec7ab1b178fdbf14d0295c": { + "balance": "36000000000000000000" + }, + "1299f180e42bfaa1162d36110d29ab062e43e1c8": { + "balance": "321570118362000000000" + }, + "12abac62150c526866ec958cd0e3721b2c78d550": { + "balance": "51898545633262000000000" + }, + "12b345087cee385b9adccaaaa6741b767c82d7ea": { + "balance": "36000000000000000000" + }, + "12cd5e8c0c93f8e34b589b95954b719f54d1515b": { + "balance": "1000000000000000000" + }, + "12d262cdd25edc39b6fd9ae78184eb548e513927": { + "balance": "500976168000000000" + }, + "12d933448218629702c48547b3446b629ec65883": { + "balance": "2168010577395000000000" + }, + "13054aa42d3e119220ac359641c15f8b54bfffef": { + "balance": "24986834005530000000000" + }, + "130bda09f463a982199849ae617062a1d68f3a85": { + "balance": "154504844790000000000" + }, + "131a5da679863c05dc627d53634f2925ba0ce731": { + "balance": "10000000000000000000000" + }, + "1334f2752b5c21f681ba9e23a9fe95a85f8e05f1": { + "balance": "121000000000000000000" + }, + "13634512e2ae79fe3febb9e55e03b47bc350d7ba": { + "balance": "338331304738000000000" + }, + "136fae842aab625768bef9079ee1711e8c007d8f": { + "balance": "2759741687626000000000" + }, + "139fa969e8b74bee1f6113a362f15060ea998b15": { + "balance": "10000000000000000000000" + }, + "13c7e1d694bde6f8f6a31eb6c99f38dc739d61fe": { + "balance": "10901074773586000000000" + }, + "13c849944ad6ad12a46c46973d562bee8284f46d": { + "balance": "35114615504000000000" + }, + "13ec3aa8f4a427ecdecc7901060ccac9bea7a61e": { + "balance": "10000000000000000000000" + }, + "13f478c74acfd6897d13e602a8d362893f4fd038": { + "balance": "3521111850000000000" + }, + "14403970d0784a6458a7bf2584a53d14234e8860": { + "balance": "25000000000000000000" + }, + "14440bb7410337e34a064a92206075575f5362ee": { + "balance": "14918844868393000000000" + }, + "144a88e7a8af70b8bef5c4b70ee0cff771d0c252": { + "balance": "67961927542000000000" + }, + "146b79f474176a4b0069199b03669ab6467a4787": { + "balance": "122518123211000000000" + }, + "148893e7811c36c6bd1ada367681ab8327b3b2fa": { + "balance": "1313118418375000000000" + }, + "14900a17784e3b4d89d98b6cb31c74c685418b89": { + "balance": "131112181597000000000" + }, + "149a483758a98ffe28f7f25cfa17d7433f852ebe": { + "balance": "10000000000000000000000" + }, + "14a03c8e84f07c5596687a98d1e0b1859e9b34ac": { + "balance": "55000000000000000000000000" + }, + "14c7899cb34b5447d6363d4e8355113ebf4bcc66": { + "balance": "197554844582000000000" + }, + "14efa63ee285277c0f8e0d5cc22193e17984e11b": { + "balance": "106221254735000000000" + }, + "151c6099b3fb5b18e0e36a3335dff186dcd2904d": { + "balance": "4304311254087000000000" + }, + "1525dce233a971eb1387f130fdf0e5bf3455723b": { + "balance": "45004174531000000000" + }, + "15271904676f2bc2511294e500152d05ea9acc85": { + "balance": "9300898622566000000000" + }, + "1556ba42ea69d72c1d0faf802906645268e36aac": { + "balance": "171939212653000000000" + }, + "156558fb71ff986953d899c9916a121fd047675c": { + "balance": "290926338537000000000" + }, + "156fbf32614aac2cf462952ec1a3f141f797316e": { + "balance": "6084388860000000000" + }, + "15b9497d6bde8017baf3c29e12430e05a47efbf4": { + "balance": "206126229839000000000" + }, + "15d532e828bdcaf1246696d679a2eb66a154db5d": { + "balance": "69656571015000000000" + }, + "15e26a60cfaf23dfd9bbb999a30904d11b6ddd05": { + "balance": "9839303178835000000000" + }, + "15f3be2f11ee3b19472cc3d171931f050d8629a2": { + "balance": "13572825921000000000" + }, + "16254bed335420e5f793de2295b0081ac41a08d1": { + "balance": "144000000000000000000" + }, + "163aa91bc2ad588116141d48fcbd943985455cac": { + "balance": "618250979557000000000" + }, + "164cff4b9341d536b8aaf2d1dd0e3ed35ecb1db7": { + "balance": "671554639913000000000" + }, + "164d2a9a63868ac25bfe26ecba446d7ce256c351": { + "balance": "7233638188261000000000" + }, + "164e759b64d3ee0a23ec3030f50a1b454a6ec15b": { + "balance": "12281161499000000000" + }, + "165d4a0f23c016b8064adf0dcf7e31bc06350777": { + "balance": "256757922324741000000000" + }, + "166b862954dacddc3333aba4edbe523d693df858": { + "balance": "123677971414000000000" + }, + "16858eb1a6f0e7ff01b91aa9c92d0a433a5f767c": { + "balance": "500000000000000000000000" + }, + "168909a1c2a43cff1fe4faeac32a609c25fbd1e8": { + "balance": "62258808044224000000000" + }, + "16987ad8e10dda7f9e5d95c0f0ee36f46b10e168": { + "balance": "10000000000000000000000" + }, + "16b5dffce79573300a6514ace5f2e844d26fc64e": { + "balance": "5576805697087000000000" + }, + "16e01370a93befe24f6ae6076cd04c84cd3515b1": { + "balance": "1922179181578000000000" + }, + "16fbafd4fc871c7589e63062133793ab244c2019": { + "balance": "2865030627000000000" + }, + "16fdf76180796c6e4335eaa2842775b2e4a22e0b": { + "balance": "20000000000000000000000" + }, + "17081d4d6ebb9f4b163e181a59c2102c99fce6bd": { + "balance": "490625378000000000000" + }, + "17218ff455aa87b29ad4c4f7ba21e9c6f74fc97a": { + "balance": "1607392037652000000000" + }, + "1725bce47f3700f4646efb343f950e2e8ba66607": { + "balance": "58472967071000000000" + }, + "172c5f71aabf072507664471ebaa435779d74a32": { + "balance": "16000000000000000000" + }, + "173a065f351ee0513cfebfe9b950fd2c641fc8cc": { + "balance": "25000000000000000000" + }, + "174e1793c96cefb584ae0a67fff85c65065dafc5": { + "balance": "50221000010000000000" + }, + "1794bc4d622d514f95da5404358ed404b3f59aa3": { + "balance": "36000000000000000000" + }, + "179839d61e7c7a0382fe08e0573bcfbe42a108ca": { + "balance": "203299791419000000000" + }, + "179eb30b5b28a961eac70a919d26ca96e6472166": { + "balance": "55000000000000000000000000" + }, + "17be72168606fb5d27761157e48fc14789f84634": { + "balance": "311205588354000000000" + }, + "17cefb6611033759b8755197b983de2d7e98315e": { + "balance": "10000000000000000000000" + }, + "17e07cc7d89bcd1708b1f05ab6e1252c629d71cc": { + "balance": "903234908997000000000" + }, + "1811be559b657685c2f163122479101c404325b0": { + "balance": "10060694170000000000" + }, + "181417a4883c429ef26a4baeb48e70d4f00278b4": { + "balance": "4621446218088000000000" + }, + "181d345cd6b5f518bdab8d40f5d4896a725b3f3d": { + "balance": "114349561983000000000" + }, + "184625e544aa31552d2911023a892f739df84be7": { + "balance": "5303698708000000000" + }, + "185e4f6eee203ca3c089baa1e643ff1aab7cc8f4": { + "balance": "33969718257699000000000" + }, + "188e4a1a7b23ff35ec90b7bf7561db9e3c0f53bb": { + "balance": "394325508701000000000" + }, + "18a4dbf513be132f9ecfd69e3eb683d710e28c4b": { + "balance": "5997985132329000000000" + }, + "18c9298f62635ef47d0ef215b8a693af60829c27": { + "balance": "100000000000000000000" + }, + "18e7e2ee0c86bc1ba3595fee3d40257776fe8172": { + "balance": "185584626033000000000" + }, + "196575e74499b741877793f8c8facf2f3b1ddb8f": { + "balance": "30318381929000000000" + }, + "196df33f2d3ed473e6e07650419969f4a39fd03b": { + "balance": "15442864665000000000" + }, + "1975c5293ec9c72a28e6cc74173cdfd8de682fea": { + "balance": "103624886552134000000000" + }, + "19832cd1b2fc4138c8d9291a0f404d3c4326b48f": { + "balance": "4732362673000000000" + }, + "198705f46f31c7ca22f5b88fab210bc5b0c7647c": { + "balance": "548940869737000000000" + }, + "19a5a213e6abfee29f17e871222cbe9ac45322c8": { + "balance": "10000000000000000000000" + }, + "19ab9a7a4e9f9c08c9b4295c406b78389a864ba7": { + "balance": "369299839157000000000" + }, + "19f19f5f01b3f6a1c4f645dc7e3992b1196ccb7a": { + "balance": "97759406000000000000" + }, + "1a11a0b0081522e60e16f154e093ac2e005d24ee": { + "balance": "88024675252000000000" + }, + "1a27309b0c09be2234fd64afdbcfb099f8e2e7cd": { + "balance": "10000000000000000000000" + }, + "1a3d61754974bea23503a61ef0fe584b7b6e6cf3": { + "balance": "326950210355000000000" + }, + "1a49bbde1457a8d4c247606b206ac8d4d389da5a": { + "balance": "402438941516000000000" + }, + "1a7a4b41be64fff3a31eb6166db59741e073d0f7": { + "balance": "250000000000000000000" + }, + "1a8d282e82c606e992f69ce618ba634d98bf2683": { + "balance": "20000000000000000000000" + }, + "1aa0ba27662816e5e3d79e223cc18f5dfef089cf": { + "balance": "187581622694000000000" + }, + "1acab416a1d3e8caa65faca378c79aaf2065b851": { + "balance": "1000000000000000000" + }, + "1acd37af3f87da1dff743dfcb97038d178b1dc4f": { + "balance": "708034481300000000000" + }, + "1ad8f036022c3e5258455d6aa05fb4be5dd121b1": { + "balance": "42957064709000000000" + }, + "1aee811e06c579c21fbcc3b53d2dcf9d5f24808e": { + "balance": "52480060284048000000000" + }, + "1b03b7a4e9908c3531618f49f8d050ba6afb4de6": { + "balance": "28410489187000000000" + }, + "1b073d026e93de51db34d5a8e19047784c277ea1": { + "balance": "20579129628026000000000" + }, + "1b0b87e414bc8fe4920fe104b6de7d17db3a1a19": { + "balance": "10720000000000000000" + }, + "1b411c692c80948e59cd805a0f8574dd67519288": { + "balance": "5416615538000000000" + }, + "1b8d57e995749618c7bb3e60194ac6fc57e9b3eb": { + "balance": "10000000000000000000000" + }, + "1b913efde1255516346b40ae2a48ebf62251682d": { + "balance": "100000000000000000000" + }, + "1ba7276c133f93d43db2f2caddec08e0167eaf15": { + "balance": "82559173174000000000" + }, + "1ba919f7742160cabf2756eb6eae67b92530f3f3": { + "balance": "1102304139883000000000" + }, + "1bb20857de494694fe15bd11f8cac1218435fbc0": { + "balance": "10221322567000000000" + }, + "1bb5c5e81d451f03e899852edc8556a9f7aac5df": { + "balance": "18781017696028000000000" + }, + "1be3507349ed07d3e7902951d490f560a75e96be": { + "balance": "660691718918000000000" + }, + "1bf1c0b2e6f64b612f35f2bf98d894b13dda9bf7": { + "balance": "3050161851140000000000" + }, + "1bfd3c2ba6a537e97cedd542cd554a5050963d54": { + "balance": "20000000000000000000000" + }, + "1c4af5003f9e7223f4141107d21640e4a85a4827": { + "balance": "612390629874000000000" + }, + "1c6a94810bd0afcf79ceea11afe86c34f6813211": { + "balance": "10000000000000000000000" + }, + "1c7e277460191c886cb1647173d27122c2146252": { + "balance": "209062806527000000000" + }, + "1c818ffa9caa61d512fa5d7d6e566f3ae37d5434": { + "balance": "454897845316000000000" + }, + "1c9599d5f8e5eaf8f68d35d52132e15a153f6d3c": { + "balance": "36000000000000000000" + }, + "1c95ab5229fd08c638a1728c022f09291b8dc55d": { + "balance": "20000000000000000000000" + }, + "1c962808c175ee5e5e365483d066c8ea95993700": { + "balance": "1362779746855000000000" + }, + "1cafad295b2188f10192c8a32440931f7e3554e4": { + "balance": "36000000000000000000" + }, + "1cdc2899ec563d79569d1ba776bc03cff331e786": { + "balance": "572163587827000000000" + }, + "1ce0042e7b4f13589f5f8490836dc63e0ca60c3c": { + "balance": "25000000000000000000" + }, + "1ce62051fd7801d294bf31a7b44cd87510e8b545": { + "balance": "2008112411284000000000" + }, + "1cf20f30cd901b2e5fef3f948289dafaaabaa77d": { + "balance": "1444000000000000000000" + }, + "1d449764d38b7a4ac848f49e2dc99df02dfd8a53": { + "balance": "48215693645000000000" + }, + "1d635125c494b1137ca5f15ac95dd6d93c3a9546": { + "balance": "10000000000000000000000" + }, + "1d85a61353c3e0b6d34e105e35c8c7833b6a1e35": { + "balance": "16000000000000000000" + }, + "1d969134ee156c41c98c3721c5dbb092c0b581a6": { + "balance": "64000000000000000000" + }, + "1da12434596a9c318dab854f06d404fe61f0a69d": { + "balance": "16675185416000000000" + }, + "1db0d23fb63681958a66e716e99df3e0b848fd12": { + "balance": "1103581911968000000000" + }, + "1dc628820da657f07ab5eb887d5f512378b5b61f": { + "balance": "6272287019755000000000" + }, + "1e05cba75b0dd379037940352e0073564957b7d9": { + "balance": "12453446342664000000000" + }, + "1e13f037a92ab6f19c4484ae3301b3ac6f48575d": { + "balance": "106244918916000000000" + }, + "1e167bc07f094915c00e7aa4c43b607ed2c998b9": { + "balance": "1000000000000000000" + }, + "1e1f9409bf92c3ef59aa2fd82dce55cd90e23f19": { + "balance": "99139000000000000" + }, + "1e4dfea7871d941e72a161022b62fdb01818c86d": { + "balance": "81000000000000000000" + }, + "1e5d0b525228167334e94314a201388bba08153b": { + "balance": "1138044078759000000000" + }, + "1e6633290c9898abf5fcac54396de770164edc5a": { + "balance": "25052055674000000000" + }, + "1e76296584058670ea80fe9a39d8f457c03747c5": { + "balance": "10000000000000000000000" + }, + "1e88b2c8dcd289929e51a15c636d0b0f3b035569": { + "balance": "87357600832000000000" + }, + "1eb59a1732a159a91a9371650943840e0eb61174": { + "balance": "20542821429000000000" + }, + "1ee077bdef6d45d491602342cee008cd1e2912e3": { + "balance": "10000000000000000000000" + }, + "1f1ebf2f80afced68424cb7b0b966fdf42d508a4": { + "balance": "1460082126494000000000" + }, + "1f3d4a903bd32a537efae19592f5516698c95a20": { + "balance": "10000000000000000000000" + }, + "1f6431696efc6f1ab98dcc2ef0e8553da697e6f1": { + "balance": "20000000000000000000000" + }, + "1f657552b745acbdf731f2ad107d6362480abc88": { + "balance": "162042599568000000000" + }, + "1f699a7682c1266291a3f49e19cac0846470abf5": { + "balance": "712268213248000000000" + }, + "1f7a332dabb00851705274c59187817d859cb9a4": { + "balance": "199999999160000000000000" + }, + "1f7c333047e168f5d3408c42a4919bd44b8f7961": { + "balance": "3918096658000000000" + }, + "1f8226f7a4525b9f3cd4da3acc1bb34529f8d28a": { + "balance": "3530829464000000000" + }, + "1f8b6fcea9e0991ad0b0b25dc65748518a28713f": { + "balance": "142069368416000000000" + }, + "1fa3de6913e4de78cc4828e246554785950c3c8e": { + "balance": "178437291360000000000" + }, + "1faa75d57fd597d2b58d2ac6f65bc2bd5946911f": { + "balance": "13092024644362000000000" + }, + "1faf1721dba3266cde1e04a7e9c789bdabdd930d": { + "balance": "862698523071976000000000" + }, + "1fb861559361701fca1df6ab4ef4d2fb9d2d7e13": { + "balance": "100000000000000000000" + }, + "20154d678cdde9ca1c0acb94726f26617a4da0d8": { + "balance": "2288800561677000000000" + }, + "202484a46ca9d54d0d456bc38e2a74ec5f469349": { + "balance": "50178714107336000000000" + }, + "20324278018b4d8e0c49e0fd1be35d3494079165": { + "balance": "484082383314000000000" + }, + "2033ef68ef6297e9229bb73e6486330543aa3eb7": { + "balance": "51260669473000000000" + }, + "20b1e0ab7b9d62a314946b55a5775f24ae3cfa00": { + "balance": "1540424185584000000000" + }, + "20b61f2eb5e18b1e8568d18235918f9e2f596c32": { + "balance": "10000000000000000000000" + }, + "20ed8ca39dd148edf22e03b8021af32cecadd42a": { + "balance": "20000000000000000000000" + }, + "20fd5feb799fbb021ba262d28332b4dda8f44a2c": { + "balance": "7607475714434000000000" + }, + "215ab8aad1c8960838225294d086f0786c2dd796": { + "balance": "19929201327000000000" + }, + "21681cda53aa1a4cfb3e3ea645c8eeaecfc3ba4f": { + "balance": "10000000000000000000000" + }, + "217b75eaf2c0be12108120ba56ddb709e1885324": { + "balance": "36000000000000000000" + }, + "21be1d75b93e96017f088f1ca64ba7076c8edf07": { + "balance": "150798073752000000000" + }, + "21ccdbe0216b486cb39c94ed13767aa061c75ce9": { + "balance": "11070639373000000000" + }, + "21f2289f2d274bddd7928622fffdf3850d42d383": { + "balance": "268859368544000000000" + }, + "21f54f92a7d9a91915e1751ceb02cb8e3ed3d622": { + "balance": "10000000000000000000000" + }, + "2202c70ec23f4605394d69944edd9f90e488eb61": { + "balance": "9000000000000000000" + }, + "220e2253e1ab9ec348cc28d38bae4cb2d5d9cf8f": { + "balance": "116100821631000000000" + }, + "22328e434957107884854999e666ad0710187e3b": { + "balance": "233364805270000000000" + }, + "22851c0487d119ee3f150010515358d6ff14807a": { + "balance": "104464221701684000000000" + }, + "22a38000f5eca29001e387b52c18fb6030683fac": { + "balance": "55000000000000000000000000" + }, + "22b655a19810307750ed1b6b093da10a863d4fe2": { + "balance": "11840799203605000000000" + }, + "22cc48cf48e8ee207bc08411240f913a4e594529": { + "balance": "10000000000000000000000" + }, + "22d6ea6cb8a9206285ccddd3b6d0d1471ba66f17": { + "balance": "64000000000000000000" + }, + "22e2f41b31a0c69472a1a02d419886539b7b6197": { + "balance": "39885451304000000000" + }, + "22e962f91d01480d027ee0060030f529a7a64c8f": { + "balance": "93285203531000000000" + }, + "22f169328fb1104b386ad7fa69f0c7bf3e9a7d3b": { + "balance": "63366769386000000000" + }, + "22f35f5e0e7a8405714de66a5875c7ef84ec4891": { + "balance": "60944382032000000000" + }, + "23041bdc8d371dc29ffc890f19317dabeef12634": { + "balance": "402327389857000000000" + }, + "230eff5e8595f418686737ae671f1f1d225080a5": { + "balance": "114574598112000000000" + }, + "2331e1756d9800800fc9b54ee6e43e1150b6e58b": { + "balance": "44594796226000000000" + }, + "233a72b132e4ab1d3884274d4402d1a2a6399f0b": { + "balance": "1372148909093000000000" + }, + "2369d9dbbfd0f8aa8a3d84d8f2aea840a0cdf760": { + "balance": "500000000000000000000000" + }, + "23754e5cef31ab60aa97a0c8f9ccb4f2969f2d6c": { + "balance": "24764775861000000000" + }, + "2387973589fb07a8c1ec92492c0b8ba9ab5e52a2": { + "balance": "11642113696681000000000" + }, + "23950cd6f23912758ebe9d412166e27994fe6ec2": { + "balance": "100000000000000000000" + }, + "23b383e11573f3ca9be84e1e11694f58a432324b": { + "balance": "206558238838000000000" + }, + "23c329bb641fa51122ea476e3bc614f5d4f9cf00": { + "balance": "35908627324000000000" + }, + "23cb9f997c39853486adfc1a8b029874d1a6af15": { + "balance": "1400984459856000000000" + }, + "23ee14215c531f6ff1baef2c74b1754306f4532d": { + "balance": "10000000000000000000000" + }, + "23f641f765cf15665b6c28d77229d3b2a58fd857": { + "balance": "266570948120000000000" + }, + "23febb49d9541360b9d099377df16b5630dfbb52": { + "balance": "228513797641000000000" + }, + "24082040652a09cbed6504f3dd6491e0ee9d2bff": { + "balance": "91160839809000000000" + }, + "240d3edf4aaf42e99d366ca36d82c370271b8e8d": { + "balance": "65535355843947000000000" + }, + "242b63ebf47678f17c176d5d4a670e46e66a823c": { + "balance": "469668185647000000000" + }, + "2433612fb939236a87a97261ff7b3bc7b754afb1": { + "balance": "20000000000000000000000" + }, + "246bb03a3fab572b3c64fc23b03dfda42b7ea34c": { + "balance": "936364046000000000" + }, + "246c510dfaf5b49bc0fe01c8256d3879c1b5f89a": { + "balance": "100000000000000000000000" + }, + "24bf4d255bd3db4e33bff1effd73b5aa61ae1ac2": { + "balance": "302436106595000000000" + }, + "24c0378e1a02113c6f0c9f0f2f68167051735111": { + "balance": "36000000000000000000" + }, + "24cf04b7450a0fac4283fa6fcfef6215274b273e": { + "balance": "83714002622000000000" + }, + "24f5f8e7d6a23b55c95fcdc1300de05f9d2abd83": { + "balance": "20000000000000000000000" + }, + "25204bfb27a08dbdee826ad6d9c3398ec6d14fe1": { + "balance": "5929256591480000000000" + }, + "253d95911b4174805d13706b449879413b1672be": { + "balance": "37012901440000000000" + }, + "256065f7e919c508b68957b1d2c9120d29181e12": { + "balance": "25000000000000000000" + }, + "25624542c14c2ecb9a0fe7daec9ac5af16868ee7": { + "balance": "16000000000000000000" + }, + "256d05b6de445179e504a6c94ce1253ae159e19a": { + "balance": "12048598744001000000000" + }, + "256d37fc8980a969063b1f7e7fda8b87d4210da6": { + "balance": "107293553721000000000" + }, + "2588af91a0e8f3ba3ab636781bb84e263acd1f52": { + "balance": "8910000000000000000" + }, + "259774584d4fcae1d84f5997c00beee8a380e46c": { + "balance": "1140713354605000000000" + }, + "25bda1418853a22eb6a5380e8a2862d2a74949bc": { + "balance": "10000000000000000000000" + }, + "25cafdab7f79f7b95d55b4c2dda1f4080aa74d64": { + "balance": "2525573681000000000" + }, + "25cca69b41bb51c51b387c47ece83f30b9a78daa": { + "balance": "163449631440000000000" + }, + "25ce9dabd0a72b02e0056931155ba99c94cbc837": { + "balance": "230073284349000000000" + }, + "25d9d1785c96acddd926b3ed52987ff74f9083f6": { + "balance": "780460361789000000000" + }, + "25e56bd3e1461f27db4eb0cce8bb5ca1574401f8": { + "balance": "1001937531200000000000" + }, + "25fa2162d5c86cda10e4be42c14a24329e455ad8": { + "balance": "50000000000000000000000" + }, + "260a932a23b344056acb8e676714ffac0a13ad2b": { + "balance": "2000000000000000" + }, + "2622efe8836095fcf48d9c8019f48c8320d6e0f2": { + "balance": "5451866545636000000000" + }, + "262447c4d8826ed23ea25e9703a11b4ad3ae9388": { + "balance": "33992454005000000000" + }, + "263eee3badb9b0dd13579c09361806503705a1de": { + "balance": "1134831344000000000" + }, + "266f4c232ebc946c46979cd90d70868380e186d8": { + "balance": "20000000000000000000000" + }, + "267dfe6fa918686942f5e1d19d5fa615f6f2086d": { + "balance": "3569373363935000000000" + }, + "268ad2272c2b71243a7391020a600fd8dfa42d45": { + "balance": "122768017414906000000000" + }, + "269e4f43be9865f05a277933c2fbb466659ada7f": { + "balance": "22064992930948000000000" + }, + "26ae161c20acb26a320fbfbd60c97335cda28bca": { + "balance": "170710653621000000000" + }, + "26b4da905780fb0c5c3e7e5315989fed3aeef135": { + "balance": "20000000000000000000000" + }, + "2704312aa5a4202f14fa3b08e587e4f0ef13accf": { + "balance": "124259630994000000000" + }, + "2704e4b0e8df0c1f298843109ae3bb26c29a22c4": { + "balance": "3155521256785000000000" + }, + "2709347d12251c01aac6455108c6bebe72f0af2d": { + "balance": "220898650215000000000" + }, + "270a32b41dde877463d2106ea4f4529557a5e1d3": { + "balance": "10000000000000000000000" + }, + "2738b3746d6bda9bd72858eaa76f8b5ce7a88c8c": { + "balance": "10000000000000000000000" + }, + "27593d2271aced83e81034e8dd603d098238320c": { + "balance": "20000000000000000000000" + }, + "2771ba4b5944bb12d74b1888255c60e0db215fd2": { + "balance": "412946979808000000000" + }, + "27780086136ea3e97d264584d819dcb2176d7544": { + "balance": "292224348060000000000" + }, + "278936fff8afb553043f038c39fe93906bdb1f4f": { + "balance": "1448466441752000000000" + }, + "27aa0d45d3506f8446816e0e2e9675d46285f6e0": { + "balance": "20000000000000000000000" + }, + "27e655dcc5728b97b3b03fb2796c561090dced1a": { + "balance": "9841344000000000" + }, + "27eb0529279f7a71e50efb70bb1767cbe1ffa4ce": { + "balance": "10000000000000000000000" + }, + "27f564956c837d7949739f419d6ac99deb33d790": { + "balance": "1505247707018000000000" + }, + "280f5618a23c41ac8c60d8bef585aa1cc628a67d": { + "balance": "1316618646306000000000" + }, + "28167a591d66ae52ab22a990954a46e1555c8098": { + "balance": "1000000000000000000000000" + }, + "28257eeb8d20f2fe5f73b0ff2eca3214e30ece4f": { + "balance": "95924728584000000000" + }, + "2827abfc49828db0370b0e3f79de448d46af534e": { + "balance": "769862008499000000000" + }, + "2832b92434e3c922206c2408442bc8274606cbd9": { + "balance": "103421320914027000000000" + }, + "2854f190a38e9b9c04cf499259c6577a68b0b5ed": { + "balance": "144000000000000000000" + }, + "288923bd91be164496e5378ee484f0e4c6c16ed6": { + "balance": "10137243270703000000000" + }, + "2897ff80794153edb721801fb91c6d8373c965f4": { + "balance": "10000000000000000000000" + }, + "28aa06e2290010374097aa2f87a67556d8d68083": { + "balance": "84783245638916000000000" + }, + "28b04ec8eb18b0c6a384f9d92cfb44d1d43ecb51": { + "balance": "14364248730194000000000" + }, + "28db0c000cad3a524bb68dfdd74ffd47b42fb13a": { + "balance": "43586590410000000000" + }, + "28ecd4c5fe98cff66a5b8423f4a27cba9634e2d0": { + "balance": "56106658052000000000" + }, + "2930822031420731f09dce572554a8b8c1eaa09b": { + "balance": "1170839742000000000" + }, + "295154c4522d7bcb2e24b7de9c543dcd1c5f51d9": { + "balance": "179028680906000000000" + }, + "296be4ef7402b00d7af673c1770a50162d7ab602": { + "balance": "8206640005889000000000" + }, + "297b84150756fa89101dd59750a7beb36fb8785c": { + "balance": "1168894124400000000000" + }, + "297cfb72cd1b8b2808fd1b25cdcf7d8de279ad96": { + "balance": "500000000000000000000000" + }, + "29cec0eca9f8508a1ba192a90bb6dee18c40745a": { + "balance": "260217025084000000000" + }, + "29d8f7e72bfa297f17fdce9cf8f4a398f547e200": { + "balance": "307787433251000000000" + }, + "29e14b01c59ba894dd090382fb193ea441164b90": { + "balance": "229028661439000000000" + }, + "29ed634e165084b720e446d28893dbeecd6a7018": { + "balance": "226530464200000000000" + }, + "2a0f8136d43248233f652fe579ef3bd2281dde24": { + "balance": "4007544428000000000" + }, + "2a10204a0c7c9f7701e33c1b71c9427ea16e2e45": { + "balance": "50000000000000000000000" + }, + "2a319ee7a9dbe5b832beae324290f7df6d66f516": { + "balance": "28127560161000000000" + }, + "2a50bfda2b06a9fb28c73f14aaff4f7ef865db65": { + "balance": "10483823413828000000000" + }, + "2a7b7feb145c331cb385b9fcb9555859c16820f6": { + "balance": "1017182951264000000000" + }, + "2ae076c36b18a60f1e3c05d434276a1e16f3f838": { + "balance": "10000000000000000000000" + }, + "2ae2e51ea2ee6a848acde342db2bf6eac927e5af": { + "balance": "494279795271000000000" + }, + "2afd69fac54c167e7ca9d8198a8de386f3acee50": { + "balance": "227162683047000000000" + }, + "2b08018d6e65a7b74ddb5ce1af99976a484b9f50": { + "balance": "16000000000000000000" + }, + "2b0c1d629ad2958ab91e31f351a91219fdbca39e": { + "balance": "113239399820000000000" + }, + "2b2bb67fe9e44165d2108676579a9437c760da30": { + "balance": "20000000000000000000000" + }, + "2b2c99e88e938d1f1416a408a7d0041a605bce16": { + "balance": "6118539729000000000" + }, + "2b5c97b6402ac189e14bbca3e7759319ca8a9222": { + "balance": "10000000000000000000000" + }, + "2b813339c7f818f578b45f17c41c7e931c7828e2": { + "balance": "842834712955000000000" + }, + "2ba6fc21f743968d51f80113aadfc0fdfe8499ed": { + "balance": "309973507270000000000" + }, + "2bb75b272b279cb54498f12b6805261af643c8b1": { + "balance": "1426727673809000000000" + }, + "2bdac062364abd9cf67ba7de214a2cceb0511033": { + "balance": "1090525272063000000000" + }, + "2bea658caa805241aa921f48c8f10cb49e16ffae": { + "balance": "1295499213027000000000" + }, + "2befe7e34299a7c1ad53fc9988ce77e2d9fab20b": { + "balance": "4326342236300000000000" + }, + "2bf466a83cd44aaf0f627606a1c954fd31deb782": { + "balance": "1388986370166000000000" + }, + "2c016a23890e9633fc17b0a8d328ec1ec7ee0113": { + "balance": "92483174342000000000" + }, + "2c45a87a63cc5c8c102d12b83bd9a3501ee41995": { + "balance": "394657687589000000000" + }, + "2c600a596368405e584f3b869f7fabef4ce54aa4": { + "balance": "9879984853585000000000" + }, + "2c7032da8b7816e16095735aee43d1c3f1c43acb": { + "balance": "10000000000000000000" + }, + "2c7275511fe06ee86663b3a618497168b35b0cdf": { + "balance": "10000000000000000000000" + }, + "2ca4074843e9519265447c0dd9ac84ddc2033c1a": { + "balance": "179612279567000000000" + }, + "2cac03ba2c45a6c8186bdceb095b7c5feced3114": { + "balance": "2022060470376000000000" + }, + "2cb8c2cd506b2d7b4cac88ce63230022d412c62d": { + "balance": "211378154058000000000" + }, + "2cd27561cf37ec229982dd592c71d1aab9c2d7d8": { + "balance": "42189968284000000000" + }, + "2cd2e85310a4fbb7f296c3d0d1cee07b191239eb": { + "balance": "1940327317417000000000" + }, + "2ceca4501c5f2194518b411def28985e84d42913": { + "balance": "25000000000000000000" + }, + "2cf7abd42394634689aa2a36d263a6345116b7df": { + "balance": "3553167226295000000000" + }, + "2cf88f29356c166df8383d3312cea10397e25150": { + "balance": "76961677759000000000" + }, + "2d0b62fe49592752cfebaa19003a60b8b39b1cb9": { + "balance": "10277397502735000000000" + }, + "2d2051887107bbd8ed45b405b9be6974a13172d9": { + "balance": "1928781992000000000" + }, + "2d2c9525e2811f4d1016c042f476faf23274aa31": { + "balance": "1000000000000000000000000" + }, + "2d2ef9e1c7a6b66d9a2994adb3ac4a9921408e69": { + "balance": "10000000000000000000" + }, + "2d3bcd18e5c97ddbf1cd28ab37eabe070e9a04d1": { + "balance": "323879852538000000000" + }, + "2d3e60496d0092a4efc665389a916be1a9f8b378": { + "balance": "161958437779000000000" + }, + "2d3fb0ae9b17d3a57d23549ae5500fbb163de25d": { + "balance": "25000000000000000000" + }, + "2d8106dbee6f728c0ff11887690a6370a7d9f5a5": { + "balance": "3102418708000000000" + }, + "2da48eeb788686811ac8270ef3baf0159fc47446": { + "balance": "252187695395000000000" + }, + "2da9d2a6f0b92651a36b05c5e9d2a717c6e166de": { + "balance": "500000000000000000000000" + }, + "2dad81b23d8447190259119019c04a4ef61ab91f": { + "balance": "53428719965000000000" + }, + "2db1faf35901e272aee74a2469a278fdaa6e6e18": { + "balance": "100000000000000000000000" + }, + "2dbae8e1ad37384ca5ff0b4470d3dbc73559841c": { + "balance": "10000000000000000000000" + }, + "2ddf9e23945c181b8592d7965e782068b4c38b37": { + "balance": "100000000000000000" + }, + "2def05d1f2abbaa193a219b87e5319c7ecd48dea": { + "balance": "51359946957000000000" + }, + "2dfd221f96a21e41ffe4dca67b15cd352fe9637e": { + "balance": "36000000000000000000" + }, + "2e1371fcfea9d8dc8e692897a91753400caa9c3a": { + "balance": "5199902650733000000000" + }, + "2e2e04945adbfaeec698ea0f5275f1ad5ffd3d5b": { + "balance": "42034514567000000000" + }, + "2e41f865cfbcf8b89f848405e04de9114087f4ff": { + "balance": "44875730962000000000" + }, + "2e530254768ce94db0ef1204ede0e12b3558e7eb": { + "balance": "14319506377747000000000" + }, + "2e5c43868f45de268967fb22f3f4107da401510d": { + "balance": "20000000000000000000000" + }, + "2e5d2e117d2ba9af9697ec023a4d10b5a2436902": { + "balance": "16000000000000000000" + }, + "2e6000778fb225ddb3e1a2f297d56774e85d9c9d": { + "balance": "10000000000000000000000" + }, + "2eb64b8ab13f0d7823158217d15ba310ed3d0e58": { + "balance": "58724606000000000" + }, + "2ec3973ff33a06d355ad4e8f73b657af8a5ed8e9": { + "balance": "1165606294808000000000" + }, + "2ed4362ea5edf510e210af733089b294f87e8f67": { + "balance": "427561040806000000000" + }, + "2ed8788f1c31b508e37079098a7337bff77b49cc": { + "balance": "10000000000000000000000" + }, + "2edbbe1e2ea482920c76a4ff4c14602b4d37c955": { + "balance": "294409476945451000000000" + }, + "2edcba2bd76128750c8aa00f832c62db30aa7868": { + "balance": "25000000000000000000" + }, + "2ee5abcc0d0d51d4b18947b5aaaa95d037be4e2c": { + "balance": "20000000000000000000000" + }, + "2f058187ef141c06c7c87da86cc1953d2fcf70fa": { + "balance": "9000000000000000000" + }, + "2f16b101da9986a18f4b0d30a26557860338c4e0": { + "balance": "254907899725000000000" + }, + "2f4363df2c61273d230071286bb0157dfefee2cc": { + "balance": "64000000000000000000" + }, + "2f6099a8cb7bc3713b87dab20994d8dc09342003": { + "balance": "1902400000000000000000" + }, + "2f7b3902ce56f74adb0f83cc7d3a99df440cca1c": { + "balance": "825246221388000000000" + }, + "2f7d0298ff6a363375b7eecfe754fca0963c8a1b": { + "balance": "101000000000000000000" + }, + "2fb7c16232b3b1f2e3a676d6d5c93ae6fe5cb14e": { + "balance": "1000000000000000000" + }, + "2fbd5ccc716d2f510d10ec84def3fa69e49f46ca": { + "balance": "1000000000000000000" + }, + "2fd84376be11772e5d072cd74c96b0d9a49c27fb": { + "balance": "1000000000000000000" + }, + "2fdab070e20e2c8923a24c196bec72c33ff0f220": { + "balance": "64000000000000000000" + }, + "3003e6007f69902a0f5e4b4e6d0468277897fc70": { + "balance": "1501210602075000000000" + }, + "30095e6a4ccd1ac2014c3d1d98dce003d775708e": { + "balance": "500000000000000000000000" + }, + "300e47e0fa556371f6c882eb98423be44de7c239": { + "balance": "9108837665958000000000" + }, + "3011231224920b62bcfcbf0aed4fde35dd0a4bdb": { + "balance": "374689586073000000000" + }, + "304be24debce62e70943efddd20457d34e85ab40": { + "balance": "81000000000000000000" + }, + "30912555bb14023e9b7c90aa2314721918cdf1f9": { + "balance": "10000000000000000000000" + }, + "309a94ca7b44bc84a7909ee2b93ed1c94eaf75a1": { + "balance": "39000000000000" + }, + "30bcc93965fa36bbaabcd781326e42227c4e1a51": { + "balance": "10000000000000000000000" + }, + "30c71fed91d24bff69f286ff8f0c6c02a21736a8": { + "balance": "409782329653000000000" + }, + "30cbaf4103757013fd8fb71c44a985939e212b86": { + "balance": "7424807960947000000000" + }, + "30dd59e66093d0bfd87b09c5f6588b9857e9a6f7": { + "balance": "26123006239871345154" + }, + "30f692235f254b02f583d5b515f4701a35c7f692": { + "balance": "148184457997000000000" + }, + "310763019a24a927ce42b00604ee664ca53ff6d0": { + "balance": "393757908273000000000" + }, + "3118a5d4d06ca8b7c8835f4860e6973228000ee2": { + "balance": "56188713212579000000000" + }, + "311adec5bfcaed44680691cc644ee120a484aa05": { + "balance": "169000000000000000000" + }, + "3124e387aa7023995643344c782dac84b9d8c7d4": { + "balance": "1393596696367000000000" + }, + "31379702391cb5a737db3f3ffc336bd03aaa181f": { + "balance": "10000000000000000000000" + }, + "3145606c3ccbaf337610185ffac14ac4f0583c0b": { + "balance": "196454968572000000000" + }, + "315e11501d2c57a62af1631fc2662d4d8745401e": { + "balance": "225000000000000000000" + }, + "31a785ad3eea177c59fb575cad0b44f9a48a12e9": { + "balance": "38039017162416000000000" + }, + "31ae64035e95c1205bf957afb5e1636df00dea3d": { + "balance": "1718600907000000000" + }, + "31c0bb22fd2e9d22984f248a16ec3ed9ad834517": { + "balance": "5982762676000000000" + }, + "31e73a3b5451ebe1163571e9e0567c425bbbfb83": { + "balance": "10000000000000000000000" + }, + "322543c74039ef61fd051021b5e6f16b54bc7c1c": { + "balance": "101346282441000000000" + }, + "3233c7ed11c25bfc41d506c3ae0daf5a3c7c1278": { + "balance": "20000000000000000000" + }, + "325dae17b5225f6734a02c677d43fd126bea89b7": { + "balance": "365067246683000000000" + }, + "326ce8166a4094b93c15557f50f2b1d47811e72c": { + "balance": "16641460224765000000000" + }, + "32cf76046ae48b609524b1a6203eb6296d04853d": { + "balance": "1094839482061000000000" + }, + "33456a28f36aa240262cf95b78b4ac2cd8aa77f6": { + "balance": "3077123488326000000000" + }, + "3348bce2ef90ffd6a59ef5079e1af84b2dd604a7": { + "balance": "9000000000000000000" + }, + "334e5f0ae77dcd3d32dfc2c4ec6ab5e2826dc4b1": { + "balance": "3176777762079000000000" + }, + "335775e19200cd0305e529bc4cdf7295a47cb2d3": { + "balance": "2945631571804000000000" + }, + "336ba81ea6ec4f0da38c1a1761ed3d97fd3ca28c": { + "balance": "3587379203826000000000" + }, + "339191e03e9d5a08ae7b58f4c860235a0721b5a1": { + "balance": "2732237722000000000" + }, + "3399bf9f94c5488c89450257b39fdf3ec8c7f413": { + "balance": "477423805836000000000" + }, + "33cb8556a6c6c867e1be7de591cb22c1b7e9824e": { + "balance": "62293494164000000000" + }, + "33ed633804f39367078e830328dd223254be3366": { + "balance": "22842013797896000000000" + }, + "3409025dce86ad441a5a80f30ce03768d37e40bc": { + "balance": "1381667933000000000" + }, + "34153174cd4d3f1eaed7438638d302f6414d5965": { + "balance": "50000000000000000000000" + }, + "343c6b82b13f0dc82d4269e2c806d2d58e6dde35": { + "balance": "9546969736042000000000" + }, + "346089ea81f7dcb79caf2444df34bd6ee78be4bb": { + "balance": "4344080889000000000" + }, + "34984a8f96dbbfd1f977826a4c2187482559a2e4": { + "balance": "25000000000000000000" + }, + "34a5cce96d2211feb04472260c4cd368bda8432e": { + "balance": "1240050112677000000000" + }, + "34c026a39e44955d1051e8669f9cc58a027455c1": { + "balance": "20000000000000000000000" + }, + "34d730652f4aa002a9f39a47212ca3bc47506b8b": { + "balance": "418050617956000000000" + }, + "34e1d8c8a32ce0f6378abb9bd05ea1f9bfdc5782": { + "balance": "20000000000000000000000" + }, + "350b228870445141f4417ea5dba4f009d693b96c": { + "balance": "76995849736776000000000" + }, + "350eaec708d5d862831aa31be2c37b2fdcef97c6": { + "balance": "258753545822704000000000" + }, + "351fc1f25e88b4ccf090266ebb408593418d8fde": { + "balance": "10000000000000000000000" + }, + "3523ac7a6e79162bb8400bf161cb59389432aa51": { + "balance": "436606776923000000000" + }, + "354d490095e79a29bda2fa11823328450f14333b": { + "balance": "50000000000000000000" + }, + "355a555a36e319e76042e62875a15e1db3012b86": { + "balance": "20000000000000000000000" + }, + "3568840d0a26f39248ab088653ede831f150ce29": { + "balance": "16000000000000000000" + }, + "357096b9c1c7c8d51b682ed3c43d150f55629ff2": { + "balance": "900090781248000000000" + }, + "3588c47ba9204b672c456ee9b5c1ae70f3c738ac": { + "balance": "10000000000000000000000" + }, + "3591edeb9c036e871b4fc6fb3ae6d42e0c0d7203": { + "balance": "1000000000000000000" + }, + "359d92e3e8757a4a97187a96d408c0c11f5c7eb9": { + "balance": "22330509101591000000000" + }, + "35aac2a948f316ba93ed111ac127e29ee9a3adb0": { + "balance": "364387817746000000000" + }, + "35b20459a7daa5f44ae423fd4a1b451ea5090b09": { + "balance": "20000000000000000000000" + }, + "35cdaa84c1f3bc2673bc0c60222c133bae0d3db1": { + "balance": "15234182435000000000" + }, + "35d554233ca690130aaa43501e121a208c657226": { + "balance": "10000000000000000000000" + }, + "35ed399940ece44d01ac873b9c0d3212e659a97e": { + "balance": "55000000000000000000000000" + }, + "35f164612afc2d678bb770f317085ae68cce19bc": { + "balance": "693763596328000000000" + }, + "3601b36cb475101d0d0976a8de9d38e5f3483a08": { + "balance": "1000021000000000000" + }, + "361368bc42c8daf365bce9f9ff3b611373d7b690": { + "balance": "21658400518000000000" + }, + "361bc43be077a269e3e37c11e91479017c47f847": { + "balance": "268900383140000000000" + }, + "363c7a2203f6f93287de091bde3c87eb6800e7a7": { + "balance": "20874859005000000000" + }, + "365dc06856dc6ef35b75b1d4eabb00a7220f4fb5": { + "balance": "30000000000000000000" + }, + "3660e246bce68e2b6e4a802681f188587d2c1c99": { + "balance": "55000000000000000000000000" + }, + "366868ef8e193d7e649ee970d476e6774d5ff1ac": { + "balance": "2544456626840000000000" + }, + "366f7f762887cfb2d09cefa4a5108cf390bdeb41": { + "balance": "26837527714000000000" + }, + "36759f9c92a016b940424404de6548632c8721b1": { + "balance": "1033159825798000000000" + }, + "36a939be88508646709d36841110015bf7cedd90": { + "balance": "144000000000000000000" + }, + "36adca6635db6b00d28a250228532fe560127efb": { + "balance": "3370820618318000000000" + }, + "36bfaed8099ee9f216193ade26d21656c98ce4b5": { + "balance": "1353728563832000000000" + }, + "36df854d0123e271529a8767d1cded4e7b5f31d6": { + "balance": "10000000000000000000000" + }, + "36f59989a902cd10725ff7fe2cab1689aa4e9326": { + "balance": "20000000000000000000000" + }, + "370d6999ae70e781c81d12dc259ea304183b01eb": { + "balance": "45563989086590000000000" + }, + "370e8af59a64a3171b422913921a1e2f982dd512": { + "balance": "170263356254000000000" + }, + "372e01083072214134018f50bde3c8ac4f6e071d": { + "balance": "1400474252324000000000" + }, + "37410fda52f94185d824258ad5f3c9ad9a331257": { + "balance": "11830521097085000000000" + }, + "3752b7e1628275522cd693307787b9564501d959": { + "balance": "67839627078000000000" + }, + "3776f82701c384ce6cbf6a8fea40772cb882b66d": { + "balance": "50000000000000000000000" + }, + "379f63e538168925ba6313f9a6a3b6e7f0e8ed52": { + "balance": "292876625446000000000" + }, + "37a24c1a8080ab429a136c5582782b276eaa931f": { + "balance": "6099055841000000000" + }, + "37abbeaf24b5e6264c87633734852e243d377010": { + "balance": "1051360014489000000000" + }, + "37c50cecab8fe9dcd81aaede95050d27c53f4d45": { + "balance": "106051638566000000000" + }, + "37f82962c3097f0cd9ff605db66e792025a540cb": { + "balance": "10000000000000000000000" + }, + "382ba1e6c53cd7b9c360ef894962d281d557561f": { + "balance": "216789631461000000000" + }, + "38309b458993916efc1ac8b0b5d41302fec21095": { + "balance": "999139000000000000" + }, + "3847f25956a97a32caac059fd9e4cdc105756e25": { + "balance": "876497264905000000000" + }, + "384fe5f399638d277d4fb93f26d527497939287a": { + "balance": "280035151914000000000" + }, + "388335d8b92b445b1b19a3107547bb6ca7c0763c": { + "balance": "167140942784000000000" + }, + "3894a1e65973a542101caa4dc01e9553a5521d63": { + "balance": "34262479791000000000" + }, + "38a0e019c6120a19acaf0e651dd8338982cdaab1": { + "balance": "153843170492000000000" + }, + "38d4bdb10819a7d4ae9a32f4abb82402dff319b5": { + "balance": "1471131830647000000000" + }, + "38e56a55e2ac8320a480562f4a7cea9220306ee3": { + "balance": "907464312139000000000" + }, + "38f18123f3643e03d24ad759afbefc90ed923a2a": { + "balance": "943729130798000000000" + }, + "38f764c861def6d5d65e5ec099536f4cfcc3af55": { + "balance": "20000000000000000000000" + }, + "391e12b51fc85fb879a72fa746ca06c7a5659e6c": { + "balance": "9000000000000000000" + }, + "392342dc7b475c3975877a41622be0fed8e386be": { + "balance": "218719857770000000000" + }, + "3944cc960b8f1993ad841629a79e53d0535a88c8": { + "balance": "210571656485000000000" + }, + "396219864b8cfb0ffb3c675690ccd7026424ad4b": { + "balance": "138984508746000000000" + }, + "396403f26b388150b4876485b124a49845101464": { + "balance": "10000000000000000000000" + }, + "396f1e0f9e7ee86d1b2159ab8f9353677d12d340": { + "balance": "121000000000000000000" + }, + "397cc9f6254d56c721c767e41628a9078bea878c": { + "balance": "225000000000000000000" + }, + "39878b0c7049fb179aba0015279eff6cc3136816": { + "balance": "33962071375000000000" + }, + "3a06b58d0cceee5b091fe6aeb0fc0db5774e9395": { + "balance": "272033811720000000000" + }, + "3a3330e0152d86c5aa1d9bdfe9e1697645d3377e": { + "balance": "2165107207206000000000" + }, + "3a3bb8ed3130e09fbdfc21db3571d4711fc92d60": { + "balance": "885484658836000000000" + }, + "3a4ac96c489c864765cb1997a0084ba745b67a87": { + "balance": "1257436384863000000000" + }, + "3a69e1c351978ced418cea6cee019f220bcb065f": { + "balance": "579242822216000000000" + }, + "3a76a23d81929bed05ef7e1982d32b456e62aa7c": { + "balance": "1027078338792000000000" + }, + "3a7beadd1e11d0e3326c0dcd0f670530612931a5": { + "balance": "20633069818937000000000" + }, + "3a867c44d0dd06517a82ad467d0aefd7f11ce729": { + "balance": "12323708574000000000" + }, + "3a969ae486215e24c7ab89e38929562e2f85d923": { + "balance": "18955477335000000000" + }, + "3ab81366d898a8b798afb08a4b722ab0eb883652": { + "balance": "1220090012596000000000" + }, + "3ac1e14ed5929d382f6488c5444e717373ed29ba": { + "balance": "2030543873000000000" + }, + "3accf4b8ef20e4fea983f13f99ab257a5f9e988d": { + "balance": "156030342415000000000" + }, + "3ad38fa6e3c078025794e213d9dcc5aa397050c2": { + "balance": "36561766773000000000" + }, + "3adef81b2c861ae39c418d55be99aee2306e29fc": { + "balance": "15752410974000000000" + }, + "3b21ff4d5801d3976643899f195fbfd1b72a50b3": { + "balance": "8971221745646000000000" + }, + "3b2f2635dd428ac0b5873088a9a81800f09d6e02": { + "balance": "56922872447000000000" + }, + "3b39919c7bc8d0afec792288c56ab7f4934dc7d2": { + "balance": "1678237240464000000000" + }, + "3b468d9d5546810aa837c29ccb8349548b0e8170": { + "balance": "1100000000000000000" + }, + "3b83d1b651f117f1559a19b04ef408619c2dc4a7": { + "balance": "53628552066000000000" + }, + "3b9a72201bb1e8e678e36129cb1570e3ac99270e": { + "balance": "25000000000000000000" + }, + "3bcab1535b04a0a3fbb673bc41fedaa80bf7901c": { + "balance": "1526488015042000000000" + }, + "3bed42c3d0c49ffac87b9d482f6338fdc9e3880e": { + "balance": "26189771073000000000" + }, + "3bf736b57f0ae47f3714a6bb852090a543b9d367": { + "balance": "652395174320000000000" + }, + "3bfd481651956105ed909eeb98be404ec5ae77e9": { + "balance": "177520143473000000000" + }, + "3c0a12a327545b5f8b7b5c1f7a1ec6a341ec9578": { + "balance": "4184342789398000000000" + }, + "3c132698d59927fe08cba433a41d08acc96c0edd": { + "balance": "151913899135971000000000" + }, + "3c27bd92c4be1a19974ec773bd20b13afe582c9f": { + "balance": "10000000000000000000000" + }, + "3c2ad171573a608286f1fa3f5ef9e6099823983e": { + "balance": "3240802189194000000000" + }, + "3c4b5e808b9fb8baab1144b981b6cd53e216fcdd": { + "balance": "61214114118619000000000" + }, + "3c4cfc6ead044819ceb41c1c64ceda1a228af801": { + "balance": "9000000000000000000" + }, + "3c553afd45535f7c2a70c701d00890e607b96ffe": { + "balance": "2678827200938000000000" + }, + "3c620d55268c55b6deea3b7dc7f59dbe93b6e141": { + "balance": "55494311990000000000" + }, + "3c9b204db23b902d4295e6aba3405917efd59449": { + "balance": "55543672571000000000" + }, + "3cf233b7730a175d05a861318b7bb917bb5bee06": { + "balance": "1867187351033000000000" + }, + "3d292272992397ed5f27d5202da693128d023d35": { + "balance": "79770828413000000000" + }, + "3d353cfe84e9a93aef90547fbeb6e4b4bef83069": { + "balance": "36000000000000000000" + }, + "3d54da4ddd0621822a114581ecd15572e6488be9": { + "balance": "1623867132383000000000" + }, + "3d62ddc67d366fb055eaf92c936a6e7df5085454": { + "balance": "124933526793000000000" + }, + "3d754df1151b9b62a6ed48b477225121c29af063": { + "balance": "50000000000000000000000" + }, + "3d79d1ebd5224ffdc13e27924ab7f9f8e3452ec9": { + "balance": "520163228474000000000" + }, + "3d84fd9785a6bd3148847038c6f1e135042a892e": { + "balance": "10000000000000000000000" + }, + "3d9574c3860f30bcb42523a0cbb08aa7dd83e733": { + "balance": "15259904884000000000" + }, + "3da809a5911ccc77f892034049a97a9022c35e7d": { + "balance": "1415009021101000000000" + }, + "3db9a6c6ab3d0cf6d3bd7e04bdad39b4d419ab13": { + "balance": "9999781764000000000" + }, + "3dc7367c3218f88de8867c425f89102d2f2056f4": { + "balance": "10000000000000000000000" + }, + "3dd273dedb28824d1309c7d60a0744a6b6353e79": { + "balance": "9000000000000000000" + }, + "3dd6b25eb91dd2f3468e0786e8beb465abe7f515": { + "balance": "275172962210000000000" + }, + "3e0d14f83b304136311a33bbac2720c0cd66f117": { + "balance": "3390479675000000000" + }, + "3e15e947ee76f52f0f2a7d84da7c4ab060eb5cbf": { + "balance": "6751398714759000000000" + }, + "3e1b5469e1da4ec27537513f4df3f1a338a7dc2d": { + "balance": "161899580000000000000" + }, + "3e3329bcc90e47e4dabb5c93572b18b5e0efa024": { + "balance": "10000000000000000000000" + }, + "3e5a585ad0f34d78899433edaed574af052616f0": { + "balance": "910225655353000000000" + }, + "3e6be9615713bb06198bf354ef434a9db649699b": { + "balance": "783525278181000000000" + }, + "3e7c7c082f2f99b1ad579400a2e93586a24ed992": { + "balance": "159035553843000000000" + }, + "3e86ea5713f90022c0914fcc25e97c39487eb957": { + "balance": "101867287023438000000000" + }, + "3e9dabab6e50a696edfba6bcd44230d087c8d04c": { + "balance": "3315882414579000000000" + }, + "3ed956f86fe78223c86e164e4f372c9a0bf4a279": { + "balance": "119959915220000000000" + }, + "3ee87e776fb12e9c894e36fd5a61daa984e8a5cb": { + "balance": "50000000000000000000" + }, + "3ef1c8f294443f776a794563ce7569a8fe4d5d20": { + "balance": "25000000000000000000" + }, + "3ef6a396d6611df6c79ec1e6ad6bbd253917fbe9": { + "balance": "10000000000000000000000" + }, + "3ef727346fc631ae6473e9a36e2e5e54df696195": { + "balance": "121000000000000000000" + }, + "3efdcf2c0998637cb82d2b5fc24f27162578d207": { + "balance": "1054861112990000000000" + }, + "3f2cb2335e2bc07744175c497e2f437e87c2a146": { + "balance": "48999979000000000000" + }, + "3f4d16663a4f76ade93eb8bd6ca8fe2158e24322": { + "balance": "237117597268000000000" + }, + "3f7c5e6aea7f3f74d764df50f0fc1aa758fc99a7": { + "balance": "63372222562060000000000" + }, + "3f92239fdb41c6ec228252248c2db3f23675e275": { + "balance": "28538064487000000000" + }, + "3f9610454b621c04f00f01f4d54046502edb21fb": { + "balance": "16000000000000000000" + }, + "3fcfb30cbfe53c0c43f58c28386d9a6e5b49f7cd": { + "balance": "79080579219000000000" + }, + "3fda0c9a3d3f0000635376f064481d05d1b930bb": { + "balance": "10599947385000000000" + }, + "3ffce0475430de0bd9b09a412e404bc63aa28eea": { + "balance": "10000000000000000000000" + }, + "3ffe7583b568448ded5183e1544bca0d283680d2": { + "balance": "1076944549283000000000" + }, + "4003a137e577351a4ad7e42d1fc2d2cf1f906b6f": { + "balance": "25000000000000000000" + }, + "40215fc4c6300d8d8179383d9028fd2d909c6cc4": { + "balance": "3941346079000000000" + }, + "4027d7bbfa5d12c1ab9d08933a1659ae8dd023ee": { + "balance": "1156537386462000000000" + }, + "4039439c960070394dbda457726d97121c7b3669": { + "balance": "4444061364102000000000" + }, + "405978c24a12d930ada6163a44fc4a70c16569e1": { + "balance": "707298643296000000000" + }, + "405d2c1b55ba3f67c8634456b99c19092b407a10": { + "balance": "1462185951849000000000" + }, + "405ddfcf45005cf5a0ee1bfa605a7346a0167945": { + "balance": "88775535985000000000" + }, + "405f72a6940acf5d36a29498075f2d0d7a75bc22": { + "balance": "402796678569000000000" + }, + "407253b005ae97857f812fc60d441e5367b4bac8": { + "balance": "1484147810895000000000" + }, + "4091e1fb1c7af51a64c201d6a0c8f0183dfb7ca5": { + "balance": "10000000000000000000000" + }, + "40950bad9580d4b111955da7d3f9ada26dd9f05a": { + "balance": "500000000000000000000000" + }, + "409a28106192cae7a76c6aa8add0f73dcd63d2c0": { + "balance": "214832616721000000000" + }, + "409d5b872b059aea9a773e854f9a17ed2d5c2ef3": { + "balance": "64000000000000000000" + }, + "40a6e3c753b04c42fcf89cc30df8f50418caecb8": { + "balance": "754228409494000000000" + }, + "40e5ce1e18c78d6c792f46ed6246bfb31bcdb6af": { + "balance": "500000000000000000000000" + }, + "4121692a14554ddca1ca662fb577d7152d4fa7d0": { + "balance": "49000000000000000000" + }, + "412acb10c8ca937ddd64cf0d413b1dd34760f72b": { + "balance": "6073360870000000000" + }, + "4166a5c94d5ae48ced410f950d40656182bf8990": { + "balance": "55000000000000000000000000" + }, + "41752b7d0d3ee58a6b69d8ba721c0894ff701237": { + "balance": "585556720807000000000" + }, + "417c86d6bf734e99892a15294230771bbfd7e1e1": { + "balance": "38233258264000000000" + }, + "418414498f7361b29428c54732e1f49fb394f813": { + "balance": "2063786326155000000000" + }, + "41a424dcbff6bf31686f5c936e00d21e8a4e0f78": { + "balance": "33554754580438000000000" + }, + "41a893429d5f8487c1866b87779155d4bfe33198": { + "balance": "20000000000000000000000" + }, + "41bbedd607fa576d130305486824cd2871bf6b05": { + "balance": "649728993301000000000" + }, + "41ee42c1fb1bcdc9c7a97a199fdcf9b63623521a": { + "balance": "7906012418597000000000" + }, + "41feffaf56d1712af6965fa6eee1b06bd624e7b8": { + "balance": "49000000000000000000" + }, + "42107e765e77ea76b3d6069d3775bc3aef7d692c": { + "balance": "25320783684183000000000" + }, + "421f4dab3240e15a1c78e3ce8642de9b578b8e4a": { + "balance": "832511242936000000000" + }, + "4246c52c3601541a873d4bbaafedf28b9bad5b73": { + "balance": "10000000000000000000" + }, + "424efe1ba28bb1aeedc38a3a5135547d0fe80751": { + "balance": "25622294162729000000000" + }, + "424fb0a3ec325bf42e7edbef7e450f2ffd1cf318": { + "balance": "20000000000000000000000" + }, + "42714c04d17f6c29029daf7f50d1cbad6590cfad": { + "balance": "271755674161000000000" + }, + "42b66e9123d304b70fef3dbcfe8587fd6189b5c4": { + "balance": "1030481609000000000" + }, + "42dacbc412b829cb304ffbc316b3f81b379bfc80": { + "balance": "304208485736000000000" + }, + "42e3d9832c8b6cdea39c97525570391803dee276": { + "balance": "2581020833000000000" + }, + "42f757898f95c1b46f64a4a6b7f86ab03022d672": { + "balance": "100000000000000000000" + }, + "42f7956fd659e00d3be2f3d1d4f3ed187aef04d6": { + "balance": "50000000000000000000000" + }, + "43160b2bc00f7f8f7fc806e2f6e2ffdc62b3a651": { + "balance": "1000000000000000000000000" + }, + "431b77cdd067003eeed26c1aee32f67fb94f7092": { + "balance": "902514849986000000000" + }, + "434e44583786e354731bca250d94ef0d8860a538": { + "balance": "1187789683866000000000" + }, + "434f1b9b193c88bf58685124aac0167fe69f9014": { + "balance": "500000000000000000000000" + }, + "43535982688844fa703cb9bd5723790cab364049": { + "balance": "100000000000000000000000" + }, + "43559f405590592c254e427fa25f03e774d8defd": { + "balance": "6913200000000000000" + }, + "435c08c481d59308a64afec0d6f936321bb120bf": { + "balance": "9005920819593000000000" + }, + "43629748a92b846f21f637aac5103412fbabb9a6": { + "balance": "1177513692845000000000" + }, + "43650b37552882d225ccc977aa2b7a86a4ca9bb1": { + "balance": "16000000000000000000" + }, + "4385de394371d26a45f18e8b3842effd015027bf": { + "balance": "187331693412000000000" + }, + "4386ff9648fe420503c9a36fe7b97c079de3b770": { + "balance": "2714401478778000000000" + }, + "43b370c4457cf39a3be86cc00c2b27614ca6e638": { + "balance": "8316429850934000000000" + }, + "43c464ea740172fe6f4f09974106fd24029837b9": { + "balance": "129643160399000000000" + }, + "43ddd2d33dcb7e578f4e59ad6b9c61a24c793aa8": { + "balance": "500000000000000000000000" + }, + "43e0f8065eb7faf3bbd13bc7c5d5d8f5ff1bdac3": { + "balance": "4454324716300000000000" + }, + "43e96cd065d7934b246d0fec8cd2dc6b36d56d7a": { + "balance": "81721481452000000000" + }, + "43e99acabfbdc6cafee3afb12fa7ed1345370b2d": { + "balance": "4595292398872000000000" + }, + "43fae764c7555b859b93d2126edfa59cfbf298b5": { + "balance": "105746805109558000000000" + }, + "44052eb938c02776b5240f38ec99f5ef51ef0d87": { + "balance": "38446396949881000000000" + }, + "440fc7621cc17f121f0bdf2a68c5be2c3af4fd3b": { + "balance": "1026958147051000000000" + }, + "4440ccbc77249a4d891d9ab5a5f2026b17aff7c7": { + "balance": "10000000000000000000000" + }, + "447f3f702c13a3fbdc8675c6285702b5aa2b66bc": { + "balance": "1089533398014000000000" + }, + "448f152be153fdb0497403f70e37d876946a5021": { + "balance": "614429461682000000000" + }, + "44a1e3a044f5d1fb00f4beb3772a3ee08d8b7093": { + "balance": "1000000000000000000" + }, + "4515edc7154bedd7143b69a04c4e738f8aa4ab18": { + "balance": "10000000000000000000000" + }, + "4572148fe5ea9d4795e1f1ed93097aac1d70991c": { + "balance": "2873782218000000000" + }, + "457581f223b8eacd757abb292613e317d6f59305": { + "balance": "3582446780073000000000" + }, + "45b450961882850f7038d5cdcd2a8fa2dc4b5469": { + "balance": "20000000000000000000000" + }, + "45bdfdf3840d4341503cd7fc87e4b66f6179e5fe": { + "balance": "10000000000000000000000" + }, + "45dd9baa87b3c94df66308d8ed4f3a5bb65c3dcb": { + "balance": "25000000000000000000" + }, + "45de332b8ee95d886cf11b99291b46f46c1ddd45": { + "balance": "36000000000000000000" + }, + "45e06afdbc70288a2cc55bccc4fb2d8195aea028": { + "balance": "790360485306000000000" + }, + "45fce5fd1acb2bc5507723c897cb340437e39735": { + "balance": "100000000000000000000" + }, + "46045cddd940d80596826ce5354489b3047663bb": { + "balance": "100000000000000000000000" + }, + "4610286f8a2649dcfbc6d91735745f418a6abc75": { + "balance": "10000000000000000000000" + }, + "4615905ecc6f7df0ccb7b86a3e1d3770adb2f874": { + "balance": "1000000000000000" + }, + "46256e00ff927d54b0ca139ddccac2148784273b": { + "balance": "10000000000000000000000" + }, + "465e40e7d129ad310fc60ff0f17c0f968611118f": { + "balance": "677971225649000000000" + }, + "4664a920f7fe9b0d78a665e1a4aeb95f287d6059": { + "balance": "20000000000000000000000" + }, + "46679de1c6143138fd9c44ff05853a52371915ff": { + "balance": "363627463229000000000" + }, + "467cdc210ae48ba99740d37ee79fa57c4216bc81": { + "balance": "10000000000000000000000" + }, + "468053d193debb88735571acb24b764f2676272e": { + "balance": "49000000000000000000" + }, + "46826d1f1418abbe4e7b9236d643e5b57a0f0208": { + "balance": "37752144164916000000000" + }, + "468df2ea57972ddeb88d470a5f3c2c0e2284ac17": { + "balance": "757320434551000000000" + }, + "4695ad5b686520ee8426d24b50ff7a5f0d703443": { + "balance": "2851082366000000000" + }, + "46a149bc8ec2b85fdf938f753a6c53777dcca2b1": { + "balance": "10123698633000000000" + }, + "46c081440f760a21b74c2499bdda13aef8245930": { + "balance": "180752319265000000000" + }, + "46e615324f6e4fb242f9bfecffc0c802ba7733c9": { + "balance": "10000000000000000000000" + }, + "46eb54f09dbdaaf3b97a1f79a3d82ee2e902b3b8": { + "balance": "3430510380318000000000" + }, + "46ebb24b04919ec0164f0bafcebca2309f2d3035": { + "balance": "129155832233000000000" + }, + "4701f9fe78111011f820fe28c47522e601655678": { + "balance": "9000000000000000000" + }, + "473f44e2c1d5d7aa53cf7041d7ad19a0d9eaf1d8": { + "balance": "162679637505000000000" + }, + "474f8bf4d03a7efa4d190905ce062eea7c75118c": { + "balance": "1259904506149000000000" + }, + "47598330e862a4f7cbda8be74ac10cd5d370a55e": { + "balance": "291763101699000000000" + }, + "476455d48fc858a06bd7854fcf1bd60bcfde9ed3": { + "balance": "10000000000000000000000" + }, + "476826d58192ad822f4686311d6c6d4d4f66ee5f": { + "balance": "453184657722000000000" + }, + "47a231eb3fdbc24f2d008f06228624b2a45ae5fa": { + "balance": "1000000000000000000" + }, + "4805f4c0eb1c83c436118ec9148019e5fc1962e3": { + "balance": "1311161626928000000000" + }, + "4809f373cdd56c8481ba3bce5a401d55a7e50a50": { + "balance": "2284845194349000000000" + }, + "4839bf9ad56873abd5695057bf71972806cde827": { + "balance": "42264923611000000000" + }, + "486dba2a47decabc9a85d1d64d74687983ab273b": { + "balance": "49000000000000000000" + }, + "4877993f5ecf02451f8d4591594cb2f30dcf9f26": { + "balance": "100000000000000000000" + }, + "489723e325f609e27be14528c4111fb3eec13f7c": { + "balance": "2489030141000000000" + }, + "48b710d16e9da736b773453089d69cc6ede116b5": { + "balance": "26651593216000000000" + }, + "491088e1e4b5c3d65870f2deef9be6ec3dc6c7c7": { + "balance": "1446809481953000000000" + }, + "49174451320ad2e14cb2b05ecdd251b75ace3038": { + "balance": "15533380764616000000000" + }, + "4956ead915594b621131b2fc2dbbb49ba43c5559": { + "balance": "1175638488000000000" + }, + "4973a0d32147ba89f525a18f989518dcfce93b0e": { + "balance": "522848489444000000000" + }, + "498c6f9063705054fae07260d4176c3d55a97650": { + "balance": "732941433000000000" + }, + "49991f68f2a76bd1cffa3e9721be36f3fd8351b8": { + "balance": "17742568700019000000000" + }, + "499a8af194e0040f349e893937fe3858f8267fca": { + "balance": "80704784160862000000000" + }, + "49bcbb7b263febf54f8ff498525bac8e7241f966": { + "balance": "603044032468000000000" + }, + "49bd72773656c4e1a4d16284aea2fb05546d2b31": { + "balance": "1896607093054000000000" + }, + "49bf80fcdefebe8cd4830ba09e46ccd7231c8e6f": { + "balance": "10000000000000000000" + }, + "49c9d82dea78f14b1c52efc0196b67f508f7859b": { + "balance": "2313040051399000000000" + }, + "4a2daeacf0468d137e3bc464d6d5fa3893a9136b": { + "balance": "10000000000000000000000" + }, + "4a6c428f245e8d9115b34764bab17eb86ac472be": { + "balance": "10000000000000000000000" + }, + "4a6e8d037acf1960dbbf14e7a02fec0ac656f9c1": { + "balance": "6516295825438000000000" + }, + "4a7e7fc3c72f2f9b92bf0dcd5297cfb19f077d7c": { + "balance": "99426213999999999" + }, + "4aaa6817a5000bb7596e000135b3051c5931e7c5": { + "balance": "102884105546478000000000" + }, + "4abcdc3d7d3d314a163da92aee53a56b87313a2e": { + "balance": "44402243657000000000" + }, + "4ac9385ade2377b061f4211b392ed6a6e7fb83cc": { + "balance": "1000000000000000000" + }, + "4ac96e1e26cb66ff788ed8c62db811d7b4fdbc74": { + "balance": "68476115774000000000" + }, + "4b10c247caf33fb872d9bf86572424410aa86752": { + "balance": "337915294240000000000" + }, + "4b23ffff1894df49005c7afc0828880924571299": { + "balance": "169848767272000000000" + }, + "4b486895caf3a0b5afa198df744de7082eec8666": { + "balance": "1672587376054000000000" + }, + "4b98fc960610573be456c0e1e319f4f863bf9095": { + "balance": "259382246718303000000000" + }, + "4bc0cc483be20223f40ed6deef63dd9645c216c4": { + "balance": "4322684620000000000" + }, + "4bf4a046afdd4ec9d0e50730ff6ded5ef2327442": { + "balance": "70601389160000000000" + }, + "4c0149058e2e74f7c900e6d6e5fa12eea882c5e0": { + "balance": "2017399852886000000000" + }, + "4c17a3997fb70599794d01a33a27a6d5b52b6f01": { + "balance": "469002093209000000000" + }, + "4c4559e7b32340dce112cf7a021ced1b113f6dd9": { + "balance": "25000000000000000000" + }, + "4c4f02b3f232b8ce8485d425639271510cd0486f": { + "balance": "68828038140000000000" + }, + "4c52ec56142bb6e8c8830e5c17b01b5165915f3c": { + "balance": "321766233041000000000" + }, + "4c58defa57875e709ca039a54a2be5aed6672f6d": { + "balance": "121000000000000000000" + }, + "4c5a886ab90b6bac68677a7eb92a06bf33ff2930": { + "balance": "236899852150000000000" + }, + "4c60539363edbd812334a54543c40ecab8af2ac8": { + "balance": "3281904094699000000000" + }, + "4c76897d0d5d39195354194710c5e7f99bef63d1": { + "balance": "10232271258305000000000" + }, + "4ca3c03780c20a64f3b5ebb75669982a71ee8a71": { + "balance": "377172198976000000000" + }, + "4caf77eefe062a6f053a464171bc75254b47f52b": { + "balance": "20000000000000000000000" + }, + "4cb7d7ce805e56f6e47e94cd755b6d97f8f996a0": { + "balance": "120998866000000000000" + }, + "4cd34f8f3299d3b7aaee180baa0b432369e1b3d6": { + "balance": "197088135242000000000" + }, + "4cd7aaa5415d809f405f520e4c0319a6029b981b": { + "balance": "686627368232000000000" + }, + "4d01067555f1ef63883f25c562b07168f79fa80d": { + "balance": "17547055698000000000" + }, + "4d2cb4c1da53e227b08c0a269402e9243a13f08d": { + "balance": "324000000000000000000" + }, + "4d38bb5f48ec37b751d16de32a4896fbda479ce1": { + "balance": "802530078718000000000" + }, + "4db3e76e2f68896cecc9826e10a5e09df0352c28": { + "balance": "555180306924000000000" + }, + "4dc8730d9f032d33dc493bcd3c6375b38f41afff": { + "balance": "5726933881000000000" + }, + "4ddde96556f5185a13617f01ebd9102800bc9e9c": { + "balance": "1181822708402000000000" + }, + "4df9359cb204bf649668ff8086a7f5e24709083c": { + "balance": "262998978400000000000" + }, + "4e0a1a3dff0d33c418758263664b490140da9e01": { + "balance": "100000000000000000000" + }, + "4e0dd6d8de5caa3a3bf9fdd6f2d7b30618623cc0": { + "balance": "10000000000000000000" + }, + "4e11af85d184b7f5e56d6b54a99198e4a5594b38": { + "balance": "76658631121000000000" + }, + "4e314349abc52c686d47dc771ebc8040966be386": { + "balance": "632341985941000000000" + }, + "4e3fb09c35375106bece137dbe0e5491e872871b": { + "balance": "153648535396000000000" + }, + "4e4f0d606f7065bfb1545e60b5e684ae1934e055": { + "balance": "48998635468000000000" + }, + "4e50957aa6c91c548075add8ec625b74c0973abd": { + "balance": "1000000000000000000" + }, + "4e5c6efa76493f0e9422582016aac50539ae60d9": { + "balance": "2078967343000000000" + }, + "4e70bbcb50c4e875fd573dcb694908abf3b30b37": { + "balance": "20000000000000000000000" + }, + "4e7f5670a7dd168a0803e53b8bf72f4db280e3ae": { + "balance": "1658463113665000000000" + }, + "4edaf859990a10977bf378df45b32f93422c84b4": { + "balance": "121000000000000000000" + }, + "4ef41923a1a426772832d3c267adbd84e5994edd": { + "balance": "5432615017384000000000" + }, + "4f11a70d80f36f46ed0c2a5fff1a39b711f3bae5": { + "balance": "8415785077000000000" + }, + "4f159095afcc75b8f5cfc90c9d07a0d77ac8ed69": { + "balance": "25000000000000000000" + }, + "4f2652322736cc18b24af582d4022fe329a9dfb7": { + "balance": "9000000000000000000" + }, + "4f328173f352f3dfdca0ff5e3185f26de77c6f75": { + "balance": "10722917874680000000000" + }, + "4f47a62aba6ea049fc0e92d8afbe1682472d98bf": { + "balance": "10000000000000000000000" + }, + "4f4c3e89f1474fe0f20125fae97db0054e9e14e0": { + "balance": "50203638983000000000" + }, + "4f5ac8dfe79c366010eb340c6135fbee56f781d8": { + "balance": "50000000000000000000000" + }, + "4f672cbd373183d77d8bd791096c6ebb82fa9a2a": { + "balance": "978111227765000000000" + }, + "4fb179c9c88decaa9b21d8fc165889b8b5c56706": { + "balance": "24750205150000000000" + }, + "4fbcf391c765b244b321875d6ab4381c44d0747a": { + "balance": "99999580000000000000" + }, + "4fc979b38b981fca67dfa96c6a38a17816d00013": { + "balance": "1088876196468000000000" + }, + "4fdfdd1832b114b4404aae23305c346beee14e1d": { + "balance": "278724179057000000000" + }, + "4feffb1836029cd0e9b8f4aa94b35ae3982fa770": { + "balance": "1674590934924000000000" + }, + "50045745a859f8fce8a2becf2c2b883b3723b2c8": { + "balance": "169000000000000000000" + }, + "5028bde29fe88e03e3de069b3907fa9df551c379": { + "balance": "196000000000000000000" + }, + "507096ed771fa8a1d004ee5377c01506df461b32": { + "balance": "2669205000000000" + }, + "50788574a0967580fdaddc4758f834d8978455f6": { + "balance": "1648581593000000000" + }, + "508d8e8f338ca98d3c09f0f15fd9e7baa80701e8": { + "balance": "16000000000000000000" + }, + "50a4dc916845172b83764a6c8b4b00d6d02d41d3": { + "balance": "3020744393592000000000" + }, + "50da06418780c220ced4898af0b1fca533f73cca": { + "balance": "36486700700823000000000" + }, + "50fb6fd8432a66219e754234e9eea1dabcc07676": { + "balance": "489500000000000000" + }, + "5104bb1b831902333732dd25209afee810dfb4fe": { + "balance": "1333614132000000000" + }, + "513963743ec6ec9dc91abf356b807ebad64df221": { + "balance": "1508002412172000000000" + }, + "51397ca69d36e515a58882a04266179843727304": { + "balance": "941648956414000000000" + }, + "514a58f2b36c2cf1b6293c36360cf658d8af30ed": { + "balance": "1233397704089000000000" + }, + "514fe0cdb3de692cab9f2ef2fd774244df71be66": { + "balance": "9670444445882000000000" + }, + "51583128081fd800d9550144afebdf3fe88149cb": { + "balance": "231190355520000000000" + }, + "517384fe92391187d0e65747a17bfaadf967c331": { + "balance": "1943121865489000000000" + }, + "51aebfaa26a54071cfe6c2d8f81157ec313984ad": { + "balance": "1422225031261000000000" + }, + "51d4f1205b272e491e94fe21f0341465f14141fc": { + "balance": "552384783614000000000" + }, + "51de598faa85276bb26a68b135028755304b6700": { + "balance": "2068484560002000000000" + }, + "51e08e0304f08ef768c80ca149da4721fcf482b0": { + "balance": "194629207228000000000" + }, + "51fa3da695e24f602952a71966f37ac3596a94a4": { + "balance": "17008166261720000000000" + }, + "520b22776b1befd3064636da0dd251afe569ef13": { + "balance": "18538137781909000000000" + }, + "52219a1e1aa82b78b971088c30583a3bbe675c8e": { + "balance": "411959222637000000000" + }, + "5252b8a0688096523498cb5c1f42bcd1f61923d7": { + "balance": "1863936864000000000" + }, + "5259154e1a5a809b2e3dab80372124cebbfd56e2": { + "balance": "110000000000000" + }, + "5264f2de516835e549710bfe34ef03b08b8557dd": { + "balance": "1216000000000000000000" + }, + "52b17fae7e9cac447f026db71dba4034a1d53174": { + "balance": "99001631977000000000" + }, + "52b3363ae882a99354faeb76733d0fa2cbb89787": { + "balance": "102517584327000000000" + }, + "52bee7fb24a7fc1f34cf0874ec2f06c5fe847cb1": { + "balance": "54443400591000000000" + }, + "52d1f12d391c7a2f3b52939a61a20da5f85eecc3": { + "balance": "2707175772061000000000" + }, + "52f27099483589e883e7eb789896de39c61e46da": { + "balance": "358944977251000000000" + }, + "52f3b715b678de95d1befb292de14c70f89f5e03": { + "balance": "2989868434000000000" + }, + "53259780569f6dd6753c1da1d53d0b155c5b30d2": { + "balance": "200489122590000000000" + }, + "532e4908e8297c90d75d2280b432b469aaafa2ac": { + "balance": "20000000000000000" + }, + "5334d1e399feacabc9648cebcd93172db95d43be": { + "balance": "25000000000000000000" + }, + "5341665addfb5e367f7a7d35de95b87a0cceb3a9": { + "balance": "60544291695000000000" + }, + "535a39a854ed1c2f0afbc5944f1ee0e2e68cf65a": { + "balance": "2141913781000000000" + }, + "536515c0c08988ee69da1d75f18c706f6b9bf7a3": { + "balance": "169000000000000000000" + }, + "5387a1ce4cd2ef4f90075c15dc3c0744948ec356": { + "balance": "50000000000000000000000" + }, + "539a30ee5724978010990718bb8b0dd25f89fd15": { + "balance": "1306896514000000000" + }, + "53a5f87dfb17149b8c2934a2a9d519ace4ac9724": { + "balance": "4569449510000000000" + }, + "53b24fb36e72c22eb830dc93857a8188b03397a9": { + "balance": "64000000000000000000" + }, + "53cc35b3daf4b8e1982e0e63d0bc68d7252e7fcc": { + "balance": "68213426853658000000000" + }, + "53e1f85147e000ae1ff6a5910407395e388c683c": { + "balance": "20000000000000000000000" + }, + "541f43ff66ed5eb1a1ea0ae3f86355ecff665274": { + "balance": "49562725831000000000" + }, + "5428a31f736c0d2b3c4e80baefb75a76ed44d3f7": { + "balance": "10000000000000000000000" + }, + "542f732aec0873bf531f6941828b6f0ed0611106": { + "balance": "8407722276000000000" + }, + "54300b6a77b95545373b2bba73e60f37c31eb1c6": { + "balance": "1581215621996000000000" + }, + "5434bd65a492a4d14d3b97eb49f6e491350ef73c": { + "balance": "484000000000000000000" + }, + "5444a1735913eeac177d947ef38de7cd6bdfc0a6": { + "balance": "1000000000000000000000000" + }, + "544ffeab53bdc59ef8edaff0042b03c2ea123615": { + "balance": "10000000000000000000000" + }, + "54613713df6c5b89c3012a7835651f25cdac8331": { + "balance": "98684037547000000000" + }, + "5471fb39b4e48c118f855492830ad9e2eaa68179": { + "balance": "91791250228000000000" + }, + "5472591efd048dd60a4d6afdb549e95a65578b0a": { + "balance": "50000000000000000000000" + }, + "547b4c1ae70567fd77a896dc05eb536f502ac8a4": { + "balance": "14037444012000000000" + }, + "547fa9f6f86a2939f9144aacb74e0af60d434535": { + "balance": "428416957729000000000" + }, + "54841d6a478cb9b6e717a9de35577a1a4a504b0d": { + "balance": "144000000000000000000" + }, + "549157e5b1c92a88a0eef335b1bcf4d162482017": { + "balance": "21019502942000000000" + }, + "5492757c55c72ac5946b21514ee16c5065ecde7b": { + "balance": "10446737491000000000" + }, + "54984a41eeaa8e710e4e5b8a7f68c96057b7df3a": { + "balance": "10000000000000000000000" + }, + "549a3717a1bca3f38d24655197c3ccef1e8c273e": { + "balance": "4416133255000000000" + }, + "54b047fbe004191cd02f31163d29bd61ccfaadf7": { + "balance": "52649445905000000000" + }, + "54b125d8b260386633b756056b7d7e78e7071715": { + "balance": "10000000000000000000000" + }, + "54ffad1ae76ab45c4218ced27e49bf2745b2a2e7": { + "balance": "1426474871178000000000" + }, + "550b28968bae36f4e99780c6d7deb54c158be6d8": { + "balance": "10000000000000000000" + }, + "55117923e8393dbf233c0f10819e7de75569962c": { + "balance": "470094520022000000000" + }, + "554a2471e6ecf2320da545d559c40b8b622465ab": { + "balance": "4052895973949000000000" + }, + "55607b39da9480ed8f54d74d0818ab8798136589": { + "balance": "13704276648975000000000" + }, + "5561cbe99fd775f5d0f05903fd62ba4877b3319d": { + "balance": "1007596371374000000000" + }, + "559ba7ab58670d4a0b118bbf6aed7f6fdb276594": { + "balance": "3127762973000000000" + }, + "55b0bc444f2a5952a98f216f61cf07382da1e156": { + "balance": "18683409750727000000000" + }, + "55c0a02dc68123aca7ee0c9cd073ead50b16406e": { + "balance": "99999999580000000000000" + }, + "55c47d593952afd637050c5758a921a204f23fc6": { + "balance": "1615608723958000000000" + }, + "55c6855b3970e5a550f0c75d5727329476406d91": { + "balance": "600705012673000000000" + }, + "55eadbe33899f53138d0fb204f42e272f447cfd6": { + "balance": "1671128311341000000000" + }, + "55fa59fa0fbba06b7184ea78868d438176eb96eb": { + "balance": "1553000000000000000000" + }, + "560a11493b5a0ec28589e80276fe975ee26c6a3e": { + "balance": "10000000000000000000000" + }, + "560fbb31d83bf6dc49e5fb15bd582d70c49fd273": { + "balance": "46015432815000000000" + }, + "5620e17ccf094b1be1a93f6f3388fb96e3a90165": { + "balance": "484000000000000000000" + }, + "5633512298cf74f4d2b8663e6f291e9e25436e7f": { + "balance": "10026444446000000000" + }, + "564423f92b8841b3b1f8bdba443067b580916e65": { + "balance": "465451550122000000000" + }, + "56730e1d11a84970355c43ac7659f2f4786dadcd": { + "balance": "20000000000000000000000" + }, + "5678851984add045f3d054623c198dfd4665d54e": { + "balance": "227651903234000000000" + }, + "569cf18b4bcb99e3f3d27235f2c4c0d8d160af03": { + "balance": "4124979731000000000" + }, + "56ac5f2c3486a9ce744a71599ab89a606e7464a7": { + "balance": "9000000000000000000" + }, + "56bc5936a6ea37c1d0839bf64bcec0d366840ace": { + "balance": "14741201469670000000000" + }, + "56bf62e0135e903525cc46b0a3cce33f4a16880a": { + "balance": "534970476270000000000" + }, + "56da0781a80a0abf5dcda4da35861e9de601bfbb": { + "balance": "166898390441000000000" + }, + "56db15729e52d615a744a04f8a59d63e3b9f735b": { + "balance": "10000000000000000000000" + }, + "56e32ed78e7f5be6b00c28847efe7b3589cdae1a": { + "balance": "1046236086484000000000" + }, + "570f7a08150e0088178276f8116bc4103f885903": { + "balance": "1124393518440000000000" + }, + "57147fdd9b52ef53b4ebd4b5712d29da83f99374": { + "balance": "39000000000000" + }, + "57395fb355fe51f1b32c1baa4e9ee0fc2b8fe05c": { + "balance": "7701013675397000000000" + }, + "5752f0f11ed12bb1d5041b0cee4ddd500cd8806f": { + "balance": "151337200533000000000" + }, + "575907d73ad5ad4980a2037efbd20860afc67ad9": { + "balance": "3568754158000000000000" + }, + "576acb4c0bccc89903ad285ac08c70fde514aaf2": { + "balance": "25000000000000000000" + }, + "5784cb8a17cfb5392c4aeec2edbd173849ca6ee3": { + "balance": "15804767597000000000" + }, + "579234645eb857a3ca51230b3a02b964f8efa2f6": { + "balance": "20576922380000000000" + }, + "57989f9fa52b4c0502e7d0c3caac0c37a0b20516": { + "balance": "462711082812000000000" + }, + "57a55c376ea03c22e21c797d83e2fb039508ad3c": { + "balance": "10000000000000000000" + }, + "57d1612ea1fddacf088b62f625ad8cd49d7517cd": { + "balance": "18001023230648000000000" + }, + "5811590907050746b897efe65fea7b65710e1a2c": { + "balance": "310984892882000000000" + }, + "582ffd8c43966aa8ad3c6cecdfc18eddc56fe5c0": { + "balance": "69136214255000000000" + }, + "583b90b3c4d00b9ddf101efbce75bb811d969fe2": { + "balance": "7839200298177000000000" + }, + "5841fee8b1965141e51b8c146b6af00f6a879a8c": { + "balance": "1210322907244000000000" + }, + "5847a576f7799ba1a35e36906b2c2a5aadeb99b1": { + "balance": "183765768447000000000" + }, + "586dea7ada0a54150f5afcf54198db473ed046a2": { + "balance": "7123598380000000000" + }, + "586f545062ec7dc0ffc213eacd59af80660df570": { + "balance": "10000000000000000000000" + }, + "587187488758f67912bd5bb8a5be787a73d97ee3": { + "balance": "702757402654000000000" + }, + "58be0a3482dc3411571f047f4128387049cb9798": { + "balance": "1000000000000000000" + }, + "58d546e2ae82efc4d8efc887ac6fd30f7eb5dac6": { + "balance": "1486717153455000000000" + }, + "58e7010e6b8d97a556c0e7f0d90151224ebf674e": { + "balance": "20000000000000000000000" + }, + "58f991b3b12d29f09ff4cc2c6e83d576e95b1f59": { + "balance": "25000000000000000000" + }, + "5923a65a796934e69081715657e8dfec8874e40d": { + "balance": "10000000000000000000000" + }, + "593b7c43073b8954355ed76020ff3780dd6ae783": { + "balance": "1403468567787000000000" + }, + "5947f1dbd79a622bcc3fa64b19f9b6eda164dcce": { + "balance": "50000000000000000000" + }, + "596311e2fc09ae1eaee57900f2ca188afd5e68a6": { + "balance": "448723397560091000000000" + }, + "597a3adac4607d457c90817220f67eb4abcf129f": { + "balance": "18000240000000000000" + }, + "598201a9bcff0a773e9323338a8a094e9d9b3999": { + "balance": "74904485722481000000000" + }, + "599e93031704c2ce36308f44d4ff8166e71ae516": { + "balance": "100000000000000000000" + }, + "59af0178699f9f3d8f0ea645dda75356119a6e2e": { + "balance": "152462578058000000000" + }, + "59b0c06e40475cd75728797add9c69c3fdb17b4e": { + "balance": "23147237210000000000" + }, + "59b79577f183b9d39c2b458646a26b2fd6ed806e": { + "balance": "4244859516807000000000" + }, + "5a03b51d67a9c660258ebc030120d5d1d4f687c5": { + "balance": "4451691855300000000000" + }, + "5a0d03dff6754963c757eb15a3339ac6c4ba6196": { + "balance": "215126489934000000000" + }, + "5a34ab3937854e407a8739fa14574d3d20e30d6f": { + "balance": "1375979293937000000000" + }, + "5a352fbeb2fd78bbe0268b0efd34f68d401e2769": { + "balance": "27929247671418000000000" + }, + "5a47c2ca4c0fad7e2fc7bbdf5f2356d68843c564": { + "balance": "3218227936000000000" + }, + "5a538adb2c7f6a80634b0ec20ec5152ff6bb4d5f": { + "balance": "10000000000000000000000" + }, + "5a8fe770c221072a7cba79ae7759cae0185adde7": { + "balance": "11913943233694000000000" + }, + "5aafe1efac688583d7facb09d3e569d58fb5a357": { + "balance": "4713219466825000000000" + }, + "5ab68d762750d5185138187db7751c9f71db5836": { + "balance": "500000000000000000000000" + }, + "5acab69851959dd5a6f0673ef757009ed36dfa3b": { + "balance": "974443209942000000000" + }, + "5ad9f2ab11b5e59b756404395f350aad6019d7a7": { + "balance": "54151179981663000000000" + }, + "5b1dc013ba1a28235cc70e785a00eff8808faef6": { + "balance": "516289257133000000000" + }, + "5b1eeb44ef61c7f35482503b7041162bec9b1e32": { + "balance": "125493885394000000000" + }, + "5b3db31996bca4625d22330686128ec234270206": { + "balance": "362316593128000000000" + }, + "5b401fc9ff3be7cdf5f0df870843bbef94f43285": { + "balance": "1373804724122000000000" + }, + "5b47ba296069041f25768e61be14437b8a469e81": { + "balance": "3152706392234000000000" + }, + "5b5030b5057c0457c190489c5d709d7dbdddee8f": { + "balance": "1154404278000000000" + }, + "5b5a4a782d37154a307868cd79bec9cb2a8f0161": { + "balance": "100277816425153000000000" + }, + "5b5e0b6b7cc27b06456ba4c7816ac4e89e1e26a3": { + "balance": "1023749119000000000" + }, + "5b638e4b6dfdb6928b07586e63d5879dce69a1f8": { + "balance": "1000000000000000000000000" + }, + "5b7be81d6ff5228a2b8c2913deea3f86823f1dee": { + "balance": "36000000000000000000" + }, + "5b7c4804bc2b8c72f3112b73d44b59c0711f83cf": { + "balance": "6803857604000000000" + }, + "5ba26d941544d07100744d8ffd6595a8eb7770bc": { + "balance": "583051897662000000000" + }, + "5bd58fc88733632b63d4f26893bc5c08fb60e2ad": { + "balance": "3480620567502000000000" + }, + "5bd85b5f0ecad08133fceb486c43998e537b3451": { + "balance": "484263880245000000000" + }, + "5c12639a5ab107f9e580cbd2278568dde10758d6": { + "balance": "101293252434000000000" + }, + "5c5522df05d6c6d960394c4762599e74247ab102": { + "balance": "149088856773000000000" + }, + "5c722f3ac94421f95389756af9cd97d0eaa6b696": { + "balance": "1435349483553000000000" + }, + "5c7b14ce51abf629bb0953ee4e2d9d87fc86eb4d": { + "balance": "10000000000000000000000" + }, + "5c8b215403da4e7912c1a1704a949087e091b111": { + "balance": "1440961256910000000000" + }, + "5cab313964f6730888e4158234bbd4806db0286e": { + "balance": "32284637230203000000000" + }, + "5cd736bf65c99469490d0523b10a658178cab10b": { + "balance": "99740204082000000000" + }, + "5ce91ef7ae254b2bd6d910cbf0d380814200811b": { + "balance": "50000000000000000000000" + }, + "5d15fc3a0ba8b3d87b80f9bbf972320112c644f9": { + "balance": "64000000000000000000" + }, + "5d2ccc795b19df400f21f24c0dca4d0e9e898093": { + "balance": "10000000000000000000000" + }, + "5d879b8b31af1e400cf53eb7170f82583190b96f": { + "balance": "93765337844000000000" + }, + "5d8dd54178b68bb36e1963d47d29c123864fd0ef": { + "balance": "20000000000000000000000" + }, + "5da1653bbe8353134edfff6158211ad7ee21dbef": { + "balance": "1491149937915000000000" + }, + "5da733ef41a7bdc0cf7975f83ed24604fbb4d40b": { + "balance": "10343699901151000000000" + }, + "5ddf5d7306f7c603b8d3ff993f03906dca14cd8b": { + "balance": "862558469755000000000" + }, + "5de87ec54e2160c7c2a8eff2d859414737501ae2": { + "balance": "21579321171000000000" + }, + "5df1b805b1361c1f39ca844aebe5ecee8a8d06b2": { + "balance": "411820472746000000000" + }, + "5df86b0a183b5e7f702e4da582ce9a8116a05f61": { + "balance": "256000000000000000000" + }, + "5e22359e20dc14be6930c6c1ce5a0c81c039cac7": { + "balance": "10000000000000000000" + }, + "5e2d38a06f33c784303abf2012f9af12622d9e5a": { + "balance": "10000000000000000000000" + }, + "5e479e616585e7fa84bd6f7465d394a1c0302be7": { + "balance": "10000000000000000000000" + }, + "5e4a55027a0d372f6da042b7f73720b143347d9c": { + "balance": "16175516772000000000" + }, + "5e52e86eda3e05f96e353d7e3f0ee90f08864f84": { + "balance": "21255916842000000000" + }, + "5e91c4d3a21c9dfac2c0994ed8890c78d58626d5": { + "balance": "325349462011000000000" + }, + "5ea797b18caba45d5504e57b80b12f5f5ae630aa": { + "balance": "7805696321000000000" + }, + "5eaec8815e859c34dba88cfe7b7fe28572c964ba": { + "balance": "145852682588000000000" + }, + "5eb974b5716fc4712d431bec7fbb2c49057a7b84": { + "balance": "4890681156035000000000" + }, + "5ee5f8407dedbac839f509419051106219458006": { + "balance": "3042761975468000000000" + }, + "5ef782abb28d1ca889ceb3039eef98713effbf32": { + "balance": "40915083108000000000" + }, + "5f23b88f06430c42570ac3fa33b1c7503b388a3c": { + "balance": "2376070180325000000000" + }, + "5f2b1641c0f2605b090039851aacf297e35632ef": { + "balance": "141615261000000000" + }, + "5f44cc8083340e644d19d3debc84dc14a0cbc53f": { + "balance": "291829106275000000000" + }, + "5f633f89adcc70e9da0b66611a5da108b4b221cd": { + "balance": "50835573000000000" + }, + "5f94ef8e9612b03a5c6ffcf423ada9a19a40818f": { + "balance": "102566595099430000000000" + }, + "5fae1977b76a5e899b384f572e4d94855f9cb52f": { + "balance": "773616125740000000000" + }, + "5fbd22cb3de462c794e523fd1ce36f230cc84b83": { + "balance": "1009995132839000000000" + }, + "5fd91676bc95bd6b5e69db8b9216dc83ed9dddaa": { + "balance": "1000000000000000000" + }, + "5fdda8f5271a08cf1b830faa497019d75fa9d231": { + "balance": "4149626365000000000" + }, + "5fdea351c5eccedf2394fb54437b149ae423ecf3": { + "balance": "100000000000000000000000" + }, + "5fe70ee123cb2e03c768138b2f71c1e1ea75ad17": { + "balance": "1074496282650000000000" + }, + "5fec9df797214459f85a040a559b186ee9161c88": { + "balance": "205282872821268000000000" + }, + "60037df7e4092466656a6b9571437fc4600c66e3": { + "balance": "1000000000000000000000000" + }, + "6009a0bcf531640a5a7f1664a69fe0f64b564ede": { + "balance": "50170000000000000000" + }, + "601668d8b678c95ec5ef98d9d2624decbdd52e9b": { + "balance": "23592727870000000000" + }, + "6027bafcd0ade24fda8c345dcbc812d59df74bf7": { + "balance": "10000000000000000000000" + }, + "6029514f24825c1fadc68cf8614951de5d53268f": { + "balance": "1389262963614000000000" + }, + "606de6db14272a314d778cf0e67913b7fabea45c": { + "balance": "144000000000000000000" + }, + "6074f20675f975ae2c081930cae8f299710f0bba": { + "balance": "10000000000000000000000" + }, + "60850fa9e09d414af3690e4b5daefb1b906b0d20": { + "balance": "10000000000000000000000" + }, + "60ad0b6239dda5df7ac0f0ca941684cf20ae0fd8": { + "balance": "81000000000000000000" + }, + "60d6136e6db631be45fefb9667c3dfa69e9d6054": { + "balance": "651902184266000000000" + }, + "60d733dedec6886908520ba57cab8c9d5c2d7f7a": { + "balance": "555461746642000000000" + }, + "61202238aea4010d115c5c64322ad790576cee43": { + "balance": "10465801848035000000000" + }, + "6142d92b61111657de4b2d65698a3621411e3adc": { + "balance": "100000000000000000000" + }, + "61879bc1a022d9cac8b7d57c8f528065beb10bb2": { + "balance": "72766025231000000000" + }, + "618b15c9a60ad89e7fc28afc79bbf7f28d4998cf": { + "balance": "444855210015000000000" + }, + "61c1169e8ba43ee6b919e5be2eac19542eb913b4": { + "balance": "500000000000000000000000" + }, + "61f1cd6efce17f5458325f022f363fd9772d8f20": { + "balance": "19704989598372000000000" + }, + "61f7d39211a0af2e226d8cbc95fb673168653b0a": { + "balance": "484884476279000000000" + }, + "621aa67f09e6506efb2fd141f080fb1d96693a57": { + "balance": "1694451603196000000000" + }, + "62332fa5127b98bd2a627a0ac22d3a1bdb418efd": { + "balance": "926882233406000000000" + }, + "624a465696ad409586a2e67d84750ba50a971fee": { + "balance": "25000000000000000000" + }, + "624d866f0d61bdefc3ec2210bfe36b6d51018f9c": { + "balance": "199592183194000000000" + }, + "6255d6d3b49443891661b209056d530ecd63bcca": { + "balance": "10000000000000000000000" + }, + "626c484055e6739d46e2ff25190c8b3a4af3fe0f": { + "balance": "1485276462321000000000" + }, + "62865e637d723393ab9654d6439db7fb5abf8803": { + "balance": "10000000000000000000000" + }, + "628a47761d5ce755de88444aaf6d7736b911672f": { + "balance": "18625552918216000000000" + }, + "62df6a38e8b15a1c4f4a7aa7c1736c612f54a0e4": { + "balance": "16468111299582000000000" + }, + "631d7916ddbb5f7c469f8ba07cd48e377560319d": { + "balance": "2493487426430000000000" + }, + "632754f5afcae7dc36d9286cfcd91c14abf0f7bd": { + "balance": "1424933496931000000000" + }, + "635788343997ea9f145c508b0cd2ed36e180f46d": { + "balance": "143040938538000000000" + }, + "636973e7dbda9e3042a8c03e25696d0faf27f025": { + "balance": "5491869128148000000000" + }, + "63707efa26d34d7ceadf4e6439324e7bde0ebc3f": { + "balance": "1000000000000000000" + }, + "637d92494f7872d397340c9b5183dce354c8c43b": { + "balance": "724687404033000000000" + }, + "63b9c2e6762a431752f7669b8bbedae9f37120b3": { + "balance": "1360967549741000000000" + }, + "63bd281d8c4d1279519237a2b68f2a73c228f7e1": { + "balance": "217457311664000000000" + }, + "63c0eb8c9a0019e36ec9a731b4bd947271a5bed0": { + "balance": "36693488147419103230" + }, + "63c6362eff56de328a29b7e9d32ced28f3602b6b": { + "balance": "148335309448000000000" + }, + "63c979c787a7b037693cadfeda738ae33178c009": { + "balance": "81000000000000000000" + }, + "63d4621d91906215d32f6fbcee1ac48bd773f630": { + "balance": "1006939236069000000000" + }, + "63ff99fec1cbd2f6e83c0e6de3c0ea4b7c7e1398": { + "balance": "1201300688980000000000" + }, + "640ffd856e48528b05d5ef1e60348048ce291960": { + "balance": "20000000000000000000000" + }, + "641c25f7c380e2745c81a268384a029b2e2be0cf": { + "balance": "635133477665000000000" + }, + "6427792a164bbeab45f6c3acf17c76f721b90e81": { + "balance": "10000000000000000000000" + }, + "6437986b4c545af9c4a5ee96371a5807275e9221": { + "balance": "2951152516627000000000" + }, + "64460d09d1bc5c425d62bef5969eb0c5916963c3": { + "balance": "1680000000000000000" + }, + "646381f92216b97abbd86ca100a773eebdf7545b": { + "balance": "211234535515000000000" + }, + "649f73d1cafeb3ab0631432f04c9d08b9f438c22": { + "balance": "248900746448000000000" + }, + "64a239be45a92df83bb85b25f8ed7de5d82313b9": { + "balance": "100000000000000000000000" + }, + "64a3d97f82e3d42eea78bbcee31a95d33767b055": { + "balance": "2511466286000000000" + }, + "64ad579975888f455217e0f801e371900d9814c9": { + "balance": "7118859416319000000000" + }, + "64af5edbfec8adea679951662c08a781175688bb": { + "balance": "822966999709000000000" + }, + "64b7f2c22c20a59c07cb0dd7f8f692153c68f3f8": { + "balance": "20000000000000000000000" + }, + "64bc17e28d468b7b8368ee8a8375710d21c3ac5d": { + "balance": "875002262415000000000" + }, + "64d17aa662e56061cebb3c2e2421e637163e8dd3": { + "balance": "363241251465000000000" + }, + "64d714ec3145308e8f939bab7591b0773038b886": { + "balance": "338231954012000000000" + }, + "65199fc9ba95434382c108b44ac553534a9a3670": { + "balance": "2537340957145000000000" + }, + "6527c67c29e47833dc2440570596023318a7bd99": { + "balance": "555434226832000000000" + }, + "654b9d299077c90768c5ca6635e5802e8099f51a": { + "balance": "119004827465000000000" + }, + "655908513607cc38de35351ff3738b201bbf39d4": { + "balance": "652902936029000000000" + }, + "656ad16063b2d397788c231e537384ece94eb0d2": { + "balance": "63116382606000000000" + }, + "656e622970b8829a7cfe24f5b82696c7777683ba": { + "balance": "20390269890405000000000" + }, + "6583a6ff4dfcf447e3b163a61b0d5cb84ceee375": { + "balance": "3858529344000000000" + }, + "658d2b7e8a6517256efafd74321757d5c384a2b9": { + "balance": "221114751567000000000" + }, + "65920758857ee5b27b0f31487ccc3c5d6986df3a": { + "balance": "16272975796000000000" + }, + "659d60d67a07774ecc5cfea9e56809bec024d639": { + "balance": "20000000000000000000000" + }, + "65a1a3f968bab5fc1f097b8e297099a3d34ef45a": { + "balance": "16000000000000000000" + }, + "65b5e3163d20b2a6fc75c0219b7f97d83479a26d": { + "balance": "1716459529041000000000" + }, + "65c9bc3b8b0ce7c4d16b35abe1a5c285a59f672e": { + "balance": "20000000000000000000000" + }, + "65d5b458d9b1a9659c1125d20d970d5e6c29dc3e": { + "balance": "20000000000000000000000" + }, + "65e75bb8ade25eb7975ea12b9afdb17ac21063b3": { + "balance": "2270407774714000000000" + }, + "65ed78d0c4ef1150e8765b24b210f056e079cd59": { + "balance": "500000000000000000000000" + }, + "664ee5e334b8378928becfbf5d5e51daaf001125": { + "balance": "860160259186000000000" + }, + "6679bdb26adc179d046607d49f4b10c65d8a40d1": { + "balance": "436794739763000000000" + }, + "6680fe9d6eda3ab9fc4ac1ac933339b533eb682b": { + "balance": "551296206326000000000" + }, + "66a1249501cc5076b040bbb165ce032ace216ea2": { + "balance": "36000000000000000000" + }, + "66a475d014c2f976704bfb93ce78dbabbfc5e072": { + "balance": "1140135640169000000000" + }, + "66ae43d92e8fb2231fee8c72d720ff90cdd267ff": { + "balance": "796696150339000000000" + }, + "66b7e0c810d6959afa8210f6ca67e3e40bd24eb9": { + "balance": "16000000000000000000" + }, + "66bf8be16f33b111b2a425743bb7ebcdfbb35034": { + "balance": "538590591000000000" + }, + "66d2eaf7fe10900d93eab17823ebfde5486aa2b7": { + "balance": "121000000000000000000" + }, + "66e525bb01b3ede1a4a105bb6087ec8a76200616": { + "balance": "1506610219207000000000" + }, + "67291e0df83d6e9f1386e87a1792d7d147341df9": { + "balance": "272330177662000000000" + }, + "6730b27b62e064b9d63df3bcbb8c4bbb0e500afe": { + "balance": "331282968154000000000" + }, + "67318617bfe19b739fac9a126fd129223db52498": { + "balance": "12699924981000000000" + }, + "674dd0b036c91f3a83288af44897b4ceb2e15a12": { + "balance": "4352791270187000000000" + }, + "6751bffd04be55c86692994fed06694cb78b62ff": { + "balance": "26049487516000000000" + }, + "6768d99a0cdcd7bb7c7d0aeee466d6bdc7208bbc": { + "balance": "309909685000000000000" + }, + "677ba2de3e5c68a4c354c9e3129ed1c41025312b": { + "balance": "127426274611000000000" + }, + "67b83745856551f1878027843be20e1473191944": { + "balance": "185757248875000000000" + }, + "68170edcfaf2c6df4e6542b2856ad33e9e2d6623": { + "balance": "4003453949471000000000" + }, + "684ae403d9a08e4f4f971cfedf81094074daa77f": { + "balance": "25139713925794000000000" + }, + "684f3b8a749c002aa434bad6af7a3e2579c69315": { + "balance": "16000000000000000000" + }, + "68538a9e8246be5a5c5ea315cb325344062cf8c4": { + "balance": "14009193210480000000000" + }, + "68935ff3a3a3b6ef16ae7df58cee50b157658dd2": { + "balance": "20000000000000000000000" + }, + "689f508256ea64f5dbd6bb77f1ce1bdaf36d7152": { + "balance": "10000000000000000000000" + }, + "68a3e6e7c191a8c1add988bfbbb9b51d4f36f521": { + "balance": "10000000000000000000000" + }, + "68a74ff2a5577321f854b56d3834a55d3c41bd94": { + "balance": "88873831171000000000" + }, + "68e6da521bde13cf4e4f423a78fda2f69b3d1c2a": { + "balance": "538392460838000000000" + }, + "68ecd5cf8cf8d9704fafc36d8da53930afeb0553": { + "balance": "1090923641219767000000000" + }, + "68fd0b8e000bd2788be6cb10fc0496fe2cbe155d": { + "balance": "32853847745000000000" + }, + "6904045feb5ef94e096894b863d314ff8a0f206b": { + "balance": "9892165615000000000" + }, + "690fbae5153849bb20797af7b8dea66a728a06c3": { + "balance": "6082107223716000000000" + }, + "693d909842877d017e0f102e37a55024517dd0ae": { + "balance": "20000000000000000000000" + }, + "694cd00fac9cded484ef2cfcd44faf161354f288": { + "balance": "3049716150137000000000" + }, + "6964c3c2c7bc719ec94a51bc4bf412e137d2b4e9": { + "balance": "1000000000000000000000000" + }, + "69a5c692516940bebad8efaa2243a8fbdf2ade62": { + "balance": "2803346939929000000000" + }, + "69f566c44802b0140f5e1c9234f46006773c03d4": { + "balance": "20000000000000000000000" + }, + "6a17eef3a6bd407260f52067592226448182cdc3": { + "balance": "1116509364305000000000" + }, + "6a200e99a0f50aab32fa7373c7880817c81f472a": { + "balance": "1836680122795000000000" + }, + "6a2a29f5f441876816dd17856051040787f48a64": { + "balance": "1131603204000000000" + }, + "6a3f855c7dceb75d0de7fa18fbc2f40c81b76756": { + "balance": "32267494586000000000" + }, + "6a46af653b938643e781cc4a0edcf5357852fd21": { + "balance": "1140718780752000000000" + }, + "6a4b2e5b45da0d70621ce71f165a11078a1745e2": { + "balance": "3768326643000000000" + }, + "6a530c813595a5b7776cced05a865dedcb110d94": { + "balance": "270559347097000000000" + }, + "6a6e3e82f98ce891f47721770301dbe2652a9e25": { + "balance": "10000000000000000000000" + }, + "6a828d6f2f7f68bde4a12608024020e593540010": { + "balance": "7531817000000000" + }, + "6aaddd1f4ff6b4d414c87271619b826ead27f09f": { + "balance": "64000000000000000000" + }, + "6ae6bce1e2865ade0d02eff9899ea3767b5511cd": { + "balance": "6893781798524000000000" + }, + "6b04e7c6a837d218fd3322b87a267fdd979358ef": { + "balance": "302679180175000000000" + }, + "6b2210b8536803b134e69c5046904acafef48cdd": { + "balance": "47823456459000000000" + }, + "6b2da6f36c2e7f61cabd7580480065360c995c93": { + "balance": "55000000000000000000000000" + }, + "6b3401986f2be7ae5a4ec160b8f96b2a651fce73": { + "balance": "16000000000000000000" + }, + "6b3847774e99dec307dcf5bf5adba49df4a9f145": { + "balance": "43276069579000000000" + }, + "6b57f2d9d95cac67fd2f70c0911d48c7f09de072": { + "balance": "1000000000000000000" + }, + "6b65d736a8ca89ec8508b52e4aca5166f9703732": { + "balance": "766421968820000000000" + }, + "6bcc55d897829e98fc3f3ac8beb331e59c33b942": { + "balance": "318115956882000000000" + }, + "6bd76e7af1775b88743d5f53ede0ce846d3d7ced": { + "balance": "139548017482371000000000" + }, + "6bd7cca99acf6eed5842417c2327c642df5473fd": { + "balance": "3321731000000000" + }, + "6bf72c4d39d6700181954a8d386c3df216634412": { + "balance": "12742769034078000000000" + }, + "6bfd3aedeac7c6ec086c0a4ec29d2d0f5bd69bc5": { + "balance": "50000000000000000000000" + }, + "6c025962810a6fb8374af5e07d7fcd631d10b1ce": { + "balance": "674126722005000000000" + }, + "6c1b72df836f410038af9e020fa2ff2ead398ef4": { + "balance": "1851293017364000000000" + }, + "6c1fddb4254ff46b3750de322ebb7d6238c0a606": { + "balance": "9977629348276000000000" + }, + "6c37069a361c5c72355bb5a56879dd0a9735a237": { + "balance": "1062230154063000000000" + }, + "6cb166eeca248a234c971b2a864a7b3fdbe5a737": { + "balance": "390222992865000000000" + }, + "6cb797289059cadcfa77eab0365e6bf1ae12df46": { + "balance": "100000000000000000000" + }, + "6cc787e6bb4f484828b080330667b93953e7a3c9": { + "balance": "16106440380234000000000" + }, + "6cdf7b334fb2ef8115198d475d431eeb7d88df77": { + "balance": "1940904395351000000000" + }, + "6ced85b035b787e9e427d0904aaf96e011417310": { + "balance": "103417697874000000000" + }, + "6d6e09acc07f388cbab99e53959f75e9ad8f07bc": { + "balance": "1305917678000000000" + }, + "6da91b02f512f412d374392247a9aaa853e9dd59": { + "balance": "2300525907893000000000" + }, + "6de5d70481cd40db468f64227228cdd362ad9980": { + "balance": "10447389944082000000000" + }, + "6dea87255c9ebfa63f017209046e894ecbbc03b7": { + "balance": "1527216854064000000000" + }, + "6df6f6b9953c2f2a8ce5985e19dd6835ae2c566c": { + "balance": "6539856530000000000" + }, + "6e013c83cac111a38fbbf8d47778fda0d3af25d5": { + "balance": "12139181929380000000000" + }, + "6e18a484f402fd433a5ac4dee5a4b8bf6f22db47": { + "balance": "23215906572368000000000" + }, + "6e4fd058e4dcd502c2015f83f3677f680ec58110": { + "balance": "480059342014000000000" + }, + "6e501ac7357fc758caf5dff6c29a995c806a1a7f": { + "balance": "1573491311733000000000" + }, + "6e6912f9fc21dfba736055e6ccef074dd62dcc59": { + "balance": "256000000000000000000" + }, + "6e869c68511c1458f4fbed9a4c5296fe961eb47e": { + "balance": "68488423994541000000000" + }, + "6ea6827b377b3d3ecf7c7628ed8daad7fd8eab1e": { + "balance": "188825714738000000000" + }, + "6eb9237738339fcaad3763466509f23efd0c5054": { + "balance": "48417242786000000000" + }, + "6eb92a61390f9d9ecdac80a8833aa801c3926b13": { + "balance": "1412936326723000000000" + }, + "6ecb93f18153ef2d2a552286ea3b7436f1f8168c": { + "balance": "20272577229669000000000" + }, + "6ee087c04cf16f4768c783a548686448fd125914": { + "balance": "1397039628538000000000" + }, + "6efbae7a34c71233329d0bb4cbec45274824ebf4": { + "balance": "8910000000000000000" + }, + "6efcd6776f287c25a6eb3cf71018adc282eeab6d": { + "balance": "1310659853178000000000" + }, + "6f9ca805ddaaea5205e85778dedb2eff4a5aaa75": { + "balance": "2585733757016000000000" + }, + "6fbbea927469f4d18942ce0aade164828fe23a2a": { + "balance": "4671857880000000000" + }, + "6fbe9df6c42151c453502960d99170445dd3ac0a": { + "balance": "20060296562115000000000" + }, + "6fed121fb310431f1659e637f35f4c878a7256c7": { + "balance": "55170085399000000000" + }, + "6ff2dd5373bd72966ef48d3183c60d74a6549cb9": { + "balance": "24103445361000000000" + }, + "703a490c4783776da244384c964897491aed3711": { + "balance": "2001677632732000000000" + }, + "704dcd2d9f75f0bbfb73f2fe58bcbf4508374381": { + "balance": "439603954369000000000" + }, + "70859a14f33b8ab873fa5781a4af1ce40dff65c0": { + "balance": "10000000000000000000000" + }, + "70b9cdfa5f6d41c60e1c0d3f544f569c9b340ea2": { + "balance": "198355566698000000000" + }, + "70d0ee793e28e320b34267ef2df69050fca0a9e0": { + "balance": "8010660534227000000000" + }, + "70dc7e5951752c22a0e3c50e8e7b1f7af4971d51": { + "balance": "3991137321749000000000" + }, + "71057f5afbed7d82c92d50790e3797fd7395d036": { + "balance": "49000000000000000000" + }, + "7109a3b3d5d6af49693549728691099d696ce016": { + "balance": "4119694297000000000" + }, + "712231a5161745fa1b33c7b0f6e8c767e1de4f81": { + "balance": "1353809351914000000000" + }, + "712aa38999c0be211654e5c84f59e3b2e018f597": { + "balance": "160199774000000000000" + }, + "713229fc94a86b71a5bd1ea6498b9373e3f3c549": { + "balance": "98289185940000000000" + }, + "715de29a0b6f467b94d4a90dc767ad52d0fb3b9e": { + "balance": "948824982990000000000" + }, + "71776853ac97ce04b008c9a7b64156a3cafc52a4": { + "balance": "608309596513759000000000" + }, + "7189f6dcfe64e1ddbfb5e51fd5f3174bc636dd0e": { + "balance": "5674608906899000000000" + }, + "718a4da87464caf6e83ca374d5ef9255b8f7cc3e": { + "balance": "761891873568000000000" + }, + "71bc447761cdb68915cc2288b4929fdc0adce02d": { + "balance": "10000000000000000000" + }, + "71d78531896642069b725bf82fc385789c63217c": { + "balance": "33103960195000000000" + }, + "71e328deeafbb1724051d1062609c43eef56ecdf": { + "balance": "493550967964000000000" + }, + "71ed0310fb51b86a61794aea17a3c792dd301e3c": { + "balance": "3234918634449000000000" + }, + "71fa264f58041e41cfe36e8f8d4e0cb22ab71925": { + "balance": "5558941960000000000" + }, + "72059c57d0fc05bc02ba54ebea6cefd1efbeadf1": { + "balance": "4458278271443000000000" + }, + "720847a28916a532bcab33e1fcbde5d1c4d820bc": { + "balance": "1392418942284000000000" + }, + "723cd2b5b836b0ee8481d37b9c51b5f3f1beddd2": { + "balance": "1856420455522000000000" + }, + "72430c6664d23c7051b0e99912fa54dfadcfdeff": { + "balance": "102078926010505000000000" + }, + "72652c4320dda25348f15c0ecfeb4b3b3ceeb7c8": { + "balance": "307639955659000000000" + }, + "7288bd1b9f4c068dd5df9bcd6fec1ccecd240195": { + "balance": "80161087899000000000" + }, + "7299cb8a288abe8e1a22c11b53a903acb7db5827": { + "balance": "752198565719000000000" + }, + "72f6bc0c3ae437756c099e02e9c084febedc5569": { + "balance": "696294297587000000000" + }, + "730e5907b344c80e0a6115723a90a23e3635192f": { + "balance": "6056082041729000000000" + }, + "732e97b992e4f8a53034cf29cf11aacba7452261": { + "balance": "100000000000000000000000" + }, + "7339df65ce293b3d501647a04c83819099f0bd38": { + "balance": "706500983417000000000" + }, + "73482f8135ca2231db5e0e034a235a9d244a8656": { + "balance": "1143989148865000000000" + }, + "73769e43058d30a530048e5a2bea7e9333534e93": { + "balance": "113542901996000000000" + }, + "73bb9e6f1709fbb7964df7b3cc0f9170c3152f38": { + "balance": "1639793026701000000000" + }, + "73e261da7978764044ee916f88bf66680952607f": { + "balance": "100000000000000000000" + }, + "740154120c4f41c50b0aaa0636a2000ff1e870ad": { + "balance": "10000000000000000000000" + }, + "741fe2a1537284b70e97e3ff659eedfd7fc5b1b6": { + "balance": "75911502037000000000" + }, + "7420bb277d834763e4429db9bf37f053f71ab769": { + "balance": "3100160195046000000000" + }, + "74281371c3b569c774da6bab686e7d7a45d4dc4c": { + "balance": "25666397941223000000000" + }, + "7428d261b5418652c5ab248d6abc3d2af25d904a": { + "balance": "56252809397000000000" + }, + "742c876433297f5a8fd4a25f75ee9a607726bd3c": { + "balance": "4132793019677000000000" + }, + "74302036cf52e11aa3f32a371bb4992e2bdc3f39": { + "balance": "19557661364000000000" + }, + "7445c657c24d014f3a9dddc3e446868bc2dbd13e": { + "balance": "10000000000000000000000" + }, + "744b8fa69d2542be3557267edaeaf2cfa8a9e991": { + "balance": "16000000000000000000" + }, + "74728999963524e7cc1736abcb4deac630142c44": { + "balance": "37000250991000000000" + }, + "74926cbdacd0e871cad0d926c8e17cb2c00475b9": { + "balance": "20000000000000000000000" + }, + "749e115a9e675bb15af5e1c04f81fede07c40120": { + "balance": "440913547154000000000" + }, + "74b7e01acf825898544d6c1b61e53356be759c56": { + "balance": "25000000000000000000" + }, + "74c5fcf875e2e9b726a7cf6e176dc2f7eb84c200": { + "balance": "59208835472000000000" + }, + "74f44579859e4a7944dda7bd810088e116ae9910": { + "balance": "1038454108527000000000" + }, + "750b1e2955ba05c1fc8a1f9dbb1624ed11587edd": { + "balance": "9545712605000000000" + }, + "75375129cff2a051f656b91f868325c3b35ee1ae": { + "balance": "25000000000000000000" + }, + "753ca28fbd89081382a996fe938da7e6c3ae6cfd": { + "balance": "156582454263000000000" + }, + "753d91c04e554680cc32a97c1abc96280e8263ee": { + "balance": "725101425969000000000" + }, + "754e5b5d64c267e83fd4804d112725531cf5abe9": { + "balance": "83276113115000000000" + }, + "7588a96a2bc65569a6c124c4a4acc55863a8ab78": { + "balance": "24062602342000000000" + }, + "759075dc3a6b9d2499a74bc57e346c9ed7ff834e": { + "balance": "225000000000000000000" + }, + "7591d6fa043801fe12462e11d9e33a53f438c073": { + "balance": "1863874274000000000" + }, + "75bda5bdf6aa749bbd62b6107941a7dd9ce3880a": { + "balance": "36000000000000000000" + }, + "75c2d3a99f144c4b9962b49be9d0a81b203906e8": { + "balance": "9000000000000000000" + }, + "75f587a69a97eb4d1c4c4078418d5fa85dff6f94": { + "balance": "10000000000000000000000" + }, + "75f67649605f49d98d866102ea2d6881ead9bea0": { + "balance": "814929108418000000000" + }, + "7602abce0f510b6ca471fd8d734e21a2591886f6": { + "balance": "50000000001006000000000" + }, + "7629b788160531b0be28bf445bf305fbe2c514d2": { + "balance": "23022256366212000000000" + }, + "762aed2e3aa2293e69dc2110b1fc6c806ae799a5": { + "balance": "10000000000000000000000" + }, + "7637b89130bc3f87e90c618fd02d6dd27179101d": { + "balance": "77765738300000000000" + }, + "765136022facade53e7a95c0c7aa510787e674d5": { + "balance": "1478178932688000000000" + }, + "765274015a308a9e6b1f264e5bac592d267f2f7b": { + "balance": "3058788819393000000000" + }, + "765cbc0a89fd727a2c1a6b055139faee53f11330": { + "balance": "500000000000000000000000" + }, + "768bb6d4b190c18a0946d92073ee446d68d98a6f": { + "balance": "144000000000000000000" + }, + "76ae8079894c760f2850c02cf5a0d7bb41e5864d": { + "balance": "156059816821000000000" + }, + "76af4103a231b1302d314c486a0ba524d0427899": { + "balance": "10000000000000000000000" + }, + "76b6394cd02ddf761e981b6a6ce1654c0e575443": { + "balance": "1078304803757000000000" + }, + "76db33eafeaf965dcf15d5460b64a48b37285259": { + "balance": "1000000000000000000" + }, + "76e5721c0a39d41274f84cb572039967a07e9beb": { + "balance": "156298167226000000000" + }, + "76e6ca6ef145d2711ab27f82376a065cc6f62a29": { + "balance": "100000000000000000" + }, + "7705d637cf9f6ceaa452deaca7ccc581beb5fa34": { + "balance": "36254762908065000000000" + }, + "7706c80af4eb372e168501eedfe7bda6dc942243": { + "balance": "50000000000000000000000" + }, + "771493da92c9fc6c6b39a4071ae70d99f6a588d3": { + "balance": "2000677471360000000000" + }, + "7719206286f26144c0f20b5e1c35cf4495271152": { + "balance": "1380480863056000000000" + }, + "771adcba1409fa2df6db19d9f784abc81a7bbf36": { + "balance": "15416381820915000000000" + }, + "772f7baa80a852e05b2fb3903a36061da132b2d8": { + "balance": "121000000000000000000" + }, + "7731a4175eee5077e2ede48878e6e2a18fce0f9e": { + "balance": "10000000000000000000000" + }, + "77385deeba01e3cd7a63e13d6048011020f56724": { + "balance": "57204247488000000000" + }, + "776808e7688432755b9e91a838410d29e532c624": { + "balance": "120318608715941000000000" + }, + "776d1b406f63082b80e250c4a0073fa0d83b9090": { + "balance": "243779839900000000000" + }, + "779848a59036ee3cd23b93ff6d53620d874f0bee": { + "balance": "82228810849000000000" + }, + "77d02a031274bd4ed2a16f3cc29d94e755142036": { + "balance": "408567696646000000000" + }, + "77d609a407aa0d126d58090b8d635f5ab7a02d6d": { + "balance": "776754055755000000000" + }, + "77dec41e116301dbd6e542f139816bfd9bf6d154": { + "balance": "16335989583000000000" + }, + "780398b42f81167731a8ef6a8bd1d14942b83267": { + "balance": "25000000000000000000" + }, + "780a645d59027e7b0670d9565898dc00704cbe5f": { + "balance": "20000000000000000000000" + }, + "78182a7711c773f306ec42ce6da3e983cd49b00b": { + "balance": "580861257254000000000" + }, + "7822622f07fec12995c4bb8eb32d62aa7f00be05": { + "balance": "5018461926846000000000" + }, + "786410c679101c0ebf06fb4f36102368121f3c8b": { + "balance": "16098386724761000000000" + }, + "787d5476038ab0a09b846645285ada23ffd7318c": { + "balance": "492047430907000000000" + }, + "788e9e27ed979d1e7aefadda798f69df1de1d1bd": { + "balance": "30965301214000000000" + }, + "78ab2d2dfaf5d2580ed89c970e771572bc91d3be": { + "balance": "36000000000000000000" + }, + "78ab7ac6f379ff084a7acf4a1a31fe2e5a6834c0": { + "balance": "107332516726000000000" + }, + "78aba95da37385c736ef93d0ca8318baf6c5ff3e": { + "balance": "9000000000000000000" + }, + "78cecbd82229dc91a530bd555c9e45125e2a6bc7": { + "balance": "28474069251604000000000" + }, + "78d4df90990248f3ac67e492a0a1e3f4ee455507": { + "balance": "10000000000000000000" + }, + "78f6de3768abc604c49b10d798e0656948cd334e": { + "balance": "9000000000000000000" + }, + "7909aca95ed899743de222e56c231f9bed1b518a": { + "balance": "5355599376491000000000" + }, + "79193e660b4431e8aca9c821b7daa88064e33750": { + "balance": "100000000000000000000000" + }, + "792487caa23b0d9b9998002810cf29439f7190bb": { + "balance": "4828579961131000000000" + }, + "793f56adea51063243a9633ecc1d1e620a91f327": { + "balance": "926742377449000000000" + }, + "796d187077c1d7591583436ae64d10a641490ca5": { + "balance": "242664407084091000000000" + }, + "79a6b7fad3b5a655679450ca82818ec2d6f58688": { + "balance": "1400472715109000000000" + }, + "79acf627e67cedf48297c26fd135973bff6c57da": { + "balance": "444598475759000000000" + }, + "79ae0dda1964ff0191b98d28c9b52a79dc9ab078": { + "balance": "325908985422000000000" + }, + "79e71dcc52fa1b28226c519f715faa3cf63cfb09": { + "balance": "497898493594000000000" + }, + "79e98193ff8770f26af824734bbb1c2ce8197b6f": { + "balance": "10000000000000000000000" + }, + "79ff3d790d52c58b7317a415278e9058915d5241": { + "balance": "48502649691864000000000" + }, + "7a0b02d16d26e8f31e57106bbdad308f513d436c": { + "balance": "841000000000000000000" + }, + "7a1d422352ec7e6ca46131728e4b71f20ed84e2f": { + "balance": "50496873413000000000" + }, + "7a2a3fbe27e33df867ba8800788995d7662c046b": { + "balance": "100000000000000000000000" + }, + "7a629c4783079cd55633661d2b02e6706b45cf8e": { + "balance": "50000000000000000000000" + }, + "7a62d8875f53e54b775ee2f67f7e2ec137bf724f": { + "balance": "25000000000000000000" + }, + "7a67285fd883d36ea3107aa3fe7727c68a99eb2d": { + "balance": "254787158217000000000" + }, + "7a90fbec48492473d54b0fad128ceda94ea66100": { + "balance": "313715004199000000000" + }, + "7a9e11463d84a08140d698972e32e66bacf7a7c9": { + "balance": "3602603216258000000000" + }, + "7ac4f33e1b93ef0f9c15014e06da24904ef4419e": { + "balance": "101000000000000000" + }, + "7ae082ad247275fd5a9e77b127cee5693784e9e1": { + "balance": "1921957343533000000000" + }, + "7b27e070ca4158d13f8333b34842d4c28b678c92": { + "balance": "10000000000000000000000" + }, + "7b2e34374921e4dc10fd9cfc670a40f5d092da1b": { + "balance": "2098457950503000000000" + }, + "7b54c6c8041c8b09240de1ff06e0d3d2d8d877e0": { + "balance": "944752036841000000000" + }, + "7b5aecb798d8f4f5a04bdaef909e09a35bde8d47": { + "balance": "21975115049000000000" + }, + "7b88a7ef9201966bd1ca634779c3b7f40c22f0d7": { + "balance": "64344833519732000000000" + }, + "7b8c22ddc5c7e59e571587d7c776fa50e65f4845": { + "balance": "225108110445000000000" + }, + "7bb4d8a169f72432494ac362eeab005ce1e02d81": { + "balance": "2098993419448000000000" + }, + "7bbaaa6690698e749d095447bdd27207c0caee43": { + "balance": "490069993631000000000" + }, + "7bbf27f92f9f726381d4f68b21ed86af8f792d04": { + "balance": "806346082666000000000" + }, + "7bc6f172fd78953c3456c571ac8394756715d5fd": { + "balance": "81000000000000000000" + }, + "7bcca29b477730ee8f219a5d1bca24415c7a4625": { + "balance": "36273885000000000000" + }, + "7bd296e1cb29ad87ed28b0ed18440ee686b157e0": { + "balance": "35964679698000000000" + }, + "7bde6d49a1af34a5a9dac0b9007e9a5583c65ebd": { + "balance": "1041474566346000000000" + }, + "7bea6240f245e649563253fa4c1da39b12625da7": { + "balance": "100000000000000000000" + }, + "7bf096396c56f27f9c39c4056ee6cfcb0db44bc6": { + "balance": "407261849111000000000" + }, + "7c3b58d3ba283bd9b1580832e9d014eff48bff7f": { + "balance": "7074518779349000000000" + }, + "7c5a56c45f23c353ff9f6f71ec86c9a6a1a0ca67": { + "balance": "11277879639596900000000" + }, + "7c783ac9b07bc6576835635f37e7e3c137055c8c": { + "balance": "16253676225000000000" + }, + "7ca2fbc0a0d1370e95048a21a300eac4d6056df3": { + "balance": "2772084065617000000000" + }, + "7cbe95802a20eb765f9fcff0a068859cc35d2660": { + "balance": "255153842674000000000" + }, + "7d004fb3a6a81c00fd2872e8079ad2912841b0e0": { + "balance": "642630220843000000000" + }, + "7d30c788d4ea18849ebae1173373c8915ffd7a35": { + "balance": "61062263242000000000" + }, + "7d39324f5ff62e849b0f0f46ab8ee396fbd85581": { + "balance": "100000000000000000000000" + }, + "7db0ce6c04537417dca1dd3415a5bf213edc2028": { + "balance": "30393443462000000000" + }, + "7dcfaa795586c92f1ce7d5c7b10608fe6a773fe4": { + "balance": "183173395920000000000" + }, + "7ddd111cfdc3133f59b82568e3deefc3cf10b0d0": { + "balance": "5622149283840000000000" + }, + "7de81daaa7ed5cbf4d379cdd26ae353cbd5a2489": { + "balance": "10000000000000000000000" + }, + "7e0a11af993a41626c5564f719442c0dfd608ec5": { + "balance": "1532083534600000000000" + }, + "7e34971b187047e7f7980650630b936eedc11023": { + "balance": "10000000000000000000000" + }, + "7e5214e16851b33c4a4d29e5a06929461d3d9555": { + "balance": "371790231197000000000" + }, + "7e52ae9c7e4b888015a3a5af7a91444510aa18e2": { + "balance": "109879329128000000000" + }, + "7e69b383671f96b7abc2d1fed8b61477b87a58dd": { + "balance": "10000000000000000000000" + }, + "7e733b1fcadc9a20dc038fba74e236af0b5a39b3": { + "balance": "43583614302000000000" + }, + "7eadcf955c90040668fb0f75a61f687e4e41f314": { + "balance": "332201682206000000000" + }, + "7eb51f3ead1dd0f5384c199ad5518ec55f77d35c": { + "balance": "38487884822000000000" + }, + "7ee73c0d64caf46f47f439969060092ecafdecd9": { + "balance": "15063618320000000000" + }, + "7ee8e4c6742a4c6d8efbfacc4d56119bc6c74ea4": { + "balance": "31882319329000000000" + }, + "7f16d981521c06347db8324da38b25eab3cee23c": { + "balance": "400000000000000" + }, + "7f6ff7db81a26fe78dd80636f0b178c669344393": { + "balance": "10000000000000000" + }, + "7f792b094c0b96d6819823cf21bc0c402fc27bf9": { + "balance": "50000000000000000000000" + }, + "7f84ae97c21cc45a7e56603ddf97449d803fb246": { + "balance": "81000000000000000000" + }, + "7f89c2b9daba034841f19ae843cfb6cd6f75b1d7": { + "balance": "20000000000000000000000" + }, + "7fb18f8b0e1fd1ed8c863a66226082bdc0429ee6": { + "balance": "11465417544634000000000" + }, + "7fb4e30579c64efe981d0057204e5bd8770a1f87": { + "balance": "249801873762000000000" + }, + "7fcc4de10e837d98691acc52732e1568c890304a": { + "balance": "1000000000000000000" + }, + "7fcc77798cd50345b2784a78b81a25dd4c1e64ab": { + "balance": "2676882485895000000000" + }, + "7fe33e773a02b995278ff595d55a0741813b19d4": { + "balance": "5788279057355000000000" + }, + "7ff32b13d531ceef500ca6c6806ffc0773639264": { + "balance": "1000000000000000" + }, + "801380158ef8f24316bdceaa00eb89c3d886707e": { + "balance": "35627521347898000000000" + }, + "804fdccdc8603858d15dec88666437505b2a106a": { + "balance": "14607090269617000000000" + }, + "807915567eed99bb9146354a32409812b9490d70": { + "balance": "1083142734057000000000" + }, + "8092ceeb2be5b271f4c156d85fe14977e919c7e0": { + "balance": "761607160308000000000" + }, + "80962bf961d0d713395dbe00379a6e207b425a76": { + "balance": "524215754483000000000" + }, + "80a9787124075c8cd44b9c8674967a54445e2354": { + "balance": "7600078997429000000000" + }, + "80aacd59dd76bf443c47ca02976178af8453f23a": { + "balance": "411856023767000000000" + }, + "80db788f7fbd7613f0fff66c21389eedbbd4bd35": { + "balance": "956888725645000000000" + }, + "80e449a70e3c7707d6441ae8863a44aee2d7f3f2": { + "balance": "16260784762856000000000" + }, + "811a2c3d0ba4e1c36a848495585da824ec3a7620": { + "balance": "36000000000000000000" + }, + "812a3c55234d5849a854ad76891c34ee90c8a0e3": { + "balance": "703378980438000000000" + }, + "814b4b5eb67afb8d1a60e3d240fe804bb752f632": { + "balance": "17578964576000000000" + }, + "817025619f37838470b90d0a25af2c02de80dae6": { + "balance": "96000000000000000000" + }, + "817233a104d87cac34d9c90243aebd7f68e0a9ea": { + "balance": "510051038684000000000" + }, + "818be95c0c13c3018b4084ea177556705e84c1f5": { + "balance": "332239667000000000" + }, + "819618c19a4a490b821f8156c5633749ea782ca2": { + "balance": "10000000000000000000000" + }, + "81a80d26b70626e07e8747bc1569dd2855834f7c": { + "balance": "521696417321000000000" + }, + "81b2fb0db882bf2538cf8788bae1ad850cef3bab": { + "balance": "102457067052000000000" + }, + "81d4c3bf72837b21203b2a4f90bf42fda10acf48": { + "balance": "10000000000000000000000" + }, + "81df59e5d7b9a2db5463b53be83b4d7c7673d163": { + "balance": "887372337013000000000" + }, + "81ef38d074e0aa9ad618deaab01bcd135301fb67": { + "balance": "24072930558567000000000" + }, + "81f3a4c5291f13f8f97a067a6ed744a686331eaf": { + "balance": "56612148225000000000" + }, + "820610d0ddd3e9f3893f7cc13f32b1ad0d169f81": { + "balance": "50000000000000000000" + }, + "822d6388145e96cdeb2900420a0e0436e940b670": { + "balance": "20000000000000000000000" + }, + "82323b748fdee9f18e34aefc4ddebd4993ac6293": { + "balance": "112752706047881000000000" + }, + "82324995b36f4ff15be3559ccee14742d5b4c75a": { + "balance": "1184047304377000000000" + }, + "8235bfba0bf0fb664271ebe534616456a78852ce": { + "balance": "6804584686000000000" + }, + "824df7b17a61392f88f7e3067f8c261abb48806b": { + "balance": "144857897574000000000" + }, + "82555a7aebfc95a01a3773aa5370394cadef0302": { + "balance": "40069354268401000000000" + }, + "82831d451b8f92fbf6a763adb708010a3e66bb60": { + "balance": "8750983992240000000000" + }, + "8294176178418f46bb18440cc87a07cf40c1669d": { + "balance": "4439783816461000000000" + }, + "82a1c733c3c937ba0a1a49481e4d1f6226157d2a": { + "balance": "50000000000000000000000" + }, + "82ad0b5dc23bc763da0352f5983efceeaee6ea08": { + "balance": "171723633433000000000" + }, + "82b4a3d16655fd71f4020e6a562592a621ff6e1c": { + "balance": "190211621484000000000" + }, + "8357d5a016a00aa5e3ef05d3ce210826adf4c501": { + "balance": "10000000000000000" + }, + "836c41d7f9e72131eff839b7d510fd0ed412f939": { + "balance": "15575572364757000000000" + }, + "8377fff2b0eb03393543ddf5ffae90b3311af5d3": { + "balance": "2058810049054000000000" + }, + "838859e6fd751539a88d00581b0e19bc98c37e47": { + "balance": "338264241636000000000" + }, + "838da0414211392b644e73541e51e9f0fba26615": { + "balance": "20000000000000000000000" + }, + "83958896a43d23ef4ba01bdf6757c36105985096": { + "balance": "9000000000000000000" + }, + "83b88314b606df40d5e716df488980bc64125b46": { + "balance": "10985538717083000000000" + }, + "83bf53fa162e1d85751be0bc6f46e8ec881392e2": { + "balance": "1497107276676000000000" + }, + "83d7c52608b445e18fb1e28dc6198908d66bb6d8": { + "balance": "265446362740000000000" + }, + "83ee8ebaed62092d2116de6b4e90778454e8dfc4": { + "balance": "1000000000000000000000000" + }, + "8402fe573658250f50fbe111596ce35ea9ec01ca": { + "balance": "3479737676000000000" + }, + "8412b877e708a7d5db2a38d9b0f4f23d12231f63": { + "balance": "9225027744855000000000" + }, + "8418dcc09fe052febf2946ee22bcc8c53d548eb6": { + "balance": "3000000000000000" + }, + "84199f54ef96bda5e14f60aa1723e811f755d3bb": { + "balance": "129197612052433000000000" + }, + "841b1400f97ecd2ca008e7b4f5a95274bc3e99dc": { + "balance": "2095180906854000000000" + }, + "844177191a120d2dc4be9169ddbc3b5430e9e238": { + "balance": "3620793599287000000000" + }, + "84578fcffc73be7d65bfa81b0cdafd26885bafbc": { + "balance": "37592478429000000000" + }, + "8460acb05c6c476ca26495aec7224c2bf90996fc": { + "balance": "8999580000000000000" + }, + "84696cdb9f018d3e7bf453efdc174e1a586e9c25": { + "balance": "118007806297016000000000" + }, + "846a8a91d2890000d1e995fc1663cf5b7c22211c": { + "balance": "27266838638307000000000" + }, + "846b5ef52d5f7ccc17d9c7e5f49db807908c63f3": { + "balance": "375423381758000000000" + }, + "847409e5d6ed2c4e54ff97f2ed58217ac5fc3d68": { + "balance": "23972870617025000000000" + }, + "84bf432c967540caafb8bf49cdc9983e8953a18a": { + "balance": "453476687224000000000" + }, + "84eba1bb76f7a3f6d2b9052d068cc6c48d449d76": { + "balance": "17655334922000000000" + }, + "851245ef1637a07578241b3c35acf215908e1898": { + "balance": "1269389304110000000000" + }, + "853708e974fd4810655d9cd19fc8dbfd3d5e1e36": { + "balance": "18000534000000000000" + }, + "8547989af8c99a3432038a03d3fb30a054d90413": { + "balance": "10000000000000000000000" + }, + "854ba39bac4c7bf619804b6773fe43bc71f3255d": { + "balance": "15999580000000000000" + }, + "85636f3e113cbe1d1bbd1b3a23e9e98edbcb94f2": { + "balance": "1199038399611000000000" + }, + "857167896b859394babf897c4c6fa57b3a057117": { + "balance": "921057404898000000000" + }, + "85799226a1474371ca76f05597a1e3835c17e7d7": { + "balance": "562141544946000000000" + }, + "85a2221cbbb47e8b74fc2617d6087a98f47e2738": { + "balance": "10000000000000000000000" + }, + "85be0bd55fb9143ff17387914a82d0a2650224c4": { + "balance": "4038654147145000000000" + }, + "85c5ff0e4956ef0fb662a2cbf6a86325a53dac8a": { + "balance": "28690160424000000000" + }, + "85caff4ec0e1719ad963e97c1c02828683070370": { + "balance": "2022427900763000000000" + }, + "8630cc2780fee566f172ed0437264c45421ce675": { + "balance": "669721278148000000000" + }, + "8633d245c5f1b63403e3d7828dc197ce1cfafc0f": { + "balance": "10000000000000000000000" + }, + "867ccceae3192a27751d870ae13b1d3d2c3584dc": { + "balance": "1491436265909000000000" + }, + "868bed241f77983ff4a7a8d0bf121299b6b2248b": { + "balance": "5600000000000000000" + }, + "868ddd283a76a26c8bbb9761df3ca647bea267e2": { + "balance": "9000000000000000000" + }, + "8696e546f96f6e51f405905e095902db8bb90118": { + "balance": "533558981421000000000" + }, + "86ac0eae4e4c20cb7019325f4dbebad053f92213": { + "balance": "697960117764000000000" + }, + "86bef47f9d2cd7526495454eb4d1737510696a5f": { + "balance": "2938307902381000000000" + }, + "86ddd4e3f444b395be8b2b2b75c35c78877fefb7": { + "balance": "15615434748526000000000" + }, + "86f115ed19a32aba4f98270b8ad45820abbc4653": { + "balance": "151868798605000000000" + }, + "870f19e7ee358de61ad0fd3c7710441156d68f66": { + "balance": "674715936435000000000" + }, + "87141a2d3857fb8a328ef8e7b503ed965294c85d": { + "balance": "1609607183158000000000" + }, + "87257783d866af25a7a71b46ea6c2bd1e9ab9596": { + "balance": "64000000000000000000" + }, + "87298979a9a0dbc272b0e15b7e5f2e42639c9912": { + "balance": "722087160930000000000" + }, + "8757b784015f88d072229176cabefa358a0e95a4": { + "balance": "204003337866000000000" + }, + "8760e60a56c5b8b61276634a571400023f08e3ac": { + "balance": "1000000000000000000" + }, + "877e54ea7e8ab03bb8e2b842dadab16bf4ae0a4c": { + "balance": "341020957932000000000" + }, + "87919285fc5d98169bbd073cebb1b3a564264dd8": { + "balance": "579080463078000000000" + }, + "87c39cfaa9c82d84119f306e6a233a3abfbb0ad1": { + "balance": "121753433796000000000" + }, + "87d479659a472af7c8ea78a3c658605f8c40bec6": { + "balance": "20000000000000000000000" + }, + "87d933ad6fba603950da9d245b9387880e6d9def": { + "balance": "1087642723520000000000" + }, + "87ec448309024bb1b756116b81652ea518cf353d": { + "balance": "344562808694000000000" + }, + "87fbbe010837f8907cc01a5bbd967f402a216488": { + "balance": "185411503628000000000" + }, + "8805a3c529bef4d19a6491f3b7d7b1b7232bb93d": { + "balance": "264150205918000000000" + }, + "880ec9548864fcd51f711ab731d847260ed0e3d5": { + "balance": "723225945994000000000" + }, + "8818d160b56b18e196871a6c7ccf02112dc13342": { + "balance": "2857439182291000000000" + }, + "8836e25baa08c19a9b0155c57072582b49f7dbef": { + "balance": "5468425690148000000000" + }, + "885b6303d06142accf2ddddbbdd4a9379d1cd124": { + "balance": "11853214736000000000" + }, + "88656958d9cd758d71546ba52c4ea646b658c84c": { + "balance": "10000000000000000000000" + }, + "88740acdf9ab5711d015391fe8cf4a7c70a0bc86": { + "balance": "510027156671000000000" + }, + "8874966976d776c3154261afa802692afedf3d3d": { + "balance": "305634301700000000000" + }, + "88aea53c727d7a5dd8a416e49faba1c4f741f01a": { + "balance": "15358334295959000000000" + }, + "88b67d05997ae3852259ca638a00ce9b9e7e4a61": { + "balance": "278125551806452000000000" + }, + "88d730e074a102048008de81d3adcba831335736": { + "balance": "5984576042159000000000" + }, + "88da27b1f0a604a87fdedd9ea51087a331179cb4": { + "balance": "10000000000000000000000" + }, + "88efaa91dab9671f5c903e69aa6ca4d9a04b5ddb": { + "balance": "1996126782729000000000" + }, + "89a9d702f64f14fae4d1a69717744dd700208d9a": { + "balance": "251686323241000000000" + }, + "89ac81571265bebbf9d3c09e9459fd1ba7fb1297": { + "balance": "162368080974000000000" + }, + "89c75c4f0ce41d283587beba1a3e3efab05ca6ad": { + "balance": "16000000000000000000" + }, + "89d44cb81cc5a1bdf4d573c4954ee641f3cb91d1": { + "balance": "97965629614355000000000" + }, + "89e2fef4f7b7c255b36afa81cf4033b22de3db25": { + "balance": "7278615226888000000000" + }, + "89fe5d3cb5283c7b87daf6103bb568f92a230631": { + "balance": "64000000000000000000" + }, + "8a07242231f4a654aeea65b857d1519385a18065": { + "balance": "20000000000000000000000" + }, + "8a5a415f0fe2a8329e14628493d11ca20d4e482a": { + "balance": "157274758238000000000" + }, + "8a6ce9f270fe3ec33a013be9e5b1ef823c0dab53": { + "balance": "20672772672000000000" + }, + "8a6fe4fa2f86f879ec9b2bf643beeb0876da46d4": { + "balance": "1041983771868000000000" + }, + "8a765ff2b429dcdf59b65a34c4bb41798dfb5886": { + "balance": "355487172996000000000" + }, + "8a9b9b65a3d443a6e4dcf696a64983f3b625774f": { + "balance": "3185351572575000000000" + }, + "8ab1f5443cf9149773b9ddb69de3e6ea047ae38f": { + "balance": "161619949415000000000" + }, + "8abeacee0078e07fb417277e8bf15dcc2cdb9fa7": { + "balance": "144000000000000000000" + }, + "8ac0d9e0e77aa4ada4080604f2118b3a5a0f8102": { + "balance": "100000000000000000" + }, + "8adae0dc99300f60d31bfa619ec83d45b48ea22b": { + "balance": "697262590215000000000" + }, + "8aef59e59a27a8662043f1a4abcaf945a5e3fafc": { + "balance": "26780431538000000000" + }, + "8b3386f32e2d77526c223ee8bb95b7dd111ced92": { + "balance": "2179932854210000000000" + }, + "8b34d5e457ef6451bb7f5ecc93c80678a30e3194": { + "balance": "31492358338840000000000" + }, + "8b47e07f192c33bd7d298bae717dfcd68a8097ae": { + "balance": "1000000000000000000000000" + }, + "8b55bff4b281f6a24ab428d66b91f9bab06f7b96": { + "balance": "1596248680941000000000" + }, + "8b576b1e2391f22193bb4f91bec5f2a8aec02af7": { + "balance": "29660301836269000000000" + }, + "8b9097b762c7bc38a487974f3551fea697087553": { + "balance": "260887123991000000000" + }, + "8b92c50e1c39466f900a578edb20a49356c4fe24": { + "balance": "35654824979000000000" + }, + "8ba3933337108841a997accf0b5735e005373f53": { + "balance": "574965182000000000" + }, + "8ba3eeb2d1b27e021ed6bf5827280807f32c7897": { + "balance": "64000000000000000000" + }, + "8bb23a5b8c48ec5bde84f39b463559b7c048c853": { + "balance": "16186405874000000000" + }, + "8be0b6ab14e15b46905335d07df03726fb1df0e8": { + "balance": "500000000000000000000000" + }, + "8bfc53af1ae6931f47ad7f7ed2f807f70fddb24e": { + "balance": "20000000000000000000" + }, + "8c0599df87df142d3aea37d50c975c1813ecb642": { + "balance": "871085782287000000000" + }, + "8c2deeeaf095be075a2646ed7b8764d3665acf14": { + "balance": "10000000000000000000000" + }, + "8c3e7381b0598356ff81e860faf25390ae7de9d9": { + "balance": "36000000000000000000" + }, + "8c5671a6f4610ddbd05a5139659c7190f54117b5": { + "balance": "50000000000000000000000" + }, + "8c60582c4e4e60da665b4a5a2d18f514ded6c49d": { + "balance": "16806447782991000000000" + }, + "8c8464ea6b17687eec36ef04966d59c7c91fa092": { + "balance": "1872124465602000000000" + }, + "8c85c5a318cc0227576adba3e91dce6adc73f6a2": { + "balance": "52479305517000000000" + }, + "8c8f3796a2942a2298d14ff1a9e3264e9f63f2bd": { + "balance": "10000000000000000000000" + }, + "8cec1886f2cc71b09ca32a1cf77a280ae3a6a9fe": { + "balance": "500000000000000000000000" + }, + "8d0b26d57eb52a62814d7876d64c8274f4371464": { + "balance": "20794037603000000000" + }, + "8d40b92e41f3cfec06e767d64b4dafc5612133b6": { + "balance": "25000000000000000000" + }, + "8d41ea1cfb70d0ef1f6572fd72a6b417739ac7dc": { + "balance": "738777348304000000000" + }, + "8d4eb54646f9d14882fc8ebb0ef15f6056d1afbb": { + "balance": "1003867239086000000000" + }, + "8d51ab29ccd190bfe12bcd94a651e9f49a003253": { + "balance": "442251355663000000000" + }, + "8d6c0c8e4ca47626115433b39feb939014b8738f": { + "balance": "119828137027000000000" + }, + "8d7acd92d664a485625bb9884e7cac9cc6077f41": { + "balance": "1381910232084000000000" + }, + "8d7ee7a9c1c263ba8061f54dcf62d9f8420e2008": { + "balance": "20000000000000000000000" + }, + "8d941c5d0c6e2b8e2934c9f80f8a63e2fb5868ef": { + "balance": "116443644149000000000" + }, + "8da0dc43ed3ccefb18f21aa13f3fa42c13e540a6": { + "balance": "516000000000000000000" + }, + "8dab4500316475e8fc3bb6494be09f549dedf026": { + "balance": "2736245677000000000" + }, + "8db39a95f4e63bde0bd8c02e386122ce2c57a30f": { + "balance": "12577347153000000000" + }, + "8dc718b49fb68584d9472490743f9be1b0ad683b": { + "balance": "50000000000000000000000" + }, + "8dd05e26224aa8a6deb0904b6d3bbb34d268e901": { + "balance": "613146658282863000000000" + }, + "8dda0e7ddde515480ef08cf90a1eb4e78f50a2c4": { + "balance": "19265526663314000000000" + }, + "8dedad1511c11798c338334dde7be967de96e9b2": { + "balance": "50000000000000000000000" + }, + "8df63c04f18a854d7bb397bca3e2ba19202e9da1": { + "balance": "1479940547081000000000" + }, + "8dfd7edb7d28e8b3df1faab70a8ef9e3b923d998": { + "balance": "10000000000000000000000" + }, + "8e2c3af057e931b5f82e83873b336a7f68e7eb03": { + "balance": "27138009123000000000" + }, + "8e2f4eaddd60468bdc09d47f65839b96f50596ef": { + "balance": "970529157231000000000" + }, + "8e750010c88ba99d75b0b5943c716d6fc0d01802": { + "balance": "42271114987000000000" + }, + "8e889d47f3307a18490e53f2108dc31b14d6300e": { + "balance": "115722965933000000000" + }, + "8e9e1953c82217ba56365e7a9c54b1ded73914bd": { + "balance": "6248835752208000000000" + }, + "8ec980d3066cb6afa793577cf88ccb46ce8d13f2": { + "balance": "100000000000000000000000" + }, + "8ef324c861de7e042c445776bcc8ac026533bc15": { + "balance": "1869634994148000000000" + }, + "8efd14464465e50af087a80a5fbe652445de373d": { + "balance": "1157403424927000000000" + }, + "8f1b57304406fd8b2eb5dabcbd322e326dd873f5": { + "balance": "194188733254000000000" + }, + "8f36ffd921e12083e374335d3cc43fcfeeadfa46": { + "balance": "100000000000000000000000" + }, + "8f813b88e6e125eab71a63455f326322ef505501": { + "balance": "19087691927734000000000" + }, + "8f83892d4d2892cd57828fde2318610a54b14498": { + "balance": "22833507983000000000" + }, + "8f89c1bcba85757cf1718d5b9eb007e27e5195ab": { + "balance": "2241600478705000000000" + }, + "8f927ab63df4c2ce46f1ea35bc875a0c006d2d4f": { + "balance": "327487123409000000000" + }, + "8fc3c231df0f93a84bbe348aff12ab576284d70f": { + "balance": "25000000000000000000" + }, + "8ffa089b07ed1388a5d1a428daf54d9591e734e6": { + "balance": "1347580402248000000000" + }, + "90040e00f585f8be44c82597037fde452472e741": { + "balance": "2746884591879000000000" + }, + "9034eb46aad2a76bdb812c981565d4701dc10718": { + "balance": "10000000000000000000" + }, + "904ca1ac2381702bd18472b175262a8928cde5f1": { + "balance": "304421909590000000000" + }, + "90502c1123692c3b86e99b328d07fae473d4a283": { + "balance": "227491252462000000000" + }, + "9052ca7e9623c1bbe3568668673d6d252b56a764": { + "balance": "35268091378000000000" + }, + "9093d12d8410193293e1fda0cca98a43b85b91a8": { + "balance": "6829489147119000000000" + }, + "909ba8cdc707c12ba577dcd8ed1df1c02a7ce2ef": { + "balance": "60524108169000000000" + }, + "90a2cc3aa73495531691e027a8c02783cea7941d": { + "balance": "65263780625000000000" + }, + "90d7c82615f151953a8d71a68096cee4d428619c": { + "balance": "298774379499000000000" + }, + "90e02deb31d98b9c85fcaa7876eb5ec51d721dd4": { + "balance": "2000000000000000000" + }, + "90e538746bbfc6181514338a608181a3c4286d1d": { + "balance": "6069511690189000000000" + }, + "9106dddc1b693e7dcb85f1dc13563d6c7c9d8a6e": { + "balance": "1977000091291000000000" + }, + "910d1e0d3f71054835ee0d4cd87054dd7add3e38": { + "balance": "40104690362000000000" + }, + "912e2349b791fe702692a6c1ccbf6f0f06b826db": { + "balance": "6305336897000000000" + }, + "9144cc61c01eb819e654b46730620c230da9e936": { + "balance": "144000000000000000000" + }, + "91478d4c15d9ba02816456030915be08fa3aa208": { + "balance": "200078339107000000000" + }, + "9160c466b5f9020b0ab1c0ff497bf0345598ec90": { + "balance": "17705350930000000000" + }, + "919025625787101c572d8340ead1444a96593424": { + "balance": "2418027749789000000000" + }, + "91926323868c65f91b6d74c85c07279610651ede": { + "balance": "538073886450000000000" + }, + "91950cd6e2dd99e024854b65c09c5a7476777a21": { + "balance": "11629505934425000000000" + }, + "91ae8d74c26d3dcc291db208fc0783347fcc197f": { + "balance": "7604593786920000000000" + }, + "91b9ac26869abc9eb3090f1d8140eabe97f41001": { + "balance": "25000000000000000000" + }, + "91c349651afb604f9b00a08e097e02c0964e148a": { + "balance": "117290771022000000000" + }, + "91ddc95cadeb6dcf6ebbdb3300a29699ac8ded39": { + "balance": "20000000000000000000000" + }, + "91ebbd36714cc069f8ce46f3e0eda5504fdd3aa2": { + "balance": "203944728497000000000" + }, + "91f2765125b84923bd506a719d72b0c1de030e32": { + "balance": "452269960816000000000" + }, + "91f2e54a9d61ef52a33d150da50d5a8f2ebcd6bf": { + "balance": "242321058694000000000" + }, + "920dc90d11e087a0d8912c1d43db102e9ba4f43e": { + "balance": "20000000000000000000000" + }, + "922ff522cf7f3ce0bab9312132df51704caa755b": { + "balance": "1414824682473000000000" + }, + "9251449b0f757ef62f63c2774eb63ba15bf3712b": { + "balance": "102688517037000000000" + }, + "926255c17386720fdc1701747a2f024475063d4a": { + "balance": "25000000000000000000" + }, + "92808a38ffc5a339b1ab6b0b472f9975718d4a07": { + "balance": "500000000000000000000000" + }, + "9286c4497e820845341e3b9127813c1b7c884830": { + "balance": "101241387488275000000000" + }, + "9298e1df6730e91e9892d19f7ce18a3db9b5d2a1": { + "balance": "169000000000000000000" + }, + "92d98aed335c29402a43ba96c610251bed97308b": { + "balance": "3032350763000000000" + }, + "9319153f24814a81d920c60cbee9b5f2f275fac0": { + "balance": "56619610984000000000" + }, + "9347532d6396bc0b86bcd34eb80facd4c3690684": { + "balance": "258912194626000000000" + }, + "93487691d71e6248d88f06b1fbaee58b6fe34615": { + "balance": "1593901704394000000000" + }, + "9375154a7f19783b26ae1c9e48f114e1cfd1307a": { + "balance": "9000000000000000000" + }, + "9377947e0db688bb09c9ca3838ca2197fb262a1e": { + "balance": "323993393587000000000" + }, + "939ca9030b28d356dc1b071169f98b0728a9aef3": { + "balance": "218900305967000000000" + }, + "93b71636b8332515c2af031aac7a8805de716a62": { + "balance": "1640174743698000000000" + }, + "93bca153afd427b0c3c1de4a5584610e4a6595b7": { + "balance": "654782426410000000000" + }, + "93cb3b73fee80cedacf5197f8b4ac8f18f0d0184": { + "balance": "100000000000000000000" + }, + "940fcd215bab373d1b736e354f2def501244885a": { + "balance": "13133641534585000000000" + }, + "943f4bc76f20580b6546b6aff2800448f82cfdc0": { + "balance": "1927982550280000000000" + }, + "946ddb5c46fb13010b9c7ec56e4055b4f3e24b4a": { + "balance": "1410000000000000000" + }, + "947961dc367226f78d722361d5821cced52db01b": { + "balance": "115598797369000000000" + }, + "948eab3ffe44d5f1f381de2c8cadcb311c25df2a": { + "balance": "870664355820000000000" + }, + "94bf674593378243fb6b811f331f77561efb4106": { + "balance": "226539311455000000000" + }, + "94ce082887dd6324d7dcfa6cae17b653be021b25": { + "balance": "420000000000000000000" + }, + "94e2aaa4b5e2b36a12f866c96e3382a1150a97b4": { + "balance": "7344059136611000000000" + }, + "94ea5b1cdceb3f1a9d5ecacb6ac8dd2db9a461d7": { + "balance": "1951787237292000000000" + }, + "95218633176c0fe2f32fb55ad3df9f387e63aed1": { + "balance": "99999999580000000000000" + }, + "9543cb22853a46cce3aadc60e46cbddbd3fcf593": { + "balance": "2806074281914000000000" + }, + "958842c5389656d156aab05ac1731a20656716ff": { + "balance": "391064461038000000000" + }, + "958fd9bbc96531a00adc5c484d06dc61ccd717b6": { + "balance": "8021794447667000000000" + }, + "9593ce72919cb0648ddacc58af233d942963e2e6": { + "balance": "32322940730755000000000" + }, + "95a8e371af9128c97c9d4d7c4d58f5f75f2d07d4": { + "balance": "49000000000000000000" + }, + "95b9a9ad563a4c1ff7b6ebcf5fabcf5dbdb4a6a3": { + "balance": "10000000000000000000000" + }, + "95ef5fac6aa3ab1b4a87246fa800cfceff43dec7": { + "balance": "119666779022000000000" + }, + "961a3aa8015cd520de43bd47d81f5194ee4dfdc2": { + "balance": "248589901007000000000" + }, + "962bad39df25d64ee1c6b4ae9c14a18d316bfc06": { + "balance": "2404608291000000000" + }, + "96392119198c4b644c64284c9a75f61210a6292d": { + "balance": "1000000000000000000" + }, + "963c82319380587eeba0bd7b07eb63ea7042984b": { + "balance": "1480123630618000000000" + }, + "963e05fb6245ec11d67ed80e9feba6e2c0a8b4ae": { + "balance": "276053287417000000000" + }, + "964452b86b0d1d4b34aa881509a99e7b631d4a85": { + "balance": "64000000000000000000" + }, + "9644a2af2ff70eb43584a4351bfbe027c42ba3f9": { + "balance": "500000000000000000000000" + }, + "96572a017489450f2dfc0e31928576acd3bc6808": { + "balance": "1140183097730000000000" + }, + "9686bfcc0dc3de20604eb77787d0dba818cc5016": { + "balance": "10593448987804000000000" + }, + "96879780764b4433589d26573fc221f5218f1877": { + "balance": "154136576560000000000" + }, + "96ac1e62c95e33dbbd4f6ed389007e16c00b205e": { + "balance": "4130528000000000" + }, + "96ba703df3a8a6dc3c5d6be02cbf6a4afa2d1650": { + "balance": "2885298549532000000000" + }, + "96d516ded110f1d7e0290716689fd1b7964d9d42": { + "balance": "40665675241000000000" + }, + "96d75950c9354cec6084ba11058dd52d00fdb1f2": { + "balance": "903158106646000000000" + }, + "96f362c59c72fa1d39ae3ec37a7b715d2dd23679": { + "balance": "110000000000000000" + }, + "97115f7544cb05009b3fad2f0c2817f3ee77dd4d": { + "balance": "10000000000000000000000" + }, + "971cbaeafd4b0fdbad24fab946051b8949efaebf": { + "balance": "8462381628000000000" + }, + "971e195e980b4fd4db8d279c80968ca1bd390edd": { + "balance": "10000000000000000000" + }, + "9722648970c455929d621546fddbff27c49acd3c": { + "balance": "70337427969000000000" + }, + "9772027a4ea991eb9eb5ae6b8f34d750a917538b": { + "balance": "148918416138000000000" + }, + "97797e3919aa35567b9eb1224be87f96c6c2e1b4": { + "balance": "973342196399000000000" + }, + "9780a9c86160e27f627179535c3d3f23b6b29917": { + "balance": "10000000000000000000000" + }, + "97a85f4e3f53aa066825de15f1d0e25d4189b037": { + "balance": "2435764858719000000000" + }, + "97f46465e99910539bd3593c16a572e159bac87d": { + "balance": "25000000000000000000" + }, + "9882505fcb54ca2d2f4f79b03f0a5ead61936979": { + "balance": "249999580000000000000" + }, + "9898e969629502a891b758efecc9fdc5ada7d32c": { + "balance": "20000000000000000000000" + }, + "98a52d325e28ca9b4474846c7e4c07a223440fab": { + "balance": "418260286015000000000" + }, + "98a9b2f7d1ba7838e3242b5e4cbf1f2897aa4bc5": { + "balance": "500000000000000000000000" + }, + "98b8308c37a2f6cc1bb382dba2ba95a3c5ca2834": { + "balance": "10000000000000000000000" + }, + "98bf0170a61f98ab0710a68810bf152b7f6c56fd": { + "balance": "2279761566089000000000" + }, + "98c8a323a0022bd147a466fa1ac867977e12eb92": { + "balance": "10000000000000000000000" + }, + "98cd102caf0866ba0a74604b01f54049503905d6": { + "balance": "34739921273310000000000" + }, + "98d7e89c2765aaac224d4015aa277fef208953c3": { + "balance": "1291811952000000000" + }, + "98fe96bfd1e10fb60b343e512b15e955aefc0778": { + "balance": "464922897623000000000" + }, + "99064a57d693e45559a1a910c9ef7d46cce0e703": { + "balance": "8969733492948000000000" + }, + "991ea5429b91a8bfc4352a1d93304dc463be5b90": { + "balance": "149367286734000000000" + }, + "9921d405fada890fee6bf76acc39141fd34e5d2b": { + "balance": "5021308706457000000000" + }, + "9938d357d3d5dcc6f6fc7fb47a98405c0ab6830e": { + "balance": "516293591974000000000" + }, + "994f4e6521a3a5752359308b9f6b2722922c60b1": { + "balance": "23993133615000000000" + }, + "995a6a1c38f037b3a9f0a2e915b8fc0efdea082a": { + "balance": "1403498530728000000000" + }, + "99709e57748a7da6556b1670ba4f15c45aef4689": { + "balance": "36000000000000000000" + }, + "99789f65655c6f917d575169f4ba8192440e659a": { + "balance": "393071814319000000000" + }, + "998f66cbde2693603fa109ad7aaa8bc42a8765a9": { + "balance": "49000000000000000000" + }, + "99afd42a58af31daa54ad9ba35b06954330107ba": { + "balance": "25000000000000000000" + }, + "99b6a9ff2b2ac9ac0361af007aba107695ff5fad": { + "balance": "12860157225353000000000" + }, + "99d16a5955d43723ed8e2b1a642f8f1195f38b64": { + "balance": "62907829047000000000" + }, + "99df609926ca536ed3be80e35dbaecc42ae67f2f": { + "balance": "316809833612000000000" + }, + "99f3faf97a36fabea7306979b30b08fa70110e29": { + "balance": "173292373556000000000" + }, + "9a26110067b473e3bdc0fc32951b39596c967a56": { + "balance": "78192198764000000000" + }, + "9a3a8eff6fb82377da6c17ba658dca87ca0dfe26": { + "balance": "50000000000000000000000" + }, + "9a3b06257088ef8c17410a8f2d63392edb9b55ce": { + "balance": "239567000000000" + }, + "9a426842301802866cca0ef89794d928d3e8f843": { + "balance": "776173297821000000000" + }, + "9a5f2c0a6d41131d9aacdb4f8c274958cbdd377e": { + "balance": "441954000000000000000" + }, + "9a6893023ac6f34b493d33e4dc63ef697169a58d": { + "balance": "439689418527000000000" + }, + "9a86eefd848acafcbd9960003e90b22162b15ef9": { + "balance": "294190908093575000000000" + }, + "9aa711f3e4eb67d2f6405b5ee6290a014d203a72": { + "balance": "9101556549634000000000" + }, + "9abf9ccf6abb8d55ede458d2d12a279d0a823944": { + "balance": "17609693072000000000" + }, + "9ac1909b983c754f0800559174025c0f0baa9d31": { + "balance": "80921948093000000000" + }, + "9ad62cd855d629e1ddab632874a6dc2b812f2348": { + "balance": "2068118534000000000" + }, + "9afc2c33aa2c9a42600abb18aedaefa433326122": { + "balance": "2485353229354000000000" + }, + "9b18d230b221a99c74877d4a1dbdee2214c7d60c": { + "balance": "4024172228743000000000" + }, + "9b18e27788c9d59053072032a480569e142595a0": { + "balance": "110789164888000000000" + }, + "9b4535b23af0b8e5f488a6f318ff6badf71d16c1": { + "balance": "84756740661000000000" + }, + "9b5e7cf43aece7b38ea2af6d08bebe2d3b926840": { + "balance": "262771268227000000000" + }, + "9b77dac92fedd0ad3eb4326d4fafe0f4315a8844": { + "balance": "3616321626000000000" + }, + "9b8f6f223641f9b1bab319dd1e88c49fd411a765": { + "balance": "2054417462086000000000" + }, + "9b9f94861d80365464912e5c7213403405a6cd8d": { + "balance": "2367093088000000000" + }, + "9ba24397002929e6239848596b67b18a8dea1eef": { + "balance": "5000000000000000000" + }, + "9ba99736c5ac468d6b644e39b8d515c39151f51d": { + "balance": "311900650761999999999" + }, + "9bf2d4ff366e1bb2313ae9a93ccca75d6bc0d232": { + "balance": "764870206925000000000" + }, + "9bfce7dbfc9ae62d450e862261d1e21e68bac92c": { + "balance": "1000000000000000000000" + }, + "9c003e74b62f192a864045d678639580c672fc22": { + "balance": "50000000000000000000000" + }, + "9c128bd2c0c96b896db6c0f398e908c98302809e": { + "balance": "3251059363800000000000" + }, + "9c255daa89ee16f32fc0ab1ed8e22db39342e6ca": { + "balance": "37695843594589000000000" + }, + "9c32e714bcb601a56a8a4e6b3f7bcd9e1c7a1b54": { + "balance": "50000000000000000000" + }, + "9c503e087b04a540ed87056c9371d591afa72df2": { + "balance": "64229084991000000000" + }, + "9c54297dd3527cbbb8ca8c305291b89bfb7ab39d": { + "balance": "61682466962052000000000" + }, + "9c55bb1db3b2bb06e605a66ced9ea2ac95718205": { + "balance": "16512365324000000000" + }, + "9c59dbc48b9cf53fe668784e89d30493da9995b3": { + "balance": "50000000000000000000000" + }, + "9c61b58aa760265f7fd1b9e749df70122ea81175": { + "balance": "50590272373000000000" + }, + "9c6c7eaf4bec0566a7bf8acd30e10311a963267c": { + "balance": "999999999580000000000000" + }, + "9c91dd4006f9d01d8caf5f5fb4f2c4f35ee63ffc": { + "balance": "175730980227000000000" + }, + "9c99275f5dee14b426302b1a47a8488c16432f2b": { + "balance": "2000000000000000000" + }, + "9ccf7b23528d062da63f6af3e26531b775c83c52": { + "balance": "928373869120000000000" + }, + "9cd21c30ccbc1087c9b351395fdea17ad669cc2e": { + "balance": "529762292313000000000" + }, + "9cfee47d6f24880af7b281cc00e1fc58e0a4a718": { + "balance": "198888257958000000000" + }, + "9d08251f7d4cfd66d15c17e1ea6bae5c795e290b": { + "balance": "813841349140000000000" + }, + "9d5411490ce89359bfbacf9f9957ebfbbc18debb": { + "balance": "22263187467000000000" + }, + "9d61e1dfaa7d0e0c5f5d733a24a1883c4e201f3d": { + "balance": "144000000000000000000" + }, + "9d754d94a15ab6d738e511fe4c775ee6d20a53ee": { + "balance": "20000000000000000000000" + }, + "9daccedf104fdcc3c39f2961ddfa1c64eb632476": { + "balance": "1237093270947000000000" + }, + "9dad4968c0e44aa729fc5732f3ee903c6799637b": { + "balance": "838788687517000000000" + }, + "9db73ca677bacbb622f44fe90b53ee1d9f0c2009": { + "balance": "472858335000000000" + }, + "9dbcb5026e0f444a33197da240856f108db14ff0": { + "balance": "10000000000000000000000" + }, + "9dc46cf729187ceed8001c4ab14fa4fc21c35f32": { + "balance": "3320792646995000000000" + }, + "9dd895c1bdac2ed9864134aaa8c543473ee5f19b": { + "balance": "1430620966869000000000" + }, + "9de2687242cbf9fb94fee0ad873acc7494ebd2bf": { + "balance": "20000000000000000000000" + }, + "9deec036282717aac93ad5cc1b6d4a5354e85c2e": { + "balance": "2048627955362000000000" + }, + "9df8dc66395aeae9b4c831b4d63bdf48db08811a": { + "balance": "215874670561486000000000" + }, + "9e1fe68a70abd8ab517878b03961da8564b43eb5": { + "balance": "67908329894526000000000" + }, + "9e33293006982abc668e199aab20260b9b754463": { + "balance": "49000000000000000000" + }, + "9e65616282a0baf89469a58915fd8fdbed210e3f": { + "balance": "829209872657000000000" + }, + "9e7b7b522834dd7e83ff2bb6b6e4cd2972330899": { + "balance": "500000000000000000000000" + }, + "9ed134b3a8feccb4056b2e511cea9a8ec58a3e77": { + "balance": "18787546978390000000000" + }, + "9edcf477687a9dee79341ed5d89d576c9a854c2d": { + "balance": "500449025554000000000" + }, + "9eeb06d4b532118afa013a01c9e89216fe0475ae": { + "balance": "1823939486758000000000" + }, + "9ef20a338e85044922f08f3648355e834874d551": { + "balance": "50000000000000000000000" + }, + "9f0855f9cc429fd3590c6ad05bb66a9e038efdca": { + "balance": "8017999878252000000000" + }, + "9f3befcc1884d16b65ae429228d26fffc146c8dc": { + "balance": "1016482445089000000000" + }, + "9f4571748463eee19e59ff9bd734a62a66613850": { + "balance": "20000000000000000000000" + }, + "9f51de282745f77b8e531e1de0b7c14e3369ba54": { + "balance": "1010657089383000000000" + }, + "9f6527175a2b581cc79f2a68c35202e0a7f2af20": { + "balance": "216495522463000000000" + }, + "9f70204d1194f539c042a8b0f9a88b0a03bbcd8b": { + "balance": "10000000000000000000000" + }, + "9f70e44704049633110ecd444f9540e241b50783": { + "balance": "9139000000000000" + }, + "9f73fea741e8506ba7acb477745dab1cfab8366e": { + "balance": "4461472359634000000000" + }, + "9f88d33d26c90e74c39c9676b8b580d21bbad124": { + "balance": "54437240781000000000" + }, + "9fa47455be14ad2eecce495281ed0eea926ec6a6": { + "balance": "10000000000000000000000" + }, + "9fbb15b595d154754a2ae77c77283db9d4e9f27b": { + "balance": "6195722646556000000000" + }, + "9fc480ab1823a59fd6130c3948980f95ac99f1d2": { + "balance": "24101151540000000000" + }, + "9fe5f054165fbf1943b1b02c01063f04e0c3890b": { + "balance": "1000000000000000000" + }, + "9fe7d3d5976e7b8b5ad6baa15ceae96c43c60fea": { + "balance": "55000000000000000000000000" + }, + "9ff116ea0e219814970cf0030932f5ce2cd9a56f": { + "balance": "36000000000000000000" + }, + "a01f6c36193839bc3a31e6d0792324771040fc05": { + "balance": "48298750000000000000" + }, + "a0264706d668522b737bbdbe949ce3e5a60fe314": { + "balance": "1423066922869000000000" + }, + "a02b13bb3b13027045ffb9b44bc7380a942e8ebb": { + "balance": "86845430807181000000000" + }, + "a03d246a931c3d422e5d2bf90f64975923a93643": { + "balance": "5834171660287000000000" + }, + "a046caaee59425ea1040867c62a6fcda11652a23": { + "balance": "83087966538000000000" + }, + "a04b57b2dd8b2082c53517d956f5909d25e14b69": { + "balance": "4518538234851000000000" + }, + "a074ef9e0ffe15619103e3de490f5813be53dcbb": { + "balance": "4568113810000000000" + }, + "a07bae42b44c085067de16e7d9846db529059acf": { + "balance": "4000000000000000000" + }, + "a08530e5fb7e569102b2c226aa5e53dc74483e4e": { + "balance": "2325665286793000000000" + }, + "a095a2c666f4f3203a2714fb04867c13c2add4be": { + "balance": "14768043990000000000" + }, + "a0a967418a3fcb3ee3827a08efa851347c528a60": { + "balance": "20000000000000000000000" + }, + "a0bb293071e07418ecb2fefc073136569ebd1736": { + "balance": "25871128320000000000" + }, + "a0c6c220a53b7dc790f7a5b462a106245c761f70": { + "balance": "1000000000000000000000000" + }, + "a0f06c86c49b248f4835bff405b620d12ec80d07": { + "balance": "484572382390000000000" + }, + "a10bc9f4d05678b26c4ffd2d92ab358163020b61": { + "balance": "10000000000000000000000" + }, + "a10c1197f7bc96639d01a652df73e49c669165dc": { + "balance": "1205859101575000000000" + }, + "a1221b2001f85f71e0655551e300ce115284b8dd": { + "balance": "1376698025177000000000" + }, + "a13fce836d65124fe5bcfa2d817ab2a043acbcf8": { + "balance": "55000000000000000000000000" + }, + "a15f1f609f7464906e0eb9d5e1d26468b90d9198": { + "balance": "16000000000000000000" + }, + "a1617dcf3acda60737e5ca9e4d0ecd82a98ef667": { + "balance": "500000000000000000000000" + }, + "a165c5f151d0daab905ba4a6d1fe5d5114fd7686": { + "balance": "41039049526000000000" + }, + "a17d5bed36c1059561e184a8a90a38ce955b92e4": { + "balance": "10000000000000000000000" + }, + "a18efb4e0950e7ac95970cd4591dacc286241246": { + "balance": "12403188476000000000" + }, + "a191fa6be64f2f6d2b4a7fb5a586416a605552c6": { + "balance": "60340281461000000000" + }, + "a194c15518cefbe94edbef3a2421586b51f7e1f6": { + "balance": "4153525550636000000000" + }, + "a1d0e41aacf83fc62fbecf35f8e873f8d734ecaf": { + "balance": "9000000000000000000" + }, + "a1ddd1f615ed483ef895e341f3266b6891f9b59c": { + "balance": "180411786335000000000" + }, + "a1f4d1e03114707a56ef9069bc20c6094e810d34": { + "balance": "51949145435222000000000" + }, + "a1fe101a65616cd03e3af03092be63434b7bf203": { + "balance": "1005401878265000000000" + }, + "a25a8225ce67c54048737601eac5e0d063c2fa17": { + "balance": "272038848571000000000" + }, + "a2714999233bcaff7294fa3e3b64c63ad45a928b": { + "balance": "14560781294000000000" + }, + "a28db3f7fb1771a3d77dfb19b54f88fd55b15c8c": { + "balance": "8000940572576000000000" + }, + "a290101bfe5fbc73146c4ec3ab5266c043eb701c": { + "balance": "1397563244603000000000" + }, + "a2924cfbcd37d0b321d6abbe57c645f9ce32340e": { + "balance": "200000000000000000" + }, + "a2a26c34f3d950c795fc965f6b1df3990e111403": { + "balance": "34525064429023000000000" + }, + "a2a2855851711bfc051c1f298821ae89e4c872c5": { + "balance": "491025000000000" + }, + "a2b956dd6f1934a4a44a026a18ac345ddabe42d5": { + "balance": "20096625821563000000000" + }, + "a2b9a118a79be81711d95485aa12e3efe78ca256": { + "balance": "10451051632647000000000" + }, + "a2bcf08ddd1778b30ea7882518148edfba2d9b20": { + "balance": "347033754668000000000" + }, + "a2bd489ec4790f4145f8a9a95c9c829c5c020146": { + "balance": "100311110878000000000" + }, + "a2ee35300ddf6a2491ec0e1848f8b56defafd7fe": { + "balance": "500000000000000000000000" + }, + "a31adf082ffd212df18d5a84b105a937e83b1b1a": { + "balance": "7124891785000000000" + }, + "a32c944e6c5fe186794b88d6bcbf51c47bea55ab": { + "balance": "732129357042000000000" + }, + "a33105d543f5d2b1220d4e1ecfdcf85699324dad": { + "balance": "74798779358000000000" + }, + "a3330c73e2d79355a14e570da1ec2e80f8048c69": { + "balance": "10000000000000000000000" + }, + "a3580034590e3052b9de5abd635e514ec5ba8694": { + "balance": "10000000000000000000000" + }, + "a360d8e2519dc6d7793cc371d91ad6add75e3314": { + "balance": "192622260840000000000" + }, + "a36b9b8b2adb20fb4a84d3025bf2e35baa8b7fef": { + "balance": "20000000000000000000000" + }, + "a3771b191237bef48339aa77ad5357f6227b358c": { + "balance": "512633055119000000000" + }, + "a3892bfd25705387cfb4eeb6d21089753c22e3e2": { + "balance": "258136912825000000000" + }, + "a38c793775ebfc7330b4331fe2dc848abb862b73": { + "balance": "1193250172232000000000" + }, + "a39417002ab94845541aded4a614a5a04af8187b": { + "balance": "1185722898000000000" + }, + "a3a79a9f929b54075de43689adb665ef914812ca": { + "balance": "100000000000000000000" + }, + "a3b59ea3d366f818ca09980846ac533d4685c121": { + "balance": "59734700360000000000" + }, + "a3c7b7c594a64225922e02039669e4d0b43fc458": { + "balance": "11779233750000000000" + }, + "a3cc39a68184e51f6445d3ba681a55f4157d4383": { + "balance": "10000000000000000000" + }, + "a3d414d9f210f7b77f90790ce09f6128abe50adc": { + "balance": "10000000000000000000000" + }, + "a3dfda16e5ae534ac100f56741b77b6f86786615": { + "balance": "9000000000000000000" + }, + "a3f79b9d1fc9d6dbaaef49d48fa9c9fb5a822536": { + "balance": "108910000000000000000" + }, + "a3f87414bc9e6f01c2fbde966fc8fb6edbf58c29": { + "balance": "441000000000000000000" + }, + "a3fa3f58c802d9a9690de760716275f14449045a": { + "balance": "437227558095000000000" + }, + "a417ec5a9749064a6521ca2bf9d05f208eeaed54": { + "balance": "959205202638000000000" + }, + "a484d5b883d2b99b81b7bef27e307957ecb64b15": { + "balance": "126491152120000000000" + }, + "a488cd48258e57d66f44e73a60c121f963cb29f5": { + "balance": "20000000000000000000000" + }, + "a488e3b5096e964b21cdeba12ab423f391765b6d": { + "balance": "1712050478592000000000" + }, + "a49dba65f28909e9bd2ce5675bd091f498c6c5db": { + "balance": "216802821062000000000" + }, + "a49eb6a791022c1324facc23d8813f9954d1c639": { + "balance": "287438914902000000000" + }, + "a4cc080a5c4649f511b5844a8e0b031927e13a87": { + "balance": "20333578449000000000" + }, + "a4d2624ac5e027f72edaa625ef22134217203b5d": { + "balance": "1000000000000000000" + }, + "a4d30e35c9617eafeda82866c96c3ce6bf14400e": { + "balance": "1223254927978000000000" + }, + "a4deae7355bd2e1d57eefa56600601b8b475a501": { + "balance": "36000000000000000000" + }, + "a4ff3b5abfe4e50adad16d01aaf62c3d4cdb5260": { + "balance": "20000000000000000000000" + }, + "a502b109869ef07451576bf0e13ab294e1f236b9": { + "balance": "94843398055000000000" + }, + "a517a3b5e4324197902e16f8a29e47335cf39c11": { + "balance": "100000000000000000000" + }, + "a51e101088da23c82907e3e2c65a058f0454b131": { + "balance": "196000000000000000000" + }, + "a52bcff6a7e2e70cd714058bc30a16138fe39899": { + "balance": "30429750204000000000" + }, + "a544e84c2bc4b17859d06f136b6e377e4e398b22": { + "balance": "143977568178000000000" + }, + "a54ddacbc17a98b9fb6292aab3d92f4c5753fd0a": { + "balance": "100583192014000000000" + }, + "a557754f6637a19c1a48cb9bf58c1fe897acf434": { + "balance": "2087038692036000000000" + }, + "a56649205d9ea247b49e03dacbed6c78c21beb4a": { + "balance": "5046177099585000000000" + }, + "a568136446ee6b3bf62a20238db3b11397a065f2": { + "balance": "11652249158033000000000" + }, + "a56a7865b526e315a9eb41f4847485c7e0c952fd": { + "balance": "50000000000000000000000" + }, + "a56bab2a9aac9d08a7bc9265864a80089b68570d": { + "balance": "37138466291329000000000" + }, + "a5965a601c5df7765cd70e5dad27dd23da67ac99": { + "balance": "10000000000000000" + }, + "a5a3161c44c34c441784b7df795067760b0ee569": { + "balance": "35053289069000000000" + }, + "a5c245cf843e691956007b94e259b437a4e6b7e3": { + "balance": "18749166170000000000" + }, + "a5d7de961c3b991dc78f2d6c0448fa6225116d3f": { + "balance": "1574510758868000000000" + }, + "a5f47d2081ef728808786128549a28a5662e92a8": { + "balance": "1750000000000000000" + }, + "a610c90f5b7e5f33044956ba431a3887de1c969f": { + "balance": "25000000000000000000" + }, + "a61c1919bc3f3181dc94e2230d35574cfc972d78": { + "balance": "8990565120000000000" + }, + "a62f1aabd91cbc0112e796d1ec3727fcd26fa293": { + "balance": "1311277302001000000000" + }, + "a64fff0bb32e32f81a541c393982bc59fa183b1e": { + "balance": "8291357610655000000000" + }, + "a673dae555d367b8d4a784274577a1884615b9d9": { + "balance": "27416452091330000000000" + }, + "a6c780b585355d84d9d3c13be5bd05374588e240": { + "balance": "913657165911000000000" + }, + "a6cc1f6f51862c2798adaa1d266988022005a71a": { + "balance": "284500645805000000000" + }, + "a6d9c82784fa20dcf28266d047db441cfeb8855b": { + "balance": "10000000000000000000000" + }, + "a6dae08f99e4fb57b066a645a259d8e4f7ac2bc8": { + "balance": "9044922773690000000000" + }, + "a6f49f36f8d10a796bc2afc9e069cb0c76004ddd": { + "balance": "128555691078000000000" + }, + "a721ce1c294a0f1957ebf9be20b0fffcf90111ad": { + "balance": "3392103457630000000000" + }, + "a72b82c33bd3d6060e8a04392d236775d48ec3ae": { + "balance": "1434465940701000000000" + }, + "a7344654f2a1a44b3774e236f130dff8a4721e82": { + "balance": "100000000000000000000000" + }, + "a748cced92a87066db8b29f931fb92e827488a9e": { + "balance": "5487679824758000000000" + }, + "a78dcb2bcbec2d0a60661e1715c9a95c9d573a68": { + "balance": "346798292989000000000" + }, + "a7a6c0505e7090e0b2c21394877f91c50be6b45f": { + "balance": "4125233658872000000000" + }, + "a7dcdd9b9785a44a2dd4c5eeeb863ac1feae0f66": { + "balance": "10000000000000000000000" + }, + "a8013e9dca1bd38975748de2fb6cb3af5cae74d9": { + "balance": "10000000000000000000000" + }, + "a807bf78b15c15cd9e8edcf586849db716fedbb1": { + "balance": "1458293606310000000000" + }, + "a83410ff00fb4b913dd0ea2003b38c5c3247350a": { + "balance": "2876442029807000000000" + }, + "a848f61298a409e77a03900712017572f35a3319": { + "balance": "2783106133600000000000" + }, + "a85bb81d0dc57f824a763814759fd93fe3020569": { + "balance": "4558027813744000000000" + }, + "a860611cd098ce98974313030d9f6f462bb274d4": { + "balance": "961594154368000000000" + }, + "a8799eeff72929ee6cbfb5b0c02985cd4841be3c": { + "balance": "500000000000000000000000" + }, + "a8c29b9b1349fac0be9a65873e1911b7439c9a63": { + "balance": "1264035560749000000000" + }, + "a8c321024a3c015d881efca33bd1b2c1788b379e": { + "balance": "528752788000000000" + }, + "a8d02e8925ed48f4274d8bee62253dc0d4f2989c": { + "balance": "209083880937000000000" + }, + "a8d2bde2ccd6bad67ee1b9550c9310accb37cd79": { + "balance": "49000000000000000000" + }, + "a8d61abc6a403adc183aeb74c83e4221fd28ee1e": { + "balance": "50000000000000000000" + }, + "a8eb6aa5a0c5b6d9260a202dc76ab674d9a5f3b9": { + "balance": "1041257515142000000000" + }, + "a8efc57efc776dcaaf4003a8cfa63f215ab0284d": { + "balance": "166144142685000000000" + }, + "a8faba86d87678294e311cfa7f8cbeb6f9d8a499": { + "balance": "124541781000000000" + }, + "a912e02f8eab0cb620316129875f919455201117": { + "balance": "6454482105955000000000" + }, + "a929ac95281d1a77a3eda3b5ac90a761ef03ff16": { + "balance": "1074305309650000000000" + }, + "a92a4e40519003813f5574397ce328d046f75802": { + "balance": "9188437500000000000" + }, + "a93850ba8fff3bd18ab259f87c58bbce84165fff": { + "balance": "39018890852058000000000" + }, + "a9843660a17c2d972246028cb8045472abdd346d": { + "balance": "1052681604185000000000" + }, + "a9866c6271733971e46df3c9bb27b3d3c513c166": { + "balance": "200000000000000000000" + }, + "a9b1299c0c064e766f9f29f4301a78c6e4931fcd": { + "balance": "267785134400000000000" + }, + "a9bc33b9c99dd5a3967387c1e99766f9bc74d591": { + "balance": "65356157048000000000" + }, + "a9ccf1cd2f816b15182997e3207d9a681bf21b06": { + "balance": "17521053440000000000" + }, + "a9e54bd9826f853f65e0be1ec0bb9c28f95e0eea": { + "balance": "6260000000000000000000" + }, + "a9ef563c872342f49817a903a5725b504d455ea9": { + "balance": "50134015139000000000000" + }, + "aa0d69c7e1382cd16c527a3fee48db19c38e1398": { + "balance": "142562301500000000000" + }, + "aa12abcc3ab373d07bf560fd200652c8580fd967": { + "balance": "5509242259903000000000" + }, + "aa1d6b968b3f8046a94f128864bfc612fc2e2700": { + "balance": "489179780895000000000" + }, + "aa20b8559d6dd1543e8c528775ae4b04c6242471": { + "balance": "169000000000000000000" + }, + "aa227e9d6074a60ecd43e1cc24092ee58560374c": { + "balance": "596190898010000000000" + }, + "aa7b660fec7b05968ba656eae9a8aaef4481720e": { + "balance": "674642002744000000000" + }, + "aa9e04077d44d288978a3a3ab0d7c251c0447a4c": { + "balance": "10000000000000000000000" + }, + "aaaac1e72955e9d67625cf8bed73fa643fb1cc1a": { + "balance": "9781187987000000000" + }, + "aab46c0c2db4e330834081f97678906252746f97": { + "balance": "16440184245000000000" + }, + "aade5358c52b8aa5ad8ff285c6b297e86f49fa0f": { + "balance": "982846000000000" + }, + "aaedb3fa2cf0ebca0ef4a121a28a406264ccc900": { + "balance": "100000000000000000000000" + }, + "aaf30bf76362a03450aefaf5bd68d28b84eb4962": { + "balance": "509106199370000000000" + }, + "aafbaaa6b6369e986ba72b196bd5f08cc458e344": { + "balance": "216372214000000000" + }, + "abb03c888d61c9102827a1dc0950145beb9d96b3": { + "balance": "144000000000000000000" + }, + "abc6dc937d7703a6b0c83659a328cde0d5008e32": { + "balance": "4052429106341000000000" + }, + "abd3910139a97cb92dc09a8a0352575bcc9ebed3": { + "balance": "24028359215749000000000" + }, + "abdc3953ef293c98989802063f8cb55e0e506432": { + "balance": "64000000000000000000" + }, + "abf1a47c582bc87d36e47cfce24e0ad249f42e73": { + "balance": "71947491720909000000000" + }, + "ac0b6e7aadfb5ffafd5cb3ef3620ebb0691cc3fe": { + "balance": "10000000000000000000000" + }, + "ac1a182607046b56e7a4bbab87cc1182874f79ef": { + "balance": "453499500178000000000" + }, + "ac251b311f781ad7a43d01b0b4b20fe891004e7e": { + "balance": "304621378298000000000" + }, + "ac258cec5ef49f96612d659f66dd4e6ea88e3c87": { + "balance": "255185373455000000000" + }, + "ac4000d9ad080740ef4a2ebe4a3075877bea277e": { + "balance": "10000000000000000000000" + }, + "ac7445c09372f15259fd852cc458783d6140c0db": { + "balance": "10000000000000000000000" + }, + "ac8d29dc05ea6c2f5409a76abe04321bf9381f32": { + "balance": "22464474197854000000000" + }, + "accd52b63822d8cb5117d9deb56596e072462614": { + "balance": "20000000000000000000000" + }, + "ace63a86a2ddfc79f677344e93dc0c4750b8fdcf": { + "balance": "1355066360964000000000" + }, + "ace83deb83fa8d319979658592b75ed13bdf97c7": { + "balance": "20000000000000000000000" + }, + "acf91515df16b21f1e5f5474dbefe596e4929b96": { + "balance": "1153047238967000000000" + }, + "ad04381f7ba89220e8fcd7e200f98a476683a904": { + "balance": "2000000000000000000" + }, + "ad22225bf225d8f705f93bdcda8d301180ea28dd": { + "balance": "1272512717188000000000" + }, + "ad3f74034ff5ca89f97b2585edf12376820307ab": { + "balance": "12303261515593000000000" + }, + "ad43a3527ad2b9445417cb73cbcb42965a5f469c": { + "balance": "67607364133000000000" + }, + "ad61cf9bf560bd5da75d55738477bd9aa25fb0b8": { + "balance": "4358939446693000000000" + }, + "ad649e8a3e1436e0604b0b8c9b1a5f1c09e06d7c": { + "balance": "344000000000000000000" + }, + "ad6b584813814db4c72c4c7eb31447d224074b46": { + "balance": "18445595367000000000" + }, + "ad7d404afc67c0e457fd3ce142cd30b506408683": { + "balance": "48218702840000000000" + }, + "adaf4d39b6806d132128ac438c2862c0a1650cff": { + "balance": "500000000000000000000000" + }, + "adda124baed2e1fdc1acc7b4a048eab0cd249212": { + "balance": "1074765673925000000000" + }, + "adef437c429d90a350b99750d4b72bc8538c5f98": { + "balance": "931901903135000000000" + }, + "adf826a0ea7dc4322d26e9d8c54c4180c1827216": { + "balance": "323567723315099000000000" + }, + "ae01d8b1668f8bfe6e225bd9bc746f7e839ac0d8": { + "balance": "321211880744000000000" + }, + "ae17de3ae6127022e53ebcf9e08457174cdee0e9": { + "balance": "3817903000000000" + }, + "ae243b0186793eddc6ebbb1a2c1f0b1cd574b07c": { + "balance": "9000000000000000000" + }, + "ae3ae1d41dfb16e19a1817b3639cd4300fd166c1": { + "balance": "55437674845679000000000" + }, + "ae506999882d4c6f05cc7979c342c0ce559a8df0": { + "balance": "1391755905401000000000" + }, + "ae524cee5aa23025d6ad185ccab75a6974335d53": { + "balance": "797132751509000000000" + }, + "ae5a55075d0541f179b085152bfc8c72c74abe23": { + "balance": "589408139567000000000" + }, + "ae63d02b18b464f0bbab4de943766bdc7ba2926d": { + "balance": "300261019201000000000" + }, + "aed8ffb86a49c09ae3a83e93d9045851434a9f0c": { + "balance": "1031991707237000000000" + }, + "aee18a9a2ccdf6025d61005827753ce4f510f7e8": { + "balance": "1818639022863000000000" + }, + "aee67910c514fa63a228769d5e15ca40bc4b26c2": { + "balance": "5688989238568000000000" + }, + "aef744eb2ec682dca128dc3149afcf881e367121": { + "balance": "818801643225000000000" + }, + "af04430b3e40e746127623532353a0f177a88fe3": { + "balance": "100000000000000000000000" + }, + "af181833edb15c9b2ee2329dcf1845b977361b7d": { + "balance": "93228805338000000000" + }, + "af30db29765b4fda6f075af96e8acd5046b099c4": { + "balance": "1000000000000000000" + }, + "af31fd30cfb10f1b0a12c2e7dd7ca56bdf517745": { + "balance": "36000000000000000000" + }, + "af70d6820e1d26194b0a9965b55254a287b162f3": { + "balance": "87593999609754000000000" + }, + "af96a573fa86c07389a71db797bea689419b23ca": { + "balance": "36000000000000000000" + }, + "afa4c5b674934e31a9aa5e3e723d85060d51c4d0": { + "balance": "10000000000000000000000" + }, + "afa6e4b4060c2e5969c2329d13cc42924412efde": { + "balance": "127502378589556000000000" + }, + "aff2308ac607f85392f4c8a6a043af67b7b849cd": { + "balance": "11130371831000000000" + }, + "b00ea9c459105b650def1e8569c85fa01837454d": { + "balance": "94928352162000000000" + }, + "b02a7d16ea8663c88416e6f64eaf57787d230be3": { + "balance": "17215604601000000000" + }, + "b03f4e9aa5c352cb1cec953d1123c2f22cd94b5b": { + "balance": "206022552274000000000" + }, + "b051459b91d253c5e8251a5a68282c291833466a": { + "balance": "297127749975000000000" + }, + "b055bdc874ca5a7d2f4bcbc51f1cfc3671b55f72": { + "balance": "1421913523478000000000" + }, + "b06156b99b891b756262c5b40db9bbe39fddc77f": { + "balance": "49000000000000000000" + }, + "b076893b9841d2775ec8883f05b74f1e5aec327c": { + "balance": "22591055478000000000" + }, + "b095de644af3c9f960f67502da6ac5eb050a158e": { + "balance": "4958067562725000000000" + }, + "b0a1f794cf70422395f74395abc9a7d0b271846c": { + "balance": "812057322000000000" + }, + "b0d36e0f426a99416425689c657fc6d64ad698ca": { + "balance": "1157727077158000000000" + }, + "b0f35fa554d6ed657bf3996cc027d045c3971fcc": { + "balance": "64000000000000000000" + }, + "b0f76b4c9afdfe35c41d588265642da60f1b97d1": { + "balance": "1000000000000000000000000" + }, + "b0f76b4c9afdfe35c41d588265b42da60f1b97d1": { + "balance": "2028311808491377000000000" + }, + "b1445842d56c56bc532d2f33ab9b93509c732a3b": { + "balance": "13522982470164000000000" + }, + "b156bafe05973bc839c4f115be847bbde8a67cb1": { + "balance": "10000000000000000000000" + }, + "b182e4d318893dc1c4c585195dbde52a84ed4ffd": { + "balance": "329498977335000000000" + }, + "b18f506e77df4db80ca57cefeaca4f1010f78f50": { + "balance": "956339304078000000000" + }, + "b1b6f617b110dd79c8fd77e729584d1fdfa9aa09": { + "balance": "16000000000000000000" + }, + "b1bba36e2d9e272e0131f4bae09bcfd92e0a63db": { + "balance": "64000000000000000000" + }, + "b2285651e57ae0ff27c619207cceacd20884d152": { + "balance": "1345938295122000000000" + }, + "b2419a93732d0d324daf7707fac3782a77b0dff8": { + "balance": "625000000000000000000" + }, + "b27206e9f2ac430841fb8da69b49d505f1558b8b": { + "balance": "29507819229000000000" + }, + "b2801fe902c7bbc987ba12ecae98765c99980fef": { + "balance": "240016083000000000" + }, + "b2843d5215ceb761e78f281402a1660c3abadf5b": { + "balance": "3335539720927000000000" + }, + "b2a22e6a04a2ce3287da3b8b6eed4ea1f18f05dd": { + "balance": "99999978999999999999" + }, + "b2d55a061fc6f90d2a05e0cbd26ffe0a1c3321c2": { + "balance": "1000000000000000000" + }, + "b326aec1cd523948ffec2fd1e8f21bd2b4308f40": { + "balance": "913000000000000000" + }, + "b32abc82b251e2d310ea7588cae4ad4acb657cd9": { + "balance": "26946233911000000000" + }, + "b36924d578973aec05ce7ab556d7ed00004949ca": { + "balance": "393041705867000000000" + }, + "b37482114c83e857c730588d7d959d300b8142da": { + "balance": "29429544454000000000" + }, + "b39998bade135ac6ccadff41cd709e161d01aa60": { + "balance": "26272579375000000000" + }, + "b3a995ee94f1d63d12f10cea5ab3d596c7c6f284": { + "balance": "64000000000000000000" + }, + "b3bf35e936fdbb7d0bbeeb1cf076f243855ed477": { + "balance": "754081187934000000000" + }, + "b3c2ac85b99abed4a2a52b5f96a2c98040d16022": { + "balance": "50000000000000000000000" + }, + "b3d1a2c0ab2d8987446d74f49e357adf5bf15986": { + "balance": "10000000000000000000000" + }, + "b3fbcd24c8394a5d2b7fe877f18681a109a404e5": { + "balance": "2558689648423000000000" + }, + "b4110f4e38405adfc054e55ff73c55842db8e2cd": { + "balance": "129000000000000000000" + }, + "b417f4681fdd4e53cfdf8550e3d326dbb0a557ec": { + "balance": "1000000000000000000" + }, + "b422970fb8799d83642b7ff715fc941d69e86053": { + "balance": "81000000000000000000" + }, + "b4237be71920497715826eae8d85c26cb3c111a8": { + "balance": "10499979000000000000" + }, + "b431839de4b21dfb44150cfc6ed00ea430a81687": { + "balance": "26839560174813000000000" + }, + "b43a0d6399c7d1be943c4b45838156a47c88f909": { + "balance": "10000000000000000000" + }, + "b44ec608b95d0d51105ce5f4b48de5dd72f346fd": { + "balance": "448125120000000000" + }, + "b47f63e14f6de6c3413b2be95a725e367ac18fb6": { + "balance": "500000000000000000000000" + }, + "b48071cd1b15f45028e9dec2237f14f10b7aedf9": { + "balance": "38042711385000000000" + }, + "b4b874b323b560aa0e4811ca574bd48b65b3fc72": { + "balance": "18063913676592000000000" + }, + "b4e4d4af0667f8158cf817bf1bc3eada08a551ca": { + "balance": "2149067370317000000000" + }, + "b4ecd625ffe470ee1fa1d97832e42ddf3f9ddf6a": { + "balance": "1181738860120000000000" + }, + "b53f380ce92787c1db461524290e8fcede552fe7": { + "balance": "12640674931821000000000" + }, + "b547e04ab8a44d3cae38704356f1f59408457b67": { + "balance": "286604155735000000000" + }, + "b562e4010a0a5fd0906a4cd9f47fc28f6f51e210": { + "balance": "1000000000000000000000000" + }, + "b584de7b38a2a2e3d9ff9c055b309ca56e5da5a9": { + "balance": "237896887904000000000" + }, + "b5c1129961c4a43673324aaedb8296f5ade82516": { + "balance": "4213058948283000000000" + }, + "b5da6711c72bf27c87923aed4a39349b4192e6b4": { + "balance": "55180742586465000000000" + }, + "b5eac5e7e03b9d31e40393e16e956cd588cb7566": { + "balance": "4508019435556000000000" + }, + "b5fd46ee4e02946dca3485439f98bdab290c82b7": { + "balance": "108321600045000000000" + }, + "b5ff2a3caef6ec30365f4f0ecbecbdeec1cacbba": { + "balance": "979696597242000000000" + }, + "b609d05242f7c13a4ae4036f6da9c0bae18dd70c": { + "balance": "229121731278000000000" + }, + "b611156a2f87fb45c431a5cf5740ded90c2dc542": { + "balance": "401783365700000000000" + }, + "b61c7623144afbd0f6cf44c951e4219ef8096119": { + "balance": "36000000000000000000" + }, + "b61cbe0e58ff6fa4c810ad03c759c79d9ff052a5": { + "balance": "1034495371371000000000" + }, + "b622bb67e95a03f58dc9aecf82c217e86f2cf7c3": { + "balance": "500000000000000000000000" + }, + "b62a50be3ce0e7cf8f61991daf8fa7e23775141e": { + "balance": "1000000000000000000" + }, + "b63cbff6b1747ad5cda101d5f919ce81dd67e363": { + "balance": "2570089937000000000000" + }, + "b65e80551a8687c9cef2d852949177c0e3b56e51": { + "balance": "100000000000000000000" + }, + "b68126ebbcb5ab9b0371b62597a38d5c1685b0df": { + "balance": "671140851028000000000" + }, + "b69f5830c371cad5a74ae823eb8892d153ef3c23": { + "balance": "18446744063709551616" + }, + "b6b4468c4db64e0b85cddc251d02f32fffcd1f7c": { + "balance": "10308006217291000000000" + }, + "b6c129312505e571148dbe69833d30550efc12c9": { + "balance": "5105834767567000000000" + }, + "b6cee8ef00b8674a9a96447e4511b30d6564ff67": { + "balance": "667754569888000000000" + }, + "b70f805aeba260d44f0730f0a9dec60f2b4f54a1": { + "balance": "2751303297000000000" + }, + "b71a901dc4b6c6463f7d221f868677bcadbcc680": { + "balance": "169000000000000000000" + }, + "b7385bd8f8257331f4c7a87c7a23724f615cff8e": { + "balance": "196000000000000000000" + }, + "b755692bc027e30730dc1d0e0b2a883830a84115": { + "balance": "30713083153428000000000" + }, + "b765305dda3c1e069a7a022ec127ff2140d0a820": { + "balance": "603122990932000000000" + }, + "b77403a4c56ffc7715b4bfdfe4b054336aeca466": { + "balance": "130840969728386000000000" + }, + "b78b2f6dc731d7d84b7eea151805f9208a1d0cf0": { + "balance": "142084687500000000000" + }, + "b792a0fd762c002a7585cfdefd36cf7ffb42fc05": { + "balance": "10000000000000000000000" + }, + "b7ccd7164aa7fb871726d9d043a8f8f890068c0f": { + "balance": "1170997140237000000000" + }, + "b801f49018317caf30f310dbe116f4e876184874": { + "balance": "50000000000000000000000" + }, + "b81ca2bc63cb4008cebdda3ce8f4eaba322efca6": { + "balance": "4678481047354000000000" + }, + "b82e3d50bf8c5b471c525ec8dd37b06688ed6178": { + "balance": "1202448975553000000000" + }, + "b841162a7a8876296f10794d8847d8095426aa54": { + "balance": "73500210754000000000" + }, + "b8421d375c3f954e22b6fd304235dd7c43b68bd0": { + "balance": "6499782706009000000000" + }, + "b859b76d77eb604728093c61fcabe6f9d22433b0": { + "balance": "196000000000000000000" + }, + "b86536268ace9be93a1db2012d6e3e59023ef2cb": { + "balance": "52878034904067000000000" + }, + "b87e1ac4fc423ab37e10ffd221df8056537b1d03": { + "balance": "119159824674000000000" + }, + "b8825a99806c5a968423e69d22f2b61a2f0ae9e4": { + "balance": "999999999580000000000000" + }, + "b8835acaf63e0e5d41fb743eb0f954040a38d381": { + "balance": "64000000000000000000" + }, + "b8844c74b227781d4b3fafd32e39ff6fa9857f77": { + "balance": "490694157000000000" + }, + "b8962e8bcbcf0f69144f8fcd2ec3ae8e54c05034": { + "balance": "1425313342735000000000" + }, + "b898b4ece8e0eea375f6eb85615652cc5c221593": { + "balance": "2284038029169000000000" + }, + "b8a949bfd9751c29c4cd547cca2e584d8dac4e12": { + "balance": "50000000000000000000000" + }, + "b8ad5ce2ae781e2d245919c15bbbc992185e5ada": { + "balance": "733786526623000000000" + }, + "b8cb6a9bc5a52b9cfce26869e627b2af0ff5ed4a": { + "balance": "98364826821577000000000" + }, + "b8cf6aac7b9028649f0d55a57b61640d70cef120": { + "balance": "104799890645000000000" + }, + "b8e827b5d1e10a3944039adb1a3dd7ff6949145c": { + "balance": "172413427060000000000" + }, + "b8f6d7f33ee5755ba56647ab8fc9ca27b8aba677": { + "balance": "1430769696978000000000" + }, + "b9221177e2b09725bc95f08c72c17c42887eea62": { + "balance": "1212779749827000000000" + }, + "b936e0d83cde9bb810b85ad58eb5ff0fa9c11654": { + "balance": "4999580000000000000" + }, + "b961d435c457e205fdbed5442c8614ecfd59616c": { + "balance": "27847452621284000000000" + }, + "b969e9d89f32002cd4f90ef5907bebbbdca6fe6a": { + "balance": "12455448454838000000000" + }, + "b981c9137cfca5389f0123927852278d2d7ff618": { + "balance": "92180707865000000000" + }, + "b98abf0fe91b0d3a16c6ed37aea446baea33fd23": { + "balance": "560454425563614000000000" + }, + "b99ab4e6ae277b9fb04537adbb781e8390b490ad": { + "balance": "32814665223319000000000" + }, + "b99d0a433d7994743dd675894c18ed03164436e1": { + "balance": "16000000000000000000" + }, + "b9d8b6f0a505d217709bb9327f3b9b3f84813e00": { + "balance": "81000000000000000000" + }, + "b9dbd64e3c8e6ad84c9c67c66e678c06ea7bcb91": { + "balance": "1161140466507000000000" + }, + "ba361f7a6dff16a96f957c63e08267dec8f9ecf7": { + "balance": "2170060167590000000000" + }, + "ba47f4136f74b566f62ba373651332b59e74e1db": { + "balance": "906249296535000000000" + }, + "ba5287cf15de91daeaea2465da4d4c1a14dea716": { + "balance": "98978398162000000000" + }, + "ba77d056d52f84e740579aa527792f826591c858": { + "balance": "50000000000000000000000" + }, + "ba895406774ced5fd2e759b58f9ffaed5e04fb14": { + "balance": "10000000000000000000000" + }, + "ba96fab21a4926fd1137558ae996b52ec14538a6": { + "balance": "10000000000000000000000" + }, + "baacc247801eddbf152fd6ec39d659f265935743": { + "balance": "2661902597584000000000" + }, + "bab2eb9fab8e699a958699b15ddc7ada5428d33a": { + "balance": "27006404153000000000" + }, + "babeacd7933c817472875c86bf126e6d11886f8c": { + "balance": "2461234517292000000000" + }, + "baf7021d4d754d4478d3c3624c2376e3f1d4ee5e": { + "balance": "1352066301857000000000" + }, + "bb0760bd1da973d8f70dd0caa6cadfcfd8199231": { + "balance": "177674700430000000000" + }, + "bb278c6a52eebd0b8950e9b78ba211453ccb1b6a": { + "balance": "25000000000000000000" + }, + "bb327e5f260b2dfe25fb180c2d3f4b63211c1dee": { + "balance": "7694972715000000000" + }, + "bb643e768ab20c135e7df3f400284cf04c40a6f7": { + "balance": "385756449779000000000" + }, + "bb73d1d1c289b4953d0033b52d9d2d0d92573d22": { + "balance": "11000000000000000000" + }, + "bb89936d562b19e4c599826ce7cd0c60cb02b512": { + "balance": "725910446589000000000" + }, + "bbc509b7999b0e94534477b98ec8927cba879677": { + "balance": "20000000000000000000000" + }, + "bbcfa9ab62f4eab14d6a1b09c1aa554dae113183": { + "balance": "589417352665000000000" + }, + "bbe78301134249b52b74d73ee3855e7e3d288a40": { + "balance": "4456159000000000" + }, + "bbe7bb4c4f1b506b58f7e3334e6c89011cf2d6a7": { + "balance": "3889127030000000000" + }, + "bc016690596e077273465d1728d18553b185654c": { + "balance": "185932953686000000000" + }, + "bc16b2ab9c7ab309249f93b496b75c6a7392cb10": { + "balance": "5000000000000000000" + }, + "bc254e5405b154b98abb5fe5508d3e7c98663f4e": { + "balance": "144000000000000000000" + }, + "bc258aeb0f18150d3ca253c6bb04f63d657d99ac": { + "balance": "6011905701701000000000" + }, + "bc2620b5ebac12a88b287b625fa5b336568e7869": { + "balance": "534886892259000000000" + }, + "bc318687cfaae2be4c5ece4a18bb9252486a19d0": { + "balance": "147226513970000000000" + }, + "bc32dd123fcc2ef0dc36484c3ab1bae5d9890761": { + "balance": "16000000000000000000" + }, + "bc5c5151be06aaf6180bc9c1058b181a5a30366e": { + "balance": "113865120384000000000" + }, + "bc66241ca430dc31a3e2f44dedba868e16b9a6a1": { + "balance": "50000000000000000000000" + }, + "bc7c371af0688b1c409f4b07662609a1c9efd120": { + "balance": "20000000000000000000000" + }, + "bc9454f7efc86e25d18a8e8b6e230de42a51d967": { + "balance": "148103676062000000000" + }, + "bc9d5456b975bf0b95c161c3355e4ceb28898fd9": { + "balance": "28083912047000000000" + }, + "bce0b47bf13e4517c53bbbe6e51544b99f3147f6": { + "balance": "919711480389000000000" + }, + "bce2d1ec7c41b426f72b352f5f2b7da3edac4157": { + "balance": "908085365725000000000" + }, + "bcf0756789a57f16206dd78bf6e1322ba9b9b85b": { + "balance": "110888224252000000000" + }, + "bd0bc4a0730f9f55a2f65f62662c7553db52238e": { + "balance": "8440290043000000000" + }, + "bd29fda37c2581a3f040c77eead3143cff24a346": { + "balance": "126022762542000000000" + }, + "bd4c1270322a26a1b825040b239008a447c31918": { + "balance": "727012140904000000000" + }, + "bd6a3da2db66dc9fa26fa2b63b14003d26ef91d0": { + "balance": "5492112771780000000000" + }, + "bd80fcccac60078fcf09f5bddd8a25a92fb9cfdf": { + "balance": "10000000000000000000" + }, + "bd92dc94b6e81a3da5dc3ae6bd80782622658196": { + "balance": "10000000000000000000000" + }, + "bdb35c2c595fe7a2864ebe20dd56d6ddaf9d447c": { + "balance": "4346566125000000000" + }, + "bded4718cbad2150c9b6df9ee7356e0f5c713cea": { + "balance": "311694803600000000000" + }, + "be1804630ecd95ac411b935566cecc5a24c6f18a": { + "balance": "85033246331000000000" + }, + "be2318ad50b0a85b95870a81dce5c31029636159": { + "balance": "5185298019030000000000" + }, + "be3de52fc1119f02f4707f353c040b7c4222d847": { + "balance": "25267399461000000000" + }, + "be4feae01d429c872601ae84dfae8fddc3372686": { + "balance": "20000000000000000000000" + }, + "be7c09d704d16e4b2c9e19cc8c07808bb335f926": { + "balance": "25000000000000000000" + }, + "be873a9525899bdad5e4376b0115950e534dea2f": { + "balance": "404116929377000000000" + }, + "be891b1680ad835aab1ac05a30c0813306cf20f2": { + "balance": "144000000000000000000" + }, + "be8ed2d85a5e3f83c6105db1a1f304e9f174bfce": { + "balance": "50000000000000000000" + }, + "beb1cd80c2f8fabc27ee3a3b2a15e35fa52e7879": { + "balance": "11539095431000000000" + }, + "beb67375e46950830906bf281209be133075452f": { + "balance": "1305262446956000000000" + }, + "bebe54437722c6000bc6a8843f159538a2abf613": { + "balance": "41042548942568000000000" + }, + "bef2a05e283ae948efa9b0e3a6ab5d26a57f1de0": { + "balance": "180614450853000000000" + }, + "bf03950f265a4182b4402703723a0311158eef4f": { + "balance": "158997402149000000000" + }, + "bf06393654baa1ad15c2e717e06dbaa61834c214": { + "balance": "34409427774000000000" + }, + "bf2b867313a44bd04aceaa644771d1e95317c881": { + "balance": "10000000000000000000000" + }, + "bf350ccad91a2a2aff4cf27a291323a297a78009": { + "balance": "124593326152000000000" + }, + "bf3d86edfcf52733e91a9c59be606a95bd921885": { + "balance": "20000000000000000000000" + }, + "bf5b21d5e339752b33b180064d0e6047338650a5": { + "balance": "1000000000000000000" + }, + "bf64c2715db8f353600a45b9264e1f22a40ef8c1": { + "balance": "2952972677360000000000" + }, + "bfaff32c8b04a61658ff94f94e4687232b8d2d7a": { + "balance": "1117691379350000000000" + }, + "bfb00182321502e0729d9a0862ec1df1b3e2208e": { + "balance": "500000000000000000000000" + }, + "bfcdfc9f60610f0ca279ca2c89b9af831332aece": { + "balance": "1431082635308000000000" + }, + "bfe14356e86f6b2ad470bc77d250517c8dc03d15": { + "balance": "310115085185000000000" + }, + "c008bd3fb881da9dca4cadcc56b1d99c56db9abd": { + "balance": "12899598792000000000" + }, + "c01efea456d30360a78ee10c790d46bcb889ee61": { + "balance": "103203021492000000000" + }, + "c03d622627bba7d5db1a9f699924e9d5ff5640f2": { + "balance": "95102233308870000000000" + }, + "c0465ed806ce7ee730e5b6eb7b86a754bfd196a9": { + "balance": "1654379359619000000000" + }, + "c061c5b0d0ce7af95ded1805abb23f743e13c455": { + "balance": "500000000000000000000000" + }, + "c074f2024f79cf8d7aab2d858dd110fc2ee89d41": { + "balance": "18382732686000000000" + }, + "c085147a76d0336b4bd6e7d5b60d394bfd3c6f42": { + "balance": "3236912707535000000000" + }, + "c089416d2d679cb2abf44251de227d0a08fa1206": { + "balance": "497124416350000000000" + }, + "c09d8cfd85989397dc723f2df821dbfb2c0c39b3": { + "balance": "833485701262000000000" + }, + "c0aaf130e3b67250d9775d62e7cd3963daf0a627": { + "balance": "1249947125780000000000" + }, + "c0aebdb5c2e8c5ff9870535c738bfe892c9365dd": { + "balance": "360097616959000000000" + }, + "c0db5680ba88052652bfd5a617c4e8a5be188077": { + "balance": "509051625766000000000" + }, + "c0ee350e5e09a2daeff332a66a6e117fad102112": { + "balance": "10000000000000000000000" + }, + "c12c0a3fd42501f8772e4ad5d262eef3f0bc4701": { + "balance": "120398848512531000000000" + }, + "c135b48c7fd11670bbfba923b28767d21d7923ea": { + "balance": "20000000000000000000" + }, + "c1397c66b7f150c0062b0e87c981c107d771b109": { + "balance": "87751498250000000000" + }, + "c1507ee435cf506fc5d8e4cb62515f2ea0f3a7ae": { + "balance": "4935384099000000000" + }, + "c150d185e2cf203054a6e328b72d8c35bfbbcc33": { + "balance": "21044148271000000000" + }, + "c163098f8b8f0736862274860b3842cf14bd2288": { + "balance": "119025568966000000000" + }, + "c1687fbbc7d504b73fe3e71af440b3dec0da88b2": { + "balance": "229520711528000000000" + }, + "c172bf224080d448261b3b66453074b28628daf7": { + "balance": "7903438287958000000000" + }, + "c18e9bc05dfee2a39fe2b6778a24a48d5bf0f141": { + "balance": "500000000000000000000000" + }, + "c198fec4069c95300d34b9c7109d7441b8e62745": { + "balance": "50000000000000000" + }, + "c1b4134f4757d19a687d05bd7087872b5625405f": { + "balance": "20000000000000000000000" + }, + "c1b43ca2af534ac6bcad8f23c30c07ba07e7e8fb": { + "balance": "194999622000000000000" + }, + "c1c2249507d2dcaf4a9103fcea2cfb47aa4957f7": { + "balance": "571416394325000000000" + }, + "c1e90af40fb64427aeb79a13607debbae9270b52": { + "balance": "50000000000000000000" + }, + "c1ffc8938f3412d19d428b8450f17fd394ae539a": { + "balance": "36000000000000000000" + }, + "c20013e25ae53d0d41bf365aa767822bbbe70936": { + "balance": "10000000000000000000000" + }, + "c20e9eadffa5529ce58a39f5898f39906dcd4b78": { + "balance": "757301065305000000000" + }, + "c211fc2623d51846d26952628d140643efa5156c": { + "balance": "865384323985000000000" + }, + "c2546c312570b30ad2ed05edb13b6469494c5b92": { + "balance": "5000000000000000000" + }, + "c25b2280ed0f835538f8ffd9dfc08a3b853f1ccf": { + "balance": "1000000000000000000" + }, + "c260e43b89a7a4e84bcc4c21dc43d4b5e6923f3a": { + "balance": "1000000000000000000" + }, + "c26aeef0e1f382c88bbdb1eb8c01afa7f58218ce": { + "balance": "79774757760000000000" + }, + "c27dd2645254bc30b6cf7bf418803b02ac808b5e": { + "balance": "4419594173874000000000" + }, + "c2b4f6cf92d6d63a20034e409a358df1803159b8": { + "balance": "1630820442000000000" + }, + "c2ba4a7ea6ca2d17231fb17ebd5dd2dfc0964de4": { + "balance": "221662324727000000000" + }, + "c2bc18f24b8097208a8b2418c444ea58beb94281": { + "balance": "1766754009521000000000" + }, + "c2c028dd17f8a89b9131b7daaeae9cb1dddf86e7": { + "balance": "10000000000000000000000" + }, + "c2ed78a0cb850c12ce8e6ff3873e8c18ffc9f4b9": { + "balance": "1017518755567000000000" + }, + "c2fd7296210b7013d476205d2517d51b21c9e76c": { + "balance": "500000000000000000000000" + }, + "c3041d3d650ff6ac3e35b60371b6798360727651": { + "balance": "1011071365226000000000" + }, + "c328ab9ce1fddd5623e0383828714a7e3ff12eff": { + "balance": "285042661579000000000" + }, + "c34ab008ddddf376dd866cccae4a4d6eb88403e2": { + "balance": "2798642711076000000000" + }, + "c3511391c4515cf8f27e9bc0f777a02a4125c8b1": { + "balance": "20000000000000000000000" + }, + "c36916a9fdf656bb1a8c2f7fb752a3489020f6ff": { + "balance": "689483152953000000000" + }, + "c37598a388d6f4e8e046923265ee9256456e40ab": { + "balance": "62865106394696000000000" + }, + "c38813db256eb221a7142d042b81ba2babab2c31": { + "balance": "98477603778000000000" + }, + "c3acd30f0bc3146fc2cab8d54904f98289021374": { + "balance": "17820000000000000000" + }, + "c3ede34dc1cd995fda1c5cb6e9ffd0c0da080587": { + "balance": "1080428143758000000000" + }, + "c3f04dffe2be55a1d6cdaa78e5c09a79d0477e7b": { + "balance": "59747493842929000000000" + }, + "c3f09f681cfb57d3cabc547dc32a71d2a6585c1a": { + "balance": "1757648436173000000000" + }, + "c3f3bb6444d853614f18c04a3c81f7d26e62e96a": { + "balance": "9022830778000000000" + }, + "c3fe4534327a2fc4144e2d3d3392f7b78d2aabc5": { + "balance": "1759225739027000000000" + }, + "c424f5be9490ec7f0f1e2debc3f72bd83e35f587": { + "balance": "1774372626989000000000" + }, + "c434f64eb937207f80e9a02d2f77ca34bfc63aa2": { + "balance": "960850858644000000000" + }, + "c438b6fa5801a4b8dea450530d975f174cdd47ef": { + "balance": "64000000000000000000" + }, + "c446effb984ff3e5ed92280e7b3dcdb1284230b3": { + "balance": "503490303680000000000" + }, + "c453ae9f94253ebdb871e9dac19056b13d1747a3": { + "balance": "1621494076559000000000" + }, + "c4a473b5e3a6bfb51f963d4dcf109bddedf4fb43": { + "balance": "104273242373000000000" + }, + "c4b8058e9e5416e526ea16e37f29dc221d28a003": { + "balance": "1833513486496000000000" + }, + "c4c09f4bbae0ee06f2a52ff0ef0de1978b5305e9": { + "balance": "20000000000000000000000" + }, + "c4c5981f5ac0a9a3701663b887c4aaac3a3a4d1d": { + "balance": "1411640000000000" + }, + "c4f7a493d16aab4d18e88e530e75e3095a3439ee": { + "balance": "191606419322000000000" + }, + "c5259c18bbd8b0485ca83d069d5ac235b28f24ea": { + "balance": "1276479076242000000000" + }, + "c526ef1124c7d0549b117e7b7463539a24209290": { + "balance": "9106523141000000000" + }, + "c5278b9eeff2221604f30f002c307ca2882fba97": { + "balance": "20875716591000000000" + }, + "c527ca73562846de9fca1649fe5144e5068a2f6e": { + "balance": "25000000000000000000" + }, + "c52a960c5df55169ed5d5cb0109a576321ab82fa": { + "balance": "1097338876493000000000" + }, + "c533ab799e5a04e0ba4e4780d632e0044262d216": { + "balance": "200529941482000000000" + }, + "c5389e3ee2f043ac2b6481f254440a97a9cf3bdb": { + "balance": "84047554571000000000" + }, + "c5594292b324c1d63f797c588a589c895c680ed0": { + "balance": "334298857161000000000" + }, + "c55d7ae4f29d857182d5f1ac2a78cbf35a694dc2": { + "balance": "500000000000000000000000" + }, + "c55ead0ece8fcfbecc573666c0170228e089aefb": { + "balance": "438775082956000000000" + }, + "c55f7d73491cdba391b631581029de32755a09b8": { + "balance": "1340000000000000000" + }, + "c56cb4e8308d6462eded0bbc74965ee135e23e11": { + "balance": "568187503785000000000" + }, + "c5b0c5f840f579536d5977a77262458d72ef1490": { + "balance": "5880686297881000000000" + }, + "c5b129c764daac8bfbf023646b9306d817a8ebdd": { + "balance": "10000000000000000000000" + }, + "c5bba43db949e2ed3de3036caf7a6e42558b1ef2": { + "balance": "763947031151000000000" + }, + "c5d57171e5b9cbafaba7d2c13cca3ec9d81bda49": { + "balance": "25000000000000000000" + }, + "c604e6c539c857ae9e60ca20d1906308ba431892": { + "balance": "100000000000000000000" + }, + "c607bdc5ad2f189e9356edb4d7975c7ba9300836": { + "balance": "55828814399000000000" + }, + "c60b0d2341ecada6c3faf1efcc9027125d99e17a": { + "balance": "121000000000000000000" + }, + "c61e1b993c3fd91a1023ba5b92d06a0aa539d92c": { + "balance": "23863993763643000000000" + }, + "c624656ee5298786cb3d0de045b0ac089c5341d6": { + "balance": "2210389938000000000" + }, + "c6573a023d6f4b5e151f266af4ec0045df0d1518": { + "balance": "52505006485983000000000" + }, + "c66b1d84c42018b16dbc4777409bf50a49febba9": { + "balance": "9078953000000000" + }, + "c69e4de93457f251b1e0879b5250b26e57839fec": { + "balance": "500000000000000000000000" + }, + "c6c51205c9f0bcaea05dce8e47e91d94a3f63c2a": { + "balance": "2720612321571000000000" + }, + "c6d237e0936c4714e701823aadb368fdc471451d": { + "balance": "541700595551000000000" + }, + "c6dcac15739872089cb3d23287e8cd546487ecf2": { + "balance": "1023857245227000000000" + }, + "c6f40b81a5860dece34305f53570be61cdf9a8fa": { + "balance": "20000000000000000000000" + }, + "c7147a95cc4f6bedce6292e8f95539caf550e9d6": { + "balance": "20000000000000000000000" + }, + "c7185b1a680d8b0893065d8213de54375d086420": { + "balance": "11564622085000000000" + }, + "c71b3876613c928197aadf3dd7888db3665f28f0": { + "balance": "112276274428000000000" + }, + "c72200bb380db62a3fd741713d332be77bc1a4ed": { + "balance": "6962060809000000000" + }, + "c7345cd5a7eafc9d7ebdc17d674f83e23336538c": { + "balance": "4425703195684000000000" + }, + "c734f9dc3ee2d857ac826b101129eb77a4a22256": { + "balance": "100000000000000000000" + }, + "c736fa9550b73f4a4ca0ac1cd94bf6f42ccbb11b": { + "balance": "449139000000000000" + }, + "c74128ea37f5d1ee016086a38e470bb332eb5270": { + "balance": "40479951869000000000" + }, + "c7647ec91e823cfe57e8a3433ddafd7b4f675b80": { + "balance": "307102062000000000000" + }, + "c76d49334ce25f5fc62841e5a87d4e03ab3edd9f": { + "balance": "109999979000000000000" + }, + "c771093ed5c4df518536b76e013e8142ecc3f9ed": { + "balance": "5247752820195000000000" + }, + "c780dfb4cdcba4dc89245a8be8a93de1a3e82d3c": { + "balance": "205580199482642000000000" + }, + "c79c6c3a0a46052f723a26b1f107a332474df3a1": { + "balance": "50370325181000000000" + }, + "c7a4e02d2c0f00fa56662cc9f323cabeff82759f": { + "balance": "1163435680762000000000" + }, + "c7c0632cff11812130c30163c83746839a625f95": { + "balance": "10000000000000000000000" + }, + "c82238664bedfa8ded51e91969a39f13a8262a37": { + "balance": "10000000000000000000000" + }, + "c877d228c350ec0d8d97802e7d874d3130171813": { + "balance": "199845203467946000000000" + }, + "c88b8a2e498fee366a1290a575a7f09da12ea8b2": { + "balance": "50895598476000000000" + }, + "c8bbd0e52b11ae6a20adc5f6bbe4d34d7440e8ca": { + "balance": "114566193776000000000" + }, + "c8ca2bd1bef02b505f0333996bcb6bf730648390": { + "balance": "1177250974576000000000" + }, + "c92c3358910418fdb3950e1a378af7246553ae38": { + "balance": "81000000000000000000" + }, + "c9325c9b6d2af226bc5ae1cc975e00cc11274cd1": { + "balance": "2927587698197000000000" + }, + "c95ae8dbc8bb075e7dcb2b2c6d9411bedf26244e": { + "balance": "931878010706000000000" + }, + "c98fc33c1d980052d75fee8b34d08796734b6a4d": { + "balance": "8671327034000000000" + }, + "c99fba8321d16cb19c55703b407c54ed106dcdc4": { + "balance": "20000000000000000000000" + }, + "c9a0da2a3be799e751738e61b9cc376eb06e2b00": { + "balance": "50000000000000000000000" + }, + "c9afc551058c32e89bc2d6704d0d00e92f5ef6d7": { + "balance": "11135553563900000000000" + }, + "c9bfa2ad4b3e9c624255c6ede116421b04487d65": { + "balance": "105514983171000000000" + }, + "c9e4b61d8ddeee339e31ba088efb5d608c3464a5": { + "balance": "20000000000000000000000" + }, + "c9e9090d9f95f401c87c7240f3bf88ca9b540f8b": { + "balance": "553735838243000000000" + }, + "c9fd40bb35284e3d7f0dd3b43a1d9e958f7c86e0": { + "balance": "50480449695128000000000" + }, + "ca038c7c9e66531ad79e4d67b42d7920b7f05c26": { + "balance": "64000000000000000000" + }, + "ca0d08f6019884f94f2b5b191ac9bb247150cd13": { + "balance": "25078089364984000000000" + }, + "ca2c6e6ed3d6a1d030807f91e1fd5c79d36af86f": { + "balance": "849454139892000000000" + }, + "ca7c7bbc24cac0f3aabfdccc77df21004672e634": { + "balance": "6952718700000000000" + }, + "ca998c74383b55c8dcddd46b49f95456fb056b7a": { + "balance": "2000000000000000000000" + }, + "caa989e6a1e934532aaae6cad282c18b1a0b9fd6": { + "balance": "2335540529729000000000" + }, + "cab32ee5cce74e0ee88bbd4b505aa587ef2e4bbf": { + "balance": "75914058971000000000" + }, + "cabe9f0d0a18de8d3495dd063b04c6a33584a8c1": { + "balance": "116083536145000000000" + }, + "cacde94daeafc06e46c86b1e20387a23d909ace8": { + "balance": "1521003430346000000000" + }, + "cafbad01b81ad6cc401883773994a9dd6e6ed913": { + "balance": "10000000000000000000" + }, + "cb343b882cfe866f73cd5f0f31fc68cebaddd882": { + "balance": "221801563082000000000" + }, + "cb3a7aa2e97517b6ea8d9ed0ac270a6a9cc6e079": { + "balance": "958830201738000000000" + }, + "cbd2c4916211ab2c234bc8a51e6f680b59aff782": { + "balance": "24279462419000000000" + }, + "cbea4ed5e8d2ffad442e482fa5f8d551ef2a58e6": { + "balance": "26730000000000000000" + }, + "cc001ce4f4417505116486bed9fdf04bf97ca246": { + "balance": "31740534557000000000" + }, + "cc0b53b26b6dee9f8226f25b834085bde13f5eb5": { + "balance": "132440104515963000000000" + }, + "cc174862456f02f349303d1b8328495de8ccd789": { + "balance": "155951512603000000000" + }, + "cc2af3921727d6d2de31d5f656f837a5475de6cf": { + "balance": "10000000000000000000000" + }, + "cc3201749f55f0d7b450110bc11f65b1ce165d2a": { + "balance": "123428947550000000000" + }, + "cc3f37ad6b449e39c544e26bbdf4d7be66b9dab0": { + "balance": "348574664284000000000" + }, + "cc5b36c9ecea12ebfd0721a58ac11b0c340a3f44": { + "balance": "384197170701000000000" + }, + "cc5b410c7797faa05ac4233eb31b468ee4bf279f": { + "balance": "10000000000000000" + }, + "cc60b223554cc6425374c5e2424df7007621368a": { + "balance": "1128118098000000000" + }, + "cc7027381d98c2e883c82bb9c2f85b985e1e7b4c": { + "balance": "1370000000000000000000" + }, + "cca378f16e07258b9c15921233110fb4729645d2": { + "balance": "151974946930000000000" + }, + "cca781d996c3ef985bf7d2b4d68d55f52efe1905": { + "balance": "2217463190039000000000" + }, + "ccd0b9f6ffb0383553c355c6a14be1200966d47d": { + "balance": "12917165349191000000000" + }, + "ccfa4594129bbb9d07cb4ae8dc2b1c8f3bf98508": { + "balance": "524845286088000000000" + }, + "cd19c879df458106d179bbb5b7f44609d68e6e5f": { + "balance": "8601633489844000000000" + }, + "cd1c55037a0570e8f9aaa95ef157ae81a1969250": { + "balance": "10000000000000000000" + }, + "cd1e47695b0fc93b82cffd0326852dc04d8441f0": { + "balance": "144000000000000000000" + }, + "cd1f90c388d76b3aeaf77850f2191f12a2311f51": { + "balance": "1728456799866000000000" + }, + "cd3aecd58de07f80b64044875fa6ad4f18f72789": { + "balance": "2648597880142000000000" + }, + "cd4f39123ece1e0ab52cfa2a5d059b49c4d63c3f": { + "balance": "1661718859439000000000" + }, + "cd6ed2f7ab49515f8fd70aeb4d72bfae8956b5f1": { + "balance": "183807926254000000000" + }, + "cd9d9d07fcf476a8ee7240324a602449606d75f4": { + "balance": "100000000000000000000000" + }, + "cda66d375a10a22f13dff8a9c40b63461daddab3": { + "balance": "1116940051064000000000" + }, + "cdb0832ee5b26da24b1775c4cf0dfd669b94ce00": { + "balance": "23919219542965000000000" + }, + "cdba5805f17df1f3e47647464de978944ed36b62": { + "balance": "4204539000000000" + }, + "cdd1df8bd54941e26ea26eebbd537e751f64f5f7": { + "balance": "5000000000000000000000" + }, + "cddf5b34342200c37ba96eb0dd662ca4c29f89f8": { + "balance": "10000000000000000000000" + }, + "cdf6c838980afd91a600e3fff755a4848d138568": { + "balance": "25000000000000000000" + }, + "cdf7f55a5a16572d2f2bbf7faeffe3c4d64f86ab": { + "balance": "3115969322502000000000" + }, + "ce0f1dbbfa3490a21ee4b28232db612f44bb7bf1": { + "balance": "9227310122000000000" + }, + "ce33184573c33dd859450304984fa63ea4f2b62d": { + "balance": "7055925237496000000000" + }, + "ce33a3db107f01c51d30b24a8db80faf05308bb7": { + "balance": "10996113113089000000000" + }, + "ce4922b3daef62914f0580a55c524e6a02e31d83": { + "balance": "5541295938315000000000" + }, + "ce4ce8a8540678dda16380c211482dd8c8b71092": { + "balance": "6224176337062000000000" + }, + "ce62cfd71abb9979a0acc398c17dbb5cb6da4721": { + "balance": "13448605175000000000" + }, + "ce724bb30c7821a9c847e0a3e9c12843c3471f9d": { + "balance": "252657175031000000000" + }, + "ce8af01494c2c5b4e74bb02dc6de982e7234fed2": { + "balance": "77349533545000000000" + }, + "ce8c774b7f92045faec43e9cc1711224a3b32435": { + "balance": "370287579971000000000" + }, + "ce8c9ed5018559f36ec72e5a9b0701724e498b51": { + "balance": "142866501748000000000" + }, + "ce995c13568a8b1521d4c9721cfc11da4891860b": { + "balance": "1000000000000000000" + }, + "ceab9dddc767a9651e98527fcf51f6e85c9ae402": { + "balance": "5251411770975000000000" + }, + "ceace25f8c7cf853500a461df007f9c9703ac4a5": { + "balance": "1428847332255000000000" + }, + "ceb0c49dad36f6169ec82a2f0d80da36c87e4209": { + "balance": "459821324064000000000" + }, + "cee8083233bcb4d50ddbf2121c90b5c2019ca58d": { + "balance": "557985245088000000000" + }, + "cf0c6bcc66eb75899bc7f8ed4b8d2b29437bfe85": { + "balance": "3252418478000000000" + }, + "cf32c5bf1d7ef0cb0f2f190f8468b01a4f2d93e2": { + "balance": "6593164924646000000000" + }, + "cf6e47463382153fcf0ec6738880925dbc08116a": { + "balance": "1091910654350000000000" + }, + "cf7539096fd0cd97cd316efcfe9d3c87a101a74c": { + "balance": "741847588809000000000" + }, + "cf9439bf2fbab65cecd783e135a37127f585f1e5": { + "balance": "50100000000000000000" + }, + "cf9bdc902604fab070c611ebf6a989ac4a785c82": { + "balance": "1501000000000000000000" + }, + "cfbbefc0e6013fa2caeabc54ac05f45dbf17ca13": { + "balance": "230809632301000000000" + }, + "cfd53f18ac7d94cadd032a0f4cdbdffaf4765d6e": { + "balance": "64000000000000000000" + }, + "cfe66dc4aa9ac9c9f87fdd05c1b2b95da5211703": { + "balance": "1656993051100000000000" + }, + "cff376eef4d69c4a47d6c7916583228fab3b5967": { + "balance": "5904462494391000000000" + }, + "cfffcb819302d05ed763026bdf84b48818938fb0": { + "balance": "289619807900000000000" + }, + "d000aa72a77d55911a5e66c2906da9206db86633": { + "balance": "3008989624945000000000" + }, + "d02d7b42213e873f91e789cbaffc734ffabd1087": { + "balance": "144960809826000000000" + }, + "d02db5279e918b3e93ff81d00d4025cc71dccaf6": { + "balance": "2386625717975000000000" + }, + "d0802cbcca2bb516f251b873eb20bb5e94af7f37": { + "balance": "9287997718210000000000" + }, + "d0c07380308972a36f57d1cd9081d7389d0421cb": { + "balance": "1280367167470000000000" + }, + "d0c131c1b60891b91e58fbed787ee4567e3f2038": { + "balance": "6360752089492000000000" + }, + "d0c71159d46c4d2af7699f682a055c79a1a68a0d": { + "balance": "1527974433762000000000" + }, + "d0d5d9f242f2613079b3b443c359c2e18ed5faab": { + "balance": "637334647476000000000" + }, + "d0dd208ce92da02eee3ee3de335e67f819581a33": { + "balance": "100000000000000000000" + }, + "d0e55ec0ad0f8986dd9fa9d738007c5bdc22f840": { + "balance": "53012893797000000000" + }, + "d0f222cec657ee444e284c07228d585155b82c0a": { + "balance": "7368748129592000000000" + }, + "d11efb07887d8b5b87a77d8fd388190614e8c077": { + "balance": "4703283503278000000000" + }, + "d129f1b89045ebfb4d1df1d9077e9359fd2990f7": { + "balance": "14496053137000000000" + }, + "d15a509424c4e04868bdcf59cbee09882ba04c8d": { + "balance": "65042393236903000000000" + }, + "d162416912b03fa65f3972a63e357ceaa3b621f7": { + "balance": "325650177224000000000" + }, + "d166183164b81bd049b2146a3ccfcc78cc6a0bdd": { + "balance": "1000000000000000000" + }, + "d173d759f0916e61400d56ca690cbf1743fe27b0": { + "balance": "53550838679000000000" + }, + "d18dc883e3881bf4c7db2afaa097bc2d33656724": { + "balance": "5000000000000000000" + }, + "d19dc9b5ae689dea1ccbfea8b44ec6034559e326": { + "balance": "135552499885000000000" + }, + "d1c79160d0b8c1a1546b86db5123e87645a45d13": { + "balance": "10000000000000000000000" + }, + "d1cccaa22259c547993df3c147d5b545f003adb8": { + "balance": "10000000000000000000000" + }, + "d209c9f32f3292ac4d15ef353fbe6f6efcd4e49d": { + "balance": "81000000000000000000" + }, + "d21ac89a20d67e309f96f64adf05fc48f55918a9": { + "balance": "500000000000000000000000" + }, + "d21f6e7adbf480600295af683091f9b9833f5330": { + "balance": "1229445878922000000000" + }, + "d22700a47a0edb137d2f0348aa0f8d4b6dbc5850": { + "balance": "21301422923000000000" + }, + "d258ddc9372e3b70ff53da171252239655ca9886": { + "balance": "16000000000000000000" + }, + "d274c69317dd836df48562455e8f5a7bd2e47d19": { + "balance": "156091832558000000000" + }, + "d286b68a358fcf8a6cec70b83467079664632ae9": { + "balance": "90377010699000000000" + }, + "d29284915d9b924ae5673e8a4a557478f68a7471": { + "balance": "324678197320000000000" + }, + "d297e64ac2bd8e98e6d276d6fe080679c398a26a": { + "balance": "3401930527000000000" + }, + "d2a1e7b51f6b5930a0d9e2ee55736f3d83a1b323": { + "balance": "44578900750000000000" + }, + "d2c9b0b0bbe61de504e4f210c168fa5999c9c23d": { + "balance": "76537483113000000000" + }, + "d2d49f650d222ec3e2cecba163ee92f0e934ca14": { + "balance": "3312486482635000000000" + }, + "d2d803bf10ba18adef5716b4056c1b1d61c45abf": { + "balance": "964679698000000000" + }, + "d2f673b589df7ef5cb32fdeef842d48d66130567": { + "balance": "1079010447581000000000" + }, + "d2ffaceef1af3f1c3e3f35e4062cd9f9abd1da59": { + "balance": "3041453068594000000000" + }, + "d30a74f5041ec6e73d066a375a105116699ce177": { + "balance": "21814020745000000000" + }, + "d30d849a2d8ff5041304014ecf6752dc769bf004": { + "balance": "1247532881540000000000" + }, + "d3113f558c6376321691931c9b21205e31f4a56e": { + "balance": "572224428451000000000" + }, + "d314bac1bf85eedeac0b359dd2106dbae8fc6947": { + "balance": "20000000000000000000000" + }, + "d3283e17112028b324327ef64a238183ba189207": { + "balance": "136000000000000000000" + }, + "d33ce3c3b64d1b3d399651432c15ecb943d16c70": { + "balance": "10000000000000000000000" + }, + "d33e1e4b10a98e82810f6d161df5d35e5677e35f": { + "balance": "10169656674000000000" + }, + "d34699fd152fe38caacd3c096f6abb1cd79e88b2": { + "balance": "25056644550000000000" + }, + "d369c0e01b9a9d519b3b099a98fead19867c019c": { + "balance": "100000000000000000000000" + }, + "d388dcfe55a9b710d05c686f033fdbdd7861ab71": { + "balance": "1439589263065000000000" + }, + "d391a7d45c7b454b743bd867f8f62f56894f9b65": { + "balance": "484904747488000000000" + }, + "d39a75b4831543e1bc99e7a5ca8875c4f69da45b": { + "balance": "10000000000000000000000" + }, + "d39ed6978b6a90fea29e735f8ea3f1d20e0fbd15": { + "balance": "144000000000000000000" + }, + "d3a0a1a00dcbd6bc44c9803ce351a4b36a69c929": { + "balance": "191222401916000000000" + }, + "d3bf1c0a6b0470c30fc49d995025af5e6b639e61": { + "balance": "10000000000000000000000" + }, + "d3cda762bafaf204469f85e6896ec64147a3452c": { + "balance": "468094119213000000000" + }, + "d3d04d78c1ab9e6887a9467b8b1e31b5c9910e5c": { + "balance": "81000000000000000000" + }, + "d3e1bfdd9396aba00d3e78646ddcdaf139a967c0": { + "balance": "833333174120000000000" + }, + "d3e502c42ff0274da12ba87ffd45fa593bba052a": { + "balance": "100409899947269000000000" + }, + "d3e76066c2e32d9a693161de07f2d3b7e6ea07eb": { + "balance": "10000000000000000000000" + }, + "d3e8d577323d97407246b198c4c61f7943c468cd": { + "balance": "10000000000000000000000" + }, + "d3fd4d1b0edbc314b103d350fff023ab75b7d7cd": { + "balance": "84129547428000000000" + }, + "d40087fca8feb72d130bbc9622575d4987f12895": { + "balance": "1000000000000000000" + }, + "d407d4126cbf3619a422c532ccf20c3da1495dbd": { + "balance": "99622000000000000" + }, + "d41a28761c8e5de8c803813667f1dc0918a105be": { + "balance": "157507410260000000000" + }, + "d46ed38228a3c3d78065b2d8b71b325bf0f0e685": { + "balance": "6787045850000000000" + }, + "d4a7463d202e804b39a93bccd77491d8791baf58": { + "balance": "171694163573000000000" + }, + "d4c20716ff7288d811d05fd6f0696a9f5627a11d": { + "balance": "100000000000000000000" + }, + "d4d95059c808cf41e64f7f353246ffae635419d4": { + "balance": "10000000000000000000000" + }, + "d4ef925157c6d0e2d649332f44416b85f8abe69e": { + "balance": "1392945162611000000000" + }, + "d4f0cb25801794f6d803306878763e08209d19f4": { + "balance": "64000000000000000000" + }, + "d55fbebc4dcf2de6341c2325448e9c198f0f06a3": { + "balance": "14206622892000000000" + }, + "d566968c40211fb25114105e36b5a7219cde9d5f": { + "balance": "4898442964000000000" + }, + "d5817b95c6b504a6d07f64faccc9aedf408b0ac4": { + "balance": "54387832478000000000" + }, + "d59679fc40a71897065bf1b3a73f331226cdae72": { + "balance": "20000000000000000000000" + }, + "d5a7deec4a5898f094e1600f9b15768d8aada258": { + "balance": "100000000000000000000000" + }, + "d5b91c29bf772ad3ba04033dfb86b672b245ad77": { + "balance": "100500000000000000000" + }, + "d5c1a9bcc5e68b7547354178fefb3d870572fd67": { + "balance": "2252066779089000000000" + }, + "d5da2a826f5909a221bfd8561dbd7dbf4aca4c35": { + "balance": "13839784966766000000000" + }, + "d5dcc82fa169b4677a3fc26d78f38e27dcc763f3": { + "balance": "10000000000000000000000" + }, + "d5f344ee8a1b954ae5fd8fc7ac702174749bc8a4": { + "balance": "1398836216771000000000" + }, + "d61cd03afbfc1bea186e5a3a51347c2c4ee3a2c3": { + "balance": "109879472702000000000" + }, + "d647fd7ca17203a0049c28ec6759612d767cfcce": { + "balance": "162681136487000000000" + }, + "d656d14acfb2f0fbde2ed2a137a52d852bb6288b": { + "balance": "20000000000000000000000" + }, + "d68130b421b19c193d03a9017b2dc687c7307d26": { + "balance": "128569735484000000000" + }, + "d69a41f7ca76b40ee94b0d04a3780a00c6c651ba": { + "balance": "2801054372864000000000" + }, + "d69af2a796a737a103f12d2f0bcc563a13900e6f": { + "balance": "7412286547000000000" + }, + "d6a5a7e149cbccb72a50b0a3ae00e6756b0a7eda": { + "balance": "1075352201657000000000" + }, + "d6aa9957f141f0dfed77e943c39aeed978834fdf": { + "balance": "20920740110000000000" + }, + "d6e99ccb72d24e8a60f24d47afd4074b1d1fd336": { + "balance": "15415994387186000000000" + }, + "d6ea4a9dda8d5bc832229c916fa45f05f99c093a": { + "balance": "27075799893190000000000" + }, + "d71de419d746ac277baa955761cced4b34c376ec": { + "balance": "1388473506822000000000" + }, + "d71ec6b5e5d4c604f741bafde0974eca49c56156": { + "balance": "61938809628000000000" + }, + "d72f90d9879f6d2d407b4fdf5d128b98d518f1a5": { + "balance": "10000000000000000000000" + }, + "d743d7925a0cfd08150814cce8cd5d3f7099e1c9": { + "balance": "25681376856000000000" + }, + "d7575a09e7498f21cda3e9e7266b7fde91dfe19b": { + "balance": "9841565066000000000" + }, + "d75c2eb5e0a2b2ee72ef4fa7249c1a1ce03f333d": { + "balance": "134491489751000000000" + }, + "d77088329ec1e280ea7a087ad20c5e965721ff4d": { + "balance": "3949070941222000000000" + }, + "d78d564bb79ea19e4a93975a38fe0882018f177c": { + "balance": "992717434142000000000" + }, + "d78efb176b252ce67b5648e04088d12c4668aad1": { + "balance": "10070463674000000000" + }, + "d7a25e43d7d4e23744f0b10e2b4f2911fd3b3bc1": { + "balance": "1000000000000000000" + }, + "d7a941cd82f8aa63c55baa81db44bcb347b8e529": { + "balance": "49000000000000000000" + }, + "d7b34387880daede6cbdad11bb3db67daf942975": { + "balance": "20000000000000000000000" + }, + "d7bca0770e2f890c1e93c3595641241454a31045": { + "balance": "2000000000000000000" + }, + "d7cb675cea1c0dafded44f611c9c344e2a5e053c": { + "balance": "25000000000000000000" + }, + "d7e53a2d8eaefd18e02bbadb7e64906ca8613151": { + "balance": "166599594268000000000" + }, + "d8076b9db0b7496efbd198b73c4bfcf51ac080fd": { + "balance": "210272077089000000000" + }, + "d81dcf5756da397ff1f783ffe5391d1ffd4ff227": { + "balance": "500000000000000000000000" + }, + "d833c6d08f5fff8f77628ab1e86584d052976d1f": { + "balance": "10000000000000000000000" + }, + "d835732e85953baf2af9e49f770bac1caa1dac23": { + "balance": "152211441541000000000" + }, + "d84005fea447e8c6aa0b5436ad79654a75348456": { + "balance": "22563694224690000000000" + }, + "d84d9c59a445911922e88c0f22cc6534f33ca3de": { + "balance": "3054115413381000000000" + }, + "d84e69926216065749e624d87783e90ce3015b82": { + "balance": "1420803164313000000000" + }, + "d884bdbdb7e13cc523e7f192310230c7bdbb4a07": { + "balance": "10000000000000000000000" + }, + "d88eedca1dd9249702f5ffc807c1e439eee1c5e5": { + "balance": "36000000000000000000" + }, + "d8a23fd234bada1c726622925ade62d3021e0037": { + "balance": "1567046607931000000000" + }, + "d8b1aee24264efebd1c677fcab6ada6e0f000cc5": { + "balance": "20000000000000000000000" + }, + "d8ba7afbb8bf2910b983a114aedec626eb7426c1": { + "balance": "275491152435000000000" + }, + "d8c8af55ebf116ba3c3904f8ac39d3a7d31aadc5": { + "balance": "1499999998278000000000000" + }, + "d8d97645f5f62aa89bf0046362dd0f45d40f821f": { + "balance": "25000000000000000000" + }, + "d8ea0e24a7e28285c4454f54181d581324da2583": { + "balance": "53039425000000000" + }, + "d8f5d258164747ccf790f5ed358162c756de49db": { + "balance": "323009990690000000000" + }, + "d9477bb62d3eb668a83a9679f3a7ef43f17c9e4d": { + "balance": "14045557127869000000000" + }, + "d9585e1b03fc86636dde1e64aed3cad77868549a": { + "balance": "1000000000000000000000" + }, + "d975f9ce3fe773fac3f8338a034a757c58f6e11f": { + "balance": "25000000000000000000" + }, + "d97e490faf19de612fb49c041d3f9e7877d3c0bb": { + "balance": "65766847746000000000" + }, + "d98117b74b2f2888d7078d3116d5758e2d09bfca": { + "balance": "1749157484422000000000" + }, + "d990b3f69ec700bdc095c184b3804551c832d612": { + "balance": "509385034698000000000" + }, + "d99b35298e709e5f54e6a5c612a326a83f4268c4": { + "balance": "71963571266000000000" + }, + "d99d9ec76005da26ccc721ec26be4ed9b3b1c586": { + "balance": "469607736824000000000" + }, + "d9bc61075c3201351584a026e5bdfb7cf9a7b6ab": { + "balance": "200000000000000000000" + }, + "d9d07b72f83491b6db26602f6b7039aeebfe6b61": { + "balance": "144000000000000000000" + }, + "d9f6f1ddf03e836b3744d008b62a6424544c67a5": { + "balance": "74347470143000000000" + }, + "d9fceff07ad69bf3b4aef54a7eee541368980cf6": { + "balance": "1143407707495000000000" + }, + "da0285fb7e37fd4be66fb862b248cea94ea8f6db": { + "balance": "80770216661309000000000" + }, + "da05c7aa330fcc5834e19deeb0a808e9ab7f3d99": { + "balance": "169000000000000000000" + }, + "da129e4481bd25450e6c7b42fe417c87ee2ce7a7": { + "balance": "256000000000000000000" + }, + "da32e3ec421993db088c71e256263158f7855b61": { + "balance": "18540215888567000000000" + }, + "da3c99669acd202ccbe6f80902c807588eca0880": { + "balance": "1000000000000000" + }, + "da72a7bec114d43aee6449db830d2d3f16e4d9b6": { + "balance": "744534872932000000000" + }, + "da72ec2cd7b8e3924f8baaea75d5ed23ef39394c": { + "balance": "38646377617204000000000" + }, + "da73078957f491827d62cb3ca0c484c2d1004ba7": { + "balance": "891774109242000000000" + }, + "da828e50c7c8580c6ce81718f11fbd43b2b0541f": { + "balance": "66094097819000000000" + }, + "da91483db6a6a034e068e69a6b46674838c5bc80": { + "balance": "4000000000000000000000" + }, + "da9551b635c3619f81641571e267755b89f7fe1e": { + "balance": "670841942250000000000" + }, + "da9b43a9c1c574580ec43da9f6acb687fc2f8c68": { + "balance": "761695404114000000000" + }, + "daa7f446923f7481115ad285ca468c865147e563": { + "balance": "10000000000000000000000" + }, + "dac6bfd15954efa4c9254e24e5831ab1884f8d67": { + "balance": "960042043423000000000" + }, + "dad85d0b8bb5ebf6ef811d0d35c89f9f343c833c": { + "balance": "37664599958479000000000" + }, + "dad9b01652de5d50bf30f9bcb0c6edc6315139e3": { + "balance": "21500996724000000000" + }, + "dae9c7d6bb0efe3f7ea20442b184f6d99b2a2c12": { + "balance": "937830189066000000000" + }, + "db0d6c28e9b913f611accaab15cc887f9b770f58": { + "balance": "20000000000000000000000" + }, + "db0e5341d64817885721c5abff04c30bd38df40f": { + "balance": "62600679700000000000" + }, + "db387dd404d14478babb60bad2391720d68b92ed": { + "balance": "115096708329000000000" + }, + "db3fb19e8a4a6ace4d8c6c02085d4cbba528b532": { + "balance": "1000000000000000000" + }, + "db4f05a66c0ccf0532ea1ecb931e05a400a6f4a7": { + "balance": "20000000000000000000000" + }, + "db571f1cdf8e83fbff6fb48cc0c81ef95ede12a0": { + "balance": "118317387393000000000" + }, + "db6a6a6db2aef3f43afbfe23027b670ebb3d33bf": { + "balance": "9960755220000000000" + }, + "db8bed34f8f34f45cb83ab19ed33fad76437d217": { + "balance": "21003651205000000000" + }, + "dbeba6a2a7f66c20c6db7b9270a5aee74de3f441": { + "balance": "4086905723945000000000" + }, + "dc04efeac13b2dab3d07833a7e7fa728fc23d18a": { + "balance": "1161834099120000000000" + }, + "dc092386c3a3e28b6b2d7d70db8f3d11e79ef5df": { + "balance": "124362293793000000000" + }, + "dc10be66aa11acbd42a2b1953714f09b5281681b": { + "balance": "20000000000000000000000" + }, + "dc2d58a383ce0bd40bed859ec2f25412b68eca0a": { + "balance": "104917823922000000000" + }, + "dc2e38183dceb2bc82b23e8ccf48dd96ea1c97b6": { + "balance": "2847787376064000000000" + }, + "dc5d9d94530d88451cf081fe7f2ac33667af9d8f": { + "balance": "65321904051000000000000" + }, + "dc993112a8d89136e0e73d67e2f26191583a50ec": { + "balance": "1000000000000000000" + }, + "dc9bb69b295945589a41feb794406558ce65dedc": { + "balance": "104077637254454000000000" + }, + "dcb0109d4fca2dace08ddca5d989a09d470161a0": { + "balance": "28897833222000000000" + }, + "dcce3a4ec516d833f5a9790c40ad0334b0d2dd01": { + "balance": "25000000000000000000" + }, + "dcdb21cc811ab733c2a80a2d5c8e5bb49cb2ddc4": { + "balance": "16000000000000000000" + }, + "dcdf8dd3ce03a2fe0d72835dbbd58725e1ed2c57": { + "balance": "113330414284000000000" + }, + "dd2165839ab95d6b24591307adcde9ee1819927a": { + "balance": "20260199589072000000000" + }, + "dd3015a5fdef66e749a000585d5574f975e3432d": { + "balance": "85465001652000000000" + }, + "dd37c478727f44943c5fd79ace30f21fae5a589a": { + "balance": "108577233510000000000" + }, + "dd3fb5810c31d37652bd17b92497ed479faf123d": { + "balance": "669996966072000000000" + }, + "ddc3bda30f7cf36bd535de4e20c9becb78d159f4": { + "balance": "99998278000000000000" + }, + "ddcce2d2431b67d4157c7ac4bd77f20c24831de6": { + "balance": "36160893899000000000" + }, + "dddcebe609f8b4354a1f27ab1915135e25800344": { + "balance": "1457846339959000000000" + }, + "dde223eb48f81748abde6cbc08cf1e6b0e8e4e5a": { + "balance": "1501921107087000000000" + }, + "ddf4ba402007060d9940a96f8e7c39f0a2c6108a": { + "balance": "377268151287000000000" + }, + "de05d9ada6626a8492acd137c7c7f7080a987cd1": { + "balance": "222144234923000000000" + }, + "de0fab89f79c4edf9766c3b7b1f508cb43c5495e": { + "balance": "8278000000000000" + }, + "de1070f3ff6c47237768fbdead88b2d5184fbe2f": { + "balance": "1000000000000000000" + }, + "de2b16d7f36f630329287822f550ec19415acb3a": { + "balance": "25000000000000000000" + }, + "de3faf6884337a99e54ac5d3f08b34be51b0755b": { + "balance": "51926806905184000000000" + }, + "de4614fd632ddac888d177de0858e62bbbf7dc11": { + "balance": "52506376589000000000" + }, + "de54cabb241dc5def530191f948f67db942a85b0": { + "balance": "9691177060000000000" + }, + "de81e488284acc4f8f6061d3a73bad112efa7a40": { + "balance": "14654060992000000000" + }, + "dea86ac3a661272691c877c1bad8355789382b69": { + "balance": "903877103000000000" + }, + "deadfc79f2a722dbf1c1a92f2824da8874189fea": { + "balance": "98905944986000000000" + }, + "decf1af47e153f6f3749a1b7abadefdcf1607a0f": { + "balance": "529000000000000000000" + }, + "dede5fa984f0def639d5b633f54c60fc5aaa272a": { + "balance": "8193771708654000000000" + }, + "df23607c63b3fd4b5fde6aab093c0c56d1188f95": { + "balance": "14687379916000000000" + }, + "df5b74bf02902e4c466821de798406b663d4d73e": { + "balance": "9000000000000000000" + }, + "df6402ee3f37389e7f65720561b54e26e5f1cbaf": { + "balance": "358266132937000000000" + }, + "df83ea5b770d5abeccac7f0cae803e8bd7b9831d": { + "balance": "25000000000000000000" + }, + "df92802ffe9892c7704875755bdec648914430e6": { + "balance": "20000000000000000000000" + }, + "dfa108bcd80e824a255679a38b2450d428e2f939": { + "balance": "489209553654000000000" + }, + "dfa9f18e859353796afe384d05353dc80b3ffc43": { + "balance": "121000000000000000000" + }, + "dfb0d6580f011e68a39d7727818b0890e70f3036": { + "balance": "537675412560000000000" + }, + "dfdf006abf2293aadc58feea6af6b35db428675e": { + "balance": "9000000000000000000" + }, + "dfdf2ba93bd47d7243b7419413458a947effcf67": { + "balance": "45080282196110000000000" + }, + "dff01277ac23a8cf93383595a80a7c070eafe5c6": { + "balance": "312778552103000000000" + }, + "e0450154c441e52c5e507e8316d4e9376c59c12b": { + "balance": "170163401434000000000" + }, + "e059374d6a7e6c63e609b65642272869fa3b2b3c": { + "balance": "300122497803000000000" + }, + "e0c0d8e739a2f274a43f019a07f7f61d7d8e11a7": { + "balance": "2630310240000000000" + }, + "e0e779e4e3573ea77096daec252ac2b3f1c0013a": { + "balance": "10000000000000000000000" + }, + "e1325eb586180a67873718a2016172afeb03c6a5": { + "balance": "531691399657000000000" + }, + "e13958af480da6443b9ec1067f0f33440634a282": { + "balance": "10000000000000000000000" + }, + "e142daac753b2c4d215372797999e9c88b65dfc9": { + "balance": "585813299366000000000" + }, + "e142ea343bc36ec49989fd43ad5c403c70a40dbe": { + "balance": "656734902975000000000" + }, + "e14d0a3d259db6bfec2fc4ef6e18729e4d93b007": { + "balance": "210234446279000000000" + }, + "e16a5316e3a113f27bafdf3d4fe44fe30ae9c210": { + "balance": "16000000000000000000" + }, + "e1770944aec145a96c9491497eacf7f3fb03c1b2": { + "balance": "335417250470000000000" + }, + "e199ac237661dcac0a4cfab404876abde72ee209": { + "balance": "340000000000000000000" + }, + "e1ad427471023f38cbdf07fdca3728ec343810c4": { + "balance": "343957267368000000000" + }, + "e1ae0223cecd738c8e530a0007ef05e8f3b33769": { + "balance": "950528515289000000000" + }, + "e1d2d4ef39f01a60c3bb5d671af91c5298d87711": { + "balance": "121000000000000000000" + }, + "e1d4a8888cbb383f3671ca96e7b55310b59a2541": { + "balance": "242387826125000000000" + }, + "e1da9039ddfe117e6a0b484fd3962426c112871c": { + "balance": "3710499693813000000000" + }, + "e1da9f16d57c601af8b6d102323c20408af8531a": { + "balance": "3135322588771000000000" + }, + "e1e1c163f391ffad2d0be68641253b0860485a95": { + "balance": "10000000000000000000000" + }, + "e1ec6361df67ad915df9e9661cd0932186db034a": { + "balance": "4279936304854000000000" + }, + "e224050bcd723e63f1fc0567a86942546aaf8d13": { + "balance": "12007628539000000000" + }, + "e2342c7f411d7ca3a86484af59a9c3f3180e2f0f": { + "balance": "16000000000000000000" + }, + "e26f2b026a258ce5801c90bb8fd6f7a152b8d267": { + "balance": "304593714834000000000" + }, + "e2717eb5fd0a1da51272b50ca8d12858009c7016": { + "balance": "506943817535000000000" + }, + "e27546d5620e6398829260e58e8cf4a3a03f4164": { + "balance": "3000000000000000000000" + }, + "e2762bb64e0606a5d635032e15164b01f612a74f": { + "balance": "884716158811000000000" + }, + "e2882066ed0a3c041d09c00c8532850fc42eac06": { + "balance": "42441412728970000000000" + }, + "e294c5d64daf7b7c0994aa9d03669c4b2658c9cf": { + "balance": "6996693830997000000000" + }, + "e2b179f0ed6870a6268aea64b0c7b39d98d97fcf": { + "balance": "334205318353000000000" + }, + "e2d1f6f7e3128340b789565b527bb91de96d54bf": { + "balance": "100000000000000000000" + }, + "e2f136d3693aa0b2346a968a22aca6707fc1d0e5": { + "balance": "10000000000000000000000" + }, + "e2f229054293e32cf3e83f9bb88d9cf1d6acd66b": { + "balance": "20000000000000000000000" + }, + "e33b8f4c9a49554c8b134861f88c8fffc399e456": { + "balance": "83552502198000000000" + }, + "e33cfc7727b1460324b34277dde14cc49bcb273d": { + "balance": "100000000000000000" + }, + "e36af9bfed4f912cae21f3d899f7354e1c902601": { + "balance": "31474316356000000000" + }, + "e36eff7c061dec48446d47675f176b4da3c2e950": { + "balance": "10000000000000000000000" + }, + "e383f3cf431f3cf645f26c7d5e5e2f77348ede6f": { + "balance": "776224304171000000000" + }, + "e398b9f004a4f891cf871a57d9124a97b56e89e9": { + "balance": "84846187740000000000" + }, + "e39ab2415144b46db522e92ed51b8089a5ec01fd": { + "balance": "4158925896363000000000" + }, + "e3aa7ac7e15e9a8a6f54565067234a9d4bf7b569": { + "balance": "1080385576951000000000" + }, + "e3ec5ebd3e822c972d802a0ee4e0ec080b8237ba": { + "balance": "2129139289000000000" + }, + "e3f1fbff8686af23ab95eeeee6a6a03782d72416": { + "balance": "401776848194000000000" + }, + "e4001b830fbd86df257ebab54aec0c66314ef9aa": { + "balance": "518220809325000000000" + }, + "e40790bff894f0b3e534942b5ad6f6592cd6e896": { + "balance": "25000000000000000000" + }, + "e409170a296e46fc96d85a2395e4324212a470ee": { + "balance": "1072528749756000000000" + }, + "e41546f68bbe1771febbdac2a4a5999eef50edf3": { + "balance": "1000000000000000000000000" + }, + "e425d63d711a9996c09d928ba8df94c88163aea9": { + "balance": "10000000000000000000000" + }, + "e4432ff1aee13f97f73a8407e4c7d6e768b8040b": { + "balance": "700508995102000000000" + }, + "e4690f5d024a395355a7cb5238fb7e0dc921b1e8": { + "balance": "1000000000000000000000000" + }, + "e4829684fb36f054766a61fb2a8f6ecdf27c9e87": { + "balance": "73885178137000000000" + }, + "e48a68e1ac007e14ac08c1b3b0df2b5602081ec2": { + "balance": "1389262869176000000000" + }, + "e4d699b3f4117eba7ed27b323048c9ffcb46ed42": { + "balance": "183131036697000000000" + }, + "e4db688c29fdf9a1c16114f99797d8409545955f": { + "balance": "16000000000000000000" + }, + "e535b94d370190d1e0955d3c0d12480e558f00dd": { + "balance": "20000000000000000000000" + }, + "e53966d4bb17fa9b50d29b44ddf3951c9ca67caa": { + "balance": "6400630678000000000" + }, + "e56f2656fdd1a5f7d3716e65dd89a37dd6e42dcc": { + "balance": "1000000000000000000" + }, + "e5a364113076273352e0c31bf505028e0b7edbaa": { + "balance": "10000000000000000000000" + }, + "e5a3c80518fab6a0a721ccbdc3e673680a65f6de": { + "balance": "171727917465000000000" + }, + "e5c71c7170e5c9b07e62cc307d81a4a3053ed64c": { + "balance": "10000000000000000000000" + }, + "e5fb6408db128c55cfb3e7fa1942d6347e34932c": { + "balance": "10000000000000000000" + }, + "e606883236f8b2045393c574153a100675cd4b90": { + "balance": "14005226900000000000" + }, + "e61869d1cf72f25e195898217f5bf5bcec9c9038": { + "balance": "50000000000000000000000" + }, + "e61e2e29c0719457ab1bf7d6d9fe442bd6107b07": { + "balance": "30943034333100000000000" + }, + "e61eb97093e9ee609647bd55f434a27bb30a9401": { + "balance": "200951434577471000000000" + }, + "e62812ad5834747f17c92435d863639e84d132fc": { + "balance": "3017271391299000000000" + }, + "e630b92aa8443eb077e1f6990a2e194d99cf53ec": { + "balance": "1000000000000000000000000" + }, + "e656fd1641c15e1a4b753be41bc4aa438b44b42c": { + "balance": "26972744083000000000" + }, + "e663f0257b98dfa80602a2af1bea1f901c4a7612": { + "balance": "97075813547000000000" + }, + "e66e411a8a9d019b53bf2e0a7e44703e1aa93ac1": { + "balance": "25000000000000000000" + }, + "e6712675d13fff27af43bb1cb3f2f283755bacf5": { + "balance": "227572496234000000000" + }, + "e68e8f04b2cff484da2d41dd639ae8880920f781": { + "balance": "20000000000000000000000" + }, + "e6972b5d7e0fe8c722dec9146b92f89291a0207a": { + "balance": "2115924954211000000000" + }, + "e698b491330cb55ecc4cc4b74015cd94eb927fc4": { + "balance": "1038111785278000000000" + }, + "e6c411e67b90109dbb0fa75f0f07ae8a504e9637": { + "balance": "123792105420000000000" + }, + "e6fb1dabc624edb45b040ad66f30dae010a6b634": { + "balance": "16076893670852000000000" + }, + "e71dac161206e7d3686d13b98fd922ab73587988": { + "balance": "500000000000000000000000" + }, + "e773f9be9b3f4b35ac149b4d759b9e47c8000bdb": { + "balance": "329623043336000000000" + }, + "e781cbbd2dccfdf68595d54fa44104a80d52dd22": { + "balance": "188679476509000000000" + }, + "e793666c7850a409b1d5494f576d122e85cfed9c": { + "balance": "1141845197779000000000" + }, + "e7a5527c6deb922e9f84309c502048f49f0c8f14": { + "balance": "81415566708000000000" + }, + "e7b0f75f9c69ae464b1b63cf295555d0815fc532": { + "balance": "10000000000000000000000" + }, + "e7b43cc673e321e607190a6fde996b71508f4d81": { + "balance": "103958781426000000000" + }, + "e7bfcf3125e37755e57804dfe4479657b212a8ca": { + "balance": "10000000000000000000000" + }, + "e7d33cbbd4eb38365c5be04ce32658a5ac741cfa": { + "balance": "1545192252109000000000" + }, + "e84cfbd7844f6aa3e830258a6b1069b6a7ff5b7e": { + "balance": "543989509107945000000000" + }, + "e8aa0cbc5c1f59fadf3ec122fa8a59ebfc60b5b6": { + "balance": "61271973066000000000" + }, + "e8adb5303c30a8ee044dc09c49818c02a16f4254": { + "balance": "737375689166000000000" + }, + "e8aeef5114e19d467c3064938c5965d04830f2ae": { + "balance": "51130466380000000000" + }, + "e8b5a83497198a513fb2e244bcf05f9d4cf09d62": { + "balance": "10000000000000000000000" + }, + "e8b6818cf0d24bd0e7ded854b3d368662a150dab": { + "balance": "63697741112000000000" + }, + "e8b68b9cb24169fd688db7a626d79d0363777c75": { + "balance": "427222669643000000000" + }, + "e8b8b57b23ea953943da3ef7efaefced9cdbb44c": { + "balance": "16000000000000000000" + }, + "e8f85dca364d26c2149b767904c6c06249c3d88a": { + "balance": "199342917246000000000" + }, + "e916c7801cdcf1b6cf640fcd9dcc1e3148c80105": { + "balance": "9000756000000000000" + }, + "e93cbef13277324caae7816c3d601e2f6bb42589": { + "balance": "121000000000000000000" + }, + "e9415fedcdf8939b551999900128530195a2a5f0": { + "balance": "85165078941891000000000" + }, + "e9a79ade714ce48a07fe88532a20d8f8ed27bac9": { + "balance": "30768493367842000000000" + }, + "e9b35c7ca775661bbd3a4844e2c6bc5effcdea58": { + "balance": "134719523000000000" + }, + "e9b819dffb600373bfd1b1608fc9744cc9167855": { + "balance": "1537634693002000000000" + }, + "e9c5ef50d4a194e53928659b4486a1c456df9e56": { + "balance": "50000000000000000000000" + }, + "e9e21f4523b11567516f6fc525e8967ac707f988": { + "balance": "2498740681000000000" + }, + "ea02821d6c730e061a9947b75188eb8bc0bbf9f1": { + "balance": "12822292582000000000" + }, + "ea3bca3a17c7e724ac0e15acab6442f222cd8688": { + "balance": "2789689549000000000" + }, + "ea4f7923d7045a148d50153f5f4620dbd31a74da": { + "balance": "113595858930000000000" + }, + "ea6d4cbae3cfe49ffd36653bb0d64c01b2bbc0b8": { + "balance": "49325017701000000000" + }, + "ea76cd4cff825301932a5c1d3a1de55a0ff00797": { + "balance": "1282028021000000000" + }, + "ea8e4c8c6500856777e2b41832ff00443db291ce": { + "balance": "553674550359000000000" + }, + "eab52191e5afc804b8685fe13d7ad6f5dc64fc12": { + "balance": "244412435341000000000" + }, + "eac1b0868b710e40d6d5c66a461dfc8f78abbaa9": { + "balance": "10000000000000000000000" + }, + "eacac2c75920b8f6e65f37ad81deb113d526d031": { + "balance": "53028042076000000000" + }, + "eacc9ef8b534143560f420031a8a7f030ff1a36e": { + "balance": "381111853842000000000" + }, + "eaf2cc9fdfe6272de269f32486b2d4c248a05afe": { + "balance": "2793234915237000000000" + }, + "eb0220406832a8a5d4f242538e82c80bd83d0ac6": { + "balance": "10000000000000000000000" + }, + "eb20efc0e0af48c8e6da4b21efa9c9f02d92d29f": { + "balance": "152958793764000000000" + }, + "eb41bce8e3aac2bcf662854a3151e3c83d98c6f3": { + "balance": "219455327737000000000" + }, + "eb44c591306972c29a7084079720d8ee5fb9b0a1": { + "balance": "49000000000000000000" + }, + "eb4b26ab55dc35df2e78d47a90fc43148a6de881": { + "balance": "12139574483030000000000" + }, + "eb4f53510db5edcaad6ea169e521bd094e8da4b1": { + "balance": "100000000000000000" + }, + "eb4fbfb7c0082aa0e7edaed934c5166fee955e5b": { + "balance": "299713748180000000000" + }, + "eb6067ab544af6289a73111e7693dc449d5c2134": { + "balance": "20000000000000000000" + }, + "eb86fea82d10d309b1365237e4855a48684e0e49": { + "balance": "81510415589000000000" + }, + "eb8abbcadeb6e19ab4392cded7a407c8d5df2d5c": { + "balance": "25000000000000000000" + }, + "eba44ca2d6f36df8221a2021bf0644cf6cb59452": { + "balance": "500000000000000000000000" + }, + "ebacbc0eace170f66415df48f74d98eb31828d15": { + "balance": "19046465915296000000000" + }, + "ebc72fb8a1029139d8abdc08da23dc559f87e1a8": { + "balance": "24177703742991000000000" + }, + "ebd561bb9001991cb6b02c8ff9e7ece8a3d73dde": { + "balance": "6684606759000000000" + }, + "ebe1dc3ee857ae4add6fa6636b678af8451d1701": { + "balance": "1485349608007000000000" + }, + "ebe68dc904c737be83aa2ee7f613dd51a6d436e4": { + "balance": "11206782120918000000000" + }, + "ebecf4db55a99f018bf136173ae823528f211380": { + "balance": "191817711082000000000" + }, + "ec15ad0aafe0c0f18089de50b2397509e15a20de": { + "balance": "20000000000000000000000" + }, + "ec2e56973a6cbd8b37d0294b16ef806ab5943ec7": { + "balance": "12031630315394000000000" + }, + "ec432a6a4685ebf6c1e872001d1de246140c8d98": { + "balance": "280056522277000000000" + }, + "ec866ba1bdadb91ca25f5ae035b0f69421ed4377": { + "balance": "431849961155000000000" + }, + "ec9be854224d3d371b79ffc1230fe704ba03be2b": { + "balance": "3692428502391000000000" + }, + "ecc2d6e129c7daa37a93f559c6d4f575171d8386": { + "balance": "20000000000000000000000" + }, + "ecc3aca2a21cb317c5b9debdcb2090f3931d5cd7": { + "balance": "100000000000000000000000" + }, + "eccc9a49ff40aa4b07aa0e1271cfb6713de683dd": { + "balance": "617207728367000000000" + }, + "ecccf24530629033fd6234ae32bde2052ebaa640": { + "balance": "16000000000000000000" + }, + "ed16770d5a56dced87224d4ff68a361a2285fef2": { + "balance": "10000000000000000000000" + }, + "ed23b8e782d5ddf203f9b80e5df83ec32e484fc6": { + "balance": "5000000000000000000" + }, + "ed3244e4168e669ae9d54175173c3f0f0e7c4c7a": { + "balance": "803397672115000000000" + }, + "ed48f39d3f022b321c0864d4955e1cdc8cf54834": { + "balance": "64000000000000000000" + }, + "ed4cb42fa6737cbbbf095f181e1425b3bc3ab4f6": { + "balance": "8974148344000000000" + }, + "ed560f7d83c27a26965f84dcface3930bc447fc5": { + "balance": "2092287996000000000" + }, + "ed6ace91369ec3b06cce474e67d1ce4aba6475a6": { + "balance": "1227081000000000000" + }, + "ed8249dd4a91f70176ffff310e5546e7e0c30b91": { + "balance": "813069034369000000000" + }, + "ed8987fa3d4d42bb8f009c99cda5868633d94f5a": { + "balance": "174952234860000000000" + }, + "ed99b72a58a519ca7aa8f46b8d254c3f1eeea0d6": { + "balance": "10000000000000000000000" + }, + "edb720c9bde4801e204e90282de2a6cf1c44c4ad": { + "balance": "10000000000000000000000" + }, + "edbea23cd0cfde3705d83aada88e78b9f4bb1a50": { + "balance": "4000000000000000000000" + }, + "edc1f174655205bb961ddf94a997cdfd24f1c2ed": { + "balance": "65211537189000000000" + }, + "edd1d2dcba881202bc546943194d64e59bf74bfd": { + "balance": "10000000000000000000000" + }, + "eded28fbd959f2351b4252abc71f0e809562fd4c": { + "balance": "1000000000000000000" + }, + "edfe4d4c83c7db76e5e8a9ccafa34d9841669dac": { + "balance": "2578239411258000000000" + }, + "ee1ef79de869b89334d883ba766e65150f3f6cf5": { + "balance": "779780646165000000000" + }, + "ee27b2da240e862f0848d31116a7b4ed91835c8d": { + "balance": "111637484977461000000000" + }, + "ee3195bdb69e97796911c63fdd3fcebad61ffe9b": { + "balance": "214483035823000000000" + }, + "ee43306530c21793c4fd6039b51cf54fbc912bf0": { + "balance": "374531713769000000000" + }, + "ee4515e30ee1b8dba4779ef213d89e8dfff26ea6": { + "balance": "1166743135013000000000" + }, + "ee591e9ca7948b8485eb210e2a3f706b97e6f9e2": { + "balance": "27793157052774000000000" + }, + "ee5ba6c854d633a04f7656d311817e5104c6de14": { + "balance": "289361919166000000000" + }, + "ee909db4ee48bff3adb9e43db940245a8e5e094d": { + "balance": "582143490064000000000" + }, + "ee94d1afa82de70eb65aad0662f48ef3170495cb": { + "balance": "242490158636000000000" + }, + "ee97e18e09bbb16137a7b4aaae464e97d70e6606": { + "balance": "442709862861000000000" + }, + "eebe957af00050c2841f3ef8768c6a77a5394012": { + "balance": "9000000000000000000" + }, + "eec052f4e2902f7cc496162ca6525997d2b3ede4": { + "balance": "69349303517000000000" + }, + "eed30e1a939d5f0b4a39598967a5f149a7b7cb8c": { + "balance": "1637195595000000000" + }, + "eed7bf1ba39bfdad0ce1b6b8d4c9bb31dc1a9843": { + "balance": "203331701702000000000" + }, + "eee276140ea24e36eccb4fd748f675df1acd3b73": { + "balance": "1000000000000000000000000" + }, + "eefb33b290741c4cded862cea777efe4b14a76da": { + "balance": "64000000000000000000" + }, + "ef17a60d15ecf68a62b4bfd5e3acd6201e1931af": { + "balance": "113292502078000000000" + }, + "ef3f4df42127d3e94b4b5883ca97ee63f90b68b5": { + "balance": "17819622000000000000" + }, + "ef4aa6833a69cf72fbf3eaac57da236970aa4241": { + "balance": "1638520372091000000000" + }, + "ef958a1db06e5b8e12547148f3b01da9a8841aad": { + "balance": "12847752197000000000" + }, + "ef9fa861eefe12a3b4c161a47db5d94b1fa873a9": { + "balance": "49000000000000000000" + }, + "efd9b1ce6bc3932961e41e875edaaa367d318b36": { + "balance": "1626378762077000000000" + }, + "efdce7f577c77f0dac6afc78dcbf5ebadc1c3a73": { + "balance": "627500067619000000000" + }, + "eff3f26bc45638d89f28b3ea7a5471af0b680b72": { + "balance": "1650959950189000000000" + }, + "eff6d78814ddae79d6d09d830dd44de55f3f919d": { + "balance": "44409266093000000000" + }, + "eff739e22b9aeb3781dc301da70761fdd178f08f": { + "balance": "574842224234000000000" + }, + "f0059b3c8a32d3d012b4fcb993431a484b67762f": { + "balance": "516933429840000000000" + }, + "f06747d8e2c76b8827bbd0bf4ea3a68d390ee8f3": { + "balance": "8124594790100000000000" + }, + "f0e29fc0aecc36d1bdd818148878ea7d01957476": { + "balance": "79821431871000000000" + }, + "f0e42acf4e027aa61ac2f56e3d2c171ec0fd6ebf": { + "balance": "672499252575000000000" + }, + "f14338307bc5e6ab71fa202447ce240947568b3c": { + "balance": "13990001528784000000000" + }, + "f14f9a1206eb436a3d2e4ba9b3976137f67a6596": { + "balance": "1086707451000000000" + }, + "f15fcf1772fa5b2a578ce4f9270996430d533000": { + "balance": "496026996898000000000" + }, + "f18c691a5827ff1fdc44b54bd9a64fabd53c1cf4": { + "balance": "3112912699000000000000" + }, + "f1960640b52af75fc71101aec2611499c17cd9c6": { + "balance": "195957678178000000000" + }, + "f1abf01ddd474949713bd7fa67ec81d6b56c87b7": { + "balance": "121000000000000000000" + }, + "f1b93a6cfd4b1c7e0e89ebed119c5fe55af2035e": { + "balance": "1000000000000000000000000" + }, + "f1d14c7659a10ff38f4ea74ff5b07ac035984b6a": { + "balance": "9986323720000000000" + }, + "f1dbf37470a2c4fef98b1023026870ae8f7df2c0": { + "balance": "132757602000000000000" + }, + "f220b958b619d5d848597dd00824ab8b1401ebd2": { + "balance": "1461699635849000000000" + }, + "f2484911e0aa707f88d9dd970db21e8f24b9de2f": { + "balance": "20000000000000000000000" + }, + "f264c15790fd7a36d9ce7a454f6bfbe878708a50": { + "balance": "64000000000000000000" + }, + "f2662356cb3ae7b82efd6c82c3591ee40854892b": { + "balance": "50000000000000000000000" + }, + "f27ae5783b96ef637bde4179080a8f5af63ae692": { + "balance": "784985848611000000000" + }, + "f2a62fc212717e411f72f9a694e30b8da21bb31b": { + "balance": "614971541702000000000" + }, + "f2d0a9594231efb87ac833c365b80944251f29d7": { + "balance": "478622654587000000000" + }, + "f2df99a3df0b9b448d0ea48b9fd5cb1ce9ce50cf": { + "balance": "851116673037000000000" + }, + "f2dff0ae1f5f74808624e4f26fa814e4e19c216a": { + "balance": "404457730686000000000" + }, + "f2ea1ac6282364ad5904c6f058827a4382111d94": { + "balance": "5502482915000000000" + }, + "f2fafdcdb2d887eb13b5362eb76be2a682868643": { + "balance": "6174264174000000000" + }, + "f314adfc2fbf632a6e5d8a261385b6054aca31b6": { + "balance": "1267558242119000000000" + }, + "f31a66a88394ed7dd6609aff07dd26a60a219bd8": { + "balance": "346102834465000000000" + }, + "f3535f2b42d8613363e6d9717cc21a8ec3a74fe0": { + "balance": "35723093185103000000000" + }, + "f36a149466982c030ce3b9717f34b593613804d5": { + "balance": "10000000000000000000000" + }, + "f3828b0eaba4acfbbcf3c58277ceb4616a34b630": { + "balance": "633998941064000000000" + }, + "f38f767eeb8002ef051b32fe2f40193bf0751d92": { + "balance": "50000000000000000000000" + }, + "f39bce177817a7338b1adaf713222e515c0d762b": { + "balance": "1128231726329000000000" + }, + "f3ac7ea27a1cefc7787e5ba54dacfd8385ee4afc": { + "balance": "11364602682758000000000" + }, + "f3d9ea511335ed418b1837766da11832aedf5578": { + "balance": "29188596603509000000000" + }, + "f3ef05ccd19df167e06797d962f6afe16037e134": { + "balance": "144000000000000000000" + }, + "f3f630148eccea0ad7bd67bb806bd5676a4ea4cb": { + "balance": "87187208643000000000" + }, + "f3ff31784e0b8c3cd2f7e18cfd07c682a42d1c8d": { + "balance": "10515373125000000000" + }, + "f40b976e8519a2c97f64783bca495ed3f2e4a7c0": { + "balance": "780184503985000000000" + }, + "f416a3af7f3181ad9c8a916989949d35b0b636ec": { + "balance": "16114504005275000000000" + }, + "f419759927eea6afe77701c4cf4a98791a709ad1": { + "balance": "1032589347112000000000" + }, + "f4368f9c9ad8236b56413f174562d6b6fef21d1c": { + "balance": "5447645343000000000" + }, + "f43c57f984b0e2b7ce4d703e82f41195585504a4": { + "balance": "1135809111749000000000" + }, + "f4449f52895de96a4638c927dc389f010bbd530c": { + "balance": "693196063498000000000" + }, + "f449bd417a674c8bfa1db3a3e09c2b03da0f0c04": { + "balance": "106343287319000000000" + }, + "f44dec8340986c06d64dc98d78772a8a9cdc41ec": { + "balance": "1379381904815000000000" + }, + "f4642be1a7685aea0dc7b362d36f58f15d806b72": { + "balance": "4717509847323000000000" + }, + "f4712925f57391043e0cc2e671f33124a0bc8613": { + "balance": "419736833200000000000" + }, + "f47317fba5927dd8dffc4049d4f3277fcef503d6": { + "balance": "149279442682000000000" + }, + "f47ce4c5aaef82692e47f7a810ba38d1faec0eea": { + "balance": "10000000000000000000000" + }, + "f491ffc412bf142788bb82d48bd4eccbe9e0a286": { + "balance": "77276422315000000000" + }, + "f4a1e27e669c29f15b9f89ac15f702340a135743": { + "balance": "324000000000000000000" + }, + "f4b5cbfa50a6c4f5f7db7a93fa565362cc7aceac": { + "balance": "195951823248000000000" + }, + "f4b949c6e10615b651675016f0d7d6ff64e31aee": { + "balance": "35516207325223000000000" + }, + "f4c5e2f043ef3548a2c1c27d968087bec65e2f7d": { + "balance": "100000000000000000000000" + }, + "f4c79ea9c6f7297e016c39296d86f0304070c31d": { + "balance": "71036374423000000000" + }, + "f4dde3733a72872a7efc095cb412672c50928f1b": { + "balance": "129914864759880000000000" + }, + "f4ed736a413464eb93f8a430e093a64f0bd4222d": { + "balance": "10000000000000000000000" + }, + "f4f07e45560fb63d5207ed7e8d7cf4fe29e06d18": { + "balance": "293103814503448000000000" + }, + "f50eac35eef0a1bfa23ba31020ef60e89bf8e9df": { + "balance": "10000000000000000000000" + }, + "f51236dfd888929ccb2fe1f1fc5554abc5df4ce2": { + "balance": "25000000000000000000" + }, + "f521eb42e9092350f2ad4391ddb42bfe7abb4db9": { + "balance": "217462745186000000000" + }, + "f54e7062b6a9a8b283acf00fcbad58aca0737676": { + "balance": "7327357122437000000000" + }, + "f553301efd81629d0856d9c95c70f4a962e602ed": { + "balance": "1500355826530000000000" + }, + "f55c555b0991b2413f2f2764d8ed6a0d77825965": { + "balance": "1174679810163000000000" + }, + "f56ff110d521ceaec29dbf2842f1e78b24463cea": { + "balance": "20000000000000000000000" + }, + "f573fec366236ab87ba041f7dc6a88d92b1fc9b7": { + "balance": "4659857040000000000" + }, + "f59987743b239379aac9353e17e0e4442aa2c684": { + "balance": "25000000000000000000" + }, + "f5a9ca298e88c5492dd44a66d815b649c2f01d39": { + "balance": "95879585325000000000" + }, + "f5b4933164c55b5ba99db906ecaa52bba4f95164": { + "balance": "25663623936000000000" + }, + "f5d20af68c6fed98144718b6beab82fde00dfedc": { + "balance": "16000000000000000000" + }, + "f5e49ce72be9b17ff39688860e5cf6fd500a886c": { + "balance": "106142276914000000000" + }, + "f5f472405a4530075805fbc11928544770fd61fe": { + "balance": "64000000000000000000" + }, + "f62096c7305eb97b221bb637f4269246fe59262b": { + "balance": "855993602798000000000" + }, + "f622bf9b8f7be2f75d5ed73d318a0e7fa62a587f": { + "balance": "20000000000000000000000" + }, + "f6231f31d524ccc444bd046123ba33bc224bdd52": { + "balance": "97550810879000000000" + }, + "f641b4a721dcefa497274fd06888eb998b9bc038": { + "balance": "39401014566340000000000" + }, + "f64f0c5172c99d74b2450a4685c3ec715b379922": { + "balance": "28337413668000000000" + }, + "f65841061cd55cbf20843d9594bce9ee133aa644": { + "balance": "9064540188290000000000" + }, + "f65f0106f3d148d0660547f0683ded4dffc12fe9": { + "balance": "87334071785367000000000" + }, + "f677961296ed933db9e1dd887711387540c0436d": { + "balance": "3982789899000000000" + }, + "f68ba7530f423b8df1625cee36f8df2363a57c49": { + "balance": "5000000000000000000000" + }, + "f69c6eaf077b795f19a9590ee8b578543558e4c4": { + "balance": "10000000000000000000000" + }, + "f69dfe3f0f76e50e2850e44e9e36b6966e277eaa": { + "balance": "288231750575462000000000" + }, + "f6a73c4b958b4d6044f3f4da7147d0fa80e2ea31": { + "balance": "50000000000000000000000" + }, + "f6b0864be5f7bbc4210a3420aa3ead614a8fe7e2": { + "balance": "880968828000000000" + }, + "f6f43a6d9517471436d2ce5047a2b707580e7149": { + "balance": "20000000000000000000000" + }, + "f6fb414d1ca7c29be35b5f97096c817bbf70b070": { + "balance": "15156317416682000000000" + }, + "f707b491ac27b2d2e5e1f9d4123635ee0af92c5c": { + "balance": "500000000000000000000000" + }, + "f71179583a471767a1b399842d7d29caefe57a5e": { + "balance": "429648186876000000000" + }, + "f71ed909eca6bfd574cd670389bc9250493d686d": { + "balance": "38189267531000000000" + }, + "f72ccdc70b7878cdb94f42ee72ca5b4b35a46238": { + "balance": "86065647347000000000" + }, + "f74035e85dbfdb961037bf689ee7dfdcfaf32d64": { + "balance": "398451682882000000000" + }, + "f77668db085a87b0a0405a275e1c2516d3e02b66": { + "balance": "10000000000000000000000" + }, + "f78990d9e50876b49f933e9d74bda44197e9aa7d": { + "balance": "51984216556000000000" + }, + "f79b9df28b7d94d1b4491fca1cbe50bd36aedb3a": { + "balance": "11546152485156000000000" + }, + "f7c773b89be413848dc4a96f064693a0c3a2eab0": { + "balance": "7084247258755000000000" + }, + "f7e29c20bb0023e9ae079da589346fdfd960dae3": { + "balance": "93132014782000000000" + }, + "f8124428ea619d30a335ecc4c2f64e36500abdcb": { + "balance": "8838170798391000000000" + }, + "f843c9d70226e6c2c8cd4cef78e2db66a8eac027": { + "balance": "498377670361000000000" + }, + "f84bb3c0d872dcdbe99d6abcc57c6b5c2b2e35ad": { + "balance": "1405105232436000000000" + }, + "f8679b915ae94e4668f2e27d1094cbb2d97cf428": { + "balance": "1000000000000000000" + }, + "f86dbb82c634cdfa818e4d0dbcfcc9a5c47a9ddb": { + "balance": "196000000000000000000" + }, + "f88bad7726aa66bc1d0ca5824044072f3551fd15": { + "balance": "37432374800000000000" + }, + "f8ab07d0751a2c283ebe2a7e28c5b6e57867e1d1": { + "balance": "25000000000000000000" + }, + "f8afb4f5684c56ff7ce71b4e4cf7e42062470e08": { + "balance": "10000000000000000000000" + }, + "f8c28df0d1a0982289ddfa2a6d562e5c75a5dd01": { + "balance": "1447386977682000000000" + }, + "f8cca137f9c12b48eafd43f038e55e2d3c481919": { + "balance": "35370515421000000000" + }, + "f8e50d1816a5e5c649756ae208209b03b1ece0c3": { + "balance": "48449640035000000000" + }, + "f8fb33ba1d93112d9c3672806e0939083f09a88e": { + "balance": "419743187776000000000" + }, + "f903bebfcc6a7050fc2c5bd14248af9b300f1600": { + "balance": "473363252199000000000" + }, + "f90ab9078f26dd881fb054b4b6e3b3e17fa94718": { + "balance": "156449634345000000000" + }, + "f93e3f392efc057f0af3a91416858a515c1ed996": { + "balance": "1147663044625000000000" + }, + "f94eac538ca66931869c312acb67721c4337842f": { + "balance": "368103335377000000000" + }, + "f94fda503c3f792491fa77b3702fd465f028810d": { + "balance": "317241487661000000000" + }, + "f95dcedbefee8ed01086c91d91a4c115ad8fc947": { + "balance": "147059838786000000000" + }, + "f961a293bbce366a6fcc98d2ba0342e2ef3c5519": { + "balance": "10000000000000000000000" + }, + "f966fdbc4a42f055f8f52d31c23ad7b6a07a5e22": { + "balance": "10000000000000000000000" + }, + "f9a3a61a2f1469835240bb0641eae40c07451e30": { + "balance": "218000000000000" + }, + "f9adcf232180378b08a46d6c8d9d97f01802e01b": { + "balance": "15658216517944000000000" + }, + "f9c68991ff7ac307e41ea1c673f8ebb1a6afbd99": { + "balance": "10000000000000000000000" + }, + "f9cc0c60431d7bdb0c7581a9ae7f011b0abefeb1": { + "balance": "16000000000000000000" + }, + "f9d43c329b61ca2169600e45c8fad3c94226adb8": { + "balance": "120128558137000000000" + }, + "f9ef5d4e2ca8888216b939d3d938438a34dd9da2": { + "balance": "144000000000000000000" + }, + "f9f3d14cd3bd09e2c4c89035b4f50e93f6175cef": { + "balance": "725000000000000000000" + }, + "fa0f5a03601bd1fc76865cdd69d9671ba6073592": { + "balance": "225298289139000000000" + }, + "fa12f10db0eb552b719194becef20af9f45de8db": { + "balance": "1012484659496000000000" + }, + "fa146c58a0709951bc2e9bccddcd002c5a0bb7dd": { + "balance": "199563276701000000000" + }, + "fa159185c156f35fa450b77c48846c2dab6349b7": { + "balance": "100660066567000000000" + }, + "fa193312655f79c7b0ee7d7ef904486836180026": { + "balance": "48141690266000000000" + }, + "fa2484de744918bd8c91350fbabc0dab8b8a44f0": { + "balance": "36000000000000000000" + }, + "fa36dc463b026d8edfeb8ac4acac43a51d643457": { + "balance": "9608761064478000000000" + }, + "fa84199010be2bf53e803c23771e0d15fd025386": { + "balance": "1474902394742000000000" + }, + "fa958bbfa367a745bcd0904db2c4e30445edaefb": { + "balance": "175679888121000000000" + }, + "fa98bcaeb55285ad7ead12ccaa15cf488f567ede": { + "balance": "136105143781000000000" + }, + "faa1be631da42b41a026774f4166c1b831ef41e9": { + "balance": "86358861589000000000" + }, + "faaa857e7f149968434f313ab8db596e1b0ae75d": { + "balance": "36000000000000000000" + }, + "fac2b85ab274055cf1415d57394e8aca4541857d": { + "balance": "289000000000000000000" + }, + "fb23a508ccdb4e91b252f5c06c465c55ed59b1db": { + "balance": "14698710175236000000000" + }, + "fb24d4e47ba70aa4b984372b4852ad3d082daa24": { + "balance": "4526648424830000000000" + }, + "fb27a7e8b8b4ae43c69ce025b46187e538608769": { + "balance": "121000000000000000000" + }, + "fb2cdb5e85872f52c99985f219b8fb4125c6a8b7": { + "balance": "8568367153000000000" + }, + "fb3d76c8165bcb3c93fd3b2b10c20588d0fa97aa": { + "balance": "500000000000000000000000" + }, + "fb5161b2cc9d48a53f47d66002905f0458e3cd9e": { + "balance": "225000000000000000000" + }, + "fb72756c4845f18ab35d29f632b662c0c0d4b94f": { + "balance": "883095068524000000000" + }, + "fb8b7efb02ea5292304c0f0abc8c555684653587": { + "balance": "10000000000000000000000" + }, + "fb9ee61e337a5c7b57c5140e84919101570e2cb7": { + "balance": "16000000000000000000" + }, + "fbae69f44b116c186a86cb0de79323ca3d6b99eb": { + "balance": "1359504686067000000000" + }, + "fbbd399eb9e5d3dd67efc48927973601dcd84321": { + "balance": "2049018637367000000000" + }, + "fbc9a3c3c429990cc306710b3dd44174dcc72ad4": { + "balance": "55507457947000000000" + }, + "fbce66a6898ecd70893db6b4b8c3d00afef8e20b": { + "balance": "20857164902458000000000" + }, + "fbe8fe04084fc93dff8228861fe100bfeeb057b6": { + "balance": "10000000000000000000000" + }, + "fbfb717f902ad79ef63565f9ab57f041ff5f7626": { + "balance": "16000000000000000000" + }, + "fc0b6c8c6be79bf0c9554f7855dc8c4a617d02c9": { + "balance": "17347593956000000000" + }, + "fc17518d05e605807847bbf6f407da89037bca00": { + "balance": "1796383702108000000000" + }, + "fc2793424c809cc80938a1be1292813adbc8ac8c": { + "balance": "10000000000000000000" + }, + "fc35930abb108ae6cae33fd065dfb799808ea326": { + "balance": "912737460000000000000" + }, + "fc5a9209799e563ae8d958774dc86345a3bc7ed2": { + "balance": "29049176573000000000" + }, + "fc8011850c09c9288e737ea58ca5c15cded6dc8d": { + "balance": "10000000000000000000000" + }, + "fc9183ed137be071ad183d025395a0ebe2674654": { + "balance": "500000000000000000000000" + }, + "fc98c9d88b1fbbb68dbdd6448aa6a32e8282800d": { + "balance": "900000000000000000000" + }, + "fc9f4b9da7a46c2bfcd50cafe1f892b9984be0ee": { + "balance": "21577116424370000000000" + }, + "fca525b732a673b953f1c23083c276cc8cbcb86c": { + "balance": "77653618624000000000" + }, + "fca57b6a4798f33478b6e23622173cda3fe1b9a0": { + "balance": "793368066098000000000" + }, + "fca79b446c513a7bed643603c42f35ff0fa89f49": { + "balance": "998082799053000000000" + }, + "fcab42f7f07735a7b09074c1f1769287069c88c8": { + "balance": "94824830574000000000" + }, + "fcacbbc6810c586522012ad32c3dfac80eb563b4": { + "balance": "10000000000000000000000" + }, + "fcb38809b63810b6673dcb4c947e01f7b49fb1b3": { + "balance": "725937240372000000000" + }, + "fcc0e531d9f6265672aa885af361534464a11015": { + "balance": "22121462657000000000" + }, + "fcc49c62d7738fa1b92aa6a69a12b671e4c7c8d9": { + "balance": "50000000000000000000000" + }, + "fcc95394fd796ca5bd8f3814883b1150d74dd9a5": { + "balance": "144000000000000000000" + }, + "fccdb068dfd599d7d5c290a6ae65eba9151d5b29": { + "balance": "5369426564000000000" + }, + "fcde41ae28bdf9084a28f47a9348d8aac5b3dd43": { + "balance": "409599263197000000000" + }, + "fce5816f066ca32d1fa02e9e8b5eb8a7fa3e4dea": { + "balance": "1193272309645000000000" + }, + "fcf9fb8996d6d9175ade6d6063be0742de20ea1f": { + "balance": "16852526239339000000000" + }, + "fd10488d55e6861cb67f7f50950d78892e7032ad": { + "balance": "165069902909000000000" + }, + "fd23e8263d89256add0dfe93da153d305ad917c7": { + "balance": "26633825496000000000" + }, + "fd3a98cc3b3f1439af35f806de2fb05fef98f279": { + "balance": "1043321187464000000000" + }, + "fd3d79185a91984a117ee6f9fd304725875094e2": { + "balance": "2349991833898000000000" + }, + "fd5e6ac22634f04ec4ace5da8996c2b7b70b22f4": { + "balance": "10000000000000000" + }, + "fd62ed1cf7a535c989fbd742b1660205a2f69dd0": { + "balance": "49000000000000000000" + }, + "fd645043bd4d7b71e63e30409b91e9fdda3a86c0": { + "balance": "362957768837969000000000" + }, + "fd7014fc1c70af482115247ff94ff6bdbd3d364d": { + "balance": "743383172317000000000" + }, + "fda0cfe95df9021497752b04863c3ec44d13e853": { + "balance": "15586809617955000000000" + }, + "fdb5b964808bcb974d3e888cbb45bcd57e57c907": { + "balance": "5549247772273000000000" + }, + "fdbaaa865ec38da13e80554b6d0abc437f60d8a5": { + "balance": "3736861227131000000000" + }, + "fdbb8693b3c20c0eac5fb585e2347d41debbffce": { + "balance": "100000000000000000" + }, + "fdbdaec57829f25ad48e18d94e0b8533f2801818": { + "balance": "6934630922926000000000" + }, + "fdc318ba5b1f8ad33e00528828b93a840592e2fb": { + "balance": "10000000000000000000000" + }, + "fdcf6a997bb10806e4d87eb4222e9f93b4202179": { + "balance": "1000000000000000000" + }, + "fde5a9911a10770d733db4d32ca9a5493478399c": { + "balance": "20000000000000000000000" + }, + "fe39185a6b84378820ee215f630533e658731ca9": { + "balance": "17022202932000000000" + }, + "fe3b1032e524674cba5f329f940c837850fa53ed": { + "balance": "50000000000000000000000" + }, + "fe3bc4ff2c3b66bc582558314b80030407e7de96": { + "balance": "1669870860988000000000" + }, + "fe668dbb1f3de744d16e13e0ed6f5708c2c15d1f": { + "balance": "39974355655263000000000" + }, + "fe95bfb97fa60341f8af2ad621e606b85e3c2e57": { + "balance": "528601649597478000000000" + }, + "fe99cf2a1fbbe7c46e4235b2d135a3a093fcf16c": { + "balance": "7271022106877000000000" + }, + "fec1f6ed4b3ff01e7ebe13fb53f60ee5a3b9e191": { + "balance": "1316316072034000000000" + }, + "fed9bec1b2145452ed5535e4ba29fafac6c35fbb": { + "balance": "10799354586000000000" + }, + "fedced7aa1cf3f3a7eec321cc0274759b154ea8e": { + "balance": "11740927210323000000000" + }, + "fef5063701a93ad02676fe0b99d0f4d2da0ccd67": { + "balance": "10178531012000000000" + }, + "fefd5627a408ca099587892ee2a46fa8cc89be19": { + "balance": "458504035686000000000" + }, + "ff1fc0f6f26188cbe18cf65d8a344d3775aecc6d": { + "balance": "81000000000000000000" + }, + "ff4fe483b3c04ebc8d6705c699ecee3e92071715": { + "balance": "1000000000000000000" + }, + "ff51bfe823394b2bce05947a6068bd5158d4af0e": { + "balance": "692533626783000000000" + }, + "ff6652e4e45f6b0f95ad4c9ec2bc80476e3f7fc6": { + "balance": "46457898024000000000" + }, + "ff68246ac7640091e5e58345736b249e036364fc": { + "balance": "2626125272000000000" + }, + "ff6d4b8a8393a503047ff829dbf2bf8e9172dc6d": { + "balance": "2865001878255000000000" + }, + "ff6fe19e056a7211b7e484c2c540d5aa5f1d83e5": { + "balance": "36000000000000000000" + }, + "ff7fa33529e1781c1b2951e57581780b229e3fda": { + "balance": "10000000000000000000" + }, + "ff82d1052538539d07cf3955476cc9a5027d8e4e": { + "balance": "83572023121000000000" + }, + "ff8acfe75afcc1efb1bc44be9f9bb242a94f73f7": { + "balance": "7556034521000000000" + }, + "ffa2b5f1685de9fcf1af4653cd3a584db1beed64": { + "balance": "114892199805000000000" + }, + "ffb1e9be68ae8be8d7d066c473589921e68825a2": { + "balance": "484660652980000000000" + }, + "ffbf91a9d1a6377b7435e3e734132e7b34188dac": { + "balance": "20000000000000000000000" + }, + "ffbff1fab9f2bc2f387d0cc9cc28f6aac533c813": { + "balance": "10000000000000000000000" + }, + "ffc4ff6433ea35544e7a07fda170e62c451301df": { + "balance": "29238210920000000000" + }, + "ffc7534b64a8fe8760e931a710883119d28ae106": { + "balance": "500000000000000000000000" + }, + "ffda6b8e3de72d7f7c18b892e6a8b80b886d5fa5": { + "balance": "214366938289000000000" + }, + "ffddb1fb7521c9772ea4886aaf022c4375ef904d": { + "balance": "554864446437000000000" + } + } } diff --git a/ethcore/res/ethereum/transition_test.json b/ethcore/res/ethereum/transition_test.json index 7c18fce4e5..9dc00fd5d8 100644 --- a/ethcore/res/ethereum/transition_test.json +++ b/ethcore/res/ethereum/transition_test.json @@ -8,10 +8,6 @@ "durationLimit": "0x0d", "blockReward": "0x4563918244F40000", "homesteadTransition": "0", - "eip150Transition": "0", - "eip160Transition": "0", - "eip161abcTransition": "0", - "eip161dTransition": "0", "eip649Reward": "0x29A2241AF62C0000", "eip100bTransition": "5", "eip649Transition": "5" @@ -27,6 +23,10 @@ "networkID" : "0x1", "maxCodeSize": 24576, "maxCodeSizeTransition": "0", + "eip150Transition": "0", + "eip160Transition": "0", + "eip161abcTransition": "0", + "eip161dTransition": "0", "eip98Transition": "5", "eip140Transition": "5", "eip211Transition": "5", diff --git a/ethcore/src/machine.rs b/ethcore/src/machine.rs index 1bd3805ef3..9c6db25cbc 100644 --- a/ethcore/src/machine.rs +++ b/ethcore/src/machine.rs @@ -46,14 +46,6 @@ pub const PARITY_GAS_LIMIT_DETERMINANT: U256 = U256([37, 0, 0, 0]); pub struct EthashExtensions { /// Homestead transition block number. pub homestead_transition: BlockNumber, - /// EIP150 transition block number. - pub eip150_transition: BlockNumber, - /// Number of first block where EIP-160 rules begin. - pub eip160_transition: u64, - /// Number of first block where EIP-161.abc begin. - pub eip161abc_transition: u64, - /// Number of first block where EIP-161.d begins. - pub eip161d_transition: u64, /// DAO hard-fork transition block (X). pub dao_hardfork_transition: u64, /// DAO hard-fork refund contract address (C). @@ -66,10 +58,6 @@ impl From<::ethjson::spec::EthashParams> for EthashExtensions { fn from(p: ::ethjson::spec::EthashParams) -> Self { EthashExtensions { homestead_transition: p.homestead_transition.map_or(0, Into::into), - eip150_transition: p.eip150_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), 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), dao_hardfork_accounts: p.dao_hardfork_accounts.unwrap_or_else(Vec::new).into_iter().map(Into::into).collect(), @@ -267,19 +255,8 @@ impl EthereumMachine { Some(ref ext) => { if block_number < ext.homestead_transition { Schedule::new_frontier() - } else if block_number < ext.eip150_transition { - Schedule::new_homestead() } else { - let max_code_size = self.params.max_code_size(block_number); - let mut schedule = Schedule::new_post_eip150( - max_code_size as _, - block_number >= ext.eip160_transition, - block_number >= ext.eip161abc_transition, - block_number >= ext.eip161d_transition - ); - - self.params.update_schedule(block_number, &mut schedule); - schedule + self.params.schedule(block_number) } } }; @@ -503,10 +480,6 @@ mod tests { fn get_default_ethash_extensions() -> EthashExtensions { EthashExtensions { homestead_transition: 1150000, - eip150_transition: u64::max_value(), - eip160_transition: u64::max_value(), - eip161abc_transition: u64::max_value(), - eip161d_transition: u64::max_value(), dao_hardfork_transition: u64::max_value(), dao_hardfork_beneficiary: "0000000000000000000000000000000000000001".into(), dao_hardfork_accounts: Vec::new(), diff --git a/ethcore/src/spec/spec.rs b/ethcore/src/spec/spec.rs index 1ee8cf7032..fa25c8894e 100644 --- a/ethcore/src/spec/spec.rs +++ b/ethcore/src/spec/spec.rs @@ -78,6 +78,14 @@ pub struct CommonParams { pub min_gas_limit: U256, /// Fork block to check. pub fork_block: Option<(BlockNumber, H256)>, + /// EIP150 transition block number. + pub eip150_transition: BlockNumber, + /// Number of first block where EIP-160 rules begin. + pub eip160_transition: u64, + /// Number of first block where EIP-161.abc begin. + pub eip161abc_transition: u64, + /// Number of first block where EIP-161.d begins. + pub eip161d_transition: u64, /// Number of first block where EIP-98 rules begin. pub eip98_transition: BlockNumber, /// Number of first block where EIP-658 rules begin. @@ -134,9 +142,20 @@ pub struct CommonParams { impl CommonParams { /// Schedule for an EVM in the post-EIP-150-era of the Ethereum main net. pub fn schedule(&self, block_number: u64) -> ::vm::Schedule { - let mut schedule = ::vm::Schedule::new_post_eip150(self.max_code_size(block_number) as _, true, true, true); - self.update_schedule(block_number, &mut schedule); - schedule + if block_number < self.eip150_transition { + ::vm::Schedule::new_homestead() + } else { + let max_code_size = self.max_code_size(block_number); + let mut schedule = ::vm::Schedule::new_post_eip150( + max_code_size as _, + block_number >= self.eip160_transition, + block_number >= self.eip161abc_transition, + block_number >= self.eip161d_transition + ); + + self.update_schedule(block_number, &mut schedule); + schedule + } } /// Returns max code size at given block. @@ -197,6 +216,10 @@ impl From for CommonParams { } else { None }, + eip150_transition: p.eip150_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(0, Into::into), 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), diff --git a/json/src/spec/ethash.rs b/json/src/spec/ethash.rs index afa8b59682..66f6913e57 100644 --- a/json/src/spec/ethash.rs +++ b/json/src/spec/ethash.rs @@ -73,21 +73,6 @@ pub struct EthashParams { #[serde(rename="eip100bTransition")] pub eip100b_transition: Option, - /// See main EthashParams docs. - #[serde(rename="eip150Transition")] - pub eip150_transition: Option, - - /// See main EthashParams docs. - #[serde(rename="eip160Transition")] - pub eip160_transition: Option, - - /// See main EthashParams docs. - #[serde(rename="eip161abcTransition")] - pub eip161abc_transition: Option, - /// See main EthashParams docs. - #[serde(rename="eip161dTransition")] - pub eip161d_transition: Option, - /// See main EthashParams docs. #[serde(rename="ecip1010PauseTransition")] pub ecip1010_pause_transition: Option, @@ -190,11 +175,7 @@ mod tests { "difficultyHardforkTransition": "0x59d9", "difficultyHardforkBoundDivisor": "0x0200", "bombDefuseTransition": "0x41", - "eip100bTransition": "0x42", - "eip150Transition": "0x43", - "eip160Transition": "0x45", - "eip161abcTransition": "0x46", - "eip161dTransition": "0x47" + "eip100bTransition": "0x42" } }"#; @@ -237,10 +218,6 @@ mod tests { difficulty_hardfork_bound_divisor: Some(Uint(U256::from(0x0200))), bomb_defuse_transition: Some(Uint(U256::from(0x41))), eip100b_transition: Some(Uint(U256::from(0x42))), - eip150_transition: Some(Uint(U256::from(0x43))), - eip160_transition: Some(Uint(U256::from(0x45))), - eip161abc_transition: Some(Uint(U256::from(0x46))), - eip161d_transition: Some(Uint(U256::from(0x47))), ecip1010_pause_transition: None, ecip1010_continue_transition: None, ecip1017_era_rounds: None, @@ -285,10 +262,6 @@ mod tests { difficulty_hardfork_bound_divisor: None, bomb_defuse_transition: None, eip100b_transition: None, - eip150_transition: None, - eip160_transition: None, - eip161abc_transition: None, - eip161d_transition: None, ecip1010_pause_transition: None, ecip1010_continue_transition: None, ecip1017_era_rounds: None, diff --git a/json/src/spec/params.rs b/json/src/spec/params.rs index 0addf52e4a..f171a88101 100644 --- a/json/src/spec/params.rs +++ b/json/src/spec/params.rs @@ -51,6 +51,21 @@ pub struct Params { #[serde(rename="forkCanonHash")] pub fork_hash: Option, + /// See main EthashParams docs. + #[serde(rename="eip150Transition")] + pub eip150_transition: Option, + + /// See main EthashParams docs. + #[serde(rename="eip160Transition")] + pub eip160_transition: Option, + + /// See main EthashParams docs. + #[serde(rename="eip161abcTransition")] + pub eip161abc_transition: Option, + /// See main EthashParams docs. + #[serde(rename="eip161dTransition")] + pub eip161d_transition: Option, + /// See `CommonParams` docs. #[serde(rename="eip98Transition")] pub eip98_transition: Option, -- GitLab From 84ecab0eaf96149be75ee127aef37d0cb0f2c4bb Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Tue, 22 May 2018 06:32:05 +0200 Subject: [PATCH 060/152] Remove HostInfo::client_version() and secret() (#8677) --- util/network-devp2p/src/handshake.rs | 3 ++- util/network-devp2p/src/host.rs | 14 +++++++------- util/network/src/lib.rs | 4 ---- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/util/network-devp2p/src/handshake.rs b/util/network-devp2p/src/handshake.rs index a203af5b4b..7aef4d4f0d 100644 --- a/util/network-devp2p/src/handshake.rs +++ b/util/network-devp2p/src/handshake.rs @@ -26,7 +26,8 @@ use node_table::NodeId; use io::{IoContext, StreamToken}; use ethkey::{KeyPair, Public, Secret, recover, sign, Generator, Random}; use ethkey::crypto::{ecdh, ecies}; -use network::{Error, ErrorKind, HostInfo}; +use network::{Error, ErrorKind, HostInfo as HostInfoTrait}; +use host::HostInfo; #[derive(PartialEq, Eq, Debug)] enum HandshakeState { diff --git a/util/network-devp2p/src/host.rs b/util/network-devp2p/src/host.rs index f3446845fb..5ccab2e4db 100644 --- a/util/network-devp2p/src/host.rs +++ b/util/network-devp2p/src/host.rs @@ -215,19 +215,19 @@ impl HostInfo { self.nonce = keccak(&self.nonce); self.nonce } -} -impl HostInfoTrait for HostInfo { - fn id(&self) -> &NodeId { - self.keys.public() + pub(crate) fn client_version(&self) -> &str { + &self.config.client_version } - fn secret(&self) -> &Secret { + pub(crate) fn secret(&self) -> &Secret { self.keys.secret() } +} - fn client_version(&self) -> &str { - &self.config.client_version +impl HostInfoTrait for HostInfo { + fn id(&self) -> &NodeId { + self.keys.public() } } diff --git a/util/network/src/lib.rs b/util/network/src/lib.rs index 0137543fdd..d16403cd34 100644 --- a/util/network/src/lib.rs +++ b/util/network/src/lib.rs @@ -330,10 +330,6 @@ impl<'a, T> NetworkContext for &'a T where T: ?Sized + NetworkContext { pub trait HostInfo { /// Returns public key fn id(&self) -> &NodeId; - /// Returns secret key - fn secret(&self) -> &Secret; - /// Returns the client version. - fn client_version(&self) -> &str; } /// Network IO protocol handler. This needs to be implemented for each new subprotocol. -- GitLab From ee41fa6f30fe275977265c7e139b4841ab47c725 Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Tue, 22 May 2018 06:34:01 +0200 Subject: [PATCH 061/152] Move connection_filter to the network crate (#8674) --- Cargo.lock | 1 + ethcore/node_filter/Cargo.toml | 1 + ethcore/node_filter/src/lib.rs | 6 ++++-- ethcore/sync/src/api.rs | 5 +++-- ethcore/sync/src/lib.rs | 4 ++-- util/network-devp2p/src/host.rs | 2 +- util/network-devp2p/src/lib.rs | 2 -- util/network-devp2p/src/service.rs | 2 +- util/{network-devp2p => network}/src/connection_filter.rs | 0 util/network/src/lib.rs | 2 ++ 10 files changed, 15 insertions(+), 10 deletions(-) rename util/{network-devp2p => network}/src/connection_filter.rs (100%) diff --git a/Cargo.lock b/Cargo.lock index e2fa0a9db8..646bc90645 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1805,6 +1805,7 @@ dependencies = [ "ethabi-derive 5.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore 1.12.0", "ethcore-io 1.12.0", + "ethcore-network 1.12.0", "ethcore-network-devp2p 1.12.0", "ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb-memorydb 0.1.0", diff --git a/ethcore/node_filter/Cargo.toml b/ethcore/node_filter/Cargo.toml index 25b5ec59f4..0d204e29ff 100644 --- a/ethcore/node_filter/Cargo.toml +++ b/ethcore/node_filter/Cargo.toml @@ -8,6 +8,7 @@ authors = ["Parity Technologies "] [dependencies] ethcore = { path = ".."} +ethcore-network = { path = "../../util/network" } ethcore-network-devp2p = { path = "../../util/network-devp2p" } ethereum-types = "0.3" log = "0.3" diff --git a/ethcore/node_filter/src/lib.rs b/ethcore/node_filter/src/lib.rs index 715b7ae3e9..c731ad356a 100644 --- a/ethcore/node_filter/src/lib.rs +++ b/ethcore/node_filter/src/lib.rs @@ -18,7 +18,8 @@ extern crate ethabi; extern crate ethcore; -extern crate ethcore_network_devp2p as network; +extern crate ethcore_network as network; +extern crate ethcore_network_devp2p as devp2p; extern crate ethereum_types; extern crate lru_cache; extern crate parking_lot; @@ -43,7 +44,8 @@ use parking_lot::Mutex; use ethcore::client::{BlockChainClient, BlockId}; use ethereum_types::{H256, Address}; -use network::{NodeId, ConnectionFilter, ConnectionDirection}; +use network::{ConnectionFilter, ConnectionDirection}; +use devp2p::NodeId; use_contract!(peer_set, "PeerSet", "res/peer_set.json"); diff --git a/ethcore/sync/src/api.rs b/ethcore/sync/src/api.rs index e901528e41..56ea8526ed 100644 --- a/ethcore/sync/src/api.rs +++ b/ethcore/sync/src/api.rs @@ -19,9 +19,10 @@ use std::collections::{HashMap, BTreeMap}; use std::io; use std::time::Duration; use bytes::Bytes; -use devp2p::{NetworkService, ConnectionFilter}; +use devp2p::NetworkService; use network::{NetworkProtocolHandler, NetworkContext, HostInfo, PeerId, ProtocolId, - NetworkConfiguration as BasicNetworkConfiguration, NonReservedPeerMode, Error, ErrorKind}; + NetworkConfiguration as BasicNetworkConfiguration, NonReservedPeerMode, Error, ErrorKind, + ConnectionFilter}; use ethereum_types::{H256, H512, U256}; use io::{TimerToken}; use ethcore::ethstore::ethkey::Secret; diff --git a/ethcore/sync/src/lib.rs b/ethcore/sync/src/lib.rs index 3eb2e8332b..c00ea5e440 100644 --- a/ethcore/sync/src/lib.rs +++ b/ethcore/sync/src/lib.rs @@ -74,6 +74,6 @@ mod api; pub use api::*; pub use chain::{SyncStatus, SyncState}; -pub use devp2p::{validate_node_url, ConnectionFilter, ConnectionDirection}; -pub use network::{NonReservedPeerMode, Error, ErrorKind}; +pub use devp2p::validate_node_url; +pub use network::{NonReservedPeerMode, Error, ErrorKind, ConnectionFilter, ConnectionDirection}; pub use private_tx::{PrivateTxHandler, NoopPrivateTxHandler, SimplePrivateTxHandler}; diff --git a/util/network-devp2p/src/host.rs b/util/network-devp2p/src/host.rs index 5ccab2e4db..3ab7b7f849 100644 --- a/util/network-devp2p/src/host.rs +++ b/util/network-devp2p/src/host.rs @@ -45,7 +45,7 @@ use discovery::{Discovery, TableUpdates, NodeEntry}; use ip_utils::{map_external_address, select_public_address}; use path::restrict_permissions_owner; use parking_lot::{Mutex, RwLock}; -use connection_filter::{ConnectionFilter, ConnectionDirection}; +use network::{ConnectionFilter, ConnectionDirection}; type Slab = ::slab::Slab; diff --git a/util/network-devp2p/src/lib.rs b/util/network-devp2p/src/lib.rs index e5bb95f220..244997a654 100644 --- a/util/network-devp2p/src/lib.rs +++ b/util/network-devp2p/src/lib.rs @@ -106,10 +106,8 @@ mod discovery; mod service; mod node_table; mod ip_utils; -mod connection_filter; pub use service::NetworkService; -pub use connection_filter::{ConnectionFilter, ConnectionDirection}; pub use host::NetworkContext; pub use io::TimerToken; diff --git a/util/network-devp2p/src/service.rs b/util/network-devp2p/src/service.rs index 10a1e9abc8..3ac1ec7f71 100644 --- a/util/network-devp2p/src/service.rs +++ b/util/network-devp2p/src/service.rs @@ -21,7 +21,7 @@ use io::*; use parking_lot::RwLock; use std::sync::Arc; use ansi_term::Colour; -use connection_filter::ConnectionFilter; +use network::ConnectionFilter; struct HostHandler { public_url: RwLock> diff --git a/util/network-devp2p/src/connection_filter.rs b/util/network/src/connection_filter.rs similarity index 100% rename from util/network-devp2p/src/connection_filter.rs rename to util/network/src/connection_filter.rs diff --git a/util/network/src/lib.rs b/util/network/src/lib.rs index d16403cd34..f3012e4c37 100644 --- a/util/network/src/lib.rs +++ b/util/network/src/lib.rs @@ -27,8 +27,10 @@ extern crate snappy; #[macro_use] extern crate error_chain; +mod connection_filter; mod error; +pub use connection_filter::{ConnectionFilter, ConnectionDirection}; pub use io::TimerToken; pub use error::{Error, ErrorKind, DisconnectReason}; -- GitLab From fe5f5b28d9be6b894545cfbbb42580068e14524b Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Tue, 22 May 2018 06:35:13 +0200 Subject: [PATCH 062/152] Remove the error when stopping the network (#8671) --- ethcore/sync/src/api.rs | 6 ++---- util/io/src/service_mio.rs | 10 ++++++---- util/network-devp2p/src/host.rs | 5 ++--- util/network-devp2p/src/service.rs | 7 +++---- util/network-devp2p/tests/tests.rs | 2 +- 5 files changed, 14 insertions(+), 16 deletions(-) diff --git a/ethcore/sync/src/api.rs b/ethcore/sync/src/api.rs index 56ea8526ed..2f90e410ae 100644 --- a/ethcore/sync/src/api.rs +++ b/ethcore/sync/src/api.rs @@ -475,7 +475,7 @@ impl ChainNotify for EthSync { fn stop(&self) { self.eth_handler.snapshot_service.abort_restore(); - self.network.stop().unwrap_or_else(|e| warn!("Error stopping network: {:?}", e)); + self.network.stop(); } fn broadcast(&self, message_type: ChainMessageType) { @@ -833,9 +833,7 @@ impl ManageNetwork for LightSync { fn stop_network(&self) { self.proto.abort(); - if let Err(e) = self.network.stop() { - warn!("Error stopping network: {}", e); - } + self.network.stop(); } fn network_config(&self) -> NetworkConfiguration { diff --git a/util/io/src/service_mio.rs b/util/io/src/service_mio.rs index f7c9f1976c..2ae3d55e0f 100644 --- a/util/io/src/service_mio.rs +++ b/util/io/src/service_mio.rs @@ -162,11 +162,13 @@ impl IoContext where Message: Send + Sync + 'static { } /// Unregister current IO handler. - pub fn unregister_handler(&self) -> Result<(), IoError> { - self.channel.send_io(IoMessage::RemoveHandler { + pub fn unregister_handler(&self) { + // `send_io` returns an error only if the channel is closed, which means that the + // background thread is no longer running. Therefore the handler is no longer active and + // can be considered as unregistered. + let _ = self.channel.send_io(IoMessage::RemoveHandler { handler_id: self.handler, - })?; - Ok(()) + }); } } diff --git a/util/network-devp2p/src/host.rs b/util/network-devp2p/src/host.rs index 3ab7b7f849..fbbeb89ff8 100644 --- a/util/network-devp2p/src/host.rs +++ b/util/network-devp2p/src/host.rs @@ -396,7 +396,7 @@ impl Host { format!("{}", Node::new(info.id().clone(), info.local_endpoint.clone())) } - pub fn stop(&self, io: &IoContext) -> Result<(), Error> { + pub fn stop(&self, io: &IoContext) { self.stopping.store(true, AtomicOrdering::Release); let mut to_kill = Vec::new(); for e in self.sessions.read().iter() { @@ -408,8 +408,7 @@ impl Host { trace!(target: "network", "Disconnecting on shutdown: {}", p); self.kill_connection(p, io, true); } - io.unregister_handler()?; - Ok(()) + io.unregister_handler(); } /// Get all connected peers. diff --git a/util/network-devp2p/src/service.rs b/util/network-devp2p/src/service.rs index 3ac1ec7f71..eb2e9685d4 100644 --- a/util/network-devp2p/src/service.rs +++ b/util/network-devp2p/src/service.rs @@ -125,15 +125,14 @@ impl NetworkService { Ok(()) } - /// Stop network IO - pub fn stop(&self) -> Result<(), Error> { + /// Stop network IO. + pub fn stop(&self) { let mut host = self.host.write(); if let Some(ref host) = *host { let io = IoContext::new(self.io_service.channel(), 0); //TODO: take token id from host - host.stop(&io)?; + host.stop(&io); } *host = None; - Ok(()) } /// Get a list of all connected peers by id. diff --git a/util/network-devp2p/tests/tests.rs b/util/network-devp2p/tests/tests.rs index e8c8eddde4..a1d178d654 100644 --- a/util/network-devp2p/tests/tests.rs +++ b/util/network-devp2p/tests/tests.rs @@ -112,7 +112,7 @@ fn net_start_stop() { let config = NetworkConfiguration::new_local(); let service = NetworkService::new(config, None).unwrap(); service.start().unwrap(); - service.stop().unwrap(); + service.stop(); service.start().unwrap(); } -- GitLab From bd1e3fc606c3bf6337cb5cabcc068a63c4e8a029 Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Tue, 22 May 2018 19:07:27 +0200 Subject: [PATCH 063/152] Allow making direct RPC queries from the C API (#8588) --- parity-clib-example/main.cpp | 17 +++++++++++++++-- parity-clib/parity.h | 16 ++++++++++++++++ parity-clib/src/lib.rs | 31 ++++++++++++++++++++++++++++++ parity/rpc.rs | 2 +- parity/run.rs | 35 ++++++++++++++++++++++++++++++---- rpc/src/v1/types/provenance.rs | 4 ++++ 6 files changed, 98 insertions(+), 7 deletions(-) diff --git a/parity-clib-example/main.cpp b/parity-clib-example/main.cpp index 1fadf1b5b5..becce8598e 100644 --- a/parity-clib-example/main.cpp +++ b/parity-clib-example/main.cpp @@ -1,4 +1,7 @@ #include +#include +#include +#include #include #include @@ -8,8 +11,8 @@ int main() { ParityParams cfg = { 0 }; cfg.on_client_restart_cb = on_restart; - const char* args[] = {"--light"}; - size_t str_lens[] = {7}; + const char* args[] = {"--no-ipc"}; + size_t str_lens[] = {8}; if (parity_config_from_cli(args, str_lens, 1, &cfg.configuration) != 0) { return 1; } @@ -19,6 +22,16 @@ int main() { return 1; } + const char* rpc = "{\"method\":\"parity_versionInfo\",\"params\":[],\"id\":1,\"jsonrpc\":\"2.0\"}"; + size_t out_len = 256; + char* out = (char*)malloc(out_len + 1); + if (parity_rpc(parity, rpc, strlen(rpc), out, &out_len)) { + return 1; + } + out[out_len] = '\0'; + printf("RPC output: %s", out); + free(out); + sleep(5); if (parity != NULL) { parity_destroy(parity); diff --git a/parity-clib/parity.h b/parity-clib/parity.h index b61da8e458..f647395ce9 100644 --- a/parity-clib/parity.h +++ b/parity-clib/parity.h @@ -86,6 +86,22 @@ int parity_start(const ParityParams* params, void** out); /// must not call this function. void parity_destroy(void* parity); +/// Performs an RPC request. +/// +/// Blocks the current thread until the request is finished. You are therefore encouraged to spawn +/// a new thread for each RPC request that requires accessing the blockchain. +/// +/// - `rpc` and `len` must contain the JSON string representing the RPC request. +/// - `out_str` and `out_len` point to a buffer where the output JSON result will be stored. If the +/// buffer is not large enough, the function fails. +/// - `out_len` will receive the final length of the string. +/// - On success, the function returns 0. On failure, it returns 1. +/// +/// **Important**: Keep in mind that this function doesn't write any null terminator on the output +/// string. +/// +int parity_rpc(void* parity, const char* rpc, size_t len, char* out_str, size_t* out_len); + #ifdef __cplusplus } #endif diff --git a/parity-clib/src/lib.rs b/parity-clib/src/lib.rs index b08d6487d1..fe631ce8a8 100644 --- a/parity-clib/src/lib.rs +++ b/parity-clib/src/lib.rs @@ -23,6 +23,7 @@ use std::os::raw::{c_char, c_void, c_int}; use std::panic; use std::ptr; use std::slice; +use std::str; #[repr(C)] pub struct ParityParams { @@ -131,3 +132,33 @@ pub extern fn parity_destroy(client: *mut c_void) { }); } } + +#[no_mangle] +pub extern fn parity_rpc(client: *mut c_void, query: *const char, len: usize, out_str: *mut c_char, out_len: *mut usize) -> c_int { + unsafe { + panic::catch_unwind(|| { + let client: &mut parity::RunningClient = &mut *(client as *mut parity::RunningClient); + + let query_str = { + let string = slice::from_raw_parts(query as *const u8, len); + match str::from_utf8(string) { + Ok(a) => a, + Err(_) => return 1, + } + }; + + if let Some(output) = client.rpc_query_sync(query_str) { + let q_out_len = output.as_bytes().len(); + if *out_len < q_out_len { + return 1; + } + + ptr::copy_nonoverlapping(output.as_bytes().as_ptr(), out_str as *mut u8, q_out_len); + *out_len = q_out_len; + 0 + } else { + 1 + } + }).unwrap_or(1) + } +} diff --git a/parity/rpc.rs b/parity/rpc.rs index 66a2715d42..21bc9a4096 100644 --- a/parity/rpc.rs +++ b/parity/rpc.rs @@ -355,7 +355,7 @@ fn with_domain(items: Option>, domain: &str, ui_address: &Option(apis: ApiSet, deps: &Dependencies) -> MetaIoHandler> +pub fn setup_apis(apis: ApiSet, deps: &Dependencies) -> MetaIoHandler> where D: rpc_apis::Dependencies { let mut handler = MetaIoHandler::with_middleware( diff --git a/parity/run.rs b/parity/run.rs index 73113055bb..fd16085c46 100644 --- a/parity/run.rs +++ b/parity/run.rs @@ -41,7 +41,7 @@ use miner::external::ExternalMiner; use node_filter::NodeFilter; use node_health; use parity_reactor::EventLoop; -use parity_rpc::{NetworkSettings, informant, is_major_importing}; +use parity_rpc::{Origin, Metadata, NetworkSettings, informant, is_major_importing}; use updater::{UpdatePolicy, Updater}; use parity_version::version; use ethcore_private_tx::{ProviderConfig, EncryptorConfig, SecretStoreEncryptor}; @@ -56,6 +56,7 @@ use cache::CacheConfig; use user_defaults::UserDefaults; use dapps; use ipfs; +use jsonrpc_core; use modules; use rpc; use rpc_apis; @@ -369,6 +370,7 @@ fn execute_light_impl(cmd: RunCmd, logger: Arc) -> Result) -> Result(cmd: RunCmd, logger: Arc, on_client_rq: }; // start rpc servers + let rpc_direct = rpc::setup_apis(rpc_apis::ApiSet::All, &dependencies); let ws_server = rpc::new_ws(cmd.ws_conf.clone(), &dependencies)?; let ipc_server = rpc::new_ipc(cmd.ipc_conf, &dependencies)?; let http_server = rpc::new_http("HTTP JSON-RPC", "jsonrpc", cmd.http_conf.clone(), &dependencies, dapps_middleware)?; @@ -878,6 +882,7 @@ fn execute_impl(cmd: RunCmd, logger: Arc, on_client_rq: Ok(RunningClient { inner: RunningClientInner::Full { + rpc: rpc_direct, informant, client, keep_alive: Box::new((watcher, service, updater, ws_server, http_server, ipc_server, ui_server, secretstore_key_server, ipfs_server, event_loop)), @@ -890,16 +895,18 @@ fn execute_impl(cmd: RunCmd, logger: Arc, on_client_rq: /// Should be destroyed by calling `shutdown()`, otherwise execution will continue in the /// background. pub struct RunningClient { - inner: RunningClientInner + inner: RunningClientInner, } enum RunningClientInner { Light { + rpc: jsonrpc_core::MetaIoHandler>, informant: Arc>, client: Arc, keep_alive: Box, }, Full { + rpc: jsonrpc_core::MetaIoHandler>, informant: Arc>, client: Arc, keep_alive: Box, @@ -907,25 +914,45 @@ enum RunningClientInner { } impl RunningClient { + /// Performs a synchronous RPC query. + /// Blocks execution until the result is ready. + pub fn rpc_query_sync(&self, request: &str) -> Option { + let metadata = Metadata { + origin: Origin::CApi, + session: None, + }; + + match self.inner { + RunningClientInner::Light { ref rpc, .. } => { + rpc.handle_request_sync(request, metadata) + }, + RunningClientInner::Full { ref rpc, .. } => { + rpc.handle_request_sync(request, metadata) + }, + } + } + /// Shuts down the client. pub fn shutdown(self) { match self.inner { - RunningClientInner::Light { informant, client, keep_alive } => { + RunningClientInner::Light { rpc, informant, client, keep_alive } => { // Create a weak reference to the client so that we can wait on shutdown // until it is dropped let weak_client = Arc::downgrade(&client); + drop(rpc); drop(keep_alive); informant.shutdown(); drop(informant); drop(client); wait_for_drop(weak_client); }, - RunningClientInner::Full { informant, client, keep_alive } => { + RunningClientInner::Full { rpc, informant, client, keep_alive } => { info!("Finishing work, please wait..."); // Create a weak reference to the client so that we can wait on shutdown // until it is dropped let weak_client = Arc::downgrade(&client); // drop this stuff as soon as exit detected. + drop(rpc); drop(keep_alive); // to make sure timer does not spawn requests while shutdown is in progress informant.shutdown(); diff --git a/rpc/src/v1/types/provenance.rs b/rpc/src/v1/types/provenance.rs index b52f0cb774..6bcd43a21f 100644 --- a/rpc/src/v1/types/provenance.rs +++ b/rpc/src/v1/types/provenance.rs @@ -49,6 +49,9 @@ pub enum Origin { /// Session id session: H256 }, + /// From the C API + #[serde(rename="c-api")] + CApi, /// Unknown #[serde(rename="unknown")] Unknown, @@ -68,6 +71,7 @@ impl fmt::Display for Origin { Origin::Ipc(ref session) => write!(f, "IPC (session: {})", session), Origin::Ws { ref session, ref dapp } => write!(f, "{} via WebSocket (session: {})", dapp, session), Origin::Signer { ref session, ref dapp } => write!(f, "{} via UI (session: {})", dapp, session), + Origin::CApi => write!(f, "C API"), Origin::Unknown => write!(f, "unknown origin"), } } -- GitLab From db9397890efbc551d8ba70c3887ddcb0f6b0e097 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Wed, 23 May 2018 10:27:45 +0100 Subject: [PATCH 064/152] Fix cli signer (#8682) * Update ethereum-types so `{:#x}` applies 0x prefix --- Cargo.lock | 102 +++++++++++++++++++-------------------- rpc/Cargo.toml | 2 +- rpc/src/v1/types/uint.rs | 8 +-- 3 files changed, 56 insertions(+), 56 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 646bc90645..c0aae6664f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -248,7 +248,7 @@ name = "common-types" version = "0.1.0" dependencies = [ "ethcore-bytes 0.1.0", - "ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "ethjson 0.1.0", "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hash 0.1.2", @@ -385,7 +385,7 @@ name = "dir" version = "0.1.0" dependencies = [ "app_dirs 1.2.1 (git+https://github.com/paritytech/app-dirs-rs)", - "ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "journaldb 0.1.0", ] @@ -457,7 +457,7 @@ version = "5.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)", @@ -530,7 +530,7 @@ dependencies = [ "ethcore-miner 1.12.0", "ethcore-stratum 1.12.0", "ethcore-transaction 0.1.0", - "ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "ethjson 0.1.0", "ethkey 0.3.0", "ethstore 0.2.0", @@ -591,7 +591,7 @@ version = "0.1.0" name = "ethcore-crypto" version = "0.1.0" dependencies = [ - "ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "quick-error 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "ring 0.12.1 (git+https://github.com/paritytech/ring)", "rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", @@ -628,7 +628,7 @@ dependencies = [ "ethcore-io 1.12.0", "ethcore-network 1.12.0", "ethcore-transaction 0.1.0", - "ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", "hashdb 0.1.1", "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -678,7 +678,7 @@ dependencies = [ "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethash 1.12.0", "ethcore-transaction 0.1.0", - "ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "ethkey 0.3.0", "fetch 0.1.0", "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", @@ -706,7 +706,7 @@ dependencies = [ "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore-crypto 0.1.0", "ethcore-io 1.12.0", - "ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "ethkey 0.3.0", "ipnetwork 0.12.7 (registry+https://github.com/rust-lang/crates.io-index)", "rlp 0.2.1", @@ -726,7 +726,7 @@ dependencies = [ "ethcore-io 1.12.0", "ethcore-logger 1.12.0", "ethcore-network 1.12.0", - "ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "ethkey 0.3.0", "igd 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "ipnetwork 0.12.7 (registry+https://github.com/rust-lang/crates.io-index)", @@ -764,7 +764,7 @@ dependencies = [ "ethcore-logger 1.12.0", "ethcore-miner 1.12.0", "ethcore-transaction 0.1.0", - "ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "ethjson 0.1.0", "ethkey 0.3.0", "fetch 0.1.0", @@ -798,7 +798,7 @@ dependencies = [ "ethcore-logger 1.12.0", "ethcore-sync 1.12.0", "ethcore-transaction 0.1.0", - "ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "ethkey 0.3.0", "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", "futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -847,7 +847,7 @@ version = "1.12.0" dependencies = [ "env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore-logger 1.12.0", - "ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core 8.0.1 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.11)", "jsonrpc-macros 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.11)", "jsonrpc-tcp-server 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.11)", @@ -871,7 +871,7 @@ dependencies = [ "ethcore-network-devp2p 1.12.0", "ethcore-private-tx 1.0.0", "ethcore-transaction 0.1.0", - "ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "ethkey 0.3.0", "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "ipnetwork 0.12.7 (registry+https://github.com/rust-lang/crates.io-index)", @@ -895,7 +895,7 @@ dependencies = [ name = "ethcore-transaction" version = "0.1.0" dependencies = [ - "ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "ethjson 0.1.0", "ethkey 0.3.0", "evm 0.1.0", @@ -908,7 +908,7 @@ dependencies = [ [[package]] name = "ethereum-types" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -917,7 +917,7 @@ dependencies = [ "fixed-hash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)", - "uint 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "uint 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -932,7 +932,7 @@ dependencies = [ name = "ethjson" version = "0.1.0" dependencies = [ - "ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)", @@ -947,7 +947,7 @@ dependencies = [ "edit-distance 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "eth-secp256k1 0.5.7 (git+https://github.com/paritytech/rust-secp256k1)", "ethcore-crypto 0.1.0", - "ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "mem 0.1.0", @@ -979,7 +979,7 @@ version = "0.2.0" dependencies = [ "dir 0.1.0", "ethcore-crypto 0.1.0", - "ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "ethkey 0.3.0", "itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1019,7 +1019,7 @@ name = "evm" version = "0.1.0" dependencies = [ "bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hash 0.1.2", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1038,7 +1038,7 @@ dependencies = [ "ethcore 1.12.0", "ethcore-bytes 0.1.0", "ethcore-transaction 0.1.0", - "ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "ethjson 0.1.0", "evm 0.1.0", "panic_hook 0.1.0", @@ -1178,7 +1178,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "hardware-wallet" version = "1.12.0" dependencies = [ - "ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "ethkey 0.3.0", "hidapi 0.3.1 (git+https://github.com/paritytech/hidapi-rs)", "libusb 0.3.0 (git+https://github.com/paritytech/libusb-rs)", @@ -1194,7 +1194,7 @@ name = "hashdb" version = "0.1.1" dependencies = [ "elastic-array 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1342,7 +1342,7 @@ version = "0.1.0" dependencies = [ "ethcore-bytes 0.1.0", "ethcore-logger 1.12.0", - "ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "hashdb 0.1.1", "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hash 0.1.2", @@ -1456,7 +1456,7 @@ dependencies = [ name = "keccak-hash" version = "0.1.2" dependencies = [ - "ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1492,7 +1492,7 @@ name = "kvdb-rocksdb" version = "0.1.0" dependencies = [ "elastic-array 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "interleaved-ordered 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb 0.1.0", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1644,7 +1644,7 @@ name = "memorydb" version = "0.1.1" dependencies = [ "elastic-array 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "hashdb 0.1.1", "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hash 0.1.2", @@ -1807,7 +1807,7 @@ dependencies = [ "ethcore-io 1.12.0", "ethcore-network 1.12.0", "ethcore-network-devp2p 1.12.0", - "ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb-memorydb 0.1.0", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "lru-cache 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1866,7 +1866,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "num-integer 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1978,7 +1978,7 @@ dependencies = [ "ethcore-service 0.1.0", "ethcore-sync 1.12.0", "ethcore-transaction 0.1.0", - "ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "ethkey 0.3.0", "fake-fetch 0.0.1", "fdlimit 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2044,7 +2044,7 @@ dependencies = [ "env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore-bytes 0.1.0", "ethcore-devtools 1.12.0", - "ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "fetch 0.1.0", "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", "futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2109,7 +2109,7 @@ dependencies = [ "ethabi-contract 5.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethabi-derive 5.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore-bytes 0.1.0", - "ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "fake-fetch 0.0.1", "fetch 0.1.0", "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2133,7 +2133,7 @@ dependencies = [ "cid 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore 1.12.0", "ethcore-bytes 0.1.0", - "ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core 8.0.1 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.11)", "jsonrpc-http-server 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.11)", "multihash 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2162,7 +2162,7 @@ dependencies = [ name = "parity-machine" version = "0.1.0" dependencies = [ - "ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2192,7 +2192,7 @@ dependencies = [ "ethcore-private-tx 1.0.0", "ethcore-sync 1.12.0", "ethcore-transaction 0.1.0", - "ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "ethjson 0.1.0", "ethkey 0.3.0", "ethstore 0.2.0", @@ -2331,7 +2331,7 @@ dependencies = [ "ethcore 1.12.0", "ethcore-bytes 0.1.0", "ethcore-sync 1.12.0", - "ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hash 0.1.2", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2376,7 +2376,7 @@ dependencies = [ "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore-crypto 0.1.0", "ethcore-network 1.12.0", - "ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "ethkey 0.3.0", "hex 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core 8.0.1 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.11)", @@ -2438,7 +2438,7 @@ dependencies = [ "elastic-array 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore-bytes 0.1.0", "ethcore-logger 1.12.0", - "ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "hashdb 0.1.1", "keccak-hash 0.1.2", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2494,7 +2494,7 @@ name = "plain_hasher" version = "0.1.0" dependencies = [ "crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2593,7 +2593,7 @@ version = "0.1.0" dependencies = [ "clap 2.29.1 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore-logger 1.12.0", - "ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "ethjson 0.1.0", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2766,7 +2766,7 @@ version = "0.2.1" dependencies = [ "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "elastic-array 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2974,7 +2974,7 @@ name = "shell32-sys" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3444,7 +3444,7 @@ name = "transaction-pool" version = "1.12.0" dependencies = [ "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "trace-time 0.1.0", @@ -3471,7 +3471,7 @@ name = "trie-standardmap" version = "0.1.0" dependencies = [ "ethcore-bytes 0.1.0", - "ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hash 0.1.2", "rlp 0.2.1", ] @@ -3481,7 +3481,7 @@ name = "triehash" version = "0.1.0" dependencies = [ "elastic-array 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hash 0.1.2", "rlp 0.2.1", "trie-standardmap 0.1.0", @@ -3489,7 +3489,7 @@ dependencies = [ [[package]] name = "uint" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3596,7 +3596,7 @@ name = "util-error" version = "0.1.0" dependencies = [ "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb 0.1.0", "rlp 0.2.1", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3628,7 +3628,7 @@ dependencies = [ "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "common-types 0.1.0", "ethcore-bytes 0.1.0", - "ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "ethjson 0.1.0", "keccak-hash 0.1.2", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3647,7 +3647,7 @@ version = "0.1.0" dependencies = [ "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore-logger 1.12.0", - "ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "parity-wasm 0.27.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3847,7 +3847,7 @@ dependencies = [ "checksum ethabi-contract 5.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "210c9e21d164c15b6ef64fe601e0e12a3c84a031d5ef558e38463e53edbd22ed" "checksum ethabi-derive 5.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d2bc7099baa147187aedaecd9fe04a6c0541c82bc43ff317cb6900fe2b983d74" "checksum ethbloom 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1a93a43ce2e9f09071449da36bfa7a1b20b950ee344b6904ff23de493b03b386" -"checksum ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3a3ae691a36ce5d25b433e63128ce5579f4a18457b6a9c849832b2c9e0fec92a" +"checksum ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9c48729b8aea8aedb12cf4cb2e5cef439fdfe2dda4a89e47eeebd15778ef53b6" "checksum ethereum-types-serialize 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4ac59a21a9ce98e188f3dace9eb67a6c4a3c67ec7fbc7218cb827852679dc002" "checksum fdlimit 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b1ee15a7050e5580b3712877157068ea713b245b080ff302ae2ca973cfcd9baa" "checksum fixed-hash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b18d6fd718fb4396e7a9c93ac59ba7143501467ca7a143c145b5555a571d5576" @@ -4045,7 +4045,7 @@ dependencies = [ "checksum toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a7540f4ffc193e0d3c94121edb19b055670d369f77d5804db11ae053a45b6e7e" "checksum transient-hashmap 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "715254c8f0811be1a79ad3ea5e6fa3c8eddec2b03d7f5ba78cf093e56d79c24f" "checksum trezor-sys 1.0.0 (git+https://github.com/paritytech/trezor-sys)" = "" -"checksum uint 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6477b2716357758c176c36719023e1f9726974d762150e4fc0a9c8c75488c343" +"checksum uint 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "38051a96565903d81c9a9210ce11076b2218f3b352926baa1f5f6abbdfce8273" "checksum unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7f4765f83163b74f957c797ad9253caf97f103fb064d3999aea9568d09fc8a33" "checksum unicase 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "284b6d3db520d67fbe88fd778c21510d1b0ba4a551e5d0fbb023d33405f6de8a" "checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" diff --git a/rpc/Cargo.toml b/rpc/Cargo.toml index 731544a55f..8fdb9ed574 100644 --- a/rpc/Cargo.toml +++ b/rpc/Cargo.toml @@ -47,7 +47,7 @@ ethcore-miner = { path = "../miner" } ethcore-private-tx = { path = "../ethcore/private-tx" } ethcore-sync = { path = "../ethcore/sync" } ethcore-transaction = { path = "../ethcore/transaction" } -ethereum-types = "0.3" +ethereum-types = "0.3.2" ethjson = { path = "../json" } ethkey = { path = "../ethkey" } diff --git a/rpc/src/v1/types/uint.rs b/rpc/src/v1/types/uint.rs index e887322dba..4e2a189a63 100644 --- a/rpc/src/v1/types/uint.rs +++ b/rpc/src/v1/types/uint.rs @@ -55,7 +55,7 @@ macro_rules! impl_uint { impl fmt::LowerHex for $name { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{:#x}", self.0) + fmt::LowerHex::fmt(&self.0, f) } } @@ -102,19 +102,19 @@ impl_uint!(U64, u64, 1); impl serde::Serialize for U128 { fn serialize(&self, serializer: S) -> Result where S: serde::Serializer { - serializer.serialize_str(&format!("0x{:x}", self.0)) + serializer.serialize_str(&format!("{:#x}", self)) } } impl serde::Serialize for U256 { fn serialize(&self, serializer: S) -> Result where S: serde::Serializer { - serializer.serialize_str(&format!("0x{:x}", self.0)) + serializer.serialize_str(&format!("{:#x}", self)) } } impl serde::Serialize for U64 { fn serialize(&self, serializer: S) -> Result where S: serde::Serializer { - serializer.serialize_str(&format!("0x{:x}", self.0)) + serializer.serialize_str(&format!("{:#x}", self)) } } -- GitLab From 6563576ae9586288516cb614ae0787cb27a8f9f2 Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Thu, 24 May 2018 04:39:52 +0200 Subject: [PATCH 065/152] Use impl Future in the light client RPC helpers (#8628) --- rpc/src/v1/helpers/light_fetch.rs | 69 +++++++++++++++---------------- rpc/src/v1/impls/eth_pubsub.rs | 2 +- rpc/src/v1/impls/light/eth.rs | 2 +- 3 files changed, 36 insertions(+), 37 deletions(-) diff --git a/rpc/src/v1/helpers/light_fetch.rs b/rpc/src/v1/helpers/light_fetch.rs index d8a157da21..413670d521 100644 --- a/rpc/src/v1/helpers/light_fetch.rs +++ b/rpc/src/v1/helpers/light_fetch.rs @@ -25,7 +25,7 @@ use ethcore::ids::BlockId; use ethcore::filter::Filter as EthcoreFilter; use ethcore::receipt::Receipt; -use jsonrpc_core::{BoxFuture, Result}; +use jsonrpc_core::{Result, Error}; use jsonrpc_core::futures::{future, Future}; use jsonrpc_core::futures::future::Either; use jsonrpc_macros::Trailing; @@ -139,58 +139,57 @@ impl LightFetch { } /// Get a block header from the on demand service or client, or error. - pub fn header(&self, id: BlockId) -> BoxFuture { + pub fn header(&self, id: BlockId) -> impl Future + Send { let mut reqs = Vec::new(); let header_ref = match self.make_header_requests(id, &mut reqs) { Ok(r) => r, - Err(e) => return Box::new(future::err(e)), + Err(e) => return Either::A(future::err(e)), }; - - self.send_requests(reqs, |res| + Either::B(self.send_requests(reqs, |res| extract_header(&res, header_ref) .expect("these responses correspond to requests that header_ref belongs to \ therefore it will not fail; qed") - ) + )) } /// Helper for getting contract code at a given block. - pub fn code(&self, address: Address, id: BlockId) -> BoxFuture> { + pub fn code(&self, address: Address, id: BlockId) -> impl Future, Error = Error> + Send { let mut reqs = Vec::new(); let header_ref = match self.make_header_requests(id, &mut reqs) { Ok(r) => r, - Err(e) => return Box::new(future::err(e)), + Err(e) => return Either::A(future::err(e)), }; reqs.push(request::Account { header: header_ref.clone(), address: address }.into()); let account_idx = reqs.len() - 1; reqs.push(request::Code { header: header_ref, code_hash: Field::back_ref(account_idx, 0) }.into()); - self.send_requests(reqs, |mut res| match res.pop() { + Either::B(self.send_requests(reqs, |mut res| match res.pop() { Some(OnDemandResponse::Code(code)) => code, _ => panic!("responses correspond directly with requests in amount and type; qed"), - }) + })) } /// Helper for getting account info at a given block. /// `None` indicates the account doesn't exist at the given block. - pub fn account(&self, address: Address, id: BlockId) -> BoxFuture> { + pub fn account(&self, address: Address, id: BlockId) -> impl Future, Error = Error> + Send { let mut reqs = Vec::new(); let header_ref = match self.make_header_requests(id, &mut reqs) { Ok(r) => r, - Err(e) => return Box::new(future::err(e)), + Err(e) => return Either::A(future::err(e)), }; reqs.push(request::Account { header: header_ref, address: address }.into()); - self.send_requests(reqs, |mut res|match res.pop() { + Either::B(self.send_requests(reqs, |mut res|match res.pop() { Some(OnDemandResponse::Account(acc)) => acc, _ => panic!("responses correspond directly with requests in amount and type; qed"), - }) + })) } /// Helper for getting proved execution. - pub fn proved_execution(&self, req: CallRequest, num: Trailing) -> BoxFuture { + pub fn proved_execution(&self, req: CallRequest, num: Trailing) -> impl Future + Send { const DEFAULT_GAS_PRICE: u64 = 21_000; // starting gas when gas not provided. const START_GAS: u64 = 50_000; @@ -280,39 +279,39 @@ impl LightFetch { } /// Get a block itself. Fails on unknown block ID. - pub fn block(&self, id: BlockId) -> BoxFuture { + pub fn block(&self, id: BlockId) -> impl Future + Send { let mut reqs = Vec::new(); let header_ref = match self.make_header_requests(id, &mut reqs) { Ok(r) => r, - Err(e) => return Box::new(future::err(e)), + Err(e) => return Either::A(future::err(e)), }; reqs.push(request::Body(header_ref).into()); - self.send_requests(reqs, |mut res| match res.pop() { + Either::B(self.send_requests(reqs, |mut res| match res.pop() { Some(OnDemandResponse::Body(b)) => b, _ => panic!("responses correspond directly with requests in amount and type; qed"), - }) + })) } /// Get the block receipts. Fails on unknown block ID. - pub fn receipts(&self, id: BlockId) -> BoxFuture> { + pub fn receipts(&self, id: BlockId) -> impl Future, Error = Error> + Send { let mut reqs = Vec::new(); let header_ref = match self.make_header_requests(id, &mut reqs) { Ok(r) => r, - Err(e) => return Box::new(future::err(e)), + Err(e) => return Either::A(future::err(e)), }; reqs.push(request::BlockReceipts(header_ref).into()); - self.send_requests(reqs, |mut res| match res.pop() { + Either::B(self.send_requests(reqs, |mut res| match res.pop() { Some(OnDemandResponse::Receipts(b)) => b, _ => panic!("responses correspond directly with requests in amount and type; qed"), - }) + })) } /// Get transaction logs - pub fn logs(&self, filter: EthcoreFilter) -> BoxFuture> { + pub fn logs(&self, filter: EthcoreFilter) -> impl Future, Error = Error> + Send { use std::collections::BTreeMap; use jsonrpc_core::futures::stream::{self, Stream}; @@ -326,9 +325,9 @@ impl LightFetch { }; match (block_number(filter.to_block), block_number(filter.from_block)) { - (Some(to), Some(from)) if to < from => return Box::new(future::ok(Vec::new())), + (Some(to), Some(from)) if to < from => return Either::A(future::ok(Vec::new())), (Some(_), Some(_)) => {}, - _ => return Box::new(future::err(errors::unknown_block())), + _ => return Either::A(future::err(errors::unknown_block())), } let maybe_future = self.sync.with_context(move |ctx| { @@ -362,15 +361,15 @@ impl LightFetch { }); match maybe_future { - Some(fut) => Box::new(fut), - None => Box::new(future::err(errors::network_disabled())), + Some(fut) => Either::B(Either::A(fut)), + None => Either::B(Either::B(future::err(errors::network_disabled()))), } } // Get a transaction by hash. also returns the index in the block. // Only returns transactions in the canonical chain. pub fn transaction_by_hash(&self, tx_hash: H256, eip86_transition: u64) - -> BoxFuture> + -> impl Future, Error = Error> + Send { let params = (self.sync.clone(), self.on_demand.clone()); let fetcher: Self = self.clone(); @@ -426,7 +425,7 @@ impl LightFetch { })) } - fn send_requests(&self, reqs: Vec, parse_response: F) -> BoxFuture where + fn send_requests(&self, reqs: Vec, parse_response: F) -> impl Future + Send where F: FnOnce(Vec) -> T + Send + 'static, T: Send + 'static, { @@ -439,7 +438,7 @@ impl LightFetch { match maybe_future { Some(recv) => recv, - None => Box::new(future::err(errors::network_disabled())) + None => Box::new(future::err(errors::network_disabled())) as Box + Send> } } } @@ -457,7 +456,7 @@ struct ExecuteParams { // 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 { +fn execute_tx(gas_known: bool, params: ExecuteParams) -> impl Future + Send { if !gas_known { Box::new(future::loop_fn(params, |mut params| { execute_tx(true, params.clone()).and_then(move |res| { @@ -480,7 +479,7 @@ fn execute_tx(gas_known: bool, params: ExecuteParams) -> BoxFuture Ok(future::Loop::Break(failed)), } }) - })) + })) as Box + Send> } else { trace!(target: "light_fetch", "Placing execution request for {} gas in on_demand", params.tx.gas); @@ -501,8 +500,8 @@ fn execute_tx(gas_known: bool, params: ExecuteParams) -> BoxFuture Box::new(fut), - None => Box::new(future::err(errors::network_disabled())), + Some(fut) => Box::new(fut) as Box + Send>, + None => Box::new(future::err(errors::network_disabled())) as Box + Send>, } } } diff --git a/rpc/src/v1/impls/eth_pubsub.rs b/rpc/src/v1/impls/eth_pubsub.rs index 3045959446..c0789910c3 100644 --- a/rpc/src/v1/impls/eth_pubsub.rs +++ b/rpc/src/v1/impls/eth_pubsub.rs @@ -199,7 +199,7 @@ impl LightClient for LightFetch { } fn logs(&self, filter: EthFilter) -> BoxFuture> { - LightFetch::logs(self, filter) + Box::new(LightFetch::logs(self, filter)) as BoxFuture<_> } } diff --git a/rpc/src/v1/impls/light/eth.rs b/rpc/src/v1/impls/light/eth.rs index 35f7792b52..10ad024f24 100644 --- a/rpc/src/v1/impls/light/eth.rs +++ b/rpc/src/v1/impls/light/eth.rs @@ -538,7 +538,7 @@ impl Filterable for EthClient { } fn logs(&self, filter: EthcoreFilter) -> BoxFuture> { - self.fetcher().logs(filter) + Box::new(self.fetcher().logs(filter)) as BoxFuture<_> } fn pending_logs(&self, _block_number: u64, _filter: &EthcoreFilter) -> Vec { -- GitLab From dc8da3743db3855ed86a52a2a36a2826d15917b7 Mon Sep 17 00:00:00 2001 From: Thibaut S <33178835+Tbaut@users.noreply.github.com> Date: Thu, 24 May 2018 10:53:37 +0200 Subject: [PATCH 066/152] Update mod.rs (#8695) - Update interfaces affected by unsafe-expose - replace `{{ }}` as this throws an error in Jekyll (wiki) --- parity/cli/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/parity/cli/mod.rs b/parity/cli/mod.rs index 34e3bf03a1..a064baeac5 100644 --- a/parity/cli/mod.rs +++ b/parity/cli/mod.rs @@ -315,7 +315,7 @@ usage! { ["Convenience options"] FLAG flag_unsafe_expose: (bool) = false, or |c: &Config| c.misc.as_ref()?.unsafe_expose, "--unsafe-expose", - "All servers will listen on external interfaces and will be remotely accessible. It's equivalent with setting the following: --{{ws,jsonrpc,ui,ipfs,secret_store,stratum}}-interface=all --*-hosts=all This option is UNSAFE and should be used with great care!", + "All servers will listen on external interfaces and will be remotely accessible. It's equivalent with setting the following: --[ws,jsonrpc,ui,ipfs-api,secretstore,stratum,dapps,secretstore-http]-interface=all --*-hosts=all This option is UNSAFE and should be used with great care!", ARG arg_config: (String) = "$BASE/config.toml", or |_| None, "-c, --config=[CONFIG]", -- GitLab From e346f3058ef806ae397571beef5901f8723116d9 Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Thu, 24 May 2018 13:06:48 +0200 Subject: [PATCH 067/152] remove empty file (#8705) --- ethstore/tests/cli.rs | 16 ---------------- 1 file changed, 16 deletions(-) delete mode 100644 ethstore/tests/cli.rs diff --git a/ethstore/tests/cli.rs b/ethstore/tests/cli.rs deleted file mode 100644 index f90ec463dc..0000000000 --- a/ethstore/tests/cli.rs +++ /dev/null @@ -1,16 +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 . - -- GitLab From 6c24d9897ae63d2fb8f9d132b95fda2871e27ff2 Mon Sep 17 00:00:00 2001 From: David Date: Thu, 24 May 2018 17:29:28 +0200 Subject: [PATCH 068/152] Set the request index to that of the current request (#8683) * Set the request index to that of the current request When setting up the chain of (two) requests to look up a block by hash, the second need to refer to the first. This fixes an issue where the back ref was set to the subsequent request, not the current one. When the requests are executed we loop through them in order and ensure the requests that should produce headers all match up. We do this by index so they better be right. In other words: off by one. --- rpc/src/v1/helpers/light_fetch.rs | 3 +-- rpc/src/v1/tests/eth.rs | 12 ++++++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/rpc/src/v1/helpers/light_fetch.rs b/rpc/src/v1/helpers/light_fetch.rs index 413670d521..1baf9a7647 100644 --- a/rpc/src/v1/helpers/light_fetch.rs +++ b/rpc/src/v1/helpers/light_fetch.rs @@ -129,9 +129,8 @@ impl LightFetch { } } BlockId::Hash(h) => { - reqs.push(request::HeaderByHash(h.into()).into()); - let idx = reqs.len(); + reqs.push(request::HeaderByHash(h.into()).into()); Ok(HeaderRef::Unresolved(idx, h.into())) } _ => Err(errors::unknown_block()) // latest, earliest, and pending will have all already returned. diff --git a/rpc/src/v1/tests/eth.rs b/rpc/src/v1/tests/eth.rs index 4b83710bc0..26117471ce 100644 --- a/rpc/src/v1/tests/eth.rs +++ b/rpc/src/v1/tests/eth.rs @@ -204,6 +204,18 @@ fn eth_get_block() { assert_eq!(tester.handler.handle_request_sync(req_block).unwrap(), res_block); } +#[test] +fn eth_get_block_by_hash() { + let chain = extract_chain!("BlockchainTests/bcGasPricerTest/RPC_API_Test"); + let tester = EthTester::from_chain(&chain); + + // We're looking for block number 4 from "RPC_API_Test_Frontier" + let req_block = r#"{"method":"eth_getBlockByHash","params":["0x9c9bdab4cb53fd834e790b13545597f026494d42112e84c0aca9dd6bcc545295",false],"id":1,"jsonrpc":"2.0"}"#; + + let res_block = r#"{"jsonrpc":"2.0","result":{"author":"0x8888f1f195afa192cfee860698584c030f4c9db1","difficulty":"0x200c0","extraData":"0x","gasLimit":"0x1dd8112","gasUsed":"0x5458","hash":"0x9c9bdab4cb53fd834e790b13545597f026494d42112e84c0aca9dd6bcc545295","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","miner":"0x8888f1f195afa192cfee860698584c030f4c9db1","mixHash":"0xaddea8d25bb0f955fa6c1d58d74ab8a3fec99d37943e2a261e3b12f97d6bff7c","nonce":"0x8e18bed16d5a88da","number":"0x4","parentHash":"0x2cbf4fc930c5b4c87598f43fc8eb26dccdab2f58a7d0d3ca92ec60a5444a330e","receiptsRoot":"0x7ed8026cf72ed0e98e6fd53ab406e51ffd34397d9da0052494ff41376fda7b5f","sealFields":["0xa0addea8d25bb0f955fa6c1d58d74ab8a3fec99d37943e2a261e3b12f97d6bff7c","0x888e18bed16d5a88da"],"sha3Uncles":"0x75cc08a7cb2cf8081446659fecb2633fb6b922d26edd59bd2272b1f5cae1c78b","size":"0x661","stateRoot":"0x68805721294e365020aca15ed56c360d9dc2cf03cbeff84c9b84b8aed023bfb5","timestamp":"0x59d662ff","totalDifficulty":"0xa0180","transactions":["0xb094b9dc356dbb8b256402c6d5709288066ad6a372c90c9c516f14277545fd58"],"transactionsRoot":"0x97a593d8d7e15b57f5c6bb25bc6c325463ef99f874bc08a78656c3ab5cb23262","uncles":["0xa1e9c9ecd2af999e0723aae1dc55dd9789ca618e0b34badcc8ac7d9a3dad3af2","0x81d429b6b6635214a2b0f976cc4b2ed49808140d6bede50129bc10d22ac9249e"]},"id":1}"#; + assert_eq!(tester.handler.handle_request_sync(req_block).unwrap(), res_block); +} + // a frontier-like test with an expanded gas limit and balance on known account. const TRANSACTION_COUNT_SPEC: &'static [u8] = br#"{ "name": "Frontier (Test)", -- GitLab From 80528c53445ed958ad6164a49ac1cf28e8f52c56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Silva?= Date: Thu, 24 May 2018 19:43:18 +0200 Subject: [PATCH 069/152] parity: trim whitespace when parsing duration strings (#8692) --- parity/helpers.rs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/parity/helpers.rs b/parity/helpers.rs index 80ade50983..a5ec3c99d4 100644 --- a/parity/helpers.rs +++ b/parity/helpers.rs @@ -47,11 +47,11 @@ fn to_seconds(s: &str) -> Result { "1minute" | "1 minute" | "minute" => Ok(60), "hourly" | "1hour" | "1 hour" | "hour" => Ok(60 * 60), "daily" | "1day" | "1 day" | "day" => Ok(24 * 60 * 60), - x if x.ends_with("seconds") => x[0..x.len() - 7].parse().map_err(bad), - x if x.ends_with("minutes") => x[0..x.len() - 7].parse::().map_err(bad).map(|x| x * 60), - x if x.ends_with("hours") => x[0..x.len() - 5].parse::().map_err(bad).map(|x| x * 60 * 60), - x if x.ends_with("days") => x[0..x.len() - 4].parse::().map_err(bad).map(|x| x * 24 * 60 * 60), - x => x.parse().map_err(bad), + x if x.ends_with("seconds") => x[0..x.len() - 7].trim().parse().map_err(bad), + x if x.ends_with("minutes") => x[0..x.len() - 7].trim().parse::().map_err(bad).map(|x| x * 60), + x if x.ends_with("hours") => x[0..x.len() - 5].trim().parse::().map_err(bad).map(|x| x * 60 * 60), + x if x.ends_with("days") => x[0..x.len() - 4].trim().parse::().map_err(bad).map(|x| x * 24 * 60 * 60), + x => x.trim().parse().map_err(bad), } } @@ -350,6 +350,8 @@ mod tests { assert_eq!(to_duration("1day").unwrap(), Duration::from_secs(1 * 24 * 60 * 60)); assert_eq!(to_duration("2days").unwrap(), Duration::from_secs(2 * 24 *60 * 60)); assert_eq!(to_duration("15days").unwrap(), Duration::from_secs(15 * 24 * 60 * 60)); + assert_eq!(to_duration("15 days").unwrap(), Duration::from_secs(15 * 24 * 60 * 60)); + assert_eq!(to_duration("2 seconds").unwrap(), Duration::from_secs(2)); } #[test] -- GitLab From 7d7d4822a5087b24b49f2a1ddb111f2daa51a017 Mon Sep 17 00:00:00 2001 From: Benjamin Kampmann Date: Fri, 25 May 2018 13:19:32 +0200 Subject: [PATCH 070/152] Implement recursive Debug for Nodes in patrica_trie::TrieDB (#8697) fixes #8184 --- util/patricia_trie/src/triedb.rs | 228 ++++++++++++++++++++++--------- 1 file changed, 164 insertions(+), 64 deletions(-) diff --git a/util/patricia_trie/src/triedb.rs b/util/patricia_trie/src/triedb.rs index aed683117d..259525e2ee 100644 --- a/util/patricia_trie/src/triedb.rs +++ b/util/patricia_trie/src/triedb.rs @@ -78,64 +78,9 @@ impl<'db> TrieDB<'db> { /// Get the data of the root node. fn root_data(&self) -> super::Result { - self.db.get(self.root).ok_or_else(|| Box::new(TrieError::InvalidStateRoot(*self.root))) - } - - /// Indentation helper for `format_all`. - fn fmt_indent(&self, f: &mut fmt::Formatter, size: usize) -> fmt::Result { - for _ in 0..size { - write!(f, " ")?; - } - Ok(()) - } - - /// Recursion helper for implementation of formatting trait. - fn fmt_all(&self, node: Node, f: &mut fmt::Formatter, deepness: usize) -> fmt::Result { - match node { - Node::Leaf(slice, value) => writeln!(f, "'{:?}: {:?}.", slice, value.pretty())?, - Node::Extension(ref slice, ref item) => { - write!(f, "'{:?} ", slice)?; - if let Ok(node) = self.get_raw_or_lookup(&*item) { - match Node::decoded(&node) { - Ok(n) => self.fmt_all(n, f, deepness)?, - Err(err) => writeln!(f, "ERROR decoding node extension Rlp: {}", err)?, - } - } - }, - Node::Branch(ref nodes, ref value) => { - writeln!(f, "")?; - if let Some(ref v) = *value { - self.fmt_indent(f, deepness + 1)?; - writeln!(f, "=: {:?}", v.pretty())? - } - for i in 0..16 { - let node = self.get_raw_or_lookup(&*nodes[i]); - match node.as_ref() { - Ok(n) => { - match Node::decoded(&*n) { - Ok(Node::Empty) => {}, - Ok(n) => { - self.fmt_indent(f, deepness + 1)?; - write!(f, "'{:x} ", i)?; - self.fmt_all(n, f, deepness + 1)?; - } - Err(e) => { - write!(f, "ERROR decoding node branch Rlp: {}", e)? - } - } - } - Err(e) => { - write!(f, "ERROR: {}", e)?; - } - } - } - }, - // empty - Node::Empty => { - writeln!(f, "")?; - } - }; - Ok(()) + self.db + .get(self.root) + .ok_or_else(|| Box::new(TrieError::InvalidStateRoot(*self.root))) } /// Given some node-describing data `node`, return the actual node RLP. @@ -174,15 +119,58 @@ impl<'db> Trie for TrieDB<'db> { } } +// This is for pretty debug output only +struct TrieAwareDebugNode<'db, 'a> { + trie: &'db TrieDB<'db>, + key: &'a[u8] +} + +impl<'db, 'a> fmt::Debug for TrieAwareDebugNode<'db, 'a> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + if let Ok(node) = self.trie.get_raw_or_lookup(self.key) { + match Node::decoded(&node) { + Ok(Node::Leaf(slice, value)) => f.debug_struct("Node::Leaf") + .field("slice", &slice) + .field("value", &value) + .finish(), + Ok(Node::Extension(ref slice, ref item)) => f.debug_struct("Node::Extension") + .field("slice", &slice) + .field("item", &TrieAwareDebugNode{trie: self.trie, key: item}) + .finish(), + Ok(Node::Branch(ref nodes, ref value)) => { + let nodes: Vec = nodes.into_iter().map(|n| TrieAwareDebugNode{trie: self.trie, key: n} ).collect(); + f.debug_struct("Node::Branch") + .field("nodes", &nodes) + .field("value", &value) + .finish() + }, + Ok(Node::Empty) => f.debug_struct("Node::Empty").finish(), + + Err(e) => f.debug_struct("BROKEN_NODE") + .field("key", &self.key) + .field("error", &format!("ERROR decoding node branch Rlp: {}", e)) + .finish() + } + } else { + f.debug_struct("BROKEN_NODE") + .field("key", &self.key) + .field("error", &"Not found") + .finish() + } + } +} + + impl<'db> fmt::Debug for TrieDB<'db> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - writeln!(f, "c={:?} [", self.hash_count)?; let root_rlp = self.db.get(self.root).expect("Trie root not found!"); - match Node::decoded(&root_rlp) { - Ok(node) => self.fmt_all(node, f, 0)?, - Err(e) => writeln!(f, "ERROR decoding node rlp: {}", e)?, - } - writeln!(f, "]") + f.debug_struct("TrieDB") + .field("hash_count", &self.hash_count) + .field("root", &TrieAwareDebugNode { + trie: self, + key: &root_rlp + }) + .finish() } } @@ -494,6 +482,118 @@ fn get_len() { assert_eq!(t.get_with(b"C", |x: &[u8]| x.len()), Ok(None)); } + +#[test] +fn debug_output_supports_pretty_print() { + use memorydb::*; + use super::TrieMut; + use super::triedbmut::*; + + let d = vec![ DBValue::from_slice(b"A"), DBValue::from_slice(b"AA"), DBValue::from_slice(b"AB"), DBValue::from_slice(b"B") ]; + + let mut memdb = MemoryDB::new(); + let mut root = H256::new(); + let root = { + let mut t = TrieDBMut::new(&mut memdb, &mut root); + for x in &d { + t.insert(x, x).unwrap(); + } + t.root().clone() + }; + let t = TrieDB::new(&memdb, &root).unwrap(); + + assert_eq!(format!("{:?}", t), "TrieDB { hash_count: 0, root: Node::Extension { slice: 4, item: Node::Branch { nodes: [Node::Empty, Node::Branch { nodes: [Node::Empty, Node::Empty, Node::Empty, Node::Empty, Node::Branch { nodes: [Node::Empty, Node::Leaf { slice: , value: [65, 65] }, Node::Leaf { slice: , value: [65, 66] }, Node::Empty, Node::Empty, Node::Empty, Node::Empty, Node::Empty, Node::Empty, Node::Empty, Node::Empty, Node::Empty, Node::Empty, Node::Empty, Node::Empty, Node::Empty], value: None }, Node::Empty, Node::Empty, Node::Empty, Node::Empty, Node::Empty, Node::Empty, Node::Empty, Node::Empty, Node::Empty, Node::Empty, Node::Empty], value: Some([65]) }, Node::Leaf { slice: , value: [66] }, Node::Empty, Node::Empty, Node::Empty, Node::Empty, Node::Empty, Node::Empty, Node::Empty, Node::Empty, Node::Empty, Node::Empty, Node::Empty, Node::Empty, Node::Empty], value: None } } }"); + assert_eq!(format!("{:#?}", t), +"TrieDB { + hash_count: 0, + root: Node::Extension { + slice: 4, + item: Node::Branch { + nodes: [ + Node::Empty, + Node::Branch { + nodes: [ + Node::Empty, + Node::Empty, + Node::Empty, + Node::Empty, + Node::Branch { + nodes: [ + Node::Empty, + Node::Leaf { + slice: , + value: [ + 65, + 65 + ] + }, + Node::Leaf { + slice: , + value: [ + 65, + 66 + ] + }, + Node::Empty, + Node::Empty, + Node::Empty, + Node::Empty, + Node::Empty, + Node::Empty, + Node::Empty, + Node::Empty, + Node::Empty, + Node::Empty, + Node::Empty, + Node::Empty, + Node::Empty + ], + value: None + }, + Node::Empty, + Node::Empty, + Node::Empty, + Node::Empty, + Node::Empty, + Node::Empty, + Node::Empty, + Node::Empty, + Node::Empty, + Node::Empty, + Node::Empty + ], + value: Some( + [ + 65 + ] + ) + }, + Node::Leaf { + slice: , + value: [ + 66 + ] + }, + Node::Empty, + Node::Empty, + Node::Empty, + Node::Empty, + Node::Empty, + Node::Empty, + Node::Empty, + Node::Empty, + Node::Empty, + Node::Empty, + Node::Empty, + Node::Empty, + Node::Empty + ], + value: None + } + } +}"); +} + // Test will work once https://github.com/paritytech/parity/pull/8527 is merged and rlp::decode returns Result instead of panicking //#[test] //fn test_lookup_with_corrupt_data_returns_decoder_error() { -- GitLab From ed8425b8b907c92ac46a1634e3a4cbda395f934e Mon Sep 17 00:00:00 2001 From: Nicolas Gotchac Date: Mon, 28 May 2018 16:32:29 +0200 Subject: [PATCH 071/152] Remove unused imports (#8722) --- util/network/src/lib.rs | 2 +- util/patricia_trie/src/triedb.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/util/network/src/lib.rs b/util/network/src/lib.rs index f3012e4c37..207a05075d 100644 --- a/util/network/src/lib.rs +++ b/util/network/src/lib.rs @@ -42,7 +42,7 @@ use std::sync::Arc; use std::time::Duration; use ipnetwork::{IpNetwork, IpNetworkError}; use ethkey::Secret; -use ethereum_types::{H256, H512}; +use ethereum_types::H512; use rlp::{Decodable, DecoderError, Rlp}; /// Protocol handler level packet id diff --git a/util/patricia_trie/src/triedb.rs b/util/patricia_trie/src/triedb.rs index 259525e2ee..ed2c19e069 100644 --- a/util/patricia_trie/src/triedb.rs +++ b/util/patricia_trie/src/triedb.rs @@ -21,7 +21,7 @@ use super::node::{Node, OwnedNode}; use super::lookup::Lookup; use super::{Trie, TrieItem, TrieError, TrieIterator, Query}; use ethereum_types::H256; -use bytes::{ToPretty, Bytes}; +use bytes::Bytes; /// A `Trie` implementation using a generic `HashDB` backing database. /// @@ -501,7 +501,7 @@ fn debug_output_supports_pretty_print() { t.root().clone() }; let t = TrieDB::new(&memdb, &root).unwrap(); - + assert_eq!(format!("{:?}", t), "TrieDB { hash_count: 0, root: Node::Extension { slice: 4, item: Node::Branch { nodes: [Node::Empty, Node::Branch { nodes: [Node::Empty, Node::Empty, Node::Empty, Node::Empty, Node::Branch { nodes: [Node::Empty, Node::Leaf { slice: , value: [65, 65] }, Node::Leaf { slice: , value: [65, 66] }, Node::Empty, Node::Empty, Node::Empty, Node::Empty, Node::Empty, Node::Empty, Node::Empty, Node::Empty, Node::Empty, Node::Empty, Node::Empty, Node::Empty, Node::Empty], value: None }, Node::Empty, Node::Empty, Node::Empty, Node::Empty, Node::Empty, Node::Empty, Node::Empty, Node::Empty, Node::Empty, Node::Empty, Node::Empty], value: Some([65]) }, Node::Leaf { slice: , value: [66] }, Node::Empty, Node::Empty, Node::Empty, Node::Empty, Node::Empty, Node::Empty, Node::Empty, Node::Empty, Node::Empty, Node::Empty, Node::Empty, Node::Empty, Node::Empty], value: None } } }"); assert_eq!(format!("{:#?}", t), "TrieDB { -- GitLab From 540044739566a4eaaba82f723eac450388777eb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Mon, 28 May 2018 16:39:26 +0200 Subject: [PATCH 072/152] Update dev chain (#8717) * Make dev chain more foundation-like and enable wasm. * Fix compilation warnings. --- ethcore/res/instant_seal.json | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/ethcore/res/instant_seal.json b/ethcore/res/instant_seal.json index acd1b49ed0..36832e698e 100644 --- a/ethcore/res/instant_seal.json +++ b/ethcore/res/instant_seal.json @@ -10,10 +10,20 @@ "minGasLimit": "0x1388", "networkID" : "0x11", "registrar" : "0x0000000000000000000000000000000000001337", + "eip150Transition": "0x0", + "eip160Transition": "0x0", + "eip161abcTransition": "0x0", + "eip161dTransition": "0x0", + "eip155Transition": "0x0", + "eip98Transition": "0x7fffffffffffff", + "eip86Transition": "0x7fffffffffffff", + "maxCodeSize": 24576, + "maxCodeSizeTransition": "0x0", "eip140Transition": "0x0", "eip211Transition": "0x0", "eip214Transition": "0x0", - "eip658Transition": "0x0" + "eip658Transition": "0x0", + "wasmActivationTransition": "0x0" }, "genesis": { "seal": { -- GitLab From 3b083d545d4f8e39ae6b96eef28f5421775990c1 Mon Sep 17 00:00:00 2001 From: David Date: Mon, 28 May 2018 16:41:08 +0200 Subject: [PATCH 073/152] Add a test for decoding corrupt data (#8713) --- util/patricia_trie/src/triedb.rs | 50 +++++++++++++++----------------- 1 file changed, 24 insertions(+), 26 deletions(-) diff --git a/util/patricia_trie/src/triedb.rs b/util/patricia_trie/src/triedb.rs index ed2c19e069..c18e4fce96 100644 --- a/util/patricia_trie/src/triedb.rs +++ b/util/patricia_trie/src/triedb.rs @@ -594,29 +594,27 @@ fn debug_output_supports_pretty_print() { }"); } -// Test will work once https://github.com/paritytech/parity/pull/8527 is merged and rlp::decode returns Result instead of panicking -//#[test] -//fn test_lookup_with_corrupt_data_returns_decoder_error() { -// use memorydb::*; -// use super::TrieMut; -// use super::triedbmut::*; -// use rlp; -// use ethereum_types::H512; -// -// let mut memdb = MemoryDB::new(); -// let mut root = H256::new(); -// { -// let mut t = TrieDBMut::new(&mut memdb, &mut root); -// t.insert(b"A", b"ABC").unwrap(); -// t.insert(b"B", b"ABCBA").unwrap(); -// } -// -// let t = TrieDB::new(&memdb, &root).unwrap(); -// -// // query for an invalid data type to trigger an error -// let q = rlp::decode::; -// let lookup = Lookup{ db: t.db, query: q, hash: root }; -// let query_result = lookup.look_up(NibbleSlice::new(b"A")); -// let expected = Box::new(TrieError::DecoderError(::rlp::DecoderError::RlpIsTooShort)); -// assert_eq!(query_result.unwrap_err(), expected); -//} +#[test] +fn test_lookup_with_corrupt_data_returns_decoder_error() { + use memorydb::*; + use super::TrieMut; + use super::triedbmut::*; + use rlp; + use ethereum_types::H512; + + let mut memdb = MemoryDB::new(); + let mut root = H256::new(); + { + let mut t = TrieDBMut::new(&mut memdb, &mut root); + t.insert(b"A", b"ABC").unwrap(); + t.insert(b"B", b"ABCBA").unwrap(); + } + + let t = TrieDB::new(&memdb, &root).unwrap(); + + // query for an invalid data type to trigger an error + let q = rlp::decode::; + let lookup = Lookup{ db: t.db, query: q, hash: root }; + let query_result = lookup.look_up(NibbleSlice::new(b"A")); + assert_eq!(query_result.unwrap().unwrap().unwrap_err(), rlp::DecoderError::RlpIsTooShort); +} -- GitLab From ec9c6e9783377ba563bdc720708c2a84dc6d14a7 Mon Sep 17 00:00:00 2001 From: David Date: Mon, 28 May 2018 17:10:29 +0200 Subject: [PATCH 074/152] Fix compilation error on nightly rust (#8707) On nightly rust passing `public_url` works but that breaks on stable. This works for both. --- util/network-devp2p/src/service.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/network-devp2p/src/service.rs b/util/network-devp2p/src/service.rs index eb2e9685d4..1b46ca1ae3 100644 --- a/util/network-devp2p/src/service.rs +++ b/util/network-devp2p/src/service.rs @@ -32,7 +32,7 @@ impl IoHandler for HostHandler { if let NetworkIoMessage::NetworkStarted(ref public_url) = *message { let mut url = self.public_url.write(); if url.as_ref().map_or(true, |uref| uref != public_url) { - info!(target: "network", "Public node URL: {}", Colour::White.bold().paint(public_url.as_ref())); + info!(target: "network", "Public node URL: {}", Colour::White.bold().paint(AsRef::::as_ref(public_url))); } *url = Some(public_url.to_owned()); } -- GitLab From 68d16b723a48ba8d3039b170d109fc3f2ca85b13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Silva?= Date: Tue, 29 May 2018 09:16:08 +0200 Subject: [PATCH 075/152] network-devp2p: handle UselessPeer disconnect (#8686) --- util/network-devp2p/src/host.rs | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/util/network-devp2p/src/host.rs b/util/network-devp2p/src/host.rs index fbbeb89ff8..2f577821a7 100644 --- a/util/network-devp2p/src/host.rs +++ b/util/network-devp2p/src/host.rs @@ -686,14 +686,17 @@ impl Host { Err(e) => { let s = session.lock(); trace!(target: "network", "Session read error: {}:{:?} ({:?}) {:?}", token, s.id(), s.remote_addr(), e); - if let ErrorKind::Disconnect(DisconnectReason::IncompatibleProtocol) = *e.kind() { - if let Some(id) = s.id() { - if !self.reserved_nodes.read().contains(id) { - let mut nodes = self.nodes.write(); - nodes.note_failure(&id); - nodes.mark_as_useless(id); + match *e.kind() { + ErrorKind::Disconnect(DisconnectReason::IncompatibleProtocol) | ErrorKind::Disconnect(DisconnectReason::UselessPeer) => { + if let Some(id) = s.id() { + if !self.reserved_nodes.read().contains(id) { + let mut nodes = self.nodes.write(); + nodes.note_failure(&id); + nodes.mark_as_useless(id); + } } - } + }, + _ => {}, } kill = true; break; -- GitLab From 7fcb082cad648ddec96743b8696d59c8b487ad7c Mon Sep 17 00:00:00 2001 From: Nicolas Gotchac Date: Tue, 29 May 2018 12:23:15 +0200 Subject: [PATCH 076/152] Shutdown the Snapshot Service early (#8658) * Shutdown the Snapshot Service when shutting down the runner * Rename `service` to `client_service` * Fix tests --- ethcore/service/src/service.rs | 7 ++++++- ethcore/src/snapshot/service.rs | 4 ++++ ethcore/src/snapshot/traits.rs | 3 +++ ethcore/sync/src/tests/snapshot.rs | 4 ++++ parity/run.rs | 9 +++++++-- rpc/src/v1/tests/helpers/snapshot_service.rs | 1 + 6 files changed, 25 insertions(+), 3 deletions(-) diff --git a/ethcore/service/src/service.rs b/ethcore/service/src/service.rs index 5f46799796..f703329d61 100644 --- a/ethcore/service/src/service.rs +++ b/ethcore/service/src/service.rs @@ -29,7 +29,7 @@ use sync::PrivateTxHandler; use ethcore::client::{Client, ClientConfig, ChainNotify, ClientIoMessage}; use ethcore::miner::Miner; use ethcore::snapshot::service::{Service as SnapshotService, ServiceParams as SnapServiceParams}; -use ethcore::snapshot::{RestorationStatus}; +use ethcore::snapshot::{SnapshotService as _SnapshotService, RestorationStatus}; use ethcore::spec::Spec; use ethcore::account_provider::AccountProvider; @@ -168,6 +168,11 @@ impl ClientService { /// Get a handle to the database. pub fn db(&self) -> Arc { self.database.clone() } + + /// Shutdown the Client Service + pub fn shutdown(&self) { + self.snapshot.shutdown(); + } } /// IO interface for the Client handler diff --git a/ethcore/src/snapshot/service.rs b/ethcore/src/snapshot/service.rs index 17c362e044..942015d0f1 100644 --- a/ethcore/src/snapshot/service.rs +++ b/ethcore/src/snapshot/service.rs @@ -743,6 +743,10 @@ impl SnapshotService for Service { trace!("Error sending snapshot service message: {:?}", e); } } + + fn shutdown(&self) { + self.abort_restore(); + } } impl Drop for Service { diff --git a/ethcore/src/snapshot/traits.rs b/ethcore/src/snapshot/traits.rs index 2b6ee9df9f..d951f4c534 100644 --- a/ethcore/src/snapshot/traits.rs +++ b/ethcore/src/snapshot/traits.rs @@ -54,4 +54,7 @@ pub trait SnapshotService : Sync + Send { /// Feed a raw block chunk to the service to be processed asynchronously. /// no-op if currently restoring. fn restore_block_chunk(&self, hash: H256, chunk: Bytes); + + /// Shutdown the Snapshot Service by aborting any ongoing restore + fn shutdown(&self); } diff --git a/ethcore/sync/src/tests/snapshot.rs b/ethcore/sync/src/tests/snapshot.rs index 864f3d4dc6..ffb71d7a73 100644 --- a/ethcore/sync/src/tests/snapshot.rs +++ b/ethcore/sync/src/tests/snapshot.rs @@ -133,6 +133,10 @@ impl SnapshotService for TestSnapshotService { self.block_restoration_chunks.lock().insert(hash, chunk); } } + + fn shutdown(&self) { + self.abort_restore(); + } } #[test] diff --git a/parity/run.rs b/parity/run.rs index fd16085c46..31f8779c0f 100644 --- a/parity/run.rs +++ b/parity/run.rs @@ -885,7 +885,8 @@ fn execute_impl(cmd: RunCmd, logger: Arc, on_client_rq: rpc: rpc_direct, informant, client, - keep_alive: Box::new((watcher, service, updater, ws_server, http_server, ipc_server, ui_server, secretstore_key_server, ipfs_server, event_loop)), + client_service: Arc::new(service), + keep_alive: Box::new((watcher, updater, ws_server, http_server, ipc_server, ui_server, secretstore_key_server, ipfs_server, event_loop)), } }) } @@ -909,6 +910,7 @@ enum RunningClientInner { rpc: jsonrpc_core::MetaIoHandler>, informant: Arc>, client: Arc, + client_service: Arc, keep_alive: Box, }, } @@ -946,11 +948,14 @@ impl RunningClient { drop(client); wait_for_drop(weak_client); }, - RunningClientInner::Full { rpc, informant, client, keep_alive } => { + RunningClientInner::Full { rpc, informant, client, client_service, keep_alive } => { info!("Finishing work, please wait..."); // Create a weak reference to the client so that we can wait on shutdown // until it is dropped let weak_client = Arc::downgrade(&client); + // Shutdown and drop the ServiceClient + client_service.shutdown(); + drop(client_service); // drop this stuff as soon as exit detected. drop(rpc); drop(keep_alive); diff --git a/rpc/src/v1/tests/helpers/snapshot_service.rs b/rpc/src/v1/tests/helpers/snapshot_service.rs index 099773ab52..91cd14d73f 100644 --- a/rpc/src/v1/tests/helpers/snapshot_service.rs +++ b/rpc/src/v1/tests/helpers/snapshot_service.rs @@ -50,4 +50,5 @@ impl SnapshotService for TestSnapshotService { fn abort_restore(&self) { } fn restore_state_chunk(&self, _hash: H256, _chunk: Bytes) { } fn restore_block_chunk(&self, _hash: H256, _chunk: Bytes) { } + fn shutdown(&self) { } } -- GitLab From 1620eabd9d0dd368ecd350815083ff6adfdd0459 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Wed, 30 May 2018 11:34:49 +0200 Subject: [PATCH 077/152] Fix local transactions policy. (#8691) --- miner/src/pool/scoring.rs | 33 +++++++++++++++++++++++++++++++++ miner/src/pool/tests/mod.rs | 33 ++++++++++++++++++++++++++++++++- 2 files changed, 65 insertions(+), 1 deletion(-) diff --git a/miner/src/pool/scoring.rs b/miner/src/pool/scoring.rs index eaf0698332..aedc40e1f2 100644 --- a/miner/src/pool/scoring.rs +++ b/miner/src/pool/scoring.rs @@ -107,6 +107,15 @@ impl txpool::Scoring for NonceAndGasPrice { } } + // Always kick out non-local transactions in favour of local ones. + if new.priority().is_local() && !old.priority().is_local() { + return true; + } + // And never kick out local transactions in favour of external ones. + if !new.priority().is_local() && old.priority.is_local() { + return false; + } + self.choose(old, new) == txpool::scoring::Choice::ReplaceOld } } @@ -119,6 +128,30 @@ mod tests { use pool::tests::tx::{Tx, TxExt}; use txpool::Scoring; + #[test] + fn should_replace_non_local_transaction_with_local_one() { + // given + let scoring = NonceAndGasPrice(PrioritizationStrategy::GasPriceOnly); + let tx1 = { + let tx = Tx::default().signed().verified(); + txpool::Transaction { + insertion_id: 0, + transaction: Arc::new(tx), + } + }; + let tx2 = { + let mut tx = Tx::default().signed().verified(); + tx.priority = ::pool::Priority::Local; + txpool::Transaction { + insertion_id: 0, + transaction: Arc::new(tx), + } + }; + + assert!(scoring.should_replace(&tx1, &tx2)); + assert!(!scoring.should_replace(&tx2, &tx1)); + } + #[test] fn should_calculate_score_correctly() { // given diff --git a/miner/src/pool/tests/mod.rs b/miner/src/pool/tests/mod.rs index 5d80c2d5bf..85dedaaa45 100644 --- a/miner/src/pool/tests/mod.rs +++ b/miner/src/pool/tests/mod.rs @@ -766,4 +766,35 @@ fn should_reject_big_transaction() { verifier::Transaction::Local(PendingTransaction::new(big_tx, transaction::Condition::Timestamp(1000).into())) ]); assert_eq!(res, vec![Err(transaction::Error::TooBig)]); -} \ No newline at end of file +} + +#[test] +fn should_include_local_transaction_to_a_full_pool() { + // given + let txq = TransactionQueue::new( + txpool::Options { + max_count: 1, + max_per_sender: 2, + max_mem_usage: 50 + }, + verifier::Options { + minimal_gas_price: 1.into(), + block_gas_limit: 1_000_000.into(), + tx_gas_limit: 1_000_000.into(), + }, + PrioritizationStrategy::GasPriceOnly, + ); + let tx1 = Tx::gas_price(10_000).signed().unverified(); + let tx2 = Tx::gas_price(1).signed().local(); + + let res = txq.import(TestClient::new().with_balance(1_000_000_000), vec![tx1]); + assert_eq!(res, vec![Ok(())]); + assert_eq!(txq.status().status.transaction_count, 1); + + // when + let res = txq.import(TestClient::new(), vec![tx2]); + assert_eq!(res, vec![Ok(())]); + + // then + assert_eq!(txq.status().status.transaction_count, 1); +} -- GitLab From 93054ef24b590a8d854cd6b2d1de6567667d39da Mon Sep 17 00:00:00 2001 From: Andronik Ordian Date: Wed, 30 May 2018 16:42:37 +0300 Subject: [PATCH 078/152] Add a deadlock detection thread (#8727) * Add a deadlock detection thread Expose it under a feature flag: `cargo build --features "deadlock_detection"` * Address Nicklas's comments --- Cargo.lock | 36 ++++++++++++++++++++++++++++++++++++ Cargo.toml | 1 + parity/lib.rs | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 69 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index c0aae6664f..c8e60dce69 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1092,6 +1092,11 @@ dependencies = [ "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "fixedbitset" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "flate2" version = "1.0.1" @@ -1939,6 +1944,11 @@ dependencies = [ "unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "ordermap" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "owning_ref" version = "0.3.3" @@ -2420,10 +2430,13 @@ name = "parking_lot_core" version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ + "backtrace 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "petgraph 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "thread-id 3.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2454,6 +2467,15 @@ name = "percent-encoding" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "petgraph" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "fixedbitset 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "ordermap 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "phf" version = "0.7.21" @@ -3183,6 +3205,16 @@ dependencies = [ "unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "thread-id" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "thread_local" version = "0.3.4" @@ -3851,6 +3883,7 @@ dependencies = [ "checksum ethereum-types-serialize 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4ac59a21a9ce98e188f3dace9eb67a6c4a3c67ec7fbc7218cb827852679dc002" "checksum fdlimit 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b1ee15a7050e5580b3712877157068ea713b245b080ff302ae2ca973cfcd9baa" "checksum fixed-hash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b18d6fd718fb4396e7a9c93ac59ba7143501467ca7a143c145b5555a571d5576" +"checksum fixedbitset 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "86d4de0081402f5e88cdac65c8dcdcc73118c1a7a465e2a05f0da05843a8ea33" "checksum flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9fac2277e84e5e858483756647a9d0aa8d9a2b7cba517fd84325a0aaa69a0909" "checksum fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6cc484842f1e2884faf56f529f960cc12ad8c71ce96cc7abba0a067c98fee344" "checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" @@ -3931,6 +3964,7 @@ dependencies = [ "checksum ole32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5d2c49021782e5233cd243168edfa8037574afed4eba4bbaf538b3d8d1789d8c" "checksum order-stat 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "efa535d5117d3661134dbf1719b6f0ffe06f2375843b13935db186cd094105eb" "checksum ordered-float 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "58d25b6c0e47b20d05226d288ff434940296e7e2f8b877975da32f862152241f" +"checksum ordermap 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a86ed3f5f244b372d6b1a00b72ef7f8876d0bc6a78a4c9985c53614041512063" "checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37" "checksum parity-dapps-glue 1.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "261c025c67ba416e9fe63aa9b3236520ce3c74cfbe43590c9cdcec4ccc8180e4" "checksum parity-tokio-ipc 0.1.5 (git+https://github.com/nikvolf/parity-tokio-ipc)" = "" @@ -3943,6 +3977,7 @@ dependencies = [ "checksum parking_lot 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "9fd9d732f2de194336fb02fe11f9eed13d9e76f13f4315b4d88a14ca411750cd" "checksum parking_lot_core 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "4f610cb9664da38e417ea3225f23051f589851999535290e077939838ab7a595" "checksum percent-encoding 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de154f638187706bde41d9b4738748933d64e6b37bdbffc0b47a97d16a6ae356" +"checksum petgraph 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "8b30dc85588cd02b9b76f5e386535db546d21dc68506cff2abebee0b6445e8e4" "checksum phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "cb325642290f28ee14d8c6201159949a872f220c62af6e110a56ea914fbe42fc" "checksum phf_codegen 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "d62594c0bb54c464f633175d502038177e90309daf2e0158be42ed5f023ce88f" "checksum phf_generator 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "6b07ffcc532ccc85e3afc45865469bf5d9e4ef5bfcf9622e3cfe80c2d275ec03" @@ -4021,6 +4056,7 @@ dependencies = [ "checksum term_size 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9e5b9a66db815dcfd2da92db471106457082577c3c278d4138ab3e3b4e189327" "checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096" "checksum textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c0b59b6b4b44d867f1370ef1bd91bfb262bf07bf0ae65c202ea2fbc16153b693" +"checksum thread-id 3.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c7fbf4c9d56b320106cd64fd024dadfa0be7cb4706725fc44a7d7ce952d820c1" "checksum thread_local 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1697c4b57aeeb7a536b647165a2825faddffb1d3bad386d507709bd51a90bb14" "checksum threadpool 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e2f0c90a5f3459330ac8bc0d2f879c693bb7a2f59689c1083fc4ef83834da865" "checksum time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)" = "d5d788d3aa77bc0ef3e9621256885555368b47bd495c13dd2e7413c89f845520" diff --git a/Cargo.toml b/Cargo.toml index de1a78bf4f..24649eff45 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -106,6 +106,7 @@ evm-debug-tests = ["ethcore/evm-debug-tests"] slow-blocks = ["ethcore/slow-blocks"] secretstore = ["ethcore-secretstore"] final = ["parity-version/final"] +deadlock_detection = ["parking_lot/deadlock_detection"] [lib] path = "parity/lib.rs" diff --git a/parity/lib.rs b/parity/lib.rs index 4d9d1a2c95..6ef332da65 100644 --- a/parity/lib.rs +++ b/parity/lib.rs @@ -141,6 +141,35 @@ fn print_hash_of(maybe_file: Option) -> Result { } } +#[cfg(feature = "deadlock_detection")] +fn run_deadlock_detection_thread() { + use std::thread; + use std::time::Duration; + use parking_lot::deadlock; + + info!("Starting deadlock detection thread."); + // Create a background thread which checks for deadlocks every 10s + thread::spawn(move || { + loop { + thread::sleep(Duration::from_secs(10)); + let deadlocks = deadlock::check_deadlock(); + if deadlocks.is_empty() { + continue; + } + + warn!("{} {} detected", deadlocks.len(), Style::new().bold().paint("deadlock(s)")); + for (i, threads) in deadlocks.iter().enumerate() { + warn!("{} #{}", Style::new().bold().paint("Deadlock"), i); + for t in threads { + warn!("Thread Id {:#?}", t.thread_id()); + warn!("{:#?}", t.backtrace()); + } + } + } + }); +} + + /// Action that Parity performed when running `start`. pub enum ExecutionAction { /// The execution didn't require starting a node, and thus has finished. @@ -161,6 +190,9 @@ fn execute(command: Execute, on_client_rq: Cr, on_updater_rq: Rr) -> Res // they want let logger = setup_log(&command.logger).expect("Logger is initialized only once; qed"); + #[cfg(feature = "deadlock_detection")] + run_deadlock_detection_thread(); + match command.cmd { Cmd::Run(run_cmd) => { if run_cmd.ui_conf.enabled && !run_cmd.ui_conf.info_page_only { -- GitLab From 686bf443e6bcca085c897806a7f808fc891c655f Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Thu, 31 May 2018 15:06:22 +0800 Subject: [PATCH 079/152] Remove unused function new_pow_test_spec (#8735) --- ethcore/src/spec/spec.rs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/ethcore/src/spec/spec.rs b/ethcore/src/spec/spec.rs index fa25c8894e..98720647d8 100644 --- a/ethcore/src/spec/spec.rs +++ b/ethcore/src/spec/spec.rs @@ -923,11 +923,6 @@ impl Spec { pub fn new_validator_multi() -> Self { load_bundled!("validator_multi") } - - /// Create a new spec for a PoW chain - pub fn new_pow_test_spec() -> Self { - load_bundled!("ethereum/olympic") - } } #[cfg(test)] -- GitLab From 6b9314eaa9df00b36afae4d7e8ab0f3d65e4fecb Mon Sep 17 00:00:00 2001 From: Benjamin Kampmann Date: Thu, 31 May 2018 13:36:47 +0200 Subject: [PATCH 080/152] Add 'interface' option to cli (#8699) Additionally as to the port, the new command line option now allows the user to specify the network interface the P2P-Parity listens, too. With support for 'all' and 'local' like in all other versions of this flag. Default is 'all' (aka ). --- parity/cli/mod.rs | 7 +++++++ parity/configuration.rs | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/parity/cli/mod.rs b/parity/cli/mod.rs index a064baeac5..fea060d593 100644 --- a/parity/cli/mod.rs +++ b/parity/cli/mod.rs @@ -438,6 +438,10 @@ usage! { "--port=[PORT]", "Override the port on which the node should listen.", + ARG arg_interface: (String) = "all", or |c: &Config| c.network.as_ref()?.interface.clone(), + "--interface=[IP]", + "Network interfaces. Valid values are 'all', 'local' or the ip of the interface you want parity to listen to.", + ARG arg_min_peers: (Option) = None, or |c: &Config| c.network.as_ref()?.min_peers.clone(), "--min-peers=[NUM]", "Try to maintain at least NUM peers.", @@ -1119,6 +1123,7 @@ struct Network { warp: Option, warp_barrier: Option, port: Option, + interface: Option, min_peers: Option, max_peers: Option, snapshot_peers: Option, @@ -1567,6 +1572,7 @@ mod tests { // -- Networking Options flag_no_warp: false, arg_port: 30303u16, + arg_interface: "all".into(), arg_min_peers: Some(25u16), arg_max_peers: Some(50u16), arg_max_pending_peers: 64u16, @@ -1823,6 +1829,7 @@ mod tests { warp: Some(false), warp_barrier: None, port: None, + interface: None, min_peers: Some(10), max_peers: Some(20), max_pending_peers: Some(30), diff --git a/parity/configuration.rs b/parity/configuration.rs index 3151621801..6bec636e2c 100644 --- a/parity/configuration.rs +++ b/parity/configuration.rs @@ -767,7 +767,7 @@ impl Configuration { fn net_addresses(&self) -> Result<(SocketAddr, Option), String> { let port = self.args.arg_ports_shift + self.args.arg_port; - let listen_address = SocketAddr::new("0.0.0.0".parse().unwrap(), port); + let listen_address = SocketAddr::new(self.interface(&self.args.arg_interface).parse().unwrap(), port); let public_address = if self.args.arg_nat.starts_with("extip:") { let host = &self.args.arg_nat[6..]; let host = host.parse().map_err(|_| format!("Invalid host given with `--nat extip:{}`", host))?; -- GitLab From 118588ef6ccdfca945fcc5733be3c7a5f857c728 Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Thu, 31 May 2018 13:38:46 +0200 Subject: [PATCH 081/152] Fix some nits using clippy (#8731) * fix some nits using clippy * fix tests --- util/network-devp2p/src/handshake.rs | 10 +++--- util/network-devp2p/src/host.rs | 30 +++++++++--------- util/network-devp2p/src/ip_utils.rs | 42 ++++++++++++------------- util/network-devp2p/src/node_table.rs | 44 +++++++++++++-------------- util/network-devp2p/src/service.rs | 2 +- util/network-devp2p/src/session.rs | 16 +++++----- whisper/cli/src/main.rs | 3 ++ 7 files changed, 75 insertions(+), 72 deletions(-) diff --git a/util/network-devp2p/src/handshake.rs b/util/network-devp2p/src/handshake.rs index 7aef4d4f0d..891dd7c257 100644 --- a/util/network-devp2p/src/handshake.rs +++ b/util/network-devp2p/src/handshake.rs @@ -84,12 +84,12 @@ impl Handshake { /// Create a new handshake object pub fn new(token: StreamToken, id: Option<&NodeId>, socket: TcpStream, nonce: &H256) -> Result { Ok(Handshake { - id: if let Some(id) = id { id.clone()} else { NodeId::new() }, + id: if let Some(id) = id { *id } else { NodeId::new() }, connection: Connection::new(token, socket), originated: false, state: HandshakeState::New, ecdhe: Random.generate()?, - nonce: nonce.clone(), + nonce: *nonce, remote_ephemeral: Public::new(), remote_nonce: H256::new(), remote_version: PROTOCOL_VERSION, @@ -166,7 +166,7 @@ impl Handshake { self.remote_version = remote_version; let shared = *ecdh::agree(host_secret, &self.id)?; let signature = H520::from_slice(sig); - self.remote_ephemeral = recover(&signature.into(), &(&shared ^ &self.remote_nonce))?; + self.remote_ephemeral = recover(&signature.into(), &(shared ^ self.remote_nonce))?; Ok(()) } @@ -189,7 +189,7 @@ impl Handshake { } Err(_) => { // Try to interpret as EIP-8 packet - let total = (((data[0] as u16) << 8 | (data[1] as u16)) as usize) + 2; + let total = ((u16::from(data[0]) << 8 | (u16::from(data[1]))) as usize) + 2; if total < V4_AUTH_PACKET_SIZE { debug!(target: "network", "Wrong EIP8 auth packet size"); return Err(ErrorKind::BadProtocol.into()); @@ -232,7 +232,7 @@ impl Handshake { } Err(_) => { // Try to interpret as EIP-8 packet - let total = (((data[0] as u16) << 8 | (data[1] as u16)) as usize) + 2; + let total = (((u16::from(data[0])) << 8 | (u16::from(data[1]))) as usize) + 2; if total < V4_ACK_PACKET_SIZE { debug!(target: "network", "Wrong EIP8 ack packet size"); return Err(ErrorKind::BadProtocol.into()); diff --git a/util/network-devp2p/src/host.rs b/util/network-devp2p/src/host.rs index 2f577821a7..f9180700fe 100644 --- a/util/network-devp2p/src/host.rs +++ b/util/network-devp2p/src/host.rs @@ -116,11 +116,11 @@ impl<'s> NetworkContext<'s> { ) -> NetworkContext<'s> { let id = session.as_ref().map(|s| s.lock().token()); NetworkContext { - io: io, - protocol: protocol, + io, + protocol, session_id: id, - session: session, - sessions: sessions, + session, + sessions, _reserved_peers: reserved_peers, } } @@ -280,7 +280,7 @@ impl Host { let tcp_listener = TcpListener::bind(&listen_address)?; listen_address = SocketAddr::new(listen_address.ip(), tcp_listener.local_addr()?.port()); debug!(target: "network", "Listening at {:?}", listen_address); - let udp_port = config.udp_port.unwrap_or(listen_address.port()); + let udp_port = config.udp_port.unwrap_or_else(|| listen_address.port()); let local_endpoint = NodeEndpoint { address: listen_address, udp_port: udp_port }; let boot_nodes = config.boot_nodes.clone(); @@ -325,7 +325,7 @@ impl Host { match Node::from_str(id) { Err(e) => { debug!(target: "network", "Could not add node {}: {:?}", id, e); }, Ok(n) => { - let entry = NodeEntry { endpoint: n.endpoint.clone(), id: n.id.clone() }; + let entry = NodeEntry { endpoint: n.endpoint.clone(), id: n.id }; self.nodes.write().add_node(n); if let Some(ref mut discovery) = *self.discovery.lock() { @@ -338,9 +338,9 @@ impl Host { pub fn add_reserved_node(&self, id: &str) -> Result<(), Error> { let n = Node::from_str(id)?; - let entry = NodeEntry { endpoint: n.endpoint.clone(), id: n.id.clone() }; - self.reserved_nodes.write().insert(n.id.clone()); - self.nodes.write().add_node(Node::new(entry.id.clone(), entry.endpoint.clone())); + let entry = NodeEntry { endpoint: n.endpoint.clone(), id: n.id }; + self.reserved_nodes.write().insert(n.id); + self.nodes.write().add_node(Node::new(entry.id, entry.endpoint.clone())); if let Some(ref mut discovery) = *self.discovery.lock() { discovery.add_node(entry); @@ -349,10 +349,10 @@ impl Host { Ok(()) } - pub fn set_non_reserved_mode(&self, mode: NonReservedPeerMode, io: &IoContext) { + pub fn set_non_reserved_mode(&self, mode: &NonReservedPeerMode, io: &IoContext) { let mut info = self.info.write(); - if info.config.non_reserved_mode != mode { + if &info.config.non_reserved_mode != mode { info.config.non_reserved_mode = mode.clone(); drop(info); if let NonReservedPeerMode::Deny = mode { @@ -388,12 +388,12 @@ impl Host { pub fn external_url(&self) -> Option { let info = self.info.read(); - info.public_endpoint.as_ref().map(|e| format!("{}", Node::new(info.id().clone(), e.clone()))) + info.public_endpoint.as_ref().map(|e| format!("{}", Node::new(*info.id(), e.clone()))) } pub fn local_url(&self) -> String { let info = self.info.read(); - format!("{}", Node::new(info.id().clone(), info.local_endpoint.clone())) + format!("{}", Node::new(*info.id(), info.local_endpoint.clone())) } pub fn stop(&self, io: &IoContext) { @@ -554,7 +554,7 @@ impl Host { // iterate over all nodes, reserved ones coming first. // if we are pinned to only reserved nodes, ignore all others. let nodes = reserved_nodes.iter().cloned().chain(if !pin { - self.nodes.read().nodes(allow_ips) + self.nodes.read().nodes(&allow_ips) } else { Vec::new() }); @@ -752,7 +752,7 @@ impl Host { let entry = NodeEntry { id: id, endpoint: endpoint }; let mut nodes = self.nodes.write(); if !nodes.contains(&entry.id) { - nodes.add_node(Node::new(entry.id.clone(), entry.endpoint.clone())); + nodes.add_node(Node::new(entry.id, entry.endpoint.clone())); let mut discovery = self.discovery.lock(); if let Some(ref mut discovery) = *discovery { discovery.add_node(entry); diff --git a/util/network-devp2p/src/ip_utils.rs b/util/network-devp2p/src/ip_utils.rs index 7c3d5c0fd3..3d7d33a066 100644 --- a/util/network-devp2p/src/ip_utils.rs +++ b/util/network-devp2p/src/ip_utils.rs @@ -109,7 +109,7 @@ impl SocketAddrExt for Ipv4Addr { fn is_within(&self, ipnet: &IpNetwork) -> bool { match ipnet { - &IpNetwork::V4(ipnet) => ipnet.contains(*self), + IpNetwork::V4(ipnet) => ipnet.contains(*self), _ => false } } @@ -167,7 +167,7 @@ impl SocketAddrExt for Ipv6Addr { fn is_within(&self, ipnet: &IpNetwork) -> bool { match ipnet { - &IpNetwork::V6(ipnet) => ipnet.contains(*self), + IpNetwork::V6(ipnet) => ipnet.contains(*self), _ => false } } @@ -212,28 +212,28 @@ impl SocketAddrExt for IpAddr { #[cfg(not(any(windows, target_os = "android")))] mod getinterfaces { - use std::{mem, io, ptr}; + use std::{mem, io}; use libc::{AF_INET, AF_INET6}; use libc::{getifaddrs, freeifaddrs, ifaddrs, sockaddr, sockaddr_in, sockaddr_in6}; use std::net::{Ipv4Addr, Ipv6Addr, IpAddr}; fn convert_sockaddr(sa: *mut sockaddr) -> Option { - if sa == ptr::null_mut() { return None; } + if sa.is_null() { return None; } - let (addr, _) = match unsafe { *sa }.sa_family as i32 { + let (addr, _) = match i32::from(unsafe { *sa }.sa_family) { AF_INET => { - let sa: *const sockaddr_in = unsafe { mem::transmute(sa) }; - let sa = & unsafe { *sa }; + let sa: *const sockaddr_in = sa as *const sockaddr_in; + let sa = unsafe { &*sa }; let (addr, port) = (sa.sin_addr.s_addr, sa.sin_port); (IpAddr::V4(Ipv4Addr::new( - (addr & 0x000000FF) as u8, - ((addr & 0x0000FF00) >> 8) as u8, - ((addr & 0x00FF0000) >> 16) as u8, - ((addr & 0xFF000000) >> 24) as u8)), + (addr & 0x0000_00FF) as u8, + ((addr & 0x0000_FF00) >> 8) as u8, + ((addr & 0x00FF_0000) >> 16) as u8, + ((addr & 0xFF00_0000) >> 24) as u8)), port) }, AF_INET6 => { - let sa: *const sockaddr_in6 = unsafe { mem::transmute(sa) }; + let sa: *const sockaddr_in6 = sa as *const sockaddr_in6; let sa = & unsafe { *sa }; let (addr, port) = (sa.sin6_addr.s6_addr, sa.sin6_port); let addr: [u16; 8] = unsafe { mem::transmute(addr) }; @@ -266,7 +266,7 @@ mod getinterfaces { let mut ret = Vec::new(); let mut cur: *mut ifaddrs = ifap; - while cur != ptr::null_mut() { + while !cur.is_null() { if let Some(ip_addr) = convert_ifaddrs(cur) { ret.push(ip_addr); } @@ -297,16 +297,16 @@ pub fn select_public_address(port: u16) -> SocketAddr { //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_reserved() => { - return SocketAddr::V4(SocketAddrV4::new(a, port)); + IpAddr::V4(a) if !a.is_reserved() => { + return SocketAddr::V4(SocketAddrV4::new(*a, port)); }, _ => {}, } } for addr in &list { match addr { - &IpAddr::V6(a) if !a.is_reserved() => { - return SocketAddr::V6(SocketAddrV6::new(a, port, 0, 0)); + IpAddr::V6(a) if !a.is_reserved() => { + return SocketAddr::V6(SocketAddrV6::new(*a, port, 0, 0)); }, _ => {}, } @@ -319,7 +319,7 @@ pub fn select_public_address(port: u16) -> SocketAddr { pub fn map_external_address(local: &NodeEndpoint) -> Option { if let SocketAddr::V4(ref local_addr) = local.address { - match search_gateway_from_timeout(local_addr.ip().clone(), Duration::new(5, 0)) { + match search_gateway_from_timeout(*local_addr.ip(), Duration::new(5, 0)) { Err(ref err) => debug!("Gateway search error: {}", err), Ok(gateway) => { match gateway.get_external_ip() { @@ -327,17 +327,17 @@ pub fn map_external_address(local: &NodeEndpoint) -> Option { debug!("IP request error: {}", err); }, Ok(external_addr) => { - match gateway.add_any_port(PortMappingProtocol::TCP, SocketAddrV4::new(local_addr.ip().clone(), local_addr.port()), 0, "Parity Node/TCP") { + match gateway.add_any_port(PortMappingProtocol::TCP, SocketAddrV4::new(*local_addr.ip(), local_addr.port()), 0, "Parity Node/TCP") { Err(ref err) => { debug!("Port mapping error: {}", err); }, Ok(tcp_port) => { - match gateway.add_any_port(PortMappingProtocol::UDP, SocketAddrV4::new(local_addr.ip().clone(), local.udp_port), 0, "Parity Node/UDP") { + match gateway.add_any_port(PortMappingProtocol::UDP, SocketAddrV4::new(*local_addr.ip(), local.udp_port), 0, "Parity Node/UDP") { Err(ref err) => { debug!("Port mapping error: {}", err); }, Ok(udp_port) => { - return Some(NodeEndpoint { address: SocketAddr::V4(SocketAddrV4::new(external_addr, tcp_port)), udp_port: udp_port }); + return Some(NodeEndpoint { address: SocketAddr::V4(SocketAddrV4::new(external_addr, tcp_port)), udp_port }); }, } }, diff --git a/util/network-devp2p/src/node_table.rs b/util/network-devp2p/src/node_table.rs index 8640901cd0..d5d0207ecd 100644 --- a/util/network-devp2p/src/node_table.rs +++ b/util/network-devp2p/src/node_table.rs @@ -26,7 +26,7 @@ use std::hash::{Hash, Hasher}; use std::net::{SocketAddr, ToSocketAddrs, SocketAddrV4, SocketAddrV6, Ipv4Addr, Ipv6Addr}; use std::path::PathBuf; use std::str::FromStr; -use std::{fs, mem, slice}; +use std::{fs, slice}; use std::time::{self, Duration, SystemTime}; use rand::{self, Rng}; @@ -45,8 +45,8 @@ pub struct NodeEndpoint { impl NodeEndpoint { pub fn udp_address(&self) -> SocketAddr { match self.address { - SocketAddr::V4(a) => SocketAddr::V4(SocketAddrV4::new(a.ip().clone(), self.udp_port)), - SocketAddr::V6(a) => SocketAddr::V6(SocketAddrV6::new(a.ip().clone(), self.udp_port, a.flowinfo(), a.scope_id())), + SocketAddr::V4(a) => SocketAddr::V4(SocketAddrV4::new(*a.ip(), self.udp_port)), + SocketAddr::V6(a) => SocketAddr::V6(SocketAddrV6::new(*a.ip(), self.udp_port, a.flowinfo(), a.scope_id())), } } @@ -61,10 +61,10 @@ impl NodeEndpoint { pub fn is_allowed_by_predefined(&self, filter: &AllowIP) -> bool { match filter { - &AllowIP::All => true, - &AllowIP::Private => self.address.ip().is_usable_private(), - &AllowIP::Public => self.address.ip().is_usable_public(), - &AllowIP::None => false, + AllowIP::All => true, + AllowIP::Private => self.address.ip().is_usable_private(), + AllowIP::Public => self.address.ip().is_usable_public(), + AllowIP::None => false, } } @@ -75,13 +75,13 @@ impl NodeEndpoint { let address = match addr_bytes.len() { 4 => Ok(SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(addr_bytes[0], addr_bytes[1], addr_bytes[2], addr_bytes[3]), tcp_port))), 16 => unsafe { - let o: *const u16 = mem::transmute(addr_bytes.as_ptr()); + let o: *const u16 = addr_bytes.as_ptr() as *const u16; let o = slice::from_raw_parts(o, 8); Ok(SocketAddr::V6(SocketAddrV6::new(Ipv6Addr::new(o[0], o[1], o[2], o[3], o[4], o[5], o[6], o[7]), tcp_port, 0, 0))) }, _ => Err(DecoderError::RlpInconsistentLengthAndData) }?; - Ok(NodeEndpoint { address: address, udp_port: udp_port }) + Ok(NodeEndpoint { address, udp_port }) } pub fn to_rlp(&self, rlp: &mut RlpStream) { @@ -90,7 +90,7 @@ impl NodeEndpoint { rlp.append(&(&a.ip().octets()[..])); } SocketAddr::V6(a) => unsafe { - let o: *const u8 = mem::transmute(a.ip().segments().as_ptr()); + let o: *const u8 = a.ip().segments().as_ptr() as *const u8; rlp.append(&slice::from_raw_parts(o, 16)); } }; @@ -184,8 +184,8 @@ pub struct Node { impl Node { pub fn new(id: NodeId, endpoint: NodeEndpoint) -> Node { Node { - id: id, - endpoint: endpoint, + id, + endpoint, peer_type: PeerType::Optional, last_contact: None, } @@ -214,8 +214,8 @@ impl FromStr for Node { }; Ok(Node { - id: id, - endpoint: endpoint, + id, + endpoint, peer_type: PeerType::Optional, last_contact: None, }) @@ -258,7 +258,7 @@ impl NodeTable { pub fn add_node(&mut self, mut node: Node) { // preserve node last_contact node.last_contact = self.nodes.get(&node.id).and_then(|n| n.last_contact); - self.nodes.insert(node.id.clone(), node); + self.nodes.insert(node.id, node); } /// Returns a list of ordered nodes according to their most recent contact @@ -315,7 +315,7 @@ impl NodeTable { /// Returns node ids sorted by failure percentage, for nodes with the same failure percentage the absolute number of /// failures is considered. - pub fn nodes(&self, filter: IpFilter) -> Vec { + pub fn nodes(&self, filter: &IpFilter) -> Vec { self.ordered_entries().iter() .filter(|n| n.endpoint.is_allowed(&filter)) .map(|n| n.id) @@ -327,7 +327,7 @@ impl NodeTable { pub fn entries(&self) -> Vec { self.ordered_entries().iter().map(|n| NodeEntry { endpoint: n.endpoint.clone(), - id: n.id.clone(), + id: n.id, }).collect() } @@ -344,7 +344,7 @@ impl NodeTable { /// Apply table changes coming from discovery pub fn update(&mut self, mut update: TableUpdates, reserved: &HashSet) { for (_, node) in update.added.drain() { - let entry = self.nodes.entry(node.id.clone()).or_insert_with(|| Node::new(node.id.clone(), node.endpoint.clone())); + let entry = self.nodes.entry(node.id).or_insert_with(|| Node::new(node.id, node.endpoint.clone())); entry.endpoint = node.endpoint; } for r in update.removed { @@ -389,7 +389,7 @@ impl NodeTable { return; } path.push(NODES_FILE); - let node_ids = self.nodes(IpFilter::default()); + let node_ids = self.nodes(&IpFilter::default()); let nodes = node_ids.into_iter() .map(|id| self.nodes.get(&id).expect("self.nodes() only returns node IDs from self.nodes")) .take(MAX_NODES) @@ -428,7 +428,7 @@ impl NodeTable { Ok(table) => { table.nodes.into_iter() .filter_map(|n| n.into_node()) - .map(|n| (n.id.clone(), n)) + .map(|n| (n.id, n)) .collect() }, Err(e) => { @@ -625,7 +625,7 @@ mod tests { // unknown - node 6 - let r = table.nodes(IpFilter::default()); + let r = table.nodes(&IpFilter::default()); assert_eq!(r[0][..], id4[..]); // most recent success assert_eq!(r[1][..], id3[..]); @@ -662,7 +662,7 @@ mod tests { { let table = NodeTable::new(Some(tempdir.path().to_str().unwrap().to_owned())); - let r = table.nodes(IpFilter::default()); + let r = table.nodes(&IpFilter::default()); assert_eq!(r[0][..], id2[..]); // latest success assert_eq!(r[1][..], id1[..]); // unknown assert_eq!(r[2][..], id3[..]); // oldest failure diff --git a/util/network-devp2p/src/service.rs b/util/network-devp2p/src/service.rs index 1b46ca1ae3..d8105f649c 100644 --- a/util/network-devp2p/src/service.rs +++ b/util/network-devp2p/src/service.rs @@ -165,7 +165,7 @@ impl NetworkService { let host = self.host.read(); if let Some(ref host) = *host { let io_ctxt = IoContext::new(self.io_service.channel(), 0); - host.set_non_reserved_mode(mode, &io_ctxt); + host.set_non_reserved_mode(&mode, &io_ctxt); } } diff --git a/util/network-devp2p/src/session.rs b/util/network-devp2p/src/session.rs index 47eb2cf728..cd8ef56bd4 100644 --- a/util/network-devp2p/src/session.rs +++ b/util/network-devp2p/src/session.rs @@ -117,7 +117,7 @@ impl Session { capabilities: Vec::new(), peer_capabilities: Vec::new(), ping: None, - originated: originated, + originated, remote_address: "Handshake".to_owned(), local_address: local_addr, }, @@ -131,7 +131,7 @@ impl Session { fn complete_handshake(&mut self, io: &IoContext, host: &HostInfo) -> Result<(), Error> where Message: Send + Sync + Clone { let connection = if let State::Handshake(ref mut h) = self.state { - self.info.id = Some(h.id.clone()); + self.info.id = Some(h.id); self.info.remote_address = h.connection.remote_addr_str(); EncryptedConnection::new(h)? } else { @@ -204,7 +204,7 @@ impl Session { } } if let Some(data) = packet_data { - return Ok(self.read_packet(io, data, host)?); + return Ok(self.read_packet(io, &data, host)?); } if create_session { self.complete_handshake(io, host)?; @@ -277,7 +277,7 @@ impl Session { None => packet_id }; let mut rlp = RlpStream::new(); - rlp.append(&(pid as u32)); + rlp.append(&(u32::from(pid))); let mut compressed = Vec::new(); let mut payload = data; // create a reference with local lifetime if self.compression { @@ -329,7 +329,7 @@ impl Session { } } - fn read_packet(&mut self, io: &IoContext, packet: Packet, host: &HostInfo) -> Result + fn read_packet(&mut self, io: &IoContext, packet: &Packet, host: &HostInfo) -> Result where Message: Send + Sync + Clone { if packet.data.len() < 2 { return Err(ErrorKind::BadProtocol.into()); @@ -390,7 +390,7 @@ impl Session { match *self.protocol_states.entry(protocol).or_insert_with(|| ProtocolState::Pending(Vec::new())) { ProtocolState::Connected => { trace!(target: "network", "Packet {} mapped to {:?}:{}, i={}, capabilities={:?}", packet_id, protocol, protocol_packet_id, i, self.info.capabilities); - Ok(SessionData::Packet { data: data, protocol: protocol, packet_id: protocol_packet_id } ) + Ok(SessionData::Packet { data, protocol, packet_id: protocol_packet_id } ) } ProtocolState::Pending(ref mut pending) => { trace!(target: "network", "Packet {} deferred until protocol connection event completion", packet_id); @@ -468,11 +468,11 @@ impl Session { self.info.peer_capabilities = peer_caps; if self.info.capabilities.is_empty() { trace!(target: "network", "No common capabilities with peer."); - return Err(From::from(self.disconnect(io, DisconnectReason::UselessPeer))); + return Err(self.disconnect(io, DisconnectReason::UselessPeer)); } if protocol < MIN_PROTOCOL_VERSION { trace!(target: "network", "Peer protocol version mismatch: {}", protocol); - return Err(From::from(self.disconnect(io, DisconnectReason::UselessPeer))); + return Err(self.disconnect(io, DisconnectReason::UselessPeer)); } self.compression = protocol >= MIN_COMPRESSION_PROTOCOL_VERSION; self.send_ping(io)?; diff --git a/whisper/cli/src/main.rs b/whisper/cli/src/main.rs index f245e99e48..d76c216be4 100644 --- a/whisper/cli/src/main.rs +++ b/whisper/cli/src/main.rs @@ -19,6 +19,9 @@ //! Spawns an Ethereum network instance and attaches the Whisper protocol RPCs to it. //! +#![warn(missing_docs)] +#![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))] + extern crate docopt; extern crate ethcore_network_devp2p as devp2p; extern crate ethcore_network as net; -- GitLab From 1020560af632d6359dcf44c43314dc2df78e2b5b Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Thu, 31 May 2018 13:39:25 +0200 Subject: [PATCH 082/152] Remove a couple of unnecessary `transmute()` (#8736) --- ethash/src/compute.rs | 5 ++--- util/plain_hasher/src/lib.rs | 17 +++++++---------- 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/ethash/src/compute.rs b/ethash/src/compute.rs index 48906b9ede..de2b57637f 100644 --- a/ethash/src/compute.rs +++ b/ethash/src/compute.rs @@ -25,9 +25,8 @@ use seed_compute::SeedHashCompute; use shared::*; use std::io; -use std::mem; +use std::{mem, ptr}; use std::path::Path; -use std::ptr; const MIX_WORDS: usize = ETHASH_MIX_BYTES / 4; const MIX_NODES: usize = MIX_WORDS / NODE_WORDS; @@ -111,7 +110,7 @@ pub fn quick_get_difficulty(header_hash: &H256, nonce: u64, mix_hash: &H256) -> let mut buf: [u8; 64 + 32] = mem::uninitialized(); ptr::copy_nonoverlapping(header_hash.as_ptr(), buf.as_mut_ptr(), 32); - ptr::copy_nonoverlapping(mem::transmute(&nonce), buf[32..].as_mut_ptr(), 8); + ptr::copy_nonoverlapping(&nonce as *const u64 as *const u8, buf[32..].as_mut_ptr(), 8); keccak_512::unchecked(buf.as_mut_ptr(), 64, buf.as_ptr(), 40); ptr::copy_nonoverlapping(mix_hash.as_ptr(), buf[64..].as_mut_ptr(), 32); diff --git a/util/plain_hasher/src/lib.rs b/util/plain_hasher/src/lib.rs index 54bad92f47..d08d4dd1ab 100644 --- a/util/plain_hasher/src/lib.rs +++ b/util/plain_hasher/src/lib.rs @@ -2,9 +2,9 @@ extern crate crunchy; extern crate ethereum_types; -use std::{hash, mem}; -use std::collections::{HashMap, HashSet}; use ethereum_types::H256; +use std::collections::{HashMap, HashSet}; +use std::hash; /// Specialized version of `HashMap` with H256 keys and fast hashing function. pub type H256FastMap = HashMap>; @@ -28,16 +28,13 @@ impl hash::Hasher for PlainHasher { #[allow(unused_assignments)] fn write(&mut self, bytes: &[u8]) { debug_assert!(bytes.len() == 32); + let mut bytes_ptr = bytes.as_ptr(); + let mut prefix_ptr = &mut self.prefix as *mut u64 as *mut u8; - unsafe { - let mut bytes_ptr = bytes.as_ptr(); - let prefix_u8: &mut [u8; 8] = mem::transmute(&mut self.prefix); - let mut prefix_ptr = prefix_u8.as_mut_ptr(); - - unroll! { - for _i in 0..8 { + unroll! { + for _i in 0..8 { + unsafe { *prefix_ptr ^= (*bytes_ptr ^ *bytes_ptr.offset(8)) ^ (*bytes_ptr.offset(16) ^ *bytes_ptr.offset(24)); - bytes_ptr = bytes_ptr.offset(1); prefix_ptr = prefix_ptr.offset(1); } -- GitLab From d32ce374847ba4ed09101535dfb66356b3a2ffe9 Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Thu, 31 May 2018 13:53:09 +0200 Subject: [PATCH 083/152] bump tinykeccak to 1.4 (#8728) --- ethcore/crypto/Cargo.toml | 2 +- ethcore/private-tx/Cargo.toml | 2 +- ethkey/Cargo.toml | 2 +- ethstore/Cargo.toml | 2 +- rpc/Cargo.toml | 2 +- secret_store/Cargo.toml | 2 +- util/network-devp2p/Cargo.toml | 2 +- whisper/Cargo.toml | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/ethcore/crypto/Cargo.toml b/ethcore/crypto/Cargo.toml index 4fe023f25c..b57b8497c0 100644 --- a/ethcore/crypto/Cargo.toml +++ b/ethcore/crypto/Cargo.toml @@ -8,5 +8,5 @@ ethereum-types = "0.3" quick-error = "1.2" ring = "0.12" rust-crypto = "0.2.36" -tiny-keccak = "1.3" +tiny-keccak = "1.4" diff --git a/ethcore/private-tx/Cargo.toml b/ethcore/private-tx/Cargo.toml index 0fa11aec84..8283ab314a 100644 --- a/ethcore/private-tx/Cargo.toml +++ b/ethcore/private-tx/Cargo.toml @@ -33,5 +33,5 @@ rustc-hex = "1.0" serde = "1.0" serde_derive = "1.0" serde_json = "1.0" -tiny-keccak = "1.3" +tiny-keccak = "1.4" url = "1" diff --git a/ethkey/Cargo.toml b/ethkey/Cargo.toml index d6698f86d9..952354739d 100644 --- a/ethkey/Cargo.toml +++ b/ethkey/Cargo.toml @@ -16,4 +16,4 @@ parity-wordlist = "1.2" quick-error = "1.2" rand = "0.4" rustc-hex = "1.0" -tiny-keccak = "1.3" +tiny-keccak = "1.4" diff --git a/ethstore/Cargo.toml b/ethstore/Cargo.toml index 6330ce97ce..6108143cb9 100644 --- a/ethstore/Cargo.toml +++ b/ethstore/Cargo.toml @@ -12,7 +12,7 @@ serde = "1.0" serde_json = "1.0" serde_derive = "1.0" rustc-hex = "1.0" -tiny-keccak = "1.3" +tiny-keccak = "1.4" time = "0.1.34" itertools = "0.5" parking_lot = "0.5" diff --git a/rpc/Cargo.toml b/rpc/Cargo.toml index 8fdb9ed574..8a0b689c65 100644 --- a/rpc/Cargo.toml +++ b/rpc/Cargo.toml @@ -23,7 +23,7 @@ serde = "1.0" serde_derive = "1.0" serde_json = "1.0" tempdir = "0.3" -tiny-keccak = "1.3" +tiny-keccak = "1.4" tokio-timer = "0.1" transient-hashmap = "0.4" itertools = "0.5" diff --git a/secret_store/Cargo.toml b/secret_store/Cargo.toml index fee832d069..261658903c 100644 --- a/secret_store/Cargo.toml +++ b/secret_store/Cargo.toml @@ -16,7 +16,7 @@ serde_derive = "1.0" futures = "0.1" futures-cpupool = "0.1" rustc-hex = "1.0" -tiny-keccak = "1.3" +tiny-keccak = "1.4" tokio = "0.1" tokio-core = "0.1" tokio-io = "0.1" diff --git a/util/network-devp2p/Cargo.toml b/util/network-devp2p/Cargo.toml index f4889fe26d..4a5d2d942e 100644 --- a/util/network-devp2p/Cargo.toml +++ b/util/network-devp2p/Cargo.toml @@ -11,7 +11,7 @@ log = "0.3" mio = "0.6.8" bytes = "0.4" rand = "0.4" -tiny-keccak = "1.3" +tiny-keccak = "1.4" rust-crypto = "0.2.34" slab = "0.2" igd = "0.7" diff --git a/whisper/Cargo.toml b/whisper/Cargo.toml index ed370e38a2..e503a74fd6 100644 --- a/whisper/Cargo.toml +++ b/whisper/Cargo.toml @@ -23,7 +23,7 @@ serde_derive = "1.0" serde_json = "1.0" slab = "0.3" smallvec = "0.4" -tiny-keccak = "1.3" +tiny-keccak = "1.4" jsonrpc-core = { git = "https://github.com/paritytech/jsonrpc.git", branch = "parity-1.11" } jsonrpc-macros = { git = "https://github.com/paritytech/jsonrpc.git", branch = "parity-1.11" } -- GitLab From 9053c0dfd9449ca8a83bac7964cd9d336e6d9f94 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Thu, 31 May 2018 15:07:35 +0300 Subject: [PATCH 084/152] ease tiny-keccak version requirements (1.4.1 -> 1.4) (#8726) --- util/hash/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/hash/Cargo.toml b/util/hash/Cargo.toml index e136ada305..4ca503751a 100644 --- a/util/hash/Cargo.toml +++ b/util/hash/Cargo.toml @@ -9,7 +9,7 @@ authors = ["Parity Technologies "] [dependencies] ethereum-types = "0.3" -tiny-keccak = "1.4.1" +tiny-keccak = "1.4" [dev-dependencies] tempdir = "0.3" -- GitLab From 581e510c2d91cfa9008ebf0de93fb4a42be3bd80 Mon Sep 17 00:00:00 2001 From: vrde Date: Thu, 31 May 2018 14:43:06 +0200 Subject: [PATCH 085/152] Remove -k/--insecure option from curl installer (#8719) Piping `curl` to `bash` while **disabling** certificate verification can lead to security problems. --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 9255d014b6..8cba4205bd 100644 --- a/README.md +++ b/README.md @@ -138,13 +138,13 @@ first. ## Simple one-line installer for Mac and Ubuntu ```bash -bash <(curl https://get.parity.io -Lk) +bash <(curl https://get.parity.io -L) ``` The one-line installer always defaults to the latest beta release. To install a stable release, run: ```bash -bash <(curl https://get.parity.io -Lk) -r stable +bash <(curl https://get.parity.io -L) -r stable ``` ## Start Parity -- GitLab From 00b209a29e96dc6827852de27d8c426189fd2f56 Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Thu, 31 May 2018 21:28:25 +0800 Subject: [PATCH 086/152] Fix PoW blockchains sealing notifications in chain_new_blocks (#8656) --- ethcore/src/client/client.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index 5cfe8fce82..b469cf4518 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -2181,7 +2181,7 @@ impl ImportSealedBlock for Client { route }; let route = ChainRoute::from([route].as_ref()); - self.importer.miner.chain_new_blocks(self, &[h.clone()], &[], route.enacted(), route.retracted(), true); + self.importer.miner.chain_new_blocks(self, &[h.clone()], &[], route.enacted(), route.retracted(), self.engine.seals_internally().is_some()); self.notify(|notify| { notify.new_blocks( vec![h.clone()], -- GitLab From 799ae29ac490e4bec035a97845a1a44d7610d7bb Mon Sep 17 00:00:00 2001 From: David Date: Fri, 1 Jun 2018 09:38:20 +0200 Subject: [PATCH 087/152] Print warnings when fetching pending blocks (#8711) * Lots of println to figure out what eth_getBlockByNumber does/should do * Remove debugging * Print warnings when fetching pending blocks When calling `eth_getBlockByNumber` with `pending`, we now print a deprecation warning and: * if a pending block is found, use it to respond * if no pending block is found, respond as if if was a request for `Latest` Addresses issue #8703 (not sure if it's enough to close it tbh) --- ethcore/src/miner/miner.rs | 10 ++++++---- rpc/src/v1/impls/eth.rs | 36 +++++++++++++++++++++++------------- 2 files changed, 29 insertions(+), 17 deletions(-) diff --git a/ethcore/src/miner/miner.rs b/ethcore/src/miner/miner.rs index 3168ff1a84..4904535a89 100644 --- a/ethcore/src/miner/miner.rs +++ b/ethcore/src/miner/miner.rs @@ -290,10 +290,12 @@ impl Miner { { self.sealing.lock().queue .peek_last_ref() - .and_then(|b| if b.block().header().number() > latest_block_number { - Some(f(b)) - } else { - None + .and_then(|b| { + if b.block().header().number() > latest_block_number { + Some(f(b)) + } else { + None + } }) } diff --git a/rpc/src/v1/impls/eth.rs b/rpc/src/v1/impls/eth.rs index 389805c176..ae8d611c12 100644 --- a/rpc/src/v1/impls/eth.rs +++ b/rpc/src/v1/impls/eth.rs @@ -108,6 +108,7 @@ pub struct EthClient where eip86_transition: u64, } +#[derive(Debug)] enum BlockNumberOrId { Number(BlockNumber), Id(BlockId), @@ -184,21 +185,30 @@ impl EthClient { let info = self.client.chain_info(); - let pending_block = self.miner.pending_block(info.best_block_number); - let difficulty = { - let latest_difficulty = self.client.block_total_difficulty(BlockId::Latest).expect("blocks in chain have details; qed"); - let pending_difficulty = self.miner.pending_block_header(info.best_block_number).map(|header| *header.difficulty()); + match self.miner.pending_block(info.best_block_number) { + Some(pending_block) => { + warn!("`Pending` is deprecated and may be removed in future versions."); - if let Some(difficulty) = pending_difficulty { - difficulty + latest_difficulty - } else { - latest_difficulty - } - }; + let difficulty = { + let latest_difficulty = self.client.block_total_difficulty(BlockId::Latest).expect("blocks in chain have details; qed"); + let pending_difficulty = self.miner.pending_block_header(info.best_block_number).map(|header| *header.difficulty()); + + if let Some(difficulty) = pending_difficulty { + difficulty + latest_difficulty + } else { + latest_difficulty + } + }; - let extra = pending_block.as_ref().map(|b| self.client.engine().extra_info(&b.header)); + let extra = self.client.engine().extra_info(&pending_block.header); - (pending_block.map(|b| encoded::Block::new(b.rlp_bytes())), Some(difficulty), extra, true) + (Some(encoded::Block::new(pending_block.rlp_bytes())), Some(difficulty), Some(extra), true) + }, + None => { + warn!("`Pending` is deprecated and may be removed in future versions. Falling back to `Latest`"); + client_query(BlockId::Latest) + } + } }, BlockNumberOrId::Number(num) => { @@ -206,7 +216,7 @@ impl EthClient BlockId::Latest, BlockNumber::Earliest => BlockId::Earliest, BlockNumber::Num(n) => BlockId::Number(n), - BlockNumber::Pending => unreachable!(), // Already covered + BlockNumber::Pending => unreachable!() // Already covered }; client_query(id) -- GitLab From 485d4aa8f3d536f8dca91b51ab4c2e4c22a3e6d5 Mon Sep 17 00:00:00 2001 From: Jim Posen Date: Fri, 1 Jun 2018 00:42:45 -0700 Subject: [PATCH 088/152] Fix XOR distance calculation in discovery Kademlia impl (#8589) * network-devp2p: Test for discovery bucket insertion. All test values are randomly generated and the assertions are checked manually. Test fails because distance metric is implemented incorrectly. * network-devp2p: Fix discovery distance function. The Kademlia distance function (XOR) was implemented incorrectly as a population count. * network-devp2p: Refactor nearest_node_entries to be on instance. Optimizations are possible with more access to the discovery state. * network-devp2p: Fix loss of precision in nearest_node_entries. * network-devp2p: More efficient nearest node search. The discovery algorithm to identify the nearest k nodes does not need to scan all entries in all buckets. --- util/network-devp2p/src/discovery.rs | 221 +++++++++++++++++++++------ 1 file changed, 172 insertions(+), 49 deletions(-) diff --git a/util/network-devp2p/src/discovery.rs b/util/network-devp2p/src/discovery.rs index f14cd5ba6f..af43546a5f 100644 --- a/util/network-devp2p/src/discovery.rs +++ b/util/network-devp2p/src/discovery.rs @@ -16,7 +16,7 @@ use ethcore_bytes::Bytes; use std::net::SocketAddr; -use std::collections::{HashSet, HashMap, BTreeMap, VecDeque}; +use std::collections::{HashSet, HashMap, VecDeque}; use std::mem; use std::default::Default; use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH}; @@ -34,9 +34,8 @@ use network::IpFilter; use PROTOCOL_VERSION; -const ADDRESS_BYTES_SIZE: u32 = 32; // Size of address type in bytes. -const ADDRESS_BITS: u32 = 8 * ADDRESS_BYTES_SIZE; // Denoted by n in [Kademlia]. -const NODE_BINS: u32 = ADDRESS_BITS - 1; // Size of m_state (excludes root, which is us). +const ADDRESS_BYTES_SIZE: usize = 32; // Size of address type in bytes. +const ADDRESS_BITS: usize = 8 * ADDRESS_BYTES_SIZE; // Denoted by n in [Kademlia]. const DISCOVERY_MAX_STEPS: u16 = 8; // Max iterations of discovery. (discover) const BUCKET_SIZE: usize = 16; // Denoted by k in [Kademlia]. Number of nodes stored in each bucket. const ALPHA: usize = 3; // Denoted by \alpha in [Kademlia]. Number of concurrent FindNode requests. @@ -119,7 +118,7 @@ impl Discovery { discovery_round: 0, discovery_id: NodeId::new(), discovery_nodes: HashSet::new(), - node_buckets: (0..NODE_BINS).map(|_| NodeBucket::new()).collect(), + node_buckets: (0..ADDRESS_BITS).map(|_| NodeBucket::new()).collect(), udp_socket: socket, send_queue: VecDeque::new(), check_timestamps: true, @@ -155,8 +154,16 @@ impl Discovery { fn update_node(&mut self, e: NodeEntry) { trace!(target: "discovery", "Inserting {:?}", &e); let id_hash = keccak(e.id); + let dist = match Discovery::distance(&self.id_hash, &id_hash) { + Some(dist) => dist, + None => { + warn!(target: "discovery", "Attempted to update own entry: {:?}", e); + return; + } + }; + let ping = { - let bucket = &mut self.node_buckets[Discovery::distance(&self.id_hash, &id_hash) as usize]; + let bucket = &mut self.node_buckets[dist]; let updated = if let Some(node) = bucket.nodes.iter_mut().find(|n| n.address.id == e.id) { node.address = e.clone(); node.timeout = None; @@ -181,7 +188,15 @@ impl Discovery { /// Removes the timeout of a given NodeId if it can be found in one of the discovery buckets fn clear_ping(&mut self, id: &NodeId) { - let bucket = &mut self.node_buckets[Discovery::distance(&self.id_hash, &keccak(id)) as usize]; + let dist = match Discovery::distance(&self.id_hash, &keccak(id)) { + Some(dist) => dist, + None => { + warn!(target: "discovery", "Received ping from self"); + return + } + }; + + let bucket = &mut self.node_buckets[dist]; if let Some(node) = bucket.nodes.iter_mut().find(|n| &n.address.id == id) { node.timeout = None; } @@ -212,7 +227,7 @@ impl Discovery { trace!(target: "discovery", "Starting round {:?}", self.discovery_round); let mut tried_count = 0; { - let nearest = Discovery::nearest_node_entries(&self.discovery_id, &self.node_buckets).into_iter(); + let nearest = self.nearest_node_entries(&self.discovery_id).into_iter(); let nearest = nearest.filter(|x| !self.discovery_nodes.contains(&x.id)).take(ALPHA).collect::>(); for r in nearest { let rlp = encode_list(&(&[self.discovery_id.clone()][..])); @@ -233,17 +248,17 @@ impl Discovery { self.discovery_round += 1; } - fn distance(a: &H256, b: &H256) -> u32 { - let d = *a ^ *b; - let mut ret:u32 = 0; - for i in 0..32 { - let mut v: u8 = d[i]; - while v != 0 { - v >>= 1; - ret += 1; + /// The base 2 log of the distance between a and b using the XOR metric. + fn distance(a: &H256, b: &H256) -> Option { + for i in (0..ADDRESS_BYTES_SIZE).rev() { + let byte_index = ADDRESS_BYTES_SIZE - i - 1; + let d: u8 = a[byte_index] ^ b[byte_index]; + if d != 0 { + let high_bit_index = 7 - d.leading_zeros() as usize; + return Some(i * 8 + high_bit_index); } } - ret + None // a and b are equal, so log distance is -inf } fn ping(&mut self, node: &NodeEndpoint) { @@ -286,36 +301,53 @@ impl Discovery { Ok(()) } - fn nearest_node_entries(target: &NodeId, buckets: &[NodeBucket]) -> Vec { - let mut found: BTreeMap> = BTreeMap::new(); - let mut count = 0; + fn nearest_node_entries(&self, target: &NodeId) -> Vec { let target_hash = keccak(target); + let target_distance = self.id_hash ^ target_hash; + + let mut ret = Vec::::with_capacity(BUCKET_SIZE); + + // Sort bucket entries by distance to target and append to end of result vector. + let append_bucket = |results: &mut Vec, bucket: &NodeBucket| -> bool { + let mut sorted_entries: Vec<&BucketEntry> = bucket.nodes.iter().collect(); + sorted_entries.sort_unstable_by_key(|entry| entry.id_hash ^ target_hash); + + let remaining_capacity = results.capacity() - results.len(); + let to_append = if remaining_capacity < sorted_entries.len() { + &sorted_entries[0..remaining_capacity] + } else { + &sorted_entries + }; + for entry in to_append.iter() { + results.push(entry.address.clone()); + } + results.len() == results.capacity() + }; - // Sort nodes by distance to target - for bucket in buckets { - for node in &bucket.nodes { - let distance = Discovery::distance(&target_hash, &node.id_hash); - found.entry(distance).or_insert_with(Vec::new).push(&node.address); - if count == BUCKET_SIZE { - // delete the most distant element - let remove = { - let (key, last) = found.iter_mut().next_back().expect("Last element is always Some when count > 0"); - last.pop(); - if last.is_empty() { Some(key.clone()) } else { None } - }; - if let Some(remove) = remove { - found.remove(&remove); - } - } - else { - count += 1; + // This algorithm leverages the structure of the routing table to efficiently find the + // nearest entries to a target hash. First, we compute the XOR distance from this node to + // the target. On a first pass, we iterate from the MSB of the distance, stopping at any + // buckets where the distance bit is set, and skipping the buckets where it is unset. These + // must be in order the nearest to the target. On a second pass, we traverse from LSB to + // MSB, appending the buckets skipped on the first pass. The reason this works is that all + // entries in bucket i have a common prefix of length exactly 32 - i - 1 with the ID of this + // node. + + for i in 0..ADDRESS_BITS { + if ((target_distance[i / 8] << (i % 8)) & 0x80) != 0 { + let bucket = &self.node_buckets[ADDRESS_BITS - i - 1]; + if !bucket.nodes.is_empty() && append_bucket(&mut ret, bucket) { + return ret; } } } - - let mut ret:Vec = Vec::new(); - for nodes in found.values() { - ret.extend(nodes.iter().map(|&n| n.clone())); + for i in (0..ADDRESS_BITS).rev() { + if ((target_distance[i / 8] << (i % 8)) & 0x80) == 0 { + let bucket = &self.node_buckets[ADDRESS_BITS - i - 1]; + if !bucket.nodes.is_empty() && append_bucket(&mut ret, bucket) { + return ret; + } + } } ret } @@ -453,7 +485,7 @@ impl Discovery { let target: NodeId = rlp.val_at(0)?; let timestamp: u64 = rlp.val_at(1)?; self.check_timestamp(timestamp)?; - let nearest = Discovery::nearest_node_entries(&target, &self.node_buckets); + let nearest = self.nearest_node_entries(&target); if nearest.is_empty() { return Ok(None); } @@ -614,7 +646,7 @@ mod tests { } discovery2.round(); } - assert_eq!(Discovery::nearest_node_entries(&NodeId::new(), &discovery2.node_buckets).len(), 3) + assert_eq!(discovery2.nearest_node_entries(&NodeId::new()).len(), 3) } #[test] @@ -625,7 +657,7 @@ mod tests { for _ in 0..1200 { discovery.add_node(NodeEntry { id: NodeId::random(), endpoint: ep.clone() }); } - assert!(Discovery::nearest_node_entries(&NodeId::new(), &discovery.node_buckets).len() <= 16); + assert!(discovery.nearest_node_entries(&NodeId::new()).len() <= 16); let removed = discovery.check_expired(true).len(); assert!(removed > 0); } @@ -633,23 +665,114 @@ mod tests { #[test] fn find_nearest_saturated() { use super::*; - let mut buckets: Vec<_> = (0..256).map(|_| NodeBucket::new()).collect(); + + 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, IpFilter::default()); + for _ in 0..(16 + 10) { - buckets[0].nodes.push_back(BucketEntry { + discovery.node_buckets[0].nodes.push_back(BucketEntry { address: NodeEntry { id: NodeId::new(), endpoint: ep.clone() }, timeout: None, id_hash: keccak(NodeId::new()), }); } - let nearest = Discovery::nearest_node_entries(&NodeId::new(), &buckets); + let nearest = discovery.nearest_node_entries(&NodeId::new()); assert_eq!(nearest.len(), 16) } + #[test] + fn routing_table_insertions_lookups() { + use super::*; + let ep = NodeEndpoint { address: SocketAddr::from_str("127.0.0.1:40448").unwrap(), udp_port: 40447 }; + let node_ids_hex: [&str; 32] = [ + "22536fa57acc12c4993295cbc26fef4550513496712b301ad2283d356c8108521244a362e64e6d907a0d0b4e65526699c5ae3cfebfc680505fe3b33d50672835", + "22c482f42401546f8dd7ed6b1c0cad976da6630730f1116614579ccb084791a528ff2676bfe94434de80e5d7e479f1ea1d7737077da3bd5e69a0f3e5bf596091", + "234c73e3a8f6835a7f9a9d2a896bff4908d66d21d5433a2c37d94f1fa9a6ca17d02388f31013ff87e3ad86506e76bd1006b9cac3815974a2b47c8d4f2124697e", + "2a5aaf4e2046c521e890dc82313c6151a55078f045a7e3d259f168238d029271cdd9a0943468d45c1e36a34a8a6d4de4b0262e48d3c8cfdd4c2aab5df42926b9", + "341d8c94d9670461186cfc1f66d4246cb12384940e9f621ec8d6c216b5d037cde5f7a41b70474ca36ced4a4f2fe91c9dc5a24a128414672661f78e8611d54bfd", + "3d9fd01851f3ae1bfd06b48e89738f29f9a2b4dce3ab7864df4fccca55d1ac88044956ba47d0c4cb44a19924626a3a3aa5a4de8958365cb7385111ce7b929200", + "406d5507a7fbc194a495800ae8cf408093336febc24d03d6c63756f522274ab02146ceb1b0213291a9a1544680503837519f88f1e8677d921de62c82935b4e6c", + "4c537f00805f320616ee49c7bc36e1d7e52a04a782b0cc00fd3d6b77200b027cef5f875ed38f1167fef4b02d7bd49a661812301d9d680bb62297131204c035f9", + "4fc8e3fdbdd7acad82b283ac52c121b805f3b15ffcaa6b2ca67b9e375aa88e978951ffa3d03ee13be99f0ee987db0bbfc6a7ca02b175e9123d79826025b4089d", + "55b5042a6910bc908a0520966e8cbcc92ac299bdb7efbfbcf703df1506fa0f9b09c5eeb930080de848d2864cca71f885942852c51233db0ee46fe0447306d61f", + "5d24f28b350c4c37fc4dad7f418e029992c9e4ac356bb3d9a1356ba1076339863c05044d7ceba233c65779401f8a3b38fe67b6a592c1be4834dc869f7bb932eb", + "5f6edaf2f2ae3003f4b4ff90b8e71a717c832c71a634d96e77fe046f9a88adc8de5718ff3c47659aea4cead5376df5b731e1b6530e6b0999f56ad75d4dabd3f6", + "6214c04211efe91abd23d65e2dc8e711b06d4fb13dcfd65b691dc51f58455b2145f9b38f523b72a45a12705a28d389308a34455720d774c9b805326df42b5a63", + "69df92573ddbbce88b72a930843dbb70728b2a020e0cc4e8ba805dcf7f19297bfc5def4ca447e9e6ec66971be1815b8f49042720431f698b6a87a185d94fa6c8", + "72ffc23de007cf8b6f4a117f7427b532d05861c314344ffa265175f57ee45dae041a710a4dc74124dba1dabdc0f52dfd21e3154d1d4285aab529810c6161d623", + "80b567f279a9512f3a66ebd8f87a93acd4d50bf66f5eff6d04039c1f5838e37021e981539659b33e0644b243fc9671209a80cbef40d1bcf7c7117d353cb45532", + "9009dc9e3bf50595f84271f46d4c7a5ad6971f7d2ffce1905bfc40a407d34fc5e2dcebd92746eadcd2c5fa4d5aaccb0e01b542d506b361851df3f19e6bc629a3", + "95264f56e091efeba911003fd01eeb2c81f6fc4bb7b10c92e4c7bfaf460b7246d232e61ad8a223d74870981a84e15b2d5134c25d931cb860c6912b20a2d3ac01", + "96013a472a9f7ff9c5c76b5ca958f14ee510d826703aa41d4c88eac51d30d14229b9f19f6e0469c37aaa6d2136a978a4aaa38ca766f48e53e569f84e44252962", + "a513c988cf8480ad2992caa64e3fa059ce07efda260dfeefed78e1d41ea3f97844603b8a9737eb633086fd9ac2f201200cb656cda8a91bf6cc500d6039db6f53", + "ab3311f38e3641c8b3b1fd36dd7f94b148166e267258e840d29d1859537c74f202bd3342359b3623f96c23fa662d1b65182a898bf20343744b37cb265182e500", + "ac8f41dbd637891a08c9cf715c23577bdd431ba40231682a5a9ba7fd6cb6d66c04f63d6d65c7d9f8737e641e05fdbeede57138a174f0d55e7835575dd6cddd98", + "accdad251888d53e4e18efee1e0d749d050216b14896efb657e9c7b1b78dab82a5b6fb3234017aa19a2f50475d73960f352d308b2e0e841cbebaf418362a4f21", + "b138622208f74d2b8e8fc10bcd4cf3302685cd77d339280a939474b92be8b93e441c50709e25c82cc88a2a4207e9f2938912d60600226efe322b43c6ef5e7aef", + "b4f64e1fa6a5cd6198b2515bde63fbdabaf7e7a31dbaf5369babbda4b8cd0bf5025ac4b7d2d6e6e3bc76c890df585d28d4815e464c8792ef677df9206864a12b", + "c1136e08a27c93812ae2dd47201d9e81c82d1995001b88dba9eec700e1d3385dfaf7ae834226c3c90a138f1808cd10b5502f49ee774a2bc707f34bd7d160b7bd", + "c203ae9b5d1953b0ac462e66338800ec26982e2af54bd444fc8978973191633d4f483e31b28233c07bb99f34d57c680fa5f8e093e64f13b235005b7ab6e2d594", + "c2e1067c58a9948e773e0a3637d946e26d95762f89ec9d35e2ad84f770309d94168d4e112c78d62b60efc6216bc5d31475f24307b1b8e0fa8dcbb18a10cb85f5", + "d60ecb1a89e0d5aeff14c9a95da9f5492eb15871c53563b86b7c5ddf0da74b4c29e682fdd22aae2290e0b16ef4b6d707ef55396ca98f755c95b689cf65ce5f80", + "df5ad4ea6242929df86f2162d1cc62b0e0a6f0a03428a39dea98f6a689335b5ceaf1f0696c17b717b141aeb45a29108d95c3a7d2d1d0bb3441219504ae672917", + "e1268f5dd9552a11989df9d4953bb388e7466711b2bd9882a3ed4d0767a21f046c53c20f9a18d66bae1d6a5544492857ddecb0b5b4818bd4557be252ddd66c71", + "e626019dc0b50b9e254461f19d29e69a4669c5256134a6352c6c30d3bc55d201a5b43fc2e006556cfaf29765b683e807e03093798942826244e4ee9e47c75d3f", + ]; + let node_entries = node_ids_hex.iter() + .map(|node_id_hex| NodeId::from_str(node_id_hex).unwrap()) + .map(|node_id| NodeEntry { id: node_id, endpoint: ep.clone() }) + .collect::>(); + + let secret_hex = "6c71d1b8930d29e6371be1081f2c909c64b46440a1716314c3c9df995cb3aed1"; + let key = Secret::from_str(secret_hex) + .and_then(|secret| KeyPair::from_secret(secret)) + .unwrap(); + let mut discovery = Discovery::new(&key, ep.address.clone(), ep.clone(), 0, IpFilter::default()); + + node_entries.iter().for_each(|entry| discovery.update_node(entry.clone())); + + let expected_bucket_sizes = vec![ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7, 8, 12 + ]; + let actual_bucket_sizes = discovery.node_buckets.iter() + .map(|ref bucket| bucket.nodes.len()) + .collect::>(); + assert_eq!(actual_bucket_sizes, expected_bucket_sizes); + + for entry in &node_entries { + let nearest = discovery.nearest_node_entries(&entry.id); + assert_eq!(nearest.len(), 16); + assert_eq!(nearest[0].id, entry.id); + + let mut expected_ids: Vec = node_entries.iter().map(|entry| entry.id).collect(); + expected_ids.sort_unstable_by_key(|id| keccak(id) ^ keccak(entry.id)); + expected_ids.resize(BUCKET_SIZE, NodeId::default()); + + let actual_ids: Vec = nearest.iter().map(|entry| entry.id).collect(); + assert_eq!(actual_ids, expected_ids); + } + } + #[test] fn packets() { let key = Random.generate().unwrap(); - let ep = NodeEndpoint { address: SocketAddr::from_str("127.0.0.1:40447").unwrap(), udp_port: 40447 }; + let ep = NodeEndpoint { address: SocketAddr::from_str("127.0.0.1:40449").unwrap(), udp_port: 40449 }; 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(); -- GitLab From dab967ace8ad1f4e02c597efda8da8eac874206a Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Fri, 1 Jun 2018 09:49:46 +0200 Subject: [PATCH 089/152] Remove NetworkService::config() (#8653) --- ethcore/sync/src/api.rs | 49 +++++++++++++++-------- parity/informant.rs | 5 ++- rpc/src/v1/impls/parity.rs | 5 ++- rpc/src/v1/tests/mocked/manage_network.rs | 5 ++- util/network-devp2p/src/service.rs | 28 +++++++++---- whisper/cli/src/main.rs | 2 +- 6 files changed, 62 insertions(+), 32 deletions(-) diff --git a/ethcore/sync/src/api.rs b/ethcore/sync/src/api.rs index 2f90e410ae..9e6cdafa6e 100644 --- a/ethcore/sync/src/api.rs +++ b/ethcore/sync/src/api.rs @@ -17,6 +17,7 @@ use std::sync::Arc; use std::collections::{HashMap, BTreeMap}; use std::io; +use std::ops::Range; use std::time::Duration; use bytes::Bytes; use devp2p::NetworkService; @@ -452,11 +453,18 @@ impl ChainNotify for EthSync { } fn start(&self) { - match self.network.start().map_err(Into::into) { - Err(ErrorKind::Io(ref e)) if e.kind() == io::ErrorKind::AddrInUse => warn!("Network port {:?} is already in use, make sure that another instance of an Ethereum client is not running or change the port using the --port option.", self.network.config().listen_address.expect("Listen address is not set.")), - Err(err) => warn!("Error starting network: {}", err), + match self.network.start() { + Err((err, listen_address)) => { + match err.into() { + ErrorKind::Io(ref e) if e.kind() == io::ErrorKind::AddrInUse => { + warn!("Network port {:?} is already in use, make sure that another instance of an Ethereum client is not running or change the port using the --port option.", listen_address.expect("Listen address is not set.")) + }, + err => warn!("Error starting network: {}", err), + } + }, _ => {}, } + self.network.register_protocol(self.eth_handler.clone(), self.subprotocol_name, &[ETH_PROTOCOL_VERSION_62, ETH_PROTOCOL_VERSION_63]) .unwrap_or_else(|e| warn!("Error registering ethereum protocol: {:?}", e)); // register the warp sync subprotocol @@ -520,8 +528,10 @@ pub trait ManageNetwork : Send + Sync { fn start_network(&self); /// Stop network fn stop_network(&self); - /// Query the current configuration of the network - fn network_config(&self) -> NetworkConfiguration; + /// Returns the minimum and maximum peers. + /// Note that `range.end` is *exclusive*. + // TODO: Range should be changed to RangeInclusive once stable (https://github.com/rust-lang/rust/pull/50758) + fn num_peers_range(&self) -> Range; /// Get network context for protocol. fn with_proto_context(&self, proto: ProtocolId, f: &mut FnMut(&NetworkContext)); } @@ -561,8 +571,8 @@ impl ManageNetwork for EthSync { self.stop(); } - fn network_config(&self) -> NetworkConfiguration { - NetworkConfiguration::from(self.network.config().clone()) + fn num_peers_range(&self) -> Range { + self.network.num_peers_range() } fn with_proto_context(&self, proto: ProtocolId, f: &mut FnMut(&NetworkContext)) { @@ -815,11 +825,15 @@ impl ManageNetwork for LightSync { } fn start_network(&self) { - match self.network.start().map_err(Into::into) { - Err(ErrorKind::Io(ref e)) if e.kind() == io::ErrorKind::AddrInUse => { - warn!("Network port {:?} is already in use, make sure that another instance of an Ethereum client is not running or change the port using the --port option.", self.network.config().listen_address.expect("Listen address is not set.")) - } - Err(err) => warn!("Error starting network: {}", err), + match self.network.start() { + Err((err, listen_address)) => { + match err.into() { + ErrorKind::Io(ref e) if e.kind() == io::ErrorKind::AddrInUse => { + warn!("Network port {:?} is already in use, make sure that another instance of an Ethereum client is not running or change the port using the --port option.", listen_address.expect("Listen address is not set.")) + }, + err => warn!("Error starting network: {}", err), + } + }, _ => {}, } @@ -836,8 +850,8 @@ impl ManageNetwork for LightSync { self.network.stop(); } - fn network_config(&self) -> NetworkConfiguration { - NetworkConfiguration::from(self.network.config().clone()) + fn num_peers_range(&self) -> Range { + self.network.num_peers_range() } fn with_proto_context(&self, proto: ProtocolId, f: &mut FnMut(&NetworkContext)) { @@ -848,12 +862,13 @@ impl ManageNetwork for LightSync { impl LightSyncProvider for LightSync { fn peer_numbers(&self) -> PeerNumbers { let (connected, active) = self.proto.peer_count(); - let config = self.network_config(); + let peers_range = self.num_peers_range(); + debug_assert!(peers_range.end > peers_range.start); PeerNumbers { connected: connected, active: active, - max: config.max_peers as usize, - min: config.min_peers as usize, + max: peers_range.end as usize - 1, + min: peers_range.start as usize, } } diff --git a/parity/informant.rs b/parity/informant.rs index e2f3960b67..43788bc9d9 100644 --- a/parity/informant.rs +++ b/parity/informant.rs @@ -145,7 +145,8 @@ impl InformantData for FullNodeInformantData { let (importing, sync_info) = match (self.sync.as_ref(), self.net.as_ref()) { (Some(sync), Some(net)) => { let status = sync.status(); - let net_config = net.network_config(); + let num_peers_range = net.num_peers_range(); + debug_assert!(num_peers_range.end > num_peers_range.start); cache_sizes.insert("sync", status.mem_used); @@ -154,7 +155,7 @@ impl InformantData for FullNodeInformantData { last_imported_block_number: status.last_imported_block_number.unwrap_or(chain_info.best_block_number), last_imported_old_block_number: status.last_imported_old_block_number, num_peers: status.num_peers, - max_peers: status.current_max_peers(net_config.min_peers, net_config.max_peers), + max_peers: status.current_max_peers(num_peers_range.start, num_peers_range.end - 1), snapshot_sync: status.is_snapshot_syncing(), })) } diff --git a/rpc/src/v1/impls/parity.rs b/rpc/src/v1/impls/parity.rs index 08d5147202..3fa9cb991b 100644 --- a/rpc/src/v1/impls/parity.rs +++ b/rpc/src/v1/impls/parity.rs @@ -212,13 +212,14 @@ impl Parity for ParityClient where fn net_peers(&self) -> Result { let sync_status = self.sync.status(); - let net_config = self.net.network_config(); + let num_peers_range = self.net.num_peers_range(); + debug_assert!(num_peers_range.end > num_peers_range.start); let peers = self.sync.peers().into_iter().map(Into::into).collect(); Ok(Peers { active: sync_status.num_active_peers, connected: sync_status.num_peers, - max: sync_status.current_max_peers(net_config.min_peers, net_config.max_peers), + max: sync_status.current_max_peers(num_peers_range.start, num_peers_range.end - 1), peers: peers }) } diff --git a/rpc/src/v1/tests/mocked/manage_network.rs b/rpc/src/v1/tests/mocked/manage_network.rs index 3a901c8e9f..da4f1aa511 100644 --- a/rpc/src/v1/tests/mocked/manage_network.rs +++ b/rpc/src/v1/tests/mocked/manage_network.rs @@ -14,7 +14,8 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -use sync::{ManageNetwork, NetworkConfiguration}; +use std::ops::Range; +use sync::ManageNetwork; use self::ethcore_network::{ProtocolId, NetworkContext}; extern crate ethcore_network; @@ -29,6 +30,6 @@ impl ManageNetwork for TestManageNetwork { fn add_reserved_peer(&self, _peer: String) -> Result<(), String> { Ok(()) } fn start_network(&self) {} fn stop_network(&self) {} - fn network_config(&self) -> NetworkConfiguration { NetworkConfiguration::new_local() } + fn num_peers_range(&self) -> Range { 25 .. 51 } fn with_proto_context(&self, _: ProtocolId, _: &mut FnMut(&NetworkContext)) { } } diff --git a/util/network-devp2p/src/service.rs b/util/network-devp2p/src/service.rs index d8105f649c..f90c660671 100644 --- a/util/network-devp2p/src/service.rs +++ b/util/network-devp2p/src/service.rs @@ -19,6 +19,8 @@ use network::{NetworkContext, PeerId, ProtocolId, NetworkIoMessage}; use host::Host; use io::*; use parking_lot::RwLock; +use std::net::SocketAddr; +use std::ops::Range; use std::sync::Arc; use ansi_term::Colour; use network::ConnectionFilter; @@ -92,9 +94,13 @@ impl NetworkService { &self.io_service } - /// Returns network configuration. - pub fn config(&self) -> &NetworkConfiguration { - &self.config + /// Returns the number of peers allowed. + /// + /// Keep in mind that `range.end` is *exclusive*. + pub fn num_peers_range(&self) -> Range { + let start = self.config.min_peers; + let end = self.config.max_peers + 1; + start .. end } /// Returns external url if available. @@ -109,17 +115,23 @@ impl NetworkService { host.as_ref().map(|h| h.local_url()) } - /// Start network IO - pub fn start(&self) -> Result<(), Error> { + /// Start network IO. + /// + /// In case of error, also returns the listening address for better error reporting. + pub fn start(&self) -> Result<(), (Error, Option)> { let mut host = self.host.write(); + let listen_addr = self.config.listen_address.clone(); if host.is_none() { - let h = Arc::new(Host::new(self.config.clone(), self.filter.clone())?); - self.io_service.register_handler(h.clone())?; + let h = Arc::new(Host::new(self.config.clone(), self.filter.clone()) + .map_err(|err| (err.into(), listen_addr))?); + self.io_service.register_handler(h.clone()) + .map_err(|err| (err.into(), listen_addr))?; *host = Some(h); } if self.host_handler.public_url.read().is_none() { - self.io_service.register_handler(self.host_handler.clone())?; + self.io_service.register_handler(self.host_handler.clone()) + .map_err(|err| (err.into(), listen_addr))?; } Ok(()) diff --git a/whisper/cli/src/main.rs b/whisper/cli/src/main.rs index d76c216be4..6f3aec8594 100644 --- a/whisper/cli/src/main.rs +++ b/whisper/cli/src/main.rs @@ -218,7 +218,7 @@ fn execute(command: I) -> Result<(), Error> where I: IntoIterator, let network = devp2p::NetworkService::new(net::NetworkConfiguration::new_local(), None)?; // Start network service - network.start()?; + network.start().map_err(|(err, _)| err)?; // Attach whisper protocol to the network service network.register_protocol(whisper_network_handler.clone(), whisper::net::PROTOCOL_ID, -- GitLab From 27f3f42ce268612083cde19ca8acbbfd54cd8b8e Mon Sep 17 00:00:00 2001 From: Afri Schoedon <5chdn@users.noreply.github.com> Date: Fri, 1 Jun 2018 09:52:30 +0200 Subject: [PATCH 090/152] CI: Fixes for Android Pipeline (#8745) * ci: Remove check for shared libraries in gitlab script * ci: allow android arm build to fail --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 95a7ebcb5e..c615be99ce 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -190,9 +190,9 @@ android-armv7: - triggers script: - cargo build --target=armv7-linux-androideabi - - if [ $(arm-linux-androideabi-objdump -x ./target/armv7-linux-androideabi/debug/parity | grep -i 'c++_shared' | wc -l) -ne 0]; then echo "FAIL!!" fi tags: - rust-arm + allow_failure: true artifacts: paths: - parity.zip -- GitLab From 0ebcc200c365a2923fa3e91d4807756ce0be46fc Mon Sep 17 00:00:00 2001 From: Benjamin Kampmann Date: Fri, 1 Jun 2018 13:37:43 +0200 Subject: [PATCH 091/152] Custom Error Messages on ENFILE and EMFILE IO Errors (#8744) * Custom Error Messages on ENFILE and EMFILE IO Errors Add custom mapping of ENFILE and EMFILE IO Errors (Failure because of missing system resource) right when chaining ioError into ::util::Network::Error to improve Error Messages given to user Note: Adds libc as a dependency to util/network * Use assert-matches for more readable tests * Fix Wording and consistency --- Cargo.lock | 2 ++ util/network/Cargo.toml | 5 ++++ util/network/src/error.rs | 53 ++++++++++++++++++++++++++++++++++++++- util/network/src/lib.rs | 4 +++ 4 files changed, 63 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index c8e60dce69..680b9606ec 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -703,12 +703,14 @@ dependencies = [ name = "ethcore-network" version = "1.12.0" dependencies = [ + "assert_matches 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore-crypto 0.1.0", "ethcore-io 1.12.0", "ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "ethkey 0.3.0", "ipnetwork 0.12.7 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", "rlp 0.2.1", "snappy 0.1.0 (git+https://github.com/paritytech/rust-snappy)", ] diff --git a/util/network/Cargo.toml b/util/network/Cargo.toml index f7131da038..4ae699098d 100644 --- a/util/network/Cargo.toml +++ b/util/network/Cargo.toml @@ -14,4 +14,9 @@ ethereum-types = "0.3" ethkey = { path = "../../ethkey" } ipnetwork = "0.12.6" rlp = { path = "../rlp" } +libc = "0.2" snappy = { git = "https://github.com/paritytech/rust-snappy" } + + +[dev-dependencies] +assert_matches = "1.2" diff --git a/util/network/src/error.rs b/util/network/src/error.rs index 6104486696..50bd01e9ba 100644 --- a/util/network/src/error.rs +++ b/util/network/src/error.rs @@ -15,6 +15,7 @@ // along with Parity. If not, see . use std::{io, net, fmt}; +use libc::{ENFILE, EMFILE}; use io::IoError; use {rlp, ethkey, crypto, snappy}; @@ -83,7 +84,6 @@ impl fmt::Display for DisconnectReason { error_chain! { foreign_links { SocketIo(IoError) #[doc = "Socket IO error."]; - Io(io::Error) #[doc = "Error concerning the Rust standard library's IO subsystem."]; Decompression(snappy::InvalidInput) #[doc = "Decompression error."]; } @@ -141,6 +141,34 @@ error_chain! { description("Packet is too large"), display("Packet is too large"), } + + #[doc = "Reached system resource limits for this process"] + ProcessTooManyFiles { + description("Too many open files in process."), + display("Too many open files in this process. Check your resource limits and restart parity"), + } + + #[doc = "Reached system wide resource limits"] + SystemTooManyFiles { + description("Too many open files on system."), + display("Too many open files on system. Consider closing some processes/release some file handlers or increas the system-wide resource limits and restart parity."), + } + + #[doc = "An unknown IO error occurred."] + Io(err: io::Error) { + description("IO Error"), + display("Unexpected IO error: {}", err), + } + } +} + +impl From for Error { + fn from(err: io::Error) -> Self { + match err.raw_os_error() { + Some(ENFILE) => ErrorKind::ProcessTooManyFiles.into(), + Some(EMFILE) => ErrorKind::SystemTooManyFiles.into(), + _ => Error::from_kind(ErrorKind::Io(err)) + } } } @@ -191,3 +219,26 @@ fn test_errors() { _ => panic!("Unexpected error"), } } + +#[test] +fn test_io_errors() { + use libc::{EMFILE, ENFILE}; + + assert_matches!( + >::from( + io::Error::from_raw_os_error(ENFILE) + ).kind(), + ErrorKind::ProcessTooManyFiles); + + assert_matches!( + >::from( + io::Error::from_raw_os_error(EMFILE) + ).kind(), + ErrorKind::SystemTooManyFiles); + + assert_matches!( + >::from( + io::Error::from_raw_os_error(0) + ).kind(), + ErrorKind::Io(_)); +} diff --git a/util/network/src/lib.rs b/util/network/src/lib.rs index 207a05075d..87d3ed9b0e 100644 --- a/util/network/src/lib.rs +++ b/util/network/src/lib.rs @@ -23,6 +23,10 @@ extern crate ethkey; extern crate rlp; extern crate ipnetwork; extern crate snappy; +extern crate libc; + +#[cfg(test)] #[macro_use] +extern crate assert_matches; #[macro_use] extern crate error_chain; -- GitLab From 79eb8f7ace85720da889b618ed4da35e9e73d608 Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Fri, 1 Jun 2018 22:49:55 +0800 Subject: [PATCH 092/152] Remove public node settings from cli (#8758) * Remove public node related settings * Fix tests * Unwrap accounts provider in all rpc apis * Unwrap AccountProvider in all cli places * Fix rpc tests --- parity/cli/mod.rs | 14 ++++++----- parity/configuration.rs | 16 ++++--------- parity/rpc_apis.rs | 23 +++++++----------- parity/run.rs | 7 +----- rpc/src/v1/helpers/accounts.rs | 27 ---------------------- rpc/src/v1/helpers/errors.rs | 8 ------- rpc/src/v1/helpers/mod.rs | 1 - rpc/src/v1/impls/eth.rs | 7 +++--- rpc/src/v1/impls/parity.rs | 19 ++++----------- rpc/src/v1/impls/parity_accounts.rs | 7 +++--- rpc/src/v1/impls/personal.rs | 9 ++++---- rpc/src/v1/impls/private.rs | 3 +-- rpc/src/v1/impls/secretstore.rs | 7 +++--- rpc/src/v1/impls/signer.rs | 7 +++--- rpc/src/v1/impls/signing.rs | 7 +++--- rpc/src/v1/impls/signing_unsafe.rs | 7 +++--- rpc/src/v1/tests/eth.rs | 2 +- rpc/src/v1/tests/mocked/eth.rs | 2 +- rpc/src/v1/tests/mocked/parity.rs | 2 +- rpc/src/v1/tests/mocked/parity_accounts.rs | 2 +- rpc/src/v1/tests/mocked/personal.rs | 4 ++-- rpc/src/v1/tests/mocked/secretstore.rs | 2 +- rpc/src/v1/tests/mocked/signer.rs | 2 +- rpc/src/v1/tests/mocked/signing.rs | 2 +- 24 files changed, 57 insertions(+), 130 deletions(-) delete mode 100644 rpc/src/v1/helpers/accounts.rs diff --git a/parity/cli/mod.rs b/parity/cli/mod.rs index fea060d593..facd01dbfb 100644 --- a/parity/cli/mod.rs +++ b/parity/cli/mod.rs @@ -240,10 +240,6 @@ usage! { { // Global flags and arguments ["Operating Options"] - FLAG flag_public_node: (bool) = false, or |c: &Config| c.parity.as_ref()?.public_node.clone(), - "--public-node", - "Start Parity as a public web server. Account storage and transaction signing will be delegated to the UI.", - FLAG flag_no_download: (bool) = false, or |c: &Config| c.parity.as_ref()?.no_download.clone(), "--no-download", "Normally new releases will be downloaded ready for updating. This disables it. Not recommended.", @@ -948,6 +944,10 @@ usage! { "--rpc", "Does nothing; JSON-RPC is on by default now.", + FLAG flag_public_node: (bool) = false, or |_| None, + "--public-node", + "Does nothing; Public node is removed from Parity.", + ARG arg_dapps_port: (Option) = None, or |c: &Config| c.dapps.as_ref()?.port.clone(), "--dapps-port=[PORT]", "Dapps server is merged with RPC server. Use --jsonrpc-port.", @@ -1070,7 +1070,6 @@ struct Operating { auto_update_delay: Option, auto_update_check_frequency: Option, release_track: Option, - public_node: Option, no_download: Option, no_consensus: Option, chain: Option, @@ -1081,6 +1080,9 @@ struct Operating { light: Option, no_persistent_txqueue: Option, no_hardcoded_sync: Option, + + #[serde(rename="public_node")] + _legacy_public_node: Option, } #[derive(Default, Debug, PartialEq, Deserialize)] @@ -1797,7 +1799,6 @@ mod tests { auto_update_delay: None, auto_update_check_frequency: None, release_track: None, - public_node: None, no_download: None, no_consensus: None, chain: Some("./chain.json".into()), @@ -1808,6 +1809,7 @@ mod tests { light: None, no_hardcoded_sync: None, no_persistent_txqueue: None, + _legacy_public_node: None, }), account: Some(Account { unlock: Some(vec!["0x1".into(), "0x2".into(), "0x3".into()]), diff --git a/parity/configuration.rs b/parity/configuration.rs index 6bec636e2c..426b651015 100644 --- a/parity/configuration.rs +++ b/parity/configuration.rs @@ -35,7 +35,6 @@ use ethcore::verification::queue::VerifierSettings; use miner::pool; use rpc::{IpcConfiguration, HttpConfiguration, WsConfiguration, UiConfiguration}; -use rpc_apis::ApiSet; use parity_rpc::NetworkSettings; use cache::CacheConfig; use helpers::{to_duration, to_mode, to_block_id, to_u256, to_pending_set, to_price, geth_ipc_path, parity_ipc_path, to_bootnodes, to_addresses, to_address, to_queue_strategy, to_queue_penalization, passwords_from_files}; @@ -138,7 +137,6 @@ impl Configuration { let fat_db = self.args.arg_fat_db.parse()?; let compaction = self.args.arg_db_compaction.parse()?; let wal = !self.args.flag_fast_and_loose; - let public_node = self.args.flag_public_node; let warp_sync = !self.args.flag_no_warp; let geth_compatibility = self.args.flag_geth; let dapps_conf = self.dapps_config(); @@ -379,7 +377,6 @@ impl Configuration { vm_type: vm_type, warp_sync: warp_sync, warp_barrier: self.args.arg_warp_barrier, - public_node: public_node, geth_compatibility: geth_compatibility, net_settings: self.network_settings()?, dapps_conf: dapps_conf, @@ -914,10 +911,7 @@ impl Configuration { enabled: self.rpc_enabled(), interface: self.rpc_interface(), port: self.args.arg_ports_shift + self.args.arg_rpcport.unwrap_or(self.args.arg_jsonrpc_port), - apis: match self.args.flag_public_node { - false => self.rpc_apis().parse()?, - true => self.rpc_apis().parse::()?.retain(ApiSet::PublicContext), - }, + apis: self.rpc_apis().parse()?, hosts: self.rpc_hosts(), cors: self.rpc_cors(), server_threads: match self.args.arg_jsonrpc_server_threads { @@ -935,10 +929,8 @@ impl Configuration { let http = self.http_config()?; let support_token_api = - // never enabled for public node - !self.args.flag_public_node - // enabled when not unlocking unless the ui is forced - && (self.args.arg_unlock.is_none() || ui.enabled); + // enabled when not unlocking + self.args.arg_unlock.is_none(); let conf = WsConfiguration { enabled: self.ws_enabled(), @@ -1263,6 +1255,7 @@ mod tests { use params::SpecType; use presale::ImportWallet; use rpc::{WsConfiguration, UiConfiguration}; + use rpc_apis::ApiSet; use run::RunCmd; use network::{AllowIP, IpFilter}; @@ -1499,7 +1492,6 @@ mod tests { ipc_conf: Default::default(), net_conf: default_network_config(), network_id: None, - public_node: false, warp_sync: true, warp_barrier: None, acc_conf: Default::default(), diff --git a/parity/rpc_apis.rs b/parity/rpc_apis.rs index 7b914f2860..855f917b13 100644 --- a/parity/rpc_apis.rs +++ b/parity/rpc_apis.rs @@ -116,8 +116,6 @@ pub enum ApiSet { SafeContext, // Unsafe context (like jsonrpc over http) UnsafeContext, - // Public context (like public jsonrpc over http) - PublicContext, // All possible APIs All, // Local "unsafe" context and accounts access @@ -219,7 +217,7 @@ pub struct FullDependencies { pub snapshot: Arc, pub sync: Arc, pub net: Arc, - pub secret_store: Option>, + pub secret_store: Arc, pub private_tx_service: Option>, pub miner: Arc, pub external_miner: Arc, @@ -316,7 +314,7 @@ impl FullDependencies { } }, Api::Personal => { - handler.extend_with(PersonalClient::new(self.secret_store.clone(), dispatcher.clone(), self.geth_compatibility).to_delegate()); + handler.extend_with(PersonalClient::new(&self.secret_store, dispatcher.clone(), self.geth_compatibility).to_delegate()); }, Api::Signer => { handler.extend_with(SignerClient::new(&self.secret_store, dispatcher.clone(), &self.signer_service, self.remote.clone()).to_delegate()); @@ -475,7 +473,7 @@ impl LightDependencies { { let deps = &$deps; let dispatcher = dispatcher.clone(); - let secret_store = Some(deps.secret_store.clone()); + let secret_store = deps.secret_store.clone(); if deps.signer_service.is_enabled() { $handler.extend_with($namespace::to_delegate( SigningQueueClient::new(&deps.signer_service, dispatcher, deps.remote.clone(), &secret_store) @@ -533,12 +531,10 @@ impl LightDependencies { handler.extend_with(EthPubSub::to_delegate(client)); }, Api::Personal => { - let secret_store = Some(self.secret_store.clone()); - handler.extend_with(PersonalClient::new(secret_store, dispatcher.clone(), self.geth_compatibility).to_delegate()); + handler.extend_with(PersonalClient::new(&self.secret_store, dispatcher.clone(), self.geth_compatibility).to_delegate()); }, Api::Signer => { - let secret_store = Some(self.secret_store.clone()); - handler.extend_with(SignerClient::new(&secret_store, dispatcher.clone(), &self.signer_service, self.remote.clone()).to_delegate()); + handler.extend_with(SignerClient::new(&self.secret_store, dispatcher.clone(), &self.signer_service, self.remote.clone()).to_delegate()); }, Api::Parity => { let signer = match self.signer_service.is_enabled() { @@ -571,8 +567,7 @@ impl LightDependencies { } }, Api::ParityAccounts => { - let secret_store = Some(self.secret_store.clone()); - handler.extend_with(ParityAccountsClient::new(&secret_store).to_delegate()); + handler.extend_with(ParityAccountsClient::new(&self.secret_store).to_delegate()); }, Api::ParitySet => { handler.extend_with(light::ParitySetClient::new( @@ -590,8 +585,7 @@ impl LightDependencies { handler.extend_with(RpcClient::new(modules).to_delegate()); }, Api::SecretStore => { - let secret_store = Some(self.secret_store.clone()); - handler.extend_with(SecretStoreClient::new(&secret_store).to_delegate()); + handler.extend_with(SecretStoreClient::new(&self.secret_store).to_delegate()); }, Api::Whisper => { if let Some(ref whisper_rpc) = self.whisper_rpc { @@ -637,7 +631,7 @@ impl ApiSet { } pub fn list_apis(&self) -> HashSet { - let mut public_list = [ + let mut public_list: HashSet = [ Api::Web3, Api::Net, Api::Eth, @@ -651,7 +645,6 @@ impl ApiSet { match *self { ApiSet::List(ref apis) => apis.clone(), - ApiSet::PublicContext => public_list, ApiSet::UnsafeContext => { public_list.insert(Api::Traces); public_list.insert(Api::ParityPubSub); diff --git a/parity/run.rs b/parity/run.rs index 31f8779c0f..bd8d4fb4a8 100644 --- a/parity/run.rs +++ b/parity/run.rs @@ -98,7 +98,6 @@ pub struct RunCmd { pub network_id: Option, pub warp_sync: bool, pub warp_barrier: Option, - pub public_node: bool, pub acc_conf: AccountsConfig, pub gas_pricer_conf: GasPricerConfig, pub miner_extras: MinerExtras, @@ -721,11 +720,7 @@ fn execute_impl(cmd: RunCmd, logger: Arc, on_client_rq: // set up dependencies for rpc servers let rpc_stats = Arc::new(informant::RpcStats::default()); - let secret_store = match cmd.public_node { - true => None, - false => Some(account_provider.clone()) - }; - + let secret_store = account_provider.clone(); let signer_service = Arc::new(signer::new_service(&cmd.ws_conf, &cmd.logger_config)); // the dapps server diff --git a/rpc/src/v1/helpers/accounts.rs b/rpc/src/v1/helpers/accounts.rs deleted file mode 100644 index 9706039355..0000000000 --- a/rpc/src/v1/helpers/accounts.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 . - -use std::sync::Arc; -use ethcore::account_provider::AccountProvider; -use jsonrpc_core::Error; -use v1::helpers::errors; - -pub fn unwrap_provider(provider: &Option>) -> Result, Error> { - match *provider { - Some(ref arc) => Ok(arc.clone()), - None => Err(errors::public_unsupported(None)), - } -} diff --git a/rpc/src/v1/helpers/errors.rs b/rpc/src/v1/helpers/errors.rs index c85beef7d5..0d36a926e9 100644 --- a/rpc/src/v1/helpers/errors.rs +++ b/rpc/src/v1/helpers/errors.rs @@ -68,14 +68,6 @@ pub fn light_unimplemented(details: Option) -> Error { } } -pub fn public_unsupported(details: Option) -> Error { - Error { - code: ErrorCode::ServerError(codes::UNSUPPORTED_REQUEST), - message: "Method disallowed when running parity as a public node.".into(), - data: details.map(Value::String), - } -} - pub fn unsupported>(msg: T, details: Option) -> Error { Error { code: ErrorCode::ServerError(codes::UNSUPPORTED_REQUEST), diff --git a/rpc/src/v1/helpers/mod.rs b/rpc/src/v1/helpers/mod.rs index 7cd4e6f60a..9adb5d68d4 100644 --- a/rpc/src/v1/helpers/mod.rs +++ b/rpc/src/v1/helpers/mod.rs @@ -17,7 +17,6 @@ #[macro_use] pub mod errors; -pub mod accounts; pub mod block_import; pub mod dapps; pub mod dispatch; diff --git a/rpc/src/v1/impls/eth.rs b/rpc/src/v1/impls/eth.rs index ae8d611c12..32ba36deb8 100644 --- a/rpc/src/v1/impls/eth.rs +++ b/rpc/src/v1/impls/eth.rs @@ -45,7 +45,6 @@ use jsonrpc_macros::Trailing; use v1::helpers::{errors, limit_logs, fake_sign}; use v1::helpers::dispatch::{FullDispatcher, default_gas_price}; use v1::helpers::block_import::is_major_importing; -use v1::helpers::accounts::unwrap_provider; use v1::traits::Eth; use v1::types::{ RichBlock, Block, BlockTransactions, BlockNumber, Bytes, SyncStatus, SyncInfo, @@ -100,7 +99,7 @@ pub struct EthClient where client: Arc, snapshot: Arc, sync: Arc, - accounts: Option>, + accounts: Arc, miner: Arc, external_miner: Arc, seed_compute: Mutex, @@ -153,7 +152,7 @@ impl EthClient, snapshot: &Arc, sync: &Arc, - accounts: &Option>, + accounts: &Arc, miner: &Arc, em: &Arc, options: EthClientOptions @@ -174,7 +173,7 @@ impl EthClient`, errors if provider was not /// set. fn account_provider(&self) -> Result> { - unwrap_provider(&self.accounts) + Ok(self.accounts.clone()) } fn rich_block(&self, id: BlockNumberOrId, include_txs: bool) -> Result> { diff --git a/rpc/src/v1/impls/parity.rs b/rpc/src/v1/impls/parity.rs index 3fa9cb991b..f5d4a58949 100644 --- a/rpc/src/v1/impls/parity.rs +++ b/rpc/src/v1/impls/parity.rs @@ -40,7 +40,6 @@ use jsonrpc_core::{BoxFuture, Result}; use jsonrpc_core::futures::{future, Future}; use jsonrpc_macros::Trailing; use v1::helpers::{self, errors, fake_sign, ipfs, SigningQueue, SignerService, NetworkSettings}; -use v1::helpers::accounts::unwrap_provider; use v1::metadata::Metadata; use v1::traits::Parity; use v1::types::{ @@ -62,7 +61,7 @@ pub struct ParityClient { sync: Arc, net: Arc, health: NodeHealth, - accounts: Option>, + accounts: Arc, logger: Arc, settings: Arc, signer: Option>, @@ -82,7 +81,7 @@ impl ParityClient where updater: Arc, net: Arc, health: NodeHealth, - accounts: Option>, + accounts: Arc, logger: Arc, settings: Arc, signer: Option>, @@ -110,7 +109,7 @@ impl ParityClient where /// Attempt to get the `Arc`, errors if provider was not /// set. fn account_provider(&self) -> Result> { - unwrap_provider(&self.accounts) + Ok(self.accounts.clone()) } } @@ -349,11 +348,6 @@ impl Parity for ParityClient where } fn local_transactions(&self) -> Result> { - // Return nothing if accounts are disabled (running as public node) - if self.accounts.is_none() { - return Ok(BTreeMap::new()); - } - let transactions = self.miner.local_transactions(); let block_number = self.client.chain_info().best_block_number; Ok(transactions @@ -418,13 +412,8 @@ impl Parity for ParityClient where fn node_kind(&self) -> Result<::v1::types::NodeKind> { use ::v1::types::{NodeKind, Availability, Capability}; - let availability = match self.accounts { - Some(_) => Availability::Personal, - None => Availability::Public - }; - Ok(NodeKind { - availability: availability, + availability: Availability::Personal, capability: Capability::Full, }) } diff --git a/rpc/src/v1/impls/parity_accounts.rs b/rpc/src/v1/impls/parity_accounts.rs index 8de8fea900..adb97db28d 100644 --- a/rpc/src/v1/impls/parity_accounts.rs +++ b/rpc/src/v1/impls/parity_accounts.rs @@ -25,18 +25,17 @@ use ethcore::account_provider::AccountProvider; use jsonrpc_core::Result; use v1::helpers::errors; -use v1::helpers::accounts::unwrap_provider; use v1::traits::ParityAccounts; use v1::types::{H160 as RpcH160, H256 as RpcH256, H520 as RpcH520, DappId, Derive, DeriveHierarchical, DeriveHash, ExtAccountInfo}; /// Account management (personal) rpc implementation. pub struct ParityAccountsClient { - accounts: Option>, + accounts: Arc, } impl ParityAccountsClient { /// Creates new PersonalClient - pub fn new(store: &Option>) -> Self { + pub fn new(store: &Arc) -> Self { ParityAccountsClient { accounts: store.clone(), } @@ -45,7 +44,7 @@ impl ParityAccountsClient { /// Attempt to get the `Arc`, errors if provider was not /// set. fn account_provider(&self) -> Result> { - unwrap_provider(&self.accounts) + Ok(self.accounts.clone()) } } diff --git a/rpc/src/v1/impls/personal.rs b/rpc/src/v1/impls/personal.rs index 03495fd37f..da5ef983a2 100644 --- a/rpc/src/v1/impls/personal.rs +++ b/rpc/src/v1/impls/personal.rs @@ -28,7 +28,6 @@ use jsonrpc_core::{BoxFuture, Result}; use jsonrpc_core::futures::{future, Future}; use v1::helpers::errors; use v1::helpers::dispatch::{self, eth_data_hash, Dispatcher, SignWith}; -use v1::helpers::accounts::unwrap_provider; use v1::traits::Personal; use v1::types::{ H160 as RpcH160, H256 as RpcH256, H520 as RpcH520, U128 as RpcU128, @@ -42,23 +41,23 @@ use v1::metadata::Metadata; /// Account management (personal) rpc implementation. pub struct PersonalClient { - accounts: Option>, + accounts: Arc, dispatcher: D, allow_perm_unlock: bool, } impl PersonalClient { /// Creates new PersonalClient - pub fn new(accounts: Option>, dispatcher: D, allow_perm_unlock: bool) -> Self { + pub fn new(accounts: &Arc, dispatcher: D, allow_perm_unlock: bool) -> Self { PersonalClient { - accounts, + accounts: accounts.clone(), dispatcher, allow_perm_unlock, } } fn account_provider(&self) -> Result> { - unwrap_provider(&self.accounts) + Ok(self.accounts.clone()) } } diff --git a/rpc/src/v1/impls/private.rs b/rpc/src/v1/impls/private.rs index ab5866e4a7..4034d2b9a1 100644 --- a/rpc/src/v1/impls/private.rs +++ b/rpc/src/v1/impls/private.rs @@ -47,7 +47,7 @@ impl PrivateClient { fn unwrap_manager(&self) -> Result<&PrivateTransactionManager, Error> { match self.private { Some(ref arc) => Ok(&**arc), - None => Err(errors::public_unsupported(None)), + None => Err(errors::light_unimplemented(None)), } } } @@ -119,4 +119,3 @@ impl Private for PrivateClient { Ok(key.into()) } } - diff --git a/rpc/src/v1/impls/secretstore.rs b/rpc/src/v1/impls/secretstore.rs index 5a60192e8a..f85fa6f584 100644 --- a/rpc/src/v1/impls/secretstore.rs +++ b/rpc/src/v1/impls/secretstore.rs @@ -25,7 +25,6 @@ use ethcore::account_provider::AccountProvider; use jsonrpc_core::Result; use v1::helpers::errors; -use v1::helpers::accounts::unwrap_provider; use v1::helpers::secretstore::{generate_document_key, encrypt_document, decrypt_document, decrypt_document_with_shadow, ordered_servers_keccak}; use v1::traits::SecretStore; @@ -33,12 +32,12 @@ use v1::types::{H160, H256, H512, Bytes, EncryptedDocumentKey}; /// Parity implementation. pub struct SecretStoreClient { - accounts: Option>, + accounts: Arc, } impl SecretStoreClient { /// Creates new SecretStoreClient - pub fn new(store: &Option>) -> Self { + pub fn new(store: &Arc) -> Self { SecretStoreClient { accounts: store.clone(), } @@ -47,7 +46,7 @@ impl SecretStoreClient { /// Attempt to get the `Arc`, errors if provider was not /// set. fn account_provider(&self) -> Result> { - unwrap_provider(&self.accounts) + Ok(self.accounts.clone()) } /// Decrypt public key using account' private key diff --git a/rpc/src/v1/impls/signer.rs b/rpc/src/v1/impls/signer.rs index 2e8d41c4ac..eafa07ad4d 100644 --- a/rpc/src/v1/impls/signer.rs +++ b/rpc/src/v1/impls/signer.rs @@ -30,7 +30,6 @@ use jsonrpc_core::futures::{future, Future, IntoFuture}; use jsonrpc_core::futures::future::Either; use jsonrpc_pubsub::SubscriptionId; use jsonrpc_macros::pubsub::{Sink, Subscriber}; -use v1::helpers::accounts::unwrap_provider; use v1::helpers::dispatch::{self, Dispatcher, WithToken, eth_data_hash}; use v1::helpers::{errors, SignerService, SigningQueue, ConfirmationPayload, FilledTransactionRequest, Subscribers}; use v1::metadata::Metadata; @@ -40,7 +39,7 @@ use v1::types::{TransactionModification, ConfirmationRequest, ConfirmationRespon /// Transactions confirmation (personal) rpc implementation. pub struct SignerClient { signer: Arc, - accounts: Option>, + accounts: Arc, dispatcher: D, subscribers: Arc>>>>, } @@ -48,7 +47,7 @@ pub struct SignerClient { impl SignerClient { /// Create new instance of signer client. pub fn new( - store: &Option>, + store: &Arc, dispatcher: D, signer: &Arc, remote: Remote, @@ -79,7 +78,7 @@ impl SignerClient { } fn account_provider(&self) -> Result> { - unwrap_provider(&self.accounts) + Ok(self.accounts.clone()) } fn confirm_internal(&self, id: U256, modification: TransactionModification, f: F) -> BoxFuture> where diff --git a/rpc/src/v1/impls/signing.rs b/rpc/src/v1/impls/signing.rs index d8a27e9526..71cf18a06b 100644 --- a/rpc/src/v1/impls/signing.rs +++ b/rpc/src/v1/impls/signing.rs @@ -32,7 +32,6 @@ use v1::helpers::{ ConfirmationResult as RpcConfirmationResult, }; use v1::helpers::dispatch::{self, Dispatcher}; -use v1::helpers::accounts::unwrap_provider; use v1::metadata::Metadata; use v1::traits::{EthSigning, ParitySigning}; use v1::types::{ @@ -90,7 +89,7 @@ fn schedule(remote: Remote, /// Implementation of functions that require signing when no trusted signer is used. pub struct SigningQueueClient { signer: Arc, - accounts: Option>, + accounts: Arc, dispatcher: D, remote: Remote, // None here means that the request hasn't yet been confirmed @@ -99,7 +98,7 @@ pub struct SigningQueueClient { impl SigningQueueClient { /// Creates a new signing queue client given shared signing queue. - pub fn new(signer: &Arc, dispatcher: D, remote: Remote, accounts: &Option>) -> Self { + pub fn new(signer: &Arc, dispatcher: D, remote: Remote, accounts: &Arc) -> Self { SigningQueueClient { signer: signer.clone(), accounts: accounts.clone(), @@ -110,7 +109,7 @@ impl SigningQueueClient { } fn account_provider(&self) -> Result> { - unwrap_provider(&self.accounts) + Ok(self.accounts.clone()) } fn dispatch(&self, payload: RpcConfirmationPayload, default_account: DefaultAccount, origin: Origin) -> BoxFuture { diff --git a/rpc/src/v1/impls/signing_unsafe.rs b/rpc/src/v1/impls/signing_unsafe.rs index ddac36a61e..75f5f5e2bf 100644 --- a/rpc/src/v1/impls/signing_unsafe.rs +++ b/rpc/src/v1/impls/signing_unsafe.rs @@ -24,7 +24,6 @@ use jsonrpc_core::{BoxFuture, Result}; use jsonrpc_core::futures::{future, Future}; use v1::helpers::{errors, DefaultAccount}; use v1::helpers::dispatch::{self, Dispatcher}; -use v1::helpers::accounts::unwrap_provider; use v1::metadata::Metadata; use v1::traits::{EthSigning, ParitySigning}; use v1::types::{ @@ -39,13 +38,13 @@ use v1::types::{ /// Implementation of functions that require signing when no trusted signer is used. pub struct SigningUnsafeClient { - accounts: Option>, + accounts: Arc, dispatcher: D, } impl SigningUnsafeClient { /// Creates new SigningUnsafeClient. - pub fn new(accounts: &Option>, dispatcher: D) -> Self { + pub fn new(accounts: &Arc, dispatcher: D) -> Self { SigningUnsafeClient { accounts: accounts.clone(), dispatcher: dispatcher, @@ -53,7 +52,7 @@ impl SigningUnsafeClient { } fn account_provider(&self) -> Result> { - unwrap_provider(&self.accounts) + Ok(self.accounts.clone()) } fn handle(&self, payload: RpcConfirmationPayload, account: DefaultAccount) -> BoxFuture { diff --git a/rpc/src/v1/tests/eth.rs b/rpc/src/v1/tests/eth.rs index 26117471ce..e0931ae6bf 100644 --- a/rpc/src/v1/tests/eth.rs +++ b/rpc/src/v1/tests/eth.rs @@ -101,7 +101,7 @@ impl EthTester { fn from_spec(spec: Spec) -> Self { let account_provider = account_provider(); - let opt_account_provider = Some(account_provider.clone()); + let opt_account_provider = account_provider.clone(); let miner_service = miner_service(&spec, account_provider.clone()); let snapshot_service = snapshot_service(); diff --git a/rpc/src/v1/tests/mocked/eth.rs b/rpc/src/v1/tests/mocked/eth.rs index 39a2e842db..a6c8772439 100644 --- a/rpc/src/v1/tests/mocked/eth.rs +++ b/rpc/src/v1/tests/mocked/eth.rs @@ -86,7 +86,7 @@ impl EthTester { let client = blockchain_client(); let sync = sync_provider(); let ap = accounts_provider(); - let opt_ap = Some(ap.clone()); + let opt_ap = ap.clone(); let miner = miner_service(); let snapshot = snapshot_service(); let hashrates = Arc::new(Mutex::new(HashMap::new())); diff --git a/rpc/src/v1/tests/mocked/parity.rs b/rpc/src/v1/tests/mocked/parity.rs index 5835e2e82c..c27615a589 100644 --- a/rpc/src/v1/tests/mocked/parity.rs +++ b/rpc/src/v1/tests/mocked/parity.rs @@ -81,7 +81,7 @@ impl Dependencies { } pub fn client(&self, signer: Option>) -> TestParityClient { - let opt_accounts = Some(self.accounts.clone()); + let opt_accounts = self.accounts.clone(); ParityClient::new( self.client.clone(), diff --git a/rpc/src/v1/tests/mocked/parity_accounts.rs b/rpc/src/v1/tests/mocked/parity_accounts.rs index 258310b85a..c30b4b9ced 100644 --- a/rpc/src/v1/tests/mocked/parity_accounts.rs +++ b/rpc/src/v1/tests/mocked/parity_accounts.rs @@ -40,7 +40,7 @@ fn accounts_provider_with_vaults_support(temp_path: &str) -> Arc) -> ParityAccountsTester { - let opt_ap = Some(accounts_provider.clone()); + let opt_ap = accounts_provider.clone(); let parity_accounts = ParityAccountsClient::new(&opt_ap); let mut io = IoHandler::default(); io.extend_with(parity_accounts.to_delegate()); diff --git a/rpc/src/v1/tests/mocked/personal.rs b/rpc/src/v1/tests/mocked/personal.rs index c11aca42fb..323f9fe137 100644 --- a/rpc/src/v1/tests/mocked/personal.rs +++ b/rpc/src/v1/tests/mocked/personal.rs @@ -52,13 +52,13 @@ fn miner_service() -> Arc { fn setup() -> PersonalTester { let accounts = accounts_provider(); - let opt_accounts = Some(accounts.clone()); + let opt_accounts = accounts.clone(); let client = blockchain_client(); let miner = miner_service(); let reservations = Arc::new(Mutex::new(nonce::Reservations::new())); let dispatcher = FullDispatcher::new(client, miner.clone(), reservations, 50); - let personal = PersonalClient::new(opt_accounts, dispatcher, false); + let personal = PersonalClient::new(&opt_accounts, dispatcher, false); let mut io = IoHandler::default(); io.extend_with(personal.to_delegate()); diff --git a/rpc/src/v1/tests/mocked/secretstore.rs b/rpc/src/v1/tests/mocked/secretstore.rs index d3ab781bcf..6ee9b6c245 100644 --- a/rpc/src/v1/tests/mocked/secretstore.rs +++ b/rpc/src/v1/tests/mocked/secretstore.rs @@ -40,7 +40,7 @@ impl Dependencies { } pub fn client(&self) -> SecretStoreClient { - SecretStoreClient::new(&Some(self.accounts.clone())) + SecretStoreClient::new(&self.accounts) } fn default_client(&self) -> IoHandler { diff --git a/rpc/src/v1/tests/mocked/signer.rs b/rpc/src/v1/tests/mocked/signer.rs index bee28b35ec..8881dc41c3 100644 --- a/rpc/src/v1/tests/mocked/signer.rs +++ b/rpc/src/v1/tests/mocked/signer.rs @@ -58,7 +58,7 @@ fn miner_service() -> Arc { fn signer_tester() -> SignerTester { let signer = Arc::new(SignerService::new_test(false)); let accounts = accounts_provider(); - let opt_accounts = Some(accounts.clone()); + let opt_accounts = accounts.clone(); let client = blockchain_client(); let miner = miner_service(); let reservations = Arc::new(Mutex::new(nonce::Reservations::new())); diff --git a/rpc/src/v1/tests/mocked/signing.rs b/rpc/src/v1/tests/mocked/signing.rs index 3a56c5a0d3..84cf2e376e 100644 --- a/rpc/src/v1/tests/mocked/signing.rs +++ b/rpc/src/v1/tests/mocked/signing.rs @@ -56,7 +56,7 @@ impl Default for SigningTester { let client = Arc::new(TestBlockChainClient::default()); let miner = Arc::new(TestMinerService::default()); let accounts = Arc::new(AccountProvider::transient_provider()); - let opt_accounts = Some(accounts.clone()); + let opt_accounts = accounts.clone(); let reservations = Arc::new(Mutex::new(nonce::Reservations::new())); let mut io = IoHandler::default(); -- GitLab From 2060ea5de388f7b3b515ba5c2d58425585a8ac1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Silva?= Date: Sat, 2 Jun 2018 09:29:44 +0100 Subject: [PATCH 093/152] ethcore-sync: fix connection to peers behind chain fork block (#8710) --- ethcore/sync/src/chain/handler.rs | 43 ++++++++++++++----------------- ethcore/sync/src/chain/mod.rs | 2 ++ 2 files changed, 22 insertions(+), 23 deletions(-) diff --git a/ethcore/sync/src/chain/handler.rs b/ethcore/sync/src/chain/handler.rs index 7668a64594..75111a4d4a 100644 --- a/ethcore/sync/src/chain/handler.rs +++ b/ethcore/sync/src/chain/handler.rs @@ -332,14 +332,6 @@ impl SyncHandler { Ok(()) } - fn on_peer_confirmed(sync: &mut ChainSync, io: &mut SyncIo, peer_id: PeerId) { - { - let peer = sync.peers.get_mut(&peer_id).expect("Is only called when peer is present in peers"); - peer.confirmation = ForkConfirmation::Confirmed; - } - sync.sync_peer(io, peer_id, false); - } - fn on_peer_fork_header(sync: &mut ChainSync, io: &mut SyncIo, peer_id: PeerId, r: &Rlp) -> Result<(), PacketDecodeError> { { let peer = sync.peers.get_mut(&peer_id).expect("Is only called when peer is present in peers"); @@ -349,24 +341,27 @@ impl SyncHandler { if item_count == 0 || item_count != 1 { trace!(target: "sync", "{}: Chain is too short to confirm the block", peer_id); - io.disable_peer(peer_id); - return Ok(()); - } + peer.confirmation = ForkConfirmation::TooShort; - let header = r.at(0)?.as_raw(); - if keccak(&header) != fork_hash { - trace!(target: "sync", "{}: Fork mismatch", peer_id); - io.disable_peer(peer_id); - return Ok(()); - } + } else { + let header = r.at(0)?.as_raw(); + if keccak(&header) != fork_hash { + trace!(target: "sync", "{}: Fork mismatch", peer_id); + io.disable_peer(peer_id); + return Ok(()); + } + + trace!(target: "sync", "{}: Confirmed peer", peer_id); + peer.confirmation = ForkConfirmation::Confirmed; - trace!(target: "sync", "{}: Confirmed peer", peer_id); - if !io.chain_overlay().read().contains_key(&fork_number) { - trace!(target: "sync", "Inserting (fork) block {} header", fork_number); - io.chain_overlay().write().insert(fork_number, header.to_vec()); + if !io.chain_overlay().read().contains_key(&fork_number) { + trace!(target: "sync", "Inserting (fork) block {} header", fork_number); + io.chain_overlay().write().insert(fork_number, header.to_vec()); + } } } - SyncHandler::on_peer_confirmed(sync, io, peer_id); + + sync.sync_peer(io, peer_id, false); return Ok(()); } @@ -686,7 +681,9 @@ impl SyncHandler { SyncRequester::request_fork_header(sync, io, peer_id, fork_block); }, _ => { - SyncHandler::on_peer_confirmed(sync, io, peer_id); + // when there's no `fork_block` defined we initialize the peer with + // `confirmation: ForkConfirmation::Confirmed`. + sync.sync_peer(io, peer_id, false); } } diff --git a/ethcore/sync/src/chain/mod.rs b/ethcore/sync/src/chain/mod.rs index 5af2892549..c0ee8299b8 100644 --- a/ethcore/sync/src/chain/mod.rs +++ b/ethcore/sync/src/chain/mod.rs @@ -294,6 +294,8 @@ pub enum BlockSet { pub enum ForkConfirmation { /// Fork block confirmation pending. Unconfirmed, + /// Peer's chain is too short to confirm the fork. + TooShort, /// Fork is confirmed. Confirmed, } -- GitLab From 3d76417353a0dfe24517815fedb0ad646e6a3add Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Sat, 2 Jun 2018 11:05:11 +0200 Subject: [PATCH 094/152] Remove HostTrait altogether (#8681) --- ethcore/light/src/net/mod.rs | 4 ++-- ethcore/sync/src/api.rs | 4 ++-- util/network-devp2p/src/handshake.rs | 2 +- util/network-devp2p/src/host.rs | 6 +----- util/network-devp2p/src/lib.rs | 2 +- util/network-devp2p/src/session.rs | 2 +- util/network-devp2p/tests/tests.rs | 2 +- util/network/src/lib.rs | 7 +------ whisper/src/net/mod.rs | 10 +++------- 9 files changed, 13 insertions(+), 26 deletions(-) diff --git a/ethcore/light/src/net/mod.rs b/ethcore/light/src/net/mod.rs index 27d5c12a5f..d8a975dc3f 100644 --- a/ethcore/light/src/net/mod.rs +++ b/ethcore/light/src/net/mod.rs @@ -21,7 +21,7 @@ use transaction::UnverifiedTransaction; use io::TimerToken; -use network::{HostInfo, NetworkProtocolHandler, NetworkContext, PeerId}; +use network::{NetworkProtocolHandler, NetworkContext, PeerId}; use rlp::{RlpStream, Rlp}; use ethereum_types::{H256, U256}; use kvdb::DBValue; @@ -1082,7 +1082,7 @@ fn punish(peer: PeerId, io: &IoContext, e: Error) { } impl NetworkProtocolHandler for LightProtocol { - fn initialize(&self, io: &NetworkContext, _host_info: &HostInfo) { + fn initialize(&self, io: &NetworkContext) { io.register_timer(TIMEOUT, TIMEOUT_INTERVAL) .expect("Error registering sync timer."); io.register_timer(TICK_TIMEOUT, TICK_TIMEOUT_INTERVAL) diff --git a/ethcore/sync/src/api.rs b/ethcore/sync/src/api.rs index 9e6cdafa6e..8419fccd7a 100644 --- a/ethcore/sync/src/api.rs +++ b/ethcore/sync/src/api.rs @@ -21,7 +21,7 @@ use std::ops::Range; use std::time::Duration; use bytes::Bytes; use devp2p::NetworkService; -use network::{NetworkProtocolHandler, NetworkContext, HostInfo, PeerId, ProtocolId, +use network::{NetworkProtocolHandler, NetworkContext, PeerId, ProtocolId, NetworkConfiguration as BasicNetworkConfiguration, NonReservedPeerMode, Error, ErrorKind, ConnectionFilter}; use ethereum_types::{H256, H512, U256}; @@ -371,7 +371,7 @@ struct SyncProtocolHandler { } impl NetworkProtocolHandler for SyncProtocolHandler { - fn initialize(&self, io: &NetworkContext, _host_info: &HostInfo) { + fn initialize(&self, io: &NetworkContext) { if io.subprotocol_name() != WARP_SYNC_PROTOCOL_ID { io.register_timer(0, Duration::from_secs(1)).expect("Error registering sync timer"); } diff --git a/util/network-devp2p/src/handshake.rs b/util/network-devp2p/src/handshake.rs index 891dd7c257..ffe0276d97 100644 --- a/util/network-devp2p/src/handshake.rs +++ b/util/network-devp2p/src/handshake.rs @@ -26,7 +26,7 @@ use node_table::NodeId; use io::{IoContext, StreamToken}; use ethkey::{KeyPair, Public, Secret, recover, sign, Generator, Random}; use ethkey::crypto::{ecdh, ecies}; -use network::{Error, ErrorKind, HostInfo as HostInfoTrait}; +use network::{Error, ErrorKind}; use host::HostInfo; #[derive(PartialEq, Eq, Debug)] diff --git a/util/network-devp2p/src/host.rs b/util/network-devp2p/src/host.rs index f9180700fe..245492de80 100644 --- a/util/network-devp2p/src/host.rs +++ b/util/network-devp2p/src/host.rs @@ -39,7 +39,6 @@ use PROTOCOL_VERSION; use node_table::*; use network::{NetworkConfiguration, NetworkIoMessage, ProtocolId, PeerId, PacketId}; use network::{NonReservedPeerMode, NetworkContext as NetworkContextTrait}; -use network::HostInfo as HostInfoTrait; use network::{SessionInfo, Error, ErrorKind, DisconnectReason, NetworkProtocolHandler}; use discovery::{Discovery, TableUpdates, NodeEntry}; use ip_utils::{map_external_address, select_public_address}; @@ -223,10 +222,8 @@ impl HostInfo { pub(crate) fn secret(&self) -> &Secret { self.keys.secret() } -} -impl HostInfoTrait for HostInfo { - fn id(&self) -> &NodeId { + pub(crate) fn id(&self) -> &NodeId { self.keys.public() } } @@ -997,7 +994,6 @@ impl IoHandler for Host { let reserved = self.reserved_nodes.read(); h.initialize( &NetworkContext::new(io, *protocol, None, self.sessions.clone(), &reserved), - &*self.info.read(), ); self.handlers.write().insert(*protocol, h); let mut info = self.info.write(); diff --git a/util/network-devp2p/src/lib.rs b/util/network-devp2p/src/lib.rs index 244997a654..12383fdbee 100644 --- a/util/network-devp2p/src/lib.rs +++ b/util/network-devp2p/src/lib.rs @@ -29,7 +29,7 @@ //! struct MyHandler; //! //! impl NetworkProtocolHandler for MyHandler { -//! fn initialize(&self, io: &NetworkContext, _host_info: &HostInfo) { +//! fn initialize(&self, io: &NetworkContext) { //! io.register_timer(0, Duration::from_secs(1)); //! } //! diff --git a/util/network-devp2p/src/session.rs b/util/network-devp2p/src/session.rs index cd8ef56bd4..f830dcc0d7 100644 --- a/util/network-devp2p/src/session.rs +++ b/util/network-devp2p/src/session.rs @@ -28,7 +28,7 @@ use connection::{EncryptedConnection, Packet, Connection, MAX_PAYLOAD_SIZE}; use handshake::Handshake; use io::{IoContext, StreamToken}; use network::{Error, ErrorKind, DisconnectReason, SessionInfo, ProtocolId, PeerCapabilityInfo}; -use network::{SessionCapabilityInfo, HostInfo as HostInfoTrait}; +use network::SessionCapabilityInfo; use host::*; use node_table::NodeId; use snappy; diff --git a/util/network-devp2p/tests/tests.rs b/util/network-devp2p/tests/tests.rs index a1d178d654..3c2333cd10 100644 --- a/util/network-devp2p/tests/tests.rs +++ b/util/network-devp2p/tests/tests.rs @@ -70,7 +70,7 @@ impl TestProtocol { } impl NetworkProtocolHandler for TestProtocol { - fn initialize(&self, io: &NetworkContext, _host_info: &HostInfo) { + fn initialize(&self, io: &NetworkContext) { io.register_timer(0, Duration::from_millis(10)).unwrap(); } diff --git a/util/network/src/lib.rs b/util/network/src/lib.rs index 87d3ed9b0e..a04eb04880 100644 --- a/util/network/src/lib.rs +++ b/util/network/src/lib.rs @@ -333,17 +333,12 @@ impl<'a, T> NetworkContext for &'a T where T: ?Sized + NetworkContext { } } -pub trait HostInfo { - /// Returns public key - fn id(&self) -> &NodeId; -} - /// Network IO protocol handler. This needs to be implemented for each new subprotocol. /// All the handler function are called from within IO event loop. /// `Message` is the type for message data. pub trait NetworkProtocolHandler: Sync + Send { /// Initialize the handler - fn initialize(&self, _io: &NetworkContext, _host_info: &HostInfo) {} + fn initialize(&self, _io: &NetworkContext) {} /// Called when new network packet received. fn read(&self, io: &NetworkContext, peer: &PeerId, packet_id: u8, data: &[u8]); /// Called when new peer is connected. Only called when peer supports the same protocol. diff --git a/whisper/src/net/mod.rs b/whisper/src/net/mod.rs index c462baa9d7..1115b17d4f 100644 --- a/whisper/src/net/mod.rs +++ b/whisper/src/net/mod.rs @@ -23,7 +23,7 @@ use std::time::{Duration, SystemTime}; use std::sync::Arc; use ethereum_types::{H256, H512}; -use network::{self, HostInfo, NetworkContext, NodeId, PeerId, ProtocolId, TimerToken}; +use network::{self, NetworkContext, NodeId, PeerId, ProtocolId, TimerToken}; use ordered_float::OrderedFloat; use parking_lot::{Mutex, RwLock}; use rlp::{DecoderError, RlpStream, Rlp}; @@ -423,7 +423,6 @@ pub struct Network { messages: Arc>, handler: T, peers: RwLock>>, - node_key: RwLock, } // public API. @@ -434,7 +433,6 @@ impl Network { messages: Arc::new(RwLock::new(Messages::new(messages_size_bytes))), handler: handler, peers: RwLock::new(HashMap::new()), - node_key: RwLock::new(Default::default()), } } @@ -685,12 +683,10 @@ impl Network { } impl ::network::NetworkProtocolHandler for Network { - fn initialize(&self, io: &NetworkContext, host_info: &HostInfo) { + fn initialize(&self, io: &NetworkContext) { // set up broadcast timer (< 1s) io.register_timer(RALLY_TOKEN, RALLY_TIMEOUT) .expect("Failed to initialize message rally timer"); - - *self.node_key.write() = host_info.id().clone(); } fn read(&self, io: &NetworkContext, peer: &PeerId, packet_id: u8, data: &[u8]) { @@ -720,7 +716,7 @@ impl ::network::NetworkProtocolHandler for Network { pub struct ParityExtensions; impl ::network::NetworkProtocolHandler for ParityExtensions { - fn initialize(&self, _io: &NetworkContext, _host_info: &HostInfo) { } + fn initialize(&self, _io: &NetworkContext) { } fn read(&self, _io: &NetworkContext, _peer: &PeerId, _id: u8, _msg: &[u8]) { } -- GitLab From 98b7c07171cd320f32877dfa5aa528f585dc9a72 Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Mon, 4 Jun 2018 10:19:50 +0200 Subject: [PATCH 095/152] Update `license header` and `scripts` (#8666) * Update `add_license` script * run script * add `remove duplicate lines script` and run it * Revert changes `English spaces` * strip whitespaces * Revert `GPL` in files with `apache/mit license` * don't append `gpl license` in files with other lic * Don't append `gpl header` in files with other lic. * re-ran script * include c and cpp files too * remove duplicate header * rebase nit --- chainspec/src/main.rs | 16 +++++++++++ dapps/js-glue/build.rs | 3 +-- dapps/js-glue/src/build.rs | 15 +++++++++++ dapps/js-glue/src/codegen.rs | 2 +- dapps/js-glue/src/js.rs | 2 +- dapps/js-glue/src/lib.rs | 3 +-- dapps/js-glue/src/lib.rs.in | 7 ++--- dapps/node-health/src/health.rs | 2 +- dapps/node-health/src/lib.rs | 2 +- dapps/node-health/src/time.rs | 2 +- dapps/node-health/src/types.rs | 2 +- dapps/src/api/api.rs | 2 +- dapps/src/api/mod.rs | 2 +- dapps/src/api/response.rs | 2 +- dapps/src/api/types.rs | 2 +- dapps/src/apps/app.rs | 2 +- dapps/src/apps/cache.rs | 2 +- dapps/src/apps/fetcher/installers.rs | 2 +- dapps/src/apps/fetcher/mod.rs | 2 +- dapps/src/apps/fs.rs | 4 +-- dapps/src/apps/manifest.rs | 2 +- dapps/src/apps/mod.rs | 2 +- dapps/src/apps/ui.rs | 2 +- dapps/src/endpoint.rs | 2 +- dapps/src/handlers/content.rs | 2 +- dapps/src/handlers/echo.rs | 2 +- dapps/src/handlers/fetch.rs | 3 +-- dapps/src/handlers/mod.rs | 2 +- dapps/src/handlers/reader.rs | 2 +- dapps/src/handlers/redirect.rs | 2 +- dapps/src/handlers/streaming.rs | 2 +- dapps/src/lib.rs | 3 +-- dapps/src/page/builtin.rs | 3 +-- dapps/src/page/handler.rs | 2 +- dapps/src/page/local.rs | 3 +-- dapps/src/page/mod.rs | 4 +-- dapps/src/proxypac.rs | 4 +-- dapps/src/router.rs | 2 +- dapps/src/tests/api.rs | 3 +-- dapps/src/tests/fetch.rs | 3 +-- dapps/src/tests/helpers/fetch.rs | 2 +- dapps/src/tests/helpers/mod.rs | 3 +-- dapps/src/tests/helpers/registrar.rs | 2 +- dapps/src/tests/home.rs | 2 +- dapps/src/tests/mod.rs | 3 +-- dapps/src/tests/redirection.rs | 3 +-- dapps/src/tests/rpc.rs | 2 +- dapps/src/tests/validation.rs | 2 +- dapps/src/web.rs | 3 +-- dapps/ui/src/lib.rs | 3 +-- devtools/src/http_client.rs | 2 +- devtools/src/lib.rs | 2 +- ethash/src/cache.rs | 2 +- ethash/src/compute.rs | 2 +- ethash/src/keccak.rs | 2 +- ethash/src/lib.rs | 2 +- ethash/src/seed_compute.rs | 2 +- ethash/src/shared.rs | 2 +- ethcore/benches/evm.rs | 4 +-- ethcore/crypto/src/aes.rs | 3 +-- ethcore/crypto/src/aes_gcm.rs | 3 +-- ethcore/crypto/src/digest.rs | 2 +- ethcore/crypto/src/error.rs | 3 +-- ethcore/crypto/src/hmac.rs | 3 +-- ethcore/crypto/src/lib.rs | 3 +-- ethcore/crypto/src/pbkdf2.rs | 3 +-- ethcore/crypto/src/scrypt.rs | 3 +-- ethcore/evm/src/benches/mod.rs | 2 +- ethcore/evm/src/evm.rs | 2 +- ethcore/evm/src/factory.rs | 2 +- ethcore/evm/src/instructions.rs | 2 +- ethcore/evm/src/interpreter/gasometer.rs | 4 +-- ethcore/evm/src/interpreter/informant.rs | 2 +- ethcore/evm/src/interpreter/memory.rs | 2 +- ethcore/evm/src/interpreter/mod.rs | 4 +-- ethcore/evm/src/interpreter/shared_cache.rs | 3 +-- ethcore/evm/src/interpreter/stack.rs | 3 +-- ethcore/evm/src/lib.rs | 2 +- ethcore/evm/src/tests.rs | 2 +- ethcore/evm/src/vmtype.rs | 2 +- ethcore/light/src/cache.rs | 2 +- ethcore/light/src/cht.rs | 5 +++- ethcore/light/src/client/fetch.rs | 2 +- ethcore/light/src/client/header_chain.rs | 2 +- ethcore/light/src/client/mod.rs | 3 +-- ethcore/light/src/client/service.rs | 2 +- ethcore/light/src/lib.rs | 2 +- ethcore/light/src/net/context.rs | 5 ++-- ethcore/light/src/net/error.rs | 2 +- ethcore/light/src/net/load_timer.rs | 2 +- ethcore/light/src/net/mod.rs | 3 +-- ethcore/light/src/net/request_credits.rs | 2 +- ethcore/light/src/net/request_set.rs | 2 +- ethcore/light/src/net/status.rs | 2 +- ethcore/light/src/net/tests/mod.rs | 2 +- ethcore/light/src/on_demand/mod.rs | 2 +- ethcore/light/src/on_demand/request.rs | 3 +-- ethcore/light/src/on_demand/tests.rs | 2 +- ethcore/light/src/provider.rs | 2 +- ethcore/light/src/transaction_queue.rs | 2 +- ethcore/light/src/types/mod.rs | 2 +- ethcore/light/src/types/request/batch.rs | 2 +- ethcore/light/src/types/request/mod.rs | 4 +-- ethcore/node_filter/src/lib.rs | 3 +-- ethcore/private-tx/src/encryptor.rs | 2 +- ethcore/private-tx/src/error.rs | 3 +-- ethcore/private-tx/src/lib.rs | 2 +- ethcore/private-tx/src/messages.rs | 2 +- .../private-tx/src/private_transactions.rs | 2 +- ethcore/private-tx/tests/private_contract.rs | 2 +- ethcore/service/src/service.rs | 2 +- ethcore/src/account_db.rs | 2 +- ethcore/src/account_provider/mod.rs | 2 +- ethcore/src/account_provider/stores.rs | 2 +- ethcore/src/block.rs | 2 +- ethcore/src/blockchain/best_block.rs | 2 +- ethcore/src/blockchain/block_info.rs | 2 +- ethcore/src/blockchain/blockchain.rs | 2 +- ethcore/src/blockchain/cache.rs | 2 +- ethcore/src/blockchain/config.rs | 2 +- ethcore/src/blockchain/extras.rs | 2 +- ethcore/src/blockchain/generator.rs | 2 +- ethcore/src/blockchain/import_route.rs | 2 +- ethcore/src/blockchain/mod.rs | 2 +- ethcore/src/blockchain/update.rs | 16 +++++++++++ ethcore/src/blooms/bloom_group.rs | 2 +- ethcore/src/blooms/group_position.rs | 2 +- ethcore/src/blooms/mod.rs | 2 +- ethcore/src/builtin.rs | 5 +--- ethcore/src/cache_manager.rs | 2 +- ethcore/src/client/ancient_import.rs | 2 +- ethcore/src/client/chain_notify.rs | 2 +- ethcore/src/client/client.rs | 6 +---- ethcore/src/client/config.rs | 3 +-- ethcore/src/client/error.rs | 2 +- ethcore/src/client/evm_test_client.rs | 2 +- ethcore/src/client/io_message.rs | 1 - ethcore/src/client/mod.rs | 2 +- ethcore/src/client/private_notify.rs | 2 +- ethcore/src/client/test_client.rs | 3 +-- ethcore/src/client/trace.rs | 15 +++++++++++ ethcore/src/client/traits.rs | 2 +- ethcore/src/db.rs | 2 +- ethcore/src/encoded.rs | 2 +- .../src/engines/authority_round/finality.rs | 2 +- ethcore/src/engines/authority_round/mod.rs | 3 +-- ethcore/src/engines/basic_authority.rs | 2 +- ethcore/src/engines/epoch.rs | 2 +- ethcore/src/engines/instant_seal.rs | 2 +- ethcore/src/engines/mod.rs | 2 +- ethcore/src/engines/null_engine.rs | 2 +- ethcore/src/engines/signer.rs | 2 +- ethcore/src/engines/tendermint/message.rs | 3 +-- ethcore/src/engines/tendermint/mod.rs | 3 +-- ethcore/src/engines/tendermint/params.rs | 2 +- ethcore/src/engines/transition.rs | 2 +- ethcore/src/engines/validator_set/contract.rs | 2 +- ethcore/src/engines/validator_set/mod.rs | 2 +- ethcore/src/engines/validator_set/multi.rs | 2 +- .../engines/validator_set/safe_contract.rs | 2 +- .../src/engines/validator_set/simple_list.rs | 2 +- ethcore/src/engines/validator_set/test.rs | 2 +- ethcore/src/engines/vote_collector.rs | 2 +- ethcore/src/error.rs | 3 +-- ethcore/src/ethereum/denominations.rs | 3 +-- ethcore/src/ethereum/ethash.rs | 2 +- ethcore/src/ethereum/mod.rs | 2 +- ethcore/src/executed.rs | 2 +- ethcore/src/executive.rs | 2 +- ethcore/src/externalities.rs | 2 +- ethcore/src/factory.rs | 2 +- ethcore/src/header.rs | 3 +-- ethcore/src/json_tests/chain.rs | 3 +-- ethcore/src/json_tests/difficulty.rs | 6 +---- ethcore/src/json_tests/executive.rs | 2 +- ethcore/src/json_tests/mod.rs | 2 +- ethcore/src/json_tests/state.rs | 3 +-- ethcore/src/json_tests/test_common.rs | 2 +- ethcore/src/json_tests/transaction.rs | 2 +- ethcore/src/json_tests/trie.rs | 2 +- ethcore/src/lib.rs | 2 +- ethcore/src/machine.rs | 3 +-- ethcore/src/miner/miner.rs | 4 +-- ethcore/src/miner/mod.rs | 4 +-- ethcore/src/miner/pool_client.rs | 2 +- .../src/miner/service_transaction_checker.rs | 4 +-- ethcore/src/miner/stratum.rs | 3 +-- ethcore/src/pod_account.rs | 3 +-- ethcore/src/pod_state.rs | 2 +- ethcore/src/snapshot/account.rs | 2 +- ethcore/src/snapshot/block.rs | 2 +- ethcore/src/snapshot/consensus/authority.rs | 2 +- ethcore/src/snapshot/consensus/mod.rs | 3 +-- ethcore/src/snapshot/consensus/work.rs | 2 +- ethcore/src/snapshot/error.rs | 2 +- ethcore/src/snapshot/io.rs | 3 +-- ethcore/src/snapshot/mod.rs | 2 +- ethcore/src/snapshot/service.rs | 2 +- ethcore/src/snapshot/tests/helpers.rs | 2 +- ethcore/src/snapshot/tests/mod.rs | 2 +- .../src/snapshot/tests/proof_of_authority.rs | 3 +-- ethcore/src/snapshot/tests/proof_of_work.rs | 2 +- ethcore/src/snapshot/tests/service.rs | 2 +- ethcore/src/snapshot/tests/state.rs | 2 +- ethcore/src/snapshot/traits.rs | 2 +- ethcore/src/snapshot/watcher.rs | 2 +- ethcore/src/spec/genesis.rs | 2 +- ethcore/src/spec/mod.rs | 2 +- ethcore/src/spec/seal.rs | 2 +- ethcore/src/spec/spec.rs | 4 +-- ethcore/src/state/account.rs | 2 +- ethcore/src/state/backend.rs | 2 +- ethcore/src/state/mod.rs | 3 +-- ethcore/src/state/substate.rs | 2 +- ethcore/src/state_db.rs | 2 +- ethcore/src/test_helpers.rs | 3 +-- ethcore/src/test_helpers_internal.rs | 2 +- ethcore/src/tests/client.rs | 4 +-- ethcore/src/tests/mod.rs | 2 +- ethcore/src/tests/trace.rs | 2 +- ethcore/src/trace/config.rs | 2 +- ethcore/src/trace/db.rs | 3 +-- ethcore/src/trace/executive_tracer.rs | 2 +- ethcore/src/trace/import.rs | 2 +- ethcore/src/trace/mod.rs | 2 +- ethcore/src/trace/noop_tracer.rs | 2 +- ethcore/src/trace/types/error.rs | 2 +- ethcore/src/trace/types/filter.rs | 2 +- ethcore/src/trace/types/flat.rs | 2 +- ethcore/src/trace/types/localized.rs | 2 +- ethcore/src/trace/types/mod.rs | 2 +- ethcore/src/trace/types/trace.rs | 3 +-- ethcore/src/tx_filter.rs | 3 +-- ethcore/src/verification/canon_verifier.rs | 2 +- ethcore/src/verification/mod.rs | 2 +- ethcore/src/verification/noop_verifier.rs | 2 +- ethcore/src/verification/queue/kind.rs | 2 +- ethcore/src/verification/queue/mod.rs | 2 +- ethcore/src/verification/verification.rs | 2 +- ethcore/src/verification/verifier.rs | 2 +- ethcore/src/views/block.rs | 2 +- ethcore/src/views/body.rs | 2 +- ethcore/src/views/header.rs | 2 +- ethcore/src/views/mod.rs | 4 +-- ethcore/src/views/transaction.rs | 2 +- ethcore/src/views/view_rlp.rs | 4 +-- ethcore/stratum/src/lib.rs | 2 +- ethcore/stratum/src/traits.rs | 2 +- ethcore/sync/src/api.rs | 3 +-- ethcore/sync/src/block_sync.rs | 2 +- ethcore/sync/src/blocks.rs | 4 +-- ethcore/sync/src/chain/mod.rs | 3 +-- ethcore/sync/src/lib.rs | 2 +- ethcore/sync/src/light_sync/mod.rs | 2 +- ethcore/sync/src/light_sync/response.rs | 2 +- ethcore/sync/src/light_sync/sync_round.rs | 2 +- ethcore/sync/src/light_sync/tests/mod.rs | 2 +- ethcore/sync/src/light_sync/tests/test_net.rs | 2 +- ethcore/sync/src/private_tx.rs | 2 +- ethcore/sync/src/snapshot.rs | 3 +-- ethcore/sync/src/sync_io.rs | 4 +-- ethcore/sync/src/tests/chain.rs | 4 +-- ethcore/sync/src/tests/consensus.rs | 2 +- ethcore/sync/src/tests/helpers.rs | 2 +- ethcore/sync/src/tests/mod.rs | 2 +- ethcore/sync/src/tests/private.rs | 2 +- ethcore/sync/src/tests/rpc.rs | 2 +- ethcore/sync/src/tests/snapshot.rs | 3 +-- ethcore/sync/src/transactions_stats.rs | 2 +- ethcore/transaction/src/error.rs | 3 +-- ethcore/transaction/src/lib.rs | 2 +- ethcore/transaction/src/transaction.rs | 2 +- ethcore/types/src/account_diff.rs | 3 +-- ethcore/types/src/basic_account.rs | 2 +- ethcore/types/src/block_status.rs | 2 +- ethcore/types/src/blockchain_info.rs | 2 +- ethcore/types/src/call_analytics.rs | 2 +- ethcore/types/src/filter.rs | 2 +- ethcore/types/src/ids.rs | 2 +- ethcore/types/src/lib.rs | 2 +- ethcore/types/src/log_entry.rs | 2 +- ethcore/types/src/mode.rs | 2 +- ethcore/types/src/pruning_info.rs | 2 +- ethcore/types/src/receipt.rs | 2 +- ethcore/types/src/restoration_status.rs | 3 +-- ethcore/types/src/security_level.rs | 2 +- ethcore/types/src/snapshot_manifest.rs | 3 +-- ethcore/types/src/state_diff.rs | 2 +- ethcore/types/src/trace_filter.rs | 2 +- ethcore/types/src/tree_route.rs | 2 +- ethcore/types/src/verification_queue_info.rs | 2 +- ethcore/vm/src/action_params.rs | 2 +- ethcore/vm/src/call_type.rs | 16 +++++++++++ ethcore/vm/src/env_info.rs | 2 +- ethcore/vm/src/error.rs | 3 +-- ethcore/vm/src/ext.rs | 2 +- ethcore/vm/src/lib.rs | 2 +- ethcore/vm/src/return_data.rs | 2 ++ ethcore/vm/src/schedule.rs | 2 +- ethcore/vm/src/tests.rs | 2 +- ethcore/wasm/run/src/fixture.rs | 18 ++++++++++++- ethcore/wasm/run/src/main.rs | 16 +++++++++++ ethcore/wasm/run/src/runner.rs | 16 +++++++++++ ethcore/wasm/src/env.rs | 4 +-- ethcore/wasm/src/lib.rs | 2 +- ethcore/wasm/src/panic_payload.rs | 2 +- ethcore/wasm/src/parser.rs | 4 +-- ethcore/wasm/src/tests.rs | 2 +- ethkey/cli/src/main.rs | 2 +- ethkey/src/brain.rs | 2 +- ethkey/src/brain_prefix.rs | 2 +- ethkey/src/brain_recover.rs | 4 +-- ethkey/src/crypto.rs | 2 +- ethkey/src/error.rs | 2 +- ethkey/src/extended.rs | 2 +- ethkey/src/keccak.rs | 2 +- ethkey/src/keypair.rs | 2 +- ethkey/src/lib.rs | 2 +- ethkey/src/math.rs | 2 +- ethkey/src/prefix.rs | 2 +- ethkey/src/random.rs | 2 +- ethkey/src/secret.rs | 2 +- ethkey/src/signature.rs | 2 +- ethstore/cli/src/crack.rs | 16 +++++++++++ ethstore/cli/src/main.rs | 2 +- ethstore/cli/tests/cli.rs | 3 +-- ethstore/src/account/cipher.rs | 2 +- ethstore/src/account/crypto.rs | 2 +- ethstore/src/account/kdf.rs | 2 +- ethstore/src/account/mod.rs | 3 +-- ethstore/src/account/safe_account.rs | 2 +- ethstore/src/account/version.rs | 2 +- ethstore/src/accounts_dir/disk.rs | 3 +-- ethstore/src/accounts_dir/memory.rs | 3 +-- ethstore/src/accounts_dir/mod.rs | 2 +- ethstore/src/accounts_dir/vault.rs | 2 +- ethstore/src/error.rs | 2 +- ethstore/src/ethkey.rs | 2 +- ethstore/src/ethstore.rs | 2 +- ethstore/src/import.rs | 2 +- ethstore/src/json/bytes.rs | 3 +-- ethstore/src/json/cipher.rs | 2 +- ethstore/src/json/crypto.rs | 2 +- ethstore/src/json/error.rs | 2 +- ethstore/src/json/hash.rs | 2 +- ethstore/src/json/id.rs | 2 +- ethstore/src/json/kdf.rs | 2 +- ethstore/src/json/key_file.rs | 3 +-- ethstore/src/json/mod.rs | 2 +- ethstore/src/json/presale.rs | 16 +++++++++++ ethstore/src/json/vault_file.rs | 2 +- ethstore/src/json/vault_key_file.rs | 2 +- ethstore/src/json/version.rs | 3 +-- ethstore/src/lib.rs | 2 +- ethstore/src/presale.rs | 16 +++++++++++ ethstore/src/random.rs | 3 +-- ethstore/src/secret_store.rs | 2 +- ethstore/tests/api.rs | 2 +- ethstore/tests/util/mod.rs | 2 +- ethstore/tests/util/transient_dir.rs | 2 +- evmbin/benches/mod.rs | 3 +-- evmbin/src/display/json.rs | 3 +-- evmbin/src/display/mod.rs | 2 +- evmbin/src/display/simple.rs | 2 +- evmbin/src/display/std_json.rs | 2 +- evmbin/src/info.rs | 2 +- evmbin/src/main.rs | 3 +-- hash-fetch/src/client.rs | 2 +- hash-fetch/src/lib.rs | 2 +- hash-fetch/src/urlhint.rs | 5 +--- hw/src/ledger.rs | 2 +- hw/src/lib.rs | 3 +-- hw/src/trezor.rs | 3 +-- ipfs/src/error.rs | 2 +- ipfs/src/lib.rs | 2 +- ipfs/src/route.rs | 2 +- json/src/blockchain/account.rs | 2 +- json/src/blockchain/block.rs | 2 +- json/src/blockchain/blockchain.rs | 2 +- json/src/blockchain/header.rs | 2 +- json/src/blockchain/mod.rs | 2 +- json/src/blockchain/state.rs | 2 +- json/src/blockchain/test.rs | 2 +- json/src/blockchain/transaction.rs | 2 +- json/src/bytes.rs | 2 +- json/src/hash.rs | 3 +-- json/src/lib.rs | 2 +- json/src/maybe.rs | 15 +++++++++++ json/src/misc/account_meta.rs | 2 +- json/src/misc/dapps_settings.rs | 2 +- json/src/misc/mod.rs | 2 +- json/src/spec/account.rs | 2 +- json/src/spec/authority_round.rs | 2 +- json/src/spec/basic_authority.rs | 2 +- json/src/spec/builtin.rs | 2 +- json/src/spec/engine.rs | 3 +-- json/src/spec/ethash.rs | 2 +- json/src/spec/genesis.rs | 2 +- json/src/spec/hardcoded_sync.rs | 2 +- json/src/spec/mod.rs | 2 +- json/src/spec/null_engine.rs | 2 +- json/src/spec/params.rs | 2 +- json/src/spec/seal.rs | 2 +- json/src/spec/spec.rs | 2 +- json/src/spec/state.rs | 2 +- json/src/spec/tendermint.rs | 2 +- json/src/spec/validator_set.rs | 2 +- json/src/state/log.rs | 2 +- json/src/state/mod.rs | 2 +- json/src/state/state.rs | 2 +- json/src/state/test.rs | 2 +- json/src/state/transaction.rs | 2 +- json/src/test/mod.rs | 3 +-- json/src/transaction/mod.rs | 2 +- json/src/transaction/test.rs | 2 +- json/src/transaction/transaction.rs | 2 +- json/src/transaction/txtest.rs | 2 +- json/src/trie/input.rs | 2 +- json/src/trie/mod.rs | 2 +- json/src/trie/test.rs | 2 +- json/src/trie/trie.rs | 2 +- json/src/uint.rs | 2 +- json/src/vm/call.rs | 2 +- json/src/vm/env.rs | 2 +- json/src/vm/mod.rs | 2 +- json/src/vm/test.rs | 2 +- json/src/vm/transaction.rs | 2 +- json/src/vm/vm.rs | 2 +- license_header | 2 +- local-store/src/lib.rs | 2 +- logger/src/lib.rs | 2 +- logger/src/rotating.rs | 3 +-- machine/src/lib.rs | 2 +- miner/src/external.rs | 3 +-- miner/src/gas_pricer.rs | 2 +- miner/src/lib.rs | 2 +- miner/src/pool/client.rs | 2 +- miner/src/pool/listener.rs | 4 +-- miner/src/pool/local_transactions.rs | 3 +-- miner/src/pool/mod.rs | 2 +- miner/src/pool/queue.rs | 3 +-- miner/src/pool/ready.rs | 3 +-- miner/src/pool/scoring.rs | 2 +- miner/src/pool/tests/client.rs | 2 +- miner/src/pool/tests/mod.rs | 4 +-- miner/src/pool/tests/tx.rs | 3 +-- miner/src/pool/verifier.rs | 3 +-- miner/src/work_notify.rs | 2 +- parity-clib-example/main.cpp | 16 +++++++++++ parity-clib/src/lib.rs | 2 +- parity/account.rs | 2 +- parity/blockchain.rs | 2 +- parity/cache.rs | 2 +- parity/cli/presets/mod.rs | 4 +-- parity/cli/usage.rs | 2 +- parity/configuration.rs | 3 +-- parity/dapps.rs | 2 +- parity/db/rocksdb/migration.rs | 3 +-- parity/deprecated.rs | 3 +-- parity/export_hardcoded_sync.rs | 2 +- parity/helpers.rs | 2 +- parity/ipfs.rs | 2 +- parity/light_helpers/epoch_fetch.rs | 2 +- parity/light_helpers/mod.rs | 2 +- parity/light_helpers/queue_cull.rs | 2 +- parity/modules.rs | 2 +- parity/params.rs | 2 +- parity/presale.rs | 2 +- parity/rpc.rs | 3 +-- parity/rpc_apis.rs | 2 +- parity/run.rs | 2 +- parity/secretstore.rs | 2 +- parity/signer.rs | 2 +- parity/snapshot.rs | 2 +- parity/stratum.rs | 2 +- parity/upgrade.rs | 2 +- parity/url.rs | 2 +- parity/user_defaults.rs | 2 +- parity/whisper.rs | 2 +- price-info/src/lib.rs | 2 +- registrar/src/lib.rs | 2 +- registrar/src/registrar.rs | 3 +-- rpc/src/authcodes.rs | 2 +- rpc/src/http_common.rs | 2 +- rpc/src/lib.rs | 2 +- rpc/src/tests/helpers.rs | 2 +- rpc/src/tests/mod.rs | 2 +- rpc/src/tests/rpc.rs | 2 +- rpc/src/tests/ws.rs | 3 +-- rpc/src/v1/extractors.rs | 2 +- rpc/src/v1/helpers/accounts.rs | 27 +++++++++++++++++++ rpc/src/v1/helpers/block_import.rs | 3 +-- rpc/src/v1/helpers/dapps.rs | 2 +- rpc/src/v1/helpers/dispatch.rs | 2 +- rpc/src/v1/helpers/errors.rs | 2 +- rpc/src/v1/helpers/fake_sign.rs | 2 +- rpc/src/v1/helpers/ipfs.rs | 2 +- rpc/src/v1/helpers/light_fetch.rs | 3 +-- rpc/src/v1/helpers/mod.rs | 2 +- rpc/src/v1/helpers/network_settings.rs | 3 ++- rpc/src/v1/helpers/nonce.rs | 2 +- rpc/src/v1/helpers/oneshot.rs | 2 +- rpc/src/v1/helpers/poll_filter.rs | 16 +++++++++++ rpc/src/v1/helpers/poll_manager.rs | 2 +- rpc/src/v1/helpers/requests.rs | 2 +- rpc/src/v1/helpers/secretstore.rs | 2 +- rpc/src/v1/helpers/signer.rs | 3 +-- rpc/src/v1/helpers/signing_queue.rs | 3 +-- rpc/src/v1/helpers/subscribers.rs | 3 +-- rpc/src/v1/helpers/subscription_manager.rs | 2 +- rpc/src/v1/impls/eth.rs | 3 +-- rpc/src/v1/impls/eth_filter.rs | 4 +-- rpc/src/v1/impls/eth_pubsub.rs | 2 +- rpc/src/v1/impls/light/eth.rs | 2 +- rpc/src/v1/impls/light/mod.rs | 2 +- rpc/src/v1/impls/light/net.rs | 2 +- rpc/src/v1/impls/light/parity.rs | 2 +- rpc/src/v1/impls/light/parity_set.rs | 2 +- rpc/src/v1/impls/light/trace.rs | 2 +- rpc/src/v1/impls/mod.rs | 2 +- rpc/src/v1/impls/net.rs | 2 +- rpc/src/v1/impls/parity.rs | 2 +- rpc/src/v1/impls/parity_accounts.rs | 2 +- rpc/src/v1/impls/parity_set.rs | 2 +- rpc/src/v1/impls/personal.rs | 2 +- rpc/src/v1/impls/private.rs | 2 +- rpc/src/v1/impls/pubsub.rs | 2 +- rpc/src/v1/impls/rpc.rs | 2 +- rpc/src/v1/impls/secretstore.rs | 2 +- rpc/src/v1/impls/signer.rs | 2 +- rpc/src/v1/impls/signing.rs | 2 +- rpc/src/v1/impls/signing_unsafe.rs | 2 +- rpc/src/v1/impls/traces.rs | 2 +- rpc/src/v1/impls/web3.rs | 2 +- rpc/src/v1/informant.rs | 2 +- rpc/src/v1/metadata.rs | 2 +- rpc/src/v1/mod.rs | 2 +- rpc/src/v1/tests/eth.rs | 2 +- rpc/src/v1/tests/helpers/dapps.rs | 2 +- rpc/src/v1/tests/helpers/miner_service.rs | 2 +- rpc/src/v1/tests/helpers/mod.rs | 2 +- rpc/src/v1/tests/helpers/snapshot_service.rs | 2 +- rpc/src/v1/tests/helpers/sync_provider.rs | 3 +-- rpc/src/v1/tests/helpers/update_service.rs | 2 +- rpc/src/v1/tests/mocked/eth.rs | 6 +---- rpc/src/v1/tests/mocked/eth_pubsub.rs | 4 +-- rpc/src/v1/tests/mocked/manage_network.rs | 2 +- rpc/src/v1/tests/mocked/mod.rs | 2 +- rpc/src/v1/tests/mocked/net.rs | 2 +- rpc/src/v1/tests/mocked/parity.rs | 3 +-- rpc/src/v1/tests/mocked/parity_accounts.rs | 4 +-- rpc/src/v1/tests/mocked/parity_set.rs | 3 +-- rpc/src/v1/tests/mocked/personal.rs | 2 +- rpc/src/v1/tests/mocked/pubsub.rs | 3 +-- rpc/src/v1/tests/mocked/rpc.rs | 3 +-- rpc/src/v1/tests/mocked/secretstore.rs | 2 +- rpc/src/v1/tests/mocked/signer.rs | 4 +-- rpc/src/v1/tests/mocked/signing.rs | 4 +-- rpc/src/v1/tests/mocked/traces.rs | 2 +- rpc/src/v1/tests/mocked/web3.rs | 2 +- rpc/src/v1/tests/mod.rs | 16 +++++++++++ rpc/src/v1/traits/eth.rs | 2 +- rpc/src/v1/traits/eth_pubsub.rs | 2 +- rpc/src/v1/traits/eth_signing.rs | 2 +- rpc/src/v1/traits/mod.rs | 2 +- rpc/src/v1/traits/net.rs | 2 +- rpc/src/v1/traits/parity.rs | 2 +- rpc/src/v1/traits/parity_accounts.rs | 2 +- rpc/src/v1/traits/parity_set.rs | 2 +- rpc/src/v1/traits/parity_signing.rs | 2 +- rpc/src/v1/traits/personal.rs | 2 +- rpc/src/v1/traits/private.rs | 2 +- rpc/src/v1/traits/pubsub.rs | 2 +- rpc/src/v1/traits/rpc.rs | 2 +- rpc/src/v1/traits/secretstore.rs | 2 +- rpc/src/v1/traits/signer.rs | 2 +- rpc/src/v1/traits/traces.rs | 2 +- rpc/src/v1/traits/web3.rs | 2 +- rpc/src/v1/types/account_info.rs | 3 +-- rpc/src/v1/types/block.rs | 2 +- rpc/src/v1/types/block_number.rs | 3 +-- rpc/src/v1/types/bytes.rs | 4 +-- rpc/src/v1/types/call_request.rs | 2 +- rpc/src/v1/types/confirmations.rs | 2 +- rpc/src/v1/types/consensus_status.rs | 2 +- rpc/src/v1/types/dapps.rs | 2 +- rpc/src/v1/types/derivation.rs | 2 +- rpc/src/v1/types/filter.rs | 2 +- rpc/src/v1/types/hash.rs | 2 +- rpc/src/v1/types/histogram.rs | 4 +-- rpc/src/v1/types/index.rs | 3 +-- rpc/src/v1/types/log.rs | 2 +- rpc/src/v1/types/mod.rs | 3 +-- rpc/src/v1/types/node_kind.rs | 2 +- rpc/src/v1/types/private_receipt.rs | 3 +-- rpc/src/v1/types/provenance.rs | 2 +- rpc/src/v1/types/pubsub.rs | 2 +- rpc/src/v1/types/receipt.rs | 3 +-- rpc/src/v1/types/rpc_settings.rs | 4 +-- rpc/src/v1/types/secretstore.rs | 2 +- rpc/src/v1/types/sync.rs | 2 +- rpc/src/v1/types/trace.rs | 3 +-- rpc/src/v1/types/trace_filter.rs | 2 +- rpc/src/v1/types/transaction.rs | 3 +-- rpc/src/v1/types/transaction_condition.rs | 3 +-- rpc/src/v1/types/transaction_request.rs | 3 +-- rpc/src/v1/types/uint.rs | 2 +- rpc/src/v1/types/work.rs | 3 +-- rpc_cli/src/lib.rs | 16 +++++++++++ rpc_client/src/client.rs | 16 +++++++++++ rpc_client/src/lib.rs | 16 +++++++++++ rpc_client/src/signer_client.rs | 16 +++++++++++ scripts/add_license.sh | 22 ++++++++++++--- scripts/remove_duplicate_empty_lines.sh | 6 +++++ secret_store/src/acl_storage.rs | 2 +- secret_store/src/key_server.rs | 2 +- .../key_version_negotiation_session.rs | 2 +- .../key_server_cluster/admin_sessions/mod.rs | 2 +- .../servers_set_change_session.rs | 2 +- .../admin_sessions/sessions_queue.rs | 2 +- .../admin_sessions/share_add_session.rs | 2 +- .../admin_sessions/share_change_session.rs | 2 +- .../client_sessions/decryption_session.rs | 2 +- .../client_sessions/encryption_session.rs | 2 +- .../client_sessions/generation_session.rs | 3 +-- .../key_server_cluster/client_sessions/mod.rs | 2 +- .../client_sessions/signing_session_ecdsa.rs | 3 +-- .../signing_session_schnorr.rs | 4 +-- .../src/key_server_cluster/cluster.rs | 2 +- .../key_server_cluster/cluster_sessions.rs | 2 +- .../cluster_sessions_creator.rs | 2 +- .../key_server_cluster/connection_trigger.rs | 2 +- .../connection_trigger_with_migration.rs | 2 +- .../src/key_server_cluster/io/deadline.rs | 2 +- .../src/key_server_cluster/io/handshake.rs | 2 +- .../src/key_server_cluster/io/message.rs | 2 +- secret_store/src/key_server_cluster/io/mod.rs | 2 +- .../src/key_server_cluster/io/read_header.rs | 2 +- .../src/key_server_cluster/io/read_message.rs | 2 +- .../src/key_server_cluster/io/read_payload.rs | 2 +- .../io/shared_tcp_stream.rs | 2 +- .../key_server_cluster/io/write_message.rs | 2 +- .../jobs/consensus_session.rs | 2 +- .../key_server_cluster/jobs/decryption_job.rs | 2 +- .../src/key_server_cluster/jobs/dummy_job.rs | 2 +- .../key_server_cluster/jobs/job_session.rs | 2 +- .../key_server_cluster/jobs/key_access_job.rs | 2 +- .../src/key_server_cluster/jobs/mod.rs | 2 +- .../jobs/servers_set_change_access_job.rs | 2 +- .../jobs/signing_job_ecdsa.rs | 2 +- .../jobs/signing_job_schnorr.rs | 4 +-- .../jobs/unknown_sessions_job.rs | 2 +- secret_store/src/key_server_cluster/math.rs | 2 +- .../src/key_server_cluster/message.rs | 2 +- secret_store/src/key_server_cluster/mod.rs | 2 +- .../net/accept_connection.rs | 2 +- .../src/key_server_cluster/net/connect.rs | 2 +- .../src/key_server_cluster/net/connection.rs | 2 +- .../src/key_server_cluster/net/mod.rs | 2 +- secret_store/src/key_server_set.rs | 2 +- secret_store/src/key_storage.rs | 3 +-- secret_store/src/lib.rs | 2 +- secret_store/src/listener/http_listener.rs | 2 +- secret_store/src/listener/mod.rs | 2 +- secret_store/src/listener/service_contract.rs | 2 +- .../listener/service_contract_aggregate.rs | 2 +- .../src/listener/service_contract_listener.rs | 2 +- secret_store/src/listener/tasks_queue.rs | 2 +- secret_store/src/node_key_pair.rs | 2 +- secret_store/src/serialization.rs | 2 +- secret_store/src/traits.rs | 2 +- secret_store/src/trusted_client.rs | 2 +- secret_store/src/types/all.rs | 2 +- secret_store/src/types/error.rs | 2 +- secret_store/src/types/mod.rs | 2 +- transaction-pool/src/error.rs | 2 +- transaction-pool/src/lib.rs | 2 +- transaction-pool/src/listener.rs | 2 +- transaction-pool/src/options.rs | 2 +- transaction-pool/src/pool.rs | 3 +-- transaction-pool/src/ready.rs | 2 +- transaction-pool/src/scoring.rs | 2 +- transaction-pool/src/status.rs | 2 +- transaction-pool/src/tests/helpers.rs | 2 +- transaction-pool/src/tests/mod.rs | 3 +-- transaction-pool/src/tests/tx_builder.rs | 2 +- transaction-pool/src/transactions.rs | 2 +- transaction-pool/src/verifier.rs | 2 +- updater/src/lib.rs | 2 +- updater/src/service.rs | 3 +-- updater/src/types/all.rs | 2 +- updater/src/types/mod.rs | 3 +-- updater/src/types/release_track.rs | 3 +-- updater/src/types/version_info.rs | 2 +- updater/src/updater.rs | 2 +- util/bloom/src/lib.rs | 4 +-- util/bloomchain/src/chain.rs | 16 +++++++++++ util/bloomchain/src/config.rs | 16 +++++++++++ util/bloomchain/src/database.rs | 16 +++++++++++ util/bloomchain/src/filter.rs | 16 +++++++++++ util/bloomchain/src/group/bridge.rs | 16 +++++++++++ util/bloomchain/src/group/chain.rs | 16 +++++++++++ util/bloomchain/src/group/database.rs | 16 +++++++++++ util/bloomchain/src/group/group.rs | 16 +++++++++++ util/bloomchain/src/group/mod.rs | 16 +++++++++++ util/bloomchain/src/group/position/manager.rs | 16 +++++++++++ util/bloomchain/src/group/position/mod.rs | 16 +++++++++++ .../bloomchain/src/group/position/position.rs | 16 +++++++++++ util/bloomchain/src/lib.rs | 16 +++++++++++ util/bloomchain/src/number.rs | 16 +++++++++++ util/bloomchain/src/position/manager.rs | 16 +++++++++++ util/bloomchain/src/position/mod.rs | 16 +++++++++++ util/bloomchain/src/position/position.rs | 16 +++++++++++ util/bloomchain/tests/bloomchain.rs | 18 +++++++++++-- util/bloomchain/tests/groupchain.rs | 19 ++++++++++--- util/bloomchain/tests/util/db.rs | 16 +++++++++++ util/bloomchain/tests/util/each.rs | 16 +++++++++++ util/bloomchain/tests/util/from_hex.rs | 16 +++++++++++ util/bloomchain/tests/util/mod.rs | 16 +++++++++++ util/bloomchain/tests/util/random.rs | 16 +++++++++++ util/bytes/src/lib.rs | 2 +- util/dir/src/helpers.rs | 2 +- util/dir/src/lib.rs | 2 +- util/error/src/lib.rs | 3 +-- util/fetch/src/client.rs | 2 +- util/fetch/src/lib.rs | 2 +- util/hash/benches/keccak_256.rs | 18 ++++++++++++- util/hash/src/lib.rs | 3 +-- util/hashdb/src/lib.rs | 2 +- util/io/src/lib.rs | 2 +- util/io/src/service_mio.rs | 2 +- util/io/src/service_non_mio.rs | 2 +- util/io/src/worker.rs | 2 +- util/journaldb/src/archivedb.rs | 2 +- util/journaldb/src/earlymergedb.rs | 3 +-- util/journaldb/src/lib.rs | 2 +- util/journaldb/src/overlaydb.rs | 2 +- util/journaldb/src/overlayrecentdb.rs | 2 +- util/journaldb/src/refcounteddb.rs | 2 +- util/journaldb/src/traits.rs | 2 +- util/kvdb-memorydb/src/lib.rs | 2 +- util/kvdb-rocksdb/src/lib.rs | 3 +-- util/kvdb/src/lib.rs | 2 +- util/macros/src/lib.rs | 2 +- util/mem/src/lib.rs | 3 +-- util/memory_cache/src/lib.rs | 2 +- util/memorydb/src/lib.rs | 2 +- util/migration-rocksdb/src/lib.rs | 2 +- util/migration-rocksdb/tests/tests.rs | 3 +-- util/network-devp2p/src/connection.rs | 2 +- util/network-devp2p/src/discovery.rs | 2 +- util/network-devp2p/src/handshake.rs | 3 +-- util/network-devp2p/src/host.rs | 3 +-- util/network-devp2p/src/ip_utils.rs | 4 +-- util/network-devp2p/src/lib.rs | 2 +- util/network-devp2p/src/node_table.rs | 2 +- util/network-devp2p/src/service.rs | 2 +- util/network-devp2p/src/session.rs | 3 +-- util/network-devp2p/tests/tests.rs | 3 +-- util/network/src/connection_filter.rs | 2 +- util/network/src/error.rs | 2 +- util/network/src/lib.rs | 2 +- util/panic_hook/src/lib.rs | 4 +-- util/path/src/lib.rs | 3 +-- util/patricia_trie/src/fatdb.rs | 2 +- util/patricia_trie/src/fatdbmut.rs | 2 +- util/patricia_trie/src/lib.rs | 2 +- util/patricia_trie/src/lookup.rs | 2 +- util/patricia_trie/src/nibbleslice.rs | 2 +- util/patricia_trie/src/nibblevec.rs | 2 +- util/patricia_trie/src/node.rs | 2 +- util/patricia_trie/src/recorder.rs | 2 +- util/patricia_trie/src/sectriedb.rs | 2 +- util/patricia_trie/src/sectriedbmut.rs | 2 +- util/patricia_trie/src/triedb.rs | 2 +- util/patricia_trie/src/triedbmut.rs | 3 +-- util/plain_hasher/benches/bench.rs | 16 +++++++++++ util/plain_hasher/src/lib.rs | 16 +++++++++++ util/reactor/src/lib.rs | 4 +-- util/rlp/src/rlpin.rs | 1 - util/rlp/src/stream.rs | 2 -- util/rlp_compress/src/lib.rs | 1 - util/rlp_compress/tests/compress.rs | 16 +++++++++++ util/rlp_derive/src/de.rs | 18 +++++++++++-- util/rlp_derive/src/en.rs | 17 +++++++++++- util/rlp_derive/src/lib.rs | 16 +++++++++++ util/rlp_derive/tests/rlp.rs | 17 +++++++++++- util/stats/src/lib.rs | 3 +-- util/stop-guard/src/lib.rs | 2 +- util/trace-time/src/lib.rs | 2 +- util/trie-standardmap/src/lib.rs | 2 +- util/triehash/src/lib.rs | 4 +-- util/unexpected/src/lib.rs | 2 +- util/using_queue/src/lib.rs | 2 +- util/version/build.rs | 2 +- util/version/src/lib.rs | 2 +- whisper/src/lib.rs | 2 +- whisper/src/message.rs | 2 +- whisper/src/net/mod.rs | 2 +- whisper/src/net/tests.rs | 2 +- whisper/src/rpc/crypto.rs | 2 +- whisper/src/rpc/filter.rs | 2 +- whisper/src/rpc/key_store.rs | 2 +- whisper/src/rpc/mod.rs | 2 +- whisper/src/rpc/payload.rs | 3 +-- whisper/src/rpc/types.rs | 2 +- windows/ptray/ptray.cpp | 3 +-- 807 files changed, 1635 insertions(+), 986 deletions(-) create mode 100644 rpc/src/v1/helpers/accounts.rs create mode 100755 scripts/remove_duplicate_empty_lines.sh diff --git a/chainspec/src/main.rs b/chainspec/src/main.rs index bcef53f3f0..708d74b503 100644 --- a/chainspec/src/main.rs +++ b/chainspec/src/main.rs @@ -1,3 +1,19 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + extern crate serde_json; extern crate serde_ignored; extern crate ethjson; diff --git a/dapps/js-glue/build.rs b/dapps/js-glue/build.rs index 442abf7dfb..19d422ab23 100644 --- a/dapps/js-glue/build.rs +++ b/dapps/js-glue/build.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -14,7 +14,6 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . - #[cfg(feature = "with-syntex")] mod inner { extern crate syntex; diff --git a/dapps/js-glue/src/build.rs b/dapps/js-glue/src/build.rs index 31f27306a9..76b0a8714c 100644 --- a/dapps/js-glue/src/build.rs +++ b/dapps/js-glue/src/build.rs @@ -1,3 +1,18 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . #[cfg(feature = "with-syntex")] pub mod inner { diff --git a/dapps/js-glue/src/codegen.rs b/dapps/js-glue/src/codegen.rs index c6e948820f..4b6c4445d7 100644 --- a/dapps/js-glue/src/codegen.rs +++ b/dapps/js-glue/src/codegen.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/dapps/js-glue/src/js.rs b/dapps/js-glue/src/js.rs index d1d1cdda91..f89fcefc76 100644 --- a/dapps/js-glue/src/js.rs +++ b/dapps/js-glue/src/js.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/dapps/js-glue/src/lib.rs b/dapps/js-glue/src/lib.rs index 143dd1fc8b..f8ada2541e 100644 --- a/dapps/js-glue/src/lib.rs +++ b/dapps/js-glue/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -14,7 +14,6 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . - #![cfg_attr(not(feature = "with-syntex"), feature(rustc_private, plugin))] #![cfg_attr(not(feature = "with-syntex"), plugin(quasi_macros))] diff --git a/dapps/js-glue/src/lib.rs.in b/dapps/js-glue/src/lib.rs.in index 99a253013d..b78eae1098 100644 --- a/dapps/js-glue/src/lib.rs.in +++ b/dapps/js-glue/src/lib.rs.in @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -8,11 +8,12 @@ // 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 +// 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 . +// along with Parity. If not, see . + extern crate quasi; diff --git a/dapps/node-health/src/health.rs b/dapps/node-health/src/health.rs index ab300a4a77..430061ea2b 100644 --- a/dapps/node-health/src/health.rs +++ b/dapps/node-health/src/health.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/dapps/node-health/src/lib.rs b/dapps/node-health/src/lib.rs index b0eb133ee3..13529004a6 100644 --- a/dapps/node-health/src/lib.rs +++ b/dapps/node-health/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/dapps/node-health/src/time.rs b/dapps/node-health/src/time.rs index c3da050a47..9dfb3aa87f 100644 --- a/dapps/node-health/src/time.rs +++ b/dapps/node-health/src/time.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/dapps/node-health/src/types.rs b/dapps/node-health/src/types.rs index ae883a626b..76fd3682f9 100644 --- a/dapps/node-health/src/types.rs +++ b/dapps/node-health/src/types.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/dapps/src/api/api.rs b/dapps/src/api/api.rs index a9f9af293b..e6bba899f9 100644 --- a/dapps/src/api/api.rs +++ b/dapps/src/api/api.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/dapps/src/api/mod.rs b/dapps/src/api/mod.rs index 4ffb9f791a..c18eb189ea 100644 --- a/dapps/src/api/mod.rs +++ b/dapps/src/api/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/dapps/src/api/response.rs b/dapps/src/api/response.rs index c8d25c1445..5fe81eaa19 100644 --- a/dapps/src/api/response.rs +++ b/dapps/src/api/response.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/dapps/src/api/types.rs b/dapps/src/api/types.rs index 6beca3b586..8bc451a849 100644 --- a/dapps/src/api/types.rs +++ b/dapps/src/api/types.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/dapps/src/apps/app.rs b/dapps/src/apps/app.rs index c75346124c..15468b4f1d 100644 --- a/dapps/src/apps/app.rs +++ b/dapps/src/apps/app.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/dapps/src/apps/cache.rs b/dapps/src/apps/cache.rs index c81d4d9af9..b93acfaece 100644 --- a/dapps/src/apps/cache.rs +++ b/dapps/src/apps/cache.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/dapps/src/apps/fetcher/installers.rs b/dapps/src/apps/fetcher/installers.rs index 5bde5cf999..99b6be218b 100644 --- a/dapps/src/apps/fetcher/installers.rs +++ b/dapps/src/apps/fetcher/installers.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/dapps/src/apps/fetcher/mod.rs b/dapps/src/apps/fetcher/mod.rs index 8ed3024fdf..78be4f4cb3 100644 --- a/dapps/src/apps/fetcher/mod.rs +++ b/dapps/src/apps/fetcher/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/dapps/src/apps/fs.rs b/dapps/src/apps/fs.rs index 3d93a2fae1..0139e0ec52 100644 --- a/dapps/src/apps/fs.rs +++ b/dapps/src/apps/fs.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -78,7 +78,6 @@ pub fn local_endpoint>(path: P, embeddable: Embeddable, pool: Cpu }) } - fn local_dapp(name: String, path: PathBuf) -> LocalDapp { // try to get manifest file let info = read_manifest(&name, path.clone()); @@ -102,7 +101,6 @@ pub fn local_endpoints>(dapps_path: P, embeddable: Embeddable, po pages } - fn local_dapps(dapps_path: &Path) -> Vec { let files = fs::read_dir(dapps_path); if let Err(e) = files { diff --git a/dapps/src/apps/manifest.rs b/dapps/src/apps/manifest.rs index e320482195..4d71af40fe 100644 --- a/dapps/src/apps/manifest.rs +++ b/dapps/src/apps/manifest.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/dapps/src/apps/mod.rs b/dapps/src/apps/mod.rs index 21947b928b..32bd7ee0fd 100644 --- a/dapps/src/apps/mod.rs +++ b/dapps/src/apps/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/dapps/src/apps/ui.rs b/dapps/src/apps/ui.rs index 39da14e5b9..696ed2523d 100644 --- a/dapps/src/apps/ui.rs +++ b/dapps/src/apps/ui.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/dapps/src/endpoint.rs b/dapps/src/endpoint.rs index fd05445c2a..948f412b38 100644 --- a/dapps/src/endpoint.rs +++ b/dapps/src/endpoint.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/dapps/src/handlers/content.rs b/dapps/src/handlers/content.rs index c7eccf474e..ec4d4f2eff 100644 --- a/dapps/src/handlers/content.rs +++ b/dapps/src/handlers/content.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/dapps/src/handlers/echo.rs b/dapps/src/handlers/echo.rs index 375f047906..d7484b6d15 100644 --- a/dapps/src/handlers/echo.rs +++ b/dapps/src/handlers/echo.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/dapps/src/handlers/fetch.rs b/dapps/src/handlers/fetch.rs index 1408d634db..860fe998c4 100644 --- a/dapps/src/handlers/fetch.rs +++ b/dapps/src/handlers/fetch.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -102,7 +102,6 @@ impl FetchControl { } } - enum WaitState { Waiting(oneshot::Receiver), Done(endpoint::Response), diff --git a/dapps/src/handlers/mod.rs b/dapps/src/handlers/mod.rs index f78f46c764..fad9c40416 100644 --- a/dapps/src/handlers/mod.rs +++ b/dapps/src/handlers/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/dapps/src/handlers/reader.rs b/dapps/src/handlers/reader.rs index 85a351c7b0..3b0aa5449b 100644 --- a/dapps/src/handlers/reader.rs +++ b/dapps/src/handlers/reader.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/dapps/src/handlers/redirect.rs b/dapps/src/handlers/redirect.rs index cb1eda2dd5..c8bf837d85 100644 --- a/dapps/src/handlers/redirect.rs +++ b/dapps/src/handlers/redirect.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/dapps/src/handlers/streaming.rs b/dapps/src/handlers/streaming.rs index 269e4c5d2a..4dfd2c4afa 100644 --- a/dapps/src/handlers/streaming.rs +++ b/dapps/src/handlers/streaming.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/dapps/src/lib.rs b/dapps/src/lib.rs index c4e244b251..255560e422 100644 --- a/dapps/src/lib.rs +++ b/dapps/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -85,7 +85,6 @@ use node_health::NodeHealth; pub use registrar::{RegistrarClient, Asynchronous}; pub use node_health::SyncStatus; - /// Validates Web Proxy tokens pub trait WebProxyTokens: Send + Sync { /// Should return a domain allowed to be accessed by this token or `None` if the token is not valid diff --git a/dapps/src/page/builtin.rs b/dapps/src/page/builtin.rs index 150cfe8642..b9f2fcdac5 100644 --- a/dapps/src/page/builtin.rs +++ b/dapps/src/page/builtin.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -146,7 +146,6 @@ impl From for EndpointInfo { } } - struct BuiltinFile { content_type: Mime, content: io::Cursor<&'static [u8]>, diff --git a/dapps/src/page/handler.rs b/dapps/src/page/handler.rs index 687c8e1e52..15e2b10c50 100644 --- a/dapps/src/page/handler.rs +++ b/dapps/src/page/handler.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/dapps/src/page/local.rs b/dapps/src/page/local.rs index a1746efcd2..f30af45237 100644 --- a/dapps/src/page/local.rs +++ b/dapps/src/page/local.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -92,7 +92,6 @@ impl Dapp { LocalFile::from_path(&file_path, mime) } - pub fn to_response(&self, path: &EndpointPath) -> Response { let (reader, response) = handler::PageHandler { file: self.get_file(path), diff --git a/dapps/src/page/mod.rs b/dapps/src/page/mod.rs index 420707bfe1..65385320c4 100644 --- a/dapps/src/page/mod.rs +++ b/dapps/src/page/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -14,10 +14,8 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . - pub mod builtin; pub mod local; mod handler; pub use self::handler::PageCache; - diff --git a/dapps/src/proxypac.rs b/dapps/src/proxypac.rs index 85ac11423a..4e11f3ea6b 100644 --- a/dapps/src/proxypac.rs +++ b/dapps/src/proxypac.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -64,5 +64,3 @@ function FindProxyForURL(url, host) {{ )) } } - - diff --git a/dapps/src/router.rs b/dapps/src/router.rs index d5f4647049..565874f6a8 100644 --- a/dapps/src/router.rs +++ b/dapps/src/router.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/dapps/src/tests/api.rs b/dapps/src/tests/api.rs index 3ae3f7cbbf..d31f796d57 100644 --- a/dapps/src/tests/api.rs +++ b/dapps/src/tests/api.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -63,7 +63,6 @@ fn should_handle_ping() { assert_security_headers(&response.headers); } - #[test] fn should_try_to_resolve_dapp() { // given diff --git a/dapps/src/tests/fetch.rs b/dapps/src/tests/fetch.rs index 59eeaf8d66..bbd766a552 100644 --- a/dapps/src/tests/fetch.rs +++ b/dapps/src/tests/fetch.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -383,7 +383,6 @@ fn should_correctly_handle_long_label_when_splitted() { fetch.assert_no_more_requests(); } - #[test] fn should_support_base32_encoded_web_urls_as_path() { // given diff --git a/dapps/src/tests/helpers/fetch.rs b/dapps/src/tests/helpers/fetch.rs index 51c98db531..4affffe6ef 100644 --- a/dapps/src/tests/helpers/fetch.rs +++ b/dapps/src/tests/helpers/fetch.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/dapps/src/tests/helpers/mod.rs b/dapps/src/tests/helpers/mod.rs index 41df0db61b..aa76089794 100644 --- a/dapps/src/tests/helpers/mod.rs +++ b/dapps/src/tests/helpers/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -140,7 +140,6 @@ pub fn assert_security_headers_for_embed(headers: &[String]) { http_client::assert_security_headers_present(headers, Some(SIGNER_PORT)) } - /// Webapps HTTP+RPC server build. pub struct ServerBuilder { dapps_path: PathBuf, diff --git a/dapps/src/tests/helpers/registrar.rs b/dapps/src/tests/helpers/registrar.rs index e770146f5a..b9acb1afc3 100644 --- a/dapps/src/tests/helpers/registrar.rs +++ b/dapps/src/tests/helpers/registrar.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/dapps/src/tests/home.rs b/dapps/src/tests/home.rs index fa5c5b4c46..024261d5df 100644 --- a/dapps/src/tests/home.rs +++ b/dapps/src/tests/home.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/dapps/src/tests/mod.rs b/dapps/src/tests/mod.rs index a47294392e..38a1d6f17a 100644 --- a/dapps/src/tests/mod.rs +++ b/dapps/src/tests/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -24,4 +24,3 @@ mod home; mod redirection; mod rpc; mod validation; - diff --git a/dapps/src/tests/redirection.rs b/dapps/src/tests/redirection.rs index b7f72009f7..722ade25b9 100644 --- a/dapps/src/tests/redirection.rs +++ b/dapps/src/tests/redirection.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -160,7 +160,6 @@ fn should_serve_rpc_at_slash_rpc() { assert_eq!(response.body, format!("4C\n{}\n\n0\n\n", r#"{"jsonrpc":"2.0","error":{"code":-32700,"message":"Parse error"},"id":null}"#)); } - #[test] fn should_serve_proxy_pac() { // given diff --git a/dapps/src/tests/rpc.rs b/dapps/src/tests/rpc.rs index 0cfc2c5a81..326fcd72a6 100644 --- a/dapps/src/tests/rpc.rs +++ b/dapps/src/tests/rpc.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/dapps/src/tests/validation.rs b/dapps/src/tests/validation.rs index bd97c940a0..ed4a3dc2f0 100644 --- a/dapps/src/tests/validation.rs +++ b/dapps/src/tests/validation.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/dapps/src/web.rs b/dapps/src/web.rs index 86c0ac28d6..14f215ca45 100644 --- a/dapps/src/web.rs +++ b/dapps/src/web.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -168,4 +168,3 @@ impl ContentValidator for WebInstaller { Ok(ValidatorResponse::Streaming(handler)) } } - diff --git a/dapps/ui/src/lib.rs b/dapps/ui/src/lib.rs index aa1c867366..f04f755a99 100644 --- a/dapps/ui/src/lib.rs +++ b/dapps/ui/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -14,7 +14,6 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . - #[cfg(feature = "parity-ui-dev")] mod inner { extern crate parity_ui_dev; diff --git a/devtools/src/http_client.rs b/devtools/src/http_client.rs index ab23410592..e2f33d4257 100644 --- a/devtools/src/http_client.rs +++ b/devtools/src/http_client.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/devtools/src/lib.rs b/devtools/src/lib.rs index efaf4b9351..6fdbc8d890 100644 --- a/devtools/src/lib.rs +++ b/devtools/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethash/src/cache.rs b/ethash/src/cache.rs index eef426bcf1..21bd0e231e 100644 --- a/ethash/src/cache.rs +++ b/ethash/src/cache.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethash/src/compute.rs b/ethash/src/compute.rs index de2b57637f..fa95038d18 100644 --- a/ethash/src/compute.rs +++ b/ethash/src/compute.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethash/src/keccak.rs b/ethash/src/keccak.rs index 36fb173547..ab6be94dca 100644 --- a/ethash/src/keccak.rs +++ b/ethash/src/keccak.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethash/src/lib.rs b/ethash/src/lib.rs index 9d0c669d9c..69b5a1d115 100644 --- a/ethash/src/lib.rs +++ b/ethash/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethash/src/seed_compute.rs b/ethash/src/seed_compute.rs index 04774b3e39..bc6f1d51e1 100644 --- a/ethash/src/seed_compute.rs +++ b/ethash/src/seed_compute.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethash/src/shared.rs b/ethash/src/shared.rs index 39e1c8eb88..90969c5222 100644 --- a/ethash/src/shared.rs +++ b/ethash/src/shared.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/benches/evm.rs b/ethcore/benches/evm.rs index 9fe2657d61..c68adc9878 100644 --- a/ethcore/benches/evm.rs +++ b/ethcore/benches/evm.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -28,7 +28,6 @@ extern crate ethcore_bigint; use self::test::{Bencher}; use rand::{StdRng}; - #[bench] fn bn_128_pairing(b: &mut Bencher) { use bn::{pairing, G1, G2, Fr, Group}; @@ -92,4 +91,3 @@ fn ecrecover(b: &mut Bencher) { let _ = ec_recover(&s, &hash); }); } - diff --git a/ethcore/crypto/src/aes.rs b/ethcore/crypto/src/aes.rs index 79a8dcc86d..42a26fad0d 100644 --- a/ethcore/crypto/src/aes.rs +++ b/ethcore/crypto/src/aes.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -51,4 +51,3 @@ pub fn decrypt_128_cbc(k: &[u8], iv: &[u8], encrypted: &[u8], dest: &mut [u8]) - encryptor.decrypt(&mut RefReadBuffer::new(encrypted), &mut buffer, true)?; Ok(len - buffer.remaining()) } - diff --git a/ethcore/crypto/src/aes_gcm.rs b/ethcore/crypto/src/aes_gcm.rs index 178b5d1e12..819c613197 100644 --- a/ethcore/crypto/src/aes_gcm.rs +++ b/ethcore/crypto/src/aes_gcm.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -196,4 +196,3 @@ mod tests { assert_eq!(plaintext, &message[..]) } } - diff --git a/ethcore/crypto/src/digest.rs b/ethcore/crypto/src/digest.rs index 095a8ca262..b2be0b8ed1 100644 --- a/ethcore/crypto/src/digest.rs +++ b/ethcore/crypto/src/digest.rs @@ -1,4 +1,4 @@ -// Copyright 2018 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/crypto/src/error.rs b/ethcore/crypto/src/error.rs index 4de3b80036..4e5582e196 100644 --- a/ethcore/crypto/src/error.rs +++ b/ethcore/crypto/src/error.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -80,4 +80,3 @@ impl From for SymmError { SymmError(PrivSymmErr::RustCrypto(e)) } } - diff --git a/ethcore/crypto/src/hmac.rs b/ethcore/crypto/src/hmac.rs index 7327250442..ff337ed024 100644 --- a/ethcore/crypto/src/hmac.rs +++ b/ethcore/crypto/src/hmac.rs @@ -1,4 +1,4 @@ -// Copyright 2018 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -86,4 +86,3 @@ impl VerifyKey { pub fn verify(k: &VerifyKey, data: &[u8], sig: &[u8]) -> bool { hmac::verify(&k.0, data, sig).is_ok() } - diff --git a/ethcore/crypto/src/lib.rs b/ethcore/crypto/src/lib.rs index 0ee42e3599..459c790319 100644 --- a/ethcore/crypto/src/lib.rs +++ b/ethcore/crypto/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -74,4 +74,3 @@ pub fn derive_mac(derived_left_bits: &[u8], cipher_text: &[u8]) -> Vec { pub fn is_equal(a: &[u8], b: &[u8]) -> bool { ring::constant_time::verify_slices_are_equal(a, b).is_ok() } - diff --git a/ethcore/crypto/src/pbkdf2.rs b/ethcore/crypto/src/pbkdf2.rs index b4c993c513..d210f6f659 100644 --- a/ethcore/crypto/src/pbkdf2.rs +++ b/ethcore/crypto/src/pbkdf2.rs @@ -1,4 +1,4 @@ -// Copyright 2018 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -26,4 +26,3 @@ pub fn sha256(iter: u32, salt: Salt, sec: Secret, out: &mut [u8; 32]) { pub fn sha512(iter: u32, salt: Salt, sec: Secret, out: &mut [u8; 64]) { ring::pbkdf2::derive(&ring::digest::SHA512, iter, salt.0, sec.0, &mut out[..]) } - diff --git a/ethcore/crypto/src/scrypt.rs b/ethcore/crypto/src/scrypt.rs index 684ab2c572..de3cd55553 100644 --- a/ethcore/crypto/src/scrypt.rs +++ b/ethcore/crypto/src/scrypt.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -36,4 +36,3 @@ pub fn derive_key(pass: &str, salt: &[u8; 32], n: u32, p: u32, r: u32) -> Result let derived_left_bits = &derived_key[KEY_LENGTH_AES..KEY_LENGTH]; Ok((derived_right_bits.to_vec(), derived_left_bits.to_vec())) } - diff --git a/ethcore/evm/src/benches/mod.rs b/ethcore/evm/src/benches/mod.rs index c87fda7bbf..244c26985a 100644 --- a/ethcore/evm/src/benches/mod.rs +++ b/ethcore/evm/src/benches/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/evm/src/evm.rs b/ethcore/evm/src/evm.rs index 16dffe77c5..4c85b37028 100644 --- a/ethcore/evm/src/evm.rs +++ b/ethcore/evm/src/evm.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/evm/src/factory.rs b/ethcore/evm/src/factory.rs index af38afede3..65a683cd4a 100644 --- a/ethcore/evm/src/factory.rs +++ b/ethcore/evm/src/factory.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/evm/src/instructions.rs b/ethcore/evm/src/instructions.rs index 6ecfc7f673..76f99a9333 100644 --- a/ethcore/evm/src/instructions.rs +++ b/ethcore/evm/src/instructions.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/evm/src/interpreter/gasometer.rs b/ethcore/evm/src/interpreter/gasometer.rs index beb22447fe..85ea8ee487 100644 --- a/ethcore/evm/src/interpreter/gasometer.rs +++ b/ethcore/evm/src/interpreter/gasometer.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -316,7 +316,6 @@ impl Gasometer { } } - #[inline] fn mem_needed_const(mem: &U256, add: usize) -> vm::Result { Gas::from_u256(overflowing!(mem.overflowing_add(U256::from(add)))) @@ -369,4 +368,3 @@ fn test_calculate_mem_cost() { assert_eq!(new_mem_gas, 3); assert_eq!(mem_size, 32); } - diff --git a/ethcore/evm/src/interpreter/informant.rs b/ethcore/evm/src/interpreter/informant.rs index f07d11ff7a..ca04be844f 100644 --- a/ethcore/evm/src/interpreter/informant.rs +++ b/ethcore/evm/src/interpreter/informant.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/evm/src/interpreter/memory.rs b/ethcore/evm/src/interpreter/memory.rs index f646d01985..843aeef3b5 100644 --- a/ethcore/evm/src/interpreter/memory.rs +++ b/ethcore/evm/src/interpreter/memory.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/evm/src/interpreter/mod.rs b/ethcore/evm/src/interpreter/mod.rs index 160a2e5b1d..ef9b3fb973 100644 --- a/ethcore/evm/src/interpreter/mod.rs +++ b/ethcore/evm/src/interpreter/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -103,7 +103,6 @@ enum InstructionResult { StopExecution, } - /// Intepreter EVM implementation pub struct Interpreter { mem: Vec, @@ -959,7 +958,6 @@ fn address_to_u256(value: Address) -> U256 { U256::from(&*H256::from(value)) } - #[cfg(test)] mod tests { use std::sync::Arc; diff --git a/ethcore/evm/src/interpreter/shared_cache.rs b/ethcore/evm/src/interpreter/shared_cache.rs index 30bc5b677d..d4e992c90e 100644 --- a/ethcore/evm/src/interpreter/shared_cache.rs +++ b/ethcore/evm/src/interpreter/shared_cache.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -91,7 +91,6 @@ impl Default for SharedCache { } } - #[test] fn test_find_jump_destinations() { use rustc_hex::FromHex; diff --git a/ethcore/evm/src/interpreter/stack.rs b/ethcore/evm/src/interpreter/stack.rs index cbe40fb67f..3902b8ff76 100644 --- a/ethcore/evm/src/interpreter/stack.rs +++ b/ethcore/evm/src/interpreter/stack.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -95,4 +95,3 @@ impl Stack for VecStack { &self.stack[self.stack.len() - no_from_top .. self.stack.len()] } } - diff --git a/ethcore/evm/src/lib.rs b/ethcore/evm/src/lib.rs index 263a11d682..1b5610cef5 100644 --- a/ethcore/evm/src/lib.rs +++ b/ethcore/evm/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/evm/src/tests.rs b/ethcore/evm/src/tests.rs index 9058d073e8..b62faf87d7 100644 --- a/ethcore/evm/src/tests.rs +++ b/ethcore/evm/src/tests.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/evm/src/vmtype.rs b/ethcore/evm/src/vmtype.rs index b3a8aaf3e9..feb567b73d 100644 --- a/ethcore/evm/src/vmtype.rs +++ b/ethcore/evm/src/vmtype.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/light/src/cache.rs b/ethcore/light/src/cache.rs index b63fd07576..7b6324a991 100644 --- a/ethcore/light/src/cache.rs +++ b/ethcore/light/src/cache.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/light/src/cht.rs b/ethcore/light/src/cht.rs index ffb7841f45..805cca3cbc 100644 --- a/ethcore/light/src/cht.rs +++ b/ethcore/light/src/cht.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -11,6 +11,9 @@ // 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 . + //! Canonical hash trie definitions and helper functions. //! //! Each CHT is a trie mapping block numbers to canonical hashes and total difficulty. diff --git a/ethcore/light/src/client/fetch.rs b/ethcore/light/src/client/fetch.rs index 86269c695f..b0f7353496 100644 --- a/ethcore/light/src/client/fetch.rs +++ b/ethcore/light/src/client/fetch.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/light/src/client/header_chain.rs b/ethcore/light/src/client/header_chain.rs index 60c7d288a7..cb370da2a7 100644 --- a/ethcore/light/src/client/header_chain.rs +++ b/ethcore/light/src/client/header_chain.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/light/src/client/mod.rs b/ethcore/light/src/client/mod.rs index 82b424cc83..a1625b0e8f 100644 --- a/ethcore/light/src/client/mod.rs +++ b/ethcore/light/src/client/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -463,7 +463,6 @@ impl Client { loop { - let is_signal = { let auxiliary = AuxiliaryData { bytes: block.as_ref().map(|x| &x[..]), diff --git a/ethcore/light/src/client/service.rs b/ethcore/light/src/client/service.rs index a3ec8a3686..d1645cfe7e 100644 --- a/ethcore/light/src/client/service.rs +++ b/ethcore/light/src/client/service.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/light/src/lib.rs b/ethcore/light/src/lib.rs index 9723854b8d..d7469fdcee 100644 --- a/ethcore/light/src/lib.rs +++ b/ethcore/light/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/light/src/net/context.rs b/ethcore/light/src/net/context.rs index 613e26b1f1..a49ef79dc2 100644 --- a/ethcore/light/src/net/context.rs +++ b/ethcore/light/src/net/context.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -12,7 +12,7 @@ // 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 . +// along with Parity. If not, see . //! I/O and event context generalizations. @@ -46,7 +46,6 @@ pub trait IoContext { fn persistent_peer_id(&self, peer: PeerId) -> Option; } - impl IoContext for T where T: ?Sized + NetworkContext { fn send(&self, peer: PeerId, packet_id: u8, packet_body: Vec) { if let Err(e) = self.send(peer, packet_id, packet_body) { diff --git a/ethcore/light/src/net/error.rs b/ethcore/light/src/net/error.rs index 35349c5539..ec2a7f91c5 100644 --- a/ethcore/light/src/net/error.rs +++ b/ethcore/light/src/net/error.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/light/src/net/load_timer.rs b/ethcore/light/src/net/load_timer.rs index 2846a57384..0ad9627021 100644 --- a/ethcore/light/src/net/load_timer.rs +++ b/ethcore/light/src/net/load_timer.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/light/src/net/mod.rs b/ethcore/light/src/net/mod.rs index d8a975dc3f..39f53445ad 100644 --- a/ethcore/light/src/net/mod.rs +++ b/ethcore/light/src/net/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -86,7 +86,6 @@ pub const PROTOCOL_VERSIONS: &'static [(u8, u8)] = &[ /// Max protocol version. pub const MAX_PROTOCOL_VERSION: u8 = 1; - // packet ID definitions. mod packet { // the status packet. diff --git a/ethcore/light/src/net/request_credits.rs b/ethcore/light/src/net/request_credits.rs index 29570b613c..e97e1aad58 100644 --- a/ethcore/light/src/net/request_credits.rs +++ b/ethcore/light/src/net/request_credits.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/light/src/net/request_set.rs b/ethcore/light/src/net/request_set.rs index 27e6c28bc2..4170f8e632 100644 --- a/ethcore/light/src/net/request_set.rs +++ b/ethcore/light/src/net/request_set.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/light/src/net/status.rs b/ethcore/light/src/net/status.rs index c9ee3d760f..d89db173cb 100644 --- a/ethcore/light/src/net/status.rs +++ b/ethcore/light/src/net/status.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/light/src/net/tests/mod.rs b/ethcore/light/src/net/tests/mod.rs index 3c04c0ffba..305ef9b354 100644 --- a/ethcore/light/src/net/tests/mod.rs +++ b/ethcore/light/src/net/tests/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/light/src/on_demand/mod.rs b/ethcore/light/src/on_demand/mod.rs index 64794d49e7..c7cc5ef5e7 100644 --- a/ethcore/light/src/on_demand/mod.rs +++ b/ethcore/light/src/on_demand/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/light/src/on_demand/request.rs b/ethcore/light/src/on_demand/request.rs index 18a309ae96..4cac6b629d 100644 --- a/ethcore/light/src/on_demand/request.rs +++ b/ethcore/light/src/on_demand/request.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -520,7 +520,6 @@ impl IncompleteRequest for CheckedRequest { } } - fn adjust_refs(&mut self, mapping: F) where F: FnMut(usize) -> usize { match_me!(*self, (_, ref mut req) => req.adjust_refs(mapping)) } diff --git a/ethcore/light/src/on_demand/tests.rs b/ethcore/light/src/on_demand/tests.rs index 95aec273f8..d3cd137ec0 100644 --- a/ethcore/light/src/on_demand/tests.rs +++ b/ethcore/light/src/on_demand/tests.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/light/src/provider.rs b/ethcore/light/src/provider.rs index aaa6f5858a..0e518ea772 100644 --- a/ethcore/light/src/provider.rs +++ b/ethcore/light/src/provider.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/light/src/transaction_queue.rs b/ethcore/light/src/transaction_queue.rs index ae3dc26915..e8880037a1 100644 --- a/ethcore/light/src/transaction_queue.rs +++ b/ethcore/light/src/transaction_queue.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/light/src/types/mod.rs b/ethcore/light/src/types/mod.rs index eba551b533..67e54141b2 100644 --- a/ethcore/light/src/types/mod.rs +++ b/ethcore/light/src/types/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/light/src/types/request/batch.rs b/ethcore/light/src/types/request/batch.rs index 21f1264672..16843ae02c 100644 --- a/ethcore/light/src/types/request/batch.rs +++ b/ethcore/light/src/types/request/batch.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/light/src/types/request/mod.rs b/ethcore/light/src/types/request/mod.rs index bda992df97..538aa0c6bf 100644 --- a/ethcore/light/src/types/request/mod.rs +++ b/ethcore/light/src/types/request/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -124,8 +124,6 @@ impl Field { } } - - // attempt conversion into scalar value. fn into_scalar(self) -> Result { match self { diff --git a/ethcore/node_filter/src/lib.rs b/ethcore/node_filter/src/lib.rs index c731ad356a..76f6fd18ff 100644 --- a/ethcore/node_filter/src/lib.rs +++ b/ethcore/node_filter/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -90,7 +90,6 @@ impl ConnectionFilter for NodeFilter { return *res; } - let address = self.contract_address; let own_low = H256::from_slice(&own_id[0..32]); let own_high = H256::from_slice(&own_id[32..64]); diff --git a/ethcore/private-tx/src/encryptor.rs b/ethcore/private-tx/src/encryptor.rs index b15acbee71..e171e3e606 100644 --- a/ethcore/private-tx/src/encryptor.rs +++ b/ethcore/private-tx/src/encryptor.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/private-tx/src/error.rs b/ethcore/private-tx/src/error.rs index 3b3c881a94..0456b33053 100644 --- a/ethcore/private-tx/src/error.rs +++ b/ethcore/private-tx/src/error.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -205,4 +205,3 @@ impl From> for Error where Error: From { Error::from(*err) } } - diff --git a/ethcore/private-tx/src/lib.rs b/ethcore/private-tx/src/lib.rs index 7aca4c85dc..31abdb1eca 100644 --- a/ethcore/private-tx/src/lib.rs +++ b/ethcore/private-tx/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/private-tx/src/messages.rs b/ethcore/private-tx/src/messages.rs index f465f752be..57362e7ce6 100644 --- a/ethcore/private-tx/src/messages.rs +++ b/ethcore/private-tx/src/messages.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/private-tx/src/private_transactions.rs b/ethcore/private-tx/src/private_transactions.rs index 1a018d927a..fcc6da514e 100644 --- a/ethcore/private-tx/src/private_transactions.rs +++ b/ethcore/private-tx/src/private_transactions.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/private-tx/tests/private_contract.rs b/ethcore/private-tx/tests/private_contract.rs index e7e608c2b6..bc678b1ab5 100644 --- a/ethcore/private-tx/tests/private_contract.rs +++ b/ethcore/private-tx/tests/private_contract.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/service/src/service.rs b/ethcore/service/src/service.rs index f703329d61..7248d97229 100644 --- a/ethcore/service/src/service.rs +++ b/ethcore/service/src/service.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/account_db.rs b/ethcore/src/account_db.rs index 4e715766d7..8fc4b95c6e 100644 --- a/ethcore/src/account_db.rs +++ b/ethcore/src/account_db.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/account_provider/mod.rs b/ethcore/src/account_provider/mod.rs index 9d6b814c6f..2ebefc988b 100644 --- a/ethcore/src/account_provider/mod.rs +++ b/ethcore/src/account_provider/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/account_provider/stores.rs b/ethcore/src/account_provider/stores.rs index 1563d21bc6..d7725deb7e 100644 --- a/ethcore/src/account_provider/stores.rs +++ b/ethcore/src/account_provider/stores.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/block.rs b/ethcore/src/block.rs index 4c47089677..682171170e 100644 --- a/ethcore/src/block.rs +++ b/ethcore/src/block.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/blockchain/best_block.rs b/ethcore/src/blockchain/best_block.rs index 017c4f86ea..adfaf68aad 100644 --- a/ethcore/src/blockchain/best_block.rs +++ b/ethcore/src/blockchain/best_block.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/blockchain/block_info.rs b/ethcore/src/blockchain/block_info.rs index ee8a50d09d..6a48e92447 100644 --- a/ethcore/src/blockchain/block_info.rs +++ b/ethcore/src/blockchain/block_info.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/blockchain/blockchain.rs b/ethcore/src/blockchain/blockchain.rs index f2621d00e1..ee781ebe53 100644 --- a/ethcore/src/blockchain/blockchain.rs +++ b/ethcore/src/blockchain/blockchain.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/blockchain/cache.rs b/ethcore/src/blockchain/cache.rs index 999be423df..0717011ae6 100644 --- a/ethcore/src/blockchain/cache.rs +++ b/ethcore/src/blockchain/cache.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/blockchain/config.rs b/ethcore/src/blockchain/config.rs index 312289b060..632f978ac5 100644 --- a/ethcore/src/blockchain/config.rs +++ b/ethcore/src/blockchain/config.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/blockchain/extras.rs b/ethcore/src/blockchain/extras.rs index 3fb25e7b1b..30dbec707e 100644 --- a/ethcore/src/blockchain/extras.rs +++ b/ethcore/src/blockchain/extras.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/blockchain/generator.rs b/ethcore/src/blockchain/generator.rs index e767f2211c..5a97f37f98 100644 --- a/ethcore/src/blockchain/generator.rs +++ b/ethcore/src/blockchain/generator.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/blockchain/import_route.rs b/ethcore/src/blockchain/import_route.rs index 080d3b0682..d8b38e6335 100644 --- a/ethcore/src/blockchain/import_route.rs +++ b/ethcore/src/blockchain/import_route.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/blockchain/mod.rs b/ethcore/src/blockchain/mod.rs index f991692ded..6389f308aa 100644 --- a/ethcore/src/blockchain/mod.rs +++ b/ethcore/src/blockchain/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/blockchain/update.rs b/ethcore/src/blockchain/update.rs index b695b9236b..8960d795aa 100644 --- a/ethcore/src/blockchain/update.rs +++ b/ethcore/src/blockchain/update.rs @@ -1,3 +1,19 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + use std::collections::HashMap; use ethereum_types::H256; use header::BlockNumber; diff --git a/ethcore/src/blooms/bloom_group.rs b/ethcore/src/blooms/bloom_group.rs index 4b47b1ad94..0eb1e9c529 100644 --- a/ethcore/src/blooms/bloom_group.rs +++ b/ethcore/src/blooms/bloom_group.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/blooms/group_position.rs b/ethcore/src/blooms/group_position.rs index b1ea827926..1f9ddca7e0 100644 --- a/ethcore/src/blooms/group_position.rs +++ b/ethcore/src/blooms/group_position.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/blooms/mod.rs b/ethcore/src/blooms/mod.rs index a66485782b..7658446c74 100644 --- a/ethcore/src/blooms/mod.rs +++ b/ethcore/src/blooms/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/builtin.rs b/ethcore/src/builtin.rs index a0833cfb5e..61739c7b1d 100644 --- a/ethcore/src/builtin.rs +++ b/ethcore/src/builtin.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -703,7 +703,6 @@ mod tests { assert_eq!(f.cost(&input[..]), expected_cost.into()); } - // test for potential exp len overflow { let input = FromHex::from_hex("\ @@ -827,7 +826,6 @@ mod tests { assert_eq!(output, expected); } - // no input, should not fail { let mut empty = [0u8; 0]; @@ -859,7 +857,6 @@ mod tests { } } - #[test] fn bn128_mul() { diff --git a/ethcore/src/cache_manager.rs b/ethcore/src/cache_manager.rs index 7d91dcc0d0..4199cb1d59 100644 --- a/ethcore/src/cache_manager.rs +++ b/ethcore/src/cache_manager.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/client/ancient_import.rs b/ethcore/src/client/ancient_import.rs index c2523a13a5..4586a04eed 100644 --- a/ethcore/src/client/ancient_import.rs +++ b/ethcore/src/client/ancient_import.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/client/chain_notify.rs b/ethcore/src/client/chain_notify.rs index 8330fb40d9..62de03591d 100644 --- a/ethcore/src/client/chain_notify.rs +++ b/ethcore/src/client/chain_notify.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index b469cf4518..9e2cfeff40 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -425,7 +425,6 @@ impl Importer { Ok(locked_block) } - /// Import a block with transaction receipts. /// /// The block is guaranteed to be the next best blocks in the @@ -918,7 +917,6 @@ impl Client { Arc::new(last_hashes) } - /// This is triggered by a message coming from a block queue when the block is ready for insertion pub fn import_verified_blocks(&self) -> usize { self.importer.import_verified_blocks(self) @@ -1566,7 +1564,6 @@ impl BlockChainClient for Client { }))) } - fn mode(&self) -> IpcMode { let r = self.mode.lock().clone().into(); trace!(target: "mode", "Asked for mode = {:?}. returning {:?}", &*self.mode.lock(), r); @@ -2280,7 +2277,6 @@ impl ProvingBlockChainClient for Client { ) } - fn epoch_signal(&self, hash: H256) -> Option> { // pending transitions are never deleted, and do not contain // finality proofs by definition. diff --git a/ethcore/src/client/config.rs b/ethcore/src/client/config.rs index 9787f822a4..288de25e4b 100644 --- a/ethcore/src/client/config.rs +++ b/ethcore/src/client/config.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -110,7 +110,6 @@ impl From for Mode { } } - /// Client configuration. Includes configs for all sub-systems. #[derive(Debug, PartialEq, Default)] pub struct ClientConfig { diff --git a/ethcore/src/client/error.rs b/ethcore/src/client/error.rs index d2af13a3b2..0e6608c0ff 100644 --- a/ethcore/src/client/error.rs +++ b/ethcore/src/client/error.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/client/evm_test_client.rs b/ethcore/src/client/evm_test_client.rs index b91414ca8f..fbf57cbdc7 100644 --- a/ethcore/src/client/evm_test_client.rs +++ b/ethcore/src/client/evm_test_client.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/client/io_message.rs b/ethcore/src/client/io_message.rs index 817c726020..d388f5ed44 100644 --- a/ethcore/src/client/io_message.rs +++ b/ethcore/src/client/io_message.rs @@ -54,4 +54,3 @@ impl fmt::Debug for Callback { write!(fmt, "") } } - diff --git a/ethcore/src/client/mod.rs b/ethcore/src/client/mod.rs index 4c410d3011..6e12c03052 100644 --- a/ethcore/src/client/mod.rs +++ b/ethcore/src/client/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/client/private_notify.rs b/ethcore/src/client/private_notify.rs index 2b865a9e2c..d1fde555c9 100644 --- a/ethcore/src/client/private_notify.rs +++ b/ethcore/src/client/private_notify.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/client/test_client.rs b/ethcore/src/client/test_client.rs index fab3234657..8acbde4f97 100644 --- a/ethcore/src/client/test_client.rs +++ b/ethcore/src/client/test_client.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -704,7 +704,6 @@ impl BlockChainClient for TestBlockChainClient { .map(|header| self.spec.engine.extra_info(&header)) } - fn block_status(&self, id: BlockId) -> BlockStatus { match id { BlockId::Number(number) if (number as usize) < self.blocks.read().len() => BlockStatus::InChain, diff --git a/ethcore/src/client/trace.rs b/ethcore/src/client/trace.rs index 75e0fe34a1..5f1b6c4f4d 100644 --- a/ethcore/src/client/trace.rs +++ b/ethcore/src/client/trace.rs @@ -1,3 +1,18 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . //! Bridge between Tracedb and Blockchain. diff --git a/ethcore/src/client/traits.rs b/ethcore/src/client/traits.rs index 358e24fa90..f0fae4b498 100644 --- a/ethcore/src/client/traits.rs +++ b/ethcore/src/client/traits.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/db.rs b/ethcore/src/db.rs index a1c7d6b0f5..39c30e9637 100644 --- a/ethcore/src/db.rs +++ b/ethcore/src/db.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/encoded.rs b/ethcore/src/encoded.rs index 5a2d376a2a..5bd723f0e2 100644 --- a/ethcore/src/encoded.rs +++ b/ethcore/src/encoded.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/engines/authority_round/finality.rs b/ethcore/src/engines/authority_round/finality.rs index 61f1c18229..3745cde96c 100644 --- a/ethcore/src/engines/authority_round/finality.rs +++ b/ethcore/src/engines/authority_round/finality.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/engines/authority_round/mod.rs b/ethcore/src/engines/authority_round/mod.rs index 02bb88c51f..067c754c7f 100644 --- a/ethcore/src/engines/authority_round/mod.rs +++ b/ethcore/src/engines/authority_round/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -655,7 +655,6 @@ impl AuthorityRound { }).cloned().collect() } - fn clear_empty_steps(&self, step: U256) { // clear old `empty_steps` messages self.empty_steps.lock().retain(|e| U256::from(e.step) > step); diff --git a/ethcore/src/engines/basic_authority.rs b/ethcore/src/engines/basic_authority.rs index e99fd88dcb..dde0af2d96 100644 --- a/ethcore/src/engines/basic_authority.rs +++ b/ethcore/src/engines/basic_authority.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/engines/epoch.rs b/ethcore/src/engines/epoch.rs index 6975e8898b..53b540cabd 100644 --- a/ethcore/src/engines/epoch.rs +++ b/ethcore/src/engines/epoch.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/engines/instant_seal.rs b/ethcore/src/engines/instant_seal.rs index c16203f105..a35dea5219 100644 --- a/ethcore/src/engines/instant_seal.rs +++ b/ethcore/src/engines/instant_seal.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/engines/mod.rs b/ethcore/src/engines/mod.rs index 0878b4595f..54a9dde2e6 100644 --- a/ethcore/src/engines/mod.rs +++ b/ethcore/src/engines/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/engines/null_engine.rs b/ethcore/src/engines/null_engine.rs index c6025e6247..f9e698307d 100644 --- a/ethcore/src/engines/null_engine.rs +++ b/ethcore/src/engines/null_engine.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/engines/signer.rs b/ethcore/src/engines/signer.rs index d9e97fee06..965b619c7d 100644 --- a/ethcore/src/engines/signer.rs +++ b/ethcore/src/engines/signer.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/engines/tendermint/message.rs b/ethcore/src/engines/tendermint/message.rs index 17b79a80b8..ba8e4390ec 100644 --- a/ethcore/src/engines/tendermint/message.rs +++ b/ethcore/src/engines/tendermint/message.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -43,7 +43,6 @@ pub struct VoteStep { pub step: Step, } - impl VoteStep { pub fn new(height: Height, view: View, step: Step) -> Self { VoteStep { height: height, view: view, step: step } diff --git a/ethcore/src/engines/tendermint/mod.rs b/ethcore/src/engines/tendermint/mod.rs index 52bf5ff67b..967ef482a6 100644 --- a/ethcore/src/engines/tendermint/mod.rs +++ b/ethcore/src/engines/tendermint/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -359,7 +359,6 @@ impl Tendermint { && lock_change_view < self.view.load(AtomicOrdering::SeqCst) } - fn has_enough_any_votes(&self) -> bool { let step_votes = self.votes.count_round_votes(&VoteStep::new(self.height.load(AtomicOrdering::SeqCst), self.view.load(AtomicOrdering::SeqCst), *self.step.read())); self.check_above_threshold(step_votes).is_ok() diff --git a/ethcore/src/engines/tendermint/params.rs b/ethcore/src/engines/tendermint/params.rs index c1fd39eb1c..fbd3839cad 100644 --- a/ethcore/src/engines/tendermint/params.rs +++ b/ethcore/src/engines/tendermint/params.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/engines/transition.rs b/ethcore/src/engines/transition.rs index a0469b6249..ddc9a70628 100644 --- a/ethcore/src/engines/transition.rs +++ b/ethcore/src/engines/transition.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/engines/validator_set/contract.rs b/ethcore/src/engines/validator_set/contract.rs index 00f74fd2eb..c44f2ab303 100644 --- a/ethcore/src/engines/validator_set/contract.rs +++ b/ethcore/src/engines/validator_set/contract.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/engines/validator_set/mod.rs b/ethcore/src/engines/validator_set/mod.rs index d439c69c2e..26b57d78f2 100644 --- a/ethcore/src/engines/validator_set/mod.rs +++ b/ethcore/src/engines/validator_set/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/engines/validator_set/multi.rs b/ethcore/src/engines/validator_set/multi.rs index 89a33abc74..3ac58cd4dc 100644 --- a/ethcore/src/engines/validator_set/multi.rs +++ b/ethcore/src/engines/validator_set/multi.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/engines/validator_set/safe_contract.rs b/ethcore/src/engines/validator_set/safe_contract.rs index f132a0bf9d..e55a0e3e36 100644 --- a/ethcore/src/engines/validator_set/safe_contract.rs +++ b/ethcore/src/engines/validator_set/safe_contract.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/engines/validator_set/simple_list.rs b/ethcore/src/engines/validator_set/simple_list.rs index bb67c9778b..e1339250ef 100644 --- a/ethcore/src/engines/validator_set/simple_list.rs +++ b/ethcore/src/engines/validator_set/simple_list.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/engines/validator_set/test.rs b/ethcore/src/engines/validator_set/test.rs index a6b8930454..6459803d19 100644 --- a/ethcore/src/engines/validator_set/test.rs +++ b/ethcore/src/engines/validator_set/test.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/engines/vote_collector.rs b/ethcore/src/engines/vote_collector.rs index 7af66b30c5..f416d0c3f7 100644 --- a/ethcore/src/engines/vote_collector.rs +++ b/ethcore/src/engines/vote_collector.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/error.rs b/ethcore/src/error.rs index bec749297c..ba53b9f93e 100644 --- a/ethcore/src/error.rs +++ b/ethcore/src/error.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -299,7 +299,6 @@ error_chain! { } } - /// Result of import block operation. pub type ImportResult = EthcoreResult; diff --git a/ethcore/src/ethereum/denominations.rs b/ethcore/src/ethereum/denominations.rs index 4892770df1..4c51932543 100644 --- a/ethcore/src/ethereum/denominations.rs +++ b/ethcore/src/ethereum/denominations.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -35,4 +35,3 @@ pub fn shannon() -> U256 { U256::exp10(9) } #[inline] /// 1 Wei in Wei pub fn wei() -> U256 { U256::exp10(0) } - diff --git a/ethcore/src/ethereum/ethash.rs b/ethcore/src/ethereum/ethash.rs index 9b3945e38b..b51da58fec 100644 --- a/ethcore/src/ethereum/ethash.rs +++ b/ethcore/src/ethereum/ethash.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/ethereum/mod.rs b/ethcore/src/ethereum/mod.rs index 5cf6462686..6456440759 100644 --- a/ethcore/src/ethereum/mod.rs +++ b/ethcore/src/ethereum/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/executed.rs b/ethcore/src/executed.rs index 9ffd673154..3d0b9767c4 100644 --- a/ethcore/src/executed.rs +++ b/ethcore/src/executed.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/executive.rs b/ethcore/src/executive.rs index e29da093c7..f375f3c2e8 100644 --- a/ethcore/src/executive.rs +++ b/ethcore/src/executive.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/externalities.rs b/ethcore/src/externalities.rs index 5d35d1109a..65d130c342 100644 --- a/ethcore/src/externalities.rs +++ b/ethcore/src/externalities.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/factory.rs b/ethcore/src/factory.rs index 68a15f164a..b429073b30 100644 --- a/ethcore/src/factory.rs +++ b/ethcore/src/factory.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/header.rs b/ethcore/src/header.rs index 3e9675aa35..5aa4be3237 100644 --- a/ethcore/src/header.rs +++ b/ethcore/src/header.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -338,7 +338,6 @@ fn change_field(hash: &mut Option, field: &mut T, value: T) where T: Pa } } - impl Decodable for Header { fn decode(r: &Rlp) -> Result { let mut blockheader = Header { diff --git a/ethcore/src/json_tests/chain.rs b/ethcore/src/json_tests/chain.rs index 89b8df4a26..814538cdbd 100644 --- a/ethcore/src/json_tests/chain.rs +++ b/ethcore/src/json_tests/chain.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -152,4 +152,3 @@ mod block_tests { declare_test!{BlockchainTests_TransitionTests_bcHomesteadToDao, "BlockchainTests/TransitionTests/bcHomesteadToDao/"} declare_test!{BlockchainTests_TransitionTests_bcHomesteadToEIP150, "BlockchainTests/TransitionTests/bcHomesteadToEIP150/"} } - diff --git a/ethcore/src/json_tests/difficulty.rs b/ethcore/src/json_tests/difficulty.rs index c0d03c810b..d111f0890d 100644 --- a/ethcore/src/json_tests/difficulty.rs +++ b/ethcore/src/json_tests/difficulty.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -56,7 +56,6 @@ mod difficulty_test_byzantium { declare_test!{DifficultyTests_difficultyByzantium, "BasicTests/difficultyByzantium.json"} } - mod difficulty_test_foundation { use super::json_difficulty_test; use tempdir::TempDir; @@ -68,6 +67,3 @@ mod difficulty_test_foundation { declare_test!{DifficultyTests_difficultyMainNetwork, "BasicTests/difficultyMainNetwork.json"} } - - - diff --git a/ethcore/src/json_tests/executive.rs b/ethcore/src/json_tests/executive.rs index 404b1c25e6..5bda6c55a3 100644 --- a/ethcore/src/json_tests/executive.rs +++ b/ethcore/src/json_tests/executive.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/json_tests/mod.rs b/ethcore/src/json_tests/mod.rs index a0966a2d29..65cc6d2134 100644 --- a/ethcore/src/json_tests/mod.rs +++ b/ethcore/src/json_tests/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/json_tests/state.rs b/ethcore/src/json_tests/state.rs index a55ab18443..45ec6f3fb0 100644 --- a/ethcore/src/json_tests/state.rs +++ b/ethcore/src/json_tests/state.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -135,4 +135,3 @@ mod state_tests { declare_test!{GeneralStateTest_stZeroCallsTest, "GeneralStateTests/stZeroCallsTest/"} declare_test!{GeneralStateTest_stZeroKnowledge, "GeneralStateTests/stZeroKnowledge/"} } - diff --git a/ethcore/src/json_tests/test_common.rs b/ethcore/src/json_tests/test_common.rs index 83f6b55272..6ce38b27a0 100644 --- a/ethcore/src/json_tests/test_common.rs +++ b/ethcore/src/json_tests/test_common.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/json_tests/transaction.rs b/ethcore/src/json_tests/transaction.rs index 1be4900b12..295093305d 100644 --- a/ethcore/src/json_tests/transaction.rs +++ b/ethcore/src/json_tests/transaction.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/json_tests/trie.rs b/ethcore/src/json_tests/trie.rs index f5803d2d37..fae7cc7380 100644 --- a/ethcore/src/json_tests/trie.rs +++ b/ethcore/src/json_tests/trie.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/lib.rs b/ethcore/src/lib.rs index b1782cb1d6..00113f7303 100644 --- a/ethcore/src/lib.rs +++ b/ethcore/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/machine.rs b/ethcore/src/machine.rs index 9c6db25cbc..d54dd2e292 100644 --- a/ethcore/src/machine.rs +++ b/ethcore/src/machine.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -472,7 +472,6 @@ fn round_block_gas_limit(gas_limit: U256, lower_limit: U256, upper_limit: U256) } } - #[cfg(test)] mod tests { use super::*; diff --git a/ethcore/src/miner/miner.rs b/ethcore/src/miner/miner.rs index 4904535a89..bf51d0b135 100644 --- a/ethcore/src/miner/miner.rs +++ b/ethcore/src/miner/miner.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -121,7 +121,6 @@ pub struct MinerOptions { /// will be invalid if mined. pub infinite_pending_block: bool, - /// Strategy to use for prioritizing transactions in the queue. pub tx_queue_strategy: PrioritizationStrategy, /// Simple senders penalization. @@ -506,7 +505,6 @@ impl Miner { || self.engine.seals_internally() == Some(true) || had_requests; - let should_disable_sealing = !sealing_enabled; trace!(target: "miner", "requires_reseal: should_disable_sealing={}; forced={:?}, has_local={:?}, internal={:?}, had_requests={:?}", diff --git a/ethcore/src/miner/mod.rs b/ethcore/src/miner/mod.rs index fbf4f11b7a..dd5f28feb6 100644 --- a/ethcore/src/miner/mod.rs +++ b/ethcore/src/miner/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -81,7 +81,6 @@ pub trait MinerService : Send + Sync { fn update_sealing(&self, chain: &C) where C: BlockChain + CallContract + BlockProducer + SealedBlockImporter + Nonce + Sync; - // Notifications /// Called when blocks are imported to chain, updates transactions queue. @@ -90,7 +89,6 @@ pub trait MinerService : Send + Sync { fn chain_new_blocks(&self, chain: &C, imported: &[H256], invalid: &[H256], enacted: &[H256], retracted: &[H256], is_internal_import: bool) where C: BlockChainClient; - // Pending block /// Get a list of all pending receipts from pending block. diff --git a/ethcore/src/miner/pool_client.rs b/ethcore/src/miner/pool_client.rs index dfcdec684f..226fe21e29 100644 --- a/ethcore/src/miner/pool_client.rs +++ b/ethcore/src/miner/pool_client.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/miner/service_transaction_checker.rs b/ethcore/src/miner/service_transaction_checker.rs index f085564d22..adae0c36ea 100644 --- a/ethcore/src/miner/service_transaction_checker.rs +++ b/ethcore/src/miner/service_transaction_checker.rs @@ -1,4 +1,4 @@ -// Copyright 2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -12,7 +12,7 @@ // 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 . +// along with Parity. If not, see . //! A service transactions contract checker. diff --git a/ethcore/src/miner/stratum.rs b/ethcore/src/miner/stratum.rs index c63124dcd0..0fd892bf50 100644 --- a/ethcore/src/miner/stratum.rs +++ b/ethcore/src/miner/stratum.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -111,7 +111,6 @@ pub struct StratumJobDispatcher { miner: Weak, } - impl JobDispatcher for StratumJobDispatcher { fn initial(&self) -> Option { // initial payload may contain additional data, not in this case diff --git a/ethcore/src/pod_account.rs b/ethcore/src/pod_account.rs index 027e2765ff..281299b3b2 100644 --- a/ethcore/src/pod_account.rs +++ b/ethcore/src/pod_account.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -165,7 +165,6 @@ pub fn diff_pod(pre: Option<&PodAccount>, post: Option<&PodAccount>) -> Option u64; } - /// Restore from secondary snapshot chunks. pub trait Rebuilder: Send { /// Feed a chunk, potentially out of order. diff --git a/ethcore/src/snapshot/consensus/work.rs b/ethcore/src/snapshot/consensus/work.rs index b71f7b9d1d..31c7b51ec5 100644 --- a/ethcore/src/snapshot/consensus/work.rs +++ b/ethcore/src/snapshot/consensus/work.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/snapshot/error.rs b/ethcore/src/snapshot/error.rs index 2741f648a2..36fb0927a6 100644 --- a/ethcore/src/snapshot/error.rs +++ b/ethcore/src/snapshot/error.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/snapshot/io.rs b/ethcore/src/snapshot/io.rs index 84faa19b48..7d2cbcf92c 100644 --- a/ethcore/src/snapshot/io.rs +++ b/ethcore/src/snapshot/io.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -214,7 +214,6 @@ impl PackedReader { return Ok(None); } - file.seek(SeekFrom::End(-8))?; let mut off_bytes = [0u8; 8]; diff --git a/ethcore/src/snapshot/mod.rs b/ethcore/src/snapshot/mod.rs index 8871ced26f..30a61b779c 100644 --- a/ethcore/src/snapshot/mod.rs +++ b/ethcore/src/snapshot/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/snapshot/service.rs b/ethcore/src/snapshot/service.rs index 942015d0f1..b76a703675 100644 --- a/ethcore/src/snapshot/service.rs +++ b/ethcore/src/snapshot/service.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/snapshot/tests/helpers.rs b/ethcore/src/snapshot/tests/helpers.rs index 067a3abab0..516e438abd 100644 --- a/ethcore/src/snapshot/tests/helpers.rs +++ b/ethcore/src/snapshot/tests/helpers.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/snapshot/tests/mod.rs b/ethcore/src/snapshot/tests/mod.rs index 6e9398356a..c09f2b965c 100644 --- a/ethcore/src/snapshot/tests/mod.rs +++ b/ethcore/src/snapshot/tests/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/snapshot/tests/proof_of_authority.rs b/ethcore/src/snapshot/tests/proof_of_authority.rs index 4b1b3d6ad0..d26ecfc404 100644 --- a/ethcore/src/snapshot/tests/proof_of_authority.rs +++ b/ethcore/src/snapshot/tests/proof_of_authority.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -52,7 +52,6 @@ lazy_static! { static ref RICH_SECRET: Secret = secret!("1"); } - /// Contract code used here: https://gist.github.com/anonymous/2a43783647e0f0dfcc359bd6fd81d6d9 /// Account with secrets keccak("1") is initially the validator. /// Transitions to the contract at block 2, initially same validator set. diff --git a/ethcore/src/snapshot/tests/proof_of_work.rs b/ethcore/src/snapshot/tests/proof_of_work.rs index 3c3b47ce9c..e689edf80f 100644 --- a/ethcore/src/snapshot/tests/proof_of_work.rs +++ b/ethcore/src/snapshot/tests/proof_of_work.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/snapshot/tests/service.rs b/ethcore/src/snapshot/tests/service.rs index 3fcb0addfa..55cb0e8338 100644 --- a/ethcore/src/snapshot/tests/service.rs +++ b/ethcore/src/snapshot/tests/service.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/snapshot/tests/state.rs b/ethcore/src/snapshot/tests/state.rs index 05926a7e66..12f19e8c27 100644 --- a/ethcore/src/snapshot/tests/state.rs +++ b/ethcore/src/snapshot/tests/state.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/snapshot/traits.rs b/ethcore/src/snapshot/traits.rs index d951f4c534..eec629ba6e 100644 --- a/ethcore/src/snapshot/traits.rs +++ b/ethcore/src/snapshot/traits.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/snapshot/watcher.rs b/ethcore/src/snapshot/watcher.rs index 6e04fe6d16..6805679627 100644 --- a/ethcore/src/snapshot/watcher.rs +++ b/ethcore/src/snapshot/watcher.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/spec/genesis.rs b/ethcore/src/spec/genesis.rs index 937d7ed873..fbfd2cbc42 100644 --- a/ethcore/src/spec/genesis.rs +++ b/ethcore/src/spec/genesis.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/spec/mod.rs b/ethcore/src/spec/mod.rs index fb60e1cc85..35705f4a8e 100644 --- a/ethcore/src/spec/mod.rs +++ b/ethcore/src/spec/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/spec/seal.rs b/ethcore/src/spec/seal.rs index 2a07e69c43..0ed41acc84 100644 --- a/ethcore/src/spec/seal.rs +++ b/ethcore/src/spec/seal.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/spec/spec.rs b/ethcore/src/spec/spec.rs index 98720647d8..a8ab757549 100644 --- a/ethcore/src/spec/spec.rs +++ b/ethcore/src/spec/spec.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -320,7 +320,6 @@ impl<'a, T: AsRef> From<&'a T> for SpecParams<'a> { } } - /// Parameters for a block chain; includes both those intrinsic to the design of the /// chain and those to be interpreted by the active chain engine. pub struct Spec { @@ -848,7 +847,6 @@ impl Spec { /// Create the EthereumMachine corresponding to Spec::new_test. pub fn new_test_machine() -> EthereumMachine { load_machine_bundled!("null_morden") } - /// Create a new Spec which conforms to the Frontier-era Morden chain except that it's a NullEngine consensus with applying reward on block close. pub fn new_test_with_reward() -> Spec { load_bundled!("null_morden_with_reward") } diff --git a/ethcore/src/state/account.rs b/ethcore/src/state/account.rs index 5c1dd40396..a7a40e6a3b 100644 --- a/ethcore/src/state/account.rs +++ b/ethcore/src/state/account.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/state/backend.rs b/ethcore/src/state/backend.rs index 1e761506d9..6b2e21cb46 100644 --- a/ethcore/src/state/backend.rs +++ b/ethcore/src/state/backend.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/state/mod.rs b/ethcore/src/state/mod.rs index 5b969bccb9..ccca20b71e 100644 --- a/ethcore/src/state/mod.rs +++ b/ethcore/src/state/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -51,7 +51,6 @@ use trie; use trie::{Trie, TrieError, TrieDB}; use trie::recorder::Recorder; - mod account; mod substate; diff --git a/ethcore/src/state/substate.rs b/ethcore/src/state/substate.rs index e70178a362..c2f3c62dcb 100644 --- a/ethcore/src/state/substate.rs +++ b/ethcore/src/state/substate.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/state_db.rs b/ethcore/src/state_db.rs index 3b00a42ee6..c3704828c2 100644 --- a/ethcore/src/state_db.rs +++ b/ethcore/src/state_db.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/test_helpers.rs b/ethcore/src/test_helpers.rs index e57d16a654..4a83752c04 100644 --- a/ethcore/src/test_helpers.rs +++ b/ethcore/src/test_helpers.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -283,7 +283,6 @@ pub fn generate_dummy_blockchain_with_extra(block_number: u32) -> BlockChain { let db = new_db(); let bc = BlockChain::new(BlockChainConfig::default(), &create_unverifiable_block(0, H256::zero()), db.clone()); - let mut batch = db.transaction(); for block_order in 1..block_number { // Total difficulty is always 0 here. diff --git a/ethcore/src/test_helpers_internal.rs b/ethcore/src/test_helpers_internal.rs index ef98c7c85b..7319d2d763 100644 --- a/ethcore/src/test_helpers_internal.rs +++ b/ethcore/src/test_helpers_internal.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/tests/client.rs b/ethcore/src/tests/client.rs index 6dcad9ba62..ccafcf6613 100644 --- a/ethcore/src/tests/client.rs +++ b/ethcore/src/tests/client.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -130,7 +130,6 @@ fn fails_to_import_block_with_invalid_rlp() { } } - #[test] fn query_none_block() { let tempdir = TempDir::new("").unwrap(); @@ -221,7 +220,6 @@ fn can_collect_garbage() { assert!(client.blockchain_cache_info().blocks < 100 * 1024); } - #[test] fn can_generate_gas_price_median() { let client = generate_dummy_client_with_data(3, 1, slice_into![1, 2, 3]); diff --git a/ethcore/src/tests/mod.rs b/ethcore/src/tests/mod.rs index 8b509d2afc..d1d5b6ef7f 100644 --- a/ethcore/src/tests/mod.rs +++ b/ethcore/src/tests/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/tests/trace.rs b/ethcore/src/tests/trace.rs index a98667b142..7071ef1486 100644 --- a/ethcore/src/tests/trace.rs +++ b/ethcore/src/tests/trace.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/trace/config.rs b/ethcore/src/trace/config.rs index dbd8a97aff..e9b003adf9 100644 --- a/ethcore/src/trace/config.rs +++ b/ethcore/src/trace/config.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/trace/db.rs b/ethcore/src/trace/db.rs index 45b9ebc150..29f294062c 100644 --- a/ethcore/src/trace/db.rs +++ b/ethcore/src/trace/db.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -590,7 +590,6 @@ mod tests { assert!(tracedb.traces(&block_0).is_some(), "Traces should be available even if block is non-canon."); } - #[test] fn test_import() { let db = new_db(); diff --git a/ethcore/src/trace/executive_tracer.rs b/ethcore/src/trace/executive_tracer.rs index b1d116d69d..1bae15d595 100644 --- a/ethcore/src/trace/executive_tracer.rs +++ b/ethcore/src/trace/executive_tracer.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/trace/import.rs b/ethcore/src/trace/import.rs index fb72e220e4..b720b0b86a 100644 --- a/ethcore/src/trace/import.rs +++ b/ethcore/src/trace/import.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/trace/mod.rs b/ethcore/src/trace/mod.rs index 381dcd9f0d..569b2a6791 100644 --- a/ethcore/src/trace/mod.rs +++ b/ethcore/src/trace/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/trace/noop_tracer.rs b/ethcore/src/trace/noop_tracer.rs index ab0bf77ff1..8312de58f8 100644 --- a/ethcore/src/trace/noop_tracer.rs +++ b/ethcore/src/trace/noop_tracer.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/trace/types/error.rs b/ethcore/src/trace/types/error.rs index f2fa192d33..a934443c5d 100644 --- a/ethcore/src/trace/types/error.rs +++ b/ethcore/src/trace/types/error.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/trace/types/filter.rs b/ethcore/src/trace/types/filter.rs index 308eb72da7..b3a5de58cd 100644 --- a/ethcore/src/trace/types/filter.rs +++ b/ethcore/src/trace/types/filter.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/trace/types/flat.rs b/ethcore/src/trace/types/flat.rs index 00cf517df8..8610692200 100644 --- a/ethcore/src/trace/types/flat.rs +++ b/ethcore/src/trace/types/flat.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/trace/types/localized.rs b/ethcore/src/trace/types/localized.rs index f649e16997..816eccc937 100644 --- a/ethcore/src/trace/types/localized.rs +++ b/ethcore/src/trace/types/localized.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/trace/types/mod.rs b/ethcore/src/trace/types/mod.rs index a9be2865b0..0e019ac552 100644 --- a/ethcore/src/trace/types/mod.rs +++ b/ethcore/src/trace/types/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/trace/types/trace.rs b/ethcore/src/trace/types/trace.rs index cdb00a5229..1dde16e23b 100644 --- a/ethcore/src/trace/types/trace.rs +++ b/ethcore/src/trace/types/trace.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -210,7 +210,6 @@ impl Decodable for Reward { } } - /// Suicide action. #[derive(Debug, Clone, PartialEq, RlpEncodable, RlpDecodable)] pub struct Suicide { diff --git a/ethcore/src/tx_filter.rs b/ethcore/src/tx_filter.rs index 8bbb499052..a20ff8e60c 100644 --- a/ethcore/src/tx_filter.rs +++ b/ethcore/src/tx_filter.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -198,4 +198,3 @@ mod test { assert!(!filter.transaction_allowed(&genesis, &call_tx.clone().sign(key4.secret(), None), &*client)); } } - diff --git a/ethcore/src/verification/canon_verifier.rs b/ethcore/src/verification/canon_verifier.rs index 3d0fd77c6e..0ace8987e0 100644 --- a/ethcore/src/verification/canon_verifier.rs +++ b/ethcore/src/verification/canon_verifier.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/verification/mod.rs b/ethcore/src/verification/mod.rs index d5fd4e8476..ed4227ee21 100644 --- a/ethcore/src/verification/mod.rs +++ b/ethcore/src/verification/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/verification/noop_verifier.rs b/ethcore/src/verification/noop_verifier.rs index 24b117bbc1..d04eec9b11 100644 --- a/ethcore/src/verification/noop_verifier.rs +++ b/ethcore/src/verification/noop_verifier.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/verification/queue/kind.rs b/ethcore/src/verification/queue/kind.rs index ce9bddf4ef..2d89f11a33 100644 --- a/ethcore/src/verification/queue/kind.rs +++ b/ethcore/src/verification/queue/kind.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/verification/queue/mod.rs b/ethcore/src/verification/queue/mod.rs index f7a558f33d..5ae4f7c8fc 100644 --- a/ethcore/src/verification/queue/mod.rs +++ b/ethcore/src/verification/queue/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/verification/verification.rs b/ethcore/src/verification/verification.rs index de2f6c7195..3b9104f0e1 100644 --- a/ethcore/src/verification/verification.rs +++ b/ethcore/src/verification/verification.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/verification/verifier.rs b/ethcore/src/verification/verifier.rs index a9ca22a4c8..188254b431 100644 --- a/ethcore/src/verification/verifier.rs +++ b/ethcore/src/verification/verifier.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/views/block.rs b/ethcore/src/views/block.rs index 3bed1818f2..2a7c2ebd53 100644 --- a/ethcore/src/views/block.rs +++ b/ethcore/src/views/block.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/views/body.rs b/ethcore/src/views/body.rs index d2864b9725..6560140cad 100644 --- a/ethcore/src/views/body.rs +++ b/ethcore/src/views/body.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/views/header.rs b/ethcore/src/views/header.rs index 8d407f0a1b..4b7b1225d0 100644 --- a/ethcore/src/views/header.rs +++ b/ethcore/src/views/header.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/views/mod.rs b/ethcore/src/views/mod.rs index b9cbad8889..6d32649382 100644 --- a/ethcore/src/views/mod.rs +++ b/ethcore/src/views/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -38,4 +38,4 @@ mod tests { fn should_include_file_line_number_in_panic_for_invalid_rlp() { let _ = view!(HeaderView, &[]).parent_hash(); } -} \ No newline at end of file +} diff --git a/ethcore/src/views/transaction.rs b/ethcore/src/views/transaction.rs index 5607482b30..911fde944e 100644 --- a/ethcore/src/views/transaction.rs +++ b/ethcore/src/views/transaction.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/src/views/view_rlp.rs b/ethcore/src/views/view_rlp.rs index 6afdb3af8c..2ecc4dbdd3 100644 --- a/ethcore/src/views/view_rlp.rs +++ b/ethcore/src/views/view_rlp.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -127,4 +127,4 @@ macro_rules! view { ($view: ident, $bytes: expr) => { $view::new($crate::views::ViewRlp::new($bytes, file!(), line!())) }; -} \ No newline at end of file +} diff --git a/ethcore/stratum/src/lib.rs b/ethcore/stratum/src/lib.rs index a4abeffd73..0e9de9b43c 100644 --- a/ethcore/stratum/src/lib.rs +++ b/ethcore/stratum/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/stratum/src/traits.rs b/ethcore/stratum/src/traits.rs index 431d338a42..d1bb9a4da7 100644 --- a/ethcore/stratum/src/traits.rs +++ b/ethcore/stratum/src/traits.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/sync/src/api.rs b/ethcore/sync/src/api.rs index 8419fccd7a..b759fb734a 100644 --- a/ethcore/sync/src/api.rs +++ b/ethcore/sync/src/api.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -536,7 +536,6 @@ pub trait ManageNetwork : Send + Sync { fn with_proto_context(&self, proto: ProtocolId, f: &mut FnMut(&NetworkContext)); } - impl ManageNetwork for EthSync { fn accept_unreserved_peers(&self) { self.network.set_non_reserved_mode(NonReservedPeerMode::Accept); diff --git a/ethcore/sync/src/block_sync.rs b/ethcore/sync/src/block_sync.rs index 7411fa30cc..bff9bb071a 100644 --- a/ethcore/sync/src/block_sync.rs +++ b/ethcore/sync/src/block_sync.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/sync/src/blocks.rs b/ethcore/sync/src/blocks.rs index 283f4ed610..8485b1d75e 100644 --- a/ethcore/sync/src/blocks.rs +++ b/ethcore/sync/src/blocks.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -194,7 +194,6 @@ impl BlockCollection { needed_bodies } - /// Returns a set of block hashes that require a receipt download. The returned set is marked as being downloaded. pub fn needed_receipts(&mut self, count: usize, _ignore_downloading: bool) -> Vec { if self.head.is_none() || !self.need_receipts { @@ -616,4 +615,3 @@ mod test { assert_eq!(bc.drain().len(), 2); } } - diff --git a/ethcore/sync/src/chain/mod.rs b/ethcore/sync/src/chain/mod.rs index c0ee8299b8..8f0aff7514 100644 --- a/ethcore/sync/src/chain/mod.rs +++ b/ethcore/sync/src/chain/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -1348,7 +1348,6 @@ pub mod tests { client.set_nonce(sender, U256::from(0)); } - // when { let queue = RwLock::new(VecDeque::new()); diff --git a/ethcore/sync/src/lib.rs b/ethcore/sync/src/lib.rs index c00ea5e440..35483f4ec3 100644 --- a/ethcore/sync/src/lib.rs +++ b/ethcore/sync/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/sync/src/light_sync/mod.rs b/ethcore/sync/src/light_sync/mod.rs index 9fa669817a..32e3a0dbfd 100644 --- a/ethcore/sync/src/light_sync/mod.rs +++ b/ethcore/sync/src/light_sync/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/sync/src/light_sync/response.rs b/ethcore/sync/src/light_sync/response.rs index 3629613224..161461c2a5 100644 --- a/ethcore/sync/src/light_sync/response.rs +++ b/ethcore/sync/src/light_sync/response.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/sync/src/light_sync/sync_round.rs b/ethcore/sync/src/light_sync/sync_round.rs index d477ecc815..79684efe53 100644 --- a/ethcore/sync/src/light_sync/sync_round.rs +++ b/ethcore/sync/src/light_sync/sync_round.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/sync/src/light_sync/tests/mod.rs b/ethcore/sync/src/light_sync/tests/mod.rs index 3fee1c7170..e3d46188a6 100644 --- a/ethcore/sync/src/light_sync/tests/mod.rs +++ b/ethcore/sync/src/light_sync/tests/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/sync/src/light_sync/tests/test_net.rs b/ethcore/sync/src/light_sync/tests/test_net.rs index badd35668b..5995bd7c6c 100644 --- a/ethcore/sync/src/light_sync/tests/test_net.rs +++ b/ethcore/sync/src/light_sync/tests/test_net.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/sync/src/private_tx.rs b/ethcore/sync/src/private_tx.rs index ded5de2d86..d7434c8bd5 100644 --- a/ethcore/sync/src/private_tx.rs +++ b/ethcore/sync/src/private_tx.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/sync/src/snapshot.rs b/ethcore/sync/src/snapshot.rs index b603a2a007..e5632e652b 100644 --- a/ethcore/sync/src/snapshot.rs +++ b/ethcore/sync/src/snapshot.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -274,4 +274,3 @@ mod test { assert_eq!(snapshot.is_known_bad(&hash), true); } } - diff --git a/ethcore/sync/src/sync_io.rs b/ethcore/sync/src/sync_io.rs index 76f323e826..c7704724c6 100644 --- a/ethcore/sync/src/sync_io.rs +++ b/ethcore/sync/src/sync_io.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -136,5 +136,3 @@ impl<'s> SyncIo for NetSyncIo<'s> { self.network.peer_client_version(peer_id) } } - - diff --git a/ethcore/sync/src/tests/chain.rs b/ethcore/sync/src/tests/chain.rs index 6b5ef65da1..0d9c83f2fb 100644 --- a/ethcore/sync/src/tests/chain.rs +++ b/ethcore/sync/src/tests/chain.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -253,7 +253,6 @@ fn high_td_attach() { assert_eq!(net.peer(0).chain.chain_info().best_block_number, 5); } - #[test] fn disconnect_on_unrelated_chain() { ::env_logger::init().ok(); @@ -267,4 +266,3 @@ fn disconnect_on_unrelated_chain() { net.sync(); assert_eq!(net.disconnect_events, vec![(0, 0)]); } - diff --git a/ethcore/sync/src/tests/consensus.rs b/ethcore/sync/src/tests/consensus.rs index 8825bad2c8..6b2502f4a6 100644 --- a/ethcore/sync/src/tests/consensus.rs +++ b/ethcore/sync/src/tests/consensus.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/sync/src/tests/helpers.rs b/ethcore/sync/src/tests/helpers.rs index 407f699e0e..112dab8a98 100644 --- a/ethcore/sync/src/tests/helpers.rs +++ b/ethcore/sync/src/tests/helpers.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/sync/src/tests/mod.rs b/ethcore/sync/src/tests/mod.rs index eb01108286..0168913aa1 100644 --- a/ethcore/sync/src/tests/mod.rs +++ b/ethcore/sync/src/tests/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/sync/src/tests/private.rs b/ethcore/sync/src/tests/private.rs index b54240bfb8..120dc8fc9c 100644 --- a/ethcore/sync/src/tests/private.rs +++ b/ethcore/sync/src/tests/private.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/sync/src/tests/rpc.rs b/ethcore/sync/src/tests/rpc.rs index 5806fbbd8d..99e95959be 100644 --- a/ethcore/sync/src/tests/rpc.rs +++ b/ethcore/sync/src/tests/rpc.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/sync/src/tests/snapshot.rs b/ethcore/sync/src/tests/snapshot.rs index ffb71d7a73..e6636c02f4 100644 --- a/ethcore/sync/src/tests/snapshot.rs +++ b/ethcore/sync/src/tests/snapshot.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -154,4 +154,3 @@ fn snapshot_sync() { assert_eq!(net.peer(4).snapshot_service.state_restoration_chunks.lock().len(), net.peer(0).snapshot_service.manifest.as_ref().unwrap().state_hashes.len()); assert_eq!(net.peer(4).snapshot_service.block_restoration_chunks.lock().len(), net.peer(0).snapshot_service.manifest.as_ref().unwrap().block_hashes.len()); } - diff --git a/ethcore/sync/src/transactions_stats.rs b/ethcore/sync/src/transactions_stats.rs index 4d33008621..c45b1ad8b3 100644 --- a/ethcore/sync/src/transactions_stats.rs +++ b/ethcore/sync/src/transactions_stats.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/transaction/src/error.rs b/ethcore/transaction/src/error.rs index eeeba4e53a..0efd18ae6b 100644 --- a/ethcore/transaction/src/error.rs +++ b/ethcore/transaction/src/error.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -130,4 +130,3 @@ impl error::Error for Error { "Transaction error" } } - diff --git a/ethcore/transaction/src/lib.rs b/ethcore/transaction/src/lib.rs index 6a478b9463..829613cf9c 100644 --- a/ethcore/transaction/src/lib.rs +++ b/ethcore/transaction/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/transaction/src/transaction.rs b/ethcore/transaction/src/transaction.rs index 6152e61acb..dd1e8ca2cc 100644 --- a/ethcore/transaction/src/transaction.rs +++ b/ethcore/transaction/src/transaction.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/types/src/account_diff.rs b/ethcore/types/src/account_diff.rs index c3edb1fb1e..521ed8ab1f 100644 --- a/ethcore/types/src/account_diff.rs +++ b/ethcore/types/src/account_diff.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -138,4 +138,3 @@ impl fmt::Display for AccountDiff { Ok(()) } } - diff --git a/ethcore/types/src/basic_account.rs b/ethcore/types/src/basic_account.rs index 79e75dfc01..94157977bc 100644 --- a/ethcore/types/src/basic_account.rs +++ b/ethcore/types/src/basic_account.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/types/src/block_status.rs b/ethcore/types/src/block_status.rs index d330b9ed1b..5455f1d40f 100644 --- a/ethcore/types/src/block_status.rs +++ b/ethcore/types/src/block_status.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/types/src/blockchain_info.rs b/ethcore/types/src/blockchain_info.rs index 836ee7618b..ddd91623d1 100644 --- a/ethcore/types/src/blockchain_info.rs +++ b/ethcore/types/src/blockchain_info.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/types/src/call_analytics.rs b/ethcore/types/src/call_analytics.rs index b0520a0d3f..ae53e6911e 100644 --- a/ethcore/types/src/call_analytics.rs +++ b/ethcore/types/src/call_analytics.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/types/src/filter.rs b/ethcore/types/src/filter.rs index 0a37482b94..c32551473d 100644 --- a/ethcore/types/src/filter.rs +++ b/ethcore/types/src/filter.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/types/src/ids.rs b/ethcore/types/src/ids.rs index e304698a4c..d1457832c0 100644 --- a/ethcore/types/src/ids.rs +++ b/ethcore/types/src/ids.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/types/src/lib.rs b/ethcore/types/src/lib.rs index 18e0dde86a..8db6163bbf 100644 --- a/ethcore/types/src/lib.rs +++ b/ethcore/types/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/types/src/log_entry.rs b/ethcore/types/src/log_entry.rs index 951a7389f2..0b7455df49 100644 --- a/ethcore/types/src/log_entry.rs +++ b/ethcore/types/src/log_entry.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/types/src/mode.rs b/ethcore/types/src/mode.rs index 539ebcdbd8..ee4f9fbf2c 100644 --- a/ethcore/types/src/mode.rs +++ b/ethcore/types/src/mode.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/types/src/pruning_info.rs b/ethcore/types/src/pruning_info.rs index 8a47fdd8b9..fcf4a774a2 100644 --- a/ethcore/types/src/pruning_info.rs +++ b/ethcore/types/src/pruning_info.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/types/src/receipt.rs b/ethcore/types/src/receipt.rs index 8846d27c02..b4f105afab 100644 --- a/ethcore/types/src/receipt.rs +++ b/ethcore/types/src/receipt.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/types/src/restoration_status.rs b/ethcore/types/src/restoration_status.rs index 51f5b8aa0a..ec15bf4809 100644 --- a/ethcore/types/src/restoration_status.rs +++ b/ethcore/types/src/restoration_status.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -40,4 +40,3 @@ pub enum RestorationStatus { /// Failed restoration. Failed, } - diff --git a/ethcore/types/src/security_level.rs b/ethcore/types/src/security_level.rs index ea39dc3280..5917584704 100644 --- a/ethcore/types/src/security_level.rs +++ b/ethcore/types/src/security_level.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/types/src/snapshot_manifest.rs b/ethcore/types/src/snapshot_manifest.rs index c59402023a..40ff4c532f 100644 --- a/ethcore/types/src/snapshot_manifest.rs +++ b/ethcore/types/src/snapshot_manifest.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -76,4 +76,3 @@ impl ManifestData { }) } } - diff --git a/ethcore/types/src/state_diff.rs b/ethcore/types/src/state_diff.rs index dd976eb36c..4cc85fff93 100644 --- a/ethcore/types/src/state_diff.rs +++ b/ethcore/types/src/state_diff.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/types/src/trace_filter.rs b/ethcore/types/src/trace_filter.rs index 2afa752ccb..69a3787027 100644 --- a/ethcore/types/src/trace_filter.rs +++ b/ethcore/types/src/trace_filter.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/types/src/tree_route.rs b/ethcore/types/src/tree_route.rs index 5d1bddd87b..9c84052be3 100644 --- a/ethcore/types/src/tree_route.rs +++ b/ethcore/types/src/tree_route.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/types/src/verification_queue_info.rs b/ethcore/types/src/verification_queue_info.rs index db818590af..bc280b15bf 100644 --- a/ethcore/types/src/verification_queue_info.rs +++ b/ethcore/types/src/verification_queue_info.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/vm/src/action_params.rs b/ethcore/vm/src/action_params.rs index 9e9a35528c..481f637310 100644 --- a/ethcore/vm/src/action_params.rs +++ b/ethcore/vm/src/action_params.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/vm/src/call_type.rs b/ethcore/vm/src/call_type.rs index dc00b2b839..0e58d76bbd 100644 --- a/ethcore/vm/src/call_type.rs +++ b/ethcore/vm/src/call_type.rs @@ -1,3 +1,19 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + //! EVM call types. use rlp::{Encodable, Decodable, DecoderError, RlpStream, Rlp}; diff --git a/ethcore/vm/src/env_info.rs b/ethcore/vm/src/env_info.rs index 71bb48eeb7..bb1c9ecd91 100644 --- a/ethcore/vm/src/env_info.rs +++ b/ethcore/vm/src/env_info.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/vm/src/error.rs b/ethcore/vm/src/error.rs index fe8d7054cf..ad23e3e020 100644 --- a/ethcore/vm/src/error.rs +++ b/ethcore/vm/src/error.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -71,7 +71,6 @@ pub enum Error { Reverted, } - impl From> for Error { fn from(err: Box) -> Self { Error::Internal(format!("Internal error: {}", err)) diff --git a/ethcore/vm/src/ext.rs b/ethcore/vm/src/ext.rs index 98661e47e2..166e8712aa 100644 --- a/ethcore/vm/src/ext.rs +++ b/ethcore/vm/src/ext.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/vm/src/lib.rs b/ethcore/vm/src/lib.rs index 67fc59bab5..0dc1b79954 100644 --- a/ethcore/vm/src/lib.rs +++ b/ethcore/vm/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/vm/src/return_data.rs b/ethcore/vm/src/return_data.rs index 067a26e35e..24191ec55f 100644 --- a/ethcore/vm/src/return_data.rs +++ b/ethcore/vm/src/return_data.rs @@ -1,3 +1,5 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. // Parity is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by diff --git a/ethcore/vm/src/schedule.rs b/ethcore/vm/src/schedule.rs index a0085ef1ec..960821e72c 100644 --- a/ethcore/vm/src/schedule.rs +++ b/ethcore/vm/src/schedule.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/vm/src/tests.rs b/ethcore/vm/src/tests.rs index daf46be0f0..9a17e0d3dc 100644 --- a/ethcore/vm/src/tests.rs +++ b/ethcore/vm/src/tests.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/wasm/run/src/fixture.rs b/ethcore/wasm/run/src/fixture.rs index ba2da06706..9fc1ca6fef 100644 --- a/ethcore/wasm/run/src/fixture.rs +++ b/ethcore/wasm/run/src/fixture.rs @@ -1,3 +1,19 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + use std::borrow::Cow; use ethjson::uint::Uint; use ethjson::hash::{Address, H256}; @@ -67,4 +83,4 @@ pub enum Assert { HasStorage(StorageAssert), UsedGas(u64), Return(Bytes), -} \ No newline at end of file +} diff --git a/ethcore/wasm/run/src/main.rs b/ethcore/wasm/run/src/main.rs index ab8ac631df..d2a3a0ff50 100644 --- a/ethcore/wasm/run/src/main.rs +++ b/ethcore/wasm/run/src/main.rs @@ -1,3 +1,19 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + extern crate serde; extern crate serde_json; #[macro_use] extern crate serde_derive; diff --git a/ethcore/wasm/run/src/runner.rs b/ethcore/wasm/run/src/runner.rs index 5ae0f941a4..3e24ced5db 100644 --- a/ethcore/wasm/run/src/runner.rs +++ b/ethcore/wasm/run/src/runner.rs @@ -1,3 +1,19 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + use fixture::{Fixture, Assert, CallLocator, Source}; use wasm::WasmInterpreter; use vm::{self, Vm, GasLeft, ActionParams, ActionValue, ParamsType}; diff --git a/ethcore/wasm/src/env.rs b/ethcore/wasm/src/env.rs index 7ffaaf98ab..9bcbee63fb 100644 --- a/ethcore/wasm/src/env.rs +++ b/ethcore/wasm/src/env.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -295,4 +295,4 @@ impl wasmi::ModuleImportResolver for ImportResolver { Err(Error::Instantiation("Memory imported under unknown name".to_owned())) } } -} \ No newline at end of file +} diff --git a/ethcore/wasm/src/lib.rs b/ethcore/wasm/src/lib.rs index 5605a7ea18..f1290318e0 100644 --- a/ethcore/wasm/src/lib.rs +++ b/ethcore/wasm/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/wasm/src/panic_payload.rs b/ethcore/wasm/src/panic_payload.rs index dc95f53fbf..36aa6c5f58 100644 --- a/ethcore/wasm/src/panic_payload.rs +++ b/ethcore/wasm/src/panic_payload.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethcore/wasm/src/parser.rs b/ethcore/wasm/src/parser.rs index 62cd66cb98..1efb89e1bd 100644 --- a/ethcore/wasm/src/parser.rs +++ b/ethcore/wasm/src/parser.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -95,4 +95,4 @@ pub fn payload<'a>(params: &'a vm::ActionParams, wasm_costs: &vm::WasmCosts) }; Ok((contract_module, data)) -} \ No newline at end of file +} diff --git a/ethcore/wasm/src/tests.rs b/ethcore/wasm/src/tests.rs index 2b71a1768e..b32ca75ae9 100644 --- a/ethcore/wasm/src/tests.rs +++ b/ethcore/wasm/src/tests.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethkey/cli/src/main.rs b/ethkey/cli/src/main.rs index 0dfc8aecde..c8f5e2e64e 100644 --- a/ethkey/cli/src/main.rs +++ b/ethkey/cli/src/main.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethkey/src/brain.rs b/ethkey/src/brain.rs index fffae0bed8..55b525e2a4 100644 --- a/ethkey/src/brain.rs +++ b/ethkey/src/brain.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethkey/src/brain_prefix.rs b/ethkey/src/brain_prefix.rs index a4e31e989c..accf947370 100644 --- a/ethkey/src/brain_prefix.rs +++ b/ethkey/src/brain_prefix.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethkey/src/brain_recover.rs b/ethkey/src/brain_recover.rs index f064c6fd0e..5133193232 100644 --- a/ethkey/src/brain_recover.rs +++ b/ethkey/src/brain_recover.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -21,7 +21,6 @@ use parity_wordlist; use super::{Address, Brain, Generator}; - /// Tries to find a phrase for address, given the number /// of expected words and a partial phrase. /// @@ -150,7 +149,6 @@ impl Iterator for PhrasesIterator { mod tests { use super::PhrasesIterator; - #[test] fn should_generate_possible_combinations() { let mut it = PhrasesIterator::new(vec![ diff --git a/ethkey/src/crypto.rs b/ethkey/src/crypto.rs index 739a463c07..3ff809614e 100644 --- a/ethkey/src/crypto.rs +++ b/ethkey/src/crypto.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethkey/src/error.rs b/ethkey/src/error.rs index c7faf67788..7cba375d0f 100644 --- a/ethkey/src/error.rs +++ b/ethkey/src/error.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethkey/src/extended.rs b/ethkey/src/extended.rs index d41ae54c53..89a4bb26a0 100644 --- a/ethkey/src/extended.rs +++ b/ethkey/src/extended.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethkey/src/keccak.rs b/ethkey/src/keccak.rs index 002f20d946..3801d841ab 100644 --- a/ethkey/src/keccak.rs +++ b/ethkey/src/keccak.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethkey/src/keypair.rs b/ethkey/src/keypair.rs index 5a13d476bb..610c14524f 100644 --- a/ethkey/src/keypair.rs +++ b/ethkey/src/keypair.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethkey/src/lib.rs b/ethkey/src/lib.rs index b5cf984530..7aec015c47 100644 --- a/ethkey/src/lib.rs +++ b/ethkey/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethkey/src/math.rs b/ethkey/src/math.rs index e2426b4fbd..6b1d4013bd 100644 --- a/ethkey/src/math.rs +++ b/ethkey/src/math.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethkey/src/prefix.rs b/ethkey/src/prefix.rs index f2ef0f0ffb..2668050ef8 100644 --- a/ethkey/src/prefix.rs +++ b/ethkey/src/prefix.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethkey/src/random.rs b/ethkey/src/random.rs index b44a4b2ca8..d42bb4ea4d 100644 --- a/ethkey/src/random.rs +++ b/ethkey/src/random.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethkey/src/secret.rs b/ethkey/src/secret.rs index c3bf2a12ba..a3560698af 100644 --- a/ethkey/src/secret.rs +++ b/ethkey/src/secret.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethkey/src/signature.rs b/ethkey/src/signature.rs index ec225ec011..cd6d88fe18 100644 --- a/ethkey/src/signature.rs +++ b/ethkey/src/signature.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethstore/cli/src/crack.rs b/ethstore/cli/src/crack.rs index 64eda66e56..3e767a6084 100644 --- a/ethstore/cli/src/crack.rs +++ b/ethstore/cli/src/crack.rs @@ -1,3 +1,19 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + use std::{cmp, thread}; use std::sync::Arc; use std::collections::VecDeque; diff --git a/ethstore/cli/src/main.rs b/ethstore/cli/src/main.rs index 8ebb206a0b..416b64d43e 100644 --- a/ethstore/cli/src/main.rs +++ b/ethstore/cli/src/main.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethstore/cli/tests/cli.rs b/ethstore/cli/tests/cli.rs index a740b95c28..1b899f7082 100644 --- a/ethstore/cli/tests/cli.rs +++ b/ethstore/cli/tests/cli.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -74,7 +74,6 @@ fn cli_cmd() { "--vault-pwd", test_password]); assert_eq!(output, "0x54ab6e5cf0c5cb40043fdca5d15d611a3a94285414a076dafecc8dc9c04183f413296a3defff61092c0bb478dc9887ec01070e1275234211208fb8f4be4a9b0101\n"); - let output = run(&["public", &address[2..], test_vault_addr, "--dir", dir_str, "--vault", "test-vault", diff --git a/ethstore/src/account/cipher.rs b/ethstore/src/account/cipher.rs index 427ccafc4a..92a5304edb 100644 --- a/ethstore/src/account/cipher.rs +++ b/ethstore/src/account/cipher.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethstore/src/account/crypto.rs b/ethstore/src/account/crypto.rs index bd65bc927b..3143958a12 100644 --- a/ethstore/src/account/crypto.rs +++ b/ethstore/src/account/crypto.rs @@ -1,4 +1,4 @@ -// Copyright 2015, 2016, 2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethstore/src/account/kdf.rs b/ethstore/src/account/kdf.rs index 31b8f304ca..4d6d7cd956 100644 --- a/ethstore/src/account/kdf.rs +++ b/ethstore/src/account/kdf.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethstore/src/account/mod.rs b/ethstore/src/account/mod.rs index c352ffe78f..e13237d827 100644 --- a/ethstore/src/account/mod.rs +++ b/ethstore/src/account/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -25,4 +25,3 @@ pub use self::crypto::Crypto; pub use self::kdf::{Kdf, Pbkdf2, Scrypt, Prf}; pub use self::safe_account::SafeAccount; pub use self::version::Version; - diff --git a/ethstore/src/account/safe_account.rs b/ethstore/src/account/safe_account.rs index 069c997e10..0bda99d02c 100644 --- a/ethstore/src/account/safe_account.rs +++ b/ethstore/src/account/safe_account.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethstore/src/account/version.rs b/ethstore/src/account/version.rs index 2ba0848a68..d206a2c12d 100644 --- a/ethstore/src/account/version.rs +++ b/ethstore/src/account/version.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethstore/src/accounts_dir/disk.rs b/ethstore/src/accounts_dir/disk.rs index 29b7e52466..79e8c0f4c3 100644 --- a/ethstore/src/accounts_dir/disk.rs +++ b/ethstore/src/accounts_dir/disk.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -153,7 +153,6 @@ impl DiskDirectory where T: KeyFileManager { ) } - /// insert account with given filename. if the filename is a duplicate of any stored account and dedup is set to /// true, a random suffix is appended to the filename. pub fn insert_with_filename(&self, account: SafeAccount, mut filename: String, dedup: bool) -> Result { diff --git a/ethstore/src/accounts_dir/memory.rs b/ethstore/src/accounts_dir/memory.rs index 5cfdba0e5c..71ddfa536e 100644 --- a/ethstore/src/accounts_dir/memory.rs +++ b/ethstore/src/accounts_dir/memory.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -72,4 +72,3 @@ impl KeyDirectory for MemoryDirectory { Ok(val) } } - diff --git a/ethstore/src/accounts_dir/mod.rs b/ethstore/src/accounts_dir/mod.rs index ec72d05da3..b8dd313d26 100644 --- a/ethstore/src/accounts_dir/mod.rs +++ b/ethstore/src/accounts_dir/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethstore/src/accounts_dir/vault.rs b/ethstore/src/accounts_dir/vault.rs index 2705262666..b2f6ce6160 100644 --- a/ethstore/src/accounts_dir/vault.rs +++ b/ethstore/src/accounts_dir/vault.rs @@ -1,4 +1,4 @@ -// Copyright 2015, 2016, 2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethstore/src/error.rs b/ethstore/src/error.rs index 7c89473280..6a2c257633 100644 --- a/ethstore/src/error.rs +++ b/ethstore/src/error.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethstore/src/ethkey.rs b/ethstore/src/ethkey.rs index 4821263910..34e89a4fb5 100644 --- a/ethstore/src/ethkey.rs +++ b/ethstore/src/ethkey.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethstore/src/ethstore.rs b/ethstore/src/ethstore.rs index 46c81153c7..13780f7f63 100644 --- a/ethstore/src/ethstore.rs +++ b/ethstore/src/ethstore.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethstore/src/import.rs b/ethstore/src/import.rs index 2aaef51f50..876119fd50 100644 --- a/ethstore/src/import.rs +++ b/ethstore/src/import.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethstore/src/json/bytes.rs b/ethstore/src/json/bytes.rs index de2c645636..b5aae19222 100644 --- a/ethstore/src/json/bytes.rs +++ b/ethstore/src/json/bytes.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -72,4 +72,3 @@ impl From for Vec { b.0 } } - diff --git a/ethstore/src/json/cipher.rs b/ethstore/src/json/cipher.rs index 33f4ec5721..6fffdde9e2 100644 --- a/ethstore/src/json/cipher.rs +++ b/ethstore/src/json/cipher.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethstore/src/json/crypto.rs b/ethstore/src/json/crypto.rs index 03f72e576e..0a926cc83f 100644 --- a/ethstore/src/json/crypto.rs +++ b/ethstore/src/json/crypto.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethstore/src/json/error.rs b/ethstore/src/json/error.rs index 8a5029642d..81b805bfe2 100644 --- a/ethstore/src/json/error.rs +++ b/ethstore/src/json/error.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethstore/src/json/hash.rs b/ethstore/src/json/hash.rs index 13564c95d1..c2ad547734 100644 --- a/ethstore/src/json/hash.rs +++ b/ethstore/src/json/hash.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethstore/src/json/id.rs b/ethstore/src/json/id.rs index aa90a4d7a4..7df5c8f7e5 100644 --- a/ethstore/src/json/id.rs +++ b/ethstore/src/json/id.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethstore/src/json/kdf.rs b/ethstore/src/json/kdf.rs index 6498323be2..f8df3c2285 100644 --- a/ethstore/src/json/kdf.rs +++ b/ethstore/src/json/kdf.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethstore/src/json/key_file.rs b/ethstore/src/json/key_file.rs index 60b34681e2..2c3cf3fdd5 100644 --- a/ethstore/src/json/key_file.rs +++ b/ethstore/src/json/key_file.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -102,7 +102,6 @@ impl<'a> Deserialize<'a> for KeyFile { } } - fn none_if_empty<'a, T>(v: Option) -> Option where T: DeserializeOwned { diff --git a/ethstore/src/json/mod.rs b/ethstore/src/json/mod.rs index 865b75dea6..e39bff651e 100644 --- a/ethstore/src/json/mod.rs +++ b/ethstore/src/json/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethstore/src/json/presale.rs b/ethstore/src/json/presale.rs index d1cffcb6ad..478f328a43 100644 --- a/ethstore/src/json/presale.rs +++ b/ethstore/src/json/presale.rs @@ -1,3 +1,19 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + use std::io::Read; use serde_json; use super::{H160, Bytes}; diff --git a/ethstore/src/json/vault_file.rs b/ethstore/src/json/vault_file.rs index d11e71451f..e962044227 100644 --- a/ethstore/src/json/vault_file.rs +++ b/ethstore/src/json/vault_file.rs @@ -1,4 +1,4 @@ -// Copyright 2015, 2016, 2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethstore/src/json/vault_key_file.rs b/ethstore/src/json/vault_key_file.rs index 76c59b3808..818487d52b 100644 --- a/ethstore/src/json/vault_key_file.rs +++ b/ethstore/src/json/vault_key_file.rs @@ -1,4 +1,4 @@ -// Copyright 2015, 2016, 2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethstore/src/json/version.rs b/ethstore/src/json/version.rs index 0eb8450f14..683d4a520f 100644 --- a/ethstore/src/json/version.rs +++ b/ethstore/src/json/version.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -56,4 +56,3 @@ impl<'a> Visitor<'a> for VersionVisitor { } } } - diff --git a/ethstore/src/lib.rs b/ethstore/src/lib.rs index b558126ada..67e636dd5c 100644 --- a/ethstore/src/lib.rs +++ b/ethstore/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethstore/src/presale.rs b/ethstore/src/presale.rs index 555d00c1e9..d7b80d240c 100644 --- a/ethstore/src/presale.rs +++ b/ethstore/src/presale.rs @@ -1,3 +1,19 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + use std::fs; use std::path::Path; use json; diff --git a/ethstore/src/random.rs b/ethstore/src/random.rs index af754471e1..b8b7a71fa8 100644 --- a/ethstore/src/random.rs +++ b/ethstore/src/random.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -43,4 +43,3 @@ pub fn random_string(length: usize) -> String { let mut rng = OsRng::new().expect("Not able to operate without random source."); rng.gen_ascii_chars().take(length).collect() } - diff --git a/ethstore/src/secret_store.rs b/ethstore/src/secret_store.rs index ebac2f9922..fd37267a74 100644 --- a/ethstore/src/secret_store.rs +++ b/ethstore/src/secret_store.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethstore/tests/api.rs b/ethstore/tests/api.rs index fb24ff3367..5e4eaab817 100644 --- a/ethstore/tests/api.rs +++ b/ethstore/tests/api.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethstore/tests/util/mod.rs b/ethstore/tests/util/mod.rs index c0002d4e13..1a7abc93ef 100644 --- a/ethstore/tests/util/mod.rs +++ b/ethstore/tests/util/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ethstore/tests/util/transient_dir.rs b/ethstore/tests/util/transient_dir.rs index dcc65ec698..c0969418d8 100644 --- a/ethstore/tests/util/transient_dir.rs +++ b/ethstore/tests/util/transient_dir.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/evmbin/benches/mod.rs b/evmbin/benches/mod.rs index 6b6746e747..8fdd5e9cfe 100644 --- a/evmbin/benches/mod.rs +++ b/evmbin/benches/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -83,4 +83,3 @@ fn rng(gas: U256, b: &mut Bencher) { run_vm(params) }); } - diff --git a/evmbin/src/display/json.rs b/evmbin/src/display/json.rs index 00ca91b94f..ccee9c3717 100644 --- a/evmbin/src/display/json.rs +++ b/evmbin/src/display/json.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -156,7 +156,6 @@ impl trace::VMTracer for Informant { self.storage.insert(pos.into(), val.into()); } - if !self.subtraces.is_empty() { self.traces.extend(mem::replace(&mut self.subtraces, vec![])); } diff --git a/evmbin/src/display/mod.rs b/evmbin/src/display/mod.rs index b9390058b6..a8eb20d9e6 100644 --- a/evmbin/src/display/mod.rs +++ b/evmbin/src/display/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/evmbin/src/display/simple.rs b/evmbin/src/display/simple.rs index 30bb8ffcf7..8ff863cfa9 100644 --- a/evmbin/src/display/simple.rs +++ b/evmbin/src/display/simple.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/evmbin/src/display/std_json.rs b/evmbin/src/display/std_json.rs index 3d8f52dbd1..6c4dac1626 100644 --- a/evmbin/src/display/std_json.rs +++ b/evmbin/src/display/std_json.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/evmbin/src/info.rs b/evmbin/src/info.rs index 1be81d9132..d1cd3cf6fc 100644 --- a/evmbin/src/info.rs +++ b/evmbin/src/info.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/evmbin/src/main.rs b/evmbin/src/main.rs index bddb40ecd2..4620143f76 100644 --- a/evmbin/src/main.rs +++ b/evmbin/src/main.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -83,7 +83,6 @@ General options: -h, --help Display this message and exit. "#; - fn main() { panic_hook::set(); diff --git a/hash-fetch/src/client.rs b/hash-fetch/src/client.rs index 1c7d417758..ebdab681a4 100644 --- a/hash-fetch/src/client.rs +++ b/hash-fetch/src/client.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/hash-fetch/src/lib.rs b/hash-fetch/src/lib.rs index 18176be500..bdbb0e3505 100644 --- a/hash-fetch/src/lib.rs +++ b/hash-fetch/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/hash-fetch/src/urlhint.rs b/hash-fetch/src/urlhint.rs index d05dd40a22..d80566ea62 100644 --- a/hash-fetch/src/urlhint.rs +++ b/hash-fetch/src/urlhint.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -265,8 +265,6 @@ pub mod tests { let calls = registrar.calls.clone(); let urlhint = URLHintContract::new(Arc::new(registrar)); - - // when let res = urlhint.resolve("test".as_bytes().into()).wait().unwrap(); let calls = calls.lock(); @@ -353,7 +351,6 @@ pub mod tests { let url4 = "https://parity.io/parity.png#content-type=image/jpeg"; let url5 = "https://parity.io/parity.png"; - assert_eq!(guess_mime_type(url1), None); assert_eq!(guess_mime_type(url2), Some(mime::IMAGE_PNG)); assert_eq!(guess_mime_type(url3), Some(mime::IMAGE_PNG)); diff --git a/hw/src/ledger.rs b/hw/src/ledger.rs index e31d49f130..992a565d5a 100644 --- a/hw/src/ledger.rs +++ b/hw/src/ledger.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/hw/src/lib.rs b/hw/src/lib.rs index f51be356ae..4cc0d30856 100644 --- a/hw/src/lib.rs +++ b/hw/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -92,7 +92,6 @@ pub trait Wallet<'a> { where F: Fn() -> Result; } - /// Hardware wallet error. #[derive(Debug)] pub enum Error { diff --git a/hw/src/trezor.rs b/hw/src/trezor.rs index 044e5487b4..21dcd9c9fd 100644 --- a/hw/src/trezor.rs +++ b/hw/src/trezor.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -164,7 +164,6 @@ impl Manager { unlocked } - fn u256_to_be_vec(&self, val: &U256) -> Vec { let mut buf = [0u8; 32]; val.to_big_endian(&mut buf); diff --git a/ipfs/src/error.rs b/ipfs/src/error.rs index fadd75b9b4..1ff2829553 100644 --- a/ipfs/src/error.rs +++ b/ipfs/src/error.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ipfs/src/lib.rs b/ipfs/src/lib.rs index bb7d0c3897..7f6ebe77c4 100644 --- a/ipfs/src/lib.rs +++ b/ipfs/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/ipfs/src/route.rs b/ipfs/src/route.rs index 2beb4ccc37..8f57fc4d10 100644 --- a/ipfs/src/route.rs +++ b/ipfs/src/route.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/json/src/blockchain/account.rs b/json/src/blockchain/account.rs index 66b5f9b844..38a0b1fa9c 100644 --- a/json/src/blockchain/account.rs +++ b/json/src/blockchain/account.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/json/src/blockchain/block.rs b/json/src/blockchain/block.rs index 503230f09e..5a6c995658 100644 --- a/json/src/blockchain/block.rs +++ b/json/src/blockchain/block.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/json/src/blockchain/blockchain.rs b/json/src/blockchain/blockchain.rs index 9edd753130..9e4d650b85 100644 --- a/json/src/blockchain/blockchain.rs +++ b/json/src/blockchain/blockchain.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/json/src/blockchain/header.rs b/json/src/blockchain/header.rs index 667a36bb1b..ee79a928ea 100644 --- a/json/src/blockchain/header.rs +++ b/json/src/blockchain/header.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/json/src/blockchain/mod.rs b/json/src/blockchain/mod.rs index e1faa07880..0d8e7ff78f 100644 --- a/json/src/blockchain/mod.rs +++ b/json/src/blockchain/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/json/src/blockchain/state.rs b/json/src/blockchain/state.rs index a64887572b..e23a31efa0 100644 --- a/json/src/blockchain/state.rs +++ b/json/src/blockchain/state.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/json/src/blockchain/test.rs b/json/src/blockchain/test.rs index 018ae767dd..792303dc7e 100644 --- a/json/src/blockchain/test.rs +++ b/json/src/blockchain/test.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/json/src/blockchain/transaction.rs b/json/src/blockchain/transaction.rs index 6b3550fd78..f14dd5e336 100644 --- a/json/src/blockchain/transaction.rs +++ b/json/src/blockchain/transaction.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/json/src/bytes.rs b/json/src/bytes.rs index 79ba4f896b..3eb1f54152 100644 --- a/json/src/bytes.rs +++ b/json/src/bytes.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/json/src/hash.rs b/json/src/hash.rs index 54aea04365..8dac3f6e73 100644 --- a/json/src/hash.rs +++ b/json/src/hash.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -23,7 +23,6 @@ use serde::de::{Error, Visitor}; use rustc_hex::ToHex; use ethereum_types::{H64 as Hash64, H160 as Hash160, H256 as Hash256, H520 as Hash520, Bloom as Hash2048}; - macro_rules! impl_hash { ($name: ident, $inner: ident) => { /// Lenient hash json deserialization for test json files. diff --git a/json/src/lib.rs b/json/src/lib.rs index 3cb1e49f57..5d31cd6c97 100644 --- a/json/src/lib.rs +++ b/json/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/json/src/maybe.rs b/json/src/maybe.rs index 8b74b22c48..1f77a98ef1 100644 --- a/json/src/maybe.rs +++ b/json/src/maybe.rs @@ -1,3 +1,18 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . //! Deserializer of empty string values into optionals. diff --git a/json/src/misc/account_meta.rs b/json/src/misc/account_meta.rs index 9c4d67286e..cb6ed1c877 100644 --- a/json/src/misc/account_meta.rs +++ b/json/src/misc/account_meta.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/json/src/misc/dapps_settings.rs b/json/src/misc/dapps_settings.rs index 5081c62b28..f59f5f1cf6 100644 --- a/json/src/misc/dapps_settings.rs +++ b/json/src/misc/dapps_settings.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/json/src/misc/mod.rs b/json/src/misc/mod.rs index d587f2f157..836094f0c0 100644 --- a/json/src/misc/mod.rs +++ b/json/src/misc/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/json/src/spec/account.rs b/json/src/spec/account.rs index fb41137aa9..acc6d96b58 100644 --- a/json/src/spec/account.rs +++ b/json/src/spec/account.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/json/src/spec/authority_round.rs b/json/src/spec/authority_round.rs index 4ef9368362..e355c6fe95 100644 --- a/json/src/spec/authority_round.rs +++ b/json/src/spec/authority_round.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/json/src/spec/basic_authority.rs b/json/src/spec/basic_authority.rs index 0a257f134b..1e5c6b8456 100644 --- a/json/src/spec/basic_authority.rs +++ b/json/src/spec/basic_authority.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/json/src/spec/builtin.rs b/json/src/spec/builtin.rs index 34e9a2df1c..850867d095 100644 --- a/json/src/spec/builtin.rs +++ b/json/src/spec/builtin.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/json/src/spec/engine.rs b/json/src/spec/engine.rs index e2545a5f90..55b9c1b2af 100644 --- a/json/src/spec/engine.rs +++ b/json/src/spec/engine.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -142,4 +142,3 @@ mod tests { }; } } - diff --git a/json/src/spec/ethash.rs b/json/src/spec/ethash.rs index 66f6913e57..19fd096627 100644 --- a/json/src/spec/ethash.rs +++ b/json/src/spec/ethash.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/json/src/spec/genesis.rs b/json/src/spec/genesis.rs index f595e7750f..d8e2ad5357 100644 --- a/json/src/spec/genesis.rs +++ b/json/src/spec/genesis.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/json/src/spec/hardcoded_sync.rs b/json/src/spec/hardcoded_sync.rs index 548fd66f0f..8b00b5413b 100644 --- a/json/src/spec/hardcoded_sync.rs +++ b/json/src/spec/hardcoded_sync.rs @@ -1,4 +1,4 @@ -// Copyright 2018 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/json/src/spec/mod.rs b/json/src/spec/mod.rs index 285596f14a..26965c887d 100644 --- a/json/src/spec/mod.rs +++ b/json/src/spec/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/json/src/spec/null_engine.rs b/json/src/spec/null_engine.rs index cfd3d6ce63..87827bd5b9 100644 --- a/json/src/spec/null_engine.rs +++ b/json/src/spec/null_engine.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/json/src/spec/params.rs b/json/src/spec/params.rs index f171a88101..e03fe7081b 100644 --- a/json/src/spec/params.rs +++ b/json/src/spec/params.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/json/src/spec/seal.rs b/json/src/spec/seal.rs index 6654a309a3..b61d141d64 100644 --- a/json/src/spec/seal.rs +++ b/json/src/spec/seal.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/json/src/spec/spec.rs b/json/src/spec/spec.rs index 7003cb4cfc..2be695689e 100644 --- a/json/src/spec/spec.rs +++ b/json/src/spec/spec.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/json/src/spec/state.rs b/json/src/spec/state.rs index ad6f2e548d..d15ad540ce 100644 --- a/json/src/spec/state.rs +++ b/json/src/spec/state.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/json/src/spec/tendermint.rs b/json/src/spec/tendermint.rs index 8f3d4c2248..e0a6568aa9 100644 --- a/json/src/spec/tendermint.rs +++ b/json/src/spec/tendermint.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/json/src/spec/validator_set.rs b/json/src/spec/validator_set.rs index 9c6b4e79a1..41fa60961a 100644 --- a/json/src/spec/validator_set.rs +++ b/json/src/spec/validator_set.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/json/src/state/log.rs b/json/src/state/log.rs index 823979f627..1e07d9ed1e 100644 --- a/json/src/state/log.rs +++ b/json/src/state/log.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/json/src/state/mod.rs b/json/src/state/mod.rs index 316744983c..6037ca514d 100644 --- a/json/src/state/mod.rs +++ b/json/src/state/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/json/src/state/state.rs b/json/src/state/state.rs index 9daecaed8e..c6837d1fd6 100644 --- a/json/src/state/state.rs +++ b/json/src/state/state.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/json/src/state/test.rs b/json/src/state/test.rs index 3a25c007df..528a49b5a6 100644 --- a/json/src/state/test.rs +++ b/json/src/state/test.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/json/src/state/transaction.rs b/json/src/state/transaction.rs index 606c40f21f..89edb08692 100644 --- a/json/src/state/transaction.rs +++ b/json/src/state/transaction.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/json/src/test/mod.rs b/json/src/test/mod.rs index 1a6e4db7da..8f95a9aec4 100644 --- a/json/src/test/mod.rs +++ b/json/src/test/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -64,4 +64,3 @@ impl DifficultyTest { serde_json::from_reader(reader) } } - diff --git a/json/src/transaction/mod.rs b/json/src/transaction/mod.rs index 5cde3eff40..8ebab3f1c2 100644 --- a/json/src/transaction/mod.rs +++ b/json/src/transaction/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/json/src/transaction/test.rs b/json/src/transaction/test.rs index a2ef9ad36a..e1bd588de3 100644 --- a/json/src/transaction/test.rs +++ b/json/src/transaction/test.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/json/src/transaction/transaction.rs b/json/src/transaction/transaction.rs index d9b6abb14e..13b342b3f6 100644 --- a/json/src/transaction/transaction.rs +++ b/json/src/transaction/transaction.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/json/src/transaction/txtest.rs b/json/src/transaction/txtest.rs index 33bc0152f2..60d65e70d6 100644 --- a/json/src/transaction/txtest.rs +++ b/json/src/transaction/txtest.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/json/src/trie/input.rs b/json/src/trie/input.rs index c84f1aa1e1..e1c46ac537 100644 --- a/json/src/trie/input.rs +++ b/json/src/trie/input.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/json/src/trie/mod.rs b/json/src/trie/mod.rs index ce19922058..5dc52cb21d 100644 --- a/json/src/trie/mod.rs +++ b/json/src/trie/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/json/src/trie/test.rs b/json/src/trie/test.rs index 30811ca661..c6cd99c25e 100644 --- a/json/src/trie/test.rs +++ b/json/src/trie/test.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/json/src/trie/trie.rs b/json/src/trie/trie.rs index e4951f8141..ca18de7daa 100644 --- a/json/src/trie/trie.rs +++ b/json/src/trie/trie.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/json/src/uint.rs b/json/src/uint.rs index 70e0390a34..25c5049c45 100644 --- a/json/src/uint.rs +++ b/json/src/uint.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/json/src/vm/call.rs b/json/src/vm/call.rs index 39d5a828eb..026951c028 100644 --- a/json/src/vm/call.rs +++ b/json/src/vm/call.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/json/src/vm/env.rs b/json/src/vm/env.rs index c7f0ccd725..f4af8119c3 100644 --- a/json/src/vm/env.rs +++ b/json/src/vm/env.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/json/src/vm/mod.rs b/json/src/vm/mod.rs index a2588e37c7..29b12d4805 100644 --- a/json/src/vm/mod.rs +++ b/json/src/vm/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/json/src/vm/test.rs b/json/src/vm/test.rs index 68112e6015..10b4aae54f 100644 --- a/json/src/vm/test.rs +++ b/json/src/vm/test.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/json/src/vm/transaction.rs b/json/src/vm/transaction.rs index efdad0f9cc..44b79e8622 100644 --- a/json/src/vm/transaction.rs +++ b/json/src/vm/transaction.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/json/src/vm/vm.rs b/json/src/vm/vm.rs index 8cc01e3bac..7fd101da83 100644 --- a/json/src/vm/vm.rs +++ b/json/src/vm/vm.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/license_header b/license_header index f90ec463dc..4738554f91 100644 --- a/license_header +++ b/license_header @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/local-store/src/lib.rs b/local-store/src/lib.rs index 078dff36ed..83bc07b901 100644 --- a/local-store/src/lib.rs +++ b/local-store/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/logger/src/lib.rs b/logger/src/lib.rs index 863075a0e5..2a50969802 100644 --- a/logger/src/lib.rs +++ b/logger/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/logger/src/rotating.rs b/logger/src/rotating.rs index e67bdfaad0..ddc24792ae 100644 --- a/logger/src/rotating.rs +++ b/logger/src/rotating.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -121,4 +121,3 @@ mod test { assert_eq!(logs.len(), 2); } } - diff --git a/machine/src/lib.rs b/machine/src/lib.rs index 075a42d731..6d152851da 100644 --- a/machine/src/lib.rs +++ b/machine/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/miner/src/external.rs b/miner/src/external.rs index b49a9a4e2c..a56be42f02 100644 --- a/miner/src/external.rs +++ b/miner/src/external.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -106,7 +106,6 @@ mod tests { m.submit_hashrate(U256::from(15), H256::from(1)); m.submit_hashrate(U256::from(20), H256::from(2)); - // then assert_eq!(m.hashrate(), U256::from(35)); } diff --git a/miner/src/gas_pricer.rs b/miner/src/gas_pricer.rs index f826ccf77d..ecb69ba572 100644 --- a/miner/src/gas_pricer.rs +++ b/miner/src/gas_pricer.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/miner/src/lib.rs b/miner/src/lib.rs index 08ea7d204f..107b9b22b5 100644 --- a/miner/src/lib.rs +++ b/miner/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/miner/src/pool/client.rs b/miner/src/pool/client.rs index 622e9a8492..bdf57312ee 100644 --- a/miner/src/pool/client.rs +++ b/miner/src/pool/client.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/miner/src/pool/listener.rs b/miner/src/pool/listener.rs index 3f42372e84..e881a2ba29 100644 --- a/miner/src/pool/listener.rs +++ b/miner/src/pool/listener.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -64,7 +64,6 @@ impl txpool::Listener for Notifier { } } - /// Transaction pool logger. #[derive(Default, Debug)] pub struct Logger; @@ -113,7 +112,6 @@ impl txpool::Listener for Logger { } } - #[cfg(test)] mod tests { use super::*; diff --git a/miner/src/pool/local_transactions.rs b/miner/src/pool/local_transactions.rs index 12ffa84c19..d69da3347a 100644 --- a/miner/src/pool/local_transactions.rs +++ b/miner/src/pool/local_transactions.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -190,7 +190,6 @@ impl txpool::Listener for LocalTransactionsList { self.clear_old(); } - /// The transaction has been mined. fn mined(&mut self, tx: &Arc) { if !tx.priority().is_local() { diff --git a/miner/src/pool/mod.rs b/miner/src/pool/mod.rs index 45d28f3c12..57f813157b 100644 --- a/miner/src/pool/mod.rs +++ b/miner/src/pool/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/miner/src/pool/queue.rs b/miner/src/pool/queue.rs index 8cf4534b76..bd5a98edc7 100644 --- a/miner/src/pool/queue.rs +++ b/miner/src/pool/queue.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -412,7 +412,6 @@ impl TransactionQueue { } } - fn convert_error(err: txpool::Error) -> transaction::Error { use self::txpool::ErrorKind; diff --git a/miner/src/pool/ready.rs b/miner/src/pool/ready.rs index c2829b34a9..0b4d27f7f2 100644 --- a/miner/src/pool/ready.rs +++ b/miner/src/pool/ready.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -83,7 +83,6 @@ impl txpool::Ready for State { _ => {}, } - let sender = tx.sender(); let state = &self.state; let state_nonce = || state.account_nonce(sender); diff --git a/miner/src/pool/scoring.rs b/miner/src/pool/scoring.rs index aedc40e1f2..e7551ed6a3 100644 --- a/miner/src/pool/scoring.rs +++ b/miner/src/pool/scoring.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/miner/src/pool/tests/client.rs b/miner/src/pool/tests/client.rs index a00cc541eb..101b6cdc21 100644 --- a/miner/src/pool/tests/client.rs +++ b/miner/src/pool/tests/client.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/miner/src/pool/tests/mod.rs b/miner/src/pool/tests/mod.rs index 85dedaaa45..552903a4bb 100644 --- a/miner/src/pool/tests/mod.rs +++ b/miner/src/pool/tests/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -491,7 +491,6 @@ fn should_accept_same_transaction_twice_if_removed() { let (tx1, _) = txs.clone(); let (hash, _) = txs.hash(); - let res = txq.import(TestClient::new(), txs.local().into_vec()); assert_eq!(res, vec![Ok(()), Ok(())]); assert_eq!(txq.status().status.transaction_count, 2); @@ -731,7 +730,6 @@ fn should_not_return_transactions_over_nonce_cap() { // This should invalidate the cache! let limited = txq.pending(TestClient::new(), 0, 0, Some(123.into())); - // then assert_eq!(all.len(), 3); assert_eq!(limited.len(), 1); diff --git a/miner/src/pool/tests/tx.rs b/miner/src/pool/tests/tx.rs index c0f8751ebb..a8b06f5436 100644 --- a/miner/src/pool/tests/tx.rs +++ b/miner/src/pool/tests/tx.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -64,7 +64,6 @@ impl Tx { self.nonce += 1; let tx3 = self.unsigned().sign(keypair.secret(), None); - (tx1, tx2, tx3) } diff --git a/miner/src/pool/verifier.rs b/miner/src/pool/verifier.rs index 0a89a784b1..4675303928 100644 --- a/miner/src/pool/verifier.rs +++ b/miner/src/pool/verifier.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -91,7 +91,6 @@ impl Transaction { } } - fn gas_price(&self) -> &U256 { match *self { Transaction::Unverified(ref tx) => &tx.gas_price, diff --git a/miner/src/work_notify.rs b/miner/src/work_notify.rs index 3436938097..8825fd4b65 100644 --- a/miner/src/work_notify.rs +++ b/miner/src/work_notify.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/parity-clib-example/main.cpp b/parity-clib-example/main.cpp index becce8598e..c5e83d0649 100644 --- a/parity-clib-example/main.cpp +++ b/parity-clib-example/main.cpp @@ -1,3 +1,19 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + #include #include #include diff --git a/parity-clib/src/lib.rs b/parity-clib/src/lib.rs index fe631ce8a8..f7a98f811d 100644 --- a/parity-clib/src/lib.rs +++ b/parity-clib/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2018 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/parity/account.rs b/parity/account.rs index 676cf93e73..c2f15546e6 100644 --- a/parity/account.rs +++ b/parity/account.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/parity/blockchain.rs b/parity/blockchain.rs index 027814f245..d33ac1eacb 100644 --- a/parity/blockchain.rs +++ b/parity/blockchain.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/parity/cache.rs b/parity/cache.rs index 0bf0717a30..5848e404c2 100644 --- a/parity/cache.rs +++ b/parity/cache.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/parity/cli/presets/mod.rs b/parity/cli/presets/mod.rs index ca1ad4559b..125ab510c3 100644 --- a/parity/cli/presets/mod.rs +++ b/parity/cli/presets/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -25,4 +25,4 @@ pub fn preset_config_string(arg: &str) -> Result<&'static str, Error> { "dev-insecure" => Ok(include_str!("./config.dev-insecure.toml")), _ => Err(Error::new(ErrorKind::InvalidInput, "Config doesn't match any presets [dev, mining, non-standard-ports, insecure, dev-insecure]")) } -} \ No newline at end of file +} diff --git a/parity/cli/usage.rs b/parity/cli/usage.rs index ce138fdff3..9a892c0091 100644 --- a/parity/cli/usage.rs +++ b/parity/cli/usage.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/parity/configuration.rs b/parity/configuration.rs index 426b651015..6f475aa83c 100644 --- a/parity/configuration.rs +++ b/parity/configuration.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -1982,7 +1982,6 @@ mod tests { assert_eq!(conf0.ipfs_config().port, 5002); assert_eq!(conf0.stratum_options().unwrap().unwrap().port, 8009); - assert_eq!(conf1.net_addresses().unwrap().0.port(), 30304); assert_eq!(conf1.network_settings().unwrap().network_port, 30304); assert_eq!(conf1.network_settings().unwrap().rpc_port, 8545); diff --git a/parity/dapps.rs b/parity/dapps.rs index 2219f7cbee..427bfa53b3 100644 --- a/parity/dapps.rs +++ b/parity/dapps.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/parity/db/rocksdb/migration.rs b/parity/db/rocksdb/migration.rs index df6a4b5dc9..e92a9db035 100644 --- a/parity/db/rocksdb/migration.rs +++ b/parity/db/rocksdb/migration.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -40,7 +40,6 @@ pub const TO_V12: ChangeColumns = ChangeColumns { version: 12, }; - /// Database is assumed to be at default version, when no version file is found. const DEFAULT_VERSION: u32 = 5; /// Current version of database models. diff --git a/parity/deprecated.rs b/parity/deprecated.rs index b41475d9db..f3e433d138 100644 --- a/parity/deprecated.rs +++ b/parity/deprecated.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -160,4 +160,3 @@ mod tests { ]); } } - diff --git a/parity/export_hardcoded_sync.rs b/parity/export_hardcoded_sync.rs index 3aa2b56149..008a5b9ecd 100644 --- a/parity/export_hardcoded_sync.rs +++ b/parity/export_hardcoded_sync.rs @@ -1,4 +1,4 @@ -// Copyright 2018 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/parity/helpers.rs b/parity/helpers.rs index a5ec3c99d4..8de3728c3a 100644 --- a/parity/helpers.rs +++ b/parity/helpers.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/parity/ipfs.rs b/parity/ipfs.rs index ac9a4662b2..2cc2effca5 100644 --- a/parity/ipfs.rs +++ b/parity/ipfs.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/parity/light_helpers/epoch_fetch.rs b/parity/light_helpers/epoch_fetch.rs index 1b9ae86484..a7d8f4171f 100644 --- a/parity/light_helpers/epoch_fetch.rs +++ b/parity/light_helpers/epoch_fetch.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/parity/light_helpers/mod.rs b/parity/light_helpers/mod.rs index 5fc9c516b4..c30b62da55 100644 --- a/parity/light_helpers/mod.rs +++ b/parity/light_helpers/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/parity/light_helpers/queue_cull.rs b/parity/light_helpers/queue_cull.rs index b6be59e2ce..03ec2efe74 100644 --- a/parity/light_helpers/queue_cull.rs +++ b/parity/light_helpers/queue_cull.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/parity/modules.rs b/parity/modules.rs index cf46149b8e..e12e8ee458 100644 --- a/parity/modules.rs +++ b/parity/modules.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/parity/params.rs b/parity/params.rs index 957b280193..9ceac1e4f0 100644 --- a/parity/params.rs +++ b/parity/params.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/parity/presale.rs b/parity/presale.rs index 216ff66a84..4106ad8992 100644 --- a/parity/presale.rs +++ b/parity/presale.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/parity/rpc.rs b/parity/rpc.rs index 21bc9a4096..cdc8e7ca5b 100644 --- a/parity/rpc.rs +++ b/parity/rpc.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -212,7 +212,6 @@ pub fn new_ws( let url = format!("{}:{}", conf.interface, conf.port); let addr = url.parse().map_err(|_| format!("Invalid WebSockets listen host/port given: {}", url))?; - let full_handler = setup_apis(rpc_apis::ApiSet::SafeContext, deps); let handler = { let mut handler = MetaIoHandler::with_middleware(( diff --git a/parity/rpc_apis.rs b/parity/rpc_apis.rs index 855f917b13..ce30f3cd85 100644 --- a/parity/rpc_apis.rs +++ b/parity/rpc_apis.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/parity/run.rs b/parity/run.rs index bd8d4fb4a8..b1bf67f022 100644 --- a/parity/run.rs +++ b/parity/run.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/parity/secretstore.rs b/parity/secretstore.rs index 168a9b3fcf..3b4a4e468c 100644 --- a/parity/secretstore.rs +++ b/parity/secretstore.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/parity/signer.rs b/parity/signer.rs index ab476ef9d7..4388e11aa8 100644 --- a/parity/signer.rs +++ b/parity/signer.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/parity/snapshot.rs b/parity/snapshot.rs index 3c0dadedaa..90ae8327a6 100644 --- a/parity/snapshot.rs +++ b/parity/snapshot.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/parity/stratum.rs b/parity/stratum.rs index 043ba50622..efaa6b307c 100644 --- a/parity/stratum.rs +++ b/parity/stratum.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/parity/upgrade.rs b/parity/upgrade.rs index c5c2e1ed48..d98123ce13 100644 --- a/parity/upgrade.rs +++ b/parity/upgrade.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/parity/url.rs b/parity/url.rs index 4f547c28f0..d9eb2c9d3c 100644 --- a/parity/url.rs +++ b/parity/url.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/parity/user_defaults.rs b/parity/user_defaults.rs index be91e302eb..cb4a0a40a4 100644 --- a/parity/user_defaults.rs +++ b/parity/user_defaults.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/parity/whisper.rs b/parity/whisper.rs index bb9aebf0b9..c3c8854dcb 100644 --- a/parity/whisper.rs +++ b/parity/whisper.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/price-info/src/lib.rs b/price-info/src/lib.rs index e3594ad2ae..93dacca338 100644 --- a/price-info/src/lib.rs +++ b/price-info/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/registrar/src/lib.rs b/registrar/src/lib.rs index 961fbb17ee..aad33765ef 100644 --- a/registrar/src/lib.rs +++ b/registrar/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/registrar/src/registrar.rs b/registrar/src/registrar.rs index c4128660d2..0a17de499a 100644 --- a/registrar/src/registrar.rs +++ b/registrar/src/registrar.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -74,4 +74,3 @@ pub trait RegistrarClient: Send + Sync { /// Call Contract fn call_contract(&self, address: Address, data: Bytes) -> Self::Call; } - diff --git a/rpc/src/authcodes.rs b/rpc/src/authcodes.rs index d18d0741fd..5b7309a317 100644 --- a/rpc/src/authcodes.rs +++ b/rpc/src/authcodes.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/http_common.rs b/rpc/src/http_common.rs index 72af6e4697..8296720b20 100644 --- a/rpc/src/http_common.rs +++ b/rpc/src/http_common.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/lib.rs b/rpc/src/lib.rs index 1fc3d0e242..2d49a8c771 100644 --- a/rpc/src/lib.rs +++ b/rpc/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/tests/helpers.rs b/rpc/src/tests/helpers.rs index db61353d53..602648d063 100644 --- a/rpc/src/tests/helpers.rs +++ b/rpc/src/tests/helpers.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/tests/mod.rs b/rpc/src/tests/mod.rs index d4d9538dca..6ecab3299a 100644 --- a/rpc/src/tests/mod.rs +++ b/rpc/src/tests/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/tests/rpc.rs b/rpc/src/tests/rpc.rs index 6e2900c8b7..015c2764a6 100644 --- a/rpc/src/tests/rpc.rs +++ b/rpc/src/tests/rpc.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/tests/ws.rs b/rpc/src/tests/ws.rs index 429ff6d3c4..91f10e6475 100644 --- a/rpc/src/tests/ws.rs +++ b/rpc/src/tests/ws.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -177,7 +177,6 @@ mod testing { ) ); - // then assert_eq!(response1.status, "HTTP/1.1 101 Switching Protocols".to_owned()); assert_eq!(response2.status, "HTTP/1.1 403 Forbidden".to_owned()); diff --git a/rpc/src/v1/extractors.rs b/rpc/src/v1/extractors.rs index 071e57dae4..c69c41dddf 100644 --- a/rpc/src/v1/extractors.rs +++ b/rpc/src/v1/extractors.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/helpers/accounts.rs b/rpc/src/v1/helpers/accounts.rs new file mode 100644 index 0000000000..4268bf2f99 --- /dev/null +++ b/rpc/src/v1/helpers/accounts.rs @@ -0,0 +1,27 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +use std::sync::Arc; +use ethcore::account_provider::AccountProvider; +use jsonrpc_core::Error; +use v1::helpers::errors; + +pub fn unwrap_provider(provider: &Option>) -> Result, Error> { + match *provider { + Some(ref arc) => Ok(arc.clone()), + None => Err(errors::public_unsupported(None)), + } +} diff --git a/rpc/src/v1/helpers/block_import.rs b/rpc/src/v1/helpers/block_import.rs index 1246faa658..9e947e5baa 100644 --- a/rpc/src/v1/helpers/block_import.rs +++ b/rpc/src/v1/helpers/block_import.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -35,7 +35,6 @@ mod tests { use sync::SyncState; use super::is_major_importing; - fn queue_info(unverified: usize, verified: usize) -> BlockQueueInfo { BlockQueueInfo { unverified_queue_size: unverified, diff --git a/rpc/src/v1/helpers/dapps.rs b/rpc/src/v1/helpers/dapps.rs index 391a12c824..88a9cce6fb 100644 --- a/rpc/src/v1/helpers/dapps.rs +++ b/rpc/src/v1/helpers/dapps.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/helpers/dispatch.rs b/rpc/src/v1/helpers/dispatch.rs index 1f43ef008e..9bec8e1d31 100644 --- a/rpc/src/v1/helpers/dispatch.rs +++ b/rpc/src/v1/helpers/dispatch.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/helpers/errors.rs b/rpc/src/v1/helpers/errors.rs index 0d36a926e9..6207d4542f 100644 --- a/rpc/src/v1/helpers/errors.rs +++ b/rpc/src/v1/helpers/errors.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/helpers/fake_sign.rs b/rpc/src/v1/helpers/fake_sign.rs index 84a225d814..eca8a5abbd 100644 --- a/rpc/src/v1/helpers/fake_sign.rs +++ b/rpc/src/v1/helpers/fake_sign.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/helpers/ipfs.rs b/rpc/src/v1/helpers/ipfs.rs index da51f1fd54..12980d3f41 100644 --- a/rpc/src/v1/helpers/ipfs.rs +++ b/rpc/src/v1/helpers/ipfs.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/helpers/light_fetch.rs b/rpc/src/v1/helpers/light_fetch.rs index 1baf9a7647..c11f47a456 100644 --- a/rpc/src/v1/helpers/light_fetch.rs +++ b/rpc/src/v1/helpers/light_fetch.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -86,7 +86,6 @@ pub fn extract_transaction_at_index(block: encoded::Block, index: usize, eip86_t .map(|tx| Transaction::from_localized(tx, eip86_transition)) } - /// Type alias for convenience. pub type ExecutionResult = ::std::result::Result; diff --git a/rpc/src/v1/helpers/mod.rs b/rpc/src/v1/helpers/mod.rs index 9adb5d68d4..97b96675e4 100644 --- a/rpc/src/v1/helpers/mod.rs +++ b/rpc/src/v1/helpers/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/helpers/network_settings.rs b/rpc/src/v1/helpers/network_settings.rs index a798286244..d011d2394f 100644 --- a/rpc/src/v1/helpers/network_settings.rs +++ b/rpc/src/v1/helpers/network_settings.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -13,6 +13,7 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . + //! Structure to hold network settings configured from CLI /// Networking & RPC settings diff --git a/rpc/src/v1/helpers/nonce.rs b/rpc/src/v1/helpers/nonce.rs index 06f38a8589..12dfd3d520 100644 --- a/rpc/src/v1/helpers/nonce.rs +++ b/rpc/src/v1/helpers/nonce.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 harity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/helpers/oneshot.rs b/rpc/src/v1/helpers/oneshot.rs index 89e90dbd18..5ede0ae912 100644 --- a/rpc/src/v1/helpers/oneshot.rs +++ b/rpc/src/v1/helpers/oneshot.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/helpers/poll_filter.rs b/rpc/src/v1/helpers/poll_filter.rs index 7ef8db0f15..c7284d6651 100644 --- a/rpc/src/v1/helpers/poll_filter.rs +++ b/rpc/src/v1/helpers/poll_filter.rs @@ -1,3 +1,19 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + //! Helper type with all filter state data. use std::collections::HashSet; diff --git a/rpc/src/v1/helpers/poll_manager.rs b/rpc/src/v1/helpers/poll_manager.rs index f367f669fd..e176ed440e 100644 --- a/rpc/src/v1/helpers/poll_manager.rs +++ b/rpc/src/v1/helpers/poll_manager.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/helpers/requests.rs b/rpc/src/v1/helpers/requests.rs index 13bfbb1b38..478f6785b4 100644 --- a/rpc/src/v1/helpers/requests.rs +++ b/rpc/src/v1/helpers/requests.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/helpers/secretstore.rs b/rpc/src/v1/helpers/secretstore.rs index 019d2b1051..f23222824f 100644 --- a/rpc/src/v1/helpers/secretstore.rs +++ b/rpc/src/v1/helpers/secretstore.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/helpers/signer.rs b/rpc/src/v1/helpers/signer.rs index 6d9606f878..0ee14bad1b 100644 --- a/rpc/src/v1/helpers/signer.rs +++ b/rpc/src/v1/helpers/signer.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -88,4 +88,3 @@ impl Deref for SignerService { &self.queue } } - diff --git a/rpc/src/v1/helpers/signing_queue.rs b/rpc/src/v1/helpers/signing_queue.rs index b73535ba4f..c6a8048825 100644 --- a/rpc/src/v1/helpers/signing_queue.rs +++ b/rpc/src/v1/helpers/signing_queue.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -227,7 +227,6 @@ impl SigningQueue for ConfirmationsQueue { } } - #[cfg(test)] mod test { use std::sync::Arc; diff --git a/rpc/src/v1/helpers/subscribers.rs b/rpc/src/v1/helpers/subscribers.rs index 11dd45d11b..6871207643 100644 --- a/rpc/src/v1/helpers/subscribers.rs +++ b/rpc/src/v1/helpers/subscribers.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -22,7 +22,6 @@ use jsonrpc_macros::pubsub::{Subscriber, Sink, SubscriptionId}; use rand::{Rng, StdRng}; use v1::types::H64; - #[derive(Debug, Clone, Hash, Eq, PartialEq)] pub struct Id(H64); impl str::FromStr for Id { diff --git a/rpc/src/v1/helpers/subscription_manager.rs b/rpc/src/v1/helpers/subscription_manager.rs index 5988824b6a..5f6d77d883 100644 --- a/rpc/src/v1/helpers/subscription_manager.rs +++ b/rpc/src/v1/helpers/subscription_manager.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/impls/eth.rs b/rpc/src/v1/impls/eth.rs index 32ba36deb8..38e36cf11c 100644 --- a/rpc/src/v1/impls/eth.rs +++ b/rpc/src/v1/impls/eth.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -495,7 +495,6 @@ impl Eth for EthClient< _ => (false, None, None), }; - if warping || is_major_importing(Some(status.state), client.queue_info()) { let chain_info = client.chain_info(); let current_block = U256::from(chain_info.best_block_number); diff --git a/rpc/src/v1/impls/eth_filter.rs b/rpc/src/v1/impls/eth_filter.rs index 6ca1c355f3..bbad2fe27d 100644 --- a/rpc/src/v1/impls/eth_filter.rs +++ b/rpc/src/v1/impls/eth_filter.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -102,8 +102,6 @@ impl Filterable for EthFilterClient where fn polls(&self) -> &Mutex> { &self.polls } } - - impl EthFilter for T { fn new_filter(&self, filter: Filter) -> Result { let mut polls = self.polls().lock(); diff --git a/rpc/src/v1/impls/eth_pubsub.rs b/rpc/src/v1/impls/eth_pubsub.rs index c0789910c3..11fef2e0bd 100644 --- a/rpc/src/v1/impls/eth_pubsub.rs +++ b/rpc/src/v1/impls/eth_pubsub.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/impls/light/eth.rs b/rpc/src/v1/impls/light/eth.rs index 10ad024f24..68afe649b8 100644 --- a/rpc/src/v1/impls/light/eth.rs +++ b/rpc/src/v1/impls/light/eth.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/impls/light/mod.rs b/rpc/src/v1/impls/light/mod.rs index 38ba2438e2..40f1df8990 100644 --- a/rpc/src/v1/impls/light/mod.rs +++ b/rpc/src/v1/impls/light/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/impls/light/net.rs b/rpc/src/v1/impls/light/net.rs index 1b374247a3..4dbc9d1908 100644 --- a/rpc/src/v1/impls/light/net.rs +++ b/rpc/src/v1/impls/light/net.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/impls/light/parity.rs b/rpc/src/v1/impls/light/parity.rs index 025538fc42..91db00ca30 100644 --- a/rpc/src/v1/impls/light/parity.rs +++ b/rpc/src/v1/impls/light/parity.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/impls/light/parity_set.rs b/rpc/src/v1/impls/light/parity_set.rs index 76c33cf458..4e907deaf1 100644 --- a/rpc/src/v1/impls/light/parity_set.rs +++ b/rpc/src/v1/impls/light/parity_set.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/impls/light/trace.rs b/rpc/src/v1/impls/light/trace.rs index 1d2c7fcaa0..d1e99fb9a1 100644 --- a/rpc/src/v1/impls/light/trace.rs +++ b/rpc/src/v1/impls/light/trace.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/impls/mod.rs b/rpc/src/v1/impls/mod.rs index 4edaf6bcd2..1349147207 100644 --- a/rpc/src/v1/impls/mod.rs +++ b/rpc/src/v1/impls/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/impls/net.rs b/rpc/src/v1/impls/net.rs index 3f42f01b94..74521d8135 100644 --- a/rpc/src/v1/impls/net.rs +++ b/rpc/src/v1/impls/net.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/impls/parity.rs b/rpc/src/v1/impls/parity.rs index f5d4a58949..e3ad5a3b1b 100644 --- a/rpc/src/v1/impls/parity.rs +++ b/rpc/src/v1/impls/parity.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/impls/parity_accounts.rs b/rpc/src/v1/impls/parity_accounts.rs index adb97db28d..eb069cf27f 100644 --- a/rpc/src/v1/impls/parity_accounts.rs +++ b/rpc/src/v1/impls/parity_accounts.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/impls/parity_set.rs b/rpc/src/v1/impls/parity_set.rs index 612e6aa78b..4ba9ab658e 100644 --- a/rpc/src/v1/impls/parity_set.rs +++ b/rpc/src/v1/impls/parity_set.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/impls/personal.rs b/rpc/src/v1/impls/personal.rs index da5ef983a2..045496fc95 100644 --- a/rpc/src/v1/impls/personal.rs +++ b/rpc/src/v1/impls/personal.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/impls/private.rs b/rpc/src/v1/impls/private.rs index 4034d2b9a1..a1110eed11 100644 --- a/rpc/src/v1/impls/private.rs +++ b/rpc/src/v1/impls/private.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/impls/pubsub.rs b/rpc/src/v1/impls/pubsub.rs index 59eef19533..564c8b90d5 100644 --- a/rpc/src/v1/impls/pubsub.rs +++ b/rpc/src/v1/impls/pubsub.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/impls/rpc.rs b/rpc/src/v1/impls/rpc.rs index 3c76a31646..9f15cc1a38 100644 --- a/rpc/src/v1/impls/rpc.rs +++ b/rpc/src/v1/impls/rpc.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/impls/secretstore.rs b/rpc/src/v1/impls/secretstore.rs index f85fa6f584..52404a58d0 100644 --- a/rpc/src/v1/impls/secretstore.rs +++ b/rpc/src/v1/impls/secretstore.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/impls/signer.rs b/rpc/src/v1/impls/signer.rs index eafa07ad4d..14fd6a33a4 100644 --- a/rpc/src/v1/impls/signer.rs +++ b/rpc/src/v1/impls/signer.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/impls/signing.rs b/rpc/src/v1/impls/signing.rs index 71cf18a06b..6229a54c84 100644 --- a/rpc/src/v1/impls/signing.rs +++ b/rpc/src/v1/impls/signing.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/impls/signing_unsafe.rs b/rpc/src/v1/impls/signing_unsafe.rs index 75f5f5e2bf..f14d1e028d 100644 --- a/rpc/src/v1/impls/signing_unsafe.rs +++ b/rpc/src/v1/impls/signing_unsafe.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/impls/traces.rs b/rpc/src/v1/impls/traces.rs index 0130b3b9c1..0e43d8c11a 100644 --- a/rpc/src/v1/impls/traces.rs +++ b/rpc/src/v1/impls/traces.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/impls/web3.rs b/rpc/src/v1/impls/web3.rs index 6fd6ff7a46..aa30447285 100644 --- a/rpc/src/v1/impls/web3.rs +++ b/rpc/src/v1/impls/web3.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/informant.rs b/rpc/src/v1/informant.rs index 9a9cde3837..07a70eeb10 100644 --- a/rpc/src/v1/informant.rs +++ b/rpc/src/v1/informant.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/metadata.rs b/rpc/src/v1/metadata.rs index f0644d455c..970ec60e48 100644 --- a/rpc/src/v1/metadata.rs +++ b/rpc/src/v1/metadata.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/mod.rs b/rpc/src/v1/mod.rs index 154317eb2f..cb510ae294 100644 --- a/rpc/src/v1/mod.rs +++ b/rpc/src/v1/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/tests/eth.rs b/rpc/src/v1/tests/eth.rs index e0931ae6bf..7354eb18b0 100644 --- a/rpc/src/v1/tests/eth.rs +++ b/rpc/src/v1/tests/eth.rs @@ -1,4 +1,4 @@ -// Copyright 2016 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/tests/helpers/dapps.rs b/rpc/src/v1/tests/helpers/dapps.rs index 10c54cf4c2..70f42a29e5 100644 --- a/rpc/src/v1/tests/helpers/dapps.rs +++ b/rpc/src/v1/tests/helpers/dapps.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/tests/helpers/miner_service.rs b/rpc/src/v1/tests/helpers/miner_service.rs index 6781d10b95..90201e346a 100644 --- a/rpc/src/v1/tests/helpers/miner_service.rs +++ b/rpc/src/v1/tests/helpers/miner_service.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/tests/helpers/mod.rs b/rpc/src/v1/tests/helpers/mod.rs index 8e1aeeb147..a2782eec60 100644 --- a/rpc/src/v1/tests/helpers/mod.rs +++ b/rpc/src/v1/tests/helpers/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/tests/helpers/snapshot_service.rs b/rpc/src/v1/tests/helpers/snapshot_service.rs index 91cd14d73f..4e45488dbe 100644 --- a/rpc/src/v1/tests/helpers/snapshot_service.rs +++ b/rpc/src/v1/tests/helpers/snapshot_service.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/tests/helpers/sync_provider.rs b/rpc/src/v1/tests/helpers/sync_provider.rs index a5ca4a4b36..7cb0acffef 100644 --- a/rpc/src/v1/tests/helpers/sync_provider.rs +++ b/rpc/src/v1/tests/helpers/sync_provider.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -123,4 +123,3 @@ impl SyncProvider for TestSyncProvider { ] } } - diff --git a/rpc/src/v1/tests/helpers/update_service.rs b/rpc/src/v1/tests/helpers/update_service.rs index eaa3b06fbe..3c4d0b1d7d 100644 --- a/rpc/src/v1/tests/helpers/update_service.rs +++ b/rpc/src/v1/tests/helpers/update_service.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/tests/mocked/eth.rs b/rpc/src/v1/tests/mocked/eth.rs index a6c8772439..a8875a3354 100644 --- a/rpc/src/v1/tests/mocked/eth.rs +++ b/rpc/src/v1/tests/mocked/eth.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -149,7 +149,6 @@ fn rpc_eth_syncing() { // causes TestBlockChainClient to return 1000 for its best block number. tester.add_blocks(1000, EachBlockWith::Nothing); - let true_res = r#"{"jsonrpc":"2.0","result":{"currentBlock":"0x3e8","highestBlock":"0x9c4","startingBlock":"0x0","warpChunksAmount":null,"warpChunksProcessed":null},"id":1}"#; assert_eq!(tester.io.handle_request_sync(request), Some(true_res.to_owned())); @@ -221,7 +220,6 @@ fn rpc_eth_logs() { log_index: 1, }]); - let request1 = r#"{"jsonrpc": "2.0", "method": "eth_getLogs", "params": [{}], "id": 1}"#; let request2 = r#"{"jsonrpc": "2.0", "method": "eth_getLogs", "params": [{"limit":1}], "id": 1}"#; let request3 = r#"{"jsonrpc": "2.0", "method": "eth_getLogs", "params": [{"limit":0}], "id": 1}"#; @@ -582,7 +580,6 @@ fn rpc_eth_pending_transaction_by_hash() { assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned())); } - #[test] fn rpc_eth_uncle_count_by_block_hash() { let request = r#"{ @@ -933,7 +930,6 @@ fn rpc_eth_send_transaction_with_bad_to() { assert_eq!(tester.io.handle_request_sync(&request), Some(response.into())); } - #[test] fn rpc_eth_send_transaction_error() { let tester = EthTester::default(); diff --git a/rpc/src/v1/tests/mocked/eth_pubsub.rs b/rpc/src/v1/tests/mocked/eth_pubsub.rs index 936695a9a1..0d886fe2f1 100644 --- a/rpc/src/v1/tests/mocked/eth_pubsub.rs +++ b/rpc/src/v1/tests/mocked/eth_pubsub.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -144,7 +144,6 @@ fn should_subscribe_to_logs() { + r#"","transactionIndex":"0x0","transactionLogIndex":"0x0","type":"removed"},"subscription":"0x416d77337e24399d"}}"#; assert_eq!(res, Some(response.into())); - // And unsubscribe let request = r#"{"jsonrpc": "2.0", "method": "eth_unsubscribe", "params": ["0x416d77337e24399d"], "id": 1}"#; let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#; @@ -154,7 +153,6 @@ fn should_subscribe_to_logs() { assert_eq!(res, None); } - #[test] fn should_subscribe_to_pending_transactions() { // given diff --git a/rpc/src/v1/tests/mocked/manage_network.rs b/rpc/src/v1/tests/mocked/manage_network.rs index da4f1aa511..a742f03c2f 100644 --- a/rpc/src/v1/tests/mocked/manage_network.rs +++ b/rpc/src/v1/tests/mocked/manage_network.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/tests/mocked/mod.rs b/rpc/src/v1/tests/mocked/mod.rs index ae51c2be67..a3de3b3b71 100644 --- a/rpc/src/v1/tests/mocked/mod.rs +++ b/rpc/src/v1/tests/mocked/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/tests/mocked/net.rs b/rpc/src/v1/tests/mocked/net.rs index 0f77dfb11a..b94bf2b113 100644 --- a/rpc/src/v1/tests/mocked/net.rs +++ b/rpc/src/v1/tests/mocked/net.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/tests/mocked/parity.rs b/rpc/src/v1/tests/mocked/parity.rs index c27615a589..c9dd50a3c6 100644 --- a/rpc/src/v1/tests/mocked/parity.rs +++ b/rpc/src/v1/tests/mocked/parity.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -150,7 +150,6 @@ fn rpc_parity_default_account() { let deps = Dependencies::new(); let io = deps.default_client(); - // Check empty let address = Address::default(); let request = r#"{"jsonrpc": "2.0", "method": "parity_defaultAccount", "params": [], "id": 1}"#; diff --git a/rpc/src/v1/tests/mocked/parity_accounts.rs b/rpc/src/v1/tests/mocked/parity_accounts.rs index c30b4b9ced..8342641d6c 100644 --- a/rpc/src/v1/tests/mocked/parity_accounts.rs +++ b/rpc/src/v1/tests/mocked/parity_accounts.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -206,7 +206,6 @@ fn rpc_parity_set_and_get_new_dapps_default_address() { assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned())); } - #[test] fn rpc_parity_recent_dapps() { // given @@ -474,7 +473,6 @@ fn derive_key_index() { assert_eq!(res, Some(response.into())); } - #[test] fn should_export_account() { // given diff --git a/rpc/src/v1/tests/mocked/parity_set.rs b/rpc/src/v1/tests/mocked/parity_set.rs index 78c73f9479..bc9f04de7c 100644 --- a/rpc/src/v1/tests/mocked/parity_set.rs +++ b/rpc/src/v1/tests/mocked/parity_set.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -181,7 +181,6 @@ fn rpc_parity_set_engine_signer() { assert_eq!(*miner.password.read(), "password".to_string()); } - #[test] fn rpc_parity_set_transactions_limit() { let miner = miner_service(); diff --git a/rpc/src/v1/tests/mocked/personal.rs b/rpc/src/v1/tests/mocked/personal.rs index 323f9fe137..131a865da7 100644 --- a/rpc/src/v1/tests/mocked/personal.rs +++ b/rpc/src/v1/tests/mocked/personal.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/tests/mocked/pubsub.rs b/rpc/src/v1/tests/mocked/pubsub.rs index 99b34366c8..a21f8a4903 100644 --- a/rpc/src/v1/tests/mocked/pubsub.rs +++ b/rpc/src/v1/tests/mocked/pubsub.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -75,4 +75,3 @@ fn should_subscribe_to_a_method() { let (res, _receiver) = receiver.into_future().wait().unwrap(); assert_eq!(res, None); } - diff --git a/rpc/src/v1/tests/mocked/rpc.rs b/rpc/src/v1/tests/mocked/rpc.rs index d0a6d2fab4..ed6503cea5 100644 --- a/rpc/src/v1/tests/mocked/rpc.rs +++ b/rpc/src/v1/tests/mocked/rpc.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -18,7 +18,6 @@ use std::collections::BTreeMap; use jsonrpc_core::IoHandler; use v1::{Rpc, RpcClient}; - fn rpc_client() -> RpcClient { let mut modules = BTreeMap::new(); modules.insert("rpc".to_owned(), "1.0".to_owned()); diff --git a/rpc/src/v1/tests/mocked/secretstore.rs b/rpc/src/v1/tests/mocked/secretstore.rs index 6ee9b6c245..33592a4883 100644 --- a/rpc/src/v1/tests/mocked/secretstore.rs +++ b/rpc/src/v1/tests/mocked/secretstore.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/tests/mocked/signer.rs b/rpc/src/v1/tests/mocked/signer.rs index 8881dc41c3..8bbb590c06 100644 --- a/rpc/src/v1/tests/mocked/signer.rs +++ b/rpc/src/v1/tests/mocked/signer.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -76,7 +76,6 @@ fn signer_tester() -> SignerTester { } } - #[test] fn should_return_list_of_items_to_confirm() { // given @@ -107,7 +106,6 @@ fn should_return_list_of_items_to_confirm() { assert_eq!(tester.io.handle_request_sync(&request), Some(response.to_owned())); } - #[test] fn should_reject_transaction_from_queue_without_dispatching() { // given diff --git a/rpc/src/v1/tests/mocked/signing.rs b/rpc/src/v1/tests/mocked/signing.rs index 84cf2e376e..2dc80f066c 100644 --- a/rpc/src/v1/tests/mocked/signing.rs +++ b/rpc/src/v1/tests/mocked/signing.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -393,7 +393,6 @@ fn should_decrypt_message_if_account_is_unlocked() { let (address, public) = tester.accounts.new_account_and_public("test").unwrap(); tester.accounts.unlock_account_permanently(address, "test".into()).unwrap(); - // First encrypt message let request = format!("{}0x{:x}{}", r#"{"jsonrpc": "2.0", "method": "parity_encryptMessage", "params":[""#, @@ -473,7 +472,6 @@ fn should_compose_transaction() { + &from + r#"","gas":"0x5208","gasPrice":"0x4a817c800","nonce":"0x0","to":null,"value":"0x5"},"id":1}"#; - // then let res = tester.io.handle_request(&request).wait().unwrap(); assert_eq!(res, Some(response.to_owned())); diff --git a/rpc/src/v1/tests/mocked/traces.rs b/rpc/src/v1/tests/mocked/traces.rs index 0b2e7d5ccb..70a862d332 100644 --- a/rpc/src/v1/tests/mocked/traces.rs +++ b/rpc/src/v1/tests/mocked/traces.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/tests/mocked/web3.rs b/rpc/src/v1/tests/mocked/web3.rs index 3c78d67ad3..e16c5f4926 100644 --- a/rpc/src/v1/tests/mocked/web3.rs +++ b/rpc/src/v1/tests/mocked/web3.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/tests/mod.rs b/rpc/src/v1/tests/mod.rs index 31ac1c5410..471569e523 100644 --- a/rpc/src/v1/tests/mod.rs +++ b/rpc/src/v1/tests/mod.rs @@ -1,3 +1,19 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + //! RPC unit test moduleS pub mod helpers; diff --git a/rpc/src/v1/traits/eth.rs b/rpc/src/v1/traits/eth.rs index f4ea1e10d6..48e315ce7e 100644 --- a/rpc/src/v1/traits/eth.rs +++ b/rpc/src/v1/traits/eth.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/traits/eth_pubsub.rs b/rpc/src/v1/traits/eth_pubsub.rs index cfbe4c54bc..38babeef42 100644 --- a/rpc/src/v1/traits/eth_pubsub.rs +++ b/rpc/src/v1/traits/eth_pubsub.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/traits/eth_signing.rs b/rpc/src/v1/traits/eth_signing.rs index 9830ac54d8..27657475ba 100644 --- a/rpc/src/v1/traits/eth_signing.rs +++ b/rpc/src/v1/traits/eth_signing.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/traits/mod.rs b/rpc/src/v1/traits/mod.rs index 26a43fa3f8..62edac8ed6 100644 --- a/rpc/src/v1/traits/mod.rs +++ b/rpc/src/v1/traits/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/traits/net.rs b/rpc/src/v1/traits/net.rs index bc2068ff9a..d70a4653a6 100644 --- a/rpc/src/v1/traits/net.rs +++ b/rpc/src/v1/traits/net.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/traits/parity.rs b/rpc/src/v1/traits/parity.rs index 83d8b19811..f78cf8052e 100644 --- a/rpc/src/v1/traits/parity.rs +++ b/rpc/src/v1/traits/parity.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/traits/parity_accounts.rs b/rpc/src/v1/traits/parity_accounts.rs index 494f1576cb..977593d44e 100644 --- a/rpc/src/v1/traits/parity_accounts.rs +++ b/rpc/src/v1/traits/parity_accounts.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/traits/parity_set.rs b/rpc/src/v1/traits/parity_set.rs index 40aad1a4bd..8cfffb50c7 100644 --- a/rpc/src/v1/traits/parity_set.rs +++ b/rpc/src/v1/traits/parity_set.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/traits/parity_signing.rs b/rpc/src/v1/traits/parity_signing.rs index 8015b04317..208422222e 100644 --- a/rpc/src/v1/traits/parity_signing.rs +++ b/rpc/src/v1/traits/parity_signing.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/traits/personal.rs b/rpc/src/v1/traits/personal.rs index 7c187fcffe..7187219105 100644 --- a/rpc/src/v1/traits/personal.rs +++ b/rpc/src/v1/traits/personal.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/traits/private.rs b/rpc/src/v1/traits/private.rs index 7106e0bf43..b7b1aa20a7 100644 --- a/rpc/src/v1/traits/private.rs +++ b/rpc/src/v1/traits/private.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/traits/pubsub.rs b/rpc/src/v1/traits/pubsub.rs index 0b77fc64d6..840de8d4b0 100644 --- a/rpc/src/v1/traits/pubsub.rs +++ b/rpc/src/v1/traits/pubsub.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/traits/rpc.rs b/rpc/src/v1/traits/rpc.rs index a813aa94e6..8c0b3c2c90 100644 --- a/rpc/src/v1/traits/rpc.rs +++ b/rpc/src/v1/traits/rpc.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/traits/secretstore.rs b/rpc/src/v1/traits/secretstore.rs index 6d2e5669c0..e15d71a72f 100644 --- a/rpc/src/v1/traits/secretstore.rs +++ b/rpc/src/v1/traits/secretstore.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/traits/signer.rs b/rpc/src/v1/traits/signer.rs index b7f60619e8..4ede0ce534 100644 --- a/rpc/src/v1/traits/signer.rs +++ b/rpc/src/v1/traits/signer.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/traits/traces.rs b/rpc/src/v1/traits/traces.rs index 1fe01f47ef..2d3665f6bc 100644 --- a/rpc/src/v1/traits/traces.rs +++ b/rpc/src/v1/traits/traces.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/traits/web3.rs b/rpc/src/v1/traits/web3.rs index e4fb8b0d1f..713cd9a32d 100644 --- a/rpc/src/v1/traits/web3.rs +++ b/rpc/src/v1/traits/web3.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/types/account_info.rs b/rpc/src/v1/types/account_info.rs index f9cabb450b..5a0e2952a1 100644 --- a/rpc/src/v1/types/account_info.rs +++ b/rpc/src/v1/types/account_info.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -41,4 +41,3 @@ pub struct HwAccountInfo { /// Device manufacturer. pub manufacturer: String, } - diff --git a/rpc/src/v1/types/block.rs b/rpc/src/v1/types/block.rs index 486e3b9c14..9ae870dc55 100644 --- a/rpc/src/v1/types/block.rs +++ b/rpc/src/v1/types/block.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/types/block_number.rs b/rpc/src/v1/types/block_number.rs index b6c1860f5b..b92a0d4a3f 100644 --- a/rpc/src/v1/types/block_number.rs +++ b/rpc/src/v1/types/block_number.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -135,4 +135,3 @@ mod tests { block_number_to_id(BlockNumber::Pending); } } - diff --git a/rpc/src/v1/types/bytes.rs b/rpc/src/v1/types/bytes.rs index fdbcb729bb..0bd62c601c 100644 --- a/rpc/src/v1/types/bytes.rs +++ b/rpc/src/v1/types/bytes.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -86,7 +86,6 @@ impl<'a> Visitor<'a> for BytesVisitor { } } - #[cfg(test)] mod tests { use super::*; @@ -118,4 +117,3 @@ mod tests { assert_eq!(bytes6, Bytes(vec![0x1, 0x23])); } } - diff --git a/rpc/src/v1/types/call_request.rs b/rpc/src/v1/types/call_request.rs index 71b562e45a..39d4d17b78 100644 --- a/rpc/src/v1/types/call_request.rs +++ b/rpc/src/v1/types/call_request.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/types/confirmations.rs b/rpc/src/v1/types/confirmations.rs index 5dcb11316c..7f4f3ad106 100644 --- a/rpc/src/v1/types/confirmations.rs +++ b/rpc/src/v1/types/confirmations.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/types/consensus_status.rs b/rpc/src/v1/types/consensus_status.rs index 96657adbc9..0cbdf1f007 100644 --- a/rpc/src/v1/types/consensus_status.rs +++ b/rpc/src/v1/types/consensus_status.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/types/dapps.rs b/rpc/src/v1/types/dapps.rs index 418717fccf..81339fb1dc 100644 --- a/rpc/src/v1/types/dapps.rs +++ b/rpc/src/v1/types/dapps.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/types/derivation.rs b/rpc/src/v1/types/derivation.rs index 76becbaebe..0e39b65322 100644 --- a/rpc/src/v1/types/derivation.rs +++ b/rpc/src/v1/types/derivation.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/types/filter.rs b/rpc/src/v1/types/filter.rs index 52217459c1..dd8b823e87 100644 --- a/rpc/src/v1/types/filter.rs +++ b/rpc/src/v1/types/filter.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/types/hash.rs b/rpc/src/v1/types/hash.rs index e3cc73e272..07c7ef24f4 100644 --- a/rpc/src/v1/types/hash.rs +++ b/rpc/src/v1/types/hash.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/types/histogram.rs b/rpc/src/v1/types/histogram.rs index 26bbc7d2de..2b71b88bf6 100644 --- a/rpc/src/v1/types/histogram.rs +++ b/rpc/src/v1/types/histogram.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -12,7 +12,7 @@ // 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 . +// along with Parity. If not, see . //! Gas prices histogram. diff --git a/rpc/src/v1/types/index.rs b/rpc/src/v1/types/index.rs index 4e44ce49ce..4c8af60004 100644 --- a/rpc/src/v1/types/index.rs +++ b/rpc/src/v1/types/index.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -73,4 +73,3 @@ mod tests { assert_eq!(deserialized, vec![Index(10), Index(10)]); } } - diff --git a/rpc/src/v1/types/log.rs b/rpc/src/v1/types/log.rs index e178516d6d..1d3335bcad 100644 --- a/rpc/src/v1/types/log.rs +++ b/rpc/src/v1/types/log.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/types/mod.rs b/rpc/src/v1/types/mod.rs index e7f764b8b1..4a0ccee906 100644 --- a/rpc/src/v1/types/mod.rs +++ b/rpc/src/v1/types/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -14,7 +14,6 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . - //! RPC types mod account_info; diff --git a/rpc/src/v1/types/node_kind.rs b/rpc/src/v1/types/node_kind.rs index 5c96fafc63..8061d82808 100644 --- a/rpc/src/v1/types/node_kind.rs +++ b/rpc/src/v1/types/node_kind.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/types/private_receipt.rs b/rpc/src/v1/types/private_receipt.rs index 328013d7f6..7e758af3a5 100644 --- a/rpc/src/v1/types/private_receipt.rs +++ b/rpc/src/v1/types/private_receipt.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -51,4 +51,3 @@ pub struct PrivateTransactionReceiptAndTransaction { #[serde(rename="transaction")] pub transaction: TransactionRequest, } - diff --git a/rpc/src/v1/types/provenance.rs b/rpc/src/v1/types/provenance.rs index 6bcd43a21f..328f2ded3e 100644 --- a/rpc/src/v1/types/provenance.rs +++ b/rpc/src/v1/types/provenance.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/types/pubsub.rs b/rpc/src/v1/types/pubsub.rs index dfac5a0abb..ea01d6427b 100644 --- a/rpc/src/v1/types/pubsub.rs +++ b/rpc/src/v1/types/pubsub.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/types/receipt.rs b/rpc/src/v1/types/receipt.rs index e20856b822..f8d111887a 100644 --- a/rpc/src/v1/types/receipt.rs +++ b/rpc/src/v1/types/receipt.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -165,4 +165,3 @@ mod tests { assert_eq!(serialized, s); } } - diff --git a/rpc/src/v1/types/rpc_settings.rs b/rpc/src/v1/types/rpc_settings.rs index bc5bf72171..3be781f206 100644 --- a/rpc/src/v1/types/rpc_settings.rs +++ b/rpc/src/v1/types/rpc_settings.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -12,7 +12,7 @@ // 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 . +// along with Parity. If not, see . //! RPC Settings data. diff --git a/rpc/src/v1/types/secretstore.rs b/rpc/src/v1/types/secretstore.rs index 4388b308ba..22b61b5e15 100644 --- a/rpc/src/v1/types/secretstore.rs +++ b/rpc/src/v1/types/secretstore.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/types/sync.rs b/rpc/src/v1/types/sync.rs index cbac3e1bbb..ec43fb27d6 100644 --- a/rpc/src/v1/types/sync.rs +++ b/rpc/src/v1/types/sync.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/types/trace.rs b/rpc/src/v1/types/trace.rs index 6eb222f5e6..08ddfb2767 100644 --- a/rpc/src/v1/types/trace.rs +++ b/rpc/src/v1/types/trace.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -327,7 +327,6 @@ impl From for RewardType { } } - /// Reward action #[derive(Debug, Serialize)] pub struct Reward { diff --git a/rpc/src/v1/types/trace_filter.rs b/rpc/src/v1/types/trace_filter.rs index 3a64f52488..83247dade0 100644 --- a/rpc/src/v1/types/trace_filter.rs +++ b/rpc/src/v1/types/trace_filter.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/types/transaction.rs b/rpc/src/v1/types/transaction.rs index 0ac3e37454..d41fc84e00 100644 --- a/rpc/src/v1/types/transaction.rs +++ b/rpc/src/v1/types/transaction.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -327,4 +327,3 @@ mod tests { ); } } - diff --git a/rpc/src/v1/types/transaction_condition.rs b/rpc/src/v1/types/transaction_condition.rs index 541bd364a3..65642224c2 100644 --- a/rpc/src/v1/types/transaction_condition.rs +++ b/rpc/src/v1/types/transaction_condition.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -64,4 +64,3 @@ mod tests { assert_eq!(transaction::Condition::Timestamp(100), TransactionCondition::Timestamp(100).into()); } } - diff --git a/rpc/src/v1/types/transaction_request.rs b/rpc/src/v1/types/transaction_request.rs index 2d4c86c7e7..7fed6f681a 100644 --- a/rpc/src/v1/types/transaction_request.rs +++ b/rpc/src/v1/types/transaction_request.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -127,7 +127,6 @@ impl Into for TransactionRequest { } } - #[cfg(test)] mod tests { use std::str::FromStr; diff --git a/rpc/src/v1/types/uint.rs b/rpc/src/v1/types/uint.rs index 4e2a189a63..cb6dd5d3fd 100644 --- a/rpc/src/v1/types/uint.rs +++ b/rpc/src/v1/types/uint.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/rpc/src/v1/types/work.rs b/rpc/src/v1/types/work.rs index 3664892df7..5fdc117a20 100644 --- a/rpc/src/v1/types/work.rs +++ b/rpc/src/v1/types/work.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -40,4 +40,3 @@ impl Serialize for Work { } } } - diff --git a/rpc_cli/src/lib.rs b/rpc_cli/src/lib.rs index f322129d1c..e4554d6ed5 100644 --- a/rpc_cli/src/lib.rs +++ b/rpc_cli/src/lib.rs @@ -1,3 +1,19 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + extern crate futures; extern crate rpassword; diff --git a/rpc_client/src/client.rs b/rpc_client/src/client.rs index 17a8d9d724..93abdac88e 100644 --- a/rpc_client/src/client.rs +++ b/rpc_client/src/client.rs @@ -1,3 +1,19 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + use std::fmt::{Debug, Formatter, Error as FmtError}; use std::io::{BufReader, BufRead}; use std::sync::Arc; diff --git a/rpc_client/src/lib.rs b/rpc_client/src/lib.rs index 49f537708e..98614bd763 100644 --- a/rpc_client/src/lib.rs +++ b/rpc_client/src/lib.rs @@ -1,3 +1,19 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + pub mod client; pub mod signer_client; diff --git a/rpc_client/src/signer_client.rs b/rpc_client/src/signer_client.rs index cee063109b..e7a241137f 100644 --- a/rpc_client/src/signer_client.rs +++ b/rpc_client/src/signer_client.rs @@ -1,3 +1,19 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + use client::{Rpc, RpcError}; use rpc::signer::{ConfirmationRequest, TransactionModification, U256, TransactionCondition}; use serde; diff --git a/scripts/add_license.sh b/scripts/add_license.sh index 1d916f4279..2b283590b0 100755 --- a/scripts/add_license.sh +++ b/scripts/add_license.sh @@ -1,6 +1,20 @@ -#!/bin/sh +#!/usr/bin/env sh -for f in $(find . -name '*.rs'); do - cat license_header $f > $f.new - mv $f.new $f +PAT_GPL="^// Copyright.*If not, see \.$" +PAT_OTHER="^// Copyright" + +for f in $(find . -type f | egrep '\.(c|cpp|rs)$'); do + HEADER=$(head -16 $f) + if [[ $HEADER =~ $PAT_GPL ]]; then + BODY=$(tail -n +17 $f) + cat license_header > temp + echo "$BODY" >> temp + mv temp $f + elif [[ $HEADER =~ $PAT_OTHER ]]; then + echo "Other license was found do nothing" + else + echo "$f was missing header" + cat license_header $f > temp + mv temp $f + fi done diff --git a/scripts/remove_duplicate_empty_lines.sh b/scripts/remove_duplicate_empty_lines.sh new file mode 100755 index 0000000000..0df265ab9f --- /dev/null +++ b/scripts/remove_duplicate_empty_lines.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env sh + +for f in $(find . -name '*.rs'); do + cat -s $f > $f.temp + mv $f.temp $f +done diff --git a/secret_store/src/acl_storage.rs b/secret_store/src/acl_storage.rs index bc75cfec44..10b58a9c74 100644 --- a/secret_store/src/acl_storage.rs +++ b/secret_store/src/acl_storage.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/secret_store/src/key_server.rs b/secret_store/src/key_server.rs index b06be2422e..099d8aa451 100644 --- a/secret_store/src/key_server.rs +++ b/secret_store/src/key_server.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/secret_store/src/key_server_cluster/admin_sessions/key_version_negotiation_session.rs b/secret_store/src/key_server_cluster/admin_sessions/key_version_negotiation_session.rs index 6c39fd8e7e..9aeb5ca34d 100644 --- a/secret_store/src/key_server_cluster/admin_sessions/key_version_negotiation_session.rs +++ b/secret_store/src/key_server_cluster/admin_sessions/key_version_negotiation_session.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/secret_store/src/key_server_cluster/admin_sessions/mod.rs b/secret_store/src/key_server_cluster/admin_sessions/mod.rs index 11c01cac53..1fedc1db40 100644 --- a/secret_store/src/key_server_cluster/admin_sessions/mod.rs +++ b/secret_store/src/key_server_cluster/admin_sessions/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/secret_store/src/key_server_cluster/admin_sessions/servers_set_change_session.rs b/secret_store/src/key_server_cluster/admin_sessions/servers_set_change_session.rs index 698872aadc..01cb03131e 100644 --- a/secret_store/src/key_server_cluster/admin_sessions/servers_set_change_session.rs +++ b/secret_store/src/key_server_cluster/admin_sessions/servers_set_change_session.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/secret_store/src/key_server_cluster/admin_sessions/sessions_queue.rs b/secret_store/src/key_server_cluster/admin_sessions/sessions_queue.rs index 35adaab68c..7657dfc826 100644 --- a/secret_store/src/key_server_cluster/admin_sessions/sessions_queue.rs +++ b/secret_store/src/key_server_cluster/admin_sessions/sessions_queue.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/secret_store/src/key_server_cluster/admin_sessions/share_add_session.rs b/secret_store/src/key_server_cluster/admin_sessions/share_add_session.rs index abe34edeab..4b79473b56 100644 --- a/secret_store/src/key_server_cluster/admin_sessions/share_add_session.rs +++ b/secret_store/src/key_server_cluster/admin_sessions/share_add_session.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/secret_store/src/key_server_cluster/admin_sessions/share_change_session.rs b/secret_store/src/key_server_cluster/admin_sessions/share_change_session.rs index 1e408ee52e..af16ef2f6d 100644 --- a/secret_store/src/key_server_cluster/admin_sessions/share_change_session.rs +++ b/secret_store/src/key_server_cluster/admin_sessions/share_change_session.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/secret_store/src/key_server_cluster/client_sessions/decryption_session.rs b/secret_store/src/key_server_cluster/client_sessions/decryption_session.rs index f852451b43..724d2fe49f 100644 --- a/secret_store/src/key_server_cluster/client_sessions/decryption_session.rs +++ b/secret_store/src/key_server_cluster/client_sessions/decryption_session.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/secret_store/src/key_server_cluster/client_sessions/encryption_session.rs b/secret_store/src/key_server_cluster/client_sessions/encryption_session.rs index 3c863d1cb9..70532b6905 100644 --- a/secret_store/src/key_server_cluster/client_sessions/encryption_session.rs +++ b/secret_store/src/key_server_cluster/client_sessions/encryption_session.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/secret_store/src/key_server_cluster/client_sessions/generation_session.rs b/secret_store/src/key_server_cluster/client_sessions/generation_session.rs index c2effe6c26..7001ccf69e 100644 --- a/secret_store/src/key_server_cluster/client_sessions/generation_session.rs +++ b/secret_store/src/key_server_cluster/client_sessions/generation_session.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -1299,7 +1299,6 @@ pub mod tests { }).unwrap_err(), Error::InvalidMessage); } - #[test] fn encryption_fails_on_session_timeout() { let (_, _, _, l) = make_simple_cluster(0, 2).unwrap(); diff --git a/secret_store/src/key_server_cluster/client_sessions/mod.rs b/secret_store/src/key_server_cluster/client_sessions/mod.rs index ba2fbd5350..133edcffbb 100644 --- a/secret_store/src/key_server_cluster/client_sessions/mod.rs +++ b/secret_store/src/key_server_cluster/client_sessions/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/secret_store/src/key_server_cluster/client_sessions/signing_session_ecdsa.rs b/secret_store/src/key_server_cluster/client_sessions/signing_session_ecdsa.rs index b0d465343b..670fa138f2 100644 --- a/secret_store/src/key_server_cluster/client_sessions/signing_session_ecdsa.rs +++ b/secret_store/src/key_server_cluster/client_sessions/signing_session_ecdsa.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -644,7 +644,6 @@ impl SessionImpl { Self::compute_inversed_nonce_coeff(&self.core, &*data)? }; - let version = data.version.as_ref().ok_or(Error::InvalidMessage)?.clone(); let message_hash = data.message_hash .expect("we are on master node; on master node message_hash is filled in initialize(); on_generation_message follows initialize; qed"); diff --git a/secret_store/src/key_server_cluster/client_sessions/signing_session_schnorr.rs b/secret_store/src/key_server_cluster/client_sessions/signing_session_schnorr.rs index 013748827c..376eab26b4 100644 --- a/secret_store/src/key_server_cluster/client_sessions/signing_session_schnorr.rs +++ b/secret_store/src/key_server_cluster/client_sessions/signing_session_schnorr.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -1289,4 +1289,4 @@ mod tests { _ => unreachable!(), } } -} \ No newline at end of file +} diff --git a/secret_store/src/key_server_cluster/cluster.rs b/secret_store/src/key_server_cluster/cluster.rs index d782ccd035..86de005b77 100644 --- a/secret_store/src/key_server_cluster/cluster.rs +++ b/secret_store/src/key_server_cluster/cluster.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/secret_store/src/key_server_cluster/cluster_sessions.rs b/secret_store/src/key_server_cluster/cluster_sessions.rs index 780c947fc3..4dcfd3f881 100644 --- a/secret_store/src/key_server_cluster/cluster_sessions.rs +++ b/secret_store/src/key_server_cluster/cluster_sessions.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/secret_store/src/key_server_cluster/cluster_sessions_creator.rs b/secret_store/src/key_server_cluster/cluster_sessions_creator.rs index a56f51f8fb..e1b5125ac4 100644 --- a/secret_store/src/key_server_cluster/cluster_sessions_creator.rs +++ b/secret_store/src/key_server_cluster/cluster_sessions_creator.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/secret_store/src/key_server_cluster/connection_trigger.rs b/secret_store/src/key_server_cluster/connection_trigger.rs index 66612f044b..71f17313fe 100644 --- a/secret_store/src/key_server_cluster/connection_trigger.rs +++ b/secret_store/src/key_server_cluster/connection_trigger.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/secret_store/src/key_server_cluster/connection_trigger_with_migration.rs b/secret_store/src/key_server_cluster/connection_trigger_with_migration.rs index 40a4b5028e..cc8db3e665 100644 --- a/secret_store/src/key_server_cluster/connection_trigger_with_migration.rs +++ b/secret_store/src/key_server_cluster/connection_trigger_with_migration.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/secret_store/src/key_server_cluster/io/deadline.rs b/secret_store/src/key_server_cluster/io/deadline.rs index 1088f4f337..94a1895227 100644 --- a/secret_store/src/key_server_cluster/io/deadline.rs +++ b/secret_store/src/key_server_cluster/io/deadline.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/secret_store/src/key_server_cluster/io/handshake.rs b/secret_store/src/key_server_cluster/io/handshake.rs index af64295632..5081004d0b 100644 --- a/secret_store/src/key_server_cluster/io/handshake.rs +++ b/secret_store/src/key_server_cluster/io/handshake.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/secret_store/src/key_server_cluster/io/message.rs b/secret_store/src/key_server_cluster/io/message.rs index 9925b789d2..e8e01a91f5 100644 --- a/secret_store/src/key_server_cluster/io/message.rs +++ b/secret_store/src/key_server_cluster/io/message.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/secret_store/src/key_server_cluster/io/mod.rs b/secret_store/src/key_server_cluster/io/mod.rs index dfea336830..02adb72ad7 100644 --- a/secret_store/src/key_server_cluster/io/mod.rs +++ b/secret_store/src/key_server_cluster/io/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/secret_store/src/key_server_cluster/io/read_header.rs b/secret_store/src/key_server_cluster/io/read_header.rs index 2fd8960e30..803e01b95b 100644 --- a/secret_store/src/key_server_cluster/io/read_header.rs +++ b/secret_store/src/key_server_cluster/io/read_header.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/secret_store/src/key_server_cluster/io/read_message.rs b/secret_store/src/key_server_cluster/io/read_message.rs index 1ffb98792a..b1d0395d57 100644 --- a/secret_store/src/key_server_cluster/io/read_message.rs +++ b/secret_store/src/key_server_cluster/io/read_message.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/secret_store/src/key_server_cluster/io/read_payload.rs b/secret_store/src/key_server_cluster/io/read_payload.rs index 1246092e90..da4f4d3c01 100644 --- a/secret_store/src/key_server_cluster/io/read_payload.rs +++ b/secret_store/src/key_server_cluster/io/read_payload.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/secret_store/src/key_server_cluster/io/shared_tcp_stream.rs b/secret_store/src/key_server_cluster/io/shared_tcp_stream.rs index a847b14280..64afbbe82f 100644 --- a/secret_store/src/key_server_cluster/io/shared_tcp_stream.rs +++ b/secret_store/src/key_server_cluster/io/shared_tcp_stream.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/secret_store/src/key_server_cluster/io/write_message.rs b/secret_store/src/key_server_cluster/io/write_message.rs index 8a89cf4552..d337a3705a 100644 --- a/secret_store/src/key_server_cluster/io/write_message.rs +++ b/secret_store/src/key_server_cluster/io/write_message.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/secret_store/src/key_server_cluster/jobs/consensus_session.rs b/secret_store/src/key_server_cluster/jobs/consensus_session.rs index 5d780a48eb..6d2866750e 100644 --- a/secret_store/src/key_server_cluster/jobs/consensus_session.rs +++ b/secret_store/src/key_server_cluster/jobs/consensus_session.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/secret_store/src/key_server_cluster/jobs/decryption_job.rs b/secret_store/src/key_server_cluster/jobs/decryption_job.rs index 2c11fe0ab3..debffa25e0 100644 --- a/secret_store/src/key_server_cluster/jobs/decryption_job.rs +++ b/secret_store/src/key_server_cluster/jobs/decryption_job.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/secret_store/src/key_server_cluster/jobs/dummy_job.rs b/secret_store/src/key_server_cluster/jobs/dummy_job.rs index 3e84c0d49d..f7e771d155 100644 --- a/secret_store/src/key_server_cluster/jobs/dummy_job.rs +++ b/secret_store/src/key_server_cluster/jobs/dummy_job.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/secret_store/src/key_server_cluster/jobs/job_session.rs b/secret_store/src/key_server_cluster/jobs/job_session.rs index d3a765bf5b..ab0300db36 100644 --- a/secret_store/src/key_server_cluster/jobs/job_session.rs +++ b/secret_store/src/key_server_cluster/jobs/job_session.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/secret_store/src/key_server_cluster/jobs/key_access_job.rs b/secret_store/src/key_server_cluster/jobs/key_access_job.rs index a47385b5ae..6a0577f022 100644 --- a/secret_store/src/key_server_cluster/jobs/key_access_job.rs +++ b/secret_store/src/key_server_cluster/jobs/key_access_job.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/secret_store/src/key_server_cluster/jobs/mod.rs b/secret_store/src/key_server_cluster/jobs/mod.rs index 817f09b71d..75d07e313b 100644 --- a/secret_store/src/key_server_cluster/jobs/mod.rs +++ b/secret_store/src/key_server_cluster/jobs/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/secret_store/src/key_server_cluster/jobs/servers_set_change_access_job.rs b/secret_store/src/key_server_cluster/jobs/servers_set_change_access_job.rs index 1d16286926..6c142d2a2f 100644 --- a/secret_store/src/key_server_cluster/jobs/servers_set_change_access_job.rs +++ b/secret_store/src/key_server_cluster/jobs/servers_set_change_access_job.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/secret_store/src/key_server_cluster/jobs/signing_job_ecdsa.rs b/secret_store/src/key_server_cluster/jobs/signing_job_ecdsa.rs index 8f4ab1d68e..6349c2e7db 100644 --- a/secret_store/src/key_server_cluster/jobs/signing_job_ecdsa.rs +++ b/secret_store/src/key_server_cluster/jobs/signing_job_ecdsa.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/secret_store/src/key_server_cluster/jobs/signing_job_schnorr.rs b/secret_store/src/key_server_cluster/jobs/signing_job_schnorr.rs index 54225a6cf5..4d1a0e7d90 100644 --- a/secret_store/src/key_server_cluster/jobs/signing_job_schnorr.rs +++ b/secret_store/src/key_server_cluster/jobs/signing_job_schnorr.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -148,4 +148,4 @@ impl JobExecutor for SchnorrSigningJob { Ok((signature_c, signature_s)) } -} \ No newline at end of file +} diff --git a/secret_store/src/key_server_cluster/jobs/unknown_sessions_job.rs b/secret_store/src/key_server_cluster/jobs/unknown_sessions_job.rs index 13f2f8b8bb..908afa1ecc 100644 --- a/secret_store/src/key_server_cluster/jobs/unknown_sessions_job.rs +++ b/secret_store/src/key_server_cluster/jobs/unknown_sessions_job.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/secret_store/src/key_server_cluster/math.rs b/secret_store/src/key_server_cluster/math.rs index ef6d88f67c..66f26b5086 100644 --- a/secret_store/src/key_server_cluster/math.rs +++ b/secret_store/src/key_server_cluster/math.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/secret_store/src/key_server_cluster/message.rs b/secret_store/src/key_server_cluster/message.rs index cc49e56fdb..8aecdc9dd6 100644 --- a/secret_store/src/key_server_cluster/message.rs +++ b/secret_store/src/key_server_cluster/message.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/secret_store/src/key_server_cluster/mod.rs b/secret_store/src/key_server_cluster/mod.rs index d5ac85b3de..018d70d305 100644 --- a/secret_store/src/key_server_cluster/mod.rs +++ b/secret_store/src/key_server_cluster/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/secret_store/src/key_server_cluster/net/accept_connection.rs b/secret_store/src/key_server_cluster/net/accept_connection.rs index d85e492dd7..3565ea3d0f 100644 --- a/secret_store/src/key_server_cluster/net/accept_connection.rs +++ b/secret_store/src/key_server_cluster/net/accept_connection.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/secret_store/src/key_server_cluster/net/connect.rs b/secret_store/src/key_server_cluster/net/connect.rs index 7515494e44..8b93479f97 100644 --- a/secret_store/src/key_server_cluster/net/connect.rs +++ b/secret_store/src/key_server_cluster/net/connect.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/secret_store/src/key_server_cluster/net/connection.rs b/secret_store/src/key_server_cluster/net/connection.rs index 577f5828f6..7776e97a74 100644 --- a/secret_store/src/key_server_cluster/net/connection.rs +++ b/secret_store/src/key_server_cluster/net/connection.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/secret_store/src/key_server_cluster/net/mod.rs b/secret_store/src/key_server_cluster/net/mod.rs index 6abf83ceb8..e76f4f476c 100644 --- a/secret_store/src/key_server_cluster/net/mod.rs +++ b/secret_store/src/key_server_cluster/net/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/secret_store/src/key_server_set.rs b/secret_store/src/key_server_set.rs index 8a0d786af9..cf95e917ae 100644 --- a/secret_store/src/key_server_set.rs +++ b/secret_store/src/key_server_set.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/secret_store/src/key_storage.rs b/secret_store/src/key_storage.rs index 848e6bf2a5..f5d6df8010 100644 --- a/secret_store/src/key_storage.rs +++ b/secret_store/src/key_storage.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -348,7 +348,6 @@ impl DocumentKeyShareVersion { } } - /// Calculate hash of given version data. pub fn data_hash<'a, I>(id_numbers: I) -> H256 where I: Iterator { let mut nodes_keccak = Keccak::new_keccak256(); diff --git a/secret_store/src/lib.rs b/secret_store/src/lib.rs index 80b15318a9..404c278d53 100644 --- a/secret_store/src/lib.rs +++ b/secret_store/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/secret_store/src/listener/http_listener.rs b/secret_store/src/listener/http_listener.rs index 074052fae4..5aa82a1cbd 100644 --- a/secret_store/src/listener/http_listener.rs +++ b/secret_store/src/listener/http_listener.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/secret_store/src/listener/mod.rs b/secret_store/src/listener/mod.rs index 0d1f3f2675..8837e7ffd6 100644 --- a/secret_store/src/listener/mod.rs +++ b/secret_store/src/listener/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/secret_store/src/listener/service_contract.rs b/secret_store/src/listener/service_contract.rs index eac3cfa9da..72c23b86b5 100644 --- a/secret_store/src/listener/service_contract.rs +++ b/secret_store/src/listener/service_contract.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/secret_store/src/listener/service_contract_aggregate.rs b/secret_store/src/listener/service_contract_aggregate.rs index 9ec467fea4..cc2e97b8d4 100644 --- a/secret_store/src/listener/service_contract_aggregate.rs +++ b/secret_store/src/listener/service_contract_aggregate.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/secret_store/src/listener/service_contract_listener.rs b/secret_store/src/listener/service_contract_listener.rs index 214235210f..724c902d12 100644 --- a/secret_store/src/listener/service_contract_listener.rs +++ b/secret_store/src/listener/service_contract_listener.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/secret_store/src/listener/tasks_queue.rs b/secret_store/src/listener/tasks_queue.rs index e228d12cef..934459940a 100644 --- a/secret_store/src/listener/tasks_queue.rs +++ b/secret_store/src/listener/tasks_queue.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/secret_store/src/node_key_pair.rs b/secret_store/src/node_key_pair.rs index 428dba6c1a..93cf285b2f 100644 --- a/secret_store/src/node_key_pair.rs +++ b/secret_store/src/node_key_pair.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/secret_store/src/serialization.rs b/secret_store/src/serialization.rs index f3e9aa1d76..7ae5e8f269 100644 --- a/secret_store/src/serialization.rs +++ b/secret_store/src/serialization.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/secret_store/src/traits.rs b/secret_store/src/traits.rs index 704be1c254..d92983fe8d 100644 --- a/secret_store/src/traits.rs +++ b/secret_store/src/traits.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/secret_store/src/trusted_client.rs b/secret_store/src/trusted_client.rs index 94b1c0174d..cf9c987be3 100644 --- a/secret_store/src/trusted_client.rs +++ b/secret_store/src/trusted_client.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/secret_store/src/types/all.rs b/secret_store/src/types/all.rs index ab0aea1b13..f0e0388104 100644 --- a/secret_store/src/types/all.rs +++ b/secret_store/src/types/all.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/secret_store/src/types/error.rs b/secret_store/src/types/error.rs index eae914ec86..74e6bb9e3c 100644 --- a/secret_store/src/types/error.rs +++ b/secret_store/src/types/error.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/secret_store/src/types/mod.rs b/secret_store/src/types/mod.rs index 9da7f6ef98..443f4acb3a 100644 --- a/secret_store/src/types/mod.rs +++ b/secret_store/src/types/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/transaction-pool/src/error.rs b/transaction-pool/src/error.rs index 4cf221a71e..c7666841a2 100644 --- a/transaction-pool/src/error.rs +++ b/transaction-pool/src/error.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/transaction-pool/src/lib.rs b/transaction-pool/src/lib.rs index 4a1bdcde14..ea77debfa2 100644 --- a/transaction-pool/src/lib.rs +++ b/transaction-pool/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/transaction-pool/src/listener.rs b/transaction-pool/src/listener.rs index 728a035e31..3339a7730d 100644 --- a/transaction-pool/src/listener.rs +++ b/transaction-pool/src/listener.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/transaction-pool/src/options.rs b/transaction-pool/src/options.rs index 8ccf8adfd1..291001a202 100644 --- a/transaction-pool/src/options.rs +++ b/transaction-pool/src/options.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/transaction-pool/src/pool.rs b/transaction-pool/src/pool.rs index 5cb6e479b8..dcd52a3e7e 100644 --- a/transaction-pool/src/pool.rs +++ b/transaction-pool/src/pool.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -95,7 +95,6 @@ impl> Pool { } } - const INITIAL_NUMBER_OF_SENDERS: usize = 16; impl Pool where diff --git a/transaction-pool/src/ready.rs b/transaction-pool/src/ready.rs index aa913a9eb5..0bee5188df 100644 --- a/transaction-pool/src/ready.rs +++ b/transaction-pool/src/ready.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/transaction-pool/src/scoring.rs b/transaction-pool/src/scoring.rs index 2acfb33748..462b708651 100644 --- a/transaction-pool/src/scoring.rs +++ b/transaction-pool/src/scoring.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/transaction-pool/src/status.rs b/transaction-pool/src/status.rs index a03bc6b062..b9e7656d44 100644 --- a/transaction-pool/src/status.rs +++ b/transaction-pool/src/status.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/transaction-pool/src/tests/helpers.rs b/transaction-pool/src/tests/helpers.rs index cfc6641b5e..b71959b08e 100644 --- a/transaction-pool/src/tests/helpers.rs +++ b/transaction-pool/src/tests/helpers.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/transaction-pool/src/tests/mod.rs b/transaction-pool/src/tests/mod.rs index b21ea31807..6edd60e60e 100644 --- a/transaction-pool/src/tests/mod.rs +++ b/transaction-pool/src/tests/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -578,4 +578,3 @@ mod listener { assert_eq!(*results.borrow(), &["added", "added", "mined", "mined"]); } } - diff --git a/transaction-pool/src/tests/tx_builder.rs b/transaction-pool/src/tests/tx_builder.rs index 88a881aca8..9478d417a2 100644 --- a/transaction-pool/src/tests/tx_builder.rs +++ b/transaction-pool/src/tests/tx_builder.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/transaction-pool/src/transactions.rs b/transaction-pool/src/transactions.rs index f1a91ff4f8..edc26b69f4 100644 --- a/transaction-pool/src/transactions.rs +++ b/transaction-pool/src/transactions.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/transaction-pool/src/verifier.rs b/transaction-pool/src/verifier.rs index e55a17e911..312a3eae3c 100644 --- a/transaction-pool/src/verifier.rs +++ b/transaction-pool/src/verifier.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/updater/src/lib.rs b/updater/src/lib.rs index 67525aa4b2..f27d74e7d7 100644 --- a/updater/src/lib.rs +++ b/updater/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/updater/src/service.rs b/updater/src/service.rs index b025eb42ea..604c01ec76 100644 --- a/updater/src/service.rs +++ b/updater/src/service.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -35,4 +35,3 @@ pub trait Service: Send + Sync { /// Information gathered concerning the release. fn info(&self) -> Option; } - diff --git a/updater/src/types/all.rs b/updater/src/types/all.rs index 7079fb8ded..9dd782683d 100644 --- a/updater/src/types/all.rs +++ b/updater/src/types/all.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/updater/src/types/mod.rs b/updater/src/types/mod.rs index b6d3c60254..8fdbcf169d 100644 --- a/updater/src/types/mod.rs +++ b/updater/src/types/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -23,4 +23,3 @@ mod version_info; pub use self::all::{ReleaseInfo, OperationsInfo, CapState}; pub use self::release_track::ReleaseTrack; pub use self::version_info::VersionInfo; - diff --git a/updater/src/types/release_track.rs b/updater/src/types/release_track.rs index a1f646805a..eefe18d9f2 100644 --- a/updater/src/types/release_track.rs +++ b/updater/src/types/release_track.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -70,7 +70,6 @@ impl From for ReleaseTrack { } } - impl From for u8 { fn from(rt: ReleaseTrack) -> Self { rt as u8 diff --git a/updater/src/types/version_info.rs b/updater/src/types/version_info.rs index 4409153e2a..955be05660 100644 --- a/updater/src/types/version_info.rs +++ b/updater/src/types/version_info.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/updater/src/updater.rs b/updater/src/updater.rs index f8a98f3b0f..8e9efa0aa1 100644 --- a/updater/src/updater.rs +++ b/updater/src/updater.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/util/bloom/src/lib.rs b/util/bloom/src/lib.rs index 22a2cbc2aa..32aad24bf2 100644 --- a/util/bloom/src/lib.rs +++ b/util/bloom/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -14,7 +14,6 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . - extern crate siphasher; use std::cmp; @@ -208,7 +207,6 @@ pub struct BloomJournal { pub entries: Vec<(usize, u64)>, } - #[cfg(test)] mod tests { use super::Bloom; diff --git a/util/bloomchain/src/chain.rs b/util/bloomchain/src/chain.rs index ba7bc21b35..1017c874e4 100644 --- a/util/bloomchain/src/chain.rs +++ b/util/bloomchain/src/chain.rs @@ -1,3 +1,19 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + use std::collections::{HashMap, HashSet}; use std::ops::Range; use number::Number; diff --git a/util/bloomchain/src/config.rs b/util/bloomchain/src/config.rs index 3e729922a1..58a600e1a1 100644 --- a/util/bloomchain/src/config.rs +++ b/util/bloomchain/src/config.rs @@ -1,3 +1,19 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + /// `BloomChain` configuration. #[derive(Debug, PartialEq, Clone, Copy)] pub struct Config { diff --git a/util/bloomchain/src/database.rs b/util/bloomchain/src/database.rs index 9aba41e7c6..b6dc77a199 100644 --- a/util/bloomchain/src/database.rs +++ b/util/bloomchain/src/database.rs @@ -1,3 +1,19 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + use position::Position; use bloom::Bloom; diff --git a/util/bloomchain/src/filter.rs b/util/bloomchain/src/filter.rs index 06d657ba44..83edd95a72 100644 --- a/util/bloomchain/src/filter.rs +++ b/util/bloomchain/src/filter.rs @@ -1,3 +1,19 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + use std::ops::Range; use bloom::Bloom; use number::Number; diff --git a/util/bloomchain/src/group/bridge.rs b/util/bloomchain/src/group/bridge.rs index b01650157c..4efbec6274 100644 --- a/util/bloomchain/src/group/bridge.rs +++ b/util/bloomchain/src/group/bridge.rs @@ -1,3 +1,19 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + use bloom::Bloom; use config::Config; use database::BloomDatabase; diff --git a/util/bloomchain/src/group/chain.rs b/util/bloomchain/src/group/chain.rs index cfd7796f4d..3108ba649b 100644 --- a/util/bloomchain/src/group/chain.rs +++ b/util/bloomchain/src/group/chain.rs @@ -1,3 +1,19 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + use std::collections::HashMap; use std::ops::Range; use bloom::Bloom; diff --git a/util/bloomchain/src/group/database.rs b/util/bloomchain/src/group/database.rs index 494184f3eb..a3d0847b65 100644 --- a/util/bloomchain/src/group/database.rs +++ b/util/bloomchain/src/group/database.rs @@ -1,3 +1,19 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + use group::{GroupPosition, BloomGroup}; /// Readonly `BloomGroup` database. diff --git a/util/bloomchain/src/group/group.rs b/util/bloomchain/src/group/group.rs index 084c8f8e48..dc19926c58 100644 --- a/util/bloomchain/src/group/group.rs +++ b/util/bloomchain/src/group/group.rs @@ -1,3 +1,19 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + use bloom::Bloom; /// Group of blooms that are in the same index. diff --git a/util/bloomchain/src/group/mod.rs b/util/bloomchain/src/group/mod.rs index b6cabf628f..9123037ec6 100644 --- a/util/bloomchain/src/group/mod.rs +++ b/util/bloomchain/src/group/mod.rs @@ -1,3 +1,19 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + //! Bloom grouping. //! //! Optimization gathering together blooms that are in the same index and are likely to be retrived together. diff --git a/util/bloomchain/src/group/position/manager.rs b/util/bloomchain/src/group/position/manager.rs index 611a5bb784..fc5656537a 100644 --- a/util/bloomchain/src/group/position/manager.rs +++ b/util/bloomchain/src/group/position/manager.rs @@ -1,3 +1,19 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + use super::{Position, GroupPosition}; use position::Position as BloomPosition; diff --git a/util/bloomchain/src/group/position/mod.rs b/util/bloomchain/src/group/position/mod.rs index fc95de4dd0..7173d1d9bb 100644 --- a/util/bloomchain/src/group/position/mod.rs +++ b/util/bloomchain/src/group/position/mod.rs @@ -1,3 +1,19 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + mod position; mod manager; diff --git a/util/bloomchain/src/group/position/position.rs b/util/bloomchain/src/group/position/position.rs index 88f26d69ab..1d8f89af54 100644 --- a/util/bloomchain/src/group/position/position.rs +++ b/util/bloomchain/src/group/position/position.rs @@ -1,3 +1,19 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + /// Uniquely identifies bloom group position. #[derive(Debug, PartialEq, Eq, Hash, Clone)] pub struct GroupPosition { diff --git a/util/bloomchain/src/lib.rs b/util/bloomchain/src/lib.rs index 997ae08391..a82b898caf 100644 --- a/util/bloomchain/src/lib.rs +++ b/util/bloomchain/src/lib.rs @@ -1,3 +1,19 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + extern crate ethbloom as bloom; mod chain; diff --git a/util/bloomchain/src/number.rs b/util/bloomchain/src/number.rs index 3ff82f1957..6c5af2e25d 100644 --- a/util/bloomchain/src/number.rs +++ b/util/bloomchain/src/number.rs @@ -1,2 +1,18 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + /// Represents block number. pub type Number = usize; diff --git a/util/bloomchain/src/position/manager.rs b/util/bloomchain/src/position/manager.rs index a405878ab5..707afb667c 100644 --- a/util/bloomchain/src/position/manager.rs +++ b/util/bloomchain/src/position/manager.rs @@ -1,3 +1,19 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + //! Simplifies working with bloom indexes. use super::Position; diff --git a/util/bloomchain/src/position/mod.rs b/util/bloomchain/src/position/mod.rs index 4fa736a163..623e9784e3 100644 --- a/util/bloomchain/src/position/mod.rs +++ b/util/bloomchain/src/position/mod.rs @@ -1,3 +1,19 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + pub mod position; pub mod manager; diff --git a/util/bloomchain/src/position/position.rs b/util/bloomchain/src/position/position.rs index 32845cbcc5..c822d03e00 100644 --- a/util/bloomchain/src/position/position.rs +++ b/util/bloomchain/src/position/position.rs @@ -1,3 +1,19 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + /// Uniquely identifies bloom position. #[derive(Debug, PartialEq, Eq, Hash)] pub struct Position { diff --git a/util/bloomchain/tests/bloomchain.rs b/util/bloomchain/tests/bloomchain.rs index 4a77407a7a..f1e260bfdd 100644 --- a/util/bloomchain/tests/bloomchain.rs +++ b/util/bloomchain/tests/bloomchain.rs @@ -1,3 +1,19 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + extern crate bloomchain; extern crate rustc_hex; @@ -53,7 +69,6 @@ fn partly_matching_bloom_searach() { db.insert_blooms(modified_blooms_1); - let chain = BloomChain::new(config, &db); assert_eq!(chain.with_bloom(&(0..100), &bloom2), vec![14, 15]); } @@ -101,7 +116,6 @@ fn bloom_replace() { db.insert_blooms(modified_blooms_3); - let reset_modified_blooms = { let chain = BloomChain::new(config, &db); chain.replace(&(15..17), vec![bloom4.clone(), bloom5.clone()]) diff --git a/util/bloomchain/tests/groupchain.rs b/util/bloomchain/tests/groupchain.rs index ec396346ac..048edc03ce 100644 --- a/util/bloomchain/tests/groupchain.rs +++ b/util/bloomchain/tests/groupchain.rs @@ -1,3 +1,19 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + extern crate bloomchain; extern crate rustc_hex; @@ -23,7 +39,6 @@ fn simple_bloom_group_search() { assert_eq!(modified_blooms.len(), config.levels); db.insert_blooms(modified_blooms); - let chain = BloomGroupChain::new(config, &db); assert_eq!(chain.with_bloom(&(0..100), &bloom), vec![23]); assert_eq!(chain.with_bloom(&(0..22), &bloom), vec![]); @@ -55,7 +70,6 @@ fn partly_matching_bloom_group_searach() { db.insert_blooms(modified_blooms_1); - let chain = BloomGroupChain::new(config, &db); assert_eq!(chain.with_bloom(&(0..100), &bloom2), vec![14, 15]); } @@ -103,7 +117,6 @@ fn bloom_group_replace() { db.insert_blooms(modified_blooms_3); - let reset_modified_blooms = { let chain = BloomGroupChain::new(config, &db); chain.replace(&(15..17), vec![bloom4.clone(), bloom5.clone()]) diff --git a/util/bloomchain/tests/util/db.rs b/util/bloomchain/tests/util/db.rs index 8101b37848..b28e7b524b 100644 --- a/util/bloomchain/tests/util/db.rs +++ b/util/bloomchain/tests/util/db.rs @@ -1,3 +1,19 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + use std::collections::HashMap; use bloomchain::{Position, Bloom, BloomDatabase}; use bloomchain::group::{GroupPosition, BloomGroup, BloomGroupDatabase}; diff --git a/util/bloomchain/tests/util/each.rs b/util/bloomchain/tests/util/each.rs index 19ca1b67cf..1d8fc9a1d4 100644 --- a/util/bloomchain/tests/util/each.rs +++ b/util/bloomchain/tests/util/each.rs @@ -1,3 +1,19 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + use std::io::{BufReader, Read, BufRead}; use bloomchain::Bloom; use super::FromHex; diff --git a/util/bloomchain/tests/util/from_hex.rs b/util/bloomchain/tests/util/from_hex.rs index 9152d304fd..20c59333ae 100644 --- a/util/bloomchain/tests/util/from_hex.rs +++ b/util/bloomchain/tests/util/from_hex.rs @@ -1,3 +1,19 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + use rustc_hex::FromHex as RustcFromHex; use bloomchain::Bloom; diff --git a/util/bloomchain/tests/util/mod.rs b/util/bloomchain/tests/util/mod.rs index 2a1e55af9a..998e7c9520 100644 --- a/util/bloomchain/tests/util/mod.rs +++ b/util/bloomchain/tests/util/mod.rs @@ -1,3 +1,19 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + mod db; mod each; mod from_hex; diff --git a/util/bloomchain/tests/util/random.rs b/util/bloomchain/tests/util/random.rs index 3d50b5ac10..06e3d13520 100644 --- a/util/bloomchain/tests/util/random.rs +++ b/util/bloomchain/tests/util/random.rs @@ -1,3 +1,19 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + extern crate rand; use self::rand::random; diff --git a/util/bytes/src/lib.rs b/util/bytes/src/lib.rs index 4303f70150..03b4745598 100644 --- a/util/bytes/src/lib.rs +++ b/util/bytes/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/util/dir/src/helpers.rs b/util/dir/src/helpers.rs index 95f8090c87..820b9dc5af 100644 --- a/util/dir/src/helpers.rs +++ b/util/dir/src/helpers.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/util/dir/src/lib.rs b/util/dir/src/lib.rs index bb36a46a83..7404a2cbca 100644 --- a/util/dir/src/lib.rs +++ b/util/dir/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/util/error/src/lib.rs b/util/error/src/lib.rs index 9a1ab87536..bacc66c283 100644 --- a/util/error/src/lib.rs +++ b/util/error/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -74,4 +74,3 @@ error_chain! { BaseData(BaseDataError); } } - diff --git a/util/fetch/src/client.rs b/util/fetch/src/client.rs index 9bb55aad0e..cda802cfb0 100644 --- a/util/fetch/src/client.rs +++ b/util/fetch/src/client.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/util/fetch/src/lib.rs b/util/fetch/src/lib.rs index f42aacec5b..8e50fa5e6a 100644 --- a/util/fetch/src/lib.rs +++ b/util/fetch/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/util/hash/benches/keccak_256.rs b/util/hash/benches/keccak_256.rs index 8b398417d8..d59e534104 100644 --- a/util/hash/benches/keccak_256.rs +++ b/util/hash/benches/keccak_256.rs @@ -1,3 +1,19 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + #![feature(test)] extern crate test; @@ -33,4 +49,4 @@ fn bench_keccak_256_with_large_input(b: &mut Bencher) { b.iter(|| { let _out = keccak(&data); }) -} \ No newline at end of file +} diff --git a/util/hash/src/lib.rs b/util/hash/src/lib.rs index b75e095a68..c54d7233cd 100644 --- a/util/hash/src/lib.rs +++ b/util/hash/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -32,7 +32,6 @@ pub const KECCAK_NULL_RLP: H256 = H256( [0x56, 0xe8, 0x1f, 0x17, 0x1b, 0xcc, 0x5 /// The KECCAK of the RLP encoding of empty list. pub const KECCAK_EMPTY_LIST_RLP: H256 = H256( [0x1d, 0xcc, 0x4d, 0xe8, 0xde, 0xc7, 0x5d, 0x7a, 0xab, 0x85, 0xb5, 0x67, 0xb6, 0xcc, 0xd4, 0x1a, 0xd3, 0x12, 0x45, 0x1b, 0x94, 0x8a, 0x74, 0x13, 0xf0, 0xa1, 0x42, 0xfd, 0x40, 0xd4, 0x93, 0x47] ); - pub fn keccak>(s: T) -> H256 { let mut result = [0u8; 32]; write_keccak(s, &mut result); diff --git a/util/hashdb/src/lib.rs b/util/hashdb/src/lib.rs index b65f304e42..182e81c5dc 100644 --- a/util/hashdb/src/lib.rs +++ b/util/hashdb/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/util/io/src/lib.rs b/util/io/src/lib.rs index cd635121ff..02dbf223be 100644 --- a/util/io/src/lib.rs +++ b/util/io/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/util/io/src/service_mio.rs b/util/io/src/service_mio.rs index 2ae3d55e0f..089d54cc45 100644 --- a/util/io/src/service_mio.rs +++ b/util/io/src/service_mio.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/util/io/src/service_non_mio.rs b/util/io/src/service_non_mio.rs index 22a795e4e8..315f84c4d1 100644 --- a/util/io/src/service_non_mio.rs +++ b/util/io/src/service_non_mio.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/util/io/src/worker.rs b/util/io/src/worker.rs index 89657810dc..da144afea4 100644 --- a/util/io/src/worker.rs +++ b/util/io/src/worker.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/util/journaldb/src/archivedb.rs b/util/journaldb/src/archivedb.rs index b58558a332..e2d8c80070 100644 --- a/util/journaldb/src/archivedb.rs +++ b/util/journaldb/src/archivedb.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/util/journaldb/src/earlymergedb.rs b/util/journaldb/src/earlymergedb.rs index c26a67e0ad..25e078bdae 100644 --- a/util/journaldb/src/earlymergedb.rs +++ b/util/journaldb/src/earlymergedb.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -394,7 +394,6 @@ impl JournalDB for EarlyMergeDB { .filter_map(|(k, (v, r))| if r > 0 { assert!(r == 1); Some((k, v)) } else { assert!(r >= -1); None }) .collect(); - // TODO: check all removes are in the db. // Process the new inserts. diff --git a/util/journaldb/src/lib.rs b/util/journaldb/src/lib.rs index c1fb23b6cd..7607271c8d 100644 --- a/util/journaldb/src/lib.rs +++ b/util/journaldb/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/util/journaldb/src/overlaydb.rs b/util/journaldb/src/overlaydb.rs index 54d0bb12d7..46bf42c0ad 100644 --- a/util/journaldb/src/overlaydb.rs +++ b/util/journaldb/src/overlaydb.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/util/journaldb/src/overlayrecentdb.rs b/util/journaldb/src/overlayrecentdb.rs index 2c9ce5cb1d..c7153b889d 100644 --- a/util/journaldb/src/overlayrecentdb.rs +++ b/util/journaldb/src/overlayrecentdb.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/util/journaldb/src/refcounteddb.rs b/util/journaldb/src/refcounteddb.rs index d182d5cf80..cc81bbfba4 100644 --- a/util/journaldb/src/refcounteddb.rs +++ b/util/journaldb/src/refcounteddb.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/util/journaldb/src/traits.rs b/util/journaldb/src/traits.rs index aaf5b27970..e37ac8aabf 100644 --- a/util/journaldb/src/traits.rs +++ b/util/journaldb/src/traits.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/util/kvdb-memorydb/src/lib.rs b/util/kvdb-memorydb/src/lib.rs index 0530c613e3..45ed1c3e69 100644 --- a/util/kvdb-memorydb/src/lib.rs +++ b/util/kvdb-memorydb/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/util/kvdb-rocksdb/src/lib.rs b/util/kvdb-rocksdb/src/lib.rs index 4f2220a11d..6052468298 100644 --- a/util/kvdb-rocksdb/src/lib.rs +++ b/util/kvdb-rocksdb/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -388,7 +388,6 @@ impl Database { DBTransaction::new() } - fn to_overlay_column(col: Option) -> usize { col.map_or(0, |c| (c + 1) as usize) } diff --git a/util/kvdb/src/lib.rs b/util/kvdb/src/lib.rs index 9ed1038bff..78e7b2dc19 100644 --- a/util/kvdb/src/lib.rs +++ b/util/kvdb/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/util/macros/src/lib.rs b/util/macros/src/lib.rs index 78bcd0397e..cc5f92ba15 100644 --- a/util/macros/src/lib.rs +++ b/util/macros/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/util/mem/src/lib.rs b/util/mem/src/lib.rs index a8b9e53f66..db3ad59239 100644 --- a/util/mem/src/lib.rs +++ b/util/mem/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2018 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -54,4 +54,3 @@ impl> DerefMut for Memzero { &mut self.mem } } - diff --git a/util/memory_cache/src/lib.rs b/util/memory_cache/src/lib.rs index af70b0cff3..ff996142b9 100644 --- a/util/memory_cache/src/lib.rs +++ b/util/memory_cache/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/util/memorydb/src/lib.rs b/util/memorydb/src/lib.rs index 12eb62e057..e297d1e6d1 100644 --- a/util/memorydb/src/lib.rs +++ b/util/memorydb/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/util/migration-rocksdb/src/lib.rs b/util/migration-rocksdb/src/lib.rs index fbc9681b40..2e39a380ba 100644 --- a/util/migration-rocksdb/src/lib.rs +++ b/util/migration-rocksdb/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/util/migration-rocksdb/tests/tests.rs b/util/migration-rocksdb/tests/tests.rs index 85c48f12b6..c98ff9d71b 100644 --- a/util/migration-rocksdb/tests/tests.rs +++ b/util/migration-rocksdb/tests/tests.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -119,7 +119,6 @@ impl Migration for AddsColumn { batch.insert(key.into_vec(), value.into_vec(), dest)?; } - if col == Some(1) { batch.insert(vec![1, 2, 3], vec![4, 5, 6], dest)?; } diff --git a/util/network-devp2p/src/connection.rs b/util/network-devp2p/src/connection.rs index 5dbf71fa01..37824ae5d7 100644 --- a/util/network-devp2p/src/connection.rs +++ b/util/network-devp2p/src/connection.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/util/network-devp2p/src/discovery.rs b/util/network-devp2p/src/discovery.rs index af43546a5f..8e8a3d6cc6 100644 --- a/util/network-devp2p/src/discovery.rs +++ b/util/network-devp2p/src/discovery.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/util/network-devp2p/src/handshake.rs b/util/network-devp2p/src/handshake.rs index ffe0276d97..18869de55f 100644 --- a/util/network-devp2p/src/handshake.rs +++ b/util/network-devp2p/src/handshake.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -515,4 +515,3 @@ mod test { check_ack(&h, 57); } } - diff --git a/util/network-devp2p/src/host.rs b/util/network-devp2p/src/host.rs index 245492de80..6d28a838c2 100644 --- a/util/network-devp2p/src/host.rs +++ b/util/network-devp2p/src/host.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -1154,7 +1154,6 @@ fn key_save_load() { assert_eq!(key, r.unwrap()); } - #[test] fn host_client_url() { let mut config = NetworkConfiguration::new_local(); diff --git a/util/network-devp2p/src/ip_utils.rs b/util/network-devp2p/src/ip_utils.rs index 3d7d33a066..a68fc51f10 100644 --- a/util/network-devp2p/src/ip_utils.rs +++ b/util/network-devp2p/src/ip_utils.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -533,5 +533,3 @@ fn ipv6_properties() { check("::", true, false, true); check("::1", false, true, false); } - - diff --git a/util/network-devp2p/src/lib.rs b/util/network-devp2p/src/lib.rs index 12383fdbee..01fc1fe25f 100644 --- a/util/network-devp2p/src/lib.rs +++ b/util/network-devp2p/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/util/network-devp2p/src/node_table.rs b/util/network-devp2p/src/node_table.rs index d5d0207ecd..087caefe18 100644 --- a/util/network-devp2p/src/node_table.rs +++ b/util/network-devp2p/src/node_table.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/util/network-devp2p/src/service.rs b/util/network-devp2p/src/service.rs index f90c660671..d7182f4618 100644 --- a/util/network-devp2p/src/service.rs +++ b/util/network-devp2p/src/service.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/util/network-devp2p/src/session.rs b/util/network-devp2p/src/session.rs index f830dcc0d7..a405ad469d 100644 --- a/util/network-devp2p/src/session.rs +++ b/util/network-devp2p/src/session.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -515,4 +515,3 @@ impl Session { Ok(()) } } - diff --git a/util/network-devp2p/tests/tests.rs b/util/network-devp2p/tests/tests.rs index 3c2333cd10..970aa3b8a5 100644 --- a/util/network-devp2p/tests/tests.rs +++ b/util/network-devp2p/tests/tests.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -99,7 +99,6 @@ impl NetworkProtocolHandler for TestProtocol { } } - #[test] fn net_service() { let service = NetworkService::new(NetworkConfiguration::new_local(), None).expect("Error creating network service"); diff --git a/util/network/src/connection_filter.rs b/util/network/src/connection_filter.rs index 5afe5865b7..e146aee4c7 100644 --- a/util/network/src/connection_filter.rs +++ b/util/network/src/connection_filter.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/util/network/src/error.rs b/util/network/src/error.rs index 50bd01e9ba..4233b9e058 100644 --- a/util/network/src/error.rs +++ b/util/network/src/error.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/util/network/src/lib.rs b/util/network/src/lib.rs index a04eb04880..9b7328bdbd 100644 --- a/util/network/src/lib.rs +++ b/util/network/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2018 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/util/panic_hook/src/lib.rs b/util/panic_hook/src/lib.rs index 1136e9e362..ef6220572a 100644 --- a/util/panic_hook/src/lib.rs +++ b/util/panic_hook/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -8,7 +8,7 @@ // 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 +// 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 diff --git a/util/path/src/lib.rs b/util/path/src/lib.rs index 761b511522..38608db660 100644 --- a/util/path/src/lib.rs +++ b/util/path/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -98,4 +98,3 @@ pub fn restrict_permissions_owner(_file_path: &Path, _write: bool, _executable: //TODO: implement me Ok(()) } - diff --git a/util/patricia_trie/src/fatdb.rs b/util/patricia_trie/src/fatdb.rs index d428ff8116..90cdef9021 100644 --- a/util/patricia_trie/src/fatdb.rs +++ b/util/patricia_trie/src/fatdb.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/util/patricia_trie/src/fatdbmut.rs b/util/patricia_trie/src/fatdbmut.rs index 4b7f2de063..9bf7b88036 100644 --- a/util/patricia_trie/src/fatdbmut.rs +++ b/util/patricia_trie/src/fatdbmut.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/util/patricia_trie/src/lib.rs b/util/patricia_trie/src/lib.rs index d1563becff..8e0e44f032 100644 --- a/util/patricia_trie/src/lib.rs +++ b/util/patricia_trie/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/util/patricia_trie/src/lookup.rs b/util/patricia_trie/src/lookup.rs index 2d63f7d00e..ae91689a31 100644 --- a/util/patricia_trie/src/lookup.rs +++ b/util/patricia_trie/src/lookup.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/util/patricia_trie/src/nibbleslice.rs b/util/patricia_trie/src/nibbleslice.rs index c2dd6611e2..4153049810 100644 --- a/util/patricia_trie/src/nibbleslice.rs +++ b/util/patricia_trie/src/nibbleslice.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/util/patricia_trie/src/nibblevec.rs b/util/patricia_trie/src/nibblevec.rs index fbe97496ae..4398dbc6f7 100644 --- a/util/patricia_trie/src/nibblevec.rs +++ b/util/patricia_trie/src/nibblevec.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/util/patricia_trie/src/node.rs b/util/patricia_trie/src/node.rs index 0b99acded3..0ded1f66db 100644 --- a/util/patricia_trie/src/node.rs +++ b/util/patricia_trie/src/node.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/util/patricia_trie/src/recorder.rs b/util/patricia_trie/src/recorder.rs index 35a515b704..6a0f9b45eb 100644 --- a/util/patricia_trie/src/recorder.rs +++ b/util/patricia_trie/src/recorder.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/util/patricia_trie/src/sectriedb.rs b/util/patricia_trie/src/sectriedb.rs index a9176d022a..c8d5ec0ec8 100644 --- a/util/patricia_trie/src/sectriedb.rs +++ b/util/patricia_trie/src/sectriedb.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/util/patricia_trie/src/sectriedbmut.rs b/util/patricia_trie/src/sectriedbmut.rs index b0436b271f..335fb2f183 100644 --- a/util/patricia_trie/src/sectriedbmut.rs +++ b/util/patricia_trie/src/sectriedbmut.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/util/patricia_trie/src/triedb.rs b/util/patricia_trie/src/triedb.rs index c18e4fce96..65ce3caba8 100644 --- a/util/patricia_trie/src/triedb.rs +++ b/util/patricia_trie/src/triedb.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/util/patricia_trie/src/triedbmut.rs b/util/patricia_trie/src/triedbmut.rs index b8d919deea..994045eb3a 100644 --- a/util/patricia_trie/src/triedbmut.rs +++ b/util/patricia_trie/src/triedbmut.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -893,7 +893,6 @@ impl<'a> TrieMut for TrieDBMut<'a> { self.lookup(NibbleSlice::new(key), &self.root_handle) } - fn insert(&mut self, key: &[u8], value: &[u8]) -> super::Result> { if value.is_empty() { return self.remove(key) } diff --git a/util/plain_hasher/benches/bench.rs b/util/plain_hasher/benches/bench.rs index e7e8570abb..cfaa95eaa6 100644 --- a/util/plain_hasher/benches/bench.rs +++ b/util/plain_hasher/benches/bench.rs @@ -1,3 +1,19 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + #![feature(test)] extern crate test; diff --git a/util/plain_hasher/src/lib.rs b/util/plain_hasher/src/lib.rs index d08d4dd1ab..74e2225dc8 100644 --- a/util/plain_hasher/src/lib.rs +++ b/util/plain_hasher/src/lib.rs @@ -1,3 +1,19 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + #[macro_use] extern crate crunchy; extern crate ethereum_types; diff --git a/util/reactor/src/lib.rs b/util/reactor/src/lib.rs index 9c049b8f75..8fd37e7c88 100644 --- a/util/reactor/src/lib.rs +++ b/util/reactor/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -14,7 +14,6 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . - //! Tokio Core Reactor wrapper. extern crate futures; @@ -122,7 +121,6 @@ impl Remote { } } - /// Spawn a future to this event loop pub fn spawn(&self, r: R) where R: IntoFuture + Send + 'static, diff --git a/util/rlp/src/rlpin.rs b/util/rlp/src/rlpin.rs index a55b4f7907..23fdc452e7 100644 --- a/util/rlp/src/rlpin.rs +++ b/util/rlp/src/rlpin.rs @@ -281,7 +281,6 @@ impl<'a, 'view> Rlp<'a> where 'a: 'view { Ok(result) } - /// consumes slice prefix of length `len` fn consume(bytes: &'a [u8], len: usize) -> Result<&'a [u8], DecoderError> { match bytes.len() >= len { diff --git a/util/rlp/src/stream.rs b/util/rlp/src/stream.rs index 000b6e15bc..550ede0399 100644 --- a/util/rlp/src/stream.rs +++ b/util/rlp/src/stream.rs @@ -133,7 +133,6 @@ impl RlpStream { self } - /// Declare appending the list of unknown size, chainable. pub fn begin_unbounded_list(&mut self) -> &mut RlpStream { self.finished_list = false; @@ -206,7 +205,6 @@ impl RlpStream { base_size } - /// Returns current RLP size in bytes for the data pushed into the list. pub fn len<'a>(&'a self) -> usize { self.estimate_size(0) diff --git a/util/rlp_compress/src/lib.rs b/util/rlp_compress/src/lib.rs index b895e1ce1a..af5b09aac7 100644 --- a/util/rlp_compress/src/lib.rs +++ b/util/rlp_compress/src/lib.rs @@ -107,4 +107,3 @@ impl<'a> Compressor for Swapper<'a> { self.rlp_to_compressed.get(rlp).cloned() } } - diff --git a/util/rlp_compress/tests/compress.rs b/util/rlp_compress/tests/compress.rs index a01dbde358..9d23f8c670 100644 --- a/util/rlp_compress/tests/compress.rs +++ b/util/rlp_compress/tests/compress.rs @@ -1,3 +1,19 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + extern crate rlp_compress; use rlp_compress::{compress, decompress, Swapper, snapshot_swapper, blocks_swapper, Compressor, Decompressor}; diff --git a/util/rlp_derive/src/de.rs b/util/rlp_derive/src/de.rs index dac4e34cdb..fe0ccfba6f 100644 --- a/util/rlp_derive/src/de.rs +++ b/util/rlp_derive/src/de.rs @@ -1,3 +1,19 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + use {syn, quote}; struct ParseQuotes { @@ -28,7 +44,6 @@ pub fn impl_decodable(ast: &syn::DeriveInput) -> quote::Tokens { _ => panic!("#[derive(RlpDecodable)] is only defined for structs."), }; - let stmts: Vec<_> = body.fields.iter().enumerate().map(decodable_field_map).collect(); let name = &ast.ident; @@ -132,4 +147,3 @@ fn decodable_field(index: usize, field: &syn::Field, quotes: ParseQuotes) -> quo _ => panic!("rlp_derive not supported"), } } - diff --git a/util/rlp_derive/src/en.rs b/util/rlp_derive/src/en.rs index 484ac015e5..607255a96c 100644 --- a/util/rlp_derive/src/en.rs +++ b/util/rlp_derive/src/en.rs @@ -1,3 +1,19 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + use {syn, quote}; pub fn impl_encodable(ast: &syn::DeriveInput) -> quote::Tokens { @@ -104,4 +120,3 @@ fn encodable_field(index: usize, field: &syn::Field) -> quote::Tokens { _ => panic!("rlp_derive not supported"), } } - diff --git a/util/rlp_derive/src/lib.rs b/util/rlp_derive/src/lib.rs index 93f8d9619d..bc6bff1d5c 100644 --- a/util/rlp_derive/src/lib.rs +++ b/util/rlp_derive/src/lib.rs @@ -1,3 +1,19 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + extern crate proc_macro; extern crate syn; #[macro_use] diff --git a/util/rlp_derive/tests/rlp.rs b/util/rlp_derive/tests/rlp.rs index ba51309146..7115b87c96 100644 --- a/util/rlp_derive/tests/rlp.rs +++ b/util/rlp_derive/tests/rlp.rs @@ -1,3 +1,19 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + extern crate rlp; #[macro_use] extern crate rlp_derive; @@ -41,4 +57,3 @@ fn test_encode_foo_wrapper() { let decoded = decode(&expected).expect("decode failure"); assert_eq!(foo, decoded); } - diff --git a/util/stats/src/lib.rs b/util/stats/src/lib.rs index 74fda92726..8d107f4e9c 100644 --- a/util/stats/src/lib.rs +++ b/util/stats/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -130,7 +130,6 @@ impl Histogram } } - #[cfg(test)] mod tests { use super::*; diff --git a/util/stop-guard/src/lib.rs b/util/stop-guard/src/lib.rs index f208138ab6..208b57c6d9 100644 --- a/util/stop-guard/src/lib.rs +++ b/util/stop-guard/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/util/trace-time/src/lib.rs b/util/trace-time/src/lib.rs index e9566e7f94..4c3b0b2743 100644 --- a/util/trace-time/src/lib.rs +++ b/util/trace-time/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/util/trie-standardmap/src/lib.rs b/util/trie-standardmap/src/lib.rs index d7ee08ac46..51c8593ea4 100644 --- a/util/trie-standardmap/src/lib.rs +++ b/util/trie-standardmap/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/util/triehash/src/lib.rs b/util/triehash/src/lib.rs index 7f20d3915e..c78ed0ca1b 100644 --- a/util/triehash/src/lib.rs +++ b/util/triehash/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -283,7 +283,6 @@ fn hash256aux, B: AsRef<[u8]>>(input: &[(A, B)], pre_len: usize, }; } - #[test] fn test_nibbles() { let v = vec![0x31, 0x23, 0x45]; @@ -296,7 +295,6 @@ fn test_nibbles() { assert_eq!(as_nibbles(&v), e); } - #[cfg(test)] mod tests { use super::{trie_root, shared_prefix_len, hex_prefix_encode}; diff --git a/util/unexpected/src/lib.rs b/util/unexpected/src/lib.rs index 4cf8448bd4..77d4035a64 100644 --- a/util/unexpected/src/lib.rs +++ b/util/unexpected/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/util/using_queue/src/lib.rs b/util/using_queue/src/lib.rs index 03862e9c8a..42eb1cbe38 100644 --- a/util/using_queue/src/lib.rs +++ b/util/using_queue/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/util/version/build.rs b/util/version/build.rs index 47c0e128f2..a367296a5f 100644 --- a/util/version/build.rs +++ b/util/version/build.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/util/version/src/lib.rs b/util/version/src/lib.rs index 6c56bfb7e6..77fc71c70f 100644 --- a/util/version/src/lib.rs +++ b/util/version/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/whisper/src/lib.rs b/whisper/src/lib.rs index 85ab55e0f4..190169b2c2 100644 --- a/whisper/src/lib.rs +++ b/whisper/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/whisper/src/message.rs b/whisper/src/message.rs index d0de9af4b5..95c2112551 100644 --- a/whisper/src/message.rs +++ b/whisper/src/message.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/whisper/src/net/mod.rs b/whisper/src/net/mod.rs index 1115b17d4f..6ec3b08a54 100644 --- a/whisper/src/net/mod.rs +++ b/whisper/src/net/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/whisper/src/net/tests.rs b/whisper/src/net/tests.rs index 51c9c00ce2..15aba5c3ee 100644 --- a/whisper/src/net/tests.rs +++ b/whisper/src/net/tests.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/whisper/src/rpc/crypto.rs b/whisper/src/rpc/crypto.rs index 667656d6bf..a796a0613c 100644 --- a/whisper/src/rpc/crypto.rs +++ b/whisper/src/rpc/crypto.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/whisper/src/rpc/filter.rs b/whisper/src/rpc/filter.rs index 8d125174ed..d1b9c4c1cc 100644 --- a/whisper/src/rpc/filter.rs +++ b/whisper/src/rpc/filter.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/whisper/src/rpc/key_store.rs b/whisper/src/rpc/key_store.rs index 1fb4e264ac..a63ef8652c 100644 --- a/whisper/src/rpc/key_store.rs +++ b/whisper/src/rpc/key_store.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/whisper/src/rpc/mod.rs b/whisper/src/rpc/mod.rs index 7daa3f4559..7406d6421d 100644 --- a/whisper/src/rpc/mod.rs +++ b/whisper/src/rpc/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/whisper/src/rpc/payload.rs b/whisper/src/rpc/payload.rs index 75d24bd7cf..5884cdee98 100644 --- a/whisper/src/rpc/payload.rs +++ b/whisper/src/rpc/payload.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -184,7 +184,6 @@ pub fn decode(payload: &[u8]) -> Result { } }; - if next_slice(1)?[0] != STANDARD_PAYLOAD_VERSION { return Err("unknown payload version."); } diff --git a/whisper/src/rpc/types.rs b/whisper/src/rpc/types.rs index 9598f48bf8..3d132c73cc 100644 --- a/whisper/src/rpc/types.rs +++ b/whisper/src/rpc/types.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/windows/ptray/ptray.cpp b/windows/ptray/ptray.cpp index 8fc29880e9..8701daecb5 100644 --- a/windows/ptray/ptray.cpp +++ b/windows/ptray/ptray.cpp @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -358,4 +358,3 @@ void EnableAutostart(bool enable) { RegDeleteValue(hKey, L"Parity"); } } - -- GitLab From 8057e8df43e78328509c3a468592b8e798772f84 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Mon, 4 Jun 2018 10:26:30 +0100 Subject: [PATCH 096/152] Remove Result wrapper from AccountProvider in RPC impls (#8763) * Remove AccountProvider Result, it's always `Ok` * Remove unnecessary clones * Remove redundant `Ok` --- rpc/src/v1/impls/eth.rs | 11 +-- rpc/src/v1/impls/parity.rs | 23 ++---- rpc/src/v1/impls/parity_accounts.rs | 117 ++++++++++------------------ rpc/src/v1/impls/personal.rs | 17 ++-- rpc/src/v1/impls/secretstore.rs | 15 +--- rpc/src/v1/impls/signer.rs | 7 +- rpc/src/v1/impls/signing.rs | 9 +-- rpc/src/v1/impls/signing_unsafe.rs | 8 +- rpc/src/v1/tests/mocked/parity.rs | 4 +- rpc/src/v1/tests/mocked/personal.rs | 3 +- rpc/src/v1/tests/mocked/signer.rs | 3 +- rpc/src/v1/tests/mocked/signing.rs | 5 +- 12 files changed, 66 insertions(+), 156 deletions(-) diff --git a/rpc/src/v1/impls/eth.rs b/rpc/src/v1/impls/eth.rs index 38e36cf11c..8de5783aa3 100644 --- a/rpc/src/v1/impls/eth.rs +++ b/rpc/src/v1/impls/eth.rs @@ -170,12 +170,6 @@ impl EthClient`, errors if provider was not - /// set. - fn account_provider(&self) -> Result> { - Ok(self.accounts.clone()) - } - fn rich_block(&self, id: BlockNumberOrId, include_txs: bool) -> Result> { let client = &self.client; @@ -404,10 +398,9 @@ impl EthClient Result> { - let store = self.account_provider()?; - store + self.accounts .note_dapp_used(dapp.clone()) - .and_then(|_| store.dapp_addresses(dapp)) + .and_then(|_| self.accounts.dapp_addresses(dapp)) .map_err(|e| errors::account("Could not fetch accounts.", e)) } diff --git a/rpc/src/v1/impls/parity.rs b/rpc/src/v1/impls/parity.rs index e3ad5a3b1b..5707104212 100644 --- a/rpc/src/v1/impls/parity.rs +++ b/rpc/src/v1/impls/parity.rs @@ -105,12 +105,6 @@ impl ParityClient where eip86_transition, } } - - /// Attempt to get the `Arc`, errors if provider was not - /// set. - fn account_provider(&self) -> Result> { - Ok(self.accounts.clone()) - } } impl Parity for ParityClient where @@ -124,15 +118,14 @@ impl Parity for ParityClient where fn accounts_info(&self, dapp: Trailing) -> Result> { let dapp = dapp.unwrap_or_default(); - let store = self.account_provider()?; - let dapp_accounts = store + let dapp_accounts = self.accounts .note_dapp_used(dapp.clone().into()) - .and_then(|_| store.dapp_addresses(dapp.into())) + .and_then(|_| self.accounts.dapp_addresses(dapp.into())) .map_err(|e| errors::account("Could not fetch accounts.", e))? .into_iter().collect::>(); - let info = store.accounts_info().map_err(|e| errors::account("Could not fetch account info.", e))?; - let other = store.addresses_info(); + let info = self.accounts.accounts_info().map_err(|e| errors::account("Could not fetch account info.", e))?; + let other = self.accounts.addresses_info(); Ok(info .into_iter() @@ -144,8 +137,7 @@ impl Parity for ParityClient where } fn hardware_accounts_info(&self) -> Result> { - let store = self.account_provider()?; - let info = store.hardware_accounts_info().map_err(|e| errors::account("Could not fetch account info.", e))?; + let info = self.accounts.hardware_accounts_info().map_err(|e| errors::account("Could not fetch account info.", e))?; Ok(info .into_iter() .map(|(a, v)| (H160::from(a), HwAccountInfo { name: v.name, manufacturer: v.meta })) @@ -154,14 +146,13 @@ impl Parity for ParityClient where } fn locked_hardware_accounts_info(&self) -> Result> { - let store = self.account_provider()?; - Ok(store.locked_hardware_accounts().map_err(|e| errors::account("Error communicating with hardware wallet.", e))?) + self.accounts.locked_hardware_accounts().map_err(|e| errors::account("Error communicating with hardware wallet.", e)) } fn default_account(&self, meta: Self::Metadata) -> Result { let dapp_id = meta.dapp_id(); - Ok(self.account_provider()? + Ok(self.accounts .dapp_default_address(dapp_id.into()) .map(Into::into) .ok() diff --git a/rpc/src/v1/impls/parity_accounts.rs b/rpc/src/v1/impls/parity_accounts.rs index eb069cf27f..d7e1fd2546 100644 --- a/rpc/src/v1/impls/parity_accounts.rs +++ b/rpc/src/v1/impls/parity_accounts.rs @@ -40,19 +40,12 @@ impl ParityAccountsClient { accounts: store.clone(), } } - - /// Attempt to get the `Arc`, errors if provider was not - /// set. - fn account_provider(&self) -> Result> { - Ok(self.accounts.clone()) - } } impl ParityAccounts for ParityAccountsClient { fn all_accounts_info(&self) -> Result> { - let store = self.account_provider()?; - let info = store.accounts_info().map_err(|e| errors::account("Could not fetch account info.", e))?; - let other = store.addresses_info(); + let info = self.accounts.accounts_info().map_err(|e| errors::account("Could not fetch account info.", e))?; + let other = self.accounts.addresses_info(); let account_iter = info .into_iter() @@ -82,29 +75,23 @@ impl ParityAccounts for ParityAccountsClient { } fn new_account_from_phrase(&self, phrase: String, pass: String) -> Result { - let store = self.account_provider()?; - let brain = Brain::new(phrase).generate().unwrap(); - store.insert_account(brain.secret().clone(), &pass) + self.accounts.insert_account(brain.secret().clone(), &pass) .map(Into::into) .map_err(|e| errors::account("Could not create account.", e)) } fn new_account_from_wallet(&self, json: String, pass: String) -> Result { - let store = self.account_provider()?; - - store.import_presale(json.as_bytes(), &pass) - .or_else(|_| store.import_wallet(json.as_bytes(), &pass, true)) + self.accounts.import_presale(json.as_bytes(), &pass) + .or_else(|_| self.accounts.import_wallet(json.as_bytes(), &pass, true)) .map(Into::into) .map_err(|e| errors::account("Could not create account.", e)) } fn new_account_from_secret(&self, secret: RpcH256, pass: String) -> Result { - let store = self.account_provider()?; - let secret = Secret::from_unsafe_slice(&secret.0) .map_err(|e| errors::account("Could not create account.", e))?; - store.insert_account(secret, &pass) + self.accounts.insert_account(secret, &pass) .map(Into::into) .map_err(|e| errors::account("Could not create account.", e)) } @@ -112,14 +99,14 @@ impl ParityAccounts for ParityAccountsClient { fn test_password(&self, account: RpcH160, password: String) -> Result { let account: Address = account.into(); - self.account_provider()? + self.accounts .test_password(&account, &password) .map_err(|e| errors::account("Could not fetch account info.", e)) } fn change_password(&self, account: RpcH160, password: String, new_password: String) -> Result { let account: Address = account.into(); - self.account_provider()? + self.accounts .change_password(&account, password, new_password) .map(|_| true) .map_err(|e| errors::account("Could not fetch account info.", e)) @@ -127,181 +114,156 @@ impl ParityAccounts for ParityAccountsClient { fn kill_account(&self, account: RpcH160, password: String) -> Result { let account: Address = account.into(); - self.account_provider()? + self.accounts .kill_account(&account, &password) .map(|_| true) .map_err(|e| errors::account("Could not delete account.", e)) } fn remove_address(&self, addr: RpcH160) -> Result { - let store = self.account_provider()?; let addr: Address = addr.into(); - store.remove_address(addr); + self.accounts.remove_address(addr); Ok(true) } fn set_account_name(&self, addr: RpcH160, name: String) -> Result { - let store = self.account_provider()?; let addr: Address = addr.into(); - store.set_account_name(addr.clone(), name.clone()) - .unwrap_or_else(|_| store.set_address_name(addr, name)); + self.accounts.set_account_name(addr.clone(), name.clone()) + .unwrap_or_else(|_| self.accounts.set_address_name(addr, name)); Ok(true) } fn set_account_meta(&self, addr: RpcH160, meta: String) -> Result { - let store = self.account_provider()?; let addr: Address = addr.into(); - store.set_account_meta(addr.clone(), meta.clone()) - .unwrap_or_else(|_| store.set_address_meta(addr, meta)); + self.accounts.set_account_meta(addr.clone(), meta.clone()) + .unwrap_or_else(|_| self.accounts.set_address_meta(addr, meta)); Ok(true) } fn set_dapp_addresses(&self, dapp: DappId, addresses: Option>) -> Result { - let store = self.account_provider()?; - - store.set_dapp_addresses(dapp.into(), addresses.map(into_vec)) + self.accounts.set_dapp_addresses(dapp.into(), addresses.map(into_vec)) .map_err(|e| errors::account("Couldn't set dapp addresses.", e)) .map(|_| true) } fn dapp_addresses(&self, dapp: DappId) -> Result> { - let store = self.account_provider()?; - - store.dapp_addresses(dapp.into()) + self.accounts.dapp_addresses(dapp.into()) .map_err(|e| errors::account("Couldn't get dapp addresses.", e)) .map(into_vec) } fn set_dapp_default_address(&self, dapp: DappId, address: RpcH160) -> Result { - let store = self.account_provider()?; - - store.set_dapp_default_address(dapp.into(), address.into()) + self.accounts.set_dapp_default_address(dapp.into(), address.into()) .map_err(|e| errors::account("Couldn't set dapp default address.", e)) .map(|_| true) } fn dapp_default_address(&self, dapp: DappId) -> Result { - let store = self.account_provider()?; - - store.dapp_default_address(dapp.into()) + self.accounts.dapp_default_address(dapp.into()) .map_err(|e| errors::account("Couldn't get dapp default address.", e)) .map(Into::into) } fn set_new_dapps_addresses(&self, addresses: Option>) -> Result { - let store = self.account_provider()?; - - store + self.accounts .set_new_dapps_addresses(addresses.map(into_vec)) .map_err(|e| errors::account("Couldn't set dapps addresses.", e)) .map(|_| true) } fn new_dapps_addresses(&self) -> Result>> { - let store = self.account_provider()?; - - store.new_dapps_addresses() + self.accounts.new_dapps_addresses() .map_err(|e| errors::account("Couldn't get dapps addresses.", e)) .map(|accounts| accounts.map(into_vec)) } fn set_new_dapps_default_address(&self, address: RpcH160) -> Result { - let store = self.account_provider()?; - - store.set_new_dapps_default_address(address.into()) + self.accounts.set_new_dapps_default_address(address.into()) .map_err(|e| errors::account("Couldn't set new dapps default address.", e)) .map(|_| true) } fn new_dapps_default_address(&self) -> Result { - let store = self.account_provider()?; - - store.new_dapps_default_address() + self.accounts.new_dapps_default_address() .map_err(|e| errors::account("Couldn't get new dapps default address.", e)) .map(Into::into) } fn recent_dapps(&self) -> Result> { - let store = self.account_provider()?; - - store.recent_dapps() + self.accounts.recent_dapps() .map_err(|e| errors::account("Couldn't get recent dapps.", e)) .map(|map| map.into_iter().map(|(k, v)| (k.into(), v)).collect()) } fn import_geth_accounts(&self, addresses: Vec) -> Result> { - let store = self.account_provider()?; - - store + self.accounts .import_geth_accounts(into_vec(addresses), false) .map(into_vec) .map_err(|e| errors::account("Couldn't import Geth accounts", e)) } fn geth_accounts(&self) -> Result> { - let store = self.account_provider()?; - - Ok(into_vec(store.list_geth_accounts(false))) + Ok(into_vec(self.accounts.list_geth_accounts(false))) } fn create_vault(&self, name: String, password: String) -> Result { - self.account_provider()? + self.accounts .create_vault(&name, &password) .map_err(|e| errors::account("Could not create vault.", e)) .map(|_| true) } fn open_vault(&self, name: String, password: String) -> Result { - self.account_provider()? + self.accounts .open_vault(&name, &password) .map_err(|e| errors::account("Could not open vault.", e)) .map(|_| true) } fn close_vault(&self, name: String) -> Result { - self.account_provider()? + self.accounts .close_vault(&name) .map_err(|e| errors::account("Could not close vault.", e)) .map(|_| true) } fn list_vaults(&self) -> Result> { - self.account_provider()? + self.accounts .list_vaults() .map_err(|e| errors::account("Could not list vaults.", e)) } fn list_opened_vaults(&self) -> Result> { - self.account_provider()? + self.accounts .list_opened_vaults() .map_err(|e| errors::account("Could not list vaults.", e)) } fn change_vault_password(&self, name: String, new_password: String) -> Result { - self.account_provider()? + self.accounts .change_vault_password(&name, &new_password) .map_err(|e| errors::account("Could not change vault password.", e)) .map(|_| true) } fn change_vault(&self, address: RpcH160, new_vault: String) -> Result { - self.account_provider()? + self.accounts .change_vault(address.into(), &new_vault) .map_err(|e| errors::account("Could not change vault.", e)) .map(|_| true) } fn get_vault_meta(&self, name: String) -> Result { - self.account_provider()? + self.accounts .get_vault_meta(&name) .map_err(|e| errors::account("Could not get vault metadata.", e)) } fn set_vault_meta(&self, name: String, meta: String) -> Result { - self.account_provider()? + self.accounts .set_vault_meta(&name, &meta) .map_err(|e| errors::account("Could not update vault metadata.", e)) .map(|_| true) @@ -309,7 +271,7 @@ impl ParityAccounts for ParityAccountsClient { fn derive_key_index(&self, addr: RpcH160, password: String, derivation: DeriveHierarchical, save_as_account: bool) -> Result { let addr: Address = addr.into(); - self.account_provider()? + self.accounts .derive_account( &addr, Some(password), @@ -322,7 +284,7 @@ impl ParityAccounts for ParityAccountsClient { fn derive_key_hash(&self, addr: RpcH160, password: String, derivation: DeriveHash, save_as_account: bool) -> Result { let addr: Address = addr.into(); - self.account_provider()? + self.accounts .derive_account( &addr, Some(password), @@ -335,7 +297,7 @@ impl ParityAccounts for ParityAccountsClient { fn export_account(&self, addr: RpcH160, password: String) -> Result { let addr = addr.into(); - self.account_provider()? + self.accounts .export_account( &addr, password, @@ -345,7 +307,7 @@ impl ParityAccounts for ParityAccountsClient { } fn sign_message(&self, addr: RpcH160, password: String, message: RpcH256) -> Result { - self.account_provider()? + self.accounts .sign( addr.into(), Some(password), @@ -356,8 +318,7 @@ impl ParityAccounts for ParityAccountsClient { } fn hardware_pin_matrix_ack(&self, path: String, pin: String) -> Result { - let store = self.account_provider()?; - Ok(store.hardware_pin_matrix_ack(&path, &pin).map_err(|e| errors::account("Error communicating with hardware wallet.", e))?) + self.accounts.hardware_pin_matrix_ack(&path, &pin).map_err(|e| errors::account("Error communicating with hardware wallet.", e)) } } diff --git a/rpc/src/v1/impls/personal.rs b/rpc/src/v1/impls/personal.rs index 045496fc95..3a8d13c82e 100644 --- a/rpc/src/v1/impls/personal.rs +++ b/rpc/src/v1/impls/personal.rs @@ -55,16 +55,12 @@ impl PersonalClient { allow_perm_unlock, } } - - fn account_provider(&self) -> Result> { - Ok(self.accounts.clone()) - } } impl PersonalClient { fn do_sign_transaction(&self, meta: Metadata, request: TransactionRequest, password: String) -> BoxFuture<(PendingTransaction, D)> { let dispatcher = self.dispatcher.clone(); - let accounts = try_bf!(self.account_provider()); + let accounts = self.accounts.clone(); let default = match request.from.as_ref() { Some(account) => Ok(account.clone().into()), @@ -94,22 +90,19 @@ impl Personal for PersonalClient { type Metadata = Metadata; fn accounts(&self) -> Result> { - let store = self.account_provider()?; - let accounts = store.accounts().map_err(|e| errors::account("Could not fetch accounts.", e))?; + let accounts = self.accounts.accounts().map_err(|e| errors::account("Could not fetch accounts.", e))?; Ok(accounts.into_iter().map(Into::into).collect::>()) } fn new_account(&self, pass: String) -> Result { - let store = self.account_provider()?; - - store.new_account(&pass) + self.accounts.new_account(&pass) .map(Into::into) .map_err(|e| errors::account("Could not create account.", e)) } fn unlock_account(&self, account: RpcH160, account_pass: String, duration: Option) -> Result { let account: Address = account.into(); - let store = self.account_provider()?; + let store = self.accounts.clone(); let duration = match duration { None => None, Some(duration) => { @@ -141,7 +134,7 @@ impl Personal for PersonalClient { fn sign(&self, data: RpcBytes, account: RpcH160, password: String) -> BoxFuture { let dispatcher = self.dispatcher.clone(); - let accounts = try_bf!(self.account_provider()); + let accounts = self.accounts.clone(); let payload = RpcConfirmationPayload::EthSignMessage((account.clone(), data).into()); diff --git a/rpc/src/v1/impls/secretstore.rs b/rpc/src/v1/impls/secretstore.rs index 52404a58d0..771599eca3 100644 --- a/rpc/src/v1/impls/secretstore.rs +++ b/rpc/src/v1/impls/secretstore.rs @@ -43,16 +43,9 @@ impl SecretStoreClient { } } - /// Attempt to get the `Arc`, errors if provider was not - /// set. - fn account_provider(&self) -> Result> { - Ok(self.accounts.clone()) - } - /// Decrypt public key using account' private key fn decrypt_key(&self, address: H160, password: String, key: Bytes) -> Result> { - let store = self.account_provider()?; - store.decrypt(address.into(), Some(password), &DEFAULT_MAC, &key.0) + self.accounts.decrypt(address.into(), Some(password), &DEFAULT_MAC, &key.0) .map_err(|e| errors::account("Could not decrypt key.", e)) } @@ -65,8 +58,7 @@ impl SecretStoreClient { impl SecretStore for SecretStoreClient { fn generate_document_key(&self, address: H160, password: String, server_key_public: H512) -> Result { - let store = self.account_provider()?; - let account_public = store.account_public(address.into(), &password) + let account_public = self.accounts.account_public(address.into(), &password) .map_err(|e| errors::account("Could not read account public.", e))?; generate_document_key(account_public, server_key_public.into()) } @@ -96,8 +88,7 @@ impl SecretStore for SecretStoreClient { } fn sign_raw_hash(&self, address: H160, password: String, raw_hash: H256) -> Result { - let store = self.account_provider()?; - store + self.accounts .sign(address.into(), Some(password), raw_hash.into()) .map(|s| Bytes::new((*s).to_vec())) .map_err(|e| errors::account("Could not sign raw hash.", e)) diff --git a/rpc/src/v1/impls/signer.rs b/rpc/src/v1/impls/signer.rs index 14fd6a33a4..e679388cbf 100644 --- a/rpc/src/v1/impls/signer.rs +++ b/rpc/src/v1/impls/signer.rs @@ -77,17 +77,12 @@ impl SignerClient { } } - fn account_provider(&self) -> Result> { - Ok(self.accounts.clone()) - } - fn confirm_internal(&self, id: U256, modification: TransactionModification, f: F) -> BoxFuture> where F: FnOnce(D, Arc, ConfirmationPayload) -> T, T: IntoFuture, Error=Error>, T::Future: Send + 'static { let id = id.into(); - let accounts = try_bf!(self.account_provider()); let dispatcher = self.dispatcher.clone(); let signer = self.signer.clone(); @@ -110,7 +105,7 @@ impl SignerClient { request.condition = condition.clone().map(Into::into); } } - let fut = f(dispatcher, accounts, payload); + let fut = f(dispatcher, self.accounts.clone(), payload); Either::A(fut.into_future().then(move |result| { // Execute if let Ok(ref response) = result { diff --git a/rpc/src/v1/impls/signing.rs b/rpc/src/v1/impls/signing.rs index 6229a54c84..b22bbc80dd 100644 --- a/rpc/src/v1/impls/signing.rs +++ b/rpc/src/v1/impls/signing.rs @@ -108,12 +108,8 @@ impl SigningQueueClient { } } - fn account_provider(&self) -> Result> { - Ok(self.accounts.clone()) - } - fn dispatch(&self, payload: RpcConfirmationPayload, default_account: DefaultAccount, origin: Origin) -> BoxFuture { - let accounts = try_bf!(self.account_provider()); + let accounts = self.accounts.clone(); let default_account = match default_account { DefaultAccount::Provided(acc) => acc, DefaultAccount::ForDapp(dapp) => accounts.dapp_default_address(dapp).ok().unwrap_or_default(), @@ -143,8 +139,7 @@ impl ParitySigning for SigningQueueClient { type Metadata = Metadata; fn compose_transaction(&self, meta: Metadata, transaction: RpcTransactionRequest) -> BoxFuture { - let accounts = try_bf!(self.account_provider()); - let default_account = accounts.dapp_default_address(meta.dapp_id().into()).ok().unwrap_or_default(); + let default_account = self.accounts.dapp_default_address(meta.dapp_id().into()).ok().unwrap_or_default(); Box::new(self.dispatcher.fill_optional_fields(transaction.into(), default_account, true).map(Into::into)) } diff --git a/rpc/src/v1/impls/signing_unsafe.rs b/rpc/src/v1/impls/signing_unsafe.rs index f14d1e028d..6016cbbfc0 100644 --- a/rpc/src/v1/impls/signing_unsafe.rs +++ b/rpc/src/v1/impls/signing_unsafe.rs @@ -51,12 +51,8 @@ impl SigningUnsafeClient { } } - fn account_provider(&self) -> Result> { - Ok(self.accounts.clone()) - } - fn handle(&self, payload: RpcConfirmationPayload, account: DefaultAccount) -> BoxFuture { - let accounts = try_bf!(self.account_provider()); + let accounts = self.accounts.clone(); let default = match account { DefaultAccount::Provided(acc) => acc, DefaultAccount::ForDapp(dapp) => accounts.dapp_default_address(dapp).ok().unwrap_or_default(), @@ -107,7 +103,7 @@ impl ParitySigning for SigningUnsafeClient { type Metadata = Metadata; fn compose_transaction(&self, meta: Metadata, transaction: RpcTransactionRequest) -> BoxFuture { - let accounts = try_bf!(self.account_provider()); + let accounts = self.accounts.clone(); let default_account = accounts.dapp_default_address(meta.dapp_id().into()).ok().unwrap_or_default(); Box::new(self.dispatcher.fill_optional_fields(transaction.into(), default_account, true).map(Into::into)) } diff --git a/rpc/src/v1/tests/mocked/parity.rs b/rpc/src/v1/tests/mocked/parity.rs index c9dd50a3c6..4bb653c4d2 100644 --- a/rpc/src/v1/tests/mocked/parity.rs +++ b/rpc/src/v1/tests/mocked/parity.rs @@ -81,8 +81,6 @@ impl Dependencies { } pub fn client(&self, signer: Option>) -> TestParityClient { - let opt_accounts = self.accounts.clone(); - ParityClient::new( self.client.clone(), self.miner.clone(), @@ -90,7 +88,7 @@ impl Dependencies { self.updater.clone(), self.network.clone(), self.health.clone(), - opt_accounts.clone(), + self.accounts.clone(), self.logger.clone(), self.settings.clone(), signer, diff --git a/rpc/src/v1/tests/mocked/personal.rs b/rpc/src/v1/tests/mocked/personal.rs index 131a865da7..1e445c67a0 100644 --- a/rpc/src/v1/tests/mocked/personal.rs +++ b/rpc/src/v1/tests/mocked/personal.rs @@ -52,13 +52,12 @@ fn miner_service() -> Arc { fn setup() -> PersonalTester { let accounts = accounts_provider(); - let opt_accounts = accounts.clone(); let client = blockchain_client(); let miner = miner_service(); let reservations = Arc::new(Mutex::new(nonce::Reservations::new())); let dispatcher = FullDispatcher::new(client, miner.clone(), reservations, 50); - let personal = PersonalClient::new(&opt_accounts, dispatcher, false); + let personal = PersonalClient::new(&accounts, dispatcher, false); let mut io = IoHandler::default(); io.extend_with(personal.to_delegate()); diff --git a/rpc/src/v1/tests/mocked/signer.rs b/rpc/src/v1/tests/mocked/signer.rs index 8bbb590c06..b935818422 100644 --- a/rpc/src/v1/tests/mocked/signer.rs +++ b/rpc/src/v1/tests/mocked/signer.rs @@ -58,7 +58,6 @@ fn miner_service() -> Arc { fn signer_tester() -> SignerTester { let signer = Arc::new(SignerService::new_test(false)); let accounts = accounts_provider(); - let opt_accounts = accounts.clone(); let client = blockchain_client(); let miner = miner_service(); let reservations = Arc::new(Mutex::new(nonce::Reservations::new())); @@ -66,7 +65,7 @@ fn signer_tester() -> SignerTester { let dispatcher = FullDispatcher::new(client, miner.clone(), reservations, 50); let mut io = IoHandler::default(); - io.extend_with(SignerClient::new(&opt_accounts, dispatcher, &signer, event_loop.remote()).to_delegate()); + io.extend_with(SignerClient::new(&accounts, dispatcher, &signer, event_loop.remote()).to_delegate()); SignerTester { signer: signer, diff --git a/rpc/src/v1/tests/mocked/signing.rs b/rpc/src/v1/tests/mocked/signing.rs index 2dc80f066c..ba9fa6d4b6 100644 --- a/rpc/src/v1/tests/mocked/signing.rs +++ b/rpc/src/v1/tests/mocked/signing.rs @@ -56,7 +56,6 @@ impl Default for SigningTester { let client = Arc::new(TestBlockChainClient::default()); let miner = Arc::new(TestMinerService::default()); let accounts = Arc::new(AccountProvider::transient_provider()); - let opt_accounts = accounts.clone(); let reservations = Arc::new(Mutex::new(nonce::Reservations::new())); let mut io = IoHandler::default(); @@ -64,9 +63,9 @@ impl Default for SigningTester { let remote = Remote::new_thread_per_future(); - let rpc = SigningQueueClient::new(&signer, dispatcher.clone(), remote.clone(), &opt_accounts); + let rpc = SigningQueueClient::new(&signer, dispatcher.clone(), remote.clone(), &accounts); io.extend_with(EthSigning::to_delegate(rpc)); - let rpc = SigningQueueClient::new(&signer, dispatcher, remote, &opt_accounts); + let rpc = SigningQueueClient::new(&signer, dispatcher, remote, &accounts); io.extend_with(ParitySigning::to_delegate(rpc)); SigningTester { -- GitLab From e2a90ce159c751fdc548610749388a3c3a3cd9ad Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Mon, 4 Jun 2018 21:58:44 +0800 Subject: [PATCH 097/152] Conditionally compile ethcore public test helpers (#8743) * Mark test helpers and test-only specs as cfg(test) * Use test-probe to conditionally compile test helpers * Remove test probe and directly use features tag --- ethcore/Cargo.toml | 2 ++ ethcore/private-tx/Cargo.toml | 3 +++ ethcore/src/client/mod.rs | 4 ++++ ethcore/src/lib.rs | 4 ++-- ethcore/src/spec/spec.rs | 25 +++++++++++++++++++------ ethcore/sync/Cargo.toml | 1 + 6 files changed, 31 insertions(+), 8 deletions(-) diff --git a/ethcore/Cargo.toml b/ethcore/Cargo.toml index 71c84a293f..2b6ab9ebc3 100644 --- a/ethcore/Cargo.toml +++ b/ethcore/Cargo.toml @@ -89,3 +89,5 @@ json-tests = ["ethcore-transaction/json-tests"] test-heavy = [] # Compile benches benches = [] +# Compile test helpers +test-helpers = [] diff --git a/ethcore/private-tx/Cargo.toml b/ethcore/private-tx/Cargo.toml index 8283ab314a..441c9882e2 100644 --- a/ethcore/private-tx/Cargo.toml +++ b/ethcore/private-tx/Cargo.toml @@ -35,3 +35,6 @@ serde_derive = "1.0" serde_json = "1.0" tiny-keccak = "1.4" url = "1" + +[dev-dependencies] +ethcore = { path = "..", features = ["test-helpers"] } diff --git a/ethcore/src/client/mod.rs b/ethcore/src/client/mod.rs index 6e12c03052..3691768dcf 100644 --- a/ethcore/src/client/mod.rs +++ b/ethcore/src/client/mod.rs @@ -20,16 +20,20 @@ mod ancient_import; mod client; mod config; mod error; +#[cfg(any(test, feature="test-helpers"))] mod evm_test_client; mod io_message; +#[cfg(any(test, feature="test-helpers"))] mod test_client; mod trace; pub use self::client::*; pub use self::config::{Mode, ClientConfig, DatabaseCompactionProfile, BlockChainConfig, VMType}; pub use self::error::Error; +#[cfg(any(test, feature="test-helpers"))] pub use self::evm_test_client::{EvmTestClient, EvmTestError, TransactResult}; pub use self::io_message::ClientIoMessage; +#[cfg(any(test, feature="test-helpers"))] pub use self::test_client::{TestBlockChainClient, EachBlockWith}; pub use self::chain_notify::{ChainNotify, ChainRoute, ChainRouteType, ChainMessageType}; pub use self::traits::{ diff --git a/ethcore/src/lib.rs b/ethcore/src/lib.rs index 00113f7303..e89b0dfff9 100644 --- a/ethcore/src/lib.rs +++ b/ethcore/src/lib.rs @@ -157,8 +157,6 @@ pub mod snapshot; pub mod spec; pub mod state; pub mod state_db; -// Test helpers made public for usage outside ethcore -pub mod test_helpers; pub mod trace; pub mod verification; @@ -177,6 +175,8 @@ mod tests; #[cfg(test)] #[cfg(feature="json-tests")] mod json_tests; +#[cfg(any(test, feature="test-helpers"))] +pub mod test_helpers; #[cfg(test)] mod test_helpers_internal; diff --git a/ethcore/src/spec/spec.rs b/ethcore/src/spec/spec.rs index a8ab757549..784aa2a4e5 100644 --- a/ethcore/src/spec/spec.rs +++ b/ethcore/src/spec/spec.rs @@ -515,6 +515,7 @@ macro_rules! load_bundled { }; } +#[cfg(any(test, feature="test-helpers"))] macro_rules! load_machine_bundled { ($e:expr) => { Spec::load_machine( @@ -838,38 +839,44 @@ impl Spec { self.engine.genesis_epoch_data(&genesis, &call) } + /// Create a new Spec with InstantSeal consensus which does internal sealing (not requiring + /// work). + pub fn new_instant() -> Spec { + load_bundled!("instant_seal") + } + /// Create a new Spec which conforms to the Frontier-era Morden chain except that it's a /// NullEngine consensus. + #[cfg(any(test, feature="test-helpers"))] pub fn new_test() -> Spec { load_bundled!("null_morden") } /// Create the EthereumMachine corresponding to Spec::new_test. + #[cfg(any(test, feature="test-helpers"))] pub fn new_test_machine() -> EthereumMachine { load_machine_bundled!("null_morden") } /// Create a new Spec which conforms to the Frontier-era Morden chain except that it's a NullEngine consensus with applying reward on block close. + #[cfg(any(test, feature="test-helpers"))] pub fn new_test_with_reward() -> Spec { load_bundled!("null_morden_with_reward") } /// Create a new Spec which is a NullEngine consensus with a premine of address whose /// secret is keccak(''). + #[cfg(any(test, feature="test-helpers"))] pub fn new_null() -> Spec { load_bundled!("null") } /// Create a new Spec which constructs a contract at address 5 with storage at 0 equal to 1. + #[cfg(any(test, feature="test-helpers"))] pub fn new_test_constructor() -> Spec { load_bundled!("constructor") } - /// Create a new Spec with InstantSeal consensus which does internal sealing (not requiring - /// work). - pub fn new_instant() -> Spec { - load_bundled!("instant_seal") - } - /// Create a new Spec with AuthorityRound consensus which does internal sealing (not /// requiring work). /// Accounts with secrets keccak("0") and keccak("1") are the validators. + #[cfg(any(test, feature="test-helpers"))] pub fn new_test_round() -> Self { load_bundled!("authority_round") } @@ -877,6 +884,7 @@ impl Spec { /// Create a new Spec with AuthorityRound consensus which does internal sealing (not /// requiring work) with empty step messages enabled. /// Accounts with secrets keccak("0") and keccak("1") are the validators. + #[cfg(any(test, feature="test-helpers"))] pub fn new_test_round_empty_steps() -> Self { load_bundled!("authority_round_empty_steps") } @@ -884,6 +892,7 @@ impl Spec { /// Create a new Spec with AuthorityRound consensus (with empty steps) using a block reward /// contract. The contract source code can be found at: /// https://github.com/parity-contracts/block-reward/blob/daf7d44383b6cdb11cb6b953b018648e2b027cfb/contracts/ExampleBlockReward.sol + #[cfg(any(test, feature="test-helpers"))] pub fn new_test_round_block_reward_contract() -> Self { load_bundled!("authority_round_block_reward_contract") } @@ -891,6 +900,7 @@ impl Spec { /// Create a new Spec with Tendermint consensus which does internal sealing (not requiring /// work). /// Account keccak("0") and keccak("1") are a authorities. + #[cfg(any(test, feature="test-helpers"))] pub fn new_test_tendermint() -> Self { load_bundled!("tendermint") } @@ -903,6 +913,7 @@ impl Spec { /// "0xbfc708a000000000000000000000000082a978b3f5962a5b0957d9ee9eef472ee55b42f1" and added /// back in using /// "0x4d238c8e00000000000000000000000082a978b3f5962a5b0957d9ee9eef472ee55b42f1". + #[cfg(any(test, feature="test-helpers"))] pub fn new_validator_safe_contract() -> Self { load_bundled!("validator_safe_contract") } @@ -910,6 +921,7 @@ impl Spec { /// The same as the `safeContract`, but allows reporting and uses AuthorityRound. /// Account is marked with `reportBenign` it can be checked as disliked with "0xd8f2e0bf". /// Validator can be removed with `reportMalicious`. + #[cfg(any(test, feature="test-helpers"))] pub fn new_validator_contract() -> Self { load_bundled!("validator_contract") } @@ -918,6 +930,7 @@ impl Spec { /// height. /// Account with secrets keccak("0") is the validator for block 1 and with keccak("1") /// onwards. + #[cfg(any(test, feature="test-helpers"))] pub fn new_validator_multi() -> Self { load_bundled!("validator_multi") } diff --git a/ethcore/sync/Cargo.toml b/ethcore/sync/Cargo.toml index cf163cc7bd..66ee566215 100644 --- a/ethcore/sync/Cargo.toml +++ b/ethcore/sync/Cargo.toml @@ -38,3 +38,4 @@ ethcore-io = { path = "../../util/io", features = ["mio"] } ethkey = { path = "../../ethkey" } kvdb-memorydb = { path = "../../util/kvdb-memorydb" } ethcore-private-tx = { path = "../private-tx" } +ethcore = { path = "..", features = ["test-helpers"] } -- GitLab From b3ea766bd5a77e1d3491db2b6f48c3ded2dd5fcb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Silva?= Date: Tue, 5 Jun 2018 08:58:09 +0100 Subject: [PATCH 098/152] rpc: fix address formatting in TransactionRequest Display (#8786) * rpc: fix address formatting in TransactionRequest Display * rpc: use unwrap_or_else when no to address provided --- rpc/src/v1/types/transaction_request.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/rpc/src/v1/types/transaction_request.rs b/rpc/src/v1/types/transaction_request.rs index 7fed6f681a..4fa47b5acd 100644 --- a/rpc/src/v1/types/transaction_request.rs +++ b/rpc/src/v1/types/transaction_request.rs @@ -69,14 +69,20 @@ impl fmt::Display for TransactionRequest { f, "{} ETH from {} to 0x{:?}", Colour::White.bold().paint(format_ether(eth)), - Colour::White.bold().paint(format!("0x{:?}", self.from)), + Colour::White.bold().paint( + self.from.as_ref() + .map(|f| format!("0x{:?}", f)) + .unwrap_or_else(|| "?".to_string())), to ), None => write!( f, "{} ETH from {} for contract creation", Colour::White.bold().paint(format_ether(eth)), - Colour::White.bold().paint(format!("0x{:?}", self.from)), + Colour::White.bold().paint( + self.from.as_ref() + .map(|f| format!("0x{:?}", f)) + .unwrap_or_else(|| "?".to_string())), ), } } -- GitLab From 6ecc63002b5357ed16955b4f28f714cec62a9023 Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Tue, 5 Jun 2018 17:28:35 +0800 Subject: [PATCH 099/152] Have space between feature cfg flag (#8791) --- dapps/js-glue/src/js.rs | 4 ++-- ethcore/evm/src/lib.rs | 2 +- ethcore/src/client/mod.rs | 8 ++++---- ethcore/src/lib.rs | 6 +++--- ethcore/src/spec/spec.rs | 26 +++++++++++++------------- parity/lib.rs | 2 +- parity/secretstore.rs | 2 +- 7 files changed, 25 insertions(+), 25 deletions(-) diff --git a/dapps/js-glue/src/js.rs b/dapps/js-glue/src/js.rs index f89fcefc76..906b238ec7 100644 --- a/dapps/js-glue/src/js.rs +++ b/dapps/js-glue/src/js.rs @@ -14,8 +14,8 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -#![cfg_attr(feature="use-precompiled-js", allow(dead_code))] -#![cfg_attr(feature="use-precompiled-js", allow(unused_imports))] +#![cfg_attr(feature = "use-precompiled-js", allow(dead_code))] +#![cfg_attr(feature = "use-precompiled-js", allow(unused_imports))] use std::fmt; use std::process::Command; diff --git a/ethcore/evm/src/lib.rs b/ethcore/evm/src/lib.rs index 1b5610cef5..6eca25f42f 100644 --- a/ethcore/evm/src/lib.rs +++ b/ethcore/evm/src/lib.rs @@ -43,7 +43,7 @@ mod instructions; #[cfg(test)] mod tests; -#[cfg(all(feature="benches", test))] +#[cfg(all(feature = "benches", test))] mod benches; pub use vm::{ diff --git a/ethcore/src/client/mod.rs b/ethcore/src/client/mod.rs index 3691768dcf..8c5abf3f5d 100644 --- a/ethcore/src/client/mod.rs +++ b/ethcore/src/client/mod.rs @@ -20,20 +20,20 @@ mod ancient_import; mod client; mod config; mod error; -#[cfg(any(test, feature="test-helpers"))] +#[cfg(any(test, feature = "test-helpers"))] mod evm_test_client; mod io_message; -#[cfg(any(test, feature="test-helpers"))] +#[cfg(any(test, feature = "test-helpers"))] mod test_client; mod trace; pub use self::client::*; pub use self::config::{Mode, ClientConfig, DatabaseCompactionProfile, BlockChainConfig, VMType}; pub use self::error::Error; -#[cfg(any(test, feature="test-helpers"))] +#[cfg(any(test, feature = "test-helpers"))] pub use self::evm_test_client::{EvmTestClient, EvmTestError, TransactResult}; pub use self::io_message::ClientIoMessage; -#[cfg(any(test, feature="test-helpers"))] +#[cfg(any(test, feature = "test-helpers"))] pub use self::test_client::{TestBlockChainClient, EachBlockWith}; pub use self::chain_notify::{ChainNotify, ChainRoute, ChainRouteType, ChainMessageType}; pub use self::traits::{ diff --git a/ethcore/src/lib.rs b/ethcore/src/lib.rs index e89b0dfff9..51e75d4b40 100644 --- a/ethcore/src/lib.rs +++ b/ethcore/src/lib.rs @@ -15,7 +15,7 @@ // along with Parity. If not, see . #![warn(missing_docs)] -#![cfg_attr(feature="benches", feature(test))] +#![cfg_attr(feature = "benches", feature(test))] //! Ethcore library //! @@ -173,9 +173,9 @@ mod tx_filter; #[cfg(test)] mod tests; #[cfg(test)] -#[cfg(feature="json-tests")] +#[cfg(feature = "json-tests")] mod json_tests; -#[cfg(any(test, feature="test-helpers"))] +#[cfg(any(test, feature = "test-helpers"))] pub mod test_helpers; #[cfg(test)] mod test_helpers_internal; diff --git a/ethcore/src/spec/spec.rs b/ethcore/src/spec/spec.rs index 784aa2a4e5..6f785fe7fb 100644 --- a/ethcore/src/spec/spec.rs +++ b/ethcore/src/spec/spec.rs @@ -515,7 +515,7 @@ macro_rules! load_bundled { }; } -#[cfg(any(test, feature="test-helpers"))] +#[cfg(any(test, feature = "test-helpers"))] macro_rules! load_machine_bundled { ($e:expr) => { Spec::load_machine( @@ -847,28 +847,28 @@ impl Spec { /// Create a new Spec which conforms to the Frontier-era Morden chain except that it's a /// NullEngine consensus. - #[cfg(any(test, feature="test-helpers"))] + #[cfg(any(test, feature = "test-helpers"))] pub fn new_test() -> Spec { load_bundled!("null_morden") } /// Create the EthereumMachine corresponding to Spec::new_test. - #[cfg(any(test, feature="test-helpers"))] + #[cfg(any(test, feature = "test-helpers"))] pub fn new_test_machine() -> EthereumMachine { load_machine_bundled!("null_morden") } /// Create a new Spec which conforms to the Frontier-era Morden chain except that it's a NullEngine consensus with applying reward on block close. - #[cfg(any(test, feature="test-helpers"))] + #[cfg(any(test, feature = "test-helpers"))] pub fn new_test_with_reward() -> Spec { load_bundled!("null_morden_with_reward") } /// Create a new Spec which is a NullEngine consensus with a premine of address whose /// secret is keccak(''). - #[cfg(any(test, feature="test-helpers"))] + #[cfg(any(test, feature = "test-helpers"))] pub fn new_null() -> Spec { load_bundled!("null") } /// Create a new Spec which constructs a contract at address 5 with storage at 0 equal to 1. - #[cfg(any(test, feature="test-helpers"))] + #[cfg(any(test, feature = "test-helpers"))] pub fn new_test_constructor() -> Spec { load_bundled!("constructor") } @@ -876,7 +876,7 @@ impl Spec { /// Create a new Spec with AuthorityRound consensus which does internal sealing (not /// requiring work). /// Accounts with secrets keccak("0") and keccak("1") are the validators. - #[cfg(any(test, feature="test-helpers"))] + #[cfg(any(test, feature = "test-helpers"))] pub fn new_test_round() -> Self { load_bundled!("authority_round") } @@ -884,7 +884,7 @@ impl Spec { /// Create a new Spec with AuthorityRound consensus which does internal sealing (not /// requiring work) with empty step messages enabled. /// Accounts with secrets keccak("0") and keccak("1") are the validators. - #[cfg(any(test, feature="test-helpers"))] + #[cfg(any(test, feature = "test-helpers"))] pub fn new_test_round_empty_steps() -> Self { load_bundled!("authority_round_empty_steps") } @@ -892,7 +892,7 @@ impl Spec { /// Create a new Spec with AuthorityRound consensus (with empty steps) using a block reward /// contract. The contract source code can be found at: /// https://github.com/parity-contracts/block-reward/blob/daf7d44383b6cdb11cb6b953b018648e2b027cfb/contracts/ExampleBlockReward.sol - #[cfg(any(test, feature="test-helpers"))] + #[cfg(any(test, feature = "test-helpers"))] pub fn new_test_round_block_reward_contract() -> Self { load_bundled!("authority_round_block_reward_contract") } @@ -900,7 +900,7 @@ impl Spec { /// Create a new Spec with Tendermint consensus which does internal sealing (not requiring /// work). /// Account keccak("0") and keccak("1") are a authorities. - #[cfg(any(test, feature="test-helpers"))] + #[cfg(any(test, feature = "test-helpers"))] pub fn new_test_tendermint() -> Self { load_bundled!("tendermint") } @@ -913,7 +913,7 @@ impl Spec { /// "0xbfc708a000000000000000000000000082a978b3f5962a5b0957d9ee9eef472ee55b42f1" and added /// back in using /// "0x4d238c8e00000000000000000000000082a978b3f5962a5b0957d9ee9eef472ee55b42f1". - #[cfg(any(test, feature="test-helpers"))] + #[cfg(any(test, feature = "test-helpers"))] pub fn new_validator_safe_contract() -> Self { load_bundled!("validator_safe_contract") } @@ -921,7 +921,7 @@ impl Spec { /// The same as the `safeContract`, but allows reporting and uses AuthorityRound. /// Account is marked with `reportBenign` it can be checked as disliked with "0xd8f2e0bf". /// Validator can be removed with `reportMalicious`. - #[cfg(any(test, feature="test-helpers"))] + #[cfg(any(test, feature = "test-helpers"))] pub fn new_validator_contract() -> Self { load_bundled!("validator_contract") } @@ -930,7 +930,7 @@ impl Spec { /// height. /// Account with secrets keccak("0") is the validator for block 1 and with keccak("1") /// onwards. - #[cfg(any(test, feature="test-helpers"))] + #[cfg(any(test, feature = "test-helpers"))] pub fn new_validator_multi() -> Self { load_bundled!("validator_multi") } diff --git a/parity/lib.rs b/parity/lib.rs index 6ef332da65..c768722552 100644 --- a/parity/lib.rs +++ b/parity/lib.rs @@ -76,7 +76,7 @@ extern crate registrar; #[macro_use] extern crate log as rlog; -#[cfg(feature="secretstore")] +#[cfg(feature = "secretstore")] extern crate ethcore_secretstore; #[cfg(feature = "dapps")] diff --git a/parity/secretstore.rs b/parity/secretstore.rs index 3b4a4e468c..0723a1d078 100644 --- a/parity/secretstore.rs +++ b/parity/secretstore.rs @@ -111,7 +111,7 @@ mod server { } } -#[cfg(feature="secretstore")] +#[cfg(feature = "secretstore")] mod server { use std::sync::Arc; use ethcore_secretstore; -- GitLab From 5d6a0d4dae8b804ea9af07f6ade0320448c4d2e6 Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Tue, 5 Jun 2018 20:40:50 +0800 Subject: [PATCH 100/152] Fix evmbin compilation (#8795) * Fix evmbin compilation * Move features declaration to dependencies --- evmbin/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evmbin/Cargo.toml b/evmbin/Cargo.toml index c3ef5847d4..51865091a9 100644 --- a/evmbin/Cargo.toml +++ b/evmbin/Cargo.toml @@ -10,7 +10,7 @@ path = "./src/main.rs" [dependencies] docopt = "0.8" -ethcore = { path = "../ethcore" } +ethcore = { path = "../ethcore", features = ["test-helpers"] } ethjson = { path = "../json" } ethcore-bytes = { path = "../util/bytes" } ethcore-transaction = { path = "../ethcore/transaction" } -- GitLab From 123b6ae62ef266131f24da9b184e68b16955fb06 Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Wed, 6 Jun 2018 01:49:11 +0800 Subject: [PATCH 101/152] Disallow unsigned transactions in case EIP-86 is disabled (#8802) * Disallow unsigned transactions in case EIP-86 is disabled * Add tests for verification * Add disallow unsigned transactions test in machine --- ethcore/src/ethereum/mod.rs | 3 +++ ethcore/src/machine.rs | 19 +++++++++++++++++++ ethcore/src/verification/verification.rs | 19 +++++++++++++++++++ ethcore/transaction/src/transaction.rs | 4 ++++ 4 files changed, 45 insertions(+) diff --git a/ethcore/src/ethereum/mod.rs b/ethcore/src/ethereum/mod.rs index 6456440759..db07cbbd49 100644 --- a/ethcore/src/ethereum/mod.rs +++ b/ethcore/src/ethereum/mod.rs @@ -101,6 +101,9 @@ pub fn new_morden<'a, T: Into>>(params: T) -> Spec { /// Create a new Foundation Frontier-era chain spec as though it never changes to Homestead. pub fn new_frontier_test() -> Spec { load(None, include_bytes!("../../res/ethereum/frontier_test.json")) } +/// Create a new Ropsten chain spec. +pub fn new_ropsten_test() -> Spec { load(None, include_bytes!("../../res/ethereum/ropsten.json")) } + /// Create a new Foundation Homestead-era chain spec as though it never changed from Frontier. pub fn new_homestead_test() -> Spec { load(None, include_bytes!("../../res/ethereum/homestead_test.json")) } diff --git a/ethcore/src/machine.rs b/ethcore/src/machine.rs index d54dd2e292..dbf66aa121 100644 --- a/ethcore/src/machine.rs +++ b/ethcore/src/machine.rs @@ -485,6 +485,25 @@ mod tests { } } + #[test] + fn should_disallow_unsigned_transactions() { + let rlp = "ea80843b9aca0083015f90948921ebb5f79e9e3920abe571004d0b1d5119c154865af3107a400080038080".into(); + let transaction: UnverifiedTransaction = ::rlp::decode(&::rustc_hex::FromHex::from_hex(rlp).unwrap()).unwrap(); + let spec = ::ethereum::new_ropsten_test(); + let ethparams = get_default_ethash_extensions(); + + let machine = EthereumMachine::with_ethash_extensions( + spec.params().clone(), + Default::default(), + ethparams, + ); + let mut header = ::header::Header::new(); + header.set_number(15); + + let res = machine.verify_transaction_basic(&transaction, &header); + assert_eq!(res, Err(transaction::Error::InvalidSignature("Crypto error (Invalid EC signature)".into()))); + } + #[test] fn ethash_gas_limit_is_multiple_of_determinant() { use ethereum_types::U256; diff --git a/ethcore/src/verification/verification.rs b/ethcore/src/verification/verification.rs index 3b9104f0e1..1275b5c5c3 100644 --- a/ethcore/src/verification/verification.rs +++ b/ethcore/src/verification/verification.rs @@ -576,7 +576,17 @@ mod tests { nonce: U256::from(2) }.sign(keypair.secret(), None); + let tr3 = Transaction { + action: Action::Call(0x0.into()), + value: U256::from(0), + data: Bytes::new(), + gas: U256::from(30_000), + gas_price: U256::from(0), + nonce: U256::zero(), + }.null_sign(0); + let good_transactions = [ tr1.clone(), tr2.clone() ]; + let eip86_transactions = [ tr3.clone() ]; let diff_inc = U256::from(0x40); @@ -612,6 +622,7 @@ mod tests { uncles_rlp.append_list(&good_uncles); let good_uncles_hash = keccak(uncles_rlp.as_raw()); let good_transactions_root = ordered_trie_root(good_transactions.iter().map(|t| ::rlp::encode::(t))); + let eip86_transactions_root = ordered_trie_root(eip86_transactions.iter().map(|t| ::rlp::encode::(t))); let mut parent = good.clone(); parent.set_number(9); @@ -632,6 +643,14 @@ mod tests { check_ok(basic_test(&create_test_block(&good), engine)); + let mut bad_header = good.clone(); + bad_header.set_transactions_root(eip86_transactions_root.clone()); + bad_header.set_uncles_hash(good_uncles_hash.clone()); + match basic_test(&create_test_block_with_data(&bad_header, &eip86_transactions, &good_uncles), engine) { + Err(Error(ErrorKind::Transaction(ref e), _)) if e == &::ethkey::Error::InvalidSignature.into() => (), + e => panic!("Block verification failed.\nExpected: Transaction Error (Invalid Signature)\nGot: {:?}", e), + } + let mut header = good.clone(); header.set_transactions_root(good_transactions_root.clone()); header.set_uncles_hash(good_uncles_hash.clone()); diff --git a/ethcore/transaction/src/transaction.rs b/ethcore/transaction/src/transaction.rs index dd1e8ca2cc..27b8b346cf 100644 --- a/ethcore/transaction/src/transaction.rs +++ b/ethcore/transaction/src/transaction.rs @@ -409,6 +409,10 @@ impl UnverifiedTransaction { if check_low_s && !(allow_empty_signature && self.is_unsigned()) { self.check_low_s()?; } + // Disallow unsigned transactions in case EIP-86 is disabled. + if !allow_empty_signature && self.is_unsigned() { + return Err(ethkey::Error::InvalidSignature.into()); + } // EIP-86: Transactions of this form MUST have gasprice = 0, nonce = 0, value = 0, and do NOT increment the nonce of account 0. if allow_empty_signature && self.is_unsigned() && !(self.gas_price.is_zero() && self.value.is_zero() && self.nonce.is_zero()) { return Err(ethkey::Error::InvalidSignature.into()) -- GitLab From 6771539a90ccd5900e72728517fa1e904a6e2664 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Tue, 5 Jun 2018 19:49:46 +0200 Subject: [PATCH 102/152] Fix ancient blocks queue deadlock (#8751) * Revert "Fix not downloading old blocks (#8642)" This reverts commit d1934363e7c2c953f17cd451bea8476f46f52b82. * Make sure only one thread actually imports old blocks. * Add some trace timers. * Bring back pending hashes set. * Separate locks so that queue can happen while we are importing. * Address grumbles. --- ethcore/src/client/client.rs | 115 +++++++++++++++++++++-------------- miner/src/pool/queue.rs | 2 +- 2 files changed, 71 insertions(+), 46 deletions(-) diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index 9e2cfeff40..f3a3dda103 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -17,7 +17,7 @@ use std::collections::{HashSet, BTreeMap, BTreeSet, VecDeque}; use std::fmt; use std::str::FromStr; -use std::sync::atomic::{AtomicBool, Ordering as AtomicOrdering}; +use std::sync::atomic::{AtomicUsize, AtomicBool, Ordering as AtomicOrdering}; use std::sync::{Arc, Weak}; use std::time::{Instant, Duration}; @@ -90,6 +90,8 @@ use_contract!(registry, "Registry", "res/contracts/registrar.json"); const MAX_TX_QUEUE_SIZE: usize = 4096; const MAX_ANCIENT_BLOCKS_QUEUE_SIZE: usize = 4096; +// Max number of blocks imported at once. +const MAX_ANCIENT_BLOCKS_TO_IMPORT: usize = 4; const MAX_QUEUE_SIZE_TO_SLEEP_ON: usize = 2; const MIN_HISTORY_SIZE: u64 = 8; @@ -210,8 +212,12 @@ pub struct Client { queue_transactions: IoChannelQueue, /// Ancient blocks import queue queue_ancient_blocks: IoChannelQueue, - /// Hashes of pending ancient block wainting to be included - pending_ancient_blocks: RwLock>, + /// Queued ancient blocks, make sure they are imported in order. + queued_ancient_blocks: Arc, + VecDeque<(Header, Bytes, Bytes)> + )>>, + ancient_blocks_import_lock: Arc>, /// Consensus messages import queue queue_consensus_message: IoChannelQueue, @@ -434,7 +440,6 @@ impl Importer { let hash = header.hash(); let _import_lock = self.import_lock.lock(); - trace!(target: "client", "Trying to import old block #{}", header.number()); { trace_time!("import_old_block"); // verify the block, passing the chain for updating the epoch verifier. @@ -763,7 +768,8 @@ impl Client { notify: RwLock::new(Vec::new()), queue_transactions: IoChannelQueue::new(MAX_TX_QUEUE_SIZE), queue_ancient_blocks: IoChannelQueue::new(MAX_ANCIENT_BLOCKS_QUEUE_SIZE), - pending_ancient_blocks: RwLock::new(HashSet::new()), + queued_ancient_blocks: Default::default(), + ancient_blocks_import_lock: Default::default(), queue_consensus_message: IoChannelQueue::new(usize::max_value()), last_hashes: RwLock::new(VecDeque::new()), factories: factories, @@ -2008,8 +2014,9 @@ impl BlockChainClient for Client { impl IoClient for Client { fn queue_transactions(&self, transactions: Vec, peer_id: usize) { + trace_time!("queue_transactions"); let len = transactions.len(); - self.queue_transactions.queue(&mut self.io_channel.lock(), move |client| { + self.queue_transactions.queue(&mut self.io_channel.lock(), len, move |client| { trace_time!("import_queued_transactions"); let txs: Vec = transactions @@ -2028,6 +2035,7 @@ impl IoClient for Client { } fn queue_ancient_block(&self, block_bytes: Bytes, receipts_bytes: Bytes) -> Result { + trace_time!("queue_ancient_block"); let header: Header = ::rlp::Rlp::new(&block_bytes).val_at(0)?; let hash = header.hash(); @@ -2036,31 +2044,51 @@ impl IoClient for Client { if self.chain.read().is_known(&hash) { bail!(BlockImportErrorKind::Import(ImportErrorKind::AlreadyInChain)); } - - let parent_hash = *header.parent_hash(); - let parent_pending = self.pending_ancient_blocks.read().contains(&parent_hash); - let status = self.block_status(BlockId::Hash(parent_hash)); - if !parent_pending && (status == BlockStatus::Unknown || status == BlockStatus::Pending) { - bail!(BlockImportErrorKind::Block(BlockError::UnknownParent(parent_hash))); + let parent_hash = header.parent_hash(); + // NOTE To prevent race condition with import, make sure to check queued blocks first + // (and attempt to acquire lock) + let is_parent_pending = self.queued_ancient_blocks.read().0.contains(parent_hash); + if !is_parent_pending { + let status = self.block_status(BlockId::Hash(*parent_hash)); + if status == BlockStatus::Unknown || status == BlockStatus::Pending { + bail!(BlockImportErrorKind::Block(BlockError::UnknownParent(*parent_hash))); + } } } - self.pending_ancient_blocks.write().insert(hash); - - trace!(target: "client", "Queuing old block #{}", header.number()); - match self.queue_ancient_blocks.queue(&mut self.io_channel.lock(), move |client| { - let result = client.importer.import_old_block( - &header, - &block_bytes, - &receipts_bytes, - &**client.db.read(), - &*client.chain.read() - ); - - client.pending_ancient_blocks.write().remove(&hash); - result.map(|_| ()).unwrap_or_else(|e| { - error!(target: "client", "Error importing ancient block: {}", e); - }); + // we queue blocks here and trigger an IO message. + { + let mut queued = self.queued_ancient_blocks.write(); + queued.0.insert(hash); + queued.1.push_back((header, block_bytes, receipts_bytes)); + } + + let queued = self.queued_ancient_blocks.clone(); + let lock = self.ancient_blocks_import_lock.clone(); + match self.queue_ancient_blocks.queue(&mut self.io_channel.lock(), 1, move |client| { + trace_time!("import_ancient_block"); + // Make sure to hold the lock here to prevent importing out of order. + // We use separate lock, cause we don't want to block queueing. + let _lock = lock.lock(); + for _i in 0..MAX_ANCIENT_BLOCKS_TO_IMPORT { + let first = queued.write().1.pop_front(); + if let Some((header, block_bytes, receipts_bytes)) = first { + let hash = header.hash(); + client.importer.import_old_block( + &header, + &block_bytes, + &receipts_bytes, + &**client.db.read(), + &*client.chain.read() + ).ok().map_or((), |e| { + error!(target: "client", "Error importing ancient block: {}", e); + }); + // remove from pending + queued.write().0.remove(&hash); + } else { + break; + } + } }) { Ok(_) => Ok(hash), Err(e) => bail!(BlockImportErrorKind::Other(format!("{}", e))), @@ -2068,7 +2096,7 @@ impl IoClient for Client { } fn queue_consensus_message(&self, message: Bytes) { - match self.queue_consensus_message.queue(&mut self.io_channel.lock(), move |client| { + match self.queue_consensus_message.queue(&mut self.io_channel.lock(), 1, move |client| { if let Err(e) = client.engine().handle_message(&message) { debug!(target: "poa", "Invalid message received: {}", e); } @@ -2480,38 +2508,35 @@ impl fmt::Display for QueueError { /// Queue some items to be processed by IO client. struct IoChannelQueue { - queue: Arc>>>, + currently_queued: Arc, limit: usize, } impl IoChannelQueue { pub fn new(limit: usize) -> Self { IoChannelQueue { - queue: Default::default(), + currently_queued: Default::default(), limit, } } - pub fn queue(&self, channel: &mut IoChannel, fun: F) -> Result<(), QueueError> - where F: Fn(&Client) + Send + Sync + 'static + pub fn queue(&self, channel: &mut IoChannel, count: usize, fun: F) -> Result<(), QueueError> where + F: Fn(&Client) + Send + Sync + 'static, { - { - let mut queue = self.queue.lock(); - let queue_size = queue.len(); - ensure!(queue_size < self.limit, QueueError::Full(self.limit)); + let queue_size = self.currently_queued.load(AtomicOrdering::Relaxed); + ensure!(queue_size < self.limit, QueueError::Full(self.limit)); - queue.push_back(Box::new(fun)); - } - - let queue = self.queue.clone(); + let currently_queued = self.currently_queued.clone(); let result = channel.send(ClientIoMessage::execute(move |client| { - while let Some(fun) = queue.lock().pop_front() { - fun(client); - } + currently_queued.fetch_sub(count, AtomicOrdering::SeqCst); + fun(client); })); match result { - Ok(_) => Ok(()), + Ok(_) => { + self.currently_queued.fetch_add(count, AtomicOrdering::SeqCst); + Ok(()) + }, Err(e) => Err(QueueError::Channel(e)), } } diff --git a/miner/src/pool/queue.rs b/miner/src/pool/queue.rs index bd5a98edc7..4ebdf9e3f1 100644 --- a/miner/src/pool/queue.rs +++ b/miner/src/pool/queue.rs @@ -174,7 +174,7 @@ impl TransactionQueue { transactions: Vec, ) -> Vec> { // Run verification - let _timer = ::trace_time::PerfTimer::new("queue::verifyAndImport"); + let _timer = ::trace_time::PerfTimer::new("pool::verify_and_import"); let options = self.options.read().clone(); let verifier = verifier::Verifier::new(client, options, self.insertion_id.clone()); -- GitLab From bd4498cffcf34cf8ef3b002dd6d268d9cae307a5 Mon Sep 17 00:00:00 2001 From: Afri Schoedon <5chdn@users.noreply.github.com> Date: Wed, 6 Jun 2018 10:01:15 +0200 Subject: [PATCH 103/152] docs: add changelogs for 1.10.6 and 1.11.3 (#8810) * docs: add changelog for 1.10.6 * docs: add changelog for 1.11.3 * docs: markdownify the changelogs --- CHANGELOG.md | 138 ++++++++++++++++++++++++++++++----------- docs/CHANGELOG-1.10.md | 104 +++++++++++++++++++++---------- 2 files changed, 174 insertions(+), 68 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ee66149ed0..25e2a28a57 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,71 @@ +## Parity [v1.11.3](https://github.com/paritytech/parity/releases/tag/v1.11.3) (2018-06-06) + +Parity 1.11.3 is a security-relevant release. Please upgrade your nodes as soon as possible to [v1.10.6](https://github.com/paritytech/parity/releases/tag/v1.10.6) or [v1.11.3](https://github.com/paritytech/parity/releases/tag/v1.11.3). + +The full list of included changes: + +- Parity-version: bump beta to 1.11.3 ([#8806](https://github.com/paritytech/parity/pull/8806)) + - Parity-version: bump beta to 1.11.3 + - Disallow unsigned transactions in case EIP-86 is disabled ([#8802](https://github.com/paritytech/parity/pull/8802)) + - Fix ancient blocks queue deadlock ([#8751](https://github.com/paritytech/parity/pull/8751)) +- Update shell32-sys to fix windows build ([#8792](https://github.com/paritytech/parity/pull/8792)) +- Backports ([#8785](https://github.com/paritytech/parity/pull/8785)) + - Fix light sync with initial validator-set contract ([#8528](https://github.com/paritytech/parity/pull/8528)) + - Fix #8468 + - Use U256::max_value() instead + - Also change initial transaction gas + - Resumable warp-sync / Seed downloaded snapshots ([#8544](https://github.com/paritytech/parity/pull/8544)) + - Start dividing sync chain : first supplier method + - WIP - updated chain sync supplier + - Finish refactoring the Chain Sync Supplier + - Create Chain Sync Requester + - Add Propagator for Chain Sync + - Add the Chain Sync Handler + - Move tests from mod -> handler + - Move tests to propagator + - Refactor SyncRequester arguments + - Refactoring peer fork header handler + - Fix wrong highest block number in snapshot sync + - Small refactor... + - Resume warp-sync downloaded chunks + - Refactoring the previous chunks import + - Address PR grumbles + - Fix not seeding current snapshot + - Update SnapshotService readiness check + - Early abort importing previous chunks + - Update Gitlab CI config + - SyncState back to Waiting when Manifest peers disconnect + - Revert GitLab CI changes + - Refactor resuming snapshots + - Revert "Refactor resuming snapshots" + - Update informant log + - Refactor resuming snapshots + - Update informant message : show chunks done + - Don't open Browser post-install on Mac ([#8641](https://github.com/paritytech/parity/pull/8641)) + - Fix not downloading old blocks ([#8642](https://github.com/paritytech/parity/pull/8642)) + - Fix PoW blockchains sealing notifications in chain_new_blocks ([#8656](https://github.com/paritytech/parity/pull/8656)) + - Shutdown the Snapshot Service early ([#8658](https://github.com/paritytech/parity/pull/8658)) + - Shutdown the Snapshot Service when shutting down the runner + - Rename `service` to `client_service` + - Fix tests + - Fix cli signer ([#8682](https://github.com/paritytech/parity/pull/8682)) + - Update ethereum-types so `{:#x}` applies 0x prefix + - Set the request index to that of the current request ([#8683](https://github.com/paritytech/parity/pull/8683)) + - Set the request index to that of the current request + - Network-devp2p: handle UselessPeer disconnect ([#8686](https://github.com/paritytech/parity/pull/8686)) + - Fix local transactions policy. ([#8691](https://github.com/paritytech/parity/pull/8691)) + - CI: Fixes for Android Pipeline ([#8745](https://github.com/paritytech/parity/pull/8745)) + - Ci: Remove check for shared libraries in gitlab script + - Ci: allow android arm build to fail + - Custom Error Messages on ENFILE and EMFILE IO Errors ([#8744](https://github.com/paritytech/parity/pull/8744)) + - Custom Error Messages on ENFILE and EMFILE IO Errors + - Use assert-matches for more readable tests + - Fix Wording and consistency + - Ethcore-sync: fix connection to peers behind chain fork block ([#8710](https://github.com/paritytech/parity/pull/8710)) +- Parity-version: bump beta to 1.11.2 ([#8750](https://github.com/paritytech/parity/pull/8750)) + - Parity-version: bump beta to 1.11.2 + - Parity-version: unset critical flag + ## Parity [v1.11.1](https://github.com/paritytech/parity/releases/tag/v1.11.1) (2018-05-15) This is the Parity 1.11.1-beta release! Hurray! @@ -156,47 +224,47 @@ The full list of included changes: - Backports ([#8558](https://github.com/paritytech/parity/pull/8558)) - Fetching logs by hash in blockchain database ([#8463](https://github.com/paritytech/parity/pull/8463)) - - Fetch logs by hash in blockchain database - - Fix tests - - Add unit test for branch block logs fetching - - Add docs that blocks must already be sorted - - Handle branch block cases properly - - typo: empty -> is_empty - - Remove return_empty_if_none by using a closure - - Use BTreeSet to avoid sorting again - - Move is_canon to BlockChain - - typo: pass value by reference - - Use loop and wrap inside blocks to simplify the code - - typo: missed a comment + - Fetch logs by hash in blockchain database + - Fix tests + - Add unit test for branch block logs fetching + - Add docs that blocks must already be sorted + - Handle branch block cases properly + - typo: empty -> is_empty + - Remove return_empty_if_none by using a closure + - Use BTreeSet to avoid sorting again + - Move is_canon to BlockChain + - typo: pass value by reference + - Use loop and wrap inside blocks to simplify the code + - typo: missed a comment - Pass on storage keys tracing to handle the case when it is not modified ([#8491](https://github.com/paritytech/parity/pull/8491)) - - Pass on storage keys even if it is not modified - - typo: account and storage query - - Fix tests - - Use state query directly because of suicided accounts - - Fix a RefCell borrow issue - - Add tests for unmodified storage trace - - Address grumbles - - typo: remove unwanted empty line - - ensure_cached compiles with the original signature + - Pass on storage keys even if it is not modified + - typo: account and storage query + - Fix tests + - Use state query directly because of suicided accounts + - Fix a RefCell borrow issue + - Add tests for unmodified storage trace + - Address grumbles + - typo: remove unwanted empty line + - ensure_cached compiles with the original signature - Update wasmi and pwasm-utils ([#8493](https://github.com/paritytech/parity/pull/8493)) - - Update wasmi to 0.2 - - Update pwasm-utils to 0.1.5 + - Update wasmi to 0.2 + - Update pwasm-utils to 0.1.5 - Show imported messages for light client ([#8517](https://github.com/paritytech/parity/pull/8517)) - Enable WebAssembly and Byzantium for Ellaism ([#8520](https://github.com/paritytech/parity/pull/8520)) - - Enable WebAssembly and Byzantium for Ellaism - - Fix indentation - - Remove empty lines + - Enable WebAssembly and Byzantium for Ellaism + - Fix indentation + - Remove empty lines - Don't panic in import_block if invalid rlp ([#8522](https://github.com/paritytech/parity/pull/8522)) - - Don't panic in import_block if invalid rlp - - Remove redundant type annotation - - Replace RLP header view usage with safe decoding + - Don't panic in import_block if invalid rlp + - Remove redundant type annotation + - Replace RLP header view usage with safe decoding - Node table sorting according to last contact data ([#8541](https://github.com/paritytech/parity/pull/8541)) - - network-devp2p: sort nodes in node table using last contact data - - network-devp2p: rename node contact types in node table json output - - network-devp2p: fix node table tests - - network-devp2p: note node failure when failed to establish connection - - network-devp2p: handle UselessPeer error - - network-devp2p: note failure when marking node as useless + - network-devp2p: sort nodes in node table using last contact data + - network-devp2p: rename node contact types in node table json output + - network-devp2p: fix node table tests + - network-devp2p: note node failure when failed to establish connection + - network-devp2p: handle UselessPeer error + - network-devp2p: note failure when marking node as useless - Betalize 1.11 :) ([#8475](https://github.com/paritytech/parity/pull/8475)) - Betalize 1.11 :) - Update Gitlab scripts diff --git a/docs/CHANGELOG-1.10.md b/docs/CHANGELOG-1.10.md index a8c7ad20a7..1c15e456ea 100644 --- a/docs/CHANGELOG-1.10.md +++ b/docs/CHANGELOG-1.10.md @@ -1,3 +1,41 @@ +## Parity [v1.10.6](https://github.com/paritytech/parity/releases/tag/v1.10.6) (2018-06-05) + +Parity 1.10.6 is a security-relevant release. Please upgrade your nodes as soon as possible. + +If you can not upgrade to 1.10+ yet, please use the following branches and build your own binaries from source: + +- git checkout [old-stable-1.9](https://github.com/paritytech/parity/tree/old-stable-1.9) # `v1.9.8` (EOL) +- git checkout [old-stable-1.8](https://github.com/paritytech/parity/tree/old-stable-1.8) # `v1.8.12` (EOL) +- git checkout [old-stable-1.7](https://github.com/paritytech/parity/tree/old-stable-1.7) # `v1.7.14` (EOL) + +The full list of included changes: + +- Parity-version: bump stable to 1.10.6 ([#8805](https://github.com/paritytech/parity/pull/8805)) + - Parity-version: bump stable to 1.10.6 + - Disallow unsigned transactions in case EIP-86 is disabled ([#8802](https://github.com/paritytech/parity/pull/8802)) +- Update shell32-sys to fix windows build ([#8793](https://github.com/paritytech/parity/pull/8793)) +- Backports ([#8782](https://github.com/paritytech/parity/pull/8782)) + - Fix light sync with initial validator-set contract ([#8528](https://github.com/paritytech/parity/pull/8528)) + - Fix #8468 + - Use U256::max_value() instead + - Fix again + - Also change initial transaction gas + - Don't open Browser post-install on Mac ([#8641](https://github.com/paritytech/parity/pull/8641)) + - Prefix uint fmt with `0x` with alternate flag + - Set the request index to that of the current request ([#8683](https://github.com/paritytech/parity/pull/8683)) + - Set the request index to that of the current request + - Node table sorting according to last contact data ([#8541](https://github.com/paritytech/parity/pull/8541)) + - Network-devp2p: sort nodes in node table using last contact data + - Network-devp2p: rename node contact types in node table json output + - Network-devp2p: fix node table tests + - Network-devp2p: note node failure when failed to establish connection + - Network-devp2p: handle UselessPeer error + - Network-devp2p: note failure when marking node as useless + - Network-devp2p: handle UselessPeer disconnect ([#8686](https://github.com/paritytech/parity/pull/8686)) +- Parity: bump stable version to 1.10.5 ([#8749](https://github.com/paritytech/parity/pull/8749)) + - Parity: bump stable version to 1.10.5 + - Fix failing doc tests running on non-code + ## Parity [v1.10.4](https://github.com/paritytech/parity/releases/tag/v1.10.4) (2018-05-15) Parity 1.10.4 is a bug-fix release to improve performance and stability. @@ -187,61 +225,61 @@ The full list of included changes: - Beta Backports ([#8136](https://github.com/paritytech/parity/pull/8136)) - Support parity protocol. ([#8035](https://github.com/paritytech/parity/pull/8035)) - updater: apply exponential backoff after download failure ([#8059](https://github.com/paritytech/parity/pull/8059)) - - updater: apply exponential backoff after download failure - - updater: reset backoff on new release + - updater: apply exponential backoff after download failure + - updater: reset backoff on new release - Max code size on Kovan ([#8067](https://github.com/paritytech/parity/pull/8067)) - - Enable code size limit on kovan - - Fix formatting. + - Enable code size limit on kovan + - Fix formatting. - Limit incoming connections. ([#8060](https://github.com/paritytech/parity/pull/8060)) - - Limit ingress connections - - Optimized handshakes logging + - Limit ingress connections + - Optimized handshakes logging - WASM libraries bump ([#7970](https://github.com/paritytech/parity/pull/7970)) - - update wasmi, parity-wasm, wasm-utils to latest version - - Update to new wasmi & error handling - - also utilize new stack limiter - - fix typo - - replace dependency url - - Cargo.lock update + - update wasmi, parity-wasm, wasm-utils to latest version + - Update to new wasmi & error handling + - also utilize new stack limiter + - fix typo + - replace dependency url + - Cargo.lock update - add some dos protection ([#8084](https://github.com/paritytech/parity/pull/8084)) - revert removing blooms ([#8066](https://github.com/paritytech/parity/pull/8066)) - Revert "fix traces, removed bloomchain crate, closes [#7228](https://github.com/paritytech/parity/issues/7228), closes [#7167](https://github.com/paritytech/parity/issues/7167)" - Revert "fixed broken logs ([#7934](https://github.com/paritytech/parity/pull/7934))" - - fixed broken logs - - bring back old lock order - - remove migration v13 - - revert CURRENT_VERSION to 12 in migration.rs + - fixed broken logs + - bring back old lock order + - remove migration v13 + - revert CURRENT_VERSION to 12 in migration.rs - more dos protection ([#8104](https://github.com/paritytech/parity/pull/8104)) - Const time comparison ([#8113](https://github.com/paritytech/parity/pull/8113)) - - Use `subtle::slices_equal` for constant time comparison. - - Also update the existing version of subtle in `ethcrypto` from 0.1 to 0.5 - - Test specifically for InvalidPassword error. + - Use `subtle::slices_equal` for constant time comparison. + - Also update the existing version of subtle in `ethcrypto` from 0.1 to 0.5 + - Test specifically for InvalidPassword error. - fix trace filter returning returning unrelated reward calls, closes #8070 ([#8098](https://github.com/paritytech/parity/pull/8098)) - network: init discovery using healthy nodes ([#8061](https://github.com/paritytech/parity/pull/8061)) - - network: init discovery using healthy nodes - - network: fix style grumble - - network: fix typo + - network: init discovery using healthy nodes + - network: fix style grumble + - network: fix typo - Postpone Kovan hard fork ([#8137](https://github.com/paritytech/parity/pull/8137)) - - ethcore: postpone Kovan hard fork - - util: update version fork metadata + - ethcore: postpone Kovan hard fork + - util: update version fork metadata - Disable UI by default. ([#8105](https://github.com/paritytech/parity/pull/8105)) - dapps: update parity-ui dependencies ([#8160](https://github.com/paritytech/parity/pull/8160)) - Probe changes one step deeper ([#8134](https://github.com/paritytech/parity/pull/8134)) ([#8135](https://github.com/paritytech/parity/pull/8135)) - Beta backports ([#8053](https://github.com/paritytech/parity/pull/8053)) - CI: Fix cargo cache ([#7968](https://github.com/paritytech/parity/pull/7968)) - - Fix cache - - Only clean locked cargo cache on windows + - Fix cache + - Only clean locked cargo cache on windows - fixed ethstore sign ([#8026](https://github.com/paritytech/parity/pull/8026)) - fixed parsing ethash seals and verify_block_undordered ([#8031](https://github.com/paritytech/parity/pull/8031)) - fix for verify_block_basic crashing on invalid transaction rlp ([#8032](https://github.com/paritytech/parity/pull/8032)) - fix cache & snapcraft CI build ([#8052](https://github.com/paritytech/parity/pull/8052)) - Add MCIP-6 Byzyantium transition to Musicoin spec ([#7841](https://github.com/paritytech/parity/pull/7841)) - - Add test chain spec for musicoin byzantium testnet - - Add MCIP-6 Byzyantium transition to Musicoin spec - - Update mcip6_byz.json - - ethcore: update musicoin byzantium block number - - ethcore: update musicoin bootnodes - - Update musicoin.json - - More bootnodes. + - Add test chain spec for musicoin byzantium testnet + - Add MCIP-6 Byzyantium transition to Musicoin spec + - Update mcip6_byz.json + - ethcore: update musicoin byzantium block number + - ethcore: update musicoin bootnodes + - Update musicoin.json + - More bootnodes. - Make 1.10 beta ([#8022](https://github.com/paritytech/parity/pull/8022)) - Make 1.10 beta - Fix gitlab builds -- GitLab From 114d4433a93e30c92aa76452dc158e64596dd0e0 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Wed, 6 Jun 2018 09:02:25 +0100 Subject: [PATCH 104/152] Remove windows tray and installer (#8778) * Remove windows tray and installer * Remove make_exe (installer) target * Change windows $ARC to amd64 for consistency * Fix windows build - revert to winapi 0.2.8 * Remove publishing of windows installer bins --- .gitlab-ci.yml | 2 +- Cargo.lock | 8 +- nsis/installer.nsi | 191 ------------------- nsis/logo.ico | Bin 102596 -> 0 bytes scripts/gitlab-build.sh | 18 -- windows/ptray/ptray.cpp | 360 ------------------------------------ windows/ptray/ptray.ico | Bin 102596 -> 0 bytes windows/ptray/ptray.rc | Bin 4364 -> 0 bytes windows/ptray/ptray.vcxproj | 155 ---------------- windows/ptray/resource.h | Bin 1788 -> 0 bytes windows/ptray/targetver.h | 8 - 11 files changed, 5 insertions(+), 737 deletions(-) delete mode 100644 nsis/installer.nsi delete mode 100644 nsis/logo.ico delete mode 100644 windows/ptray/ptray.cpp delete mode 100644 windows/ptray/ptray.ico delete mode 100644 windows/ptray/ptray.rc delete mode 100644 windows/ptray/ptray.vcxproj delete mode 100644 windows/ptray/resource.h delete mode 100644 windows/ptray/targetver.h diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index c615be99ce..6be6b45838 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -173,7 +173,7 @@ windows: - stable - triggers script: - - sh scripts/gitlab-build.sh x86_64-pc-windows-msvc x86_64-pc-windows-msvc installer "" "" windows + - sh scripts/gitlab-build.sh x86_64-pc-windows-msvc x86_64-pc-windows-msvc amd64 "" "" windows tags: - rust-windows artifacts: diff --git a/Cargo.lock b/Cargo.lock index 680b9606ec..a9d9ab7d10 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -22,7 +22,7 @@ version = "1.2.1" source = "git+https://github.com/paritytech/app-dirs-rs#0b37f9481ce29e9d5174ad185bca695b206368eb" dependencies = [ "ole32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "shell32-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "shell32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "xdg 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2995,10 +2995,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "shell32-sys" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -4032,7 +4032,7 @@ dependencies = [ "checksum serde_ignored 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "190e9765dcedb56be63b6e0993a006c7e3b071a016a304736e4a315dc01fb142" "checksum serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "c9db7266c7d63a4c4b7fe8719656ccdd51acf1bed6124b174f933b009fb10bcb" "checksum sha1 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cc30b1e1e8c40c121ca33b86c23308a090d19974ef001b4bf6e61fd1a0fb095c" -"checksum shell32-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "72f20b8f3c060374edb8046591ba28f62448c369ccbdc7b02075103fb3a9e38d" +"checksum shell32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9ee04b46101f57121c9da2b151988283b6beb79b34f5bb29a58ee48cb695122c" "checksum siphasher 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "833011ca526bd88f16778d32c699d325a9ad302fa06381cd66f7be63351d3f6d" "checksum siphasher 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0df90a788073e8d0235a67e50441d47db7c8ad9debd91cbf43736a2a92d36537" "checksum skeptic 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "24ebf8a06f5f8bae61ae5bbc7af7aac4ef6907ae975130faba1199e5fe82256a" diff --git a/nsis/installer.nsi b/nsis/installer.nsi deleted file mode 100644 index c1f4033312..0000000000 --- a/nsis/installer.nsi +++ /dev/null @@ -1,191 +0,0 @@ -!include WinMessages.nsh - -!define WND_CLASS "Parity" -!define WND_TITLE "Parity" -!define WAIT_MS 5000 -!define SYNC_TERM 0x00100001 - -!define APPNAME "Parity" -!define COMPANYNAME "Parity Technologies" -!define DESCRIPTION "Fast, light, robust Ethereum implementation" -!define VERSIONMAJOR 1 -!define VERSIONMINOR 12 -!define VERSIONBUILD 0 -!define ARGS "" -!define FIRST_START_ARGS "--mode=passive ui" - -!addplugindir .\ - -!define HELPURL "https://paritytech.github.io/wiki/" # "Support Information" link -!define UPDATEURL "https://github.com/paritytech/parity/releases" # "Product Updates" link -!define ABOUTURL "https://github.com/paritytech/parity" # "Publisher" link -!define INSTALLSIZE 26120 - -!define termMsg "Installer cannot stop running ${WND_TITLE}.$\nDo you want to terminate process?" -!define stopMsg "Stopping ${WND_TITLE} Application" - - -RequestExecutionLevel admin ;Require admin rights on NT6+ (When UAC is turned on) - -InstallDir "$PROGRAMFILES64\${COMPANYNAME}\${APPNAME}" - -LicenseData "..\LICENSE" -Name "${COMPANYNAME} ${APPNAME}" -Icon "logo.ico" -outFile "installer.exe" - -!include LogicLib.nsh - -page license -page directory -page instfiles - -!macro VerifyUserIsAdmin -UserInfo::GetAccountType -pop $0 -${If} $0 != "admin" ;Require admin rights on NT4+ - messageBox mb_iconstop "Administrator rights required!" - setErrorLevel 740 ;ERROR_ELEVATION_REQUIRED - quit -${EndIf} -!macroend - -!macro TerminateApp - Push $0 ; window handle - Push $1 - Push $2 ; process handle - DetailPrint "$(stopMsg)" - FindWindow $0 '${WND_CLASS}' '' - IntCmp $0 0 done - System::Call 'user32.dll::GetWindowThreadProcessId(i r0, *i .r1) i .r2' - System::Call 'kernel32.dll::OpenProcess(i ${SYNC_TERM}, i 0, i r1) i .r2' - SendMessage $0 ${WM_CLOSE} 0 0 /TIMEOUT=${TO_MS} - System::Call 'kernel32.dll::WaitForSingleObject(i r2, i ${WAIT_MS}) i .r1' - IntCmp $1 0 close - MessageBox MB_YESNOCANCEL|MB_ICONEXCLAMATION "$(termMsg)" /SD IDYES IDYES terminate IDNO close - System::Call 'kernel32.dll::CloseHandle(i r2) i .r1' - Quit - terminate: - System::Call 'kernel32.dll::TerminateProcess(i r2, i 0) i .r1' - close: - System::Call 'kernel32.dll::CloseHandle(i r2) i .r1' - done: - Pop $2 - Pop $1 - Pop $0 -!macroend - -function .onInit - setShellVarContext all - !insertmacro VerifyUserIsAdmin -functionEnd - -section "install" - # Files for the install directory - to build the installer, these should be in the same directory as the install script (this file) - setOutPath $INSTDIR - - # Close parity if running - !insertmacro TerminateApp - - # Files added here should be removed by the uninstaller (see section "uninstall") - file /oname=parity.exe ..\target\x86_64-pc-windows-msvc\release\parity.exe - file /oname=parity-evm.exe ..\target\x86_64-pc-windows-msvc\release\parity-evm.exe - file /oname=ethstore.exe ..\target\x86_64-pc-windows-msvc\release\ethstore.exe - file /oname=ethkey.exe ..\target\x86_64-pc-windows-msvc\release\ethkey.exe - file /oname=ptray.exe ..\windows\ptray\x64\Release\ptray.exe - - file "logo.ico" - # Add any other files for the install directory (license files, app data, etc) here - - # Uninstaller - See function un.onInit and section "uninstall" for configuration - writeUninstaller "$INSTDIR\uninstall.exe" - - # Start Menu - createDirectory "$SMPROGRAMS\${COMPANYNAME}" - delete "$SMPROGRAMS\${COMPANYNAME}\${APPNAME}.lnk" - createShortCut "$SMPROGRAMS\${COMPANYNAME}\${APPNAME} Ethereum.lnk" "$INSTDIR\ptray.exe" "ui" "$INSTDIR\logo.ico" - createShortCut "$DESKTOP\${APPNAME} Ethereum.lnk" "$INSTDIR\ptray.exe" "ui" "$INSTDIR\logo.ico" - - # Firewall remove rules if exists - SimpleFC::AdvRemoveRule "Parity incoming peers (TCP:30303)" - SimpleFC::AdvRemoveRule "Parity outgoing peers (TCP:30303)" - SimpleFC::AdvRemoveRule "Parity web queries (TCP:80)" - SimpleFC::AdvRemoveRule "Parity UDP discovery (UDP:30303)" - - # Firewall exception rules - SimpleFC::AdvAddRule "Parity incoming peers (TCP:30303)" "" 6 1 1 2147483647 1 "$INSTDIR\parity.exe" "" "" "Parity" 30303 "" "" "" - SimpleFC::AdvAddRule "Parity outgoing peers (TCP:30303)" "" 6 2 1 2147483647 1 "$INSTDIR\parity.exe" "" "" "Parity" "" 30303 "" "" - SimpleFC::AdvAddRule "Parity UDP discovery (UDP:30303)" "" 17 2 1 2147483647 1 "$INSTDIR\parity.exe" "" "" "Parity" "" 30303 "" "" - - # Registry information for add/remove programs - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "DisplayName" "${APPNAME} - ${DESCRIPTION}" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "UninstallString" "$\"$INSTDIR\uninstall.exe$\"" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "QuietUninstallString" "$\"$INSTDIR\uninstall.exe$\" /S" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "InstallLocation" "$\"$INSTDIR$\"" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "DisplayIcon" "$\"$INSTDIR\logo.ico$\"" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "Publisher" "${COMPANYNAME}" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "HelpLink" "$\"${HELPURL}$\"" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "URLUpdateInfo" "$\"${UPDATEURL}$\"" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "URLInfoAbout" "$\"${ABOUTURL}$\"" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "DisplayVersion" "${VERSIONMAJOR}.${VERSIONMINOR}.${VERSIONBUILD}" - WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "VersionMajor" ${VERSIONMAJOR} - WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "VersionMinor" ${VERSIONMINOR} - # There is no option for modifying or repairing the install - WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "NoModify" 1 - WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "NoRepair" 1 - # Set the INSTALLSIZE constant (!defined at the top of this script) so Add/Remove Programs can accurately report the size - WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "EstimatedSize" ${INSTALLSIZE} - - WriteRegStr HKEY_CURRENT_USER "Software\Microsoft\Windows\CurrentVersion\Run" ${APPNAME} "$INSTDIR\ptray.exe ${ARGS}" - DeleteRegValue HKLM "Software\Microsoft\Windows\CurrentVersion\Run" "${APPNAME}" - ExecShell "" "$INSTDIR\ptray.exe" "${FIRST_START_ARGS}" -sectionEnd - -# Uninstaller - -function un.onInit - SetShellVarContext all - - #Verify the uninstaller - last chance to back out - MessageBox MB_OKCANCEL "Permanently remove ${APPNAME}?" IDOK next - Abort - - next: - !insertmacro VerifyUserIsAdmin -functionEnd - -section "uninstall" - !insertmacro TerminateApp - # Remove Start Menu launcher - delete "$SMPROGRAMS\${COMPANYNAME}\${APPNAME}.lnk" - delete "$SMPROGRAMS\${COMPANYNAME}\${APPNAME} Ethereum.lnk" - delete "$DESKTOP\${APPNAME} Ethereum.lnk" - - # Try to remove the Start Menu folder - this will only happen if it is empty - rmDir "$SMPROGRAMS\${COMPANYNAME}" - - # Remove files - delete $INSTDIR\parity.exe - delete $INSTDIR\parity-evm.exe - delete $INSTDIR\ethstore.exe - delete $INSTDIR\ethkey.exe - delete $INSTDIR\ptray.exe - delete $INSTDIR\logo.ico - - # Always delete uninstaller as the last action - delete $INSTDIR\uninstall.exe - - # Try to remove the install directory - this will only happen if it is empty - rmDir $INSTDIR - - # Firewall exception rules - SimpleFC::AdvRemoveRule "Parity incoming peers (TCP:30303)" - SimpleFC::AdvRemoveRule "Parity outgoing peers (TCP:30303)" - SimpleFC::AdvRemoveRule "Parity web queries (TCP:80)" - SimpleFC::AdvRemoveRule "Parity UDP discovery (UDP:30303)" - - # Remove uninstaller information from the registry - DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" - DeleteRegValue HKLM "Software\Microsoft\Windows\CurrentVersion\Run" "${APPNAME}" - DeleteRegValue HKCU "Software\Microsoft\Windows\CurrentVersion\Run" "${APPNAME}" -sectionEnd diff --git a/nsis/logo.ico b/nsis/logo.ico deleted file mode 100644 index cda99eef8b3668827befd6a13ff8268c096ceae4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 102596 zcmeFYbz79}*ET#ff~0gSARrQgbV?{gh_rNwfOK~ZDj*>sAdQ5iluGviB1lW8lyrA9 z&vANr{qCpk=L5XktAEJmIdh!rSh=r#EnqM-@E7`n24jMiM5Dndz|Wyi9zP<$qrn3| z62KMY)L}48@FOM+7aRN&K+pLK20jdzd!Xr=x-sn$r?q%mwQIvq#&HMFteJFUI{!-w zRcJDmjb;|M&)uy7Me2Zf#*nzz5#Sd4E5zG;ow!_sK zzRB~e!Kvex%~}H+%-p^7o6QNx5F{Hiug6&Gc3B|sQU8~a6Z3ha+hDB6yx3^6*=w>n z)4`2bRx-mzQDgfG(VY+{Uau$eCBK`*0xy0IKCPZygkJP0_lI%bX@&j%dO&)Lj%gCy zf{K^gv-DJe+LQ7G+zlS17Xf`X^Mz{eml?7#;<2LB^;+psM9q+Q4=X>eC%$LJ>AH=1 zFy>n{7Z6<gNW+kQ|PNkKXvu4|hU z&d2K2MFmnO8^ug!3^-pJt(4x*2+f{4yY5NhS$isQE%CbsWaE(WeDhr72DJ zI7P(w-wlcOFoC<$c-Eh;Pi2I%z_ETnpVEoPa=$&evyE;myOiw@AJ@ec#}R*M!L)<9 zW7jVill>CPBXL7v7kT3-fh3Ky@Rzq^@HB2D>0>jn@soL?Co%xZ3RIkd^m^*k9rw?h zZ2ax;%JGvG6!Y55dr3U2PYZ=EbF!84Ly(t99>-x)yGPiaMY|1C>U6;&cEg0+mEm&b|* z{-=D!8K_IHCdnu!4lqy$UTXP!-1@PEQ*GMhJi@KuzZ(YxpZyTc~;Qm z!R*}_%_orhw~8=QVRQrs*TL&1YD*D?ft-jR;Nt2JplDLc!yQXdUT6}NoaBMmR8n~o zQxQxN+=nh^mjD!_Xu-;-f`Vmufb-%g(%*TBo80H+f^Ojg9qulO@fd>;BmNpVe85`L zQGyrGQviC(51tP6+2CA|2-A;2pC1VD!L7!vPUv1hkI80)Oy+MOG^@b(7UliN3KMna zg6QAT%ODGkKv8#TY=fSM-i|&EuEp})^7f7gFnAPnM{P)Hm+iNaBFIeX5Tq^(T*;Dz zmr$6<^N(QU;MJrXn5p<11ai>P&Yaj=Xu)Wzn7y~)4@6+maoQxGDU-ejEJNSqdUh-6 z0n(H26&hTT8~}xZTntCtBrTK*^wywVQQp*UX7q4$@K%Zin6$c{>n)f3nQ^2Zbg*7X z)Q?mWM^;`baKBD5@NK+lK64sWv-CD}bn&32IRgRJt5+~MRyP_VTV|MAII{aw)7vIc zC474Wu+jFRb5ntb74*AeN3so`lu`(XvlQ4R%Pd78ehTA8{|TTwWNCpnI#Sn~6oC!0 zTXwKe)R^4_K;iMpz(96}kNDmOT>I?&=iveC6Cwk`yO6C(p>vC^ap(v&(VK9S<$(DZ z(a4d9(i)H{1%R{@$+%;T`B;LGBgQ>;fIUY_!K9Rx{@Bi1$sJ=2VJD08j^&ysAv-n$ z9=%*lyj)#B8q14own|H_!>`6Jlw$Ov>^ka&Brt6$f#8>Sgl3Er0(&+)%Cv+pU@^f8fk=L@+utMrWpQcRx^Wa zg#jD~S9*3k3B!ixdm#pE1u1a!3W|VRWm`@5D@-vgi~Z(&QCL%+bdRh zX97V-{iu=bQiDzmDJaAop}4|$o;QTEP6NRAE!rah)R6niWc)O~0H zXppaQ90LjP1_S@`i|h?sjC$#%eiJy>cQl0N)7of}m2JTc9}wjrmFUHHk3Z1CFa+r= zP8NDsq)K24LPZ9$71jdRtjQl+aY+clvRfR*lPr%Qr%~s&!xfiZDhtjQ>?ME|*sY@* zJX~610F9DwEg==Gn*iLFj}Vq!X@db-f(EjL;@eSB!5IjmhrXZSB8CJHF+Q{{83VD4 zRDOt)_VWOBkAsXiqQ9w%v`{2S8!4e2Ku|ioaj8TO3<(9M8jEf44*w?4q$X)jgs8M9gV7cmz9;(4{FXD z#cZh>Sq~w7wm=z<20Ji+@e{gs8w^!5;7!d9ye~-4w<;)?3248&^htKPjT+F3#tbE2 zQYVgG=sr~ET);-Wbi|l#Z*#g3o3+Szv;vZ>MVUp9*-3xql=EN@>Ts}@+px|NB}?>W z?NcGPGFyfBV4!RkyEnUQ^hgJTawc%bid#-}>1b0?z!|aJjtxD&Jerwt+OJNz>ccs# zaamH=G9qD58nQTmZP{GeG8epe#E^bajkYs0FT8a<0_`jWsNluX&k#m6BfXYyY`3pA z(i=9yer_~|;G`=l%|4tRV-H&jA{@{gd&NP91H)@ULk4_vs>gO@`>X}Ys~t|kH6PaX z$Yr&SvdnR=h4quJ*L$sMR3^^qNU{EhK{(bNmI;bIO!68~(r2I~;80j(?Yo4?GGG{W z-ag6w>pt73j~*I0Hj@gWV8;HtSj^njOi@3wUw$RuvE8?1ga?8YiXOUf!h^&#dEc+g z!tvIkH?euPtZ$A7hq1*cmd()@=b5X3PFcPJlVWt`Hw$Br7;>b2F{K}5pOPSi zBbhU>*|7)Cd1PY1Nr__iO=-ck-r$&bZhi?RhE%TKsp*`4tC3akbjr#U%(h8mJfV?S zyOToV!y7aY1BbZ5`hCY{Dv%E{0SuyPKwX{3ktghQ52~_#nz1{cF32z0!;|I^vd1A* zU6?~0ncxAy@ls&{#uT}r1>minEGXOMx}QzZ5)8dLKJwJ1%7;@tH*5lCRX5UFEkLPn zN#Ji#%KxOyd{xf!?@R4q#O=GckrGHf=&cjtB2Kp!b8>u7nnQF)Dags4zNtOBw-Uj> zGEkwk)e1*Hp&H{1%NmuzdBO3o0E3VK(}DVdi;w{KlO+8_4+Scw+?LZq*Mw%wT&&mE z$30_JoKuwth!U|bM8dLgz}K(+`}Hp9>&$`oq(dOJbIl7cjifl3K9$7)UfNmPXfs-p z>eefAAa%hzQL*2`Qh>#U9vPmslHC7buLrniIT5||9Ze^?glLgXDf&S|xHZ-@bMGP#=$uy0NVmR(Ynv^mWq}gLDRI`sCag49MWp`H+$Gul$0y22~jQp zv+QqV=)nn7SX4M0v`{FwH8J``><#cqUjB|PvI(D{+#P)uwKz1Wn&-0I>!rZB%M7hH;6Ds>8}>q%h9BvtZo4gC+C+kh5@VNZyI?!(?Jc+&E5T7RHog?k;1=sT$K zdE)Xk9jIrW`5jFs#O(2TA8jN73HCs@lmhDm0^t8EKpZ51U!YjvbI1#11Rb^v9!66A z7%MEvD&RQhZyqtQ;re7_Gk!WMwtO=!n}Uz_M1xG8D2VWD`9?EY7zPYW4Hp9h(J_WS zw&ML`_9d-J(6Bz_jjzw+&47Wjj?+~t1J~H3kc?q?0RIP9WhYGBm`lgPYpRSNj3SH z5Tw5Q=>bFP%_aaVA0-jg0OW+WEf+dc^CO zGbv>cvj`&Gll@nZdN@Fj9&BZzm3GiA*th5dhy=8>lv4z`)+ZjPi8^(@$a9{$#@65H zcMg()Ch`N8KcoE5?*0c?3I7W5CnJ+1Z~}|}gu>2`c18^&z3&UCE03%*W7Lw6=CEej zlAg_?a8fo|66OYj{LhH~2aSDy(?&s6zGHvR&YY83=W{A@c`ZR(uxZMu~dP&2CCEUn0Y6wp`CMC>q+!7M*N1GVVE5CHP{gzE24c#|w$9qqhK7fB z4o8hG4JT_{EFUx8fAcX)Bsl9x9;87yYSGK2s=o^3Z{5Fj@W*@*s5zoJSm&`##}=ENesDi&60PwXIr8tNZ~igdO_$-B-ewsEb=peD zIhlvX?jlev#HZx$uJvEk(#|Z(N|oBEv1Ay450HAj>?Ss`f73Me_k>JrSWgd10_pGy zGdf#vD=9BMw>~@W_?HjQ`h@%Dgwq&Fh|70f%b&&iRlxGuMdElH(Dp==60{k29uD=h#qUr+M9eMCZjKFVC>YR-ko8`8j}0 zeq3rWF8W``bB63r;z;{BAp9~XMicfcMLcO>p7evy(YV~9&&AbooR0R_&QFEEg_Bqo zr_!XG*u!Y_=XoGpxhaDay~hEPP&IZ+09?-upW?2`H!RA}#~%Wehb~HM*FHrs@CP@& zZJb(?3KWj4xvZR|a-7-~yr$kY&PX+RF|Ky!>830=!@)F zA3+Ta3lm;Td`2Z~#gta(`a`z11?Y8K%}BkIUsZ|#SxxKko9EJxHdap|z~r{0;tG>` zBf#A+twJBc=7mepJNK_B;p%87YlWp&`Naz*V%xwWPAO6}fGa+vbx2(>U;S*-jLuzm zpbps_;KegkQ`5%Ru07=I5ZxC!@6mH()$?wLW!3u!m;cRIjgZ5n6Gn8e8{dLsF-1PJ zXYjbu8bY|3;?Ve`wo$*zKGknagl?iqYIEY$+>})HajJsX3l2vAojIbb{f47oDdF5T z)z4+&G-UE>za*6={sFJI(jiBPf_+DqY-NQ@&81b%WR_PaQr=bp(X(t6kX@AZ(x}0E zQCL@0IbAaCEO~-;qPBW1`OAexf}tMM`)rGQj;>_#qrVqZCSP$7gNVFk{HHErZNcho z6l46q)qCw%n-8&<(D4WVfhRh~&j>(ewN8|Px9{4kkxASTjVLdl0^p=(3IZpFvv4GH4C`tDD2s`-rA;69 zL(>h|jO}X{g)MhX2qh1qDQcQ?h%e8-w6pVYxva}rPv)YDJyg3dLOIj@H`Hs+ zh^gCm70r`TZZ3NStObbr)9 zsdgE!Zzpf(CqZjl{Qv~Aq7`4#O=Nk_<-@;G+|dT5FmBL9)a6`R0H%4VH>pdW`4QjI zr$Q_1PXB4&V&futH#>T<&3X-n0rJMSa7zBIU|L~^v7MZW+LQg8I6f6wLucX`2XC{i zwg!A}{Ke^aH=%=X@#S4^r^EsZn~A}H=jNTRt|Y$aiX#>DqOP;AZ{Rr2|6m&|(8v?d z=Ja)FJiVPG8|HPIlR!GWUAEmA7nks}%(4$8&p25R3>-PNxXafSNq-%|nHNw!j%M}) z3hI+W&pXMi?-Y8@UY*|$J`1A-wRL`O>_5Sc@t~kfzLWW1=-}fBAcQ_Zl;lKrj8lSf z5qF2<(8%kQyi-xp^Ri-;bePd`Ht;$JhiMSGPKVQ1*Auf&N=+T@+rMhZEGF#=ic28} zs56`0VGpzKsO@J^294emVmO4BjX886OBR04{Bs89l21q44ppiKO4H>sWE%aeopV+Au9?mMw*+ngQkJ&2P0%F0QkPe5Q5~og$rO*;;3}Y zkfMNqpwsXSsyF`~bCQsQ(a52M_d!N=dEDhyc>u#ePV43I^dqB1&+@+DOu#o+Hnh+;5fmMSRzv{YEy*jekI^gMnpZcue$ zY$5WapO57Qy#8Q59O}iFQXFo7+VoihxZ~jYVW^PHWYSf7fYiFx#)% zrydQ5`8N3;>oNl#OXz+d*}a!St}_1ysJ|_!?YnEpePkyWjY16i3tL_+l`AWoHXDP@uu~SY%T(Qfv;hiks!Klqb+w zUhQBNb%pUazg+bHlen4!i}l5U%sW$MeQMh3Ex$cxdTIs3Ze2N#nSwri{BGUGS1$#f z6Uoz)XPru2o)XNuf56p6(YlV_3s%L>t}&l< zzrES(n$!?I9k5jNoDDJ_jcpb=`2Z0B^cj9#u1Hx`sX0g~jnu@p4&G4kn`S7R>{|lR0CTmxwk_K@IoY!U4xs`D$-)61&{WX`I+QD>YfGS!_NG~(|bmu@r zRZZKV1&7f$+Rd)ceN%WopPAZqDamznLV#!$Zw5S&mVZGFAWUMu|7fFMK~X`j$M!GK zMRBwlVO6rZsALSy10o|1x0-r|67Z&r6QjlfDzb+3sOrl|xkG?ksVffMY-`6YL>|Wz z0z7Sg@I1j~JSX8cNHlt`i~b$mPB{KE4c%+s}C zV3UickCFbGFzdh(mJvTh;z>4k(~%I~8Op{GkP6X2|AD|~rR|Vkx^4}yLS_N9qK2M9 z3m|S&^8KS`P#^X>6@i>V2V^_?Oy?L%*_d>&d{#ruR0`48EL_EWWH*?C07(!~mORc_-^29UMt+UhZ$ z>+|`~B28zRASH?h+;$N|#OVMPk_y5;V8jF3JtoHcyts;ki+ib!(nvwGY4n$m2Ix=~ zIlV9yNsavu$st0}Z`2ToJ!Xb)O}jR3weS|uaWT&Gv?ltqoBaM2A~q3#Sj%@5fjwz7#HV8bx?|m4VUBvDruW@4-7ntFPVM|wq}UZElo8`~Et3Ag zrKUr{=d7&tye|ORCAHN+3Eb&mZI}}@xf~897?HU2GC^Hvh`m+J*}eXoEFAh8O&2k1 zpYCkc9UF(P1yuBu<`)z`Yd9S319>b_$blgtf~M{Lv+qzL_IoRkUs5~=5`PTnw&Oh5 zU^=e}Gh4tK!|7M*o$LJ~UEb*&h}|e{b=G0E#_aiS&ak;ngQo*`x>75ACYz0uJCr~D%@0PK8 z%Kn*6shXZacVTILG61$xo2pJPI6z&8(ru!s+a17dT&#ca0YIog6r@&XBGjMci=pLLrY{gNFv5H%BAsl{7St)|Z-A_VFP?&nYj>nUNc-ak930 zwthcR!pHp|(Sbp@aTvYd=u=*k*gd&1#qTeEC`)_c!Ct}rF%T_NHvcn3-C`{>fzeI{ z36bOuOpBb{_ugW7k&T$^3K9|f*c=IG`}rR@yNk^#8@$umRm$>d#sPK7!R@kstKfeM z37Bo&X63~y5(7Oi=0JiCMub)sM3~hwhmCN4!8I#y5(K6prSR&k3N++2#<& z+;hCfw@Sqw*G-gWKLUMI0e$O)Ap$VOp!us*Zo!vOo9{+F9VE<&Vr=K_cXXaQVFky< z?c`w)I%D+V9RZfa=vkM`l7Y4*!s^{Jhdqb9kBYg*u6S~8B>UUnDE|9MX z&BjibD;)2@r54~Olo|J2i7WgFVR4)l((n~xu#y9TVa4!puZ6?W8^er4rHrq_Lrw;N zz6OWOxXH5uy-H`DZC1{F0QGr9*JGNFO)12-M7!R9>aA^4Dt~o8Y_{26R#=H%fo+YNVgHg1PFDFyH7$f^Is7ErJO$Hw9eDOo2+eg z0FOiW_^*JglnZE7O_!W35P5PdVj?SR%lP)i3WjpFXSbbm!q1fwL*tg_D10vhKAYUE?1Gqz>EW%HwB zM&JN1tL!3xalQSBD3lF}&fdN+Ah>(XS!zDi@$MhO4m6Ta)Q!G3o^K|ExUM?RG@!C- zKZO+-`zQUw&92622>T}CIhp(D__kQ$w`6%3yMlq>A8!fQ_>6v?vvV%_1hWX0j3 zEyxcL@Pp#~Br6=GxPKdjqPWYW87ZRGfw@c^#_Uh^ErsMcu3mU20!giCIjl?6FvWRW zD8|t}X51*1blGWpn@z^6i{3q{k=dJPCK^ zl;O?37e61xCB*N2TTlhrVzH_z=Tl|yu#T}r`;UP+!0*gmn6^@TEW8C_ZoRfPcBa$R z2@E|tH1@4xG~)TUAWH9wtT=o8K)b*MSsb-Vuog7FqL6z!BMvh4YPr?VTP4-L_Y;hK z@BLvG8+A&J;{!beNY{h)Jqs$P%eymv@88}5io)81us6s7f2NMK@+6l;QmJLVA}N0m zk>Old+lc&gH}ZcQ2oR+;An{hu)vh<_sSO<4JznBJiv|`ItVYXVt-#n3PQrk(7PJBA z@(LiBDfjhaFqivfegkT7&BD2$&JlnfYJTtg2@$o4SojnG3k)c7s%fh=Gamoqgbe%t z4$Bz5z}tK{=#u23Z}g;aV0xr!9R{aW5U3ttj(oONzrZ*&I?T7QPOUrYu{99%!1DTh z$H&Or{D!hF7UwT+PD|sKUpBt}qDuJ&h3Io#5ikN*03quBD|Ah-R69<6p36kZ#D9g! zdKyexl(L|3=32Qtp2;h!er@@|UsUbVzHa-myc>C8Nv$>1RCOouQ;+b*0WwTP?eZb5 zo!n+WHi&|=E$cP_D)<8YkJ1-?4ptt(y}&r4${5hW);WSK`$-MLASZzZk(Fgz0`a%4 zx8PhRb1gvzS5-|;<2eD(erCz*j+O$Dsi~>;<($FiH^7GH_Ul=I=KW9K!Ry#B9VvQ7 z1zzWEI=}*W3R1&jDtVFs$=@d6E(3)mV+@I4Nkoqa2L{$q0+$1Oz}AE2$%j;}t~mkeJ1)GCywKX_so&u+ zK!fVERk&l=o&XM2ND{&hWG7<1wq_(`;9mE@-~s}dr^_EyHBliF$JzB?Um9_iLcA|D zT+lGquhZ101XPG^ZIY51{H|X48%}P664c>=Y<@HmA|?APim9|ci;wo6kvy2kLd~)Wzz=r z$bf&?S-@c|nyqJn@x*%_T~=UI)1?UNq(X9s8dk`G9hB{48z3`$M+bg5ekvPj; zUy<=z;Y(Lhk5zzpgSMei1*4R_bniR=gsPWT4!Dh;UO-#liS-gpdPX<2+xtlr@TUqt zhlWE6)>k1rdrCa4pJps){5UvxK3evDfDjtgN`MM-vAnFVNUc zN*zw^f8#POn=F~o7E>84K+S<>w9!QptTDw8K>VfKPk95k#hDk@ombIK0wV^o$+dd! zSBIthzy@4^R!;f;b^!zvse@sv8{q%X5}K;r-u1`cU{g2J>jcOx5%dpgB+wuRqffjQ zIMt#$5nuXY6mY7!8Z@R3amoYUBz~~}`tBN$YR1>1h(0Nl`1-`r=A_F70xi|G^T*w? zZa%1#f=XuxLATu?NoCyTo^O=>*>G^0+GTSDv(Z|&cTc!WwC|P{ zWsG)mE`veSWyWFPO=`;W^_DTbPoP zu2UO1l!tQtPg#fGYuOuO@&#P^a#OqA(=l?A&nhH`RxzHd2-F=N0=c>D(ExZU21*IW zKpcdD-EBjVN{8Hm#32w_Tk)*a6zoChjvlWLh9m>rI%6907qzP#?zL;SA z0Zf%MXPN`tK{%%x6bm~trHOg;0@76PR@6HYjP8fLL3FU}QDX$HOi1*QySO9j5^&6W zZE-wbOE&v6G1xx%l43j-4UME1gXjWKpxdHjNWBksS`t`tRZX$c%hFsA4GcNJG= z*Lr>UU045S61yUPU@{dl^g=<)zskf;pw@2y73c3{jNx{%{WjWqCqC@WANn;q4UlMp=GTii6Mw-5ki<1 zzjza|s`(OdG3h@6z8NblHT(VMU3ZF@(E1sUk?o)N4qI^#6=TZca$|#cB?G63r0I_&NnsNIyjA?9NJoaTm~LuImo*|7BnwPx#*h zxtv!(X2nn}qy@4LfVo9saO5u12oM$4X^odh`rN|XzV_8yqA~SSMP*yHV1{4TQ#lEh zUmI)N`Q$G;{PQg&khjduUDJ$zzx%&V6&{O>LmDSPhWUgLX2yf@yy4L;epqxiYT?)J zF^HeG@)v`^l0yYIz^Lm^dzvHq=H$7nE@^4~1zt{DTmA0YdgvMvaQ)^s*_Fl?yg#W3 zERhLl4MSP-?Ge@$wdiX-$P1rhdlEcl12D0;i;Xcr`MDR?fAt%~6%|D_BYHIi@uXl7 zvve`HT;oQfprLUCgaSR~hX8-z;9$JnTO*6@(w`2%oO;S3+UI*vWG<#l<-()NzMLi; zNW6Xf)1{3`V<}b`zK)@8ZLEBSt@8foQ zC%4TF0SE<-#coL?nXnkI&kb=`|8!GH`jmnH*Kh-jzWbO{J2WU~T0*BqV+5{v;SAmo zY`V{LEm6RR0vfe0ISGLrZ_-MTZ(}w44}H4YKQ`8(rE`@AfEq;Y{QQW+y7+vfZpI(F z91z|KVgg2z^OL0)>Vag;>-pDhHP6QjiYp&$`eaigDJ?DrMi<*{s$B?2pVrtS1# zev$)PSIFL|I=3&UOZqz@Qd`ub@!2SMUhq2wcYtN0qF`i|Z@N)|RnWGrFr(iI2_TZd z9-Ud%nc?|S&ez=JUkyIXAg6<&Y&cXkbDb7Q>G!Ixu-7%fQkS;ALmDWOrGPW|qGQ|! zID-bgd(n*G>cfSUM9Q9t0QO@k-(JNL$G0UKW1(Qjfdv&yIr@R_zvXGQd~mfi9G zXdY2b?Oc=vha6aIG9gd4zy*~#(PGh5!(!BLfp(?((w$~)ElK3rL%>$ox|{YVSvr4v z_efpyH_k2#Sf$VftA(Bpd%ufpKC)+_=0aQm_^Sg5AurumMqalD-0+ zei#6A+GGLRI{qtLR!`*7rezqnO=t+wTbQpsr6Rio*%%FNE(@$aH~~ z{2zcPubP6fi?3spqHS?2V%ayp#4>PS&53B-a0dE{bG!UhSfcpcO`vJg53I3p`a03= zM~Q7gn<~`CY?HNMLxcDcgIoD}-!*7!2(&NtdiRK{xU*l5;@aZX(~G`wZU?bdLodt( zV(V03H#Af;?)}~z4x@#kzNRKn6k`wa!K;7PMRSnn+fAyvPN7hi0L~BCT4%5}OgilF zc@BF>;J)XHflSRn>iDhvmTkU>_T)fvdC!!4)EtVpMRDp!hk^8U?pek@KNWT zJ0Q??psp1x*A~tY+@bSk#8?ONCf}LDwW`9+)d}A18 z+9$#BFG2))@x&Wjc6}Y%DIy&P{K$arT5-5h1AA!^7%JTnzeJd$OtlMvy*4=k@)iH7 zbO#0^JEyWX8AN+*zJFnHRc>xcB!S=*6Vy5V*ZS_?y^?}Y#ZCa(feSAjO}@x4v|NfX z*Wn}--B*qj-ctw*GZ0d3DaHrjg}}sx>0C&mf(C3d^{b14NG<5m|I_YN2kr+GSRQSR z>yCoeH|JD-PhN1Q);B4uJOiK)p}>XSQ&Hd53%Z=BBqlz%apz#u*e0z(+GV3Mxk^+`5T4LhM`>B%a{4Cx<{w4bb4L- z8kXgj+KVv6W{%U3KlH8pepvo+BW=dt!oR%MBrYW-ylr<^;c5NrRcrZxfB-7x+pe2O znHUoyQa`jQTOaj5y24cpW`PmFes>za{+x*=y-I=ZeZrPK)Y;o9V_-|CUGfwyMdc#7 zM0<0BSO4xx|Cd+b%S}x>lx5E>=D;pY);{?iO=QFl?{ymSM9IDOm7UDi{$08ld$!Qt zPnvfkPS!Y;2?%lu$*HI7y>5s`<_%-rl#7^P_r*?P^B`#nrhw%nP$J}D2SFS%ikZg8 zTd&kg+b_?Lt8QdtaH2HTI;B~SWs3aZ^j-p(} z+*CQaxh>WdpWW~$hr?7-1cF%kNZz16j9xTr2W=2SW zjAB{{5kreP?`(pEPvTzjWO<-TMTY&8=x;r7H^n&d_vhz#Hic{p!;>qln{7$@zi6=G zl)L!5*U{6CIv|Tyta1yV^&MN2AE7;aYWzeyupft{zCX4dJky~|PVEpc&i!D63#y}Xv` zwZg_tJRR7$Gv&?se)J4i8vH-TtaiK-2j8LOF)-;oUY}vKj+AAcQ6v@82nP3;;Z6GN zGs>OoyDnI4TKSY%v-HEC`-{=;?o*nKf6Y+_3{}1w26kC!iMF|U)#UDF@Y^?`VP<-U zo<2U$9zLZi=El8=(ib2rftf9G%Y1{pXaQ^XHtcMk@FuIl!-v>r%iYb%T7_y)o-m0T zSJ@jQOgW6*?>mCw>Ke!H(Z(-=*ycBnh#13qy*)imre0se zWuQbSA|it9McJDk62IVhHRY9iVR?D}pvP(F@bGzTDPidqBeeSKm1vcK z0a6-`ej$Xscovx0*osri)O`H>Bx06?+NB0<<+ZriufHC*&K$=2*i@>WN>2YOBI5eb zQ#|rJOm}agW8e^F4P!Cu84}AFm7T+0N^>IAUxAS5qUvvzy2%>DH52ThQ-rJ^dunbO zj^ghh9i>dw4wpnEQ(lasqL}mxPUx)d|Yi#$ZBR_JE*JruS-q3}az`RIrh&Fn$4XAKM|(TFW^aYH?;-g6hd?BlZ? zP`*t>lnFlR5XCES>Q!1V0@v6!E)1_0Hn)5p+IxO>Ce!1zGP%v~y<>W?{>zVd?GSin zZC%|nTLs?ls@a9)x`vIe*Xn~?$D6LqI*-?;X;U970rM$1VP!aCeSWfa>-R9QpJ;XF z&NNC7vLD&R7eBGPxA_^Q{O^jcudapy2Qxhw`{L;G(d8)xps%nPGruo(B_!=(U=zw! zCu>s{F-Usi#x^62k2Xv@tLz7{Uk<;leeeLN1RFA-Vul!O4ZS0w4)@gZK&WqEPU(*g zTc*W4G8QU?PudxkPakhL;KZ6d?9n?genG)wRFB+9)IG7^)LR-30{Q|0NDuTiZYx-1 zRDt)!Wr>MX<6^BPPn}iHYG?&@x(rf!dB995?~1E(A-<51Pz1rX=GX8)abH4#m#(Yb zW%&AnAEY;5ZWv%q?|P8P#NCyWV(cO%C2lgg>FoTiXXY zm-el4VL0FOPLuiHaH<=0;OvJWW^nRGX6J+Ol~4UI&t-d@@_*~Y=Pf#+m{8zwBtcHX zR?x~YKVl$aN+}U`&IwF%KOU!vUwd5K{C0g*-qO&(U}rJKz=ksVp6CJgXTvSh-%XGZ+r%($coZ>pc3vK{C?8&mpuKsg zko6F*MIlztjMpO|d31Vu)M8h>>0JFOxb7XTPl(a={xTgNoN|p|i8_x~bKd!%vXzD8 z?J9|gS*M$>6}SGxrD7&?hGhcjTSAy(B_X>wjOlf~g?_*UdiXe4biMymmxqT(`5Hl+ z&c}xj7IU4Y#g;wRe#3WY2uDi|Z=|_7IW^DnG<^g0Q8WKZGumdVv9mMZbv=5*jhVhU zhnY+a<(CN2KsT1n95QNZ>NjcpI5yhF7J7#Dr%Nfkx|on({oZ3hyaM_~Q8(b~ehum} zL=fk|m6cydE;t=@kmUM;-&D&GN+Kqfu5$nCd9*=omX-C{=@L8F_f;@~NoYhi$UFgH zpg|kHv0?ku%h=f1QIG4)cVrZ8GcHh@@-;CVF`+1o{R@Z=XMu-v?WmO?2^phT_4R-i zHhKxrLq}KFjkJJ|dIBrgy?rl!un}72U56A<$iyTdpyfK!)rB9M_qZ*;v?&)#a=oc& zdD;tW?+cYr17G2oT6hXW=|@C_`e7R3dBAgh!*ZJ$hTGu?BvLvwg+%6!l{>8G$;n+= zMJnL82BuJ1HVT)DVh95FTOZ;2sjH)-bDdEHT_aCLw#Io8N+_(;k6(g>{(HwX_X5YT z7HI-rTu8}dWa9369jt*zo?6Q*Ws`I1S3u@?1SRns&JX6wx_LpKLxoeoST(p{LJx56 zzZM=EEYEvW{&Z(ysYm(ryGk;W^o4wE)l57n4!;){O;=+u@9I@Yd%0x}ukQTFo2Ku7 zOzmzvL)dK963eD4XDJ~eanEUwC4xaL9=PklXcB+FwXi{>ZxRQpEh7*&{7nWZ{@E;@ zI8P{%^x)+Ij{?jRlw+k)RX4wxZn%s2kCk8h`A$tC;7rr?*W@H^=3w5lu{U#13aspV z=TE*o1E)>Zduh0i3=fmbh7h%uQ}bJa48N5o*1xMqcdzjA{>lK{$qeZdazj=rZ zNf6X`pC44>D|#-N;s9{sp4}a=kJ3J}31l3d{INf6dVRC}h?&4FJt;Vo+^z~7ul^QjO zUcY^#)^}_e#6$YDeS1`j5c7c9b3MbjL+ZL)Jlmi=L_xlbwFm6l1Jy576tHVJC!!Gc5&)|={35<9yybKuVsJP>5byDr zAH8iE>Mz*2qdx*(I@3cdl(FbZC*>Z&F|+wGDubV9c6*!0iT}BRs_G+Gb234@sg5{@ zp?s3p3Y^IT4&30$iH{q}pB(Bew_K=QjQ2QCzR#$Eu0N7khHeWRfeph0@5TFxo?*U< z1wfY^pXvwkz&7*mM|P8mdp*fQA;d4_KR$d50kxW%nx}M(QLo#ScJ>yPetP|{z`Slc z(oVm!#Y~Wyi%Z4z7YHv68QI<8d^M1fK5DS3zSJ08li@zznr`i-mjd+`Rl;L1WRTRiTUi}0apgDjRrN&iPQ|i&9cGB;o)I4g0vaX z-)Am}uuNMR8!9J>l0R<%0OHoYdnBTf?LV0xCGHtYZs0ZiRM6q%Qv`}p)+B43K~~mU zjeWieDW+*Z63X6Cfl1(MZSmTF7aRL3!~3uw{O(JQ4M~={#seS>b_4no=X$JJbiC~z zme;(s-ivpDRV^QsklYPhLh|bO4agUZrR*|?gCZWMi((mlY_2FAy*iXC1nzaTF{xDQ zL~^V2HjKN|@MS-mH2fP+uMzFqH)@k5m(~gWO@W4-@eKHCk=rRZJnH)gfh9A*{y?mibsTu7M&ie6IkA{ zq2MdvSG|IP!fg$j=A^E+o6gQ`9QCdQs&2i$AnJleysyK|1jQ-~4I~`?5AIXoL2wc;&n9YCap9VO!YT+ zma8l53EvK^8&s6+ayT3wIBxZ=B;A8=QNP^w8c3UmYoiGu{V9B@jQBALr?kjyCA7w6hPSv_8{mE3V53fI3Iap=aDM^KT#q3FV zzq7$R9ZClwKU%4agBzF2X~d^iXt>S^Peesw(do1ZeV8@qjiLv#GBRN6BSmc+iBx~O zA)TV9B&H-JCuaT9)z$r$LQgMt&$mJ9o2v8Can)YTZCSbZjMr(;93+ccr%Tatx~LoN zQT&TiXD82Au48NNm)-_}>zRB+_KpI-nA?00MB81%7{mz{zFaA{XBr{%BftMa*muWc z-M;-__TCwhEqj&<*}D=+nVFSPLRpE(4v|u+Y$b(|k?fJo%xu}Rl98S9JI+hp_xuviT?G81? z%GE^8wZ9XSG-i7!WPn-&JR9nC{m%}7g&5#22b*V6pLi^+bgOi&OyO*%87pDVlhWX( zNx-kQ{LdA<1ZC!CXYamhe`&cEOtT~;nLJt(u9PFJuie@f2=kOHci+RV`Hw)d^ z$z@pCWZgMrX1;$92Z+RU#1gkYN?;U$^?$OCmk#EsHz?1(J`)KKOZLVhJ}{5IclPJ& zk6a$u_b63U@=Et90A%y4(^f{xxMroE0y5?$9xh0nSkFpB;sn${_9G7J&#UWm3;AbE z8Bk+fo2P*a$hqH-HNXJZ?0!-3=~f}kB9`Hfm3hn$;e^S^t;~LDi1L1CZxStxJKdQf z1h2pLFCn8Mw-5m5;YJ2B8D~I6p}xMjSNgMXa*~ps05jVyj4ePhDcNPnMQU27m3iO6 z4bra~?vD39Fs|^elfvTx&Gz;-?GbMOJ$__9)R+h3qDg0RG4~>fNEQ5*6zoAzz(5HhH^EGcz;LsG9) zqd9J9S>{ZJ@mcg>#_H${KjG%vf2ogh=q#4TPb0WH;Bf+B*uMoGTbJRvIjWMnV5%aQ z>xxH}gYnyR*W@q@-gVs7>SUO8attu6MemrSHz|wN{Z257!LPtBjv2N)B)G1BAH5jQ zd1_uioU(5{RZ$LKQYheGaq;s-{i&y?$57mXt<Q&ZLf-7I%1_%u18tK8292;-gLyD; zKRQAHUHXDpWad?99I58&dYGXJ%P!#55Q0AR?C`CK$y!a>n=4vaV0W;xQv5>qDS-2* zHzbM5R{|_6!_08*X$1EZ5DSppfAGMvW!lkV=T?g6PfAvce8W>k+V;@+{Pv`gJy0tz zvhS0D-Xz4&UtW0Vvcyqd!Y5Cjfbb@yuUcSy7YDBlU}o|l(w#}y+&N^$Sv_6JL!3%ysL^J2Jo4d_fbRF#vpvR-gFZKd-+B8O zbxSE8G^&xgj_MeroO_XxoHFLwR%-rgszaelct|w)55Wmg?ZhdXfM)f}&^dX~C%J{E zC`L+KePer5+FDKReAULX#rlNy7U43dVFvtWFHrR|DWw>EV|e>Uc6M!36GQCk@-o58 zj-=*GUWh-eY%h{&dEmhjsu)#94-XDd>-dSs<*z!RiPw$RL~t^lT)R<2nX-9Q#8@%Q zxHZ8N4>6?+D@2n$lX*#aK3zh@<%cj!IXJpevwis$RtHAw9`Nm=ajA<3KrF*Ma)enV zdu^t1ucMtywm##*s;c49QEt=>|E!Z442WtX?jWGgsGj3P$qJ7H+lRX{s?sN!QaaQE zNa?rp3KJqWX-1;HVVINV_ueTcTzWUvHFFsnrS3hz*ewgP&}^WQlwH5X^ojR#s*xV5 zVii;bjD% zOJ||}C4mD$&)>3EH7PuajNUv;T72hkpIdQe;Ul!*VGiL0?+_8v+}*Zb-EhW(ic28n zw26;ci$gy(mbKiotP%%AS^rQ7>78@`$=w1$7iE8^oO?`-jM)D%yZc%ar8Ma!*7gvlf*!JYS5 zOK|KR5rCTV-1=Q#_IORaMIJHWF<`rCSB(6%$*O}R&9SnH%7okE2aruDuAVCsm6;hC z@f8aquK?L3O3Zu!F*c}c7A@2BfR?q^DOrz}^Zc%nDxfcaZHl`K=szn%bh5yRZ6+c|l)U~CUV;p?$|pQYEx1F=OvFIgv|%R21d#YX zxoiFcgX2|i#G|!R%}NRpJ-*+e_M9F#90JDB;Mc6zuQf)5s%UG6PkN5mKZIjB`Q>E< zUavsa_t+wf1I&?&laZ6(2Gc?%D$WnXf9S6PBlA?9;Mg4>;3jEs*#`!R%ChyLIG6s%3) zj|(0=NC!%z#d7^wP{lx$LH*cX!}}00mS@SB-Uidko>m;6(Grk`CpQ#Ec*5DFaan7) zB_wp6^j;;nA=21nTt0(kvYE`m9T0^)w+J< z^;y5BgqoUo&k^+R*w5%2YFR%|Ndd3G!^5gAN?^^S(FRpvBzfzlIl-ey*(|T{qh_E{ z0x5KLZZJscW!1J<*@5xCJO`==YKj&X38)5Xe;_D7h2ec4Dg~OW)Brt(VoX$tSO|gF z(j7J=?C9t)#;&fcd<5Y}+<8qr^^D|^OA8aN$sp{cbOfZO2?a*%Q$nWBgD8a5TPjqv z)>n_Z1?q}}RKWbJDqDvV{L->6L1XTt7ZMjc%m5fI=|^d4=}@lm()Yd~`9%$4fso4y zm-vE`@Gv!Yctg?s`-v@GMmJpGQfbFY)kW<*zv%`N-df2*Ae`x8+g?3YW8pQYAJ!?J zqr4|A?&K!b^*NjX`vL&@ofju)vuuWyp@D8~ZYFfhw3gJoM9u$bzC#eGKY#Qa6?jbl zQp{y`{Q_=(srPO;`yLnh=Oii6u+E$SX`+&gkB+Oy=GFV zH}uV}S+?`4nsD1fou;eN@qs%1<0D0@5hEib`QF3i2P>_UK+HgAh{wn@`edqZP73;+ zz>kb(W%Zlu%s6jsiry! z+=)3bK5LiNYlT`BVp(4voE(mi;)-Bb2<#BH_?d67wQl|CSrsk)oj?i}WH4R3ejRC1 zk3@}>)5!LA&$?b&U*Izo!Hr9iqmNw`Gy%S(EMYZffHZ7q>+P4C6xSEWk+<-r`V@r1+9p{fR)NcYw)`A1?VfdN0h9)!B};y69B zDpsb!4+61|gPyfWrF`XbRHxH7KOV^H-oLC_d<=nnor zBsj1zS|h7Ke!J1HT`VG#cKVgL=a{BeEW>f6w*6Dzrz)znIDkGHWDu$8=mYM~91$O9 zk-UOAae-%7gCph~Gxx-C#+%RSSBs&5x2Nt6Z*OsMUw0WhVFo4C{iGb^Aj`Q5^J>T8 z>*(m9c3_Zsjv%vDJW~|BAQH1oFshS3e?9|6p?h&uM{E7vvr-DUKTsRcnMVRsXMBG7 zFIf_){#aR(9~Ee`&}LBj?k5{yo@@N@KF#$))&n2>*e^w{65}R$R|(*+!GZ(5K=2@h zqmNJx3Y$}!l&*EC-Fn$*LZ!1R-Aj zZ#C|@>5A6xEC4QO1i)!@+h%!eq$#ngoOjC$GIDD=TwGk9tLku8&N7oK5c6+;h~6{+ z(r$JMy+5TZhgmu^j6$VztT_)J)N?MistzGGNRzM_VsvzJa#B>8Slw0VpkCLX43IeQ z2N#g68hM}$y0W5@k811 zpXzybEz>S*P=$$dx&7~XkA+rVN-H_A>L}=p;V5Yy7geks6g4ZrfRed>ed5WY*H14( zisq`W$4$A0u!|Nyr_SG0VeUfxJDVO_a7m{-GLc|i`zMDY%pqZS1|Qo9%EIRS)@pEg zn6igQ;bif{sHuU?OAfY8^HEoE7$s=M_3a2Dq+mgB?AoDUr-R$p~M>Q zd~rjK3p}jgrpIFDYzMh3C2Zy`0F*@Xq=gFT4V}$TN9_99k*hvkjzBS_^tO{D6aqUF zg38Lu;5l;2$+6z_UMIjST~q!p=r5JL4Iikk1;@wv9LAH^jU-7n-;+f@W0N8K`uWJ% zhx=vB>)z2y?u#hhl23jw4LdVdD^uG?EBuI(ascc@c*56-jyC~jZ_yijbM8H^sPf$$ z@2%>nxsIYEQn3vGUvcjrO4YxjN4pNk_KaP%j}JzscE75}7Dfw4aqi6tpHdu-*nCVl zs73q@u;is8?NEW|6s_K^az=BGbF4Vv0Hb0=#U|^c`|^^RX>nh^2y|Zv|6IIu(Q>=^ zhGF(53lOzW#(5U`#FO2x9-ya&gg(PEHW2y{o`4v$N`n(1E*@;rz4n=3iz4QT;u*SZ*%9)PoF5xt0;@# z8o|>4|5O6+J$*`=W>nrOViLXhSELE61kURi2=RW=R^Idth(3J2P-~Xh$#@GDVe~n# zVp4_NNJchYzpw4}t@DqH+SA&D{Qb=jcmAPp!7agqBGy(NsUBXsRC|15A0+ogL&7$-AuM%S!+uAvTw6~^Ee+*WT$ z{!1A9?ptSJ0kJ5EAc2?&(sdx&L^B*VDev#HdZi9!%?ZOd);2Z}ggeb92Y>iE=%@f7 zvK_ZQh0XKH^F0^RLXjb5b9i{GDfWffOAI_}km&twF7vdtw}-|Yby?&=o}Q99rK`nJ zwtN<@?^Bh;m&bRa{ud)x=4-UqtN0 z2H|LsnQXu>yFJD2O~HKF2ZAu6k3_I9`7f#sa2{mDy(rTYYPEK;nGJMX(650he)+;W z${VIpyS6YtKaX0G+d?G)P#y&Pu!>{wUriHA{szS~Y6gGf=l?DFU80mW8o^0Dm^B>D z2Su8;>SR76Kk=95b$D|BV2z8PU#)p8*`)SQDm)TK{-a3EFk~K*azsT%kzEDSVgeuu zR6S8c@Y4?3`g!YO{kwl;9|Tmat$9bjezaPyf2hU2o1gQ!@+liVJ{V`>B~PFDqK zahvPc8$&`q1}@J)oN$+i1K^H?gxSNvH;NGTe4F#ZJY#ZZhU`#HA{^DpilEj3^INxd zGhf0X6*Vu!*UtF(K4&6&(Q9KR;OWFE0OwE@svrnqA@L;JtM71%XU^A8mUlu_s{$$Z z1K?UW_wb>_ganx3@UzjAPVD45@ihM8mXJoO*mvI6CGW46 zd+8#l=wV7BgLJr-pI@7@0GDQ!f!|wANeQQPFe?(6&+{csmEp^nk)7MeFp!xn=)KLh zeM|zf0p!NvH4qd~y<}=?Dgo-fR=hMFs6Ak|Ot|q0kjTWDwKFV4ArCr?HZlw@oK zrBN6zj7a-*(!V-GN4*2h(Ibzb_hWmn4m!#%bMj2iGP3UTirAz4OA?L}(EEre=zsME zK#xOY333n%Vid@L0^mMLX6}D%qy1&@TlJBklh2|T9S&V32h{y5(IIAD`T+#K4`PPF z{r%@!Z-C(rriuLQF$YX`@B7h9(RbBlZ*3Yn=R?DfmbyW^8|Y|-1`LI~05Fx__75C9 z>O|ct$fBVqUPVM@d4OrYAx=(fz0=z&`34{G9e$<))pgf2Xd%OP~p-Yvf*jS#^feu&3Dut2D zRJ(TVEw*j}q(>nhcOaw*tenq--}uB;M7QE#ik@P=*P8l9vHh0|s28~OQiq0>{_aVZ zBL~J=U8z7!1Ox<@Co8ymBa1TPNSWxXY$F@}bNT2aQU2Sc7e@{-f>oW76J$r(ix-v`{ zAQZZFv1UuRBa)k@@*31Q{47%_KRNs+X3fz@laUi zsZ_JD_G3~v#k1=wyRw61lE?Bi2x5VtGjZ|?l0pL8qW*|YHwMK-yeC)@KmqYUUwDV` z$LI+BhQCcK_Kkjuw7>Fw3kE`e2ZWV@X%}J{LyDn+kX^22$2HtQ%5Wg{u7$Wh>fL54tWq_~83k;U35CIHw!JX0UJt6S+Ko0d$ zH&MtE*TE=JY`Kg$32v`j0($!uaX6{ug_NfxjWJoal%R?3+=eh!%H2T-K+-~ArNc^( zVOioJnMHl4vv!8S+~f@r&}h{zofV`95_20u2^GK6EdRlqQ^^0fL;tUW3ke#}A}fNg z)gQTz9yM_u_}_f;J2x@#(+= za?_JELz}4V$iO{#pwC~ts1PLnrwH)^o)Ad6D7&FX#>gcmrsF&?clSs_`^>_xR37Ra zp>>V9h4V{GAI4tkA(HMLD~$&|3yLUYc!{Vg8|NL@*47Z^gAfBISvvw)&w=ql`#uH; ziNf|xkPwMEDVI0_O-XtX_Q)7}X)F-Iq5!hH= zo#ukWI5jnu^aCXDX!+~Bf#fWt4@1~I4Y3`BBIwx>hmfYi!a}Rbc}qa*geVO;8OWp5D%>yMg_QlLIN+O9+xIh zNbcW%oJ9sh-Aq=lhsmYjUPF+qYua%&e9c7j%vC{8IS)zRlTUCVqlyHd->L;ken&Om zmm-x*Ey!a3GXi-fJHa+51zj~@qLA7{Z39AI^FREWED}1@B))Z*vii3A^XbHaZ4LtZ zNK_q@oHcoWzsqdvQ66_H=PMds>X(U6d(mm`__!oSlY!88cskE}UC z_IB5Nb8)E#<;Y6CTMOlbAbspy%s{lW<|i;XRkDiG$3|(75OqeO1nW46sxKkU4UotUGJ;SuCdpv{!dv%}y2b5-rbZV_bImVA|#X#r})vSLvZFJZ{ zh!8%ZSq|nn@Ms|!^Z!+nu_hA}80uUyGsDBTNgnW8LJYnipfIEnx%}Qhqt%5&EGvUK zl`3TL#wYaD=r?n3iSe7u-zgxr_)yUKHhySL1bda$f%7#hvs&w4=Zf(-+d}?Um$Rkh z*+9G!H_e!Y9^zN$|K`gid!jJB6;;%&Kjs%kGc$+KaF-=TY)Z%gCxPjb|Hx_1!7Q!# z^irdNkn3bO4sV5TuZ!J@{xE8;gBzmHG?yqaPM$cjgo+AZ1U3KRwf^+K-0_Cu0Y}1l zz72H}Y*c5L!7q#itQizT1~lRc%`lUsJJ1p)R(WS8nK%`wVAv!Ijk#CAtHeae4PmpM zu;v4lE~%A?c&&BF%J>ajK#}OBC1+I)b<6gTceU2x?kNT5CK>(siX0c@-V2+DuRA$` zwnh`1dG7rI5IjnLE;&KUMw7&X=oG!rnvmn35C+VMGp^jGQ2n;~YE?qV$oAIHU73}I z))(GMn^$ERQclb=D!^D0$3FeLk2E@7pGASaKcXszT->db8Sjv|fzqLGZD<||8$&ru z{c29(kxcVNexnxh+Sr}~t6UyE;+2^h9}f^nOkA`33=%B1r{wOdan4IZnl+OoHN@sp z4YQN*dTEr86Ep4^z|T7So$CbwD<-)8*mvBqW%soqP8c46$(c{s^iLxLj?(fpBEx?R z+5o=bjxfNFSdX@PUqp%`@H89=U0wI>&G(a@5XVN=_OGzy|D6Yd&-RCy4ZR$)9*Tc( z63G1zCdh-70)sft*ay8N56HF_&T-5tXrucY{+<-Vq6;riPwF?iqku~%VOP4~o#}QS8;LzKxiHVK8%izVv$h(9H41%!*>E`(# zKOPhqwF0W)IKoFHw)bif26N;gi)@MP#iIq9Cr<{PrOsOBTfxSpv5L69BrtP$Ra#xN zxB*A@xZm)oTM51KcThED=Lkrg%+9~VszOhpfsK9rdO%L9sGy*{y1JQ(-$aGlLRsnm3k+dHrZ0 zhhtU$&h87TZ-;S`KBHy(rJsb&OPWkDNhlgjGZ`_h^dK9%X@N6o%xWqxFe{szP zUh^F=?nY)>lP~`4`0;;dc^X{vMyB*$mS2`Ea9w_i^>zp;*utQSq@GIjMZXZFZ4<_& zVq~4}3+w=_NNk@OUj4{Idqn6dns|Z-(N*#@dhwr{u2HM($(tdXp)YEKTy{+U>7u6F z`~$cx)t~td+$K4^-gCL5h{}E*4wy3AHCW4MoDrd~Pf;Fr!?@N1p-;f`NlLc8L)Qy4 zURs3QY;t>cLLUYN5yA5Zt;6ZzYX;J0EULhs3ZtUrvwM-n*Ov9)GLHx81Ioo)$50Y zT&`Dz-{!o9Xz9AXZ{TR_yTMCu_YL%bw~%E^my{9tZ;N|z-@xqFIAin@;a{|tbF_vN zMEV~2GdD-pNKndSpnwyb^5Corw1fuTgIrMBaXCn8N5cPFOZePyxMKf3XvQHf{yRDP z>2-%znIQooVdVvymN#BE;Z(>1uZ7&N=c28f(e@S@DQVWNFEWiG;Y#Z2fs>vPV**G2 zHVmcIv!<7Dlz!BjmT4Wc+YCHq+2g{*5iw@;lT}n-34ME;C-pct@J4 zf2C6kQi=CYhsAY-1cOGBBJ86Nf$Zx4H27bhY5H`+w{1Jl(W#)YaHJto<>FTLGz#5* zp0+CCOaCf;=GAGn5o@&v&PPc+?5DhR*1%|{4&&V{K2M~#9m^mB&WcS-*6k0ULU;l2 z!1S)=m#2py@&OZU5N6K3+TM#ZYbNrKS&d6;r!Fi{cUX!)YlS>NQSQw{&>6w}QH3;e zZT$rk)7`{Y*_E_V5ru91G_`U-l1V@Q!7P!jyy=i}YORrXn?0OVg$Se8&Y(DTvzKG% z>u)t@{Q!vj<+q6qG|Fpg(3sY#{#Abzvq-jhG|QMa;_-JhxuMMa9|&PLjg@cMl9=o{ zMy9pMGK07IKeNfmuHGl9nIEw^+rMxS{{hKg#2Y#UOc)#Hi#4(Xf-nxRihaI| zAR?31E$t@HxIcV2VORa{oY*6K7c`nQDaGc^CRZOd*E_2M;hZy>W~L}=$~PQd>5!kj zrKYC@4a^3TuRd8f7e)xIHEM>6TxOzgWs}03BZ!gu8MgS9Nx5Zw=gwU$X|S?OEiNO#JwdAxELU=@CF!5M0{a?sL#u z508~WQAil9%dHNXgq%iJbYpj^J&Rr`z#D3=44coXk-yHsFVOo${*1|yf5go)AN?IZ zYVAtGRXns~*TQmla-~%R2{}#&Vo|&cSiD-h{&!sePydl?0K&;rH?90})ju@N=>acs ztOP4$r{8Y=RQQkFvA*O#a}|&MJF1Hdq&$C8{Df?0bSrlD`eq&i#vqiFO?i-PuEoO)whiv|?5kJ&8)vmS9CU?`f z-FA3lg3l=@={+bfFf4fMsH2a-VB&d@1<35WA}5-&VDiwA0LSFk<{g0@*Ya#D+o7-tFgwkhrC0@z||Mew#wW(?CR-B`)8w^B4DF(~A zJZcV-m!J0q9WPykTJpbOIm*Sw@-TBYq_h5aLOkRv$b%3CuUut0e1LV}5J)lBp=vNc zne&&Q5jJI4job|Ec+Fz}=HJ(fxg_(c>d!c3)oxc(GIcR_RJy#5iJSb3x5IbcGqO$+x&ugCL7?cV7KLY5{lDhC~ z>iiP@=@-1=JULbTnvsT3wzFc9K@p6jfDz576LX>7yRGCX;K0oRcM#(JsRL|@WH4(Q z&X{?-rEPDL)m1V5|3l0|(Qn{t5PHQ99nSR<aLooO@R{fri4$TNPcMF63;4B*iJ}8XJ zOt!(`68e4gPM@}b_dGKZtF_J`Vp0i{kR=<-`>*OtHpeT}q^H_|g&GI4N|}-uv3?p{ zERaQzpnQ>pLg!Gvl42#n{h7EgZ`s`ucv1sfH^ovqM@Na0{3QDEuvuv1pHIK z;6Ega6&BOGnzi26c&BiD)-pMS z@a4Lk=j?7R~b8yRQ`FD1uNVd#S+7H1H+f|r$9r|ns&?_}{Clto>M+Qi=%JiDUbM4b|G9U0ur8m2>p8w& z;{4w5SwV4vgrGieb-MesV=&F5T(j_J@}+hq^sMb;08hr@LY>pfO{joOG{>LUMt;s! zR+vu!7u*n@U(fNlcTZ7f#Bm!Jc0`mfxvW5n0XAC5c+cNPZ@EmL5u}4A+MQ(I%uF#! z*$7zI@Nn6#S~HY>N(U)Sv4<(DG{T~0=f4A?uxOc@AF9A>HG;7d7^A2tAfdYe@A<<5 z9q4F~IRZKlielhiOXwBb>^CP^^{ew-7XpZVyXonRvTGi7UzU8-eKU;ta#(kk50_(8 zKytR$IDtWIQo5Y0|X^&#cbT;HDeXn1_B>B`rFz1BP1n^!v@ zxXg|6H5LsnziD_Z=GSGj(3e?8JN0vAhDbZp@7=q1jZL2`%+Crf8jHBj^=ZsDOZr7d z*y0_=teJFUhT<*pd^{Deoj!0yUkEhV}I?Ngb8HAW;P;!_lBmOHn&yk-vDTjZ0bo=tlMKjhvoz1K3)vit3ggOQ~bMRUqo zcWiodU!k8sAcibCDa)?C>i>>rX23fDP<%{b-J4KkB zJ@&2Nxf1+k!H>#)UzIOT($C+A@RcOQ-A z@QvQWEa=reuV2vh_wWG@KareFljFQsH!mq7f@+DEyTh(J?{X){wE@{;%?G6}y04vW zZKOm9srD+{&sf#u&r)aL-hc3Xhx~`I@gAHUTyfX_OP}*aDcPimADHQ!$uKN%v|Q8n z0ND;w=lE^}>>97>zx4NKU7lkD_w%QS%z5!exmBDj6?1Pq7R;s`Jw~(a`-gi0EM1v? zUDu>Q$cx-gW|K=e!mQi+G6~-N?Y8Tc$N7YW$g(9Q42vCUbhW!-PF=?Dww<>7Xdp!} zar}uWI#Jyud|W@j)UW=l-+C!R>-;q$*p78F2%N@mx7G@pdwvW)Vw72iyXg0Q?imba z=Ea)NcibmW;a`^IH%-Y!&ka^zwOp6ICGX^`Ihc3z2uuQ=d96A@!L=}~5`CBVTVK&* z&B3ILWW-6qy)M(W-?UgY?`q{;>7X^gI-r&D$+x2Rd--=Zi9_MH`X(z)Fy@|p z;OVEy-jZi@{q&v}U{Bh?N384IV@t2vhw_ZUd^q_QB_!g*_uVNU;@Bf*)=%>N+x7Lu zi;kSkAGTIlB1_G8wuhEvqJ#{ztuKW;O|00%JKuy5cVwwbO}IE2!jEdL_Z{^hmkF<$HF?K#8Clg=H{I8W)~a&&V;O~BTp#^N zF)3}94d?d3{rkS+Cj2+F3zYDP6Aybx4>O8oaR`!{r=L@cqI;uXBGc#_V5}_#Z(GRf ze71XqGMYVji^j%>C_I*CyPDw<=~2I?U!CnC%V`aUvFJKuC|heM<0%J^(Y-n=#0I80 zp;^${ntPowtZjh32!uE}m#QF8jUFxvW*Cb!#UIsq&MxInohuswnI!Zw#||CH+xa=y zgYl_YGkD?{LK9 z!O{NKUy7H+!66`U?Cn5%JKaG%-1(lhg)`SHVdn(I_aCQ=oGTEAs(R9X0hUm2ECp(3zSPffpBs>4a`D)7 zpXZ1yg$0ptgHz4?nmVh^O)ouGhDyg7%*A}zjwk0}jpm6HDr1mBgV0jz{2OZ!-AEYh z;5}+I*{KowEhuC;ye~t)AKOaM$2w30t$utwNlZmi4ar`fnNWJ6KWAIrj6$z|5S8|QMSU)u9QWN#m&E+WyNX^6kmj-yt{BnHh&Sn$-kF9#{ z?^o>zp%>KmAFxr3h?9#QYLdS;=I@us>?!NapBFRVG<(z{&oKC%sP)><^P8|>x36$* z3YnLz;QwqZ3O{#g zhtFeWnxLdr(S8OA^f25cm9;~}zCF~zVh+CN2f2N z5HE!j`-r=qgi-Je@%fK;Up%ENh0R-V)W|04u2uR4k_QHkrjGkNY&ns^g#~yQyu|K0 zg_~R*R{wA+mrS6{ZbOlR)j(P38FJ=5UXAx_SnOKxE2lGa^2}cGZuDqx-YMOc{h|kl(-a=)waGPrhj^2aj`PJTrrIK;8VC~MP5H4 z?-YEk5^}QWM)2yyDvR)WEV=-lHM2`E^IWnobzL>o z;+6GS(tMk*8Ob&OOrE0j0dK{pPoGfNSgO^Xyb+hmCZ$mRntm_&be2P5nGclEFcyq! z&o_}%ua{S&;Sx3w~ zW17CD(wRNF+69nyYFU&eBxlwX;VXuKUw1m!>H9k#j}i5$44GKFYUIA!UFd5s^qDSq@yGyso<*$%I5a=hlxde4>OG=t8us* zPNOwd3gzr^YEx%~K2}%XrhG`@#gj?K zf#q%oj$RKVBB25qU}4K`kY>sx-;N;kY{DZt?PJH3qDA(Y9CqMsJ7UvnlUL4Ta6J?xh-M17c{Ic83cKDcSB~Te`1-fixX>6GQ+4Yc2MO z_hUX2I7a42ZsNls-78ZRCs++oi~-iZ{#>pqScta_iD%D4*k!71|2%Vs6@s9dV)`cs zZ&G!hVuAkfW1^Xch9O++$Q6!ylCC#;M9=~OklH#+qC%5q&_=WczmE8C{MVxa90Ek2 z?ri&`s%i7@vfp@D=Gf>0NIKttX%yiWSx0K#5;oYW^I#V$XvGBE9!$|IYPz-3xEDan z8?(rPtWlUsg>agMwx;;;D1Ly~EAOG_AVeD{cVc`n-XMzYiIq61_}y|s%npLrdkR5ze@bNIKPZXl_tsZnWO*clkRfBf-PQ%lKby01>} ze-bOLK2jAV&T=xOq-lF;O3yzCWRY2m0TCFkw{UJjZUkz}4bwq$iS&-hTZu(fB)s|V0JHNs=W9a@s%-lB>HaPrDP z0m*P;B78+wbqKwRMaw=<8M{4zd;oFzK{URK2+*P4=BBu9{RKPe;dq@GAMFNCd3m$9 z`KJ<{337`f|#nuBRN4&af& zShX3D7ie;hr%%(WDwT)Z_uW~7L|Y(7h)s8J)7*JmTif8LN7yfSrE`X8b)*~7L3G1) zc52^iujOg_M`EE$OG#=lS{;=R;Zj+Mym_pAA4lv4%)~&K85$Zk?WKe17wYa4ciI5E z;g>s5ZIOEK3Z@#P>Ak?8kX7cj{kYJAeJ9K_1YQwEO(NhG^os6Ku~%L>U^&S4Hbxv2 z_9N265W%IHn(4?SO8XSJI^b;%A3HKGE*t`qR%%y-;ftvMfy6#ZmzSl{b92KV5H&JS z(c0@M!@5DWPjR+(u*)Q$Lo1ha|9-W%Xs1>VE}jJRXavs7nr{8sy{|3tH^vF4IZukwEnHKlh;0pg0MIQ$GN8?#2@^8&9*x`@*TaAavJ)`Avv)ll4bXjx&+G>5 zAV4gpfArm)4?nT0v?Yw(HO{ZrtTijVd_*VjIY~_}Blj1UrStTXu>VMo5~$GGM{fP3 zC{|DFj+sa6pWxs2nwE?#1@XRR?^5ciY+&X4MiG)_3ELG!p5@zH=9B(LvI2E=#Ps%S z9t{j!TSXKs%G7F-w!Nx|r*h2_a7{GVz*&HA+_n3hj+4W2s;}^r$Aypz3s`J%w+5<~ zFEmz0nJp9YkAn#a|I}U9b}vu3-Lkl3mVWg&Y8{id#3EK9)ZkE;1vqrQ60JDn2uU@G zFw>UG><9tas@A}OE)>Y{s$#}ruzHab3tOQDi5m<58@7fNH^sqv8+(&?mDco;_k{t& zrW)wtH$H`-yBb}Vfh}0H3X3ynX=!;bgQkIQ-|OXa*drDgKDx&Q8jJWg#m|pF#Q@=X zTY5_|t^2}vkAU^Ve;9a2)V9?_h!aG=XaLpcDL>!2L@Tw)B@ehUcUcZwTs4$Bt*5tt z=0p_#ZD8KyED|x}p!#@>5j*dTIQq`vL?;UHZTdG$od2rj&hSDngNc!G)njI4b@0xT zio*KXa;KWDOyn!b`YFF0pKoYZpqnaknS+sLd~g#`VOCbgh0ngwsfOe$nhYd}pk~43 zorGhLw@w1k+q|2dlJM+UJqZ<)WDCjn&q`+3D?yB|fH32$62tLBe6qWc^7$jWQh>Wd zl22vF{SV0o0SiDK{X0}+xy-7__*-0UZkt1RP~M<6?ZS+qK8I4ywj*A1a)v7Qspj!b zvT}zG(bEiHr@t91_ooQ;7qeceYpVa)dnk=Y+FRc2`LV%5{J(?9GPJ&QFt`j$)hT-)e6Ze;4@>s*dky_nzLm%*ft*SQTk)Pf1Er^D0&PwFA-f&Cqw*GQO#~LE0$+2*Kdm;=6@A@l0`Ak= z)`%L{R*gy!mugyKzDwd#?H<31H4U>N7dp((d4fL7n!{@!ug!z}92(l)c66=91hH@v zZakn14+-P($QCqBkyOrw`*5L-q&e;`oXyh!6D)S9U?*)z6UlXEkvHZ=yhcA$j3vaS zh~cBVAzk6UCjqcx^X9nyZD=mBScwW|Tj5}QgaIhaAs5uK|LB~){3BliDG)z^s95w7 zH^c&ToKy3mm1P+c*wwA?BG*4Pjf z1DxC zbI^fe)c>Jkm_;no3!;{d06mO%vQx3~w7r{aVY99XnLadm#gvC{KX+qFKazQrR827# zylv^l(bI3ap=^~J0yHSyuyh|RM>>5$yMQBMi81ZGMubw0Q-RmaqYD`@fcx<-d&HCN z?a$XLCz@l4GCTf4e2P_0{HB4RHnA^wD>nZK`9#7e?@0`1Af%URr(kIxj?y08BFfko z?_cV~TU|9|I_%J|Dp{OnP{sy)0hU)Hf^q{AM+{=;{JX~`YMbtZuKfPmMKF_Pyw?(c zX$QXrqIk=T4UY(3cIkfk)f%X)@=JCI0L>B|##l(vznJiU7!Do#fm*_f)qZqCauPv! zN30M^sDuI+F07j3ZXoG;O^|a|5vm|%p(FtF=3?(aXrWtd#i zVi^yOXw7;;+wc?mQQ zHuMT%>}>KztQG9>CRdNM9Q44pG`!gMFJZVk$B);SnWt-}nwQDrKdS{@AGK&0sa1Bj z;fKAAyhi5fh7$OMpDJD^^MjWCJpk5sRuQ$O(W6!L)y-57QnUh#ii%K~c^vN@7&l7) zjIPvu7#Ao2yfnTxs(rG=%;73MZ!e;2`)<2{zz@4e69~V;CbfF#UNkj}%m9xiV&A$j z7>}o!8g%F+hhAy6<$>523T9okVS@Fenn3v9nVAwNY1+>yBZ}z9$@0x)&OD2`eCHl% zd1yX~dWAB=xXDmGy%>byUu$ZkCXX9 zVN&ZQQ-x(^d1(f8tm|pIIfRYAJ^<{_2$gy)lQulAzGr?3CXhXnBYRy|z~e8b*Uk&DLTJU8DL1m z0?xvl(|Lkg3A4IG&%bhVi;?WD`E3$mc^PE_vH%WDJLUgoRgeHfMZ@bL3{RVD4T_~49< z)soDR6E01+_o3!tpzRJ~@#i-=b69&aC+T|SjST%Is`;Qxx-!zk|HcYRuiBhn(>n|l zlf*vK`{uIpe<&sT8PV`wvRcHi^b|kQ931-M#@VeZY2SP17iXCa2&HBziV;3=_62De z!@)ePDWLyKsZa41NLprkck^)q7i&L#s_x7zQ%|)4B^gBd3hx!+PQDl-fKo0~tAikQ zW7&v;#gL+nd$^r;cS8GUt&RfC)X`h>IE}spXVY5Og;4r0i$ovZnx38>4UIe_EVDUa;zG@W>Q<{(3oCYU0hVQI7Qtt^KEdpj|c!s5Y_YD?_>b^4jvL(q=_u1JEJv; z6Yd{sYIa%FQnv(gv>c0>nX~Z&v90Z+?jjoJGP=QzvT>2kLr}by@j2e9EwPa+7|b5L z`50()+v6z9DuP?u^ZtS6V6Lqm@!?4HmLel>N542h|I_Lr$VY$M=C@)?&P=tnI2x0) z9qD6H6 zPoL(QDJd=%7ZRsV{uq|xnz}MXMFe-?4mM3Nbkvr%!%pqRFSk4t;&O|?mi5@>H|I)WQ`~NQm%V}etmAbz2s*;XS@$MK%k(ph#Z3qxcKng#&9@&i ze8qbj9tm^4)=xi`&9$VChrXWTmzwl=ri+`)^9>Y^!EgN}X+6F$d8XNkrZ@x36h7*# z#Te&}=)iJ(D1%M2efRU;1ei)}|7ez|8jSDlRO@#rgDsCvpd@o`wOCeBr;{kXI{gB9 ze((hic$ppd9ZZ+NAB-HpRaGJ;O1R z^S~BTbVWlKY`o%5eNQw(g4D;<8sbG)Pk4grxK4~hB`ge+=ESu8NYDrqfk?OH5MTHW zXu+U5S}e9w$oxpN5?nCt^@cu1AYenR@BA=r!u05&~`8~wY>|j&rW`rwfICX!HN-SL}+OWb3bcE{o znR5c=XpK{xtw|3Xa)-~DGwE&gK>F^i?9+SL;`vsIy(wA-T<{nZz57TnQ9YbQ766rX zL-DGoQL^gUdCY9=6$4z0QAYmwADR)fZDEUu)nLS7(?WnR3`JBT#y}p7QAB8)t=LW7jX2|zc^(6}#>wiCJR<#ptURB2l-qh95m(Nvk{pJ3oSnM)Dch~wGfq_{NS&dl}D=rH2}@Wv=+pDa+Ur5YNzV> zdCXYkStvK!ALE@PyxE}pnE{2Ym__tti~%*=_4S9v$S3w11gI5q`NLj5+j3vnY!W;& zH#aw1OolgvZ{?CSqm{dF3!U&=3SLxlAzI2ItuOMf7Wrozq*ffTu@M2w z4VAZcot)*;-I8CM?=FltgvKn_rsP0fJaZ(EcTU%q1f$Hc<8qc7%V^3D?GgEjYZzue zcnABjuG?gyG~BXKZk|uM@-nmHLejB8g#ZcHr2Cc6=MCFEr^fxQ*(XtUlq>-zaTf#c-%JH=bKcweW0&VvUZ%NaC-Txw%p}X;iZNM z%$d=sTk^d0=mfj*D&8eamukKyv&6Palr4gaH&AGXVPG4MRLHUy^8;A<9{R&10X!M; z`NEm>ME5ixuu96jR6B9TW=xtP;AOgzfjqJ5#QL~$VRp{m*1Lyh=NVe;aEsh*T)*Bi}6Ts)W5n{Nx#zAU9L0GAS&l{S|wR#z@(%nGE`uXA8z;Jf%Bl$CQ8 zB|84FZ|A=8AD`8R-zzCd?BmoWS;?WjXzsf$eL4Wdy1(Ag2Ix*DVW>1T8zROZxb+zSdC8AO1 zuZnu068Y>5z%wl(ffAKo#(eXN!0JzcR=U}SWI38j6PX)(9zwp&Pj67cSX&#AbEUGOdpsK^aw9+Z;siTkAfoT z+*xpX)p#E`{Y3EB+u8&kqWp&GeZuhEl?tA}+!tV}bw$-#r=v#^|CtuI$M%U+@;NBR zfl*ozJqT?%*5kPDB~ix69~OY%t_p93N_sB=W{HhiCHF@;d!q{M=)lS9yes+*d6|vv zdmrr-Q{*a&vn1C^d49zEB}2||7SftRk==FAmE~C!3e|*C6a>?*Ya9C z@DO(%wX)AG{OjCS0;0KhJMY!_f?L#VH2QoY(d=$H7PO5zNyA9jnD*){;Bvh~~bXkqly^0Aj(2kH4MJjg(1?QtP#q6*ANFpuQ&kg|-|j=gREtFw$HXXiZ|j}Ita*lI3g3zs z|LV>FMwY(01Nb0TnI5W9fCNbdVCTunF)p?c1>cFW>oURNp4P0J+;7+L|Kz<(7i(qA z7#qwlV?#S61!iHMw!XqvE6zDTPQj?vZ8x^!_A1W>56M`+yK);=ku6*r$z$-v*J;JUw~O#$)h( z^%|lh(+EY}U8bQE`O)>qe**1)BwfTCKjd1lynhgRf%aWpUFcb(Wj&*}wPW~^|LHL5 zw&$;4_p?YK_zyz*;aw?yd-XOV z>PO}>N+v7;vbHpsZOJj?j!sDg|E+5UR)G)z zIi4u|!>MYonJos}`{gHINa!fNpbllwZ@nT^05l#MJoe%(Q}adNDdXIa%V?i)hUaG@heG-mr>Hu+xUIuHwR*G}~_}aELku2u{&h6Uwn%s&_9^>E7%77GWpN)iOx9pCUEgKmLsr$`C}&>uo)5$B}2DHX?BB zt`x{mPJ5oSM=Q<=Y&-*DQMdoA`g%?|$3=*t1QE)!-4U5Ni>%=#I16SHzVBaSoO@!; z9-TrJ#-6!M2=2&wr|)@gM$8w(rpMe;(zZi(n9Wt0df4=I-cgAR+YpeYk|pGp7CO_r zpRZZ1IHR5T?RAL)WCW*ApSE#(XffXykWfJOTnZEYW0FfhXEyoUiu zhGzgv{4KG46ViyiX@S@+;pab_7Bk;(E zyX&xrKoOaWN6KT#VoW_Tk53$m{&i5IlpcXVtyd+vy z#G;5Ml@K}6!D4qkr#6I_S|+HY!9x&QU2kRqwJPCvFi29O4t@tBP`hsgQlSa4^uR^< z>XPZ2==h^wYtAq7Q?B_(7eXX7@n#PFzU3lH`R%>{zAaKX36J|6V+Yb3*Rx?+s)3D; z?7DT_2-_8ed%&E%z9~x&AQARiA2Kn{+UiGXJo!RlP^gk* z1{gFW=$u*~b>F3-k_p6UDFf`-xYo~d3D`%7O4p|F8GO42d=SGGibiJ6RxBe1<@ zW}8z1#W27w{?J)fswu;Jv3OItUT)1Z3tcLSOGe6iPJWMeN`@;6P$CyvbcIAG$MT&# zrZ%9%0FVqPFp%7Hs07V@+qq(&o>hjd@7>Fnq;>VonO9Z=7epJ*PcDzysyNMzE)J1F z>va*YTfjGLRzZJdg8u5B+sF#=CpfpF^`m{S$RyVrJT5(o-j{;d>u~0i;NQvvEd%<8 zdFBU_NdfHWQn8(PwK_aBY&@_NUCdVto?m`v!K*cv?^TJW z?$f@va;P`|$m~JLcn~ z9g~`kzQO0;Lv!l{2!uccczFRT=7mkm7!&UCHXunaC9r^6Un38*b{Qdh1C=p>8SWD2t^Q4c|LDFH!TX4$li+KHm z_KXGK@Bs9X=qf$U+UUuec9K#iug}lO{#ru&DjA6Sg_&Ih!b4^1BnhqhFpY;r?$k#% z=oL`gT&4=yfx(i=i=|pAKP*Ld(qsdR6c=sUmgorZ7razj6TbVB;%%oeS~3LZM|-r? z0EEkIxIm?^pms+8sSvOLwMqhx)0Q;TOuZqB_m_sXbLNxSglLJgP8$ysR9v)fYKp{B z0(sr&8U)p>I(`JsbdGD|ArmBe(4AOQh>nPeS`xFMX<^W-ns|1-mOM@bqsGUVjrn;3 zaGq+%A^TT(GQ=-!7t8%Nm7aReNS?SmImP{33t;v{^lL$T&@g;8XD2t2UT>{}HAHxR z_FWywuh}=9LTAz8#BImO3Q8A(VWFH_F>c^rZlf|9wgqU0>%g<;F@PGzEBVhP#qjVo}??cqIdl~3}1*O!Dhq1SNO(lR|Q=Cff0D+l-<2`ZQnf+Q}Or!u-j zB$Qw7BA76j$>uen7~gkwEu~HXVr*dy)-|hF|7hZ3Av%sl4B#;?6cLE#GC#L}(vg>KuXLAg;NB8$iX%pMYkv#EuKrUC?b@ zUCmKa7et!_l5hS!?($$Y7dkLFt+$?+X$2T0$(+H6U^7pB8}HwfTEJwk0DEqIO= zgUKpB5fd^Va}D#6Y%ECGy3Z6(8s7g=t}6uxFwCur8dW{SgW8=rC!!i|rwUITbr}C9 zGdq9B>B!9o*b!Z-$vvTs{GzPcN|SYOuw8G<$dqfZrb6X$vMMpj13mY#J_h_sU`*sl zX4|V30qwGWcRfESdSe)BbP$ouul+l^;2jH6-MaY{4V_utlsqkFoEVs{*`8h%>SY8NcHnL^`pXJJy!YZ5@3EWMMJ+ zlag0fYZw__vGKrBvb+;HXn9pi$7%OKEwl?{4Q*cVHq9%Lc{HRigBJc_dD}N_ z;eYHs!t&}_65M*?&tR;8xP31%6naV6fL|FPyGJU{&PTm z{FfZe7HL6!x(d1t6TH?k%#llh(nbvUC(r^t*e&)&Ad0|VnznmxPxQhl2Cy9(QRE6N z<5vwDnnE?R2jY)UecboH?@o|bZb#bb^f+n!^`1M+Y{w_M@&>zboi3sI%VZ%hkVEMXGYuTkd?k*^^G(KK z8Hupa$nM{M<@eO7#|jlR@)|Dy(j~M1lCa@koCPPugN|_fRVly>3%0P4;7xTPXeh^! zEX-1@Tc0n?5WhMoqkCAUCcvg*pVBtEGPf@N2F-2TysPc3JSr~142{e~{TGewoGmT} zl1xmDmLGcbs8z=Q8XB>eygXFZZ?CpUBTQ&%{qerH3&e?T&CqtmJ-#zd%Ju^i8oS=38`7aq#S34bU%+l?yI)Co$0yZrYk-l8tfQZC_ZerW( zt1C>%*$! z_`6#<;Ve~{gBw;(NMNgDwj5cXw`5sc zc4as-1Xe;|(_j9qAsrg>ut!2?Yf~#P-U`AZGB1nt1dOQ;|WN#pI+AS5S+a<>VHe;N7>zAasS- zHEVhbQ`f3rJQYbc{|nvd>-b;x74jI~{2RZ>UD7XUn8uJ$?MwExk#7mWPvP$2Ks%lb z(a_<3Ly($f%V_br@P#q_fPkzqCD;91C6$wj{W%3v@mE*vuTfj@+rw?%xx| zWYTr#84hcWX=XCYF8E1X0jBX{M`?({qZPfnx~&_)Ny)fLDB7{c$==Wl#W&%k2osskYo|$(v zExdQnGPvCUdyg(3HsurpfA_oK)SvwuitvB1>93)T2c_ihU?t8{V}TL|Dio3R=ZIWG zIc+GOng;s+mN6mQ1?@u?V%lm(N-?Kd|FsCcxWVwE6BdQ?kGKm>c2dGi58ro#H9_&v za|Kdl_pUY*S+RBw%>AI-NTC`*U=geW_1$7qAMgQHRbyG2L>eqVkw^!HFD4mC;=FL+ zjjlcUVoOncLRl}1{DIuiB!$WJlzsPd@uldf^~FX4J3M+s^2F-XQqDJju{}7Cu>F;J zoiRNtd}wj_w2FJaRqxs)EZ!qK%wgEE1hYg?1fD@iTDB`Oh`ef|EBX@@Xp0S`+0-ci zmr=HqaFX@^9zn-md9ByG!B4s;`0Rf^M4^5-#m`I>Khed0)^Tr7QR`l zVZ*RQN{an-(8rw~73bIfh5-zglgjKr^`92FxPL+8`!vzy{W)idGkWys;K*)s(WktR zao9+=1JjcuZNUCVW)chaSNZ`623?|qE&xnSX$&)PBTTjF-> zA~FHRoNG2Bwhwge((T8j?UxANA2*S(Q~FbrGE(OvZ?6Hgti)6p}1L|6II}tw{mZS%CqH8DrXybn zg|KGgOo|2vv5g!~B~?lpJ|rW93`JKI7sW~7P^mGDbcT~>PWds-74d)b5~{~Jw=eA^ zIDgect3lrYRgVhP-t>qnFsh-}GOYz1wh1g8!rQWpjvYTt8qRvgbc%jlfm15#F0(sJqJ?L zGq1)Je>`8eDa~c#z2w|kaT|Npit1142m2o5R8>mbmc_EP_Nm;_TQS!(RYc;ruN%&oB64As9(h-x2B5kK;nhv?NMGs0J{qZeC_}J##pYEAm%o~04?J+Rv z12;X#KdtWl`TbMPd@nEe78yPau`=O|0;trYY5?IK8p$Q(4To3+7>bAN3I5N@LD-zJ4$hR!TFn`S7R{ zU4_ushgA?6!V+aHh--jjK%;c>CwPsixCX|~GjADVA1_NmZyrW@8KU6-3a4a+`)JSE zyI)$%E!M{2*=p@|(IlI1voCOx%|@Eo3b`Zbx5n4CBU@o$B$y|Xo6Cnf2Lr{K&#T^- zdB;}=N3F~K^y#K$L;v71Blo_Fnwr_xHDQ&_gI%du1=rt{wKcgr#Y9gO;}TeR5S`u- zV3!~JxhT3W>7 zpUoDA0B3?Q(%3^OvT_Lnyi+cYFwU7@78t4m#V9eE^jJa)guOe|K!(5T!(1vBZE~WA82|6{&Pqp99*)16ie9SOQigX!QuAITz zMyrpDT{wcm$S(R~qv#$*cpB@tpwS}l=?ZxQm(1Gl0W42#RZc$|| z%6Cj&-XSynN4gr4ZuD7$lzU;Y^X=I=F+e#!i(gLA;&V0O>^%5RolwuLfz5VUPuWz!xLk;8|# z*wH8KQB8V`GlRiz#_&8_>yb1=gUl2P*Z{9vQWqnVW)_*jGYztRILS{fcP(d5l48D` z@aCw~1`bN%fk|fH3jqqpzbbW5#Q>T!&Nb&>MujfZzZHt_LkuDKcMbUo&|_ff%w++$gCJAFnmRb`iFPTZHKJlf@ngkFew^H3mPvcfH4WA|})Zk^AjE zMaMLr#kLwEt1g3qelpne?vwubfaQm#%@4{%n1jxpyPPpHI9ML(Y`x}41;dADQ4k@$ z6~<|;@``)osEpTQFfl-{JQ=a+)DJeJyr9gzccrQJ03pxRadogZkUT4>%)L`h24m`z z;$E@#ybZv;Z2`jyGfZj~+uz?GqN#tYBVBJX39OI;C?$7Crt?gAOw0MMFE_}1w9Ua` zWvK5BIadORMyjs+)d`ZfGj=oOhw_OHGcs{+nrACdas$`zY@I8}#XHXz+U@PHCw~64 zbhi*;n!7+79|$56p;4T6L9M@oZD}qHeH}aU-xqB-6uFBp3#%mU z-ejbb$HX2;kAhsKDr3*K9pTfGyTjwv;yUm2yee3oB*l+Bq&&Impq8NS9P&g2Cq$SJ z9PR(O1B&(MH{>c4ztv|-9&_J3!m{on=S@mfwePcbuNQ!wbQU5F^}VKHd5~wW+#?hK zL~!wD)A6wDfZUann-YNRkV8vgr#c&}G^3|c8&^Nv8I4nNuLH^(3`%@#s6H??F1js2 zxy}lwP5DYgfSPI}aWhiqbmU1Rku1KA=>f@GzdN?$G!Iw7$ z7>XX%xNBc+S=rI87B-pVL>ua&VR=&`{l3JW{_ZaU#O50t3mYV!K7zWtoHl@`+1?wmGj?4MITuy_h=(fKy{(SdhQF1} zY{9D0Uyz+eL2J(G-nCDo)&-{V@L16TqIPP?rjy^v>PLQ{#fY{DZN3*m?H@2UZlc6$ zP*_x$;8#Vq$OQHHf&&Oq=61(%63$DcO9nbj6#C^PxPjSoc=kq*utK2 zX70>IOxf2S&VTRiL%(LREHkX^K}C#yD)*a>JV@*jHQOQXj$FlSkfxo=%Dc=}ne%DN z-Fapx$yJl)a{5b>LGh9P*Os<+{0Mq4USYMDe_4mcu&}ImJX#95(+ofx-bM1$ZnN;3 zS<`gWkFMUtwHf_VU(3GleVS%7LkocPA32OL zhq)c;Ieb#^Bcn#r3yi%vn>YF}Q5cjzMBafphq|g&cQ6kwCW>6&7OOby4k5|Ld5XzD zz+Ys!=6LIdKWZ5~b^;wR+^G3h_kiTmla@ULodY)oC|EV{^I58QWV^M+Gt&qsSxlqPx2;GdND*8s^%*?kI_33~he^4tGLU2Gp^}mkl-S1F zk?X_9{TIa9tL-N(pyB+S{X-nu<3%HVDtAlbu%;a%-jeU*0>! zCsC+ByVYxwE56R3DrY6t9@)+$XFtEV1nUVT6v(Y;p;Emw^NqgD^e~79Xyk-hU}Sb^ zr{bF4D49b{b@rHRXe2owtE{EHzV2JOx9C!;Ne=cWU|BqYTP8mmDB+~a9G>KjlMy5v zVE4eFH?Y^oXUu9qgp|-9(Ahd~Ld=7pr<8wFB&pAExR^JE5z}d^G&`Zi|5tB`Vo@ae z3@*uL<7sJU?qW*wWf^5oM@huLLq?hEB>riJPwUzv{&6L;JVfBBTkM4{_<^u{435ei zXYh$A)Ubr}S>m_1NvsThi;~(-YM}TNStCj(Y9v_NdgrX>46vN7cTDuMJU5f(os@yF zA&gW!zKA+Xy#2~b7Fg4vc0?N?Kjz#jW2|k91M7cuz())BcT&QazKoT^cv(h;(^2s1 zYSUSOv>taq(H@5%k_x1#5>L1NtGZE5=OI(q1h>WX{l^zEfl1rr5#!Od`IS4UOt3G6 z9(k%3##tY~Jz*}htF)-9cC3@Y`8E2pA-FxMgk-MC5Rry{Cw>XA_xt zLv#A=t10!Ohw}gA5ucdQ@AKu7OXC?4U;Oyea>!6!vD76&>tmcnckPF;uQQ9 z_o(@=M)&Zfa4enDEQ&zbJO=NZZr{$-T2ysuge^HV^r6-d=HwR8Q<1QWA#-BQc%oA* zqICDSwwD7!xE|lh;G;S>aiyl(1tY5dCPRPu`k?gIZVcZ4_>zysdfj}n#ZV{1NMg3} zDlz>&G4tt3G-Ndct2JkdP7W!e1gNy>?9Sr037>jmfj(6B0z7 zHl1I%`Ela6fk6%FNbO&tj}BF$3YWpu+>{?Ep4V(tE@WZ9Pj8-O>?6m;MN<_RW$??! zu$OH4g6XHej{jcWkh?MtM8J2$pJ5Q`{p63&3o>lE_7*r;);Fb_bJ&KUf>{6+Ss9W4 z*_Er@YEUCE*+v1BtU*GlA>OHU{4$f<5oP9$j;+~TpJs+m(CWtW!`>p7IwtQO#puhv z`)=nn+o8!}IOwYf^$h`&(~JzRpap$;F0?B6zjS$vcjv#474^g4c$AZ%fk%M{vXttm z0Uulj?I7{^o4ob|kw#vwpSiIhd&tWvB#|D{z_ zV8@B?s^f2;V7no=_zp;$tW$PIa*=0O6Sk<_VZG((ZBy-WbgoJWFc`rnPZsy-++URr zF;H&zm{_H9Sah5Ar5mS5hK4E|dS9(M(ZhM-q~6XW+#ZWkpyePSUTy#KQNdCkH&6)B*;ff{K_26PeqS=QJHc#0(VC{4W zp*GzJEVr8K5br7yUz}xyj4?}W8yJW&A+_967%Vc^Gj!#_h-xm^V(4ML%_Oo7CEZVT zriU+HbMP^yg={|j$lQx6FM3OLWD)iQ$d`B@*Sd;PDf!rjfL!7#u$@=Kvb^{tSb?!8 zUgA%AeZv&oQ~`s{SRVKHO&J%|#Z~O}IKa>;*8Js%;)K6>>FMQr%%O^N@@0Q_Y8a!$ zuGy!Wq+soghZyuf`$f`U0TQ^LZ%^biFe9GF`e}99#p)2tf>x*qpmOzV31t^{#qS#p z+{O3!D2Cq#Or%=vtAXn%t-mgPV7l1r(SkwV*ggjD*-sW`3)V4|El=9P>Hn5!C_!ws z797Fg(TNisAJ8_P4@GD_G9-;YrWN)l;?d%S~ z#=Hs}FE3nEl!p5?wYMn+HJa-TO3+nYu*kjfFW!1G)Es3E{-m589n*H z`!LEb2C$|5h($m5ZNqe4)hM1{eP^t_T6fFP&nOCQW9aT<5^cN^8}!BXVK_o#YZg zj*9)k?JY~$L+Qzma5{N+I-8LD1J+hzwsz%{ju-{FsILSu2dxw*~Fr|5LT+w@%mY^uJ5n>e?*hKjjQR)%M zE*-gJ+3wrXze?>8)Tn8f%@~#)hpEY?nW6oy54zBkit-PSB_2KSk9sYssrHY04QbM)6Mos{0)K{W5{MI;HHh-% z;OG%?k5{(OEba!8ZWV()03NKWbGuP4&*71*aNweW8JCDkg7d_p2O2X{XnMK>;wl3d zTl5)x7=5z(f!zDU>LX!guN-5tUQn1Ty7{-*EYrCmE4t?s2qvti5VLr*e*QAuGM49W zg-N(0+eu$Pb;{VAcV;D(`PeHasVPSf4oDU+S{%g=>?%=@;aiFXa=ZdI=PvoD#IdO zu?E{pG&xKAr{MOuS(+0L&bJx@iu9)F2i8+4UrBZ~?rBNqlkplQ{tnS!6#KEMV&t~n@;*m5L z92cH9FL7fcWl;(iKbqXNPl}xRoe9MD_QfB+xihZ&Wc4n-vn(v+AH$nwbV zz&rTz3d@T#^HGFMHML8^+yc&(Tl&UwWlt*F*G%Q9QU)FXWdTh9&a!IgVV^RL(M;C7)j>f*>S@Oqw-!mL<0an~C zcWgj}!K}t8v*$|ympKCI;MJ5ZbRFg2y)Q-$F7lStiV|Tq`s}9Q?$-a~lg33Dt3kg* zhgsqePj;?u&E;IUaIR06^XDEtagV?-Mc+0%gA9{3Uk9xtL)AaG)!xmqf1Ajnn$FmG zsNq7(p65hYQlX+knqYB{XC@mgb6Q@;T5i1-(;Z5R!ERHb}|Dek|4}}P#kjH&($S~BmJ>VbplAqGbdgI8fxfJhNl*G{j&Z@mt zE$a@voXPV{+5KP(zH5H_shtP6OPx*MEop0OYXyy&R0-9^{7+1feJHu zizmL`C-=%FQ3^evYya}dqR0(kp)y@+8v@d)NKE@_zk!$1ze)vnT@jFUEraX^ZL>7! zy_>4&m!;id@qIKG1c4GH?Y)7E7UP0qPEAx^-h}#Kwgz(e%`~J2AIZRE6!aWxdrx`1 z5j44>fdRPvxE5BPVPr00_z{=52O3Qa>8MNFO{=O=t6DXkkI^QIol2{`6<3PjRl`^T zDcG|jSMA2&#*Xs*v0r{zO3~BLs%ozuJ)Ax_h`f;(3ey?KbxfA`QjfG|}Sb3wU=bfNQj7w_BspH>N zvbdcF%IL(WW(#{VC$uCQ=fB6iAtrAJyY3#=9v`18u*`k!Wf}#9{StHa`-ll6uE6@k zuNzpt=2D$Y;O}~|TJOY2-({+^i-q*H`Lw(9wXDs2v?BIZXJ=*L#e59-@^5xq3En29 z`Gs`F((o=R6HZZ_s;EO~MyW8QmiPW!yh`#Yi{sSqem^hlrN zx`G`$PL|}D-19wbZJ6q^G*Xq-q(D!cI;Wn+_p(F-dV(i6NI=EDU`tU^$bv6stk#Vs zWua9^ta5OS_Lny~+(_8Y&h;;Jhdw?F8RV9*f;Z5>;Gi>t3!1asRMy>}^gb^R5(lO> zPfLlO@{-aqcRfXfnMdSFO!lwJpBjgZOYE28l&IU!X??iDI9=^#sYkC)WVre013&gp@JbmC6*zQWAz8-AE-hg63MZ(&C;ZUO)Z`0BuxCC=WgzJn|bQEldn#WeKqK_ ztuOkWEM`2#J)$_?lr0Gkz9r=l&-hnY&Kq@Z7vGBNPA7{meH(y9KOfdT3}pjnVq-_1 z=M+HLY?YC3v2i{WE&EcMr6h-59sE{=Qai-ZKJBGES5V8PzhA(Y>A$i zdAnDWyLo(@DRm`E?FZ^Z#L_U3uSfIWCwoj_Y}z1m+lMRdmt_WIlyKc9ZxLcN+Hd9Y z3K>cJCYVI!MTg^h+>oP(rU#?7z!%{34KDsEGyATUuFlwy0(9?BQX@$UxfID1JKM<)IL|YNsk<0$ z(;3O;XkP`DfNfdsF4WTu2F*Vz9LTrhMu%g)=Nf5y(<5b!K*E*#Yevj}!2P=a#N?u> z`!<;*g|Z8u_fFLhZ{K;ZA%Hs7wO`x=M=7pTcK)hc+I@%wmotq{BU##>Ib+o|J{Nf$ zlMrb7i4hKY?r7tqikxP9z9|v3O$bjlS%cvuFATUs7Zmz(qi_n-K)WVWM>2xDh)bBl zTNc4%vwnPQtx0rzcWZ-oJmcjRl6g7qROqKJ>6`z7z(8vpEQi#PG()UDp1P z_w1`(54{%Kv@*0;rw{=U-Z~FI(T__a5dVww`jy{MRn7kKEznG&V|sJ%&Lt$reMr$G z7JGQMj{&k+ax#3L>fSBx@x&<8A~y)lZt&CR%$FnPjK8K=V)6F+w2|_7{z+~IQP$g~ zIWB(@pG6-Yu8@@Mf6-9=ud3N-J(fsb8yMqiec1ObCVQ7)IxW+qsYo$d^Kq2F$8{45 z=%>FybnJIujdK|Hqd|?-BX^DQJ%xSb-IdzeMb$3#yB#JHCPOmhbSA7NEN{gTor}AjD0GM-H4*j3ls#QC3OOeyD*23N64SWuB zYZj*Qc(vrsR#*Opn1L-H3|ZYyRB;k4$xp92A$@E1bD+tKZ{H|#ay2VH;qzNzaMO}h z17Jw()!yG!8W*lVG6x?oV0f2}ugLtZ=M_3>{mJc~hmY-f2eEFT*2LW09Eu}G^K$|$ zj*k1Mmnoj;pfH$y$~{gzZRwNiq?4p5u`^|KIG;wi+4vL#CS>u5O+D#Udf40%9?tnL zdhofWGSRUuo)P$pVLFu0d!BFm3n{Uxr5N5vNB!0Q8*LABOp z3#RJsc1WqEUtuRSd16X~*M$o%IqJe?37x(bwm2RqZ{GNU{1{aE0&5A)2p!n!)k`UvDZ` zVfq7tMyshJ*T@9|AMv1R^iNfEQKantwd&^ulA0g({Vze&W9m}BzXdJ_*9RL)PXB0i z1XxV04}Pm1koBH2E%u!5l@KSEpO$xnXzT7=&ZH+x?OS;N-TD37uUbt<-_z!3ys}Jh zR@#hwx`Sl%!c*rilMz+%A8&y>5dt{n2k5aC*h3*W+S+rWypjb zyDkn;chE$~ZpEe=(%(UbrG&z$r$bqM3R)U0z=~6;4kpz#=nRK^E3(UC^}Zlbg=>z;30LR5SU7ilY=#?wP@+khp5l8#(rHA&vSZ|-&F7vvZNYRZ zo1B&_m|pT=a*m%!$GyxSI;A1!+hZ)I#bUe-^&1gv* z`)$d?9hhXN%&_b|xm=ku_kG{-3P@zzDff{# z84Fa?)$S>DR;i+yY}V()AS_$X@~cJLwpW7J$Z_c11sTB{9*gx+FYlTv{Cw6;L1%(x z1C~c@mb{8_LPG?x)9~j;tf0#!IDC|hXNYdpT+kI)Ge&{K50@#i39L1)YY2eI^xquT zqX-F@#nr{-@%!<$w(3Y#v=xg6k<`JMH9EIp@4b{rq+p z9B!fRRQu-Nlwoo%Xipwc&XD=5f<<;n10>s-qtLlgFr6&Q8^?RG4u&RAXpKtFxkjI< ziMS>fslAye05=YpWIi#HZ2Qe_Bwrhjx$ou^+mz6t@a+)_!A&OyC`>UOZ&E|{mAb~+ zpur*(5jp^4S+6bn`R^5ywr`bSM!i>j?&Zd|2g+De@gc3Ai5crHovHf-s%4Dsm17$Q ztd{&{?xYS34e3`^c5lC0cJL1JjnKbfgmN1cWL$iFF#8NLRd8F|E4bkZ8v-NbJ>;&E zz_@P7e6VW=Ah(3EGnt+6&fvR*YRWIOd0hEerrdG?d8JlO;1@U$yKH3 zkND!Uo!Bp!WCpjfXkf2%qvURYYHc2)*a0nOa>oJIk}VN5g@Gl!rg1rl!XUY+E8=+! zsS@7CnK;AeF#Eb14*Di!v0-_-(XVY#CZT8z$|@xoK5jfMtLgTspj%0g_*d}&F$Vd7 zwrdB+1;fTjG?!RSr%JE;(dn{?fq!~C%O_s2XWCI~=*eEVt5?^qtDzC8$66FRVRoXN z+zl89lWl-vf!T@zip8I7x^2doTt{R$+T&&=r?$fR0D^oHo$jw$1DF>CuPt?1mwH_& zb?+Vy$;s~wPz3z{nGAvKpP8(WbYDC2XNC7C*=TS>7W_kVDmO!d5AgWiK3~)hZajmK^Nfe`Sg4%KKdK8s=Ux&3gd>IwLN_~}VJ@8UA_;7~jyCGIK zUvKotwIy{zO2^`P2vLq{1odZ zslZ!I(aX+(xUJgbz|;cj98>~=c}R(|4=hd}nIr&d0A?Zbo=M$r)!#y8*|~RX&b{Tw zf!cWWl8h4P*C2A>{m{UuhZ;=l7$>{DK#i_V`Y$ zp969Z0-1^xSzBAm@FTWEErHB;dv9jsxV-D&h|7L_`8eN?++9q-Qs_D_j_Ic=w<%DGmIwCps= z$LE`I%9Uq04;wY48Ey~vnhC+;xJ3dFPfP3rcWUflRQ=T-R{uGq*xggi?{?obw-l0U z43s=hk`iLiFw39Am1iruVJRF*w$;VM=XbcbbvOF;RZ(8vjbdV=W`K<#*XEMmK&d?A zl?ou`e_$WKG9KB$@NXgMlSR9CqT_%Zz{EkO!SfqcG(v0(R+;$oJh{>pC|t1IO+MMB zhoNJpv-~@2TvQjmNO#zSc?{)`$N-!}?Yyh+jBCr`?e{X{^bt@7w z>-=Tjy*}#(sx83ucK<~Vv3HD2$fY-B8fN6EB^A%=7_BistBAmAew1B_%0Q-z)x-?I z;en^s_?|q1VE}v=sAUP4r@-$7&P?w`GK?N5peW2^Ja62JO^&$>|^PET~)6J3oWaB=oevZ8sJZe!&9- zh4m+=2C1r7-Q@*G+8ChAf%sLMtV>mam=V$s!gId3vDxpLRr!@?ijz(4taERkEghNj z-0`;-;HJkdZ^=d%y5Sw8<_Kz8dsr+Y>&2NX8l6VYT~4?}TAl(8g>%*L|JSnh1c)d=~pazf{=3wV$G1htB> z+TiMqMsjiBcYr&BorC+Ri~1i>%r2OD82J3=w4_e8B}$R4BUG8%KQkN^hGp8(n{Y-K-1F$?g-Znt)~8#&q!5@uq*&%v%!nRH`{Y~C)TX|SZlLKH zWgwlrB_8TqihyPb;})my`>evMOrupnGLi!8F#rrS3y<&Q(T^5CbN3_D6LQo}rn8b5 zs!N>`Lc6xo{QSM}aJ;HQ@-SIhoLlUxNh-!FoCM>$4b_;wSmQP+i|k87;ZaI#!crMX zV6;qABHt%S zNnSggDfRasGpncp=f=3hNZ=}1fH)kl`1##ZOUXO_c*Vr%7e82$K;?Nc->l7ye}g+4 zXicm_H7Drm(5L4lj}mYFU>sb$8?2E z7Fq41&8wHQ`yOoWAh92)9F4j*{LiFJg#*ZjR<^lYU0iZ)Jixb+zW`hvs;ls=vpG~c zutsO}w#{Lv1qWWOJ{8>&Jmz(Y!Q<5w-?3Q(O`GVQIJ^)2IM3xDf!g45IyY*`%~aEb z$l--s`Y0u}{?yG?z&SU2vgOrQ75|Hr0%Tl~k$nxXWz5z(AMq4y3I2z&7;ItbyUV#=y}U%`0y*wL)ElDJMe zqHsYN=EP$0=F%9=_H4byK}P9MZwEc-*wWKAvpSBhY~~}I9Yu+A#s_uUeR=pRAPe({ z@UFBd;`U5Fc95B=`>Q`3PjikuGa-cSI~G2vef-J-bH_(!_MwQURVbak`n?bI$Nmyw zUV@fI{`>(ny^xVsJ<5`9X*Wk70P(pu$Lo$a`G>TL{omqk+@WG>!KA!@ic?9 z{>SK6Gt>5^|7yJD(s-Wn0(UAa6yTg5i9JZ%gXzI&LJ##DfqBeLeH8sTfhkfr$B<*k4}GfnN)y}}h?1cNI26(9d4kn72@miENJO0LU)6i;Y_XI7%wBIT#o)|ooaDq(G* zjW_PSPCa^6>SZruvA)SQ9JmP1nepn5zhv*Uxy62Z>@YXp)66Y7oZmT=j_&)%q_*7P(rp_bUp;T14bkd&T z*4V^i$QDVrL%mqE_O|SW;#5_lBelcD)(*o6D6F<^-%mVeG%EexOQ zkgr00hk_`%tAvkzZqWQrQR>Ba9Xilg!RuSa0J}|3PtSpyGCXML^jEs(kXf>N!N`q9 z*n?JG$ih9p)i?&O=kn)|BE~`1;sdgLDC?KhiUx>s>*U@QMK zaf6IR?f)R7%H~-e?Iq)9@tXSk+khQn0tqH%0qAruT)&7_L5X&H42L%KOtc(;3d!bM z)+x)Ey#oWCTWd`)7K+XAyxih?eJaY$W`%}y4YLMDH&K+{*)Y&q^u(6SxgY!bLZNfH zK0fX}`Qu00nSfbB+a>OiymO0>g*0kvq2B{*&1SMk02M+*O4>V;sIZovi1rUIMhg4# zCSUYSv+i#IhpKcu)^hGL5S-kk?Q6WA@1w1_hqGPB@A0OVA#qpOe4a^6Tv9vk%gAbl zIRx5V+lp>5DOjZW2PVU=7Q#cdW|%+09AE2?l}=DmuRlBsU2%S2BVd_r9io)|X7X-y zpw~tnm4rfnp#UhOG2Ms^ z=HTG{Jp+ezait_(1jhp&_~>T6!Tu>fbmMv`f`5ZuL$_?cL^V|3DO<42AmsvqaA*T^ zvd6EiI{5}1*MPeZ?%h&3xdnNZmGE^EATwo#=@m9yGz%cwOxbNSzn0EU0DHX4cQGjc z7Wh0KqW9jS6?I~7T;1pPqe6s}qbMakzAWwheaTbynxwivIh5sU(vu)(*G z?mhH6jV0vS8K${{j}ay(uN7gp8oR>YzCRK>wZQmr*Tng)KMPsON(5Cu>zBfl?5dQR zRsHDKq2+frg<$UwqXecEmsf17=BiUpn5{VYsduNZbM-h@FD?1^CWMz-+y=V58QAYOqUH7BT>3z?6 zfB(FHbb5Q9=li|yYkbCa#bcmt8HNV1E1LoI3s+&chIdP^^PNSg;=_cc$VZVtBZj z#Z0_5Va21RGsxd_%xl7IDj@ayHGA}3>Apv*mkI%`XpOZl84inUF03s`TZsy>IKJxt>_xTw9Ba zoKx@l3@y7-_;01ovt+{$+k0XBSu?8Wc3(4eg)hLQ2mD4qz4B?^t3nfKC&zA! z@T)}lt?2?+U5?sLp#%7K*n!lAqLyU-71@88Sddo_RVlxVwgm>i!atSlu98ZaCLw)d z6Sj=*h6um6IGC%O`@;p+MDz)m#gP=SG29C zxCsk3>?M3Q3;LS2oH&~>XYF3%os33wsZuDwrGNWbv4Wgq0C2&~lWq$vQp(g?Q3JSj zYnT08f&3Yvu(m4On!NK7&#J*iG z@~IrtA>389!ylFNDq?dRDD(*%lC9YL)BEUNTb4lqyk;imohHmLcLIwMHvGNR0B zWi~q{1L9p~mF)PcBEhV`?8k;bd>!V7+*v$z?#Ii)I=ZPrtYtgY)1>30HY}im@fLq6 zKwbUbnq(QG``5dN=!ml|KmL=d%O;$%5FACY9Rx72mucwm!J~DX(IDGsS{4H8MukC* z){8S75>PY`U2{J>#|wa~zqTgH8Ki&trz!6ataL^>9xG4b|5J1Y`e5)jyS4m{Q~k4$ z+nu5EPfGAmEVGi=g!R_!_07XSRV|mbaJX@Vf_urX5;2PzbID?>-?-lJx&O8>>0Jj6 zG=k7}?f5S!vy3!bI!&4|fkb3jN6W5~0vJ^g?0DZaP6DeDm^W}yxBvqZj01vESg@^( z(rOcIxoH!(rl?t|aTDl)GCW*4)GFXW2YTNWJ4ctRL_}m{iRjfJWime<(O!ZRAaz)o z=VVP(@MT*D^tJ{q|9LcO@h_b@uxFFcArq!j5C5_5)#W*A4; zg=2U2uwOh#FkTOx3Czkpn12>@GHCch#bGkQ^O5%pd1NTKuR&46!zoK6<|7Lb6qZ#~ z`goTV@E4Fw1hEdh;o+ zxBKhlKlRMYeYT_@Zw#&l?F?{!#nXE&e>B4~Ru3oq=Q|USu0{`iE@gUh_Wm_vPFVo~ z0hG%tZoPTi6+ZWCEU3lCXDogPe%mJiY#q-dE(9SXpa&BT5!%=VDnLkrIRU*Wuzv0@ zkTQjG0tV5jad>s*Y7_Vs!t%{eU54>n{dTCmF}X`RkfiJd!m{f1&IAGi5IBz`ZkI5@ zt3B}nl|~06XnVzi;LO&=) zAzmtnqn%XXK0r>-md+#@Vyx@^?noBd+(Ca#)lqg#)u{xG6rNse#?dEd`w6kVfX09v z304o}1s1uBk7)D3$M{J>Sia?1P9Fs49=ITpGz#`bQrfBn!C;JL z#&>tYLh$JoXqljdl>-wDsEQ3_UYrtaIM87J47?>zuKEBJ4jXH%K3UbCfN+HMhKF8K z71)(AAb;t~&>>9c%z-WUD7Z;H_~<6N^qM5CJ1(DklBoc?Ah<#ZqvcQ0?3Z(ZvK<~7 zw6(J6P5l_zav85Lw`1RG%zG9qx>7I8j&DMO3hv?~B+&5t} z&-GW=pE_;{K7e{bgB8^akO~3VfcAKo%FK2`yOx8pNI{L@2J`l5zzl?n!<<{n;6BE% zJ$Z5)1~8z{gqbc+0P~(2{->=Ous19eFWZ)oD4F>#5s`ODcVoJ3kMy9A`w=N>@xZpT z=T;O~kGaSGo8_-0==YqZz>K-#3%kwq=MY=~t)UO)&5rSEzx^Y$Qe}WJz)2#%VtX97 z625jma2TLYhB61LR@f-tl}I8udzdLj2|mpv3E8$ePp3Ytl)B&$UEvMPV*H(Z!EFHi z{+8zeFpKu7KoJ2M9sNEKk_uSO{|^pHh9Q^t-^;0wUDq;QTg@f7ceNZYiqi1e(oDLC{G=!R0m5F6ymw-6;r$8Ge91OHI-tGTvVy# z`sdlNU;?;PXm11c0?ZKrVIG>!2pXEye=DW_GUB=;!t=>bcZ0vCju@TWOK7HA?Wxq%R1ivRrs*Epjp~X_ z*5JoQN$5{Wt%ONZ%iViNPaX9PV339W0jwc=(#xN882O7U|8m*^eiqd_-3;9jToNSh z+{`v2L!xy7hl}!PkcH>H3z{I`gO>slxi=Ggy zdIYaXetFYY(Voe}7=75TxyPBcas1exq5Hty0|)nPX~4cTKb2LHQLk4d_-zvm>c!G< z-p@6lHeh%_XzM4Q>K*XQJH<-<1Zo4l)OYwD7ZsD~YAXyTcTyj#4#@;O+{kjGI>6M1 z@qNjTqmTPUBK2)N-Nm=~H%PwS;;o+HkD@8?ypJP)k?!F0ClcwmV;;XE#1STN6{^Yl zGO$!ozEon(dV$8GVWYRrin20uNP;zD;`GROjV`fmN2Lus!q8heR?UghChI?^b>*gq zeFk=5qX^9WKU$xzuC8u5+2*NE^K8H6bcq(ncSX|N4CY>Di6HuDi?sa~um>`qnM>7a zDWJuEmNuf8_(wF1o#&+`I1E!9B_nwQf?IXz9O6F%AjGZ2tYWzQnzF^ykdc^fpPo}A zgNQhuQ0O_eBWEuiJ8)D>)?tf-B96h?B#BdvLy_BRA!fXLZq78Aq9T5vH;a z7z$h8A5MMGeUOAxCvzC)E2aiB)o{sP;&}M1Z;XAWVhX$t+2m4%JKwLwu7SpTaNZ_C zF5z`UHANkW7H-UGCtD3I+axIGeTF}hWXWJ2uL~*n7xxptb*r5Ztt(G@bR{Lzy6?!h z@0Vz3o;C(D6HK;0cY(E?g%l5f?zF!SM zW@l>0|14Sd&`+{NKy**kMK-#cjrc2&x*a6F&|qjdtx-;@I=pC`{W_+=%9qweW#5rg zl0hGT+?*D^^EQi_kb>KzTuY;Jc~)XEB}>nx+!#&0LvI0AKUGXDqs?8hYcTVE$lE9G z>xj>EnB<;Ul-`6ydhmtwGOHeAT=A`8vPfM758GRlq(El*k~gk*(5&V~kms(QqPX(< z(QFUdBhAe5p7!iBgy4PRXdJH#_H)GBhsJDC)6i_a`o5iJtJ$9O@Bw@`jV@3JE9a%Y zk(}vE7t=3X>MOa@M1hny zN!HS)mv5uj!tn;_CPY>F&sy}F*S&|oa?DbiGzMLw1g}QiwYZlpxkToex4!mxLV0|} zB*kx{A5n<}elyeL03K;!qVb2j<;vs1Vw|K4=?mU6UR?dfhUuptXeggo?sxC)4&U!*&$l~JUgEv!ggI>Fea}E<`uDMer10z9sa&8 zmrms!_oFyJol8YC@CmfZ1S5*1@UQvwX^hncvxVrE(v*B_PA7$~>@4VO&~Jbs;>y!d zwrtenKOS1NeOfjz{LPz_;eMVNOHw*qy`lpL)LSr3%zL}=^Ytu=s9ZUrmC?R$FDx`5 z2TpF^918(iTj^{#P1yw$NEZnoyRu?XE>28qzOignzlb&k7^W|bE1IlP^=)bE=xlHB zs|S!J#>dmaCUo^l@Ai=PM6)Z(pqEftG;9dt`PQ03S+M@|f^I{Y`BTz_$Vh0iW9OQ(F>Xt zNwSA5>FMcVKw)rqx-NYd^BHE^#-h0=aLX}ER~F_{g3n;$<-N{e@Q<==L#kb|6_=1` z;fq8^_%MY?=StowI8~51&&YO9qNII`_iJ@@yu6`j5PO-KZ_|O?21raJ* zY`SE2@$_=Cmyik4dw+u22^B9X>S3ZaMH5kx-cO&-1FkF}VBiHv63G=-fsr1ogQ^Z}bs2MX&(^)czU89{A^sJnS zzB^Wfo>XUws;*=S9o(gN`3lV=i+8eA_|a)%9FPlO_AZ@e1sIQ?DO`HIVJ!LpF>GyV z=A$Gh_wF_rOO|Cqw+Ws7!Wp*f<(0Y#R`V*Ags$#n7S^Pb$*^LN3qG3LaWfkmj9_hX z9Z0wiKU79OQLpObpWwGBgK&W&$jjt`Lo_@1_4#{MF2U5}W}aaDV*_O5XNju0Fm0n4 zW{jveA+_tOu5GVe_ZdPJ$1xK09Z?9nq*RuDSrd1;Vk$9!VLrE4sW8dmiuCv1oKt{c z*f&Mz?cSTIM)E5xmE~rzUOsjWy(MbSj!(zFT`l^p1?VXEEp>-LV7R53*s_^eAF655 z4ZISVdpxvgjSFk&r^lHtyr67^io#zd*fwJ`I-8H;G$$(zMSfdbRi#!v zT>jz|M+jK+>lb07jGBlcqft+mUx(YO^hdKF@{IM9XI-wJ#u%_>cjD^l!bK|ES)LAL zlDnl7OO|+s#~clGxn`2I{Jr}rgvynVeG-dIidiLEsh|o=MhB(RKs2uM*0+{eE2(8Q z2xT&H#>#vGk?LHs=vDTjSZ$qpclsT?U+WQvHoFCJ^r(8WOxUzrv~(In5+FFpd^k>+ zN^2%>!5UQkrYD z|6;0{IW?U!&#esmSi~0%;jMn#84`kVbn0@joAudYx%v};@g>-B^6`Zk_X(oy-VwJTsZ zU`!^M7mC?VxuJq{`@sorbxVAzvI4S1CnnVfI#v7Pe!1kWZM(2XS0)(q4cV@|6 zdlx4zt8cD4D?P)_d-=RM<`u_=%ZKak zMAZI}Z?rRetYfUr&~b+U%W&Eif0LvL$MI82Dn4*@V39)(sC?5K{l_U&RLHX$ANCrQ zV~SEGZr;>ft_zk7W|vQ}y7P~^<9wuJP1l|19J6a17veV87TNe7odb6Qmtp3+4CWU` z$}?Yc2)wGx3JdJusOYyole>4u?I2mY!sVuLP)P)pepwlCh+|g;g({!GC78_A0{7m0 zzq7%0cl`Sc2ZcK9pF%`d_h@Uo|6VGhBa=Pt3aW7V#)OUx98()d^U@$)>Ue`mJS1-pfGaO%v|zGhDZ(6R1!8)ukc!`byXc5 zZHyd%BI-x63*H;e5#i5P^D`EWLza1mjFeYC0#Q{}eSE?oi0<`5eb}cA`qjcQz@z`kajuN)Ywnw$&0=-oi|DTZN7f}hlJmc2#%d5<+;vZX$5q=;SXFe$nf)-5@tr>~5!-H0bh zMoxXZ8b_$Z70=W8a^%+&)MaoB52Vy4+iS{fc+$>YC?m7g=cSW%e41062^duqe)P&ZN@t@yX zxs4u;wLb^Zammb2wb5{tJ~ZI8OwYD0TcvbLBV&fJltlFYuNwM9F> zYJdNOl01Cj3xkTJP>O_bUxp1k-}JxP^XU@$U62}Gp6v;lK$5p^ow53?{)KC~O>=!A z9NA~2n8P}^qrRfI7pE!+i`9*~+zmu;%RlAY)b%`r(dy%>!f_^Yw1C_O8|pxC_#nio zK$L*-QD_vG>?1Eko{8(DwJeaSY698DD2`OQctr#jo@d8D2!OjKGWcAq^wlr7=HOcv|O&1XA8qU9~qlNK8<31 zwo99@m{()tVi&7>bL`pGaiN}sEEyerSur`k{X;C2l0<^h_M? z>JXhjR-XFR+ejJ0l!uvS1zi^N^|FeV_p^D=9KyFyos`3mlLvui3l@dKt=dm`=61+V zp4A;#1sU#l;ET@akYMd7ZL~n)bwZ45lN&u}U}NBi0^Nr{y=7!&5)}4kbv}fgHrtaG z%&O0tu3LYO|CZhKJJ4Km_cE*K89?q3DnwkusA_ExTMcO=0O%ZzVxpp#wYpe%AAQ$? z>#^~puyoASbUSRh1A@^xhxMh{#{-4GvbP_tlv=u6SGIa|%ce!6pik?_d&_Svs8QrH z?p2$KZ~m7WhZxs6;QD_2eG3Pj1wPW0g!z4beGxg0ZS9n;QzN?dlG} z&*sBrsw-OqZWH(u^Hc2!_j6vWQ_{C-!_=#*AQ7uX@rIt>bGGL*eZfb}igEbEwj}+o zrxU0`3}M=w-}nLjYySF0Xpx4`Kc9xT6w{kq{t_nVKmH!pVlOFq2vl|F0q{fxwo5;F zR&Hv-_E4~phU(cEH1|P29WnuP@H|Ur-+%L} z$Y91*2D|~ckFsdTrCe(ml)}(tl$1=u)cMluhqz|u=$b%FbS$*I=9#MFoe-0Sne=Qv z;~IaaLG#-~r6gD5n89H)F zj;I+br@1cQjE4jLpE`u!_GGK$ae4*7%h!uIeB?;n!z|-Nr};b}m9JAN&*gRIvMg5q zaH6Xx>&wNrgo;J|ehJ-D`*R<`m$d!5*k2VGxcsBTt;XHJ3wFlVV1lsk;lxgO zQpeIm?d*Qcy3I2?%J)RVlWN1O^HA2TIc+T#4G@2Ck2?bUm08cq4_+}H#Ef@wKiXc4 zYuO|-DfH~tiPdXk&prSO zB3TBH->#WFE4=3^R6QzAOELiFbQbM&-;);f?wN>%KwYtyK+P852RnXtVP)xqiWGd8v!_BhbVcTER*xzm=^YhO3Z4e>$0H^L6PyD4YKWWolEMEc@HZ> zFov?CCVq9#Qio`!LAHZRMEpIm2`%B?&Qot0-#TQzSXG5aQq|8H2NjWWhW#0y4dlFc zxpP^}bl6}6VuLK@8o{|~MC-S^OdGjrdk^RPWiQI}TgOny9sJ#Vt4;JlF$hs2FZnvf_7(;NFp-9Q4bM^wg z_{P3WFtW@I4SvZVNDj?lcD?idY@=K*^cN2N`!}_qOn(BopjK~rq4xMirLIXjoNs?5 zUdli6;_@BcpV872#r(C$Lmf(8F6&z=VZ4RC~JScqyQKn+Bl*P z2-?MZM7BZFSvt*uS{6vgrFGxf-UwJ-1hA%=Z|BDRaMzhfDmF_pf-%Ixej;zrz1=#l zyh$V9k&t4kcD|_<4vLv50O-*M(L{FiYkWskM?etLav%_1EMYaC|IFg|omHTv-W@K2e zRaSxYLyVPr5{>&2&C9`E>y@&xYY#%XD#t$&FM1rOmw~G#oZneX8tL?rT@`Fg`SSt> zZAl3bcG5&<1@-1Bs~IrsUVE4^3nghp!%^}ZTPxhNk3eISVzd0C{dvL0@_8(lM7oK( z>vlt(&IVEUyCR%Zqw*vCVw!msNhW+m_q)+=eApBBnSGn>UJO@wlZ8xxD6nxiaj3wT z_?lrxESnzuuX!V!C|4X;0`s*~&SS@q9kV$?IJdW{4_%KzvyqC!72c<6q3*lGlby;;O z;3M7~>v?F*z?RkwHFNIDjQFp{O!>-Vm;nP~zm%5ED@I?59zKu0t-dCZbP!$8^XJ_F zR%LzMP$`k@#j0I9ylku28{>%@I;aC+gJsR6>z;o}1$$nTx>!M?xemueaHv>csPF@| z>+MJDZS*sMHShfNYq1}>;B98Z=g;&&YCw$&M(YHpMpw>#dnYQ9h=%pK_Dn~8xhK8$ z>j|MwoLl`#2J@k`-6kNm{rSrvEk41$d#SwIk!*6A_Eoc&RqOvyBc7n8e@=svdS8ctHq73u8}~5iGei zn;fLVvP)2-L=2_U(BFRRj2<(nzeYZNUDe;Rja`GGN<$0Q^egch%=b}V`#T3*OqON5 zA5TQ10qBdyiOmd0{zqOi37|4QD&-TgqClFaaA(h_I80_=;Bet6rg(=C*XIyZ(gcT(gibpOn-6o_DRhxdOmlll37bc^Vw%=V@42gC(P zjev2e1l_7NsCX3u&nDcElq{RIOj{2%2^gR5NOb4w7aOY_ZIn9NL`c&p<#;{?vpS$r ztPlBAWcf4DF!shrfRpLq3%&B#7y?h({=Ph7ilg7%Ex(u`$h%$#xSaSuA#bR#C*i+d zf_-!qw@!~(+QnE!P5x?6+!jgc97a>@*A}?>jUkiJ0cC}(`;UI=L9Y+O`cp^AYV&5l zN=!r9BML?QqZZ6u(ZS-QLXOk~P*V~+g%=xerrWe$h+PBFvV7>#9f->4X@HiU?SlI8 zn?a0s6p~lv0xA&#k^G<$s-j4!d$N`{ewclo4HJ9}l)~R##%Nt|EBp-v)d41)`f!3d zb}dWcbD35qT2Bofkh+KDTUOJy$+KT12{9Be>x;aYjmx zx2NZqanre}hxL%v*zGgT&#MF}LUI@^J+k&z>@hWUjAWd!0%-*=ryS40s8x;OevW(uYqI%Xd+1ybrRL!8s6$*H@lRhf=d+CvG3KfklN-D3jK&`XMT z$Kr4rF+%8~%3i6LR$)QMy+!}KVL}OQAd!UjMWj#-Qzk50Np}lORuu13YW8{PRIHwE z_E+eiY7GTY(-#~1iA!!1ydWex7=trsdVF64ZrYv)9z>7Me>)gGJhIlgFeb6+^C0CV zun4lV3Mg$p{?V`9@gi6&!ud^78MUC8p7p zD6?}=DtNcGqR<}?wKlJRgK{nr1vBN^y?JO7z?A|MKt0C0KYe21wVWygd^Xl9>IS@u zb-T=Ai1+~tq<}Y;0N+t`)d8hC0Ad*BSRxOMRG3Y_hn_U5#Lbf}RBvm!2cWz!GYq3c zJ5jIjoZWSCpuiESLgV3~SAp%3GWy%GI`yCO!u;v(2v2B54Z*mW7tf{D)^sE3>jhN` zc#R{2z~nQ%TlHEGd|cm`)mjaLN}wid0#KlAjYj1~CLBY6CN`G8%Y-<^-6FeQQGSP8 z0gl6DJsYo3{Hq5TiU`xeb1NU1ggwrp{tf7#U>=8k@aTaOekXDOQtu^ByK2-BfGG$# zrel$vr2*$=Ne|jAjBC%m`eONQy%0VK^()~54yW_VYru&TgXI^Y_|UGcHV`F&N#ZXk zuLOds8AkC(*%U&(4ypJw-;zIN%K_inFuWRE{p}|nVTeswN;(BoKdJvTq!N_pe zK7*l@5hs0Y>t@mU5&9q3{5v*FM@Vs@Gk#WYI0W^h|G26_$Dz>HtJSZ~RT9zFKnQcg zOt<8k-s={F@^_+M8fgkz5G|9|9&s?cKLvSmeL9cDc+7w^4&;@4vJB5}r(tYXo%GPr zl-Wm!yMP-+bafIm!GPDoBG)K()x<|k`SbJl?KT1Jc6;`}Y0)pz@cBK3MzEgD6P#`E z&HodNfkG>s$6}v*d&RodwEs96rvc=@*xqP35LD-h;}7cXd^zu5g;QL*!Zw!#oi5RO zH9#Kev9%||UlqfwP4>o#+901_1++OVm~wahVzT)DRu`kZp0ee)lDARUJf1&C6(9Gb znUk`9JU0h&q4vuKQ0p=;l?#yi_tvXa13t*0pq8N6iQcTO0xxA_aA}MuF`VFCN)@7} z>xaWt>CM+5iu2i9yxOU9!#@oZ0ZPv3YCy1-SgcodI-J-iB`Nu$p<4JFh?fL>+(}gJ z6WGyyDn0>9m?*&a_+@mh$$heN#bR2J>-*4~=JYqgc;A@Y&%Cph$ON;SNN| zqbvfPa4LQG6_*B)auZZZ+fw1mfh82?BdRYa1;@n2K8(1eoXZY0(}b$^mtTjnHprnO ze$^U+{{8!HMT#f^dZYGqIE5He3iMww>^s7(@4J+xP`?2q(qD+5EN?k~6BGu2!f;X^ z&SvCvIC=v<^#0;_gF|_H8TYN9CKthv8V`zes?bR_hmr={VS%XhDRfw`0cJ**92)Qn zC`W(_004*6{HfC1N1)3LU?~XE=F9;-NtvG2C++l@n%8U}OYK z{hQ0t*Zso6l57fvTyS4_c*h!TJaTobK1M`B#${M+@EKXHcG2zWZ5WGx_*YRi4e{*U z>hS-H`VC3)0HXwBqdv?~C^g7hRPgHD0@TGh^MIbArN`}aeKaGIVgMvoEhFl%TuWyn z(&=J-(foMm8zb50Czw8dFof2Xj4!9pPUE7an|8;sKJ<`*bZ&?G_A+)I}E3lj?};b;^QWvSwX| zVf=Qo*ouVTcIn-K^Y&;>KrO0BT=4d@R90vwSgEHepzT?3U!TGS3HU4AKZ76%qchbW z^VlTFv!OE$=`d+^_@=$ekq56cvX~b}>uU$8o_=dtazIZY(%}i;CK(XU6(8`=;Evi# zco@Q7fJG3;{8M`*4104A0u!P2Jil6e8BK%wq}s(S`}Hq zgB??>_)%_UEt%d8R$(atc-xdBJu7tH4q6A1$M1jPJ-qz;sad` zh}F6FYpeoU?jV_iYxO~yz^Actq&*R3R*+M z0W3*W!eaO6M+Jn&9})Z#i_q1Da;FEEG_#$2v-DdF;ARCk_1Gn);(wD&U@?L~l|+&& zmQ!@e1fq(ZCKWoLO*dD~AW@l*zP0FNM&$^|S^%4&rmL>pIdmZfbMg`{cSFGub$lv{ zcR-+A28sn%FS0kv#^1&X>MU(-p-1>p$N(RLsyHx8 zuv7+j6&i)M*e`afmKvl(!WM-!e5-sEvi9?_E%q>}4AD#}cdnsVkl89^BebD#DvAtV z!KK4*4rGIdLL{CZ)~SxW@BGas-2zHx%bzj(-&zM=1ys@OB5KfJjRK7FA8()ivw)JJxn`Rx;0zI~kgK-I@{@Fd_g^y{}zxloFr z?Zsnk~!&jHNh1@W&KKRqo8KG9FN14KPXE)OhFKE z6|C^uneX2H6FUO!89oQSko@;#%<+A%@tkKgPc)SRX6_oYwXxj1;LWwuxDxpnjWc#l z@`O@{;|@QR>)^D1h^5x0iwXf4dGM?Ihms_p`Ej5ugDt3c?kB%P(F+t#?{5Xy07HG_ zW~<|x96~~jxo)W%LR1%aebFr>9eoX-2U8_Qv40t3o=jbK?Zl6z`T3ddoz)-xMxB92 zQ&W#$ygx}5caRVkHkPZWr$U?nphdrn2spA|$_138P=sPsse5xL8kBh*d}!JjB;^I; zyw3~1f};O3kQ2$T?D^CRznTz}7HZ|3-$q+@Ezo@WL`r_!Op(K(M$%cLjuVe}d!plNDs( zB)Y~#zS0ddyat~gl!eJWUo7mwC|_hu&Y$Zbgd`nYZv`O?Qd0{T`hCzqeS*eFSCLau zi+$*4qf@6qyC!3s!3;VDdr%S9Br8gWvH03pOrYjk@#7h0A9v_C5oUwbH{V{LMDmYEs`{l7$ zFvRB6728AL-4q#neDhC68+-8LDh(xCo?%88!%_{;9zUu)E3xp)tfe_5yZUtC8{WZGM9UxDepOXBe#O`hSSD%4bH;wB z@3F+<5*d5($l~49*I_$}puAFVDf9dn!e7`m-=$b9`kKd1B#^;^YtHwaH%Tr)wuRM5 zZhZzLFiG}qh)HkEWq4F+V>RE%7)3xb`4o6TiRqHFxk<9@Wk_h+9ygl@Giy^+mWOQ%m4DG2mc!$`a`WN1$MVicD{!n_# zTf@s(7W)L#b6~N(xdwg$i;cx4x(moG!aNJ?mg(xV95;-H>vRr^k#;~5y^(K<6I5Ca z;y*a=Njv8Ngp&wh0O=?GylUN5itTiAkWff#yF^#vcoR{Ref@vyb#cI7poNhbHwtAYJ$IF);Ji$c6l#HVAlg`6WQsr<~c0MCbKy_%Py(R!vm#T#zO@ZnX zxz3N|KBncP?)??;tbj2Hdz1&SstN(?+{Sza+qp;8rNei9iA7|GTz`2yCFWm{@3b zJrENU1C{T~mlcMY3p%w~F~%SDW>*GAGJ1HNr0k}t|5iPr%EHv)DPO6UBDzi-`#4WR zp?TC65fwAR>2G*#Sg}L}B{A{S`k}%0&JehudU81$dj+xp;n>%`HW3MEK$=4HSrqQH zAJ2ilOkz=*e~TTuWmr--iC#Y@LNr1>jS0f$HYaY2Jh3nzd(qA^nXF%Mw3v@UM7=M~ zeo&`rRDDt(tquAO`B))T_vPvOI4@F$WZ9(qIjsHGluHrzEvN;7?rCwtp~Q8b_(qP^ z%|-j6$&xp9Clo##pHC*BdXaj{=23OWDCX>j9o}jUTv(66$NwAhfRx-1wCa#qF33z% zL4746QpFW0Gt-+xoLF6ll|1#pNce&dQFZxbI#-u|;Rxk44)kM6ocW7K5SFng4&d6t z)lG}x0s)xE3A~}neUMC(OH4E{9~kY{HM8mUr&pAPtW32F z&Vo=>7)qW$LzOGh>6wv!_qs70HZnh&shLZ}C->HI!A+%Jg)Y6hVV&<*TK+vAG8Qna3)o*}vxV>O}!+gsnd z^GJa&aJ)h5+N5`UVJ>o39PccP2(B0=M*-MXY7UNoZ};L@E!Gcx?=MKSDg0AdzgMtN zffS3@BomPId^RpWqdQzRREnjUty8Y;f98GWD#*DJQS`4kML;Xp8zSL$@wdm`ZuuOX zzl}b*cW(v84{1d4?Xg1P)Va?2BKF2-?(VI-Qg2~^iPqf-a8M-$1NfgvtFxGo8x4Gh z72jo1Pu=0`xw)Zz70)VP#z0So9%j{(bRkipjf4p6N%V2Xcn6Blp4#?gPy4bNmu? z&l3R;R6#=8H23cjEU3ecsJoNrd*624NpcasllquFfydR@S(*|5GQ$Kk26#DH>^dY{ zT3a|8gP4_1yZ4kYUdkW*Rqtr0Dnj6IIG4`8!zx0Eg(nT!;pNsdOGjFGowd2yB&bZ(yfAz&aqhvGbt-+u1ANl2@Tr06A{z$8*Y5{nKM!je-wC zQdFY%L72cQRiUl3TVYPusnePotpIm}wh zFOD}(Zla#JE8-cY1Nm#zE6<|G?2A!a? zBr5S?#*F#mIXlxFb}sfWDIm@=Ll5rcLzqzjD-i!p{Q%eBT8X((dC9vaKZ7~#0$g$Z zd+%8uR!G8mfUP`b-z{t4BK?AA&#l@kiQj#w32tbN|_oPmgQY29(Y&wZxmz{Hloh-+PCC3aJm{GZS7kw6^9}&a={N8U&pVLn4U` zkkN-A+WsS+u~L;?dsS7?v!e*V>MQ!lSj>FYbqtkoLoTIb8NlAlGxGK6h^(6F3;m;{ zL*XIzX3$&?KcM;0Qo$sd`LYcy=qv!?(2)$Sc%k14y)gg)#p9MuGh;!3bl}gwT7Bid z<9r?-Wgr1JzCWspN_K#F_Ng5j1fdfcM__meMPv}Hq4}+TfX4*%jz6$GAU9K9v@f(@ zJ1Jnk2gYQ)YJdJ5NfGKb{sm73?2+0z9P{Moc(j2UwB-J9Q`9A8cNm( z-T?2;WzyfqrwVdZK#>=qxVy{sz&`*hw1P_eb%*E)n88Mr*v$xzRP(h3ZF`C%pt#tD zP5}(T;(>5RFw7tXdkar*&J8aQ^Nsc3QP<^}es6Gz^z+;Kk1G~!ae@-WEt=pLxGje) z7QyVEz~2D_$9QjFP-T63BmV^Ag?@<&?%VTqepGJdqa-0gNEfJzqM9e)7LL+PQJ-s5Q_QYgbHLZpwkSvyHY{Sb0Iw<}H&o-_gteXRzP z<)79LjY69X`E9&TJkoJ%vOSIqU}q>_2cZGcJb&TB@FQONt@c!UZY0{SDa0~mm2^QD4Fr#CnM(d1v&q9{Y(wSk_ni{B+1r2QFYutmDgU8 z;77~R_)N^Tb@u6zliYf*&~uc!g!d4XZ)xZQYkh?7p%2Uum%cgSmt(P}SF#7jDzZ0< ziHT``Rp2SwrE zcc{V>*t5GlxxJ)*4ns@n4(kUB9qWWK4~QF-Jp95y+EGX z$UaRm@A1}huRCizN(tuLAPJe`r;pseO$Cmpt?cFfXE@2Aqip3PJ9SDtMW6sYMUg;( zSc2oKF4gQ$k-h}*%pgQ{tPH+Pr0RWWH<+fo-(e=ZV z(mpB$9v-iDLKCYDric3;8J#)`Sd9#PUa9uuPs?_hjUDXPQ}n$mK1e+R-8SW|uqs;0 zMi~Q`fcAhesPfjxgaUP6fg>~k9FCxJFAISh{!TOMS+9iK!?24M`>lOTW_AU;QfFZg!x`S&r*5$G zdNc)Xo+l1F=F;q3iGG;f_x@Y0n{$-^sfCNv`f>|VLZIH>>`Dc#@ohLG04kepEk`fSF#G58m}L}eLtzC3=|0jd<}_mZue!QNuKGD`!kk#G-X@jYk0 zbNlEaJUbqC@$S8Hh)DP(BeWnvs`j2BC)?g?q@Y(h6I$B9kWy%%mR9_Ep_atD&ln8G z?2QuB)YIF&sdyGjXZ9b7cVNr~<^d59Fkb}4h5tspf;zA5s={6IS%QU#)%@Ui?m(2$ zlRKEf!Rtyi9Py(gDN6N+z-X24Qz>O$Hqc^01l6@na<&8*cIE^_C|AN(GIg?75?VY3 z5kjXrE)wt}`=lC8FySEu!f#8PC$V@=?3PU5YpM=`1k^PoQG#O;*p1z#eSlt98M6T5~&j% z`_lG8s|GgI-3JIGu3hRiw88ZxvDnDJ!$%kdWa!1*ze6CDB>@*7RLm~j#ZubD!h2ZA z203|M=LF%Uk>|KLIOh-2y5iq>@cJXskEMn3iAaX}2Pt>(O!5I+f4;4f%nb&yyZ7#a z-;hD}P-0)hLnf6KRNT*gFfqLnzN-ATJj>IJ`1eRzf0kSOHrE#aP)%qR3Zug zf%&$N%8ICO{!?I-yruCG#JzGeoC^8#&roOdr0lV?JrOiw@EHk*X7-sw*1@OR_Ji^d zd5~bnaE{%|$MH3+Eh|TFy~XRd0eHSVsLZawAdzHoe5~~9Q$%8;J;R{WgMtLx>&>gU z6CNVJ90sGaR;j{?sBgsJa=4U2kUHX%zvqN4As(@_92R*J?EYVpHtl)O=ew59t~8tU z7W>v9m9imoq`X5>;}>(ReKYW4{R7bHo7nS7w| z5!5IlK@BZmZDY~xkQDjE3&trA&=vaoDnq*`_MEiRAblPy>5;-eTIRS<1v7e;We+%^ z^b!wldfF4+hI&6XCWb}3<=l8(#4THe-0`&*?V7=bY@1~sp3?jCK#~+%gS7eswn?Wd zeb$_6L5m3Ol>x_616GTllXrHhBFzb@L#H@j0Kc(@j)O-mu9fo^JiiJMdkFX7s2x{B zodmTdQjQTOdV}cfA-0(X2MJjHB7ZfrSIk#gK*5mgWC+5MOdAVE&QMh10CELZ<6YAT z=!lVqAPK=-uCJS`N}X=_?Q^a=JhO)a`w7|qTHh{=NR)$gNVopYRoL|S>&Sx>QR5!U z#DB_g%taUN|CZr^o*6%Cis&|3wvi=~`WfKdFt=PNvsaWcP}9pmM+@+}2AJs1(LUVi zzx}uT>)444g75De_I|=i>@L}@ZUMeY-q?R=bM6{?e&9s_$0ur^!5*h-vp2C+3T8(E z?d^(B6)eOyCFwFmdDABv)1w4t4SGcw$jX%W=2smP=V;u1RGzX19yMO|KQ zuRSpP5{sFU*0?6Ze7_jy8z5?hxLy|~@D$t`1`(I;yxT(<e>A_azdjyzc`JDPUVKXen`yJLOdsIJ~7KgQ#@0 zYj-S$H<(@Zu|(B_$bN)EE9Gci^?aW6QPv)710#bHsuj`I|3#ldbZDn=QUZp?gNXB( z%_`}R4?CvJiDX~Weyx;1BH{G^Hqk=G3OFN@F+d;jhTV+XV!}QN%9DGa8JT@T!PYwc ztJ8x3#L7!`HNnakhAM%(zrl|D3dmIOqvBMZCvsK}W2ivYwt1=DncP{a-~biH4cO-c zh_)_x_Ih(|0GRz-eT8VPKL;1=s3doRRQ4Au`~!yQzZsD<9Qb@ozi@3jMLn|zU<$C0 z6H%AJZF-gIG+YFisca{M(iBGpg@?2vRKflstz}_lehCEEzfrzD(*cl>&~IhcKW3rR zcmZp3vJ7U0oD^ZVZG$lPvVx*-V?(N&TrC))opZRWB=N}9Ewbz%7FM^Kswod+?xDE} znP8Aj@&NzFFZJvOsL){AJ9wgj1BYR=poD(OX*3Yf;r0%7cVMmo^b~Riba${+as9}d z8(8JH6h2iK4m+j=D!w#QIDR|T#Kk{^Vo>?sT^nNZV8onPJm2){-_lsyrE`Bs-v2O^ zQ#Tj}!fyjLE>!La-;G_%U78x2U$ahn4vi$Z34`p8>^MPxtR)DJs#WRjJ;OMm*bgfG z=U9Upeg!E=tyjTUxT9*fa!N# zp2uL3%GjrZ!+DTgJBkYeomEvnoBuW3-_;?`JaMiTmb}>0=d_`~&1B+am zLGg8l)-Ps9_splgESD^aNG=dyn5xImP2glJibzCpsW^qF4VBuMY}(1!AK{+4jlS(d z?WM>Ot#7Zq5=kDCP02q@&NL5WBnOv%`FT>+lEa;U^l z&Zon#`U1{L>?O5Qc>TbIz*#-&=?w#3$PN>m;KiQpP^^AWw>_3y6!S64rJi$zvDuKF zS#MODYtz^3Qtq4Xbk-sTGdE@imi(j_ct?1vX2<1ihv$nfze{_aQn-F`q#Jg`o0SY+ z4YRDF|DOA*&7ZlXyeP1k9HVgBNL=dJEIF@7%%mebaYMN;lOAi?^PfU(~7_U34QeYk?`P#9= zTJ7H1McpO;izhG&3O%^ec<15g)c72Tbd=Dx;c4XCl9XM%GMmrVp2?B)d3}mUDv*#( zr*81cV#CBZnMs{NXZhCx+dG|2#es@O!S0sjDXFQxf;-=&mF$Py>Oz9oK6*7UBo)u4 z-6dRKO6jwrN=V?qy@K25PWY~5qK8dEp%E|IrKRcWxv>r~u;+Xad6+$%Rtq99CtnqHT`S+8VhiuRP{+d(9}Aw=?~Fao$R1T;L%xZABkdQG2OC(ng=2(qUD-BK^*B zv$A5BFsp`c#;jg*n;Q={1$H(qKGZN+PgT>x6H~7wk55R9o;ZyjCLDIt=Dnn*t&t{L zLnUsf8dD0EzqYk?rY>>zj8cW4V+!DMPM&XbVmeQN(Kf()oru%(jF6h%?p~af_Rp$2 zy*3-O^7ScM{kCo1r^O=$9ME|?!6;X})VZY|{85%MF-fgxYo+m8uBG+pkb6S%$DsjL zUB^s~>5gQc`BA@9mcwcaS;pb+majAJk7E>ZyNy)uUR=X>W?dqz*2Ivy!Dm^(($OD% zD^0gmE3@tu)>{{XzcuXg=%JTuv#I_WKX1G;%wL{L^bZPL*tYwj%SR@9)ScqdN!`dR zZRl=+|B2<@yVpfND=jZ#9VNtQ)8Iy69vvVTX=&LQ z^^=ZgWS9UUT&+Rj592)6ckiFc$jYCutZq^NnxU`6vd)(xdnm^2DveYAwk>nPs)kNu zMEJZt@C|f{@oGDGN2;#ziq~`vxb!*KMXKKYAdjI_Y>9Y|I3#Y$%cdEvrKtZ;n zBD;u3c*P$LW1SYh8}(-2PaJ{6i2SP)+S6-TwT#BRas`T?wGM{%JyGYY|09`$3$k4-en4>))+NH|qI3 z=HDtkl0D+{7{aaaBB}jsvbGw|TkTA07Q)G+5F^U?opM6gzbd?!3J;k#bSEU|UYtqi zS%`P>_qVQ67^PYH5*_&q_UrUABmsO|K2BO3MI$MWqPLWp5?5w|NB*z9 zFMot`5Br|6Obtuj44YAr*==s)>*#Buoj%zNC-v80?|q(J)Ktl$#8l+XSQkHO3~#)jdZAl zcFnrzQFn4{IggvV9iJ|&m+OoZCBVzcsp^)V_q2SK&*i>ufOC0n58Ydtu82d_cj7*I zHW1bk)r0=o792435^{pY_!E{?7A9xfQT#h#;o26Dvyr)vvkWo5;$HtkFE9Nm^@)zq;&Jy74tTBB8W z(avf<$hY^-c2(7!f(8YRlX3+ASuwJ02_-EbbxJ21eR7M0KG92trs4d6oi?yCb=2Qd z7Q!@F+H?ODZU6l;lanC+cyQW%qtCO;zBMQo!iMIoJExy`83+VSl{rgx5Qq+TtlXRu z`ZYBydW<$nKan%KApO0oeP^dCS_h``hhiT+K4=UvZ0x)5-s{7LPfSviX9E%Y4H!Qa zE9^%pS1wq1H{WV*X7j2OW2>Btj}ioC+PO6*_xRcyx||$ff5mnooHz69pXiLho-Kac zXU^{ATR`X)6rP4oT z#JW8m#~>+k&P6R>buUF3_#>+Kwc^! zoxQ$4>~g_5a?6%o;GO){=aUes!?za~FZ36?Bg#qi!*p||ubh^&Mm@tV$l=h*TrlQ( z*Sm18vY*MerKAP_KsZoQq}BIZ=k3B)iEkex8|n9-ravlplLnXpA`OACwN5->k2AN% z&1>I##~>%F-kvrTWDXt0n0XeWPMI@!JOaR6i%MsQ>de(#)!i#+k6F#H{3wxfx+CE8 z{j(~PIRMync6H9t))t*r2b~j5o=K^a2Py)_)bC?e%g{85M@OG6Atc&!q={<&g>8PQ z8r7&=ku;gN!Wt8EUuv%8dh5f^PhI}SeNXpHfW z7xn;MKx z^NSyzm`HXAR4vw49S01NSM|#V>}k4?Z^ZJB&*Ueix_T_`mQd(}Q2$3a4d@-X-b8=YSTC?fl;Z%SnNxF8v_Hck`IM)3h+@*WibJ4xEn(7OkW8_H{IkGU<+$JqJ2Wp7H;I55P3 zS3JGlCOmj`hPP$PHynNUb#Zu*dD7CK-7#<$500;7tiJx&kuoJlP zJ)!MLlCmI*GfVs#4|up|KtP|mLPLY_;-}J_Q9ku?J)_1(IP=OFah5~O^+Uy~s@kh< zj=+WMd^1(5ho)Jz>J*zufH$-C>_L{`D&c=5r1@O;7~e^bY=txL%9h@7G3I$f{`?m; zm5ru!s&y7Nzv>-@v}z0G#GygI9YSfo4p!yL$&SJPEfP9uM>$q&?S;sZ?e^G1=gYR4 zCxZEGGvnW0=ZT^FlODJEV+G>sB!iLw-7fuGDD=Npy=khM@OJkD13*mk@wrPCD=k_G z*7=m`?xb49L}O0bn6*SI=H7$EX0fdn-OF;n zV{rYg2BX^b@3(VCOZwfkT)s`7@orW{lJ$k=w3-?r`}gVYrPA5i0wFI)RRANNEB{{7 z8l+B8;5H9^ktx6YkLo@Bmq2oq`$Y6msnpC~Nltkj7g7cd{p|9dfHElHQ%>|)IlPQA zQ?Q>G#9WfK%%6 zR;>cKdaCzStIg#XcMw5%w8UnPzncyj5+jd{}DF z(&SA(Gh6#+2wG6+!LglB)2=Dh@rfEVCM#{|@8_s3qQ4(n)8|z~W~3wb=J=>TIDJMM z{EWJ@f@4Y;-_G}$*hS)md~#&9Q%lEFJdfiIr;mGw9+`8%d57HI%!0_L4+HmSGbFC{ zC8WHzxt{y-nA^>)_t7E;N@rH*%NVt($a^Md7BdPVZnG-k zPzJESJor?n&QlzH=xZ~I_`J`zwc=ps$9?{D!_m&Y#h2@-Pt#kbW3^(*$+8H>bO`uq z2|>jVO7IO-=FTfYYdc$gCYUiYAAb^*)l8$wM+RR@7}>PKtcqW_*r89fMA|DxlML>S zDf1^zz{yE_ajFoKVMmFIjLYRSS3g=J=KaJpy@m1kn0N1sk_$iIE!>@4C%^uiL#;P( zUYn9gx$uRZ^i)1_RB1xxHHW!8M7mvx0qH~PKRC283k|kA32&QH55-;1m8_o5D}}QK zlb2E^m=l#9Miy3(yH|)(=cSnEDz?C9*c@DHQM_^lzaQP z7}3_TwKhnt#k0WYo^FUvSFA|&ox6^2VOi|JLx7uFBX{mh6}Ju`bxL!Cc18$4Uc~bfvcL=EQy z5xn;42ZlE?^Vz;$75e7bPD+TCxba1^zj7E=k;6TeGktjC=oN{@{s4DCqKiHEmJ?*G z-Pe9@REW)~bswvkhfmuxR&uV{=k%R(dj33nqGaXAh8jOd=?%(9UQlWj^5l7P3SfeP z@`fJE(XHqTuQ_&Er9}1Evb9gW>LCjk|3%exu@V{q;~L_@!wE$f+jsG8jT-cB)iDOR zkRCWk*r*e@wU_1pPP-~7q3MIv=`Npi*j`0tUi?}REWH`ChM%KQw}wiE2wU5foE10n?Scvl%gJ1Gf+-?e?ff zilxlG3Fl|i83GEr?=}->*`5t267^%5QBtJdZU&5`s8XJGIj`dHTK4<8yk(!iWgp0V zlJdZ}N0x6Q(owt)Y(*mNkPH9+0^L_zG{pDK80J|eQKSy-=vIx)oXUO4*q-~AKaxH4 z#y?llsBLwgj`Xt`S6iw|DN;YbOP7i+cPYahgAr1J zdI;|O?{x%$*nSVQ5SMw;Rk`XJgn^FzJ}BJjOnFhUx>*!mnO5?WA~%B+ki|H%lo(+w!XpIUx2aYMN;@GEpj|G7#jNmU)b+g;(nQwx35cKARX)ljU6~3=38C+j6w=p{j z8^`9Qo^LTpQ%_h&sdk+G>D7u zSa!0wvBh2_yUS;FUn%J`0%fCY-HHXS^8C!{&pu7JX#N1FEtNrXEM0%C+tz)L@i7uQ zC4?(M5?WKG=a4F@{k4d&Fy3rH$nf{54b@fP=LD|VVa!nJ z;hAmu-tj1M(LLXR;MBPeVr_-0ayEmNS2Mn2&g(Vo$bdAK#A(VB08eLAt6u(oy3$wx z0rT5Q5hQ7B*5}PSp={PPq~%+Dm1>t=B9zpxdIz!vWO2r=sDNW;NsLd~;(%#30^InO z=bqxeERyW6wu%}MziF>`pR+h^ISVgAIcxVmw^Tf-&A@V``~303b_3HHg$soq1`$-g zue!f`Q!`uaQKw^pRjcH0&lMi}t-4z`yO;N0v*`L*@X6-#2$Y^# z4T>~3Gky~;k>3$2{M5$dEPDmJu|9%?8Y%*YUw?@MFkI90@DAhL6Gb2Eu#N&RK=-s8 zj1qHl3iVKEr5S&anC7ibDR55UUB&C{2`58~+2WJT5x6)~ZOj-epT3|P@=qu_O>4?d zGcR8ssjt4hK~G8I+uyexp|R+FL7=+60umz~5-4ol2Z4g-K?K&)-ypD7tnhk5$+bL( zPSu0?BUZMfP>W}^OzKt1N6JO;&K=&2-~2Xc6w_av?n#;l0jN5L1kFghWM|)3-#35g zK6G%a!3f{Y-sEV9-TDZY>h!-e{D6sjbaPM3rX7W!L4?pJ;>SI6=J& zW|!c*l|hgYE);*XY6K|phliqv4?lkXD8^b8GsZBMpFAhv5RmAxUf+wY0GNlLJ&v1=*CjNhAEPJ9N9OWMU~PZL z*dOdDJ@GmWssw#S-#MXZN@soP9AIw0*>ItPl))E{y3bvnPi#O-0$K0?pZb1)0nB>1E~xg!O0n3r?R^`awod%o6Bfx>*~z7-$qW5cE=)DSnqfoy$6p<;N;F5H3E!z+94jEt;KCWbg|;6<}K@oM0M0vNiCZ#TiF zuPQ9)vHW!npLo09QEi_93I#UP z-N^+R9Tao~k{EaPu>U6!RvYdZbAC7N6PWX|=l{K#iUqa)b5x(u!SqW2r@sB@<}i6P zDn-8BfOUuK--fRI-Lh*U;(vg3Ig}M6o$oRPlVLQy4X|f8FZuFsxBRr>Q-9EnNT#msSf~_dis+Wc>~)F5zUx2iLxTMl>>U{JkDv_hR58ag&RV z4aW@RCfw{-@PI??fL^d`(G1#FGyeWmT6PJP!>5m?y_~n$&FC)FnkE!2jUw<8hVJjIucKUzVp$&z&1}#{aZC#{-prH!M`n0az?z zYei$AtzZIU)c+o114z5E+F`^+U<~eBoqfsM1q1>aBX?od%(aIMfN6Bt+!O&!NNBLR zks3M#nNm#C(A;}7+1hM4s7!|Vvsy70N)Bw@>FSIYetRxXC*|WRtp4Hw0KpR2ZfML9 zjHNlAhrX7NB$f&P4sR(N%G5?J$>#?hx(+|l9sCC`WJiOv4^?Sj*@3ZS-ZA=7 z-q}HE0_Qn34_AIXd^G(N3dJ`*k>Y2o& zGV-8gu*GFP!;zWt#mOnB%_$twt5Q~8*c$j4&L_SNqD@lrBUZypg7|h=WN_!{V|5kO zjI;Pha(&XV&}KF7zcwcCU@ze+c*VEj+y81iLOJM-3BBQgq4Cvt_Qei+(5j(+<@^Xx zaH48OGH|`e+4$$8ZHZg+ZAg0=J1`$!U!Bx`iddDcA@52m90vLbad4Zzcz13E$x7hc zx6^v`Mi=i9aBaEv&|Gx6`wf;)`>$y)jLW3KM@5v^WpQc8=xOqiu^zK30vu53Zt+E} z7OBUspi9v95aKx7{|lss&4fvo7Wsqdm6hpeY`7}B`oYM|x}zAJ!KO#fgfm*BhWwPs z-e@)62Y7{piE<`?E>@QBho-pHDnpu;!{f)ySsyr%>ePNh$1Zm?25+`tHoh|)i7T_) zQB)NCzAyiWrqR_;K3a3|=m+30(;4<1(0n@7H?0Rx^$ixlUxMk@>szGsJ}j@CjVevj0Xv%IH~N z@(!QVuz!V&od`K0S5`m%64ve4w7F1J#`xAgUe_I(x3EB?3W_y!D|G8^_LuM*H`lSz zPtye8S28x?jT}Qj8BT_(mOv5beYVVCAf_L|0)A>j#nx0uW?iUb(Q~Q1p14Zy-wVr6 zA=tT=Ydy-D4#1&A3rjUQFtoBA)s{WZVC?O_fKW#X5&D6vp6SU2{o5^ z>o3R1z-2?1CxL8w3X)==n#l;>T?BGuZ8_}`trTWe((*+a)|?a1m-V;;?Qkqr-p+XL zGwkZH!1kec3Ov0@2)^jci!iIIWga#ZR<4gpNU{|~5oc{!OW8LTC&`_z+8A-(Kv7uO z?L+AE3*ww&>ty9(MaT%hB3*y^?+1vLD8W<{`CJ|{`7Rq%(E|xy*=^lG#mHSP6vbyr zs|{0n0O8o;)Q?^MG4!vFMrbY+?ywwd6*`vX3405W{x0R%Tnc>~iAdi=PPr8aBX;gs zl4(1HJk~i}%TmQI_ZROj>ZLMPJ)@^v^>pbcNGIV|EcH^8G^1ybPl!oWfNLGgG!xnr zL?0CR^679!l`k;HAFGAJR&crUM6-!*5MTDuaPB~`nBA%|b&MB9i0TzwV$F9zh`)3{ z1{2HvkPr3_o%O(kQfdzKxpG9a2(lqG78HgKJ2ReuT8e~$=Ve@KVjq7#m@7O-jgis# z!u$wK3rKEU%VV)ceWb0@tifnnQ%&a%1aQH8%Uge-;)@Qd$@TE$TO$unF#ThO?U^M& zrbRcX=F+7%crSB3+}=YTf?y)|xRMf9qp!`XT)GVxapo0a`)GM^FBVs`j^^H_G2uu~ zjs)(UT(t8K)EDa~Rv&|FS3$Be4C|?{j>KcgnASe5$|w#NGelqlg~FxV)y3`!t4C2T zG_dFql^57^S%O6nv%`-E(G5thKv&8kDRg`i*Exb4=QEB`L_@@v_m0mM7V|-f7zu?L zM?Sx%eZ;oP8IdVd+FQ9f2Ds9W61T$=I>jy^Za5*dI!pzTHMNXE9(KOy2)sA!<3bS_ z+gMA;QyjwKaqNcVBJ6xW}>^x{xY(Nc)oOF^|n z^QCR$d{b59-UKq66dDu18tpTyf|~{gsnlZD7Pbb#AY}saa}$SXD3=iYXaWn>MES#n z7K}RoEyQ=Ixc9Uxw7n#KkOT1_xOlM_C8V-!Nv8bylV$Ju_B=BGU(P5)&hP9bEjmeC zN{?(2sKdq)znbF>6Ul>G6|gVD%)`7gyb(z%MN#!6>XpqF z6uNS68mliV?l%)bmyAW6(_Q zG(1!}Og3Kht6hv9ETQ=Zu;G$x!*ZPEqh2dwf)jhghCQmp!r0F~HYASjL19&WUxe)l zBW45uCzP)XJZ&gDo+cg`r{Ds}^Gp$jBQdS=4dRWIuQTrSKyo;<2?n}!A5go3+V>^* z?fG8F#nFk&_QyhYAu^zL|mbT;BLE|QgBtGJjwVTFdo7Uaom-$RE8 zk)f6dvjR_4!rE!Yr89Re-UCHhcw4$UUHpxz9yw_#dRT;cIZOk2ZUCM$O0}Y$rIpc^ z;Sc0@es|AjGnF=ci&_tYH_G19eV4MOTNzx2_`xq0uCj)z+>p(RWe>%^jm6?=4%nJd zEYx5(VhylNUZDvj%geaV~Iz)E4G-*pxBrTLOhZQ36;nbejS}+5k;N zZx9(<_n=@Yzu&eq;B;7lgK)K>sg^cD`=ZwiS8*>!3aB^Pl7*_oM3Kr+6<49gM+_w7Qag8SXp%yF$*k z9V90a;T8+wWDG}q61tau^#(bmO4u(9=+mnAUMEvR!9=JtIRvkZ^e-EBKzuSFtI;-X zMIS;W90jIFdG`sUe&f7v=oq`9f<-!{#Y3#_9Kgx)R)l=*BGjwhJpwag8OGh}8Pkx*w-STLym>e__P=pfd<^6{aqBnOy| zVuwio>%!W7G-l888AVrdLNjeQ?JzcK-FfzYFhM~RNKE1tV_8vJ?j}=q#wWRPh214Q zoT!rW(}J6cl?aK;IR;*S^oQ7pt=G84juUsJptU))xwTQN8@HH4#Gv?G=9xlGu}|?V z@WLIE(U^5kZ38d+^wxP}q7jTi7F^^aE#jrh(Tx}r8JyUM(5i&AZl?T9UdAOXfxQ~k zxL|I>Vw<2Xm#>)rGgCLw;*20lg`D<@*`3)c#AX74*$`-@WPRM;eV@YJeP@{TR{s1> zT-Kjt)|H267H0Wp?Ar{;lnZZRsH7JHgciPTktKmPjQmy+Lj__CEtRGlx|{HDC|!Ji zJeKMYL}N#cc9Zo<$4R?MTp5;a2E_S;QhwpX57wR%1Xn-Yl!L5=m^QJ}2lYz2MTfUw0(~9H{I|f>sBJmiu9f5G z3h`CBf(H}e9A1nAyMygiSKbYv>C!$#45Jx}^-8R%C^41gz##4Or_MHEz%K7ImFO|} zbW=_d$d9sMn^@J;FG3w?f77mG$F}D1t^RRQV(;C^I&FFoJ)PDY6&!?F3Z<}tJgkwM z1;EEOu}-vQY>nPDKID@QNm(G*8XL7di=CdTDje_P^L(U2P}qeKaL`)dOhEhbJctp@ z0Y%QJUJLp;GJb7QN=j*YX%|VEKu(DUUI@2yS4;TE30^ZKQxcG7yN&-96&o=V#ChV( z0)uV6ynB%m2w)WvPLYo$nV%(lzS@f&{U+ z>Dv`DAlZZ?qnCY*VJ4#wuaC{UVYRjjGS4WVXd+e0_?HCF#@)t7t<(rD4~FRMJ8=R~ zY8>*w**i1U`lRrh;O}fjvbe3ute+F63@(<8xAw-1yLO9?=XZCxqW3Um2D3k8PM4G( zBQ3|R_FtmCs|nUk9JW}srrD8r_ofa%SnR=atxOB9F?{H@ msbuild.cmd echo "@ signtool sign /f "\%"1 /p "\%"2 /tr http://timestamp.comodoca.com /du https://parity.io "\%"3" > sign.cmd } build () { @@ -166,19 +165,6 @@ make_pkg () { sign_exe () { ./sign.cmd $keyfile $certpass "target/$PLATFORM/release/parity.exe" } -make_exe () { - ./msbuild.cmd - ./sign.cmd $keyfile $certpass windows/ptray/x64/release/ptray.exe - cd nsis - curl -sL --url "https://github.com/paritytech/win-build/raw/master/vc_redist.x64.exe" -o vc_redist.x64.exe - echo "makensis.exe installer.nsi" > nsis.cmd - ./nsis.cmd - cd .. - cp nsis/installer.exe "parity_"$VER"_"$IDENT"_"$ARC"."$EXT - ./sign.cmd $keyfile $certpass "parity_"$VER"_"$IDENT"_"$ARC"."$EXT - $MD5_BIN "parity_"$VER"_"$IDENT"_"$ARC"."$EXT -p %h > "parity_"$VER"_"$IDENT"_"$ARC"."$EXT".md5" - $SHA256_BIN "parity_"$VER"_"$IDENT"_"$ARC"."$EXT -p %h > "parity_"$VER"_"$IDENT"_"$ARC"."$EXT".sha256" -} push_binaries () { echo "Push binaries to AWS S3" aws configure set aws_access_key_id $s3_key @@ -205,9 +191,6 @@ push_binaries () { aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/$BUILD_PLATFORM/whisper$S3WIN --body target/$PLATFORM/release/whisper$S3WIN aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/$BUILD_PLATFORM/whisper$S3WIN.md5 --body whisper$S3WIN.md5 aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/$BUILD_PLATFORM/whisper$S3WIN.sha256 --body whisper$S3WIN.sha256 - aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/$BUILD_PLATFORM/"parity_"$VER"_"$IDENT"_"$ARC"."$EXT --body "parity_"$VER"_"$IDENT"_"$ARC"."$EXT - aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/$BUILD_PLATFORM/"parity_"$VER"_"$IDENT"_"$ARC"."$EXT".md5" --body "parity_"$VER"_"$IDENT"_"$ARC"."$EXT".md5" - aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/$BUILD_PLATFORM/"parity_"$VER"_"$IDENT"_"$ARC"."$EXT".sha256" --body "parity_"$VER"_"$IDENT"_"$ARC"."$EXT".sha256" } make_archive () { echo "add artifacts to archive" @@ -356,7 +339,6 @@ case $BUILD_PLATFORM in build sign_exe calculate_checksums - make_exe make_archive push_binaries updater_push_release diff --git a/windows/ptray/ptray.cpp b/windows/ptray/ptray.cpp deleted file mode 100644 index 8701daecb5..0000000000 --- a/windows/ptray/ptray.cpp +++ /dev/null @@ -1,360 +0,0 @@ -// Copyright 2015-2018 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity. If not, see . - -#define WIN32_LEAN_AND_MEAN -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "resource.h" - -#pragma comment(lib, "shlwapi.lib") - -#define MAX_LOADSTRING 100 -#define IDM_EXIT 100 -#define IDM_OPEN 101 -#define IDM_AUTOSTART 102 -#define WM_USER_SHELLICON WM_USER + 1 - -HANDLE parityHandle = INVALID_HANDLE_VALUE; -DWORD parityProcId = 0; -NOTIFYICONDATA nidApp; -WCHAR szTitle[MAX_LOADSTRING]; -WCHAR szWindowClass[MAX_LOADSTRING]; -LPCWCHAR commandLineFiltered = L""; - -LPCWSTR cParityExe = _T("parity.exe"); - -ATOM MyRegisterClass(HINSTANCE hInstance); -bool InitInstance(HINSTANCE, int, LPWSTR cmdLine); -LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); -void KillParity(); -void OpenUI(); -bool ParityIsRunning(); -bool AutostartEnabled(); -void EnableAutostart(bool enable); - -bool GetParityExePath(TCHAR* dest, size_t destSize) -{ - if (!dest || MAX_PATH > destSize) - return false; - GetModuleFileName(NULL, dest, (DWORD)destSize); - if (!PathRemoveFileSpec(dest)) - return false; - return PathAppend(dest, _T("parity.exe")) == TRUE; -} - -bool GetTrayExePath(TCHAR* dest, size_t destSize) -{ - if (!dest || MAX_PATH > destSize) - return false; - GetModuleFileName(NULL, dest, (DWORD)destSize); - return true; -} - -int APIENTRY wWinMain(_In_ HINSTANCE hInstance, - _In_opt_ HINSTANCE hPrevInstance, - _In_ LPWSTR lpCmdLine, - _In_ int nCmdShow) -{ - UNREFERENCED_PARAMETER(hPrevInstance); - UNREFERENCED_PARAMETER(lpCmdLine); - - CreateMutex(0, FALSE, _T("Local\\ParityTray")); - if (GetLastError() == ERROR_ALREADY_EXISTS) { - // open the UI - OpenUI(); - return 0; - } - - LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); - LoadStringW(hInstance, IDC_PTRAY, szWindowClass, MAX_LOADSTRING); - MyRegisterClass(hInstance); - - if (!InitInstance(hInstance, nCmdShow, lpCmdLine)) - return FALSE; - - HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_PTRAY)); - MSG msg; - // Main message loop: - while (GetMessage(&msg, nullptr, 0, 0)) - { - if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) - { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - } - - return (int)msg.wParam; -} - -ATOM MyRegisterClass(HINSTANCE hInstance) -{ - WNDCLASSEXW wcex; - - wcex.cbSize = sizeof(WNDCLASSEX); - - wcex.style = CS_HREDRAW | CS_VREDRAW; - wcex.lpfnWndProc = WndProc; - wcex.cbClsExtra = 0; - wcex.cbWndExtra = 0; - wcex.hInstance = hInstance; - wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_PTRAY)); - wcex.hCursor = LoadCursor(nullptr, IDC_ARROW); - wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); - wcex.lpszMenuName = MAKEINTRESOURCEW(IDC_PTRAY); - wcex.lpszClassName = szWindowClass; - wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL)); - - return RegisterClassExW(&wcex); -} - - -bool InitInstance(HINSTANCE hInstance, int nCmdShow, LPWSTR cmdLine) -{ - if (lstrlen(cmdLine) > 0) - { - int commandLineArgs = 0; - LPWSTR* commandLine = CommandLineToArgvW(cmdLine, &commandLineArgs); - LPWSTR filteredArgs = new WCHAR[lstrlen(cmdLine) + 2]; - filteredArgs[0] = '\0'; - for (int i = 0; i < commandLineArgs; i++) - { - // Remove "ui" from command line - if (lstrcmp(commandLine[i], L"ui") != 0) - { - lstrcat(filteredArgs, commandLine[i]); - lstrcat(filteredArgs, L" "); - } - } - commandLineFiltered = filteredArgs; - } - - // Check if already running - PROCESSENTRY32 entry; - entry.dwSize = sizeof(PROCESSENTRY32); - - HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL); - if (Process32First(snapshot, &entry) == TRUE) - { - while (Process32Next(snapshot, &entry) == TRUE) - { - if (lstrcmp(entry.szExeFile, cParityExe) == 0) - { - parityHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, entry.th32ProcessID); - parityProcId = entry.th32ProcessID; - break; - } - } - } - - CloseHandle(snapshot); - - if (parityHandle == INVALID_HANDLE_VALUE) - { - // Launch parity - TCHAR path[MAX_PATH] = { 0 }; - if (!GetParityExePath(path, MAX_PATH)) - return false; - - PROCESS_INFORMATION procInfo = { 0 }; - STARTUPINFO startupInfo = { sizeof(STARTUPINFO) }; - - LPWSTR cmd = new WCHAR[lstrlen(cmdLine) + lstrlen(path) + 2]; - lstrcpy(cmd, path); - lstrcat(cmd, _T(" ")); - lstrcat(cmd, cmdLine); - if (!CreateProcess(nullptr, cmd, nullptr, nullptr, false, CREATE_NO_WINDOW, nullptr, nullptr, &startupInfo, &procInfo)) - return false; - delete[] cmd; - parityHandle = procInfo.hProcess; - parityProcId = procInfo.dwProcessId; - } - - HWND hWnd = CreateWindowW(szWindowClass, szTitle, 0, - CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr); - - if (!hWnd) - return false; - - HICON hMainIcon = LoadIcon(hInstance, (LPCTSTR)MAKEINTRESOURCE(IDI_PTRAY)); - - nidApp.cbSize = sizeof(NOTIFYICONDATA); // sizeof the struct in bytes - nidApp.hWnd = (HWND)hWnd; //handle of the window which will process this app. messages - nidApp.uID = IDI_PTRAY; //ID of the icon that willl appear in the system tray - nidApp.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP; //ORing of all the flags - nidApp.hIcon = hMainIcon; // handle of the Icon to be displayed, obtained from LoadIcon - nidApp.uCallbackMessage = WM_USER_SHELLICON; - LoadString(hInstance, IDS_CONTROL_PARITY, nidApp.szTip, MAX_LOADSTRING); - Shell_NotifyIcon(NIM_ADD, &nidApp); - - SetTimer(hWnd, 0, 1000, nullptr); - return true; - -} - -LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - switch (message) - { - case WM_USER_SHELLICON: - // systray msg callback - POINT lpClickPoint; - switch (LOWORD(lParam)) - { - case WM_LBUTTONDOWN: - OpenUI(); - break; - case WM_RBUTTONDOWN: - UINT uFlag = MF_BYPOSITION | MF_STRING; - GetCursorPos(&lpClickPoint); - HMENU hPopMenu = CreatePopupMenu(); - InsertMenu(hPopMenu, 0xFFFFFFFF, MF_BYPOSITION | MF_STRING, IDM_OPEN, _T("Open")); - InsertMenu(hPopMenu, 0xFFFFFFFF, MF_SEPARATOR | MF_BYPOSITION, 0, nullptr); - InsertMenu(hPopMenu, 0xFFFFFFFF, MF_BYPOSITION | MF_STRING, IDM_AUTOSTART, _T("Start at Login")); - InsertMenu(hPopMenu, 0xFFFFFFFF, MF_SEPARATOR | MF_BYPOSITION, 0, nullptr); - InsertMenu(hPopMenu, 0xFFFFFFFF, MF_BYPOSITION | MF_STRING, IDM_EXIT, _T("Exit")); - bool autoStart = AutostartEnabled(); - CheckMenuItem(hPopMenu, IDM_AUTOSTART, autoStart ? MF_CHECKED : autoStart); - - SetForegroundWindow(hWnd); - TrackPopupMenu(hPopMenu, TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_BOTTOMALIGN, lpClickPoint.x, lpClickPoint.y, 0, hWnd, NULL); - return TRUE; - - } - break; - case WM_COMMAND: - { - int wmId = LOWORD(wParam); - // Parse the menu selections: - switch (wmId) - { - case IDM_EXIT: - DestroyWindow(hWnd); - break; - case IDM_OPEN: - OpenUI(); - break; - case IDM_AUTOSTART: - { - bool autoStart = AutostartEnabled(); - EnableAutostart(!autoStart); - } - break; - default: - return DefWindowProc(hWnd, message, wParam, lParam); - } - } - break; - case WM_DESTROY: - Shell_NotifyIcon(NIM_DELETE, &nidApp); - KillParity(); - PostQuitMessage(0); - break; - case WM_TIMER: - if (!ParityIsRunning()) - DestroyWindow(hWnd); - default: - return DefWindowProc(hWnd, message, wParam, lParam); - } - return 0; -} - -void KillParity() -{ - DWORD procId = parityProcId; - //This does not require the console window to be visible. - if (AttachConsole(procId)) - { - // Disable Ctrl-C handling for our program - SetConsoleCtrlHandler(nullptr, true); - GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0); - FreeConsole(); - - //Re-enable Ctrl-C handling or any subsequently started - //programs will inherit the disabled state. - SetConsoleCtrlHandler(nullptr, false); - } - WaitForSingleObject(parityHandle, INFINITE); -} - -bool ParityIsRunning() -{ - return WaitForSingleObject(parityHandle, 0) == WAIT_TIMEOUT; -} - -void OpenUI() -{ - // Launch parity - TCHAR path[MAX_PATH] = { 0 }; - if (!GetParityExePath(path, MAX_PATH)) - return; - - PROCESS_INFORMATION procInfo = { 0 }; - STARTUPINFO startupInfo = { sizeof(STARTUPINFO) }; - - LPWSTR args = new WCHAR[lstrlen(commandLineFiltered) + MAX_PATH + 2]; - lstrcpy(args, L"parity.exe "); - lstrcat(args, commandLineFiltered); - lstrcat(args, L" ui"); - CreateProcess(path, args, nullptr, nullptr, false, CREATE_NO_WINDOW, nullptr, nullptr, &startupInfo, &procInfo); -} - -bool AutostartEnabled() { - HKEY hKey; - LONG lRes = RegOpenKeyExW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Run", 0, KEY_READ, &hKey); - if (lRes != ERROR_SUCCESS) - return false; - - WCHAR szBuffer[512]; - DWORD dwBufferSize = sizeof(szBuffer); - ULONG nError; - nError = RegQueryValueExW(hKey, L"Parity", 0, nullptr, (LPBYTE)szBuffer, &dwBufferSize); - if (ERROR_SUCCESS != nError) - return false; - return true; -} - -void EnableAutostart(bool enable) { - HKEY hKey; - LONG lRes = RegOpenKeyExW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Run", 0, KEY_WRITE, &hKey); - if (lRes != ERROR_SUCCESS) - return; - - if (enable) - { - LPWSTR args = new WCHAR[lstrlen(commandLineFiltered) + MAX_PATH + 2]; - if (GetTrayExePath(args, MAX_PATH)) - { - lstrcat(args, L" "); - lstrcat(args, commandLineFiltered); - RegSetValueEx(hKey, L"Parity", 0, REG_SZ, (LPBYTE)args, MAX_PATH); - } - delete[] args; - } - else - { - RegDeleteValue(hKey, L"Parity"); - } -} diff --git a/windows/ptray/ptray.ico b/windows/ptray/ptray.ico deleted file mode 100644 index cda99eef8b3668827befd6a13ff8268c096ceae4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 102596 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 UthP^z@jit)bXR-G*R9U_4@oN!P5=M^ diff --git a/windows/ptray/ptray.vcxproj b/windows/ptray/ptray.vcxproj deleted file mode 100644 index e015d55c1e..0000000000 --- a/windows/ptray/ptray.vcxproj +++ /dev/null @@ -1,155 +0,0 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - {37C89E90-8C9E-4FFC-AAE7-B3695D5EB6F4} - Win32Proj - ptray - 8.1 - - - - Application - true - v140 - Unicode - - - Application - false - v140 - true - Unicode - - - Application - true - v140 - Unicode - - - Application - false - v140 - true - Unicode - - - - - - - - - - - - - - - - - - - - - true - - - true - - - false - - - false - - - - NotUsing - Level3 - Disabled - WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) - - - Windows - true - - - - - NotUsing - Level3 - Disabled - _DEBUG;_WINDOWS;%(PreprocessorDefinitions) - - - Windows - true - - - - - Level3 - NotUsing - MaxSpeed - true - true - WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) - - - Windows - true - true - true - - - - - Level3 - NotUsing - MaxSpeed - true - true - NDEBUG;_WINDOWS;%(PreprocessorDefinitions) - - - Windows - true - true - true - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/windows/ptray/resource.h b/windows/ptray/resource.h deleted file mode 100644 index 1f4b023431b96fb9c6edaf617bd5e9ac940c75c7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1788 zcmb7_QEw7K6ot>TiT_~}AB|Gbr24o58X`*xONo6VmV&`F#XwOT<6pOaXQreS*ab3K zX6EjlbI;zn=W_qAqKf`7Iy%!(4K>x}>4a5Bb+y>#`pbB(XZTi>DAQCU%{9}4XQEqd z18fT|^;OsG>UzmY^i5;k@XWE_GGAevVj1DJWH)9%!E(*&^;(2;u%h>+?(q4+X=B{s zHRtq-i{}>s$0&}Jz_>yDAuKOg*ZHmv*270FpzlI$fZA1GJ*8kfTP;>?B7EA5U)70< zk#o>eu)EBCQ2U@Z_hQCxGV+^3&RIbI0LODs56^-l`oslybJ3A?B^S>yK zRgT;WNUJ;_&-t{FvypQu!?)HhWw;&HoZl59yW$>eWBYWO#mMgqk$WJUaf>?s7-}y& zqBd%KIOp6|%44OJaol|Oit4cXR!U4@H`eda3#{u2YF(mh_lBRWt@kmiw%%uGI0s)CAqto;U@Hxnob#q^WN+P#jImrIicqFWqOs9ct5`3a@MZVYUo-K+5bIP M{4Y!%B0b&z2Q6jVQ2+n{ diff --git a/windows/ptray/targetver.h b/windows/ptray/targetver.h deleted file mode 100644 index 87c0086de7..0000000000 --- a/windows/ptray/targetver.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -// Including SDKDDKVer.h defines the highest available Windows platform. - -// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and -// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. - -#include -- GitLab From a5190449da29790b1d69b31154c1c7e3f1f2bfed Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Wed, 6 Jun 2018 16:05:52 +0800 Subject: [PATCH 105/152] Remove UI related settings from CLI (#8783) * Remove all ui reference in dapps interface * Pass primary cli build * Add back parity wallet dapp as builtin * Clean up ui settings * Fix all tests in cli * Missed ui files to commit * Add parity-utils endpoint back * Fix non-dapp feature compiling * Inline styles * Remove parity-utils endpoint * Remove ui precompiled crate * Remove parity-ui alltogether * Remove ui feature flags * Move errors to static methods * Fix tests * Remove all reference to utils endpoint and remove server side injection According to https://github.com/paritytech/parity/pull/8539, inject.js is already handled by Parity UI. --- Cargo.lock | 56 ------- Cargo.toml | 11 +- dapps/Cargo.toml | 6 - dapps/src/apps/fetcher/installers.rs | 8 +- dapps/src/apps/fetcher/mod.rs | 33 ++--- dapps/src/apps/fs.rs | 9 +- dapps/src/apps/mod.rs | 51 +------ dapps/src/apps/ui.rs | 57 ------- dapps/src/error_tpl.html | 83 ++++++++++- dapps/src/handlers/content.rs | 19 +-- dapps/src/handlers/echo.rs | 2 +- dapps/src/handlers/errors.rs | 66 +++++++++ dapps/src/handlers/fetch.rs | 83 +---------- dapps/src/handlers/mod.rs | 46 +----- dapps/src/handlers/streaming.rs | 7 +- dapps/src/lib.rs | 125 +--------------- dapps/src/page/builtin.rs | 21 +-- dapps/src/page/handler.rs | 6 +- dapps/src/page/local.rs | 8 +- dapps/src/proxypac.rs | 11 +- dapps/src/router.rs | 43 +----- dapps/src/tests/fetch.rs | 30 ++-- dapps/src/tests/helpers/mod.rs | 43 +----- dapps/src/tests/home.rs | 62 -------- dapps/src/tests/mod.rs | 2 - dapps/src/tests/redirection.rs | 206 -------------------------- dapps/src/tests/validation.rs | 43 +----- dapps/src/web.rs | 19 +-- dapps/ui-deprecation/Cargo.toml | 18 --- dapps/ui-deprecation/build.rs | 21 --- dapps/ui-deprecation/build/index.html | 119 --------------- dapps/ui-deprecation/src/lib.rs | 21 --- dapps/ui-deprecation/src/lib.rs.in | 55 ------- dapps/ui/Cargo.toml | 20 --- dapps/ui/src/lib.rs | 45 ------ parity/cli/mod.rs | 88 ++++++----- parity/configuration.rs | 196 +----------------------- parity/dapps.rs | 48 ------ parity/lib.rs | 37 +---- parity/rpc.rs | 64 +------- parity/run.rs | 19 +-- parity/signer.rs | 36 +---- 42 files changed, 305 insertions(+), 1638 deletions(-) delete mode 100644 dapps/src/apps/ui.rs create mode 100644 dapps/src/handlers/errors.rs delete mode 100644 dapps/src/tests/home.rs delete mode 100644 dapps/src/tests/redirection.rs delete mode 100644 dapps/ui-deprecation/Cargo.toml delete mode 100644 dapps/ui-deprecation/build.rs delete mode 100644 dapps/ui-deprecation/build/index.html delete mode 100644 dapps/ui-deprecation/src/lib.rs delete mode 100644 dapps/ui-deprecation/src/lib.rs.in delete mode 100644 dapps/ui/Cargo.toml delete mode 100644 dapps/ui/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index a9d9ab7d10..a22012300b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2071,8 +2071,6 @@ dependencies = [ "parity-dapps-glue 1.9.1 (registry+https://github.com/rust-lang/crates.io-index)", "parity-hash-fetch 1.12.0", "parity-reactor 0.1.0", - "parity-ui 1.12.0", - "parity-ui-deprecation 1.10.0", "parity-version 1.12.0", "parking_lot 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2283,56 +2281,6 @@ dependencies = [ "tokio-uds 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "parity-ui" -version = "1.12.0" -dependencies = [ - "parity-ui-dev 1.9.0 (git+https://github.com/parity-js/shell.git?rev=eecaadcb9e421bce31e91680d14a20bbd38f92a2)", - "parity-ui-old-dev 1.9.0 (git+https://github.com/parity-js/dapp-wallet.git?rev=65deb02e7c007a0fd8aab0c089c93e3fd1de6f87)", - "parity-ui-old-precompiled 1.9.0 (git+https://github.com/js-dist-paritytech/parity-master-1-10-wallet.git?rev=4b6f112412716cd05123d32eeb7fda448288a6c6)", - "parity-ui-precompiled 1.9.0 (git+https://github.com/js-dist-paritytech/parity-master-1-10-shell.git?rev=bd25b41cd642c6b822d820dded3aa601a29aa079)", - "rustc_version 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "parity-ui-deprecation" -version = "1.10.0" -dependencies = [ - "parity-dapps-glue 1.9.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "parity-ui-dev" -version = "1.9.0" -source = "git+https://github.com/parity-js/shell.git?rev=eecaadcb9e421bce31e91680d14a20bbd38f92a2#eecaadcb9e421bce31e91680d14a20bbd38f92a2" -dependencies = [ - "parity-dapps-glue 1.9.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "parity-ui-old-dev" -version = "1.9.0" -source = "git+https://github.com/parity-js/dapp-wallet.git?rev=65deb02e7c007a0fd8aab0c089c93e3fd1de6f87#65deb02e7c007a0fd8aab0c089c93e3fd1de6f87" -dependencies = [ - "parity-dapps-glue 1.9.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "parity-ui-old-precompiled" -version = "1.9.0" -source = "git+https://github.com/js-dist-paritytech/parity-master-1-10-wallet.git?rev=4b6f112412716cd05123d32eeb7fda448288a6c6#4b6f112412716cd05123d32eeb7fda448288a6c6" -dependencies = [ - "parity-dapps-glue 1.9.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "parity-ui-precompiled" -version = "1.9.0" -source = "git+https://github.com/js-dist-paritytech/parity-master-1-10-shell.git?rev=bd25b41cd642c6b822d820dded3aa601a29aa079#bd25b41cd642c6b822d820dded3aa601a29aa079" -dependencies = [ - "parity-dapps-glue 1.9.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "parity-updater" version = "1.12.0" @@ -3970,10 +3918,6 @@ dependencies = [ "checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37" "checksum parity-dapps-glue 1.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "261c025c67ba416e9fe63aa9b3236520ce3c74cfbe43590c9cdcec4ccc8180e4" "checksum parity-tokio-ipc 0.1.5 (git+https://github.com/nikvolf/parity-tokio-ipc)" = "" -"checksum parity-ui-dev 1.9.0 (git+https://github.com/parity-js/shell.git?rev=eecaadcb9e421bce31e91680d14a20bbd38f92a2)" = "" -"checksum parity-ui-old-dev 1.9.0 (git+https://github.com/parity-js/dapp-wallet.git?rev=65deb02e7c007a0fd8aab0c089c93e3fd1de6f87)" = "" -"checksum parity-ui-old-precompiled 1.9.0 (git+https://github.com/js-dist-paritytech/parity-master-1-10-wallet.git?rev=4b6f112412716cd05123d32eeb7fda448288a6c6)" = "" -"checksum parity-ui-precompiled 1.9.0 (git+https://github.com/js-dist-paritytech/parity-master-1-10-shell.git?rev=bd25b41cd642c6b822d820dded3aa601a29aa079)" = "" "checksum parity-wasm 0.27.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a93ad771f67ce8a6af64c6444a99c07b15f4674203657496fc31244ffb1de2c3" "checksum parity-wordlist 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d0dec124478845b142f68b446cbee953d14d4b41f1bc0425024417720dce693" "checksum parking_lot 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "9fd9d732f2de194336fb02fe11f9eed13d9e76f13f4315b4d88a14ca411750cd" diff --git a/Cargo.toml b/Cargo.toml index 24649eff45..7795fb3b3b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -88,16 +88,7 @@ winapi = { version = "0.3.4", features = ["winsock2", "winuser", "shellapi"] } daemonize = { git = "https://github.com/paritytech/daemonize" } [features] -default = ["ui-precompiled"] -ui = [ - "ui-enabled", - "parity-dapps/ui", -] -ui-precompiled = [ - "ui-enabled", - "parity-dapps/ui-precompiled", -] -ui-enabled = ["dapps"] +default = ["dapps"] dapps = ["parity-dapps"] json-tests = ["ethcore/json-tests"] test-heavy = ["ethcore/test-heavy"] diff --git a/dapps/Cargo.toml b/dapps/Cargo.toml index a7ce5a5489..c3fd75ddc1 100644 --- a/dapps/Cargo.toml +++ b/dapps/Cargo.toml @@ -34,8 +34,6 @@ fetch = { path = "../util/fetch" } node-health = { path = "./node-health" } parity-hash-fetch = { path = "../hash-fetch" } parity-reactor = { path = "../util/reactor" } -parity-ui = { path = "./ui" } -parity-ui-deprecation = { path = "./ui-deprecation" } keccak-hash = { path = "../util/hash" } parity-version = { path = "../util/version" } registrar = { path = "../registrar" } @@ -43,7 +41,3 @@ registrar = { path = "../registrar" } [dev-dependencies] env_logger = "0.4" ethcore-devtools = { path = "../devtools" } - -[features] -ui = ["parity-ui/no-precompiled-js"] -ui-precompiled = ["parity-ui/use-precompiled-js"] diff --git a/dapps/src/apps/fetcher/installers.rs b/dapps/src/apps/fetcher/installers.rs index 99b6be218b..9fba80aabe 100644 --- a/dapps/src/apps/fetcher/installers.rs +++ b/dapps/src/apps/fetcher/installers.rs @@ -27,7 +27,6 @@ use mime_guess::Mime; use apps::manifest::{MANIFEST_FILENAME, deserialize_manifest, serialize_manifest, Manifest}; use handlers::{ContentValidator, ValidatorResponse}; use page::{local, PageCache}; -use Embeddable; type OnDone = Box) + Send>; @@ -124,17 +123,15 @@ pub struct Dapp { id: String, dapps_path: PathBuf, on_done: OnDone, - embeddable_on: Embeddable, pool: CpuPool, } impl Dapp { - pub fn new(id: String, dapps_path: PathBuf, on_done: OnDone, embeddable_on: Embeddable, pool: CpuPool) -> Self { + pub fn new(id: String, dapps_path: PathBuf, on_done: OnDone, pool: CpuPool) -> Self { Dapp { id, dapps_path, on_done, - embeddable_on, pool, } } @@ -170,7 +167,6 @@ impl ContentValidator for Dapp { fn validate_and_install(self, response: fetch::Response) -> Result { let id = self.id.clone(); let pool = self.pool; - let embeddable_on = self.embeddable_on; let validate = move |dapp_path: PathBuf| { let (file, zip_path) = write_response_and_check_hash(&id, dapp_path.clone(), &format!("{}.zip", id), response)?; trace!(target: "dapps", "Opening dapp bundle at {:?}", zip_path); @@ -210,7 +206,7 @@ impl ContentValidator for Dapp { let mut manifest_file = fs::File::create(manifest_path)?; manifest_file.write_all(manifest_str.as_bytes())?; // Create endpoint - let endpoint = local::Dapp::new(pool, dapp_path, manifest.into(), PageCache::Enabled, embeddable_on); + let endpoint = local::Dapp::new(pool, dapp_path, manifest.into(), PageCache::Enabled); Ok(endpoint) }; diff --git a/dapps/src/apps/fetcher/mod.rs b/dapps/src/apps/fetcher/mod.rs index 78be4f4cb3..a7afd91eed 100644 --- a/dapps/src/apps/fetcher/mod.rs +++ b/dapps/src/apps/fetcher/mod.rs @@ -31,7 +31,7 @@ use hash_fetch::urlhint::{URLHintContract, URLHint, URLHintResult}; use hyper::StatusCode; use ethereum_types::H256; -use {Embeddable, SyncStatus, random_filename}; +use {SyncStatus, random_filename}; use parking_lot::Mutex; use page::local; use handlers::{ContentHandler, ContentFetcherHandler}; @@ -50,7 +50,6 @@ pub struct ContentFetcher>, sync: Arc, - embeddable_on: Embeddable, fetch: F, pool: CpuPool, only_content: bool, @@ -78,7 +77,6 @@ impl ContentFetcher { resolver, sync, cache: Arc::new(Mutex::new(ContentCache::default())), - embeddable_on: None, fetch, pool, only_content: true, @@ -90,38 +88,30 @@ impl ContentFetcher { self } - pub fn embeddable_on(mut self, embeddable_on: Embeddable) -> Self { - self.embeddable_on = embeddable_on; - self - } - - fn not_found(embeddable: Embeddable) -> endpoint::Response { + fn not_found() -> endpoint::Response { Box::new(future::ok(ContentHandler::error( StatusCode::NotFound, "Resource Not Found", "Requested resource was not found.", None, - embeddable, ).into())) } - fn still_syncing(embeddable: Embeddable) -> endpoint::Response { + fn still_syncing() -> endpoint::Response { Box::new(future::ok(ContentHandler::error( StatusCode::ServiceUnavailable, "Sync In Progress", "Your node is still syncing. We cannot resolve any content before it's fully synced.", Some("Refresh"), - embeddable, ).into())) } - fn dapps_disabled(address: Embeddable) -> endpoint::Response { + fn dapps_disabled() -> endpoint::Response { Box::new(future::ok(ContentHandler::error( StatusCode::ServiceUnavailable, "Network Dapps Not Available", "This interface doesn't support network dapps for security reasons.", None, - address, ).into())) } @@ -195,10 +185,10 @@ impl Endpoint for ContentFetcher { match content { // Don't serve dapps if we are still syncing (but serve content) Some(URLHintResult::Dapp(_)) if self.sync.is_major_importing() => { - (None, Self::still_syncing(self.embeddable_on.clone())) + (None, Self::still_syncing()) }, Some(URLHintResult::Dapp(_)) if self.only_content => { - (None, Self::dapps_disabled(self.embeddable_on.clone())) + (None, Self::dapps_disabled()) }, Some(content) => { let handler = match content { @@ -211,10 +201,8 @@ impl Endpoint for ContentFetcher { content_id.clone(), self.cache_path.clone(), Box::new(on_done), - self.embeddable_on.clone(), self.pool.clone(), ), - self.embeddable_on.clone(), self.fetch.clone(), self.pool.clone(), ) @@ -228,10 +216,8 @@ impl Endpoint for ContentFetcher { content_id.clone(), self.cache_path.clone(), Box::new(on_done), - self.embeddable_on.clone(), self.pool.clone(), ), - self.embeddable_on.clone(), self.fetch.clone(), self.pool.clone(), ) @@ -248,7 +234,6 @@ impl Endpoint for ContentFetcher { Box::new(on_done), self.pool.clone(), ), - self.embeddable_on.clone(), self.fetch.clone(), self.pool.clone(), ) @@ -258,12 +243,12 @@ impl Endpoint for ContentFetcher { (Some(ContentStatus::Fetching(handler.fetch_control())), Box::new(handler) as endpoint::Response) }, None if self.sync.is_major_importing() => { - (None, Self::still_syncing(self.embeddable_on.clone())) + (None, Self::still_syncing()) }, None => { // This may happen when sync status changes in between // `contains` and `to_handler` - (None, Self::not_found(self.embeddable_on.clone())) + (None, Self::not_found()) }, } }, @@ -330,7 +315,7 @@ mod tests { icon_url: "".into(), local_url: Some("".into()), allow_js_eval: None, - }, Default::default(), None); + }, Default::default()); // when fetcher.set_status("test", ContentStatus::Ready(handler)); diff --git a/dapps/src/apps/fs.rs b/dapps/src/apps/fs.rs index 0139e0ec52..975f3067ee 100644 --- a/dapps/src/apps/fs.rs +++ b/dapps/src/apps/fs.rs @@ -24,7 +24,6 @@ use futures_cpupool::CpuPool; use apps::manifest::{MANIFEST_FILENAME, deserialize_manifest}; use endpoint::{Endpoint, EndpointInfo}; use page::{local, PageCache}; -use Embeddable; struct LocalDapp { id: String, @@ -65,14 +64,14 @@ fn read_manifest(name: &str, mut path: PathBuf) -> EndpointInfo { /// Returns Dapp Id and Local Dapp Endpoint for given filesystem path. /// Parses the path to extract last component (for name). /// `None` is returned when path is invalid or non-existent. -pub fn local_endpoint>(path: P, embeddable: Embeddable, pool: CpuPool) -> Option<(String, Box)> { +pub fn local_endpoint>(path: P, pool: CpuPool) -> Option<(String, Box)> { let path = path.as_ref().to_owned(); path.canonicalize().ok().and_then(|path| { let name = path.file_name().and_then(|name| name.to_str()); name.map(|name| { let dapp = local_dapp(name.into(), path.clone()); (dapp.id, Box::new(local::Dapp::new( - pool.clone(), dapp.path, dapp.info, PageCache::Disabled, embeddable.clone()) + pool.clone(), dapp.path, dapp.info, PageCache::Disabled) )) }) }) @@ -90,12 +89,12 @@ fn local_dapp(name: String, path: PathBuf) -> LocalDapp { /// Returns endpoints for Local Dapps found for given filesystem path. /// Scans the directory and collects `local::Dapp`. -pub fn local_endpoints>(dapps_path: P, embeddable: Embeddable, pool: CpuPool) -> BTreeMap> { +pub fn local_endpoints>(dapps_path: P, pool: CpuPool) -> BTreeMap> { let mut pages = BTreeMap::>::new(); for dapp in local_dapps(dapps_path.as_ref()) { pages.insert( dapp.id, - Box::new(local::Dapp::new(pool.clone(), dapp.path, dapp.info, PageCache::Disabled, embeddable.clone())) + Box::new(local::Dapp::new(pool.clone(), dapp.path, dapp.info, PageCache::Disabled)) ); } pages diff --git a/dapps/src/apps/mod.rs b/dapps/src/apps/mod.rs index 32bd7ee0fd..3fe394b6de 100644 --- a/dapps/src/apps/mod.rs +++ b/dapps/src/apps/mod.rs @@ -17,17 +17,15 @@ use std::path::PathBuf; use std::sync::Arc; -use endpoint::{Endpoints, Endpoint}; +use endpoint::Endpoints; use futures_cpupool::CpuPool; -use page; use proxypac::ProxyPac; use web::Web; use fetch::Fetch; -use {WebProxyTokens, ParentFrameSettings}; +use WebProxyTokens; mod app; mod cache; -mod ui; pub mod fs; pub mod fetcher; pub mod manifest; @@ -35,70 +33,37 @@ pub mod manifest; pub use self::app::App; pub const HOME_PAGE: &'static str = "home"; -pub const RPC_PATH: &'static str = "rpc"; -pub const API_PATH: &'static str = "api"; -pub const UTILS_PATH: &'static str = "parity-utils"; +pub const RPC_PATH: &'static str = "rpc"; +pub const API_PATH: &'static str = "api"; pub const WEB_PATH: &'static str = "web"; pub const URL_REFERER: &'static str = "__referer="; -pub fn utils(pool: CpuPool) -> Box { - Box::new(page::builtin::Dapp::new(pool, ::parity_ui::App::default())) -} - -pub fn ui(pool: CpuPool) -> Box { - Box::new(page::builtin::Dapp::with_fallback_to_index(pool, ::parity_ui::App::default())) -} - -pub fn ui_deprecation(pool: CpuPool) -> Box { - Box::new(page::builtin::Dapp::with_fallback_to_index(pool, ::parity_ui_deprecation::App::default())) -} - -pub fn ui_redirection(embeddable: Option) -> Box { - Box::new(ui::Redirection::new(embeddable)) -} - pub fn all_endpoints( dapps_path: PathBuf, extra_dapps: Vec, dapps_domain: &str, - embeddable: Option, web_proxy_tokens: Arc, fetch: F, pool: CpuPool, ) -> (Vec, Endpoints) { // fetch fs dapps at first to avoid overwriting builtins - let mut pages = fs::local_endpoints(dapps_path.clone(), embeddable.clone(), pool.clone()); + let mut pages = fs::local_endpoints(dapps_path.clone(), pool.clone()); let local_endpoints: Vec = pages.keys().cloned().collect(); for path in extra_dapps { - if let Some((id, endpoint)) = fs::local_endpoint(path.clone(), embeddable.clone(), pool.clone()) { + if let Some((id, endpoint)) = fs::local_endpoint(path.clone(), pool.clone()) { pages.insert(id, endpoint); } else { warn!(target: "dapps", "Ignoring invalid dapp at {}", path.display()); } } - // NOTE [ToDr] Dapps will be currently embeded on 8180 - pages.insert( - "ui".into(), - Box::new(page::builtin::Dapp::new_safe_to_embed(pool.clone(), ::parity_ui::App::default(), embeddable.clone())) - ); - // old version - pages.insert( - "v1".into(), - Box::new({ - let mut page = page::builtin::Dapp::new_safe_to_embed(pool.clone(), ::parity_ui::old::App::default(), embeddable.clone()); - // allow JS eval on old Wallet - page.allow_js_eval(); - page - }) - ); pages.insert( "proxy".into(), - ProxyPac::boxed(embeddable.clone(), dapps_domain.to_owned()) + ProxyPac::boxed(dapps_domain.to_owned()) ); pages.insert( WEB_PATH.into(), - Web::boxed(embeddable.clone(), web_proxy_tokens.clone(), fetch.clone(), pool.clone()) + Web::boxed(web_proxy_tokens.clone(), fetch.clone(), pool.clone()) ); (local_endpoints, pages) diff --git a/dapps/src/apps/ui.rs b/dapps/src/apps/ui.rs deleted file mode 100644 index 696ed2523d..0000000000 --- a/dapps/src/apps/ui.rs +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright 2015-2018 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity. If not, see . - -//! UI redirections - -use hyper::StatusCode; -use futures::future; - -use endpoint::{Endpoint, Request, Response, EndpointPath}; -use {handlers, Embeddable}; - -/// Redirection to UI server. -pub struct Redirection { - embeddable_on: Embeddable, -} - -impl Redirection { - pub fn new( - embeddable_on: Embeddable, - ) -> Self { - Redirection { - embeddable_on, - } - } -} - -impl Endpoint for Redirection { - fn respond(&self, _path: EndpointPath, req: Request) -> Response { - Box::new(future::ok(if let Some(ref frame) = self.embeddable_on { - trace!(target: "dapps", "Redirecting to signer interface."); - let protocol = req.uri().scheme().unwrap_or("http"); - handlers::Redirection::new(format!("{}://{}:{}", protocol, &frame.host, frame.port)).into() - } else { - trace!(target: "dapps", "Signer disabled, returning 404."); - handlers::ContentHandler::error( - StatusCode::NotFound, - "404 Not Found", - "Your homepage is not available when Trusted Signer is disabled.", - Some("You can still access dapps by writing a correct address, though. Re-enable Signer to get your homepage back."), - None, - ).into() - })) - } -} diff --git a/dapps/src/error_tpl.html b/dapps/src/error_tpl.html index c6b4db0e7f..4b155cf35d 100644 --- a/dapps/src/error_tpl.html +++ b/dapps/src/error_tpl.html @@ -4,7 +4,88 @@ {title} - +

diff --git a/dapps/src/handlers/content.rs b/dapps/src/handlers/content.rs index ec4d4f2eff..9449f0f796 100644 --- a/dapps/src/handlers/content.rs +++ b/dapps/src/handlers/content.rs @@ -22,14 +22,12 @@ use hyper::StatusCode; use parity_version::version; use handlers::add_security_headers; -use Embeddable; #[derive(Debug, Clone)] pub struct ContentHandler { code: StatusCode, content: String, mimetype: mime::Mime, - safe_to_embed_on: Embeddable, } impl ContentHandler { @@ -37,8 +35,8 @@ impl ContentHandler { Self::new(StatusCode::Ok, content, mimetype) } - pub fn html(code: StatusCode, content: String, embeddable_on: Embeddable) -> Self { - Self::new_embeddable(code, content, mime::TEXT_HTML, embeddable_on) + pub fn html(code: StatusCode, content: String) -> Self { + Self::new(code, content, mime::TEXT_HTML) } pub fn error( @@ -46,7 +44,6 @@ impl ContentHandler { title: &str, message: &str, details: Option<&str>, - embeddable_on: Embeddable, ) -> Self { Self::html(code, format!( include_str!("../error_tpl.html"), @@ -54,24 +51,18 @@ impl ContentHandler { message=message, details=details.unwrap_or_else(|| ""), version=version(), - ), embeddable_on) + )) } - pub fn new(code: StatusCode, content: String, mimetype: mime::Mime) -> Self { - Self::new_embeddable(code, content, mimetype, None) - } - - pub fn new_embeddable( + pub fn new( code: StatusCode, content: String, mimetype: mime::Mime, - safe_to_embed_on: Embeddable, ) -> Self { ContentHandler { code, content, mimetype, - safe_to_embed_on, } } } @@ -82,7 +73,7 @@ impl Into for ContentHandler { .with_status(self.code) .with_header(header::ContentType(self.mimetype)) .with_body(self.content); - add_security_headers(&mut res.headers_mut(), self.safe_to_embed_on, false); + add_security_headers(&mut res.headers_mut(), false); res } } diff --git a/dapps/src/handlers/echo.rs b/dapps/src/handlers/echo.rs index d7484b6d15..03dfd1c974 100644 --- a/dapps/src/handlers/echo.rs +++ b/dapps/src/handlers/echo.rs @@ -40,7 +40,7 @@ impl Into for EchoHandler { .with_header(content_type.unwrap_or(header::ContentType::json())) .with_body(self.request.body()); - add_security_headers(res.headers_mut(), None, false); + add_security_headers(res.headers_mut(), false); res } } diff --git a/dapps/src/handlers/errors.rs b/dapps/src/handlers/errors.rs new file mode 100644 index 0000000000..5261dc3c15 --- /dev/null +++ b/dapps/src/handlers/errors.rs @@ -0,0 +1,66 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +//! Handler errors. + +use handlers::{ContentHandler, FETCH_TIMEOUT}; +use hyper::StatusCode; +use std::fmt; + +pub fn streaming() -> ContentHandler { + ContentHandler::error( + StatusCode::BadGateway, + "Streaming Error", + "This content is being streamed in other place.", + None, + ) +} + +pub fn download_error(e: E) -> ContentHandler { + ContentHandler::error( + StatusCode::BadGateway, + "Download Error", + "There was an error when fetching the content.", + Some(&format!("{:?}", e)), + ) +} + +pub fn invalid_content(e: E) -> ContentHandler { + ContentHandler::error( + StatusCode::BadGateway, + "Invalid Dapp", + "Downloaded bundle does not contain a valid content.", + Some(&format!("{:?}", e)), + ) +} + +pub fn timeout_error() -> ContentHandler { + ContentHandler::error( + StatusCode::GatewayTimeout, + "Download Timeout", + &format!("Could not fetch content within {} seconds.", FETCH_TIMEOUT.as_secs()), + None, + ) +} + +pub fn method_not_allowed() -> ContentHandler { + ContentHandler::error( + StatusCode::MethodNotAllowed, + "Method Not Allowed", + "Only GET requests are allowed.", + None, + ) +} diff --git a/dapps/src/handlers/fetch.rs b/dapps/src/handlers/fetch.rs index 860fe998c4..3fee3b1fec 100644 --- a/dapps/src/handlers/fetch.rs +++ b/dapps/src/handlers/fetch.rs @@ -19,20 +19,17 @@ use std::{fmt, mem}; use std::sync::Arc; use std::sync::atomic::{AtomicBool, Ordering}; -use std::time::{Instant, Duration}; +use std::time::Instant; use fetch::{self, Fetch}; use futures::sync::oneshot; use futures::{self, Future}; use futures_cpupool::CpuPool; -use hyper::{self, StatusCode}; +use hyper; use parking_lot::Mutex; use endpoint::{self, EndpointPath}; -use handlers::{ContentHandler, StreamingHandler}; +use handlers::{ContentHandler, StreamingHandler, FETCH_TIMEOUT, errors}; use page::local; -use {Embeddable}; - -const FETCH_TIMEOUT: Duration = Duration::from_secs(300); pub enum ValidatorResponse { Local(local::Dapp), @@ -134,8 +131,7 @@ impl Future for WaitingHandler { return Ok(futures::Async::Ready(handler.into())); }, WaitResult::NonAwaitable => { - let errors = Errors { embeddable_on: None }; - return Ok(futures::Async::Ready(errors.streaming().into())); + return Ok(futures::Async::Ready(errors::streaming().into())); }, WaitResult::Done(endpoint) => { WaitState::Done(endpoint.to_response(&self.path).into()) @@ -152,63 +148,6 @@ impl Future for WaitingHandler { } } -#[derive(Debug, Clone)] -struct Errors { - embeddable_on: Embeddable, -} - -impl Errors { - fn streaming(&self) -> ContentHandler { - ContentHandler::error( - StatusCode::BadGateway, - "Streaming Error", - "This content is being streamed in other place.", - None, - self.embeddable_on.clone(), - ) - } - - fn download_error(&self, e: E) -> ContentHandler { - ContentHandler::error( - StatusCode::BadGateway, - "Download Error", - "There was an error when fetching the content.", - Some(&format!("{:?}", e)), - self.embeddable_on.clone(), - ) - } - - fn invalid_content(&self, e: E) -> ContentHandler { - ContentHandler::error( - StatusCode::BadGateway, - "Invalid Dapp", - "Downloaded bundle does not contain a valid content.", - Some(&format!("{:?}", e)), - self.embeddable_on.clone(), - ) - } - - fn timeout_error(&self) -> ContentHandler { - ContentHandler::error( - StatusCode::GatewayTimeout, - "Download Timeout", - &format!("Could not fetch content within {} seconds.", FETCH_TIMEOUT.as_secs()), - None, - self.embeddable_on.clone(), - ) - } - - fn method_not_allowed(&self) -> ContentHandler { - ContentHandler::error( - StatusCode::MethodNotAllowed, - "Method Not Allowed", - "Only GET requests are allowed.", - None, - self.embeddable_on.clone(), - ) - } -} - enum FetchState { Error(ContentHandler), InProgress(Box + Send>), @@ -237,7 +176,6 @@ impl fmt::Debug for FetchState { pub struct ContentFetcherHandler { fetch_control: FetchControl, status: FetchState, - errors: Errors, } impl ContentFetcherHandler { @@ -250,12 +188,10 @@ impl ContentFetcherHandler { url: &str, path: EndpointPath, installer: H, - embeddable_on: Embeddable, fetch: F, pool: CpuPool, ) -> Self { let fetch_control = FetchControl::default(); - let errors = Errors { embeddable_on }; // Validation of method let status = match *method { @@ -268,18 +204,16 @@ impl ContentFetcherHandler { url, fetch_control.abort.clone(), path, - errors.clone(), installer, )) }, // or return error - _ => FetchState::Error(errors.method_not_allowed()), + _ => FetchState::Error(errors::method_not_allowed()), }; ContentFetcherHandler { fetch_control, status, - errors, } } @@ -289,7 +223,6 @@ impl ContentFetcherHandler { url: &str, abort: Arc, path: EndpointPath, - errors: Errors, installer: H, ) -> Box + Send> { // Start fetching the content @@ -311,12 +244,12 @@ impl ContentFetcherHandler { }, Err(e) => { trace!(target: "dapps", "Error while validating content: {:?}", e); - FetchState::Error(errors.invalid_content(e)) + FetchState::Error(errors::invalid_content(e)) }, }, Err(e) => { warn!(target: "dapps", "Unable to fetch content: {:?}", e); - FetchState::Error(errors.download_error(e)) + FetchState::Error(errors::download_error(e)) }, }) }); @@ -347,7 +280,7 @@ impl Future for ContentFetcherHandler { // Request may time out FetchState::InProgress(_) if self.fetch_control.is_deadline_reached() => { trace!(target: "dapps", "Fetching dapp failed because of timeout."); - FetchState::Error(self.errors.timeout_error()) + FetchState::Error(errors::timeout_error()) }, FetchState::InProgress(ref mut receiver) => { // Check if there is a response diff --git a/dapps/src/handlers/mod.rs b/dapps/src/handlers/mod.rs index fad9c40416..cb0eba0429 100644 --- a/dapps/src/handlers/mod.rs +++ b/dapps/src/handlers/mod.rs @@ -22,6 +22,7 @@ mod fetch; mod reader; mod redirect; mod streaming; +mod errors; pub use self::content::ContentHandler; pub use self::echo::EchoHandler; @@ -30,20 +31,16 @@ pub use self::reader::Reader; pub use self::redirect::Redirection; pub use self::streaming::StreamingHandler; -use std::iter; -use itertools::Itertools; use hyper::header; -use {apps, address, Embeddable}; +use std::time::Duration; + +const FETCH_TIMEOUT: Duration = Duration::from_secs(300); /// Adds security-related headers to the Response. -pub fn add_security_headers(headers: &mut header::Headers, embeddable_on: Embeddable, allow_js_eval: bool) { +pub fn add_security_headers(headers: &mut header::Headers, allow_js_eval: bool) { headers.set_raw("X-XSS-Protection", "1; mode=block"); headers.set_raw("X-Content-Type-Options", "nosniff"); - - // Embedding header: - if let None = embeddable_on { - headers.set_raw("X-Frame-Options", "SAMEORIGIN"); - } + headers.set_raw("X-Frame-Options", "SAMEORIGIN"); // Content Security Policy headers headers.set_raw("Content-Security-Policy", String::new() @@ -70,11 +67,7 @@ pub fn add_security_headers(headers: &mut header::Headers, embeddable_on: Embedd + "object-src 'none';" // Allow scripts + { - let script_src = embeddable_on.as_ref() - .map(|e| e.extra_script_src.iter() - .map(|&(ref host, port)| address(host, port)) - .join(" ") - ).unwrap_or_default(); + let script_src = ""; let eval = if allow_js_eval { " 'unsafe-eval'" } else { "" }; &format!( @@ -93,29 +86,6 @@ pub fn add_security_headers(headers: &mut header::Headers, embeddable_on: Embedd // Never allow mixed content + "block-all-mixed-content;" // Specify if the site can be embedded. - + &match embeddable_on { - Some(ref embed) => { - let std = address(&embed.host, embed.port); - let proxy = format!("{}.{}", apps::HOME_PAGE, embed.dapps_domain); - let domain = format!("*.{}:{}", embed.dapps_domain, embed.port); - - let mut ancestors = vec![std, domain, proxy] - .into_iter() - .chain(embed.extra_embed_on - .iter() - .map(|&(ref host, port)| address(host, port)) - ); - - let ancestors = if embed.host == "127.0.0.1" { - let localhost = address("localhost", embed.port); - ancestors.chain(iter::once(localhost)).join(" ") - } else { - ancestors.join(" ") - }; - - format!("frame-ancestors {};", ancestors) - }, - None => format!("frame-ancestors 'self';"), - } + + "frame-ancestors 'self';" ); } diff --git a/dapps/src/handlers/streaming.rs b/dapps/src/handlers/streaming.rs index 4dfd2c4afa..b6feaa6382 100644 --- a/dapps/src/handlers/streaming.rs +++ b/dapps/src/handlers/streaming.rs @@ -20,24 +20,21 @@ use std::io; use hyper::{self, header, mime, StatusCode}; use handlers::{add_security_headers, Reader}; -use Embeddable; pub struct StreamingHandler { initial: Vec, content: R, status: StatusCode, mimetype: mime::Mime, - safe_to_embed_on: Embeddable, } impl StreamingHandler { - pub fn new(content: R, status: StatusCode, mimetype: mime::Mime, safe_to_embed_on: Embeddable) -> Self { + pub fn new(content: R, status: StatusCode, mimetype: mime::Mime) -> Self { StreamingHandler { initial: Vec::new(), content, status, mimetype, - safe_to_embed_on, } } @@ -51,7 +48,7 @@ impl StreamingHandler { .with_status(self.status) .with_header(header::ContentType(self.mimetype)) .with_body(body); - add_security_headers(&mut res.headers_mut(), self.safe_to_embed_on, false); + add_security_headers(&mut res.headers_mut(), false); (reader, res) } diff --git a/dapps/src/lib.rs b/dapps/src/lib.rs index 255560e422..12a6a80508 100644 --- a/dapps/src/lib.rs +++ b/dapps/src/lib.rs @@ -38,8 +38,6 @@ extern crate fetch; extern crate node_health; extern crate parity_dapps_glue as parity_dapps; extern crate parity_hash_fetch as hash_fetch; -extern crate parity_ui; -extern crate parity_ui_deprecation; extern crate keccak_hash as hash; extern crate parity_version; extern crate registrar; @@ -84,6 +82,7 @@ use node_health::NodeHealth; pub use registrar::{RegistrarClient, Asynchronous}; pub use node_health::SyncStatus; +pub use page::builtin::Dapp; /// Validates Web Proxy tokens pub trait WebProxyTokens: Send + Sync { @@ -101,7 +100,6 @@ pub struct Endpoints { local_endpoints: Arc>>, endpoints: Arc>, dapps_path: PathBuf, - embeddable: Option, pool: Option, } @@ -119,7 +117,7 @@ impl Endpoints { None => return, Some(pool) => pool, }; - let new_local = apps::fs::local_endpoints(&self.dapps_path, self.embeddable.clone(), pool.clone()); + let new_local = apps::fs::local_endpoints(&self.dapps_path, pool.clone()); let old_local = mem::replace(&mut *self.local_endpoints.write(), new_local.keys().cloned().collect()); let (_, to_remove): (_, Vec<_>) = old_local .into_iter() @@ -151,69 +149,10 @@ impl Middleware { &self.endpoints } - /// Creates new middleware for UI server. - pub fn ui( - pool: CpuPool, - health: NodeHealth, - dapps_domain: &str, - registrar: Arc>, - sync_status: Arc, - fetch: F, - info_page_only: bool, - ) -> Self { - let content_fetcher = Arc::new(apps::fetcher::ContentFetcher::new( - hash_fetch::urlhint::URLHintContract::new(registrar), - sync_status.clone(), - fetch.clone(), - pool.clone(), - ).embeddable_on(None).allow_dapps(false)); - - if info_page_only { - let mut special = HashMap::default(); - special.insert(router::SpecialEndpoint::Home, Some(apps::ui_deprecation(pool.clone()))); - - return Middleware { - endpoints: Default::default(), - router: router::Router::new( - content_fetcher, - None, - special, - None, - dapps_domain.to_owned(), - ), - } - } - - let special = { - let mut special = special_endpoints( - pool.clone(), - health, - content_fetcher.clone(), - ); - special.insert(router::SpecialEndpoint::Home, Some(apps::ui(pool.clone()))); - special - }; - let router = router::Router::new( - content_fetcher, - None, - special, - None, - dapps_domain.to_owned(), - ); - - Middleware { - endpoints: Default::default(), - router: router, - } - } - /// Creates new Dapps server middleware. pub fn dapps( pool: CpuPool, health: NodeHealth, - ui_address: Option<(String, u16)>, - extra_embed_on: Vec<(String, u16)>, - extra_script_src: Vec<(String, u16)>, dapps_path: PathBuf, extra_dapps: Vec, dapps_domain: &str, @@ -222,18 +161,16 @@ impl Middleware { web_proxy_tokens: Arc, fetch: F, ) -> Self { - let embeddable = as_embeddable(ui_address, extra_embed_on, extra_script_src, dapps_domain); let content_fetcher = Arc::new(apps::fetcher::ContentFetcher::new( hash_fetch::urlhint::URLHintContract::new(registrar), sync_status.clone(), fetch.clone(), pool.clone(), - ).embeddable_on(embeddable.clone()).allow_dapps(true)); + ).allow_dapps(true)); let (local_endpoints, endpoints) = apps::all_endpoints( dapps_path.clone(), extra_dapps, dapps_domain, - embeddable.clone(), web_proxy_tokens, fetch.clone(), pool.clone(), @@ -242,28 +179,18 @@ impl Middleware { endpoints: Arc::new(RwLock::new(endpoints)), dapps_path, local_endpoints: Arc::new(RwLock::new(local_endpoints)), - embeddable: embeddable.clone(), pool: Some(pool.clone()), }; - let special = { - let mut special = special_endpoints( - pool.clone(), - health, - content_fetcher.clone(), - ); - special.insert( - router::SpecialEndpoint::Home, - Some(apps::ui_redirection(embeddable.clone())), - ); - special - }; + let special = special_endpoints( + health, + content_fetcher.clone(), + ); let router = router::Router::new( content_fetcher, Some(endpoints.clone()), special, - embeddable, dapps_domain.to_owned(), ); @@ -281,13 +208,11 @@ impl http::RequestMiddleware for Middleware { } fn special_endpoints( - pool: CpuPool, health: NodeHealth, content_fetcher: Arc, ) -> HashMap>> { let mut special = HashMap::new(); special.insert(router::SpecialEndpoint::Rpc, None); - special.insert(router::SpecialEndpoint::Utils, Some(apps::utils(pool))); special.insert(router::SpecialEndpoint::Api, Some(api::RestApi::new( content_fetcher, health, @@ -295,45 +220,9 @@ fn special_endpoints( special } -fn address(host: &str, port: u16) -> String { - format!("{}:{}", host, port) -} - -fn as_embeddable( - ui_address: Option<(String, u16)>, - extra_embed_on: Vec<(String, u16)>, - extra_script_src: Vec<(String, u16)>, - dapps_domain: &str, -) -> Option { - ui_address.map(|(host, port)| ParentFrameSettings { - host, - port, - extra_embed_on, - extra_script_src, - dapps_domain: dapps_domain.to_owned(), - }) -} - /// Random filename fn random_filename() -> String { use ::rand::Rng; let mut rng = ::rand::OsRng::new().unwrap(); rng.gen_ascii_chars().take(12).collect() } - -type Embeddable = Option; - -/// Parent frame host and port allowed to embed the content. -#[derive(Debug, Clone)] -pub struct ParentFrameSettings { - /// Hostname - pub host: String, - /// Port - pub port: u16, - /// Additional URLs the dapps can be embedded on. - pub extra_embed_on: Vec<(String, u16)>, - /// Additional URLs the dapp scripts can be loaded from. - pub extra_script_src: Vec<(String, u16)>, - /// Dapps Domain (web3.site) - pub dapps_domain: String, -} diff --git a/dapps/src/page/builtin.rs b/dapps/src/page/builtin.rs index b9f2fcdac5..685b1401d1 100644 --- a/dapps/src/page/builtin.rs +++ b/dapps/src/page/builtin.rs @@ -23,15 +23,13 @@ use parity_dapps::{WebApp, Info}; use endpoint::{Endpoint, EndpointInfo, EndpointPath, Request, Response}; use page::{handler, PageCache}; -use Embeddable; +/// Represents a builtin Dapp. pub struct Dapp { /// futures cpu pool pool: CpuPool, /// Content of the files app: T, - /// Safe to be loaded in frame by other origin. (use wisely!) - safe_to_embed_on: Embeddable, info: EndpointInfo, fallback_to_index_html: bool, } @@ -43,7 +41,6 @@ impl Dapp { Dapp { pool, app, - safe_to_embed_on: None, info: EndpointInfo::from(info), fallback_to_index_html: false, } @@ -56,26 +53,11 @@ impl Dapp { Dapp { pool, app, - safe_to_embed_on: None, info: EndpointInfo::from(info), fallback_to_index_html: true, } } - /// Creates new `Dapp` which can be safely used in iframe - /// even from different origin. It might be dangerous (clickjacking). - /// Use wisely! - pub fn new_safe_to_embed(pool: CpuPool, app: T, address: Embeddable) -> Self { - let info = app.info(); - Dapp { - pool, - app, - safe_to_embed_on: address, - info: EndpointInfo::from(info), - fallback_to_index_html: false, - } - } - /// Allow the dapp to use `unsafe-eval` to run JS. pub fn allow_js_eval(&mut self) { self.info.allow_js_eval = Some(true); @@ -121,7 +103,6 @@ impl Endpoint for Dapp { let (reader, response) = handler::PageHandler { file, cache: PageCache::Disabled, - safe_to_embed_on: self.safe_to_embed_on.clone(), allow_js_eval: self.info.allow_js_eval.clone().unwrap_or(false), }.into_response(); diff --git a/dapps/src/page/handler.rs b/dapps/src/page/handler.rs index 15e2b10c50..d7fcefa7f0 100644 --- a/dapps/src/page/handler.rs +++ b/dapps/src/page/handler.rs @@ -20,7 +20,6 @@ use hyper::{self, header, StatusCode}; use hyper::mime::{Mime}; use handlers::{Reader, ContentHandler, add_security_headers}; -use {Embeddable}; /// Represents a file that can be sent to client. /// Implementation should keep track of bytes already sent internally. @@ -54,8 +53,6 @@ impl Default for PageCache { pub struct PageHandler { /// File currently being served pub file: Option, - /// Flag indicating if the file can be safely embeded (put in iframe). - pub safe_to_embed_on: Embeddable, /// Cache settings for this page. pub cache: PageCache, /// Allow JS unsafe-eval. @@ -70,7 +67,6 @@ impl PageHandler { "File not found", "Requested file has not been found.", None, - self.safe_to_embed_on, ).into()), Some(file) => file, }; @@ -94,7 +90,7 @@ impl PageHandler { headers.set(header::ContentType(file.content_type().to_owned())); - add_security_headers(&mut headers, self.safe_to_embed_on, self.allow_js_eval); + add_security_headers(&mut headers, self.allow_js_eval); } let (reader, body) = Reader::pair(file.into_reader(), Vec::new()); diff --git a/dapps/src/page/local.rs b/dapps/src/page/local.rs index f30af45237..a43735d768 100644 --- a/dapps/src/page/local.rs +++ b/dapps/src/page/local.rs @@ -22,7 +22,6 @@ use futures_cpupool::CpuPool; use page::handler::{self, PageCache}; use endpoint::{Endpoint, EndpointInfo, EndpointPath, Request, Response}; use hyper::mime::Mime; -use Embeddable; #[derive(Clone)] pub struct Dapp { @@ -31,7 +30,6 @@ pub struct Dapp { mime: Option, info: Option, cache: PageCache, - embeddable_on: Embeddable, } impl fmt::Debug for Dapp { @@ -41,20 +39,18 @@ impl fmt::Debug for Dapp { .field("mime", &self.mime) .field("info", &self.info) .field("cache", &self.cache) - .field("embeddable_on", &self.embeddable_on) .finish() } } impl Dapp { - pub fn new(pool: CpuPool, path: PathBuf, info: EndpointInfo, cache: PageCache, embeddable_on: Embeddable) -> Self { + pub fn new(pool: CpuPool, path: PathBuf, info: EndpointInfo, cache: PageCache) -> Self { Dapp { pool, path, mime: None, info: Some(info), cache, - embeddable_on, } } @@ -65,7 +61,6 @@ impl Dapp { mime: Some(mime), info: None, cache, - embeddable_on: None, } } @@ -96,7 +91,6 @@ impl Dapp { let (reader, response) = handler::PageHandler { file: self.get_file(path), cache: self.cache, - safe_to_embed_on: self.embeddable_on.clone(), allow_js_eval: self.info.as_ref().and_then(|x| x.allow_js_eval).unwrap_or(false), }.into_response(); diff --git a/dapps/src/proxypac.rs b/dapps/src/proxypac.rs index 4e11f3ea6b..1acd7b1b9e 100644 --- a/dapps/src/proxypac.rs +++ b/dapps/src/proxypac.rs @@ -21,25 +21,20 @@ use endpoint::{Endpoint, Request, Response, EndpointPath}; use futures::future; use handlers::ContentHandler; use hyper::mime; -use {address, Embeddable}; pub struct ProxyPac { - embeddable: Embeddable, dapps_domain: String, } impl ProxyPac { - pub fn boxed(embeddable: Embeddable, dapps_domain: String) -> Box { - Box::new(ProxyPac { embeddable, dapps_domain }) + pub fn boxed(dapps_domain: String) -> Box { + Box::new(ProxyPac { dapps_domain }) } } impl Endpoint for ProxyPac { fn respond(&self, path: EndpointPath, _req: Request) -> Response { - let ui = self.embeddable - .as_ref() - .map(|ref parent| address(&parent.host, parent.port)) - .unwrap_or_else(|| format!("{}:{}", path.host, path.port)); + let ui = format!("{}:{}", path.host, path.port); let content = format!( r#" diff --git a/dapps/src/router.rs b/dapps/src/router.rs index 565874f6a8..28a3e24c3f 100644 --- a/dapps/src/router.rs +++ b/dapps/src/router.rs @@ -29,14 +29,12 @@ use apps::fetcher::Fetcher; use endpoint::{self, Endpoint, EndpointPath}; use Endpoints; use handlers; -use Embeddable; /// Special endpoints are accessible on every domain (every dapp) #[derive(Debug, PartialEq, Hash, Eq)] pub enum SpecialEndpoint { Rpc, Api, - Utils, Home, None, } @@ -52,16 +50,14 @@ pub struct Router { endpoints: Option, fetch: Arc, special: HashMap>>, - embeddable_on: Embeddable, dapps_domain: String, } impl Router { - fn resolve_request(&self, req: hyper::Request, refresh_dapps: bool) -> (bool, Response) { + fn resolve_request(&self, req: hyper::Request, refresh_dapps: bool) -> Response { // Choose proper handler depending on path / domain let endpoint = extract_endpoint(req.uri(), req.headers().get(), &self.dapps_domain); let referer = extract_referer_endpoint(&req, &self.dapps_domain); - let is_utils = endpoint.1 == SpecialEndpoint::Utils; let is_get_request = *req.method() == hyper::Method::Get; let is_head_request = *req.method() == hyper::Method::Head; let has_dapp = |dapp: &str| self.endpoints @@ -71,7 +67,7 @@ impl Router { trace!(target: "dapps", "Routing request to {:?}. Details: {:?}", req.uri(), req); debug!(target: "dapps", "Handling endpoint request: {:?}, referer: {:?}", endpoint, referer); - (is_utils, match (endpoint.0, endpoint.1, referer) { + match (endpoint.0, endpoint.1, referer) { // Handle invalid web requests that we can recover from (ref path, SpecialEndpoint::None, Some(ref referer)) if referer.app_id == apps::WEB_PATH @@ -132,7 +128,6 @@ impl Router { "404 Not Found", "Requested content was not found.", None, - self.embeddable_on.clone(), ).into()))) } }, @@ -161,20 +156,19 @@ impl Router { "404 Not Found", "Requested content was not found.", None, - self.embeddable_on.clone(), ).into()))) }, - }) + } } } impl http::RequestMiddleware for Router { fn on_request(&self, req: hyper::Request) -> http::RequestMiddlewareAction { let is_origin_set = req.headers().get::().is_some(); - let (is_utils, response) = self.resolve_request(req, self.endpoints.is_some()); + let response = self.resolve_request(req, self.endpoints.is_some()); match response { Response::Some(response) => http::RequestMiddlewareAction::Respond { - should_validate_hosts: !is_utils, + should_validate_hosts: true, response, }, Response::None(request) => http::RequestMiddlewareAction::Proceed { @@ -190,14 +184,12 @@ impl Router { content_fetcher: Arc, endpoints: Option, special: HashMap>>, - embeddable_on: Embeddable, dapps_domain: String, ) -> Self { Router { endpoints: endpoints, fetch: content_fetcher, special: special, - embeddable_on: embeddable_on, dapps_domain: format!(".{}", dapps_domain), } } @@ -250,7 +242,6 @@ fn extract_endpoint(url: &Uri, extra_host: Option<&header::Host>, dapps_domain: match path[0].as_ref() { apps::RPC_PATH => SpecialEndpoint::Rpc, apps::API_PATH => SpecialEndpoint::Api, - apps::UTILS_PATH => SpecialEndpoint::Utils, apps::HOME_PAGE => SpecialEndpoint::Home, _ => SpecialEndpoint::None, } @@ -351,30 +342,6 @@ mod tests { }), SpecialEndpoint::Rpc) ); - assert_eq!( - extract_endpoint(&"http://my.status.web3.site/parity-utils/inject.js".parse().unwrap(), None, dapps_domain), - (Some(EndpointPath { - app_id: "status".to_owned(), - app_params: vec!["my".into(), "inject.js".into()], - query: None, - host: "my.status.web3.site".to_owned(), - port: 80, - using_dapps_domains: true, - }), SpecialEndpoint::Utils) - ); - - assert_eq!( - extract_endpoint(&"http://my.status.web3.site/inject.js".parse().unwrap(), None, dapps_domain), - (Some(EndpointPath { - app_id: "status".to_owned(), - app_params: vec!["my".into(), "inject.js".into()], - query: None, - host: "my.status.web3.site".to_owned(), - port: 80, - using_dapps_domains: true, - }), SpecialEndpoint::None) - ); - // By Subdomain assert_eq!( extract_endpoint(&"http://status.web3.site/test.html".parse().unwrap(), None, dapps_domain), diff --git a/dapps/src/tests/fetch.rs b/dapps/src/tests/fetch.rs index bbd766a552..444d5b656a 100644 --- a/dapps/src/tests/fetch.rs +++ b/dapps/src/tests/fetch.rs @@ -19,7 +19,7 @@ use rustc_hex::FromHex; use tests::helpers::{ serve_with_registrar, serve_with_registrar_and_sync, serve_with_fetch, serve_with_registrar_and_fetch, - request, assert_security_headers_for_embed, + request, assert_security_headers }; #[test] @@ -40,7 +40,7 @@ fn should_resolve_dapp() { // then response.assert_status("HTTP/1.1 404 Not Found"); assert_eq!(registrar.calls.lock().len(), 4); - assert_security_headers_for_embed(&response.headers); + assert_security_headers(&response.headers); } #[test] @@ -61,7 +61,7 @@ fn should_return_503_when_syncing_but_should_make_the_calls() { // then response.assert_status("HTTP/1.1 503 Service Unavailable"); assert_eq!(registrar.calls.lock().len(), 2); - assert_security_headers_for_embed(&response.headers); + assert_security_headers(&response.headers); } const GAVCOIN_DAPP: &'static str = "00000000000000000000000000000000000000000000000000000000000000609faf32e1e3845e237cc6efd27187cee13b3b99db000000000000000000000000000000000000000000000000d8bd350823e28ff75e74a34215faefdc8a52fd8e00000000000000000000000000000000000000000000000000000000000000116761766f66796f726b2f676176636f696e000000000000000000000000000000"; @@ -95,7 +95,7 @@ fn should_return_502_on_hash_mismatch() { response.assert_status("HTTP/1.1 502 Bad Gateway"); assert!(response.body.contains("HashMismatch"), "Expected hash mismatch response, got: {:?}", response.body); - assert_security_headers_for_embed(&response.headers); + assert_security_headers(&response.headers); } #[test] @@ -126,7 +126,7 @@ fn should_return_error_for_invalid_dapp_zip() { response.assert_status("HTTP/1.1 502 Bad Gateway"); assert!(response.body.contains("InvalidArchive"), "Expected invalid zip response, got: {:?}", response.body); - assert_security_headers_for_embed(&response.headers); + assert_security_headers(&response.headers); } #[test] @@ -165,7 +165,7 @@ fn should_return_fetched_dapp_content() { fetch.assert_no_more_requests(); response1.assert_status("HTTP/1.1 200 OK"); - assert_security_headers_for_embed(&response1.headers); + assert_security_headers(&response1.headers); assert!( response1.body.contains(r#"18

Hello Gavcoin!

@@ -178,7 +178,7 @@ fn should_return_fetched_dapp_content() { ); response2.assert_status("HTTP/1.1 200 OK"); - assert_security_headers_for_embed(&response2.headers); + assert_security_headers(&response2.headers); assert_eq!( response2.body, r#"EA @@ -331,7 +331,7 @@ fn should_stream_web_content() { // then response.assert_status("HTTP/1.1 200 OK"); - assert_security_headers_for_embed(&response.headers); + assert_security_headers(&response.headers); fetch.assert_requested("https://parity.io/"); fetch.assert_no_more_requests(); @@ -354,7 +354,7 @@ fn should_support_base32_encoded_web_urls() { // then response.assert_status("HTTP/1.1 200 OK"); - assert_security_headers_for_embed(&response.headers); + assert_security_headers(&response.headers); fetch.assert_requested("https://parity.io/styles.css?test=123"); fetch.assert_no_more_requests(); @@ -377,7 +377,7 @@ fn should_correctly_handle_long_label_when_splitted() { // then response.assert_status("HTTP/1.1 200 OK"); - assert_security_headers_for_embed(&response.headers); + assert_security_headers(&response.headers); fetch.assert_requested("https://contribution.melonport.com/styles.css?test=123"); fetch.assert_no_more_requests(); @@ -400,7 +400,7 @@ fn should_support_base32_encoded_web_urls_as_path() { // then response.assert_status("HTTP/1.1 200 OK"); - assert_security_headers_for_embed(&response.headers); + assert_security_headers(&response.headers); fetch.assert_requested("https://parity.io/styles.css?test=123"); fetch.assert_no_more_requests(); @@ -423,7 +423,7 @@ fn should_return_error_on_non_whitelisted_domain() { // then response.assert_status("HTTP/1.1 400 Bad Request"); - assert_security_headers_for_embed(&response.headers); + assert_security_headers(&response.headers); fetch.assert_no_more_requests(); } @@ -445,7 +445,7 @@ fn should_return_error_on_invalid_token() { // then response.assert_status("HTTP/1.1 400 Bad Request"); - assert_security_headers_for_embed(&response.headers); + assert_security_headers(&response.headers); fetch.assert_no_more_requests(); } @@ -467,7 +467,7 @@ fn should_return_error_on_invalid_protocol() { // then response.assert_status("HTTP/1.1 400 Bad Request"); - assert_security_headers_for_embed(&response.headers); + assert_security_headers(&response.headers); fetch.assert_no_more_requests(); } @@ -492,7 +492,7 @@ fn should_disallow_non_get_requests() { // then response.assert_status("HTTP/1.1 405 Method Not Allowed"); - assert_security_headers_for_embed(&response.headers); + assert_security_headers(&response.headers); fetch.assert_no_more_requests(); } diff --git a/dapps/src/tests/helpers/mod.rs b/dapps/src/tests/helpers/mod.rs index aa76089794..58ec71d733 100644 --- a/dapps/src/tests/helpers/mod.rs +++ b/dapps/src/tests/helpers/mod.rs @@ -36,8 +36,6 @@ mod fetch; use self::registrar::FakeRegistrar; use self::fetch::FakeFetch; -const SIGNER_PORT: u16 = 18180; - #[derive(Debug)] struct FakeSync(bool); impl SyncStatus for FakeSync { @@ -63,8 +61,7 @@ pub fn init_server(process: F, io: IoHandler) -> (Server, Arc Server { init_server(|builder| builder, Default::default()).0 } -pub fn serve_ui() -> Server { - init_server(|mut builder| { - builder.serve_ui = true; - builder - }, Default::default()).0 -} - pub fn request(server: Server, request: &str) -> http_client::Response { http_client::request(server.addr(), request) } @@ -136,9 +126,6 @@ pub fn request(server: Server, request: &str) -> http_client::Response { pub fn assert_security_headers(headers: &[String]) { http_client::assert_security_headers_present(headers, None) } -pub fn assert_security_headers_for_embed(headers: &[String]) { - http_client::assert_security_headers_present(headers, Some(SIGNER_PORT)) -} /// Webapps HTTP+RPC server build. pub struct ServerBuilder { @@ -146,10 +133,8 @@ pub struct ServerBuilder { registrar: Arc>, sync_status: Arc, web_proxy_tokens: Arc, - signer_address: Option<(String, u16)>, allowed_hosts: DomainsValidation, fetch: T, - serve_ui: bool, } impl ServerBuilder { @@ -160,10 +145,8 @@ impl ServerBuilder { registrar: registrar, sync_status: Arc::new(FakeSync(false)), web_proxy_tokens: Arc::new(|_| None), - signer_address: None, allowed_hosts: DomainsValidation::Disabled, fetch: fetch, - serve_ui: false, } } } @@ -176,10 +159,8 @@ impl ServerBuilder { registrar: self.registrar, sync_status: self.sync_status, web_proxy_tokens: self.web_proxy_tokens, - signer_address: self.signer_address, allowed_hosts: self.allowed_hosts, fetch: fetch, - serve_ui: self.serve_ui, } } @@ -190,7 +171,6 @@ impl ServerBuilder { addr, io, self.allowed_hosts, - self.signer_address, self.dapps_path, vec![], self.registrar, @@ -198,7 +178,6 @@ impl ServerBuilder { self.web_proxy_tokens, Remote::new_sync(), self.fetch, - self.serve_ui, ) } } @@ -215,7 +194,6 @@ impl Server { addr: &SocketAddr, io: IoHandler, allowed_hosts: DomainsValidation, - signer_address: Option<(String, u16)>, dapps_path: PathBuf, extra_dapps: Vec, registrar: Arc>, @@ -223,7 +201,6 @@ impl Server { web_proxy_tokens: Arc, remote: Remote, fetch: F, - serve_ui: bool, ) -> io::Result { let health = NodeHealth::new( sync_status.clone(), @@ -231,23 +208,10 @@ impl Server { remote.clone(), ); let pool = ::futures_cpupool::CpuPool::new(1); - let middleware = if serve_ui { - Middleware::ui( - pool, - health, - DAPPS_DOMAIN.into(), - registrar, - sync_status, - fetch, - false, - ) - } else { + let middleware = Middleware::dapps( pool, health, - signer_address, - vec![], - vec![], dapps_path, extra_dapps, DAPPS_DOMAIN.into(), @@ -255,8 +219,7 @@ impl Server { sync_status, web_proxy_tokens, fetch, - ) - }; + ); let mut allowed_hosts: Option> = allowed_hosts.into(); allowed_hosts.as_mut().map(|hosts| { diff --git a/dapps/src/tests/home.rs b/dapps/src/tests/home.rs deleted file mode 100644 index 024261d5df..0000000000 --- a/dapps/src/tests/home.rs +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright 2015-2018 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity. If not, see . - -use tests::helpers::{serve_ui, request, assert_security_headers}; - -#[test] -fn should_serve_home_js() { - // given - let server = serve_ui(); - - // when - let response = request(server, - "\ - GET /inject.js HTTP/1.1\r\n\ - Host: 127.0.0.1:8080\r\n\ - Connection: close\r\n\ - \r\n\ - {} - " - ); - - // then - response.assert_status("HTTP/1.1 200 OK"); - response.assert_header("Content-Type", "application/javascript"); - assert_eq!(response.body.contains("function(){"), true, "Expected function in: {}", response.body); - assert_security_headers(&response.headers); -} - -#[test] -fn should_serve_home() { - // given - let server = serve_ui(); - - // when - let response = request(server, - "\ - GET / HTTP/1.1\r\n\ - Host: 127.0.0.1:8080\r\n\ - Connection: close\r\n\ - \r\n\ - {} - " - ); - - // then - response.assert_status("HTTP/1.1 200 OK"); - response.assert_header("Content-Type", "text/html"); - assert_security_headers(&response.headers); -} diff --git a/dapps/src/tests/mod.rs b/dapps/src/tests/mod.rs index 38a1d6f17a..c4d88cf9f1 100644 --- a/dapps/src/tests/mod.rs +++ b/dapps/src/tests/mod.rs @@ -20,7 +20,5 @@ mod helpers; mod api; mod fetch; -mod home; -mod redirection; mod rpc; mod validation; diff --git a/dapps/src/tests/redirection.rs b/dapps/src/tests/redirection.rs deleted file mode 100644 index 722ade25b9..0000000000 --- a/dapps/src/tests/redirection.rs +++ /dev/null @@ -1,206 +0,0 @@ -// Copyright 2015-2018 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity. If not, see . - -use tests::helpers::{serve, request, assert_security_headers, assert_security_headers_for_embed}; - -#[test] -fn should_redirect_to_home() { - // given - let server = serve(); - - // when - let response = request(server, - "\ - GET / HTTP/1.1\r\n\ - Host: 127.0.0.1:8080\r\n\ - Connection: close\r\n\ - \r\n\ - " - ); - - // then - response.assert_status("HTTP/1.1 302 Found"); - assert_eq!(response.headers.get(0).unwrap(), "Location: http://127.0.0.1:18180"); -} - -#[test] -fn should_redirect_to_home_with_domain() { - // given - let server = serve(); - - // when - let response = request(server, - "\ - GET / HTTP/1.1\r\n\ - Host: home.web3.site\r\n\ - Connection: close\r\n\ - \r\n\ - " - ); - - // then - response.assert_status("HTTP/1.1 302 Found"); - assert_eq!(response.headers.get(0).unwrap(), "Location: http://127.0.0.1:18180"); -} - -#[test] -fn should_redirect_to_home_when_trailing_slash_is_missing() { - // given - let server = serve(); - - // when - let response = request(server, - "\ - GET /app HTTP/1.1\r\n\ - Host: 127.0.0.1:8080\r\n\ - Connection: close\r\n\ - \r\n\ - " - ); - - // then - response.assert_status("HTTP/1.1 302 Found"); - assert_eq!(response.headers.get(0).unwrap(), "Location: http://127.0.0.1:18180"); -} - -#[test] -fn should_display_404_on_invalid_dapp() { - // given - let server = serve(); - - // when - let response = request(server, - "\ - GET /invaliddapp/ HTTP/1.1\r\n\ - Host: 127.0.0.1:8080\r\n\ - Connection: close\r\n\ - \r\n\ - " - ); - - // then - response.assert_status("HTTP/1.1 404 Not Found"); - assert_security_headers_for_embed(&response.headers); -} - -#[test] -fn should_display_404_on_invalid_dapp_with_domain() { - // given - let server = serve(); - - // when - let response = request(server, - "\ - GET / HTTP/1.1\r\n\ - Host: invaliddapp.web3.site\r\n\ - Connection: close\r\n\ - \r\n\ - " - ); - - // then - response.assert_status("HTTP/1.1 404 Not Found"); - assert_security_headers_for_embed(&response.headers); -} - -#[test] -fn should_serve_rpc() { - // given - let server = serve(); - - // when - let response = request(server, - "\ - POST / HTTP/1.1\r\n\ - Host: 127.0.0.1:8080\r\n\ - Connection: close\r\n\ - Content-Type: application/json\r\n - \r\n\ - {} - " - ); - - // then - response.assert_status("HTTP/1.1 200 OK"); - assert_eq!(response.body, format!("4C\n{}\n\n0\n\n", r#"{"jsonrpc":"2.0","error":{"code":-32700,"message":"Parse error"},"id":null}"#)); -} - -#[test] -fn should_serve_rpc_at_slash_rpc() { - // given - let server = serve(); - - // when - let response = request(server, - "\ - POST /rpc HTTP/1.1\r\n\ - Host: 127.0.0.1:8080\r\n\ - Connection: close\r\n\ - Content-Type: application/json\r\n - \r\n\ - {} - " - ); - - // then - response.assert_status("HTTP/1.1 200 OK"); - assert_eq!(response.body, format!("4C\n{}\n\n0\n\n", r#"{"jsonrpc":"2.0","error":{"code":-32700,"message":"Parse error"},"id":null}"#)); -} - -#[test] -fn should_serve_proxy_pac() { - // given - let server = serve(); - - // when - let response = request(server, - "\ - GET /proxy/proxy.pac HTTP/1.1\r\n\ - Host: 127.0.0.1:8080\r\n\ - Connection: close\r\n\ - \r\n\ - {} - " - ); - - // then - response.assert_status("HTTP/1.1 200 OK"); - assert_eq!(response.body, "DB\n\nfunction FindProxyForURL(url, host) {\n\tif (shExpMatch(host, \"home.web3.site\"))\n\t{\n\t\treturn \"PROXY 127.0.0.1:18180\";\n\t}\n\n\tif (shExpMatch(host, \"*.web3.site\"))\n\t{\n\t\treturn \"PROXY 127.0.0.1:8080\";\n\t}\n\n\treturn \"DIRECT\";\n}\n\n0\n\n".to_owned()); - assert_security_headers(&response.headers); -} - -#[test] -fn should_serve_utils() { - // given - let server = serve(); - - // when - let response = request(server, - "\ - GET /parity-utils/inject.js HTTP/1.1\r\n\ - Host: 127.0.0.1:8080\r\n\ - Connection: close\r\n\ - \r\n\ - {} - " - ); - - // then - response.assert_status("HTTP/1.1 200 OK"); - response.assert_header("Content-Type", "application/javascript"); - assert_eq!(response.body.contains("function(){"), true, "Expected function in: {}", response.body); - assert_security_headers(&response.headers); -} diff --git a/dapps/src/tests/validation.rs b/dapps/src/tests/validation.rs index ed4a3dc2f0..f9d22f802d 100644 --- a/dapps/src/tests/validation.rs +++ b/dapps/src/tests/validation.rs @@ -37,26 +37,6 @@ fn should_reject_invalid_host() { assert!(response.body.contains("Provided Host header is not whitelisted."), response.body); } -#[test] -fn should_allow_valid_host() { - // given - let server = serve_hosts(Some(vec!["localhost:8080".into()])); - - // when - let response = request(server, - "\ - GET /ui/ HTTP/1.1\r\n\ - Host: localhost:8080\r\n\ - Connection: close\r\n\ - \r\n\ - {} - " - ); - - // then - response.assert_status("HTTP/1.1 200 OK"); -} - #[test] fn should_serve_dapps_domains() { // given @@ -66,28 +46,7 @@ fn should_serve_dapps_domains() { let response = request(server, "\ GET / HTTP/1.1\r\n\ - Host: ui.web3.site\r\n\ - Connection: close\r\n\ - \r\n\ - {} - " - ); - - // then - response.assert_status("HTTP/1.1 200 OK"); -} - -#[test] -// NOTE [todr] This is required for error pages to be styled properly. -fn should_allow_parity_utils_even_on_invalid_domain() { - // given - let server = serve_hosts(Some(vec!["localhost:8080".into()])); - - // when - let response = request(server, - "\ - GET /parity-utils/styles.css HTTP/1.1\r\n\ - Host: 127.0.0.1:8080\r\n\ + Host: proxy.web3.site\r\n\ Connection: close\r\n\ \r\n\ {} diff --git a/dapps/src/web.rs b/dapps/src/web.rs index 14f215ca45..fac0dca1af 100644 --- a/dapps/src/web.rs +++ b/dapps/src/web.rs @@ -30,10 +30,9 @@ use handlers::{ ContentFetcherHandler, ContentHandler, ContentValidator, ValidatorResponse, StreamingHandler, }; -use {Embeddable, WebProxyTokens}; +use WebProxyTokens; pub struct Web { - embeddable_on: Embeddable, web_proxy_tokens: Arc, fetch: F, pool: CpuPool, @@ -41,13 +40,11 @@ pub struct Web { impl Web { pub fn boxed( - embeddable_on: Embeddable, web_proxy_tokens: Arc, fetch: F, pool: CpuPool, ) -> Box { Box::new(Web { - embeddable_on, web_proxy_tokens, fetch, pool, @@ -64,7 +61,6 @@ impl Web { "Invalid parameter", "Couldn't parse given parameter:", path.app_params.get(0).map(String::as_str), - self.embeddable_on.clone() ))?; let mut token_it = token_and_url.split('+'); @@ -76,7 +72,7 @@ impl Web { Some(domain) => domain, _ => { return Err(ContentHandler::error( - StatusCode::BadRequest, "Invalid Access Token", "Invalid or old web proxy access token supplied.", Some("Try refreshing the page."), self.embeddable_on.clone() + StatusCode::BadRequest, "Invalid Access Token", "Invalid or old web proxy access token supplied.", Some("Try refreshing the page."), )); } }; @@ -86,14 +82,14 @@ impl Web { Some(url) if url.starts_with("http://") || url.starts_with("https://") => url.to_owned(), _ => { return Err(ContentHandler::error( - StatusCode::BadRequest, "Invalid Protocol", "Invalid protocol used.", None, self.embeddable_on.clone() + StatusCode::BadRequest, "Invalid Protocol", "Invalid protocol used.", None, )); } }; if !target_url.starts_with(&*domain) { return Err(ContentHandler::error( - StatusCode::BadRequest, "Invalid Domain", "Dapp attempted to access invalid domain.", Some(&target_url), self.embeddable_on.clone(), + StatusCode::BadRequest, "Invalid Domain", "Dapp attempted to access invalid domain.", Some(&target_url), )); } @@ -128,10 +124,8 @@ impl Endpoint for Web { &target_url, path, WebInstaller { - embeddable_on: self.embeddable_on.clone(), token, }, - self.embeddable_on.clone(), self.fetch.clone(), self.pool.clone(), )) @@ -139,7 +133,6 @@ impl Endpoint for Web { } struct WebInstaller { - embeddable_on: Embeddable, token: String, } @@ -154,12 +147,10 @@ impl ContentValidator for WebInstaller { fetch::BodyReader::new(response), status, mime, - self.embeddable_on, ); if is_html { handler.set_initial_content(&format!( - r#""#, - apps::UTILS_PATH, + r#""#, apps::URL_REFERER, apps::WEB_PATH, &self.token, diff --git a/dapps/ui-deprecation/Cargo.toml b/dapps/ui-deprecation/Cargo.toml deleted file mode 100644 index f4479c2367..0000000000 --- a/dapps/ui-deprecation/Cargo.toml +++ /dev/null @@ -1,18 +0,0 @@ -[package] -description = "Parity UI deprecation notice." -name = "parity-ui-deprecation" -version = "1.10.0" -license = "GPL-3.0" -authors = ["Parity Technologies "] -build = "build.rs" - -[features] -default = ["with-syntex", "use-precompiled-js"] -use-precompiled-js = ["parity-dapps-glue/use-precompiled-js"] -with-syntex = ["parity-dapps-glue/with-syntex"] - -[build-dependencies] -parity-dapps-glue = "1.9" - -[dependencies] -parity-dapps-glue = "1.9" diff --git a/dapps/ui-deprecation/build.rs b/dapps/ui-deprecation/build.rs deleted file mode 100644 index c427f3d54d..0000000000 --- a/dapps/ui-deprecation/build.rs +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2015-2018 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity. If not, see . - -extern crate parity_dapps_glue; - -fn main() { - parity_dapps_glue::generate(); -} diff --git a/dapps/ui-deprecation/build/index.html b/dapps/ui-deprecation/build/index.html deleted file mode 100644 index 07059743c6..0000000000 --- a/dapps/ui-deprecation/build/index.html +++ /dev/null @@ -1,119 +0,0 @@ - - - - - - Parity - - - -
-
-
-

The Parity UI has been split off into a standalone project.

-

Get the standalone Parity UI from here

-

- -

-
-
-
- - diff --git a/dapps/ui-deprecation/src/lib.rs b/dapps/ui-deprecation/src/lib.rs deleted file mode 100644 index 79a4a42497..0000000000 --- a/dapps/ui-deprecation/src/lib.rs +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2015-2018 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity. If not, see . - -#[cfg(feature = "with-syntex")] -include!(concat!(env!("OUT_DIR"), "/lib.rs")); - -#[cfg(not(feature = "with-syntex"))] -include!("lib.rs.in"); diff --git a/dapps/ui-deprecation/src/lib.rs.in b/dapps/ui-deprecation/src/lib.rs.in deleted file mode 100644 index 892ebbded2..0000000000 --- a/dapps/ui-deprecation/src/lib.rs.in +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright 2015-2018 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity. If not, see . - -extern crate parity_dapps_glue; - -use std::collections::HashMap; -use parity_dapps_glue::{WebApp, File, Info}; - -#[derive(WebAppFiles)] -#[webapp(path = "../build")] -pub struct App { - pub files: HashMap<&'static str, File>, -} - -impl Default for App { - fn default() -> App { - App { - files: Self::files(), - } - } -} - -impl WebApp for App { - fn file(&self, path: &str) -> Option<&File> { - self.files.get(path) - } - - fn info(&self) -> Info { - Info { - name: "Parity Wallet info page", - version: env!("CARGO_PKG_VERSION"), - author: "Parity ", - description: "Deprecation notice for Parity Wallet", - icon_url: "icon.png", - } - } -} - -#[test] -fn test_js() { - parity_dapps_glue::js::build(env!("CARGO_MANIFEST_DIR"), "build"); -} diff --git a/dapps/ui/Cargo.toml b/dapps/ui/Cargo.toml deleted file mode 100644 index acb7a91735..0000000000 --- a/dapps/ui/Cargo.toml +++ /dev/null @@ -1,20 +0,0 @@ -[package] -description = "Ethcore Parity UI" -homepage = "http://parity.io" -license = "GPL-3.0" -name = "parity-ui" -version = "1.12.0" -authors = ["Parity Technologies "] - -[build-dependencies] -rustc_version = "0.2" - -[dependencies] -parity-ui-dev = { git = "https://github.com/parity-js/shell.git", rev = "eecaadcb9e421bce31e91680d14a20bbd38f92a2", optional = true } -parity-ui-old-dev = { git = "https://github.com/parity-js/dapp-wallet.git", rev = "65deb02e7c007a0fd8aab0c089c93e3fd1de6f87", optional = true } -parity-ui-precompiled = { git = "https://github.com/js-dist-paritytech/parity-master-1-10-shell.git", rev="bd25b41cd642c6b822d820dded3aa601a29aa079", optional = true } -parity-ui-old-precompiled = { git = "https://github.com/js-dist-paritytech/parity-master-1-10-wallet.git", rev="4b6f112412716cd05123d32eeb7fda448288a6c6", optional = true } - -[features] -no-precompiled-js = ["parity-ui-dev", "parity-ui-old-dev"] -use-precompiled-js = ["parity-ui-precompiled", "parity-ui-old-precompiled"] diff --git a/dapps/ui/src/lib.rs b/dapps/ui/src/lib.rs deleted file mode 100644 index f04f755a99..0000000000 --- a/dapps/ui/src/lib.rs +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright 2015-2018 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity. If not, see . - -#[cfg(feature = "parity-ui-dev")] -mod inner { - extern crate parity_ui_dev; - - pub use self::parity_ui_dev::*; -} - -#[cfg(feature = "parity-ui-precompiled")] -mod inner { - extern crate parity_ui_precompiled; - - pub use self::parity_ui_precompiled::*; -} - -#[cfg(feature = "parity-ui-old-dev")] -pub mod old { - extern crate parity_ui_old_dev; - - pub use self::parity_ui_old_dev::*; -} - -#[cfg(feature = "parity-ui-old-precompiled")] -pub mod old { - extern crate parity_ui_old_precompiled; - - pub use self::parity_ui_old_precompiled::*; -} - -pub use self::inner::*; diff --git a/parity/cli/mod.rs b/parity/cli/mod.rs index facd01dbfb..a3f3d4887f 100644 --- a/parity/cli/mod.rs +++ b/parity/cli/mod.rs @@ -26,10 +26,6 @@ usage! { // Arguments must start with arg_ // Flags must start with flag_ - CMD cmd_ui { - "Manage ui", - } - CMD cmd_dapp { "Manage dapps", @@ -376,35 +372,10 @@ usage! { "Provide a file containing passwords for unlocking accounts (signer, private account, validators).", ["UI options"] - FLAG flag_force_ui: (bool) = false, or |c: &Config| c.ui.as_ref()?.force.clone(), - "--force-ui", - "Enable Trusted UI WebSocket endpoint, even when --unlock is in use.", - - FLAG flag_no_ui: (bool) = false, or |c: &Config| c.ui.as_ref()?.disable.clone(), - "--no-ui", - "Disable Trusted UI WebSocket endpoint.", - - // NOTE [todr] For security reasons don't put this to config files - FLAG flag_ui_no_validation: (bool) = false, or |_| None, - "--ui-no-validation", - "Disable Origin and Host headers validation for Trusted UI. WARNING: INSECURE. Used only for development.", - - ARG arg_ui_interface: (String) = "local", or |c: &Config| c.ui.as_ref()?.interface.clone(), - "--ui-interface=[IP]", - "Specify the hostname portion of the Trusted UI server, IP should be an interface's IP address, or local.", - - ARG arg_ui_hosts: (String) = "none", or |c: &Config| c.ui.as_ref()?.hosts.as_ref().map(|vec| vec.join(",")), - "--ui-hosts=[HOSTS]", - "List of allowed Host header values. This option will validate the Host header sent by the browser, it is additional security against some attack vectors. Special options: \"all\", \"none\",.", - ARG arg_ui_path: (String) = "$BASE/signer", or |c: &Config| c.ui.as_ref()?.path.clone(), "--ui-path=[PATH]", "Specify directory where Trusted UIs tokens should be stored.", - ARG arg_ui_port: (u16) = 8180u16, or |c: &Config| c.ui.as_ref()?.port.clone(), - "--ui-port=[PORT]", - "Specify the port of Trusted UI server.", - ["Networking options"] FLAG flag_no_warp: (bool) = false, or |c: &Config| c.network.as_ref()?.warp.clone().map(|w| !w), "--no-warp", @@ -948,6 +919,30 @@ usage! { "--public-node", "Does nothing; Public node is removed from Parity.", + FLAG flag_force_ui: (bool) = false, or |_| None, + "--force-ui", + "Does nothing; UI is now a separate project.", + + FLAG flag_no_ui: (bool) = false, or |_| None, + "--no-ui", + "Does nothing; UI is now a separate project.", + + FLAG flag_ui_no_validation: (bool) = false, or |_| None, + "--ui-no-validation", + "Does nothing; UI is now a separate project.", + + ARG arg_ui_interface: (String) = "local", or |_| None, + "--ui-interface=[IP]", + "Does nothing; UI is now a separate project.", + + ARG arg_ui_hosts: (String) = "none", or |_| None, + "--ui-hosts=[HOSTS]", + "Does nothing; UI is now a separate project.", + + ARG arg_ui_port: (u16) = 8180u16, or |_| None, + "--ui-port=[PORT]", + "Does nothing; UI is now a separate project.", + ARG arg_dapps_port: (Option) = None, or |c: &Config| c.dapps.as_ref()?.port.clone(), "--dapps-port=[PORT]", "Dapps server is merged with RPC server. Use --jsonrpc-port.", @@ -1111,12 +1106,18 @@ struct PrivateTransactions { #[derive(Default, Debug, PartialEq, Deserialize)] #[serde(deny_unknown_fields)] struct Ui { - force: Option, - disable: Option, - port: Option, - interface: Option, - hosts: Option>, path: Option, + + #[serde(rename="force")] + _legacy_force: Option, + #[serde(rename="disable")] + _legacy_disable: Option, + #[serde(rename="port")] + _legacy_port: Option, + #[serde(rename="interface")] + _legacy_interface: Option, + #[serde(rename="hosts")] + _legacy_hosts: Option>, } #[derive(Default, Debug, PartialEq, Deserialize)] @@ -1404,15 +1405,13 @@ mod tests { let args = Args::parse(&["parity", "--secretstore-nodes", "abc@127.0.0.1:3333,cde@10.10.10.10:4444"]).unwrap(); assert_eq!(args.arg_secretstore_nodes, "abc@127.0.0.1:3333,cde@10.10.10.10:4444"); - let args = Args::parse(&["parity", "--password", "~/.safe/1", "--password", "~/.safe/2", "--ui-port", "8123", "ui"]).unwrap(); + let args = Args::parse(&["parity", "--password", "~/.safe/1", "--password", "~/.safe/2", "--ui-port", "8123"]).unwrap(); assert_eq!(args.arg_password, vec!["~/.safe/1".to_owned(), "~/.safe/2".to_owned()]); assert_eq!(args.arg_ui_port, 8123); - assert_eq!(args.cmd_ui, true); - let args = Args::parse(&["parity", "--password", "~/.safe/1,~/.safe/2", "--ui-port", "8123", "ui"]).unwrap(); + let args = Args::parse(&["parity", "--password", "~/.safe/1,~/.safe/2", "--ui-port", "8123"]).unwrap(); assert_eq!(args.arg_password, vec!["~/.safe/1".to_owned(), "~/.safe/2".to_owned()]); assert_eq!(args.arg_ui_port, 8123); - assert_eq!(args.cmd_ui, true); } #[test] @@ -1476,7 +1475,6 @@ mod tests { // then assert_eq!(args, Args { // Commands - cmd_ui: false, cmd_dapp: false, cmd_daemon: false, cmd_account: false, @@ -1566,7 +1564,7 @@ mod tests { flag_force_ui: false, flag_no_ui: false, arg_ui_port: 8180u16, - arg_ui_interface: "127.0.0.1".into(), + arg_ui_interface: "local".into(), arg_ui_hosts: "none".into(), arg_ui_path: "$HOME/.parity/signer".into(), flag_ui_no_validation: false, @@ -1820,12 +1818,12 @@ mod tests { fast_unlock: None, }), ui: Some(Ui { - force: None, - disable: Some(true), - port: None, - interface: None, - hosts: None, path: None, + _legacy_force: None, + _legacy_disable: Some(true), + _legacy_port: None, + _legacy_interface: None, + _legacy_hosts: None, }), network: Some(Network { warp: Some(false), diff --git a/parity/configuration.rs b/parity/configuration.rs index 6f475aa83c..ec73046a49 100644 --- a/parity/configuration.rs +++ b/parity/configuration.rs @@ -20,7 +20,6 @@ use std::net::SocketAddr; use std::path::{Path, PathBuf}; use std::collections::BTreeMap; use std::cmp; -use std::str::FromStr; use cli::{Args, ArgsError}; use hash::keccak; use ethereum_types::{U256, H256, Address}; @@ -34,7 +33,7 @@ use ethcore::miner::{stratum, MinerOptions}; use ethcore::verification::queue::VerifierSettings; use miner::pool; -use rpc::{IpcConfiguration, HttpConfiguration, WsConfiguration, UiConfiguration}; +use rpc::{IpcConfiguration, HttpConfiguration, WsConfiguration}; use parity_rpc::NetworkSettings; use cache::CacheConfig; use helpers::{to_duration, to_mode, to_block_id, to_u256, to_pending_set, to_price, geth_ipc_path, parity_ipc_path, to_bootnodes, to_addresses, to_address, to_queue_strategy, to_queue_penalization, passwords_from_files}; @@ -65,7 +64,7 @@ pub enum Cmd { Account(AccountCmd), ImportPresaleWallet(ImportWallet), Blockchain(BlockchainCmd), - SignerToken(WsConfiguration, UiConfiguration, LogConfig), + SignerToken(WsConfiguration, LogConfig), SignerSign { id: Option, pwfile: Option, @@ -130,7 +129,6 @@ impl Configuration { let http_conf = self.http_config()?; let ipc_conf = self.ipc_config()?; let net_conf = self.net_config()?; - let ui_conf = self.ui_config(); let network_id = self.network_id(); let cache_config = self.cache_config(); let tracing = self.args.arg_tracing.parse()?; @@ -150,7 +148,7 @@ impl Configuration { let authfile = ::signer::codes_path(&ws_conf.signer_path); if self.args.cmd_signer_new_token { - Cmd::SignerToken(ws_conf, ui_conf, logger_config.clone()) + Cmd::SignerToken(ws_conf, logger_config.clone()) } else if self.args.cmd_signer_sign { let pwfile = self.accounts_config()?.password_files.first().map(|pwfile| { PathBuf::from(pwfile) @@ -381,13 +379,11 @@ impl Configuration { net_settings: self.network_settings()?, dapps_conf: dapps_conf, ipfs_conf: ipfs_conf, - ui_conf: ui_conf, secretstore_conf: secretstore_conf, private_provider_conf: private_provider_conf, private_encryptor_conf: private_enc_conf, private_tx_enabled, dapp: self.dapp_to_open()?, - ui: self.args.cmd_ui, name: self.args.arg_identity, custom_bootnodes: self.args.arg_bootnodes.is_some(), no_periodic_snapshot: self.args.flag_no_periodic_snapshot, @@ -588,29 +584,11 @@ impl Configuration { }) } - fn ui_port(&self) -> u16 { - self.args.arg_ports_shift + self.args.arg_ui_port - } - fn ntp_servers(&self) -> Vec { self.args.arg_ntp_servers.split(",").map(str::to_owned).collect() } - fn ui_config(&self) -> UiConfiguration { - let ui = self.ui_enabled(); - UiConfiguration { - enabled: ui.enabled, - interface: self.ui_interface(), - port: self.ui_port(), - hosts: self.ui_hosts(), - info_page_only: ui.info_page_only, - } - } - fn dapps_config(&self) -> DappsConfiguration { - let dev_ui = if self.args.flag_ui_no_validation { vec![("127.0.0.1".to_owned(), 3000)] } else { vec![] }; - let ui_port = self.ui_port(); - DappsConfiguration { enabled: self.dapps_enabled(), dapps_path: PathBuf::from(self.directories().dapps), @@ -619,31 +597,6 @@ impl Configuration { } else { vec![] }, - extra_embed_on: { - let mut extra_embed = dev_ui.clone(); - match self.ui_hosts() { - // In case host validation is disabled allow all frame ancestors - None => { - // NOTE Chrome does not seem to support "*:" - // we use `http(s)://*:` instead. - extra_embed.push(("http://*".to_owned(), ui_port)); - extra_embed.push(("https://*".to_owned(), ui_port)); - }, - Some(hosts) => extra_embed.extend(hosts.into_iter().filter_map(|host| { - let mut it = host.split(":"); - let host = it.next(); - let port = it.next().and_then(|v| u16::from_str(v).ok()); - - match (host, port) { - (Some(host), Some(port)) => Some((host.into(), port)), - (Some(host), None) => Some((host.into(), ui_port)), - _ => None, - } - })), - } - extra_embed - }, - extra_script_src: dev_ui, } } @@ -863,10 +816,6 @@ impl Configuration { Some(hosts) } - fn ui_hosts(&self) -> Option> { - self.hosts(&self.args.arg_ui_hosts, &self.ui_interface()) - } - fn rpc_hosts(&self) -> Option> { self.hosts(&self.args.arg_jsonrpc_hosts, &self.rpc_interface()) } @@ -876,7 +825,7 @@ impl Configuration { } fn ws_origins(&self) -> Option> { - if self.args.flag_unsafe_expose || self.args.flag_ui_no_validation { + if self.args.flag_unsafe_expose { return None; } @@ -925,7 +874,6 @@ impl Configuration { } fn ws_config(&self) -> Result { - let ui = self.ui_config(); let http = self.http_config()?; let support_token_api = @@ -941,7 +889,6 @@ impl Configuration { origins: self.ws_origins(), signer_path: self.directories().signer.into(), support_token_api, - ui_address: ui.address(), dapps_address: http.address(), max_connections: self.args.arg_ws_max_connections, }; @@ -1065,10 +1012,6 @@ impl Configuration { }.into() } - fn ui_interface(&self) -> String { - self.interface(&self.args.arg_ui_interface) - } - fn rpc_interface(&self) -> String { let rpc_interface = self.args.arg_rpcaddr.clone().unwrap_or(self.args.arg_jsonrpc_interface.clone()); self.interface(&rpc_interface) @@ -1184,24 +1127,6 @@ impl Configuration { into_secretstore_service_contract_address(self.args.arg_secretstore_doc_sretr_contract.as_ref()) } - fn ui_enabled(&self) -> UiEnabled { - if self.args.flag_force_ui { - return UiEnabled { - enabled: true, - info_page_only: false, - }; - } - - let ui_disabled = self.args.arg_unlock.is_some() || - self.args.flag_geth || - self.args.flag_no_ui; - - return UiEnabled { - enabled: (self.args.cmd_ui || !ui_disabled) && cfg!(feature = "ui-enabled"), - info_page_only: !self.args.cmd_ui, - } - } - fn verifier_settings(&self) -> VerifierSettings { let mut settings = VerifierSettings::default(); settings.scale_verifiers = self.args.flag_scale_verifiers; @@ -1220,12 +1145,6 @@ impl Configuration { } } -#[derive(Debug, PartialEq, Eq, Clone, Copy)] -struct UiEnabled { - pub enabled: bool, - pub info_page_only: bool, -} - fn into_secretstore_service_contract_address(s: &str) -> Result, String> { match s { "none" => Ok(None), @@ -1254,7 +1173,7 @@ mod tests { use helpers::{default_network_config}; use params::SpecType; use presale::ImportWallet; - use rpc::{WsConfiguration, UiConfiguration}; + use rpc::WsConfiguration; use rpc_apis::ApiSet; use run::RunCmd; @@ -1438,16 +1357,9 @@ mod tests { origins: Some(vec!["parity://*".into(),"chrome-extension://*".into(), "moz-extension://*".into()]), hosts: Some(vec![]), signer_path: expected.into(), - ui_address: Some("127.0.0.1:8180".into()), dapps_address: Some("127.0.0.1:8545".into()), support_token_api: true, max_connections: 100, - }, UiConfiguration { - enabled: true, - interface: "127.0.0.1".into(), - port: 8180, - hosts: Some(vec![]), - info_page_only: true, }, LogConfig { color: true, mode: None, @@ -1516,12 +1428,10 @@ mod tests { net_settings: Default::default(), dapps_conf: Default::default(), ipfs_conf: Default::default(), - ui_conf: Default::default(), secretstore_conf: Default::default(), private_provider_conf: Default::default(), private_encryptor_conf: Default::default(), private_tx_enabled: false, - ui: false, dapp: None, name: "".into(), custom_bootnodes: false, @@ -1704,49 +1614,6 @@ mod tests { assert_eq!(conf2.ipfs_cors(), Some(vec!["http://parity.io".into(),"http://something.io".into()])); } - #[test] - fn should_disable_signer_in_geth_compat() { - // given - - // when - let conf0 = parse(&["parity", "--geth"]); - let conf1 = parse(&["parity", "--geth", "--force-ui"]); - let conf2 = parse(&["parity", "--geth", "ui"]); - let conf3 = parse(&["parity"]); - - // then - assert_eq!(conf0.ui_enabled(), UiEnabled { - enabled: false, - info_page_only: true, - }); - assert_eq!(conf1.ui_enabled(), UiEnabled { - enabled: true, - info_page_only: false, - }); - assert_eq!(conf2.ui_enabled(), UiEnabled { - enabled: true, - info_page_only: false, - }); - assert_eq!(conf3.ui_enabled(), UiEnabled { - enabled: true, - info_page_only: true, - }); - } - - #[test] - fn should_disable_signer_when_account_is_unlocked() { - // given - - // when - let conf0 = parse(&["parity", "--unlock", "0x0"]); - - // then - assert_eq!(conf0.ui_enabled(), UiEnabled { - enabled: false, - info_page_only: true, - }); - } - #[test] fn should_parse_ui_configuration() { // given @@ -1757,69 +1624,22 @@ mod tests { let conf2 = parse(&["parity", "--ui-path=signer", "--ui-port", "3123"]); let conf3 = parse(&["parity", "--ui-path=signer", "--ui-interface", "test"]); let conf4 = parse(&["parity", "--ui-path=signer", "--force-ui"]); - let conf5 = parse(&["parity", "--ui-path=signer", "ui"]); // then assert_eq!(conf0.directories().signer, "signer".to_owned()); - assert_eq!(conf0.ui_config(), UiConfiguration { - enabled: true, - interface: "127.0.0.1".into(), - port: 8180, - hosts: Some(vec![]), - info_page_only: true, - }); assert!(conf1.ws_config().unwrap().hosts.is_some()); - assert_eq!(conf1.ws_config().unwrap().origins, None); + assert_eq!(conf1.ws_config().unwrap().origins, Some(vec!["parity://*".into(), "chrome-extension://*".into(), "moz-extension://*".into()])); assert_eq!(conf1.directories().signer, "signer".to_owned()); - assert_eq!(conf1.ui_config(), UiConfiguration { - enabled: true, - interface: "127.0.0.1".into(), - port: 8180, - hosts: Some(vec![]), - info_page_only: true, - }); - assert_eq!(conf1.dapps_config().extra_embed_on, vec![("127.0.0.1".to_owned(), 3000)]); assert!(conf2.ws_config().unwrap().hosts.is_some()); assert_eq!(conf2.directories().signer, "signer".to_owned()); - assert_eq!(conf2.ui_config(), UiConfiguration { - enabled: true, - interface: "127.0.0.1".into(), - port: 3123, - hosts: Some(vec![]), - info_page_only: true, - }); assert!(conf3.ws_config().unwrap().hosts.is_some()); assert_eq!(conf3.directories().signer, "signer".to_owned()); - assert_eq!(conf3.ui_config(), UiConfiguration { - enabled: true, - interface: "test".into(), - port: 8180, - hosts: Some(vec![]), - info_page_only: true, - }); assert!(conf4.ws_config().unwrap().hosts.is_some()); assert_eq!(conf4.directories().signer, "signer".to_owned()); - assert_eq!(conf4.ui_config(), UiConfiguration { - enabled: true, - interface: "127.0.0.1".into(), - port: 8180, - hosts: Some(vec![]), - info_page_only: false, - }); - - assert!(conf5.ws_config().unwrap().hosts.is_some()); - assert_eq!(conf5.directories().signer, "signer".to_owned()); - assert_eq!(conf5.ui_config(), UiConfiguration { - enabled: true, - interface: "127.0.0.1".into(), - port: 8180, - hosts: Some(vec![]), - info_page_only: false, - }); } #[test] @@ -1976,7 +1796,6 @@ mod tests { assert_eq!(conf0.network_settings().unwrap().rpc_port, 8546); assert_eq!(conf0.http_config().unwrap().port, 8546); assert_eq!(conf0.ws_config().unwrap().port, 8547); - assert_eq!(conf0.ui_config().port, 8181); assert_eq!(conf0.secretstore_config().unwrap().port, 8084); assert_eq!(conf0.secretstore_config().unwrap().http_port, 8083); assert_eq!(conf0.ipfs_config().port, 5002); @@ -1987,7 +1806,6 @@ mod tests { assert_eq!(conf1.network_settings().unwrap().rpc_port, 8545); assert_eq!(conf1.http_config().unwrap().port, 8545); assert_eq!(conf1.ws_config().unwrap().port, 8547); - assert_eq!(conf1.ui_config().port, 8181); assert_eq!(conf1.secretstore_config().unwrap().port, 8084); assert_eq!(conf1.secretstore_config().unwrap().http_port, 8083); assert_eq!(conf1.ipfs_config().port, 5002); @@ -2007,8 +1825,6 @@ mod tests { assert_eq!(&conf0.ws_config().unwrap().interface, "0.0.0.0"); assert_eq!(conf0.ws_config().unwrap().hosts, None); assert_eq!(conf0.ws_config().unwrap().origins, None); - assert_eq!(&conf0.ui_config().interface, "0.0.0.0"); - assert_eq!(conf0.ui_config().hosts, None); assert_eq!(&conf0.secretstore_config().unwrap().interface, "0.0.0.0"); assert_eq!(&conf0.secretstore_config().unwrap().http_interface, "0.0.0.0"); assert_eq!(&conf0.ipfs_config().interface, "0.0.0.0"); diff --git a/parity/dapps.rs b/parity/dapps.rs index 427bfa53b3..ce5b3a8daa 100644 --- a/parity/dapps.rs +++ b/parity/dapps.rs @@ -39,8 +39,6 @@ pub struct Configuration { pub enabled: bool, pub dapps_path: PathBuf, pub extra_dapps: Vec, - pub extra_embed_on: Vec<(String, u16)>, - pub extra_script_src: Vec<(String, u16)>, } impl Default for Configuration { @@ -50,8 +48,6 @@ impl Default for Configuration { enabled: true, dapps_path: replace_home(&data_dir, "$BASE/dapps").into(), extra_dapps: vec![], - extra_embed_on: vec![], - extra_script_src: vec![], } } } @@ -163,8 +159,6 @@ pub struct Dependencies { pub fetch: FetchClient, pub pool: CpuPool, pub signer: Arc, - pub ui_address: Option<(String, u16)>, - pub info_page_only: bool, } pub fn new(configuration: Configuration, deps: Dependencies) -> Result, String> { @@ -177,19 +171,6 @@ pub fn new(configuration: Configuration, deps: Dependencies) -> Result Result, String> { - if !enabled { - return Ok(None); - } - - server::ui_middleware( - deps, - rpc::DAPPS_DOMAIN, ).map(Some) } @@ -215,19 +196,10 @@ mod server { _dapps_path: PathBuf, _extra_dapps: Vec, _dapps_domain: &str, - _extra_embed_on: Vec<(String, u16)>, - _extra_script_src: Vec<(String, u16)>, ) -> Result { Err("Your Parity version has been compiled without WebApps support.".into()) } - pub fn ui_middleware( - _deps: Dependencies, - _dapps_domain: &str, - ) -> Result { - Err("Your Parity version has been compiled without UI support.".into()) - } - pub fn service(_: &Option) -> Option> { None } @@ -249,8 +221,6 @@ mod server { dapps_path: PathBuf, extra_dapps: Vec, dapps_domain: &str, - extra_embed_on: Vec<(String, u16)>, - extra_script_src: Vec<(String, u16)>, ) -> Result { let signer = deps.signer; let web_proxy_tokens = Arc::new(move |token| signer.web_proxy_access_token_domain(&token)); @@ -258,9 +228,6 @@ mod server { Ok(parity_dapps::Middleware::dapps( deps.pool, deps.node_health, - deps.ui_address, - extra_embed_on, - extra_script_src, dapps_path, extra_dapps, dapps_domain, @@ -271,21 +238,6 @@ mod server { )) } - pub fn ui_middleware( - deps: Dependencies, - dapps_domain: &str, - ) -> Result { - Ok(parity_dapps::Middleware::ui( - deps.pool, - deps.node_health, - dapps_domain, - deps.contract_client, - deps.sync_status, - deps.fetch, - deps.info_page_only, - )) - } - pub fn service(middleware: &Option) -> Option> { middleware.as_ref().map(|m| Arc::new(DappsServiceWrapper { endpoints: m.endpoints().clone(), diff --git a/parity/lib.rs b/parity/lib.rs index c768722552..8c3242afb4 100644 --- a/parity/lib.rs +++ b/parity/lib.rs @@ -118,15 +118,13 @@ mod user_defaults; mod whisper; mod db; -use std::net::{TcpListener}; use std::io::BufReader; use std::fs::File; -use ansi_term::Style; use hash::keccak_buffer; use cli::Args; use configuration::{Cmd, Execute}; use deprecated::find_deprecated; -use ethcore_logger::{Config as LogConfig, setup_log}; +use ethcore_logger::setup_log; pub use self::configuration::Configuration; pub use self::run::RunningClient; @@ -195,24 +193,6 @@ fn execute(command: Execute, on_client_rq: Cr, on_updater_rq: Rr) -> Res match command.cmd { Cmd::Run(run_cmd) => { - if run_cmd.ui_conf.enabled && !run_cmd.ui_conf.info_page_only { - warn!("{}", Style::new().bold().paint("Parity browser interface is deprecated. It's going to be removed in the next version, use standalone Parity UI instead.")); - warn!("{}", Style::new().bold().paint("Standalone Parity UI: https://github.com/Parity-JS/shell/releases")); - } - - if run_cmd.ui && run_cmd.dapps_conf.enabled { - // Check if Parity is already running - let addr = format!("{}:{}", run_cmd.ui_conf.interface, run_cmd.ui_conf.port); - if !TcpListener::bind(&addr as &str).is_ok() { - return open_ui(&run_cmd.ws_conf, &run_cmd.ui_conf, &run_cmd.logger_config).map(|_| ExecutionAction::Instant(None)); - } - } - - // start ui - if run_cmd.ui { - open_ui(&run_cmd.ws_conf, &run_cmd.ui_conf, &run_cmd.logger_config)?; - } - if let Some(ref dapp) = run_cmd.dapp { open_dapp(&run_cmd.dapps_conf, &run_cmd.http_conf, dapp)?; } @@ -225,7 +205,7 @@ fn execute(command: Execute, on_client_rq: Cr, on_updater_rq: Rr) -> Res Cmd::Account(account_cmd) => account::execute(account_cmd).map(|s| ExecutionAction::Instant(Some(s))), Cmd::ImportPresaleWallet(presale_cmd) => presale::execute(presale_cmd).map(|s| ExecutionAction::Instant(Some(s))), Cmd::Blockchain(blockchain_cmd) => blockchain::execute(blockchain_cmd).map(|_| ExecutionAction::Instant(None)), - Cmd::SignerToken(ws_conf, ui_conf, logger_config) => signer::execute(ws_conf, ui_conf, logger_config).map(|s| ExecutionAction::Instant(Some(s))), + Cmd::SignerToken(ws_conf, logger_config) => signer::execute(ws_conf, logger_config).map(|s| ExecutionAction::Instant(Some(s))), Cmd::SignerSign { id, pwfile, port, authfile } => rpc_cli::signer_sign(id, pwfile, port, authfile).map(|s| ExecutionAction::Instant(Some(s))), Cmd::SignerList { port, authfile } => rpc_cli::signer_list(port, authfile).map(|s| ExecutionAction::Instant(Some(s))), Cmd::SignerReject { id, port, authfile } => rpc_cli::signer_reject(id, port, authfile).map(|s| ExecutionAction::Instant(Some(s))), @@ -257,19 +237,6 @@ pub fn start(conf: Configuration, on_client_rq: Cr, on_updater_rq: Rr) - execute(conf.into_command()?, on_client_rq, on_updater_rq) } -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, logger_config)?; - // Open a browser - url::open(&token.url).map_err(|e| format!("{}", e))?; - // Print a message - println!("{}", token.message); - Ok(()) -} - fn open_dapp(dapps_conf: &dapps::Configuration, rpc_conf: &rpc::HttpConfiguration, dapp: &str) -> Result<(), String> { if !dapps_conf.enabled { return Err("Cannot use DAPP command with Dapps turned off.".into()) diff --git a/parity/rpc.rs b/parity/rpc.rs index cdc8e7ca5b..3e71cc6295 100644 --- a/parity/rpc.rs +++ b/parity/rpc.rs @@ -68,58 +68,6 @@ impl Default for HttpConfiguration { } } -#[derive(Debug, PartialEq, Clone)] -pub struct UiConfiguration { - pub enabled: bool, - pub interface: String, - pub port: u16, - pub hosts: Option>, - pub info_page_only: bool, -} - -impl UiConfiguration { - pub fn address(&self) -> Option { - address(self.enabled, &self.interface, self.port, &self.hosts) - } - - pub fn redirection_address(&self) -> Option<(String, u16)> { - self.address().map(|host| { - let mut it = host.split(':'); - let hostname: Option = it.next().map(|s| s.to_owned()); - let port: Option = it.next().and_then(|s| s.parse().ok()); - - (hostname.unwrap_or_else(|| "localhost".into()), port.unwrap_or(8180)) - }) - } -} - -impl From for HttpConfiguration { - fn from(conf: UiConfiguration) -> Self { - HttpConfiguration { - enabled: conf.enabled, - interface: conf.interface, - port: conf.port, - apis: rpc_apis::ApiSet::UnsafeContext, - cors: Some(vec![]), - hosts: conf.hosts, - server_threads: 1, - processing_threads: 0, - } - } -} - -impl Default for UiConfiguration { - fn default() -> Self { - UiConfiguration { - enabled: cfg!(feature = "ui-enabled"), - port: 8180, - interface: "127.0.0.1".into(), - hosts: Some(vec![]), - info_page_only: true, - } - } -} - #[derive(Debug, PartialEq)] pub struct IpcConfiguration { pub enabled: bool, @@ -153,7 +101,6 @@ pub struct WsConfiguration { pub hosts: Option>, pub signer_path: PathBuf, pub support_token_api: bool, - pub ui_address: Option, pub dapps_address: Option, } @@ -170,7 +117,6 @@ impl Default for WsConfiguration { hosts: Some(Vec::new()), signer_path: replace_home(&data_dir, "$BASE/signer").into(), support_token_api: true, - ui_address: Some("127.0.0.1:8180".into()), dapps_address: Some("127.0.0.1:8545".into()), } } @@ -225,9 +171,8 @@ pub fn new_ws( }; let remote = deps.remote.clone(); - let ui_address = conf.ui_address.clone(); - let allowed_origins = into_domains(with_domain(conf.origins, domain, &ui_address, &conf.dapps_address)); - let allowed_hosts = into_domains(with_domain(conf.hosts, domain, &Some(url.clone().into()), &None)); + let allowed_origins = into_domains(with_domain(conf.origins, domain, &conf.dapps_address)); + let allowed_hosts = into_domains(with_domain(conf.hosts, domain, &Some(url.clone().into()))); let signer_path; let path = match conf.support_token_api { @@ -276,7 +221,7 @@ pub fn new_http( let remote = deps.remote.clone(); let cors_domains = into_domains(conf.cors); - let allowed_hosts = into_domains(with_domain(conf.hosts, domain, &Some(url.clone().into()), &None)); + let allowed_hosts = into_domains(with_domain(conf.hosts, domain, &Some(url.clone().into()))); let start_result = rpc::start_http( &addr, @@ -328,7 +273,7 @@ fn into_domains>(items: Option>) -> DomainsValidatio items.map(|vals| vals.into_iter().map(T::from).collect()).into() } -fn with_domain(items: Option>, domain: &str, ui_address: &Option, dapps_address: &Option) -> Option> { +fn with_domain(items: Option>, domain: &str, dapps_address: &Option) -> Option> { fn extract_port(s: &str) -> Option { s.split(':').nth(1).and_then(|s| s.parse().ok()) } @@ -347,7 +292,6 @@ fn with_domain(items: Option>, domain: &str, ui_address: &Option, - pub ui: bool, pub name: String, pub custom_bootnodes: bool, pub stratum: Option, @@ -185,7 +183,7 @@ fn execute_light_impl(cmd: RunCmd, logger: Arc) -> Result) -> Result) -> Result) -> Result(cmd: RunCmd, logger: Arc, on_client_rq: execute_upgrades(&cmd.dirs.base, &db_dirs, algorithm, &cmd.compaction)?; // create dirs used by parity - cmd.dirs.create_dirs(cmd.dapps_conf.enabled, cmd.ui_conf.enabled, cmd.secretstore_conf.enabled)?; + cmd.dirs.create_dirs(cmd.dapps_conf.enabled, cmd.acc_conf.unlocked_accounts.len() == 0, cmd.secretstore_conf.enabled)?; // run in daemon mode if let Some(pid_file) = cmd.daemon { @@ -756,12 +750,9 @@ fn execute_impl(cmd: RunCmd, logger: Arc, on_client_rq: fetch: fetch.clone(), pool: cpu_pool.clone(), signer: signer_service.clone(), - ui_address: cmd.ui_conf.redirection_address(), - info_page_only: cmd.ui_conf.info_page_only, }) }; let dapps_middleware = dapps::new(cmd.dapps_conf.clone(), dapps_deps.clone())?; - let ui_middleware = dapps::new_ui(cmd.ui_conf.enabled, dapps_deps)?; let dapps_service = dapps::service(&dapps_middleware); let deps_for_rpc_apis = Arc::new(rpc_apis::FullDependencies { @@ -807,8 +798,6 @@ fn execute_impl(cmd: RunCmd, logger: Arc, on_client_rq: let ws_server = rpc::new_ws(cmd.ws_conf.clone(), &dependencies)?; let ipc_server = rpc::new_ipc(cmd.ipc_conf, &dependencies)?; let http_server = rpc::new_http("HTTP JSON-RPC", "jsonrpc", cmd.http_conf.clone(), &dependencies, dapps_middleware)?; - // the ui server - let ui_server = rpc::new_http("UI WALLET", "ui", cmd.ui_conf.clone().into(), &dependencies, ui_middleware)?; // secret store key server let secretstore_deps = secretstore::Dependencies { @@ -881,7 +870,7 @@ fn execute_impl(cmd: RunCmd, logger: Arc, on_client_rq: informant, client, client_service: Arc::new(service), - keep_alive: Box::new((watcher, updater, ws_server, http_server, ipc_server, ui_server, secretstore_key_server, ipfs_server, event_loop)), + keep_alive: Box::new((watcher, updater, ws_server, http_server, ipc_server, secretstore_key_server, ipfs_server, event_loop)), } }) } diff --git a/parity/signer.rs b/parity/signer.rs index 4388e11aa8..e9a636bf8b 100644 --- a/parity/signer.rs +++ b/parity/signer.rs @@ -28,7 +28,6 @@ pub const CODES_FILENAME: &'static str = "authcodes"; pub struct NewToken { pub token: String, - pub url: String, pub message: String, } @@ -49,45 +48,26 @@ pub fn codes_path(path: &Path) -> PathBuf { p } -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 execute(ws_conf: rpc::WsConfiguration, logger_config: LogConfig) -> Result { + Ok(generate_token_and_url(&ws_conf, &logger_config)?.message) } -pub fn generate_token_and_url(ws_conf: &rpc::WsConfiguration, ui_conf: &rpc::UiConfiguration, logger_config: &LogConfig) -> Result { +pub fn generate_token_and_url(ws_conf: &rpc::WsConfiguration, 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); let colored = |s: String| match logger_config.color { true => format!("{}", White.bold().paint(s)), false => s, }; - if !ui_conf.enabled { - return Ok(NewToken { - token: code.clone(), - url: auth_url.clone(), - message: format!( - r#" -Generated token: -{} -"#, - colored(code) - ), - }) - } - - // And print in to the console Ok(NewToken { token: code.clone(), - url: auth_url.clone(), message: format!( r#" -Open: {} -to authorize your browser. -Or use the generated token: -{}"#, - colored(auth_url), - code - ) +Generated token: +{} +"#, + colored(code) + ), }) } -- GitLab From 107f0fa4c6738e857e0d14fbe26648bb44d82555 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Wed, 6 Jun 2018 14:14:45 +0200 Subject: [PATCH 106/152] Removed obsolete IpcMode enum (#8819) --- ethcore/src/client/client.rs | 11 +++++------ ethcore/src/client/config.rs | 23 ---------------------- ethcore/src/client/test_client.rs | 3 +-- ethcore/src/client/traits.rs | 2 +- ethcore/types/src/lib.rs | 1 - ethcore/types/src/mode.rs | 32 ------------------------------- rpc/src/v1/impls/parity.rs | 8 +------- rpc/src/v1/impls/parity_set.rs | 8 ++++---- 8 files changed, 12 insertions(+), 76 deletions(-) delete mode 100644 ethcore/types/src/mode.rs diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index f3a3dda103..3f19f491ba 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -72,7 +72,6 @@ use trace; use trace::{TraceDB, ImportRequest as TraceImportRequest, LocalizedTrace, Database as TraceDatabase}; use transaction::{self, LocalizedTransaction, UnverifiedTransaction, SignedTransaction, Transaction, Action}; use types::filter::Filter; -use types::mode::Mode as IpcMode; use types::ancestry_action::AncestryAction; use verification; use verification::{PreverifiedBlock, Verifier}; @@ -1570,19 +1569,19 @@ impl BlockChainClient for Client { }))) } - fn mode(&self) -> IpcMode { + fn mode(&self) -> Mode { let r = self.mode.lock().clone().into(); trace!(target: "mode", "Asked for mode = {:?}. returning {:?}", &*self.mode.lock(), r); r } fn disable(&self) { - self.set_mode(IpcMode::Off); + self.set_mode(Mode::Off); self.enabled.store(false, AtomicOrdering::Relaxed); self.clear_queue(); } - fn set_mode(&self, new_mode: IpcMode) { + fn set_mode(&self, new_mode: Mode) { trace!(target: "mode", "Client::set_mode({:?})", new_mode); if !self.enabled.load(AtomicOrdering::Relaxed) { return; @@ -1597,8 +1596,8 @@ impl BlockChainClient for Client { } } match new_mode { - IpcMode::Active => self.wake_up(), - IpcMode::Off => self.sleep(), + Mode::Active => self.wake_up(), + Mode::Off => self.sleep(), _ => {(*self.sleep_state.lock()).last_activity = Some(Instant::now()); } } } diff --git a/ethcore/src/client/config.rs b/ethcore/src/client/config.rs index 288de25e4b..dbba4f4a96 100644 --- a/ethcore/src/client/config.rs +++ b/ethcore/src/client/config.rs @@ -17,7 +17,6 @@ use std::str::FromStr; use std::fmt::{Display, Formatter, Error as FmtError}; -use mode::Mode as IpcMode; use verification::{VerifierType, QueueConfig}; use journaldb; @@ -88,28 +87,6 @@ impl Display for Mode { } } -impl Into for Mode { - fn into(self) -> IpcMode { - match self { - Mode::Off => IpcMode::Off, - Mode::Dark(timeout) => IpcMode::Dark(timeout.as_secs()), - Mode::Passive(timeout, alarm) => IpcMode::Passive(timeout.as_secs(), alarm.as_secs()), - Mode::Active => IpcMode::Active, - } - } -} - -impl From for Mode { - fn from(mode: IpcMode) -> Self { - match mode { - IpcMode::Off => Mode::Off, - IpcMode::Dark(timeout) => Mode::Dark(Duration::from_secs(timeout)), - IpcMode::Passive(timeout, alarm) => Mode::Passive(Duration::from_secs(timeout), Duration::from_secs(alarm)), - IpcMode::Active => Mode::Active, - } - } -} - /// Client configuration. Includes configs for all sub-systems. #[derive(Debug, PartialEq, Default)] pub struct ClientConfig { diff --git a/ethcore/src/client/test_client.rs b/ethcore/src/client/test_client.rs index 8acbde4f97..4bd76b4495 100644 --- a/ethcore/src/client/test_client.rs +++ b/ethcore/src/client/test_client.rs @@ -36,7 +36,7 @@ use transaction::{self, Transaction, LocalizedTransaction, SignedTransaction, Ac use blockchain::{TreeRoute, BlockReceipts}; use client::{ Nonce, Balance, ChainInfo, BlockInfo, ReopenBlock, CallContract, TransactionInfo, RegistryInfo, - PrepareOpenBlock, BlockChainClient, BlockChainInfo, BlockStatus, BlockId, + PrepareOpenBlock, BlockChainClient, BlockChainInfo, BlockStatus, BlockId, Mode, TransactionId, UncleId, TraceId, TraceFilter, LastHashes, CallAnalytics, BlockImportError, ProvingBlockChainClient, ScheduleInfo, ImportSealedBlock, BroadcastProposalBlock, ImportBlock, StateOrBlock, Call, StateClient, EngineInfo, AccountData, BlockChain, BlockProducer, SealedBlockImporter, IoClient @@ -51,7 +51,6 @@ use vm::Schedule; use miner::{Miner, MinerService}; use spec::Spec; use types::basic_account::BasicAccount; -use types::mode::Mode; use types::pruning_info::PruningInfo; use verification::queue::QueueInfo; diff --git a/ethcore/src/client/traits.rs b/ethcore/src/client/traits.rs index f0fae4b498..d3a20dcff8 100644 --- a/ethcore/src/client/traits.rs +++ b/ethcore/src/client/traits.rs @@ -21,6 +21,7 @@ use itertools::Itertools; use block::{OpenBlock, SealedBlock, ClosedBlock}; use blockchain::TreeRoute; +use client::Mode; use encoded; use vm::LastHashes; use error::{ImportResult, CallError, BlockImportError}; @@ -48,7 +49,6 @@ use types::trace_filter::Filter as TraceFilter; use types::call_analytics::CallAnalytics; use types::blockchain_info::BlockChainInfo; use types::block_status::BlockStatus; -use types::mode::Mode; use types::pruning_info::PruningInfo; /// State information to be used during client query diff --git a/ethcore/types/src/lib.rs b/ethcore/types/src/lib.rs index 8db6163bbf..5ac8ff12ad 100644 --- a/ethcore/types/src/lib.rs +++ b/ethcore/types/src/lib.rs @@ -36,7 +36,6 @@ pub mod call_analytics; pub mod filter; pub mod ids; pub mod log_entry; -pub mod mode; pub mod pruning_info; pub mod receipt; pub mod restoration_status; diff --git a/ethcore/types/src/mode.rs b/ethcore/types/src/mode.rs deleted file mode 100644 index ee4f9fbf2c..0000000000 --- a/ethcore/types/src/mode.rs +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2015-2018 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity. If not, see . - -//! Mode type - -pub use std::time::Duration; - -/// IPC-capable shadow-type for `client::config::Mode` -#[derive(Clone, Debug)] -pub enum Mode { - /// Same as `ClientMode::Off`. - Off, - /// Same as `ClientMode::Dark`; values in seconds. - Dark(u64), - /// Same as `ClientMode::Passive`; values in seconds. - Passive(u64, u64), - /// Same as `ClientMode::Active`. - Active, -} diff --git a/rpc/src/v1/impls/parity.rs b/rpc/src/v1/impls/parity.rs index 5707104212..f18723eafe 100644 --- a/rpc/src/v1/impls/parity.rs +++ b/rpc/src/v1/impls/parity.rs @@ -30,7 +30,6 @@ use ethcore::account_provider::AccountProvider; use ethcore::client::{BlockChainClient, StateClient, Call}; use ethcore::ids::BlockId; use ethcore::miner::{self, MinerService}; -use ethcore::mode::Mode; use ethcore::state::StateInfo; use ethcore_logger::RotatingLogger; use node_health::{NodeHealth, Health}; @@ -365,12 +364,7 @@ impl Parity for ParityClient where } fn mode(&self) -> Result { - Ok(match self.client.mode() { - Mode::Off => "offline", - Mode::Dark(..) => "dark", - Mode::Passive(..) => "passive", - Mode::Active => "active", - }.into()) + Ok(self.client.mode().to_string()) } fn enode(&self) -> Result { diff --git a/rpc/src/v1/impls/parity_set.rs b/rpc/src/v1/impls/parity_set.rs index 4ba9ab658e..18f5776c69 100644 --- a/rpc/src/v1/impls/parity_set.rs +++ b/rpc/src/v1/impls/parity_set.rs @@ -17,10 +17,10 @@ /// Parity-specific rpc interface for operations altering the settings. use std::io; use std::sync::Arc; +use std::time::Duration; -use ethcore::client::BlockChainClient; +use ethcore::client::{BlockChainClient, Mode}; use ethcore::miner::MinerService; -use ethcore::mode::Mode; use sync::ManageNetwork; use fetch::{self, Fetch}; use futures_cpupool::CpuPool; @@ -160,8 +160,8 @@ impl ParitySet for ParitySetClient where fn set_mode(&self, mode: String) -> Result { self.client.set_mode(match mode.as_str() { "offline" => Mode::Off, - "dark" => Mode::Dark(300), - "passive" => Mode::Passive(300, 3600), + "dark" => Mode::Dark(Duration::from_secs(300)), + "passive" => Mode::Passive(Duration::from_secs(300), Duration::from_secs(3600)), "active" => Mode::Active, e => { return Err(errors::invalid_params("mode", e.to_owned())); }, }); -- GitLab From bc2f86e806f70d23c1b5123c43be0d4cc73819bc Mon Sep 17 00:00:00 2001 From: Afri Schoedon <5chdn@users.noreply.github.com> Date: Wed, 6 Jun 2018 14:15:13 +0200 Subject: [PATCH 107/152] parity: fix indentation in sync logging (#8794) --- parity/informant.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/parity/informant.rs b/parity/informant.rs index 43788bc9d9..1840be3bad 100644 --- a/parity/informant.rs +++ b/parity/informant.rs @@ -304,7 +304,7 @@ impl Informant { paint(White.bold(), format!("{}", chain_info.best_block_hash)), if self.target.executes_transactions() { format!("{} blk/s {} tx/s {} Mgas/s", - paint(Yellow.bold(), format!("{:5.2}", (client_report.blocks_imported * 1000) as f64 / elapsed.as_milliseconds() as f64)), + paint(Yellow.bold(), format!("{:7.2}", (client_report.blocks_imported * 1000) as f64 / elapsed.as_milliseconds() as f64)), paint(Yellow.bold(), format!("{:6.1}", (client_report.transactions_applied * 1000) as f64 / elapsed.as_milliseconds() as f64)), paint(Yellow.bold(), format!("{:4}", (client_report.gas_processed / From::from(elapsed.as_milliseconds() * 1000)).low_u64())) ) -- GitLab From 1318f536c9d13acc1740b401e304e9b88a540d87 Mon Sep 17 00:00:00 2001 From: Afri Schoedon <5chdn@users.noreply.github.com> Date: Wed, 6 Jun 2018 15:45:55 +0200 Subject: [PATCH 108/152] CI: Fix docker tags (#8822) * scripts: enable docker builds for beta and stable * scripts: docker latest should be beta not master * scripts: docker latest is master --- .gitlab-ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 6be6b45838..d4add41721 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -201,6 +201,8 @@ docker-build: stage: build only: - tags + - beta + - stable - triggers before_script: - docker info -- GitLab From c8877d40989fa69822b7c4764af7e67ddb4cfb52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Silva?= Date: Thu, 7 Jun 2018 10:15:21 +0100 Subject: [PATCH 109/152] ethcore: fix ancient block error msg handling (#8832) --- ethcore/src/client/client.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index 3f19f491ba..ea8fa88630 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -2073,15 +2073,16 @@ impl IoClient for Client { let first = queued.write().1.pop_front(); if let Some((header, block_bytes, receipts_bytes)) = first { let hash = header.hash(); - client.importer.import_old_block( + let result = client.importer.import_old_block( &header, &block_bytes, &receipts_bytes, &**client.db.read(), - &*client.chain.read() - ).ok().map_or((), |e| { + &*client.chain.read(), + ); + if let Err(e) = result { error!(target: "client", "Error importing ancient block: {}", e); - }); + } // remove from pending queued.write().0.remove(&hash); } else { -- GitLab From a6d267abc04bd268a7c9330a9b225244b36f5e5c Mon Sep 17 00:00:00 2001 From: Alex Baranov Date: Thu, 7 Jun 2018 10:47:41 -0400 Subject: [PATCH 110/152] added from and to to Receipt (#8756) --- ethcore/src/client/client.rs | 10 ++++++++++ ethcore/types/src/receipt.rs | 6 +++++- rpc/src/v1/tests/mocked/eth.rs | 6 ++++-- rpc/src/v1/types/receipt.rs | 14 +++++++++++++- 4 files changed, 32 insertions(+), 4 deletions(-) diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index ea8fa88630..2d0201067f 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -2336,6 +2336,11 @@ fn transaction_receipt(machine: &::machine::EthereumMachine, mut tx: LocalizedTr let transaction_index = tx.transaction_index; LocalizedReceipt { + from: sender, + to: match tx.action { + Action::Create => None, + Action::Call(ref address) => Some(address.clone().into()) + }, transaction_hash: transaction_hash, transaction_index: transaction_index, block_hash: block_hash, @@ -2461,6 +2466,11 @@ mod tests { // then assert_eq!(receipt, LocalizedReceipt { + from: tx1.sender().into(), + to: match tx1.action { + Action::Create => None, + Action::Call(ref address) => Some(address.clone().into()) + }, transaction_hash: tx1.hash(), transaction_index: 1, block_hash: block_hash, diff --git a/ethcore/types/src/receipt.rs b/ethcore/types/src/receipt.rs index b4f105afab..81233d212a 100644 --- a/ethcore/types/src/receipt.rs +++ b/ethcore/types/src/receipt.rs @@ -16,7 +16,7 @@ //! Receipt -use ethereum_types::{H256, U256, Address, Bloom}; +use ethereum_types::{H160, H256, U256, Address, Bloom}; use heapsize::HeapSizeOf; use rlp::{Rlp, RlpStream, Encodable, Decodable, DecoderError}; @@ -157,6 +157,10 @@ pub struct LocalizedReceipt { pub log_bloom: Bloom, /// Transaction outcome. pub outcome: TransactionOutcome, + /// Receiver address + pub to: Option, + /// Sender + pub from: H160 } #[cfg(test)] diff --git a/rpc/src/v1/tests/mocked/eth.rs b/rpc/src/v1/tests/mocked/eth.rs index a8875a3354..c0ed3306fe 100644 --- a/rpc/src/v1/tests/mocked/eth.rs +++ b/rpc/src/v1/tests/mocked/eth.rs @@ -19,7 +19,7 @@ use std::collections::HashMap; use std::sync::Arc; use std::time::{Instant, Duration, SystemTime, UNIX_EPOCH}; -use ethereum_types::{H256, U256, Address}; +use ethereum_types::{H160, H256, U256, Address}; use parking_lot::Mutex; use ethcore::account_provider::AccountProvider; use ethcore::client::{BlockChainClient, BlockId, EachBlockWith, Executed, TestBlockChainClient, TransactionId}; @@ -1004,6 +1004,8 @@ fn rpc_eth_send_raw_transaction() { #[test] fn rpc_eth_transaction_receipt() { let receipt = LocalizedReceipt { + from: H160::from_str("b60e8dd61c5d32be8058bb8eb970870f07233155").unwrap(), + to: Some(H160::from_str("d46e8dd67c5d32be8058bb8eb970870f07244567").unwrap()), transaction_hash: H256::zero(), transaction_index: 0, block_hash: H256::from_str("ed76641c68a1c641aee09a94b3b471f4dc0316efe5ac19cf488e2674cf8d05b5").unwrap(), @@ -1041,7 +1043,7 @@ fn rpc_eth_transaction_receipt() { "params": ["0xb903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238"], "id": 1 }"#; - let response = r#"{"jsonrpc":"2.0","result":{"blockHash":"0xed76641c68a1c641aee09a94b3b471f4dc0316efe5ac19cf488e2674cf8d05b5","blockNumber":"0x4510c","contractAddress":null,"cumulativeGasUsed":"0x20","gasUsed":"0x10","logs":[{"address":"0x33990122638b9132ca29c723bdf037f1a891a70c","blockHash":"0xed76641c68a1c641aee09a94b3b471f4dc0316efe5ac19cf488e2674cf8d05b5","blockNumber":"0x4510c","data":"0x","logIndex":"0x1","topics":["0xa6697e974e6a320f454390be03f74955e8978f1a6971ea6730542e37b66179bc","0x4861736852656700000000000000000000000000000000000000000000000000"],"transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionIndex":"0x0","transactionLogIndex":"0x0","type":"mined"}],"logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","root":"0x0000000000000000000000000000000000000000000000000000000000000000","status":null,"transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionIndex":"0x0"},"id":1}"#; + let response = r#"{"jsonrpc":"2.0","result":{"blockHash":"0xed76641c68a1c641aee09a94b3b471f4dc0316efe5ac19cf488e2674cf8d05b5","blockNumber":"0x4510c","contractAddress":null,"cumulativeGasUsed":"0x20","from":"0xb60e8dd61c5d32be8058bb8eb970870f07233155","gasUsed":"0x10","logs":[{"address":"0x33990122638b9132ca29c723bdf037f1a891a70c","blockHash":"0xed76641c68a1c641aee09a94b3b471f4dc0316efe5ac19cf488e2674cf8d05b5","blockNumber":"0x4510c","data":"0x","logIndex":"0x1","topics":["0xa6697e974e6a320f454390be03f74955e8978f1a6971ea6730542e37b66179bc","0x4861736852656700000000000000000000000000000000000000000000000000"],"transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionIndex":"0x0","transactionLogIndex":"0x0","type":"mined"}],"logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","root":"0x0000000000000000000000000000000000000000000000000000000000000000","status":null,"to":"0xd46e8dd67c5d32be8058bb8eb970870f07244567","transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionIndex":"0x0"},"id":1}"#; assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned())); } diff --git a/rpc/src/v1/types/receipt.rs b/rpc/src/v1/types/receipt.rs index f8d111887a..e46b640f14 100644 --- a/rpc/src/v1/types/receipt.rs +++ b/rpc/src/v1/types/receipt.rs @@ -29,6 +29,10 @@ pub struct Receipt { /// Block hash #[serde(rename="blockHash")] pub block_hash: Option, + /// Sender + pub from: Option, + /// Recipient + pub to: Option, /// Block number #[serde(rename="blockNumber")] pub block_number: Option, @@ -73,6 +77,8 @@ impl Receipt { impl From for Receipt { fn from(r: LocalizedReceipt) -> Self { Receipt { + to: r.to.map(Into::into), + from: Some(r.from.into()), transaction_hash: Some(r.transaction_hash.into()), transaction_index: Some(r.transaction_index.into()), block_hash: Some(r.block_hash.into()), @@ -91,6 +97,8 @@ impl From for Receipt { impl From for Receipt { fn from(r: RichReceipt) -> Self { Receipt { + from: None, + to: None, transaction_hash: Some(r.transaction_hash.into()), transaction_index: Some(r.transaction_index.into()), block_hash: None, @@ -109,6 +117,8 @@ impl From for Receipt { impl From for Receipt { fn from(r: EthReceipt) -> Self { Receipt { + from: None, + to: None, transaction_hash: None, transaction_index: None, block_hash: None, @@ -131,9 +141,11 @@ mod tests { #[test] fn receipt_serialization() { - let s = r#"{"transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionIndex":"0x0","blockHash":"0xed76641c68a1c641aee09a94b3b471f4dc0316efe5ac19cf488e2674cf8d05b5","blockNumber":"0x4510c","cumulativeGasUsed":"0x20","gasUsed":"0x10","contractAddress":null,"logs":[{"address":"0x33990122638b9132ca29c723bdf037f1a891a70c","topics":["0xa6697e974e6a320f454390be03f74955e8978f1a6971ea6730542e37b66179bc","0x4861736852656700000000000000000000000000000000000000000000000000"],"data":"0x","blockHash":"0xed76641c68a1c641aee09a94b3b471f4dc0316efe5ac19cf488e2674cf8d05b5","blockNumber":"0x4510c","transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionIndex":"0x0","logIndex":"0x1","transactionLogIndex":null,"type":"mined"}],"root":"0x000000000000000000000000000000000000000000000000000000000000000a","logsBloom":"0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f","status":"0x1"}"#; + let s = r#"{"transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionIndex":"0x0","blockHash":"0xed76641c68a1c641aee09a94b3b471f4dc0316efe5ac19cf488e2674cf8d05b5","from":null,"to":null,"blockNumber":"0x4510c","cumulativeGasUsed":"0x20","gasUsed":"0x10","contractAddress":null,"logs":[{"address":"0x33990122638b9132ca29c723bdf037f1a891a70c","topics":["0xa6697e974e6a320f454390be03f74955e8978f1a6971ea6730542e37b66179bc","0x4861736852656700000000000000000000000000000000000000000000000000"],"data":"0x","blockHash":"0xed76641c68a1c641aee09a94b3b471f4dc0316efe5ac19cf488e2674cf8d05b5","blockNumber":"0x4510c","transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionIndex":"0x0","logIndex":"0x1","transactionLogIndex":null,"type":"mined"}],"root":"0x000000000000000000000000000000000000000000000000000000000000000a","logsBloom":"0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f","status":"0x1"}"#; let receipt = Receipt { + from: None, + to: None, transaction_hash: Some(0.into()), transaction_index: Some(0.into()), block_hash: Some("ed76641c68a1c641aee09a94b3b471f4dc0316efe5ac19cf488e2674cf8d05b5".parse().unwrap()), -- GitLab From 24c43513a64a9795129c35ee95c6e1db30012f2b Mon Sep 17 00:00:00 2001 From: Andronik Ordian Date: Thu, 7 Jun 2018 17:48:01 +0300 Subject: [PATCH 111/152] Use system allocator when profiling memory (#8831) --- Cargo.toml | 7 +++++++ parity/lib.rs | 10 ++++++++++ 2 files changed, 17 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index 7795fb3b3b..8df37d5942 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -98,6 +98,13 @@ slow-blocks = ["ethcore/slow-blocks"] secretstore = ["ethcore-secretstore"] final = ["parity-version/final"] deadlock_detection = ["parking_lot/deadlock_detection"] +# to create a memory profile (requires nightly rust), use e.g. +# `heaptrack /path/to/parity `, +# to visualize a memory profile, use `heaptrack_gui` +# or +# `valgrind --tool=massif /path/to/parity ` +# and `massif-visualizer` for visualization +memory_profiling = [] [lib] path = "parity/lib.rs" diff --git a/parity/lib.rs b/parity/lib.rs index 8c3242afb4..5d0c80289d 100644 --- a/parity/lib.rs +++ b/parity/lib.rs @@ -17,6 +17,7 @@ //! Ethcore client application. #![warn(missing_docs)] +#![cfg_attr(feature = "memory_profiling", feature(alloc_system, global_allocator, allocator_api))] extern crate ansi_term; extern crate docopt; @@ -91,6 +92,9 @@ extern crate pretty_assertions; #[cfg(test)] extern crate tempdir; +#[cfg(feature = "memory_profiling")] +extern crate alloc_system; + mod account; mod blockchain; mod cache; @@ -125,10 +129,16 @@ use cli::Args; use configuration::{Cmd, Execute}; use deprecated::find_deprecated; use ethcore_logger::setup_log; +#[cfg(feature = "memory_profiling")] +use alloc_system::System; pub use self::configuration::Configuration; pub use self::run::RunningClient; +#[cfg(feature = "memory_profiling")] +#[global_allocator] +static A: System = System; + fn print_hash_of(maybe_file: Option) -> Result { if let Some(file) = maybe_file { let mut f = BufReader::new(File::open(&file).map_err(|_| "Unable to open file".to_owned())?); -- GitLab From a48ed024333df586e64c0648e52b297cb1c8583f Mon Sep 17 00:00:00 2001 From: Andronik Ordian Date: Fri, 8 Jun 2018 11:04:12 +0300 Subject: [PATCH 112/152] Fix `deadlock_detection` feature branch compilation (#8824) --- parity/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/parity/lib.rs b/parity/lib.rs index 5d0c80289d..a4f7d7963f 100644 --- a/parity/lib.rs +++ b/parity/lib.rs @@ -154,6 +154,7 @@ fn run_deadlock_detection_thread() { use std::thread; use std::time::Duration; use parking_lot::deadlock; + use ansi_term::Style; info!("Starting deadlock detection thread."); // Create a background thread which checks for deadlocks every 10s -- GitLab From 13efb6586dde45fba7a28a95d3a15e3f3981e680 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Fri, 8 Jun 2018 14:54:23 +0100 Subject: [PATCH 113/152] Specify critical release flag per network (#8821) --- util/version/Cargo.toml | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/util/version/Cargo.toml b/util/version/Cargo.toml index 297211b2bd..c7bd4f581e 100644 --- a/util/version/Cargo.toml +++ b/util/version/Cargo.toml @@ -12,14 +12,13 @@ build = "build.rs" # Used by auto-updater and for Parity version string. track = "nightly" -# Indicates a critical release in this track (i.e. consensus issue) -critical = false - -# Latest supported fork blocks for various networks. Used ONLY by auto-updater. -[package.metadata.forks] -foundation = 4370000 -ropsten = 10 -kovan = 6600000 +# Network specific settings, used ONLY by auto-updater. +# Latest supported fork blocks. +# Indicates a critical release in this track (i.e. consensus issue). +[package.metadata.networks] +foundation = { forkBlock = 4370000, critical = false } +ropsten = { forkBlock = 10, critical = false } +kovan = { forkBlock = 6600000, critical = false } [dependencies] ethcore-bytes = { path = "../bytes" } -- GitLab From 1f39a1bd768ae8b490068313bb41ca78bccf964b Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Fri, 8 Jun 2018 16:30:44 +0200 Subject: [PATCH 114/152] Fixed AuthorityRound deadlock on shutdown, closes #8088 (#8803) --- ethcore/src/engines/authority_round/mod.rs | 90 ++++++++++++---------- 1 file changed, 51 insertions(+), 39 deletions(-) diff --git a/ethcore/src/engines/authority_round/mod.rs b/ethcore/src/engines/authority_round/mod.rs index 067c754c7f..e2e88c8178 100644 --- a/ethcore/src/engines/authority_round/mod.rs +++ b/ethcore/src/engines/authority_round/mod.rs @@ -382,12 +382,16 @@ impl Decodable for SealedEmptyStep { } } +struct PermissionedStep { + inner: Step, + can_propose: AtomicBool, +} + /// Engine using `AuthorityRound` proof-of-authority BFT consensus. pub struct AuthorityRound { transition_service: IoService<()>, - step: Arc, - can_propose: AtomicBool, - client: RwLock>>, + step: Arc, + client: Arc>>>, signer: RwLock, validators: Box, validate_score_transition: u64, @@ -407,7 +411,7 @@ pub struct AuthorityRound { // header-chain validator. struct EpochVerifier { - step: Arc, + step: Arc, subchain_validators: SimpleList, empty_steps_transition: u64, } @@ -415,7 +419,7 @@ struct EpochVerifier { impl super::EpochVerifier for EpochVerifier { fn verify_light(&self, header: &Header) -> Result<(), Error> { // Validate the timestamp - verify_timestamp(&*self.step, header_step(header, self.empty_steps_transition)?)?; + verify_timestamp(&self.step.inner, header_step(header, self.empty_steps_transition)?)?; // always check the seal since it's fast. // nothing heavier to do. verify_external(header, &self.subchain_validators, self.empty_steps_transition) @@ -615,13 +619,15 @@ impl AuthorityRound { let engine = Arc::new( AuthorityRound { transition_service: IoService::<()>::start()?, - step: Arc::new(Step { - inner: AtomicUsize::new(initial_step), - calibrate: our_params.start_step.is_none(), - duration: our_params.step_duration, + step: Arc::new(PermissionedStep { + inner: Step { + inner: AtomicUsize::new(initial_step), + calibrate: our_params.start_step.is_none(), + duration: our_params.step_duration, + }, + can_propose: AtomicBool::new(true), }), - can_propose: AtomicBool::new(true), - client: RwLock::new(None), + client: Arc::new(RwLock::new(None)), signer: Default::default(), validators: our_params.validators, validate_score_transition: our_params.validate_score_transition, @@ -641,7 +647,10 @@ impl AuthorityRound { // Do not initialize timeouts for tests. if should_timeout { - let handler = TransitionHandler { engine: Arc::downgrade(&engine) }; + let handler = TransitionHandler { + step: engine.step.clone(), + client: engine.client.clone(), + }; engine.transition_service.register_handler(Arc::new(handler))?; } Ok(engine) @@ -666,7 +675,7 @@ impl AuthorityRound { } fn generate_empty_step(&self, parent_hash: &H256) { - let step = self.step.load(); + let step = self.step.inner.load(); let empty_step_rlp = empty_step_rlp(step, parent_hash); if let Ok(signature) = self.sign(keccak(&empty_step_rlp)).map(Into::into) { @@ -698,34 +707,37 @@ fn unix_now() -> Duration { } struct TransitionHandler { - engine: Weak, + step: Arc, + client: Arc>>>, } const ENGINE_TIMEOUT_TOKEN: TimerToken = 23; impl IoHandler<()> for TransitionHandler { fn initialize(&self, io: &IoContext<()>) { - if let Some(engine) = self.engine.upgrade() { - let remaining = engine.step.duration_remaining().as_millis(); - io.register_timer_once(ENGINE_TIMEOUT_TOKEN, Duration::from_millis(remaining)) - .unwrap_or_else(|e| warn!(target: "engine", "Failed to start consensus step timer: {}.", e)) - } + let remaining = self.step.inner.duration_remaining().as_millis(); + io.register_timer_once(ENGINE_TIMEOUT_TOKEN, Duration::from_millis(remaining)) + .unwrap_or_else(|e| warn!(target: "engine", "Failed to start consensus step timer: {}.", e)) } fn timeout(&self, io: &IoContext<()>, timer: TimerToken) { if timer == ENGINE_TIMEOUT_TOKEN { - if let Some(engine) = self.engine.upgrade() { - // NOTE we might be lagging by couple of steps in case the timeout - // has not been called fast enough. - // Make sure to advance up to the actual step. - while engine.step.duration_remaining().as_millis() == 0 { - engine.step(); + // NOTE we might be lagging by couple of steps in case the timeout + // has not been called fast enough. + // Make sure to advance up to the actual step. + while self.step.inner.duration_remaining().as_millis() == 0 { + self.step.inner.increment(); + self.step.can_propose.store(true, AtomicOrdering::SeqCst); + if let Some(ref weak) = *self.client.read() { + if let Some(c) = weak.upgrade() { + c.update_sealing(); + } } - - let next_run_at = engine.step.duration_remaining().as_millis() >> 2; - io.register_timer_once(ENGINE_TIMEOUT_TOKEN, Duration::from_millis(next_run_at)) - .unwrap_or_else(|e| warn!(target: "engine", "Failed to restart consensus step timer: {}.", e)) } + + let next_run_at = self.step.inner.duration_remaining().as_millis() >> 2; + io.register_timer_once(ENGINE_TIMEOUT_TOKEN, Duration::from_millis(next_run_at)) + .unwrap_or_else(|e| warn!(target: "engine", "Failed to restart consensus step timer: {}.", e)) } } } @@ -742,8 +754,8 @@ impl Engine for AuthorityRound { } fn step(&self) { - self.step.increment(); - self.can_propose.store(true, AtomicOrdering::SeqCst); + self.step.inner.increment(); + self.step.can_propose.store(true, AtomicOrdering::SeqCst); if let Some(ref weak) = *self.client.read() { if let Some(c) = weak.upgrade() { c.update_sealing(); @@ -790,7 +802,7 @@ impl Engine for AuthorityRound { fn populate_from_parent(&self, header: &mut Header, parent: &Header) { let parent_step = header_step(parent, self.empty_steps_transition).expect("Header has been verified; qed"); - let current_step = self.step.load(); + let current_step = self.step.inner.load(); let current_empty_steps_len = if header.number() >= self.empty_steps_transition { self.empty_steps(parent_step.into(), current_step.into(), parent.hash()).len() @@ -816,7 +828,7 @@ impl Engine for AuthorityRound { let empty_step: EmptyStep = rlp.as_val().map_err(fmt_err)?;; if empty_step.verify(&*self.validators).unwrap_or(false) { - if self.step.check_future(empty_step.step).is_ok() { + if self.step.inner.check_future(empty_step.step).is_ok() { trace!(target: "engine", "handle_message: received empty step message {:?}", empty_step); self.handle_empty_step_message(empty_step); } else { @@ -836,7 +848,7 @@ impl Engine for AuthorityRound { fn generate_seal(&self, block: &ExecutedBlock, parent: &Header) -> Seal { // first check to avoid generating signature most of the time // (but there's still a race to the `compare_and_swap`) - if !self.can_propose.load(AtomicOrdering::SeqCst) { + if !self.step.can_propose.load(AtomicOrdering::SeqCst) { trace!(target: "engine", "Aborting seal generation. Can't propose."); return Seal::None; } @@ -845,7 +857,7 @@ impl Engine for AuthorityRound { let parent_step: U256 = header_step(parent, self.empty_steps_transition) .expect("Header has been verified; qed").into(); - let step = self.step.load(); + let step = self.step.inner.load(); // filter messages from old and future steps and different parents let empty_steps = if header.number() >= self.empty_steps_transition { @@ -922,7 +934,7 @@ impl Engine for AuthorityRound { trace!(target: "engine", "generate_seal: Issuing a block for step {}.", step); // only issue the seal if we were the first to reach the compare_and_swap. - if self.can_propose.compare_and_swap(true, false, AtomicOrdering::SeqCst) { + if self.step.can_propose.compare_and_swap(true, false, AtomicOrdering::SeqCst) { self.clear_empty_steps(parent_step); @@ -999,7 +1011,7 @@ impl Engine for AuthorityRound { .decode()?; let parent_step = header_step(&parent, self.empty_steps_transition)?; - let current_step = self.step.load(); + let current_step = self.step.inner.load(); self.empty_steps(parent_step.into(), current_step.into(), parent.hash()) } else { // we're verifying a block, extract empty steps from the seal @@ -1052,7 +1064,7 @@ impl Engine for AuthorityRound { // If yes then probably benign reporting needs to be moved further in the verification. let set_number = header.number(); - match verify_timestamp(&*self.step, header_step(header, self.empty_steps_transition)?) { + match verify_timestamp(&self.step.inner, header_step(header, self.empty_steps_transition)?) { Err(BlockError::InvalidSeal) => { self.validators.report_benign(header.author(), set_number, header.number()); Err(BlockError::InvalidSeal.into()) @@ -1294,7 +1306,7 @@ impl Engine for AuthorityRound { // This way, upon encountering an epoch change, the proposer from the // new set will be forced to wait until the next step to avoid sealing a // block that breaks the invariant that the parent's step < the block's step. - self.can_propose.store(false, AtomicOrdering::SeqCst); + self.step.can_propose.store(false, AtomicOrdering::SeqCst); return Some(combine_proofs(signal_number, &pending.proof, &*finality_proof)); } } -- GitLab From 13bc922e546351e962c414b8adcf59eeb1041753 Mon Sep 17 00:00:00 2001 From: Jim Posen Date: Fri, 8 Jun 2018 07:31:48 -0700 Subject: [PATCH 115/152] devp2p: Move UDP socket handling from Discovery to Host. (#8790) * devp2p: Move UDP socket handling from Discovery to Host. * devp2p: Fix bug with potentially incorrect UDP registration. This works right now because the Host handler happens to be the first one registered on the IoService. * devp2p: Use 0-initialized memory buffer instead of unsafe. * Remove send_queue field from public interface of Discovery. * Rename Datagramm to Datagram. sed -i 's/Datagramm/Datagram/g' util/network-devp2p/src/discovery.rs util/network-devp2p/src/host.rs sed -i 's/datagramm/datagram/g' util/network-devp2p/src/discovery.rs util/network-devp2p/src/host.rs * Include target in log statements. --- util/network-devp2p/src/discovery.rs | 122 ++++++++------------------- util/network-devp2p/src/host.rs | 107 +++++++++++++++++++---- 2 files changed, 125 insertions(+), 104 deletions(-) diff --git a/util/network-devp2p/src/discovery.rs b/util/network-devp2p/src/discovery.rs index 8e8a3d6cc6..b7cce2832f 100644 --- a/util/network-devp2p/src/discovery.rs +++ b/util/network-devp2p/src/discovery.rs @@ -17,18 +17,13 @@ use ethcore_bytes::Bytes; use std::net::SocketAddr; use std::collections::{HashSet, HashMap, VecDeque}; -use std::mem; use std::default::Default; use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH}; -use mio::*; -use mio::deprecated::{Handler, EventLoop}; -use mio::udp::*; use hash::keccak; use ethereum_types::{H256, H520}; use rlp::{Rlp, RlpStream, encode_list}; use node_table::*; use network::{Error, ErrorKind}; -use io::{StreamToken, IoContext}; use ethkey::{Secret, KeyPair, sign, recover}; use network::IpFilter; @@ -39,7 +34,7 @@ const ADDRESS_BITS: usize = 8 * ADDRESS_BYTES_SIZE; // Denoted by n in [Kademl const DISCOVERY_MAX_STEPS: u16 = 8; // Max iterations of discovery. (discover) const BUCKET_SIZE: usize = 16; // Denoted by k in [Kademlia]. Number of nodes stored in each bucket. const ALPHA: usize = 3; // Denoted by \alpha in [Kademlia]. Number of concurrent FindNode requests. -const MAX_DATAGRAM_SIZE: usize = 1280; +pub const MAX_DATAGRAM_SIZE: usize = 1280; const PACKET_PING: u8 = 1; const PACKET_PONG: u8 = 2; @@ -79,9 +74,9 @@ impl NodeBucket { } } -struct Datagramm { - payload: Bytes, - address: SocketAddr, +pub struct Datagram { + pub payload: Bytes, + pub address: SocketAddr, } pub struct Discovery { @@ -89,13 +84,11 @@ pub struct Discovery { id_hash: H256, secret: Secret, public_endpoint: NodeEndpoint, - udp_socket: UdpSocket, - token: StreamToken, discovery_round: u16, discovery_id: NodeId, discovery_nodes: HashSet, node_buckets: Vec, - send_queue: VecDeque, + send_queue: VecDeque, check_timestamps: bool, adding_nodes: Vec, ip_filter: IpFilter, @@ -107,19 +100,16 @@ pub struct TableUpdates { } impl 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"); + pub fn new(key: &KeyPair, public: NodeEndpoint, ip_filter: IpFilter) -> Discovery { Discovery { id: key.public().clone(), id_hash: keccak(key.public()), secret: key.secret().clone(), public_endpoint: public, - token: token, discovery_round: 0, discovery_id: NodeId::new(), discovery_nodes: HashSet::new(), node_buckets: (0..ADDRESS_BITS).map(|_| NodeBucket::new()).collect(), - udp_socket: socket, send_queue: VecDeque::new(), check_timestamps: true, adding_nodes: Vec::new(), @@ -352,53 +342,12 @@ impl Discovery { ret } - pub fn writable(&mut self, io: &IoContext) where Message: Send + Sync + Clone { - while let Some(data) = self.send_queue.pop_front() { - match self.udp_socket.send_to(&data.payload, &data.address) { - Ok(Some(size)) if size == data.payload.len() => { - }, - Ok(Some(_)) => { - warn!("UDP sent incomplete datagramm"); - }, - Ok(None) => { - self.send_queue.push_front(data); - return; - } - Err(e) => { - debug!("UDP send error: {:?}, address: {:?}", e, &data.address); - return; - } - } - } - io.update_registration(self.token).unwrap_or_else(|e| debug!("Error updating discovery registration: {:?}", e)); - } - fn send_to(&mut self, payload: Bytes, address: SocketAddr) { - self.send_queue.push_back(Datagramm { payload: payload, address: address }); - } - - pub fn readable(&mut self, io: &IoContext) -> Option where Message: Send + Sync + Clone { - let mut buf: [u8; MAX_DATAGRAM_SIZE] = unsafe { mem::uninitialized() }; - let writable = !self.send_queue.is_empty(); - let res = match self.udp_socket.recv_from(&mut buf) { - Ok(Some((len, address))) => self.on_packet(&buf[0..len], address).unwrap_or_else(|e| { - debug!("Error processing UDP packet: {:?}", e); - None - }), - Ok(_) => None, - Err(e) => { - debug!("Error reading UPD socket: {:?}", e); - None - } - }; - let new_writable = !self.send_queue.is_empty(); - if writable != new_writable { - io.update_registration(self.token).unwrap_or_else(|e| debug!("Error updating discovery registration: {:?}", e)); - } - res + self.send_queue.push_back(Datagram { payload: payload, address: address }); } - fn on_packet(&mut self, packet: &[u8], from: SocketAddr) -> Result, Error> { + + pub fn on_packet(&mut self, packet: &[u8], from: SocketAddr) -> Result, Error> { // validate packet if packet.len() < 32 + 65 + 4 + 1 { return Err(ErrorKind::BadProtocol.into()); @@ -571,19 +520,16 @@ impl Discovery { self.start(); } - pub fn register_socket(&self, event_loop: &mut EventLoop) -> Result<(), Error> { - event_loop.register(&self.udp_socket, Token(self.token), Ready::all(), PollOpt::edge()).expect("Error registering UDP socket"); - Ok(()) + pub fn any_sends_queued(&self) -> bool { + !self.send_queue.is_empty() } - pub fn update_registration(&self, event_loop: &mut EventLoop) -> Result<(), Error> { - let registration = if !self.send_queue.is_empty() { - Ready::readable() | Ready::writable() - } else { - Ready::readable() - }; - event_loop.reregister(&self.udp_socket, Token(self.token), registration, PollOpt::edge()).expect("Error reregistering UDP socket"); - Ok(()) + pub fn dequeue_send(&mut self) -> Option { + self.send_queue.pop_front() + } + + pub fn requeue_send(&mut self, datagram: Datagram) { + self.send_queue.push_front(datagram) } } @@ -620,8 +566,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, IpFilter::default()); - let mut discovery2 = Discovery::new(&key2, ep2.address.clone(), ep2.clone(), 0, IpFilter::default()); + let mut discovery1 = Discovery::new(&key1, ep1.clone(), IpFilter::default()); + let mut discovery2 = Discovery::new(&key2, ep2.clone(), 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(); @@ -632,16 +578,14 @@ mod tests { discovery2.refresh(); for _ in 0 .. 10 { - while !discovery1.send_queue.is_empty() { - let datagramm = discovery1.send_queue.pop_front().unwrap(); - if datagramm.address == ep2.address { - discovery2.on_packet(&datagramm.payload, ep1.address.clone()).ok(); + while let Some(datagram) = discovery1.dequeue_send() { + if datagram.address == ep2.address { + discovery2.on_packet(&datagram.payload, ep1.address.clone()).ok(); } } - while !discovery2.send_queue.is_empty() { - let datagramm = discovery2.send_queue.pop_front().unwrap(); - if datagramm.address == ep1.address { - discovery1.on_packet(&datagramm.payload, ep2.address.clone()).ok(); + while let Some(datagram) = discovery2.dequeue_send() { + if datagram.address == ep1.address { + discovery1.on_packet(&datagram.payload, ep2.address.clone()).ok(); } } discovery2.round(); @@ -653,7 +597,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, IpFilter::default()); + let mut discovery = Discovery::new(&key, ep.clone(), IpFilter::default()); for _ in 0..1200 { discovery.add_node(NodeEntry { id: NodeId::random(), endpoint: ep.clone() }); } @@ -668,7 +612,7 @@ mod tests { 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, IpFilter::default()); + let mut discovery = Discovery::new(&key, ep.clone(), IpFilter::default()); for _ in 0..(16 + 10) { discovery.node_buckets[0].nodes.push_back(BucketEntry { @@ -728,7 +672,7 @@ mod tests { let key = Secret::from_str(secret_hex) .and_then(|secret| KeyPair::from_secret(secret)) .unwrap(); - let mut discovery = Discovery::new(&key, ep.address.clone(), ep.clone(), 0, IpFilter::default()); + let mut discovery = Discovery::new(&key, ep.clone(), IpFilter::default()); node_entries.iter().for_each(|entry| discovery.update_node(entry.clone())); @@ -773,7 +717,7 @@ mod tests { fn packets() { let key = Random.generate().unwrap(); let ep = NodeEndpoint { address: SocketAddr::from_str("127.0.0.1:40449").unwrap(), udp_port: 40449 }; - let mut discovery = Discovery::new(&key, ep.address.clone(), ep.clone(), 0, IpFilter::default()); + let mut discovery = Discovery::new(&key, ep.clone(), IpFilter::default()); discovery.check_timestamps = false; let from = SocketAddr::from_str("99.99.99.99:40445").unwrap(); @@ -840,13 +784,13 @@ mod tests { let key2 = Random.generate().unwrap(); let ep1 = NodeEndpoint { address: SocketAddr::from_str("127.0.0.1:40344").unwrap(), udp_port: 40344 }; let ep2 = NodeEndpoint { address: SocketAddr::from_str("127.0.0.1:40345").unwrap(), udp_port: 40345 }; - 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 mut discovery1 = Discovery::new(&key1, ep1.clone(), IpFilter::default()); + let mut discovery2 = Discovery::new(&key2, ep2.clone(), IpFilter::default()); discovery1.ping(&ep2); - let ping_data = discovery1.send_queue.pop_front().unwrap(); + let ping_data = discovery1.dequeue_send().unwrap(); discovery2.on_packet(&ping_data.payload, ep1.address.clone()).ok(); - let pong_data = discovery2.send_queue.pop_front().unwrap(); + let pong_data = discovery2.dequeue_send().unwrap(); let data = &pong_data.payload[(32 + 65)..]; let rlp = Rlp::new(&data[1..]); assert_eq!(ping_data.payload[0..32], rlp.val_at::>(1).unwrap()[..]) diff --git a/util/network-devp2p/src/host.rs b/util/network-devp2p/src/host.rs index 6d28a838c2..0fbd64b420 100644 --- a/util/network-devp2p/src/host.rs +++ b/util/network-devp2p/src/host.rs @@ -30,6 +30,7 @@ use hash::keccak; use mio::*; use mio::deprecated::{EventLoop}; use mio::tcp::*; +use mio::udp::*; use ethereum_types::H256; use rlp::{RlpStream, Encodable}; @@ -40,7 +41,7 @@ use node_table::*; use network::{NetworkConfiguration, NetworkIoMessage, ProtocolId, PeerId, PacketId}; use network::{NonReservedPeerMode, NetworkContext as NetworkContextTrait}; use network::{SessionInfo, Error, ErrorKind, DisconnectReason, NetworkProtocolHandler}; -use discovery::{Discovery, TableUpdates, NodeEntry}; +use discovery::{Discovery, TableUpdates, NodeEntry, MAX_DATAGRAM_SIZE}; use ip_utils::{map_external_address, select_public_address}; use path::restrict_permissions_owner; use parking_lot::{Mutex, RwLock}; @@ -239,6 +240,7 @@ struct ProtocolTimer { /// Root IO handler. Manages protocol handlers, IO timers and network connections. pub struct Host { pub info: RwLock, + udp_socket: Mutex>, tcp_listener: Mutex, sessions: Arc>>, discovery: Mutex>, @@ -295,6 +297,7 @@ impl Host { local_endpoint: local_endpoint, }), discovery: Mutex::new(None), + udp_socket: Mutex::new(None), tcp_listener: Mutex::new(tcp_listener), sessions: Arc::new(RwLock::new(Slab::new_starting_at(FIRST_SESSION, MAX_SESSIONS))), nodes: RwLock::new(NodeTable::new(path)), @@ -458,13 +461,16 @@ impl Host { let discovery = { let info = self.info.read(); if info.config.discovery_enabled && info.config.non_reserved_mode == NonReservedPeerMode::Accept { - let mut udp_addr = local_endpoint.address.clone(); - udp_addr.set_port(local_endpoint.udp_port); - Some(Discovery::new(&info.keys, udp_addr, public_endpoint, DISCOVERY, allow_ips)) + Some(Discovery::new(&info.keys, public_endpoint, allow_ips)) } else { None } }; if let Some(mut discovery) = discovery { + let mut udp_addr = local_endpoint.address; + udp_addr.set_port(local_endpoint.udp_port); + let socket = UdpSocket::bind(&udp_addr).expect("Error binding UDP socket"); + *self.udp_socket.lock() = Some(socket); + discovery.init_node_list(self.nodes.read().entries()); discovery.add_node_list(self.nodes.read().entries()); *self.discovery.lock() = Some(discovery); @@ -819,6 +825,67 @@ impl Host { } } + fn discovery_readable(&self, io: &IoContext) { + let node_changes = match (self.udp_socket.lock().as_ref(), self.discovery.lock().as_mut()) { + (Some(udp_socket), Some(discovery)) => { + let mut buf = [0u8; MAX_DATAGRAM_SIZE]; + let writable = discovery.any_sends_queued(); + let res = match udp_socket.recv_from(&mut buf) { + Ok(Some((len, address))) => discovery.on_packet(&buf[0..len], address).unwrap_or_else(|e| { + debug!(target: "network", "Error processing UDP packet: {:?}", e); + None + }), + Ok(_) => None, + Err(e) => { + debug!(target: "network", "Error reading UPD socket: {:?}", e); + None + } + }; + let new_writable = discovery.any_sends_queued(); + if writable != new_writable { + io.update_registration(DISCOVERY) + .unwrap_or_else(|e| { + debug!(target: "network" ,"Error updating discovery registration: {:?}", e) + }); + } + res + }, + _ => None, + }; + if let Some(node_changes) = node_changes { + self.update_nodes(io, node_changes); + } + } + + fn discovery_writable(&self, io: &IoContext) { + match (self.udp_socket.lock().as_ref(), self.discovery.lock().as_mut()) { + (Some(udp_socket), Some(discovery)) => { + while let Some(data) = discovery.dequeue_send() { + match udp_socket.send_to(&data.payload, &data.address) { + Ok(Some(size)) if size == data.payload.len() => { + }, + Ok(Some(_)) => { + warn!(target: "network", "UDP sent incomplete datagram"); + }, + Ok(None) => { + discovery.requeue_send(data); + return; + } + Err(e) => { + debug!(target: "network", "UDP send error: {:?}, address: {:?}", e, &data.address); + return; + } + } + } + io.update_registration(DISCOVERY) + .unwrap_or_else(|e| { + debug!(target: "network", "Error updating discovery registration: {:?}", e) + }); + }, + _ => (), + } + } + fn connection_timeout(&self, token: StreamToken, io: &IoContext) { trace!(target: "network", "Connection timeout: {}", token); self.kill_connection(token, io, true) @@ -920,12 +987,7 @@ impl IoHandler for Host { } match stream { FIRST_SESSION ... LAST_SESSION => self.session_readable(stream, io), - DISCOVERY => { - let node_changes = { self.discovery.lock().as_mut().map_or(None, |d| d.readable(io)) }; - if let Some(node_changes) = node_changes { - self.update_nodes(io, node_changes); - } - }, + DISCOVERY => self.discovery_readable(io), TCP_ACCEPT => self.accept(io), _ => panic!("Received unknown readable token"), } @@ -937,9 +999,7 @@ impl IoHandler for Host { } match stream { FIRST_SESSION ... LAST_SESSION => self.session_writable(stream, io), - DISCOVERY => { - self.discovery.lock().as_mut().map(|d| d.writable(io)); - } + DISCOVERY => self.discovery_writable(io), _ => panic!("Received unknown writable token"), } } @@ -1055,7 +1115,13 @@ impl IoHandler for Host { session.lock().register_socket(reg, event_loop).expect("Error registering socket"); } } - DISCOVERY => self.discovery.lock().as_ref().and_then(|d| d.register_socket(event_loop).ok()).expect("Error registering discovery socket"), + DISCOVERY => match self.udp_socket.lock().as_ref() { + Some(udp_socket) => { + event_loop.register(udp_socket, reg, Ready::all(), PollOpt::edge()) + .expect("Error registering UDP socket"); + }, + _ => panic!("Error registering discovery socket"), + } TCP_ACCEPT => event_loop.register(&*self.tcp_listener.lock(), Token(TCP_ACCEPT), Ready::all(), PollOpt::edge()).expect("Error registering stream"), _ => warn!("Unexpected stream registration") } @@ -1086,7 +1152,18 @@ impl IoHandler for Host { connection.lock().update_socket(reg, event_loop).expect("Error updating socket"); } } - DISCOVERY => self.discovery.lock().as_ref().and_then(|d| d.update_registration(event_loop).ok()).expect("Error reregistering discovery socket"), + DISCOVERY => match (self.udp_socket.lock().as_ref(), self.discovery.lock().as_ref()) { + (Some(udp_socket), Some(discovery)) => { + let registration = if discovery.any_sends_queued() { + Ready::readable() | Ready::writable() + } else { + Ready::readable() + }; + event_loop.reregister(udp_socket, reg, registration, PollOpt::edge()) + .expect("Error reregistering UDP socket"); + }, + _ => panic!("Error reregistering discovery socket"), + } TCP_ACCEPT => event_loop.reregister(&*self.tcp_listener.lock(), Token(TCP_ACCEPT), Ready::all(), PollOpt::edge()).expect("Error reregistering stream"), _ => warn!("Unexpected stream update") } -- GitLab From af1088ef61323f171915555023d8e993aaaed755 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Fri, 8 Jun 2018 17:05:46 +0200 Subject: [PATCH 116/152] Disable parallel verification and skip verifiying already imported txs. (#8834) * Reject transactions that are already in pool without verifying them. * Avoid verifying already imported transactions. --- Cargo.lock | 1 - miner/Cargo.toml | 1 - miner/src/lib.rs | 1 - miner/src/pool/queue.rs | 11 ++++++++--- miner/src/pool/tests/client.rs | 9 +++++++++ miner/src/pool/tests/mod.rs | 34 ++++++++++++++++++++++++++++++++++ miner/src/pool/verifier.rs | 4 +++- 7 files changed, 54 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a22012300b..9334d01028 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -691,7 +691,6 @@ dependencies = [ "parity-reactor 0.1.0", "parking_lot 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "price-info 1.12.0", - "rayon 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "rlp 0.2.1", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "trace-time 0.1.0", diff --git a/miner/Cargo.toml b/miner/Cargo.toml index 707352484e..e692d2f708 100644 --- a/miner/Cargo.toml +++ b/miner/Cargo.toml @@ -27,7 +27,6 @@ linked-hash-map = "0.5" log = "0.3" parking_lot = "0.5" price-info = { path = "../price-info" } -rayon = "1.0" rlp = { path = "../util/rlp" } trace-time = { path = "../util/trace-time" } transaction-pool = { path = "../transaction-pool" } diff --git a/miner/src/lib.rs b/miner/src/lib.rs index 107b9b22b5..9dc180fefe 100644 --- a/miner/src/lib.rs +++ b/miner/src/lib.rs @@ -29,7 +29,6 @@ extern crate keccak_hash as hash; extern crate linked_hash_map; extern crate parking_lot; extern crate price_info; -extern crate rayon; extern crate rlp; extern crate trace_time; extern crate transaction_pool as txpool; diff --git a/miner/src/pool/queue.rs b/miner/src/pool/queue.rs index 4ebdf9e3f1..cf4a956f42 100644 --- a/miner/src/pool/queue.rs +++ b/miner/src/pool/queue.rs @@ -23,7 +23,6 @@ use std::collections::BTreeMap; use ethereum_types::{H256, U256, Address}; use parking_lot::RwLock; -use rayon::prelude::*; use transaction; use txpool::{self, Verifier}; @@ -179,8 +178,14 @@ impl TransactionQueue { let verifier = verifier::Verifier::new(client, options, self.insertion_id.clone()); let results = transactions - .into_par_iter() - .map(|transaction| verifier.verify_transaction(transaction)) + .into_iter() + .map(|transaction| { + if self.pool.read().find(&transaction.hash()).is_some() { + bail!(transaction::Error::AlreadyImported) + } + + verifier.verify_transaction(transaction) + }) .map(|result| result.and_then(|verified| { self.pool.write().import(verified) .map(|_imported| ()) diff --git a/miner/src/pool/tests/client.rs b/miner/src/pool/tests/client.rs index 101b6cdc21..08b43f12ad 100644 --- a/miner/src/pool/tests/client.rs +++ b/miner/src/pool/tests/client.rs @@ -14,6 +14,8 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . +use std::sync::{atomic, Arc}; + use ethereum_types::{U256, H256, Address}; use rlp::Rlp; use transaction::{self, Transaction, SignedTransaction, UnverifiedTransaction}; @@ -25,6 +27,7 @@ const MAX_TRANSACTION_SIZE: usize = 15 * 1024; #[derive(Debug, Clone)] pub struct TestClient { + verification_invoked: Arc, account_details: AccountDetails, gas_required: U256, is_service_transaction: bool, @@ -35,6 +38,7 @@ pub struct TestClient { impl Default for TestClient { fn default() -> Self { TestClient { + verification_invoked: Default::default(), account_details: AccountDetails { nonce: 123.into(), balance: 63_100.into(), @@ -88,6 +92,10 @@ impl TestClient { insertion_id: 1, } } + + pub fn was_verification_triggered(&self) -> bool { + self.verification_invoked.load(atomic::Ordering::SeqCst) + } } impl pool::client::Client for TestClient { @@ -98,6 +106,7 @@ impl pool::client::Client for TestClient { fn verify_transaction(&self, tx: UnverifiedTransaction) -> Result { + self.verification_invoked.store(true, atomic::Ordering::SeqCst); Ok(SignedTransaction::new(tx)?) } diff --git a/miner/src/pool/tests/mod.rs b/miner/src/pool/tests/mod.rs index 552903a4bb..ac2e6b008e 100644 --- a/miner/src/pool/tests/mod.rs +++ b/miner/src/pool/tests/mod.rs @@ -796,3 +796,37 @@ fn should_include_local_transaction_to_a_full_pool() { // then assert_eq!(txq.status().status.transaction_count, 1); } + +#[test] +fn should_avoid_verifying_transaction_already_in_pool() { + // given + let txq = TransactionQueue::new( + txpool::Options { + max_count: 1, + max_per_sender: 2, + max_mem_usage: 50 + }, + verifier::Options { + minimal_gas_price: 1.into(), + block_gas_limit: 1_000_000.into(), + tx_gas_limit: 1_000_000.into(), + }, + PrioritizationStrategy::GasPriceOnly, + ); + let client = TestClient::new(); + let tx1 = Tx::default().signed().unverified(); + + let res = txq.import(client.clone(), vec![tx1.clone()]); + assert_eq!(res, vec![Ok(())]); + assert_eq!(txq.status().status.transaction_count, 1); + assert!(client.was_verification_triggered()); + + // when + let client = TestClient::new(); + let res = txq.import(client.clone(), vec![tx1]); + assert_eq!(res, vec![Err(transaction::Error::AlreadyImported)]); + assert!(!client.was_verification_triggered()); + + // then + assert_eq!(txq.status().status.transaction_count, 1); +} diff --git a/miner/src/pool/verifier.rs b/miner/src/pool/verifier.rs index 4675303928..5e6e22077a 100644 --- a/miner/src/pool/verifier.rs +++ b/miner/src/pool/verifier.rs @@ -57,6 +57,7 @@ impl Default for Options { } /// Transaction to verify. +#[cfg_attr(test, derive(Clone))] pub enum Transaction { /// Fresh, never verified transaction. /// @@ -75,7 +76,8 @@ pub enum Transaction { } impl Transaction { - fn hash(&self) -> H256 { + /// Return transaction hash + pub fn hash(&self) -> H256 { match *self { Transaction::Unverified(ref tx) => tx.hash(), Transaction::Retracted(ref tx) => tx.hash(), -- GitLab From 986f485b3e66ec4724c0d026a19894cbc91ef9a3 Mon Sep 17 00:00:00 2001 From: Elichai Turkel Date: Mon, 11 Jun 2018 11:02:46 +0300 Subject: [PATCH 117/152] Clearing up a comment about the prefix for signing (#8828) --- rpc/src/v1/helpers/dispatch.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpc/src/v1/helpers/dispatch.rs b/rpc/src/v1/helpers/dispatch.rs index 9bec8e1d31..dbfdd51bc5 100644 --- a/rpc/src/v1/helpers/dispatch.rs +++ b/rpc/src/v1/helpers/dispatch.rs @@ -237,7 +237,7 @@ pub fn fetch_gas_price_corpus( /// Returns a eth_sign-compatible hash of data to sign. /// The data is prepended with special message to prevent -/// chosen-plaintext attacks. +/// malicious DApps from using the function to sign forged transactions. pub fn eth_data_hash(mut data: Bytes) -> H256 { let mut message_data = format!("\x19Ethereum Signed Message:\n{}", data.len()) -- GitLab From 10fc74eb8119330ff3a065e0d3e5400e9de18240 Mon Sep 17 00:00:00 2001 From: Afri Schoedon <5chdn@users.noreply.github.com> Date: Mon, 11 Jun 2018 10:03:16 +0200 Subject: [PATCH 118/152] network-devp2p: downgrade logging to debug, add target (#8784) * network-devp2p: downgrade logging to debug, add target * network-devp2p: rename s/datagramm/datagram --- util/network-devp2p/src/discovery.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/util/network-devp2p/src/discovery.rs b/util/network-devp2p/src/discovery.rs index b7cce2832f..5f8f0cdbc2 100644 --- a/util/network-devp2p/src/discovery.rs +++ b/util/network-devp2p/src/discovery.rs @@ -147,7 +147,7 @@ impl Discovery { let dist = match Discovery::distance(&self.id_hash, &id_hash) { Some(dist) => dist, None => { - warn!(target: "discovery", "Attempted to update own entry: {:?}", e); + debug!(target: "discovery", "Attempted to update own entry: {:?}", e); return; } }; @@ -181,7 +181,7 @@ impl Discovery { let dist = match Discovery::distance(&self.id_hash, &keccak(id)) { Some(dist) => dist, None => { - warn!(target: "discovery", "Received ping from self"); + debug!(target: "discovery", "Received ping from self"); return } }; @@ -370,7 +370,7 @@ impl Discovery { PACKET_FIND_NODE => self.on_find_node(&rlp, &node_id, &from), PACKET_NEIGHBOURS => self.on_neighbours(&rlp, &node_id, &from), _ => { - debug!("Unknown UDP packet: {}", packet_id); + debug!(target: "discovery", "Unknown UDP packet: {}", packet_id); Ok(None) } } -- GitLab From 09ee6e147750f4ea22be7e87157598539f5032b7 Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Mon, 11 Jun 2018 18:26:49 +0800 Subject: [PATCH 119/152] Fix subcrate test compile (#8862) * Fix test compile for light, node_filter, service in ethcore * Fix ipfs, local-store, rpc, secret_store, updater subcrate test compile --- ethcore/light/Cargo.toml | 1 + ethcore/node_filter/Cargo.toml | 1 + ethcore/service/Cargo.toml | 1 + ipfs/Cargo.toml | 3 +++ local-store/Cargo.toml | 1 + rpc/Cargo.toml | 1 + secret_store/Cargo.toml | 1 + updater/Cargo.toml | 1 + 8 files changed, 10 insertions(+) diff --git a/ethcore/light/Cargo.toml b/ethcore/light/Cargo.toml index 3853ad910f..ab347c62e8 100644 --- a/ethcore/light/Cargo.toml +++ b/ethcore/light/Cargo.toml @@ -38,6 +38,7 @@ memory-cache = { path = "../../util/memory_cache" } error-chain = { version = "0.11", default-features = false } [dev-dependencies] +ethcore = { path = "..", features = ["test-helpers"] } kvdb-memorydb = { path = "../../util/kvdb-memorydb" } tempdir = "0.3" diff --git a/ethcore/node_filter/Cargo.toml b/ethcore/node_filter/Cargo.toml index 0d204e29ff..11be807652 100644 --- a/ethcore/node_filter/Cargo.toml +++ b/ethcore/node_filter/Cargo.toml @@ -19,6 +19,7 @@ ethabi-contract = "5.0" lru-cache = "0.1" [dev-dependencies] +ethcore = { path = "..", features = ["test-helpers"] } kvdb-memorydb = { path = "../../util/kvdb-memorydb" } ethcore-io = { path = "../../util/io" } tempdir = "0.3" diff --git a/ethcore/service/Cargo.toml b/ethcore/service/Cargo.toml index 3a10849b61..634ee55dba 100644 --- a/ethcore/service/Cargo.toml +++ b/ethcore/service/Cargo.toml @@ -16,5 +16,6 @@ stop-guard = { path = "../../util/stop-guard" } trace-time = { path = "../../util/trace-time" } [dev-dependencies] +ethcore = { path = "..", features = ["test-helpers"] } tempdir = "0.3" kvdb-rocksdb = { path = "../../util/kvdb-rocksdb" } diff --git a/ipfs/Cargo.toml b/ipfs/Cargo.toml index 9c7b5f3b00..5a72048134 100644 --- a/ipfs/Cargo.toml +++ b/ipfs/Cargo.toml @@ -15,3 +15,6 @@ rlp = { path = "../util/rlp" } cid = "0.2" multihash = "0.7" unicase = "2.0" + +[dev-dependencies] +ethcore = { path = "../ethcore", features = ["test-helpers"] } diff --git a/local-store/Cargo.toml b/local-store/Cargo.toml index 6d09eb76f6..d2c3469ca4 100644 --- a/local-store/Cargo.toml +++ b/local-store/Cargo.toml @@ -16,5 +16,6 @@ serde_derive = "1.0" serde_json = "1.0" [dev-dependencies] +ethcore = { path = "../ethcore", features = ["test-helpers"] } ethkey = { path = "../ethkey" } kvdb-memorydb = { path = "../util/kvdb-memorydb" } diff --git a/rpc/Cargo.toml b/rpc/Cargo.toml index 8a0b689c65..338a892682 100644 --- a/rpc/Cargo.toml +++ b/rpc/Cargo.toml @@ -65,6 +65,7 @@ stats = { path = "../util/stats" } vm = { path = "../ethcore/vm" } [dev-dependencies] +ethcore = { path = "../ethcore", features = ["test-helpers"] } ethcore-network = { path = "../util/network" } fake-fetch = { path = "../util/fake-fetch" } kvdb-memorydb = { path = "../util/kvdb-memorydb" } diff --git a/secret_store/Cargo.toml b/secret_store/Cargo.toml index 261658903c..a8aed83127 100644 --- a/secret_store/Cargo.toml +++ b/secret_store/Cargo.toml @@ -39,5 +39,6 @@ ethabi-derive = "5.0" ethabi-contract = "5.0" [dev-dependencies] +ethcore = { path = "../ethcore", features = ["test-helpers"] } tempdir = "0.3" kvdb-rocksdb = { path = "../util/kvdb-rocksdb" } diff --git a/updater/Cargo.toml b/updater/Cargo.toml index d76db6ec0e..8d94680335 100644 --- a/updater/Cargo.toml +++ b/updater/Cargo.toml @@ -25,5 +25,6 @@ path = { path = "../util/path" } rand = "0.4" [dev-dependencies] +ethcore = { path = "../ethcore", features = ["test-helpers"] } tempdir = "0.3" matches = "0.1" -- GitLab From 861d829420ff28e387642659ffe256955352d939 Mon Sep 17 00:00:00 2001 From: Benjamin Kampmann Date: Mon, 11 Jun 2018 20:38:01 +0200 Subject: [PATCH 120/152] Fix Cli Return Code on --help for ethkey, ethstore & whisper (#8863) Docopt handles `--help` automatically for us, however we've handled those Errors the same as all others: by exiting with Return Code `1`, which is wrong for a totally appropriate a quit on `--help`. Fortunately `docopt:Error` provides an `exit` helper function that discriminates properly between fatal and non-fatal errors and exist appropriately. This patch makes sure we use that handy function in case we encounter such an error in the CLI of ethkey, ethstore and whisper. Thus those are now giving the appropriate Return code on `--help`. fixes #8851 --- ethkey/cli/src/main.rs | 3 ++- ethstore/cli/src/main.rs | 1 + whisper/cli/src/main.rs | 5 +++-- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/ethkey/cli/src/main.rs b/ethkey/cli/src/main.rs index c8f5e2e64e..af50f86b31 100644 --- a/ethkey/cli/src/main.rs +++ b/ethkey/cli/src/main.rs @@ -166,10 +166,11 @@ fn main() { match execute(env::args()) { Ok(ok) => println!("{}", ok), + Err(Error::Docopt(ref e)) => e.exit(), Err(err) => { println!("{}", err); process::exit(1); - }, + } } } diff --git a/ethstore/cli/src/main.rs b/ethstore/cli/src/main.rs index 416b64d43e..922d857149 100644 --- a/ethstore/cli/src/main.rs +++ b/ethstore/cli/src/main.rs @@ -149,6 +149,7 @@ fn main() { match execute(env::args()) { Ok(result) => println!("{}", result), + Err(Error::Docopt(ref e)) => e.exit(), Err(err) => { println!("{}", err); process::exit(1); diff --git a/whisper/cli/src/main.rs b/whisper/cli/src/main.rs index 6f3aec8594..1d57691418 100644 --- a/whisper/cli/src/main.rs +++ b/whisper/cli/src/main.rs @@ -190,11 +190,12 @@ fn main() { Ok(_) => { println!("whisper-cli terminated"); process::exit(1); - } + }, + Err(Error::Docopt(ref e)) => e.exit(), Err(err) => { println!("{}", err); process::exit(1); - }, + } } } -- GitLab From 2a470deeafa194dbb53d277d7839cd8c78deed28 Mon Sep 17 00:00:00 2001 From: Andronik Ordian Date: Tue, 12 Jun 2018 09:15:52 +0300 Subject: [PATCH 121/152] Don't allocate in expect_valid_rlp unless necessary (#8867) * don't allocate via format! in case there's no error * fix test? --- ethcore/src/views/view_rlp.rs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/ethcore/src/views/view_rlp.rs b/ethcore/src/views/view_rlp.rs index 2ecc4dbdd3..2dd1b33a94 100644 --- a/ethcore/src/views/view_rlp.rs +++ b/ethcore/src/views/view_rlp.rs @@ -39,10 +39,10 @@ impl<'a, 'view> ViewRlp<'a> where 'a : 'view { /// Returns a new instance replacing existing rlp with new rlp, maintaining debug info fn new_from_rlp(&self, rlp: Rlp<'a>) -> Self { - ViewRlp { - rlp, + ViewRlp { + rlp, file: self.file, - line: self.line + line: self.line } } @@ -53,7 +53,12 @@ impl<'a, 'view> ViewRlp<'a> where 'a : 'view { } fn expect_valid_rlp(&self, r: Result) -> T { - r.expect(&format!("View rlp is trusted and should be valid. Constructed in {} on line {}", self.file, self.line)) + r.unwrap_or_else(|e| panic!( + "View rlp is trusted and should be valid. Constructed in {} on line {}: {}", + self.file, + self.line, + e + )) } /// Returns rlp at the given index, panics if no rlp at that index @@ -75,7 +80,7 @@ impl<'a, 'view> ViewRlp<'a> where 'a : 'view { /// Returns decoded value at the given index, panics not present or valid at that index pub fn val_at(&self, index: usize) -> T where T : Decodable { self.expect_valid_rlp(self.rlp.val_at(index)) - } + } /// Returns decoded list of values, panics if rlp is invalid pub fn list_at(&self, index: usize) -> Vec where T: Decodable { -- GitLab From 4817b94d0bb23356a5ee9b659ab8f4c4cbbd660d Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Tue, 12 Jun 2018 14:21:55 +0800 Subject: [PATCH 122/152] Use sealing.enabled to emit eth_mining information (#8844) * Use sealing.enabled to emit eth_mining information * Be more accurate on last_requests by using Option * Add tests for internal sealing * Add test for pow non-mining * Add test for mining pow --- ethcore/src/miner/miner.rs | 71 +++++++++++++++++++++++++++++++++----- 1 file changed, 62 insertions(+), 9 deletions(-) diff --git a/ethcore/src/miner/miner.rs b/ethcore/src/miner/miner.rs index bf51d0b135..e91e03e8bc 100644 --- a/ethcore/src/miner/miner.rs +++ b/ethcore/src/miner/miner.rs @@ -180,7 +180,7 @@ struct SealingWork { next_allowed_reseal: Instant, next_mandatory_reseal: Instant, // block number when sealing work was last requested - last_request: u64, + last_request: Option, } impl SealingWork { @@ -231,7 +231,7 @@ impl Miner { || spec.engine.seals_internally().is_some(), next_allowed_reseal: Instant::now(), next_mandatory_reseal: Instant::now() + options.reseal_max_period, - last_request: 0, + last_request: None, }), params: RwLock::new(AuthoringParams::default()), listeners: RwLock::new(vec![]), @@ -496,8 +496,10 @@ impl Miner { trace!(target: "miner", "requires_reseal: sealing enabled"); // Disable sealing if there were no requests for SEALING_TIMEOUT_IN_BLOCKS - let had_requests = best_block > sealing.last_request - && best_block - sealing.last_request <= SEALING_TIMEOUT_IN_BLOCKS; + let had_requests = sealing.last_request.map(|last_request| { + best_block > last_request + && best_block - last_request <= SEALING_TIMEOUT_IN_BLOCKS + }).unwrap_or(false); // keep sealing enabled if any of the conditions is met let sealing_enabled = self.forced_sealing() @@ -516,7 +518,7 @@ impl Miner { ); if should_disable_sealing { - trace!(target: "miner", "Miner sleeping (current {}, last {})", best_block, sealing.last_request); + trace!(target: "miner", "Miner sleeping (current {}, last {})", best_block, sealing.last_request.unwrap_or(0)); sealing.enabled = false; sealing.queue.reset(); false @@ -676,13 +678,13 @@ impl Miner { let best_number = client.chain_info().best_block_number; let mut sealing = self.sealing.lock(); - if sealing.last_request != best_number { + if sealing.last_request != Some(best_number) { trace!( target: "miner", "prepare_pending_block: Miner received request (was {}, now {}) - waking up.", - sealing.last_request, best_number + sealing.last_request.unwrap_or(0), best_number ); - sealing.last_request = best_number; + sealing.last_request = Some(best_number); } // Return if we restarted @@ -954,7 +956,7 @@ impl miner::MinerService for Miner { } fn is_currently_sealing(&self) -> bool { - self.sealing.lock().queue.is_in_use() + self.sealing.lock().enabled } fn work_package(&self, chain: &C) -> Option<(H256, BlockNumber, u64, U256)> where @@ -1266,4 +1268,55 @@ mod tests { let client = generate_dummy_client_with_spec_and_accounts(spec, None); assert!(match client.miner().set_author(addr, Some("".into())) { Err(AccountError::NotFound) => true, _ => false }); } + + #[test] + fn should_mine_if_internal_sealing_is_enabled() { + let spec = Spec::new_instant(); + let miner = Miner::new_for_tests(&spec, None); + + let client = generate_dummy_client(2); + miner.update_sealing(&*client); + + assert!(miner.is_currently_sealing()); + } + + #[test] + fn should_not_mine_if_internal_sealing_is_disabled() { + let spec = Spec::new_test_round(); + let miner = Miner::new_for_tests(&spec, None); + + let client = generate_dummy_client(2); + miner.update_sealing(&*client); + + assert!(!miner.is_currently_sealing()); + } + + #[test] + fn should_not_mine_if_no_fetch_work_request() { + let spec = Spec::new_test(); + let miner = Miner::new_for_tests(&spec, None); + + let client = generate_dummy_client(2); + miner.update_sealing(&*client); + + assert!(!miner.is_currently_sealing()); + } + + #[test] + fn should_mine_if_fetch_work_request() { + struct DummyNotifyWork; + + impl NotifyWork for DummyNotifyWork { + fn notify(&self, _pow_hash: H256, _difficulty: U256, _number: u64) { } + } + + let spec = Spec::new_test(); + let miner = Miner::new_for_tests(&spec, None); + miner.add_work_listener(Box::new(DummyNotifyWork)); + + let client = generate_dummy_client(2); + miner.update_sealing(&*client); + + assert!(miner.is_currently_sealing()); + } } -- GitLab From 4938d5dde5c83403e6cffc7301ebd35cbdcf04a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Tue, 12 Jun 2018 08:22:54 +0200 Subject: [PATCH 123/152] Limit the number of transactions in pending set (#8777) * Unordered iterator. * Use unordered and limited set if full not required. * Split timeout work into smaller timers. * Avoid collecting all pending transactions when mining * Remove println. * Use priority ordering in eth-filter. * Fix ethcore-miner tests and tx propagation. * Review grumbles addressed. * Add test for unordered not populating the cache. * Fix ethcore tests. * Fix light tests. * Fix ethcore-sync tests. * Fix RPC tests. --- Cargo.lock | 6 +- ethcore/light/src/net/mod.rs | 5 +- ethcore/light/src/net/tests/mod.rs | 4 +- ethcore/light/src/provider.rs | 13 ++- ethcore/src/client/client.rs | 4 +- ethcore/src/client/test_client.rs | 6 +- ethcore/src/client/traits.rs | 2 +- ethcore/src/miner/miner.rs | 51 ++++++--- ethcore/src/miner/mod.rs | 7 +- ethcore/src/tests/client.rs | 10 +- ethcore/sync/src/api.rs | 21 +++- ethcore/sync/src/chain/mod.rs | 10 +- ethcore/sync/src/chain/propagator.rs | 3 +- miner/src/lib.rs | 3 +- miner/src/pool/mod.rs | 39 ++++++- miner/src/pool/queue.rs | 71 ++++++++++--- miner/src/pool/tests/mod.rs | 124 ++++++++++++++++------ parity/rpc_apis.rs | 4 +- rpc/Cargo.toml | 2 +- rpc/src/v1/impls/eth_filter.rs | 2 +- rpc/src/v1/impls/eth_pubsub.rs | 2 +- rpc/src/v1/impls/light/parity.rs | 3 +- rpc/src/v1/impls/parity.rs | 10 +- rpc/src/v1/tests/helpers/miner_service.rs | 4 +- rpc/src/v1/tests/mocked/eth_pubsub.rs | 2 +- rpc/src/v1/traits/parity.rs | 2 +- transaction-pool/Cargo.toml | 2 +- transaction-pool/src/pool.rs | 58 +++++++++- transaction-pool/src/tests/mod.rs | 60 +++++++++++ 29 files changed, 415 insertions(+), 115 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9334d01028..60565f1758 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -694,7 +694,7 @@ dependencies = [ "rlp 0.2.1", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "trace-time 0.1.0", - "transaction-pool 1.12.0", + "transaction-pool 1.12.1", "url 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2241,7 +2241,7 @@ dependencies = [ "tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-timer 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "transaction-pool 1.12.0", + "transaction-pool 1.12.1", "transient-hashmap 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "vm 0.1.0", ] @@ -3422,7 +3422,7 @@ dependencies = [ [[package]] name = "transaction-pool" -version = "1.12.0" +version = "1.12.1" dependencies = [ "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/ethcore/light/src/net/mod.rs b/ethcore/light/src/net/mod.rs index 39f53445ad..179f709003 100644 --- a/ethcore/light/src/net/mod.rs +++ b/ethcore/light/src/net/mod.rs @@ -72,6 +72,9 @@ const PROPAGATE_TIMEOUT_INTERVAL: Duration = Duration::from_secs(5); const RECALCULATE_COSTS_TIMEOUT: TimerToken = 3; const RECALCULATE_COSTS_INTERVAL: Duration = Duration::from_secs(60 * 60); +/// Max number of transactions in a single packet. +const MAX_TRANSACTIONS_TO_PROPAGATE: usize = 64; + // minimum interval between updates. const UPDATE_INTERVAL: Duration = Duration::from_millis(5000); @@ -647,7 +650,7 @@ impl LightProtocol { fn propagate_transactions(&self, io: &IoContext) { if self.capabilities.read().tx_relay { return } - let ready_transactions = self.provider.ready_transactions(); + let ready_transactions = self.provider.ready_transactions(MAX_TRANSACTIONS_TO_PROPAGATE); if ready_transactions.is_empty() { return } trace!(target: "pip", "propagate transactions: {} ready", ready_transactions.len()); diff --git a/ethcore/light/src/net/tests/mod.rs b/ethcore/light/src/net/tests/mod.rs index 305ef9b354..e182f38b8a 100644 --- a/ethcore/light/src/net/tests/mod.rs +++ b/ethcore/light/src/net/tests/mod.rs @@ -173,8 +173,8 @@ impl Provider for TestProvider { }) } - fn ready_transactions(&self) -> Vec { - self.0.client.ready_transactions() + fn ready_transactions(&self, max_len: usize) -> Vec { + self.0.client.ready_transactions(max_len) } } diff --git a/ethcore/light/src/provider.rs b/ethcore/light/src/provider.rs index 0e518ea772..e75915e8cf 100644 --- a/ethcore/light/src/provider.rs +++ b/ethcore/light/src/provider.rs @@ -125,7 +125,7 @@ pub trait Provider: Send + Sync { fn header_proof(&self, req: request::CompleteHeaderProofRequest) -> Option; /// Provide pending transactions. - fn ready_transactions(&self) -> Vec; + fn ready_transactions(&self, max_len: usize) -> Vec; /// Provide a proof-of-execution for the given transaction proof request. /// Returns a vector of all state items necessary to execute the transaction. @@ -280,8 +280,8 @@ impl Provider for T { .map(|(_, proof)| ::request::ExecutionResponse { items: proof }) } - fn ready_transactions(&self) -> Vec { - BlockChainClient::ready_transactions(self) + fn ready_transactions(&self, max_len: usize) -> Vec { + BlockChainClient::ready_transactions(self, max_len) .into_iter() .map(|tx| tx.pending().clone()) .collect() @@ -367,9 +367,12 @@ impl Provider for LightProvider { None } - fn ready_transactions(&self) -> Vec { + fn ready_transactions(&self, max_len: usize) -> Vec { let chain_info = self.chain_info(); - self.txqueue.read().ready_transactions(chain_info.best_block_number, chain_info.best_block_timestamp) + let mut transactions = self.txqueue.read() + .ready_transactions(chain_info.best_block_number, chain_info.best_block_timestamp); + transactions.truncate(max_len); + transactions } } diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index 2d0201067f..d47d1afa49 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -1956,8 +1956,8 @@ impl BlockChainClient for Client { (*self.build_last_hashes(&self.chain.read().best_block_hash())).clone() } - fn ready_transactions(&self) -> Vec> { - self.importer.miner.ready_transactions(self) + fn ready_transactions(&self, max_len: usize) -> Vec> { + self.importer.miner.ready_transactions(self, max_len, ::miner::PendingOrdering::Priority) } fn signing_chain_id(&self) -> Option { diff --git a/ethcore/src/client/test_client.rs b/ethcore/src/client/test_client.rs index 4bd76b4495..620f1af333 100644 --- a/ethcore/src/client/test_client.rs +++ b/ethcore/src/client/test_client.rs @@ -48,7 +48,7 @@ use log_entry::LocalizedLogEntry; use receipt::{Receipt, LocalizedReceipt, TransactionOutcome}; use error::ImportResult; use vm::Schedule; -use miner::{Miner, MinerService}; +use miner::{self, Miner, MinerService}; use spec::Spec; use types::basic_account::BasicAccount; use types::pruning_info::PruningInfo; @@ -806,8 +806,8 @@ impl BlockChainClient for TestBlockChainClient { self.traces.read().clone() } - fn ready_transactions(&self) -> Vec> { - self.miner.ready_transactions(self) + fn ready_transactions(&self, max_len: usize) -> Vec> { + self.miner.ready_transactions(self, max_len, miner::PendingOrdering::Priority) } fn signing_chain_id(&self) -> Option { None } diff --git a/ethcore/src/client/traits.rs b/ethcore/src/client/traits.rs index d3a20dcff8..29876fe80a 100644 --- a/ethcore/src/client/traits.rs +++ b/ethcore/src/client/traits.rs @@ -321,7 +321,7 @@ pub trait BlockChainClient : Sync + Send + AccountData + BlockChain + CallContra fn last_hashes(&self) -> LastHashes; /// List all transactions that are allowed into the next block. - fn ready_transactions(&self) -> Vec>; + fn ready_transactions(&self, max_len: usize) -> Vec>; /// Sorted list of transaction gas prices from at least last sample_size blocks. fn gas_price_corpus(&self, sample_size: usize) -> ::stats::Corpus { diff --git a/ethcore/src/miner/miner.rs b/ethcore/src/miner/miner.rs index e91e03e8bc..2547fea62b 100644 --- a/ethcore/src/miner/miner.rs +++ b/ethcore/src/miner/miner.rs @@ -364,18 +364,28 @@ impl Miner { let client = self.pool_client(chain); let engine_params = self.engine.params(); - let min_tx_gas = self.engine.schedule(chain_info.best_block_number).tx_gas.into(); + let min_tx_gas: U256 = self.engine.schedule(chain_info.best_block_number).tx_gas.into(); let nonce_cap: Option = if chain_info.best_block_number + 1 >= engine_params.dust_protection_transition { Some((engine_params.nonce_cap_increment * (chain_info.best_block_number + 1)).into()) } else { None }; + // we will never need more transactions than limit divided by min gas + let max_transactions = if min_tx_gas.is_zero() { + usize::max_value() + } else { + (*open_block.block().header().gas_limit() / min_tx_gas).as_u64() as usize + }; let pending: Vec> = self.transaction_queue.pending( client.clone(), - chain_info.best_block_number, - chain_info.best_block_timestamp, - nonce_cap, + pool::PendingSettings { + block_number: chain_info.best_block_number, + current_timestamp: chain_info.best_block_timestamp, + nonce_cap, + max_len: max_transactions, + ordering: miner::PendingOrdering::Priority, + } ); let took_ms = |elapsed: &Duration| { @@ -807,20 +817,28 @@ impl miner::MinerService for Miner { self.transaction_queue.all_transactions() } - fn ready_transactions(&self, chain: &C) -> Vec> where + fn ready_transactions(&self, chain: &C, max_len: usize, ordering: miner::PendingOrdering) + -> Vec> + where C: ChainInfo + Nonce + Sync, { let chain_info = chain.chain_info(); let from_queue = || { + // We propagate transactions over the nonce cap. + // The mechanism is only to limit number of transactions in pending block + // those transactions are valid and will just be ready to be included in next block. + let nonce_cap = None; + self.transaction_queue.pending( CachedNonceClient::new(chain, &self.nonce_cache), - chain_info.best_block_number, - chain_info.best_block_timestamp, - // We propagate transactions over the nonce cap. - // The mechanism is only to limit number of transactions in pending block - // those transactions are valid and will just be ready to be included in next block. - None, + pool::PendingSettings { + block_number: chain_info.best_block_number, + current_timestamp: chain_info.best_block_timestamp, + nonce_cap, + max_len, + ordering, + }, ) }; @@ -830,6 +848,7 @@ impl miner::MinerService for Miner { .iter() .map(|signed| pool::VerifiedTransaction::from_pending_block_transaction(signed.clone())) .map(Arc::new) + .take(max_len) .collect() }, chain_info.best_block_number) }; @@ -1083,7 +1102,7 @@ mod tests { use rustc_hex::FromHex; use client::{TestBlockChainClient, EachBlockWith, ChainInfo, ImportSealedBlock}; - use miner::MinerService; + use miner::{MinerService, PendingOrdering}; use test_helpers::{generate_dummy_client, generate_dummy_client_with_spec_and_accounts}; use transaction::{Transaction}; @@ -1179,7 +1198,7 @@ mod tests { assert_eq!(res.unwrap(), ()); assert_eq!(miner.pending_transactions(best_block).unwrap().len(), 1); assert_eq!(miner.pending_receipts(best_block).unwrap().len(), 1); - assert_eq!(miner.ready_transactions(&client).len(), 1); + assert_eq!(miner.ready_transactions(&client, 10, PendingOrdering::Priority).len(), 1); // This method will let us know if pending block was created (before calling that method) assert!(!miner.prepare_pending_block(&client)); } @@ -1198,7 +1217,7 @@ mod tests { assert_eq!(res.unwrap(), ()); assert_eq!(miner.pending_transactions(best_block), None); assert_eq!(miner.pending_receipts(best_block), None); - assert_eq!(miner.ready_transactions(&client).len(), 1); + assert_eq!(miner.ready_transactions(&client, 10, PendingOrdering::Priority).len(), 1); } #[test] @@ -1217,11 +1236,11 @@ mod tests { assert_eq!(miner.pending_transactions(best_block), None); assert_eq!(miner.pending_receipts(best_block), None); // By default we use PendingSet::AlwaysSealing, so no transactions yet. - assert_eq!(miner.ready_transactions(&client).len(), 0); + assert_eq!(miner.ready_transactions(&client, 10, PendingOrdering::Priority).len(), 0); // This method will let us know if pending block was created (before calling that method) assert!(miner.prepare_pending_block(&client)); // After pending block is created we should see a transaction. - assert_eq!(miner.ready_transactions(&client).len(), 1); + assert_eq!(miner.ready_transactions(&client, 10, PendingOrdering::Priority).len(), 1); } #[test] diff --git a/ethcore/src/miner/mod.rs b/ethcore/src/miner/mod.rs index dd5f28feb6..631941de61 100644 --- a/ethcore/src/miner/mod.rs +++ b/ethcore/src/miner/mod.rs @@ -26,6 +26,7 @@ pub mod pool_client; pub mod stratum; pub use self::miner::{Miner, MinerOptions, Penalization, PendingSet, AuthoringParams}; +pub use ethcore_miner::pool::PendingOrdering; use std::sync::Arc; use std::collections::BTreeMap; @@ -156,10 +157,12 @@ pub trait MinerService : Send + Sync { fn next_nonce(&self, chain: &C, address: &Address) -> U256 where C: Nonce + Sync; - /// Get a list of all ready transactions. + /// Get a list of all ready transactions either ordered by priority or unordered (cheaper). /// /// Depending on the settings may look in transaction pool or only in pending block. - fn ready_transactions(&self, chain: &C) -> Vec> + /// If you don't need a full set of transactions, you can add `max_len` and create only a limited set of + /// transactions. + fn ready_transactions(&self, chain: &C, max_len: usize, ordering: PendingOrdering) -> Vec> where C: ChainInfo + Nonce + Sync; /// Get a list of all transactions in the pool (some of them might not be ready for inclusion yet). diff --git a/ethcore/src/tests/client.rs b/ethcore/src/tests/client.rs index ccafcf6613..e18b4db983 100644 --- a/ethcore/src/tests/client.rs +++ b/ethcore/src/tests/client.rs @@ -30,7 +30,7 @@ use test_helpers::{ use types::filter::Filter; use ethereum_types::{U256, Address}; use kvdb_rocksdb::{Database, DatabaseConfig}; -use miner::Miner; +use miner::{Miner, PendingOrdering}; use spec::Spec; use views::BlockView; use ethkey::KeyPair; @@ -343,12 +343,12 @@ fn does_not_propagate_delayed_transactions() { client.miner().import_own_transaction(&*client, tx0).unwrap(); client.miner().import_own_transaction(&*client, tx1).unwrap(); - assert_eq!(0, client.ready_transactions().len()); - assert_eq!(0, client.miner().ready_transactions(&*client).len()); + assert_eq!(0, client.ready_transactions(10).len()); + assert_eq!(0, client.miner().ready_transactions(&*client, 10, PendingOrdering::Priority).len()); push_blocks_to_client(&client, 53, 2, 2); client.flush_queue(); - assert_eq!(2, client.ready_transactions().len()); - assert_eq!(2, client.miner().ready_transactions(&*client).len()); + assert_eq!(2, client.ready_transactions(10).len()); + assert_eq!(2, client.miner().ready_transactions(&*client, 10, PendingOrdering::Priority).len()); } #[test] diff --git a/ethcore/sync/src/api.rs b/ethcore/sync/src/api.rs index b759fb734a..56bc579ad8 100644 --- a/ethcore/sync/src/api.rs +++ b/ethcore/sync/src/api.rs @@ -359,6 +359,10 @@ impl SyncProvider for EthSync { } } +const PEERS_TIMER: TimerToken = 0; +const SYNC_TIMER: TimerToken = 1; +const TX_TIMER: TimerToken = 2; + struct SyncProtocolHandler { /// Shared blockchain client. chain: Arc, @@ -373,7 +377,9 @@ struct SyncProtocolHandler { impl NetworkProtocolHandler for SyncProtocolHandler { fn initialize(&self, io: &NetworkContext) { if io.subprotocol_name() != WARP_SYNC_PROTOCOL_ID { - io.register_timer(0, Duration::from_secs(1)).expect("Error registering sync timer"); + io.register_timer(PEERS_TIMER, Duration::from_millis(700)).expect("Error registering peers timer"); + io.register_timer(SYNC_TIMER, Duration::from_millis(1100)).expect("Error registering sync timer"); + io.register_timer(TX_TIMER, Duration::from_millis(1300)).expect("Error registering transactions timer"); } } @@ -399,12 +405,17 @@ impl NetworkProtocolHandler for SyncProtocolHandler { } } - fn timeout(&self, io: &NetworkContext, _timer: TimerToken) { + fn timeout(&self, io: &NetworkContext, timer: TimerToken) { trace_time!("sync::timeout"); let mut io = NetSyncIo::new(io, &*self.chain, &*self.snapshot_service, &self.overlay); - self.sync.write().maintain_peers(&mut io); - self.sync.write().maintain_sync(&mut io); - self.sync.write().propagate_new_transactions(&mut io); + match timer { + PEERS_TIMER => self.sync.write().maintain_peers(&mut io), + SYNC_TIMER => self.sync.write().maintain_sync(&mut io), + TX_TIMER => { + self.sync.write().propagate_new_transactions(&mut io); + }, + _ => warn!("Unknown timer {} triggered.", timer), + } } } diff --git a/ethcore/sync/src/chain/mod.rs b/ethcore/sync/src/chain/mod.rs index 8f0aff7514..84e6344e68 100644 --- a/ethcore/sync/src/chain/mod.rs +++ b/ethcore/sync/src/chain/mod.rs @@ -149,6 +149,10 @@ const MAX_NEW_HASHES: usize = 64; const MAX_NEW_BLOCK_AGE: BlockNumber = 20; // maximal packet size with transactions (cannot be greater than 16MB - protocol limitation). const MAX_TRANSACTION_PACKET_SIZE: usize = 8 * 1024 * 1024; +// Maximal number of transactions queried from miner to propagate. +// This set is used to diff with transactions known by the peer and +// we will send a difference of length up to `MAX_TRANSACTIONS_TO_PROPAGATE`. +const MAX_TRANSACTIONS_TO_QUERY: usize = 4096; // Maximal number of transactions in sent in single packet. const MAX_TRANSACTIONS_TO_PROPAGATE: usize = 64; // Min number of blocks to be behind for a snapshot sync @@ -1143,7 +1147,7 @@ pub mod tests { use super::{PeerInfo, PeerAsking}; use ethcore::header::*; use ethcore::client::{BlockChainClient, EachBlockWith, TestBlockChainClient, ChainInfo, BlockInfo}; - use ethcore::miner::MinerService; + use ethcore::miner::{MinerService, PendingOrdering}; use private_tx::NoopPrivateTxHandler; pub fn get_dummy_block(order: u32, parent_hash: H256) -> Bytes { @@ -1355,7 +1359,7 @@ pub mod tests { let mut io = TestIo::new(&mut client, &ss, &queue, None); io.chain.miner.chain_new_blocks(io.chain, &[], &[], &[], &good_blocks, false); sync.chain_new_blocks(&mut io, &[], &[], &[], &good_blocks, &[], &[]); - assert_eq!(io.chain.miner.ready_transactions(io.chain).len(), 1); + assert_eq!(io.chain.miner.ready_transactions(io.chain, 10, PendingOrdering::Priority).len(), 1); } // We need to update nonce status (because we say that the block has been imported) for h in &[good_blocks[0]] { @@ -1371,7 +1375,7 @@ pub mod tests { } // then - assert_eq!(client.miner.ready_transactions(&client).len(), 1); + assert_eq!(client.miner.ready_transactions(&client, 10, PendingOrdering::Priority).len(), 1); } #[test] diff --git a/ethcore/sync/src/chain/propagator.rs b/ethcore/sync/src/chain/propagator.rs index 4ae0518a53..75cf550f28 100644 --- a/ethcore/sync/src/chain/propagator.rs +++ b/ethcore/sync/src/chain/propagator.rs @@ -33,6 +33,7 @@ use super::{ MAX_PEERS_PROPAGATION, MAX_TRANSACTION_PACKET_SIZE, MAX_TRANSACTIONS_TO_PROPAGATE, + MAX_TRANSACTIONS_TO_QUERY, MIN_PEERS_PROPAGATION, CONSENSUS_DATA_PACKET, NEW_BLOCK_HASHES_PACKET, @@ -114,7 +115,7 @@ impl SyncPropagator { return 0; } - let transactions = io.chain().ready_transactions(); + let transactions = io.chain().ready_transactions(MAX_TRANSACTIONS_TO_QUERY); if transactions.is_empty() { return 0; } diff --git a/miner/src/lib.rs b/miner/src/lib.rs index 9dc180fefe..6b61df4de4 100644 --- a/miner/src/lib.rs +++ b/miner/src/lib.rs @@ -30,13 +30,14 @@ extern crate linked_hash_map; extern crate parking_lot; extern crate price_info; extern crate rlp; -extern crate trace_time; extern crate transaction_pool as txpool; #[macro_use] extern crate error_chain; #[macro_use] extern crate log; +#[macro_use] +extern crate trace_time; #[cfg(test)] extern crate rustc_hex; diff --git a/miner/src/pool/mod.rs b/miner/src/pool/mod.rs index 57f813157b..fd4ef6ef2e 100644 --- a/miner/src/pool/mod.rs +++ b/miner/src/pool/mod.rs @@ -16,7 +16,7 @@ //! Transaction Pool -use ethereum_types::{H256, Address}; +use ethereum_types::{U256, H256, Address}; use heapsize::HeapSizeOf; use transaction; use txpool; @@ -45,6 +45,43 @@ pub enum PrioritizationStrategy { GasPriceOnly, } +/// Transaction ordering when requesting pending set. +#[derive(Debug, PartialEq, Eq, Clone, Copy)] +pub enum PendingOrdering { + /// Get pending transactions ordered by their priority (potentially expensive) + Priority, + /// Get pending transactions without any care of particular ordering (cheaper). + Unordered, +} + +/// Pending set query settings +#[derive(Debug, Clone)] +pub struct PendingSettings { + /// Current block number (affects readiness of some transactions). + pub block_number: u64, + /// Current timestamp (affects readiness of some transactions). + pub current_timestamp: u64, + /// Nonce cap (for dust protection; EIP-168) + pub nonce_cap: Option, + /// Maximal number of transactions in pending the set. + pub max_len: usize, + /// Ordering of transactions. + pub ordering: PendingOrdering, +} + +impl PendingSettings { + /// Get all transactions (no cap or len limit) prioritized. + pub fn all_prioritized(block_number: u64, current_timestamp: u64) -> Self { + PendingSettings { + block_number, + current_timestamp, + nonce_cap: None, + max_len: usize::max_value(), + ordering: PendingOrdering::Priority, + } + } +} + /// Transaction priority. #[derive(Debug, PartialEq, Eq, Clone, Copy)] pub(crate) enum Priority { diff --git a/miner/src/pool/queue.rs b/miner/src/pool/queue.rs index cf4a956f42..4351087b29 100644 --- a/miner/src/pool/queue.rs +++ b/miner/src/pool/queue.rs @@ -26,7 +26,10 @@ use parking_lot::RwLock; use transaction; use txpool::{self, Verifier}; -use pool::{self, scoring, verifier, client, ready, listener, PrioritizationStrategy}; +use pool::{ + self, scoring, verifier, client, ready, listener, + PrioritizationStrategy, PendingOrdering, PendingSettings, +}; use pool::local_transactions::LocalTransactionsList; type Listener = (LocalTransactionsList, (listener::Notifier, listener::Logger)); @@ -74,6 +77,7 @@ struct CachedPending { nonce_cap: Option, has_local_pending: bool, pending: Option>>, + max_len: usize, } impl CachedPending { @@ -85,6 +89,7 @@ impl CachedPending { has_local_pending: false, pending: None, nonce_cap: None, + max_len: 0, } } @@ -99,6 +104,7 @@ impl CachedPending { block_number: u64, current_timestamp: u64, nonce_cap: Option<&U256>, + max_len: usize, ) -> Option>> { // First check if we have anything in cache. let pending = self.pending.as_ref()?; @@ -123,7 +129,12 @@ impl CachedPending { return None; } - Some(pending.clone()) + // It's fine to just take a smaller subset, but not other way around. + if max_len > self.max_len { + return None; + } + + Some(pending.iter().take(max_len).cloned().collect()) } } @@ -173,7 +184,7 @@ impl TransactionQueue { transactions: Vec, ) -> Vec> { // Run verification - let _timer = ::trace_time::PerfTimer::new("pool::verify_and_import"); + trace_time!("pool::verify_and_import"); let options = self.options.read().clone(); let verifier = verifier::Verifier::new(client, options, self.insertion_id.clone()); @@ -203,13 +214,13 @@ impl TransactionQueue { results } - /// Returns all transactions in the queue ordered by priority. + /// Returns all transactions in the queue without explicit ordering. pub fn all_transactions(&self) -> Vec> { let ready = |_tx: &pool::VerifiedTransaction| txpool::Readiness::Ready; - self.pool.read().pending(ready).collect() + self.pool.read().unordered_pending(ready).collect() } - /// Returns current pneding transactions. + /// Returns current pending transactions ordered by priority. /// /// NOTE: This may return a cached version of pending transaction set. /// Re-computing the pending set is possible with `#collect_pending` method, @@ -217,24 +228,31 @@ impl TransactionQueue { pub fn pending( &self, client: C, - block_number: u64, - current_timestamp: u64, - nonce_cap: Option, + settings: PendingSettings, ) -> Vec> where C: client::NonceClient, { - - if let Some(pending) = self.cached_pending.read().pending(block_number, current_timestamp, nonce_cap.as_ref()) { + let PendingSettings { block_number, current_timestamp, nonce_cap, max_len, ordering } = settings; + if let Some(pending) = self.cached_pending.read().pending(block_number, current_timestamp, nonce_cap.as_ref(), max_len) { return pending; } // Double check after acquiring write lock let mut cached_pending = self.cached_pending.write(); - if let Some(pending) = cached_pending.pending(block_number, current_timestamp, nonce_cap.as_ref()) { + if let Some(pending) = cached_pending.pending(block_number, current_timestamp, nonce_cap.as_ref(), max_len) { return pending; } - let pending: Vec<_> = self.collect_pending(client, block_number, current_timestamp, nonce_cap, |i| i.collect()); + // In case we don't have a cached set, but we don't care about order + // just return the unordered set. + if let PendingOrdering::Unordered = ordering { + let ready = Self::ready(client, block_number, current_timestamp, nonce_cap); + return self.pool.read().unordered_pending(ready).take(max_len).collect(); + } + + let pending: Vec<_> = self.collect_pending(client, block_number, current_timestamp, nonce_cap, |i| { + i.take(max_len).collect() + }); *cached_pending = CachedPending { block_number, @@ -242,6 +260,7 @@ impl TransactionQueue { nonce_cap, has_local_pending: self.has_local_pending_transactions(), pending: Some(pending.clone()), + max_len, }; pending @@ -266,15 +285,27 @@ impl TransactionQueue { scoring::NonceAndGasPrice, Listener, >) -> T, + { + debug!(target: "txqueue", "Re-computing pending set for block: {}", block_number); + trace_time!("pool::collect_pending"); + let ready = Self::ready(client, block_number, current_timestamp, nonce_cap); + collect(self.pool.read().pending(ready)) + } + + fn ready( + client: C, + block_number: u64, + current_timestamp: u64, + nonce_cap: Option, + ) -> (ready::Condition, ready::State) where + C: client::NonceClient, { let pending_readiness = ready::Condition::new(block_number, current_timestamp); // don't mark any transactions as stale at this point. let stale_id = None; let state_readiness = ready::State::new(client, stale_id, nonce_cap); - let ready = (pending_readiness, state_readiness); - - collect(self.pool.read().pending(ready)) + (pending_readiness, state_readiness) } /// Culls all stalled transactions from the pool. @@ -415,6 +446,12 @@ impl TransactionQueue { let mut pool = self.pool.write(); (pool.listener_mut().1).0.add(f); } + + /// Check if pending set is cached. + #[cfg(test)] + pub fn is_pending_cached(&self) -> bool { + self.cached_pending.read().pending.is_some() + } } fn convert_error(err: txpool::Error) -> transaction::Error { @@ -440,7 +477,7 @@ mod tests { fn should_get_pending_transactions() { let queue = TransactionQueue::new(txpool::Options::default(), verifier::Options::default(), PrioritizationStrategy::GasPriceOnly); - let pending: Vec<_> = queue.pending(TestClient::default(), 0, 0, None); + let pending: Vec<_> = queue.pending(TestClient::default(), PendingSettings::all_prioritized(0, 0)); for tx in pending { assert!(tx.signed().nonce > 0.into()); diff --git a/miner/src/pool/tests/mod.rs b/miner/src/pool/tests/mod.rs index ac2e6b008e..ef83db4a90 100644 --- a/miner/src/pool/tests/mod.rs +++ b/miner/src/pool/tests/mod.rs @@ -18,7 +18,7 @@ use ethereum_types::U256; use transaction::{self, PendingTransaction}; use txpool; -use pool::{verifier, TransactionQueue, PrioritizationStrategy}; +use pool::{verifier, TransactionQueue, PrioritizationStrategy, PendingSettings, PendingOrdering}; pub mod tx; pub mod client; @@ -108,7 +108,7 @@ fn should_handle_same_transaction_imported_twice_with_different_state_nonces() { // and then there should be only one transaction in current (the one with higher gas_price) assert_eq!(res, vec![Ok(())]); assert_eq!(txq.status().status.transaction_count, 1); - let top = txq.pending(TestClient::new(), 0, 0, None); + let top = txq.pending(TestClient::new(), PendingSettings::all_prioritized(0, 0)); assert_eq!(top[0].hash, hash); } @@ -133,7 +133,7 @@ fn should_move_all_transactions_from_future() { // then assert_eq!(res, vec![Ok(())]); assert_eq!(txq.status().status.transaction_count, 2); - let top = txq.pending(TestClient::new(), 0, 0, None); + let top = txq.pending(TestClient::new(), PendingSettings::all_prioritized(0, 0)); assert_eq!(top[0].hash, hash); assert_eq!(top[1].hash, hash2); } @@ -207,7 +207,7 @@ fn should_import_txs_from_same_sender() { txq.import(TestClient::new(), txs.local().into_vec()); // then - let top = txq.pending(TestClient::new(), 0 ,0, None); + let top = txq.pending(TestClient::new(), PendingSettings::all_prioritized(0 ,0)); assert_eq!(top[0].hash, hash); assert_eq!(top[1].hash, hash2); assert_eq!(top.len(), 2); @@ -229,7 +229,7 @@ fn should_prioritize_local_transactions_within_same_nonce_height() { assert_eq!(res, vec![Ok(()), Ok(())]); // then - let top = txq.pending(client, 0, 0, None); + let top = txq.pending(client, PendingSettings::all_prioritized(0, 0)); assert_eq!(top[0].hash, hash); // local should be first assert_eq!(top[1].hash, hash2); assert_eq!(top.len(), 2); @@ -251,7 +251,7 @@ fn should_prioritize_reimported_transactions_within_same_nonce_height() { assert_eq!(res, vec![Ok(()), Ok(())]); // then - let top = txq.pending(TestClient::new(), 0, 0, None); + let top = txq.pending(TestClient::new(), PendingSettings::all_prioritized(0, 0)); assert_eq!(top[0].hash, hash); // retracted should be first assert_eq!(top[1].hash, hash2); assert_eq!(top.len(), 2); @@ -270,7 +270,7 @@ fn should_not_prioritize_local_transactions_with_different_nonce_height() { assert_eq!(res, vec![Ok(()), Ok(())]); // then - let top = txq.pending(TestClient::new(), 0, 0, None); + let top = txq.pending(TestClient::new(), PendingSettings::all_prioritized(0, 0)); assert_eq!(top[0].hash, hash); assert_eq!(top[1].hash, hash2); assert_eq!(top.len(), 2); @@ -288,7 +288,7 @@ fn should_put_transaction_to_futures_if_gap_detected() { // then assert_eq!(res, vec![Ok(()), Ok(())]); - let top = txq.pending(TestClient::new(), 0, 0, None); + let top = txq.pending(TestClient::new(), PendingSettings::all_prioritized(0, 0)); assert_eq!(top.len(), 1); assert_eq!(top[0].hash, hash); } @@ -308,9 +308,9 @@ fn should_handle_min_block() { assert_eq!(res, vec![Ok(()), Ok(())]); // then - let top = txq.pending(TestClient::new(), 0, 0, None); + let top = txq.pending(TestClient::new(), PendingSettings::all_prioritized(0, 0)); assert_eq!(top.len(), 0); - let top = txq.pending(TestClient::new(), 1, 0, None); + let top = txq.pending(TestClient::new(), PendingSettings::all_prioritized(1, 0)); assert_eq!(top.len(), 2); } @@ -341,7 +341,7 @@ fn should_move_transactions_if_gap_filled() { let res = txq.import(TestClient::new(), vec![tx, tx2].local()); assert_eq!(res, vec![Ok(()), Ok(())]); assert_eq!(txq.status().status.transaction_count, 2); - assert_eq!(txq.pending(TestClient::new(), 0, 0, None).len(), 1); + assert_eq!(txq.pending(TestClient::new(), PendingSettings::all_prioritized(0, 0)).len(), 1); // when let res = txq.import(TestClient::new(), vec![tx1.local()]); @@ -349,7 +349,7 @@ fn should_move_transactions_if_gap_filled() { // then assert_eq!(txq.status().status.transaction_count, 3); - assert_eq!(txq.pending(TestClient::new(), 0, 0, None).len(), 3); + assert_eq!(txq.pending(TestClient::new(), PendingSettings::all_prioritized(0, 0)).len(), 3); } #[test] @@ -361,12 +361,12 @@ fn should_remove_transaction() { let res = txq.import(TestClient::default(), vec![tx, tx2].local()); assert_eq!(res, vec![Ok(()), Ok(())]); assert_eq!(txq.status().status.transaction_count, 2); - assert_eq!(txq.pending(TestClient::new(), 0, 0, None).len(), 1); + assert_eq!(txq.pending(TestClient::new(), PendingSettings::all_prioritized(0, 0)).len(), 1); // when txq.cull(TestClient::new().with_nonce(124)); assert_eq!(txq.status().status.transaction_count, 1); - assert_eq!(txq.pending(TestClient::new().with_nonce(125), 0, 0, None).len(), 1); + assert_eq!(txq.pending(TestClient::new().with_nonce(125), PendingSettings::all_prioritized(0, 0)).len(), 1); txq.cull(TestClient::new().with_nonce(126)); // then @@ -384,19 +384,19 @@ fn should_move_transactions_to_future_if_gap_introduced() { let res = txq.import(TestClient::new(), vec![tx3, tx2].local()); assert_eq!(res, vec![Ok(()), Ok(())]); assert_eq!(txq.status().status.transaction_count, 2); - assert_eq!(txq.pending(TestClient::new(), 0, 0, None).len(), 1); + assert_eq!(txq.pending(TestClient::new(), PendingSettings::all_prioritized(0, 0)).len(), 1); let res = txq.import(TestClient::new(), vec![tx].local()); assert_eq!(res, vec![Ok(())]); assert_eq!(txq.status().status.transaction_count, 3); - assert_eq!(txq.pending(TestClient::new(), 0, 0, None).len(), 3); + assert_eq!(txq.pending(TestClient::new(), PendingSettings::all_prioritized(0, 0)).len(), 3); // when txq.remove(vec![&hash], true); // then assert_eq!(txq.status().status.transaction_count, 2); - assert_eq!(txq.pending(TestClient::new(), 0, 0, None).len(), 1); + assert_eq!(txq.pending(TestClient::new(), PendingSettings::all_prioritized(0, 0)).len(), 1); } #[test] @@ -447,7 +447,7 @@ fn should_prefer_current_transactions_when_hitting_the_limit() { assert_eq!(res, vec![Ok(())]); assert_eq!(txq.status().status.transaction_count, 1); - let top = txq.pending(TestClient::new(), 0, 0, None); + let top = txq.pending(TestClient::new(), PendingSettings::all_prioritized(0, 0)); assert_eq!(top.len(), 1); assert_eq!(top[0].hash, hash); assert_eq!(txq.next_nonce(TestClient::new(), &sender), Some(124.into())); @@ -494,19 +494,19 @@ fn should_accept_same_transaction_twice_if_removed() { let res = txq.import(TestClient::new(), txs.local().into_vec()); assert_eq!(res, vec![Ok(()), Ok(())]); assert_eq!(txq.status().status.transaction_count, 2); - assert_eq!(txq.pending(TestClient::new(), 0, 0, None).len(), 2); + assert_eq!(txq.pending(TestClient::new(), PendingSettings::all_prioritized(0, 0)).len(), 2); // when txq.remove(vec![&hash], true); assert_eq!(txq.status().status.transaction_count, 1); - assert_eq!(txq.pending(TestClient::new(), 0, 0, None).len(), 0); + assert_eq!(txq.pending(TestClient::new(), PendingSettings::all_prioritized(0, 0)).len(), 0); let res = txq.import(TestClient::new(), vec![tx1].local()); assert_eq!(res, vec![Ok(())]); // then assert_eq!(txq.status().status.transaction_count, 2); - assert_eq!(txq.pending(TestClient::new(), 0, 0, None).len(), 2); + assert_eq!(txq.pending(TestClient::new(), PendingSettings::all_prioritized(0, 0)).len(), 2); } #[test] @@ -526,8 +526,8 @@ fn should_not_replace_same_transaction_if_the_fee_is_less_than_minimal_bump() { // then assert_eq!(res, vec![Err(transaction::Error::TooCheapToReplace), Ok(())]); assert_eq!(txq.status().status.transaction_count, 2); - assert_eq!(txq.pending(client.clone(), 0, 0, None)[0].signed().gas_price, U256::from(20)); - assert_eq!(txq.pending(client.clone(), 0, 0, None)[1].signed().gas_price, U256::from(2)); + assert_eq!(txq.pending(client.clone(), PendingSettings::all_prioritized(0, 0))[0].signed().gas_price, U256::from(20)); + assert_eq!(txq.pending(client.clone(), PendingSettings::all_prioritized(0, 0))[1].signed().gas_price, U256::from(2)); } #[test] @@ -569,7 +569,7 @@ fn should_return_valid_last_nonce_after_cull() { let client = TestClient::new().with_nonce(124); txq.cull(client.clone()); // tx2 should be not be promoted to current - assert_eq!(txq.pending(client.clone(), 0, 0, None).len(), 0); + assert_eq!(txq.pending(client.clone(), PendingSettings::all_prioritized(0, 0)).len(), 0); // then assert_eq!(txq.next_nonce(client.clone(), &sender), None); @@ -667,7 +667,7 @@ fn should_accept_local_transactions_below_min_gas_price() { assert_eq!(res, vec![Ok(())]); // then - assert_eq!(txq.pending(TestClient::new(), 0, 0, None).len(), 1); + assert_eq!(txq.pending(TestClient::new(), PendingSettings::all_prioritized(0, 0)).len(), 1); } #[test] @@ -685,7 +685,7 @@ fn should_accept_local_service_transaction() { assert_eq!(res, vec![Ok(())]); // then - assert_eq!(txq.pending(TestClient::new(), 0, 0, None).len(), 1); + assert_eq!(txq.pending(TestClient::new(), PendingSettings::all_prioritized(0, 0)).len(), 1); } #[test] @@ -726,15 +726,77 @@ fn should_not_return_transactions_over_nonce_cap() { assert_eq!(res, vec![Ok(()), Ok(()), Ok(())]); // when - let all = txq.pending(TestClient::new(), 0, 0, None); + let all = txq.pending(TestClient::new(), PendingSettings::all_prioritized(0, 0)); // This should invalidate the cache! - let limited = txq.pending(TestClient::new(), 0, 0, Some(123.into())); + let limited = txq.pending(TestClient::new(), PendingSettings { + block_number: 0, + current_timestamp: 0, + nonce_cap: Some(123.into()), + max_len: usize::max_value(), + ordering: PendingOrdering::Priority, + }); // then assert_eq!(all.len(), 3); assert_eq!(limited.len(), 1); } +#[test] +fn should_return_cached_pending_even_if_unordered_is_requested() { + // given + let txq = new_queue(); + let tx1 = Tx::default().signed(); + let (tx2_1, tx2_2)= Tx::default().signed_pair(); + let tx2_1_hash = tx2_1.hash(); + let res = txq.import(TestClient::new(), vec![tx1].unverified()); + assert_eq!(res, vec![Ok(())]); + let res = txq.import(TestClient::new(), vec![tx2_1, tx2_2].local()); + assert_eq!(res, vec![Ok(()), Ok(())]); + + // when + let all = txq.pending(TestClient::new(), PendingSettings::all_prioritized(0, 0)); + assert_eq!(all[0].hash, tx2_1_hash); + assert_eq!(all.len(), 3); + + // This should not invalidate the cache! + let limited = txq.pending(TestClient::new(), PendingSettings { + block_number: 0, + current_timestamp: 0, + nonce_cap: None, + max_len: 3, + ordering: PendingOrdering::Unordered, + }); + + // then + assert_eq!(all, limited); +} + +#[test] +fn should_return_unordered_and_not_populate_the_cache() { + // given + let txq = new_queue(); + let tx1 = Tx::default().signed(); + let (tx2_1, tx2_2)= Tx::default().signed_pair(); + let res = txq.import(TestClient::new(), vec![tx1].unverified()); + assert_eq!(res, vec![Ok(())]); + let res = txq.import(TestClient::new(), vec![tx2_1, tx2_2].local()); + assert_eq!(res, vec![Ok(()), Ok(())]); + + // when + // This should not invalidate the cache! + let limited = txq.pending(TestClient::new(), PendingSettings { + block_number: 0, + current_timestamp: 0, + nonce_cap: None, + max_len: usize::max_value(), + ordering: PendingOrdering::Unordered, + }); + + // then + assert_eq!(limited.len(), 3); + assert!(!txq.is_pending_cached()); +} + #[test] fn should_clear_cache_after_timeout_for_local() { // given @@ -748,12 +810,12 @@ fn should_clear_cache_after_timeout_for_local() { // This should populate cache and set timestamp to 1 // when - assert_eq!(txq.pending(TestClient::new(), 0, 1, None).len(), 0); - assert_eq!(txq.pending(TestClient::new(), 0, 1000, None).len(), 0); + assert_eq!(txq.pending(TestClient::new(), PendingSettings::all_prioritized(0, 1)).len(), 0); + assert_eq!(txq.pending(TestClient::new(), PendingSettings::all_prioritized(0, 1000)).len(), 0); // This should invalidate the cache and trigger transaction ready. // then - assert_eq!(txq.pending(TestClient::new(), 0, 1002, None).len(), 2); + assert_eq!(txq.pending(TestClient::new(), PendingSettings::all_prioritized(0, 1002)).len(), 2); } #[test] diff --git a/parity/rpc_apis.rs b/parity/rpc_apis.rs index ce30f3cd85..31af69eaa0 100644 --- a/parity/rpc_apis.rs +++ b/parity/rpc_apis.rs @@ -304,7 +304,7 @@ impl FullDependencies { let client = EthPubSubClient::new(self.client.clone(), self.remote.clone()); let h = client.handler(); self.miner.add_transactions_listener(Box::new(move |hashes| if let Some(h) = h.upgrade() { - h.new_transactions(hashes); + h.notify_new_transactions(hashes); })); if let Some(h) = client.handler().upgrade() { @@ -525,7 +525,7 @@ impl LightDependencies { let h = client.handler(); self.transaction_queue.write().add_listener(Box::new(move |transactions| { if let Some(h) = h.upgrade() { - h.new_transactions(transactions); + h.notify_new_transactions(transactions); } })); handler.extend_with(EthPubSub::to_delegate(client)); diff --git a/rpc/Cargo.toml b/rpc/Cargo.toml index 338a892682..d227f45f53 100644 --- a/rpc/Cargo.toml +++ b/rpc/Cargo.toml @@ -36,7 +36,7 @@ jsonrpc-macros = { git = "https://github.com/paritytech/jsonrpc.git", branch = " jsonrpc-pubsub = { git = "https://github.com/paritytech/jsonrpc.git", branch = "parity-1.11" } ethash = { path = "../ethash" } -ethcore = { path = "../ethcore" } +ethcore = { path = "../ethcore", features = ["test-helpers"] } ethcore-bytes = { path = "../util/bytes" } ethcore-crypto = { path = "../ethcore/crypto" } ethcore-devtools = { path = "../devtools" } diff --git a/rpc/src/v1/impls/eth_filter.rs b/rpc/src/v1/impls/eth_filter.rs index bbad2fe27d..c91070cbfb 100644 --- a/rpc/src/v1/impls/eth_filter.rs +++ b/rpc/src/v1/impls/eth_filter.rs @@ -85,7 +85,7 @@ impl Filterable for EthFilterClient where } fn pending_transactions_hashes(&self) -> Vec { - self.miner.ready_transactions(&*self.client) + self.miner.ready_transactions(&*self.client, usize::max_value(), miner::PendingOrdering::Priority) .into_iter() .map(|tx| tx.signed().hash()) .collect() diff --git a/rpc/src/v1/impls/eth_pubsub.rs b/rpc/src/v1/impls/eth_pubsub.rs index 11fef2e0bd..38162e8ea1 100644 --- a/rpc/src/v1/impls/eth_pubsub.rs +++ b/rpc/src/v1/impls/eth_pubsub.rs @@ -175,7 +175,7 @@ impl ChainNotificationHandler { } /// Notify all subscribers about new transaction hashes. - pub fn new_transactions(&self, hashes: &[H256]) { + pub fn notify_new_transactions(&self, hashes: &[H256]) { for subscriber in self.transactions_subscribers.read().values() { for hash in hashes { Self::notify(&self.remote, subscriber, pubsub::Result::TransactionHash((*hash).into())); diff --git a/rpc/src/v1/impls/light/parity.rs b/rpc/src/v1/impls/light/parity.rs index 91db00ca30..6e93132b92 100644 --- a/rpc/src/v1/impls/light/parity.rs +++ b/rpc/src/v1/impls/light/parity.rs @@ -264,12 +264,13 @@ impl Parity for ParityClient { .map(Into::into) } - fn pending_transactions(&self) -> Result> { + fn pending_transactions(&self, limit: Trailing) -> Result> { let txq = self.light_dispatch.transaction_queue.read(); let chain_info = self.light_dispatch.client.chain_info(); Ok( txq.ready_transactions(chain_info.best_block_number, chain_info.best_block_timestamp) .into_iter() + .take(limit.unwrap_or_else(usize::max_value)) .map(|tx| Transaction::from_pending(tx, chain_info.best_block_number, self.eip86_transition)) .collect::>() ) diff --git a/rpc/src/v1/impls/parity.rs b/rpc/src/v1/impls/parity.rs index f18723eafe..d7c26014ed 100644 --- a/rpc/src/v1/impls/parity.rs +++ b/rpc/src/v1/impls/parity.rs @@ -303,15 +303,19 @@ impl Parity for ParityClient where .map(Into::into) } - fn pending_transactions(&self) -> Result> { + fn pending_transactions(&self, limit: Trailing) -> Result> { let block_number = self.client.chain_info().best_block_number; - let ready_transactions = self.miner.ready_transactions(&*self.client); + let ready_transactions = self.miner.ready_transactions( + &*self.client, + limit.unwrap_or_else(usize::max_value), + miner::PendingOrdering::Priority, + ); Ok(ready_transactions .into_iter() .map(|t| Transaction::from_pending(t.pending().clone(), block_number, self.eip86_transition)) .collect() - ) + ) } fn all_transactions(&self) -> Result> { diff --git a/rpc/src/v1/tests/helpers/miner_service.rs b/rpc/src/v1/tests/helpers/miner_service.rs index 90201e346a..8d0ec23ae1 100644 --- a/rpc/src/v1/tests/helpers/miner_service.rs +++ b/rpc/src/v1/tests/helpers/miner_service.rs @@ -27,7 +27,7 @@ use ethcore::engines::EthEngine; use ethcore::error::Error; use ethcore::header::{BlockNumber, Header}; use ethcore::ids::BlockId; -use ethcore::miner::{MinerService, AuthoringParams}; +use ethcore::miner::{self, MinerService, AuthoringParams}; use ethcore::receipt::{Receipt, RichReceipt}; use ethereum_types::{H256, U256, Address}; use miner::pool::local_transactions::Status as LocalTransactionStatus; @@ -208,7 +208,7 @@ impl MinerService for TestMinerService { self.local_transactions.lock().iter().map(|(hash, stats)| (*hash, stats.clone())).collect() } - fn ready_transactions(&self, _chain: &C) -> Vec> { + fn ready_transactions(&self, _chain: &C, _max_len: usize, _ordering: miner::PendingOrdering) -> Vec> { self.queued_transactions() } diff --git a/rpc/src/v1/tests/mocked/eth_pubsub.rs b/rpc/src/v1/tests/mocked/eth_pubsub.rs index 0d886fe2f1..30c99fc67a 100644 --- a/rpc/src/v1/tests/mocked/eth_pubsub.rs +++ b/rpc/src/v1/tests/mocked/eth_pubsub.rs @@ -181,7 +181,7 @@ fn should_subscribe_to_pending_transactions() { assert_eq!(io.handle_request_sync(request, metadata.clone()), Some(response.to_owned())); // Send new transactions - handler.new_transactions(&[5.into(), 7.into()]); + handler.notify_new_transactions(&[5.into(), 7.into()]); let (res, receiver) = receiver.into_future().wait().unwrap(); let response = r#"{"jsonrpc":"2.0","method":"eth_subscription","params":{"result":"0x0000000000000000000000000000000000000000000000000000000000000005","subscription":"0x416d77337e24399d"}}"#; diff --git a/rpc/src/v1/traits/parity.rs b/rpc/src/v1/traits/parity.rs index f78cf8052e..1b9a7d09f5 100644 --- a/rpc/src/v1/traits/parity.rs +++ b/rpc/src/v1/traits/parity.rs @@ -141,7 +141,7 @@ build_rpc_trait! { /// Returns all pending transactions from transaction queue. #[rpc(name = "parity_pendingTransactions")] - fn pending_transactions(&self) -> Result>; + fn pending_transactions(&self, Trailing) -> Result>; /// Returns all transactions from transaction queue. /// diff --git a/transaction-pool/Cargo.toml b/transaction-pool/Cargo.toml index 8965c8cee0..0ba1790a47 100644 --- a/transaction-pool/Cargo.toml +++ b/transaction-pool/Cargo.toml @@ -1,7 +1,7 @@ [package] description = "Generic transaction pool." name = "transaction-pool" -version = "1.12.0" +version = "1.12.1" license = "GPL-3.0" authors = ["Parity Technologies "] diff --git a/transaction-pool/src/pool.rs b/transaction-pool/src/pool.rs index dcd52a3e7e..4bbf00ef24 100644 --- a/transaction-pool/src/pool.rs +++ b/transaction-pool/src/pool.rs @@ -15,7 +15,8 @@ // along with Parity. If not, see . use std::sync::Arc; -use std::collections::{HashMap, BTreeSet}; +use std::slice; +use std::collections::{hash_map, HashMap, BTreeSet}; use error; use listener::{Listener, NoopListener}; @@ -416,7 +417,16 @@ impl Pool where PendingIterator { ready, best_transactions, - pool: self + pool: self, + } + } + + /// Returns unprioritized list of ready transactions. + pub fn unordered_pending>(&self, ready: R) -> UnorderedIterator { + UnorderedIterator { + ready, + senders: self.transactions.iter(), + transactions: None, } } @@ -482,6 +492,50 @@ impl Pool where } } +/// An iterator over all pending (ready) transactions in unoredered fashion. +/// +/// NOTE: Current implementation will iterate over all transactions from particular sender +/// ordered by nonce, but that might change in the future. +/// +/// NOTE: the transactions are not removed from the queue. +/// You might remove them later by calling `cull`. +pub struct UnorderedIterator<'a, T, R, S> where + T: VerifiedTransaction + 'a, + S: Scoring + 'a, +{ + ready: R, + senders: hash_map::Iter<'a, T::Sender, Transactions>, + transactions: Option>>, +} + +impl<'a, T, R, S> Iterator for UnorderedIterator<'a, T, R, S> where + T: VerifiedTransaction, + R: Ready, + S: Scoring, +{ + type Item = Arc; + + fn next(&mut self) -> Option { + loop { + if let Some(transactions) = self.transactions.as_mut() { + if let Some(tx) = transactions.next() { + match self.ready.is_ready(&tx) { + Readiness::Ready => { + return Some(tx.transaction.clone()); + }, + state => trace!("[{:?}] Ignoring {:?} transaction.", tx.hash(), state), + } + } + } + + // otherwise fallback and try next sender + let next_sender = self.senders.next()?; + self.transactions = Some(next_sender.1.iter()); + } + } +} + + /// An iterator over all pending (ready) transactions. /// NOTE: the transactions are not removed from the queue. /// You might remove them later by calling `cull`. diff --git a/transaction-pool/src/tests/mod.rs b/transaction-pool/src/tests/mod.rs index 6edd60e60e..77c2528757 100644 --- a/transaction-pool/src/tests/mod.rs +++ b/transaction-pool/src/tests/mod.rs @@ -250,6 +250,66 @@ fn should_construct_pending() { assert_eq!(pending.next(), None); } +#[test] +fn should_return_unordered_iterator() { + // given + let b = TransactionBuilder::default(); + let mut txq = TestPool::default(); + + let tx0 = txq.import(b.tx().nonce(0).gas_price(5).new()).unwrap(); + let tx1 = txq.import(b.tx().nonce(1).gas_price(5).new()).unwrap(); + let tx2 = txq.import(b.tx().nonce(2).new()).unwrap(); + let tx3 = txq.import(b.tx().nonce(3).gas_price(4).new()).unwrap(); + //gap + txq.import(b.tx().nonce(5).new()).unwrap(); + + let tx5 = txq.import(b.tx().sender(1).nonce(0).new()).unwrap(); + let tx6 = txq.import(b.tx().sender(1).nonce(1).new()).unwrap(); + let tx7 = txq.import(b.tx().sender(1).nonce(2).new()).unwrap(); + let tx8 = txq.import(b.tx().sender(1).nonce(3).gas_price(4).new()).unwrap(); + // gap + txq.import(b.tx().sender(1).nonce(5).new()).unwrap(); + + let tx9 = txq.import(b.tx().sender(2).nonce(0).new()).unwrap(); + assert_eq!(txq.light_status().transaction_count, 11); + assert_eq!(txq.status(NonceReady::default()), Status { + stalled: 0, + pending: 9, + future: 2, + }); + assert_eq!(txq.status(NonceReady::new(1)), Status { + stalled: 3, + pending: 6, + future: 2, + }); + + // when + let all: Vec<_> = txq.unordered_pending(NonceReady::default()).collect(); + + let chain1 = vec![tx0, tx1, tx2, tx3]; + let chain2 = vec![tx5, tx6, tx7, tx8]; + let chain3 = vec![tx9]; + + assert_eq!(all.len(), chain1.len() + chain2.len() + chain3.len()); + + let mut options = vec![ + vec![chain1.clone(), chain2.clone(), chain3.clone()], + vec![chain2.clone(), chain1.clone(), chain3.clone()], + vec![chain2.clone(), chain3.clone(), chain1.clone()], + vec![chain3.clone(), chain2.clone(), chain1.clone()], + vec![chain3.clone(), chain1.clone(), chain2.clone()], + vec![chain1.clone(), chain3.clone(), chain2.clone()], + ].into_iter().map(|mut v| { + let mut first = v.pop().unwrap(); + for mut x in v { + first.append(&mut x); + } + first + }); + + assert!(options.any(|opt| all == opt)); +} + #[test] fn should_update_scoring_correctly() { // given -- GitLab From 0bb78814a60d1abc759ded380906a79cf3474f78 Mon Sep 17 00:00:00 2001 From: Vladyslav Lupashevskyi Date: Tue, 12 Jun 2018 10:31:14 +0300 Subject: [PATCH 124/152] Tx permission contract improvement (#8400) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Tx permission contract improvement * Use tuple for to address * Introduced ABI for deprecated tx permission contract * Improved ABI for tx permission contract with contract name, name hash and version * Introduced support for deprecated tx permission contract + fixed cache for the new version + introduced `target` for tx filter loging * Introduced test for the new tx permission contract version + old test renamed as deprecated * Removed empty lines * Introduced filter_only_sender return value in allowedTxTypes fn + improved caching * Introduced version checking for tx permission contract * Moved tx permission contract test genesis specs to separate files * handle queue import errors a bit more gracefully (#8385) * Some tweaks to main.rs for parity as a library (#8370) * Some tweaks to main.rs for parity as a library * Remove pub from PostExecutionAction * New Transaction Queue implementation (#8074) * Implementation of Verifier, Scoring and Ready. * Queue in progress. * TransactionPool. * Prepare for txpool release. * Miner refactor [WiP] * WiP reworking miner. * Make it compile. * Add some docs. * Split blockchain access to a separate file. * Work on miner API. * Fix ethcore tests. * Refactor miner interface for sealing/work packages. * Implement next nonce. * RPC compiles. * Implement couple of missing methdods for RPC. * Add transaction queue listeners. * Compiles! * Clean-up and parallelize. * Get rid of RefCell in header. * Revert "Get rid of RefCell in header." This reverts commit 0f2424c9b7319a786e1565ea2a8a6d801a21b4fb. * Override Sync requirement. * Fix status display. * Unify logging. * Extract some cheap checks. * Measurements and optimizations. * Fix scoring bug, heap size of bug and add cache * Disable tx queueing and parallel verification. * Make ethcore and ethcore-miner compile again. * Make RPC compile again. * Bunch of txpool tests. * Migrate transaction queue tests. * Nonce Cap * Nonce cap cache and tests. * Remove stale future transactions from the queue. * Optimize scoring and write some tests. * Simple penalization. * Clean up and support for different scoring algorithms. * Add CLI parameters for the new queue. * Remove banning queue. * Disable debug build. * Change per_sender limit to be 1% instead of 5% * Avoid cloning when propagating transactions. * Remove old todo. * Post-review fixes. * Fix miner options default. * Implement back ready transactions for light client. * Get rid of from_pending_block * Pass rejection reason. * Add more details to drop. * Rollback heap size of. * Avoid cloning hashes when propagating and include more details on rejection. * Fix tests. * Introduce nonces cache. * Remove uneccessary hashes allocation. * Lower the mem limit. * Re-enable parallel verification. * Add miner log. Don't check the type if not below min_gas_price. * Add more traces, fix disabling miner. * Fix creating pending blocks twice on AuRa authorities. * Fix tests. * re-use pending blocks in AuRa * Use reseal_min_period to prevent too frequent update_sealing. * Fix log to contain hash not sender. * Optimize local transactions. * Fix aura tests. * Update locks comments. * Get rid of unsafe Sync impl. * Review fixes. * Remove excessive matches. * Fix compilation errors. * Use new pool in private transactions. * Fix private-tx test. * Fix secret store tests. * Actually use gas_floor_target * Fix config tests. * Fix pool tests. * Address grumbles. * clarify that windows need perl and yasm (#8402) * Unify and limit rocksdb dependency places (#8371) * secret_store: remove kvdb_rocksdb dependency * cli: init db mod for open dispatch * cli: move db, client_db, restoration_db, secretstore_db to a separate mod * migration: rename to migration-rocksdb and remove ethcore-migrations * ethcore: re-move kvdb-rocksdb dep to test * mark test_helpers as test only and fix migration mod naming * Move restoration_db_handler to test_helpers_internal * Fix missing preambles in test_helpers_internal and rocksdb/helpers * Move test crates downward * Fix missing docs * cli, db::open_db: move each argument to a separate line * Use featuregate instead of dead code for `open_secretstore_db` * Move pathbuf import to open_secretstore_db Because it's only used there behind a feature gate * Use tokio::spawn in secret_store listener and fix Uri (#8373) * Directly wait for future to resolve in a threadpool * Ignore return value * Use path.starts_with instead of req_uri.is_absolute The later now means something else in hyper 0.11.. * Use tokio::spawn * typo: remove accidential unsafe impl * remove Tendermint extra_info due to seal inconsistencies (#8367) * More code refactoring to integrate Duration (#8322) * More code refactoring to integrate Duration * Fix typo * Fix tests * More test fix * tokio-core v0.1.16 -> v0.1.17 (#8408) * Replace legacy Rlp with UntrustedRlp and use in ethcore rlp views (#8316) * WIP * Replace Rlp with UntrustedRlp in views, explicity unwrap with expect First pass to get it to compile. Need to figure out whether to do this or to propogate Errors upstream, which would require many more changes to dependent code. If we do this way we are assuming that the views are always used in a context where the rlp is trusted to be valid e.g. when reading from our own DB. So need to fid out whether views are used with data received from an untrusted (e.g. extrernal peer). * Remove original Rlp impl, rename UntrustedRlp -> Rlp * Create rlp views with view! macro to record debug info Views are assumed to be over valid rlp, so if there is a decoding error we record where the view was created in the first place and report it in the expect * Use $crate in view! macro to avoid import, fix tests * Expect valid rlp in decode functions for now * Replace spaces with tabs in new file * Add doc tests for creating views with macro * Update rlp docs to reflect removing of UntrustedRlp * Replace UntrustedRlp usages in private-tx merge * Fix TODO comments (#8413) * update zip to 0.3 (#8381) * update zip to 0.3 * enable zip deflate feature * typo, docs parity_chainId: empty string -> None (#8434) * Fix receipts stripping. (#8414) * Changelogs for 1.9.6 and 1.10.1 (#8411) * Add changelog for 1.9.6 * Add Changelog for 1.10.1 * Move ethcore::Error to error_chain (#8386) * WIP * Convert Ethcore error to use error_chain * Use error_chain for ImportError and BlockImportError * Fix error pattern matches for error_chain in miner * Implement explicit From for AccountsError * Fix pattern matches for ErrorKinds * Handle ethcore error_chain in light client * Explicitly define Result type to avoid shadowing * Fix remaining Error pattern matches * Fix tab space formatting * Helps if the tests compile * Fix error chain matching after merge * remove From::from. (#8390) * Some tiny modifications. 1. fix some typo in the comment. 2. sort the order of methods in 'impl state::Backend for StateDB` * Remove the clone of code_cache, as it has been done in clone_basic. * remove From::from. It seems not necessary. * Use forked app_dirs crate for reverted Windows dir behavior (#8438) * Remove unused appdirs dependency in CLI * Use forked app_dirs crate for reverted Windows dir behavior * Permission fix (#8441) * Block reward contract (#8419) * engine: add block reward contract abi and helper client * aura: add support for block reward contract * engine: test block reward contract client * aura: test block reward contract * engine + aura: add missing docs * engine: share SystemCall type alias * aura: add transition for block reward contract * engine: fix example block reward contract source link and bytecode * Improve VM executor stack size estimation rules (#8439) * Improve VM executor stack size estimation rules * typo: docs add "(Debug build)" comment * Fix an off by one typo and set minimal stack size This avoids the case if `depth_threshold == max_depth`. Usually setting stack size to zero will just rebound it to platform minimal stack size, but we set it here just in case. * Use saturating_sub to avoid potential overflow * Private transactions processing error handling (#8431) * Integration test for private transaction returned * Do not interrupt verification in case of errors * Helpers use specified * Review comments fixed * Update Cargo hidapi-rs dependency (#8447) * Allow 32 bit pipelines to fail (#8454) * Disable 32bit tragets for gitlab * Rename linux pipelines * Update wasmi (#8452) * Return error in case eth_call returns VM errors (#8448) * Add VMError generator * Return executed exceptions in eth_call * ParityShell::open `Return result` (#8377) * start * add error handling for winapi * fix typo * fix warnings and windows errors * formatting * Address review comments * fix docker build (#8462) * Add changelog for 1.9.7 and 1.10.2 (#8460) * Add changelog for 1.9.7 * Add Changelog for 1.10.2 * Apply proper markdown * Run a spellchecker :) * Be pedantic about the 32-bit pipelines :) * fix typos in vm description comment (#8446) * Use rename_all for RichBlock and RichHeader serialization (#8471) * typo: fix a resolved TODO comment * Use rename_all instead of individual renames * Don't require write lock when fetching status. (#8481) * Bump master to 1.12 (#8477) * Bump master to 1.12 * Bump crates to 1.12 * Bump mac installer version to 1.12 * Update Gitlab scripts * Fix snap builds (#8483) * Update hardcodedSync for Ethereum, Kovan, and Ropsten (#8489) * Update wasmi and pwasm-utils (#8493) * Update wasmi to 0.2 New wasmi supports 32bit platforms and no longer requires a special feature to build for such platforms. * Update pwasm-utils to 0.1.5 * Remove three old warp boot nodes. (#8497) * Return error if RLP size of transaction exceeds the limit (#8473) * Return error if RLP size of transaction exceeds the limit * Review comments fixed * RLP check moved to verifier, corresponding pool test added * `duration_ns: u64 -> duration: Duration` (#8457) * duration_ns: u64 -> duration: Duration * format on millis {:.2} -> {} * Remove unused dependency `bigint` (#8505) * remove unused dependency bigint in * remove bigint in rpc_cli * Show imported messages for light client (#8517) * Directly return None if tracing is disabled (#8504) * Directly return None if tracing is disabled * Address gumbles: release read locks as fast as possible * Hardware Wallet trait (#8071) * getting started with replacing HardwareWalletManager * trezor and ledger impls the new trait with some drawbacks * Everything move to the new trait * It required lifetime annotations in the trait because [u8] in unsized * Lets now start moving entry point from HardwareWalletManager * rename trait to Wallet * move thread management to the actual wallets * Moved thread management to each respective Wallet * Cleaned up pub items that is needed to be pub * Wallet trait more or less finished * Cleaned up docs * fix tests * omit removed docs * fix spelling, naming och remove old comments * ledger test is broken, add correct logging format * So locally on my machine Linux Ubuntu 17.10 the test doesn't panic but on the CI server libusb::Context::new() fails which I don't understand because it has worked before * Additionally the ledger test is optional so I lean toward ignoring it the CI Server * ignore hardware tests by default * more verbose checking in ledger test * SecretStore: merge two types of errors into single one + Error::is_non_fatal (#8357) * SecretStore: error unify initial commit SecretStore: pass real error in error messages SecretStore: is_internal_error -> Error::is_non_fatal warnings SecretStore: ConsensusTemporaryUnreachable fix after merge removed comments removed comments SecretStore: updated HTTP error responses SecretStore: more ConsensusTemporaryUnreachable tests fix after rebase * fixed grumbles * use HashSet in tests * Enable WebAssembly and Byzantium for Ellaism (#8520) * Enable WebAssembly and Byzantium for Ellaism * Fix indentation * Remove empty lines * More changes for Android (#8421) * Transaction Pool improvements (#8470) * Don't use ethereum_types in transaction pool. * Hide internal insertion_id. * Fix tests. * Review grumbles. * Fetching logs by hash in blockchain database (#8463) * Fetch logs by hash in blockchain database * Fix tests * Add unit test for branch block logs fetching * Add docs that blocks must already be sorted * Handle branch block cases properly * typo: empty -> is_empty * Remove return_empty_if_none by using a closure * Use BTreeSet to avoid sorting again * Move is_canon to BlockChain * typo: pass value by reference * Use loop and wrap inside blocks to simplify the code Borrowed from https://github.com/paritytech/parity/pull/8463#discussion_r183453326 * typo: missed a comment * Pass on storage keys tracing to handle the case when it is not modified (#8491) * Pass on storage keys even if it is not modified * typo: account and storage query `to_pod_diff` builds both `touched_addresses` merge and storage keys merge. * Fix tests * Use state query directly because of suicided accounts * Fix a RefCell borrow issue * Add tests for unmodified storage trace * Address grumbles * typo: remove unwanted empty line * ensure_cached compiles with the original signature * Don't panic in import_block if invalid rlp (#8522) * Don't panic in import_block if invalid rlp * Remove redundant type annotation * Replace RLP header view usage with safe decoding Using the view will panic with invalid RLP. Here we use Rlp decoding directly which will return a `Result<_, DecoderError>`. While this path currently should not have any invalid RLP - it makes it safer if ever called with invalid RLP from other code paths. * Remove expect (#8536) * Remove expect and propagate rlp::DecoderErrors as TrieErrors * EIP 145: Bitwise shifting instructions in EVM (#8451) * Add SHL, SHR, SAR opcodes * Add have_bitwise_shifting schedule flag * Add all EIP tests for SHL * Add SHR implementation and tests * Implement SAR and add tests * Add eip145transition config param * Change map_or to map_or_else when possible * Consolidate crypto functionality in `ethcore-crypto`. (#8432) * Consolidate crypto functionality in `ethcore-crypto`. - Move `ecdh`/`ecies` modules to `ethkey`. - Refactor `ethcore-crypto` to use file per module. - Replace `subtle` with `ethcore_crypto::is_equal`. - Add `aes_gcm` module to `ethcore-crypto`. * Rename `aes::{encrypt,decrypt,decrypt_cbc}` ... ... to `aes::{encrypt_128_ctr,decrypt_128_ctr,decrypt_128_cbc}`. * ethcore, rpc, machine: refactor block reward application and tracing (#8490) * Keep all enacted blocks notify in order (#8524) * Keep all enacted blocks notify in order * Collect is unnecessary * Update ChainNotify to use ChainRouteType * Fix all ethcore fn defs * Wrap the type within ChainRoute * Fix private-tx and sync api * Fix secret_store API * Fix updater API * Fix rpc api * Fix informant api * Eagerly cache enacted/retracted and remove contain_enacted/retracted * Fix indent * tests: should use full expr form for struct constructor * Use into_enacted_retracted to further avoid copy * typo: not a function * rpc/tests: ChainRoute -> ChainRoute::new * Node table sorting according to last contact data (#8541) * network-devp2p: sort nodes in node table using last contact data * network-devp2p: rename node contact types in node table json output * network-devp2p: fix node table tests * network-devp2p: note node failure when failed to establish connection * network-devp2p: handle UselessPeer error * network-devp2p: note failure when marking node as useless * Rlp decode returns Result (#8527) rlp::decode returns Result Make a best effort to handle decoding errors gracefully throughout the code, using `expect` where the value is guaranteed to be valid (and in other places where it makes sense). * Parity as a library (#8412) * Parity as a library * Fix concerns * Allow using a null on_client_restart_cb * Fix more concerns * Test the C library in test.sh * Reduce CMake version to 3.5 * Move the clib test before cargo test * Add println in test * Trace precompiled contracts when the transfer value is not zero (#8486) * Trace precompiled contracts when the transfer value is not zero * Add tests for precompiled CALL tracing * Use byzantium test machine for the new test * Add notes in comments on why we don't trace all precompileds * Use is_transferred instead of transferred * Don't block sync when importing old blocks (#8530) * Alter IO queueing. * Don't require IoMessages to be Clone * Ancient blocks imported via IoChannel. * Get rid of private transactions io message. * Get rid of deadlock and fix disconnected handler. * Revert to old disconnect condition. * Fix tests. * Fix deadlock. * Make trace-time publishable. (#8568) * Remove State::replace_backend (#8569) * Refactoring `ethcore-sync` - Fixing warp-sync barrier (#8543) * Start dividing sync chain : first supplier method * WIP - updated chain sync supplier * Finish refactoring the Chain Sync Supplier * Create Chain Sync Requester * Add Propagator for Chain Sync * Add the Chain Sync Handler * Move tests from mod -> handler * Move tests to propagator * Refactor SyncRequester arguments * Refactoring peer fork header handler * Fix wrong highest block number in snapshot sync * Small refactor... * Address PR grumbles * Retry failed CI job * Fix tests * PR Grumbles * Decoding headers can fail (#8570) * rlp::decode returns Result * Fix journaldb to handle rlp::decode Result * Fix ethcore to work with rlp::decode returning Result * Light client handles rlp::decode returning Result * Fix tests in rlp_derive * Fix tests * Cleanup * cleanup * Allow panic rather than breaking out of iterator * Let decoding failures when reading from disk blow up * syntax * Fix the trivial grumbles * Fix failing tests * Make Account::from_rlp return Result * Syntx, sigh * Temp-fix for decoding failures * Header::decode returns Result Handle new return type throughout the code base. * Do not continue reading from the DB when a value could not be read * Fix tests * Handle header decoding in light_sync * Handling header decoding errors * Let the DecodeError bubble up unchanged * Remove redundant error conversion * Update CHANGELOG for 1.9, 1.10, and 1.11 (#8556) * Move changelog for 1.10.x * Mark 1.9 EOL * Prepare changelog for 1.10.3 stable * Prepare changelog for 1.11.0 stable * Update changelogs * Update CHANGELOG for 1.10.3 beta * Update CHANGELOG for 1.11.0 beta * Update CHANGELOG for 1.11.0 beta * Update CHANGELOG for 1.11.0 beta * Format changelog * Handle socket address parsing errors (#8545) Unpack errors and check for io::ErrorKind::InvalidInput and return our own AddressParse error. Remove the foreign link to std::net::AddrParseError and add an `impl From` for that error. Test parsing properly. * Remove unnecessary cloning in overwrite_with (#8580) * Remove unnecessary cloning in overwrite_with * Remove into_iter * changelog nit (#8585) * Rename `whisper-cli binary` to `whisper` (#8579) * rename whisper-cli binary to whisper * fix tests * Add whisper CLI to the pipelines (#8578) * Add whisper CLI to the pipelines * Address todo, ref #8579 * Added Dockerfile for alpine linux by @andresilva, closes #3565 (#8587) * Changelog and Readme (#8591) * Move changelog for 1.10.x * Mark 1.9 EOL * Prepare changelog for 1.10.3 stable * Prepare changelog for 1.11.0 stable * Update changelogs * Update CHANGELOG for 1.10.3 beta * Update CHANGELOG for 1.11.0 beta * Update CHANGELOG for 1.11.0 beta * Update CHANGELOG for 1.11.0 beta * Format changelog * Update README for 1.11 * Fix typo * Attempt to fix intermittent test failures (#8584) Occasionally should_return_correct_nonces_when_dropped_because_of_limit fails, possibly because of multiple threads competing to finish. See CI logs here for an example: https://gitlab.parity.io/parity/parity/-/jobs/86738 * Make mio optional in ethcore-io (#8537) * Make mio optional in ethcore-io * Add some annotations, plus a check for features * Increase timer for test * Fix Parity UI link (#8600) Fix link https://github.com/paritytech/parity/issues/8599 * fix compiler warning (#8590) * Block::decode() returns Result (#8586) * block_header can fail so return Result (#8581) * block_header can fail so return Result * Restore previous return type based on feedback * Fix failing doc tests running on non-code * Remove inject.js server-side injection for dapps (#8539) * Remove inject.js server-side injection for dapps * Remove dapps test `should_inject_js` Parity doesn't inject a