From 9436e88d27adb1152607367a1be5ee57e5efadb5 Mon Sep 17 00:00:00 2001 From: lihuafeng <31607114+EighteenZi@users.noreply.github.com> Date: Mon, 9 Apr 2018 17:35:54 +0800 Subject: [PATCH 01/25] remove the clone operation of code_cache (#8334) * 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. --- ethcore/src/state/account.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/ethcore/src/state/account.rs b/ethcore/src/state/account.rs index e08ad7b1854..9d72ed158cf 100755 --- a/ethcore/src/state/account.rs +++ b/ethcore/src/state/account.rs @@ -424,7 +424,6 @@ impl Account { pub fn clone_dirty(&self) -> Account { let mut account = self.clone_basic(); account.storage_changes = self.storage_changes.clone(); - account.code_cache = self.code_cache.clone(); account } From c039ab79b59e418a210f630a5ae485c39171f0e4 Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Mon, 9 Apr 2018 20:21:37 +0800 Subject: [PATCH 02/25] Decouple rocksdb dependency from ethcore (#8320) * Move client DB opening logic to CLI * Move restoration db open logic to CLI This adds KeyValueDBHandler which handles opening a new database, thus allow us to move the restoration db open logic out of ethcore. * Move rocksdb's compactionprofile conversion to CLI * Move kvdb_rocksdb as test dependency for ethcore * Fix tests due to interface change * Fix service tests * Remove unused migration dep for ethcore --- Cargo.lock | 1 - ethcore/Cargo.toml | 3 +- ethcore/service/Cargo.toml | 2 +- ethcore/service/src/lib.rs | 4 +- ethcore/service/src/service.rs | 61 +++++++++++++++++---------- ethcore/src/client/config.rs | 13 ------ ethcore/src/lib.rs | 5 ++- ethcore/src/snapshot/service.rs | 27 ++++++------ ethcore/src/snapshot/tests/service.rs | 6 +-- ethcore/src/tests/helpers.rs | 19 +++++++++ parity/blockchain.rs | 22 +++++++--- parity/export_hardcoded_sync.rs | 4 +- parity/helpers.rs | 52 ++++++++++++++++++++++- parity/run.rs | 13 ++++-- parity/snapshot.rs | 11 +++-- util/kvdb/src/lib.rs | 9 ++++ 16 files changed, 176 insertions(+), 76 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c66c6147295..403b468f843 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -535,7 +535,6 @@ dependencies = [ "macros 0.1.0", "memory-cache 0.1.0", "memorydb 0.1.1", - "migration 0.1.0", "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)", "parity-machine 0.1.0", diff --git a/ethcore/Cargo.toml b/ethcore/Cargo.toml index ba984f315ff..9c61fd8ea4b 100644 --- a/ethcore/Cargo.toml +++ b/ethcore/Cargo.toml @@ -51,12 +51,10 @@ rlp = { path = "../util/rlp" } rlp_compress = { path = "../util/rlp_compress" } rlp_derive = { path = "../util/rlp_derive" } kvdb = { path = "../util/kvdb" } -kvdb-rocksdb = { path = "../util/kvdb-rocksdb" } kvdb-memorydb = { path = "../util/kvdb-memorydb" } util-error = { path = "../util/error" } snappy = { git = "https://github.com/paritytech/rust-snappy" } stop-guard = { path = "../util/stop-guard" } -migration = { path = "../util/migration" } macros = { path = "../util/macros" } rust-crypto = "0.2.34" rustc-hex = "1.0" @@ -74,6 +72,7 @@ journaldb = { path = "../util/journaldb" } [dev-dependencies] tempdir = "0.3" trie-standardmap = { path = "../util/trie-standardmap" } +kvdb-rocksdb = { path = "../util/kvdb-rocksdb" } [features] evm-debug = ["slow-blocks"] diff --git a/ethcore/service/Cargo.toml b/ethcore/service/Cargo.toml index 634769d0b54..4b53f5d00a5 100644 --- a/ethcore/service/Cargo.toml +++ b/ethcore/service/Cargo.toml @@ -8,9 +8,9 @@ ansi_term = "0.10" ethcore = { path = ".." } ethcore-io = { path = "../../util/io" } kvdb = { path = "../../util/kvdb" } -kvdb-rocksdb = { path = "../../util/kvdb-rocksdb" } log = "0.3" stop-guard = { path = "../../util/stop-guard" } [dev-dependencies] tempdir = "0.3" +kvdb-rocksdb = { path = "../../util/kvdb-rocksdb" } diff --git a/ethcore/service/src/lib.rs b/ethcore/service/src/lib.rs index 907009ba324..83d9a8fe10c 100644 --- a/ethcore/service/src/lib.rs +++ b/ethcore/service/src/lib.rs @@ -18,7 +18,6 @@ extern crate ansi_term; extern crate ethcore; extern crate ethcore_io as io; extern crate kvdb; -extern crate kvdb_rocksdb; extern crate stop_guard; #[macro_use] @@ -27,6 +26,9 @@ extern crate log; #[cfg(test)] extern crate tempdir; +#[cfg(test)] +extern crate kvdb_rocksdb; + mod service; pub use service::ClientService; diff --git a/ethcore/service/src/service.rs b/ethcore/service/src/service.rs index f190d6e6ac3..4337996e2b0 100644 --- a/ethcore/service/src/service.rs +++ b/ethcore/service/src/service.rs @@ -21,12 +21,10 @@ use std::path::Path; use ansi_term::Colour; use io::{IoContext, TimerToken, IoHandler, IoService, IoError}; -use kvdb::KeyValueDB; -use kvdb_rocksdb::{Database, DatabaseConfig}; +use kvdb::{KeyValueDB, KeyValueDBHandler}; use stop_guard::StopGuard; -use ethcore::client::{self, Client, ClientConfig, ChainNotify, ClientIoMessage}; -use ethcore::db; +use ethcore::client::{Client, ClientConfig, ChainNotify, ClientIoMessage}; use ethcore::error::Error; use ethcore::miner::Miner; use ethcore::snapshot::service::{Service as SnapshotService, ServiceParams as SnapServiceParams}; @@ -38,7 +36,7 @@ pub struct ClientService { io_service: Arc>, client: Arc, snapshot: Arc, - database: Arc, + database: Arc, _stop_guard: StopGuard, } @@ -47,8 +45,9 @@ impl ClientService { pub fn start( config: ClientConfig, spec: &Spec, - client_path: &Path, + client_db: Arc, snapshot_path: &Path, + restoration_db_handler: Box, _ipc_path: &Path, miner: Arc, ) -> Result @@ -57,25 +56,13 @@ impl ClientService { info!("Configured for {} using {} engine", Colour::White.bold().paint(spec.name.clone()), Colour::Yellow.bold().paint(spec.engine.name())); - let mut db_config = DatabaseConfig::with_columns(db::NUM_COLUMNS); - - db_config.memory_budget = config.db_cache_size; - db_config.compaction = config.db_compaction.compaction_profile(client_path); - db_config.wal = config.db_wal; - - let db = Arc::new(Database::open( - &db_config, - &client_path.to_str().expect("DB path could not be converted to string.") - ).map_err(client::Error::Database)?); - - let pruning = config.pruning; - let client = Client::new(config, &spec, db.clone(), miner, io_service.channel())?; + let client = Client::new(config, &spec, client_db.clone(), miner, io_service.channel())?; let snapshot_params = SnapServiceParams { engine: spec.engine.clone(), genesis_block: spec.genesis_block(), - db_config: db_config.clone(), + restoration_db_handler: restoration_db_handler, pruning: pruning, channel: io_service.channel(), snapshot_root: snapshot_path.into(), @@ -97,7 +84,7 @@ impl ClientService { io_service: Arc::new(io_service), client: client, snapshot: snapshot, - database: db, + database: client_db, _stop_guard: stop_guard, }) } @@ -208,6 +195,9 @@ mod tests { use ethcore::client::ClientConfig; use ethcore::miner::Miner; use ethcore::spec::Spec; + use ethcore::db::NUM_COLUMNS; + use kvdb::Error; + use kvdb_rocksdb::{Database, DatabaseConfig, CompactionProfile}; use super::*; #[test] @@ -216,12 +206,39 @@ mod tests { let client_path = tempdir.path().join("client"); let snapshot_path = tempdir.path().join("snapshot"); + let client_config = ClientConfig::default(); + let mut client_db_config = DatabaseConfig::with_columns(NUM_COLUMNS); + + client_db_config.memory_budget = client_config.db_cache_size; + client_db_config.compaction = CompactionProfile::auto(&client_path); + client_db_config.wal = client_config.db_wal; + + let client_db = Arc::new(Database::open( + &client_db_config, + &client_path.to_str().expect("DB path could not be converted to string.") + ).unwrap()); + + struct RestorationDBHandler { + config: DatabaseConfig, + } + + impl KeyValueDBHandler for RestorationDBHandler { + fn open(&self, db_path: &Path) -> Result, Error> { + Ok(Arc::new(Database::open(&self.config, &db_path.to_string_lossy())?)) + } + } + + let restoration_db_handler = Box::new(RestorationDBHandler { + config: client_db_config, + }); + let spec = Spec::new_test(); let service = ClientService::start( ClientConfig::default(), &spec, - &client_path, + client_db, &snapshot_path, + restoration_db_handler, tempdir.path(), Arc::new(Miner::with_spec(&spec)), ); diff --git a/ethcore/src/client/config.rs b/ethcore/src/client/config.rs index b337bf4319e..9787f822a4d 100644 --- a/ethcore/src/client/config.rs +++ b/ethcore/src/client/config.rs @@ -15,13 +15,11 @@ // along with Parity. If not, see . use std::str::FromStr; -use std::path::Path; use std::fmt::{Display, Formatter, Error as FmtError}; use mode::Mode as IpcMode; use verification::{VerifierType, QueueConfig}; use journaldb; -use kvdb_rocksdb::CompactionProfile; pub use std::time::Duration; pub use blockchain::Config as BlockChainConfig; @@ -45,17 +43,6 @@ impl Default for DatabaseCompactionProfile { } } -impl DatabaseCompactionProfile { - /// Returns corresponding compaction profile. - pub fn compaction_profile(&self, db_path: &Path) -> CompactionProfile { - match *self { - DatabaseCompactionProfile::Auto => CompactionProfile::auto(db_path), - DatabaseCompactionProfile::SSD => CompactionProfile::ssd(), - DatabaseCompactionProfile::HDD => CompactionProfile::hdd(), - } - } -} - impl FromStr for DatabaseCompactionProfile { type Err = String; diff --git a/ethcore/src/lib.rs b/ethcore/src/lib.rs index 43c3336f6f8..d822195d321 100644 --- a/ethcore/src/lib.rs +++ b/ethcore/src/lib.rs @@ -93,11 +93,9 @@ extern crate triehash; extern crate ansi_term; extern crate unexpected; extern crate kvdb; -extern crate kvdb_rocksdb; extern crate kvdb_memorydb; extern crate util_error; extern crate snappy; -extern crate migration; extern crate ethabi; #[macro_use] @@ -130,6 +128,9 @@ extern crate trace_time; #[cfg_attr(test, macro_use)] extern crate evm; +#[cfg(test)] +extern crate kvdb_rocksdb; + pub extern crate ethstore; pub mod account_provider; diff --git a/ethcore/src/snapshot/service.rs b/ethcore/src/snapshot/service.rs index 7def518f357..fad150645db 100644 --- a/ethcore/src/snapshot/service.rs +++ b/ethcore/src/snapshot/service.rs @@ -39,7 +39,7 @@ use parking_lot::{Mutex, RwLock, RwLockReadGuard}; use util_error::UtilError; use bytes::Bytes; use journaldb::Algorithm; -use kvdb_rocksdb::{Database, DatabaseConfig}; +use kvdb::{KeyValueDB, KeyValueDBHandler}; use snappy; /// Helper for removing directories in case of error. @@ -79,14 +79,13 @@ struct Restoration { snappy_buffer: Bytes, final_state_root: H256, guard: Guard, - db: Arc, + db: Arc, } struct RestorationParams<'a> { manifest: ManifestData, // manifest to base restoration on. pruning: Algorithm, // pruning algorithm for the database. - db_path: PathBuf, // database path - db_config: &'a DatabaseConfig, // configuration for the database. + db: Arc, // database writer: Option, // writer for recovered snapshot. genesis: &'a [u8], // genesis block of the chain. guard: Guard, // guard for the restoration directory. @@ -101,8 +100,7 @@ impl Restoration { let state_chunks = manifest.state_hashes.iter().cloned().collect(); let block_chunks = manifest.block_hashes.iter().cloned().collect(); - let raw_db = Arc::new(Database::open(params.db_config, &*params.db_path.to_string_lossy()) - .map_err(UtilError::from)?); + let raw_db = params.db; let chain = BlockChain::new(Default::default(), params.genesis, raw_db.clone()); let components = params.engine.snapshot_components() @@ -211,10 +209,10 @@ pub struct ServiceParams { pub engine: Arc, /// The chain's genesis block. pub genesis_block: Bytes, - /// Database configuration options. - pub db_config: DatabaseConfig, /// State pruning algorithm. pub pruning: Algorithm, + /// Handler for opening a restoration DB. + pub restoration_db_handler: Box, /// Async IO channel for sending messages. pub channel: Channel, /// The directory to put snapshots in. @@ -228,8 +226,8 @@ pub struct ServiceParams { /// This controls taking snapshots and restoring from them. pub struct Service { restoration: Mutex>, + restoration_db_handler: Box, snapshot_root: PathBuf, - db_config: DatabaseConfig, io_channel: Mutex, pruning: Algorithm, status: Mutex, @@ -249,8 +247,8 @@ impl Service { pub fn new(params: ServiceParams) -> Result { let mut service = Service { restoration: Mutex::new(None), + restoration_db_handler: params.restoration_db_handler, snapshot_root: params.snapshot_root, - db_config: params.db_config, io_channel: Mutex::new(params.channel), pruning: params.pruning, status: Mutex::new(RestorationStatus::Inactive), @@ -437,8 +435,7 @@ impl Service { let params = RestorationParams { manifest: manifest, pruning: self.pruning, - db_path: self.restoration_db(), - db_config: &self.db_config, + db: self.restoration_db_handler.open(&self.restoration_db())?, writer: writer, genesis: &self.genesis_block, guard: Guard::new(rest_dir), @@ -638,6 +635,7 @@ mod tests { use snapshot::{ManifestData, RestorationStatus, SnapshotService}; use super::*; use tempdir::TempDir; + use tests::helpers::restoration_db_handler; struct NoopDBRestore; impl DatabaseRestore for NoopDBRestore { @@ -657,7 +655,7 @@ mod tests { let snapshot_params = ServiceParams { engine: spec.engine.clone(), genesis_block: spec.genesis_block(), - db_config: Default::default(), + restoration_db_handler: restoration_db_handler(Default::default()), pruning: Algorithm::Archive, channel: service.channel(), snapshot_root: dir, @@ -709,8 +707,7 @@ mod tests { block_hash: H256::default(), }, pruning: Algorithm::Archive, - db_path: tempdir.path().to_owned(), - db_config: &db_config, + db: restoration_db_handler(db_config).open(&tempdir.path().to_owned()).unwrap(), writer: None, genesis: &gb, guard: Guard::benign(), diff --git a/ethcore/src/snapshot/tests/service.rs b/ethcore/src/snapshot/tests/service.rs index 52b4b3cc979..4548741f399 100644 --- a/ethcore/src/snapshot/tests/service.rs +++ b/ethcore/src/snapshot/tests/service.rs @@ -24,7 +24,7 @@ use ids::BlockId; use snapshot::service::{Service, ServiceParams}; use snapshot::{self, ManifestData, SnapshotService}; use spec::Spec; -use tests::helpers::generate_dummy_client_with_spec_and_data; +use tests::helpers::{generate_dummy_client_with_spec_and_data, restoration_db_handler}; use io::IoChannel; use kvdb_rocksdb::{Database, DatabaseConfig}; @@ -65,7 +65,7 @@ fn restored_is_equivalent() { let service_params = ServiceParams { engine: spec.engine.clone(), genesis_block: spec.genesis_block(), - db_config: db_config, + restoration_db_handler: restoration_db_handler(db_config), pruning: ::journaldb::Algorithm::Archive, channel: IoChannel::disconnected(), snapshot_root: path, @@ -107,7 +107,7 @@ fn guards_delete_folders() { let service_params = ServiceParams { engine: spec.engine.clone(), genesis_block: spec.genesis_block(), - db_config: DatabaseConfig::with_columns(::db::NUM_COLUMNS), + restoration_db_handler: restoration_db_handler(DatabaseConfig::with_columns(::db::NUM_COLUMNS)), pruning: ::journaldb::Algorithm::Archive, channel: IoChannel::disconnected(), snapshot_root: tempdir.path().to_owned(), diff --git a/ethcore/src/tests/helpers.rs b/ethcore/src/tests/helpers.rs index fd37164dcbb..14dcf3630b0 100644 --- a/ethcore/src/tests/helpers.rs +++ b/ethcore/src/tests/helpers.rs @@ -33,8 +33,11 @@ use spec::Spec; use state_db::StateDB; use state::*; use std::sync::Arc; +use std::path::Path; use transaction::{Action, Transaction, SignedTransaction}; use views::BlockView; +use kvdb::{KeyValueDB, KeyValueDBHandler}; +use kvdb_rocksdb::{Database, DatabaseConfig}; pub fn create_test_block(header: &Header) -> Bytes { let mut rlp = RlpStream::new_list(3); @@ -349,3 +352,19 @@ impl ChainNotify for TestNotify { self.messages.write().push(data); } } + +pub fn restoration_db_handler(config: DatabaseConfig) -> Box { + use kvdb::Error; + + struct RestorationDBHandler { + config: DatabaseConfig, + } + + impl KeyValueDBHandler for RestorationDBHandler { + fn open(&self, db_path: &Path) -> Result, Error> { + Ok(Arc::new(Database::open(&self.config, &db_path.to_string_lossy())?)) + } + } + + Box::new(RestorationDBHandler { config }) +} diff --git a/parity/blockchain.rs b/parity/blockchain.rs index 9dab9069d78..26eae459765 100644 --- a/parity/blockchain.rs +++ b/parity/blockchain.rs @@ -35,7 +35,7 @@ use cache::CacheConfig; use informant::{Informant, FullNodeInformantData, MillisecondDuration}; use kvdb_rocksdb::{Database, DatabaseConfig}; use params::{SpecType, Pruning, Switch, tracing_switch_to_bool, fatdb_switch_to_bool}; -use helpers::{to_client_config, execute_upgrades}; +use helpers::{to_client_config, execute_upgrades, open_client_db, client_db_config, restoration_db_handler, compaction_profile}; use dir::Directories; use user_defaults::UserDefaults; use fdlimit; @@ -186,7 +186,7 @@ fn execute_import_light(cmd: ImportBlockchain) -> Result<(), String> { let client_path = db_dirs.client_path(algorithm); // execute upgrades - let compaction = cmd.compaction.compaction_profile(db_dirs.db_root_path().as_path()); + let compaction = compaction_profile(&cmd.compaction, db_dirs.db_root_path().as_path()); execute_upgrades(&cmd.dirs.base, &db_dirs, algorithm, compaction)?; // create dirs used by parity @@ -352,7 +352,7 @@ fn execute_import(cmd: ImportBlockchain) -> Result<(), String> { let snapshot_path = db_dirs.snapshot_path(); // execute upgrades - execute_upgrades(&cmd.dirs.base, &db_dirs, algorithm, cmd.compaction.compaction_profile(db_dirs.db_root_path().as_path()))?; + execute_upgrades(&cmd.dirs.base, &db_dirs, algorithm, compaction_profile(&cmd.compaction, db_dirs.db_root_path().as_path()))?; // create dirs used by parity cmd.dirs.create_dirs(false, false, false)?; @@ -376,12 +376,17 @@ fn execute_import(cmd: ImportBlockchain) -> Result<(), String> { client_config.queue.verifier_settings = cmd.verifier_settings; + let client_db_config = client_db_config(&client_path, &client_config); + let client_db = open_client_db(&client_path, &client_db_config)?; + let restoration_db_handler = restoration_db_handler(client_db_config); + // build client let service = ClientService::start( client_config, &spec, - &client_path, + client_db, &snapshot_path, + restoration_db_handler, &cmd.dirs.ipc_path(), Arc::new(Miner::with_spec(&spec)), ).map_err(|e| format!("Client service error: {:?}", e))?; @@ -537,7 +542,7 @@ fn start_client( let snapshot_path = db_dirs.snapshot_path(); // execute upgrades - execute_upgrades(&dirs.base, &db_dirs, algorithm, compaction.compaction_profile(db_dirs.db_root_path().as_path()))?; + execute_upgrades(&dirs.base, &db_dirs, algorithm, compaction_profile(&compaction, db_dirs.db_root_path().as_path()))?; // create dirs used by parity dirs.create_dirs(false, false, false)?; @@ -559,11 +564,16 @@ fn start_client( true, ); + let client_db_config = client_db_config(&client_path, &client_config); + let client_db = open_client_db(&client_path, &client_db_config)?; + let restoration_db_handler = restoration_db_handler(client_db_config); + let service = ClientService::start( client_config, &spec, - &client_path, + client_db, &snapshot_path, + restoration_db_handler, &dirs.ipc_path(), Arc::new(Miner::with_spec(&spec)), ).map_err(|e| format!("Client service error: {:?}", e))?; diff --git a/parity/export_hardcoded_sync.rs b/parity/export_hardcoded_sync.rs index 7a48c0592e9..accb6159fa3 100644 --- a/parity/export_hardcoded_sync.rs +++ b/parity/export_hardcoded_sync.rs @@ -25,7 +25,7 @@ use light::client::fetch::Unavailable as UnavailableDataFetcher; use light::Cache as LightDataCache; use params::{SpecType, Pruning}; -use helpers::execute_upgrades; +use helpers::{execute_upgrades, compaction_profile}; use dir::Directories; use cache::CacheConfig; use user_defaults::UserDefaults; @@ -66,7 +66,7 @@ pub fn execute(cmd: ExportHsyncCmd) -> Result { // select pruning algorithm let algorithm = cmd.pruning.to_algorithm(&user_defaults); - let compaction = cmd.compaction.compaction_profile(db_dirs.db_root_path().as_path()); + let compaction = compaction_profile(&cmd.compaction, db_dirs.db_root_path().as_path()); // execute upgrades execute_upgrades(&cmd.dirs.base, &db_dirs, algorithm, compaction.clone())?; diff --git a/parity/helpers.rs b/parity/helpers.rs index 959dddba92d..1c6c70cdae9 100644 --- a/parity/helpers.rs +++ b/parity/helpers.rs @@ -18,11 +18,13 @@ use std::io; use std::io::{Write, BufReader, BufRead}; use std::time::Duration; use std::fs::File; +use std::sync::Arc; +use std::path::Path; use ethereum_types::{U256, clean_0x, Address}; -use kvdb_rocksdb::CompactionProfile; use journaldb::Algorithm; use ethcore::client::{Mode, BlockId, VMType, DatabaseCompactionProfile, ClientConfig, VerifierType}; use ethcore::miner::{PendingSet, GasLimit}; +use ethcore::db::NUM_COLUMNS; use miner::transaction_queue::PrioritizationStrategy; use cache::CacheConfig; use dir::DatabaseDirectories; @@ -30,6 +32,8 @@ use dir::helpers::replace_home; use upgrade::{upgrade, upgrade_data_paths}; use migration::migrate; use ethsync::{validate_node_url, self}; +use kvdb::{KeyValueDB, KeyValueDBHandler}; +use kvdb_rocksdb::{Database, DatabaseConfig, CompactionProfile}; use path; pub fn to_duration(s: &str) -> Result { @@ -255,6 +259,52 @@ pub fn to_client_config( client_config } +// We assume client db has similar config as restoration db. +pub fn client_db_config(client_path: &Path, client_config: &ClientConfig) -> DatabaseConfig { + let mut client_db_config = DatabaseConfig::with_columns(NUM_COLUMNS); + + client_db_config.memory_budget = client_config.db_cache_size; + client_db_config.compaction = compaction_profile(&client_config.db_compaction, &client_path); + client_db_config.wal = client_config.db_wal; + + client_db_config +} + +pub fn open_client_db(client_path: &Path, client_db_config: &DatabaseConfig) -> Result, String> { + let client_db = Arc::new(Database::open( + &client_db_config, + &client_path.to_str().expect("DB path could not be converted to string.") + ).map_err(|e| format!("Client service database error: {:?}", e))?); + + Ok(client_db) +} + +pub fn restoration_db_handler(client_db_config: DatabaseConfig) -> Box { + use kvdb::Error; + + struct RestorationDBHandler { + config: DatabaseConfig, + } + + impl KeyValueDBHandler for RestorationDBHandler { + fn open(&self, db_path: &Path) -> Result, Error> { + Ok(Arc::new(Database::open(&self.config, &db_path.to_string_lossy())?)) + } + } + + Box::new(RestorationDBHandler { + config: client_db_config, + }) +} + +pub fn compaction_profile(profile: &DatabaseCompactionProfile, db_path: &Path) -> CompactionProfile { + match profile { + &DatabaseCompactionProfile::Auto => CompactionProfile::auto(db_path), + &DatabaseCompactionProfile::SSD => CompactionProfile::ssd(), + &DatabaseCompactionProfile::HDD => CompactionProfile::hdd(), + } +} + pub fn execute_upgrades( base_path: &str, dirs: &DatabaseDirectories, diff --git a/parity/run.rs b/parity/run.rs index 7baeaaed340..816ddd4dd30 100644 --- a/parity/run.rs +++ b/parity/run.rs @@ -55,7 +55,7 @@ use params::{ SpecType, Pruning, AccountsConfig, GasPricerConfig, MinerExtras, Switch, tracing_switch_to_bool, fatdb_switch_to_bool, mode_switch_to_bool }; -use helpers::{to_client_config, execute_upgrades, passwords_from_files}; +use helpers::{to_client_config, execute_upgrades, passwords_from_files, client_db_config, open_client_db, restoration_db_handler, compaction_profile}; use upgrade::upgrade_key_location; use dir::{Directories, DatabaseDirectories}; use cache::CacheConfig; @@ -206,7 +206,7 @@ fn execute_light_impl(cmd: RunCmd, logger: Arc) -> Result(cmd: RunCmd, logger: Arc, on_client_rq: let snapshot_path = db_dirs.snapshot_path(); // execute upgrades - execute_upgrades(&cmd.dirs.base, &db_dirs, algorithm, cmd.compaction.compaction_profile(db_dirs.db_root_path().as_path()))?; + execute_upgrades(&cmd.dirs.base, &db_dirs, algorithm, compaction_profile(&cmd.compaction, db_dirs.db_root_path().as_path()))?; // create dirs used by parity cmd.dirs.create_dirs(cmd.dapps_conf.enabled, cmd.ui_conf.enabled, cmd.secretstore_conf.enabled)?; @@ -609,12 +609,17 @@ fn execute_impl(cmd: RunCmd, logger: Arc, on_client_rq: // set network path. net_conf.net_config_path = Some(db_dirs.network_path().to_string_lossy().into_owned()); + let client_db_config = client_db_config(&client_path, &client_config); + let client_db = open_client_db(&client_path, &client_db_config)?; + let restoration_db_handler = restoration_db_handler(client_db_config); + // create client service. let service = ClientService::start( client_config, &spec, - &client_path, + client_db, &snapshot_path, + restoration_db_handler, &cmd.dirs.ipc_path(), miner.clone(), ).map_err(|e| format!("Client service error: {:?}", e))?; diff --git a/parity/snapshot.rs b/parity/snapshot.rs index bda5059f7e5..ae7a0698b74 100644 --- a/parity/snapshot.rs +++ b/parity/snapshot.rs @@ -31,7 +31,7 @@ use ethcore_service::ClientService; use cache::CacheConfig; use params::{SpecType, Pruning, Switch, tracing_switch_to_bool, fatdb_switch_to_bool}; -use helpers::{to_client_config, execute_upgrades}; +use helpers::{to_client_config, execute_upgrades, client_db_config, open_client_db, restoration_db_handler, compaction_profile}; use dir::Directories; use user_defaults::UserDefaults; use fdlimit; @@ -162,7 +162,7 @@ impl SnapshotCommand { let snapshot_path = db_dirs.snapshot_path(); // execute upgrades - execute_upgrades(&self.dirs.base, &db_dirs, algorithm, self.compaction.compaction_profile(db_dirs.db_root_path().as_path()))?; + execute_upgrades(&self.dirs.base, &db_dirs, algorithm, compaction_profile(&self.compaction, db_dirs.db_root_path().as_path()))?; // prepare client config let client_config = to_client_config( @@ -181,11 +181,16 @@ impl SnapshotCommand { true ); + let client_db_config = client_db_config(&client_path, &client_config); + let client_db = open_client_db(&client_path, &client_db_config)?; + let restoration_db_handler = restoration_db_handler(client_db_config); + let service = ClientService::start( client_config, &spec, - &client_path, + client_db, &snapshot_path, + restoration_db_handler, &self.dirs.ipc_path(), Arc::new(Miner::with_spec(&spec)) ).map_err(|e| format!("Client service error: {:?}", e))?; diff --git a/util/kvdb/src/lib.rs b/util/kvdb/src/lib.rs index 6a8412c0e8c..9ed1038bffd 100644 --- a/util/kvdb/src/lib.rs +++ b/util/kvdb/src/lib.rs @@ -22,6 +22,8 @@ extern crate elastic_array; extern crate ethcore_bytes as bytes; use std::io; +use std::path::Path; +use std::sync::Arc; use elastic_array::{ElasticArray128, ElasticArray32}; use bytes::Bytes; @@ -176,3 +178,10 @@ pub trait KeyValueDB: Sync + Send { /// Attempt to replace this database with a new one located at the given path. fn restore(&self, new_db: &str) -> Result<()>; } + +/// Generic key-value database handler. This trait contains one function `open`. When called, it opens database with a +/// predefined config. +pub trait KeyValueDBHandler: Send + Sync { + /// Open the predefined key-value database. + fn open(&self, path: &Path) -> Result>; +} From e6f75bccfe86e3a7b56909720f8d1d0755d4f6ee Mon Sep 17 00:00:00 2001 From: Anton Gavrilov Date: Mon, 9 Apr 2018 16:14:33 +0200 Subject: [PATCH 03/25] Private transactions integration pr (#6422) * Private transaction message added * Empty line removed * Private transactions logic removed from client into the separate module * Fixed compilation after merge with head * Signed private transaction message added as well * Comments after the review fixed * Private tx execution * Test update * Renamed some methods * Fixed some tests * Reverted submodules * Fixed build * Private transaction message added * Empty line removed * Private transactions logic removed from client into the separate module * Fixed compilation after merge with head * Signed private transaction message added as well * Comments after the review fixed * Encrypted private transaction message and signed reply added * Private tx execution * Test update * Main scenario completed * Merged with the latest head * Private transactions API * Comments after review fixed * Parameters for private transactions added to parity arguments * New files added * New API methods added * Do not process packets from unconfirmed peers * Merge with ptm_ss branch * Encryption and permissioning with key server added * Fixed compilation after merge * Version of Parity protocol incremented in order to support private transactions * Doc strings for constants added * Proper format for doc string added * fixed some encryptor.rs grumbles * Private transactions functionality moved to the separate crate * Refactoring in order to remove late initialisation * Tests fixed after moving to the separate crate * Fetch method removed * Sync test helpers refactored * Interaction with encryptor refactored * Contract address retrieving via substate removed * Sensible gas limit for private transactions implemented * New private contract with nonces added * Parsing of the response from key server fixed * Build fixed after the merge, native contracts removed * Crate renamed * Tests moved to the separate directory * Handling of errors reworked in order to use error chain * Encodable macro added, new constructor replaced with default * Native ethabi usage removed * Couple conversions optimized * Interactions with client reworked * Errors omitting removed * Fix after merge * Fix after the merge * private transactions improvements in progress * private_transactions -> ethcore/private-tx * making private transactions more idiomatic * private-tx encryptor uses shared FetchClient and is more idiomatic * removed redundant tests, moved integration tests to tests/ dir * fixed failing service test * reenable add_notify on private tx provider * removed private_tx tests from sync module * removed commented out code * Use plain password instead of unlocking account manager * remove dead code * Link to the contract changed * Transaction signature chain replay protection module created * Redundant type conversion removed * Contract address returned by private provider * Test fixed * Addressing grumbles in PrivateTransactions (#8249) * Tiny fixes part 1. * A bunch of additional comments and todos. * Fix ethsync tests. * resolved merge conflicts * final private tx pr (#8318) * added cli option that enables private transactions * fixed failing test * fixed failing test * fixed failing test * fixed failing test --- Cargo.lock | 41 ++ Cargo.toml | 1 + dapps/src/handlers/fetch.rs | 6 +- dapps/src/tests/helpers/fetch.rs | 4 +- ethcore/Cargo.toml | 3 +- ethcore/private-tx/Cargo.toml | 36 + ethcore/private-tx/res/private.evm | 1 + ethcore/private-tx/res/private.json | 1 + ethcore/private-tx/src/encryptor.rs | 272 +++++++ ethcore/private-tx/src/error.rs | 208 ++++++ ethcore/private-tx/src/lib.rs | 676 ++++++++++++++++++ ethcore/private-tx/src/messages.rs | 76 ++ .../private-tx/src/private_transactions.rs | 173 +++++ ethcore/private-tx/tests/private_contract.rs | 137 ++++ ethcore/service/Cargo.toml | 3 + ethcore/service/src/error.rs | 30 + ethcore/service/src/lib.rs | 13 +- ethcore/service/src/service.rs | 57 +- ethcore/src/block.rs | 2 +- ethcore/src/blockchain/blockchain.rs | 2 +- ethcore/src/client/chain_notify.rs | 12 +- ethcore/src/client/client.rs | 6 +- ethcore/src/client/io_message.rs | 4 +- ethcore/src/client/mod.rs | 4 +- ethcore/src/client/private_notify.rs | 23 + ethcore/src/engines/authority_round/mod.rs | 2 +- ethcore/src/engines/basic_authority.rs | 2 +- ethcore/src/engines/instant_seal.rs | 2 +- ethcore/src/engines/tendermint/mod.rs | 3 +- ethcore/src/engines/validator_set/contract.rs | 2 +- ethcore/src/engines/validator_set/multi.rs | 2 +- .../engines/validator_set/safe_contract.rs | 2 +- ethcore/src/error.rs | 9 +- ethcore/src/ethereum/ethash.rs | 2 +- ethcore/src/ethereum/mod.rs | 2 +- ethcore/src/executive.rs | 3 +- ethcore/src/externalities.rs | 2 +- ethcore/src/json_tests/executive.rs | 2 +- ethcore/src/lib.rs | 8 +- ethcore/src/miner/miner.rs | 5 +- ethcore/src/snapshot/account.rs | 2 +- ethcore/src/snapshot/service.rs | 2 +- .../src/snapshot/tests/proof_of_authority.rs | 4 +- ethcore/src/snapshot/tests/service.rs | 2 +- ethcore/src/spec/spec.rs | 2 +- ethcore/src/state/account.rs | 10 + ethcore/src/state/mod.rs | 14 +- ethcore/src/state_db.rs | 2 +- .../src/{tests/helpers.rs => test_helpers.rs} | 59 +- ethcore/src/tests/client.rs | 2 +- ethcore/src/tests/evm.rs | 2 +- ethcore/src/tests/mod.rs | 1 - ethcore/src/tests/trace.rs | 2 +- ethcore/src/verification/queue/mod.rs | 2 +- ethcore/src/verification/verification.rs | 2 +- ethcore/transaction/src/transaction.rs | 24 +- hash-fetch/src/client.rs | 6 +- parity/blockchain.rs | 8 + parity/cli/mod.rs | 58 +- parity/cli/tests/config.full.toml | 9 + parity/configuration.rs | 33 +- parity/main.rs | 7 +- parity/modules.rs | 4 +- parity/rpc_apis.rs | 35 +- parity/run.rs | 23 +- parity/snapshot.rs | 7 +- price-info/src/lib.rs | 6 +- rpc/Cargo.toml | 1 + rpc/src/lib.rs | 1 + rpc/src/v1/helpers/errors.rs | 18 + rpc/src/v1/impls/light/parity_set.rs | 2 +- rpc/src/v1/impls/mod.rs | 2 + rpc/src/v1/impls/parity_set.rs | 2 +- rpc/src/v1/impls/private.rs | 122 ++++ rpc/src/v1/mod.rs | 2 +- rpc/src/v1/tests/helpers/fetch.rs | 4 +- rpc/src/v1/traits/mod.rs | 2 + rpc/src/v1/traits/private.rs | 45 ++ rpc/src/v1/types/mod.rs | 2 + rpc/src/v1/types/private_receipt.rs | 54 ++ sync/Cargo.toml | 1 + sync/src/api.rs | 32 +- sync/src/chain.rs | 103 ++- sync/src/lib.rs | 3 + sync/src/light_sync/tests/test_net.rs | 4 + sync/src/private_tx.rs | 60 ++ sync/src/tests/consensus.rs | 31 +- sync/src/tests/helpers.rs | 221 +++++- util/fetch/src/client.rs | 57 +- util/fetch/src/lib.rs | 1 + 90 files changed, 2745 insertions(+), 192 deletions(-) create mode 100644 ethcore/private-tx/Cargo.toml create mode 100644 ethcore/private-tx/res/private.evm create mode 100644 ethcore/private-tx/res/private.json create mode 100644 ethcore/private-tx/src/encryptor.rs create mode 100644 ethcore/private-tx/src/error.rs create mode 100644 ethcore/private-tx/src/lib.rs create mode 100644 ethcore/private-tx/src/messages.rs create mode 100644 ethcore/private-tx/src/private_transactions.rs create mode 100644 ethcore/private-tx/tests/private_contract.rs create mode 100644 ethcore/service/src/error.rs create mode 100644 ethcore/src/client/private_notify.rs rename ethcore/src/{tests/helpers.rs => test_helpers.rs} (82%) create mode 100644 rpc/src/v1/impls/private.rs create mode 100644 rpc/src/v1/traits/private.rs create mode 100644 rpc/src/v1/types/private_receipt.rs create mode 100644 sync/src/private_tx.rs diff --git a/Cargo.lock b/Cargo.lock index 403b468f843..28a4b8a7af0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -519,6 +519,7 @@ dependencies = [ "ethkey 0.3.0", "ethstore 0.2.0", "evm 0.1.0", + "fetch 0.1.0", "futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "hardware-wallet 1.11.0", "hashdb 0.1.1", @@ -720,6 +721,40 @@ dependencies = [ "tiny-keccak 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "ethcore-private-tx" +version = "1.0.0" +dependencies = [ + "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethabi 5.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ethabi-contract 5.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "ethabi-derive 5.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "ethcore 1.11.0", + "ethcore-bytes 0.1.0", + "ethcore-io 1.11.0", + "ethcore-logger 1.11.0", + "ethcore-miner 1.11.0", + "ethcore-transaction 0.1.0", + "ethcrypto 0.1.0", + "ethereum-types 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethjson 0.1.0", + "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", + "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", + "rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", + "rlp 0.2.1", + "rlp_derive 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)", + "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)", +] + [[package]] name = "ethcore-secretstore" version = "1.0.0" @@ -762,8 +797,11 @@ name = "ethcore-service" version = "0.1.0" dependencies = [ "ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", + "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore 1.11.0", "ethcore-io 1.11.0", + "ethcore-private-tx 1.0.0", + "ethsync 1.11.0", "kvdb 0.1.0", "kvdb-rocksdb 0.1.0", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -948,6 +986,7 @@ dependencies = [ "plain_hasher 0.1.0", "rand 0.4.2 (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)", "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)", "triehash 0.1.0", @@ -1939,6 +1978,7 @@ dependencies = [ "ethcore-migrations 0.1.0", "ethcore-miner 1.11.0", "ethcore-network 1.11.0", + "ethcore-private-tx 1.0.0", "ethcore-secretstore 1.0.0", "ethcore-service 0.1.0", "ethcore-stratum 1.11.0", @@ -2145,6 +2185,7 @@ dependencies = [ "ethcore-logger 1.11.0", "ethcore-miner 1.11.0", "ethcore-network 1.11.0", + "ethcore-private-tx 1.0.0", "ethcore-transaction 0.1.0", "ethcrypto 0.1.0", "ethereum-types 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index 87daa076c1f..202215ab34b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -42,6 +42,7 @@ ethcore-logger = { path = "logger" } ethcore-migrations = { path = "ethcore/migrations" } ethcore-miner = { path = "miner" } ethcore-network = { path = "util/network" } +ethcore-private-tx = { path = "ethcore/private-tx" } ethcore-service = { path = "ethcore/service" } ethcore-stratum = { path = "stratum" } ethcore-transaction = { path = "ethcore/transaction" } diff --git a/dapps/src/handlers/fetch.rs b/dapps/src/handlers/fetch.rs index 94fe608819a..1408d634dbb 100644 --- a/dapps/src/handlers/fetch.rs +++ b/dapps/src/handlers/fetch.rs @@ -24,7 +24,7 @@ use fetch::{self, Fetch}; use futures::sync::oneshot; use futures::{self, Future}; use futures_cpupool::CpuPool; -use hyper::{self, Method, StatusCode}; +use hyper::{self, StatusCode}; use parking_lot::Mutex; use endpoint::{self, EndpointPath}; @@ -261,7 +261,7 @@ impl ContentFetcherHandler { // Validation of method let status = match *method { // Start fetching content - Method::Get => { + hyper::Method::Get => { trace!(target: "dapps", "Fetching content from: {:?}", url); FetchState::InProgress(Self::fetch_content( pool, @@ -295,7 +295,7 @@ impl ContentFetcherHandler { ) -> Box + Send> { // Start fetching the content let pool2 = pool.clone(); - let future = fetch.fetch(url, abort.into()).then(move |result| { + let future = fetch.get(url, abort.into()).then(move |result| { trace!(target: "dapps", "Fetching content finished. Starting validation: {:?}", result); Ok(match result { Ok(response) => match installer.validate_and_install(response) { diff --git a/dapps/src/tests/helpers/fetch.rs b/dapps/src/tests/helpers/fetch.rs index dfe523200e4..d65d9d09b07 100644 --- a/dapps/src/tests/helpers/fetch.rs +++ b/dapps/src/tests/helpers/fetch.rs @@ -20,7 +20,7 @@ use parking_lot::Mutex; use hyper; use futures::{self, Future}; -use fetch::{self, Fetch, Url}; +use fetch::{self, Fetch, Url, Method}; pub struct FetchControl { sender: mpsc::Sender<()>, @@ -97,7 +97,7 @@ impl FakeFetch { impl Fetch for FakeFetch { type Result = Box + Send>; - fn fetch(&self, url: &str, abort: fetch::Abort) -> Self::Result { + fn fetch(&self, url: &str, _method: Method, abort: fetch::Abort) -> Self::Result { let u = Url::parse(url).unwrap(); self.requested.lock().push(url.into()); let manual = self.manual.clone(); diff --git a/ethcore/Cargo.toml b/ethcore/Cargo.toml index 9c61fd8ea4b..c028f8e6b05 100644 --- a/ethcore/Cargo.toml +++ b/ethcore/Cargo.toml @@ -16,6 +16,7 @@ crossbeam = "0.3" ethash = { path = "../ethash" } ethcore-bloom-journal = { path = "../util/bloom" } ethcore-bytes = { path = "../util/bytes" } +fetch = { path = "../util/fetch" } hashdb = { path = "../util/hashdb" } memorydb = { path = "../util/memorydb" } patricia-trie = { path = "../util/patricia_trie" } @@ -52,6 +53,7 @@ rlp_compress = { path = "../util/rlp_compress" } rlp_derive = { path = "../util/rlp_derive" } kvdb = { path = "../util/kvdb" } kvdb-memorydb = { path = "../util/kvdb-memorydb" } +kvdb-rocksdb = { path = "../util/kvdb-rocksdb" } util-error = { path = "../util/error" } snappy = { git = "https://github.com/paritytech/rust-snappy" } stop-guard = { path = "../util/stop-guard" } @@ -72,7 +74,6 @@ journaldb = { path = "../util/journaldb" } [dev-dependencies] tempdir = "0.3" trie-standardmap = { path = "../util/trie-standardmap" } -kvdb-rocksdb = { path = "../util/kvdb-rocksdb" } [features] evm-debug = ["slow-blocks"] diff --git a/ethcore/private-tx/Cargo.toml b/ethcore/private-tx/Cargo.toml new file mode 100644 index 00000000000..6ecfdb54647 --- /dev/null +++ b/ethcore/private-tx/Cargo.toml @@ -0,0 +1,36 @@ +[package] +description = "Parity Private Transactions" +name = "ethcore-private-tx" +version = "1.0.0" +license = "GPL-3.0" +authors = ["Parity Technologies "] + +[dependencies] +error-chain = { version = "0.11", default-features = false } +ethabi = "5.1" +ethabi-contract = "5.0" +ethabi-derive = "5.0" +ethcore = { path = ".." } +ethcore-bytes = { path = "../../util/bytes" } +ethcore-io = { path = "../../util/io" } +ethcore-logger = { path = "../../logger" } +ethcore-miner = { path = "../../miner" } +ethcore-transaction = { path = "../transaction" } +ethcrypto = { path = "../../ethcrypto" } +ethereum-types = "0.3" +ethjson = { path = "../../json" } +ethkey = { path = "../../ethkey" } +fetch = { path = "../../util/fetch" } +futures = "0.1" +keccak-hash = { path = "../../util/hash" } +log = "0.3" +parking_lot = "0.5" +patricia-trie = { path = "../../util/patricia_trie" } +rand = "0.3" +rlp = { path = "../../util/rlp" } +rlp_derive = { path = "../../util/rlp_derive" } +rustc-hex = "1.0" +serde = "1.0" +serde_derive = "1.0" +serde_json = "1.0" +tiny-keccak = "1.3" diff --git a/ethcore/private-tx/res/private.evm b/ethcore/private-tx/res/private.evm new file mode 100644 index 00000000000..cd19d757aad --- /dev/null +++ b/ethcore/private-tx/res/private.evm @@ -0,0 +1 @@ +6060604052341561000f57600080fd5b604051610b0d380380610b0d833981016040528080518201919060200180518201919060200180518201919050508260009080519060200190610053929190610092565b50816002908051906020019061006a92919061011c565b50806001908051906020019061008192919061011c565b506001600381905550505050610204565b82805482825590600052602060002090810192821561010b579160200282015b8281111561010a5782518260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550916020019190600101906100b2565b5b509050610118919061019c565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061015d57805160ff191683800117855561018b565b8280016001018555821561018b579182015b8281111561018a57825182559160200191906001019061016f565b5b50905061019891906101df565b5090565b6101dc91905b808211156101d857600081816101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055506001016101a2565b5090565b90565b61020191905b808211156101fd5760008160009055506001016101e5565b5090565b90565b6108fa806102136000396000f300606060405260043610610078576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806317ac53a21461007d57806324c12bf61461019a57806335aa2e4414610228578063affed0e01461028b578063b7ab4db5146102b4578063c19d93fb1461031e575b600080fd5b341561008857600080fd5b610198600480803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050919080359060200190820180359060200190808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050509190803590602001908201803590602001908080602002602001604051908101604052809392919081815260200183836020028082843782019150505050505091908035906020019082018035906020019080806020026020016040519081016040528093929190818152602001838360200280828437820191505050505050919050506103ac565b005b34156101a557600080fd5b6101ad610600565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156101ed5780820151818401526020810190506101d2565b50505050905090810190601f16801561021a5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561023357600080fd5b610249600480803590602001909190505061069e565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561029657600080fd5b61029e6106dd565b6040518082815260200191505060405180910390f35b34156102bf57600080fd5b6102c76106e3565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b8381101561030a5780820151818401526020810190506102ef565b505050509050019250505060405180910390f35b341561032957600080fd5b610331610777565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610371578082015181840152602081019050610356565b50505050905090810190601f16801561039e5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6000806040805190810160405280876040518082805190602001908083835b6020831015156103f057805182526020820191506020810190506020830392506103cb565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390206000191660001916815260200160035460010260001916600019168152506040518082600260200280838360005b8381101561046657808201518184015260208101905061044b565b5050505090500191505060405180910390209150600090505b6000805490508110156105d55760008181548110151561049b57fe5b906000526020600020900160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660018387848151811015156104ee57fe5b90602001906020020151878581518110151561050657fe5b90602001906020020151878681518110151561051e57fe5b90602001906020020151604051600081526020016040526000604051602001526040518085600019166000191681526020018460ff1660ff16815260200183600019166000191681526020018260001916600019168152602001945050505050602060405160208103908084039060008661646e5a03f115156105a057600080fd5b50506020604051035173ffffffffffffffffffffffffffffffffffffffff161415156105c857fe5b808060010191505061047f565b85600190805190602001906105eb929190610815565b50600160035401600381905550505050505050565b60028054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156106965780601f1061066b57610100808354040283529160200191610696565b820191906000526020600020905b81548152906001019060200180831161067957829003601f168201915b505050505081565b6000818154811015156106ad57fe5b90600052602060002090016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60035481565b6106eb610895565b600080548060200260200160405190810160405280929190818152602001828054801561076d57602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311610723575b5050505050905090565b60018054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561080d5780601f106107e25761010080835404028352916020019161080d565b820191906000526020600020905b8154815290600101906020018083116107f057829003601f168201915b505050505081565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061085657805160ff1916838001178555610884565b82800160010185558215610884579182015b82811115610883578251825591602001919060010190610868565b5b50905061089191906108a9565b5090565b602060405190810160405280600081525090565b6108cb91905b808211156108c75760008160009055506001016108af565b5090565b905600a165627a7a723058200ae0215fae320b646a22fdd58278b328f46d915bd65ddbfeb5b4a09643d6e0220029 diff --git a/ethcore/private-tx/res/private.json b/ethcore/private-tx/res/private.json new file mode 100644 index 00000000000..82a5e86bc2e --- /dev/null +++ b/ethcore/private-tx/res/private.json @@ -0,0 +1 @@ +[{"constant": false,"inputs": [{"name": "newState","type": "bytes"},{"name": "v","type": "uint8[]"},{"name": "r","type": "bytes32[]"},{"name": "s","type": "bytes32[]"}],"name": "setState","outputs": [],"payable": false,"stateMutability": "nonpayable","type": "function"},{"constant": true,"inputs": [],"name": "code","outputs": [{"name": "","type": "bytes"}],"payable": false,"stateMutability": "view","type": "function"},{"constant": true,"inputs": [{"name": "","type": "uint256"}],"name": "validators","outputs": [{"name": "","type": "address"}],"payable": false,"stateMutability": "view","type": "function"},{"constant": true,"inputs": [],"name": "nonce","outputs": [{"name": "","type": "uint256"}],"payable": false,"stateMutability": "view","type": "function"},{"constant": true,"inputs": [],"name": "getValidators","outputs": [{"name": "","type": "address[]"}],"payable": false,"stateMutability": "view","type": "function"},{"constant": true,"inputs": [],"name": "state","outputs": [{"name": "","type": "bytes"}],"payable": false,"stateMutability": "view","type": "function"},{"inputs": [{"name": "initialValidators","type": "address[]"},{"name": "initialCode","type": "bytes"},{"name": "initialState","type": "bytes"}],"payable": false,"stateMutability": "nonpayable","type": "constructor"}] diff --git a/ethcore/private-tx/src/encryptor.rs b/ethcore/private-tx/src/encryptor.rs new file mode 100644 index 00000000000..385356227fa --- /dev/null +++ b/ethcore/private-tx/src/encryptor.rs @@ -0,0 +1,272 @@ +// 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 . + +//! Encryption providers. + +use std::io::Read; +use std::iter::repeat; +use std::time::{Instant, Duration}; +use std::collections::HashMap; +use std::collections::hash_map::Entry; +use parking_lot::Mutex; +use ethcore::account_provider::AccountProvider; +use ethereum_types::{H128, H256, Address}; +use ethjson; +use ethkey::{Signature, Public}; +use ethcrypto; +use futures::Future; +use fetch::{Fetch, Client as FetchClient, Method, BodyReader}; +use bytes::{Bytes, ToPretty}; +use error::{Error, ErrorKind}; +use super::find_account_password; + +/// Initialization vector length. +const INIT_VEC_LEN: usize = 16; + +/// Duration of storing retrieved keys (in ms) +const ENCRYPTION_SESSION_DURATION: u64 = 30 * 1000; + +/// Trait for encryption/decryption operations. +pub trait Encryptor: Send + Sync + 'static { + /// Generate unique contract key && encrypt passed data. Encryption can only be performed once. + fn encrypt( + &self, + contract_address: &Address, + accounts: &AccountProvider, + initialisation_vector: &H128, + plain_data: &[u8], + ) -> Result; + + /// Decrypt data using previously generated contract key. + fn decrypt( + &self, + contract_address: &Address, + accounts: &AccountProvider, + cypher: &[u8], + ) -> Result; +} + +/// Configurtion for key server encryptor +#[derive(Default, PartialEq, Debug, Clone)] +pub struct EncryptorConfig { + /// URL to key server + pub base_url: Option, + /// Key server's threshold + pub threshold: u32, + /// Account used for signing requests to key server + pub key_server_account: Option
, + /// Passwords used to unlock accounts + pub passwords: Vec, +} + +struct EncryptionSession { + key: Bytes, + end_time: Instant, +} + +/// SecretStore-based encryption/decryption operations. +pub struct SecretStoreEncryptor { + config: EncryptorConfig, + client: FetchClient, + sessions: Mutex>, +} + +impl SecretStoreEncryptor { + /// Create new encryptor + pub fn new(config: EncryptorConfig, client: FetchClient) -> Result { + Ok(SecretStoreEncryptor { + config, + client, + sessions: Mutex::default(), + }) + } + + /// Ask secret store for key && decrypt the key. + fn retrieve_key( + &self, + url_suffix: &str, + use_post: bool, + contract_address: &Address, + accounts: &AccountProvider, + ) -> Result { + // check if the key was already cached + if let Some(key) = self.obtained_key(contract_address) { + return Ok(key); + } + let contract_address_signature = self.sign_contract_address(contract_address, accounts)?; + let requester = self.config.key_server_account.ok_or_else(|| ErrorKind::KeyServerAccountNotSet)?; + + // key id in SS is H256 && we have H160 here => expand with assitional zeros + let contract_address_extended: H256 = contract_address.into(); + let base_url = self.config.base_url.clone().ok_or_else(|| ErrorKind::KeyServerNotSet)?; + + // prepare request url + let url = format!("{}/{}/{}{}", + base_url, + contract_address_extended.to_hex(), + contract_address_signature, + url_suffix, + ); + + // send HTTP request + let method = if use_post { + Method::Post + } else { + Method::Get + }; + + let response = self.client.fetch(&url, method, Default::default()).wait() + .map_err(|e| ErrorKind::Encrypt(e.to_string()))?; + + if response.is_not_found() { + bail!(ErrorKind::EncryptionKeyNotFound(*contract_address)); + } + + if !response.is_success() { + bail!(ErrorKind::Encrypt(response.status().canonical_reason().unwrap_or("unknown").into())); + } + + // read HTTP response + let mut result = String::new(); + BodyReader::new(response).read_to_string(&mut result)?; + + // response is JSON string (which is, in turn, hex-encoded, encrypted Public) + let encrypted_bytes: ethjson::bytes::Bytes = result.trim_matches('\"').parse().map_err(|e| ErrorKind::Encrypt(e))?; + let password = find_account_password(&self.config.passwords, &*accounts, &requester); + + // decrypt Public + let decrypted_bytes = accounts.decrypt(requester, password, ðcrypto::DEFAULT_MAC, &encrypted_bytes)?; + let decrypted_key = Public::from_slice(&decrypted_bytes); + + // and now take x coordinate of Public as a key + let key: Bytes = (*decrypted_key)[..INIT_VEC_LEN].into(); + + // cache the key in the session and clear expired sessions + self.sessions.lock().insert(*contract_address, EncryptionSession{ + key: key.clone(), + end_time: Instant::now() + Duration::from_millis(ENCRYPTION_SESSION_DURATION), + }); + self.clean_expired_sessions(); + Ok(key) + } + + fn clean_expired_sessions(&self) { + let mut sessions = self.sessions.lock(); + sessions.retain(|_, session| session.end_time < Instant::now()); + } + + fn obtained_key(&self, contract_address: &Address) -> Option { + let mut sessions = self.sessions.lock(); + let stored_session = sessions.entry(*contract_address); + match stored_session { + Entry::Occupied(session) => { + if Instant::now() > session.get().end_time { + session.remove_entry(); + None + } else { + Some(session.get().key.clone()) + } + } + Entry::Vacant(_) => None, + } + } + + fn sign_contract_address(&self, contract_address: &Address, accounts: &AccountProvider) -> Result { + // key id in SS is H256 && we have H160 here => expand with assitional zeros + let contract_address_extended: H256 = contract_address.into(); + let key_server_account = self.config.key_server_account.ok_or_else(|| ErrorKind::KeyServerAccountNotSet)?; + let password = find_account_password(&self.config.passwords, accounts, &key_server_account); + Ok(accounts.sign(key_server_account, password, H256::from_slice(&contract_address_extended))?) + } +} + +impl Encryptor for SecretStoreEncryptor { + fn encrypt( + &self, + contract_address: &Address, + accounts: &AccountProvider, + initialisation_vector: &H128, + plain_data: &[u8], + ) -> Result { + // retrieve the key, try to generate it if it doesn't exist yet + let key = match self.retrieve_key("", false, contract_address, &*accounts) { + Ok(key) => Ok(key), + Err(Error(ErrorKind::EncryptionKeyNotFound(_), _)) => { + trace!("Key for account wasnt found in sstore. Creating. Address: {:?}", contract_address); + self.retrieve_key(&format!("/{}", self.config.threshold), true, contract_address, &*accounts) + } + Err(err) => Err(err), + }?; + + // encrypt data + let mut cypher = Vec::with_capacity(plain_data.len() + initialisation_vector.len()); + cypher.extend(repeat(0).take(plain_data.len())); + ethcrypto::aes::encrypt(&key, initialisation_vector, plain_data, &mut cypher); + cypher.extend_from_slice(&initialisation_vector); + + Ok(cypher) + } + + /// Decrypt data using previously generated contract key. + fn decrypt( + &self, + contract_address: &Address, + accounts: &AccountProvider, + cypher: &[u8], + ) -> Result { + // initialization vector takes INIT_VEC_LEN bytes + let cypher_len = cypher.len(); + if cypher_len < INIT_VEC_LEN { + bail!(ErrorKind::Decrypt("Invalid cypher".into())); + } + + // retrieve existing key + let key = self.retrieve_key("", false, contract_address, accounts)?; + + // use symmetric decryption to decrypt document + 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)); + ethcrypto::aes::decrypt(&key, &iv, cypher, &mut plain_data); + + Ok(plain_data) + } +} + +/// Dummy encryptor. +#[derive(Default)] +pub struct NoopEncryptor; + +impl Encryptor for NoopEncryptor { + fn encrypt( + &self, + _contract_address: &Address, + _accounts: &AccountProvider, + _initialisation_vector: &H128, + data: &[u8], + ) -> Result { + Ok(data.to_vec()) + } + + fn decrypt( + &self, + _contract_address: &Address, + _accounts: &AccountProvider, + data: &[u8], + ) -> Result { + Ok(data.to_vec()) + } +} diff --git a/ethcore/private-tx/src/error.rs b/ethcore/private-tx/src/error.rs new file mode 100644 index 00000000000..3b3c881a945 --- /dev/null +++ b/ethcore/private-tx/src/error.rs @@ -0,0 +1,208 @@ +// 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 ethereum_types::Address; +use rlp::DecoderError; +use trie::TrieError; +use ethcore::account_provider::SignError; +use ethcore::error::{Error as EthcoreError, ExecutionError}; +use transaction::Error as TransactionError; +use ethkey::Error as KeyError; + +error_chain! { + foreign_links { + Io(::std::io::Error) #[doc = "Error concerning the Rust standard library's IO subsystem."]; + Decoder(DecoderError) #[doc = "RLP decoding error."]; + Trie(TrieError) #[doc = "Error concerning TrieDBs."]; + } + + errors { + #[doc = "Encryption error."] + Encrypt(err: String) { + description("Encryption error"), + display("Encryption error. ({})", err), + } + + #[doc = "Decryption error."] + Decrypt(err: String) { + description("Decryption error"), + display("Decryption error. ({})", err), + } + + #[doc = "Address not authorized."] + NotAuthorised(address: Address) { + description("Address not authorized"), + display("Private transaction execution is not authorised for {}", address), + } + + #[doc = "Transaction creates more than one contract."] + TooManyContracts { + description("Transaction creates more than one contract."), + display("Private transaction created too many contracts"), + } + + #[doc = "Contract call error."] + Call(err: String) { + description("Contract call error."), + display("Contract call error. ({})", err), + } + + #[doc = "State is not available."] + StatePruned { + description("State is not available."), + display("State is not available"), + } + + #[doc = "State is incorrect."] + StateIncorrect { + description("State is incorrect."), + display("State is incorrect"), + } + + #[doc = "Wrong private transaction type."] + BadTransactonType { + description("Wrong private transaction type."), + display("Wrong private transaction type"), + } + + #[doc = "Contract does not exist or was not created."] + ContractDoesNotExist { + description("Contract does not exist or was not created."), + display("Contract does not exist or was not created"), + } + + #[doc = "Reference to the client is corrupted."] + ClientIsMalformed { + description("Reference to the client is corrupted."), + display("Reference to the client is corrupted"), + } + + #[doc = "Queue of private transactions for verification is full."] + QueueIsFull { + description("Queue of private transactions for verification is full."), + display("Queue of private transactions for verification is full"), + } + + #[doc = "The transaction already exists in queue of private transactions."] + PrivateTransactionAlreadyImported { + description("The transaction already exists in queue of private transactions."), + display("The transaction already exists in queue of private transactions."), + } + + #[doc = "The information about private transaction is not found in the store."] + PrivateTransactionNotFound { + description("The information about private transaction is not found in the store."), + display("The information about private transaction is not found in the store."), + } + + #[doc = "Account for signing public transactions not set."] + SignerAccountNotSet { + description("Account for signing public transactions not set."), + display("Account for signing public transactions not set."), + } + + #[doc = "Account for validating private transactions not set."] + ValidatorAccountNotSet { + description("Account for validating private transactions not set."), + display("Account for validating private transactions not set."), + } + + #[doc = "Account for signing requests to key server not set."] + KeyServerAccountNotSet { + description("Account for signing requests to key server not set."), + display("Account for signing requests to key server not set."), + } + + #[doc = "Encryption key is not found on key server."] + EncryptionKeyNotFound(address: Address) { + description("Encryption key is not found on key server"), + display("Encryption key is not found on key server for {}", address), + } + + #[doc = "Key server URL is not set."] + KeyServerNotSet { + description("Key server URL is not set."), + display("Key server URL is not set."), + } + + #[doc = "VM execution error."] + Execution(err: ExecutionError) { + description("VM execution error."), + display("VM execution error {}", err), + } + + #[doc = "General signing error."] + Key(err: KeyError) { + description("General signing error."), + display("General signing error {}", err), + } + + #[doc = "Account provider signing error."] + Sign(err: SignError) { + description("Account provider signing error."), + display("Account provider signing error {}", err), + } + + #[doc = "Error of transactions processing."] + Transaction(err: TransactionError) { + description("Error of transactions processing."), + display("Error of transactions processing {}", err), + } + + #[doc = "General ethcore error."] + Ethcore(err: EthcoreError) { + description("General ethcore error."), + display("General ethcore error {}", err), + } + } +} + +impl From for Error { + fn from(err: SignError) -> Self { + ErrorKind::Sign(err).into() + } +} + +impl From for Error { + fn from(err: KeyError) -> Self { + ErrorKind::Key(err).into() + } +} + +impl From for Error { + fn from(err: ExecutionError) -> Self { + ErrorKind::Execution(err).into() + } +} + +impl From for Error { + fn from(err: TransactionError) -> Self { + ErrorKind::Transaction(err).into() + } +} + +impl From for Error { + fn from(err: EthcoreError) -> Self { + ErrorKind::Ethcore(err).into() + } +} + +impl From> for Error where Error: From { + fn from(err: Box) -> Error { + Error::from(*err) + } +} + diff --git a/ethcore/private-tx/src/lib.rs b/ethcore/private-tx/src/lib.rs new file mode 100644 index 00000000000..4fa1f8789c1 --- /dev/null +++ b/ethcore/private-tx/src/lib.rs @@ -0,0 +1,676 @@ +// 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 . + +//! Private transactions module. + +// Recursion limit required because of +// error_chain foreign_links. +#![recursion_limit="256"] + +mod encryptor; +mod private_transactions; +mod messages; +mod error; + +extern crate ethcore; +extern crate ethcore_io as io; +extern crate ethcore_bytes as bytes; +extern crate ethcore_transaction as transaction; +extern crate ethcore_miner; +extern crate ethcrypto; +extern crate ethabi; +extern crate ethereum_types; +extern crate ethkey; +extern crate ethjson; +extern crate fetch; +extern crate futures; +extern crate keccak_hash as hash; +extern crate parking_lot; +extern crate patricia_trie as trie; +extern crate rlp; +extern crate rustc_hex; +#[macro_use] +extern crate log; +#[macro_use] +extern crate ethabi_derive; +#[macro_use] +extern crate ethabi_contract; +#[macro_use] +extern crate error_chain; +#[macro_use] +extern crate rlp_derive; + +#[cfg(test)] +extern crate rand; +#[cfg(test)] +extern crate ethcore_logger; + +pub use encryptor::{Encryptor, SecretStoreEncryptor, EncryptorConfig, NoopEncryptor}; +pub use private_transactions::{PrivateTransactionDesc, VerificationStore, PrivateTransactionSigningDesc, SigningStore}; +pub use messages::{PrivateTransaction, SignedPrivateTransaction}; +pub use error::{Error, ErrorKind}; + +use std::sync::{Arc, Weak}; +use std::collections::{HashMap, HashSet}; +use ethereum_types::{H128, H256, U256, Address}; +use hash::keccak; +use rlp::*; +use parking_lot::{Mutex, RwLock}; +use bytes::Bytes; +use ethkey::{Signature, recover, public_to_address}; +use io::IoChannel; +use ethcore::executive::{Executive, TransactOptions}; +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, + MiningBlockChainClient, ChainInfo, Nonce, CallContract +}; +use ethcore::account_provider::AccountProvider; +use ethcore_miner::transaction_queue::{TransactionDetailsProvider as TransactionQueueDetailsProvider, AccountDetails}; +use ethcore::miner::MinerService; +use ethcore::trace::{Tracer, VMTracer}; +use rustc_hex::FromHex; + +// Source avaiable at https://github.com/parity-contracts/private-tx/blob/master/contracts/PrivateContract.sol +const DEFAULT_STUB_CONTRACT: &'static str = include_str!("../res/private.evm"); + +use_contract!(private, "PrivateContract", "res/private.json"); + +/// Initialization vector length. +const INIT_VEC_LEN: usize = 16; + +struct TransactionDetailsProvider<'a> { + client: &'a MiningBlockChainClient, +} + +impl<'a> TransactionDetailsProvider<'a> { + pub fn new(client: &'a MiningBlockChainClient) -> Self { + TransactionDetailsProvider { + client: client, + } + } +} + +impl<'a> TransactionQueueDetailsProvider for TransactionDetailsProvider<'a> { + fn fetch_account(&self, address: &Address) -> AccountDetails { + AccountDetails { + nonce: self.client.latest_nonce(address), + balance: self.client.latest_balance(address), + } + } + + fn estimate_gas_required(&self, tx: &SignedTransaction) -> U256 { + tx.gas_required(&self.client.latest_schedule()).into() + } + + fn is_service_transaction_acceptable(&self, _tx: &SignedTransaction) -> Result { + Ok(false) + } +} + +/// Configurtion for private transaction provider +#[derive(Default, PartialEq, Debug, Clone)] +pub struct ProviderConfig { + /// Accounts that can be used for validation + pub validator_accounts: Vec
, + /// Account used for signing public transactions created from private transactions + pub signer_account: Option
, + /// Passwords used to unlock accounts + pub passwords: Vec, +} + +#[derive(Debug)] +/// Private transaction execution receipt. +pub struct Receipt { + /// Private transaction hash. + pub hash: H256, + /// Created contract address if any. + pub contract_address: Option
, + /// Execution status. + pub status_code: u8, +} + +/// Manager of private transactions +pub struct Provider { + encryptor: Box, + validator_accounts: HashSet
, + signer_account: Option
, + passwords: Vec, + notify: RwLock>>, + transactions_for_signing: Mutex, + transactions_for_verification: Mutex, + client: Arc, + accounts: Arc, + channel: IoChannel, +} + +#[derive(Debug)] +pub struct PrivateExecutionResult where T: Tracer, V: VMTracer { + code: Option, + state: Bytes, + contract_address: Option
, + result: Executed, +} + +impl Provider where { + /// Create a new provider. + pub fn new( + client: Arc, + accounts: Arc, + encryptor: Box, + config: ProviderConfig, + channel: IoChannel, + ) -> Result { + Ok(Provider { + encryptor, + validator_accounts: config.validator_accounts.into_iter().collect(), + signer_account: config.signer_account, + passwords: config.passwords, + notify: RwLock::default(), + transactions_for_signing: Mutex::default(), + transactions_for_verification: Mutex::default(), + client, + accounts, + channel, + }) + } + + // TODO [ToDr] Don't use `ChainNotify` here! + // Better to create a separate notification type for this. + /// Adds an actor to be notified on certain events + pub fn add_notify(&self, target: Arc) { + self.notify.write().push(Arc::downgrade(&target)); + } + + fn notify(&self, f: F) where F: Fn(&ChainNotify) { + for np in self.notify.read().iter() { + if let Some(n) = np.upgrade() { + f(&*n); + } + } + } + + /// 1. Create private transaction from the signed transaction + /// 2. Executes private transaction + /// 3. Save it with state returned on prev step to the queue for signing + /// 4. Broadcast corresponding message to the chain + pub fn create_private_transaction(&self, signed_transaction: SignedTransaction) -> Result { + trace!("Creating private transaction from regular transaction: {:?}", signed_transaction); + if self.signer_account.is_none() { + trace!("Signing account not set"); + bail!(ErrorKind::SignerAccountNotSet); + } + let tx_hash = signed_transaction.hash(); + match signed_transaction.action { + Action::Create => { + bail!(ErrorKind::BadTransactonType); + } + Action::Call(contract) => { + let data = signed_transaction.rlp_bytes(); + let encrypted_transaction = self.encrypt(&contract, &Self::iv_from_transaction(&signed_transaction), &data)?; + let private = PrivateTransaction { + encrypted: encrypted_transaction, + contract, + }; + // TODO [ToDr] Using BlockId::Latest is bad here, + // the block may change in the middle of execution + // causing really weird stuff to happen. + // We should retrieve hash and stick to that. IMHO + // best would be to change the API and only allow H256 instead of BlockID + // in private-tx to avoid such mistakes. + let contract_nonce = self.get_contract_nonce(&contract, BlockId::Latest)?; + let private_state = self.execute_private_transaction(BlockId::Latest, &signed_transaction)?; + trace!("Private transaction created, encrypted transaction: {:?}, private state: {:?}", private, private_state); + let contract_validators = self.get_validators(BlockId::Latest, &contract)?; + trace!("Required validators: {:?}", contract_validators); + let private_state_hash = self.calculate_state_hash(&private_state, contract_nonce); + trace!("Hashed effective private state for sender: {:?}", private_state_hash); + self.transactions_for_signing.lock().add_transaction(private.hash(), signed_transaction, contract_validators, private_state, contract_nonce)?; + self.broadcast_private_transaction(private.rlp_bytes().into_vec()); + Ok(Receipt { + hash: tx_hash, + contract_address: None, + status_code: 0, + }) + } + } + } + + /// Calculate hash from united private state and contract nonce + pub fn calculate_state_hash(&self, state: &Bytes, nonce: U256) -> H256 { + let state_hash = keccak(state); + let mut state_buf = [0u8; 64]; + state_buf[..32].clone_from_slice(&state_hash); + state_buf[32..].clone_from_slice(&H256::from(nonce)); + keccak(&state_buf.as_ref()) + } + + /// Extract signed transaction from private transaction + fn extract_original_transaction(&self, private: PrivateTransaction, contract: &Address) -> Result { + let encrypted_transaction = private.encrypted; + let transaction_bytes = self.decrypt(contract, &encrypted_transaction)?; + let original_transaction: UnverifiedTransaction = UntrustedRlp::new(&transaction_bytes).as_val()?; + 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 = UntrustedRlp::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 => { + // 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); + let details_provider = TransactionDetailsProvider::new(&*self.client as &MiningBlockChainClient); + let insertion_time = self.client.chain_info().best_block_number; + // Verify with the first account available + trace!("The following account will be used for verification: {:?}", validation_account); + self.transactions_for_verification.lock() + .add_transaction(original_tx, contract, validation_account, hash, &details_provider, insertion_time)?; + self.channel.send(ClientIoMessage::NewPrivateTransaction).map_err(|_| ErrorKind::ClientIsMalformed.into()) + } + } + } + + /// 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 + fn process_queue(&self) -> Result<(), Error> { + let mut verification_queue = self.transactions_for_verification.lock(); + let ready_transactions = verification_queue.ready_transactions(); + let fetch_nonce = |a: &Address| self.client.latest_nonce(a); + for transaction in ready_transactions { + let transaction_hash = transaction.hash(); + match verification_queue.private_transaction_descriptor(&transaction_hash) { + Ok(desc) => { + if !self.validator_accounts.contains(&desc.validator_account) { + trace!("Cannot find validator account in config"); + bail!(ErrorKind::ValidatorAccountNotSet); + } + let account = desc.validator_account; + if let Action::Call(contract) = transaction.action { + let contract_nonce = self.get_contract_nonce(&contract, BlockId::Latest)?; + let private_state = self.execute_private_transaction(BlockId::Latest, &transaction)?; + let private_state_hash = self.calculate_state_hash(&private_state, contract_nonce); + trace!("Hashed effective private state for validator: {:?}", private_state_hash); + let password = find_account_password(&self.passwords, &*self.accounts, &account); + let signed_state = self.accounts.sign(account, password, private_state_hash)?; + let signed_private_transaction = SignedPrivateTransaction::new(desc.private_hash, signed_state, None); + trace!("Sending signature for private transaction: {:?}", signed_private_transaction); + self.broadcast_signed_private_transaction(signed_private_transaction.rlp_bytes().into_vec()); + } else { + trace!("Incorrect type of action for the transaction"); + bail!(ErrorKind::BadTransactonType); + } + }, + Err(e) => { + trace!("Cannot retrieve descriptor for transaction with error {:?}", e); + bail!(e); + } + } + verification_queue.remove_private_transaction(&transaction_hash, &fetch_nonce); + } + 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 = UntrustedRlp::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 => { + // 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.client.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); + } + let state_hash = self.calculate_state_hash(&desc.state, desc.contract_nonce); + match recover(&sign, &state_hash) { + Ok(public) => { + let sender = public_to_address(&public); + match desc.validators.contains(&sender) { + true => { + Ok(desc.received_signatures.len() + 1 == desc.validators.len()) + } + false => { + trace!("Sender's state doesn't correspond to validator's"); + bail!(ErrorKind::StateIncorrect); + } + } + } + Err(err) => { + trace!("Sender's state doesn't correspond to validator's, error {:?}", err); + bail!(err); + } + } + } + + /// Broadcast the private transaction message to the chain + fn broadcast_private_transaction(&self, message: Bytes) { + self.notify(|notify| notify.broadcast(ChainMessageType::PrivateTransaction(message.clone()))); + } + + /// Broadcast signed private transaction message to the chain + fn broadcast_signed_private_transaction(&self, message: Bytes) { + self.notify(|notify| notify.broadcast(ChainMessageType::SignedPrivateTransaction(message.clone()))); + } + + fn iv_from_transaction(transaction: &SignedTransaction) -> H128 { + let nonce = keccak(&transaction.nonce.rlp_bytes()); + let (iv, _) = nonce.split_at(INIT_VEC_LEN); + H128::from_slice(iv) + } + + fn iv_from_address(contract_address: &Address) -> H128 { + let address = keccak(&contract_address.rlp_bytes()); + let (iv, _) = address.split_at(INIT_VEC_LEN); + H128::from_slice(iv) + } + + fn encrypt(&self, contract_address: &Address, initialisation_vector: &H128, data: &[u8]) -> Result { + trace!("Encrypt data using key(address): {:?}", contract_address); + Ok(self.encryptor.encrypt(contract_address, &*self.accounts, initialisation_vector, data)?) + } + + fn decrypt(&self, contract_address: &Address, data: &[u8]) -> Result { + trace!("Decrypt data using key(address): {:?}", contract_address); + Ok(self.encryptor.decrypt(contract_address, &*self.accounts, data)?) + } + + fn get_decrypted_state(&self, address: &Address, block: BlockId) -> Result { + let contract = private::PrivateContract::default(); + let state = contract.functions() + .state() + .call(&|data| self.client.call_contract(block, *address, data)) + .map_err(|e| ErrorKind::Call(format!("Contract call failed {:?}", e)))?; + + self.decrypt(address, &state) + } + + fn get_decrypted_code(&self, address: &Address, block: BlockId) -> Result { + let contract = private::PrivateContract::default(); + let code = contract.functions() + .code() + .call(&|data| self.client.call_contract(block, *address, data)) + .map_err(|e| ErrorKind::Call(format!("Contract call failed {:?}", e)))?; + + self.decrypt(address, &code) + } + + pub fn get_contract_nonce(&self, address: &Address, block: BlockId) -> Result { + let contract = private::PrivateContract::default(); + Ok(contract.functions() + .nonce() + .call(&|data| self.client.call_contract(block, *address, data)) + .map_err(|e| ErrorKind::Call(format!("Contract call failed {:?}", e)))?) + } + + fn snapshot_to_storage(raw: Bytes) -> HashMap { + let items = raw.len() / 64; + (0..items).map(|i| { + let offset = i * 64; + let key = H256::from_slice(&raw[offset..(offset + 32)]); + let value = H256::from_slice(&raw[(offset + 32)..(offset + 64)]); + (key, value) + }).collect() + } + + fn snapshot_from_storage(storage: &HashMap) -> Bytes { + let mut raw = Vec::with_capacity(storage.len() * 64); + for (key, value) in storage { + raw.extend_from_slice(key); + raw.extend_from_slice(value); + }; + raw + } + + pub fn execute_private(&self, transaction: &SignedTransaction, options: TransactOptions, block: BlockId) -> Result, Error> + where + T: Tracer, + V: VMTracer, + { + let mut env_info = self.client.env_info(block).ok_or(ErrorKind::StatePruned)?; + env_info.gas_limit = transaction.gas; + + let mut state = self.client.state_at(block).ok_or(ErrorKind::StatePruned)?; + // TODO: in case of BlockId::Latest these need to operate on the same state + let contract_address = match transaction.action { + Action::Call(ref contract_address) => { + let contract_code = Arc::new(self.get_decrypted_code(contract_address, block)?); + let contract_state = self.get_decrypted_state(contract_address, block)?; + trace!("Patching contract at {:?}, code: {:?}, state: {:?}", contract_address, contract_code, contract_state); + state.patch_account(contract_address, contract_code, Self::snapshot_to_storage(contract_state))?; + Some(*contract_address) + }, + Action::Create => None, + }; + + let engine = self.client.engine(); + let contract_address = contract_address.or({ + let sender = transaction.sender(); + let nonce = state.nonce(&sender)?; + let (new_address, _) = ethcore_contract_address(engine.create_address_scheme(env_info.number), &sender, &nonce, &transaction.data); + Some(new_address) + }); + let result = Executive::new(&mut state, &env_info, engine.machine()).transact_virtual(transaction, options)?; + let (encrypted_code, encrypted_storage) = match contract_address { + None => bail!(ErrorKind::ContractDoesNotExist), + Some(address) => { + let (code, storage) = state.into_account(&address)?; + let enc_code = match code { + Some(c) => Some(self.encrypt(&address, &Self::iv_from_address(&address), &c)?), + None => None, + }; + (enc_code, self.encrypt(&address, &Self::iv_from_transaction(transaction), &Self::snapshot_from_storage(&storage))?) + }, + }; + trace!("Private contract executed. code: {:?}, state: {:?}, result: {:?}", encrypted_code, encrypted_storage, result.output); + Ok(PrivateExecutionResult { + code: encrypted_code, + state: encrypted_storage, + contract_address, + result, + }) + } + + fn generate_constructor(validators: &[Address], code: Bytes, storage: Bytes) -> Bytes { + let constructor_code = DEFAULT_STUB_CONTRACT.from_hex().expect("Default contract code is valid"); + let private = private::PrivateContract::default(); + private.constructor(constructor_code, validators.iter().map(|a| *a).collect::>(), code, storage) + } + + fn generate_set_state_call(signatures: &[Signature], storage: Bytes) -> Bytes { + let private = private::PrivateContract::default(); + private.functions().set_state().input( + storage, + signatures.iter().map(|s| { + let mut v: [u8; 32] = [0; 32]; + v[31] = s.v(); + v + }).collect::>(), + signatures.iter().map(|s| s.r()).collect::>(), + signatures.iter().map(|s| s.s()).collect::>() + ) + } + + /// Returns the key from the key server associated with the contract + pub fn contract_key_id(&self, contract_address: &Address) -> Result { + //current solution uses contract address extended with 0 as id + let contract_address_extended: H256 = contract_address.into(); + + Ok(H256::from_slice(&contract_address_extended)) + } + + /// Create encrypted public contract deployment transaction. + pub fn public_creation_transaction(&self, block: BlockId, source: &SignedTransaction, validators: &[Address], gas_price: U256) -> Result<(Transaction, Option
), Error> { + if let Action::Call(_) = source.action { + bail!(ErrorKind::BadTransactonType); + } + let sender = source.sender(); + let state = self.client.state_at(block).ok_or(ErrorKind::StatePruned)?; + let nonce = state.nonce(&sender)?; + let executed = self.execute_private(source, TransactOptions::with_no_tracing(), block)?; + let gas: u64 = 650000 + + validators.len() as u64 * 30000 + + executed.code.as_ref().map_or(0, |c| c.len() as u64) * 8000 + + executed.state.len() as u64 * 8000; + Ok((Transaction { + nonce: nonce, + action: Action::Create, + gas: gas.into(), + gas_price: gas_price, + value: source.value, + data: Self::generate_constructor(validators, executed.code.unwrap_or_default(), executed.state) + }, + executed.contract_address)) + } + + /// Create encrypted public contract deployment transaction. Returns updated encrypted state. + pub fn execute_private_transaction(&self, block: BlockId, source: &SignedTransaction) -> Result { + if let Action::Create = source.action { + bail!(ErrorKind::BadTransactonType); + } + let result = self.execute_private(source, TransactOptions::with_no_tracing(), block)?; + Ok(result.state) + } + + /// Create encrypted public transaction from private transaction. + pub fn public_transaction(&self, state: Bytes, source: &SignedTransaction, signatures: &[Signature], nonce: U256, gas_price: U256) -> Result { + let gas: u64 = 650000 + state.len() as u64 * 8000 + signatures.len() as u64 * 50000; + Ok(Transaction { + nonce: nonce, + action: source.action.clone(), + gas: gas.into(), + gas_price: gas_price, + value: 0.into(), + data: Self::generate_set_state_call(signatures, state) + }) + } + + /// Call into private contract. + pub fn private_call(&self, block: BlockId, transaction: &SignedTransaction) -> Result { + let result = self.execute_private(transaction, TransactOptions::with_no_tracing(), block)?; + Ok(result.result) + } + + /// Returns private validators for a contract. + pub fn get_validators(&self, block: BlockId, address: &Address) -> Result, Error> { + let contract = private::PrivateContract::default(); + Ok(contract.functions() + .get_validators() + .call(&|data| self.client.call_contract(block, *address, data)) + .map_err(|e| ErrorKind::Call(format!("Contract call failed {:?}", e)))?) + } +} + +/// 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 { + if let Ok(true) = account_provider.test_password(account, password) { + return Some(password.clone()); + } + } + None +} + +impl ChainNotify for Provider { + fn new_blocks(&self, imported: Vec, _invalid: Vec, _enacted: Vec, _retracted: Vec, _sealed: Vec, _proposed: Vec, _duration: u64) { + if !imported.is_empty() { + trace!("New blocks imported, try to prune the queue"); + if let Err(err) = self.process_queue() { + trace!("Cannot prune private transactions queue. error: {:?}", err); + } + } + } +} + diff --git a/ethcore/private-tx/src/messages.rs b/ethcore/private-tx/src/messages.rs new file mode 100644 index 00000000000..f465f752be9 --- /dev/null +++ b/ethcore/private-tx/src/messages.rs @@ -0,0 +1,76 @@ +// 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 ethereum_types::{H256, U256, Address}; +use bytes::Bytes; +use hash::keccak; +use rlp::Encodable; +use ethkey::Signature; +use transaction::signature::{add_chain_replay_protection, check_replay_protection}; + +/// Message with private transaction encrypted +#[derive(Default, Debug, Clone, PartialEq, RlpEncodable, RlpDecodable, Eq)] +pub struct PrivateTransaction { + /// Encrypted data + pub encrypted: Bytes, + /// Address of the contract + pub contract: Address, +} + +impl PrivateTransaction { + /// Compute hash on private transaction + pub fn hash(&self) -> H256 { + keccak(&*self.rlp_bytes()) + } +} + +/// Message about private transaction's signing +#[derive(Default, Debug, Clone, PartialEq, RlpEncodable, RlpDecodable, Eq)] +pub struct SignedPrivateTransaction { + /// Hash of the corresponding private transaction + private_transaction_hash: H256, + /// Signature of the validator + /// The V field of the signature + v: u64, + /// The R field of the signature + r: U256, + /// The S field of the signature + s: U256, +} + +impl SignedPrivateTransaction { + /// Construct a signed private transaction message + pub fn new(private_transaction_hash: H256, sig: Signature, chain_id: Option) -> Self { + SignedPrivateTransaction { + private_transaction_hash: private_transaction_hash, + r: sig.r().into(), + s: sig.s().into(), + v: add_chain_replay_protection(sig.v() as u64, chain_id), + } + } + + pub fn standard_v(&self) -> u8 { check_replay_protection(self.v) } + + /// Construct a signature object from the sig. + pub fn signature(&self) -> Signature { + Signature::from_rsv(&self.r.into(), &self.s.into(), self.standard_v()) + } + + /// Get the hash of of the original transaction. + pub fn private_transaction_hash(&self) -> H256 { + self.private_transaction_hash + } +} diff --git a/ethcore/private-tx/src/private_transactions.rs b/ethcore/private-tx/src/private_transactions.rs new file mode 100644 index 00000000000..502694294ec --- /dev/null +++ b/ethcore/private-tx/src/private_transactions.rs @@ -0,0 +1,173 @@ +// 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 ethkey::Signature; +use bytes::Bytes; +use std::collections::HashMap; +use ethereum_types::{H256, U256, Address}; +use transaction::{UnverifiedTransaction, SignedTransaction}; +use ethcore_miner::transaction_queue::{TransactionQueue, RemovalReason, + TransactionDetailsProvider as TransactionQueueDetailsProvider, TransactionOrigin}; +use error::{Error, ErrorKind}; +use ethcore::header::BlockNumber; + +/// Maximum length for private transactions queues. +const MAX_QUEUE_LEN: usize = 8312; + +/// Desriptor for private transaction stored in queue for verification +#[derive(Default, Debug, Clone, PartialEq, Eq)] +pub struct PrivateTransactionDesc { + /// Hash of the private transaction + pub private_hash: H256, + /// Contract's address used in private transaction + pub contract: Address, + /// Address that should be used for verification + pub validator_account: Address, +} + +/// Storage for private transactions for verification +#[derive(Default)] +pub struct VerificationStore { + /// Descriptors for private transactions in queue for verification with key - hash of the original transaction + descriptors: HashMap, + /// Queue with transactions for verification + transactions: TransactionQueue, +} + +impl VerificationStore { + /// Adds private transaction for verification into the store + pub fn add_transaction( + &mut self, + transaction: UnverifiedTransaction, + contract: Address, + validator_account: Address, + private_hash: H256, + details_provider: &TransactionQueueDetailsProvider, + insertion_time: BlockNumber, + ) -> Result<(), Error> { + if self.descriptors.len() > MAX_QUEUE_LEN { + bail!(ErrorKind::QueueIsFull); + } + + if self.descriptors.get(&transaction.hash()).is_some() { + bail!(ErrorKind::PrivateTransactionAlreadyImported); + } + let transaction_hash = transaction.hash(); + let signed_transaction = SignedTransaction::new(transaction)?; + self.transactions + .add(signed_transaction, TransactionOrigin::External, insertion_time, None, details_provider) + .and_then(|_| { + self.descriptors.insert(transaction_hash, PrivateTransactionDesc{ + private_hash, + contract, + validator_account, + }); + Ok(()) + }) + .map_err(Into::into) + } + + /// Returns transactions ready for verification + /// Returns only one transaction per sender because several cannot be verified in a row without verification from other peers + pub fn ready_transactions(&self) -> Vec { + // TODO [ToDr] Performance killer, re-work with new transaction queue. + let mut transactions = self.transactions.top_transactions(); + // TODO [ToDr] Potential issue (create low address to have your transactions processed first) + transactions.sort_by(|a, b| a.sender().cmp(&b.sender())); + transactions.dedup_by(|a, b| a.sender().eq(&b.sender())); + transactions + } + + /// Returns descriptor of the corresponding private transaction + pub fn private_transaction_descriptor(&self, transaction_hash: &H256) -> Result<&PrivateTransactionDesc, Error> { + self.descriptors.get(transaction_hash).ok_or(ErrorKind::PrivateTransactionNotFound.into()) + } + + /// Remove transaction from the queue for verification + pub fn remove_private_transaction(&mut self, transaction_hash: &H256, fetch_nonce: &F) + where F: Fn(&Address) -> U256 { + + self.descriptors.remove(transaction_hash); + self.transactions.remove(transaction_hash, fetch_nonce, RemovalReason::Invalid); + } +} + +/// Desriptor for private transaction stored in queue for signing +#[derive(Debug, Clone)] +pub struct PrivateTransactionSigningDesc { + /// Original unsigned transaction + pub original_transaction: SignedTransaction, + /// Supposed validators from the contract + pub validators: Vec
, + /// Already obtained signatures + pub received_signatures: Vec, + /// State after transaction execution to compare further with received from validators + pub state: Bytes, + /// Build-in nonce of the contract + pub contract_nonce: U256, +} + +/// Storage for private transactions for signing +#[derive(Default)] +pub struct SigningStore { + /// Transactions and descriptors for signing + transactions: HashMap, +} + +impl SigningStore { + /// Adds new private transaction into the store for signing + pub fn add_transaction( + &mut self, + private_hash: H256, + transaction: SignedTransaction, + validators: Vec
, + state: Bytes, + contract_nonce: U256, + ) -> Result<(), Error> { + if self.transactions.len() > MAX_QUEUE_LEN { + bail!(ErrorKind::QueueIsFull); + } + + self.transactions.insert(private_hash, PrivateTransactionSigningDesc { + original_transaction: transaction.clone(), + validators: validators.clone(), + received_signatures: Vec::new(), + state, + contract_nonce, + }); + Ok(()) + } + + /// Get copy of private transaction's description from the storage + pub fn get(&self, private_hash: &H256) -> Option { + self.transactions.get(private_hash).cloned() + } + + /// Removes desc from the store (after verification is completed) + pub fn remove(&mut self, private_hash: &H256) -> Result<(), Error> { + self.transactions.remove(private_hash); + Ok(()) + } + + /// Adds received signature for the stored private transaction + pub fn add_signature(&mut self, private_hash: &H256, signature: Signature) -> Result<(), Error> { + let desc = self.transactions.get_mut(private_hash).ok_or_else(|| ErrorKind::PrivateTransactionNotFound)?; + if !desc.received_signatures.contains(&signature) { + desc.received_signatures.push(signature); + } + Ok(()) + } +} diff --git a/ethcore/private-tx/tests/private_contract.rs b/ethcore/private-tx/tests/private_contract.rs new file mode 100644 index 00000000000..ba918c96361 --- /dev/null +++ b/ethcore/private-tx/tests/private_contract.rs @@ -0,0 +1,137 @@ +// 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 . + +//! Contract for private transactions tests. + +extern crate rustc_hex; +extern crate ethcore; +extern crate ethkey; +extern crate keccak_hash as hash; +extern crate ethcore_io; +extern crate ethcore_logger; +extern crate ethcore_private_tx; +extern crate ethcore_transaction; + +#[macro_use] +extern crate log; + +use std::sync::Arc; +use rustc_hex::FromHex; + +use ethcore::CreateContractAddress; +use ethcore::account_provider::AccountProvider; +use ethcore::client::BlockChainClient; +use ethcore::client::BlockId; +use ethcore::executive::{contract_address}; +use ethcore::test_helpers::{generate_dummy_client, push_block_with_transactions}; +use ethcore_transaction::{Transaction, Action}; +use ethkey::{Secret, KeyPair, Signature}; +use hash::keccak; + +use ethcore_private_tx::{NoopEncryptor, Provider, ProviderConfig}; + +#[test] +fn private_contract() { + // This uses a simple private contract: contract Test1 { bytes32 public x; function setX(bytes32 _x) { x = _x; } } + ethcore_logger::init_log(); + let client = generate_dummy_client(0); + let chain_id = client.signing_chain_id(); + let key1 = KeyPair::from_secret(Secret::from("0000000000000000000000000000000000000000000000000000000000000011")).unwrap(); + let _key2 = KeyPair::from_secret(Secret::from("0000000000000000000000000000000000000000000000000000000000000012")).unwrap(); + let key3 = KeyPair::from_secret(Secret::from("0000000000000000000000000000000000000000000000000000000000000013")).unwrap(); + let key4 = KeyPair::from_secret(Secret::from("0000000000000000000000000000000000000000000000000000000000000014")).unwrap(); + let ap = Arc::new(AccountProvider::transient_provider()); + ap.insert_account(key1.secret().clone(), "").unwrap(); + ap.insert_account(key3.secret().clone(), "").unwrap(); + ap.insert_account(key4.secret().clone(), "").unwrap(); + + let config = ProviderConfig{ + validator_accounts: vec![key3.address(), key4.address()], + signer_account: None, + passwords: vec!["".into()], + }; + + let io = ethcore_io::IoChannel::disconnected(); + let pm = Arc::new(Provider::new(client.clone(), ap.clone(), Box::new(NoopEncryptor::default()), config, io).unwrap()); + + let (address, _) = contract_address(CreateContractAddress::FromSenderAndNonce, &key1.address(), &0.into(), &[]); + + trace!("Creating private contract"); + let private_contract_test = "6060604052341561000f57600080fd5b60d88061001d6000396000f30060606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680630c55699c146046578063bc64b76d14607457600080fd5b3415605057600080fd5b60566098565b60405180826000191660001916815260200191505060405180910390f35b3415607e57600080fd5b6096600480803560001916906020019091905050609e565b005b60005481565b8060008160001916905550505600a165627a7a723058206acbdf4b15ca4c2d43e1b1879b830451a34f1e9d02ff1f2f394d8d857e79d2080029".from_hex().unwrap(); + let mut private_create_tx = Transaction::default(); + private_create_tx.action = Action::Create; + private_create_tx.data = private_contract_test; + private_create_tx.gas = 200000.into(); + let private_create_tx_signed = private_create_tx.sign(&key1.secret(), None); + let validators = vec![key3.address(), key4.address()]; + let (public_tx, _) = pm.public_creation_transaction(BlockId::Latest, &private_create_tx_signed, &validators, 0.into()).unwrap(); + let public_tx = public_tx.sign(&key1.secret(), chain_id); + trace!("Transaction created. Pushing block"); + push_block_with_transactions(&client, &[public_tx]); + + trace!("Modifying private state"); + let mut private_tx = Transaction::default(); + private_tx.action = Action::Call(address.clone()); + private_tx.data = "bc64b76d2a00000000000000000000000000000000000000000000000000000000000000".from_hex().unwrap(); //setX(42) + private_tx.gas = 120000.into(); + private_tx.nonce = 1.into(); + let private_tx = private_tx.sign(&key1.secret(), None); + let private_contract_nonce = pm.get_contract_nonce(&address, BlockId::Latest).unwrap(); + let private_state = pm.execute_private_transaction(BlockId::Latest, &private_tx).unwrap(); + let nonced_state_hash = pm.calculate_state_hash(&private_state, private_contract_nonce); + let signatures: Vec<_> = [&key3, &key4].iter().map(|k| + Signature::from(::ethkey::sign(&k.secret(), &nonced_state_hash).unwrap().into_electrum())).collect(); + let public_tx = pm.public_transaction(private_state, &private_tx, &signatures, 1.into(), 0.into()).unwrap(); + let public_tx = public_tx.sign(&key1.secret(), chain_id); + push_block_with_transactions(&client, &[public_tx]); + + trace!("Querying private state"); + let mut query_tx = Transaction::default(); + query_tx.action = Action::Call(address.clone()); + query_tx.data = "0c55699c".from_hex().unwrap(); // getX + query_tx.gas = 50000.into(); + query_tx.nonce = 2.into(); + let query_tx = query_tx.sign(&key1.secret(), chain_id); + let result = pm.private_call(BlockId::Latest, &query_tx).unwrap(); + assert_eq!(&result.output[..], &("2a00000000000000000000000000000000000000000000000000000000000000".from_hex().unwrap()[..])); + assert_eq!(pm.get_validators(BlockId::Latest, &address).unwrap(), validators); + + // Now try modification with just one signature + trace!("Modifying private state"); + let mut private_tx = Transaction::default(); + private_tx.action = Action::Call(address.clone()); + private_tx.data = "bc64b76d2b00000000000000000000000000000000000000000000000000000000000000".from_hex().unwrap(); //setX(43) + private_tx.gas = 120000.into(); + private_tx.nonce = 2.into(); + let private_tx = private_tx.sign(&key1.secret(), None); + let private_state = pm.execute_private_transaction(BlockId::Latest, &private_tx).unwrap(); + let private_state_hash = keccak(&private_state); + let signatures: Vec<_> = [&key4].iter().map(|k| + Signature::from(::ethkey::sign(&k.secret(), &private_state_hash).unwrap().into_electrum())).collect(); + let public_tx = pm.public_transaction(private_state, &private_tx, &signatures, 2.into(), 0.into()).unwrap(); + let public_tx = public_tx.sign(&key1.secret(), chain_id); + push_block_with_transactions(&client, &[public_tx]); + + trace!("Querying private state"); + let mut query_tx = Transaction::default(); + query_tx.action = Action::Call(address.clone()); + query_tx.data = "0c55699c".from_hex().unwrap(); // getX + query_tx.gas = 50000.into(); + query_tx.nonce = 3.into(); + let query_tx = query_tx.sign(&key1.secret(), chain_id); + let result = pm.private_call(BlockId::Latest, &query_tx).unwrap(); + assert_eq!(result.output, "2a00000000000000000000000000000000000000000000000000000000000000".from_hex().unwrap()); +} diff --git a/ethcore/service/Cargo.toml b/ethcore/service/Cargo.toml index 4b53f5d00a5..608d591e09b 100644 --- a/ethcore/service/Cargo.toml +++ b/ethcore/service/Cargo.toml @@ -5,8 +5,11 @@ authors = ["Parity Technologies "] [dependencies] ansi_term = "0.10" +error-chain = { version = "0.11", default-features = false } ethcore = { path = ".." } ethcore-io = { path = "../../util/io" } +ethcore-private-tx = { path = "../private-tx" } +ethsync = { path = "../../sync" } kvdb = { path = "../../util/kvdb" } log = "0.3" stop-guard = { path = "../../util/stop-guard" } diff --git a/ethcore/service/src/error.rs b/ethcore/service/src/error.rs new file mode 100644 index 00000000000..bb403d0bfc0 --- /dev/null +++ b/ethcore/service/src/error.rs @@ -0,0 +1,30 @@ +// 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 ethcore; +use io; +use ethcore_private_tx; + +error_chain! { + links { + PrivateTransactions(ethcore_private_tx::Error, ethcore_private_tx::ErrorKind); + } + + foreign_links { + Ethcore(ethcore::error::Error); + IoError(io::IoError); + } +} diff --git a/ethcore/service/src/lib.rs b/ethcore/service/src/lib.rs index 83d9a8fe10c..5bd1c39de5f 100644 --- a/ethcore/service/src/lib.rs +++ b/ethcore/service/src/lib.rs @@ -17,18 +17,25 @@ extern crate ansi_term; extern crate ethcore; extern crate ethcore_io as io; +extern crate ethsync; extern crate kvdb; +extern crate ethcore_private_tx; extern crate stop_guard; +#[macro_use] +extern crate error_chain; + #[macro_use] extern crate log; #[cfg(test)] extern crate tempdir; +mod error; +mod service; + #[cfg(test)] extern crate kvdb_rocksdb; -mod service; - -pub use service::ClientService; +pub use error::{Error, ErrorKind}; +pub use service::{ClientService, PrivateTxService}; diff --git a/ethcore/service/src/service.rs b/ethcore/service/src/service.rs index 4337996e2b0..27f58b42151 100644 --- a/ethcore/service/src/service.rs +++ b/ethcore/service/src/service.rs @@ -24,18 +24,50 @@ use io::{IoContext, TimerToken, IoHandler, IoService, IoError}; use kvdb::{KeyValueDB, KeyValueDBHandler}; use stop_guard::StopGuard; +use ethsync::PrivateTxHandler; use ethcore::client::{Client, ClientConfig, ChainNotify, ClientIoMessage}; -use ethcore::error::Error; use ethcore::miner::Miner; use ethcore::snapshot::service::{Service as SnapshotService, ServiceParams as SnapServiceParams}; use ethcore::snapshot::{RestorationStatus}; use ethcore::spec::Spec; +use ethcore::account_provider::AccountProvider; + +use ethcore_private_tx; +use Error; + +pub struct PrivateTxService { + provider: Arc, +} + +impl PrivateTxService { + fn new(provider: Arc) -> Self { + PrivateTxService { + provider, + } + } + + /// Returns underlying provider. + pub fn provider(&self) -> Arc { + self.provider.clone() + } +} + +impl PrivateTxHandler for PrivateTxService { + fn import_private_transaction(&self, rlp: &[u8]) -> Result<(), String> { + self.provider.import_private_transaction(rlp).map_err(|e| e.to_string()) + } + + fn import_signed_private_transaction(&self, rlp: &[u8]) -> Result<(), String> { + self.provider.import_signed_private_transaction(rlp).map_err(|e| e.to_string()) + } +} /// Client service setup. Creates and registers client and network services with the IO subsystem. pub struct ClientService { io_service: Arc>, client: Arc, snapshot: Arc, + private_tx: Arc, database: Arc, _stop_guard: StopGuard, } @@ -50,6 +82,9 @@ impl ClientService { restoration_db_handler: Box, _ipc_path: &Path, miner: Arc, + account_provider: Arc, + encryptor: Box, + private_tx_conf: ethcore_private_tx::ProviderConfig, ) -> Result { let io_service = IoService::::start()?; @@ -70,9 +105,13 @@ impl ClientService { }; let snapshot = Arc::new(SnapshotService::new(snapshot_params)?); + let provider = Arc::new(ethcore_private_tx::Provider::new(client.clone(), account_provider, encryptor, private_tx_conf, 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)?; @@ -84,6 +123,7 @@ impl ClientService { io_service: Arc::new(io_service), client: client, snapshot: snapshot, + private_tx, database: client_db, _stop_guard: stop_guard, }) @@ -104,6 +144,11 @@ impl ClientService { self.snapshot.clone() } + /// Get private transaction service. + pub fn private_tx_service(&self) -> Arc { + self.private_tx.clone() + } + /// Get network service component pub fn io(&self) -> Arc> { self.io_service.clone() @@ -122,6 +167,7 @@ impl ClientService { struct ClientIoHandler { client: Arc, snapshot: Arc, + private_tx: Arc, } const CLIENT_TICK_TIMER: TimerToken = 0; @@ -180,6 +226,9 @@ impl IoHandler for ClientIoHandler { 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); + }, _ => {} // ignore other messages } } @@ -192,6 +241,7 @@ mod tests { use tempdir::TempDir; + use ethcore::account_provider::AccountProvider; use ethcore::client::ClientConfig; use ethcore::miner::Miner; use ethcore::spec::Spec; @@ -200,6 +250,8 @@ mod tests { use kvdb_rocksdb::{Database, DatabaseConfig, CompactionProfile}; use super::*; + use ethcore_private_tx; + #[test] fn it_can_be_started() { let tempdir = TempDir::new("").unwrap(); @@ -241,6 +293,9 @@ mod tests { restoration_db_handler, tempdir.path(), Arc::new(Miner::with_spec(&spec)), + Arc::new(AccountProvider::transient_provider()), + Box::new(ethcore_private_tx::NoopEncryptor), + Default::default() ); assert!(service.is_ok()); drop(service.unwrap()); diff --git a/ethcore/src/block.rs b/ethcore/src/block.rs index 2280b40dea3..8e1fac1792e 100644 --- a/ethcore/src/block.rs +++ b/ethcore/src/block.rs @@ -645,7 +645,7 @@ pub fn enact_verified( #[cfg(test)] mod tests { - use tests::helpers::get_temp_state_db; + use test_helpers::get_temp_state_db; use super::*; use engines::EthEngine; use vm::LastHashes; diff --git a/ethcore/src/blockchain/blockchain.rs b/ethcore/src/blockchain/blockchain.rs index ae5ac18eb9b..5dffc9ec371 100644 --- a/ethcore/src/blockchain/blockchain.rs +++ b/ethcore/src/blockchain/blockchain.rs @@ -1421,7 +1421,7 @@ mod tests { use ethereum_types::*; use receipt::{Receipt, TransactionOutcome}; use blockchain::{BlockProvider, BlockChain, Config, ImportRoute}; - use tests::helpers::{ + use test_helpers::{ generate_dummy_blockchain, generate_dummy_blockchain_with_extra, generate_dummy_empty_blockchain }; diff --git a/ethcore/src/client/chain_notify.rs b/ethcore/src/client/chain_notify.rs index d05c95b8c85..bdd8d00278c 100644 --- a/ethcore/src/client/chain_notify.rs +++ b/ethcore/src/client/chain_notify.rs @@ -17,6 +17,16 @@ use ethereum_types::H256; use bytes::Bytes; +/// Messages to broadcast via chain +pub enum ChainMessageType { + /// Consensus message + Consensus(Vec), + /// Message with private transaction + PrivateTransaction(Vec), + /// Message with signed private transaction + SignedPrivateTransaction(Vec), +} + /// Represents what has to be handled by actor listening to chain events pub trait ChainNotify : Send + Sync { /// fires when chain has new blocks. @@ -45,7 +55,7 @@ pub trait ChainNotify : Send + Sync { } /// fires when chain broadcasts a message - fn broadcast(&self, _data: Vec) {} + fn broadcast(&self, _message_type: ChainMessageType) {} /// fires when new transactions are received from a peer fn transactions_received(&self, diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index 31f8f2f25df..a8ce3f65c3c 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -45,7 +45,7 @@ use client::{ use client::{ BlockId, TransactionId, UncleId, TraceId, ClientConfig, BlockChainClient, MiningBlockChainClient, TraceFilter, CallAnalytics, BlockImportError, Mode, - ChainNotify, PruningInfo, ProvingBlockChainClient, EngineInfo + ChainNotify, PruningInfo, ProvingBlockChainClient, EngineInfo, ChainMessageType }; use encoded; use engines::{EthEngine, EpochTransition}; @@ -2126,7 +2126,7 @@ impl super::traits::EngineClient for Client { } fn broadcast_consensus_message(&self, message: Bytes) { - self.notify(|notify| notify.broadcast(message.clone())); + self.notify(|notify| notify.broadcast(ChainMessageType::Consensus(message.clone()))); } fn epoch_transition_for(&self, parent_hash: H256) -> Option<::engines::EpochTransition> { @@ -2237,7 +2237,7 @@ mod tests { #[test] fn should_not_cache_details_before_commit() { use client::{BlockChainClient, ChainInfo}; - use tests::helpers::{generate_dummy_client, get_good_dummy_block_hash}; + use test_helpers::{generate_dummy_client, get_good_dummy_block_hash}; use std::thread; use std::time::Duration; diff --git a/ethcore/src/client/io_message.rs b/ethcore/src/client/io_message.rs index c2823a39f65..e19d3054fe0 100644 --- a/ethcore/src/client/io_message.rs +++ b/ethcore/src/client/io_message.rs @@ -36,6 +36,8 @@ pub enum ClientIoMessage { /// Take a snapshot for the block with given number. TakeSnapshot(u64), /// New consensus message received. - NewMessage(Bytes) + NewMessage(Bytes), + /// New private transaction arrived + NewPrivateTransaction, } diff --git a/ethcore/src/client/mod.rs b/ethcore/src/client/mod.rs index b92240591b5..2ae3436aa98 100644 --- a/ethcore/src/client/mod.rs +++ b/ethcore/src/client/mod.rs @@ -31,11 +31,12 @@ 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; +pub use self::chain_notify::{ChainNotify, 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 }; +//pub use self::private_notify::PrivateNotify; pub use state::StateInfo; pub use self::traits::{BlockChainClient, MiningBlockChainClient, EngineClient, ProvingBlockChainClient}; @@ -53,3 +54,4 @@ pub use verification::VerifierType; mod traits; mod chain_notify; +mod private_notify; diff --git a/ethcore/src/client/private_notify.rs b/ethcore/src/client/private_notify.rs new file mode 100644 index 00000000000..2b865a9e2c7 --- /dev/null +++ b/ethcore/src/client/private_notify.rs @@ -0,0 +1,23 @@ +// 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::TransactionImportError; + +/// Represent private transactions handler inside the client +pub trait PrivateNotify : Send + Sync { + /// fires when private transaction message queued via client io queue + fn private_transaction_queued(&self) -> Result<(), TransactionImportError>; +} diff --git a/ethcore/src/engines/authority_round/mod.rs b/ethcore/src/engines/authority_round/mod.rs index 0acde347e2b..8282e5738a8 100644 --- a/ethcore/src/engines/authority_round/mod.rs +++ b/ethcore/src/engines/authority_round/mod.rs @@ -1326,7 +1326,7 @@ mod tests { use header::Header; use rlp::encode; use block::*; - use tests::helpers::{ + use test_helpers::{ generate_dummy_client_with_spec_and_accounts, get_temp_state_db, generate_dummy_client, TestNotify }; diff --git a/ethcore/src/engines/basic_authority.rs b/ethcore/src/engines/basic_authority.rs index 4d1f38dce4c..c4eafd851c6 100644 --- a/ethcore/src/engines/basic_authority.rs +++ b/ethcore/src/engines/basic_authority.rs @@ -199,7 +199,7 @@ mod tests { use hash::keccak; use ethereum_types::H520; use block::*; - use tests::helpers::get_temp_state_db; + use test_helpers::get_temp_state_db; use account_provider::AccountProvider; use header::Header; use spec::Spec; diff --git a/ethcore/src/engines/instant_seal.rs b/ethcore/src/engines/instant_seal.rs index af997c022e6..40a96e2b713 100644 --- a/ethcore/src/engines/instant_seal.rs +++ b/ethcore/src/engines/instant_seal.rs @@ -67,7 +67,7 @@ impl Engine for InstantSeal mod tests { use std::sync::Arc; use ethereum_types::{H520, Address}; - use tests::helpers::{get_temp_state_db}; + use test_helpers::get_temp_state_db; use spec::Spec; use header::Header; use block::*; diff --git a/ethcore/src/engines/tendermint/mod.rs b/ethcore/src/engines/tendermint/mod.rs index 4d0656749a3..011e3f8d425 100644 --- a/ethcore/src/engines/tendermint/mod.rs +++ b/ethcore/src/engines/tendermint/mod.rs @@ -514,7 +514,6 @@ impl Engine for Tendermint { fn fmt_err(x: T) -> EngineError { EngineError::MalformedMessage(format!("{:?}", x)) } - let rlp = UntrustedRlp::new(rlp); let message: ConsensusMessage = rlp.as_val().map_err(fmt_err)?; if !self.votes.is_old_or_known(&message) { @@ -783,7 +782,7 @@ mod tests { use header::Header; use client::ChainInfo; use miner::MinerService; - use tests::helpers::{ + use test_helpers::{ TestNotify, get_temp_state_db, generate_dummy_client, generate_dummy_client_with_spec_and_accounts }; diff --git a/ethcore/src/engines/validator_set/contract.rs b/ethcore/src/engines/validator_set/contract.rs index 319d96db938..fb9fccf3e22 100644 --- a/ethcore/src/engines/validator_set/contract.rs +++ b/ethcore/src/engines/validator_set/contract.rs @@ -145,8 +145,8 @@ mod tests { use account_provider::AccountProvider; use miner::MinerService; use types::ids::BlockId; + use test_helpers::generate_dummy_client_with_spec_and_accounts; use client::{BlockChainClient, ChainInfo, BlockInfo, CallContract}; - use tests::helpers::generate_dummy_client_with_spec_and_accounts; use super::super::ValidatorSet; use super::ValidatorContract; diff --git a/ethcore/src/engines/validator_set/multi.rs b/ethcore/src/engines/validator_set/multi.rs index 2794b57a2a4..9c287f9a371 100644 --- a/ethcore/src/engines/validator_set/multi.rs +++ b/ethcore/src/engines/validator_set/multi.rs @@ -155,7 +155,7 @@ mod tests { use header::Header; use miner::MinerService; use spec::Spec; - use tests::helpers::{generate_dummy_client_with_spec_and_accounts, generate_dummy_client_with_spec_and_data}; + use test_helpers::{generate_dummy_client_with_spec_and_accounts, generate_dummy_client_with_spec_and_data}; use types::ids::BlockId; use ethereum_types::Address; diff --git a/ethcore/src/engines/validator_set/safe_contract.rs b/ethcore/src/engines/validator_set/safe_contract.rs index 668feac26f4..82befdadff2 100644 --- a/ethcore/src/engines/validator_set/safe_contract.rs +++ b/ethcore/src/engines/validator_set/safe_contract.rs @@ -459,7 +459,7 @@ mod tests { use client::{ChainInfo, BlockInfo, ImportBlock}; use ethkey::Secret; use miner::MinerService; - use tests::helpers::{generate_dummy_client_with_spec_and_accounts, generate_dummy_client_with_spec_and_data}; + use test_helpers::{generate_dummy_client_with_spec_and_accounts, generate_dummy_client_with_spec_and_data}; use super::super::ValidatorSet; use super::{ValidatorSafeContract, EVENT_NAME_HASH}; diff --git a/ethcore/src/error.rs b/ethcore/src/error.rs index aae22411682..defb301dcbe 100644 --- a/ethcore/src/error.rs +++ b/ethcore/src/error.rs @@ -16,7 +16,7 @@ //! General error types for use in ethcore. -use std::fmt; +use std::{fmt, error}; use kvdb; use ethereum_types::{H256, U256, Address, Bloom}; use util_error::UtilError; @@ -268,6 +268,13 @@ impl fmt::Display for Error { } } +impl error::Error for Error { + fn description(&self) -> &str { + // improve description + "ethcore error" + } +} + /// Result of import block operation. pub type ImportResult = Result; diff --git a/ethcore/src/ethereum/ethash.rs b/ethcore/src/ethereum/ethash.rs index 68a07d0cda3..41ab777d4a7 100644 --- a/ethcore/src/ethereum/ethash.rs +++ b/ethcore/src/ethereum/ethash.rs @@ -487,7 +487,7 @@ mod tests { use std::sync::Arc; use ethereum_types::{H64, H256, U256, Address}; use block::*; - use tests::helpers::get_temp_state_db; + use test_helpers::get_temp_state_db; use error::{BlockError, Error}; use header::Header; use spec::Spec; diff --git a/ethcore/src/ethereum/mod.rs b/ethcore/src/ethereum/mod.rs index aea53ecaea5..1bdcb01e14e 100644 --- a/ethcore/src/ethereum/mod.rs +++ b/ethcore/src/ethereum/mod.rs @@ -145,7 +145,7 @@ mod tests { use ethereum_types::U256; use state::*; use super::*; - use tests::helpers::get_temp_state_db; + use test_helpers::get_temp_state_db; use views::BlockView; #[test] diff --git a/ethcore/src/executive.rs b/ethcore/src/executive.rs index c33eb2ecd6f..a97ee37081a 100644 --- a/ethcore/src/executive.rs +++ b/ethcore/src/executive.rs @@ -701,7 +701,7 @@ mod tests { use error::ExecutionError; use machine::EthereumMachine; use state::{Substate, CleanupMode}; - use tests::helpers::{get_temp_state_with_factory, get_temp_state}; + use test_helpers::{get_temp_state_with_factory, get_temp_state}; use trace::trace; use trace::{FlatTrace, Tracer, NoopTracer, ExecutiveTracer}; use trace::{VMTrace, VMOperation, VMExecutedOperation, MemoryDiff, StorageDiff, VMTracer, NoopVMTracer, ExecutiveVMTracer}; @@ -746,7 +746,6 @@ mod tests { assert_eq!(state.storage_at(&address, &H256::new()).unwrap(), H256::from(&U256::from(0xf9u64))); assert_eq!(state.balance(&sender).unwrap(), U256::from(0xf9)); assert_eq!(state.balance(&address).unwrap(), U256::from(0x7)); - // 0 cause contract hasn't returned assert_eq!(substate.contracts_created.len(), 0); // TODO: just test state root. diff --git a/ethcore/src/externalities.rs b/ethcore/src/externalities.rs index 732d3499a83..5d35d1109ae 100644 --- a/ethcore/src/externalities.rs +++ b/ethcore/src/externalities.rs @@ -414,7 +414,7 @@ mod tests { use ethereum_types::{U256, Address}; use evm::{EnvInfo, Ext, CallType}; use state::{State, Substate}; - use tests::helpers::get_temp_state; + use test_helpers::get_temp_state; use super::*; use trace::{NoopTracer, NoopVMTracer}; diff --git a/ethcore/src/json_tests/executive.rs b/ethcore/src/json_tests/executive.rs index 0ec60d49319..404b1c25e69 100644 --- a/ethcore/src/json_tests/executive.rs +++ b/ethcore/src/json_tests/executive.rs @@ -25,7 +25,7 @@ use vm::{ CreateContractAddress, ReturnData, }; use externalities::*; -use tests::helpers::get_temp_state; +use test_helpers::get_temp_state; use ethjson; use trace::{Tracer, NoopTracer}; use trace::{VMTracer, NoopVMTracer}; diff --git a/ethcore/src/lib.rs b/ethcore/src/lib.rs index d822195d321..c71a266f740 100644 --- a/ethcore/src/lib.rs +++ b/ethcore/src/lib.rs @@ -94,6 +94,7 @@ extern crate ansi_term; extern crate unexpected; extern crate kvdb; extern crate kvdb_memorydb; +extern crate kvdb_rocksdb; extern crate util_error; extern crate snappy; @@ -128,9 +129,6 @@ extern crate trace_time; #[cfg_attr(test, macro_use)] extern crate evm; -#[cfg(test)] -extern crate kvdb_rocksdb; - pub extern crate ethstore; pub mod account_provider; @@ -142,6 +140,7 @@ pub mod engines; pub mod error; pub mod ethereum; pub mod executed; +pub mod executive; pub mod header; pub mod machine; pub mod miner; @@ -150,6 +149,8 @@ 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; pub mod views; @@ -159,7 +160,6 @@ mod blooms; mod pod_account; mod account_db; mod builtin; -mod executive; mod externalities; mod blockchain; mod factory; diff --git a/ethcore/src/miner/miner.rs b/ethcore/src/miner/miner.rs index b0628b3e0b2..96094dce413 100644 --- a/ethcore/src/miner/miner.rs +++ b/ethcore/src/miner/miner.rs @@ -24,7 +24,7 @@ use ethereum_types::{H256, U256, Address}; use parking_lot::{Mutex, RwLock}; use bytes::Bytes; use engines::{EthEngine, Seal}; -use error::*; +use error::{ExecutionError, Error}; use ethcore_miner::banning_queue::{BanningTransactionQueue, Threshold}; use ethcore_miner::local_transactions::{Status as LocalTransactionStatus}; use ethcore_miner::transaction_queue::{ @@ -1327,8 +1327,7 @@ mod tests { use spec::Spec; use transaction::{SignedTransaction, Transaction, PendingTransaction, Action}; use miner::MinerService; - - use tests::helpers::{generate_dummy_client, generate_dummy_client_with_spec_and_accounts}; + use test_helpers::{generate_dummy_client, generate_dummy_client_with_spec_and_accounts}; #[test] fn should_prepare_block_to_seal() { diff --git a/ethcore/src/snapshot/account.rs b/ethcore/src/snapshot/account.rs index b85f8f4013f..222875b842f 100644 --- a/ethcore/src/snapshot/account.rs +++ b/ethcore/src/snapshot/account.rs @@ -210,7 +210,7 @@ pub fn from_fat_rlp( mod tests { use account_db::{AccountDB, AccountDBMut}; use basic_account::BasicAccount; - use tests::helpers::get_temp_state_db; + use test_helpers::get_temp_state_db; use snapshot::tests::helpers::fill_storage; use hash::{KECCAK_EMPTY, KECCAK_NULL_RLP, keccak}; diff --git a/ethcore/src/snapshot/service.rs b/ethcore/src/snapshot/service.rs index fad150645db..7d5eea1eff4 100644 --- a/ethcore/src/snapshot/service.rs +++ b/ethcore/src/snapshot/service.rs @@ -635,7 +635,7 @@ mod tests { use snapshot::{ManifestData, RestorationStatus, SnapshotService}; use super::*; use tempdir::TempDir; - use tests::helpers::restoration_db_handler; + use test_helpers::restoration_db_handler; struct NoopDBRestore; impl DatabaseRestore for NoopDBRestore { diff --git a/ethcore/src/snapshot/tests/proof_of_authority.rs b/ethcore/src/snapshot/tests/proof_of_authority.rs index 101de5c586c..7283a05863d 100644 --- a/ethcore/src/snapshot/tests/proof_of_authority.rs +++ b/ethcore/src/snapshot/tests/proof_of_authority.rs @@ -25,7 +25,7 @@ use client::{Client, BlockChainClient, ChainInfo}; use ethkey::Secret; use snapshot::tests::helpers as snapshot_helpers; use spec::Spec; -use tests::helpers; +use test_helpers::generate_dummy_client_with_spec_and_accounts; use transaction::{Transaction, Action, SignedTransaction}; use tempdir::TempDir; @@ -89,7 +89,7 @@ enum Transition { // create a chain with the given transitions and some blocks beyond that transition. fn make_chain(accounts: Arc, blocks_beyond: usize, transitions: Vec) -> Arc { - let client = helpers::generate_dummy_client_with_spec_and_accounts( + let client = generate_dummy_client_with_spec_and_accounts( spec_fixed_to_contract, Some(accounts.clone())); let mut cur_signers = vec![*RICH_ADDR]; diff --git a/ethcore/src/snapshot/tests/service.rs b/ethcore/src/snapshot/tests/service.rs index 4548741f399..7e81b05796f 100644 --- a/ethcore/src/snapshot/tests/service.rs +++ b/ethcore/src/snapshot/tests/service.rs @@ -24,7 +24,7 @@ use ids::BlockId; use snapshot::service::{Service, ServiceParams}; use snapshot::{self, ManifestData, SnapshotService}; use spec::Spec; -use tests::helpers::{generate_dummy_client_with_spec_and_data, restoration_db_handler}; +use test_helpers::{generate_dummy_client_with_spec_and_data, restoration_db_handler}; use io::IoChannel; use kvdb_rocksdb::{Database, DatabaseConfig}; diff --git a/ethcore/src/spec/spec.rs b/ethcore/src/spec/spec.rs index f0b3b9203bb..ec1b5edf3da 100644 --- a/ethcore/src/spec/spec.rs +++ b/ethcore/src/spec/spec.rs @@ -892,7 +892,7 @@ impl Spec { mod tests { use super::*; use state::State; - use tests::helpers::get_temp_state_db; + use test_helpers::get_temp_state_db; use views::BlockView; use tempdir::TempDir; diff --git a/ethcore/src/state/account.rs b/ethcore/src/state/account.rs index 9d72ed158cf..f9c8f258e60 100755 --- a/ethcore/src/state/account.rs +++ b/ethcore/src/state/account.rs @@ -180,6 +180,16 @@ impl Account { self.init_code(code); } + /// Reset this account's code and storage to given values. + pub fn reset_code_and_storage(&mut self, code: Arc, storage: HashMap) { + self.code_hash = keccak(&*code); + self.code_cache = code; + self.code_size = Some(self.code_cache.len()); + self.code_filth = Filth::Dirty; + self.storage_cache = Self::empty_storage_cache(); + self.storage_changes = storage; + } + /// Set (and cache) the contents of the trie's storage at `key` to `value`. pub fn set_storage(&mut self, key: H256, value: H256) { self.storage_changes.insert(key, value); diff --git a/ethcore/src/state/mod.rs b/ethcore/src/state/mod.rs index 757f5451154..9fd3fd8525e 100755 --- a/ethcore/src/state/mod.rs +++ b/ethcore/src/state/mod.rs @@ -494,6 +494,13 @@ impl State { (self.root, self.db) } + /// Destroy the current object and return single account data. + pub fn into_account(self, account: &Address) -> trie::Result<(Option>, HashMap)> { + // TODO: deconstruct without cloning. + let account = self.require(account, true)?; + Ok((account.code().clone(), account.storage_changes().clone())) + } + /// Return reference to root pub fn root(&self) -> &H256 { &self.root @@ -1014,6 +1021,11 @@ impl State { } })) } + + /// Replace account code and storage. Creates account if it does not exist. + pub fn patch_account(&self, a: &Address, code: Arc, storage: HashMap) -> trie::Result<()> { + Ok(self.require(a, false)?.reset_code_and_storage(code, storage)) + } } // State proof implementations; useful for light client protocols. @@ -1099,7 +1111,7 @@ mod tests { use super::*; use ethkey::Secret; use ethereum_types::{H256, U256, Address}; - use tests::helpers::{get_temp_state, get_temp_state_db}; + use test_helpers::{get_temp_state, get_temp_state_db}; use machine::EthereumMachine; use vm::EnvInfo; use spec::*; diff --git a/ethcore/src/state_db.rs b/ethcore/src/state_db.rs index 346ad9cc2a6..3b00a42ee6d 100755 --- a/ethcore/src/state_db.rs +++ b/ethcore/src/state_db.rs @@ -480,7 +480,7 @@ unsafe impl Sync for SyncAccount {} mod tests { use ethereum_types::{H256, U256, Address}; use kvdb::DBTransaction; - use tests::helpers::{get_temp_state_db}; + use test_helpers::get_temp_state_db; use state::{Account, Backend}; use ethcore_logger::init_log; diff --git a/ethcore/src/tests/helpers.rs b/ethcore/src/test_helpers.rs similarity index 82% rename from ethcore/src/tests/helpers.rs rename to ethcore/src/test_helpers.rs index 14dcf3630b0..4c013dd251d 100644 --- a/ethcore/src/tests/helpers.rs +++ b/ethcore/src/test_helpers.rs @@ -14,12 +14,14 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . +//! Set of different helpers for client tests + use account_provider::AccountProvider; -use ethereum_types::{H256, U256}; +use ethereum_types::{H256, U256, Address}; use block::{OpenBlock, Drain}; use blockchain::{BlockChain, Config as BlockChainConfig}; use bytes::Bytes; -use client::{Client, ClientConfig, ChainInfo, ImportBlock, ChainNotify}; +use client::{Client, ClientConfig, ChainInfo, ImportBlock, ChainNotify, ChainMessageType, PrepareOpenBlock}; use ethkey::KeyPair; use evm::Factory as EvmFactory; use factory::Factories; @@ -39,6 +41,7 @@ use views::BlockView; use kvdb::{KeyValueDB, KeyValueDBHandler}; use kvdb_rocksdb::{Database, DatabaseConfig}; +/// Creates test block with corresponding header pub fn create_test_block(header: &Header) -> Bytes { let mut rlp = RlpStream::new_list(3); rlp.append(header); @@ -76,6 +79,7 @@ fn create_unverifiable_block(order: u32, parent_hash: H256) -> Bytes { create_test_block(&create_unverifiable_block_header(order, parent_hash)) } +/// Creates test block with corresponding header and data pub fn create_test_block_with_data(header: &Header, transactions: &[SignedTransaction], uncles: &[Header]) -> Bytes { let mut rlp = RlpStream::new_list(3); rlp.append(header); @@ -87,23 +91,27 @@ pub fn create_test_block_with_data(header: &Header, transactions: &[SignedTransa rlp.out() } +/// Generates dummy client (not test client) with corresponding amount of blocks pub fn generate_dummy_client(block_number: u32) -> Arc { generate_dummy_client_with_spec_and_data(Spec::new_test, block_number, 0, &[]) } +/// Generates dummy client (not test client) with corresponding amount of blocks and txs per every block pub fn generate_dummy_client_with_data(block_number: u32, txs_per_block: usize, tx_gas_prices: &[U256]) -> Arc { generate_dummy_client_with_spec_and_data(Spec::new_null, block_number, txs_per_block, tx_gas_prices) } - +/// Generates dummy client (not test client) with corresponding amount of blocks, txs per block and spec pub fn generate_dummy_client_with_spec_and_data(test_spec: F, block_number: u32, txs_per_block: usize, tx_gas_prices: &[U256]) -> Arc where F: Fn()->Spec { generate_dummy_client_with_spec_accounts_and_data(test_spec, None, block_number, txs_per_block, tx_gas_prices) } +/// Generates dummy client (not test client) with corresponding spec and accounts pub fn generate_dummy_client_with_spec_and_accounts(test_spec: F, accounts: Option>) -> Arc where F: Fn()->Spec { generate_dummy_client_with_spec_accounts_and_data(test_spec, accounts, 0, 0, &[]) } +/// Generates dummy client (not test client) with corresponding blocks, accounts and spec pub fn generate_dummy_client_with_spec_accounts_and_data(test_spec: F, accounts: Option>, block_number: u32, txs_per_block: usize, tx_gas_prices: &[U256]) -> Arc where F: Fn()->Spec { let test_spec = test_spec(); let client_db = new_db(); @@ -174,6 +182,7 @@ pub fn generate_dummy_client_with_spec_accounts_and_data(test_spec: F, accoun client } +/// Adds blocks to the client pub fn push_blocks_to_client(client: &Arc, timestamp_salt: u64, starting_number: usize, block_number: usize) { let test_spec = Spec::new_test(); let state_root = test_spec.genesis_header().state_root().clone(); @@ -203,6 +212,29 @@ pub fn push_blocks_to_client(client: &Arc, timestamp_salt: u64, starting } } +/// Adds one block with transactions +pub fn push_block_with_transactions(client: &Arc, transactions: &[SignedTransaction]) { + let test_spec = Spec::new_test(); + let test_engine = &*test_spec.engine; + let block_number = client.chain_info().best_block_number as u64 + 1; + + let mut b = client.prepare_open_block(Address::default(), (0.into(), 5000000.into()), Bytes::new()); + b.set_timestamp(block_number * 10); + + for t in transactions { + b.push_transaction(t.clone(), None).unwrap(); + } + let b = b.close_and_lock().seal(test_engine, vec![]).unwrap(); + + if let Err(e) = client.import_block(b.rlp_bytes()) { + panic!("error importing block which is valid by definition: {:?}", e); + } + + client.flush_queue(); + client.import_verified_blocks(); +} + +/// Creates dummy client (not test client) with corresponding blocks pub fn get_test_client_with_blocks(blocks: Vec) -> Arc { let test_spec = Spec::new_test(); let client_db = new_db(); @@ -229,6 +261,7 @@ fn new_db() -> Arc<::kvdb::KeyValueDB> { Arc::new(::kvdb_memorydb::create(::db::NUM_COLUMNS.unwrap_or(0))) } +/// Generates dummy blockchain with corresponding amount of blocks pub fn generate_dummy_blockchain(block_number: u32) -> BlockChain { let db = new_db(); let bc = BlockChain::new(BlockChainConfig::default(), &create_unverifiable_block(0, H256::zero()), db.clone()); @@ -242,6 +275,7 @@ pub fn generate_dummy_blockchain(block_number: u32) -> BlockChain { bc } +/// Generates dummy blockchain with corresponding amount of blocks (using creation with extra method for blocks creation) 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()); @@ -256,17 +290,20 @@ pub fn generate_dummy_blockchain_with_extra(block_number: u32) -> BlockChain { bc } +/// Returns empty dummy blockchain pub fn generate_dummy_empty_blockchain() -> BlockChain { let db = new_db(); let bc = BlockChain::new(BlockChainConfig::default(), &create_unverifiable_block(0, H256::zero()), db.clone()); bc } +/// Returns temp state pub fn get_temp_state() -> State<::state_db::StateDB> { let journal_db = get_temp_state_db(); State::new(journal_db, U256::from(0), Default::default()) } +/// Returns temp state using coresponding factory pub fn get_temp_state_with_factory(factory: EvmFactory) -> State<::state_db::StateDB> { let journal_db = get_temp_state_db(); let mut factories = Factories::default(); @@ -274,17 +311,20 @@ pub fn get_temp_state_with_factory(factory: EvmFactory) -> State<::state_db::Sta State::new(journal_db, U256::from(0), factories) } +/// Returns temp state db pub fn get_temp_state_db() -> StateDB { let db = new_db(); let journal_db = ::journaldb::new(db, ::journaldb::Algorithm::EarlyMerge, ::db::COL_STATE); StateDB::new(journal_db, 5 * 1024 * 1024) } +/// Returns sequence of hashes of the dummy blocks pub fn get_good_dummy_block_seq(count: usize) -> Vec { let test_spec = Spec::new_test(); get_good_dummy_block_fork_seq(1, count, &test_spec.genesis_header().hash()) } +/// Returns sequence of hashes of the dummy blocks beginning from corresponding parent pub fn get_good_dummy_block_fork_seq(start_number: usize, count: usize, parent_hash: &H256) -> Vec { let test_spec = Spec::new_test(); let genesis_gas = test_spec.genesis_header().gas_limit().clone(); @@ -308,6 +348,7 @@ pub fn get_good_dummy_block_fork_seq(start_number: usize, count: usize, parent_h r } +/// Returns hash and header of the correct dummy block pub fn get_good_dummy_block_hash() -> (H256, Bytes) { let mut block_header = Header::new(); let test_spec = Spec::new_test(); @@ -322,11 +363,13 @@ pub fn get_good_dummy_block_hash() -> (H256, Bytes) { (block_header.hash(), create_test_block(&block_header)) } +/// Returns hash of the correct dummy block pub fn get_good_dummy_block() -> Bytes { let (_, bytes) = get_good_dummy_block_hash(); bytes } +/// Returns hash of the dummy block with incorrect state root pub fn get_bad_state_dummy_block() -> Bytes { let mut block_header = Header::new(); let test_spec = Spec::new_test(); @@ -342,17 +385,25 @@ pub fn get_bad_state_dummy_block() -> Bytes { create_test_block(&block_header) } +/// Test actor for chain events #[derive(Default)] pub struct TestNotify { + /// Messages store pub messages: RwLock>, } impl ChainNotify for TestNotify { - fn broadcast(&self, data: Vec) { + fn broadcast(&self, message: ChainMessageType) { + let data = match message { + ChainMessageType::Consensus(data) => data, + ChainMessageType::SignedPrivateTransaction(data) => data, + ChainMessageType::PrivateTransaction(data) => data, + }; self.messages.write().push(data); } } +/// Creates new instance of KeyValueDBHandler pub fn restoration_db_handler(config: DatabaseConfig) -> Box { use kvdb::Error; diff --git a/ethcore/src/tests/client.rs b/ethcore/src/tests/client.rs index 8091ae73e12..e6333f56ad0 100644 --- a/ethcore/src/tests/client.rs +++ b/ethcore/src/tests/client.rs @@ -23,7 +23,7 @@ use state::{self, State, CleanupMode}; use executive::{Executive, TransactOptions}; use ethereum; use block::IsBlock; -use tests::helpers::{ +use test_helpers::{ generate_dummy_client, push_blocks_to_client, get_test_client_with_blocks, get_good_dummy_block_seq, generate_dummy_client_with_data, get_good_dummy_block, get_bad_state_dummy_block }; diff --git a/ethcore/src/tests/evm.rs b/ethcore/src/tests/evm.rs index 60d5e12b06b..4f4ad4241f2 100644 --- a/ethcore/src/tests/evm.rs +++ b/ethcore/src/tests/evm.rs @@ -22,7 +22,7 @@ use vm::{EnvInfo, ActionParams, ActionValue, CallType, ParamsType}; use evm::{Factory, VMType}; use executive::Executive; use state::Substate; -use tests::helpers::get_temp_state_with_factory; +use test_helpers::get_temp_state_with_factory; use trace::{NoopVMTracer, NoopTracer}; use transaction::SYSTEM_ADDRESS; diff --git a/ethcore/src/tests/mod.rs b/ethcore/src/tests/mod.rs index eec71efafbf..8b509d2afcc 100644 --- a/ethcore/src/tests/mod.rs +++ b/ethcore/src/tests/mod.rs @@ -14,7 +14,6 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -pub mod helpers; mod client; mod evm; mod trace; diff --git a/ethcore/src/tests/trace.rs b/ethcore/src/tests/trace.rs index 5483c626342..4646bc091fe 100644 --- a/ethcore/src/tests/trace.rs +++ b/ethcore/src/tests/trace.rs @@ -24,7 +24,7 @@ use ethereum_types::{U256, Address}; use io::*; use spec::*; use client::*; -use tests::helpers::get_temp_state_db; +use test_helpers::get_temp_state_db; use client::{BlockChainClient, Client, ClientConfig}; use kvdb_rocksdb::{Database, DatabaseConfig}; use std::sync::Arc; diff --git a/ethcore/src/verification/queue/mod.rs b/ethcore/src/verification/queue/mod.rs index 58b1bb7bb3c..b6e60d042ae 100644 --- a/ethcore/src/verification/queue/mod.rs +++ b/ethcore/src/verification/queue/mod.rs @@ -731,7 +731,7 @@ mod tests { use spec::Spec; use super::{BlockQueue, Config, State}; use super::kind::blocks::Unverified; - use tests::helpers::{get_good_dummy_block_seq, get_good_dummy_block}; + use test_helpers::{get_good_dummy_block_seq, get_good_dummy_block}; use error::*; use views::*; diff --git a/ethcore/src/verification/verification.rs b/ethcore/src/verification/verification.rs index e6289c2b0d6..e50eb79194d 100644 --- a/ethcore/src/verification/verification.rs +++ b/ethcore/src/verification/verification.rs @@ -359,7 +359,7 @@ mod tests { use error::BlockError::*; use ethkey::{Random, Generator}; use spec::{CommonParams, Spec}; - use tests::helpers::{create_test_block_with_data, create_test_block}; + use test_helpers::{create_test_block_with_data, create_test_block}; use transaction::{SignedTransaction, Transaction, UnverifiedTransaction, Action}; use types::log_entry::{LogEntry, LocalizedLogEntry}; use rlp; diff --git a/ethcore/transaction/src/transaction.rs b/ethcore/transaction/src/transaction.rs index d458e1f602d..4df63294bda 100644 --- a/ethcore/transaction/src/transaction.rs +++ b/ethcore/transaction/src/transaction.rs @@ -77,6 +77,25 @@ pub enum Condition { Timestamp(u64), } +/// Replay protection logic for v part of transaction's signature +pub mod signature { + /// Adds chain id into v + pub fn add_chain_replay_protection(v: u64, chain_id: Option) -> u64 { + v + if let Some(n) = chain_id { 35 + n * 2 } else { 27 } + } + + /// Returns refined v + /// 0 if `v` would have been 27 under "Electrum" notation, 1 if 28 or 4 if invalid. + pub fn check_replay_protection(v: u64) -> u8 { + match v { + v if v == 27 => 0, + v if v == 28 => 1, + v if v > 36 => ((v - 1) % 2) as u8, + _ => 4 + } + } +} + /// A set of information describing an externally-originating message call /// or contract creation operation. #[derive(Default, Debug, Clone, PartialEq, Eq)] @@ -186,7 +205,7 @@ impl Transaction { unsigned: self, r: sig.r().into(), s: sig.s().into(), - v: sig.v() as u64 + if let Some(n) = chain_id { 35 + n * 2 } else { 27 }, + v: signature::add_chain_replay_protection(sig.v() as u64, chain_id), hash: 0.into(), }.compute_hash() } @@ -330,8 +349,7 @@ impl UnverifiedTransaction { &self.unsigned } - /// 0 if `v` would have been 27 under "Electrum" notation, 1 if 28 or 4 if invalid. - pub fn standard_v(&self) -> u8 { match self.v { v if v == 27 || v == 28 || v > 36 => ((v - 1) % 2) as u8, _ => 4 } } + pub fn standard_v(&self) -> u8 { signature::check_replay_protection(self.v) } /// The `v` value that appears in the RLP. pub fn original_v(&self) -> u64 { self.v } diff --git a/hash-fetch/src/client.rs b/hash-fetch/src/client.rs index b3a9356ea2c..ce2e44054e3 100644 --- a/hash-fetch/src/client.rs +++ b/hash-fetch/src/client.rs @@ -153,7 +153,7 @@ impl HashFetch for Client { .into_future() .and_then(move |url| { debug!(target: "fetch", "Resolved {:?} to {:?}. Fetching...", hash, url); - remote_fetch.fetch(&url, abort).from_err() + remote_fetch.get(&url, abort).from_err() }) .and_then(move |response| { if !response.is_success() { @@ -199,7 +199,7 @@ mod tests { use parking_lot::Mutex; use futures::future; use futures_cpupool::CpuPool; - use fetch::{self, Fetch, Url}; + use fetch::{self, Fetch, Url, Method}; use parity_reactor::Remote; use urlhint::tests::{FakeRegistrar, URLHINT}; use super::{Error, Client, HashFetch, random_temp_path}; @@ -214,7 +214,7 @@ mod tests { impl Fetch for FakeFetch { type Result = future::Ok; - fn fetch(&self, url: &str, abort: fetch::Abort) -> Self::Result { + fn fetch(&self, url: &str, _method: Method, abort: fetch::Abort) -> Self::Result { assert_eq!(url, "https://parity.io/assets/images/ethcore-black-horizontal.png"); let u = Url::parse(url).unwrap(); future::ok(if self.return_success { diff --git a/parity/blockchain.rs b/parity/blockchain.rs index 26eae459765..c2c6f2aa5cf 100644 --- a/parity/blockchain.rs +++ b/parity/blockchain.rs @@ -25,6 +25,7 @@ use hash::{keccak, KECCAK_NULL_RLP}; use ethereum_types::{U256, H256, Address}; use bytes::ToPretty; use rlp::PayloadInfo; +use ethcore::account_provider::AccountProvider; use ethcore::client::{Mode, DatabaseCompactionProfile, VMType, BlockImportError, Nonce, Balance, BlockChainClient, BlockId, BlockInfo, ImportBlock}; use ethcore::db::NUM_COLUMNS; use ethcore::error::ImportError; @@ -39,6 +40,7 @@ use helpers::{to_client_config, execute_upgrades, open_client_db, client_db_conf use dir::Directories; use user_defaults::UserDefaults; use fdlimit; +use ethcore_private_tx; #[derive(Debug, PartialEq)] pub enum DataFormat { @@ -389,6 +391,9 @@ fn execute_import(cmd: ImportBlockchain) -> Result<(), String> { restoration_db_handler, &cmd.dirs.ipc_path(), Arc::new(Miner::with_spec(&spec)), + Arc::new(AccountProvider::transient_provider()), + Box::new(ethcore_private_tx::NoopEncryptor), + Default::default() ).map_err(|e| format!("Client service error: {:?}", e))?; // free up the spec in memory. @@ -576,6 +581,9 @@ fn start_client( restoration_db_handler, &dirs.ipc_path(), Arc::new(Miner::with_spec(&spec)), + Arc::new(AccountProvider::transient_provider()), + Box::new(ethcore_private_tx::NoopEncryptor), + Default::default() ).map_err(|e| format!("Client service error: {:?}", e))?; drop(spec); diff --git a/parity/cli/mod.rs b/parity/cli/mod.rs index 2cc0ef7c290..a160661b913 100644 --- a/parity/cli/mod.rs +++ b/parity/cli/mod.rs @@ -350,6 +350,35 @@ usage! { "--password=[FILE]...", "Provide a file containing a password for unlocking an account. Leading and trailing whitespace is trimmed.", + ["Private transactions options"] + FLAG flag_private_enabled: (bool) = false, or |c: &Config| c.private_tx.as_ref()?.enabled, + "--private-tx-enabled", + "Enable private transactions.", + + ARG arg_private_signer: (Option) = None, or |c: &Config| c.private_tx.as_ref()?.signer.clone(), + "--private-signer=[ACCOUNT]", + "Specify the account for signing public transaction created upon verified private transaction.", + + ARG arg_private_validators: (Option) = None, or |c: &Config| c.private_tx.as_ref()?.validators.as_ref().map(|vec| vec.join(",")), + "--private-validators=[ACCOUNTS]", + "Specify the accounts for validating private transactions. ACCOUNTS is a comma-delimited list of addresses.", + + ARG arg_private_account: (Option) = None, or |c: &Config| c.private_tx.as_ref()?.account.clone(), + "--private-account=[ACCOUNT]", + "Specify the account for signing requests to secret store.", + + ARG arg_private_sstore_url: (Option) = None, or |c: &Config| c.private_tx.as_ref()?.sstore_url.clone(), + "--private-sstore-url=[URL]", + "Specify secret store URL used for encrypting private transactions.", + + ARG arg_private_sstore_threshold: (Option) = None, or |c: &Config| c.private_tx.as_ref()?.sstore_threshold.clone(), + "--private-sstore-threshold=[NUM]", + "Specify secret store threshold used for encrypting private transactions.", + + ARG arg_private_passwords: (Option) = None, or |c: &Config| c.private_tx.as_ref()?.passwords.clone(), + "--private-passwords=[FILE]...", + "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", @@ -462,7 +491,7 @@ usage! { "--jsonrpc-interface=[IP]", "Specify the hostname portion of the JSONRPC API server, IP should be an interface's IP address, or all (all interfaces) or local.", - ARG arg_jsonrpc_apis: (String) = "web3,eth,pubsub,net,parity,parity_pubsub,traces,rpc,shh,shh_pubsub", or |c: &Config| c.rpc.as_ref()?.apis.as_ref().map(|vec| vec.join(",")), + ARG arg_jsonrpc_apis: (String) = "web3,eth,pubsub,net,parity,private,parity_pubsub,traces,rpc,shh,shh_pubsub", or |c: &Config| c.rpc.as_ref()?.apis.as_ref().map(|vec| vec.join(",")), "--jsonrpc-apis=[APIS]", "Specify the APIs available through the JSONRPC interface using a comma-delimited list of API names. Possible names are: all, safe, web3, net, eth, pubsub, personal, signer, parity, parity_pubsub, parity_accounts, parity_set, traces, rpc, secretstore, shh, shh_pubsub. You can also disable a specific API by putting '-' in the front, example: all,-personal. safe contains following apis: web3, net, eth, pubsub, parity, parity_pubsub, traces, rpc, shh, shh_pubsub", @@ -495,7 +524,7 @@ usage! { "--ws-interface=[IP]", "Specify the hostname portion of the WebSockets server, IP should be an interface's IP address, or all (all interfaces) or local.", - ARG arg_ws_apis: (String) = "web3,eth,pubsub,net,parity,parity_pubsub,traces,rpc,shh,shh_pubsub", or |c: &Config| c.websockets.as_ref()?.apis.as_ref().map(|vec| vec.join(",")), + ARG arg_ws_apis: (String) = "web3,eth,pubsub,net,parity,parity_pubsub,private,traces,rpc,shh,shh_pubsub", or |c: &Config| c.websockets.as_ref()?.apis.as_ref().map(|vec| vec.join(",")), "--ws-apis=[APIS]", "Specify the APIs available through the WebSockets interface using a comma-delimited list of API names. Possible names are: all, safe, web3, net, eth, pubsub, personal, signer, parity, parity_pubsub, parity_accounts, parity_set, traces, rpc, secretstore, shh, shh_pubsub. You can also disable a specific API by putting '-' in the front, example: all,-personal. safe contains following apis: web3, net, eth, pubsub, parity, parity_pubsub, traces, rpc, shh, shh_pubsub", @@ -520,7 +549,7 @@ usage! { "--ipc-path=[PATH]", "Specify custom path for JSON-RPC over IPC service.", - ARG arg_ipc_apis: (String) = "web3,eth,pubsub,net,parity,parity_pubsub,parity_accounts,traces,rpc,shh,shh_pubsub", or |c: &Config| c.ipc.as_ref()?.apis.as_ref().map(|vec| vec.join(",")), + ARG arg_ipc_apis: (String) = "web3,eth,pubsub,net,parity,parity_pubsub,parity_accounts,private,traces,rpc,shh,shh_pubsub", or |c: &Config| c.ipc.as_ref()?.apis.as_ref().map(|vec| vec.join(",")), "--ipc-apis=[APIS]", "Specify custom API set available via JSON-RPC over IPC using a comma-delimited list of API names. Possible names are: all, safe, web3, net, eth, pubsub, personal, signer, parity, parity_pubsub, parity_accounts, parity_set, traces, rpc, secretstore, shh, shh_pubsub. You can also disable a specific API by putting '-' in the front, example: all,-personal. safe contains: web3, net, eth, pubsub, parity, parity_pubsub, traces, rpc, shh, shh_pubsub", @@ -1014,6 +1043,7 @@ struct Config { ipc: Option, dapps: Option, secretstore: Option, + private_tx: Option, ipfs: Option, mining: Option, footprint: Option, @@ -1057,6 +1087,18 @@ struct Account { fast_unlock: Option, } +#[derive(Default, Debug, PartialEq, Deserialize)] +#[serde(deny_unknown_fields)] +struct PrivateTransactions { + enabled: Option, + signer: Option, + validators: Option>, + account: Option, + passwords: Option, + sstore_url: Option, + sstore_threshold: Option, +} + #[derive(Default, Debug, PartialEq, Deserialize)] #[serde(deny_unknown_fields)] struct Ui { @@ -1501,6 +1543,15 @@ mod tests { flag_no_hardware_wallets: false, flag_fast_unlock: false, + // -- Private Transactions Options + flag_private_enabled: true, + arg_private_signer: Some("0xdeadbeefcafe0000000000000000000000000000".into()), + arg_private_validators: Some("0xdeadbeefcafe0000000000000000000000000000".into()), + arg_private_passwords: Some("~/.safe/password.file".into()), + arg_private_account: Some("0xdeadbeefcafe0000000000000000000000000000".into()), + arg_private_sstore_url: Some("http://localhost:8082".into()), + arg_private_sstore_threshold: Some(0), + flag_force_ui: false, flag_no_ui: false, arg_ui_port: 8180u16, @@ -1834,6 +1885,7 @@ mod tests { http_port: Some(8082), path: None, }), + private_tx: None, ipfs: Some(Ipfs { enable: Some(false), port: Some(5001), diff --git a/parity/cli/tests/config.full.toml b/parity/cli/tests/config.full.toml index 2e546b5f1ef..08df68ee508 100644 --- a/parity/cli/tests/config.full.toml +++ b/parity/cli/tests/config.full.toml @@ -23,6 +23,15 @@ unlock = ["0xdeadbeefcafe0000000000000000000000000000"] password = ["~/.safe/password.file"] keys_iterations = 10240 +[private_tx] +enabled = true +signer = "0xdeadbeefcafe0000000000000000000000000000" +validators = ["0xdeadbeefcafe0000000000000000000000000000"] +passwords = "~/.safe/password.file" +account = "0xdeadbeefcafe0000000000000000000000000000" +sstore_url = "http://localhost:8082" +sstore_threshold = 0 + [ui] force = false disable = false diff --git a/parity/configuration.rs b/parity/configuration.rs index eb6ce713db7..7ce3db1240e 100644 --- a/parity/configuration.rs +++ b/parity/configuration.rs @@ -38,13 +38,14 @@ 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_gas_limit, to_queue_strategy}; +to_bootnodes, to_addresses, to_address, to_gas_limit, to_queue_strategy, passwords_from_files}; use dir::helpers::{replace_home, replace_home_and_local}; use params::{ResealPolicy, AccountsConfig, GasPricerConfig, MinerExtras, SpecType}; use ethcore_logger::Config as LogConfig; use dir::{self, Directories, default_hypervisor_path, default_local_path, default_data_path}; use dapps::Configuration as DappsConfiguration; use ipfs::Configuration as IpfsConfiguration; +use ethcore_private_tx::{ProviderConfig, EncryptorConfig}; use secretstore::{NodeSecretKey, Configuration as SecretStoreConfiguration, ContractAddress as SecretStoreContractAddress}; use updater::{UpdatePolicy, UpdateFilter, ReleaseTrack}; use run::RunCmd; @@ -341,6 +342,7 @@ impl Configuration { let verifier_settings = self.verifier_settings(); let whisper_config = self.whisper_config(); + let (private_provider_conf, private_enc_conf, private_tx_enabled) = self.private_provider_config()?; let run_cmd = RunCmd { cache_config: cache_config, @@ -379,6 +381,9 @@ impl Configuration { 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, @@ -934,6 +939,29 @@ impl Configuration { Ok(conf) } + fn private_provider_config(&self) -> Result<(ProviderConfig, EncryptorConfig, bool), String> { + let provider_conf = ProviderConfig { + validator_accounts: to_addresses(&self.args.arg_private_validators)?, + signer_account: self.args.arg_private_signer.clone().and_then(|account| to_address(Some(account)).ok()), + passwords: match self.args.arg_private_passwords.clone() { + Some(file) => passwords_from_files(&vec![file].as_slice())?, + None => Vec::new(), + }, + }; + + let encryptor_conf = EncryptorConfig { + base_url: self.args.arg_private_sstore_url.clone(), + threshold: self.args.arg_private_sstore_threshold.unwrap_or(0), + key_server_account: self.args.arg_private_account.clone().and_then(|account| to_address(Some(account)).ok()), + passwords: match self.args.arg_private_passwords.clone() { + Some(file) => passwords_from_files(&vec![file].as_slice())?, + None => Vec::new(), + }, + }; + + Ok((provider_conf, encryptor_conf, self.args.flag_private_enabled)) + } + fn network_settings(&self) -> Result { let http_conf = self.http_config()?; let net_addresses = self.net_addresses()?; @@ -1468,6 +1496,9 @@ mod tests { 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(), diff --git a/parity/main.rs b/parity/main.rs index 30c3cf0e986..9ff3d97ab36 100644 --- a/parity/main.rs +++ b/parity/main.rs @@ -53,14 +53,15 @@ extern crate ethcore_logger; extern crate ethcore_migrations as migrations; extern crate ethcore_miner as miner; extern crate ethcore_network as network; +extern crate ethcore_private_tx; extern crate ethcore_service; extern crate ethcore_transaction as transaction; extern crate ethereum_types; -extern crate migration as migr; -extern crate kvdb; -extern crate kvdb_rocksdb; extern crate ethkey; extern crate ethsync; +extern crate kvdb; +extern crate kvdb_rocksdb; +extern crate migration as migr; extern crate node_health; extern crate panic_hook; extern crate parity_hash_fetch as hash_fetch; diff --git a/parity/modules.rs b/parity/modules.rs index 36cffe2ec6b..22f8afe9f18 100644 --- a/parity/modules.rs +++ b/parity/modules.rs @@ -21,7 +21,7 @@ use ethsync::{self, AttachedProtocol, SyncConfig, NetworkConfiguration, Params, use ethcore::snapshot::SnapshotService; use light::Provider; -pub use ethsync::{EthSync, SyncProvider, ManageNetwork}; +pub use ethsync::{EthSync, SyncProvider, ManageNetwork, PrivateTxHandler}; pub use ethcore::client::ChainNotify; use ethcore_logger::Config as LogConfig; @@ -32,6 +32,7 @@ pub fn sync( net_cfg: NetworkConfiguration, client: Arc, snapshot_service: Arc, + private_tx_handler: Arc, provider: Arc, _log_settings: &LogConfig, attached_protos: Vec, @@ -42,6 +43,7 @@ pub fn sync( chain: client, provider: provider, snapshot_service: snapshot_service, + private_tx_handler, network_config: net_cfg, attached_protos: attached_protos, }, diff --git a/parity/rpc_apis.rs b/parity/rpc_apis.rs index 5ba18dc09bf..23a69755ff1 100644 --- a/parity/rpc_apis.rs +++ b/parity/rpc_apis.rs @@ -22,6 +22,7 @@ use std::sync::{Arc, Weak}; pub use parity_rpc::signer::SignerService; pub use parity_rpc::dapps::{DappsService, LocalDapp}; +use ethcore_service::PrivateTxService; use ethcore::account_provider::AccountProvider; use ethcore::client::Client; use ethcore::miner::Miner; @@ -40,6 +41,7 @@ use parity_rpc::dispatch::{FullDispatcher, LightDispatcher}; use parity_rpc::informant::{ActivityNotifier, ClientNotifier}; use parity_rpc::{Metadata, NetworkSettings, Host}; use parking_lot::{Mutex, RwLock}; +use ethcore_private_tx::Provider as PrivateTransactionManager; use updater::Updater; #[derive(Debug, PartialEq, Clone, Eq, Hash)] @@ -70,6 +72,8 @@ pub enum Api { Rpc, /// SecretStore (UNSAFE: arbitrary hash signing) SecretStore, + /// Private transaction manager (Safe) + Private, /// Whisper (Safe) // TODO: _if_ someone guesses someone else's key or filter IDs they can remove // BUT these are all ephemeral so it seems fine. @@ -98,6 +102,7 @@ impl FromStr for Api { "traces" => Ok(Traces), "rpc" => Ok(Rpc), "secretstore" => Ok(SecretStore), + "private" => Ok(Private), "shh" => Ok(Whisper), "shh_pubsub" => Ok(WhisperPubSub), api => Err(format!("Unknown api: {}", api)) @@ -183,6 +188,7 @@ fn to_modules(apis: &HashSet) -> BTreeMap { Api::Traces => ("traces", "1.0"), Api::Rpc => ("rpc", "1.0"), Api::SecretStore => ("secretstore", "1.0"), + Api::Private => ("private", "1.0"), Api::Whisper => ("shh", "1.0"), Api::WhisperPubSub => ("shh_pubsub", "1.0"), }; @@ -214,6 +220,7 @@ pub struct FullDependencies { pub sync: Arc, pub net: Arc, pub secret_store: Option>, + pub private_tx_service: Option>, pub miner: Arc, pub external_miner: Arc, pub logger: Arc, @@ -385,7 +392,10 @@ impl FullDependencies { ); } } - } + }, + Api::Private => { + handler.extend_with(PrivateClient::new(self.private_tx_service.as_ref().map(|p| p.provider())).to_delegate()); + }, } } } @@ -437,6 +447,7 @@ pub struct LightDependencies { pub geth_compatibility: bool, pub remote: parity_reactor::Remote, pub whisper_rpc: Option<::whisper::RpcFactory>, + pub private_tx_service: Option>, pub gas_price_percentile: usize, } @@ -587,12 +598,18 @@ impl LightDependencies { let whisper = whisper_rpc.make_handler(self.net.clone()); handler.extend_with(::parity_whisper::rpc::Whisper::to_delegate(whisper)); } - } + }, Api::WhisperPubSub => { if let Some(ref whisper_rpc) = self.whisper_rpc { let whisper = whisper_rpc.make_handler(self.net.clone()); handler.extend_with(::parity_whisper::rpc::WhisperPubSub::to_delegate(whisper)); } + }, + Api::Private => { + if let Some(ref tx_manager) = self.private_tx_service { + let private_tx_service = Some(tx_manager.clone()); + handler.extend_with(PrivateClient::new(private_tx_service).to_delegate()); + } } } } @@ -629,6 +646,7 @@ impl ApiSet { Api::Rpc, Api::Whisper, Api::WhisperPubSub, + Api::Private, ].into_iter().cloned().collect(); match *self { @@ -693,6 +711,7 @@ mod test { assert_eq!(Api::Traces, "traces".parse().unwrap()); assert_eq!(Api::Rpc, "rpc".parse().unwrap()); assert_eq!(Api::SecretStore, "secretstore".parse().unwrap()); + assert_eq!(Api::Private, "private".parse().unwrap()); assert_eq!(Api::Whisper, "shh".parse().unwrap()); assert_eq!(Api::WhisperPubSub, "shh_pubsub".parse().unwrap()); assert!("rp".parse::().is_err()); @@ -712,7 +731,7 @@ mod test { fn test_api_set_unsafe_context() { let expected = vec![ // make sure this list contains only SAFE methods - Api::Web3, Api::Net, Api::Eth, Api::EthPubSub, Api::Parity, Api::ParityPubSub, Api::Traces, Api::Rpc, Api::Whisper, Api::WhisperPubSub, + Api::Web3, Api::Net, Api::Eth, Api::EthPubSub, Api::Parity, Api::ParityPubSub, Api::Traces, Api::Rpc, Api::Whisper, Api::WhisperPubSub, Api::Private, ].into_iter().collect(); assert_eq!(ApiSet::UnsafeContext.list_apis(), expected); } @@ -721,7 +740,7 @@ mod test { fn test_api_set_ipc_context() { let expected = vec![ // safe - Api::Web3, Api::Net, Api::Eth, Api::EthPubSub, Api::Parity, Api::ParityPubSub, Api::Traces, Api::Rpc, Api::Whisper, Api::WhisperPubSub, + Api::Web3, Api::Net, Api::Eth, Api::EthPubSub, Api::Parity, Api::ParityPubSub, Api::Traces, Api::Rpc, Api::Whisper, Api::WhisperPubSub, Api::Private, // semi-safe Api::ParityAccounts ].into_iter().collect(); @@ -732,7 +751,7 @@ mod test { fn test_api_set_safe_context() { let expected = vec![ // safe - Api::Web3, Api::Net, Api::Eth, Api::EthPubSub, Api::Parity, Api::ParityPubSub, Api::Traces, Api::Rpc, Api::SecretStore, Api::Whisper, Api::WhisperPubSub, + Api::Web3, Api::Net, Api::Eth, Api::EthPubSub, Api::Parity, Api::ParityPubSub, Api::Traces, Api::Rpc, Api::SecretStore, Api::Whisper, Api::WhisperPubSub, Api::Private, // semi-safe Api::ParityAccounts, // Unsafe @@ -747,7 +766,8 @@ mod test { Api::Web3, Api::Net, Api::Eth, Api::EthPubSub, Api::Parity, Api::ParityPubSub, Api::Traces, Api::Rpc, Api::SecretStore, Api::Whisper, Api::WhisperPubSub, Api::ParityAccounts, Api::ParitySet, Api::Signer, - Api::Personal + Api::Personal, + Api::Private, ].into_iter().collect())); } @@ -757,13 +777,14 @@ mod test { Api::Web3, Api::Net, Api::Eth, Api::EthPubSub, Api::Parity, Api::ParityPubSub, Api::Traces, Api::Rpc, Api::SecretStore, Api::Whisper, Api::WhisperPubSub, Api::ParityAccounts, Api::ParitySet, Api::Signer, + Api::Private ].into_iter().collect())); } #[test] fn test_safe_parsing() { assert_eq!("safe".parse::().unwrap(), ApiSet::List(vec![ - Api::Web3, Api::Net, Api::Eth, Api::EthPubSub, Api::Parity, Api::ParityPubSub, Api::Traces, Api::Rpc, Api::Whisper, Api::WhisperPubSub, + Api::Web3, Api::Net, Api::Eth, Api::EthPubSub, Api::Parity, Api::ParityPubSub, Api::Traces, Api::Rpc, Api::Whisper, Api::WhisperPubSub, Api::Private, ].into_iter().collect())); } } diff --git a/parity/run.rs b/parity/run.rs index 816ddd4dd30..fbc24a90d74 100644 --- a/parity/run.rs +++ b/parity/run.rs @@ -50,7 +50,7 @@ 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}; use params::{ SpecType, Pruning, AccountsConfig, GasPricerConfig, MinerExtras, Switch, tracing_switch_to_bool, fatdb_switch_to_bool, mode_switch_to_bool @@ -120,6 +120,9 @@ pub struct RunCmd { pub ipfs_conf: ipfs::Configuration, pub ui_conf: rpc::UiConfiguration, pub secretstore_conf: secretstore::Configuration, + pub private_provider_conf: ProviderConfig, + pub private_encryptor_conf: EncryptorConfig, + pub private_tx_enabled: bool, pub dapp: Option, pub ui: bool, pub name: String, @@ -388,6 +391,7 @@ fn execute_light_impl(cmd: RunCmd, logger: Arc) -> Result(cmd: RunCmd, logger: Arc, on_client_rq: restoration_db_handler, &cmd.dirs.ipc_path(), miner.clone(), + account_provider.clone(), + Box::new(SecretStoreEncryptor::new(cmd.private_encryptor_conf, fetch.clone()).map_err(|e| e.to_string())?), + cmd.private_provider_conf, ).map_err(|e| format!("Client service error: {:?}", e))?; let connection_filter_address = spec.params().node_permission_contract; @@ -630,6 +637,9 @@ fn execute_impl(cmd: RunCmd, logger: Arc, on_client_rq: // take handle to client let client = service.client(); + // take handle to private transactions service + let private_tx_service = service.private_tx_service(); + let private_tx_provider = private_tx_service.provider(); let connection_filter = connection_filter_address.map(|a| Arc::new(NodeFilter::new(Arc::downgrade(&client) as Weak, a))); let snapshot_service = service.snapshot_service(); @@ -697,6 +707,7 @@ fn execute_impl(cmd: RunCmd, logger: Arc, on_client_rq: net_conf.clone().into(), client.clone(), snapshot_service.clone(), + private_tx_service.clone(), client.clone(), &cmd.logger_config, attached_protos, @@ -705,6 +716,15 @@ fn execute_impl(cmd: RunCmd, logger: Arc, on_client_rq: service.add_notify(chain_notify.clone()); + // provider not added to a notification center is effectively disabled + // TODO [debris] refactor it later on + if cmd.private_tx_enabled { + service.add_notify(private_tx_provider.clone()); + // TODO [ToDr] PrivateTX should use separate notifications + // re-using ChainNotify for this is a bit abusive. + private_tx_provider.add_notify(chain_notify.clone()); + } + // start network if network_enabled { chain_notify.start(); @@ -796,6 +816,7 @@ fn execute_impl(cmd: RunCmd, logger: Arc, on_client_rq: pool: cpu_pool.clone(), remote: event_loop.remote(), whisper_rpc: whisper_factory, + private_tx_service: Some(private_tx_service.clone()), gas_price_percentile: cmd.gas_price_percentile, }); diff --git a/parity/snapshot.rs b/parity/snapshot.rs index ae7a0698b74..90967328083 100644 --- a/parity/snapshot.rs +++ b/parity/snapshot.rs @@ -21,6 +21,7 @@ use std::path::{Path, PathBuf}; use std::sync::Arc; use hash::keccak; +use ethcore::account_provider::AccountProvider; use ethcore::snapshot::{Progress, RestorationStatus, SnapshotService as SS}; use ethcore::snapshot::io::{SnapshotReader, PackedReader, PackedWriter}; use ethcore::snapshot::service::Service as SnapshotService; @@ -35,6 +36,7 @@ use helpers::{to_client_config, execute_upgrades, client_db_config, open_client_ use dir::Directories; use user_defaults::UserDefaults; use fdlimit; +use ethcore_private_tx; /// Kinds of snapshot commands. #[derive(Debug, PartialEq, Clone, Copy)] @@ -192,7 +194,10 @@ impl SnapshotCommand { &snapshot_path, restoration_db_handler, &self.dirs.ipc_path(), - Arc::new(Miner::with_spec(&spec)) + Arc::new(Miner::with_spec(&spec)), + Arc::new(AccountProvider::transient_provider()), + Box::new(ethcore_private_tx::NoopEncryptor), + Default::default() ).map_err(|e| format!("Client service error: {:?}", e))?; Ok(service) diff --git a/price-info/src/lib.rs b/price-info/src/lib.rs index e233062b431..9be27a1319f 100644 --- a/price-info/src/lib.rs +++ b/price-info/src/lib.rs @@ -96,7 +96,7 @@ impl Client { /// Gets the current ETH price and calls `set_price` with the result. pub fn get(&self, set_price: G) { - let future = self.fetch.fetch(&self.api_endpoint, fetch::Abort::default()) + let future = self.fetch.get(&self.api_endpoint, fetch::Abort::default()) .from_err() .and_then(|response| { if !response.is_success() { @@ -140,7 +140,7 @@ mod test { use std::sync::Arc; use std::sync::atomic::{AtomicBool, Ordering}; use fetch; - use fetch::{Fetch, Url}; + use fetch::{Fetch, Url, Method}; use futures_cpupool::CpuPool; use futures::future::{self, FutureResult}; use Client; @@ -158,7 +158,7 @@ mod test { impl Fetch for FakeFetch { type Result = FutureResult; - fn fetch(&self, url: &str, abort: fetch::Abort) -> Self::Result { + fn fetch(&self, url: &str, _method: Method, abort: fetch::Abort) -> Self::Result { assert_eq!(url, "https://api.etherscan.io/api?module=stats&action=ethprice"); let u = Url::parse(url).unwrap(); let mut val = self.1.lock(); diff --git a/rpc/Cargo.toml b/rpc/Cargo.toml index 51f2e8ff369..ed59a91e8dd 100644 --- a/rpc/Cargo.toml +++ b/rpc/Cargo.toml @@ -44,6 +44,7 @@ ethcore-io = { path = "../util/io" } ethcore-light = { path = "../ethcore/light" } ethcore-logger = { path = "../logger" } ethcore-miner = { path = "../miner" } +ethcore-private-tx = { path = "../ethcore/private-tx" } ethcore-transaction = { path = "../ethcore/transaction" } ethereum-types = "0.3" diff --git a/rpc/src/lib.rs b/rpc/src/lib.rs index a08a1a88a8a..79911938b84 100644 --- a/rpc/src/lib.rs +++ b/rpc/src/lib.rs @@ -67,6 +67,7 @@ extern crate rlp; extern crate stats; extern crate keccak_hash as hash; extern crate hardware_wallet; +extern crate ethcore_private_tx; extern crate patricia_trie as trie; #[macro_use] diff --git a/rpc/src/v1/helpers/errors.rs b/rpc/src/v1/helpers/errors.rs index 9393fc53a01..e86ab630f57 100644 --- a/rpc/src/v1/helpers/errors.rs +++ b/rpc/src/v1/helpers/errors.rs @@ -23,6 +23,7 @@ use ethcore::error::{Error as EthcoreError, CallError}; use jsonrpc_core::{futures, Error, ErrorCode, Value}; use rlp::DecoderError; use transaction::Error as TransactionError; +use ethcore_private_tx::Error as PrivateTransactionError; mod codes { // NOTE [ToDr] Codes from [-32099, -32000] @@ -39,6 +40,7 @@ mod codes { pub const ACCOUNT_LOCKED: i64 = -32020; pub const PASSWORD_INVALID: i64 = -32021; pub const ACCOUNT_ERROR: i64 = -32023; + pub const PRIVATE_ERROR: i64 = -32024; pub const REQUEST_REJECTED: i64 = -32040; pub const REQUEST_REJECTED_LIMIT: i64 = -32041; pub const REQUEST_NOT_FOUND: i64 = -32042; @@ -288,6 +290,22 @@ pub fn password(error: AccountError) -> Error { } } +pub fn private_message(error: PrivateTransactionError) -> Error { + Error { + code: ErrorCode::ServerError(codes::PRIVATE_ERROR), + message: "Private transactions call failed.".into(), + data: Some(Value::String(format!("{:?}", error))), + } +} + +pub fn private_message_block_id_not_supported() -> Error { + Error { + code: ErrorCode::ServerError(codes::PRIVATE_ERROR), + message: "Pending block id not supported.".into(), + data: None, + } +} + pub fn transaction_message(error: TransactionError) -> String { use self::TransactionError::*; diff --git a/rpc/src/v1/impls/light/parity_set.rs b/rpc/src/v1/impls/light/parity_set.rs index a1344fa69b9..0a6c2c5a57d 100644 --- a/rpc/src/v1/impls/light/parity_set.rs +++ b/rpc/src/v1/impls/light/parity_set.rs @@ -128,7 +128,7 @@ impl ParitySet for ParitySetClient { } fn hash_content(&self, url: String) -> BoxFuture { - let future = self.fetch.fetch(&url, Default::default()).then(move |result| { + let future = self.fetch.get(&url, Default::default()).then(move |result| { result .map_err(errors::fetch) .and_then(move |response| { diff --git a/rpc/src/v1/impls/mod.rs b/rpc/src/v1/impls/mod.rs index d3e0554c24f..4edaf6bcd27 100644 --- a/rpc/src/v1/impls/mod.rs +++ b/rpc/src/v1/impls/mod.rs @@ -32,6 +32,7 @@ mod rpc; mod secretstore; mod traces; mod web3; +mod private; pub mod light; @@ -51,3 +52,4 @@ pub use self::traces::TracesClient; pub use self::web3::Web3Client; pub use self::rpc::RpcClient; pub use self::secretstore::SecretStoreClient; +pub use self::private::PrivateClient; diff --git a/rpc/src/v1/impls/parity_set.rs b/rpc/src/v1/impls/parity_set.rs index 9d071187230..1be136e1de7 100644 --- a/rpc/src/v1/impls/parity_set.rs +++ b/rpc/src/v1/impls/parity_set.rs @@ -170,7 +170,7 @@ impl ParitySet for ParitySetClient where } fn hash_content(&self, url: String) -> BoxFuture { - let future = self.fetch.fetch(&url, Default::default()).then(move |result| { + let future = self.fetch.get(&url, Default::default()).then(move |result| { result .map_err(errors::fetch) .and_then(move |response| { diff --git a/rpc/src/v1/impls/private.rs b/rpc/src/v1/impls/private.rs new file mode 100644 index 00000000000..bf797d5a589 --- /dev/null +++ b/rpc/src/v1/impls/private.rs @@ -0,0 +1,122 @@ +// 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 . + +//! Privte transaction signing RPC implementation. + +use std::sync::Arc; + +use rlp::UntrustedRlp; + +use ethcore_private_tx::Provider as PrivateTransactionManager; +use ethereum_types::Address; +use transaction::SignedTransaction; + +use jsonrpc_core::{Error}; +use v1::types::{Bytes, PrivateTransactionReceipt, H160, H256, TransactionRequest, U256, + BlockNumber, PrivateTransactionReceiptAndTransaction, CallRequest, block_number_to_id}; +use v1::traits::Private; +use v1::metadata::Metadata; +use v1::helpers::{errors, fake_sign}; + +/// Private transaction manager API endpoint implementation. +pub struct PrivateClient { + private: Option>, +} + +impl PrivateClient { + /// Creates a new instance. + pub fn new(private: Option>) -> Self { + PrivateClient { + private, + } + } + + fn unwrap_manager(&self) -> Result<&PrivateTransactionManager, Error> { + match self.private { + Some(ref arc) => Ok(&**arc), + None => Err(errors::public_unsupported(None)), + } + } +} + +impl Private for PrivateClient { + type Metadata = Metadata; + + fn send_transaction(&self, request: Bytes) -> Result { + let signed_transaction = UntrustedRlp::new(&request.into_vec()).as_val() + .map_err(errors::rlp) + .and_then(|tx| SignedTransaction::new(tx).map_err(errors::transaction))?; + let client = self.unwrap_manager()?; + let receipt = client.create_private_transaction(signed_transaction).map_err(|e| errors::private_message(e))?; + Ok(receipt.into()) + } + + fn compose_deployment_transaction(&self, block_number: BlockNumber, request: Bytes, validators: Vec, gas_price: U256) -> Result { + let signed_transaction = UntrustedRlp::new(&request.into_vec()).as_val() + .map_err(errors::rlp) + .and_then(|tx| SignedTransaction::new(tx).map_err(errors::transaction))?; + let client = self.unwrap_manager()?; + + let addresses: Vec
= validators.into_iter().map(Into::into).collect(); + let id = match block_number { + BlockNumber::Pending => return Err(errors::private_message_block_id_not_supported()), + num => block_number_to_id(num) + }; + + let (transaction, contract_address) = client.public_creation_transaction(id, &signed_transaction, addresses.as_slice(), gas_price.into()) + .map_err(|e| errors::private_message(e))?; + let tx_hash = transaction.hash(None); + let request = TransactionRequest { + from: Some(signed_transaction.sender().into()), + to: None, + nonce: Some(transaction.nonce.into()), + gas_price: Some(transaction.gas_price.into()), + gas: Some(transaction.gas.into()), + value: Some(transaction.value.into()), + data: Some(transaction.data.into()), + condition: None, + }; + + Ok(PrivateTransactionReceiptAndTransaction { + transaction: request, + receipt: PrivateTransactionReceipt { + transaction_hash: tx_hash.into(), + contract_address: contract_address.map(|address| address.into()), + status_code: 0, + } + }) + } + + fn private_call(&self, meta: Self::Metadata, block_number: BlockNumber, request: CallRequest) -> Result { + let id = match block_number { + BlockNumber::Pending => return Err(errors::private_message_block_id_not_supported()), + num => block_number_to_id(num) + }; + + let request = CallRequest::into(request); + let signed = fake_sign::sign_call(request, meta.is_dapp())?; + let client = self.unwrap_manager()?; + let executed_result = client.private_call(id, &signed).map_err(|e| errors::private_message(e))?; + Ok(executed_result.output.into()) + } + + fn private_contract_key(&self, contract_address: H160) -> Result { + let client = self.unwrap_manager()?; + let key = client.contract_key_id(&contract_address.into()).map_err(|e| errors::private_message(e))?; + Ok(key.into()) + } +} + diff --git a/rpc/src/v1/mod.rs b/rpc/src/v1/mod.rs index b5e1cfa4dba..154317eb2f4 100644 --- a/rpc/src/v1/mod.rs +++ b/rpc/src/v1/mod.rs @@ -41,7 +41,7 @@ pub mod informant; pub mod metadata; pub mod traits; -pub use self::traits::{Web3, Eth, EthFilter, EthPubSub, EthSigning, Net, Parity, ParityAccounts, ParitySet, ParitySigning, PubSub, Signer, Personal, Traces, Rpc, SecretStore}; +pub use self::traits::{Web3, Eth, EthFilter, EthPubSub, EthSigning, Net, Parity, ParityAccounts, ParitySet, ParitySigning, PubSub, Signer, Personal, Traces, Rpc, SecretStore, Private}; pub use self::impls::*; pub use self::helpers::{NetworkSettings, block_import, dispatch}; pub use self::metadata::Metadata; diff --git a/rpc/src/v1/tests/helpers/fetch.rs b/rpc/src/v1/tests/helpers/fetch.rs index 316d0682554..f3b7543f704 100644 --- a/rpc/src/v1/tests/helpers/fetch.rs +++ b/rpc/src/v1/tests/helpers/fetch.rs @@ -18,7 +18,7 @@ use std::thread; use jsonrpc_core::futures::{self, Future}; -use fetch::{self, Fetch, Url}; +use fetch::{self, Fetch, Url, Method}; use hyper; /// Test implementation of fetcher. Will always return the same file. @@ -28,7 +28,7 @@ pub struct TestFetch; impl Fetch for TestFetch { type Result = Box + Send + 'static>; - fn fetch(&self, url: &str, abort: fetch::Abort) -> Self::Result { + fn fetch(&self, url: &str, _method: Method, abort: fetch::Abort) -> Self::Result { let u = Url::parse(url).unwrap(); let (tx, rx) = futures::oneshot(); thread::spawn(move || { diff --git a/rpc/src/v1/traits/mod.rs b/rpc/src/v1/traits/mod.rs index 528463a4a4e..26a43fa3f83 100644 --- a/rpc/src/v1/traits/mod.rs +++ b/rpc/src/v1/traits/mod.rs @@ -31,6 +31,7 @@ pub mod signer; pub mod traces; pub mod rpc; pub mod secretstore; +pub mod private; pub use self::web3::Web3; pub use self::eth::{Eth, EthFilter}; @@ -47,3 +48,4 @@ pub use self::signer::Signer; pub use self::traces::Traces; pub use self::rpc::Rpc; pub use self::secretstore::SecretStore; +pub use self::private::Private; diff --git a/rpc/src/v1/traits/private.rs b/rpc/src/v1/traits/private.rs new file mode 100644 index 00000000000..7106e0bf43e --- /dev/null +++ b/rpc/src/v1/traits/private.rs @@ -0,0 +1,45 @@ +// 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 . + +//! SecretStore-specific rpc interface. + +use jsonrpc_core::Error; + +use v1::types::{Bytes, PrivateTransactionReceipt, H160, H256, U256, BlockNumber, + PrivateTransactionReceiptAndTransaction, CallRequest}; + +build_rpc_trait! { + /// Private transaction management RPC interface. + pub trait Private { + type Metadata; + + /// Sends private transaction; Transaction will be added to the validation queue and sent out when ready. + #[rpc(name = "private_sendTransaction")] + fn send_transaction(&self, Bytes) -> Result; + + /// Creates a transaction for contract's deployment from origin (signed transaction) + #[rpc(name = "private_composeDeploymentTransaction")] + fn compose_deployment_transaction(&self, BlockNumber, Bytes, Vec, U256) -> Result; + + /// Make a call to the private contract + #[rpc(meta, name = "private_call")] + fn private_call(&self, Self::Metadata, BlockNumber, CallRequest) -> Result; + + /// Retrieve the id of the key associated with the contract + #[rpc(name = "private_contractKey")] + fn private_contract_key(&self, H160) -> Result; + } +} diff --git a/rpc/src/v1/types/mod.rs b/rpc/src/v1/types/mod.rs index 7f1e51fad01..e7f764b8b1b 100644 --- a/rpc/src/v1/types/mod.rs +++ b/rpc/src/v1/types/mod.rs @@ -44,6 +44,7 @@ mod transaction_request; mod transaction_condition; mod uint; mod work; +mod private_receipt; pub mod pubsub; @@ -80,6 +81,7 @@ pub use self::transaction_request::TransactionRequest; pub use self::transaction_condition::TransactionCondition; pub use self::uint::{U128, U256, U64}; pub use self::work::Work; +pub use self::private_receipt::{PrivateTransactionReceipt, PrivateTransactionReceiptAndTransaction}; // TODO [ToDr] Refactor to a proper type Vec of enums? /// Expected tracing type. diff --git a/rpc/src/v1/types/private_receipt.rs b/rpc/src/v1/types/private_receipt.rs new file mode 100644 index 00000000000..328013d7f60 --- /dev/null +++ b/rpc/src/v1/types/private_receipt.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 v1::types::{H160, H256, TransactionRequest}; +use ethcore_private_tx::{Receipt as EthPrivateReceipt}; + +/// Receipt +#[derive(Debug, Serialize)] +pub struct PrivateTransactionReceipt { + /// Transaction Hash + #[serde(rename="transactionHash")] + pub transaction_hash: H256, + /// Private contract address + #[serde(rename="contractAddress")] + pub contract_address: Option, + /// Status code + #[serde(rename="status")] + pub status_code: u8, +} + +impl From for PrivateTransactionReceipt { + fn from(r: EthPrivateReceipt) -> Self { + PrivateTransactionReceipt { + transaction_hash: r.hash.into(), + contract_address: r.contract_address.map(Into::into), + status_code: r.status_code.into(), + } + } +} + +/// Receipt and Transaction +#[derive(Debug, Serialize)] +pub struct PrivateTransactionReceiptAndTransaction { + /// Receipt + #[serde(rename="receipt")] + pub receipt: PrivateTransactionReceipt, + /// Transaction + #[serde(rename="transaction")] + pub transaction: TransactionRequest, +} + diff --git a/sync/Cargo.toml b/sync/Cargo.toml index c5384de71df..23cbbcf3418 100644 --- a/sync/Cargo.toml +++ b/sync/Cargo.toml @@ -18,6 +18,7 @@ ethcore = { path = "../ethcore" } ethereum-types = "0.3" plain_hasher = { path = "../util/plain_hasher" } rlp = { path = "../util/rlp" } +rustc-hex = "1.0" keccak-hash = { path = "../util/hash" } triehash = { path = "../util/triehash" } kvdb = { path = "../util/kvdb" } diff --git a/sync/src/api.rs b/sync/src/api.rs index 735b6eb033c..62a237da48d 100644 --- a/sync/src/api.rs +++ b/sync/src/api.rs @@ -24,7 +24,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}; +use ethcore::client::{BlockChainClient, ChainNotify, ChainMessageType}; use ethcore::snapshot::SnapshotService; use ethcore::header::BlockNumber; use sync_io::NetSyncIo; @@ -32,11 +32,13 @@ 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}; +use chain::{ETH_PACKET_COUNT, SNAPSHOT_SYNC_PACKET_COUNT, 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; use light::net::{self as light_net, LightProtocol, Params as LightParams, Capabilities, Handler as LightHandler, EventContext}; use network::IpFilter; +use private_tx::PrivateTxHandler; /// Parity sync protocol pub const WARP_SYNC_PROTOCOL_ID: ProtocolId = *b"par"; @@ -227,6 +229,8 @@ pub struct Params { pub chain: Arc, /// Snapshot service. pub snapshot_service: Arc, + /// Private tx service. + pub private_tx_handler: Arc, /// Light data provider. pub provider: Arc<::light::Provider>, /// Network layer configuration. @@ -288,7 +292,7 @@ impl EthSync { }) }; - let chain_sync = ChainSync::new(params.config, &*params.chain); + let chain_sync = ChainSync::new(params.config, &*params.chain, params.private_tx_handler.clone()); let service = NetworkService::new(params.network_config.clone().into_basic()?, connection_filter)?; let sync = Arc::new(EthSync { @@ -392,9 +396,10 @@ impl NetworkProtocolHandler for SyncProtocolHandler { } fn timeout(&self, io: &NetworkContext, _timer: TimerToken) { - self.sync.write().maintain_peers(&mut NetSyncIo::new(io, &*self.chain, &*self.snapshot_service, &self.overlay)); - self.sync.write().maintain_sync(&mut NetSyncIo::new(io, &*self.chain, &*self.snapshot_service, &self.overlay)); - self.sync.write().propagate_new_transactions(&mut NetSyncIo::new(io, &*self.chain, &*self.snapshot_service, &self.overlay)); + 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); } } @@ -411,7 +416,8 @@ impl ChainNotify for EthSync { use light::net::Announcement; self.network.with_context(self.subprotocol_name, |context| { - let mut sync_io = NetSyncIo::new(context, &*self.eth_handler.chain, &*self.eth_handler.snapshot_service, &self.eth_handler.overlay); + let mut sync_io = NetSyncIo::new(context, &*self.eth_handler.chain, &*self.eth_handler.snapshot_service, + &self.eth_handler.overlay); self.eth_handler.sync.write().chain_new_blocks( &mut sync_io, &imported, @@ -448,10 +454,10 @@ 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, &[62u8, 63u8]) + self.network.register_protocol(self.eth_handler.clone(), self.subprotocol_name, ETH_PACKET_COUNT, &[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, &[1u8, 2u8]) + 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]) .unwrap_or_else(|e| warn!("Error registering snapshot sync protocol: {:?}", e)); // register the light protocol. @@ -469,10 +475,14 @@ impl ChainNotify for EthSync { self.network.stop().unwrap_or_else(|e| warn!("Error stopping network: {:?}", e)); } - fn broadcast(&self, message: Vec) { + fn broadcast(&self, message_type: ChainMessageType) { self.network.with_context(WARP_SYNC_PROTOCOL_ID, |context| { let mut sync_io = NetSyncIo::new(context, &*self.eth_handler.chain, &*self.eth_handler.snapshot_service, &self.eth_handler.overlay); - self.eth_handler.sync.write().propagate_consensus_packet(&mut sync_io, message.clone()); + match message_type { + ChainMessageType::Consensus(message) => self.eth_handler.sync.write().propagate_consensus_packet(&mut sync_io, message), + ChainMessageType::PrivateTransaction(message) => self.eth_handler.sync.write().propagate_private_transaction(&mut sync_io, message), + ChainMessageType::SignedPrivateTransaction(message) => self.eth_handler.sync.write().propagate_signed_private_transaction(&mut sync_io, message), + } }); } diff --git a/sync/src/chain.rs b/sync/src/chain.rs index 97802459129..b2494e1f038 100644 --- a/sync/src/chain.rs +++ b/sync/src/chain.rs @@ -88,6 +88,7 @@ /// All other messages are ignored. /// +use std::sync::Arc; use std::collections::{HashSet, HashMap}; use std::cmp; use std::time::Instant; @@ -111,15 +112,23 @@ use rand::Rng; use snapshot::{Snapshot, ChunkType}; use api::{EthProtocolInfo as PeerInfoDigest, WARP_SYNC_PROTOCOL_ID}; use transactions_stats::{TransactionsStats, Stats as TransactionStats}; +use private_tx::PrivateTxHandler; known_heap_size!(0, PeerInfo); type PacketDecodeError = DecoderError; -const PROTOCOL_VERSION_63: u8 = 63; -const PROTOCOL_VERSION_62: u8 = 62; -const PROTOCOL_VERSION_1: u8 = 1; -const PROTOCOL_VERSION_2: u8 = 2; +/// 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; @@ -160,8 +169,10 @@ 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 = 0x16; +pub const SNAPSHOT_SYNC_PACKET_COUNT: u8 = 0x18; const MAX_SNAPSHOT_CHUNKS_DOWNLOAD_AHEAD: usize = 3; @@ -384,6 +395,8 @@ pub struct ChainSync { 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, } @@ -392,7 +405,7 @@ type RlpResponseResult = Result, PacketDecodeError impl ChainSync { /// Create a new instance of syncing strategy. - pub fn new(config: SyncConfig, chain: &BlockChainClient) -> ChainSync { + 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 { @@ -417,6 +430,7 @@ impl ChainSync { snapshot: Snapshot::new(), sync_start_time: None, transactions_stats: TransactionsStats::default(), + private_tx_handler, warp_sync: config.warp_sync, }; sync.update_targets(chain); @@ -428,7 +442,7 @@ impl ChainSync { let last_imported_number = self.new_blocks.last_imported_block_number(); SyncStatus { state: self.state.clone(), - protocol_version: PROTOCOL_VERSION_63, + 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), @@ -662,7 +676,8 @@ impl ChainSync { 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 != PROTOCOL_VERSION_1 && peer.protocol_version != PROTOCOL_VERSION_2) || (!warp_protocol && peer.protocol_version != PROTOCOL_VERSION_63 && peer.protocol_version != PROTOCOL_VERSION_62) { + 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(()); @@ -1493,6 +1508,7 @@ impl ChainSync { } 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()?; @@ -1515,7 +1531,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 { PROTOCOL_VERSION_63 }; + 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(); @@ -1792,6 +1808,8 @@ impl ChainSync { 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(()) @@ -1945,7 +1963,11 @@ impl ChainSync { } fn get_consensus_peers(&self) -> Vec { - self.peers.iter().filter_map(|(id, p)| if p.protocol_version == PROTOCOL_VERSION_2 { Some(*id) } else { None }).collect() + 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 @@ -2223,6 +2245,54 @@ impl ChainSync { 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: &UntrustedRlp) -> 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: &UntrustedRlp) -> 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 @@ -2247,7 +2317,7 @@ mod tests { use std::collections::{HashSet, VecDeque}; use ethkey; use network::PeerId; - use tests::helpers::*; + use tests::helpers::{TestIo}; use tests::snapshot::TestSnapshotService; use ethereum_types::{H256, U256, Address}; use parking_lot::RwLock; @@ -2260,6 +2330,7 @@ mod tests { use ethcore::client::{BlockChainClient, EachBlockWith, TestBlockChainClient, ChainInfo, BlockInfo}; use ethcore::miner::MinerService; use transaction::UnverifiedTransaction; + use private_tx::NoopPrivateTxHandler; fn get_dummy_block(order: u32, parent_hash: H256) -> Bytes { let mut header = Header::new(); @@ -2483,7 +2554,7 @@ mod tests { } fn dummy_sync_with_peer(peer_latest_hash: H256, client: &BlockChainClient) -> ChainSync { - let mut sync = ChainSync::new(SyncConfig::default(), client); + let mut sync = ChainSync::new(SyncConfig::default(), client, Arc::new(NoopPrivateTxHandler)); insert_dummy_peer(&mut sync, 0, peer_latest_hash); sync } @@ -2608,7 +2679,7 @@ mod tests { 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); + let mut sync = ChainSync::new(SyncConfig::default(), &client, Arc::new(NoopPrivateTxHandler)); sync.peers.insert(0, PeerInfo { // Messaging protocol @@ -2695,7 +2766,7 @@ mod tests { client.add_blocks(100, EachBlockWith::Uncle); client.insert_transaction_to_queue(); // Sync with no peers - let mut sync = ChainSync::new(SyncConfig::default(), &client); + 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); @@ -2765,7 +2836,7 @@ mod tests { 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); + 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); @@ -2798,7 +2869,7 @@ mod tests { 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); + 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); diff --git a/sync/src/lib.rs b/sync/src/lib.rs index 9aee8f3d4ef..a6e0c7db24c 100644 --- a/sync/src/lib.rs +++ b/sync/src/lib.rs @@ -44,6 +44,7 @@ extern crate ethcore_light as light; #[cfg(test)] extern crate ethkey; #[cfg(test)] extern crate kvdb_memorydb; +#[cfg(test)] extern crate rustc_hex; #[macro_use] extern crate macros; @@ -56,6 +57,7 @@ mod chain; mod blocks; mod block_sync; mod sync_io; +mod private_tx; mod snapshot; mod transactions_stats; @@ -70,3 +72,4 @@ pub use api::*; pub use chain::{SyncStatus, SyncState}; pub use devp2p::{validate_node_url, ConnectionFilter, ConnectionDirection}; pub use network::{NonReservedPeerMode, Error, ErrorKind}; +pub use private_tx::{PrivateTxHandler, NoopPrivateTxHandler, SimplePrivateTxHandler}; diff --git a/sync/src/light_sync/tests/test_net.rs b/sync/src/light_sync/tests/test_net.rs index f935680573f..badd35668b9 100644 --- a/sync/src/light_sync/tests/test_net.rs +++ b/sync/src/light_sync/tests/test_net.rs @@ -205,6 +205,10 @@ impl PeerLike for Peer { } fn restart_sync(&self) { } + + fn process_all_io_messages(&self) { } + + fn process_all_new_block_messages(&self) { } } impl TestNet { diff --git a/sync/src/private_tx.rs b/sync/src/private_tx.rs new file mode 100644 index 00000000000..ded5de2d866 --- /dev/null +++ b/sync/src/private_tx.rs @@ -0,0 +1,60 @@ +// 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 parking_lot::Mutex; + +/// Trait which should be implemented by a private transaction handler. +pub trait PrivateTxHandler: Send + Sync + 'static { + /// Function called on new private transaction received. + fn import_private_transaction(&self, rlp: &[u8]) -> Result<(), String>; + + /// Function called on new signed private transaction received. + fn import_signed_private_transaction(&self, rlp: &[u8]) -> Result<(), String>; +} + +/// Nonoperative private transaction handler. +pub struct NoopPrivateTxHandler; + +impl PrivateTxHandler for NoopPrivateTxHandler { + fn import_private_transaction(&self, _rlp: &[u8]) -> Result<(), String> { + Ok(()) + } + + fn import_signed_private_transaction(&self, _rlp: &[u8]) -> Result<(), String> { + Ok(()) + } +} + +/// Simple private transaction handler. Used for tests. +#[derive(Default)] +pub struct SimplePrivateTxHandler { + /// imported private transactions + pub txs: Mutex>>, + /// imported signed private transactions + pub signed_txs: Mutex>>, +} + +impl PrivateTxHandler for SimplePrivateTxHandler { + fn import_private_transaction(&self, rlp: &[u8]) -> Result<(), String> { + self.txs.lock().push(rlp.to_vec()); + Ok(()) + } + + fn import_signed_private_transaction(&self, rlp: &[u8]) -> Result<(), String> { + self.signed_txs.lock().push(rlp.to_vec()); + Ok(()) + } +} diff --git a/sync/src/tests/consensus.rs b/sync/src/tests/consensus.rs index 951c027afe8..f4a58a18af4 100644 --- a/sync/src/tests/consensus.rs +++ b/sync/src/tests/consensus.rs @@ -17,8 +17,8 @@ use std::sync::Arc; use hash::keccak; use ethereum_types::{U256, Address}; -use io::{IoHandler, IoContext, IoChannel}; -use ethcore::client::{Client, ChainInfo, ClientIoMessage}; +use io::{IoHandler, IoChannel}; +use ethcore::client::{ChainInfo, ClientIoMessage}; use ethcore::spec::Spec; use ethcore::miner::MinerService; use ethcore::account_provider::AccountProvider; @@ -27,21 +27,6 @@ use transaction::{Action, PendingTransaction, Transaction}; use super::helpers::*; use SyncConfig; -struct TestIoHandler { - client: Arc, -} - -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); - }, - _ => {} // ignore other messages - } - } -} - fn new_tx(secret: &Secret, nonce: U256, chain_id: u64) -> PendingTransaction { let signed = Transaction { nonce: nonce.into(), @@ -63,9 +48,9 @@ fn authority_round() { ap.insert_account(s1.secret().clone(), "").unwrap(); let chain_id = Spec::new_test_round().chain_id(); - let mut net = TestNet::with_spec_and_accounts(2, SyncConfig::default(), Spec::new_test_round, Some(ap)); - let io_handler0: Arc> = Arc::new(TestIoHandler { client: net.peer(0).chain.clone() }); - let io_handler1: Arc> = Arc::new(TestIoHandler { client: net.peer(1).chain.clone() }); + let mut net = TestNet::with_spec_and_accounts(2, SyncConfig::default(), Spec::new_test_round, Some(ap), false); + let io_handler0: Arc> = Arc::new(TestIoHandler::new(net.peer(0).chain.clone())); + let io_handler1: Arc> = Arc::new(TestIoHandler::new(net.peer(1).chain.clone())); // Push transaction to both clients. Only one of them gets lucky to produce a block. net.peer(0).chain.miner().set_engine_signer(s0.address(), "".to_owned()).unwrap(); net.peer(1).chain.miner().set_engine_signer(s1.address(), "".to_owned()).unwrap(); @@ -150,9 +135,9 @@ fn tendermint() { ap.insert_account(s1.secret().clone(), "").unwrap(); let chain_id = Spec::new_test_tendermint().chain_id(); - let mut net = TestNet::with_spec_and_accounts(2, SyncConfig::default(), Spec::new_test_tendermint, Some(ap)); - let io_handler0: Arc> = Arc::new(TestIoHandler { client: net.peer(0).chain.clone() }); - let io_handler1: Arc> = Arc::new(TestIoHandler { client: net.peer(1).chain.clone() }); + let mut net = TestNet::with_spec_and_accounts(2, SyncConfig::default(), Spec::new_test_tendermint, Some(ap), false); + let io_handler0: Arc> = Arc::new(TestIoHandler::new(net.peer(0).chain.clone())); + let io_handler1: Arc> = Arc::new(TestIoHandler::new(net.peer(1).chain.clone())); // Push transaction to both clients. Only one of them issues a proposal. net.peer(0).chain.miner().set_engine_signer(s0.address(), "".to_owned()).unwrap(); trace!(target: "poa", "Peer 0 is {}.", s0.address()); diff --git a/sync/src/tests/helpers.rs b/sync/src/tests/helpers.rs index 32a90b414fe..495603020dc 100644 --- a/sync/src/tests/helpers.rs +++ b/sync/src/tests/helpers.rs @@ -17,21 +17,23 @@ use std::collections::{VecDeque, HashSet, HashMap}; use std::sync::Arc; use ethereum_types::H256; -use parking_lot::RwLock; +use parking_lot::{RwLock, Mutex}; use bytes::Bytes; use network::{self, PeerId, ProtocolId, PacketId, SessionInfo}; use tests::snapshot::*; -use ethcore::client::{TestBlockChainClient, BlockChainClient, Client as EthcoreClient, ClientConfig, ChainNotify}; +use ethcore::client::{TestBlockChainClient, BlockChainClient, Client as EthcoreClient, + ClientConfig, ChainNotify, ChainMessageType, ClientIoMessage}; use ethcore::header::BlockNumber; use ethcore::snapshot::SnapshotService; use ethcore::spec::Spec; use ethcore::account_provider::AccountProvider; use ethcore::miner::Miner; use sync_io::SyncIo; -use io::IoChannel; +use io::{IoChannel, IoContext, IoHandler}; use api::WARP_SYNC_PROTOCOL_ID; -use chain::ChainSync; -use ::SyncConfig; +use chain::{ChainSync, ETH_PROTOCOL_VERSION_63, PAR_PROTOCOL_VERSION_3}; +use SyncConfig; +use private_tx::{NoopPrivateTxHandler, PrivateTxHandler, SimplePrivateTxHandler}; pub trait FlushingBlockChainClient: BlockChainClient { fn flush(&self) {} @@ -131,11 +133,11 @@ impl<'p, C> SyncIo for TestIo<'p, C> where C: FlushingBlockChainClient, C: 'p { } fn eth_protocol_version(&self, _peer: PeerId) -> u8 { - 63 + ETH_PROTOCOL_VERSION_63 } fn protocol_version(&self, protocol: &ProtocolId, peer_id: PeerId) -> u8 { - if protocol == &WARP_SYNC_PROTOCOL_ID { 2 } else { self.eth_protocol_version(peer_id) } + if protocol == &WARP_SYNC_PROTOCOL_ID { PAR_PROTOCOL_VERSION_3 } else { self.eth_protocol_version(peer_id) } } fn chain_overlay(&self) -> &RwLock> { @@ -143,6 +145,16 @@ impl<'p, C> SyncIo for TestIo<'p, C> where C: FlushingBlockChainClient, C: 'p { } } +/// Mock for emulution of async run of new blocks +struct NewBlockMessage { + imported: Vec, + invalid: Vec, + enacted: Vec, + retracted: Vec, + sealed: Vec, + proposed: Vec, +} + /// Abstract messages between peers. pub trait Message { /// The intended recipient of this message. @@ -184,6 +196,12 @@ pub trait Peer { /// Restart sync for a peer. fn restart_sync(&self); + + /// Process the queue of pending io messages + fn process_all_io_messages(&self); + + /// Process the queue of new block messages + fn process_all_new_block_messages(&self); } pub struct EthPeer where C: FlushingBlockChainClient { @@ -191,6 +209,41 @@ pub struct EthPeer where C: FlushingBlockChainClient { pub snapshot_service: Arc, pub sync: RwLock, pub queue: RwLock>, + pub private_tx_handler: Arc, + pub io_queue: RwLock>, + new_blocks_queue: RwLock>, +} + +impl EthPeer where C: FlushingBlockChainClient { + fn is_io_queue_empty(&self) -> bool { + self.io_queue.read().is_empty() + } + + fn is_new_blocks_queue_empty(&self) -> bool { + self.new_blocks_queue.read().is_empty() + } + + fn process_io_message(&self, message: ChainMessageType) { + let mut io = TestIo::new(&*self.chain, &self.snapshot_service, &self.queue, None); + match message { + ChainMessageType::Consensus(data) => self.sync.write().propagate_consensus_packet(&mut io, data), + ChainMessageType::PrivateTransaction(data) => self.sync.write().propagate_private_transaction(&mut io, data), + ChainMessageType::SignedPrivateTransaction(data) => self.sync.write().propagate_signed_private_transaction(&mut io, data), + } + } + + fn process_new_block_message(&self, message: NewBlockMessage) { + let mut io = TestIo::new(&*self.chain, &self.snapshot_service, &self.queue, None); + self.sync.write().chain_new_blocks( + &mut io, + &message.imported, + &message.invalid, + &message.enacted, + &message.retracted, + &message.sealed, + &message.proposed + ); + } } impl Peer for EthPeer { @@ -198,7 +251,12 @@ impl Peer for EthPeer { fn on_connect(&self, other: PeerId) { self.sync.write().update_targets(&*self.chain); - self.sync.write().on_peer_connected(&mut TestIo::new(&*self.chain, &self.snapshot_service, &self.queue, Some(other)), other); + self.sync.write().on_peer_connected(&mut TestIo::new( + &*self.chain, + &self.snapshot_service, + &self.queue, + Some(other)), + other); } fn on_disconnect(&self, other: PeerId) { @@ -219,7 +277,7 @@ impl Peer for EthPeer { } fn is_done(&self) -> bool { - self.queue.read().is_empty() + self.queue.read().is_empty() && self.is_io_queue_empty() && self.is_new_blocks_queue_empty() } fn sync_step(&self) { @@ -232,6 +290,22 @@ impl Peer for EthPeer { fn restart_sync(&self) { self.sync.write().restart(&mut TestIo::new(&*self.chain, &self.snapshot_service, &self.queue, None)); } + + fn process_all_io_messages(&self) { + if !self.is_io_queue_empty() { + while let Some(message) = self.io_queue.write().pop_front() { + self.process_io_message(message); + } + } + } + + fn process_all_new_block_messages(&self) { + if !self.is_new_blocks_queue_empty() { + while let Some(message) = self.new_blocks_queue.write().pop_front() { + self.process_new_block_message(message); + } + } + } } pub struct TestNet

{ @@ -260,20 +334,35 @@ impl TestNet> { for _ in 0..n { let chain = TestBlockChainClient::new(); let ss = Arc::new(TestSnapshotService::new()); - let sync = ChainSync::new(config.clone(), &chain); + let private_tx_handler = Arc::new(NoopPrivateTxHandler); + let sync = ChainSync::new(config.clone(), &chain, private_tx_handler.clone()); net.peers.push(Arc::new(EthPeer { sync: RwLock::new(sync), snapshot_service: ss, chain: Arc::new(chain), queue: RwLock::new(VecDeque::new()), + private_tx_handler, + io_queue: RwLock::new(VecDeque::new()), + new_blocks_queue: RwLock::new(VecDeque::new()), })); } net } + + // relies on Arc uniqueness, which is only true when we haven't registered a ChainNotify. + pub fn peer_mut(&mut self, i: usize) -> &mut EthPeer { + Arc::get_mut(&mut self.peers[i]).expect("Arc never exposed externally") + } } impl TestNet> { - pub fn with_spec_and_accounts(n: usize, config: SyncConfig, spec_factory: F, accounts: Option>) -> Self + pub fn with_spec_and_accounts( + n: usize, + config: SyncConfig, + spec_factory: F, + accounts: Option>, + private_tx_handler: bool, + ) -> Self where F: Fn() -> Spec { let mut net = TestNet { @@ -282,11 +371,42 @@ impl TestNet> { disconnect_events: Vec::new(), }; for _ in 0..n { - net.add_peer(config.clone(), spec_factory(), accounts.clone()); + if private_tx_handler { + net.add_peer_with_private_config(config.clone(), spec_factory(), accounts.clone()); + } else { + net.add_peer(config.clone(), spec_factory(), accounts.clone()); + } } net } + pub fn add_peer_with_private_config(&mut self, config: SyncConfig, spec: Spec, accounts: Option>) { + let channel = IoChannel::disconnected(); + let client = EthcoreClient::new( + ClientConfig::default(), + &spec, + Arc::new(::kvdb_memorydb::create(::ethcore::db::NUM_COLUMNS.unwrap_or(0))), + Arc::new(Miner::with_spec_and_accounts(&spec, accounts.clone())), + channel.clone() + ).unwrap(); + + let private_tx_handler = Arc::new(SimplePrivateTxHandler::default()); + let ss = Arc::new(TestSnapshotService::new()); + let sync = ChainSync::new(config, &*client, private_tx_handler.clone()); + let peer = Arc::new(EthPeer { + sync: RwLock::new(sync), + snapshot_service: ss, + chain: client, + queue: RwLock::new(VecDeque::new()), + private_tx_handler, + io_queue: RwLock::new(VecDeque::new()), + new_blocks_queue: RwLock::new(VecDeque::new()), + }); + peer.chain.add_notify(peer.clone()); + //private_provider.add_notify(peer.clone()); + self.peers.push(peer); + } + pub fn add_peer(&mut self, config: SyncConfig, spec: Spec, accounts: Option>) { let client = EthcoreClient::new( ClientConfig::default(), @@ -297,12 +417,16 @@ impl TestNet> { ).unwrap(); let ss = Arc::new(TestSnapshotService::new()); - let sync = ChainSync::new(config, &*client); + let private_tx_handler = Arc::new(NoopPrivateTxHandler); + let sync = ChainSync::new(config, &*client, private_tx_handler.clone()); let peer = Arc::new(EthPeer { sync: RwLock::new(sync), snapshot_service: ss, chain: client, queue: RwLock::new(VecDeque::new()), + private_tx_handler, + io_queue: RwLock::new(VecDeque::new()), + new_blocks_queue: RwLock::new(VecDeque::new()), }); peer.chain.add_notify(peer.clone()); self.peers.push(peer); @@ -366,6 +490,8 @@ impl

TestNet

where P: Peer { let mut total_steps = 0; while !self.done() { self.sync_step(); + self.deliver_io_messages(); + self.deliver_new_block_messages(); total_steps += 1; } total_steps @@ -378,15 +504,20 @@ impl

TestNet

where P: Peer { } } - pub fn done(&self) -> bool { - self.peers.iter().all(|p| p.is_done()) + pub fn deliver_io_messages(&mut self) { + for peer in self.peers.iter() { + peer.process_all_io_messages(); + } } -} -impl TestNet> { - // relies on Arc uniqueness, which is only true when we haven't registered a ChainNotify. - pub fn peer_mut(&mut self, i: usize) -> &mut EthPeer { - Arc::get_mut(&mut self.peers[i]).expect("Arc never exposed externally") + pub fn deliver_new_block_messages(&mut self) { + for peer in self.peers.iter() { + peer.process_all_new_block_messages(); + } + } + + pub fn done(&self) -> bool { + self.peers.iter().all(|p| p.is_done()) } } @@ -397,6 +528,34 @@ impl TestNet> { } } +pub struct TestIoHandler { + pub client: Arc, + pub private_tx_queued: Mutex, +} + +impl TestIoHandler { + pub fn new(client: Arc) -> Self { + TestIoHandler { + client, + private_tx_queued: Mutex::default(), + } + } +} + +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 => { + *self.private_tx_queued.lock() += 1; + }, + _ => {} // ignore other messages + } + } +} + impl ChainNotify for EthPeer { fn new_blocks(&self, imported: Vec, @@ -407,23 +566,21 @@ impl ChainNotify for EthPeer { proposed: Vec, _duration: u64) { - let mut io = TestIo::new(&*self.chain, &self.snapshot_service, &self.queue, None); - self.sync.write().chain_new_blocks( - &mut io, - &imported, - &invalid, - &enacted, - &retracted, - &sealed, - &proposed); + self.new_blocks_queue.write().push_back(NewBlockMessage { + imported, + invalid, + enacted, + retracted, + sealed, + proposed, + }); } fn start(&self) {} fn stop(&self) {} - fn broadcast(&self, message: Vec) { - let mut io = TestIo::new(&*self.chain, &self.snapshot_service, &self.queue, None); - self.sync.write().propagate_consensus_packet(&mut io, message.clone()); + fn broadcast(&self, message_type: ChainMessageType) { + self.io_queue.write().push_back(message_type) } } diff --git a/util/fetch/src/client.rs b/util/fetch/src/client.rs index fee3130c428..b3274ca4f73 100644 --- a/util/fetch/src/client.rs +++ b/util/fetch/src/client.rs @@ -119,13 +119,23 @@ pub trait Fetch: Clone + Send + Sync + 'static { /// The result future. type Result: Future + Send + 'static; + /// Make a request to given URL + fn fetch(&self, url: &str, method: Method, abort: Abort) -> Self::Result; + /// Get content from some URL. - fn fetch(&self, url: &str, abort: Abort) -> Self::Result; + fn get(&self, url: &str, abort: Abort) -> Self::Result { + self.fetch(url, Method::Get, abort) + } + + /// Post content to some URL. + fn post(&self, url: &str, abort: Abort) -> Self::Result { + self.fetch(url, Method::Post, abort) + } } type TxResponse = oneshot::Sender>; type TxStartup = std::sync::mpsc::SyncSender>; -type ChanItem = Option<(Url, Abort, TxResponse)>; +type ChanItem = Option<(Url, Method, Abort, TxResponse)>; /// An implementation of `Fetch` using a `hyper` client. // Due to the `Send` bound of `Fetch` we spawn a background thread for @@ -203,17 +213,17 @@ impl Client { let future = rx_proto.take_while(|item| Ok(item.is_some())) .map(|item| item.expect("`take_while` is only passing on channel items != None; qed")) - .for_each(|(url, abort, sender)| + .for_each(|(url, method, abort, sender)| { trace!(target: "fetch", "new request to {}", url); if abort.is_aborted() { return future::ok(sender.send(Err(Error::Aborted)).unwrap_or(())) } - let ini = (hyper.clone(), url, abort, 0); - let fut = future::loop_fn(ini, |(client, url, abort, redirects)| { + let ini = (hyper.clone(), url, method, abort, 0); + let fut = future::loop_fn(ini, |(client, url, method, abort, redirects)| { let url2 = url.clone(); let abort2 = abort.clone(); - client.request(get(&url)) + client.request(build_request(&url, method.clone())) .map(move |resp| Response::new(url2, resp, abort2)) .from_err() .and_then(move |resp| { @@ -225,7 +235,7 @@ impl Client { if redirects >= abort.max_redirects() { return Err(Error::TooManyRedirects) } - Ok(Loop::Continue((client, next_url, abort, redirects + 1))) + Ok(Loop::Continue((client, next_url, method, abort, redirects + 1))) } else { let content_len = resp.headers.get::().cloned(); if content_len.map(|n| *n > abort.max_size() as u64).unwrap_or(false) { @@ -257,7 +267,7 @@ impl Client { impl Fetch for Client { type Result = Box + Send>; - fn fetch(&self, url: &str, abort: Abort) -> Self::Result { + fn fetch(&self, url: &str, method: Method, abort: Abort) -> Self::Result { debug!(target: "fetch", "fetching: {:?}", url); if abort.is_aborted() { return Box::new(future::err(Error::Aborted)) @@ -269,7 +279,7 @@ impl Fetch for Client { let (tx_res, rx_res) = oneshot::channel(); let maxdur = abort.max_duration(); let sender = self.core.clone(); - let future = sender.send(Some((url.clone(), abort, tx_res))) + let future = sender.send(Some((url.clone(), method, abort, tx_res))) .map_err(|e| { error!(target: "fetch", "failed to schedule request: {}", e); Error::BackgroundThreadDead @@ -308,10 +318,10 @@ fn redirect_location(u: Url, r: &Response) -> Option { } } -// Build a simple GET request for the given Url. -fn get(u: &Url) -> hyper::Request { +// Build a simple request for the given Url and method +fn build_request(u: &Url, method: Method) -> hyper::Request { let uri = u.as_ref().parse().expect("Every valid URL is aso a URI."); - let mut rq = Request::new(Method::Get, uri); + let mut rq = Request::new(method, uri); rq.headers_mut().set(UserAgent::new("Parity Fetch Neo")); rq } @@ -350,6 +360,11 @@ impl Response { self.status() == StatusCode::Ok } + /// Status code == 404. + pub fn is_not_found(&self) -> bool { + self.status() == StatusCode::NotFound + } + /// Is the content-type text/html? pub fn is_html(&self) -> bool { if let Some(ref mime) = self.content_type() { @@ -512,7 +527,7 @@ mod test { use futures::future; use futures::sync::mpsc; use futures_timer::Delay; - use hyper::StatusCode; + use hyper::{StatusCode, Method}; use hyper::server::{Http, Request, Response, Service}; use std; use std::io::Read; @@ -524,7 +539,7 @@ mod test { fn it_should_fetch() { let server = TestServer::run(); let client = Client::new().unwrap(); - let future = client.fetch(&format!("http://{}?123", server.addr()), Default::default()); + let future = client.fetch(&format!("http://{}?123", server.addr()), Method::Get, Default::default()); let resp = future.wait().unwrap(); assert!(resp.is_success()); let body = resp.concat2().wait().unwrap(); @@ -536,7 +551,7 @@ mod test { let server = TestServer::run(); let client = Client::new().unwrap(); let abort = Abort::default().with_max_duration(Duration::from_secs(1)); - match client.fetch(&format!("http://{}/delay?3", server.addr()), abort).wait() { + match client.fetch(&format!("http://{}/delay?3", server.addr()), Method::Get, abort).wait() { Err(Error::Timeout) => {} other => panic!("expected timeout, got {:?}", other) } @@ -547,7 +562,7 @@ mod test { let server = TestServer::run(); let client = Client::new().unwrap(); let abort = Abort::default(); - let future = client.fetch(&format!("http://{}/redirect?http://{}/", server.addr(), server.addr()), abort); + let future = client.fetch(&format!("http://{}/redirect?http://{}/", server.addr(), server.addr()), Method::Get, abort); assert!(future.wait().unwrap().is_success()) } @@ -556,7 +571,7 @@ mod test { let server = TestServer::run(); let client = Client::new().unwrap(); let abort = Abort::default().with_max_redirects(4); - let future = client.fetch(&format!("http://{}/redirect?/", server.addr()), abort); + let future = client.fetch(&format!("http://{}/redirect?/", server.addr()), Method::Get, abort); assert!(future.wait().unwrap().is_success()) } @@ -565,7 +580,7 @@ mod test { let server = TestServer::run(); let client = Client::new().unwrap(); let abort = Abort::default().with_max_redirects(3); - match client.fetch(&format!("http://{}/loop", server.addr()), abort).wait() { + match client.fetch(&format!("http://{}/loop", server.addr()), Method::Get, abort).wait() { Err(Error::TooManyRedirects) => {} other => panic!("expected too many redirects error, got {:?}", other) } @@ -576,7 +591,7 @@ mod test { let server = TestServer::run(); let client = Client::new().unwrap(); let abort = Abort::default(); - let future = client.fetch(&format!("http://{}?abcdefghijklmnopqrstuvwxyz", server.addr()), abort); + let future = client.fetch(&format!("http://{}?abcdefghijklmnopqrstuvwxyz", server.addr()), Method::Get, abort); let resp = future.wait().unwrap(); assert!(resp.is_success()); assert_eq!(&resp.concat2().wait().unwrap()[..], b"abcdefghijklmnopqrstuvwxyz") @@ -587,7 +602,7 @@ mod test { let server = TestServer::run(); let client = Client::new().unwrap(); let abort = Abort::default().with_max_size(3); - let resp = client.fetch(&format!("http://{}/?1234", server.addr()), abort).wait().unwrap(); + let resp = client.fetch(&format!("http://{}/?1234", server.addr()), Method::Get, abort).wait().unwrap(); assert!(resp.is_success()); match resp.concat2().wait() { Err(Error::SizeLimit) => {} @@ -600,7 +615,7 @@ mod test { let server = TestServer::run(); let client = Client::new().unwrap(); let abort = Abort::default().with_max_size(3); - let resp = client.fetch(&format!("http://{}/?1234", server.addr()), abort).wait().unwrap(); + let resp = client.fetch(&format!("http://{}/?1234", server.addr()), Method::Get, abort).wait().unwrap(); assert!(resp.is_success()); let mut buffer = Vec::new(); let mut reader = BodyReader::new(resp); diff --git a/util/fetch/src/lib.rs b/util/fetch/src/lib.rs index a5722dfe26a..55785633f5a 100644 --- a/util/fetch/src/lib.rs +++ b/util/fetch/src/lib.rs @@ -36,4 +36,5 @@ pub mod client; pub use url::Url; pub use self::client::{Client, Fetch, Error, Response, Abort, BodyReader}; +pub use hyper::Method; From d97cf341388ced3f5eb501bc9e06cb461e349758 Mon Sep 17 00:00:00 2001 From: Akira Takizawa Date: Mon, 9 Apr 2018 23:18:00 +0900 Subject: [PATCH 04/25] Add Ethereum Social support (#8325) --- ethcore/res/ethereum/social.json | 8857 ++++++++++++++++++++++++++++++ ethcore/src/ethereum/mod.rs | 5 + parity/cli/mod.rs | 2 +- parity/params.rs | 4 + 4 files changed, 8867 insertions(+), 1 deletion(-) create mode 100644 ethcore/res/ethereum/social.json diff --git a/ethcore/res/ethereum/social.json b/ethcore/res/ethereum/social.json new file mode 100644 index 00000000000..87d1f2e4b1f --- /dev/null +++ b/ethcore/res/ethereum/social.json @@ -0,0 +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" + } + } +} diff --git a/ethcore/src/ethereum/mod.rs b/ethcore/src/ethereum/mod.rs index 1bdcb01e14e..71cf2e86af0 100644 --- a/ethcore/src/ethereum/mod.rs +++ b/ethcore/src/ethereum/mod.rs @@ -76,6 +76,11 @@ pub fn new_easthub<'a, T: Into>>(params: T) -> Spec { load(params.into(), include_bytes!("../../res/ethereum/easthub.json")) } +/// Create a new Ethereum Social mainnet chain spec ¯\_(ツ)_/¯ . +pub fn new_social<'a, T: Into>>(params: T) -> Spec { + load(params.into(), include_bytes!("../../res/ethereum/social.json")) +} + /// Create a new Kovan testnet chain spec. pub fn new_kovan<'a, T: Into>>(params: T) -> Spec { load(params.into(), include_bytes!("../../res/ethereum/kovan.json")) diff --git a/parity/cli/mod.rs b/parity/cli/mod.rs index a160661b913..cb6470e9b81 100644 --- a/parity/cli/mod.rs +++ b/parity/cli/mod.rs @@ -294,7 +294,7 @@ usage! { ARG arg_chain: (String) = "foundation", or |c: &Config| c.parity.as_ref()?.chain.clone(), "--chain=[CHAIN]", - "Specify the blockchain type. CHAIN may be either a JSON chain specification file or olympic, frontier, homestead, mainnet, morden, ropsten, classic, expanse, musicoin, ellaism, easthub, testnet, kovan or dev.", + "Specify the blockchain type. CHAIN may be either a JSON chain specification file or olympic, frontier, homestead, mainnet, morden, ropsten, classic, expanse, musicoin, ellaism, easthub, social, testnet, kovan or dev.", ARG arg_keys_path: (String) = "$BASE/keys", or |c: &Config| c.parity.as_ref()?.keys_path.clone(), "--keys-path=[PATH]", diff --git a/parity/params.rs b/parity/params.rs index ef58bc37b63..59676108ed8 100644 --- a/parity/params.rs +++ b/parity/params.rs @@ -39,6 +39,7 @@ pub enum SpecType { Musicoin, Ellaism, Easthub, + Social, Dev, Custom(String), } @@ -64,6 +65,7 @@ impl str::FromStr for SpecType { "musicoin" => SpecType::Musicoin, "ellaism" => SpecType::Ellaism, "easthub" => SpecType::Easthub, + "social" => SpecType::Social, "dev" => SpecType::Dev, other => SpecType::Custom(other.into()), }; @@ -83,6 +85,7 @@ impl fmt::Display for SpecType { SpecType::Musicoin => "musicoin", SpecType::Ellaism => "ellaism", SpecType::Easthub => "easthub", + SpecType::Social => "social", SpecType::Kovan => "kovan", SpecType::Dev => "dev", SpecType::Custom(ref custom) => custom, @@ -103,6 +106,7 @@ impl SpecType { SpecType::Musicoin => Ok(ethereum::new_musicoin(params)), SpecType::Ellaism => Ok(ethereum::new_ellaism(params)), SpecType::Easthub => Ok(ethereum::new_easthub(params)), + SpecType::Social => Ok(ethereum::new_social(params)), SpecType::Kovan => Ok(ethereum::new_kovan(params)), SpecType::Dev => Ok(Spec::new_instant()), SpecType::Custom(ref filename) => { From 431b27d3e19fb70eee309aaa723e910070506867 Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Mon, 9 Apr 2018 22:34:47 +0800 Subject: [PATCH 05/25] replace_home for password_files, reserved_peers and log_file (#8324) * replace_home for password_files, reserved_peers and log_file * typo: arg_log_file is Option --- parity/configuration.rs | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/parity/configuration.rs b/parity/configuration.rs index 7ce3db1240e..7760fe470a4 100644 --- a/parity/configuration.rs +++ b/parity/configuration.rs @@ -149,7 +149,7 @@ impl Configuration { if self.args.cmd_signer_new_token { Cmd::SignerToken(ws_conf, ui_conf, logger_config.clone()) } else if self.args.cmd_signer_sign { - let pwfile = self.args.arg_password.first().map(|pwfile| { + let pwfile = self.accounts_config()?.password_files.first().map(|pwfile| { PathBuf::from(pwfile) }); Cmd::SignerSign { @@ -186,7 +186,7 @@ impl Configuration { iterations: self.args.arg_keys_iterations, path: dirs.keys, spec: spec, - password_file: self.args.arg_password.first().map(|x| x.to_owned()), + password_file: self.accounts_config()?.password_files.first().map(|x| x.to_owned()), }; AccountCmd::New(new_acc) } else if self.args.cmd_account_list { @@ -220,8 +220,8 @@ impl Configuration { iterations: self.args.arg_keys_iterations, path: dirs.keys, spec: spec, - wallet_path: self.args.arg_wallet_import_path.unwrap().clone(), - password_file: self.args.arg_password.first().map(|x| x.to_owned()), + wallet_path: self.args.arg_wallet_import_path.clone().unwrap(), + password_file: self.accounts_config()?.password_files.first().map(|x| x.to_owned()), }; Cmd::ImportPresaleWallet(presale_cmd) } else if self.args.cmd_import { @@ -456,7 +456,7 @@ impl Configuration { LogConfig { mode: self.args.arg_logging.clone(), color: !self.args.flag_no_color && !cfg!(windows), - file: self.args.arg_log_file.clone(), + file: self.args.arg_log_file.as_ref().map(|log_file| replace_home(&self.directories().base, log_file)), } } @@ -508,7 +508,7 @@ impl Configuration { iterations: self.args.arg_keys_iterations, refresh_time: self.args.arg_accounts_refresh, testnet: self.args.flag_testnet, - password_files: self.args.arg_password.clone(), + password_files: self.args.arg_password.iter().map(|s| replace_home(&self.directories().base, s)).collect(), unlocked_accounts: to_addresses(&self.args.arg_unlock)?, enable_hardware_wallets: !self.args.flag_no_hardware_wallets, enable_fast_unlock: self.args.flag_fast_unlock, @@ -728,8 +728,10 @@ impl Configuration { match self.args.arg_reserved_peers { Some(ref path) => { + let path = replace_home(&self.directories().base, path); + let mut buffer = String::new(); - let mut node_file = File::open(path).map_err(|e| format!("Error opening reserved nodes file: {}", e))?; + let mut node_file = File::open(&path).map_err(|e| format!("Error opening reserved nodes file: {}", e))?; node_file.read_to_string(&mut buffer).map_err(|_| "Error reading reserved node file")?; let lines = buffer.lines().map(|s| s.trim().to_owned()).filter(|s| !s.is_empty() && !s.starts_with("#")).collect::>(); From 1c75e8eb479924f1a596635c9537acdfd12031a6 Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Mon, 9 Apr 2018 16:35:45 +0200 Subject: [PATCH 06/25] Whisper cli (#8201) * getting started * wip wip * add parsing of pool-size and enable panic-hook * more cli options * remove explicit unwrapping * bump dependencies to parity-jsonrpc * add tests * remove tests * bump jsonrpc * Remove unused dependencies * add logging to the cli * Fix so `FilterManager` drops its resources * Introduced an AtomicBool flag in FilterManager to cancel the `Decryption Worker Thread` * Added some very basic test to faulty arguments * ignore privileged port test --- Cargo.lock | 18 +++ Cargo.toml | 3 +- whisper/cli/Cargo.toml | 22 +++ whisper/cli/src/main.rs | 300 ++++++++++++++++++++++++++++++++++++++ whisper/src/rpc/filter.rs | 28 +++- 5 files changed, 364 insertions(+), 7 deletions(-) create mode 100644 whisper/cli/Cargo.toml create mode 100644 whisper/cli/src/main.rs diff --git a/Cargo.lock b/Cargo.lock index 28a4b8a7af0..80bdcf34978 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3697,6 +3697,24 @@ dependencies = [ "webpki 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "whisper-cli" +version = "0.1.0" +dependencies = [ + "docopt 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)", + "ethcore-logger 1.11.0", + "ethcore-network 1.11.0", + "ethcore-network-devp2p 1.11.0", + "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)", + "jsonrpc-pubsub 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.11)", + "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "panic_hook 0.1.0", + "parity-whisper 0.1.0", + "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)", +] + [[package]] name = "winapi" version = "0.2.8" diff --git a/Cargo.toml b/Cargo.toml index 202215ab34b..bb92fff358f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -132,7 +132,8 @@ members = [ "evmbin", "miner", "transaction-pool", - "whisper" + "whisper", + "whisper/cli", ] [patch.crates-io] diff --git a/whisper/cli/Cargo.toml b/whisper/cli/Cargo.toml new file mode 100644 index 00000000000..363471a1a34 --- /dev/null +++ b/whisper/cli/Cargo.toml @@ -0,0 +1,22 @@ +[package] +name = "whisper-cli" +version = "0.1.0" +authors = ["Parity Technologies "] + +[dependencies] +ethcore-network-devp2p = { path = "../../util/network-devp2p" } +ethcore-network = { path = "../../util/network" } +ethcore-logger = { path = "../../logger" } +parity-whisper = { path = "../" } +docopt = "0.8" +serde = "1.0" +serde_derive = "1.0" +panic_hook = { path = "../../util/panic_hook" } +jsonrpc-core = { git = "https://github.com/paritytech/jsonrpc.git", branch = "parity-1.11" } +jsonrpc-pubsub = { git = "https://github.com/paritytech/jsonrpc.git", branch = "parity-1.11" } +jsonrpc-http-server = { git = "https://github.com/paritytech/jsonrpc.git", branch = "parity-1.11" } +log = "0.3" + +[[bin]] +name = "whisper-cli" +path = "src/main.rs" diff --git a/whisper/cli/src/main.rs b/whisper/cli/src/main.rs new file mode 100644 index 00000000000..d0866cd66a8 --- /dev/null +++ b/whisper/cli/src/main.rs @@ -0,0 +1,300 @@ +// 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 . + +//! Whisper command line interface +//! +//! Spawns an Ethereum network instance and attaches the Whisper protocol RPCs to it. +//! + +extern crate docopt; +extern crate ethcore_network_devp2p as devp2p; +extern crate ethcore_network as net; +extern crate parity_whisper as whisper; +extern crate serde; +extern crate panic_hook; + +extern crate jsonrpc_core; +extern crate jsonrpc_pubsub; +extern crate jsonrpc_http_server; +extern crate ethcore_logger as log; + +#[macro_use] +extern crate log as rlog; + +#[macro_use] +extern crate serde_derive; + +use docopt::Docopt; +use std::{fmt, io, process, env, sync::Arc}; +use jsonrpc_core::{Metadata, MetaIoHandler}; +use jsonrpc_pubsub::{PubSubMetadata, Session}; +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 + +Usage: + whisper [options] + whisper [-h | --help] + +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]. + -h, --help Display this message and exit. +"#; + +#[derive(Clone, Default)] +struct Meta; + +impl Metadata for Meta {} + +impl PubSubMetadata for Meta { + fn session(&self) -> Option> { + None + } +} + +#[derive(Debug, Deserialize)] +struct Args { + flag_whisper_pool_size: usize, + flag_port: String, + flag_address: String, + flag_log: String, +} + +struct WhisperPoolHandle { + /// Pool handle. + handle: Arc>>, + /// Network manager. + net: Arc, +} + +impl whisper::rpc::PoolHandle for WhisperPoolHandle { + fn relay(&self, message: whisper::message::Message) -> bool { + let mut res = false; + let mut message = Some(message); + self.with_proto_context(whisper::net::PROTOCOL_ID, &mut |ctx| { + if let Some(message) = message.take() { + res = self.handle.post_message(message, ctx); + } + }); + res + } + + fn pool_status(&self) -> whisper::net::PoolStatus { + self.handle.pool_status() + } +} + +impl WhisperPoolHandle { + fn with_proto_context(&self, proto: net::ProtocolId, f: &mut FnMut(&net::NetworkContext)) { + self.net.with_context_eval(proto, f); + } +} + +struct RpcFactory { + handle: Arc>>, + manager: Arc, +} + +impl RpcFactory { + fn make_handler(&self, net: Arc) -> whisper::rpc::WhisperClient { + let whisper_pool_handle = WhisperPoolHandle { handle: self.handle.clone(), net: net }; + whisper::rpc::WhisperClient::new(whisper_pool_handle, self.manager.clone()) + } +} + +#[derive(Debug)] +enum Error { + Docopt(docopt::Error), + Io(io::Error), + JsonRpc(jsonrpc_core::Error), + Network(net::Error), + SockAddr(std::net::AddrParseError), + Logger(String), +} + +impl From for Error { + fn from(err: std::net::AddrParseError) -> Self { + Error::SockAddr(err) + } +} + +impl From for Error { + fn from(err: net::Error) -> Self { + Error::Network(err) + } +} + +impl From for Error { + fn from(err: docopt::Error) -> Self { + Error::Docopt(err) + } +} + +impl From for Error { + fn from(err: io::Error) -> Self { + Error::Io(err) + } +} + +impl From for Error { + fn from(err: jsonrpc_core::Error) -> Self { + Error::JsonRpc(err) + } +} + +impl From for Error { + fn from(err: String) -> Self { + Error::Logger(err) + } +} + +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), + } + } +} + +fn main() { + panic_hook::set(); + + match execute(env::args()) { + Ok(_) => { + println!("whisper-cli terminated"); + process::exit(1); + } + Err(err) => { + println!("{}", err); + process::exit(1); + }, + } +} + +fn execute(command: I) -> Result<(), Error> where I: IntoIterator, S: AsRef { + + // Parse arguments + let args: Args = Docopt::new(USAGE).and_then(|d| d.argv(command).deserialize())?; + let pool_size = args.flag_whisper_pool_size * POOL_UNIT; + let url = format!("{}:{}", args.flag_address, args.flag_port); + + initialize_logger(args.flag_log)?; + info!(target: "whisper-cli", "start"); + + // Filter manager that will dispatch `decryption tasks` + let manager = Arc::new(whisper::rpc::FilterManager::new()?); + + // Whisper protocol network handler + let whisper_network_handler = Arc::new(whisper::net::Network::new(pool_size, manager.clone())); + + // Create network service + let network = devp2p::NetworkService::new(net::NetworkConfiguration::new_local(), None)?; + + // Start network service + network.start()?; + + // Attach whisper protocol to the network service + network.register_protocol(whisper_network_handler.clone(), whisper::net::PROTOCOL_ID, whisper::net::PACKET_COUNT, + 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)?; + + // Request handler + let mut io = MetaIoHandler::default(); + + // Shared network service + let shared_network = Arc::new(network); + + // Pool handler + let whisper_factory = RpcFactory { handle: whisper_network_handler, manager: manager }; + + io.extend_with(whisper::rpc::Whisper::to_delegate(whisper_factory.make_handler(shared_network.clone()))); + io.extend_with(whisper::rpc::WhisperPubSub::to_delegate(whisper_factory.make_handler(shared_network.clone()))); + + let server = jsonrpc_http_server::ServerBuilder::new(io) + .cors(DomainsValidation::AllowOnly(vec![AccessControlAllowOrigin::Null])) + .start_http(&url.parse()?)?; + + server.wait(); + + // This will never return if the http server runs without errors + Ok(()) +} + +fn initialize_logger(log_level: String) -> Result<(), String> { + let mut l = log::Config::default(); + l.mode = Some(log_level); + log::setup_log(&l)?; + Ok(()) +} + + +#[cfg(test)] +mod tests { + use super::execute; + + #[test] + fn invalid_argument() { + let command = vec!["whisper-cli", "--foo=12"] + .into_iter() + .map(Into::into) + .collect::>(); + + assert!(execute(command).is_err()); + } + + #[test] + #[ignore] + fn privileged_port() { + let command = vec!["whisper-cli", "--port=3"] + .into_iter() + .map(Into::into) + .collect::>(); + + assert!(execute(command).is_err()); + } + + #[test] + fn invalid_ip_address() { + let command = vec!["whisper-cli", "--address=x.x.x.x"] + .into_iter() + .map(Into::into) + .collect::>(); + + assert!(execute(command).is_err()); + } + + #[test] + fn invalid_whisper_pool_size() { + let command = vec!["whisper-cli", "--whisper-pool-size=-100000000000000000000000000000000000000"] + .into_iter() + .map(Into::into) + .collect::>(); + + assert!(execute(command).is_err()); + } +} diff --git a/whisper/src/rpc/filter.rs b/whisper/src/rpc/filter.rs index 663c6a6bf7b..5a192ac04cd 100644 --- a/whisper/src/rpc/filter.rs +++ b/whisper/src/rpc/filter.rs @@ -17,8 +17,7 @@ //! Abstraction over filters which works with polling and subscription. use std::collections::HashMap; -use std::sync::{mpsc, Arc}; -use std::thread; +use std::{sync::{Arc, atomic, atomic::AtomicBool, mpsc}, thread}; use ethereum_types::{H256, H512}; use ethkey::Public; @@ -27,8 +26,7 @@ use parking_lot::{Mutex, RwLock}; use rand::{Rng, OsRng}; use message::{Message, Topic}; -use super::key_store::KeyStore; -use super::types::{self, FilterItem, HexEncode}; +use super::{key_store::KeyStore, types::{self, FilterItem, HexEncode}}; /// Kinds of filters, #[derive(PartialEq, Eq, Clone, Copy)] @@ -53,6 +51,7 @@ pub struct Manager { filters: RwLock>, tx: Mutex>>, join: Option>, + exit: Arc, } impl Manager { @@ -60,15 +59,29 @@ impl Manager { /// the given thread pool. pub fn new() -> ::std::io::Result { let (tx, rx) = mpsc::channel::>(); + let exit = Arc::new(AtomicBool::new(false)); + let e = exit.clone(); + let join_handle = thread::Builder::new() .name("Whisper Decryption Worker".to_string()) - .spawn(move || for item in rx { (item)() })?; + .spawn(move || { + trace!(target: "parity_whisper", "Start decryption worker"); + loop { + if exit.load(atomic::Ordering::Acquire) { + break; + } + if let Ok(item) = rx.try_recv() { + item(); + } + } + })?; Ok(Manager { key_store: Arc::new(RwLock::new(KeyStore::new()?)), filters: RwLock::new(HashMap::new()), tx: Mutex::new(tx), join: Some(join_handle), + exit: e, }) } @@ -103,7 +116,7 @@ impl Manager { } /// Insert new subscription filter. Generates a secure ID and sends it to - /// the + /// the subscriber pub fn insert_subscription(&self, filter: Filter, sub: Subscriber) -> Result<(), &'static str> { @@ -180,9 +193,12 @@ impl ::net::MessageHandler for Arc { impl Drop for Manager { fn drop(&mut self) { + trace!(target: "parity_whisper", "waiting to drop FilterManager"); + self.exit.store(true, atomic::Ordering::Release); if let Some(guard) = self.join.take() { let _ = guard.join(); } + trace!(target: "parity_whisper", "FilterManager dropped"); } } From 0d75d01c84ace637b903259c32d71699e8e1ef46 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Mon, 9 Apr 2018 17:38:59 +0300 Subject: [PATCH 07/25] SecretStore: get rid of engine.signer dependency (#8173) * SecretStore: get rid of engine.signer dependency * SecretStore: fixed self for transact_contract * SecretStore: fixed pending requests + 1-of-1 sessions completion * SecretStore: fixed completion signal in 1-of-1 case * fixed test(s) * removed obsolete TODO && redundant statement * ok_or -> ok_or_else --- Cargo.lock | 1 + parity/run.rs | 1 + parity/secretstore.rs | 5 +- secret_store/Cargo.toml | 1 + secret_store/src/acl_storage.rs | 2 +- .../client_sessions/generation_session.rs | 7 +- .../signing_session_schnorr.rs | 2 +- .../src/key_server_cluster/cluster.rs | 79 ++++++++----------- secret_store/src/key_server_set.rs | 8 +- secret_store/src/lib.rs | 6 +- secret_store/src/listener/service_contract.rs | 2 +- .../src/listener/service_contract_listener.rs | 4 +- secret_store/src/trusted_client.rs | 36 ++++++++- 13 files changed, 94 insertions(+), 60 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 80bdcf34978..d6f38caa406 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -766,6 +766,7 @@ dependencies = [ "ethcore 1.11.0", "ethcore-bytes 0.1.0", "ethcore-logger 1.11.0", + "ethcore-transaction 0.1.0", "ethcrypto 0.1.0", "ethereum-types 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethkey 0.3.0", diff --git a/parity/run.rs b/parity/run.rs index fbc24a90d74..9d43801ac06 100644 --- a/parity/run.rs +++ b/parity/run.rs @@ -843,6 +843,7 @@ fn execute_impl(cmd: RunCmd, logger: Arc, on_client_rq: let secretstore_deps = secretstore::Dependencies { client: client.clone(), sync: sync_provider.clone(), + miner: miner, account_provider: account_provider, accounts_passwords: &passwords, }; diff --git a/parity/secretstore.rs b/parity/secretstore.rs index 797f8673b11..8e9f5fef5a0 100644 --- a/parity/secretstore.rs +++ b/parity/secretstore.rs @@ -20,6 +20,7 @@ use dir::default_data_path; use dir::helpers::replace_home; use ethcore::account_provider::AccountProvider; use ethcore::client::Client; +use ethcore::miner::Miner; use ethkey::{Secret, Public}; use ethsync::SyncProvider; use ethereum_types::Address; @@ -87,6 +88,8 @@ pub struct Dependencies<'a> { pub client: Arc, /// Sync provider. pub sync: Arc, + /// Miner service. + pub miner: Arc, /// Account provider. pub account_provider: Arc, /// Passed accounts passwords. @@ -190,7 +193,7 @@ mod server { cconf.cluster_config.nodes.insert(self_secret.public().clone(), cconf.cluster_config.listener_address.clone()); - let key_server = ethcore_secretstore::start(deps.client, deps.sync, self_secret, cconf) + let key_server = ethcore_secretstore::start(deps.client, deps.sync, deps.miner, self_secret, cconf) .map_err(|e| format!("Error starting KeyServer {}: {}", key_server_name, e))?; Ok(KeyServer { diff --git a/secret_store/Cargo.toml b/secret_store/Cargo.toml index 3b60a3c6c58..d894bb4efd0 100644 --- a/secret_store/Cargo.toml +++ b/secret_store/Cargo.toml @@ -24,6 +24,7 @@ tokio-proto = "0.1" url = "1.0" ethcore = { path = "../ethcore" } ethcore-bytes = { path = "../util/bytes" } +ethcore-transaction = { path = "../ethcore/transaction" } ethereum-types = "0.3" ethsync = { path = "../sync" } kvdb = { path = "../util/kvdb" } diff --git a/secret_store/src/acl_storage.rs b/secret_store/src/acl_storage.rs index 0ff8a2f3070..58d9bc47756 100644 --- a/secret_store/src/acl_storage.rs +++ b/secret_store/src/acl_storage.rs @@ -62,7 +62,7 @@ impl OnChainAclStorage { contract: Mutex::new(CachedContract::new(trusted_client)), }); client - .ok_or(Error::Internal("Constructing OnChainAclStorage without active Client".into()))? + .ok_or_else(|| Error::Internal("Constructing OnChainAclStorage without active Client".into()))? .add_notify(acl_storage.clone()); Ok(acl_storage) } 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 2c0cbe2b1e4..0afe618246d 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 @@ -326,7 +326,12 @@ impl SessionImpl { self.complete_initialization(derived_point)?; self.disseminate_keys()?; self.verify_keys()?; - self.complete_generation() + self.complete_generation()?; + + self.data.lock().state = SessionState::Finished; + self.completed.notify_all(); + + Ok(()) } } } 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 b4041da53fd..ed7164ca3a9 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 @@ -280,7 +280,7 @@ impl SessionImpl { }); generation_session.initialize(Default::default(), Default::default(), false, 0, vec![self.core.meta.self_node_id.clone()].into_iter().collect::>().into())?; - debug_assert_eq!(generation_session.state(), GenerationSessionState::WaitingForGenerationConfirmation); + debug_assert_eq!(generation_session.state(), GenerationSessionState::Finished); let joint_public_and_secret = generation_session .joint_public_and_secret() .expect("session key is generated before signature is computed; we are in SignatureComputing state; qed")?; diff --git a/secret_store/src/key_server_cluster/cluster.rs b/secret_store/src/key_server_cluster/cluster.rs index c90474fa63e..26f0e7ef1fa 100644 --- a/secret_store/src/key_server_cluster/cluster.rs +++ b/secret_store/src/key_server_cluster/cluster.rs @@ -896,6 +896,20 @@ impl ClusterClientImpl { } } } + + fn process_initialization_result, D>(result: Result<(), Error>, session: Arc, sessions: &ClusterSessionsContainer) -> Result, Error> { + match result { + Ok(()) if session.is_finished() => { + sessions.remove(&session.id()); + Ok(session) + }, + Ok(()) => Ok(session), + Err(error) => { + sessions.remove(&session.id()); + Err(error) + }, + } + } } impl ClusterClient for ClusterClientImpl { @@ -909,13 +923,9 @@ impl ClusterClient for ClusterClientImpl { let cluster = create_cluster_view(&self.data, true)?; let session = self.data.sessions.generation_sessions.insert(cluster, self.data.self_key_pair.public().clone(), session_id, None, false, None)?; - match session.initialize(origin, author, false, threshold, connected_nodes.into()) { - Ok(()) => Ok(session), - Err(error) => { - self.data.sessions.generation_sessions.remove(&session.id()); - Err(error) - }, - } + Self::process_initialization_result( + session.initialize(origin, author, false, threshold, connected_nodes.into()), + session, &self.data.sessions.generation_sessions) } fn new_encryption_session(&self, session_id: SessionId, requester: Requester, common_point: Public, encrypted_point: Public) -> Result, Error> { @@ -924,13 +934,9 @@ impl ClusterClient for ClusterClientImpl { let cluster = create_cluster_view(&self.data, true)?; let session = self.data.sessions.encryption_sessions.insert(cluster, self.data.self_key_pair.public().clone(), session_id, None, false, None)?; - match session.initialize(requester, common_point, encrypted_point) { - Ok(()) => Ok(session), - Err(error) => { - self.data.sessions.encryption_sessions.remove(&session.id()); - Err(error) - }, - } + Self::process_initialization_result( + session.initialize(requester, common_point, encrypted_point), + session, &self.data.sessions.encryption_sessions) } fn new_decryption_session(&self, session_id: SessionId, origin: Option

, requester: Requester, version: Option, is_shadow_decryption: bool, is_broadcast_decryption: bool) -> Result, Error> { @@ -954,13 +960,9 @@ impl ClusterClient for ClusterClientImpl { }, }; - match initialization_result { - Ok(()) => Ok(session), - Err(error) => { - self.data.sessions.decryption_sessions.remove(&session.id()); - Err(error) - }, - } + Self::process_initialization_result( + initialization_result, + session, &self.data.sessions.decryption_sessions) } fn new_schnorr_signing_session(&self, session_id: SessionId, requester: Requester, version: Option, message_hash: H256) -> Result, Error> { @@ -983,13 +985,9 @@ impl ClusterClient for ClusterClientImpl { }, }; - match initialization_result { - Ok(()) => Ok(session), - Err(error) => { - self.data.sessions.schnorr_signing_sessions.remove(&session.id()); - Err(error) - }, - } + Self::process_initialization_result( + initialization_result, + session, &self.data.sessions.schnorr_signing_sessions) } fn new_ecdsa_signing_session(&self, session_id: SessionId, requester: Requester, version: Option, message_hash: H256) -> Result, Error> { @@ -1012,13 +1010,9 @@ impl ClusterClient for ClusterClientImpl { }, }; - match initialization_result { - Ok(()) => Ok(session), - Err(error) => { - self.data.sessions.ecdsa_signing_sessions.remove(&session.id()); - Err(error) - }, - } + Self::process_initialization_result( + initialization_result, + session, &self.data.sessions.ecdsa_signing_sessions) } fn new_key_version_negotiation_session(&self, session_id: SessionId) -> Result>, Error> { @@ -1042,16 +1036,13 @@ impl ClusterClient for ClusterClientImpl { let initialization_result = session.as_servers_set_change().expect("servers set change session is created; qed") .initialize(new_nodes_set, old_set_signature, new_set_signature); - match initialization_result { - Ok(()) => { - self.data.connections.servers_set_change_creator_connector().set_key_servers_set_change_session(session.clone()); - Ok(session) - }, - Err(error) => { - self.data.sessions.admin_sessions.remove(&session.id()); - Err(error) - }, + if initialization_result.is_ok() { + self.data.connections.servers_set_change_creator_connector().set_key_servers_set_change_session(session.clone()); } + + Self::process_initialization_result( + initialization_result, + session, &self.data.sessions.admin_sessions) } fn add_generation_listener(&self, listener: Arc>) { diff --git a/secret_store/src/key_server_set.rs b/secret_store/src/key_server_set.rs index 899709a7d5c..7697408557e 100644 --- a/secret_store/src/key_server_set.rs +++ b/secret_store/src/key_server_set.rs @@ -141,7 +141,7 @@ impl OnChainKeyServerSet { contract: Mutex::new(CachedContract::new(trusted_client, self_key_pair, auto_migrate_enabled, key_servers)?), }); client - .ok_or(Error::Internal("Constructing OnChainKeyServerSet without active Client".into()))? + .ok_or_else(|| Error::Internal("Constructing OnChainKeyServerSet without active Client".into()))? .add_notify(key_server_set.clone()); Ok(key_server_set) } @@ -292,7 +292,7 @@ impl CachedContract { let transaction_data = self.contract.functions().start_migration().input(migration_id); // send transaction - if let Err(error) = client.transact_contract(*contract_address, transaction_data) { + if let Err(error) = self.client.transact_contract(*contract_address, transaction_data) { warn!(target: "secretstore_net", "{}: failed to submit auto-migration start transaction: {}", self.self_key_pair.public(), error); } else { @@ -314,7 +314,7 @@ impl CachedContract { let transaction_data = self.contract.functions().confirm_migration().input(migration_id); // send transaction - if let Err(error) = client.transact_contract(contract_address, transaction_data) { + if let Err(error) = self.client.transact_contract(contract_address, transaction_data) { warn!(target: "secretstore_net", "{}: failed to submit auto-migration confirmation transaction: {}", self.self_key_pair.public(), error); } else { @@ -551,7 +551,6 @@ 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 { - // TODO [Reliability]: add the same mechanism to the contract listener, if accepted let last_block = client.block_number(BlockId::Latest).unwrap_or_default(); match previous_transaction.as_ref() { // no previous transaction => send immideately @@ -565,7 +564,6 @@ fn update_last_transaction_block(client: &Client, migration_id: &H256, previous_ // or the transaction has been removed from the queue (and never reached any miner node) // if we have restarted after sending tx => assume we have never sent it Some(tx) => { - let last_block = client.block_number(BlockId::Latest).unwrap_or_default(); if tx.block > last_block || last_block - tx.block < TRANSACTION_RETRY_INTERVAL_BLOCKS { return false; } diff --git a/secret_store/src/lib.rs b/secret_store/src/lib.rs index f08a26a907a..d58e37ffe79 100644 --- a/secret_store/src/lib.rs +++ b/secret_store/src/lib.rs @@ -19,6 +19,7 @@ extern crate ethabi; extern crate ethcore; extern crate ethcore_bytes as bytes; extern crate ethcore_logger as logger; +extern crate ethcore_transaction as transaction; extern crate ethcrypto; extern crate ethereum_types; extern crate ethkey; @@ -68,6 +69,7 @@ mod trusted_client; use std::sync::Arc; use ethcore::client::Client; +use ethcore::miner::Miner; use ethsync::SyncProvider; pub use types::all::{ServerKeyId, EncryptedDocumentKey, RequestSignature, Public, @@ -76,8 +78,8 @@ pub use traits::{NodeKeyPair, KeyServer}; pub use self::node_key_pair::{PlainNodeKeyPair, KeyStoreNodeKeyPair}; /// Start new key server instance -pub fn start(client: Arc, sync: Arc, self_key_pair: Arc, config: ServiceConfiguration) -> Result, Error> { - let trusted_client = trusted_client::TrustedClient::new(client.clone(), sync); +pub fn start(client: Arc, sync: Arc, miner: Arc, self_key_pair: Arc, config: ServiceConfiguration) -> Result, Error> { + let trusted_client = trusted_client::TrustedClient::new(self_key_pair.clone(), client.clone(), sync, miner); let acl_storage: Arc = if config.acl_check_enabled { acl_storage::OnChainAclStorage::new(trusted_client.clone())? } else { diff --git a/secret_store/src/listener/service_contract.rs b/secret_store/src/listener/service_contract.rs index 4d6ac14c81e..eac3cfa9dad 100644 --- a/secret_store/src/listener/service_contract.rs +++ b/secret_store/src/listener/service_contract.rs @@ -188,7 +188,7 @@ impl OnChainServiceContract { let transaction_data = prepare_tx(&*client, origin, &self.contract)?; // send transaction - client.transact_contract( + self.client.transact_contract( origin.clone(), transaction_data ).map_err(|e| format!("{}", e))?; diff --git a/secret_store/src/listener/service_contract_listener.rs b/secret_store/src/listener/service_contract_listener.rs index 8776dc218e9..2975eaa134c 100644 --- a/secret_store/src/listener/service_contract_listener.rs +++ b/secret_store/src/listener/service_contract_listener.rs @@ -268,9 +268,9 @@ impl ServiceContractListener { let pending_tasks = data.contract.read_pending_requests() .filter_map(|(is_confirmed, task)| Self::filter_task(data, task) .map(|t| (is_confirmed, t))); - for (is_confirmed, task) in pending_tasks { + for (is_response_required, task) in pending_tasks { // only process requests, which we haven't confirmed yet - if is_confirmed { + if !is_response_required { continue; } diff --git a/secret_store/src/trusted_client.rs b/secret_store/src/trusted_client.rs index 8a0f83d44f3..e40961e0443 100644 --- a/secret_store/src/trusted_client.rs +++ b/secret_store/src/trusted_client.rs @@ -15,24 +15,35 @@ // along with Parity. If not, see . use std::sync::{Arc, Weak}; -use ethcore::client::{Client, BlockChainClient, ChainInfo}; +use bytes::Bytes; +use ethereum_types::Address; +use ethcore::client::{Client, BlockChainClient, ChainInfo, Nonce}; +use ethcore::miner::{Miner, MinerService}; use ethsync::SyncProvider; +use transaction::{Transaction, SignedTransaction, Action}; +use {Error, NodeKeyPair}; #[derive(Clone)] /// 'Trusted' client weak reference. pub struct TrustedClient { + /// This key server node key pair. + self_key_pair: Arc, /// Blockchain client. client: Weak, /// Sync provider. sync: Weak, + /// Miner service. + miner: Weak, } impl TrustedClient { /// Create new trusted client. - pub fn new(client: Arc, sync: Arc) -> Self { + pub fn new(self_key_pair: Arc, client: Arc, sync: Arc, miner: Arc) -> Self { TrustedClient { + self_key_pair: self_key_pair, client: Arc::downgrade(&client), sync: Arc::downgrade(&sync), + miner: Arc::downgrade(&miner), } } @@ -54,4 +65,25 @@ impl TrustedClient { pub fn get_untrusted(&self) -> Option> { self.client.upgrade() } + + /// Transact contract. + pub fn transact_contract(&self, contract: Address, tx_data: Bytes) -> Result<(), Error> { + let client = self.client.upgrade().ok_or_else(|| Error::Internal("cannot submit tx when client is offline".into()))?; + let miner = self.miner.upgrade().ok_or_else(|| Error::Internal("cannot submit tx when miner is offline".into()))?; + let engine = client.engine(); + let transaction = Transaction { + nonce: client.latest_nonce(&self.self_key_pair.address()), + action: Action::Call(contract), + gas: miner.gas_floor_target(), + gas_price: miner.sensible_gas_price(), + value: Default::default(), + data: tx_data, + }; + let chain_id = engine.signing_chain_id(&client.latest_env_info()); + let signature = self.self_key_pair.sign(&transaction.hash(chain_id))?; + let signed = SignedTransaction::new(transaction.with_signature(signature, chain_id))?; + miner.import_own_transaction(&*client, signed.into()) + .map_err(|e| Error::Internal(format!("failed to import tx: {}", e))) + .map(|_| ()) + } } From 8e7a08f865715c964dc3dd83d211c2beddb3539f Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Tue, 10 Apr 2018 10:13:42 +0200 Subject: [PATCH 08/25] ethcore-stratum crate moved to ethcore directory (#8338) --- Cargo.toml | 2 +- ethcore/Cargo.toml | 2 +- {stratum => ethcore/stratum}/Cargo.toml | 5 ++--- {stratum => ethcore/stratum}/src/lib.rs | 17 ++++++++--------- {stratum => ethcore/stratum}/src/traits.rs | 0 5 files changed, 12 insertions(+), 14 deletions(-) rename {stratum => ethcore/stratum}/Cargo.toml (83%) rename {stratum => ethcore/stratum}/src/lib.rs (96%) rename {stratum => ethcore/stratum}/src/traits.rs (100%) diff --git a/Cargo.toml b/Cargo.toml index bb92fff358f..34d347d4533 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -44,7 +44,7 @@ ethcore-miner = { path = "miner" } ethcore-network = { path = "util/network" } ethcore-private-tx = { path = "ethcore/private-tx" } ethcore-service = { path = "ethcore/service" } -ethcore-stratum = { path = "stratum" } +ethcore-stratum = { path = "ethcore/stratum" } ethcore-transaction = { path = "ethcore/transaction" } ethereum-types = "0.3" node-filter = { path = "ethcore/node_filter" } diff --git a/ethcore/Cargo.toml b/ethcore/Cargo.toml index c028f8e6b05..0ffb7034a35 100644 --- a/ethcore/Cargo.toml +++ b/ethcore/Cargo.toml @@ -23,7 +23,7 @@ patricia-trie = { path = "../util/patricia_trie" } ethcore-io = { path = "../util/io" } ethcore-logger = { path = "../logger" } ethcore-miner = { path = "../miner" } -ethcore-stratum = { path = "../stratum" } +ethcore-stratum = { path = "./stratum" } ethcore-transaction = { path = "./transaction" } ethereum-types = "0.3" memory-cache = { path = "../util/memory_cache" } diff --git a/stratum/Cargo.toml b/ethcore/stratum/Cargo.toml similarity index 83% rename from stratum/Cargo.toml rename to ethcore/stratum/Cargo.toml index 5f66cfd49c8..de65a470c66 100644 --- a/stratum/Cargo.toml +++ b/ethcore/stratum/Cargo.toml @@ -6,9 +6,8 @@ license = "GPL-3.0" authors = ["Parity Technologies "] [dependencies] -ethcore-logger = { path = "../logger" } ethereum-types = "0.3" -keccak-hash = { path = "../util/hash" } +keccak-hash = { path = "../../util/hash" } 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" } jsonrpc-tcp-server = { git = "https://github.com/paritytech/jsonrpc.git", branch = "parity-1.11" } @@ -19,4 +18,4 @@ parking_lot = "0.5" env_logger = "0.4" tokio-core = "0.1" tokio-io = "0.1" -ethcore-logger = { path = "../logger" } +ethcore-logger = { path = "../../logger" } diff --git a/stratum/src/lib.rs b/ethcore/stratum/src/lib.rs similarity index 96% rename from stratum/src/lib.rs rename to ethcore/stratum/src/lib.rs index d43bcc5569e..a4abeffd73e 100644 --- a/stratum/src/lib.rs +++ b/ethcore/stratum/src/lib.rs @@ -77,10 +77,10 @@ impl Stratum { ) -> Result, Error> { let implementation = Arc::new(StratumImpl { - subscribers: RwLock::new(Vec::new()), - job_que: RwLock::new(HashSet::new()), + subscribers: RwLock::default(), + job_que: RwLock::default(), dispatcher, - workers: Arc::new(RwLock::new(HashMap::new())), + workers: Arc::new(RwLock::default()), secret, notify_counter: RwLock::new(NOTIFY_COUNTER_INITIAL), }); @@ -323,7 +323,6 @@ impl MetaExtractor for PeerMetaExtractor { #[cfg(test)] mod tests { use super::*; - use std::str::FromStr; use std::net::SocketAddr; use std::sync::Arc; @@ -366,7 +365,7 @@ mod tests { #[test] fn can_be_started() { - let stratum = Stratum::start(&SocketAddr::from_str("127.0.0.1:19980").unwrap(), Arc::new(VoidManager), None); + let stratum = Stratum::start(&"127.0.0.1:19980".parse().unwrap(), Arc::new(VoidManager), None); assert!(stratum.is_ok()); } @@ -374,7 +373,7 @@ mod tests { fn records_subscriber() { init_log(); - let addr = SocketAddr::from_str("127.0.0.1:19985").unwrap(); + let addr = "127.0.0.1:19985".parse().unwrap(); let stratum = Stratum::start(&addr, Arc::new(VoidManager), None).unwrap(); let request = r#"{"jsonrpc": "2.0", "method": "mining.subscribe", "params": [], "id": 1}"#; dummy_request(&addr, request); @@ -419,7 +418,7 @@ mod tests { #[test] fn receives_initial_paylaod() { - let addr = SocketAddr::from_str("127.0.0.1:19975").unwrap(); + let addr = "127.0.0.1:19975".parse().unwrap(); let _stratum = Stratum::start(&addr, DummyManager::new(), None).expect("There should be no error starting stratum"); let request = r#"{"jsonrpc": "2.0", "method": "mining.subscribe", "params": [], "id": 2}"#; @@ -430,7 +429,7 @@ mod tests { #[test] fn can_authorize() { - let addr = SocketAddr::from_str("127.0.0.1:19970").unwrap(); + let addr = "127.0.0.1:19970".parse().unwrap(); let stratum = Stratum::start( &addr, Arc::new(DummyManager::build().of_initial(r#"["dummy autorize payload"]"#)), @@ -448,7 +447,7 @@ mod tests { fn can_push_work() { init_log(); - let addr = SocketAddr::from_str("127.0.0.1:19995").unwrap(); + let addr = "127.0.0.1:19995".parse().unwrap(); let stratum = Stratum::start( &addr, Arc::new(DummyManager::build().of_initial(r#"["dummy autorize payload"]"#)), diff --git a/stratum/src/traits.rs b/ethcore/stratum/src/traits.rs similarity index 100% rename from stratum/src/traits.rs rename to ethcore/stratum/src/traits.rs From d1487b31770fdd511bb5d9a539f014ff41d8ea85 Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Tue, 10 Apr 2018 16:36:14 +0800 Subject: [PATCH 09/25] rpc, eth_filter: return error if the filter id does not exist (#8341) --- rpc/src/v1/helpers/errors.rs | 8 ++++++++ rpc/src/v1/impls/eth_filter.rs | 7 ++++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/rpc/src/v1/helpers/errors.rs b/rpc/src/v1/helpers/errors.rs index e86ab630f57..6e8836c20d4 100644 --- a/rpc/src/v1/helpers/errors.rs +++ b/rpc/src/v1/helpers/errors.rs @@ -399,6 +399,14 @@ pub fn deprecated>>(message: T) -> Error { } } +pub fn filter_not_found() -> Error { + Error { + code: ErrorCode::ServerError(codes::UNSUPPORTED_REQUEST), + message: "Filter not found".into(), + data: None, + } +} + // on-demand sender cancelled. pub fn on_demand_cancel(_cancel: futures::sync::oneshot::Canceled) -> Error { internal("on-demand sender cancelled", "") diff --git a/rpc/src/v1/impls/eth_filter.rs b/rpc/src/v1/impls/eth_filter.rs index 6c3d6837ebd..9e2f2f88874 100644 --- a/rpc/src/v1/impls/eth_filter.rs +++ b/rpc/src/v1/impls/eth_filter.rs @@ -30,7 +30,7 @@ use jsonrpc_core::futures::{future, Future}; use jsonrpc_core::futures::future::Either; use v1::traits::EthFilter; use v1::types::{BlockNumber, Index, Filter, FilterChanges, Log, H256 as RpcH256, U256 as RpcU256}; -use v1::helpers::{PollFilter, PollManager, limit_logs}; +use v1::helpers::{errors, PollFilter, PollManager, limit_logs}; use v1::impls::eth::pending_logs; /// Something which provides data that can be filtered over. @@ -127,7 +127,7 @@ impl EthFilter for T { fn filter_changes(&self, index: Index) -> BoxFuture { let mut polls = self.polls().lock(); Box::new(match polls.poll_mut(&index.value()) { - None => Either::A(future::ok(FilterChanges::Empty)), + None => Either::A(future::err(errors::filter_not_found())), Some(filter) => match *filter { PollFilter::Block(ref mut block_number) => { // +1, cause we want to return hashes including current block hash. @@ -217,7 +217,8 @@ impl EthFilter for T { match polls.poll(&index.value()) { Some(&PollFilter::Logs(ref _block_number, ref _previous_log, ref filter)) => filter.clone(), // just empty array - _ => return Box::new(future::ok(Vec::new())), + Some(_) => return Box::new(future::ok(Vec::new())), + None => return Box::new(future::err(errors::filter_not_found())), } }; From 86446d713a9b379e0eddf32402182c387ddc3748 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Tue, 10 Apr 2018 12:13:49 +0200 Subject: [PATCH 10/25] ethcore-sync (#8347) --- Cargo.lock | 72 +++++++++---------- Cargo.toml | 2 +- ethcore/service/Cargo.toml | 2 +- ethcore/service/src/lib.rs | 4 +- ethcore/service/src/service.rs | 2 +- ethcore/sync/Cargo.toml | 37 ++++++++++ {sync => ethcore/sync}/src/api.rs | 0 {sync => ethcore/sync}/src/block_sync.rs | 0 {sync => ethcore/sync}/src/blocks.rs | 0 {sync => ethcore/sync}/src/chain.rs | 0 {sync => ethcore/sync}/src/lib.rs | 0 {sync => ethcore/sync}/src/light_sync/mod.rs | 0 .../sync}/src/light_sync/response.rs | 0 .../sync}/src/light_sync/sync_round.rs | 0 .../sync}/src/light_sync/tests/mod.rs | 0 .../sync}/src/light_sync/tests/test_net.rs | 0 {sync => ethcore/sync}/src/private_tx.rs | 0 {sync => ethcore/sync}/src/snapshot.rs | 0 {sync => ethcore/sync}/src/sync_io.rs | 0 {sync => ethcore/sync}/src/tests/chain.rs | 0 {sync => ethcore/sync}/src/tests/consensus.rs | 0 {sync => ethcore/sync}/src/tests/helpers.rs | 0 {sync => ethcore/sync}/src/tests/mod.rs | 0 {sync => ethcore/sync}/src/tests/rpc.rs | 0 {sync => ethcore/sync}/src/tests/snapshot.rs | 0 .../sync}/src/transactions_stats.rs | 0 parity/configuration.rs | 4 +- parity/dapps.rs | 2 +- parity/helpers.rs | 8 +-- parity/informant.rs | 2 +- parity/light_helpers/epoch_fetch.rs | 2 +- parity/light_helpers/queue_cull.rs | 2 +- parity/main.rs | 2 +- parity/modules.rs | 6 +- parity/rpc_apis.rs | 2 +- parity/run.rs | 20 +++--- parity/secretstore.rs | 2 +- parity/whisper.rs | 2 +- rpc/Cargo.toml | 2 +- rpc/src/lib.rs | 6 +- rpc/src/v1/helpers/block_import.rs | 4 +- rpc/src/v1/helpers/dispatch.rs | 2 +- rpc/src/v1/helpers/light_fetch.rs | 2 +- rpc/src/v1/impls/eth.rs | 2 +- rpc/src/v1/impls/eth_pubsub.rs | 2 +- rpc/src/v1/impls/light/eth.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/net.rs | 2 +- rpc/src/v1/impls/parity.rs | 2 +- rpc/src/v1/impls/parity_set.rs | 2 +- rpc/src/v1/tests/helpers/sync_provider.rs | 2 +- rpc/src/v1/tests/mocked/eth.rs | 2 +- rpc/src/v1/tests/mocked/manage_network.rs | 2 +- rpc/src/v1/tests/mocked/parity.rs | 2 +- rpc/src/v1/tests/mocked/parity_set.rs | 2 +- rpc/src/v1/types/sync.rs | 10 +-- secret_store/Cargo.toml | 2 +- secret_store/src/lib.rs | 4 +- secret_store/src/trusted_client.rs | 2 +- sync/Cargo.toml | 37 ---------- updater/Cargo.toml | 2 +- updater/src/lib.rs | 2 +- updater/src/updater.rs | 2 +- 65 files changed, 139 insertions(+), 139 deletions(-) create mode 100644 ethcore/sync/Cargo.toml rename {sync => ethcore/sync}/src/api.rs (100%) rename {sync => ethcore/sync}/src/block_sync.rs (100%) rename {sync => ethcore/sync}/src/blocks.rs (100%) rename {sync => ethcore/sync}/src/chain.rs (100%) rename {sync => ethcore/sync}/src/lib.rs (100%) rename {sync => ethcore/sync}/src/light_sync/mod.rs (100%) rename {sync => ethcore/sync}/src/light_sync/response.rs (100%) rename {sync => ethcore/sync}/src/light_sync/sync_round.rs (100%) rename {sync => ethcore/sync}/src/light_sync/tests/mod.rs (100%) rename {sync => ethcore/sync}/src/light_sync/tests/test_net.rs (100%) rename {sync => ethcore/sync}/src/private_tx.rs (100%) rename {sync => ethcore/sync}/src/snapshot.rs (100%) rename {sync => ethcore/sync}/src/sync_io.rs (100%) rename {sync => ethcore/sync}/src/tests/chain.rs (100%) rename {sync => ethcore/sync}/src/tests/consensus.rs (100%) rename {sync => ethcore/sync}/src/tests/helpers.rs (100%) rename {sync => ethcore/sync}/src/tests/mod.rs (100%) rename {sync => ethcore/sync}/src/tests/rpc.rs (100%) rename {sync => ethcore/sync}/src/tests/snapshot.rs (100%) rename {sync => ethcore/sync}/src/transactions_stats.rs (100%) delete mode 100644 sync/Cargo.toml diff --git a/Cargo.lock b/Cargo.lock index d6f38caa406..275c224f362 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -766,11 +766,11 @@ dependencies = [ "ethcore 1.11.0", "ethcore-bytes 0.1.0", "ethcore-logger 1.11.0", + "ethcore-sync 1.11.0", "ethcore-transaction 0.1.0", "ethcrypto 0.1.0", "ethereum-types 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethkey 0.3.0", - "ethsync 1.11.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)", "hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)", @@ -802,7 +802,7 @@ dependencies = [ "ethcore 1.11.0", "ethcore-io 1.11.0", "ethcore-private-tx 1.0.0", - "ethsync 1.11.0", + "ethcore-sync 1.11.0", "kvdb 0.1.0", "kvdb-rocksdb 0.1.0", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -827,6 +827,37 @@ dependencies = [ "tokio-io 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "ethcore-sync" +version = "1.11.0" +dependencies = [ + "env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "ethcore 1.11.0", + "ethcore-bytes 0.1.0", + "ethcore-io 1.11.0", + "ethcore-light 1.11.0", + "ethcore-network 1.11.0", + "ethcore-network-devp2p 1.11.0", + "ethcore-transaction 0.1.0", + "ethereum-types 0.3.0 (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)", + "keccak-hash 0.1.0", + "kvdb 0.1.0", + "kvdb-memorydb 0.1.0", + "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "macros 0.1.0", + "parking_lot 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", + "plain_hasher 0.1.0", + "rand 0.4.2 (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)", + "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)", + "triehash 0.1.0", +] + [[package]] name = "ethcore-transaction" version = "0.1.0" @@ -962,37 +993,6 @@ dependencies = [ "tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "ethsync" -version = "1.11.0" -dependencies = [ - "env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "ethcore 1.11.0", - "ethcore-bytes 0.1.0", - "ethcore-io 1.11.0", - "ethcore-light 1.11.0", - "ethcore-network 1.11.0", - "ethcore-network-devp2p 1.11.0", - "ethcore-transaction 0.1.0", - "ethereum-types 0.3.0 (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)", - "keccak-hash 0.1.0", - "kvdb 0.1.0", - "kvdb-memorydb 0.1.0", - "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "macros 0.1.0", - "parking_lot 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", - "plain_hasher 0.1.0", - "rand 0.4.2 (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)", - "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)", - "triehash 0.1.0", -] - [[package]] name = "evm" version = "0.1.0" @@ -1983,10 +1983,10 @@ dependencies = [ "ethcore-secretstore 1.0.0", "ethcore-service 0.1.0", "ethcore-stratum 1.11.0", + "ethcore-sync 1.11.0", "ethcore-transaction 0.1.0", "ethereum-types 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethkey 0.3.0", - "ethsync 1.11.0", "fdlimit 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "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)", @@ -2187,13 +2187,13 @@ dependencies = [ "ethcore-miner 1.11.0", "ethcore-network 1.11.0", "ethcore-private-tx 1.0.0", + "ethcore-sync 1.11.0", "ethcore-transaction 0.1.0", "ethcrypto 0.1.0", "ethereum-types 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethjson 0.1.0", "ethkey 0.3.0", "ethstore 0.2.0", - "ethsync 1.11.0", "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)", @@ -2320,8 +2320,8 @@ dependencies = [ "ethabi-derive 5.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore 1.11.0", "ethcore-bytes 0.1.0", + "ethcore-sync 1.11.0", "ethereum-types 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "ethsync 1.11.0", "keccak-hash 0.1.0", "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)", diff --git a/Cargo.toml b/Cargo.toml index 34d347d4533..09c00b3386b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,7 +33,6 @@ fdlimit = "0.1" ws2_32-sys = "0.2" ctrlc = { git = "https://github.com/paritytech/rust-ctrlc.git" } jsonrpc-core = { git = "https://github.com/paritytech/jsonrpc.git", branch = "parity-1.11" } -ethsync = { path = "sync" } ethcore = { path = "ethcore" } ethcore-bytes = { path = "util/bytes" } ethcore-io = { path = "util/io" } @@ -45,6 +44,7 @@ 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" node-filter = { path = "ethcore/node_filter" } diff --git a/ethcore/service/Cargo.toml b/ethcore/service/Cargo.toml index 608d591e09b..b612baf5660 100644 --- a/ethcore/service/Cargo.toml +++ b/ethcore/service/Cargo.toml @@ -9,7 +9,7 @@ error-chain = { version = "0.11", default-features = false } ethcore = { path = ".." } ethcore-io = { path = "../../util/io" } ethcore-private-tx = { path = "../private-tx" } -ethsync = { path = "../../sync" } +ethcore-sync = { path = "../sync" } kvdb = { path = "../../util/kvdb" } log = "0.3" stop-guard = { path = "../../util/stop-guard" } diff --git a/ethcore/service/src/lib.rs b/ethcore/service/src/lib.rs index 5bd1c39de5f..1604e84b10a 100644 --- a/ethcore/service/src/lib.rs +++ b/ethcore/service/src/lib.rs @@ -17,9 +17,9 @@ extern crate ansi_term; extern crate ethcore; extern crate ethcore_io as io; -extern crate ethsync; -extern crate kvdb; extern crate ethcore_private_tx; +extern crate ethcore_sync as sync; +extern crate kvdb; extern crate stop_guard; #[macro_use] diff --git a/ethcore/service/src/service.rs b/ethcore/service/src/service.rs index 27f58b42151..8fab545574c 100644 --- a/ethcore/service/src/service.rs +++ b/ethcore/service/src/service.rs @@ -24,7 +24,7 @@ use io::{IoContext, TimerToken, IoHandler, IoService, IoError}; use kvdb::{KeyValueDB, KeyValueDBHandler}; use stop_guard::StopGuard; -use ethsync::PrivateTxHandler; +use sync::PrivateTxHandler; use ethcore::client::{Client, ClientConfig, ChainNotify, ClientIoMessage}; use ethcore::miner::Miner; use ethcore::snapshot::service::{Service as SnapshotService, ServiceParams as SnapServiceParams}; diff --git a/ethcore/sync/Cargo.toml b/ethcore/sync/Cargo.toml new file mode 100644 index 00000000000..a09f161e2a9 --- /dev/null +++ b/ethcore/sync/Cargo.toml @@ -0,0 +1,37 @@ +[package] +description = "Ethcore blockchain sync" +name = "ethcore-sync" +version = "1.11.0" +license = "GPL-3.0" +authors = ["Parity Technologies "] + +[lib] + +[dependencies] +ethcore-bytes = { path = "../../util/bytes" } +ethcore-network = { path = "../../util/network" } +ethcore-network-devp2p = { path = "../../util/network-devp2p" } +ethcore-io = { path = "../../util/io" } +ethcore-light = { path = "../light" } +ethcore-transaction = { path = "../transaction" } +ethcore = { path = ".." } +ethereum-types = "0.3" +plain_hasher = { path = "../../util/plain_hasher" } +rlp = { path = "../../util/rlp" } +rustc-hex = "1.0" +keccak-hash = { path = "../../util/hash" } +triehash = { path = "../../util/triehash" } +kvdb = { path = "../../util/kvdb" } +macros = { path = "../../util/macros" } +log = "0.3" +env_logger = "0.4" +rand = "0.4" +heapsize = "0.4" +semver = "0.9" +smallvec = { version = "0.4", features = ["heapsizeof"] } +parking_lot = "0.5" +ipnetwork = "0.12.6" + +[dev-dependencies] +ethkey = { path = "../../ethkey" } +kvdb-memorydb = { path = "../../util/kvdb-memorydb" } diff --git a/sync/src/api.rs b/ethcore/sync/src/api.rs similarity index 100% rename from sync/src/api.rs rename to ethcore/sync/src/api.rs diff --git a/sync/src/block_sync.rs b/ethcore/sync/src/block_sync.rs similarity index 100% rename from sync/src/block_sync.rs rename to ethcore/sync/src/block_sync.rs diff --git a/sync/src/blocks.rs b/ethcore/sync/src/blocks.rs similarity index 100% rename from sync/src/blocks.rs rename to ethcore/sync/src/blocks.rs diff --git a/sync/src/chain.rs b/ethcore/sync/src/chain.rs similarity index 100% rename from sync/src/chain.rs rename to ethcore/sync/src/chain.rs diff --git a/sync/src/lib.rs b/ethcore/sync/src/lib.rs similarity index 100% rename from sync/src/lib.rs rename to ethcore/sync/src/lib.rs diff --git a/sync/src/light_sync/mod.rs b/ethcore/sync/src/light_sync/mod.rs similarity index 100% rename from sync/src/light_sync/mod.rs rename to ethcore/sync/src/light_sync/mod.rs diff --git a/sync/src/light_sync/response.rs b/ethcore/sync/src/light_sync/response.rs similarity index 100% rename from sync/src/light_sync/response.rs rename to ethcore/sync/src/light_sync/response.rs diff --git a/sync/src/light_sync/sync_round.rs b/ethcore/sync/src/light_sync/sync_round.rs similarity index 100% rename from sync/src/light_sync/sync_round.rs rename to ethcore/sync/src/light_sync/sync_round.rs diff --git a/sync/src/light_sync/tests/mod.rs b/ethcore/sync/src/light_sync/tests/mod.rs similarity index 100% rename from sync/src/light_sync/tests/mod.rs rename to ethcore/sync/src/light_sync/tests/mod.rs diff --git a/sync/src/light_sync/tests/test_net.rs b/ethcore/sync/src/light_sync/tests/test_net.rs similarity index 100% rename from sync/src/light_sync/tests/test_net.rs rename to ethcore/sync/src/light_sync/tests/test_net.rs diff --git a/sync/src/private_tx.rs b/ethcore/sync/src/private_tx.rs similarity index 100% rename from sync/src/private_tx.rs rename to ethcore/sync/src/private_tx.rs diff --git a/sync/src/snapshot.rs b/ethcore/sync/src/snapshot.rs similarity index 100% rename from sync/src/snapshot.rs rename to ethcore/sync/src/snapshot.rs diff --git a/sync/src/sync_io.rs b/ethcore/sync/src/sync_io.rs similarity index 100% rename from sync/src/sync_io.rs rename to ethcore/sync/src/sync_io.rs diff --git a/sync/src/tests/chain.rs b/ethcore/sync/src/tests/chain.rs similarity index 100% rename from sync/src/tests/chain.rs rename to ethcore/sync/src/tests/chain.rs diff --git a/sync/src/tests/consensus.rs b/ethcore/sync/src/tests/consensus.rs similarity index 100% rename from sync/src/tests/consensus.rs rename to ethcore/sync/src/tests/consensus.rs diff --git a/sync/src/tests/helpers.rs b/ethcore/sync/src/tests/helpers.rs similarity index 100% rename from sync/src/tests/helpers.rs rename to ethcore/sync/src/tests/helpers.rs diff --git a/sync/src/tests/mod.rs b/ethcore/sync/src/tests/mod.rs similarity index 100% rename from sync/src/tests/mod.rs rename to ethcore/sync/src/tests/mod.rs diff --git a/sync/src/tests/rpc.rs b/ethcore/sync/src/tests/rpc.rs similarity index 100% rename from sync/src/tests/rpc.rs rename to ethcore/sync/src/tests/rpc.rs diff --git a/sync/src/tests/snapshot.rs b/ethcore/sync/src/tests/snapshot.rs similarity index 100% rename from sync/src/tests/snapshot.rs rename to ethcore/sync/src/tests/snapshot.rs diff --git a/sync/src/transactions_stats.rs b/ethcore/sync/src/transactions_stats.rs similarity index 100% rename from sync/src/transactions_stats.rs rename to ethcore/sync/src/transactions_stats.rs diff --git a/parity/configuration.rs b/parity/configuration.rs index 7760fe470a4..3e8f58b6faa 100644 --- a/parity/configuration.rs +++ b/parity/configuration.rs @@ -27,7 +27,7 @@ use ethereum_types::{U256, H256, Address}; use parity_version::{version_data, version}; use bytes::Bytes; use ansi_term::Colour; -use ethsync::{NetworkConfiguration, validate_node_url, self}; +use sync::{NetworkConfiguration, validate_node_url, self}; use ethcore::ethstore::ethkey::{Secret, Public}; use ethcore::client::{VMType}; use ethcore::miner::{MinerOptions, Banning, StratumOptions}; @@ -738,7 +738,7 @@ impl Configuration { for line in &lines { match validate_node_url(line).map(Into::into) { None => continue, - Some(ethsync::ErrorKind::AddressResolve(_)) => return Err(format!("Failed to resolve hostname of a boot node: {}", line)), + Some(sync::ErrorKind::AddressResolve(_)) => return Err(format!("Failed to resolve hostname of a boot node: {}", line)), Some(_) => return Err(format!("Invalid node address format given for a boot node: {}", line)), } } diff --git a/parity/dapps.rs b/parity/dapps.rs index d93ae2db7cc..42ff21b58f9 100644 --- a/parity/dapps.rs +++ b/parity/dapps.rs @@ -21,7 +21,7 @@ use bytes::Bytes; use dir::default_data_path; use dir::helpers::replace_home; use ethcore::client::{Client, BlockChainClient, BlockId, CallContract}; -use ethsync::LightSync; +use sync::LightSync; use futures::{Future, future, IntoFuture}; use futures_cpupool::CpuPool; use hash_fetch::fetch::Client as FetchClient; diff --git a/parity/helpers.rs b/parity/helpers.rs index 1c6c70cdae9..0494be40d8e 100644 --- a/parity/helpers.rs +++ b/parity/helpers.rs @@ -31,7 +31,7 @@ use dir::DatabaseDirectories; use dir::helpers::replace_home; use upgrade::{upgrade, upgrade_data_paths}; use migration::migrate; -use ethsync::{validate_node_url, self}; +use sync::{validate_node_url, self}; use kvdb::{KeyValueDB, KeyValueDBHandler}; use kvdb_rocksdb::{Database, DatabaseConfig, CompactionProfile}; use path; @@ -174,7 +174,7 @@ pub fn to_bootnodes(bootnodes: &Option) -> Result, String> { Some(ref x) if !x.is_empty() => x.split(',').map(|s| { match validate_node_url(s).map(Into::into) { None => Ok(s.to_owned()), - Some(ethsync::ErrorKind::AddressResolve(_)) => Err(format!("Failed to resolve hostname of a boot node: {}", s)), + Some(sync::ErrorKind::AddressResolve(_)) => Err(format!("Failed to resolve hostname of a boot node: {}", s)), Some(_) => Err(format!("Invalid node address format given for a boot node: {}", s)), } }).collect(), @@ -184,8 +184,8 @@ pub fn to_bootnodes(bootnodes: &Option) -> Result, String> { } #[cfg(test)] -pub fn default_network_config() -> ::ethsync::NetworkConfiguration { - use ethsync::{NetworkConfiguration}; +pub fn default_network_config() -> ::sync::NetworkConfiguration { + use sync::{NetworkConfiguration}; use super::network::IpFilter; NetworkConfiguration { config_path: Some(replace_home(&::dir::default_data_path(), "$BASE/network")), diff --git a/parity/informant.rs b/parity/informant.rs index b834b018d6c..2ccc622a708 100644 --- a/parity/informant.rs +++ b/parity/informant.rs @@ -29,7 +29,7 @@ use ethcore::client::{ use ethcore::header::BlockNumber; use ethcore::snapshot::{RestorationStatus, SnapshotService as SS}; use ethcore::snapshot::service::Service as SnapshotService; -use ethsync::{LightSyncProvider, LightSync, SyncProvider, ManageNetwork}; +use sync::{LightSyncProvider, LightSync, SyncProvider, ManageNetwork}; use io::{TimerToken, IoContext, IoHandler}; use isatty::{stdout_isatty}; use light::Cache as LightDataCache; diff --git a/parity/light_helpers/epoch_fetch.rs b/parity/light_helpers/epoch_fetch.rs index ff384c1310e..1b9ae864846 100644 --- a/parity/light_helpers/epoch_fetch.rs +++ b/parity/light_helpers/epoch_fetch.rs @@ -21,7 +21,7 @@ use ethcore::engines::{EthEngine, StateDependentProof}; use ethcore::header::Header; use ethcore::machine::EthereumMachine; use ethcore::receipt::Receipt; -use ethsync::LightSync; +use sync::LightSync; use futures::{future, Future}; use futures::future::Either; diff --git a/parity/light_helpers/queue_cull.rs b/parity/light_helpers/queue_cull.rs index 9acf2bf1f9c..0d0ff6d4502 100644 --- a/parity/light_helpers/queue_cull.rs +++ b/parity/light_helpers/queue_cull.rs @@ -20,7 +20,7 @@ use std::sync::Arc; use std::time::Duration; use ethcore::client::ClientIoMessage; -use ethsync::LightSync; +use sync::LightSync; use io::{IoContext, IoHandler, TimerToken}; use light::client::LightChainClient; diff --git a/parity/main.rs b/parity/main.rs index 9ff3d97ab36..7179996bf58 100644 --- a/parity/main.rs +++ b/parity/main.rs @@ -55,10 +55,10 @@ 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 ethsync; extern crate kvdb; extern crate kvdb_rocksdb; extern crate migration as migr; diff --git a/parity/modules.rs b/parity/modules.rs index 22f8afe9f18..cf46149b8e8 100644 --- a/parity/modules.rs +++ b/parity/modules.rs @@ -17,11 +17,11 @@ use std::sync::Arc; use ethcore::client::BlockChainClient; -use ethsync::{self, AttachedProtocol, SyncConfig, NetworkConfiguration, Params, ConnectionFilter}; +use sync::{self, AttachedProtocol, SyncConfig, NetworkConfiguration, Params, ConnectionFilter}; use ethcore::snapshot::SnapshotService; use light::Provider; -pub use ethsync::{EthSync, SyncProvider, ManageNetwork, PrivateTxHandler}; +pub use sync::{EthSync, SyncProvider, ManageNetwork, PrivateTxHandler}; pub use ethcore::client::ChainNotify; use ethcore_logger::Config as LogConfig; @@ -37,7 +37,7 @@ pub fn sync( _log_settings: &LogConfig, attached_protos: Vec, connection_filter: Option>, -) -> Result { +) -> Result { let eth_sync = EthSync::new(Params { config: sync_cfg, chain: client, diff --git a/parity/rpc_apis.rs b/parity/rpc_apis.rs index 23a69755ff1..7b914f2860d 100644 --- a/parity/rpc_apis.rs +++ b/parity/rpc_apis.rs @@ -28,7 +28,7 @@ use ethcore::client::Client; use ethcore::miner::Miner; use ethcore::snapshot::SnapshotService; use ethcore_logger::RotatingLogger; -use ethsync::{ManageNetwork, SyncProvider, LightSync}; +use sync::{ManageNetwork, SyncProvider, LightSync}; use futures_cpupool::CpuPool; use hash_fetch::fetch::Client as FetchClient; use jsonrpc_core::{self as core, MetaIoHandler}; diff --git a/parity/run.rs b/parity/run.rs index 9d43801ac06..9db2f1ca4ca 100644 --- a/parity/run.rs +++ b/parity/run.rs @@ -34,7 +34,7 @@ use ethcore::spec::{SpecParams, OptimizeFor}; use ethcore::verification::queue::VerifierSettings; use ethcore_logger::{Config as LogConfig, RotatingLogger}; use ethcore_service::ClientService; -use ethsync::{self, SyncConfig}; +use sync::{self, SyncConfig}; use fdlimit::raise_fd_limit; use futures_cpupool::CpuPool; use hash_fetch::{self, fetch}; @@ -99,7 +99,7 @@ pub struct RunCmd { pub ws_conf: rpc::WsConfiguration, pub http_conf: rpc::HttpConfiguration, pub ipc_conf: rpc::IpcConfiguration, - pub net_conf: ethsync::NetworkConfiguration, + pub net_conf: sync::NetworkConfiguration, pub network_id: Option, pub warp_sync: bool, pub warp_barrier: Option, @@ -188,7 +188,7 @@ type LightClient = ::light::client::Client<::light_helpers::EpochFetch>; // helper for light execution. fn execute_light_impl(cmd: RunCmd, logger: Arc) -> Result { use light::client as light_client; - use ethsync::{LightSyncParams, LightSync, ManageNetwork}; + use sync::{LightSyncParams, LightSync, ManageNetwork}; use parking_lot::{Mutex, RwLock}; // load spec @@ -290,7 +290,7 @@ fn execute_light_impl(cmd: RunCmd, logger: Arc) -> Result) -> Result bool { self.0.is_major_importing() } fn peers(&self) -> (usize, usize) { - let peers = ethsync::LightSyncProvider::peer_numbers(&*self.0); + let peers = sync::LightSyncProvider::peer_numbers(&*self.0); (peers.connected, peers.max) } } @@ -535,9 +535,9 @@ fn execute_impl(cmd: RunCmd, logger: Arc, on_client_rq: } } sync_config.warp_sync = match (warp_sync, cmd.warp_barrier) { - (true, Some(block)) => ethsync::WarpSync::OnlyAndAfter(block), - (true, _) => ethsync::WarpSync::Enabled, - _ => ethsync::WarpSync::Disabled, + (true, Some(block)) => sync::WarpSync::OnlyAndAfter(block), + (true, _) => sync::WarpSync::Enabled, + _ => sync::WarpSync::Disabled, }; sync_config.download_old_blocks = cmd.download_old_blocks; sync_config.serve_light = cmd.serve_light; @@ -711,7 +711,7 @@ fn execute_impl(cmd: RunCmd, logger: Arc, on_client_rq: client.clone(), &cmd.logger_config, attached_protos, - connection_filter.clone().map(|f| f as Arc<::ethsync::ConnectionFilter + 'static>), + connection_filter.clone().map(|f| f as Arc<::sync::ConnectionFilter + 'static>), ).map_err(|e| format!("Sync error: {}", e))?; service.add_notify(chain_notify.clone()); @@ -758,7 +758,7 @@ fn execute_impl(cmd: RunCmd, logger: Arc, on_client_rq: let (node_health, dapps_deps) = { let (sync, client) = (sync_provider.clone(), client.clone()); - struct SyncStatus(Arc, Arc, ethsync::NetworkConfiguration); + struct SyncStatus(Arc, Arc, sync::NetworkConfiguration); impl fmt::Debug for SyncStatus { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { write!(fmt, "Dapps Sync Status") diff --git a/parity/secretstore.rs b/parity/secretstore.rs index 8e9f5fef5a0..9c130a59a92 100644 --- a/parity/secretstore.rs +++ b/parity/secretstore.rs @@ -22,7 +22,7 @@ use ethcore::account_provider::AccountProvider; use ethcore::client::Client; use ethcore::miner::Miner; use ethkey::{Secret, Public}; -use ethsync::SyncProvider; +use sync::SyncProvider; use ethereum_types::Address; /// This node secret key. diff --git a/parity/whisper.rs b/parity/whisper.rs index ed4812063d6..c7acd8f9d6f 100644 --- a/parity/whisper.rs +++ b/parity/whisper.rs @@ -17,7 +17,7 @@ use std::sync::Arc; use std::io; -use ethsync::{AttachedProtocol, ManageNetwork}; +use sync::{AttachedProtocol, ManageNetwork}; use parity_rpc::Metadata; use parity_whisper::message::Message; use parity_whisper::net::{self as whisper_net, Network as WhisperNetwork}; diff --git a/rpc/Cargo.toml b/rpc/Cargo.toml index ed59a91e8dd..7f975ca9dd1 100644 --- a/rpc/Cargo.toml +++ b/rpc/Cargo.toml @@ -45,6 +45,7 @@ ethcore-light = { path = "../ethcore/light" } ethcore-logger = { path = "../logger" } 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" @@ -52,7 +53,6 @@ ethcrypto = { path = "../ethcrypto" } ethjson = { path = "../json" } ethkey = { path = "../ethkey" } ethstore = { path = "../ethstore" } -ethsync = { path = "../sync" } fetch = { path = "../util/fetch" } hardware-wallet = { path = "../hw" } keccak-hash = { path = "../util/hash" } diff --git a/rpc/src/lib.rs b/rpc/src/lib.rs index 79911938b84..13e700375e8 100644 --- a/rpc/src/lib.rs +++ b/rpc/src/lib.rs @@ -49,14 +49,15 @@ extern crate ethcore_bytes as bytes; extern crate ethcore_devtools as devtools; 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_private_tx; +extern crate ethcore_sync as sync; extern crate ethcore_transaction as transaction; extern crate ethcrypto as crypto; extern crate ethereum_types; extern crate ethkey; extern crate ethstore; -extern crate ethsync; -extern crate ethcore_logger; extern crate vm; extern crate fetch; extern crate node_health; @@ -67,7 +68,6 @@ extern crate rlp; extern crate stats; extern crate keccak_hash as hash; extern crate hardware_wallet; -extern crate ethcore_private_tx; extern crate patricia_trie as trie; #[macro_use] diff --git a/rpc/src/v1/helpers/block_import.rs b/rpc/src/v1/helpers/block_import.rs index 3c3f84635d6..1246faa658b 100644 --- a/rpc/src/v1/helpers/block_import.rs +++ b/rpc/src/v1/helpers/block_import.rs @@ -17,7 +17,7 @@ //! Block import analysis functions. use ethcore::client::BlockQueueInfo; -use ethsync::SyncState; +use sync::SyncState; /// Check if client is during major sync or during block import. pub fn is_major_importing(sync_state: Option, queue_info: BlockQueueInfo) -> bool { @@ -32,7 +32,7 @@ pub fn is_major_importing(sync_state: Option, queue_info: BlockQueueI #[cfg(test)] mod tests { use ethcore::client::BlockQueueInfo; - use ethsync::SyncState; + use sync::SyncState; use super::is_major_importing; diff --git a/rpc/src/v1/helpers/dispatch.rs b/rpc/src/v1/helpers/dispatch.rs index b082320d579..b1fc07a22d7 100644 --- a/rpc/src/v1/helpers/dispatch.rs +++ b/rpc/src/v1/helpers/dispatch.rs @@ -32,7 +32,7 @@ use parking_lot::{Mutex, RwLock}; use stats::Corpus; use ethkey::Signature; -use ethsync::LightSync; +use sync::LightSync; use ethcore::ids::BlockId; use ethcore::miner::MinerService; use ethcore::client::MiningBlockChainClient; diff --git a/rpc/src/v1/helpers/light_fetch.rs b/rpc/src/v1/helpers/light_fetch.rs index f0c389d5778..d8a157da21b 100644 --- a/rpc/src/v1/helpers/light_fetch.rs +++ b/rpc/src/v1/helpers/light_fetch.rs @@ -36,7 +36,7 @@ use light::cht; use light::on_demand::{request, OnDemand, HeaderRef, Request as OnDemandRequest, Response as OnDemandResponse}; use light::request::Field; -use ethsync::LightSync; +use sync::LightSync; use ethereum_types::{U256, Address}; use hash::H256; use parking_lot::Mutex; diff --git a/rpc/src/v1/impls/eth.rs b/rpc/src/v1/impls/eth.rs index 4c48ccb6164..c833e3ee7f7 100644 --- a/rpc/src/v1/impls/eth.rs +++ b/rpc/src/v1/impls/eth.rs @@ -35,7 +35,7 @@ use ethcore::log_entry::LogEntry; use ethcore::miner::MinerService; use ethcore::snapshot::SnapshotService; use ethcore::encoded; -use ethsync::{SyncProvider}; +use sync::{SyncProvider}; use miner::external::ExternalMinerService; use transaction::{SignedTransaction, LocalizedTransaction}; diff --git a/rpc/src/v1/impls/eth_pubsub.rs b/rpc/src/v1/impls/eth_pubsub.rs index 315fc2f4f89..d7e6112a93a 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 ethsync::LightSync; +use sync::LightSync; use light::cache::Cache; use light::on_demand::OnDemand; use light::client::{LightChainClient, LightChainNotify}; diff --git a/rpc/src/v1/impls/light/eth.rs b/rpc/src/v1/impls/light/eth.rs index b449a2a2276..c617c03b1d7 100644 --- a/rpc/src/v1/impls/light/eth.rs +++ b/rpc/src/v1/impls/light/eth.rs @@ -32,7 +32,7 @@ use ethcore::account_provider::{AccountProvider, DappId}; use ethcore::encoded; use ethcore::filter::Filter as EthcoreFilter; use ethcore::ids::BlockId; -use ethsync::LightSync; +use sync::LightSync; use hash::{KECCAK_NULL_RLP, KECCAK_EMPTY_LIST_RLP}; use ethereum_types::U256; use parking_lot::{RwLock, Mutex}; diff --git a/rpc/src/v1/impls/light/net.rs b/rpc/src/v1/impls/light/net.rs index 3491b35ba77..1b374247a37 100644 --- a/rpc/src/v1/impls/light/net.rs +++ b/rpc/src/v1/impls/light/net.rs @@ -17,7 +17,7 @@ //! Net rpc implementation. use std::sync::Arc; use jsonrpc_core::Result; -use ethsync::LightSyncProvider; +use sync::LightSyncProvider; use v1::traits::Net; /// Net rpc implementation. diff --git a/rpc/src/v1/impls/light/parity.rs b/rpc/src/v1/impls/light/parity.rs index 3b2fab9a3cb..e1dc8d4d3d8 100644 --- a/rpc/src/v1/impls/light/parity.rs +++ b/rpc/src/v1/impls/light/parity.rs @@ -23,7 +23,7 @@ use version::version_data; use crypto::{ecies, DEFAULT_MAC}; use ethkey::{Brain, Generator}; use ethstore::random_phrase; -use ethsync::LightSyncProvider; +use sync::LightSyncProvider; use ethcore::account_provider::AccountProvider; use ethcore_logger::RotatingLogger; use node_health::{NodeHealth, Health}; diff --git a/rpc/src/v1/impls/light/parity_set.rs b/rpc/src/v1/impls/light/parity_set.rs index 0a6c2c5a57d..76c33cf4589 100644 --- a/rpc/src/v1/impls/light/parity_set.rs +++ b/rpc/src/v1/impls/light/parity_set.rs @@ -20,7 +20,7 @@ use std::io; use std::sync::Arc; -use ethsync::ManageNetwork; +use sync::ManageNetwork; use fetch::{self, Fetch}; use futures_cpupool::CpuPool; use hash::keccak_buffer; diff --git a/rpc/src/v1/impls/net.rs b/rpc/src/v1/impls/net.rs index 50dbffdc79e..3f42f01b947 100644 --- a/rpc/src/v1/impls/net.rs +++ b/rpc/src/v1/impls/net.rs @@ -17,7 +17,7 @@ //! Net rpc implementation. use std::sync::Arc; use jsonrpc_core::Result; -use ethsync::SyncProvider; +use sync::SyncProvider; use v1::traits::Net; /// Net rpc implementation. diff --git a/rpc/src/v1/impls/parity.rs b/rpc/src/v1/impls/parity.rs index 95c810aa1a3..451556e856a 100644 --- a/rpc/src/v1/impls/parity.rs +++ b/rpc/src/v1/impls/parity.rs @@ -25,7 +25,7 @@ use version::version_data; use crypto::{DEFAULT_MAC, ecies}; use ethkey::{Brain, Generator}; use ethstore::random_phrase; -use ethsync::{SyncProvider, ManageNetwork}; +use sync::{SyncProvider, ManageNetwork}; use ethcore::account_provider::AccountProvider; use ethcore::client::{MiningBlockChainClient, StateClient, Call}; use ethcore::ids::BlockId; diff --git a/rpc/src/v1/impls/parity_set.rs b/rpc/src/v1/impls/parity_set.rs index 1be136e1de7..475f5e01959 100644 --- a/rpc/src/v1/impls/parity_set.rs +++ b/rpc/src/v1/impls/parity_set.rs @@ -21,7 +21,7 @@ use std::sync::Arc; use ethcore::miner::MinerService; use ethcore::client::MiningBlockChainClient; use ethcore::mode::Mode; -use ethsync::ManageNetwork; +use sync::ManageNetwork; use fetch::{self, Fetch}; use futures_cpupool::CpuPool; use hash::keccak_buffer; diff --git a/rpc/src/v1/tests/helpers/sync_provider.rs b/rpc/src/v1/tests/helpers/sync_provider.rs index cbe66542352..a5ca4a4b367 100644 --- a/rpc/src/v1/tests/helpers/sync_provider.rs +++ b/rpc/src/v1/tests/helpers/sync_provider.rs @@ -19,7 +19,7 @@ use std::collections::BTreeMap; use ethereum_types::H256; use parking_lot::RwLock; -use ethsync::{SyncProvider, EthProtocolInfo, SyncStatus, SyncState, PeerInfo, TransactionStats}; +use sync::{SyncProvider, EthProtocolInfo, SyncStatus, SyncState, PeerInfo, TransactionStats}; /// TestSyncProvider config. pub struct Config { diff --git a/rpc/src/v1/tests/mocked/eth.rs b/rpc/src/v1/tests/mocked/eth.rs index 99c67286eb0..e79411f7056 100644 --- a/rpc/src/v1/tests/mocked/eth.rs +++ b/rpc/src/v1/tests/mocked/eth.rs @@ -27,7 +27,7 @@ use ethcore::log_entry::{LocalizedLogEntry, LogEntry}; use ethcore::miner::MinerService; use ethcore::receipt::{LocalizedReceipt, TransactionOutcome}; use ethkey::Secret; -use ethsync::SyncState; +use sync::SyncState; use miner::external::ExternalMiner; use rlp; use rustc_hex::{FromHex, ToHex}; diff --git a/rpc/src/v1/tests/mocked/manage_network.rs b/rpc/src/v1/tests/mocked/manage_network.rs index 9438429cdb6..3a901c8e9fd 100644 --- a/rpc/src/v1/tests/mocked/manage_network.rs +++ b/rpc/src/v1/tests/mocked/manage_network.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -use ethsync::{ManageNetwork, NetworkConfiguration}; +use sync::{ManageNetwork, NetworkConfiguration}; use self::ethcore_network::{ProtocolId, NetworkContext}; extern crate ethcore_network; diff --git a/rpc/src/v1/tests/mocked/parity.rs b/rpc/src/v1/tests/mocked/parity.rs index 332221b081d..18f76c6719b 100644 --- a/rpc/src/v1/tests/mocked/parity.rs +++ b/rpc/src/v1/tests/mocked/parity.rs @@ -20,7 +20,7 @@ use ethcore::client::{TestBlockChainClient, Executed}; use ethcore::miner::LocalTransactionStatus; use ethcore_logger::RotatingLogger; use ethstore::ethkey::{Generator, Random}; -use ethsync::ManageNetwork; +use sync::ManageNetwork; use node_health::{self, NodeHealth}; use parity_reactor; use ethereum_types::{Address, U256, H256}; diff --git a/rpc/src/v1/tests/mocked/parity_set.rs b/rpc/src/v1/tests/mocked/parity_set.rs index 549811bd583..2ae8ab5b2be 100644 --- a/rpc/src/v1/tests/mocked/parity_set.rs +++ b/rpc/src/v1/tests/mocked/parity_set.rs @@ -21,7 +21,7 @@ use ethereum_types::{U256, Address}; use ethcore::miner::MinerService; use ethcore::client::TestBlockChainClient; -use ethsync::ManageNetwork; +use sync::ManageNetwork; use futures_cpupool::CpuPool; use jsonrpc_core::IoHandler; diff --git a/rpc/src/v1/types/sync.rs b/rpc/src/v1/types/sync.rs index ae421ed4047..cbac3e1bbb7 100644 --- a/rpc/src/v1/types/sync.rs +++ b/rpc/src/v1/types/sync.rs @@ -15,7 +15,7 @@ // along with Parity. If not, see . use std::collections::BTreeMap; -use ethsync::{self, PeerInfo as SyncPeerInfo, TransactionStats as SyncTransactionStats}; +use sync::{self, PeerInfo as SyncPeerInfo, TransactionStats as SyncTransactionStats}; use serde::{Serialize, Serializer}; use v1::types::{U256, H512}; @@ -98,8 +98,8 @@ pub struct EthProtocolInfo { pub head: String, } -impl From for EthProtocolInfo { - fn from(info: ethsync::EthProtocolInfo) -> Self { +impl From for EthProtocolInfo { + fn from(info: sync::EthProtocolInfo) -> Self { EthProtocolInfo { version: info.version, difficulty: info.difficulty.map(Into::into), @@ -119,8 +119,8 @@ pub struct PipProtocolInfo { pub head: String, } -impl From for PipProtocolInfo { - fn from(info: ethsync::PipProtocolInfo) -> Self { +impl From for PipProtocolInfo { + fn from(info: sync::PipProtocolInfo) -> Self { PipProtocolInfo { version: info.version, difficulty: info.difficulty.into(), diff --git a/secret_store/Cargo.toml b/secret_store/Cargo.toml index d894bb4efd0..b9dee7303b7 100644 --- a/secret_store/Cargo.toml +++ b/secret_store/Cargo.toml @@ -24,9 +24,9 @@ tokio-proto = "0.1" url = "1.0" ethcore = { path = "../ethcore" } ethcore-bytes = { path = "../util/bytes" } +ethcore-sync = { path = "../ethcore/sync" } ethcore-transaction = { path = "../ethcore/transaction" } ethereum-types = "0.3" -ethsync = { path = "../sync" } kvdb = { path = "../util/kvdb" } kvdb-rocksdb = { path = "../util/kvdb-rocksdb" } keccak-hash = { path = "../util/hash" } diff --git a/secret_store/src/lib.rs b/secret_store/src/lib.rs index d58e37ffe79..c087d665112 100644 --- a/secret_store/src/lib.rs +++ b/secret_store/src/lib.rs @@ -19,11 +19,11 @@ extern crate ethabi; extern crate ethcore; extern crate ethcore_bytes as bytes; extern crate ethcore_logger as logger; +extern crate ethcore_sync as sync; extern crate ethcore_transaction as transaction; extern crate ethcrypto; extern crate ethereum_types; extern crate ethkey; -extern crate ethsync; extern crate futures_cpupool; extern crate hyper; extern crate keccak_hash as hash; @@ -70,7 +70,7 @@ mod trusted_client; use std::sync::Arc; use ethcore::client::Client; use ethcore::miner::Miner; -use ethsync::SyncProvider; +use sync::SyncProvider; pub use types::all::{ServerKeyId, EncryptedDocumentKey, RequestSignature, Public, Error, NodeAddress, ContractAddress, ServiceConfiguration, ClusterConfiguration}; diff --git a/secret_store/src/trusted_client.rs b/secret_store/src/trusted_client.rs index e40961e0443..5a9efe4b680 100644 --- a/secret_store/src/trusted_client.rs +++ b/secret_store/src/trusted_client.rs @@ -19,7 +19,7 @@ use bytes::Bytes; use ethereum_types::Address; use ethcore::client::{Client, BlockChainClient, ChainInfo, Nonce}; use ethcore::miner::{Miner, MinerService}; -use ethsync::SyncProvider; +use sync::SyncProvider; use transaction::{Transaction, SignedTransaction, Action}; use {Error, NodeKeyPair}; diff --git a/sync/Cargo.toml b/sync/Cargo.toml deleted file mode 100644 index 23cbbcf3418..00000000000 --- a/sync/Cargo.toml +++ /dev/null @@ -1,37 +0,0 @@ -[package] -description = "Ethcore blockchain sync" -name = "ethsync" -version = "1.11.0" -license = "GPL-3.0" -authors = ["Parity Technologies "] - -[lib] - -[dependencies] -ethcore-bytes = { path = "../util/bytes" } -ethcore-network = { path = "../util/network" } -ethcore-network-devp2p = { path = "../util/network-devp2p" } -ethcore-io = { path = "../util/io" } -ethcore-light = { path = "../ethcore/light" } -ethcore-transaction = { path = "../ethcore/transaction" } -ethcore = { path = "../ethcore" } -ethereum-types = "0.3" -plain_hasher = { path = "../util/plain_hasher" } -rlp = { path = "../util/rlp" } -rustc-hex = "1.0" -keccak-hash = { path = "../util/hash" } -triehash = { path = "../util/triehash" } -kvdb = { path = "../util/kvdb" } -macros = { path = "../util/macros" } -log = "0.3" -env_logger = "0.4" -rand = "0.4" -heapsize = "0.4" -semver = "0.9" -smallvec = { version = "0.4", features = ["heapsizeof"] } -parking_lot = "0.5" -ipnetwork = "0.12.6" - -[dev-dependencies] -ethkey = { path = "../ethkey" } -kvdb-memorydb = { path = "../util/kvdb-memorydb" } diff --git a/updater/Cargo.toml b/updater/Cargo.toml index 4afe802c616..9e7733bc46e 100644 --- a/updater/Cargo.toml +++ b/updater/Cargo.toml @@ -15,8 +15,8 @@ ethabi-contract = "5.0" target_info = "0.1" semver = "0.9" ethcore = { path = "../ethcore" } -ethsync = { path = "../sync" } ethcore-bytes = { path = "../util/bytes" } +ethcore-sync = { path = "../ethcore/sync" } ethereum-types = "0.3" parking_lot = "0.5" parity-hash-fetch = { path = "../hash-fetch" } diff --git a/updater/src/lib.rs b/updater/src/lib.rs index 91c66d76806..67525aa4b27 100644 --- a/updater/src/lib.rs +++ b/updater/src/lib.rs @@ -19,8 +19,8 @@ extern crate ethabi; extern crate ethcore; extern crate ethcore_bytes as bytes; +extern crate ethcore_sync as sync; extern crate ethereum_types; -extern crate ethsync; extern crate keccak_hash as hash; extern crate parity_hash_fetch as hash_fetch; extern crate parity_version as version; diff --git a/updater/src/updater.rs b/updater/src/updater.rs index 60984e10f1b..3b5ce01a935 100644 --- a/updater/src/updater.rs +++ b/updater/src/updater.rs @@ -30,7 +30,7 @@ use ethcore::BlockNumber; use ethcore::filter::Filter; use ethcore::client::{BlockId, BlockChainClient, ChainNotify}; use ethereum_types::H256; -use ethsync::{SyncProvider}; +use sync::{SyncProvider}; use hash_fetch::{self as fetch, HashFetch}; use path::restrict_permissions_owner; use service::Service; From 692cd10d4af2aaf1125d79808c0a510127f3ed7c Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Tue, 10 Apr 2018 19:51:29 +0800 Subject: [PATCH 11/25] Use hyper 0.11 in ethcore-miner and improvements in parity-reactor (#8335) * parity-reactor: Pass over Handle in spawning fn to allow normal tokio ops * Allow fetch to work with arbitrary requests * typo: Fix missing handler closure * miner, work_notify: use fetch and parity-reactor * Fix work_notify pushing in parity CLI --- Cargo.lock | 72 +---------- dapps/node-health/src/health.rs | 2 +- dapps/src/tests/helpers/fetch.rs | 26 +++- ethcore/private-tx/Cargo.toml | 1 + ethcore/private-tx/src/encryptor.rs | 7 +- ethcore/private-tx/src/lib.rs | 2 +- ethcore/src/miner/miner.rs | 12 +- hash-fetch/src/client.rs | 25 +++- miner/Cargo.toml | 7 +- miner/src/work_notify.rs | 82 ++++--------- parity/configuration.rs | 3 +- parity/light_helpers/queue_cull.rs | 2 +- parity/run.rs | 11 +- price-info/src/lib.rs | 24 +++- rpc/src/v1/tests/eth.rs | 1 - rpc/src/v1/tests/helpers/fetch.rs | 24 +++- util/fetch/Cargo.toml | 1 + util/fetch/src/client.rs | 181 +++++++++++++++++++++------- util/fetch/src/lib.rs | 4 +- util/reactor/src/lib.rs | 36 ++++-- 20 files changed, 302 insertions(+), 221 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 275c224f362..f802b863e48 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -250,15 +250,6 @@ dependencies = [ "custom_derive 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "cookie" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "crossbeam" version = "0.3.2" @@ -660,16 +651,19 @@ dependencies = [ "ethcore-transaction 0.1.0", "ethereum-types 0.3.0 (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)", "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper 0.10.0-a.0 (git+https://github.com/paritytech/hyper)", + "hyper 0.11.24 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hash 0.1.0", "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", "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)", "table 0.1.0", "transient-hashmap 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -753,6 +747,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)", "tiny-keccak 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1041,6 +1036,7 @@ dependencies = [ name = "fetch" version = "0.1.0" dependencies = [ + "bytes 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", "futures-timer 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.11.24 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1204,25 +1200,6 @@ name = "httparse" version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "hyper" -version = "0.10.0-a.0" -source = "git+https://github.com/paritytech/hyper#da10f69a4924cd44e98a8d1f9562bd7534d13dcc" -dependencies = [ - "cookie 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "httparse 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "mime 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", - "rotor 0.6.3 (git+https://github.com/tailhook/rotor)", - "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", - "spmc 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)", - "unicase 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)", - "vecio 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "hyper" version = "0.10.13" @@ -2634,11 +2611,6 @@ 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" @@ -2807,18 +2779,6 @@ dependencies = [ "snappy-sys 0.1.0 (git+https://github.com/paritytech/rust-snappy)", ] -[[package]] -name = "rotor" -version = "0.6.3" -source = "git+https://github.com/tailhook/rotor#80ce2e4cd82fdc7f88bb2d737407fa5106799790" -dependencies = [ - "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)", - "quick-error 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "rpassword" version = "1.0.2" @@ -3054,11 +3014,6 @@ dependencies = [ "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "spmc" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "stable_deref_trait" version = "1.0.0" @@ -3612,15 +3567,6 @@ name = "vec_map" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "vecio" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "vergen" version = "0.1.1" @@ -3831,7 +3777,6 @@ dependencies = [ "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" -"checksum cookie 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d53b80dde876f47f03cda35303e368a79b91c70b0d65ecba5fd5280944a08591" "checksum crossbeam 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "24ce9782d4d5c53674646a6a4c1863a21a8fc0cb649b3c94dfc16e45071dea19" "checksum crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f739f8c5363aca78cfb059edf753d8f0d36908c348f3d8d1503f03d8b75d9cf3" "checksum crossbeam-deque 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c1bdc73742c36f7f35ebcda81dbb33a7e0d33757d03a06d9ddca762712ec5ea2" @@ -3878,7 +3823,6 @@ dependencies = [ "checksum hex 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d6a22814455d41612f41161581c2883c0c6a1c41852729b17d5ed88f01e153aa" "checksum hidapi 0.3.1 (git+https://github.com/paritytech/hidapi-rs)" = "" "checksum httparse 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "af2f2dd97457e8fb1ae7c5a420db346af389926e36f43768b96f101546b04a07" -"checksum hyper 0.10.0-a.0 (git+https://github.com/paritytech/hyper)" = "" "checksum hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)" = "368cb56b2740ebf4230520e2b90ebb0461e69034d85d1945febd9b3971426db2" "checksum hyper 0.11.24 (registry+https://github.com/rust-lang/crates.io-index)" = "df4dd5dae401458087396b6db7fabc4d6760aa456a5fa8e92bda549f39cae661" "checksum hyper-rustls 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d6cdc1751771a14b8175764394f025e309a28c825ed9eaf97fa62bb831dc8c5" @@ -3973,7 +3917,6 @@ 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" @@ -3988,7 +3931,6 @@ dependencies = [ "checksum ring 0.12.1 (git+https://github.com/paritytech/ring)" = "" "checksum rocksdb 0.4.5 (git+https://github.com/paritytech/rust-rocksdb)" = "" "checksum rocksdb-sys 0.3.0 (git+https://github.com/paritytech/rust-rocksdb)" = "" -"checksum rotor 0.6.3 (git+https://github.com/tailhook/rotor)" = "" "checksum rpassword 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b273c91bd242ca03ad6d71c143b6f17a48790e61f21a6c78568fa2b6774a24a4" "checksum rprompt 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1601f32bc5858aae3cbfa1c645c96c4d820cc5c16be0194f089560c00b6eb625" "checksum rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)" = "f76d05d3993fd5f4af9434e8e436db163a12a9d40e1a58a726f27a01dfd12a2a" @@ -4020,7 +3962,6 @@ dependencies = [ "checksum smallvec 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8fcd03faf178110ab0334d74ca9631d77f94c8c11cc77fcb59538abf0025695d" "checksum snappy 0.1.0 (git+https://github.com/paritytech/rust-snappy)" = "" "checksum snappy-sys 0.1.0 (git+https://github.com/paritytech/rust-snappy)" = "" -"checksum spmc 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cd1f11d1fb5fd41834e55ce0b85a186efbf2f2afd9fdb09e2c8d72f9bff1ad1a" "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" @@ -4075,7 +4016,6 @@ dependencies = [ "checksum url 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eeb819346883532a271eb626deb43c4a1bb4c4dd47c519bd78137c3e72a4fe27" "checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122" "checksum vec_map 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "887b5b631c2ad01628bbbaa7dd4c869f80d3186688f8d0b6f58774fbe324988c" -"checksum vecio 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0795a11576d29ae80525a3fda315bf7b534f8feb9d34101e5fe63fb95bb2fd24" "checksum vergen 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c3365f36c57e5df714a34be40902b27a992eeddb9996eca52d0584611cf885d" "checksum version_check 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6b772017e347561807c1aa192438c5fd74242a670a6cffacc40f2defd1dc069d" "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" diff --git a/dapps/node-health/src/health.rs b/dapps/node-health/src/health.rs index ab52b22330e..ab300a4a771 100644 --- a/dapps/node-health/src/health.rs +++ b/dapps/node-health/src/health.rs @@ -53,7 +53,7 @@ impl NodeHealth { let tx = Arc::new(Mutex::new(Some(tx))); let tx2 = tx.clone(); self.remote.spawn_with_timeout( - move || time.then(move |result| { + move |_| time.then(move |result| { let _ = tx.lock().take().expect(PROOF).send(Ok(result)); Ok(()) }), diff --git a/dapps/src/tests/helpers/fetch.rs b/dapps/src/tests/helpers/fetch.rs index d65d9d09b07..146163a77f4 100644 --- a/dapps/src/tests/helpers/fetch.rs +++ b/dapps/src/tests/helpers/fetch.rs @@ -19,8 +19,8 @@ use std::sync::{atomic, mpsc, Arc}; use parking_lot::Mutex; use hyper; -use futures::{self, Future}; -use fetch::{self, Fetch, Url, Method}; +use futures::{self, future, Future}; +use fetch::{self, Fetch, Url, Request, Abort}; pub struct FetchControl { sender: mpsc::Sender<()>, @@ -97,9 +97,9 @@ impl FakeFetch { impl Fetch for FakeFetch { type Result = Box + Send>; - fn fetch(&self, url: &str, _method: Method, abort: fetch::Abort) -> Self::Result { - let u = Url::parse(url).unwrap(); - self.requested.lock().push(url.into()); + fn fetch(&self, request: Request, abort: fetch::Abort) -> Self::Result { + let u = request.url().clone(); + self.requested.lock().push(u.as_str().into()); let manual = self.manual.clone(); let response = self.response.clone(); @@ -115,4 +115,20 @@ impl Fetch for FakeFetch { Box::new(rx.map_err(|_| fetch::Error::Aborted)) } + + fn get(&self, url: &str, abort: Abort) -> Self::Result { + let url: Url = match url.parse() { + Ok(u) => u, + Err(e) => return Box::new(future::err(e.into())) + }; + self.fetch(Request::get(url), abort) + } + + fn post(&self, url: &str, abort: Abort) -> Self::Result { + let url: Url = match url.parse() { + Ok(u) => u, + Err(e) => return Box::new(future::err(e.into())) + }; + self.fetch(Request::post(url), abort) + } } diff --git a/ethcore/private-tx/Cargo.toml b/ethcore/private-tx/Cargo.toml index 6ecfdb54647..ff37f20ab2b 100644 --- a/ethcore/private-tx/Cargo.toml +++ b/ethcore/private-tx/Cargo.toml @@ -34,3 +34,4 @@ serde = "1.0" serde_derive = "1.0" serde_json = "1.0" tiny-keccak = "1.3" +url = "1" diff --git a/ethcore/private-tx/src/encryptor.rs b/ethcore/private-tx/src/encryptor.rs index 385356227fa..fd7eaa680f7 100644 --- a/ethcore/private-tx/src/encryptor.rs +++ b/ethcore/private-tx/src/encryptor.rs @@ -17,6 +17,7 @@ //! Encryption providers. use std::io::Read; +use std::str::FromStr; use std::iter::repeat; use std::time::{Instant, Duration}; use std::collections::HashMap; @@ -28,9 +29,10 @@ use ethjson; use ethkey::{Signature, Public}; use ethcrypto; use futures::Future; -use fetch::{Fetch, Client as FetchClient, Method, BodyReader}; +use fetch::{Fetch, Client as FetchClient, Method, BodyReader, Request}; use bytes::{Bytes, ToPretty}; use error::{Error, ErrorKind}; +use url::Url; use super::find_account_password; /// Initialization vector length. @@ -128,7 +130,8 @@ impl SecretStoreEncryptor { Method::Get }; - let response = self.client.fetch(&url, method, Default::default()).wait() + let url = Url::from_str(&url).map_err(|e| ErrorKind::Encrypt(e.to_string()))?; + let response = self.client.fetch(Request::new(url, method), Default::default()).wait() .map_err(|e| ErrorKind::Encrypt(e.to_string()))?; if response.is_not_found() { diff --git a/ethcore/private-tx/src/lib.rs b/ethcore/private-tx/src/lib.rs index 4fa1f8789c1..5b7a62b7cd3 100644 --- a/ethcore/private-tx/src/lib.rs +++ b/ethcore/private-tx/src/lib.rs @@ -41,6 +41,7 @@ extern crate keccak_hash as hash; extern crate parking_lot; extern crate patricia_trie as trie; extern crate rlp; +extern crate url; extern crate rustc_hex; #[macro_use] extern crate log; @@ -673,4 +674,3 @@ impl ChainNotify for Provider { } } } - diff --git a/ethcore/src/miner/miner.rs b/ethcore/src/miner/miner.rs index 96094dce413..755294637b8 100644 --- a/ethcore/src/miner/miner.rs +++ b/ethcore/src/miner/miner.rs @@ -36,7 +36,7 @@ use ethcore_miner::transaction_queue::{ TransactionOrigin, }; use futures_cpupool::CpuPool; -use ethcore_miner::work_notify::{WorkPoster, NotifyWork}; +use ethcore_miner::work_notify::NotifyWork; use miner::service_transaction_checker::ServiceTransactionChecker; use miner::{MinerService, MinerStatus}; use price_info::fetch::Client as FetchClient; @@ -104,8 +104,6 @@ pub enum Banning { /// Configures the behaviour of the miner. #[derive(Debug, PartialEq)] pub struct MinerOptions { - /// URLs to notify when there is new work. - pub new_work_notify: Vec, /// Force the miner to reseal, even when nobody has asked for work. pub force_sealing: bool, /// Reseal on receipt of new external transactions. @@ -147,7 +145,6 @@ pub struct MinerOptions { impl Default for MinerOptions { fn default() -> Self { MinerOptions { - new_work_notify: vec![], force_sealing: false, reseal_on_external_tx: false, reseal_on_own_tx: true, @@ -305,10 +302,7 @@ impl Miner { ), }; - let notifiers: Vec> = match options.new_work_notify.is_empty() { - true => Vec::new(), - false => vec![Box::new(WorkPoster::new(&options.new_work_notify))], - }; + let notifiers: Vec> = Vec::new(); let service_transaction_action = match options.refuse_service_transactions { true => ServiceTransactionAction::Refuse, @@ -324,7 +318,6 @@ impl Miner { sealing_work: Mutex::new(SealingWork{ queue: UsingQueue::new(options.work_queue_size), enabled: options.force_sealing - || !options.new_work_notify.is_empty() || spec.engine.seals_internally().is_some() }), gas_range_target: RwLock::new((U256::zero(), U256::zero())), @@ -1364,7 +1357,6 @@ mod tests { fn miner() -> Miner { Arc::try_unwrap(Miner::new( MinerOptions { - new_work_notify: Vec::new(), force_sealing: false, reseal_on_external_tx: false, reseal_on_own_tx: true, diff --git a/hash-fetch/src/client.rs b/hash-fetch/src/client.rs index ce2e44054e3..201d65ba79e 100644 --- a/hash-fetch/src/client.rs +++ b/hash-fetch/src/client.rs @@ -199,7 +199,7 @@ mod tests { use parking_lot::Mutex; use futures::future; use futures_cpupool::CpuPool; - use fetch::{self, Fetch, Url, Method}; + use fetch::{self, Fetch, Url, Request}; use parity_reactor::Remote; use urlhint::tests::{FakeRegistrar, URLHINT}; use super::{Error, Client, HashFetch, random_temp_path}; @@ -214,15 +214,31 @@ mod tests { impl Fetch for FakeFetch { type Result = future::Ok; - fn fetch(&self, url: &str, _method: Method, abort: fetch::Abort) -> Self::Result { - assert_eq!(url, "https://parity.io/assets/images/ethcore-black-horizontal.png"); - let u = Url::parse(url).unwrap(); + fn fetch(&self, request: Request, abort: fetch::Abort) -> Self::Result { + assert_eq!(request.url().as_str(), "https://parity.io/assets/images/ethcore-black-horizontal.png"); + let u = request.url().clone(); future::ok(if self.return_success { fetch::client::Response::new(u, hyper::Response::new().with_body(&b"result"[..]), abort) } else { fetch::client::Response::new(u, hyper::Response::new().with_status(StatusCode::NotFound), abort) }) } + + fn get(&self, url: &str, abort: fetch::Abort) -> Self::Result { + let url: Url = match url.parse() { + Ok(u) => u, + Err(e) => return future::err(e.into()) + }; + self.fetch(Request::get(url), abort) + } + + fn post(&self, url: &str, abort: fetch::Abort) -> Self::Result { + let url: Url = match url.parse() { + Ok(u) => u, + Err(e) => return future::err(e.into()) + }; + self.fetch(Request::post(url), abort) + } } fn registrar() -> FakeRegistrar { @@ -311,4 +327,3 @@ mod tests { assert!(result.is_ok(), "Should return path, got: {:?}", result); } } - diff --git a/miner/Cargo.toml b/miner/Cargo.toml index a3464cf7d00..4ee8d74c0f9 100644 --- a/miner/Cargo.toml +++ b/miner/Cargo.toml @@ -7,9 +7,6 @@ version = "1.11.0" authors = ["Parity Technologies "] [dependencies] -# TODO [ToDr] Rewrite using reqwest -hyper = { git = "https://github.com/paritytech/hyper", default-features = false } - common-types = { path = "../ethcore/types" } ethabi = "5.1" ethabi-contract = "5.0" @@ -27,3 +24,7 @@ parking_lot = "0.5" rustc-hex = "1.0" table = { path = "../util/table" } transient-hashmap = "0.4" +fetch = { path = "../util/fetch" } +parity-reactor = { path = "../util/reactor" } +url = "1" +hyper = "0.11" diff --git a/miner/src/work_notify.rs b/miner/src/work_notify.rs index 8ab65ed8324..3436938097a 100644 --- a/miner/src/work_notify.rs +++ b/miner/src/work_notify.rs @@ -17,19 +17,20 @@ //! Sends HTTP notifications to a list of URLs every time new work is available. extern crate ethash; +extern crate fetch; +extern crate parity_reactor; +extern crate url; extern crate hyper; -use self::hyper::header::ContentType; -use self::hyper::method::Method; -use self::hyper::client::{Request, Response, Client}; -use self::hyper::{Next, Url}; -use self::hyper::net::HttpStream; - +use self::fetch::{Fetch, Request, Client as FetchClient, Method}; +use self::parity_reactor::Remote; use self::ethash::SeedHashCompute; +use self::url::Url; +use self::hyper::header::ContentType; -use std::io::Write; use ethereum_types::{H256, U256}; use parking_lot::Mutex; +use futures::Future; /// Trait for notifying about new mining work pub trait NotifyWork : Send + Sync { @@ -40,13 +41,14 @@ pub trait NotifyWork : Send + Sync { /// POSTs info about new work to given urls. pub struct WorkPoster { urls: Vec, - client: Mutex>, + client: FetchClient, + remote: Remote, seed_compute: Mutex, } impl WorkPoster { /// Create new `WorkPoster`. - pub fn new(urls: &[String]) -> Self { + pub fn new(urls: &[String], fetch: FetchClient, remote: Remote) -> Self { let urls = urls.into_iter().filter_map(|u| { match Url::parse(u) { Ok(url) => Some(url), @@ -56,20 +58,13 @@ impl WorkPoster { } } }).collect(); - let client = WorkPoster::create_client(); WorkPoster { - client: Mutex::new(client), + client: fetch, + remote: remote, urls: urls, seed_compute: Mutex::new(SeedHashCompute::new()), } } - - fn create_client() -> Client { - Client::::configure() - .keep_alive(true) - .build() - .expect("Error creating HTTP client") - } } /// Convert an Ethash difficulty to the target boundary. Basically just `f(x) = 2^256 / x`. @@ -91,51 +86,16 @@ impl NotifyWork for WorkPoster { r#"{{ "result": ["0x{:x}","0x{:x}","0x{:x}","0x{:x}"] }}"#, pow_hash, seed_hash, target, number ); - let mut client = self.client.lock(); + for u in &self.urls { - if let Err(e) = client.request(u.clone(), PostHandler { body: body.clone() }) { + let u = u.clone(); + self.remote.spawn(self.client.fetch( + Request::new(u.clone(), Method::Post) + .with_header(ContentType::json()) + .with_body(body.clone()), Default::default() + ).map_err(move |e| { warn!("Error sending HTTP notification to {} : {}, retrying", u, e); - // TODO: remove this once https://github.com/hyperium/hyper/issues/848 is fixed - *client = WorkPoster::create_client(); - if let Err(e) = client.request(u.clone(), PostHandler { body: body.clone() }) { - warn!("Error sending HTTP notification to {} : {}", u, e); - } - } - } - } -} - -struct PostHandler { - body: String, -} - -impl hyper::client::Handler for PostHandler { - fn on_request(&mut self, request: &mut Request) -> Next { - request.set_method(Method::Post); - request.headers_mut().set(ContentType::json()); - Next::write() - } - - fn on_request_writable(&mut self, encoder: &mut hyper::Encoder) -> Next { - if let Err(e) = encoder.write_all(self.body.as_bytes()) { - trace!("Error posting work data: {}", e); + }).map(|_| ())); } - encoder.close(); - Next::read() - - } - - fn on_response(&mut self, _response: Response) -> Next { - Next::end() - } - - fn on_response_readable(&mut self, _decoder: &mut hyper::Decoder) -> Next { - Next::end() - } - - fn on_error(&mut self, err: hyper::Error) -> Next { - trace!("Error posting work data: {}", err); - Next::end() } } - diff --git a/parity/configuration.rs b/parity/configuration.rs index 3e8f58b6faa..d1c02d5bc7a 100644 --- a/parity/configuration.rs +++ b/parity/configuration.rs @@ -354,6 +354,7 @@ impl Configuration { daemon: daemon, logger_config: logger_config.clone(), miner_options: self.miner_options()?, + work_notify: self.work_notify(), gas_price_percentile: self.args.arg_gas_price_percentile, ntp_servers: self.ntp_servers(), ws_conf: ws_conf, @@ -537,7 +538,6 @@ impl Configuration { let reseal = self.args.arg_reseal_on_txs.parse::()?; let options = MinerOptions { - new_work_notify: self.work_notify(), force_sealing: self.args.flag_force_sealing, reseal_on_external_tx: reseal.external, reseal_on_own_tx: reseal.own, @@ -1516,6 +1516,7 @@ mod tests { no_hardcoded_sync: false, no_persistent_txqueue: false, whisper: Default::default(), + work_notify: Vec::new(), }; expected.secretstore_conf.enabled = cfg!(feature = "secretstore"); expected.secretstore_conf.http_enabled = cfg!(feature = "secretstore"); diff --git a/parity/light_helpers/queue_cull.rs b/parity/light_helpers/queue_cull.rs index 0d0ff6d4502..e0725406199 100644 --- a/parity/light_helpers/queue_cull.rs +++ b/parity/light_helpers/queue_cull.rs @@ -70,7 +70,7 @@ impl IoHandler for QueueCull let start_nonce = self.client.engine().account_start_nonce(best_header.number()); info!(target: "cull", "Attempting to cull queued transactions from {} senders.", senders.len()); - self.remote.spawn_with_timeout(move || { + self.remote.spawn_with_timeout(move |_| { let maybe_fetching = sync.with_context(move |ctx| { // fetch the nonce of each sender in the queue. let nonce_reqs = senders.iter() diff --git a/parity/run.rs b/parity/run.rs index 9db2f1ca4ca..8fa76693b8f 100644 --- a/parity/run.rs +++ b/parity/run.rs @@ -35,6 +35,7 @@ use ethcore::verification::queue::VerifierSettings; 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}; @@ -137,6 +138,7 @@ pub struct RunCmd { pub no_persistent_txqueue: bool, pub whisper: ::whisper::Config, pub no_hardcoded_sync: bool, + pub work_notify: Vec, } pub fn open_ui(ws_conf: &rpc::WsConfiguration, ui_conf: &rpc::UiConfiguration, logger_config: &LogConfig) -> Result<(), String> { @@ -549,6 +551,9 @@ fn execute_impl(cmd: RunCmd, logger: Arc, on_client_rq: let cpu_pool = CpuPool::new(4); + // spin up event loop + let event_loop = EventLoop::spawn(); + // fetch service let fetch = fetch::Client::new().map_err(|e| format!("Error starting fetch client: {:?}", e))?; @@ -561,6 +566,9 @@ fn execute_impl(cmd: RunCmd, logger: Arc, on_client_rq: miner.set_extra_data(cmd.miner_extras.extra_data); miner.set_minimal_gas_price(initial_min_gas_price); miner.recalibrate_minimal_gas_price(); + if !cmd.work_notify.is_empty() { + miner.push_notifier(Box::new(WorkPoster::new(&cmd.work_notify, fetch.clone(), event_loop.remote()))); + } let engine_signer = cmd.miner_extras.engine_signer; if engine_signer != Default::default() { @@ -730,9 +738,6 @@ fn execute_impl(cmd: RunCmd, logger: Arc, on_client_rq: chain_notify.start(); } - // spin up event loop - let event_loop = EventLoop::spawn(); - let contract_client = Arc::new(::dapps::FullRegistrar::new(client.clone())); // the updater service diff --git a/price-info/src/lib.rs b/price-info/src/lib.rs index 9be27a1319f..8b87f0c11de 100644 --- a/price-info/src/lib.rs +++ b/price-info/src/lib.rs @@ -140,7 +140,7 @@ mod test { use std::sync::Arc; use std::sync::atomic::{AtomicBool, Ordering}; use fetch; - use fetch::{Fetch, Url, Method}; + use fetch::{Fetch, Url, Request}; use futures_cpupool::CpuPool; use futures::future::{self, FutureResult}; use Client; @@ -158,9 +158,9 @@ mod test { impl Fetch for FakeFetch { type Result = FutureResult; - fn fetch(&self, url: &str, _method: Method, abort: fetch::Abort) -> Self::Result { - assert_eq!(url, "https://api.etherscan.io/api?module=stats&action=ethprice"); - let u = Url::parse(url).unwrap(); + fn fetch(&self, request: Request, abort: fetch::Abort) -> Self::Result { + assert_eq!(request.url().as_str(), "https://api.etherscan.io/api?module=stats&action=ethprice"); + let u = request.url().clone(); let mut val = self.1.lock(); *val = *val + 1; if let Some(ref response) = self.0 { @@ -171,6 +171,22 @@ mod test { future::ok(fetch::client::Response::new(u, r, abort)) } } + + fn get(&self, url: &str, abort: fetch::Abort) -> Self::Result { + let url: Url = match url.parse() { + Ok(u) => u, + Err(e) => return future::err(e.into()) + }; + self.fetch(Request::get(url), abort) + } + + fn post(&self, url: &str, abort: fetch::Abort) -> Self::Result { + let url: Url = match url.parse() { + Ok(u) => u, + Err(e) => return future::err(e.into()) + }; + self.fetch(Request::post(url), abort) + } } fn price_info_ok(response: &str) -> Client { diff --git a/rpc/src/v1/tests/eth.rs b/rpc/src/v1/tests/eth.rs index bb03808c582..747c10200df 100644 --- a/rpc/src/v1/tests/eth.rs +++ b/rpc/src/v1/tests/eth.rs @@ -60,7 +60,6 @@ fn sync_provider() -> Arc { fn miner_service(spec: &Spec, accounts: Arc) -> Arc { Miner::new( MinerOptions { - new_work_notify: vec![], force_sealing: true, reseal_on_external_tx: true, reseal_on_own_tx: true, diff --git a/rpc/src/v1/tests/helpers/fetch.rs b/rpc/src/v1/tests/helpers/fetch.rs index f3b7543f704..7de3949c4bc 100644 --- a/rpc/src/v1/tests/helpers/fetch.rs +++ b/rpc/src/v1/tests/helpers/fetch.rs @@ -17,8 +17,10 @@ //! Test implementation of fetch client. use std::thread; +use std::boxed::Box; use jsonrpc_core::futures::{self, Future}; -use fetch::{self, Fetch, Url, Method}; +use fetch::{self, Fetch, Url, Request}; +use futures::future; use hyper; /// Test implementation of fetcher. Will always return the same file. @@ -28,8 +30,8 @@ pub struct TestFetch; impl Fetch for TestFetch { type Result = Box + Send + 'static>; - fn fetch(&self, url: &str, _method: Method, abort: fetch::Abort) -> Self::Result { - let u = Url::parse(url).unwrap(); + fn fetch(&self, request: Request, abort: fetch::Abort) -> Self::Result { + let u = request.url().clone(); let (tx, rx) = futures::oneshot(); thread::spawn(move || { let r = hyper::Response::new().with_body(&b"Some content"[..]); @@ -38,4 +40,20 @@ impl Fetch for TestFetch { Box::new(rx.map_err(|_| fetch::Error::Aborted)) } + + fn get(&self, url: &str, abort: fetch::Abort) -> Self::Result { + let url: Url = match url.parse() { + Ok(u) => u, + Err(e) => return Box::new(future::err(e.into())) + }; + self.fetch(Request::get(url), abort) + } + + fn post(&self, url: &str, abort: fetch::Abort) -> Self::Result { + let url: Url = match url.parse() { + Ok(u) => u, + Err(e) => return Box::new(future::err(e.into())) + }; + self.fetch(Request::post(url), abort) + } } diff --git a/util/fetch/Cargo.toml b/util/fetch/Cargo.toml index 61925e189d1..98b1fc58234 100644 --- a/util/fetch/Cargo.toml +++ b/util/fetch/Cargo.toml @@ -14,6 +14,7 @@ hyper-rustls = "0.11" log = "0.4" tokio-core = "0.1" url = "1" +bytes = "0.4" [features] default = [] diff --git a/util/fetch/src/client.rs b/util/fetch/src/client.rs index b3274ca4f73..9bb55aad0e0 100644 --- a/util/fetch/src/client.rs +++ b/util/fetch/src/client.rs @@ -20,7 +20,7 @@ use futures::{self, Future, Async, Sink, Stream}; use futures_timer::FutureExt; use hyper::header::{UserAgent, Location, ContentLength, ContentType}; use hyper::mime::Mime; -use hyper::{self, Request, Method, StatusCode}; +use hyper::{self, Method, StatusCode}; use hyper_rustls; use std; use std::cmp::min; @@ -32,6 +32,7 @@ use std::time::Duration; use std::{io, fmt}; use tokio_core::reactor; use url::{self, Url}; +use bytes::Bytes; const MAX_SIZE: usize = 64 * 1024 * 1024; const MAX_SECS: Duration = Duration::from_secs(5); @@ -120,22 +121,18 @@ pub trait Fetch: Clone + Send + Sync + 'static { type Result: Future + Send + 'static; /// Make a request to given URL - fn fetch(&self, url: &str, method: Method, abort: Abort) -> Self::Result; + fn fetch(&self, request: Request, abort: Abort) -> Self::Result; /// Get content from some URL. - fn get(&self, url: &str, abort: Abort) -> Self::Result { - self.fetch(url, Method::Get, abort) - } + fn get(&self, url: &str, abort: Abort) -> Self::Result; /// Post content to some URL. - fn post(&self, url: &str, abort: Abort) -> Self::Result { - self.fetch(url, Method::Post, abort) - } + fn post(&self, url: &str, abort: Abort) -> Self::Result; } type TxResponse = oneshot::Sender>; type TxStartup = std::sync::mpsc::SyncSender>; -type ChanItem = Option<(Url, Method, Abort, TxResponse)>; +type ChanItem = Option<(Request, Abort, TxResponse)>; /// An implementation of `Fetch` using a `hyper` client. // Due to the `Send` bound of `Fetch` we spawn a background thread for @@ -213,29 +210,37 @@ impl Client { let future = rx_proto.take_while(|item| Ok(item.is_some())) .map(|item| item.expect("`take_while` is only passing on channel items != None; qed")) - .for_each(|(url, method, abort, sender)| + .for_each(|(request, abort, sender)| { - trace!(target: "fetch", "new request to {}", url); + trace!(target: "fetch", "new request to {}", request.url()); if abort.is_aborted() { return future::ok(sender.send(Err(Error::Aborted)).unwrap_or(())) } - let ini = (hyper.clone(), url, method, abort, 0); - let fut = future::loop_fn(ini, |(client, url, method, abort, redirects)| { - let url2 = url.clone(); + let ini = (hyper.clone(), request, abort, 0); + let fut = future::loop_fn(ini, |(client, request, abort, redirects)| { + let request2 = request.clone(); + let url2 = request2.url().clone(); let abort2 = abort.clone(); - client.request(build_request(&url, method.clone())) + client.request(request.into()) .map(move |resp| Response::new(url2, resp, abort2)) .from_err() .and_then(move |resp| { if abort.is_aborted() { - debug!(target: "fetch", "fetch of {} aborted", url); + debug!(target: "fetch", "fetch of {} aborted", request2.url()); return Err(Error::Aborted) } - if let Some(next_url) = redirect_location(url, &resp) { + if let Some((next_url, preserve_method)) = redirect_location(request2.url().clone(), &resp) { if redirects >= abort.max_redirects() { return Err(Error::TooManyRedirects) } - Ok(Loop::Continue((client, next_url, method, abort, redirects + 1))) + let request = if preserve_method { + let mut request2 = request2.clone(); + request2.set_url(next_url); + request2 + } else { + Request::new(next_url, Method::Get) + }; + Ok(Loop::Continue((client, request, abort, redirects + 1))) } else { let content_len = resp.headers.get::().cloned(); if content_len.map(|n| *n > abort.max_size() as u64).unwrap_or(false) { @@ -267,19 +272,15 @@ impl Client { impl Fetch for Client { type Result = Box + Send>; - fn fetch(&self, url: &str, method: Method, abort: Abort) -> Self::Result { - debug!(target: "fetch", "fetching: {:?}", url); + fn fetch(&self, request: Request, abort: Abort) -> Self::Result { + debug!(target: "fetch", "fetching: {:?}", request.url()); if abort.is_aborted() { return Box::new(future::err(Error::Aborted)) } - let url: Url = match url.parse() { - Ok(u) => u, - Err(e) => return Box::new(future::err(e.into())) - }; let (tx_res, rx_res) = oneshot::channel(); let maxdur = abort.max_duration(); let sender = self.core.clone(); - let future = sender.send(Some((url.clone(), method, abort, tx_res))) + let future = sender.send(Some((request, abort, tx_res))) .map_err(|e| { error!(target: "fetch", "failed to schedule request: {}", e); Error::BackgroundThreadDead @@ -297,11 +298,33 @@ impl Fetch for Client { }); Box::new(future) } + + /// Get content from some URL. + fn get(&self, url: &str, abort: Abort) -> Self::Result { + let url: Url = match url.parse() { + Ok(u) => u, + Err(e) => return Box::new(future::err(e.into())) + }; + self.fetch(Request::get(url), abort) + } + + /// Post content to some URL. + fn post(&self, url: &str, abort: Abort) -> Self::Result { + let url: Url = match url.parse() { + Ok(u) => u, + Err(e) => return Box::new(future::err(e.into())) + }; + self.fetch(Request::post(url), abort) + } } -// Extract redirect location from response. -fn redirect_location(u: Url, r: &Response) -> Option { +// Extract redirect location from response. The second return value indicate whether the original method should be preserved. +fn redirect_location(u: Url, r: &Response) -> Option<(Url, bool)> { use hyper::StatusCode::*; + let preserve_method = match r.status() { + TemporaryRedirect | PermanentRedirect => true, + _ => false, + }; match r.status() { MovedPermanently | PermanentRedirect @@ -309,7 +332,7 @@ fn redirect_location(u: Url, r: &Response) -> Option { | Found | SeeOther => { if let Some(loc) = r.headers.get::() { - u.join(loc).ok() + u.join(loc).ok().map(|url| (url, preserve_method)) } else { None } @@ -318,12 +341,84 @@ fn redirect_location(u: Url, r: &Response) -> Option { } } -// Build a simple request for the given Url and method -fn build_request(u: &Url, method: Method) -> hyper::Request { - let uri = u.as_ref().parse().expect("Every valid URL is aso a URI."); - let mut rq = Request::new(method, uri); - rq.headers_mut().set(UserAgent::new("Parity Fetch Neo")); - rq +/// A wrapper for hyper::Request using Url and with methods. +#[derive(Debug, Clone)] +pub struct Request { + url: Url, + method: Method, + headers: hyper::Headers, + body: Bytes, +} + +impl Request { + /// Create a new request, with given url and method. + pub fn new(url: Url, method: Method) -> Request { + Request { + url, method, + headers: hyper::Headers::new(), + body: Default::default(), + } + } + + /// Create a new GET request. + pub fn get(url: Url) -> Request { + Request::new(url, Method::Get) + } + + /// Create a new empty POST request. + pub fn post(url: Url) -> Request { + Request::new(url, Method::Post) + } + + /// Read the url. + pub fn url(&self) -> &Url { + &self.url + } + + /// Read the request headers. + pub fn headers(&self) -> &hyper::Headers { + &self.headers + } + + /// Get a mutable reference to the headers. + pub fn headers_mut(&mut self) -> &mut hyper::Headers { + &mut self.headers + } + + /// Set the body of the request. + pub fn set_body>(&mut self, body: T) { + self.body = body.into(); + } + + /// Set the url of the request. + pub fn set_url(&mut self, url: Url) { + self.url = url; + } + + /// Consume self, and return it with the added given header. + pub fn with_header(mut self, value: H) -> Self { + self.headers_mut().set(value); + self + } + + /// Consume self, and return it with the body. + pub fn with_body>(mut self, body: T) -> Self { + self.set_body(body); + self + } +} + +impl Into for Request { + fn into(mut self) -> hyper::Request { + let uri = self.url.as_ref().parse().expect("Every valid URLis also a URI."); + let mut req = hyper::Request::new(self.method, uri); + + self.headers.set(UserAgent::new("Parity Fetch Neo")); + *req.headers_mut() = self.headers; + req.set_body(self.body); + + req + } } /// An HTTP response. @@ -527,7 +622,7 @@ mod test { use futures::future; use futures::sync::mpsc; use futures_timer::Delay; - use hyper::{StatusCode, Method}; + use hyper::StatusCode; use hyper::server::{Http, Request, Response, Service}; use std; use std::io::Read; @@ -539,7 +634,7 @@ mod test { fn it_should_fetch() { let server = TestServer::run(); let client = Client::new().unwrap(); - let future = client.fetch(&format!("http://{}?123", server.addr()), Method::Get, Default::default()); + let future = client.get(&format!("http://{}?123", server.addr()), Default::default()); let resp = future.wait().unwrap(); assert!(resp.is_success()); let body = resp.concat2().wait().unwrap(); @@ -551,7 +646,7 @@ mod test { let server = TestServer::run(); let client = Client::new().unwrap(); let abort = Abort::default().with_max_duration(Duration::from_secs(1)); - match client.fetch(&format!("http://{}/delay?3", server.addr()), Method::Get, abort).wait() { + match client.get(&format!("http://{}/delay?3", server.addr()), abort).wait() { Err(Error::Timeout) => {} other => panic!("expected timeout, got {:?}", other) } @@ -562,7 +657,7 @@ mod test { let server = TestServer::run(); let client = Client::new().unwrap(); let abort = Abort::default(); - let future = client.fetch(&format!("http://{}/redirect?http://{}/", server.addr(), server.addr()), Method::Get, abort); + let future = client.get(&format!("http://{}/redirect?http://{}/", server.addr(), server.addr()), abort); assert!(future.wait().unwrap().is_success()) } @@ -571,7 +666,7 @@ mod test { let server = TestServer::run(); let client = Client::new().unwrap(); let abort = Abort::default().with_max_redirects(4); - let future = client.fetch(&format!("http://{}/redirect?/", server.addr()), Method::Get, abort); + let future = client.get(&format!("http://{}/redirect?/", server.addr()), abort); assert!(future.wait().unwrap().is_success()) } @@ -580,7 +675,7 @@ mod test { let server = TestServer::run(); let client = Client::new().unwrap(); let abort = Abort::default().with_max_redirects(3); - match client.fetch(&format!("http://{}/loop", server.addr()), Method::Get, abort).wait() { + match client.get(&format!("http://{}/loop", server.addr()), abort).wait() { Err(Error::TooManyRedirects) => {} other => panic!("expected too many redirects error, got {:?}", other) } @@ -591,7 +686,7 @@ mod test { let server = TestServer::run(); let client = Client::new().unwrap(); let abort = Abort::default(); - let future = client.fetch(&format!("http://{}?abcdefghijklmnopqrstuvwxyz", server.addr()), Method::Get, abort); + let future = client.get(&format!("http://{}?abcdefghijklmnopqrstuvwxyz", server.addr()), abort); let resp = future.wait().unwrap(); assert!(resp.is_success()); assert_eq!(&resp.concat2().wait().unwrap()[..], b"abcdefghijklmnopqrstuvwxyz") @@ -602,7 +697,7 @@ mod test { let server = TestServer::run(); let client = Client::new().unwrap(); let abort = Abort::default().with_max_size(3); - let resp = client.fetch(&format!("http://{}/?1234", server.addr()), Method::Get, abort).wait().unwrap(); + let resp = client.get(&format!("http://{}/?1234", server.addr()), abort).wait().unwrap(); assert!(resp.is_success()); match resp.concat2().wait() { Err(Error::SizeLimit) => {} @@ -615,7 +710,7 @@ mod test { let server = TestServer::run(); let client = Client::new().unwrap(); let abort = Abort::default().with_max_size(3); - let resp = client.fetch(&format!("http://{}/?1234", server.addr()), Method::Get, abort).wait().unwrap(); + let resp = client.get(&format!("http://{}/?1234", server.addr()), abort).wait().unwrap(); assert!(resp.is_success()); let mut buffer = Vec::new(); let mut reader = BodyReader::new(resp); diff --git a/util/fetch/src/lib.rs b/util/fetch/src/lib.rs index 55785633f5a..f42aacec5b8 100644 --- a/util/fetch/src/lib.rs +++ b/util/fetch/src/lib.rs @@ -30,11 +30,11 @@ extern crate hyper_rustls; extern crate tokio_core; extern crate url; +extern crate bytes; /// Fetch client implementation. pub mod client; pub use url::Url; -pub use self::client::{Client, Fetch, Error, Response, Abort, BodyReader}; +pub use self::client::{Client, Fetch, Error, Response, Request, Abort, BodyReader}; pub use hyper::Method; - diff --git a/util/reactor/src/lib.rs b/util/reactor/src/lib.rs index f5a37fb0fcb..9c049b8f75a 100644 --- a/util/reactor/src/lib.rs +++ b/util/reactor/src/lib.rs @@ -24,7 +24,7 @@ use std::{fmt, thread}; use std::sync::mpsc; use std::time::Duration; use futures::{Future, IntoFuture}; -pub use tokio_core::reactor::{Remote as TokioRemote, Timeout}; +pub use tokio_core::reactor::{Remote as TokioRemote, Handle, Timeout}; /// Event Loop for futures. /// Wrapper around `tokio::reactor::Core`. @@ -143,18 +143,22 @@ impl Remote { /// Spawn a new future returned by given closure. pub fn spawn_fn(&self, f: F) where - F: FnOnce() -> R + Send + 'static, + F: FnOnce(&Handle) -> R + Send + 'static, R: IntoFuture, R::Future: 'static, { match self.inner { - Mode::Tokio(ref remote) => remote.spawn(move |_| f()), + Mode::Tokio(ref remote) => remote.spawn(move |handle| f(handle)), Mode::Sync => { - let _ = f().into_future().wait(); + let mut core = tokio_core::reactor::Core::new().expect("Creating an event loop should not fail."); + let handle = core.handle(); + let _ = core.run(f(&handle).into_future()); }, Mode::ThreadPerFuture => { thread::spawn(move || { - let _= f().into_future().wait(); + let mut core = tokio_core::reactor::Core::new().expect("Creating an event loop should not fail."); + let handle = core.handle(); + let _ = core.run(f(&handle).into_future()); }); }, } @@ -163,13 +167,13 @@ impl Remote { /// Spawn a new future and wait for it or for a timeout to occur. pub fn spawn_with_timeout(&self, f: F, duration: Duration, on_timeout: T) where T: FnOnce() -> () + Send + 'static, - F: FnOnce() -> R + Send + 'static, + F: FnOnce(&Handle) -> R + Send + 'static, R: IntoFuture, R::Future: 'static, { match self.inner { Mode::Tokio(ref remote) => remote.spawn(move |handle| { - let future = f().into_future(); + let future = f(handle).into_future(); let timeout = Timeout::new(duration, handle).expect("Event loop is still up."); future.select(timeout.then(move |_| { on_timeout(); @@ -177,11 +181,25 @@ impl Remote { })).then(|_| Ok(())) }), Mode::Sync => { - let _ = f().into_future().wait(); + let mut core = tokio_core::reactor::Core::new().expect("Creating an event loop should not fail."); + let handle = core.handle(); + let future = f(&handle).into_future(); + let timeout = Timeout::new(duration, &handle).expect("Event loop is still up."); + let _: Result<(), ()> = core.run(future.select(timeout.then(move |_| { + on_timeout(); + Ok(()) + })).then(|_| Ok(()))); }, Mode::ThreadPerFuture => { thread::spawn(move || { - let _ = f().into_future().wait(); + let mut core = tokio_core::reactor::Core::new().expect("Creating an event loop should not fail."); + let handle = core.handle(); + let future = f(&handle).into_future(); + let timeout = Timeout::new(duration, &handle).expect("Event loop is still up."); + let _: Result<(), ()> = core.run(future.select(timeout.then(move |_| { + on_timeout(); + Ok(()) + })).then(|_| Ok(()))); }); }, } From 4f447c50b2d90d1b012051c6fe1d0c52566ef2b4 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Tue, 10 Apr 2018 14:56:17 +0300 Subject: [PATCH 12/25] SecretStore: having , node: GenerationNode) -> Node { + fn create_node(meta: ShareChangeSessionMeta, admin_public: Public, all_nodes_set: BTreeSet, node: &GenerationNode) -> Node { for n in &all_nodes_set { node.cluster.add_node(n.clone()); } @@ -1065,18 +1072,18 @@ pub mod tests { Node { cluster: node.cluster.clone(), key_storage: node.key_storage.clone(), - session: create_session(meta, node.session.node().clone(), admin_public, all_nodes_set, node.cluster, node.key_storage), + session: create_session(meta, node.session.node().clone(), admin_public, all_nodes_set, node.cluster.clone(), node.key_storage.clone()), } } impl MessageLoop { - pub fn new(gml: GenerationMessageLoop, master_node_id: NodeId, new_nodes_ids: BTreeSet, removed_nodes_ids: BTreeSet, isolated_nodes_ids: BTreeSet) -> Self { + pub fn new(gml: &GenerationMessageLoop, master_node_id: NodeId, original_key_pair: Option, new_nodes_ids: BTreeSet, removed_nodes_ids: BTreeSet, isolated_nodes_ids: BTreeSet) -> Self { // generate admin key pair let admin_key_pair = Random.generate().unwrap(); let admin_public = admin_key_pair.public().clone(); // compute original secret key - let original_key_pair = gml.compute_key_pair(1); + let original_key_pair = original_key_pair.unwrap_or_else(|| gml.compute_key_pair(1)); // all active nodes set let mut all_nodes_set: BTreeSet<_> = gml.nodes.keys() @@ -1099,7 +1106,7 @@ pub mod tests { id: SessionId::default(), }; - let old_nodes = gml.nodes.into_iter().map(|n| create_node(meta.clone(), admin_public.clone(), all_nodes_set.clone(), n.1)); + let old_nodes = gml.nodes.iter().map(|n| create_node(meta.clone(), admin_public.clone(), all_nodes_set.clone(), n.1)); let new_nodes = new_nodes_ids.into_iter().map(|new_node_id| { let new_node_cluster = Arc::new(DummyCluster::new(new_node_id.clone())); for node in &all_nodes_set { @@ -1182,7 +1189,7 @@ pub mod tests { // insert 1 node so that it becames 2-of-4 session let nodes_to_add: BTreeSet<_> = (0..1).map(|_| Random.generate().unwrap().public().clone()).collect(); - let mut ml = MessageLoop::new(gml, master_node_id, nodes_to_add, BTreeSet::new(), BTreeSet::new()); + let mut ml = MessageLoop::new(&gml, master_node_id, None, nodes_to_add, BTreeSet::new(), BTreeSet::new()); ml.nodes[&master_node_id].session.initialize(ml.nodes.keys().cloned().collect(), ml.all_set_signature.clone(), ml.new_set_signature.clone()).unwrap(); ml.run(); @@ -1205,7 +1212,7 @@ pub mod tests { // 3) delegated session is returned back to added node let nodes_to_add: BTreeSet<_> = (0..1).map(|_| Random.generate().unwrap().public().clone()).collect(); let master_node_id = nodes_to_add.iter().cloned().nth(0).unwrap(); - let mut ml = MessageLoop::new(gml, master_node_id, nodes_to_add, BTreeSet::new(), BTreeSet::new()); + let mut ml = MessageLoop::new(&gml, master_node_id, None, nodes_to_add, BTreeSet::new(), BTreeSet::new()); ml.nodes[&master_node_id].session.initialize(ml.nodes.keys().cloned().collect(), ml.all_set_signature.clone(), ml.new_set_signature.clone()).unwrap(); ml.run(); @@ -1222,7 +1229,7 @@ pub mod tests { // remove 1 node && insert 1 node so that one share is moved let nodes_to_remove: BTreeSet<_> = gml.nodes.keys().cloned().skip(1).take(1).collect(); let nodes_to_add: BTreeSet<_> = (0..1).map(|_| Random.generate().unwrap().public().clone()).collect(); - let mut ml = MessageLoop::new(gml, master_node_id, nodes_to_add.clone(), nodes_to_remove.clone(), BTreeSet::new()); + let mut ml = MessageLoop::new(&gml, master_node_id, None, nodes_to_add.clone(), nodes_to_remove.clone(), BTreeSet::new()); let new_nodes_set = ml.nodes.keys().cloned().filter(|n| !nodes_to_remove.contains(n)).collect(); ml.nodes[&master_node_id].session.initialize(new_nodes_set, ml.all_set_signature.clone(), ml.new_set_signature.clone()).unwrap(); ml.run(); @@ -1249,7 +1256,7 @@ pub mod tests { // remove 1 node so that session becames 2-of-2 let nodes_to_remove: BTreeSet<_> = gml.nodes.keys().cloned().skip(1).take(1).collect(); let new_nodes_set: BTreeSet<_> = gml.nodes.keys().cloned().filter(|n| !nodes_to_remove.contains(&n)).collect(); - let mut ml = MessageLoop::new(gml, master_node_id, BTreeSet::new(), nodes_to_remove.clone(), BTreeSet::new()); + let mut ml = MessageLoop::new(&gml, master_node_id, None, BTreeSet::new(), nodes_to_remove.clone(), BTreeSet::new()); ml.nodes[&master_node_id].session.initialize(new_nodes_set, ml.all_set_signature.clone(), ml.new_set_signature.clone()).unwrap(); ml.run(); @@ -1275,7 +1282,7 @@ pub mod tests { // remove 1 node so that session becames 2-of-2 let nodes_to_isolate: BTreeSet<_> = gml.nodes.keys().cloned().skip(1).take(1).collect(); let new_nodes_set: BTreeSet<_> = gml.nodes.keys().cloned().filter(|n| !nodes_to_isolate.contains(&n)).collect(); - let mut ml = MessageLoop::new(gml, master_node_id, BTreeSet::new(), BTreeSet::new(), nodes_to_isolate.clone()); + let mut ml = MessageLoop::new(&gml, master_node_id, None, BTreeSet::new(), BTreeSet::new(), nodes_to_isolate.clone()); ml.nodes[&master_node_id].session.initialize(new_nodes_set, ml.all_set_signature.clone(), ml.new_set_signature.clone()).unwrap(); ml.run(); @@ -1291,4 +1298,41 @@ pub mod tests { // check that all sessions have finished assert!(ml.nodes.iter().filter(|&(k, _)| !nodes_to_isolate.contains(k)).all(|(_, v)| v.session.is_finished())); } + + #[test] + fn having_less_than_required_nodes_after_change_does_not_fail_change_session() { + // initial 2-of-3 session + let gml = generate_key(1, generate_nodes_ids(3)); + let master_node_id = gml.nodes.keys().cloned().nth(0).unwrap(); + + // remove 2 nodes so that key becomes irrecoverable (make sure the session is completed, even though key is irrecoverable) + let nodes_to_remove: BTreeSet<_> = gml.nodes.keys().cloned().skip(1).take(2).collect(); + let new_nodes_set: BTreeSet<_> = gml.nodes.keys().cloned().filter(|n| !nodes_to_remove.contains(&n)).collect(); + let mut ml = MessageLoop::new(&gml, master_node_id, None, BTreeSet::new(), nodes_to_remove.clone(), BTreeSet::new()); + ml.nodes[&master_node_id].session.initialize(new_nodes_set, ml.all_set_signature.clone(), ml.new_set_signature.clone()).unwrap(); + ml.run(); + + // check that all removed nodes do not own key share + assert!(ml.nodes.iter().filter(|&(k, _)| nodes_to_remove.contains(k)).all(|(_, v)| v.key_storage.get(&SessionId::default()).unwrap().is_none())); + + // check that all sessions have finished + assert!(ml.nodes.values().all(|n| n.session.is_finished())); + + // and now let's add new node (make sure the session is completed, even though key is still irrecoverable) + // isolated here are not actually isolated, but removed on the previous step + let nodes_to_add: BTreeSet<_> = (0..1).map(|_| Random.generate().unwrap().public().clone()).collect(); + let new_nodes_set: BTreeSet<_> = gml.nodes.keys().cloned().filter(|n| !nodes_to_remove.contains(&n)) + .chain(nodes_to_add.iter().cloned()) + .collect(); + let master_node_id = nodes_to_add.iter().cloned().nth(0).unwrap(); + let mut ml = MessageLoop::new(&gml, master_node_id, Some(ml.original_key_pair.clone()), nodes_to_add.clone(), BTreeSet::new(), nodes_to_remove.clone()); + ml.nodes[&master_node_id].session.initialize(new_nodes_set, ml.all_set_signature.clone(), ml.new_set_signature.clone()).unwrap(); + ml.run(); + + // check that all added nodes do not own key share (there's not enough nodes to run share add session) + assert!(ml.nodes.iter().filter(|&(k, _)| nodes_to_add.contains(k)).all(|(_, v)| v.key_storage.get(&SessionId::default()).unwrap().is_none())); + + // check that all sessions have finished + assert!(ml.nodes.iter().filter(|&(k, _)| !nodes_to_remove.contains(k)).all(|(_, n)| n.session.is_finished())); + } } 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 228d7ba9876..1e408ee52e7 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 @@ -18,7 +18,7 @@ use std::sync::Arc; use std::collections::{BTreeSet, BTreeMap}; use ethereum_types::H256; use ethkey::Secret; -use key_server_cluster::{Error, NodeId, SessionId, KeyStorage}; +use key_server_cluster::{Error, NodeId, SessionId, ServerKeyId, KeyStorage}; use key_server_cluster::cluster::Cluster; use key_server_cluster::cluster_sessions::ClusterSession; use key_server_cluster::math; @@ -235,7 +235,24 @@ impl ShareAddSessionTransport for ShareChangeTransport { } /// Prepare share change plan for moving from old `old_key_version_owners` to `new_nodes_set`. -pub fn prepare_share_change_session_plan(cluster_nodes: &BTreeSet, threshold: usize, key_version: H256, master: &NodeId, old_key_version_owners: &BTreeSet, new_nodes_set: &BTreeSet) -> Result { +pub fn prepare_share_change_session_plan(cluster_nodes: &BTreeSet, threshold: usize, key_id: &ServerKeyId, key_version: H256, master: &NodeId, old_key_version_owners: &BTreeSet, new_nodes_set: &BTreeSet) -> Result { + // we can't do anything if there are no enought shares + if old_key_version_owners.len() < threshold + 1 { + warn!("cannot add shares to key {} with threshold {}: only {} shares owners are available", + key_id, threshold, old_key_version_owners.len()); + return Ok(ShareChangeSessionPlan { + key_version: key_version, + consensus_group: Default::default(), + new_nodes_map: Default::default(), + }); + } + + // warn if we're loosing the key + if new_nodes_set.len() < threshold + 1 { + warn!("losing key {} with threshold {}: only {} nodes left after servers set change session", + key_id, threshold, new_nodes_set.len()); + } + // make new nodes map, so that: // all non-isolated old nodes will have their id number preserved // all new nodes will have new id number @@ -285,7 +302,8 @@ mod tests { let master = cluster_nodes[0].clone(); let old_key_version_owners = cluster_nodes.iter().cloned().collect(); let new_nodes_set = cluster_nodes.iter().cloned().collect(); - let plan = prepare_share_change_session_plan(&cluster_nodes.iter().cloned().collect(), 1, Default::default(), &master, &old_key_version_owners, &new_nodes_set).unwrap(); + let plan = prepare_share_change_session_plan(&cluster_nodes.iter().cloned().collect(), + 1, &Default::default(), Default::default(), &master, &old_key_version_owners, &new_nodes_set).unwrap(); assert!(plan.is_empty()); } @@ -296,7 +314,8 @@ mod tests { let master = cluster_nodes[0].clone(); let old_key_version_owners = cluster_nodes[0..2].iter().cloned().collect(); let new_nodes_set = cluster_nodes.iter().cloned().collect(); - let plan = prepare_share_change_session_plan(&cluster_nodes.iter().cloned().collect(), 1, Default::default(), &master, &old_key_version_owners, &new_nodes_set).unwrap(); + let plan = prepare_share_change_session_plan(&cluster_nodes.iter().cloned().collect(), + 1, &Default::default(), Default::default(), &master, &old_key_version_owners, &new_nodes_set).unwrap(); assert!(!plan.is_empty()); assert_eq!(old_key_version_owners, plan.consensus_group); From bd7273061e3f13f53fdd2fa91dc641a83bcc47f0 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Tue, 10 Apr 2018 13:56:56 +0200 Subject: [PATCH 13/25] ethcrypto renamed to ethcore-crypto and moved to ethcore dir (#8340) * ethcrypto renamed to ethcore-crypto and moved to ethcore dir * fixed renaming --- Cargo.lock | 38 +++++++++---------- {ethcrypto => ethcore/crypto}/Cargo.toml | 4 +- {ethcrypto => ethcore/crypto}/README.md | 0 {ethcrypto => ethcore/crypto}/src/lib.rs | 0 ethcore/private-tx/Cargo.toml | 2 +- ethcore/private-tx/src/encryptor.rs | 8 ++-- ethcore/private-tx/src/lib.rs | 6 +-- ethstore/Cargo.toml | 2 +- ethstore/src/lib.rs | 2 +- rpc/Cargo.toml | 2 +- rpc/src/lib.rs | 2 +- secret_store/Cargo.toml | 4 +- secret_store/src/key_server.rs | 32 ++++++++-------- .../client_sessions/decryption_session.rs | 8 ++-- .../src/key_server_cluster/io/handshake.rs | 2 +- .../src/key_server_cluster/io/message.rs | 4 +- .../key_server_cluster/jobs/decryption_job.rs | 4 +- secret_store/src/key_server_cluster/mod.rs | 6 +-- secret_store/src/lib.rs | 2 +- secret_store/src/node_key_pair.rs | 2 +- util/network-devp2p/Cargo.toml | 4 +- util/network-devp2p/src/lib.rs | 2 +- util/network/Cargo.toml | 6 +-- util/network/src/lib.rs | 2 +- whisper/Cargo.toml | 2 +- whisper/src/lib.rs | 2 +- whisper/src/rpc/crypto.rs | 5 ++- 27 files changed, 77 insertions(+), 76 deletions(-) rename {ethcrypto => ethcore/crypto}/Cargo.toml (81%) rename {ethcrypto => ethcore/crypto}/README.md (100%) rename {ethcrypto => ethcore/crypto}/src/lib.rs (100%) diff --git a/Cargo.lock b/Cargo.lock index f802b863e48..71ad5fc0bb6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -566,6 +566,18 @@ dependencies = [ name = "ethcore-bytes" version = "0.1.0" +[[package]] +name = "ethcore-crypto" +version = "0.1.0" +dependencies = [ + "eth-secp256k1 0.5.7 (git+https://github.com/paritytech/rust-secp256k1)", + "ethereum-types 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethkey 0.3.0", + "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)", +] + [[package]] name = "ethcore-devtools" version = "1.11.0" @@ -671,8 +683,8 @@ name = "ethcore-network" version = "1.11.0" dependencies = [ "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethcore-crypto 0.1.0", "ethcore-io 1.11.0", - "ethcrypto 0.1.0", "ethereum-types 0.3.0 (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)", @@ -688,10 +700,10 @@ dependencies = [ "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", + "ethcore-crypto 0.1.0", "ethcore-io 1.11.0", "ethcore-logger 1.11.0", "ethcore-network 1.11.0", - "ethcrypto 0.1.0", "ethereum-types 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethkey 0.3.0", "igd 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -725,11 +737,11 @@ dependencies = [ "ethabi-derive 5.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore 1.11.0", "ethcore-bytes 0.1.0", + "ethcore-crypto 0.1.0", "ethcore-io 1.11.0", "ethcore-logger 1.11.0", "ethcore-miner 1.11.0", "ethcore-transaction 0.1.0", - "ethcrypto 0.1.0", "ethereum-types 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethjson 0.1.0", "ethkey 0.3.0", @@ -760,10 +772,10 @@ dependencies = [ "ethabi-derive 5.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore 1.11.0", "ethcore-bytes 0.1.0", + "ethcore-crypto 0.1.0", "ethcore-logger 1.11.0", "ethcore-sync 1.11.0", "ethcore-transaction 0.1.0", - "ethcrypto 0.1.0", "ethereum-types 0.3.0 (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)", @@ -868,18 +880,6 @@ dependencies = [ "unexpected 0.1.0", ] -[[package]] -name = "ethcrypto" -version = "0.1.0" -dependencies = [ - "eth-secp256k1 0.5.7 (git+https://github.com/paritytech/rust-secp256k1)", - "ethereum-types 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "ethkey 0.3.0", - "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)", -] - [[package]] name = "ethereum-types" version = "0.3.0" @@ -950,7 +950,7 @@ name = "ethstore" version = "0.2.0" dependencies = [ "dir 0.1.0", - "ethcrypto 0.1.0", + "ethcore-crypto 0.1.0", "ethereum-types 0.3.0 (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)", @@ -2157,6 +2157,7 @@ dependencies = [ "ethash 1.11.0", "ethcore 1.11.0", "ethcore-bytes 0.1.0", + "ethcore-crypto 0.1.0", "ethcore-devtools 1.11.0", "ethcore-io 1.11.0", "ethcore-light 1.11.0", @@ -2166,7 +2167,6 @@ dependencies = [ "ethcore-private-tx 1.0.0", "ethcore-sync 1.11.0", "ethcore-transaction 0.1.0", - "ethcrypto 0.1.0", "ethereum-types 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethjson 0.1.0", "ethkey 0.3.0", @@ -2341,8 +2341,8 @@ version = "0.1.0" dependencies = [ "bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ethcore-crypto 0.1.0", "ethcore-network 1.11.0", - "ethcrypto 0.1.0", "ethereum-types 0.3.0 (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)", diff --git a/ethcrypto/Cargo.toml b/ethcore/crypto/Cargo.toml similarity index 81% rename from ethcrypto/Cargo.toml rename to ethcore/crypto/Cargo.toml index 887b44ab4f4..c3a2191b55a 100644 --- a/ethcrypto/Cargo.toml +++ b/ethcore/crypto/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "ethcrypto" +name = "ethcore-crypto" version = "0.1.0" authors = ["Parity Technologies "] @@ -7,7 +7,7 @@ authors = ["Parity Technologies "] 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 } +ethkey = { path = "../../ethkey", optional = true } ethereum-types = "0.3" subtle = "0.5" diff --git a/ethcrypto/README.md b/ethcore/crypto/README.md similarity index 100% rename from ethcrypto/README.md rename to ethcore/crypto/README.md diff --git a/ethcrypto/src/lib.rs b/ethcore/crypto/src/lib.rs similarity index 100% rename from ethcrypto/src/lib.rs rename to ethcore/crypto/src/lib.rs diff --git a/ethcore/private-tx/Cargo.toml b/ethcore/private-tx/Cargo.toml index ff37f20ab2b..0fa11aec84b 100644 --- a/ethcore/private-tx/Cargo.toml +++ b/ethcore/private-tx/Cargo.toml @@ -12,11 +12,11 @@ ethabi-contract = "5.0" ethabi-derive = "5.0" ethcore = { path = ".." } ethcore-bytes = { path = "../../util/bytes" } +ethcore-crypto = { path = "../crypto" } ethcore-io = { path = "../../util/io" } ethcore-logger = { path = "../../logger" } ethcore-miner = { path = "../../miner" } ethcore-transaction = { path = "../transaction" } -ethcrypto = { path = "../../ethcrypto" } ethereum-types = "0.3" ethjson = { path = "../../json" } ethkey = { path = "../../ethkey" } diff --git a/ethcore/private-tx/src/encryptor.rs b/ethcore/private-tx/src/encryptor.rs index fd7eaa680f7..5d592de6032 100644 --- a/ethcore/private-tx/src/encryptor.rs +++ b/ethcore/private-tx/src/encryptor.rs @@ -27,7 +27,7 @@ use ethcore::account_provider::AccountProvider; use ethereum_types::{H128, H256, Address}; use ethjson; use ethkey::{Signature, Public}; -use ethcrypto; +use crypto; use futures::Future; use fetch::{Fetch, Client as FetchClient, Method, BodyReader, Request}; use bytes::{Bytes, ToPretty}; @@ -151,7 +151,7 @@ impl SecretStoreEncryptor { let password = find_account_password(&self.config.passwords, &*accounts, &requester); // decrypt Public - let decrypted_bytes = accounts.decrypt(requester, password, ðcrypto::DEFAULT_MAC, &encrypted_bytes)?; + let decrypted_bytes = accounts.decrypt(requester, password, &crypto::DEFAULT_MAC, &encrypted_bytes)?; let decrypted_key = Public::from_slice(&decrypted_bytes); // and now take x coordinate of Public as a key @@ -217,7 +217,7 @@ 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())); - ethcrypto::aes::encrypt(&key, initialisation_vector, plain_data, &mut cypher); + crypto::aes::encrypt(&key, initialisation_vector, plain_data, &mut cypher); cypher.extend_from_slice(&initialisation_vector); Ok(cypher) @@ -243,7 +243,7 @@ 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)); - ethcrypto::aes::decrypt(&key, &iv, cypher, &mut plain_data); + crypto::aes::decrypt(&key, &iv, cypher, &mut plain_data); Ok(plain_data) } diff --git a/ethcore/private-tx/src/lib.rs b/ethcore/private-tx/src/lib.rs index 5b7a62b7cd3..ef97c6e2e6d 100644 --- a/ethcore/private-tx/src/lib.rs +++ b/ethcore/private-tx/src/lib.rs @@ -26,11 +26,11 @@ mod messages; mod error; extern crate ethcore; -extern crate ethcore_io as io; extern crate ethcore_bytes as bytes; -extern crate ethcore_transaction as transaction; +extern crate ethcore_crypto as crypto; +extern crate ethcore_io as io; extern crate ethcore_miner; -extern crate ethcrypto; +extern crate ethcore_transaction as transaction; extern crate ethabi; extern crate ethereum_types; extern crate ethkey; diff --git a/ethstore/Cargo.toml b/ethstore/Cargo.toml index 34f61a8f753..d0524baeafd 100755 --- a/ethstore/Cargo.toml +++ b/ethstore/Cargo.toml @@ -17,7 +17,7 @@ tiny-keccak = "1.3" time = "0.1.34" itertools = "0.5" parking_lot = "0.5" -ethcrypto = { path = "../ethcrypto" } +ethcore-crypto = { path = "../ethcore/crypto" } ethereum-types = "0.3" dir = { path = "../util/dir" } smallvec = "0.4" diff --git a/ethstore/src/lib.rs b/ethstore/src/lib.rs index 3422a5ff72f..75df0953ce4 100755 --- a/ethstore/src/lib.rs +++ b/ethstore/src/lib.rs @@ -33,7 +33,7 @@ extern crate time; extern crate tiny_keccak; extern crate tempdir; -extern crate ethcrypto as crypto; +extern crate ethcore_crypto as crypto; extern crate ethereum_types; extern crate ethkey as _ethkey; extern crate parity_wordlist; diff --git a/rpc/Cargo.toml b/rpc/Cargo.toml index 7f975ca9dd1..c467f055375 100644 --- a/rpc/Cargo.toml +++ b/rpc/Cargo.toml @@ -39,6 +39,7 @@ jsonrpc-pubsub = { git = "https://github.com/paritytech/jsonrpc.git", branch = " ethash = { path = "../ethash" } ethcore = { path = "../ethcore" } ethcore-bytes = { path = "../util/bytes" } +ethcore-crypto = { path = "../ethcore/crypto" } ethcore-devtools = { path = "../devtools" } ethcore-io = { path = "../util/io" } ethcore-light = { path = "../ethcore/light" } @@ -49,7 +50,6 @@ ethcore-sync = { path = "../ethcore/sync" } ethcore-transaction = { path = "../ethcore/transaction" } ethereum-types = "0.3" -ethcrypto = { path = "../ethcrypto" } ethjson = { path = "../json" } ethkey = { path = "../ethkey" } ethstore = { path = "../ethstore" } diff --git a/rpc/src/lib.rs b/rpc/src/lib.rs index 13e700375e8..1a0989d4a2a 100644 --- a/rpc/src/lib.rs +++ b/rpc/src/lib.rs @@ -46,6 +46,7 @@ extern crate jsonrpc_pubsub; extern crate ethash; extern crate ethcore; extern crate ethcore_bytes as bytes; +extern crate ethcore_crypto as crypto; extern crate ethcore_devtools as devtools; extern crate ethcore_io as io; extern crate ethcore_light as light; @@ -54,7 +55,6 @@ extern crate ethcore_miner as miner; extern crate ethcore_private_tx; extern crate ethcore_sync as sync; extern crate ethcore_transaction as transaction; -extern crate ethcrypto as crypto; extern crate ethereum_types; extern crate ethkey; extern crate ethstore; diff --git a/secret_store/Cargo.toml b/secret_store/Cargo.toml index b9dee7303b7..fcd022f7d9f 100644 --- a/secret_store/Cargo.toml +++ b/secret_store/Cargo.toml @@ -24,14 +24,14 @@ tokio-proto = "0.1" url = "1.0" ethcore = { path = "../ethcore" } ethcore-bytes = { path = "../util/bytes" } +ethcore-crypto = { path = "../ethcore/crypto" } +ethcore-logger = { path = "../logger" } ethcore-sync = { path = "../ethcore/sync" } ethcore-transaction = { path = "../ethcore/transaction" } ethereum-types = "0.3" kvdb = { path = "../util/kvdb" } kvdb-rocksdb = { path = "../util/kvdb-rocksdb" } keccak-hash = { path = "../util/hash" } -ethcore-logger = { path = "../logger" } -ethcrypto = { path = "../ethcrypto" } ethkey = { path = "../ethkey" } lazy_static = "1.0" ethabi = "5.1" diff --git a/secret_store/src/key_server.rs b/secret_store/src/key_server.rs index 02d19eede1f..783e760455f 100644 --- a/secret_store/src/key_server.rs +++ b/secret_store/src/key_server.rs @@ -21,7 +21,7 @@ use std::sync::mpsc; use futures::{self, Future}; use parking_lot::Mutex; use tokio_core::reactor::Core; -use ethcrypto; +use crypto; use super::acl_storage::AclStorage; use super::key_storage::KeyStorage; use super::key_server_set::KeyServerSet; @@ -105,7 +105,7 @@ impl DocumentKeyServer for KeyServerImpl { self.store_document_key(key_id, author, encrypted_document_key.common_point, encrypted_document_key.encrypted_point)?; // encrypt document key with requestor public key - let document_key = ethcrypto::ecies::encrypt(&public, ðcrypto::DEFAULT_MAC, &document_key) + let document_key = crypto::ecies::encrypt(&public, &crypto::DEFAULT_MAC, &document_key) .map_err(|err| Error::Internal(format!("Error encrypting document key: {}", err)))?; Ok(document_key) } @@ -122,7 +122,7 @@ impl DocumentKeyServer for KeyServerImpl { .decrypted_secret; // encrypt document key with requestor public key - let document_key = ethcrypto::ecies::encrypt(&public, ðcrypto::DEFAULT_MAC, &document_key) + let document_key = crypto::ecies::encrypt(&public, &crypto::DEFAULT_MAC, &document_key) .map_err(|err| Error::Internal(format!("Error encrypting document key: {}", err)))?; Ok(document_key) } @@ -152,7 +152,7 @@ impl MessageSigner for KeyServerImpl { combined_signature[32..].clone_from_slice(&**message_signature.1); // encrypt combined signature with requestor public key - let message_signature = ethcrypto::ecies::encrypt(&public, ðcrypto::DEFAULT_MAC, &combined_signature) + let message_signature = crypto::ecies::encrypt(&public, &crypto::DEFAULT_MAC, &combined_signature) .map_err(|err| Error::Internal(format!("Error encrypting message signature: {}", err)))?; Ok(message_signature) } @@ -167,7 +167,7 @@ impl MessageSigner for KeyServerImpl { let message_signature = signing_session.wait()?; // encrypt combined signature with requestor public key - let message_signature = ethcrypto::ecies::encrypt(&public, ðcrypto::DEFAULT_MAC, &*message_signature) + let message_signature = crypto::ecies::encrypt(&public, &crypto::DEFAULT_MAC, &*message_signature) .map_err(|err| Error::Internal(format!("Error encrypting message signature: {}", err)))?; Ok(message_signature) } @@ -229,7 +229,7 @@ pub mod tests { use std::sync::Arc; use std::net::SocketAddr; use std::collections::BTreeMap; - use ethcrypto; + use crypto; use ethkey::{self, Secret, Random, Generator, verify_public}; use acl_storage::DummyAclStorage; use key_storage::KeyStorage; @@ -358,12 +358,12 @@ pub mod tests { let secret = Random.generate().unwrap().secret().clone(); let signature = ethkey::sign(&secret, &document).unwrap(); let generated_key = key_servers[0].generate_document_key(&document, &signature.clone().into(), threshold).unwrap(); - let generated_key = ethcrypto::ecies::decrypt(&secret, ðcrypto::DEFAULT_MAC, &generated_key).unwrap(); + let generated_key = crypto::ecies::decrypt(&secret, &crypto::DEFAULT_MAC, &generated_key).unwrap(); // now let's try to retrieve key back for key_server in key_servers.iter() { let retrieved_key = key_server.restore_document_key(&document, &signature.clone().into()).unwrap(); - let retrieved_key = ethcrypto::ecies::decrypt(&secret, ðcrypto::DEFAULT_MAC, &retrieved_key).unwrap(); + let retrieved_key = crypto::ecies::decrypt(&secret, &crypto::DEFAULT_MAC, &retrieved_key).unwrap(); assert_eq!(retrieved_key, generated_key); } } @@ -380,12 +380,12 @@ pub mod tests { let secret = Random.generate().unwrap().secret().clone(); let signature = ethkey::sign(&secret, &document).unwrap(); let generated_key = key_servers[0].generate_document_key(&document, &signature.clone().into(), *threshold).unwrap(); - let generated_key = ethcrypto::ecies::decrypt(&secret, ðcrypto::DEFAULT_MAC, &generated_key).unwrap(); + let generated_key = crypto::ecies::decrypt(&secret, &crypto::DEFAULT_MAC, &generated_key).unwrap(); // now let's try to retrieve key back for (i, key_server) in key_servers.iter().enumerate() { let retrieved_key = key_server.restore_document_key(&document, &signature.clone().into()).unwrap(); - let retrieved_key = ethcrypto::ecies::decrypt(&secret, ðcrypto::DEFAULT_MAC, &retrieved_key).unwrap(); + let retrieved_key = crypto::ecies::decrypt(&secret, &crypto::DEFAULT_MAC, &retrieved_key).unwrap(); assert_eq!(retrieved_key, generated_key); let key_share = key_storages[i].get(&document).unwrap().unwrap(); @@ -419,7 +419,7 @@ pub mod tests { // now let's try to retrieve key back for key_server in key_servers.iter() { let retrieved_key = key_server.restore_document_key(&server_key_id, &signature.clone().into()).unwrap(); - let retrieved_key = ethcrypto::ecies::decrypt(&requestor_secret, ðcrypto::DEFAULT_MAC, &retrieved_key).unwrap(); + let retrieved_key = crypto::ecies::decrypt(&requestor_secret, &crypto::DEFAULT_MAC, &retrieved_key).unwrap(); let retrieved_key = Public::from_slice(&retrieved_key); assert_eq!(retrieved_key, generated_key); } @@ -442,7 +442,7 @@ pub mod tests { // sign message let message_hash = H256::from(42); let combined_signature = key_servers[0].sign_message_schnorr(&server_key_id, &signature.into(), message_hash.clone()).unwrap(); - let combined_signature = ethcrypto::ecies::decrypt(&requestor_secret, ðcrypto::DEFAULT_MAC, &combined_signature).unwrap(); + let combined_signature = crypto::ecies::decrypt(&requestor_secret, &crypto::DEFAULT_MAC, &combined_signature).unwrap(); let signature_c = Secret::from_slice(&combined_signature[..32]); let signature_s = Secret::from_slice(&combined_signature[32..]); @@ -462,14 +462,14 @@ pub mod tests { let secret = Random.generate().unwrap().secret().clone(); let signature = ethkey::sign(&secret, &document).unwrap(); let generated_key = key_servers[0].generate_document_key(&document, &signature.clone().into(), threshold).unwrap(); - let generated_key = ethcrypto::ecies::decrypt(&secret, ðcrypto::DEFAULT_MAC, &generated_key).unwrap(); + let generated_key = crypto::ecies::decrypt(&secret, &crypto::DEFAULT_MAC, &generated_key).unwrap(); // remove key from node0 key_servers[0].cluster().key_storage().remove(&document).unwrap(); // now let's try to retrieve key back by requesting it from node0, so that session must be delegated let retrieved_key = key_servers[0].restore_document_key(&document, &signature.into()).unwrap(); - let retrieved_key = ethcrypto::ecies::decrypt(&secret, ðcrypto::DEFAULT_MAC, &retrieved_key).unwrap(); + let retrieved_key = crypto::ecies::decrypt(&secret, &crypto::DEFAULT_MAC, &retrieved_key).unwrap(); assert_eq!(retrieved_key, generated_key); } @@ -491,7 +491,7 @@ pub mod tests { // sign message let message_hash = H256::from(42); let combined_signature = key_servers[0].sign_message_schnorr(&server_key_id, &signature.into(), message_hash.clone()).unwrap(); - let combined_signature = ethcrypto::ecies::decrypt(&requestor_secret, ðcrypto::DEFAULT_MAC, &combined_signature).unwrap(); + let combined_signature = crypto::ecies::decrypt(&requestor_secret, &crypto::DEFAULT_MAC, &combined_signature).unwrap(); let signature_c = Secret::from_slice(&combined_signature[..32]); let signature_s = Secret::from_slice(&combined_signature[32..]); @@ -517,7 +517,7 @@ pub mod tests { // sign message let message_hash = H256::random(); let signature = key_servers[0].sign_message_ecdsa(&server_key_id, &signature.into(), message_hash.clone()).unwrap(); - let signature = ethcrypto::ecies::decrypt(&requestor_secret, ðcrypto::DEFAULT_MAC, &signature).unwrap(); + let signature = crypto::ecies::decrypt(&requestor_secret, &crypto::DEFAULT_MAC, &signature).unwrap(); let signature: H520 = signature[0..65].into(); // check signature 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 49c4e26d61b..3343652c2bc 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 @@ -1269,8 +1269,8 @@ mod tests { assert!(decrypted_secret.common_point.is_some()); assert!(decrypted_secret.decrypt_shadows.is_some()); // check that KS client is able to restore original secret - use ethcrypto::DEFAULT_MAC; - use ethcrypto::ecies::decrypt; + use crypto::DEFAULT_MAC; + use crypto::ecies::decrypt; let decrypt_shadows: Vec<_> = decrypted_secret.decrypt_shadows.unwrap().into_iter() .map(|c| Secret::from_slice(&decrypt(key_pair.secret(), &DEFAULT_MAC, &c).unwrap())) .collect(); @@ -1413,8 +1413,8 @@ mod tests { assert_eq!(1, sessions.iter().skip(1).filter(|s| s.broadcast_shadows().is_none()).count()); // 4 nodes must be able to recover original secret - use ethcrypto::DEFAULT_MAC; - use ethcrypto::ecies::decrypt; + use crypto::DEFAULT_MAC; + use 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 c48ed27daed..838e48e1f74 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 ethcrypto::ecdh::agree; +use 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 94030ef416d..784b0b2b6a4 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 ethcrypto::ecies; +use 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 ethcrypto::ecdh::agree; + use 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 7bf1a294acb..6864665f3bc 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 ethcrypto::ecies::encrypt; -use ethcrypto::DEFAULT_MAC; +use crypto::ecies::encrypt; +use crypto::DEFAULT_MAC; 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/key_server_cluster/mod.rs b/secret_store/src/key_server_cluster/mod.rs index 804c85e311b..94386d0510a 100644 --- a/secret_store/src/key_server_cluster/mod.rs +++ b/secret_store/src/key_server_cluster/mod.rs @@ -17,7 +17,7 @@ use std::fmt; use std::io::Error as IoError; use ethkey; -use ethcrypto; +use crypto; use super::types::all::ServerKeyId; pub use super::traits::NodeKeyPair; @@ -124,8 +124,8 @@ impl From for Error { } } -impl From for Error { - fn from(err: ethcrypto::Error) -> Self { +impl From for Error { + fn from(err: crypto::Error) -> Self { Error::EthKey(err.into()) } } diff --git a/secret_store/src/lib.rs b/secret_store/src/lib.rs index c087d665112..9a7310b11db 100644 --- a/secret_store/src/lib.rs +++ b/secret_store/src/lib.rs @@ -18,10 +18,10 @@ extern crate byteorder; extern crate ethabi; extern crate ethcore; extern crate ethcore_bytes as bytes; +extern crate ethcore_crypto as crypto; extern crate ethcore_logger as logger; extern crate ethcore_sync as sync; extern crate ethcore_transaction as transaction; -extern crate ethcrypto; extern crate ethereum_types; extern crate ethkey; extern crate futures_cpupool; diff --git a/secret_store/src/node_key_pair.rs b/secret_store/src/node_key_pair.rs index 75c84018568..55c2a8a28a1 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 ethcrypto::ecdh::agree; +use 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}; diff --git a/util/network-devp2p/Cargo.toml b/util/network-devp2p/Cargo.toml index 466ff95161d..f6718d6b51c 100644 --- a/util/network-devp2p/Cargo.toml +++ b/util/network-devp2p/Cargo.toml @@ -21,13 +21,13 @@ ansi_term = "0.10" rustc-hex = "1.0" ethcore-io = { path = "../io" } ethcore-bytes = { path = "../bytes" } +ethcore-crypto = { path = "../../ethcore/crypto" } +ethcore-logger = { path ="../../logger" } ethcore-network = { path = "../network" } ethereum-types = "0.3" ethkey = { path = "../../ethkey" } -ethcrypto = { path = "../../ethcrypto" } rlp = { path = "../rlp" } path = { path = "../path" } -ethcore-logger = { path ="../../logger" } ipnetwork = "0.12.6" keccak-hash = { path = "../hash" } snappy = { git = "https://github.com/paritytech/rust-snappy" } diff --git a/util/network-devp2p/src/lib.rs b/util/network-devp2p/src/lib.rs index fc3e66e3a5d..f326ff4b1ee 100644 --- a/util/network-devp2p/src/lib.rs +++ b/util/network-devp2p/src/lib.rs @@ -61,6 +61,7 @@ extern crate ethcore_io as io; extern crate ethcore_bytes; +extern crate ethcore_crypto as crypto; extern crate ethereum_types; extern crate parking_lot; extern crate mio; @@ -73,7 +74,6 @@ extern crate igd; extern crate libc; extern crate slab; extern crate ethkey; -extern crate ethcrypto as crypto; extern crate rlp; extern crate bytes; extern crate path; diff --git a/util/network/Cargo.toml b/util/network/Cargo.toml index 7d3d48b5af9..f98cd9e93ca 100644 --- a/util/network/Cargo.toml +++ b/util/network/Cargo.toml @@ -7,11 +7,11 @@ version = "1.11.0" authors = ["Parity Technologies "] [dependencies] +error-chain = { version = "0.11", default-features = false } +ethcore-crypto = { path = "../../ethcore/crypto" } ethcore-io = { path = "../io" } ethereum-types = "0.3" ethkey = { path = "../../ethkey" } -ethcrypto = { path = "../../ethcrypto" } -rlp = { path = "../rlp" } ipnetwork = "0.12.6" +rlp = { path = "../rlp" } snappy = { git = "https://github.com/paritytech/rust-snappy" } -error-chain = { version = "0.11", default-features = false } diff --git a/util/network/src/lib.rs b/util/network/src/lib.rs index 7bd13d1f392..55c31dd2e64 100644 --- a/util/network/src/lib.rs +++ b/util/network/src/lib.rs @@ -16,8 +16,8 @@ #![recursion_limit="128"] +extern crate ethcore_crypto as crypto; extern crate ethcore_io as io; -extern crate ethcrypto as crypto; extern crate ethereum_types; extern crate ethkey; extern crate rlp; diff --git a/whisper/Cargo.toml b/whisper/Cargo.toml index b972bf5cf1b..49d4dffede5 100644 --- a/whisper/Cargo.toml +++ b/whisper/Cargo.toml @@ -9,7 +9,7 @@ bitflags = "0.9" byteorder = "1.0.0" ethereum-types = "0.3" ethcore-network = { path = "../util/network" } -ethcrypto = { path = "../ethcrypto" } +ethcore-crypto = { path = "../ethcore/crypto" } ethkey = { path = "../ethkey" } hex = "0.2" log = "0.3" diff --git a/whisper/src/lib.rs b/whisper/src/lib.rs index 1f8449604bd..bcee122ec01 100644 --- a/whisper/src/lib.rs +++ b/whisper/src/lib.rs @@ -18,8 +18,8 @@ //! interface. extern crate byteorder; +extern crate ethcore_crypto as crypto; extern crate ethcore_network as network; -extern crate ethcrypto; extern crate ethereum_types; extern crate ethkey; extern crate hex; diff --git a/whisper/src/rpc/crypto.rs b/whisper/src/rpc/crypto.rs index 8dcfed88a61..e7782a07725 100644 --- a/whisper/src/rpc/crypto.rs +++ b/whisper/src/rpc/crypto.rs @@ -16,6 +16,7 @@ //! Encryption schemes supported by RPC layer. +use crypto; use ethereum_types::H256; use ethkey::{self, Public, Secret}; use ring::aead::{self, AES_256_GCM, SealingKey, OpeningKey}; @@ -117,7 +118,7 @@ impl EncryptionInstance { } } EncryptionInner::ECIES(valid_public) => { - ::ethcrypto::ecies::encrypt(&valid_public, &[], plain) + crypto::ecies::encrypt(&valid_public, &[], plain) .expect("validity of public key an invariant of the type; qed") } } @@ -213,7 +214,7 @@ impl DecryptionInstance { } DecryptionInner::ECIES(secret) => { // secret is checked for validity, so only fails on invalid message. - ::ethcrypto::ecies::decrypt(&secret, &[], ciphertext).ok() + crypto::ecies::decrypt(&secret, &[], ciphertext).ok() } } } From 8348147a4ff101688736f82b36d2da78d9348486 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Tue, 10 Apr 2018 16:14:15 +0200 Subject: [PATCH 14/25] Enable UI by default, but only display deprecation notice (#8262) * Enable UI by default, but only display info page. * Fix test. * Fix naming and remove old todo. * Change "wallet" with "browser UI" * Update text, its not deprecated, its moved --- Cargo.lock | 8 ++ dapps/Cargo.toml | 1 + dapps/src/apps/mod.rs | 13 +-- dapps/src/lib.rs | 19 ++++ dapps/src/router.rs | 14 ++- dapps/src/tests/helpers/mod.rs | 1 + 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 ++++++++++++ parity/configuration.rs | 110 +++++++++++++++++------- parity/dapps.rs | 2 + parity/rpc.rs | 6 +- parity/run.rs | 4 +- 15 files changed, 369 insertions(+), 43 deletions(-) create mode 100644 dapps/ui-deprecation/Cargo.toml create mode 100644 dapps/ui-deprecation/build.rs create mode 100644 dapps/ui-deprecation/build/index.html create mode 100644 dapps/ui-deprecation/src/lib.rs create mode 100644 dapps/ui-deprecation/src/lib.rs.in diff --git a/Cargo.lock b/Cargo.lock index 71ad5fc0bb6..4f86b1df4b8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2037,6 +2037,7 @@ dependencies = [ "parity-hash-fetch 1.11.0", "parity-reactor 0.1.0", "parity-ui 1.11.0", + "parity-ui-deprecation 1.10.0", "parity-version 1.11.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)", @@ -2256,6 +2257,13 @@ dependencies = [ "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" diff --git a/dapps/Cargo.toml b/dapps/Cargo.toml index d63150b0a55..fdd497763f1 100644 --- a/dapps/Cargo.toml +++ b/dapps/Cargo.toml @@ -35,6 +35,7 @@ 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" } diff --git a/dapps/src/apps/mod.rs b/dapps/src/apps/mod.rs index 0b8865e76f9..21947b928bf 100644 --- a/dapps/src/apps/mod.rs +++ b/dapps/src/apps/mod.rs @@ -23,7 +23,6 @@ use page; use proxypac::ProxyPac; use web::Web; use fetch::Fetch; -use parity_ui; use {WebProxyTokens, ParentFrameSettings}; mod app; @@ -43,11 +42,15 @@ 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())) + 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())) + 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 { @@ -77,13 +80,13 @@ pub fn all_endpoints( // 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())) + 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()); + 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 diff --git a/dapps/src/lib.rs b/dapps/src/lib.rs index 482ee395958..c4e244b251d 100644 --- a/dapps/src/lib.rs +++ b/dapps/src/lib.rs @@ -39,6 +39,7 @@ 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; @@ -159,6 +160,7 @@ impl Middleware { 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), @@ -166,6 +168,23 @@ impl Middleware { 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(), diff --git a/dapps/src/router.rs b/dapps/src/router.rs index e5770ca72b8..d5f46470493 100644 --- a/dapps/src/router.rs +++ b/dapps/src/router.rs @@ -150,10 +150,20 @@ impl Router { } }, // RPC by default - _ => { + _ if self.special.contains_key(&SpecialEndpoint::Rpc) => { trace!(target: "dapps", "Resolving to RPC call."); Response::None(req) - } + }, + // 404 otherwise + _ => { + Response::Some(Box::new(future::ok(handlers::ContentHandler::error( + hyper::StatusCode::NotFound, + "404 Not Found", + "Requested content was not found.", + None, + self.embeddable_on.clone(), + ).into()))) + }, }) } } diff --git a/dapps/src/tests/helpers/mod.rs b/dapps/src/tests/helpers/mod.rs index 3a1311578c7..41df0db61b9 100644 --- a/dapps/src/tests/helpers/mod.rs +++ b/dapps/src/tests/helpers/mod.rs @@ -240,6 +240,7 @@ impl Server { registrar, sync_status, fetch, + false, ) } else { Middleware::dapps( diff --git a/dapps/ui-deprecation/Cargo.toml b/dapps/ui-deprecation/Cargo.toml new file mode 100644 index 00000000000..f4479c2367e --- /dev/null +++ b/dapps/ui-deprecation/Cargo.toml @@ -0,0 +1,18 @@ +[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 new file mode 100644 index 00000000000..c427f3d54d5 --- /dev/null +++ b/dapps/ui-deprecation/build.rs @@ -0,0 +1,21 @@ +// 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 new file mode 100644 index 00000000000..07059743c62 --- /dev/null +++ b/dapps/ui-deprecation/build/index.html @@ -0,0 +1,119 @@ + + + + + + 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 new file mode 100644 index 00000000000..79a4a424974 --- /dev/null +++ b/dapps/ui-deprecation/src/lib.rs @@ -0,0 +1,21 @@ +// 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 new file mode 100644 index 00000000000..892ebbded21 --- /dev/null +++ b/dapps/ui-deprecation/src/lib.rs.in @@ -0,0 +1,55 @@ +// 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/parity/configuration.rs b/parity/configuration.rs index d1c02d5bc7a..96f819cba2c 100644 --- a/parity/configuration.rs +++ b/parity/configuration.rs @@ -581,11 +581,13 @@ impl Configuration { } fn ui_config(&self) -> UiConfiguration { + let ui = self.ui_enabled(); UiConfiguration { - enabled: self.ui_enabled(), + enabled: ui.enabled, interface: self.ui_interface(), port: self.ui_port(), hosts: self.ui_hosts(), + info_page_only: ui.info_page_only, } } @@ -1176,16 +1178,22 @@ impl Configuration { into_secretstore_service_contract_address(self.args.arg_secretstore_doc_sretr_contract.as_ref()) } - fn ui_enabled(&self) -> bool { + fn ui_enabled(&self) -> UiEnabled { if self.args.flag_force_ui { - return true; + 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; - self.args.cmd_ui && !ui_disabled && cfg!(feature = "ui-enabled") + 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 { @@ -1206,6 +1214,12 @@ 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), @@ -1418,15 +1432,16 @@ mod tests { origins: Some(vec!["parity://*".into(),"chrome-extension://*".into(), "moz-extension://*".into()]), hosts: Some(vec![]), signer_path: expected.into(), - ui_address: None, + 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: false, + enabled: true, interface: "127.0.0.1".into(), port: 8180, hosts: Some(vec![]), + info_page_only: true, }, LogConfig { color: true, mode: None, @@ -1698,10 +1713,26 @@ mod tests { // 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(), false); - assert_eq!(conf1.ui_enabled(), true); + 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] @@ -1712,7 +1743,10 @@ mod tests { let conf0 = parse(&["parity", "--unlock", "0x0"]); // then - assert_eq!(conf0.ui_enabled(), false); + assert_eq!(conf0.ui_enabled(), UiEnabled { + enabled: false, + info_page_only: true, + }); } #[test] @@ -1730,54 +1764,64 @@ mod tests { // then assert_eq!(conf0.directories().signer, "signer".to_owned()); assert_eq!(conf0.ui_config(), UiConfiguration { - enabled: false, - interface: "127.0.0.1".into(), - port: 8180, - hosts: Some(vec![]), - }); - 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: true, }); - assert!(conf5.ws_config().unwrap().hosts.is_some()); - 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![]), - }); - assert!(conf5.ws_config().unwrap().hosts.is_some()); + + assert!(conf1.ws_config().unwrap().hosts.is_some()); + assert_eq!(conf1.ws_config().unwrap().origins, None); assert_eq!(conf1.directories().signer, "signer".to_owned()); assert_eq!(conf1.ui_config(), UiConfiguration { - enabled: false, + 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_eq!(conf1.ws_config().unwrap().origins, None); + + assert!(conf2.ws_config().unwrap().hosts.is_some()); assert_eq!(conf2.directories().signer, "signer".to_owned()); assert_eq!(conf2.ui_config(), UiConfiguration { - enabled: false, + enabled: true, interface: "127.0.0.1".into(), port: 3123, hosts: Some(vec![]), + info_page_only: true, }); - assert!(conf2.ws_config().unwrap().hosts.is_some()); + + assert!(conf3.ws_config().unwrap().hosts.is_some()); assert_eq!(conf3.directories().signer, "signer".to_owned()); assert_eq!(conf3.ui_config(), UiConfiguration { - enabled: false, + 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, }); - assert!(conf3.ws_config().unwrap().hosts.is_some()); } #[test] diff --git a/parity/dapps.rs b/parity/dapps.rs index 42ff21b58f9..2219f7cbee5 100644 --- a/parity/dapps.rs +++ b/parity/dapps.rs @@ -164,6 +164,7 @@ pub struct Dependencies { 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> { @@ -281,6 +282,7 @@ mod server { deps.contract_client, deps.sync_status, deps.fetch, + deps.info_page_only, )) } diff --git a/parity/rpc.rs b/parity/rpc.rs index a1b2271c44f..66a2715d42b 100644 --- a/parity/rpc.rs +++ b/parity/rpc.rs @@ -74,6 +74,7 @@ pub struct UiConfiguration { pub interface: String, pub port: u16, pub hosts: Option>, + pub info_page_only: bool, } impl UiConfiguration { @@ -110,10 +111,11 @@ impl From for HttpConfiguration { impl Default for UiConfiguration { fn default() -> Self { UiConfiguration { - enabled: false, + enabled: cfg!(feature = "ui-enabled"), port: 8180, interface: "127.0.0.1".into(), hosts: Some(vec![]), + info_page_only: true, } } } @@ -168,7 +170,7 @@ impl Default for WsConfiguration { hosts: Some(Vec::new()), signer_path: replace_home(&data_dir, "$BASE/signer").into(), support_token_api: true, - ui_address: None, + ui_address: Some("127.0.0.1:8180".into()), dapps_address: Some("127.0.0.1:8545".into()), } } diff --git a/parity/run.rs b/parity/run.rs index 8fa76693b8f..4cc7b29b04d 100644 --- a/parity/run.rs +++ b/parity/run.rs @@ -365,6 +365,7 @@ fn execute_light_impl(cmd: RunCmd, logger: Arc) -> Result(cmd: RunCmd, logger: Arc, on_client_rq: 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())?; @@ -970,7 +972,7 @@ impl RunningClient { } pub fn execute(cmd: RunCmd, can_restart: bool, logger: Arc) -> Result<(bool, Option), String> { - if cmd.ui_conf.enabled { + 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")); } From 99e37844fddc827cb871ba0e239b182e3495ab7b Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Wed, 11 Apr 2018 01:25:27 +0800 Subject: [PATCH 15/25] Use async hyper server in secret_store and upgrade igd (#8359) * Update secret_store hyper dep to 0.11 * Upgrade igd to 0.7 * typo: spawn --- Cargo.lock | 85 ++---- secret_store/Cargo.toml | 7 +- secret_store/src/lib.rs | 1 + secret_store/src/listener/http_listener.rs | 335 +++++++++++---------- secret_store/src/types/all.rs | 14 + util/network-devp2p/Cargo.toml | 2 +- 6 files changed, 228 insertions(+), 216 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4f86b1df4b8..dbc605dac5c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -706,7 +706,7 @@ dependencies = [ "ethcore-network 1.11.0", "ethereum-types 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethkey 0.3.0", - "igd 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "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", "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", @@ -780,7 +780,7 @@ dependencies = [ "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)", - "hyper 0.10.13 (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", "kvdb 0.1.0", "kvdb-rocksdb 0.1.0", @@ -793,6 +793,7 @@ dependencies = [ "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)", + "tokio 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-core 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-proto 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1200,24 +1201,6 @@ name = "httparse" version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "hyper" -version = "0.10.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "base64 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "httparse 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "mime 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", - "traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "unicase 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)", -] - [[package]] name = "hyper" version = "0.11.24" @@ -1271,14 +1254,18 @@ dependencies = [ [[package]] name = "igd" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.11.24 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "regex 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", - "xml-rs 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "xmltree 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-core 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-retry 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-timer 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "xml-rs 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "xmltree 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1654,14 +1641,6 @@ dependencies = [ "tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "mime" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "mime" version = "0.3.4" @@ -3291,6 +3270,17 @@ dependencies = [ "tokio-io 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "tokio-retry" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-core 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "tokio-rustls" version = "0.4.0" @@ -3398,11 +3388,6 @@ dependencies = [ "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "traitobject" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "transaction-pool" version = "1.11.0" @@ -3450,11 +3435,6 @@ dependencies = [ "trie-standardmap 0.1.0", ] -[[package]] -name = "typeable" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "uint" version = "0.2.0" @@ -3731,18 +3711,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "xml-rs" -version = "0.3.6" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "xmltree" -version = "0.3.2" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "xml-rs 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "xml-rs 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3831,11 +3811,10 @@ dependencies = [ "checksum hex 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d6a22814455d41612f41161581c2883c0c6a1c41852729b17d5ed88f01e153aa" "checksum hidapi 0.3.1 (git+https://github.com/paritytech/hidapi-rs)" = "" "checksum httparse 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "af2f2dd97457e8fb1ae7c5a420db346af389926e36f43768b96f101546b04a07" -"checksum hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)" = "368cb56b2740ebf4230520e2b90ebb0461e69034d85d1945febd9b3971426db2" "checksum hyper 0.11.24 (registry+https://github.com/rust-lang/crates.io-index)" = "df4dd5dae401458087396b6db7fabc4d6760aa456a5fa8e92bda549f39cae661" "checksum hyper-rustls 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d6cdc1751771a14b8175764394f025e309a28c825ed9eaf97fa62bb831dc8c5" "checksum idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "014b298351066f1512874135335d62a789ffe78a9974f94b43ed5621951eaf7d" -"checksum igd 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "356a0dc23a4fa0f8ce4777258085d00a01ea4923b2efd93538fc44bf5e1bda76" +"checksum igd 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8a254e265e8810deb357a9de757f784787ec415d056ededf410c0aa460afee9e" "checksum integer-encoding 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a053c9c7dcb7db1f2aa012c37dc176c62e4cdf14898dee0eecc606de835b8acb" "checksum interleaved-ordered 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "141340095b15ed7491bd3d4ced9d20cebfb826174b6bb03386381f62b01e3d77" "checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08" @@ -3870,7 +3849,6 @@ dependencies = [ "checksum memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e2ffa2c986de11a9df78620c01eeaaf27d94d3ff02bf81bfcca953102dd0c6ff" "checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3" "checksum memory_units 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "71d96e3f3c0b6325d8ccd83c33b28acb183edcb6c67938ba104ec546854b0882" -"checksum mime 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ba626b8a6de5da682e1caa06bdb42a335aee5a84db8e5046a3e8ab17ba0a3ae0" "checksum mime 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "e3d709ffbb330e1566dc2f2a3c9b58a5ad4a381f740b810cd305dc3f089bc160" "checksum mime_guess 2.0.0-alpha.2 (registry+https://github.com/rust-lang/crates.io-index)" = "27a5e6679a0614e25adc14c6434ba84e41632b765a6d9cb2031a0cca682699ae" "checksum miniz-sys 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "609ce024854aeb19a0ef7567d348aaa5a746b32fb72e336df7fcc16869d7e2b4" @@ -3996,6 +3974,7 @@ dependencies = [ "checksum tokio-named-pipes 0.1.0 (git+https://github.com/nikvolf/tokio-named-pipes)" = "" "checksum tokio-proto 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8fbb47ae81353c63c487030659494b295f6cb6576242f907f203473b191b0389" "checksum tokio-reactor 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3cedc8e5af5131dc3423ffa4f877cce78ad25259a9a62de0613735a13ebc64b" +"checksum tokio-retry 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f05746ae87dca83a2016b4f5dba5b237b897dd12fd324f60afe282112f16969a" "checksum tokio-rustls 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a9263e472d976e4345e50c6cce4cfe6b17c71593ea593cce1df26f1efd36debb" "checksum tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "24da22d077e0f15f55162bdbdc661228c1581892f52074fb242678d015b45162" "checksum tokio-tcp 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ec9b094851aadd2caf83ba3ad8e8c4ce65a42104f7b94d9e6550023f0407853f" @@ -4005,10 +3984,8 @@ dependencies = [ "checksum tokio-udp 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "137bda266504893ac4774e0ec4c2108f7ccdbcb7ac8dced6305fe9e4e0b5041a" "checksum tokio-uds 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6116c71be48f8f1656551fd16458247fdd6c03201d7893ad81189055fcde03e8" "checksum toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a7540f4ffc193e0d3c94121edb19b055670d369f77d5804db11ae053a45b6e7e" -"checksum traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079" "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 typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1410f6f91f21d1612654e7cc69193b0334f909dcf2c790c4826254fbb86f8887" "checksum uint 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6477b2716357758c176c36719023e1f9726974d762150e4fc0a9c8c75488c343" "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" @@ -4038,6 +4015,6 @@ dependencies = [ "checksum ws 0.7.5 (git+https://github.com/tomusdrw/ws-rs)" = "" "checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" "checksum xdg 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a66b7c2281ebde13cf4391d70d4c7e5946c3c25e72a7b859ca8f677dcd0b0c61" -"checksum xml-rs 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7ec6c39eaa68382c8e31e35239402c0a9489d4141a8ceb0c716099a0b515b562" -"checksum xmltree 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "472a9d37c7c53ab2391161df5b89b1f3bf76dab6ab150d7941ecbdd832282082" +"checksum xml-rs 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3c1cb601d29fe2c2ac60a2b2e5e293994d87a1f6fa9687a31a15270f909be9c2" +"checksum xmltree 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a9cfb54ca6b8f17d2377219ce485b134d53561b77e1393c7ea416f543a527431" "checksum zip 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)" = "c0deac03fc7d43abcf19f2c2db6bd9289f9ea3d31f350e26eb0ed8b4117983c1" diff --git a/secret_store/Cargo.toml b/secret_store/Cargo.toml index fcd022f7d9f..91889d7012e 100644 --- a/secret_store/Cargo.toml +++ b/secret_store/Cargo.toml @@ -9,7 +9,7 @@ authors = ["Parity Technologies "] byteorder = "1.0" log = "0.3" parking_lot = "0.5" -hyper = { version = "0.10", default-features = false } +hyper = { version = "0.11", default-features = false } serde = "1.0" serde_json = "1.0" serde_derive = "1.0" @@ -17,8 +17,9 @@ futures = "0.1" futures-cpupool = "0.1" rustc-hex = "1.0" tiny-keccak = "1.3" -tokio-core = "0.1.6" -tokio-io = "0.1.0" +tokio = "0.1" +tokio-core = "0.1" +tokio-io = "0.1" tokio-service = "0.1" tokio-proto = "0.1" url = "1.0" diff --git a/secret_store/src/lib.rs b/secret_store/src/lib.rs index 9a7310b11db..dc45f1af369 100644 --- a/secret_store/src/lib.rs +++ b/secret_store/src/lib.rs @@ -34,6 +34,7 @@ extern crate rustc_hex; extern crate serde; extern crate serde_json; extern crate tiny_keccak; +extern crate tokio; extern crate tokio_core; extern crate tokio_io; extern crate tokio_proto; diff --git a/secret_store/src/listener/http_listener.rs b/secret_store/src/listener/http_listener.rs index 1680201e195..7d4385ccc5b 100644 --- a/secret_store/src/listener/http_listener.rs +++ b/secret_store/src/listener/http_listener.rs @@ -15,16 +15,16 @@ // along with Parity. If not, see . use std::collections::BTreeSet; -use std::io::Read; use std::sync::{Arc, Weak}; -use hyper::header; -use hyper::uri::RequestUri; -use hyper::method::Method as HttpMethod; -use hyper::status::StatusCode as HttpStatusCode; -use hyper::server::{Server as HttpServer, Request as HttpRequest, Response as HttpResponse, Handler as HttpHandler, - Listening as HttpListening}; +use hyper::{self, header, Chunk, Uri, Request as HttpRequest, Response as HttpResponse, Method as HttpMethod, StatusCode as HttpStatusCode}; +use hyper::server::Http; use serde::Serialize; use serde_json; +use tokio::executor::current_thread; +use tokio::net::TcpListener; +use tokio::runtime::Runtime; +use tokio_service::Service; +use futures::{future, Future, Stream}; use url::percent_encoding::percent_decode; use traits::KeyServer; @@ -34,16 +34,16 @@ use types::all::{Error, Public, MessageHash, NodeAddress, RequestSignature, Serv /// Key server http-requests listener. Available requests: /// To generate server key: POST /shadow/{server_key_id}/{signature}/{threshold} -/// To store pregenerated encrypted document key: POST /shadow/{server_key_id}/{signature}/{common_point}/{encrypted_key} -/// To generate server && document key: POST /{server_key_id}/{signature}/{threshold} +/// To store pregenerated encrypted document key: POST /shadow/{server_key_id}/{signature}/{common_point}/{encrypted_key} +/// To generate server && document key: POST /{server_key_id}/{signature}/{threshold} /// To get document key: GET /{server_key_id}/{signature} -/// To get document key shadow: GET /shadow/{server_key_id}/{signature} +/// To get document key shadow: GET /shadow/{server_key_id}/{signature} /// To generate Schnorr signature with server key: GET /schnorr/{server_key_id}/{signature}/{message_hash} /// To generate ECDSA signature with server key: GET /ecdsa/{server_key_id}/{signature}/{message_hash} /// To change servers set: POST /admin/servers_set_change/{old_signature}/{new_signature} + BODY: json array of hex-encoded nodes ids pub struct KeyServerHttpListener { - http_server: HttpListening, + _runtime: Runtime, _handler: Arc, } @@ -71,6 +71,7 @@ enum Request { } /// Cloneable http handler +#[derive(Clone)] struct KeyServerHttpHandler { handler: Arc, } @@ -87,194 +88,212 @@ impl KeyServerHttpListener { key_server: key_server, }); - let listener_address = format!("{}:{}", listener_address.address, listener_address.port); - let http_server = HttpServer::http(&listener_address) - .and_then(|http_server| http_server.handle(KeyServerHttpHandler { - handler: shared_handler.clone(), - })).map_err(|err| Error::Hyper(format!("{}", err)))?; + let mut runtime = Runtime::new()?; + let listener_address = format!("{}:{}", listener_address.address, listener_address.port).parse()?; + let listener = TcpListener::bind(&listener_address)?; + + let shared_handler2 = shared_handler.clone(); + + let server = listener.incoming() + .map_err(|e| warn!("Key server listener error: {:?}", e)) + .for_each(move |socket| { + let http: Http = Http::new(); + let serve = http.serve_connection(socket, KeyServerHttpHandler { + handler: shared_handler2.clone(), + }).map(|_| ()).map_err(|e| { + warn!("Key server handler error: {:?}", e); + }); + + // TODO: Change this to tokio::spawn once hyper is Send. + current_thread::spawn(serve); + future::ok(()) + }); + + runtime.spawn(server); let listener = KeyServerHttpListener { - http_server: http_server, + _runtime: runtime, _handler: shared_handler, }; + Ok(listener) } } -impl Drop for KeyServerHttpListener { - fn drop(&mut self) { - // ignore error as we are dropping anyway - let _ = self.http_server.close(); +impl KeyServerHttpHandler { + fn process(self, req_method: HttpMethod, req_uri: Uri, path: &str, req_body: &[u8]) -> HttpResponse { + match parse_request(&req_method, &path, &req_body) { + Request::GenerateServerKey(document, signature, threshold) => { + return_server_public_key(&req_uri, self.handler.key_server.upgrade() + .map(|key_server| key_server.generate_key(&document, &signature.into(), threshold)) + .unwrap_or(Err(Error::Internal("KeyServer is already destroyed".into()))) + .map_err(|err| { + warn!(target: "secretstore", "GenerateServerKey request {} has failed with: {}", req_uri, err); + err + })) + }, + Request::StoreDocumentKey(document, signature, common_point, encrypted_document_key) => { + return_empty(&req_uri, self.handler.key_server.upgrade() + .map(|key_server| key_server.store_document_key(&document, &signature.into(), common_point, encrypted_document_key)) + .unwrap_or(Err(Error::Internal("KeyServer is already destroyed".into()))) + .map_err(|err| { + warn!(target: "secretstore", "StoreDocumentKey request {} has failed with: {}", req_uri, err); + err + })) + }, + Request::GenerateDocumentKey(document, signature, threshold) => { + return_document_key(&req_uri, self.handler.key_server.upgrade() + .map(|key_server| key_server.generate_document_key(&document, &signature.into(), threshold)) + .unwrap_or(Err(Error::Internal("KeyServer is already destroyed".into()))) + .map_err(|err| { + warn!(target: "secretstore", "GenerateDocumentKey request {} has failed with: {}", req_uri, err); + err + })) + }, + Request::GetDocumentKey(document, signature) => { + return_document_key(&req_uri, self.handler.key_server.upgrade() + .map(|key_server| key_server.restore_document_key(&document, &signature.into())) + .unwrap_or(Err(Error::Internal("KeyServer is already destroyed".into()))) + .map_err(|err| { + warn!(target: "secretstore", "GetDocumentKey request {} has failed with: {}", req_uri, err); + err + })) + }, + Request::GetDocumentKeyShadow(document, signature) => { + return_document_key_shadow(&req_uri, self.handler.key_server.upgrade() + .map(|key_server| key_server.restore_document_key_shadow(&document, &signature.into())) + .unwrap_or(Err(Error::Internal("KeyServer is already destroyed".into()))) + .map_err(|err| { + warn!(target: "secretstore", "GetDocumentKeyShadow request {} has failed with: {}", req_uri, err); + err + })) + }, + Request::SchnorrSignMessage(document, signature, message_hash) => { + return_message_signature(&req_uri, self.handler.key_server.upgrade() + .map(|key_server| key_server.sign_message_schnorr(&document, &signature.into(), message_hash)) + .unwrap_or(Err(Error::Internal("KeyServer is already destroyed".into()))) + .map_err(|err| { + warn!(target: "secretstore", "SchnorrSignMessage request {} has failed with: {}", req_uri, err); + err + })) + }, + Request::EcdsaSignMessage(document, signature, message_hash) => { + return_message_signature(&req_uri, self.handler.key_server.upgrade() + .map(|key_server| key_server.sign_message_ecdsa(&document, &signature.into(), message_hash)) + .unwrap_or(Err(Error::Internal("KeyServer is already destroyed".into()))) + .map_err(|err| { + warn!(target: "secretstore", "EcdsaSignMessage request {} has failed with: {}", req_uri, err); + err + })) + }, + Request::ChangeServersSet(old_set_signature, new_set_signature, new_servers_set) => { + return_empty(&req_uri, self.handler.key_server.upgrade() + .map(|key_server| key_server.change_servers_set(old_set_signature, new_set_signature, new_servers_set)) + .unwrap_or(Err(Error::Internal("KeyServer is already destroyed".into()))) + .map_err(|err| { + warn!(target: "secretstore", "ChangeServersSet request {} has failed with: {}", req_uri, err); + err + })) + }, + Request::Invalid => { + warn!(target: "secretstore", "Ignoring invalid {}-request {}", req_method, req_uri); + HttpResponse::new().with_status(HttpStatusCode::BadRequest) + }, + } } } -impl HttpHandler for KeyServerHttpHandler { - fn handle(&self, mut req: HttpRequest, mut res: HttpResponse) { - if req.headers.has::() { - warn!(target: "secretstore", "Ignoring {}-request {} with Origin header", req.method, req.uri); - *res.status_mut() = HttpStatusCode::NotFound; - return; - } +impl Service for KeyServerHttpHandler { + type Request = HttpRequest; + type Response = HttpResponse; + type Error = hyper::Error; + type Future = Box>; - let mut req_body = Default::default(); - if let Err(error) = req.read_to_string(&mut req_body) { - warn!(target: "secretstore", "Error {} reading body of {}-request {}", error, req.method, req.uri); - *res.status_mut() = HttpStatusCode::BadRequest; - return; + fn call(&self, req: HttpRequest) -> Self::Future { + if req.headers().has::() { + warn!(target: "secretstore", "Ignoring {}-request {} with Origin header", req.method(), req.uri()); + return Box::new(future::ok(HttpResponse::new().with_status(HttpStatusCode::NotFound))); } - let req_method = req.method.clone(); - let req_uri = req.uri.clone(); - match &req_uri { - &RequestUri::AbsolutePath(ref path) => match parse_request(&req_method, &path, &req_body) { - Request::GenerateServerKey(document, signature, threshold) => { - return_server_public_key(req, res, self.handler.key_server.upgrade() - .map(|key_server| key_server.generate_key(&document, &signature.into(), threshold)) - .unwrap_or(Err(Error::Internal("KeyServer is already destroyed".into()))) - .map_err(|err| { - warn!(target: "secretstore", "GenerateServerKey request {} has failed with: {}", req_uri, err); - err - })); - }, - Request::StoreDocumentKey(document, signature, common_point, encrypted_document_key) => { - return_empty(req, res, self.handler.key_server.upgrade() - .map(|key_server| key_server.store_document_key(&document, &signature.into(), common_point, encrypted_document_key)) - .unwrap_or(Err(Error::Internal("KeyServer is already destroyed".into()))) - .map_err(|err| { - warn!(target: "secretstore", "StoreDocumentKey request {} has failed with: {}", req_uri, err); - err - })); - }, - Request::GenerateDocumentKey(document, signature, threshold) => { - return_document_key(req, res, self.handler.key_server.upgrade() - .map(|key_server| key_server.generate_document_key(&document, &signature.into(), threshold)) - .unwrap_or(Err(Error::Internal("KeyServer is already destroyed".into()))) - .map_err(|err| { - warn!(target: "secretstore", "GenerateDocumentKey request {} has failed with: {}", req_uri, err); - err - })); - }, - Request::GetDocumentKey(document, signature) => { - return_document_key(req, res, self.handler.key_server.upgrade() - .map(|key_server| key_server.restore_document_key(&document, &signature.into())) - .unwrap_or(Err(Error::Internal("KeyServer is already destroyed".into()))) - .map_err(|err| { - warn!(target: "secretstore", "GetDocumentKey request {} has failed with: {}", req_uri, err); - err - })); - }, - Request::GetDocumentKeyShadow(document, signature) => { - return_document_key_shadow(req, res, self.handler.key_server.upgrade() - .map(|key_server| key_server.restore_document_key_shadow(&document, &signature.into())) - .unwrap_or(Err(Error::Internal("KeyServer is already destroyed".into()))) - .map_err(|err| { - warn!(target: "secretstore", "GetDocumentKeyShadow request {} has failed with: {}", req_uri, err); - err - })); - }, - Request::SchnorrSignMessage(document, signature, message_hash) => { - return_message_signature(req, res, self.handler.key_server.upgrade() - .map(|key_server| key_server.sign_message_schnorr(&document, &signature.into(), message_hash)) - .unwrap_or(Err(Error::Internal("KeyServer is already destroyed".into()))) - .map_err(|err| { - warn!(target: "secretstore", "SchnorrSignMessage request {} has failed with: {}", req_uri, err); - err - })); - }, - Request::EcdsaSignMessage(document, signature, message_hash) => { - return_message_signature(req, res, self.handler.key_server.upgrade() - .map(|key_server| key_server.sign_message_ecdsa(&document, &signature.into(), message_hash)) - .unwrap_or(Err(Error::Internal("KeyServer is already destroyed".into()))) - .map_err(|err| { - warn!(target: "secretstore", "EcdsaSignMessage request {} has failed with: {}", req_uri, err); - err - })); - }, - Request::ChangeServersSet(old_set_signature, new_set_signature, new_servers_set) => { - return_empty(req, res, self.handler.key_server.upgrade() - .map(|key_server| key_server.change_servers_set(old_set_signature, new_set_signature, new_servers_set)) - .unwrap_or(Err(Error::Internal("KeyServer is already destroyed".into()))) - .map_err(|err| { - warn!(target: "secretstore", "ChangeServersSet request {} has failed with: {}", req_uri, err); - err - })); - }, - Request::Invalid => { - warn!(target: "secretstore", "Ignoring invalid {}-request {}", req_method, req_uri); - *res.status_mut() = HttpStatusCode::BadRequest; - }, - }, - _ => { + let req_method = req.method().clone(); + let req_uri = req.uri().clone(); + // We cannot consume Self because of the Service trait requirement. + let this = self.clone(); + + Box::new(req.body().concat2().map(move |body| { + let path = req_uri.path().to_string(); + if req_uri.is_absolute() { + this.process(req_method, req_uri, &path, &body) + } else { warn!(target: "secretstore", "Ignoring invalid {}-request {}", req_method, req_uri); - *res.status_mut() = HttpStatusCode::NotFound; - }, - }; + HttpResponse::new().with_status(HttpStatusCode::NotFound) + } + })) } } -fn return_empty(req: HttpRequest, res: HttpResponse, empty: Result<(), Error>) { - return_bytes::(req, res, empty.map(|_| None)) +fn return_empty(req_uri: &Uri, empty: Result<(), Error>) -> HttpResponse { + return_bytes::(req_uri, empty.map(|_| None)) } -fn return_server_public_key(req: HttpRequest, res: HttpResponse, server_public: Result) { - return_bytes(req, res, server_public.map(|k| Some(SerializablePublic(k)))) +fn return_server_public_key(req_uri: &Uri, server_public: Result) -> HttpResponse { + return_bytes(req_uri, server_public.map(|k| Some(SerializablePublic(k)))) } -fn return_message_signature(req: HttpRequest, res: HttpResponse, signature: Result) { - return_bytes(req, res, signature.map(|s| Some(SerializableBytes(s)))) +fn return_message_signature(req_uri: &Uri, signature: Result) -> HttpResponse { + return_bytes(req_uri, signature.map(|s| Some(SerializableBytes(s)))) } -fn return_document_key(req: HttpRequest, res: HttpResponse, document_key: Result) { - return_bytes(req, res, document_key.map(|k| Some(SerializableBytes(k)))) +fn return_document_key(req_uri: &Uri, document_key: Result) -> HttpResponse { + return_bytes(req_uri, document_key.map(|k| Some(SerializableBytes(k)))) } -fn return_document_key_shadow(req: HttpRequest, res: HttpResponse, document_key_shadow: Result) { - return_bytes(req, res, document_key_shadow.map(|k| Some(SerializableEncryptedDocumentKeyShadow { +fn return_document_key_shadow(req_uri: &Uri, document_key_shadow: Result) -> HttpResponse { + return_bytes(req_uri, document_key_shadow.map(|k| Some(SerializableEncryptedDocumentKeyShadow { decrypted_secret: k.decrypted_secret.into(), common_point: k.common_point.expect("always filled when requesting document_key_shadow; qed").into(), decrypt_shadows: k.decrypt_shadows.expect("always filled when requesting document_key_shadow; qed").into_iter().map(Into::into).collect(), }))) } -fn return_bytes(req: HttpRequest, mut res: HttpResponse, result: Result, Error>) { +fn return_bytes(req_uri: &Uri, result: Result, Error>) -> HttpResponse { match result { Ok(Some(result)) => match serde_json::to_vec(&result) { - Ok(result) => { - res.headers_mut().set(header::ContentType::json()); - if let Err(err) = res.send(&result) { - // nothing to do, but to log an error - warn!(target: "secretstore", "response to request {} has failed with: {}", req.uri, err); - } - }, + Ok(result) => HttpResponse::new() + .with_header(header::ContentType::json()) + .with_body(result), Err(err) => { - warn!(target: "secretstore", "response to request {} has failed with: {}", req.uri, err); + warn!(target: "secretstore", "response to request {} has failed with: {}", req_uri, err); + HttpResponse::new().with_status(HttpStatusCode::InternalServerError) } }, - Ok(None) => *res.status_mut() = HttpStatusCode::Ok, - Err(err) => return_error(res, err), + Ok(None) => HttpResponse::new().with_status(HttpStatusCode::Ok), + Err(err) => return_error(err), } } -fn return_error(mut res: HttpResponse, err: Error) { - match err { - Error::InsufficientRequesterData(_) => *res.status_mut() = HttpStatusCode::BadRequest, - Error::AccessDenied => *res.status_mut() = HttpStatusCode::Forbidden, - Error::DocumentNotFound => *res.status_mut() = HttpStatusCode::NotFound, - Error::Hyper(_) => *res.status_mut() = HttpStatusCode::BadRequest, - Error::Serde(_) => *res.status_mut() = HttpStatusCode::BadRequest, - Error::Database(_) => *res.status_mut() = HttpStatusCode::InternalServerError, - Error::Internal(_) => *res.status_mut() = HttpStatusCode::InternalServerError, - } +fn return_error(err: Error) -> HttpResponse { + let mut res = match err { + Error::InsufficientRequesterData(_) => HttpResponse::new().with_status(HttpStatusCode::BadRequest), + Error::AccessDenied => HttpResponse::new().with_status(HttpStatusCode::Forbidden), + Error::DocumentNotFound => HttpResponse::new().with_status(HttpStatusCode::NotFound), + Error::Hyper(_) => HttpResponse::new().with_status(HttpStatusCode::BadRequest), + Error::Serde(_) => HttpResponse::new().with_status(HttpStatusCode::BadRequest), + Error::Database(_) => HttpResponse::new().with_status(HttpStatusCode::InternalServerError), + Error::Internal(_) => HttpResponse::new().with_status(HttpStatusCode::InternalServerError), + }; // return error text. ignore errors when returning error let error_text = format!("\"{}\"", err); if let Ok(error_text) = serde_json::to_vec(&error_text) { res.headers_mut().set(header::ContentType::json()); - let _ = res.send(&error_text); + res.set_body(error_text); } + + res } -fn parse_request(method: &HttpMethod, uri_path: &str, body: &str) -> Request { +fn parse_request(method: &HttpMethod, uri_path: &str, body: &[u8]) -> Request { let uri_path = match percent_decode(uri_path.as_bytes()).decode_utf8() { Ok(path) => path, Err(_) => return Request::Invalid, @@ -328,7 +347,7 @@ fn parse_request(method: &HttpMethod, uri_path: &str, body: &str) -> Request { } } -fn parse_admin_request(method: &HttpMethod, path: Vec, body: &str) -> Request { +fn parse_admin_request(method: &HttpMethod, path: Vec, body: &[u8]) -> Request { let args_count = path.len(); if *method != HttpMethod::Post || args_count != 4 || path[1] != "servers_set_change" { return Request::Invalid; @@ -344,7 +363,7 @@ fn parse_admin_request(method: &HttpMethod, path: Vec, body: &str) -> Re _ => return Request::Invalid, }; - let new_servers_set: BTreeSet = match serde_json::from_str(body) { + let new_servers_set: BTreeSet = match serde_json::from_slice(body) { Ok(new_servers_set) => new_servers_set, _ => return Request::Invalid, }; @@ -356,7 +375,7 @@ fn parse_admin_request(method: &HttpMethod, path: Vec, body: &str) -> Re #[cfg(test)] mod tests { use std::sync::Arc; - use hyper::method::Method as HttpMethod; + use hyper::Method as HttpMethod; use ethkey::Public; use traits::KeyServer; use key_server::tests::DummyKeyServer; @@ -370,7 +389,7 @@ mod tests { let listener = KeyServerHttpListener::start(address, Arc::downgrade(&key_server)).unwrap(); drop(listener); } - + #[test] fn parse_request_successful() { // POST /shadow/{server_key_id}/{signature}/{threshold} => generate server key @@ -416,7 +435,7 @@ mod tests { let nodes = vec![node1, node2].into_iter().collect(); assert_eq!(parse_request(&HttpMethod::Post, "/admin/servers_set_change/a199fb39e11eefb61c78a4074a53c0d4424600a3e74aad4fb9d93a26c30d067e1d4d29936de0c73f19827394a1dd049480a0d581aee7ae7546968da7d3d1c2fd01/b199fb39e11eefb61c78a4074a53c0d4424600a3e74aad4fb9d93a26c30d067e1d4d29936de0c73f19827394a1dd049480a0d581aee7ae7546968da7d3d1c2fd01", &r#"["0x843645726384530ffb0c52f175278143b5a93959af7864460f5a4fec9afd1450cfb8aef63dec90657f43f55b13e0a73c7524d4e9a13c051b4e5f1e53f39ecd91", - "0x07230e34ebfe41337d3ed53b186b3861751f2401ee74b988bba55694e2a6f60c757677e194be2e53c3523cc8548694e636e6acb35c4e8fdc5e29d28679b9b2f3"]"#), + "0x07230e34ebfe41337d3ed53b186b3861751f2401ee74b988bba55694e2a6f60c757677e194be2e53c3523cc8548694e636e6acb35c4e8fdc5e29d28679b9b2f3"]"#.as_bytes()), Request::ChangeServersSet( "a199fb39e11eefb61c78a4074a53c0d4424600a3e74aad4fb9d93a26c30d067e1d4d29936de0c73f19827394a1dd049480a0d581aee7ae7546968da7d3d1c2fd01".parse().unwrap(), "b199fb39e11eefb61c78a4074a53c0d4424600a3e74aad4fb9d93a26c30d067e1d4d29936de0c73f19827394a1dd049480a0d581aee7ae7546968da7d3d1c2fd01".parse().unwrap(), @@ -437,9 +456,9 @@ mod tests { assert_eq!(parse_request(&HttpMethod::Get, "/ecdsa/0000000000000000000000000000000000000000000000000000000000000001/a199fb39e11eefb61c78a4074a53c0d4424600a3e74aad4fb9d93a26c30d067e1d4d29936de0c73f19827394a1dd049480a0d581aee7ae7546968da7d3d1c2fd01/0000000000000000000000000000000000000000000000000000000000000002/0000000000000000000000000000000000000000000000000000000000000002", Default::default()), Request::Invalid); assert_eq!(parse_request(&HttpMethod::Post, "/admin/servers_set_change/xxx/yyy", &r#"["0x843645726384530ffb0c52f175278143b5a93959af7864460f5a4fec9afd1450cfb8aef63dec90657f43f55b13e0a73c7524d4e9a13c051b4e5f1e53f39ecd91", - "0x07230e34ebfe41337d3ed53b186b3861751f2401ee74b988bba55694e2a6f60c757677e194be2e53c3523cc8548694e636e6acb35c4e8fdc5e29d28679b9b2f3"]"#), + "0x07230e34ebfe41337d3ed53b186b3861751f2401ee74b988bba55694e2a6f60c757677e194be2e53c3523cc8548694e636e6acb35c4e8fdc5e29d28679b9b2f3"]"#.as_bytes()), Request::Invalid); - assert_eq!(parse_request(&HttpMethod::Post, "/admin/servers_set_change/a199fb39e11eefb61c78a4074a53c0d4424600a3e74aad4fb9d93a26c30d067e1d4d29936de0c73f19827394a1dd049480a0d581aee7ae7546968da7d3d1c2fd01/a199fb39e11eefb61c78a4074a53c0d4424600a3e74aad4fb9d93a26c30d067e1d4d29936de0c73f19827394a1dd049480a0d581aee7ae7546968da7d3d1c2fd01", ""), + assert_eq!(parse_request(&HttpMethod::Post, "/admin/servers_set_change/a199fb39e11eefb61c78a4074a53c0d4424600a3e74aad4fb9d93a26c30d067e1d4d29936de0c73f19827394a1dd049480a0d581aee7ae7546968da7d3d1c2fd01/a199fb39e11eefb61c78a4074a53c0d4424600a3e74aad4fb9d93a26c30d067e1d4d29936de0c73f19827394a1dd049480a0d581aee7ae7546968da7d3d1c2fd01", "".as_bytes()), Request::Invalid); } } diff --git a/secret_store/src/types/all.rs b/secret_store/src/types/all.rs index 356f1f1f00f..5e28415b188 100644 --- a/secret_store/src/types/all.rs +++ b/secret_store/src/types/all.rs @@ -15,6 +15,8 @@ // along with Parity. If not, see . use std::fmt; +use std::io; +use std::net; use std::collections::BTreeMap; use serde_json; @@ -162,6 +164,18 @@ impl From for Error { } } +impl From for Error { + fn from(err: io::Error) -> Error { + Error::Internal(err.to_string()) + } +} + +impl From for Error { + fn from(err: net::AddrParseError) -> Error { + Error::Internal(err.to_string()) + } +} + impl From for Error { fn from(err: kvdb::Error) -> Self { Error::Database(err.to_string()) diff --git a/util/network-devp2p/Cargo.toml b/util/network-devp2p/Cargo.toml index f6718d6b51c..74edf83ad5d 100644 --- a/util/network-devp2p/Cargo.toml +++ b/util/network-devp2p/Cargo.toml @@ -14,7 +14,7 @@ rand = "0.4" tiny-keccak = "1.3" rust-crypto = "0.2.34" slab = "0.2" -igd = "0.6" +igd = "0.7" libc = "0.2.7" parking_lot = "0.5" ansi_term = "0.10" From 6cf441fc9e73c50f50d599f792cda0399d1c700c Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Wed, 11 Apr 2018 11:41:02 +0200 Subject: [PATCH 16/25] bump snappy and ring, use single rayon version, closes #8296 (#8364) --- Cargo.lock | 32 +++++--------------------------- 1 file changed, 5 insertions(+), 27 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index dbc605dac5c..04475067813 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1112,9 +1112,6 @@ dependencies = [ name = "gcc" version = "0.3.54" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "rayon 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", -] [[package]] name = "getopts" @@ -2625,23 +2622,6 @@ dependencies = [ "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "rayon" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "rayon-core 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rayon" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "either 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rayon-core 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "rayon" version = "1.0.1" @@ -2707,12 +2687,12 @@ dependencies = [ [[package]] name = "ring" version = "0.12.1" -source = "git+https://github.com/paritytech/ring#13eec16273e5e8fbbb21def81eaeb11972f4f903" +source = "git+https://github.com/paritytech/ring#b98d7f586c0467d68e9946a5f47b4a04b9a86b4a" dependencies = [ "cc 1.0.9 (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 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rayon 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "tempfile 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "untrusted 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2986,7 +2966,7 @@ dependencies = [ [[package]] name = "snappy" version = "0.1.0" -source = "git+https://github.com/paritytech/rust-snappy#858eac97192ea25d18d3f3626a8cc13ca0b175bb" +source = "git+https://github.com/paritytech/rust-snappy#40ac9a0d9fd613e7f38df800a11a589b7296da73" dependencies = [ "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", "snappy-sys 0.1.0 (git+https://github.com/paritytech/rust-snappy)", @@ -2995,9 +2975,9 @@ dependencies = [ [[package]] name = "snappy-sys" version = "0.1.0" -source = "git+https://github.com/paritytech/rust-snappy#858eac97192ea25d18d3f3626a8cc13ca0b175bb" +source = "git+https://github.com/paritytech/rust-snappy#40ac9a0d9fd613e7f38df800a11a589b7296da73" dependencies = [ - "gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3906,8 +3886,6 @@ dependencies = [ "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" -"checksum rayon 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b614fe08b6665cb9a231d07ac1364b0ef3cb3698f1239ee0c4c3a88a524f54c8" -"checksum rayon 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ed02d09394c94ffbdfdc755ad62a132e94c3224a8354e78a1200ced34df12edf" "checksum rayon 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "80e811e76f1dbf68abf87a759083d34600017fc4e10b6bd5ad84a700f9dba4b1" "checksum rayon-core 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9d24ad214285a7729b174ed6d3bcfcb80177807f959d95fafd5bfc5c4f201ac8" "checksum redox_syscall 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)" = "8dde11f18c108289bef24469638a04dce49da56084f2d50618b226e47eb04509" From 9fe991db1cd0962851832c9fd0f2f3fdec1ed6d8 Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Wed, 11 Apr 2018 11:59:04 +0200 Subject: [PATCH 17/25] util `fake-fetch` (#8363) * start * hash-fetch * rpc * revert price-info * remove used file * adapt to changes in fetch * make fake-fetch generic over * fix tests to comply with the new `fake-fetch` --- Cargo.lock | 13 ++++ Cargo.toml | 1 + hash-fetch/Cargo.toml | 1 + hash-fetch/src/client.rs | 53 ++------------- hash-fetch/src/lib.rs | 4 ++ price-info/Cargo.toml | 1 + price-info/src/lib.rs | 65 +++---------------- rpc/Cargo.toml | 1 + rpc/src/lib.rs | 3 + rpc/src/v1/tests/helpers/mod.rs | 2 - rpc/src/v1/tests/mocked/parity_set.rs | 8 ++- util/fake-fetch/Cargo.toml | 11 ++++ .../fetch.rs => util/fake-fetch/src/lib.rs | 47 ++++++++------ 13 files changed, 82 insertions(+), 128 deletions(-) create mode 100644 util/fake-fetch/Cargo.toml rename rpc/src/v1/tests/helpers/fetch.rs => util/fake-fetch/src/lib.rs (58%) diff --git a/Cargo.lock b/Cargo.lock index 04475067813..d5c7963f64c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1025,6 +1025,15 @@ dependencies = [ "vm 0.1.0", ] +[[package]] +name = "fake-fetch" +version = "0.0.1" +dependencies = [ + "fetch 0.1.0", + "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.11.24 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "fdlimit" version = "0.1.1" @@ -1940,6 +1949,7 @@ dependencies = [ "ethcore-transaction 0.1.0", "ethereum-types 0.3.0 (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)", "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)", @@ -2063,6 +2073,7 @@ dependencies = [ "ethabi-derive 5.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore-bytes 0.1.0", "ethereum-types 0.3.0 (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)", "futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2148,6 +2159,7 @@ dependencies = [ "ethjson 0.1.0", "ethkey 0.3.0", "ethstore 0.2.0", + "fake-fetch 0.0.1", "fetch 0.1.0", "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", "futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2465,6 +2477,7 @@ dependencies = [ name = "price-info" version = "1.11.0" dependencies = [ + "fake-fetch 0.0.1", "fetch 0.1.0", "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", "futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index 09c00b3386b..291e157cc40 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -82,6 +82,7 @@ rustc_version = "0.2" pretty_assertions = "0.1" ipnetwork = "0.12.6" tempdir = "0.3" +fake-fetch = { path = "util/fake-fetch" } [target.'cfg(windows)'.dependencies] winapi = "0.2" diff --git a/hash-fetch/Cargo.toml b/hash-fetch/Cargo.toml index 12d49e648ca..6a735fe37e0 100644 --- a/hash-fetch/Cargo.toml +++ b/hash-fetch/Cargo.toml @@ -28,3 +28,4 @@ ethabi-contract = "5.0" [dev-dependencies] hyper = "0.11" parking_lot = "0.5" +fake-fetch = { path = "../util/fake-fetch" } diff --git a/hash-fetch/src/client.rs b/hash-fetch/src/client.rs index 201d65ba79e..1c7d417758f 100644 --- a/hash-fetch/src/client.rs +++ b/hash-fetch/src/client.rs @@ -193,53 +193,14 @@ fn random_temp_path() -> PathBuf { #[cfg(test)] mod tests { - extern crate hyper; + use fake_fetch::FakeFetch; use rustc_hex::FromHex; use std::sync::{Arc, mpsc}; use parking_lot::Mutex; - use futures::future; use futures_cpupool::CpuPool; - use fetch::{self, Fetch, Url, Request}; use parity_reactor::Remote; use urlhint::tests::{FakeRegistrar, URLHINT}; use super::{Error, Client, HashFetch, random_temp_path}; - use self::hyper::StatusCode; - - - #[derive(Clone)] - struct FakeFetch { - return_success: bool - } - - impl Fetch for FakeFetch { - type Result = future::Ok; - - fn fetch(&self, request: Request, abort: fetch::Abort) -> Self::Result { - assert_eq!(request.url().as_str(), "https://parity.io/assets/images/ethcore-black-horizontal.png"); - let u = request.url().clone(); - future::ok(if self.return_success { - fetch::client::Response::new(u, hyper::Response::new().with_body(&b"result"[..]), abort) - } else { - fetch::client::Response::new(u, hyper::Response::new().with_status(StatusCode::NotFound), abort) - }) - } - - fn get(&self, url: &str, abort: fetch::Abort) -> Self::Result { - let url: Url = match url.parse() { - Ok(u) => u, - Err(e) => return future::err(e.into()) - }; - self.fetch(Request::get(url), abort) - } - - fn post(&self, url: &str, abort: fetch::Abort) -> Self::Result { - let url: Url = match url.parse() { - Ok(u) => u, - Err(e) => return future::err(e.into()) - }; - self.fetch(Request::post(url), abort) - } - } fn registrar() -> FakeRegistrar { let mut registrar = FakeRegistrar::new(); @@ -254,7 +215,7 @@ mod tests { fn should_return_error_if_hash_not_found() { // given let contract = Arc::new(FakeRegistrar::new()); - let fetch = FakeFetch { return_success: false }; + let fetch = FakeFetch::new(None::); let client = Client::with_fetch(contract.clone(), CpuPool::new(1), fetch, Remote::new_sync()); // when @@ -272,7 +233,7 @@ mod tests { fn should_return_error_if_response_is_not_successful() { // given let registrar = Arc::new(registrar()); - let fetch = FakeFetch { return_success: false }; + let fetch = FakeFetch::new(None::); let client = Client::with_fetch(registrar.clone(), CpuPool::new(1), fetch, Remote::new_sync()); // when @@ -290,7 +251,7 @@ mod tests { fn should_return_hash_mismatch() { // given let registrar = Arc::new(registrar()); - let fetch = FakeFetch { return_success: true }; + let fetch = FakeFetch::new(Some(1)); let mut client = Client::with_fetch(registrar.clone(), CpuPool::new(1), fetch, Remote::new_sync()); let path = random_temp_path(); let path2 = path.clone(); @@ -304,7 +265,7 @@ mod tests { // then let result = rx.recv().unwrap(); - let hash = "0x06b0a4f426f6713234b2d4b2468640bc4e0bb72657a920ad24c5087153c593c8".into(); + let hash = "0x2be00befcf008bc0e7d9cdefc194db9c75352e8632f48498b5a6bfce9f02c88e".into(); assert_eq!(result.unwrap_err(), Error::HashMismatch { expected: 2.into(), got: hash }); assert!(!path.exists(), "Temporary file should be removed."); } @@ -313,12 +274,12 @@ mod tests { fn should_return_path_if_hash_matches() { // given let registrar = Arc::new(registrar()); - let fetch = FakeFetch { return_success: true }; + let fetch = FakeFetch::new(Some(1)); let client = Client::with_fetch(registrar.clone(), CpuPool::new(1), fetch, Remote::new_sync()); // when let (tx, rx) = mpsc::channel(); - client.fetch("0x06b0a4f426f6713234b2d4b2468640bc4e0bb72657a920ad24c5087153c593c8".into(), + client.fetch("0x2be00befcf008bc0e7d9cdefc194db9c75352e8632f48498b5a6bfce9f02c88e".into(), Default::default(), Box::new(move |result| { tx.send(result).unwrap(); })); diff --git a/hash-fetch/src/lib.rs b/hash-fetch/src/lib.rs index 6e74982bb84..18176be5005 100644 --- a/hash-fetch/src/lib.rs +++ b/hash-fetch/src/lib.rs @@ -42,6 +42,10 @@ extern crate ethabi_derive; extern crate ethabi_contract; #[cfg(test)] extern crate parking_lot; +#[cfg(test)] +extern crate hyper; +#[cfg(test)] +extern crate fake_fetch; mod client; diff --git a/price-info/Cargo.toml b/price-info/Cargo.toml index 5122ebb9dd7..8dd497be9a1 100644 --- a/price-info/Cargo.toml +++ b/price-info/Cargo.toml @@ -16,3 +16,4 @@ serde_json = "1.0" [dev-dependencies] hyper = "0.11" parking_lot = "0.5" +fake-fetch = { path = "../util/fake-fetch" } diff --git a/price-info/src/lib.rs b/price-info/src/lib.rs index 8b87f0c11de..9685fc7eee9 100644 --- a/price-info/src/lib.rs +++ b/price-info/src/lib.rs @@ -25,6 +25,9 @@ extern crate serde_json; #[macro_use] extern crate log; +#[cfg(test)] +extern crate fake_fetch; + pub extern crate fetch; use std::cmp; @@ -133,68 +136,18 @@ impl Client { #[cfg(test)] mod test { - extern crate hyper; - extern crate parking_lot; - - use self::parking_lot::Mutex; use std::sync::Arc; - use std::sync::atomic::{AtomicBool, Ordering}; - use fetch; - use fetch::{Fetch, Url, Request}; use futures_cpupool::CpuPool; - use futures::future::{self, FutureResult}; use Client; - use self::hyper::StatusCode; - - #[derive(Clone)] - struct FakeFetch(Option, Arc>); - - impl FakeFetch { - fn new() -> Result { - Ok(FakeFetch(None, Default::default())) - } - } - - impl Fetch for FakeFetch { - type Result = FutureResult; - - fn fetch(&self, request: Request, abort: fetch::Abort) -> Self::Result { - assert_eq!(request.url().as_str(), "https://api.etherscan.io/api?module=stats&action=ethprice"); - let u = request.url().clone(); - let mut val = self.1.lock(); - *val = *val + 1; - if let Some(ref response) = self.0 { - let r = hyper::Response::new().with_body(response.clone()); - future::ok(fetch::client::Response::new(u, r, abort)) - } else { - let r = hyper::Response::new().with_status(StatusCode::NotFound); - future::ok(fetch::client::Response::new(u, r, abort)) - } - } - - fn get(&self, url: &str, abort: fetch::Abort) -> Self::Result { - let url: Url = match url.parse() { - Ok(u) => u, - Err(e) => return future::err(e.into()) - }; - self.fetch(Request::get(url), abort) - } - - fn post(&self, url: &str, abort: fetch::Abort) -> Self::Result { - let url: Url = match url.parse() { - Ok(u) => u, - Err(e) => return future::err(e.into()) - }; - self.fetch(Request::post(url), abort) - } - } + use std::sync::atomic::{AtomicBool, Ordering}; + use fake_fetch::FakeFetch; - fn price_info_ok(response: &str) -> Client { - Client::new(FakeFetch(Some(response.to_owned()), Default::default()), CpuPool::new(1)) + fn price_info_ok(response: &str) -> Client> { + Client::new(FakeFetch::new(Some(response.to_owned())), CpuPool::new(1)) } - fn price_info_not_found() -> Client { - Client::new(FakeFetch::new().unwrap(), CpuPool::new(1)) + fn price_info_not_found() -> Client> { + Client::new(FakeFetch::new(None::), CpuPool::new(1)) } #[test] diff --git a/rpc/Cargo.toml b/rpc/Cargo.toml index c467f055375..a0639c4ccc2 100644 --- a/rpc/Cargo.toml +++ b/rpc/Cargo.toml @@ -70,3 +70,4 @@ pretty_assertions = "0.1" macros = { path = "../util/macros" } ethcore-network = { path = "../util/network" } kvdb-memorydb = { path = "../util/kvdb-memorydb" } +fake-fetch = { path = "../util/fake-fetch" } diff --git a/rpc/src/lib.rs b/rpc/src/lib.rs index 1a0989d4a2a..f3ba68a0650 100644 --- a/rpc/src/lib.rs +++ b/rpc/src/lib.rs @@ -91,6 +91,9 @@ extern crate macros; #[cfg(test)] extern crate kvdb_memorydb; +#[cfg(test)] +extern crate fake_fetch; + extern crate tempdir; pub extern crate jsonrpc_ws_server as ws; diff --git a/rpc/src/v1/tests/helpers/mod.rs b/rpc/src/v1/tests/helpers/mod.rs index aae48a2d280..8e1aeeb147d 100644 --- a/rpc/src/v1/tests/helpers/mod.rs +++ b/rpc/src/v1/tests/helpers/mod.rs @@ -17,14 +17,12 @@ //! Test rpc services. mod dapps; -mod fetch; mod miner_service; mod snapshot_service; mod sync_provider; mod update_service; pub use self::dapps::TestDappsService; -pub use self::fetch::TestFetch; pub use self::miner_service::TestMinerService; pub use self::snapshot_service::TestSnapshotService; pub use self::sync_provider::{Config, TestSyncProvider}; diff --git a/rpc/src/v1/tests/mocked/parity_set.rs b/rpc/src/v1/tests/mocked/parity_set.rs index 2ae8ab5b2be..af08236fdf6 100644 --- a/rpc/src/v1/tests/mocked/parity_set.rs +++ b/rpc/src/v1/tests/mocked/parity_set.rs @@ -26,9 +26,11 @@ use futures_cpupool::CpuPool; use jsonrpc_core::IoHandler; use v1::{ParitySet, ParitySetClient}; -use v1::tests::helpers::{TestMinerService, TestFetch, TestUpdater, TestDappsService}; +use v1::tests::helpers::{TestMinerService, TestUpdater, TestDappsService}; use super::manage_network::TestManageNetwork; +use fake_fetch::FakeFetch; + fn miner_service() -> Arc { Arc::new(TestMinerService::default()) } @@ -45,7 +47,7 @@ fn updater_service() -> Arc { Arc::new(TestUpdater::default()) } -pub type TestParitySetClient = ParitySetClient; +pub type TestParitySetClient = ParitySetClient>; fn parity_set_client( client: &Arc, @@ -55,7 +57,7 @@ fn parity_set_client( ) -> TestParitySetClient { let dapps_service = Arc::new(TestDappsService); let pool = CpuPool::new(1); - ParitySetClient::new(client, miner, updater, &(net.clone() as Arc), Some(dapps_service), TestFetch::default(), pool) + ParitySetClient::new(client, miner, updater, &(net.clone() as Arc), Some(dapps_service), FakeFetch::new(Some(1)), pool) } #[test] diff --git a/util/fake-fetch/Cargo.toml b/util/fake-fetch/Cargo.toml new file mode 100644 index 00000000000..217d7f461a5 --- /dev/null +++ b/util/fake-fetch/Cargo.toml @@ -0,0 +1,11 @@ +[package] +description = "Mock fetcher for testing" +name = "fake-fetch" +version = "0.0.1" +license = "GPL-3.0" +authors = ["Parity Technologies "] + +[dependencies] +fetch = { path = "../fetch" } +futures = "0.1" +hyper = "0.11" diff --git a/rpc/src/v1/tests/helpers/fetch.rs b/util/fake-fetch/src/lib.rs similarity index 58% rename from rpc/src/v1/tests/helpers/fetch.rs rename to util/fake-fetch/src/lib.rs index 7de3949c4bc..9dbe05b9cab 100644 --- a/rpc/src/v1/tests/helpers/fetch.rs +++ b/util/fake-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 @@ -14,37 +14,42 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -//! Test implementation of fetch client. +extern crate fetch; +extern crate hyper; +extern crate futures; -use std::thread; -use std::boxed::Box; -use jsonrpc_core::futures::{self, Future}; -use fetch::{self, Fetch, Url, Request}; -use futures::future; -use hyper; +use hyper::StatusCode; +use futures::{future, future::FutureResult}; +use fetch::{Fetch, Url, Request}; -/// Test implementation of fetcher. Will always return the same file. -#[derive(Default, Clone)] -pub struct TestFetch; +#[derive(Clone, Default)] +pub struct FakeFetch where T: Clone + Send + Sync { + val: Option, +} -impl Fetch for TestFetch { - type Result = Box + Send + 'static>; +impl FakeFetch where T: Clone + Send + Sync { + pub fn new(t: Option) -> Self { + FakeFetch { val : t } + } +} + +impl Fetch for FakeFetch where T: Clone + Send+ Sync { + type Result = FutureResult; fn fetch(&self, request: Request, abort: fetch::Abort) -> Self::Result { let u = request.url().clone(); - let (tx, rx) = futures::oneshot(); - thread::spawn(move || { + future::ok(if self.val.is_some() { let r = hyper::Response::new().with_body(&b"Some content"[..]); - tx.send(fetch::Response::new(u, r, abort)).unwrap(); - }); - - Box::new(rx.map_err(|_| fetch::Error::Aborted)) + fetch::client::Response::new(u, r, abort) + } else { + fetch::client::Response::new(u, hyper::Response::new().with_status(StatusCode::NotFound), abort) + }) } fn get(&self, url: &str, abort: fetch::Abort) -> Self::Result { let url: Url = match url.parse() { Ok(u) => u, - Err(e) => return Box::new(future::err(e.into())) + Err(e) => return future::err(e.into()) }; self.fetch(Request::get(url), abort) } @@ -52,7 +57,7 @@ impl Fetch for TestFetch { fn post(&self, url: &str, abort: fetch::Abort) -> Self::Result { let url: Url = match url.parse() { Ok(u) => u, - Err(e) => return Box::new(future::err(e.into())) + Err(e) => return future::err(e.into()) }; self.fetch(Request::post(url), abort) } From 6737484eda25aa9c5bc816e8318c8ce1f133c68b Mon Sep 17 00:00:00 2001 From: Thibaut S <33178835+Tbaut@users.noreply.github.com> Date: Wed, 11 Apr 2018 12:10:57 +0200 Subject: [PATCH 18/25] Increase gasLimit to 8'000'000 (#8362) - fix https://github.com/paritytech/parity/issues/8342 --- ethcore/res/instant_seal.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ethcore/res/instant_seal.json b/ethcore/res/instant_seal.json index e01c927ffdc..acd1b49ed04 100644 --- a/ethcore/res/instant_seal.json +++ b/ethcore/res/instant_seal.json @@ -24,7 +24,7 @@ "timestamp": "0x00", "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "extraData": "0x", - "gasLimit": "0x5B8D80" + "gasLimit": "0x7A1200" }, "accounts": { "0000000000000000000000000000000000000001": { "balance": "1", "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } }, From dd2c27958cfaabfab040a1cd583eee60c16ec2b1 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Wed, 11 Apr 2018 12:56:37 +0200 Subject: [PATCH 19/25] use atty instead of isatty (#8365) --- Cargo.lock | 45 +++++++++++++++++++++++++++------------------ Cargo.toml | 2 +- logger/Cargo.toml | 2 +- logger/src/lib.rs | 14 +++++++------- parity/informant.rs | 4 ++-- parity/main.rs | 2 +- 6 files changed, 39 insertions(+), 30 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d5c7963f64c..6315a88c2d5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -40,12 +40,12 @@ dependencies = [ [[package]] name = "atty" -version = "0.2.2" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "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)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -220,7 +220,7 @@ version = "2.29.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", - "atty 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "atty 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -635,8 +635,8 @@ version = "1.11.0" dependencies = [ "ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "atty 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "isatty 0.1.3 (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)", "parking_lot 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1298,16 +1298,6 @@ name = "ipnetwork" version = "0.12.7" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "isatty" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "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)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "itertools" version = "0.5.10" @@ -1927,6 +1917,7 @@ version = "1.11.0" dependencies = [ "ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", "app_dirs 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "atty 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "clap 2.29.1 (registry+https://github.com/rust-lang/crates.io-index)", "ctrlc 1.1.1 (git+https://github.com/paritytech/rust-ctrlc.git)", "daemonize 0.2.3 (git+https://github.com/paritytech/daemonize)", @@ -1954,7 +1945,6 @@ 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)", "ipnetwork 0.12.7 (registry+https://github.com/rust-lang/crates.io-index)", - "isatty 0.1.3 (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", @@ -2661,6 +2651,14 @@ name = "redox_syscall" version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "redox_termios" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "redox_syscall 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "regex" version = "0.2.5" @@ -3125,6 +3123,16 @@ dependencies = [ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "termion" +version = "1.5.1" +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)", + "redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "textwrap" version = "0.9.0" @@ -3735,7 +3743,7 @@ dependencies = [ "checksum app_dirs 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e73a24bad9bd6a94d6395382a6c69fe071708ae4409f763c5475e14ee896313d" "checksum arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef" "checksum aster 0.41.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4ccfdf7355d9db158df68f976ed030ab0f6578af811f5a7bb6dcf221ec24e0e0" -"checksum atty 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d912da0db7fa85514874458ca3651fe2cddace8d0b0505571dbdcd41ab490159" +"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" "checksum backtrace-sys 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "c63ea141ef8fdb10409d0f5daf30ac51f84ef43bff66f16627773d2a292cd189" "checksum base-x 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2f59103b47307f76e03bef1633aec7fa9e29bfb5aa6daf5a334f94233c71f6c1" @@ -3812,7 +3820,6 @@ dependencies = [ "checksum interleaved-ordered 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "141340095b15ed7491bd3d4ced9d20cebfb826174b6bb03386381f62b01e3d77" "checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08" "checksum ipnetwork 0.12.7 (registry+https://github.com/rust-lang/crates.io-index)" = "2134e210e2a024b5684f90e1556d5f71a1ce7f8b12e9ac9924c67fb36f63b336" -"checksum isatty 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "fa500db770a99afe2a0f2229be2a3d09c7ed9d7e4e8440bf71253141994e240f" "checksum itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4833d6978da405305126af4ac88569b5d71ff758581ce5a987dbfa3755f694fc" "checksum itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8324a32baf01e2ae060e9de58ed0bc2320c9a2833491ee36cd3b4c414de4db8c" "checksum jsonrpc-core 8.0.1 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.11)" = "" @@ -3902,6 +3909,7 @@ dependencies = [ "checksum rayon 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "80e811e76f1dbf68abf87a759083d34600017fc4e10b6bd5ad84a700f9dba4b1" "checksum rayon-core 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9d24ad214285a7729b174ed6d3bcfcb80177807f959d95fafd5bfc5c4f201ac8" "checksum redox_syscall 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)" = "8dde11f18c108289bef24469638a04dce49da56084f2d50618b226e47eb04509" +"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" "checksum regex 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "744554e01ccbd98fff8c457c3b092cd67af62a555a43bfe97ae8a0451f7799fa" "checksum regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad890a5eef7953f55427c50575c680c42841653abd2b028b68cd223d157f62db" "checksum relay 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1576e382688d7e9deecea24417e350d3062d97e32e45d70b1cde65994ff1489a" @@ -3953,6 +3961,7 @@ dependencies = [ "checksum tempfile 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "11ce2fe9db64b842314052e2421ac61a73ce41b898dc8e3750398b219c5fc1e0" "checksum term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "fa63644f74ce96fbeb9b794f66aff2a52d601cbd5e80f4b97123e3899f4570f1" "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_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" diff --git a/Cargo.toml b/Cargo.toml index 291e157cc40..b6c573a23b2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,7 +21,7 @@ semver = "0.9" ansi_term = "0.10" parking_lot = "0.5" regex = "0.2" -isatty = "0.1" +atty = "0.2.8" toml = "0.4" serde = "1.0" serde_json = "1.0" diff --git a/logger/Cargo.toml b/logger/Cargo.toml index 0e1b03f9411..368d860fd44 100644 --- a/logger/Cargo.toml +++ b/logger/Cargo.toml @@ -8,7 +8,7 @@ authors = ["Parity Technologies "] [dependencies] log = "0.3" env_logger = "0.4" -isatty = "0.1" +atty = "0.2" lazy_static = "1.0" regex = "0.2" time = "0.1" diff --git a/logger/src/lib.rs b/logger/src/lib.rs index a2cf6d2a02d..863075a0e52 100644 --- a/logger/src/lib.rs +++ b/logger/src/lib.rs @@ -16,23 +16,23 @@ //! Logger for parity executables +extern crate ansi_term; extern crate arrayvec; +extern crate atty; +extern crate env_logger; extern crate log as rlog; -extern crate isatty; +extern crate parking_lot; extern crate regex; -extern crate env_logger; extern crate time; + #[macro_use] extern crate lazy_static; -extern crate parking_lot; -extern crate ansi_term; mod rotating; use std::{env, thread, fs}; use std::sync::{Weak, Arc}; use std::io::Write; -use isatty::{stderr_isatty, stdout_isatty}; use env_logger::LogBuilder; use regex::Regex; use ansi_term::Colour; @@ -86,7 +86,7 @@ pub fn setup_log(config: &Config) -> Result, String> { builder.parse(s); } - let isatty = stderr_isatty(); + let isatty = atty::is(atty::Stream::Stderr); let enable_color = config.color && isatty; let logs = Arc::new(RotatingLogger::new(levels)); let logger = logs.clone(); @@ -122,7 +122,7 @@ pub fn setup_log(config: &Config) -> Result, String> { let _ = file.write_all(b"\n"); } logger.append(removed_color); - if !isatty && record.level() <= LogLevel::Info && stdout_isatty() { + if !isatty && record.level() <= LogLevel::Info && atty::is(atty::Stream::Stdout) { // duplicate INFO/WARN output to console println!("{}", ret); } diff --git a/parity/informant.rs b/parity/informant.rs index 2ccc622a708..fddcadebd87 100644 --- a/parity/informant.rs +++ b/parity/informant.rs @@ -22,6 +22,7 @@ use std::sync::{Arc}; use std::sync::atomic::{AtomicUsize, AtomicBool, Ordering as AtomicOrdering}; use std::time::{Instant, Duration}; +use atty; use ethcore::client::{ BlockId, BlockChainClient, ChainInfo, BlockInfo, BlockChainInfo, BlockQueueInfo, ChainNotify, ClientReport, Client, ClientIoMessage @@ -31,7 +32,6 @@ use ethcore::snapshot::{RestorationStatus, SnapshotService as SS}; use ethcore::snapshot::service::Service as SnapshotService; use sync::{LightSyncProvider, LightSync, SyncProvider, ManageNetwork}; use io::{TimerToken, IoContext, IoHandler}; -use isatty::{stdout_isatty}; use light::Cache as LightDataCache; use light::client::LightChainClient; use number_prefix::{binary_prefix, Standalone, Prefixed}; @@ -293,7 +293,7 @@ impl Informant { *self.last_tick.write() = Instant::now(); - let paint = |c: Style, t: String| match self.with_color && stdout_isatty() { + let paint = |c: Style, t: String| match self.with_color && atty::is(atty::Stream::Stdout) { true => format!("{}", c.paint(t)), false => t, }; diff --git a/parity/main.rs b/parity/main.rs index 7179996bf58..4908f38d9ac 100644 --- a/parity/main.rs +++ b/parity/main.rs @@ -29,7 +29,7 @@ extern crate env_logger; extern crate fdlimit; extern crate futures; extern crate futures_cpupool; -extern crate isatty; +extern crate atty; extern crate jsonrpc_core; extern crate num_cpus; extern crate number_prefix; From 2b05eb43a989fae5239e01fa93da294c43ec7d99 Mon Sep 17 00:00:00 2001 From: Toralf Wittner Date: Wed, 11 Apr 2018 13:57:12 +0200 Subject: [PATCH 20/25] Add `util/mem` to zero out memory on drop. (#8356) * Add `util/mem` to zero out memory on drop. * Remove nonsense. * Remove `Into` impls for `Memzero`. * Update ethereum-types and remove H256Mut. --- Cargo.lock | 107 ++++++++++-------- Cargo.toml | 1 + .../src/snapshot/tests/proof_of_authority.rs | 2 +- ethcore/transaction/src/transaction.rs | 2 +- ethkey/Cargo.toml | 1 + ethkey/src/extended.rs | 4 +- ethkey/src/lib.rs | 1 + ethkey/src/secret.rs | 30 +++-- rpc/src/v1/tests/mocked/eth.rs | 2 +- rpc/src/v1/tests/mocked/signing.rs | 2 +- secret_store/src/key_server.rs | 8 +- .../client_sessions/decryption_session.rs | 4 +- secret_store/src/key_server_cluster/math.rs | 4 +- util/mem/Cargo.toml | 6 + util/mem/src/lib.rs | 57 ++++++++++ whisper/Cargo.toml | 1 + whisper/src/lib.rs | 1 + whisper/src/rpc/crypto.rs | 40 ++++--- whisper/src/rpc/key_store.rs | 9 +- whisper/src/rpc/mod.rs | 3 +- 20 files changed, 190 insertions(+), 95 deletions(-) create mode 100644 util/mem/Cargo.toml create mode 100644 util/mem/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 6315a88c2d5..9456324fda5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -233,7 +233,7 @@ name = "common-types" version = "0.1.0" dependencies = [ "ethcore-bytes 0.1.0", - "ethereum-types 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "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", @@ -362,7 +362,7 @@ name = "dir" version = "0.1.0" dependencies = [ "app_dirs 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "ethereum-types 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "journaldb 0.1.0", ] @@ -434,7 +434,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.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.1 (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)", @@ -479,7 +479,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "ethereum-types-serialize 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "fixed-hash 0.2.0 (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)", ] @@ -505,7 +505,7 @@ dependencies = [ "ethcore-miner 1.11.0", "ethcore-stratum 1.11.0", "ethcore-transaction 0.1.0", - "ethereum-types 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "ethjson 0.1.0", "ethkey 0.3.0", "ethstore 0.2.0", @@ -571,7 +571,7 @@ name = "ethcore-crypto" version = "0.1.0" dependencies = [ "eth-secp256k1 0.5.7 (git+https://github.com/paritytech/rust-secp256k1)", - "ethereum-types 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "ethkey 0.3.0", "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)", @@ -603,7 +603,7 @@ dependencies = [ "ethcore-io 1.11.0", "ethcore-network 1.11.0", "ethcore-transaction 0.1.0", - "ethereum-types 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.1 (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)", @@ -661,7 +661,7 @@ dependencies = [ "ethabi-derive 5.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "ethash 1.11.0", "ethcore-transaction 0.1.0", - "ethereum-types 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.1 (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)", @@ -685,7 +685,7 @@ dependencies = [ "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore-crypto 0.1.0", "ethcore-io 1.11.0", - "ethereum-types 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.1 (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", @@ -704,7 +704,7 @@ dependencies = [ "ethcore-io 1.11.0", "ethcore-logger 1.11.0", "ethcore-network 1.11.0", - "ethereum-types 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.1 (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)", @@ -742,7 +742,7 @@ dependencies = [ "ethcore-logger 1.11.0", "ethcore-miner 1.11.0", "ethcore-transaction 0.1.0", - "ethereum-types 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "ethjson 0.1.0", "ethkey 0.3.0", "fetch 0.1.0", @@ -776,7 +776,7 @@ dependencies = [ "ethcore-logger 1.11.0", "ethcore-sync 1.11.0", "ethcore-transaction 0.1.0", - "ethereum-types 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.1 (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)", @@ -824,7 +824,7 @@ version = "1.11.0" dependencies = [ "env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore-logger 1.11.0", - "ethereum-types 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.1 (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)", @@ -847,7 +847,7 @@ dependencies = [ "ethcore-network 1.11.0", "ethcore-network-devp2p 1.11.0", "ethcore-transaction 0.1.0", - "ethereum-types 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.1 (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)", @@ -870,7 +870,7 @@ dependencies = [ name = "ethcore-transaction" version = "0.1.0" dependencies = [ - "ethereum-types 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "ethjson 0.1.0", "ethkey 0.3.0", "evm 0.1.0", @@ -883,13 +883,13 @@ dependencies = [ [[package]] name = "ethereum-types" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "ethbloom 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethereum-types-serialize 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "fixed-hash 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "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)", @@ -907,7 +907,7 @@ dependencies = [ name = "ethjson" version = "0.1.0" dependencies = [ - "ethereum-types 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.1 (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)", @@ -921,9 +921,10 @@ 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)", - "ethereum-types 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "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)", "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)", @@ -952,7 +953,7 @@ version = "0.2.0" dependencies = [ "dir 0.1.0", "ethcore-crypto 0.1.0", - "ethereum-types 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.1 (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)", @@ -994,7 +995,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.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", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1013,7 +1014,7 @@ dependencies = [ "ethcore 1.11.0", "ethcore-bytes 0.1.0", "ethcore-transaction 0.1.0", - "ethereum-types 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "ethjson 0.1.0", "evm 0.1.0", "panic_hook 0.1.0", @@ -1058,7 +1059,7 @@ dependencies = [ [[package]] name = "fixed-hash" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1153,7 +1154,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "hardware-wallet" version = "1.11.0" dependencies = [ - "ethereum-types 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.1 (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)", @@ -1169,7 +1170,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.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1317,7 +1318,7 @@ version = "0.1.0" dependencies = [ "ethcore-bytes 0.1.0", "ethcore-logger 1.11.0", - "ethereum-types 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "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", @@ -1432,7 +1433,7 @@ name = "keccak-hash" version = "0.1.0" dependencies = [ "cc 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", - "ethereum-types 0.3.0 (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)", ] @@ -1468,7 +1469,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.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.1 (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)", @@ -1576,6 +1577,10 @@ name = "matches" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "mem" +version = "0.1.0" + [[package]] name = "memchr" version = "2.0.1" @@ -1617,7 +1622,7 @@ version = "0.1.1" dependencies = [ "bigint 4.2.0 (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.0 (registry+https://github.com/rust-lang/crates.io-index)", + "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", @@ -1764,7 +1769,7 @@ dependencies = [ "ethcore 1.11.0", "ethcore-io 1.11.0", "ethcore-network-devp2p 1.11.0", - "ethereum-types 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.1 (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)", @@ -1938,7 +1943,7 @@ dependencies = [ "ethcore-stratum 1.11.0", "ethcore-sync 1.11.0", "ethcore-transaction 0.1.0", - "ethereum-types 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.1 (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)", @@ -1951,6 +1956,7 @@ dependencies = [ "kvdb 0.1.0", "kvdb-rocksdb 0.1.0", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "mem 0.1.0", "migration 0.1.0", "node-filter 1.11.0", "node-health 0.1.0", @@ -1997,7 +2003,7 @@ dependencies = [ "env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore-bytes 0.1.0", "ethcore-devtools 1.11.0", - "ethereum-types 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.1 (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)", @@ -2062,7 +2068,7 @@ dependencies = [ "ethabi-contract 5.0.3 (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.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.1 (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)", @@ -2086,7 +2092,7 @@ dependencies = [ "cid 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore 1.11.0", "ethcore-bytes 0.1.0", - "ethereum-types 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.1 (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)", @@ -2115,7 +2121,7 @@ dependencies = [ name = "parity-machine" version = "0.1.0" dependencies = [ - "ethereum-types 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2145,7 +2151,7 @@ dependencies = [ "ethcore-private-tx 1.0.0", "ethcore-sync 1.11.0", "ethcore-transaction 0.1.0", - "ethereum-types 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "ethjson 0.1.0", "ethkey 0.3.0", "ethstore 0.2.0", @@ -2284,7 +2290,7 @@ dependencies = [ "ethcore 1.11.0", "ethcore-bytes 0.1.0", "ethcore-sync 1.11.0", - "ethereum-types 0.3.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", "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)", @@ -2329,13 +2335,14 @@ dependencies = [ "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore-crypto 0.1.0", "ethcore-network 1.11.0", - "ethereum-types 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.1 (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)", "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)", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "mem 0.1.0", "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)", @@ -2391,7 +2398,7 @@ dependencies = [ "elastic-array 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore-bytes 0.1.0", "ethcore-logger 1.11.0", - "ethereum-types 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "hashdb 0.1.1", "keccak-hash 0.1.0", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2447,7 +2454,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.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2546,7 +2553,7 @@ version = "0.1.0" dependencies = [ "clap 2.29.1 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore-logger 1.11.0", - "ethereum-types 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.1 (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)", @@ -2714,7 +2721,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.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3394,7 +3401,7 @@ name = "transaction-pool" version = "1.11.0" dependencies = [ "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "ethereum-types 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.1 (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)", ] @@ -3420,7 +3427,7 @@ name = "trie-standardmap" version = "0.1.0" dependencies = [ "ethcore-bytes 0.1.0", - "ethereum-types 0.3.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", "rlp 0.2.1", ] @@ -3430,7 +3437,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.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", "rlp 0.2.1", "trie-standardmap 0.1.0", @@ -3545,7 +3552,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.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.1 (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)", @@ -3577,7 +3584,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.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "ethjson 0.1.0", "keccak-hash 0.1.0", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3596,7 +3603,7 @@ version = "0.1.0" dependencies = [ "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore-logger 1.11.0", - "ethereum-types 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.1 (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)", @@ -3791,10 +3798,10 @@ dependencies = [ "checksum ethabi-contract 5.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ca2263c24359e827348ac99aa1f2e28ba5bab0d6c0b83941fa252de8a9e9c073" "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.0 (registry+https://github.com/rust-lang/crates.io-index)" = "53eabbad504e438e20b6559fd070d79b92cb31c02f994c7ecb05e9b2df716013" +"checksum ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3a3ae691a36ce5d25b433e63128ce5579f4a18457b6a9c849832b2c9e0fec92a" "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.0 (registry+https://github.com/rust-lang/crates.io-index)" = "362f32e2fbc5ed45f01a23ca074f936bb3aee4122a66e7118e8c3e965d96104c" +"checksum fixed-hash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b18d6fd718fb4396e7a9c93ac59ba7143501467ca7a143c145b5555a571d5576" "checksum flate2 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)" = "e6234dd4468ae5d1e2dbb06fe2b058696fdc50a339c68a393aefbf00bc81e423" "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" diff --git a/Cargo.toml b/Cargo.toml index b6c573a23b2..ffeb01ef87d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -69,6 +69,7 @@ migration = { path = "util/migration" } kvdb = { path = "util/kvdb" } kvdb-rocksdb = { path = "util/kvdb-rocksdb" } journaldb = { path = "util/journaldb" } +mem = { path = "util/mem" } parity-dapps = { path = "dapps", optional = true } ethcore-secretstore = { path = "secret_store", optional = true } diff --git a/ethcore/src/snapshot/tests/proof_of_authority.rs b/ethcore/src/snapshot/tests/proof_of_authority.rs index 7283a05863d..b0741b4c49e 100644 --- a/ethcore/src/snapshot/tests/proof_of_authority.rs +++ b/ethcore/src/snapshot/tests/proof_of_authority.rs @@ -39,7 +39,7 @@ const TRANSITION_BLOCK_1: usize = 2; // block at which the contract becomes acti const TRANSITION_BLOCK_2: usize = 10; // block at which the second contract activates. macro_rules! secret { - ($e: expr) => { Secret::from_slice(&$crate::hash::keccak($e)) } + ($e: expr) => { Secret::from($crate::hash::keccak($e).0) } } lazy_static! { diff --git a/ethcore/transaction/src/transaction.rs b/ethcore/transaction/src/transaction.rs index 4df63294bda..49f2534fac6 100644 --- a/ethcore/transaction/src/transaction.rs +++ b/ethcore/transaction/src/transaction.rs @@ -141,7 +141,7 @@ impl HeapSizeOf for Transaction { impl From for SignedTransaction { fn from(t: ethjson::state::Transaction) -> Self { let to: Option = t.to.into(); - let secret = t.secret.map(|s| Secret::from_slice(&s.0)); + let secret = t.secret.map(|s| Secret::from(s.0)); let tx = Transaction { nonce: t.nonce.into(), gas_price: t.gas_price.into(), diff --git a/ethkey/Cargo.toml b/ethkey/Cargo.toml index 51052bdca6b..335f92fe15a 100644 --- a/ethkey/Cargo.toml +++ b/ethkey/Cargo.toml @@ -10,6 +10,7 @@ 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" rand = "0.4" rust-crypto = "0.2" diff --git a/ethkey/src/extended.rs b/ethkey/src/extended.rs index 23aff0bee8e..55bae627542 100644 --- a/ethkey/src/extended.rs +++ b/ethkey/src/extended.rs @@ -99,7 +99,7 @@ impl ExtendedSecret { pub fn derive(&self, index: Derivation) -> ExtendedSecret where T: Label { let (derived_key, next_chain_code) = derivation::private(*self.secret, self.chain_code, index); - let derived_secret = Secret::from_slice(&*derived_key); + let derived_secret = Secret::from(derived_key.0); ExtendedSecret::with_code(derived_secret, next_chain_code) } @@ -399,7 +399,7 @@ mod tests { fn test_extended(f: F, test_private: H256) where F: Fn(ExtendedSecret) -> ExtendedSecret { let (private_seed, chain_code) = master_chain_basic(); - let extended_secret = ExtendedSecret::with_code(Secret::from_slice(&*private_seed), chain_code); + let extended_secret = ExtendedSecret::with_code(Secret::from(private_seed.0), chain_code); let derived = f(extended_secret); assert_eq!(**derived.as_raw(), test_private); } diff --git a/ethkey/src/lib.rs b/ethkey/src/lib.rs index 09a100b74cd..951179771b2 100644 --- a/ethkey/src/lib.rs +++ b/ethkey/src/lib.rs @@ -20,6 +20,7 @@ extern crate byteorder; extern crate crypto as rcrypto; extern crate edit_distance; extern crate ethereum_types; +extern crate mem; extern crate parity_wordlist; extern crate rand; extern crate rustc_hex; diff --git a/ethkey/src/secret.rs b/ethkey/src/secret.rs index 9b2faee7c6a..c3bf2a12bae 100644 --- a/ethkey/src/secret.rs +++ b/ethkey/src/secret.rs @@ -18,18 +18,20 @@ use std::fmt; use std::ops::Deref; use std::str::FromStr; use rustc_hex::ToHex; +use secp256k1::constants::{SECRET_KEY_SIZE as SECP256K1_SECRET_KEY_SIZE}; use secp256k1::key; use ethereum_types::H256; +use mem::Memzero; use {Error, SECP256K1}; #[derive(Clone, PartialEq, Eq)] pub struct Secret { - inner: H256, + inner: Memzero, } impl ToHex for Secret { fn to_hex(&self) -> String { - format!("{:x}", self.inner) + format!("{:x}", *self.inner) } } @@ -52,17 +54,19 @@ impl fmt::Display for Secret { } impl Secret { - pub fn from_slice(key: &[u8]) -> Self { - assert_eq!(32, key.len(), "Caller should provide 32-byte length slice"); - + /// Creates a `Secret` from the given slice, returning `None` if the slice length != 32. + pub fn from_slice(key: &[u8]) -> Option { + if key.len() != 32 { + return None + } let mut h = H256::default(); h.copy_from_slice(&key[0..32]); - Secret { inner: h } + Some(Secret { inner: Memzero::from(h) }) } /// Creates zero key, which is invalid for crypto operations, but valid for math operation. pub fn zero() -> Self { - Secret { inner: Default::default() } + Secret { inner: Memzero::from(H256::default()) } } /// Imports and validates the key. @@ -208,9 +212,15 @@ impl FromStr for Secret { } } +impl From<[u8; 32]> for Secret { + fn from(k: [u8; 32]) -> Self { + Secret { inner: Memzero::from(H256(k)) } + } +} + impl From for Secret { fn from(s: H256) -> Self { - Secret::from_slice(&s) + s.0.into() } } @@ -222,7 +232,9 @@ impl From<&'static str> for Secret { impl From for Secret { fn from(key: key::SecretKey) -> Self { - Self::from_slice(&key[0..32]) + let mut a = [0; SECP256K1_SECRET_KEY_SIZE]; + a.copy_from_slice(&key[0 .. SECP256K1_SECRET_KEY_SIZE]); + a.into() } } diff --git a/rpc/src/v1/tests/mocked/eth.rs b/rpc/src/v1/tests/mocked/eth.rs index e79411f7056..c79b02c2d23 100644 --- a/rpc/src/v1/tests/mocked/eth.rs +++ b/rpc/src/v1/tests/mocked/eth.rs @@ -329,7 +329,7 @@ fn rpc_eth_submit_hashrate() { fn rpc_eth_sign() { let tester = EthTester::default(); - let account = tester.accounts_provider.insert_account(Secret::from_slice(&[69u8; 32]), "abcd").unwrap(); + let account = tester.accounts_provider.insert_account(Secret::from([69u8; 32]), "abcd").unwrap(); tester.accounts_provider.unlock_account_permanently(account, "abcd".into()).unwrap(); let _message = "0cc175b9c0f1b6a831c399e26977266192eb5ffee6ae2fec3ad71c777531578f".from_hex().unwrap(); diff --git a/rpc/src/v1/tests/mocked/signing.rs b/rpc/src/v1/tests/mocked/signing.rs index 11e1ac44d41..118bbe91ce3 100644 --- a/rpc/src/v1/tests/mocked/signing.rs +++ b/rpc/src/v1/tests/mocked/signing.rs @@ -211,7 +211,7 @@ fn should_sign_if_account_is_unlocked() { // given let tester = eth_signing(); let data = vec![5u8]; - let acc = tester.accounts.insert_account(Secret::from_slice(&[69u8; 32]), "test").unwrap(); + let acc = tester.accounts.insert_account(Secret::from([69u8; 32]), "test").unwrap(); tester.accounts.unlock_account_permanently(acc, "test".into()).unwrap(); // when diff --git a/secret_store/src/key_server.rs b/secret_store/src/key_server.rs index 783e760455f..ea3a3c0a571 100644 --- a/secret_store/src/key_server.rs +++ b/secret_store/src/key_server.rs @@ -443,8 +443,8 @@ pub mod tests { let message_hash = H256::from(42); let combined_signature = key_servers[0].sign_message_schnorr(&server_key_id, &signature.into(), message_hash.clone()).unwrap(); let combined_signature = crypto::ecies::decrypt(&requestor_secret, &crypto::DEFAULT_MAC, &combined_signature).unwrap(); - let signature_c = Secret::from_slice(&combined_signature[..32]); - let signature_s = Secret::from_slice(&combined_signature[32..]); + let signature_c = Secret::from_slice(&combined_signature[..32]).unwrap(); + let signature_s = Secret::from_slice(&combined_signature[32..]).unwrap(); // check signature assert_eq!(math::verify_schnorr_signature(&server_public, &(signature_c, signature_s), &message_hash), Ok(true)); @@ -492,8 +492,8 @@ pub mod tests { let message_hash = H256::from(42); let combined_signature = key_servers[0].sign_message_schnorr(&server_key_id, &signature.into(), message_hash.clone()).unwrap(); let combined_signature = crypto::ecies::decrypt(&requestor_secret, &crypto::DEFAULT_MAC, &combined_signature).unwrap(); - let signature_c = Secret::from_slice(&combined_signature[..32]); - let signature_s = Secret::from_slice(&combined_signature[32..]); + let signature_c = Secret::from_slice(&combined_signature[..32]).unwrap(); + let signature_s = Secret::from_slice(&combined_signature[32..]).unwrap(); // check signature assert_eq!(math::verify_schnorr_signature(&server_public, &(signature_c, signature_s), &message_hash), Ok(true)); 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 3343652c2bc..c47dd26bad7 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 @@ -1272,7 +1272,7 @@ mod tests { use crypto::DEFAULT_MAC; use crypto::ecies::decrypt; let decrypt_shadows: Vec<_> = decrypted_secret.decrypt_shadows.unwrap().into_iter() - .map(|c| Secret::from_slice(&decrypt(key_pair.secret(), &DEFAULT_MAC, &c).unwrap())) + .map(|c| Secret::from_slice(&decrypt(key_pair.secret(), &DEFAULT_MAC, &c).unwrap()).unwrap()) .collect(); let decrypted_secret = math::decrypt_with_shadow_coefficients(decrypted_secret.decrypted_secret, decrypted_secret.common_point.unwrap(), decrypt_shadows).unwrap(); assert_eq!(decrypted_secret, SECRET_PLAIN.into()); @@ -1418,7 +1418,7 @@ mod tests { 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() - .map(|c| Secret::from_slice(&decrypt(key_pair.secret(), &DEFAULT_MAC, &c).unwrap())) + .map(|c| Secret::from_slice(&decrypt(key_pair.secret(), &DEFAULT_MAC, &c).unwrap()).unwrap()) .collect(); let decrypted_secret = math::decrypt_with_shadow_coefficients(result.decrypted_secret, result.common_point.unwrap(), decrypt_shadows).unwrap(); assert_eq!(decrypted_secret, SECRET_PLAIN.into()); diff --git a/secret_store/src/key_server_cluster/math.rs b/secret_store/src/key_server_cluster/math.rs index 78c444822be..ef6d88f67ce 100644 --- a/secret_store/src/key_server_cluster/math.rs +++ b/secret_store/src/key_server_cluster/math.rs @@ -37,7 +37,7 @@ pub fn zero_scalar() -> Secret { pub fn to_scalar(hash: H256) -> Result { let scalar: U256 = hash.into(); let scalar: H256 = (scalar % math::curve_order()).into(); - let scalar = Secret::from_slice(&*scalar); + let scalar = Secret::from(scalar.0); scalar.check_validity()?; Ok(scalar) } @@ -697,7 +697,7 @@ pub mod tests { // === required to generate shares of inv(x) mod r with out revealing // === any information about x or inv(x). // === https://www.researchgate.net/publication/280531698_Robust_Threshold_Elliptic_Curve_Digital_Signature - + // generate shared random secret e for given t let n = artifacts.id_numbers.len(); assert!(t * 2 + 1 <= n); diff --git a/util/mem/Cargo.toml b/util/mem/Cargo.toml new file mode 100644 index 00000000000..1cca222142e --- /dev/null +++ b/util/mem/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "mem" +version = "0.1.0" +authors = ["Parity Technologies "] + +[dependencies] diff --git a/util/mem/src/lib.rs b/util/mem/src/lib.rs new file mode 100644 index 00000000000..a8b9e53f66c --- /dev/null +++ b/util/mem/src/lib.rs @@ -0,0 +1,57 @@ +// 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 std::ops::{Deref, DerefMut}; +use std::ptr; + +/// Wrapper to zero out memory when dropped. +#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct Memzero> { + mem: T, +} + +impl> From for Memzero { + fn from(mem: T) -> Memzero { + Memzero { mem } + } +} + +impl> Drop for Memzero { + fn drop(&mut self) { + let n = self.mem.as_mut().len(); + let p = self.mem.as_mut().as_mut_ptr(); + for i in 0..n { + unsafe { + ptr::write_volatile(p.offset(i as isize), 0) + } + } + } +} + +impl> Deref for Memzero { + type Target = T; + + fn deref(&self) -> &Self::Target { + &self.mem + } +} + +impl> DerefMut for Memzero { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.mem + } +} + diff --git a/whisper/Cargo.toml b/whisper/Cargo.toml index 49d4dffede5..bd1fc2dbb05 100644 --- a/whisper/Cargo.toml +++ b/whisper/Cargo.toml @@ -13,6 +13,7 @@ ethcore-crypto = { path = "../ethcore/crypto" } ethkey = { path = "../ethkey" } hex = "0.2" log = "0.3" +mem = { path = "../util/mem" } ordered-float = "0.5" parking_lot = "0.5" rand = "0.4" diff --git a/whisper/src/lib.rs b/whisper/src/lib.rs index bcee122ec01..4aa1a99b9e6 100644 --- a/whisper/src/lib.rs +++ b/whisper/src/lib.rs @@ -23,6 +23,7 @@ extern crate ethcore_network as network; extern crate ethereum_types; extern crate ethkey; extern crate hex; +extern crate mem; extern crate ordered_float; extern crate parking_lot; extern crate rand; diff --git a/whisper/src/rpc/crypto.rs b/whisper/src/rpc/crypto.rs index e7782a07725..8780045b472 100644 --- a/whisper/src/rpc/crypto.rs +++ b/whisper/src/rpc/crypto.rs @@ -19,6 +19,7 @@ use crypto; 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 @@ -36,7 +37,7 @@ enum AesEncode { } enum EncryptionInner { - AES([u8; AES_KEY_LEN], [u8; AES_NONCE_LEN], AesEncode), + AES(Memzero<[u8; AES_KEY_LEN]>, [u8; AES_NONCE_LEN], AesEncode), ECIES(Public), } @@ -58,7 +59,7 @@ impl EncryptionInstance { /// /// If generating nonces with a secure RNG, limit uses such that /// the chance of collision is negligible. - pub fn aes(key: [u8; AES_KEY_LEN], nonce: [u8; AES_NONCE_LEN]) -> Self { + pub fn aes(key: Memzero<[u8; AES_KEY_LEN]>, nonce: [u8; AES_NONCE_LEN]) -> Self { EncryptionInstance(EncryptionInner::AES(key, nonce, AesEncode::AppendedNonce)) } @@ -66,7 +67,7 @@ impl EncryptionInstance { /// /// Key reuse here is extremely dangerous. It should be randomly generated /// with a secure RNG. - pub fn broadcast(key: [u8; AES_KEY_LEN], topics: Vec) -> Self { + pub fn broadcast(key: Memzero<[u8; AES_KEY_LEN]>, topics: Vec) -> Self { EncryptionInstance(EncryptionInner::AES(key, BROADCAST_IV, AesEncode::OnTopics(topics))) } @@ -74,7 +75,7 @@ impl EncryptionInstance { pub fn encrypt(self, plain: &[u8]) -> Vec { match self.0 { EncryptionInner::AES(key, nonce, encode) => { - let sealing_key = SealingKey::new(&AES_256_GCM, &key) + let sealing_key = SealingKey::new(&AES_256_GCM, &*key) .expect("key is of correct len; qed"); let encrypt_plain = move |buf: &mut Vec| { @@ -106,12 +107,10 @@ impl EncryptionInstance { } AesEncode::OnTopics(topics) => { let mut buf = Vec::new(); - let key = H256(key); - - for topic in topics { - buf.extend(&*(topic ^ key)); + for mut t in topics { + xor(&mut t.0, &key); + buf.extend(&t.0); } - encrypt_plain(&mut buf); buf } @@ -125,8 +124,15 @@ impl EncryptionInstance { } } +#[inline] +fn xor(a: &mut [u8; 32], b: &[u8; 32]) { + for i in 0 .. 32 { + a[i] ^= b[i] + } +} + enum AesExtract { - AppendedNonce([u8; AES_KEY_LEN]), // extract appended nonce. + AppendedNonce(Memzero<[u8; AES_KEY_LEN]>), // extract appended nonce. OnTopics(usize, usize, H256), // number of topics, index we know, topic we know. } @@ -147,7 +153,7 @@ impl DecryptionInstance { } /// 256-bit AES GCM decryption with appended nonce. - pub fn aes(key: [u8; AES_KEY_LEN]) -> Self { + pub fn aes(key: Memzero<[u8; AES_KEY_LEN]>) -> Self { DecryptionInstance(DecryptionInner::AES(AesExtract::AppendedNonce(key))) } @@ -164,13 +170,13 @@ impl DecryptionInstance { match self.0 { DecryptionInner::AES(extract) => { let decrypt = | - key: [u8; AES_KEY_LEN], + 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) + let opening_key = OpeningKey::new(&AES_256_GCM, &*key) .expect("key length is valid for mode; qed"); let mut buf = ciphertext.to_vec(); @@ -205,7 +211,7 @@ impl DecryptionInstance { let mut salted_topic = H256::new(); salted_topic.copy_from_slice(&ciphertext[(known_index * 32)..][..32]); - let key = (salted_topic ^ known_topic).0; + let key = Memzero::from((salted_topic ^ known_topic).0); let offset = num_topics * 32; decrypt(key, BROADCAST_IV, &ciphertext[offset..]) @@ -264,9 +270,9 @@ mod tests { let mut rng = OsRng::new().unwrap(); let mut test_message = move |message: &[u8]| { - let key = rng.gen(); + let key = Memzero::from(rng.gen::<[u8; 32]>()); - let instance = EncryptionInstance::aes(key, rng.gen()); + let instance = EncryptionInstance::aes(key.clone(), rng.gen()); let ciphertext = instance.encrypt(message); if !message.is_empty() { @@ -294,7 +300,7 @@ mod tests { let all_topics = (0..5).map(|_| rng.gen()).collect::>(); let known_idx = 2; let known_topic = all_topics[2]; - let key = rng.gen(); + let key = Memzero::from(rng.gen::<[u8; 32]>()); let instance = EncryptionInstance::broadcast(key, all_topics); let ciphertext = instance.encrypt(message); diff --git a/whisper/src/rpc/key_store.rs b/whisper/src/rpc/key_store.rs index f71ec5bf3b3..02781e20adc 100644 --- a/whisper/src/rpc/key_store.rs +++ b/whisper/src/rpc/key_store.rs @@ -23,6 +23,7 @@ use std::collections::HashMap; use ethereum_types::H256; use ethkey::{KeyPair, Public, Secret}; +use mem::Memzero; use rand::{Rng, OsRng}; use ring::error::Unspecified; @@ -35,7 +36,7 @@ pub enum Key { /// and signing. Asymmetric(KeyPair), /// AES-256 GCM mode. Suitable for encryption, decryption, but not signing. - Symmetric([u8; AES_KEY_LEN]), + Symmetric(Memzero<[u8; AES_KEY_LEN]>), } impl Key { @@ -49,7 +50,7 @@ impl Key { /// Generate a random symmetric key with the given cryptographic RNG. pub fn new_symmetric(rng: &mut OsRng) -> Self { - Key::Symmetric(rng.gen()) + Key::Symmetric(Memzero::from(rng.gen::<[u8; 32]>())) } /// From secret asymmetric key. Fails if secret is invalid. @@ -61,7 +62,7 @@ impl Key { /// From raw symmetric key. pub fn from_raw_symmetric(key: [u8; AES_KEY_LEN]) -> Self { - Key::Symmetric(key) + Key::Symmetric(Memzero::from(key)) } /// Get a handle to the public key if this is an asymmetric key. @@ -177,7 +178,7 @@ mod tests { #[test] fn rejects_invalid_secret() { - let bad_secret = ::ethkey::Secret::from_slice(&[0xff; 32]); + let bad_secret = ::ethkey::Secret::from([0xff; 32]); assert!(Key::from_secret(bad_secret).is_err()); } diff --git a/whisper/src/rpc/mod.rs b/whisper/src/rpc/mod.rs index 039df08a87a..e9e65770853 100644 --- a/whisper/src/rpc/mod.rs +++ b/whisper/src/rpc/mod.rs @@ -28,6 +28,7 @@ use jsonrpc_pubsub::{Session, PubSubMetadata, SubscriptionId}; use jsonrpc_macros::pubsub; use ethereum_types::H256; +use mem::Memzero; use parking_lot::RwLock; use self::filter::Filter; @@ -286,7 +287,7 @@ impl Whisper for WhisperClien let mut rng = OsRng::new() .map_err(|_| whisper_error("unable to acquire secure randomness"))?; - let key = rng.gen(); + let key = Memzero::from(rng.gen::<[u8; 32]>()); if req.topics.is_empty() { return Err(whisper_error("must supply at least one topic for broadcast message")); } From 0a9114203b8346971fdeab24e181e88a0d180d08 Mon Sep 17 00:00:00 2001 From: Maciej Hirsz Date: Wed, 11 Apr 2018 14:41:06 +0200 Subject: [PATCH 21/25] No hardcoded client name (#8368) * Fixes issues with version string if client name is substituted (required for Energy Web) --- rpc/src/v1/impls/web3.rs | 2 +- rpc/src/v1/tests/mocked/web3.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/rpc/src/v1/impls/web3.rs b/rpc/src/v1/impls/web3.rs index 6915af1d1e0..6fd6ff7a463 100644 --- a/rpc/src/v1/impls/web3.rs +++ b/rpc/src/v1/impls/web3.rs @@ -31,7 +31,7 @@ impl Web3Client { impl Web3 for Web3Client { fn client_version(&self) -> Result { - Ok(version().to_owned().replace("Parity/", "Parity//")) + Ok(version().to_owned().replacen("/", "//", 1)) } fn sha3(&self, data: Bytes) -> Result { diff --git a/rpc/src/v1/tests/mocked/web3.rs b/rpc/src/v1/tests/mocked/web3.rs index aceb36e5651..3c78d67ad38 100644 --- a/rpc/src/v1/tests/mocked/web3.rs +++ b/rpc/src/v1/tests/mocked/web3.rs @@ -24,7 +24,7 @@ fn rpc_web3_version() { let mut io = IoHandler::new(); io.extend_with(web3); - let v = version().to_owned().replace("Parity/", "Parity//"); + let v = version().to_owned().replacen("/", "//", 1); let request = r#"{"jsonrpc": "2.0", "method": "web3_clientVersion", "params": [], "id": 1}"#; let response = r#"{"jsonrpc":"2.0","result":"VER","id":1}"#.to_owned().replace("VER", v.as_ref()); From 1356d6d8d55d98fc328bbf1e0c6ae4e3f64be1ee Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Wed, 11 Apr 2018 15:22:48 +0200 Subject: [PATCH 22/25] parity uses winapi 0.3.4 (#8366) * parity uses winapi 0.3.4 * remove redundant unsafe --- Cargo.lock | 3 +-- Cargo.toml | 3 +-- parity/main.rs | 7 +++---- parity/url.rs | 33 +++++++++------------------------ 4 files changed, 14 insertions(+), 32 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9456324fda5..fb1d9ce5575 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1991,8 +1991,7 @@ dependencies = [ "term_size 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index ffeb01ef87d..5103c2b2b73 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,7 +30,6 @@ app_dirs = "1.2.1" futures = "0.1" futures-cpupool = "0.1" fdlimit = "0.1" -ws2_32-sys = "0.2" ctrlc = { git = "https://github.com/paritytech/rust-ctrlc.git" } jsonrpc-core = { git = "https://github.com/paritytech/jsonrpc.git", branch = "parity-1.11" } ethcore = { path = "ethcore" } @@ -86,7 +85,7 @@ tempdir = "0.3" fake-fetch = { path = "util/fake-fetch" } [target.'cfg(windows)'.dependencies] -winapi = "0.2" +winapi = { version = "0.3.4", features = ["winsock2", "winuser", "shellapi"] } [target.'cfg(not(windows))'.dependencies] daemonize = { git = "https://github.com/paritytech/daemonize" } diff --git a/parity/main.rs b/parity/main.rs index 4908f38d9ac..0b7c31d954d 100644 --- a/parity/main.rs +++ b/parity/main.rs @@ -95,7 +95,6 @@ extern crate parity_dapps; #[macro_use] extern crate pretty_assertions; -#[cfg(windows)] extern crate ws2_32; #[cfg(windows)] extern crate winapi; #[cfg(test)] @@ -238,7 +237,7 @@ fn global_cleanup() { // The loop is required because of internal refernce 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 { - unsafe { ::ws2_32::WSACleanup(); } + unsafe { ::winapi::um::winsock2::WSACleanup(); } } } @@ -250,8 +249,8 @@ fn global_init() { // When restarting in the same process this reinits windows sockets. unsafe { const WS_VERSION: u16 = 0x202; - let mut wsdata: ::winapi::winsock2::WSADATA = ::std::mem::zeroed(); - ::ws2_32::WSAStartup(WS_VERSION, &mut wsdata); + let mut wsdata: ::winapi::um::winsock2::WSADATA = ::std::mem::zeroed(); + ::winapi::um::winsock2::WSAStartup(WS_VERSION, &mut wsdata); } } diff --git a/parity/url.rs b/parity/url.rs index fd64e46eca8..9b8959f01db 100644 --- a/parity/url.rs +++ b/parity/url.rs @@ -16,34 +16,19 @@ //! Cross-platform open url in default browser -#[cfg(windows)] -mod shell { - extern crate winapi; - - use self::winapi::*; - extern "system" { - pub fn ShellExecuteA( - hwnd: HWND, lpOperation: LPCSTR, lpFile: LPCSTR, lpParameters: LPCSTR, lpDirectory: LPCSTR, - nShowCmd: c_int - ) -> HINSTANCE; - } - - pub use self::winapi::SW_SHOWNORMAL as Normal; -} - #[cfg(windows)] pub fn open(url: &str) { use std::ffi::CString; use std::ptr; - - unsafe { - shell::ShellExecuteA(ptr::null_mut(), - CString::new("open").unwrap().as_ptr(), - CString::new(url.to_owned().replace("\n", "%0A")).unwrap().as_ptr(), - ptr::null(), - ptr::null(), - shell::Normal); - } + use winapi::um::shellapi::ShellExecuteA; + use winapi::um::winuser::SW_SHOWNORMAL as Normal; + + ShellExecuteA(ptr::null_mut(), + CString::new("open").unwrap().as_ptr(), + CString::new(url.to_owned().replace("\n", "%0A")).unwrap().as_ptr(), + ptr::null(), + ptr::null(), + Normal); } #[cfg(any(target_os="macos", target_os="freebsd"))] From 0a170efaa5ee9a1df824630db2a997ad52f6ef57 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Wed, 11 Apr 2018 18:21:29 +0200 Subject: [PATCH 23/25] fixed unsafe shell call on windows (#8372) --- parity/url.rs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/parity/url.rs b/parity/url.rs index 9b8959f01db..4189ae24184 100644 --- a/parity/url.rs +++ b/parity/url.rs @@ -23,12 +23,14 @@ pub fn open(url: &str) { use winapi::um::shellapi::ShellExecuteA; use winapi::um::winuser::SW_SHOWNORMAL as Normal; - ShellExecuteA(ptr::null_mut(), - CString::new("open").unwrap().as_ptr(), - CString::new(url.to_owned().replace("\n", "%0A")).unwrap().as_ptr(), - ptr::null(), - ptr::null(), - Normal); + unsafe { + ShellExecuteA(ptr::null_mut(), + CString::new("open").unwrap().as_ptr(), + CString::new(url.to_owned().replace("\n", "%0A")).unwrap().as_ptr(), + ptr::null(), + ptr::null(), + Normal); + } } #[cfg(any(target_os="macos", target_os="freebsd"))] From 16f435b906836a7979d50120d27d384641bec9e2 Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Thu, 12 Apr 2018 13:05:45 +0200 Subject: [PATCH 24/25] Fix config test by adding no-hardcodec-sync (#8380) --- parity/cli/tests/config.full.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/parity/cli/tests/config.full.toml b/parity/cli/tests/config.full.toml index 08df68ee508..fb3614aa96d 100644 --- a/parity/cli/tests/config.full.toml +++ b/parity/cli/tests/config.full.toml @@ -17,6 +17,7 @@ db_path = "$HOME/.parity/chains" keys_path = "$HOME/.parity/keys" identity = "" light = false +no_hardcoded_sync = false [account] unlock = ["0xdeadbeefcafe0000000000000000000000000000"] From bc2f5586eeb902860f81558d274264b8c1f084b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Silva?= Date: Thu, 12 Apr 2018 14:53:54 +0100 Subject: [PATCH 25/25] ci: fix change detection in master builds (#8382) --- scripts/gitlab-test.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/gitlab-test.sh b/scripts/gitlab-test.sh index 812317a2704..a617f68e227 100755 --- a/scripts/gitlab-test.sh +++ b/scripts/gitlab-test.sh @@ -2,7 +2,7 @@ #ARGUMENT test for RUST and COVERAGE set -e # fail on any error set -u # treat unset variables as error -if [[ "$CI_COMMIT_REF_NAME" = "beta" || "$CI_COMMIT_REF_NAME" = "stable" ]]; then +if [[ "$CI_COMMIT_REF_NAME" = "master" || "$CI_COMMIT_REF_NAME" = "beta" || "$CI_COMMIT_REF_NAME" = "stable" ]]; then export GIT_COMPARE=$CI_COMMIT_REF_NAME~; else export GIT_COMPARE=master;