From eea3de00c1636a84966271597f6f49f14b2f7da4 Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Thu, 10 Jan 2019 13:11:39 +0100 Subject: [PATCH 001/168] Merge Machine and WithRewards (#10071) --- ethcore/src/engines/block_reward.rs | 4 ++-- ethcore/src/engines/null_engine.rs | 4 ++-- ethcore/src/machine.rs | 12 +++++------- machine/src/lib.rs | 17 +++++++---------- 4 files changed, 16 insertions(+), 21 deletions(-) diff --git a/ethcore/src/engines/block_reward.rs b/ethcore/src/engines/block_reward.rs index 39d1afa7dc..42db6889c8 100644 --- a/ethcore/src/engines/block_reward.rs +++ b/ethcore/src/engines/block_reward.rs @@ -25,7 +25,7 @@ use std::sync::Arc; use hash::keccak; use error::Error; use machine::WithRewards; -use parity_machine::{Machine, WithBalances}; +use parity_machine::Machine; use trace; use types::BlockNumber; use super::{SystemOrCodeCall, SystemOrCodeCallKind}; @@ -152,7 +152,7 @@ impl BlockRewardContract { /// Applies the given block rewards, i.e. adds the given balance to each beneficiary' address. /// If tracing is enabled the operations are recorded. -pub fn apply_block_rewards( +pub fn apply_block_rewards( rewards: &[(Address, RewardKind, U256)], block: &mut M::LiveBlock, machine: &M, diff --git a/ethcore/src/engines/null_engine.rs b/ethcore/src/engines/null_engine.rs index c62d372e9d..4a2610259c 100644 --- a/ethcore/src/engines/null_engine.rs +++ b/ethcore/src/engines/null_engine.rs @@ -18,7 +18,7 @@ use engines::Engine; use engines::block_reward::{self, RewardKind}; use ethereum_types::U256; use machine::WithRewards; -use parity_machine::{Header, LiveBlock, WithBalances, TotalScoredHeader}; +use parity_machine::{Machine, Header, LiveBlock, TotalScoredHeader}; use types::BlockNumber; /// Params for a null engine. @@ -58,7 +58,7 @@ impl Default for NullEngine { } } -impl Engine for NullEngine +impl Engine for NullEngine where M::ExtendedHeader: TotalScoredHeader, ::Value: Ord { diff --git a/ethcore/src/machine.rs b/ethcore/src/machine.rs index 4ceab9bf02..873262d5dc 100644 --- a/ethcore/src/machine.rs +++ b/ethcore/src/machine.rs @@ -437,14 +437,7 @@ impl ::parity_machine::Machine for EthereumMachine { type AncestryAction = ::types::ancestry_action::AncestryAction; type Error = Error; -} - -impl<'a> ::parity_machine::LocalizedMachine<'a> for EthereumMachine { - type StateContext = Call<'a>; - type AuxiliaryData = AuxiliaryData<'a>; -} -impl ::parity_machine::WithBalances for EthereumMachine { fn balance(&self, live: &ExecutedBlock, address: &Address) -> Result { live.state().balance(address).map_err(Into::into) } @@ -454,6 +447,11 @@ impl ::parity_machine::WithBalances for EthereumMachine { } } +impl<'a> ::parity_machine::LocalizedMachine<'a> for EthereumMachine { + type StateContext = Call<'a>; + type AuxiliaryData = AuxiliaryData<'a>; +} + /// A state machine that uses block rewards. pub trait WithRewards: ::parity_machine::Machine { /// Note block rewards, traces each reward storing information about benefactor, amount and type diff --git a/machine/src/lib.rs b/machine/src/lib.rs index 8a0b5e3f2e..b7054ca038 100644 --- a/machine/src/lib.rs +++ b/machine/src/lib.rs @@ -112,6 +112,13 @@ pub trait Machine: for<'a> LocalizedMachine<'a> { /// Errors which can occur when querying or interacting with the machine. type Error; + + /// Get the balance, in base units, associated with an account. + /// Extracts data from the live block. + fn balance(&self, live: &Self::LiveBlock, address: &Address) -> Result; + + /// Increment the balance of an account in the state of the live block. + fn add_balance(&self, live: &mut Self::LiveBlock, address: &Address, amount: &U256) -> Result<(), Self::Error>; } /// Machine-related types localized to a specific lifetime. @@ -123,13 +130,3 @@ pub trait LocalizedMachine<'a>: Sync + Send { /// Generally also provides verifiable proofs. type StateContext: ?Sized + 'a; } - -/// A state machine that uses balances. -pub trait WithBalances: Machine { - /// Get the balance, in base units, associated with an account. - /// Extracts data from the live block. - fn balance(&self, live: &Self::LiveBlock, address: &Address) -> Result; - - /// Increment the balance of an account in the state of the live block. - fn add_balance(&self, live: &mut Self::LiveBlock, address: &Address, amount: &U256) -> Result<(), Self::Error>; -} From 38af7f35fcba1f17191af2900f088750a76bd019 Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Thu, 10 Jan 2019 13:12:14 +0100 Subject: [PATCH 002/168] refactor(trim_right_matches -> trim_end_matches) (#10159) --- rpc/src/v1/types/transaction_request.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/rpc/src/v1/types/transaction_request.rs b/rpc/src/v1/types/transaction_request.rs index bfefde462d..e7a2126b40 100644 --- a/rpc/src/v1/types/transaction_request.rs +++ b/rpc/src/v1/types/transaction_request.rs @@ -57,8 +57,7 @@ pub fn format_ether(i: U256) -> String { } else { string.insert(idx as usize, '.'); } - String::from(string.trim_right_matches('0') - .trim_right_matches('.')) + String::from(string.trim_end_matches('0').trim_end_matches('.')) } impl fmt::Display for TransactionRequest { From eea5f6f2326ff79f5631d0c2b38dc361ff20e84b Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Thu, 10 Jan 2019 13:13:15 +0100 Subject: [PATCH 003/168] fix(android): remove dependency to libusb (#10161) --- ethcore/Cargo.toml | 4 ++-- ethcore/src/lib.rs | 4 ++-- rpc/Cargo.toml | 4 ++-- rpc/src/lib.rs | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/ethcore/Cargo.toml b/ethcore/Cargo.toml index 5179584c11..9a286dcb9b 100644 --- a/ethcore/Cargo.toml +++ b/ethcore/Cargo.toml @@ -71,10 +71,10 @@ using_queue = { path = "../miner/using-queue" } vm = { path = "vm" } wasm = { path = "wasm" } -[target.'cfg(any(target_os = "linux", target_os = "macos", target_os = "windows", target_os = "android"))'.dependencies] +[target.'cfg(any(target_os = "linux", target_os = "macos", target_os = "windows"))'.dependencies] hardware-wallet = { path = "../accounts/hw" } -[target.'cfg(not(any(target_os = "linux", target_os = "macos", target_os = "windows", target_os = "android")))'.dependencies] +[target.'cfg(not(any(target_os = "linux", target_os = "macos", target_os = "windows")))'.dependencies] fake-hardware-wallet = { path = "../accounts/fake-hardware-wallet" } [dev-dependencies] diff --git a/ethcore/src/lib.rs b/ethcore/src/lib.rs index 89f6f8e09e..73fdb64fde 100644 --- a/ethcore/src/lib.rs +++ b/ethcore/src/lib.rs @@ -115,10 +115,10 @@ extern crate kvdb_rocksdb; #[cfg(any(test, feature = "blooms-db"))] extern crate blooms_db; -#[cfg(any(target_os = "linux", target_os = "macos", target_os = "windows", target_os = "android"))] +#[cfg(any(target_os = "linux", target_os = "macos", target_os = "windows"))] extern crate hardware_wallet; -#[cfg(not(any(target_os = "linux", target_os = "macos", target_os = "windows", target_os = "android")))] +#[cfg(not(any(target_os = "linux", target_os = "macos", target_os = "windows")))] extern crate fake_hardware_wallet as hardware_wallet; #[macro_use] diff --git a/rpc/Cargo.toml b/rpc/Cargo.toml index a04ca970b7..c3acc4664c 100644 --- a/rpc/Cargo.toml +++ b/rpc/Cargo.toml @@ -62,10 +62,10 @@ eip-712 = { path = "../util/EIP-712" } stats = { path = "../util/stats" } vm = { path = "../ethcore/vm" } -[target.'cfg(any(target_os = "linux", target_os = "macos", target_os = "windows", target_os = "android"))'.dependencies] +[target.'cfg(any(target_os = "linux", target_os = "macos", target_os = "windows"))'.dependencies] hardware-wallet = { path = "../accounts/hw" } -[target.'cfg(not(any(target_os = "linux", target_os = "macos", target_os = "windows", target_os = "android")))'.dependencies] +[target.'cfg(not(any(target_os = "linux", target_os = "macos", target_os = "windows")))'.dependencies] fake-hardware-wallet = { path = "../accounts/fake-hardware-wallet" } [dev-dependencies] diff --git a/rpc/src/lib.rs b/rpc/src/lib.rs index a72e5e1837..001343d649 100644 --- a/rpc/src/lib.rs +++ b/rpc/src/lib.rs @@ -67,9 +67,9 @@ extern crate rlp; extern crate stats; extern crate vm; -#[cfg(any(target_os = "linux", target_os = "macos", target_os = "windows", target_os = "android"))] +#[cfg(any(target_os = "linux", target_os = "macos", target_os = "windows"))] extern crate hardware_wallet; -#[cfg(not(any(target_os = "linux", target_os = "macos", target_os = "windows", target_os = "android")))] +#[cfg(not(any(target_os = "linux", target_os = "macos", target_os = "windows")))] extern crate fake_hardware_wallet as hardware_wallet; #[macro_use] From 83f706186f198370ed2cc0a353b52a7d8ca34c83 Mon Sep 17 00:00:00 2001 From: Kirill Pimenov Date: Thu, 10 Jan 2019 19:43:16 +0000 Subject: [PATCH 004/168] Ping nodes from discovery (#10167) --- util/network-devp2p/src/discovery.rs | 93 ++++++++++++++++++++++------ 1 file changed, 73 insertions(+), 20 deletions(-) diff --git a/util/network-devp2p/src/discovery.rs b/util/network-devp2p/src/discovery.rs index 980531ba2f..f6eaf494b9 100644 --- a/util/network-devp2p/src/discovery.rs +++ b/util/network-devp2p/src/discovery.rs @@ -53,12 +53,15 @@ const REQUEST_BACKOFF: [Duration; 4] = [ Duration::from_secs(64) ]; +const NODE_LAST_SEEN_TIMEOUT: Duration = Duration::from_secs(24*60*60); + #[derive(Clone, Debug)] pub struct NodeEntry { pub id: NodeId, pub endpoint: NodeEndpoint, } +#[derive(Debug)] pub struct BucketEntry { pub address: NodeEntry, pub id_hash: H256, @@ -89,6 +92,12 @@ struct FindNodeRequest { answered: bool, } +#[derive(Clone, Copy)] +enum PingReason { + Default, + FromDiscoveryRequest(NodeId) +} + struct PingRequest { // Time when the request was sent sent_at: Instant, @@ -99,8 +108,10 @@ struct PingRequest { // The hash Parity used to respond with (until rev 01f825b0e1f1c4c420197b51fc801cbe89284b29) #[deprecated()] deprecated_echo_hash: H256, + reason: PingReason } +#[derive(Debug)] pub struct NodeBucket { nodes: VecDeque, //sorted by last active } @@ -178,7 +189,7 @@ impl<'a> Discovery<'a> { if self.node_buckets[dist].nodes.iter().any(|n| n.id_hash == id_hash) { return; } - self.try_ping(e); + self.try_ping(e, PingReason::Default); } } @@ -221,7 +232,7 @@ impl<'a> Discovery<'a> { } else { None } }; if let Some(node) = ping { - self.try_ping(node); + self.try_ping(node, PingReason::Default); } Some(TableUpdates { added: added_map, removed: HashSet::new() }) } @@ -244,7 +255,7 @@ impl<'a> Discovery<'a> { fn update_new_nodes(&mut self) { while self.in_flight_pings.len() < MAX_NODES_PING { match self.adding_nodes.pop() { - Some(next) => self.try_ping(next), + Some(next) => self.try_ping(next, PingReason::Default), None => break, } } @@ -298,7 +309,7 @@ impl<'a> Discovery<'a> { None // a and b are equal, so log distance is -inf } - fn try_ping(&mut self, node: NodeEntry) { + fn try_ping(&mut self, node: NodeEntry, reason: PingReason) { if !self.is_allowed(&node) { trace!(target: "discovery", "Node {:?} not allowed", node); return; @@ -313,7 +324,7 @@ impl<'a> Discovery<'a> { } if self.in_flight_pings.len() < MAX_NODES_PING { - self.ping(&node) + self.ping(&node, reason) .unwrap_or_else(|e| { warn!(target: "discovery", "Error sending Ping packet: {:?}", e); }); @@ -322,7 +333,7 @@ impl<'a> Discovery<'a> { } } - fn ping(&mut self, node: &NodeEntry) -> Result<(), Error> { + fn ping(&mut self, node: &NodeEntry, reason: PingReason) -> Result<(), Error> { let mut rlp = RlpStream::new_list(4); rlp.append(&PROTOCOL_VERSION); self.public_endpoint.to_rlp_list(&mut rlp); @@ -336,6 +347,7 @@ impl<'a> Discovery<'a> { node: node.clone(), echo_hash: hash, deprecated_echo_hash: old_parity_hash, + reason: reason }); trace!(target: "discovery", "Sent Ping to {:?} ; node_id={:#x}", &node.endpoint, node.id); @@ -514,7 +526,7 @@ impl<'a> Discovery<'a> { if request.deprecated_echo_hash == echo_hash { trace!(target: "discovery", "Got Pong from an old parity-ethereum version."); } - Some(request.node.clone()) + Some((request.node.clone(), request.reason.clone())) } }; @@ -528,7 +540,10 @@ impl<'a> Discovery<'a> { }, }; - if let Some(node) = expected_node { + if let Some((node, ping_reason)) = expected_node { + if let PingReason::FromDiscoveryRequest(target) = ping_reason { + self.respond_with_discovery(target, &node)?; + } Ok(self.update_node(node)) } else { debug!(target: "discovery", "Got unexpected Pong from {:?} ; request not found", &from); @@ -536,21 +551,59 @@ impl<'a> Discovery<'a> { } } - fn on_find_node(&mut self, rlp: &Rlp, _node: &NodeId, from: &SocketAddr) -> Result, Error> { + fn on_find_node(&mut self, rlp: &Rlp, node_id: &NodeId, from: &SocketAddr) -> Result, Error> { trace!(target: "discovery", "Got FindNode from {:?}", &from); let target: NodeId = rlp.val_at(0)?; let timestamp: u64 = rlp.val_at(1)?; self.check_timestamp(timestamp)?; + + let node = NodeEntry { + id: node_id.clone(), + endpoint: NodeEndpoint { + address: *from, + udp_port: from.port() + } + }; + + if self.is_a_valid_known_node(&node) { + self.respond_with_discovery(target, &node)?; + } else { + // Make sure the request source is actually there and responds to pings before actually responding + self.try_ping(node, PingReason::FromDiscoveryRequest(target)); + } + Ok(None) + } + + fn is_a_valid_known_node(&self, node: &NodeEntry) -> bool { + let id_hash = keccak(node.id); + let dist = match Discovery::distance(&self.id_hash, &id_hash) { + Some(dist) => dist, + None => { + debug!(target: "discovery", "Got an incoming discovery request from self: {:?}", node); + return false; + } + }; + + let bucket = &self.node_buckets[dist]; + if let Some(known_node) = bucket.nodes.iter().find(|n| n.address.id == node.id) { + debug!(target: "discovery", "Found a known node in a bucket when processing discovery: {:?}/{:?}", known_node, node); + (known_node.address.endpoint == node.endpoint) && (known_node.last_seen.elapsed() < NODE_LAST_SEEN_TIMEOUT) + } else { + false + } + } + + fn respond_with_discovery(&mut self, target: NodeId, node: &NodeEntry) -> Result<(), Error> { let nearest = self.nearest_node_entries(&target); if nearest.is_empty() { - return Ok(None); + return Ok(()); } let mut packets = Discovery::prepare_neighbours_packets(&nearest); for p in packets.drain(..) { - self.send_packet(PACKET_NEIGHBOURS, from, &p)?; + self.send_packet(PACKET_NEIGHBOURS, &node.endpoint.address, &p)?; } - trace!(target: "discovery", "Sent {} Neighbours to {:?}", nearest.len(), &from); - Ok(None) + trace!(target: "discovery", "Sent {} Neighbours to {:?}", nearest.len(), &node.endpoint); + Ok(()) } fn prepare_neighbours_packets(nearest: &[NodeEntry]) -> Vec { @@ -825,7 +878,7 @@ mod tests { } // After 4 discovery rounds, the first one should have learned about the rest. - for _round in 0 .. 4 { + for _round in 0 .. 5 { discovery_handlers[0].round(); let mut continue_loop = true; @@ -833,9 +886,9 @@ mod tests { continue_loop = false; // Process all queued messages. - for i in 0 .. 5 { - let src = discovery_handlers[i].public_endpoint.address.clone(); - while let Some(datagram) = discovery_handlers[i].dequeue_send() { + for i in 0 .. 20 { + let src = discovery_handlers[i%5].public_endpoint.address.clone(); + while let Some(datagram) = discovery_handlers[i%5].dequeue_send() { let dest = discovery_handlers.iter_mut() .find(|disc| datagram.address == disc.public_endpoint.address) .unwrap(); @@ -927,14 +980,14 @@ mod tests { let mut discovery = Discovery { request_backoff: &request_backoff, ..discovery }; for _ in 0..2 { - discovery.ping(&node_entries[101]).unwrap(); + discovery.ping(&node_entries[101], PingReason::Default).unwrap(); let num_nodes = total_bucket_nodes(&discovery.node_buckets); discovery.check_expired(Instant::now() + PING_TIMEOUT); let removed = num_nodes - total_bucket_nodes(&discovery.node_buckets); assert_eq!(removed, 0); } - discovery.ping(&node_entries[101]).unwrap(); + discovery.ping(&node_entries[101], PingReason::Default).unwrap(); let num_nodes = total_bucket_nodes(&discovery.node_buckets); discovery.check_expired(Instant::now() + PING_TIMEOUT); let removed = num_nodes - total_bucket_nodes(&discovery.node_buckets); @@ -1121,7 +1174,7 @@ mod tests { let mut discovery1 = Discovery::new(&key1, ep1.clone(), IpFilter::default()); let mut discovery2 = Discovery::new(&key2, ep2.clone(), IpFilter::default()); - discovery1.ping(&NodeEntry { id: discovery2.id, endpoint: ep2.clone() }).unwrap(); + discovery1.ping(&NodeEntry { id: discovery2.id, endpoint: ep2.clone() }, PingReason::Default).unwrap(); let ping_data = discovery1.dequeue_send().unwrap(); assert!(!discovery1.any_sends_queued()); let data = &ping_data.payload[(32 + 65)..]; From 83ba9df85be98936686810ca1a61d43f3fa3c44d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Fri, 11 Jan 2019 16:55:03 +0100 Subject: [PATCH 005/168] Bump JSON-RPC (#10151) * Bump JSON-RPC * Fix test casing. --- Cargo.lock | 51 +++++++++++++++++++++++++--------------- rpc/src/tests/ws.rs | 2 +- rpc/src/v1/extractors.rs | 9 ++++--- 3 files changed, 37 insertions(+), 25 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 29e0f174bf..b09013a0bf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1746,7 +1746,7 @@ dependencies = [ [[package]] name = "jsonrpc-core" version = "9.0.0" -source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-2.2#f8a54f46f7f1d68b4e7899ca1e929803bf966a5b" +source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-2.2#84360bf1d03821b8fd669a6a95fcdf847aaf6cca" dependencies = [ "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1758,7 +1758,7 @@ dependencies = [ [[package]] name = "jsonrpc-http-server" version = "9.0.0" -source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-2.2#f8a54f46f7f1d68b4e7899ca1e929803bf966a5b" +source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-2.2#84360bf1d03821b8fd669a6a95fcdf847aaf6cca" dependencies = [ "hyper 0.12.11 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core 9.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-2.2)", @@ -1771,7 +1771,7 @@ dependencies = [ [[package]] name = "jsonrpc-ipc-server" version = "9.0.0" -source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-2.2#f8a54f46f7f1d68b4e7899ca1e929803bf966a5b" +source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-2.2#84360bf1d03821b8fd669a6a95fcdf847aaf6cca" dependencies = [ "jsonrpc-core 9.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-2.2)", "jsonrpc-server-utils 9.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-2.2)", @@ -1784,7 +1784,7 @@ dependencies = [ [[package]] name = "jsonrpc-macros" version = "9.0.0" -source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-2.2#f8a54f46f7f1d68b4e7899ca1e929803bf966a5b" +source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-2.2#84360bf1d03821b8fd669a6a95fcdf847aaf6cca" dependencies = [ "jsonrpc-core 9.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-2.2)", "jsonrpc-pubsub 9.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-2.2)", @@ -1794,7 +1794,7 @@ dependencies = [ [[package]] name = "jsonrpc-pubsub" version = "9.0.0" -source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-2.2#f8a54f46f7f1d68b4e7899ca1e929803bf966a5b" +source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-2.2#84360bf1d03821b8fd669a6a95fcdf847aaf6cca" dependencies = [ "jsonrpc-core 9.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-2.2)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1804,7 +1804,7 @@ dependencies = [ [[package]] name = "jsonrpc-server-utils" version = "9.0.0" -source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-2.2#f8a54f46f7f1d68b4e7899ca1e929803bf966a5b" +source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-2.2#84360bf1d03821b8fd669a6a95fcdf847aaf6cca" dependencies = [ "bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "globset 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1820,7 +1820,7 @@ dependencies = [ [[package]] name = "jsonrpc-tcp-server" version = "9.0.0" -source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-2.2#f8a54f46f7f1d68b4e7899ca1e929803bf966a5b" +source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-2.2#84360bf1d03821b8fd669a6a95fcdf847aaf6cca" dependencies = [ "jsonrpc-core 9.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-2.2)", "jsonrpc-server-utils 9.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-2.2)", @@ -1832,7 +1832,7 @@ dependencies = [ [[package]] name = "jsonrpc-ws-server" version = "9.0.0" -source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-2.2#f8a54f46f7f1d68b4e7899ca1e929803bf966a5b" +source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-2.2#84360bf1d03821b8fd669a6a95fcdf847aaf6cca" dependencies = [ "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core 9.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-2.2)", @@ -1840,7 +1840,7 @@ dependencies = [ "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "ws 0.7.5 (git+https://github.com/tomusdrw/ws-rs)", + "ws 0.7.9 (git+https://github.com/tomusdrw/ws-rs)", ] [[package]] @@ -2133,6 +2133,17 @@ dependencies = [ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "mio-extras" +version = "2.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lazycell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "mio-named-pipes" version = "0.1.6" @@ -3413,12 +3424,12 @@ dependencies = [ [[package]] name = "sha1" -version = "0.2.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "sha1" -version = "0.5.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -4310,17 +4321,18 @@ dependencies = [ [[package]] name = "ws" -version = "0.7.5" -source = "git+https://github.com/tomusdrw/ws-rs#f12d19c4c19422fc79af28a3181f598bc07ecd1e" +version = "0.7.9" +source = "git+https://github.com/tomusdrw/ws-rs#4baef2dc1abc8e216559af51cfc120bbcc777e21" dependencies = [ "byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "httparse 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", - "sha1 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "mio-extras 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -4509,6 +4521,7 @@ dependencies = [ "checksum mime 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)" = "0a907b83e7b9e987032439a387e187119cddafc92d5c2aaeb1d92580a793f630" "checksum mime_guess 2.0.0-alpha.6 (registry+https://github.com/rust-lang/crates.io-index)" = "30de2e4613efcba1ec63d8133f344076952090c122992a903359be5a4f99c3ed" "checksum mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)" = "71646331f2619b1026cc302f87a2b8b648d5c6dd6937846a16cc8ce0f347f432" +"checksum mio-extras 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "46e73a04c2fa6250b8d802134d56d554a9ec2922bf977777c805ea5def61ce40" "checksum mio-named-pipes 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "f5e374eff525ce1c5b7687c4cef63943e7686524a387933ad27ca7ec43779cb3" "checksum mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "966257a94e196b11bb43aca423754d87429960a768de9414f3691d6957abf125" "checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" @@ -4612,8 +4625,8 @@ dependencies = [ "checksum serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)" = "15c141fc7027dd265a47c090bf864cf62b42c4d228bbcf4e51a0c9e2b0d3f7ef" "checksum serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)" = "225de307c6302bec3898c51ca302fc94a7a1697ef0845fcee6448f33c032249c" "checksum serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)" = "43344e7ce05d0d8280c5940cabb4964bea626aa58b1ec0e8c73fa2a8512a38ce" -"checksum sha1 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cc30b1e1e8c40c121ca33b86c23308a090d19974ef001b4bf6e61fd1a0fb095c" "checksum sha1 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "171698ce4ec7cbb93babeb3190021b4d72e96ccb98e33d277ae4ea959d6f2d9e" +"checksum sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" "checksum sha2 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9eb6be24e4c23a84d7184280d2722f7f2731fcdd4a9d886efbfe4413e4847ea0" "checksum shell32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9ee04b46101f57121c9da2b151988283b6beb79b34f5bb29a58ee48cb695122c" "checksum simplelog 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e95345f185d5adeb8ec93459d2dc99654e294cc6ccf5b75414d8ea262de9a13" @@ -4709,7 +4722,7 @@ dependencies = [ "checksum winapi-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "afc5508759c5bf4285e61feb862b6083c8480aec864fa17a81fdec6f69b461ab" "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" "checksum wincolor 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "561ed901ae465d6185fa7864d63fbd5720d0ef718366c9a4dc83cf6170d7e9ba" -"checksum ws 0.7.5 (git+https://github.com/tomusdrw/ws-rs)" = "" +"checksum ws 0.7.9 (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.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3c1cb601d29fe2c2ac60a2b2e5e293994d87a1f6fa9687a31a15270f909be9c2" diff --git a/rpc/src/tests/ws.rs b/rpc/src/tests/ws.rs index aded13953c..7bb0b00894 100644 --- a/rpc/src/tests/ws.rs +++ b/rpc/src/tests/ws.rs @@ -75,7 +75,7 @@ mod testing { ); // then - assert_eq!(response.status, "HTTP/1.1 200 Ok".to_owned()); + assert_eq!(response.status, "HTTP/1.1 200 OK".to_owned()); } #[test] diff --git a/rpc/src/v1/extractors.rs b/rpc/src/v1/extractors.rs index adcf569d9b..2620125e0d 100644 --- a/rpc/src/v1/extractors.rs +++ b/rpc/src/v1/extractors.rs @@ -98,17 +98,16 @@ impl ws::RequestMiddleware for WsExtractor { fn process(&self, req: &ws::ws::Request) -> ws::MiddlewareAction { use self::ws::ws::Response; - // Reply with 200 Ok to HEAD requests. + // Reply with 200 OK to HEAD requests. if req.method() == "HEAD" { - let mut response = Response::new(200, "Ok"); + let mut response = Response::new(200, "OK", vec![]); add_security_headers(&mut response); return Some(response).into(); } // Display WS info. if req.header("sec-websocket-key").is_none() { - let mut response = Response::new(200, "Ok"); - response.set_body("WebSocket interface is active. Open WS connection to access RPC."); + let mut response = Response::new(200, "OK", b"WebSocket interface is active. Open WS connection to access RPC.".to_vec()); add_security_headers(&mut response); return Some(response).into(); } @@ -123,7 +122,7 @@ impl ws::RequestMiddleware for WsExtractor { "Blocked connection from {} using invalid token.", req.header("origin").and_then(|e| ::std::str::from_utf8(e).ok()).unwrap_or("Unknown Origin") ); - let mut response = Response::new(403, "Forbidden"); + let mut response = Response::new(403, "Forbidden", vec![]); add_security_headers(&mut response); return Some(response).into(); } From 67eee6aeb729084d1e45e6971bdbe31ad70e11da Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Fri, 11 Jan 2019 17:48:58 +0100 Subject: [PATCH 006/168] fix(whisper): correct PoW calculation (#10166) * Fix off-by-one error on `leading_zeros` which was used to index in the hash to get leading zeros when not aligned on byte boundary (i.e, all the bits in a byte was not zero such as 0001 1111) * Fix overflow by shifting with bigger value than 63 --- whisper/src/message.rs | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/whisper/src/message.rs b/whisper/src/message.rs index 14a6fcf9ce..f8e8565a8e 100644 --- a/whisper/src/message.rs +++ b/whisper/src/message.rs @@ -32,12 +32,13 @@ pub fn work_factor_proved(size: u64, ttl: u64, hash: H256) -> f64 { assert!(size != 0 && ttl != 0); let leading_zeros = { - let leading_zeros = hash.iter().take_while(|&&x| x == 0).count(); - (leading_zeros * 8) + hash.get(leading_zeros + 1).map_or(0, |b| b.leading_zeros() as usize) + let leading_bytes = hash.iter().take_while(|&&x| x == 0).count(); + let remaining_leading_bits = hash.get(leading_bytes).map_or(0, |byte| byte.leading_zeros() as usize); + (leading_bytes * 8) + remaining_leading_bits }; let spacetime = size as f64 * ttl as f64; - (1u64 << leading_zeros) as f64 / spacetime + 2.0_f64.powi(leading_zeros as i32) / spacetime } /// A topic of a message. @@ -416,6 +417,7 @@ impl Message { #[cfg(test)] mod tests { + use ethereum_types::H256; use super::*; use std::time::{self, Duration, SystemTime}; use rlp::Rlp; @@ -518,4 +520,14 @@ mod tests { let now = unix_time(95_000); Message::decode(Rlp::new(&*encoded), now).unwrap(); } + + #[test] + fn work_factor() { + // 256 leading zeros -> 2^256 / 1 + assert_eq!(work_factor_proved(1, 1, H256::from(0)), 115792089237316200000000000000000000000000000000000000000000000000000000000000.0); + // 255 leading zeros -> 2^255 / 1 + assert_eq!(work_factor_proved(1, 1, H256::from(1)), 57896044618658100000000000000000000000000000000000000000000000000000000000000.0); + // 0 leading zeros -> 2^0 / 1 + assert_eq!(work_factor_proved(1, 1, serde_json::from_str::("\"0xff00000000000000000000000000000000000000000000000000000000000000\"").unwrap()), 1.0); + } } From 3687df8da2a3fb547de0c9aa391f824d6c14d925 Mon Sep 17 00:00:00 2001 From: Nicolas Gotchac Date: Fri, 11 Jan 2019 17:59:05 +0100 Subject: [PATCH 007/168] Fix _cannot recursively call into `Core`_ issue (#10144) * Change igd to github:maufl/rust-igd * Run `igd::search_gateway_from_timeout` from own thread --- Cargo.lock | 63 +++++++++++++-------------- util/network-devp2p/src/ip_utils.rs | 66 ++++++++++++++++------------- 2 files changed, 67 insertions(+), 62 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b09013a0bf..e5f5ea27f7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -405,7 +405,7 @@ dependencies = [ "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -419,7 +419,7 @@ dependencies = [ "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -432,7 +432,7 @@ dependencies = [ "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-utils 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -539,7 +539,7 @@ name = "docopt" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", @@ -561,7 +561,7 @@ dependencies = [ "indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "lunarity-lexer 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -715,7 +715,7 @@ dependencies = [ "kvdb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb-memorydb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb-rocksdb 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "len-caching-lock 0.1.1", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "lru-cache 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -864,7 +864,7 @@ dependencies = [ "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1008,7 +1008,7 @@ dependencies = [ "keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb-rocksdb 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-crypto 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1135,7 +1135,7 @@ dependencies = [ "edit-distance 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "eth-secp256k1 0.5.7 (git+https://github.com/paritytech/rust-secp256k1)", "ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "memzero 0.1.0", "parity-crypto 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1214,7 +1214,7 @@ dependencies = [ "ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "memory-cache 0.1.0", "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1353,7 +1353,7 @@ name = "fs-swap" version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", "libloading 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1455,7 +1455,7 @@ name = "handlebars" version = "0.32.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "pest 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "pest_derive 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1809,7 +1809,7 @@ dependencies = [ "bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "globset 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core 9.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-2.2)", - "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1912,11 +1912,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "lazy_static" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", -] [[package]] name = "lazycell" @@ -2376,7 +2373,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "ring 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)", + "ring 0.13.5 (registry+https://github.com/rust-lang/crates.io-index)", "rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", "tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2677,7 +2674,7 @@ dependencies = [ "ethcore-sync 1.12.0", "ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2745,7 +2742,7 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3142,7 +3139,7 @@ version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3229,11 +3226,11 @@ dependencies = [ [[package]] name = "ring" -version = "0.13.2" +version = "0.13.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", "untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3264,7 +3261,7 @@ name = "rlp_compress" version = "0.1.0" dependencies = [ "elastic-array 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "rlp 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3341,7 +3338,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "ring 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)", + "ring 0.13.5 (registry+https://github.com/rust-lang/crates.io-index)", "sct 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "webpki 0.18.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3380,7 +3377,7 @@ name = "sct" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "ring 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)", + "ring 0.13.5 (registry+https://github.com/rust-lang/crates.io-index)", "untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3663,7 +3660,7 @@ name = "thread_local" version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3805,7 +3802,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4120,7 +4117,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4134,7 +4131,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "if_chain 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4242,7 +4239,7 @@ name = "webpki" version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "ring 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)", + "ring 0.13.5 (registry+https://github.com/rust-lang/crates.io-index)", "untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -4498,7 +4495,7 @@ dependencies = [ "checksum kvdb-memorydb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "45bcdf5eb083602cff61a6f8438dce2a7900d714e893fc48781c39fb119d37aa" "checksum kvdb-rocksdb 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "06cf755dc587839ba34d3cbe3f12b6ad55850fbcdfe67336157a021a1a5c43ae" "checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" -"checksum lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca488b89a5657b0a2ecd45b95609b3e848cf1755da332a0da46e2b2b1cb371a7" +"checksum lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a374c89b9db55895453a74c1e38861d9deec0b01b405a82516e9d5de4820dea1" "checksum lazycell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ddba4c30a78328befecec92fc94970e53b3ae385827d28620f0f5bb2493081e0" "checksum libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)" = "76e3a3ef172f1a0b9a9ff0dd1491ae5e6c948b94479a3021819ba7d860c8645d" "checksum libloading 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9c3ad660d7cb8c5822cd83d10897b0f1f1526792737a179e73896152f85b88c2" @@ -4602,7 +4599,7 @@ dependencies = [ "checksum regex-syntax 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "747ba3b235651f6e2f67dfa8bcdcd073ddb7c243cb21c442fc12395dfcac212d" "checksum relay 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1576e382688d7e9deecea24417e350d3062d97e32e45d70b1cde65994ff1489a" "checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5" -"checksum ring 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe642b9dd1ba0038d78c4a3999d1ee56178b4d415c1e1fbaba83b06dce012f0" +"checksum ring 0.13.5 (registry+https://github.com/rust-lang/crates.io-index)" = "2c4db68a2e35f3497146b7e4563df7d4773a2433230c5e4b448328e31740458a" "checksum rlp 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "524c5ad554859785dfc8469df3ed5e0b5784d4d335877ed47c8d90fc0eb238fe" "checksum rlp 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "16d1effe9845d54f90e7be8420ee49e5c94623140b97ee4bc6fb5bfddb745720" "checksum rpassword 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b273c91bd242ca03ad6d71c143b6f17a48790e61f21a6c78568fa2b6774a24a4" diff --git a/util/network-devp2p/src/ip_utils.rs b/util/network-devp2p/src/ip_utils.rs index a0834466a7..306f283934 100644 --- a/util/network-devp2p/src/ip_utils.rs +++ b/util/network-devp2p/src/ip_utils.rs @@ -40,7 +40,7 @@ pub trait SocketAddrExt { fn is_documentation_s(&self) -> bool { false } fn is_global_multicast(&self) -> bool { false } fn is_other_multicast(&self) -> bool { false } - + fn is_reserved(&self) -> bool; fn is_usable_public(&self) -> bool; fn is_usable_private(&self) -> bool; @@ -50,38 +50,38 @@ pub trait SocketAddrExt { impl SocketAddrExt for Ipv4Addr { fn is_global_s(&self) -> bool { - !self.is_private() && - !self.is_loopback() && + !self.is_private() && + !self.is_loopback() && !self.is_link_local() && - !self.is_broadcast() && + !self.is_broadcast() && !self.is_documentation() } - // Used for communications between a service provider and its subscribers when using a carrier-grade NAT + // Used for communications between a service provider and its subscribers when using a carrier-grade NAT // see: https://en.wikipedia.org/wiki/Reserved_IP_addresses fn is_shared_space(&self) -> bool { - *self >= Ipv4Addr::new(100, 64, 0, 0) && + *self >= Ipv4Addr::new(100, 64, 0, 0) && *self <= Ipv4Addr::new(100, 127, 255, 255) } // Used for the IANA IPv4 Special Purpose Address Registry // see: https://en.wikipedia.org/wiki/Reserved_IP_addresses fn is_special_purpose(&self) -> bool { - *self >= Ipv4Addr::new(192, 0, 0, 0) && + *self >= Ipv4Addr::new(192, 0, 0, 0) && *self <= Ipv4Addr::new(192, 0, 0, 255) } // Used for testing of inter-network communications between two separate subnets // see: https://en.wikipedia.org/wiki/Reserved_IP_addresses fn is_benchmarking(&self) -> bool { - *self >= Ipv4Addr::new(198, 18, 0, 0) && + *self >= Ipv4Addr::new(198, 18, 0, 0) && *self <= Ipv4Addr::new(198, 19, 255, 255) } // Reserved for future use // see: https://en.wikipedia.org/wiki/Reserved_IP_addresses fn is_future_use(&self) -> bool { - *self >= Ipv4Addr::new(240, 0, 0, 0) && + *self >= Ipv4Addr::new(240, 0, 0, 0) && *self <= Ipv4Addr::new(255, 255, 255, 254) } @@ -102,7 +102,7 @@ impl SocketAddrExt for Ipv4Addr { !self.is_reserved() && !self.is_private() } - + fn is_usable_private(&self) -> bool { self.is_private() } @@ -118,7 +118,7 @@ impl SocketAddrExt for Ipv4Addr { impl SocketAddrExt for Ipv6Addr { fn is_global_s(&self) -> bool { self.is_global_multicast() || - (!self.is_loopback() && + (!self.is_loopback() && !self.is_unique_local_s() && !self.is_unicast_link_local_s() && !self.is_documentation_s() && @@ -134,7 +134,7 @@ impl SocketAddrExt for Ipv6Addr { fn is_unicast_link_local_s(&self) -> bool { (self.segments()[0] & 0xffc0) == 0xfe80 } - + // reserved for documentation (2001:db8::/32). fn is_documentation_s(&self) -> bool { (self.segments()[0] == 0x2001) && (self.segments()[1] == 0xdb8) @@ -160,7 +160,7 @@ impl SocketAddrExt for Ipv6Addr { !self.is_reserved() && !self.is_unique_local_s() } - + fn is_usable_private(&self) -> bool { self.is_unique_local_s() } @@ -194,7 +194,7 @@ impl SocketAddrExt for IpAddr { IpAddr::V6(ref ip) => ip.is_usable_public(), } } - + fn is_usable_private(&self) -> bool { match *self { IpAddr::V4(ref ip) => ip.is_usable_private(), @@ -308,7 +308,15 @@ pub fn select_public_address(port: u16) -> SocketAddr { pub fn map_external_address(local: &NodeEndpoint) -> Option { if let SocketAddr::V4(ref local_addr) = local.address { - match search_gateway_from_timeout(*local_addr.ip(), Duration::new(5, 0)) { + let local_ip = *local_addr.ip(); + let search_gateway_child = ::std::thread::spawn(move || { + search_gateway_from_timeout(local_ip, Duration::new(5, 0)) + }); + let gateway_result = match search_gateway_child.join() { + Err(_) => return None, + Ok(gateway_result) => gateway_result, + }; + match gateway_result { Err(ref err) => debug!("Gateway search error: {}", err), Ok(gateway) => { match gateway.get_external_ip() { @@ -425,32 +433,32 @@ fn ipv4_future_use() { fn ipv4_usable_public() { assert!(!Ipv4Addr::new(0,0,0,0).is_usable_public()); // unspecified assert!(Ipv4Addr::new(0,0,0,1).is_usable_public()); - + assert!(Ipv4Addr::new(9,255,255,255).is_usable_public()); assert!(!Ipv4Addr::new(10,0,0,0).is_usable_public()); // private intra-network assert!(!Ipv4Addr::new(10,255,255,255).is_usable_public()); // private intra-network assert!(Ipv4Addr::new(11,0,0,0).is_usable_public()); - + assert!(Ipv4Addr::new(100, 63, 255, 255).is_usable_public()); - assert!(!Ipv4Addr::new(100, 64, 0, 0).is_usable_public()); // shared space + assert!(!Ipv4Addr::new(100, 64, 0, 0).is_usable_public()); // shared space assert!(!Ipv4Addr::new(100, 127, 255, 255).is_usable_public()); // shared space assert!(Ipv4Addr::new(100, 128, 0, 0).is_usable_public()); - + assert!(Ipv4Addr::new(126,255,255,255).is_usable_public()); assert!(!Ipv4Addr::new(127,0,0,0).is_usable_public()); // loopback assert!(!Ipv4Addr::new(127,255,255,255).is_usable_public()); // loopback assert!(Ipv4Addr::new(128,0,0,0).is_usable_public()); - + assert!(Ipv4Addr::new(169,253,255,255).is_usable_public()); assert!(!Ipv4Addr::new(169,254,0,0).is_usable_public()); // link-local assert!(!Ipv4Addr::new(169,254,255,255).is_usable_public()); // link-local assert!(Ipv4Addr::new(169,255,0,0).is_usable_public()); - + assert!(Ipv4Addr::new(172,15,255,255).is_usable_public()); assert!(!Ipv4Addr::new(172,16,0,0).is_usable_public()); // private intra-network assert!(!Ipv4Addr::new(172,31,255,255).is_usable_public()); // private intra-network assert!(Ipv4Addr::new(172,32,255,255).is_usable_public()); - + assert!(Ipv4Addr::new(191,255,255,255).is_usable_public()); assert!(!Ipv4Addr::new(192,0,0,0).is_usable_public()); // special purpose assert!(!Ipv4Addr::new(192,0,0,255).is_usable_public()); // special purpose @@ -458,19 +466,19 @@ fn ipv4_usable_public() { assert!(Ipv4Addr::new(192,0,1,255).is_usable_public()); assert!(!Ipv4Addr::new(192,0,2,0).is_usable_public()); // documentation - assert!(!Ipv4Addr::new(192,0,2,255).is_usable_public()); // documentation + assert!(!Ipv4Addr::new(192,0,2,255).is_usable_public()); // documentation assert!(Ipv4Addr::new(192,0,3,0).is_usable_public()); - + assert!(Ipv4Addr::new(192,167,255,255).is_usable_public()); assert!(!Ipv4Addr::new(192,168,0,0).is_usable_public()); // private intra-network assert!(!Ipv4Addr::new(192,168,255,255).is_usable_public()); // private intra-network assert!(Ipv4Addr::new(192,169,0,0).is_usable_public()); - + assert!(Ipv4Addr::new(198,17,255,255).is_usable_public()); assert!(!Ipv4Addr::new(198,18,0,0).is_usable_public()); // benchmarking assert!(!Ipv4Addr::new(198,19,255,255).is_usable_public()); // benchmarking assert!(Ipv4Addr::new(198,20,0,0).is_usable_public()); - + assert!(Ipv4Addr::new(198,51,99,255).is_usable_public()); assert!(!Ipv4Addr::new(198,51,100,0).is_usable_public()); // documentation assert!(!Ipv4Addr::new(198,51,100,255).is_usable_public()); // documentation @@ -485,7 +493,7 @@ fn ipv4_usable_public() { assert!(!Ipv4Addr::new(224,0,0,0).is_usable_public()); // multicast assert!(!Ipv4Addr::new(239, 255, 255, 255).is_usable_public()); // multicast assert!(!Ipv4Addr::new(240, 0, 0, 0).is_usable_public()); // future use - assert!(!Ipv4Addr::new(255, 255, 255, 254).is_usable_public()); // future use + assert!(!Ipv4Addr::new(255, 255, 255, 254).is_usable_public()); // future use assert!(!Ipv4Addr::new(255, 255, 255, 255).is_usable_public()); // limited broadcast } @@ -495,12 +503,12 @@ fn ipv4_usable_private() { assert!(Ipv4Addr::new(10,0,0,0).is_usable_private()); // private intra-network assert!(Ipv4Addr::new(10,255,255,255).is_usable_private()); // private intra-network assert!(!Ipv4Addr::new(11,0,0,0).is_usable_private()); - + assert!(!Ipv4Addr::new(172,15,255,255).is_usable_private()); assert!(Ipv4Addr::new(172,16,0,0).is_usable_private()); // private intra-network assert!(Ipv4Addr::new(172,31,255,255).is_usable_private()); // private intra-network assert!(!Ipv4Addr::new(172,32,255,255).is_usable_private()); - + assert!(!Ipv4Addr::new(192,167,255,255).is_usable_private()); assert!(Ipv4Addr::new(192,168,0,0).is_usable_private()); // private intra-network assert!(Ipv4Addr::new(192,168,255,255).is_usable_private()); // private intra-network From 1ac1224cd3f983d66d650e78428d274350c84a30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Fri, 11 Jan 2019 18:08:58 +0100 Subject: [PATCH 008/168] Fix #9822: trace_filter does not return failed contract creation (#10140) currently trace_filter can't return failed contract creation transaction but trace_block can query the failed contract creation transaction.it because the logic of parity-ethereum/ethcore/src/trace/types/filter.rs Line 109 in 9982eba ``` _ => false ``` this patch correct the logic: ``` _ => self.to_address.matches_all() ``` Signed-off-by: Deshi Xiao --- ethcore/src/trace/types/filter.rs | 42 ++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/ethcore/src/trace/types/filter.rs b/ethcore/src/trace/types/filter.rs index 00fe38e484..d7b8fcc180 100644 --- a/ethcore/src/trace/types/filter.rs +++ b/ethcore/src/trace/types/filter.rs @@ -106,7 +106,7 @@ impl Filter { let to_matches = match trace.result { Res::Create(ref create_result) => self.to_address.matches(&create_result.address), - _ => false + _ => self.to_address.matches_all(), }; from_matches && to_matches @@ -385,4 +385,44 @@ mod tests { assert!(f1.matches(&trace)); assert!(f2.matches(&trace)); } + + #[test] + fn filter_match_failed_contract_creation_fix_9822() { + + let f0 = Filter { + range: (0..0), + from_address: vec![1.into()].into(), + to_address: vec![].into(), + }; + + let f1 = Filter { + range: (0..0), + from_address: vec![].into(), + to_address: vec![].into(), + }; + + let f2 = Filter { + range: (0..0), + from_address: vec![].into(), + to_address: vec![2.into()].into(), + }; + + let trace = FlatTrace { + action: Action::Create(Create { + from: 1.into(), + gas: 4.into(), + init: vec![0x5], + value: 3.into(), + }), + result: Res::FailedCall(TraceError::BadInstruction), + trace_address: vec![].into_iter().collect(), + subtraces: 0 + }; + + assert!(f0.matches(&trace)); + assert!(f1.matches(&trace)); + assert!(!f2.matches(&trace)); + } + } + From 181738a736b0b2ea0302162d05fa78997f9684dd Mon Sep 17 00:00:00 2001 From: shoffmeister Date: Sat, 12 Jan 2019 13:12:03 +0100 Subject: [PATCH 009/168] Remove reference to ui-interface command-line option (#10170) --- parity/cli/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/parity/cli/mod.rs b/parity/cli/mod.rs index 29c975acfe..77c1aac2ef 100644 --- a/parity/cli/mod.rs +++ b/parity/cli/mod.rs @@ -309,7 +309,7 @@ usage! { ["Convenience Options"] FLAG flag_unsafe_expose: (bool) = false, or |c: &Config| c.misc.as_ref()?.unsafe_expose, "--unsafe-expose", - "All servers will listen on external interfaces and will be remotely accessible. It's equivalent with setting the following: --[ws,jsonrpc,ui,ipfs-api,secretstore,stratum,dapps,secretstore-http]-interface=all --*-hosts=all This option is UNSAFE and should be used with great care!", + "All servers will listen on external interfaces and will be remotely accessible. It's equivalent with setting the following: --[ws,jsonrpc,ipfs-api,secretstore,stratum,dapps,secretstore-http]-interface=all --*-hosts=all This option is UNSAFE and should be used with great care!", ARG arg_config: (String) = "$BASE/config.toml", or |_| None, "-c, --config=[CONFIG]", From e8e087fc37b6e5aa78bd15eb32f8fb7dec3bb6d9 Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Mon, 14 Jan 2019 15:33:10 +0100 Subject: [PATCH 010/168] Skip locking in statedb for non-canon blocks (#10141) --- ethcore/src/state_db.rs | 37 ++++++++++++++++++------------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/ethcore/src/state_db.rs b/ethcore/src/state_db.rs index 6b31864526..1ceb8ff0c5 100644 --- a/ethcore/src/state_db.rs +++ b/ethcore/src/state_db.rs @@ -379,14 +379,7 @@ impl StateDB { /// Check if the account can be returned from cache by matching current block parent hash against canonical /// state and filtering out account modified in later blocks. - fn is_allowed(addr: &Address, parent_hash: &Option, modifications: &VecDeque) -> bool { - let mut parent = match *parent_hash { - None => { - trace!("Cache lookup skipped for {:?}: no parent hash", addr); - return false; - } - Some(ref parent) => parent, - }; + fn is_allowed(addr: &Address, parent_hash: &H256, modifications: &VecDeque) -> bool { if modifications.is_empty() { return true; } @@ -395,6 +388,7 @@ impl StateDB { // We search for our parent in that list first and then for // all its parent until we hit the canonical block, // checking against all the intermediate modifications. + let mut parent = parent_hash; for m in modifications { if &m.hash == parent { if m.is_canon { @@ -434,20 +428,25 @@ impl state::Backend for StateDB { } fn get_cached_account(&self, addr: &Address) -> Option> { - let mut cache = self.account_cache.lock(); - if !Self::is_allowed(addr, &self.parent_hash, &cache.modifications) { - return None; - } - cache.accounts.get_mut(addr).map(|a| a.as_ref().map(|a| a.clone_basic())) + self.parent_hash.as_ref().and_then(|parent_hash| { + let mut cache = self.account_cache.lock(); + if !Self::is_allowed(addr, parent_hash, &cache.modifications) { + return None; + } + cache.accounts.get_mut(addr).map(|a| a.as_ref().map(|a| a.clone_basic())) + }) } fn get_cached(&self, a: &Address, f: F) -> Option - where F: FnOnce(Option<&mut Account>) -> U { - let mut cache = self.account_cache.lock(); - if !Self::is_allowed(a, &self.parent_hash, &cache.modifications) { - return None; - } - cache.accounts.get_mut(a).map(|c| f(c.as_mut())) + where F: FnOnce(Option<&mut Account>) -> U + { + self.parent_hash.as_ref().and_then(|parent_hash| { + let mut cache = self.account_cache.lock(); + if !Self::is_allowed(a, parent_hash, &cache.modifications) { + return None; + } + cache.accounts.get_mut(a).map(|c| f(c.as_mut())) + }) } fn get_cached_code(&self, hash: &H256) -> Option>> { From d356c6640d1ab43b714bb168f7d17cefc4974bbf Mon Sep 17 00:00:00 2001 From: Afri Schoedon <5chdn@users.noreply.github.com> Date: Mon, 14 Jan 2019 17:29:17 +0100 Subject: [PATCH 011/168] version: bump nightly to 2.4 (#10165) * version: bump nightly to 2.4 * revert rand downgrade --- Cargo.lock | 12 ++++++------ Cargo.toml | 2 +- util/version/Cargo.toml | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e5f5ea27f7..8544d62ce4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2362,7 +2362,7 @@ dependencies = [ "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", "jni 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", "panic_hook 0.1.0", - "parity-ethereum 2.3.0", + "parity-ethereum 2.4.0", "tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-current-thread 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2380,7 +2380,7 @@ dependencies = [ [[package]] name = "parity-ethereum" -version = "2.3.0" +version = "2.4.0" dependencies = [ "ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2430,7 +2430,7 @@ dependencies = [ "parity-rpc 1.12.0", "parity-runtime 0.1.0", "parity-updater 1.12.0", - "parity-version 2.3.0", + "parity-version 2.4.0", "parity-whisper 0.1.0", "parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2582,7 +2582,7 @@ dependencies = [ "parity-crypto 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-runtime 0.1.0", "parity-updater 1.12.0", - "parity-version 2.3.0", + "parity-version 2.4.0", "parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "patricia-trie 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2680,7 +2680,7 @@ dependencies = [ "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-hash-fetch 1.12.0", "parity-path 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-version 2.3.0", + "parity-version 2.4.0", "parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2690,7 +2690,7 @@ dependencies = [ [[package]] name = "parity-version" -version = "2.3.0" +version = "2.4.0" dependencies = [ "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "rlp 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index be7a916bf1..5e95600357 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ description = "Parity Ethereum client" name = "parity-ethereum" # NOTE Make sure to update util/version/Cargo.toml as well -version = "2.3.0" +version = "2.4.0" license = "GPL-3.0" authors = ["Parity Technologies "] diff --git a/util/version/Cargo.toml b/util/version/Cargo.toml index f309c3b04c..041030da5f 100644 --- a/util/version/Cargo.toml +++ b/util/version/Cargo.toml @@ -3,7 +3,7 @@ [package] name = "parity-version" # NOTE: this value is used for Parity Ethereum version string (via env CARGO_PKG_VERSION) -version = "2.3.0" +version = "2.4.0" authors = ["Parity Technologies "] build = "build.rs" From 53a04e1686691a9cc3cc6cd9293d2edcf3fbffbb Mon Sep 17 00:00:00 2001 From: Nicolas Gotchac Date: Tue, 15 Jan 2019 09:14:15 +0100 Subject: [PATCH 012/168] Drop `runtime` after others (especially `ws_server`) (#10179) --- parity/run.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/parity/run.rs b/parity/run.rs index 8b4bfff5b9..6c53e675cd 100644 --- a/parity/run.rs +++ b/parity/run.rs @@ -376,7 +376,7 @@ fn execute_light_impl(cmd: RunCmd, logger: Arc) -> Result Date: Tue, 15 Jan 2019 09:36:55 +0100 Subject: [PATCH 013/168] Align personal_unlockAccount behaviour when permanent unlock is disabled (#10060) * align with docs > If permanent unlocking is disabled (the default) then the duration argument will be ignored, and the account will be unlocked for a single signing. Current behaviour throws an error that is no longer relevant. * fix test * Change back to throwing error * Fix test again * formatting * oops * whitespace fixes --- rpc/src/v1/impls/personal.rs | 4 ++-- rpc/src/v1/tests/mocked/personal.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/rpc/src/v1/impls/personal.rs b/rpc/src/v1/impls/personal.rs index 56135544a6..abaebc3d08 100644 --- a/rpc/src/v1/impls/personal.rs +++ b/rpc/src/v1/impls/personal.rs @@ -129,8 +129,8 @@ impl Personal for PersonalClient { let r = match (self.allow_perm_unlock, duration) { (false, None) => store.unlock_account_temporarily(account, account_pass.into()), (false, _) => return Err(errors::unsupported( - "Time-unlocking is only supported in --geth compatibility mode.", - Some("Restart your client with --geth flag or use personal_sendTransaction instead."), + "Time-unlocking is not supported when permanent unlock is disabled.", + Some("Use personal_sendTransaction or enable permanent unlocking, instead."), )), (true, Some(0)) => store.unlock_account_permanently(account, account_pass.into()), (true, Some(d)) => store.unlock_account_timed(account, account_pass.into(), Duration::from_secs(d.into())), diff --git a/rpc/src/v1/tests/mocked/personal.rs b/rpc/src/v1/tests/mocked/personal.rs index b74553bc7f..bdf6067418 100644 --- a/rpc/src/v1/tests/mocked/personal.rs +++ b/rpc/src/v1/tests/mocked/personal.rs @@ -303,7 +303,7 @@ fn ec_recover_invalid_signature() { } #[test] -fn should_unlock_not_account_temporarily_if_allow_perm_is_disabled() { +fn should_not_unlock_account_temporarily_if_allow_perm_is_disabled() { let tester = setup(); let address = tester.accounts.new_account(&"password123".into()).unwrap(); @@ -317,7 +317,7 @@ fn should_unlock_not_account_temporarily_if_allow_perm_is_disabled() { ], "id": 1 }"#; - let response = r#"{"jsonrpc":"2.0","error":{"code":-32000,"message":"Time-unlocking is only supported in --geth compatibility mode.","data":"Restart your client with --geth flag or use personal_sendTransaction instead."},"id":1}"#; + let response = r#"{"jsonrpc":"2.0","error":{"code":-32000,"message":"Time-unlocking is not supported when permanent unlock is disabled.","data":"Use personal_sendTransaction or enable permanent unlocking, instead."},"id":1}"#; assert_eq!(tester.io.handle_request_sync(&request), Some(response.into())); assert!(tester.accounts.sign(address, None, Default::default()).is_err(), "Should not unlock account."); From 64704c456fffb6043671692e65486f6daf529d58 Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Tue, 15 Jan 2019 10:21:44 +0100 Subject: [PATCH 014/168] Handle the case for contract creation on an empty but exist account with storage items (#10065) * Add is_base_storage_root_unchanged * Fix compile, use a shortcut for check, and remove ignored tests * Add a warn! * Update ethereum/tests to v6.0.0-beta.2 * grumble: use {:#x} instead of 0x{:x} Co-Authored-By: sorpaas --- ethcore/res/ethereum/tests | 2 +- .../res/ethereum/tests-issues/currents.json | 44 ++----------------- ethcore/src/externalities.rs | 7 ++- ethcore/src/state/account.rs | 5 +++ ethcore/src/state/mod.rs | 7 +++ 5 files changed, 22 insertions(+), 43 deletions(-) diff --git a/ethcore/res/ethereum/tests b/ethcore/res/ethereum/tests index 2cd62aeec1..420f443477 160000 --- a/ethcore/res/ethereum/tests +++ b/ethcore/res/ethereum/tests @@ -1 +1 @@ -Subproject commit 2cd62aeec11da29766b30d500f2b9a96f1f28cf0 +Subproject commit 420f443477caa8516f1f9ee8122fafc3415c0f34 diff --git a/ethcore/res/ethereum/tests-issues/currents.json b/ethcore/res/ethereum/tests-issues/currents.json index 2ece034d09..d4d3f5e3aa 100644 --- a/ethcore/res/ethereum/tests-issues/currents.json +++ b/ethcore/res/ethereum/tests-issues/currents.json @@ -1,42 +1,4 @@ -{ "block": - [ - { - "reference": "None", - "comment": "This failing test is deemed skippable. Could not happen on a mainnet.", - "failing": "GeneralStateTest_stCreate2", - "subtests": ["RevertInCreateInInitCreate2_d0g0v0_Constantinople"] - }, - { - "reference": "None", - "comment": "This failing test is deemed skippable. Could not happen on a mainnet.", - "failing": "GeneralStateTest_stRevertTest", - "subtests": ["RevertInCreateInInit_d0g0v0_Constantinople"] - } - ], - "state": - [ - { - "reference": "None", - "comment": "This failing test is deemed skippable. Could not happen on a mainnet.", - "failing": "stCreate2Test", - "subtests": { - "RevertInCreateInInitCreate2": { - "subnumbers": ["1"], - "chain": "Constantinople (test)" - } - } - }, - { - "reference": "None", - "comment": "This failing test is deemed skippable. Could not happen on a mainnet.", - "failing": "stRevertTest", - "subtests": { - "RevertInCreateInInit": { - "subnumbers": ["1"], - "chain": "Constantinople (test)" - } - } - } - - ] +{ + "block": [], + "state": [] } diff --git a/ethcore/src/externalities.rs b/ethcore/src/externalities.rs index 0cda8ac875..a2f35b6ded 100644 --- a/ethcore/src/externalities.rs +++ b/ethcore/src/externalities.rs @@ -116,7 +116,12 @@ impl<'a, T: 'a, V: 'a, B: 'a> Ext for Externalities<'a, T, V, B> where T: Tracer, V: VMTracer, B: StateBackend { fn initial_storage_at(&self, key: &H256) -> vm::Result { - self.state.checkpoint_storage_at(0, &self.origin_info.address, key).map(|v| v.unwrap_or(H256::zero())).map_err(Into::into) + if self.state.is_base_storage_root_unchanged(&self.origin_info.address)? { + self.state.checkpoint_storage_at(0, &self.origin_info.address, key).map(|v| v.unwrap_or(H256::zero())).map_err(Into::into) + } else { + warn!(target: "externalities", "Detected existing account {:#x} where a forced contract creation happened.", self.origin_info.address); + Ok(H256::zero()) + } } fn storage_at(&self, key: &H256) -> vm::Result { diff --git a/ethcore/src/state/account.rs b/ethcore/src/state/account.rs index d4a42dd31a..e4553b906f 100644 --- a/ethcore/src/state/account.rs +++ b/ethcore/src/state/account.rs @@ -451,6 +451,11 @@ impl Account { } } + /// Whether the base storage root of this account is unchanged. + pub fn is_base_storage_root_unchanged(&self) -> bool { + self.original_storage_cache.is_none() + } + /// Storage root where the account changes are based upon. pub fn base_storage_root(&self) -> H256 { self.storage_root diff --git a/ethcore/src/state/mod.rs b/ethcore/src/state/mod.rs index 8a46c7e1d1..2939c97297 100644 --- a/ethcore/src/state/mod.rs +++ b/ethcore/src/state/mod.rs @@ -539,6 +539,13 @@ impl State { |a| a.as_ref().map_or(self.account_start_nonce, |account| *account.nonce())) } + /// Whether the base storage root of an account remains unchanged. + pub fn is_base_storage_root_unchanged(&self, a: &Address) -> TrieResult { + Ok(self.ensure_cached(a, RequireCache::None, true, + |a| a.as_ref().map(|account| account.is_base_storage_root_unchanged()))? + .unwrap_or(true)) + } + /// Get the storage root of account `a`. pub fn storage_root(&self, a: &Address) -> TrieResult> { self.ensure_cached(a, RequireCache::None, true, From 53c408f5492c972cd7849f7cc4b325b0c20fb48c Mon Sep 17 00:00:00 2001 From: Afri Schoedon <5chdn@users.noreply.github.com> Date: Tue, 15 Jan 2019 15:48:50 +0100 Subject: [PATCH 015/168] version: bump fork blocks for kovan and foundation (#10186) --- util/version/Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/util/version/Cargo.toml b/util/version/Cargo.toml index 041030da5f..5c8266d6f2 100644 --- a/util/version/Cargo.toml +++ b/util/version/Cargo.toml @@ -16,9 +16,9 @@ track = "nightly" # Latest supported fork blocks. # Indicates a critical release in this track (i.e. consensus issue). [package.metadata.networks] -foundation = { forkBlock = 4370000, critical = false } +foundation = { forkBlock = 7080000, critical = false } ropsten = { forkBlock = 4230000, critical = false } -kovan = { forkBlock = 6600000, critical = false } +kovan = { forkBlock = 9200000, critical = false } [dependencies] parity-bytes = "0.1" From ed6f2877d7474c5da75e8d62dc024195d820dbca Mon Sep 17 00:00:00 2001 From: TriplEight Date: Tue, 15 Jan 2019 17:27:43 +0100 Subject: [PATCH 016/168] Update for Android cross-compilation. (#10180) * build-unix update * .gitlab-ci update * Update build-unix.sh add android postprocessing * path to android lib libparity.so * fix path to libparity * add android lib to artifacts --- .gitlab-ci.yml | 3 ++- scripts/gitlab/build-unix.sh | 40 +++++++++++++++++------------------- 2 files changed, 21 insertions(+), 22 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 5d5f483da1..a1a1c97998 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -146,8 +146,9 @@ build-android: script: - scripts/gitlab/build-unix.sh tags: - - rust-arm + - linux-docker allow_failure: true + <<: *collect_artifacts test-beta: stage: optional diff --git a/scripts/gitlab/build-unix.sh b/scripts/gitlab/build-unix.sh index cf6bfe1476..9bb6cd0f3f 100755 --- a/scripts/gitlab/build-unix.sh +++ b/scripts/gitlab/build-unix.sh @@ -10,38 +10,36 @@ echo "CARGO_TARGET: " $CARGO_TARGET echo "CC: " $CC echo "CXX: " $CXX -echo "__________CARGO CONFIG__________" +echo "_____ Building target: "$CARGO_TARGET" _____" if [ "${CARGO_TARGET}" = "armv7-linux-androideabi" ] then - # use build container's cargo config - cat /.cargo/config +# only thing we need for android + time cargo build --target $CARGO_TARGET --release -p parity-clib --features final else - mkdir -p .cargo - rm -f .cargo/config - echo "[target.$CARGO_TARGET]" >> .cargo/config - echo "linker= \"$CC\"" >> .cargo/config - cat .cargo/config + time cargo build --target $CARGO_TARGET --release --features final + time cargo build --target $CARGO_TARGET --release -p evmbin + time cargo build --target $CARGO_TARGET --release -p ethstore-cli + time cargo build --target $CARGO_TARGET --release -p ethkey-cli + time cargo build --target $CARGO_TARGET --release -p whisper-cli fi - -echo "_____ Building target: "$CARGO_TARGET" _____" -time cargo build --target $CARGO_TARGET --release --features final -time cargo build --target $CARGO_TARGET --release -p evmbin -time cargo build --target $CARGO_TARGET --release -p ethstore-cli -time cargo build --target $CARGO_TARGET --release -p ethkey-cli -time cargo build --target $CARGO_TARGET --release -p whisper-cli - echo "_____ Post-processing binaries _____" rm -rf artifacts mkdir -p artifacts cd artifacts mkdir -p $CARGO_TARGET cd $CARGO_TARGET -cp -v ../../target/$CARGO_TARGET/release/parity ./parity -cp -v ../../target/$CARGO_TARGET/release/parity-evm ./parity-evm -cp -v ../../target/$CARGO_TARGET/release/ethstore ./ethstore -cp -v ../../target/$CARGO_TARGET/release/ethkey ./ethkey -cp -v ../../target/$CARGO_TARGET/release/whisper ./whisper +if [ "${CARGO_TARGET}" = "armv7-linux-androideabi" ] +then +# only thing we need for android + cp -v ../../target/$CARGO_TARGET/release/libparity.so ./libparity.so +else + cp -v ../../target/$CARGO_TARGET/release/parity ./parity + cp -v ../../target/$CARGO_TARGET/release/parity-evm ./parity-evm + cp -v ../../target/$CARGO_TARGET/release/ethstore ./ethstore + cp -v ../../target/$CARGO_TARGET/release/ethkey ./ethkey + cp -v ../../target/$CARGO_TARGET/release/whisper ./whisper +fi # stripping can also be done on release build time From a6c6c7c0703dbf69c2fdfe7e3f3e3c69753fa5fa Mon Sep 17 00:00:00 2001 From: Afri Schoedon <5chdn@users.noreply.github.com> Date: Tue, 15 Jan 2019 21:50:41 +0100 Subject: [PATCH 017/168] pull constantinople on ethereum network (#10189) * ethcore: pull constantinople on ethereum network * version: mark update as critical * ethcore: remove constantinople alltogether from chain spec * version: revert fork block for ethereum --- ethcore/res/ethereum/foundation.json | 12 +++--------- util/version/Cargo.toml | 4 ++-- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/ethcore/res/ethereum/foundation.json b/ethcore/res/ethereum/foundation.json index 2522a09ae2..69f150fad6 100644 --- a/ethcore/res/ethereum/foundation.json +++ b/ethcore/res/ethereum/foundation.json @@ -9,8 +9,7 @@ "durationLimit": "0xd", "blockReward": { "0x0": "0x4563918244f40000", - "0x42ae50": "0x29a2241af62c0000", - "0x6c0840": "0x1bc16d674ec80000" + "0x42ae50": "0x29a2241af62c0000" }, "homesteadTransition": "0x118c30", "daoHardforkTransition": "0x1d4c00", @@ -135,8 +134,7 @@ ], "eip100bTransition": "0x42ae50", "difficultyBombDelays": { - "0x42ae50": "0x2dc6c0", - "0x6c0840": "0x1e8480" + "0x42ae50": "0x2dc6c0" } } } @@ -160,11 +158,7 @@ "eip140Transition": "0x42ae50", "eip211Transition": "0x42ae50", "eip214Transition": "0x42ae50", - "eip658Transition": "0x42ae50", - "eip145Transition": "0x6c0840", - "eip1014Transition": "0x6c0840", - "eip1052Transition": "0x6c0840", - "eip1283Transition": "0x6c0840" + "eip658Transition": "0x42ae50" }, "genesis": { "seal": { diff --git a/util/version/Cargo.toml b/util/version/Cargo.toml index 5c8266d6f2..f778d290ed 100644 --- a/util/version/Cargo.toml +++ b/util/version/Cargo.toml @@ -16,9 +16,9 @@ track = "nightly" # Latest supported fork blocks. # Indicates a critical release in this track (i.e. consensus issue). [package.metadata.networks] -foundation = { forkBlock = 7080000, critical = false } +foundation = { forkBlock = 4370000, critical = true } ropsten = { forkBlock = 4230000, critical = false } -kovan = { forkBlock = 9200000, critical = false } +kovan = { forkBlock = 9200000, critical = true } [dependencies] parity-bytes = "0.1" From 1df6361753bc8231884d959b72b6c1d68fe9c485 Mon Sep 17 00:00:00 2001 From: Nicolas Gotchac Date: Wed, 16 Jan 2019 16:35:28 +0100 Subject: [PATCH 018/168] Run all `igd` methods in its own thread (#10195) --- util/network-devp2p/src/ip_utils.rs | 64 ++++++++++++++--------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/util/network-devp2p/src/ip_utils.rs b/util/network-devp2p/src/ip_utils.rs index 306f283934..4b8473ceca 100644 --- a/util/network-devp2p/src/ip_utils.rs +++ b/util/network-devp2p/src/ip_utils.rs @@ -309,40 +309,40 @@ pub fn select_public_address(port: u16) -> SocketAddr { pub fn map_external_address(local: &NodeEndpoint) -> Option { if let SocketAddr::V4(ref local_addr) = local.address { let local_ip = *local_addr.ip(); + let local_port = local_addr.port(); + let local_udp_port = local.udp_port; + let search_gateway_child = ::std::thread::spawn(move || { - search_gateway_from_timeout(local_ip, Duration::new(5, 0)) + match search_gateway_from_timeout(local_ip, Duration::new(5, 0)) { + Err(ref err) => debug!("Gateway search error: {}", err), + Ok(gateway) => { + match gateway.get_external_ip() { + Err(ref err) => { + debug!("IP request error: {}", err); + }, + Ok(external_addr) => { + match gateway.add_any_port(PortMappingProtocol::TCP, SocketAddrV4::new(local_ip, local_port), 0, "Parity Node/TCP") { + Err(ref err) => { + debug!("Port mapping error: {}", err); + }, + Ok(tcp_port) => { + match gateway.add_any_port(PortMappingProtocol::UDP, SocketAddrV4::new(local_ip, local_udp_port), 0, "Parity Node/UDP") { + Err(ref err) => { + debug!("Port mapping error: {}", err); + }, + Ok(udp_port) => { + return Some(NodeEndpoint { address: SocketAddr::V4(SocketAddrV4::new(external_addr, tcp_port)), udp_port }); + }, + } + }, + } + }, + } + }, + } + None }); - let gateway_result = match search_gateway_child.join() { - Err(_) => return None, - Ok(gateway_result) => gateway_result, - }; - match gateway_result { - Err(ref err) => debug!("Gateway search error: {}", err), - Ok(gateway) => { - match gateway.get_external_ip() { - Err(ref err) => { - debug!("IP request error: {}", err); - }, - Ok(external_addr) => { - match gateway.add_any_port(PortMappingProtocol::TCP, SocketAddrV4::new(*local_addr.ip(), local_addr.port()), 0, "Parity Node/TCP") { - Err(ref err) => { - debug!("Port mapping error: {}", err); - }, - Ok(tcp_port) => { - match gateway.add_any_port(PortMappingProtocol::UDP, SocketAddrV4::new(*local_addr.ip(), local.udp_port), 0, "Parity Node/UDP") { - Err(ref err) => { - debug!("Port mapping error: {}", err); - }, - Ok(udp_port) => { - return Some(NodeEndpoint { address: SocketAddr::V4(SocketAddrV4::new(external_addr, tcp_port)), udp_port }); - }, - } - }, - } - }, - } - }, - } + return search_gateway_child.join().ok()?; } None } From cdba22a2cbf80dce48df84a5a9650a197420de60 Mon Sep 17 00:00:00 2001 From: Seun LanLege Date: Wed, 16 Jan 2019 19:37:26 +0400 Subject: [PATCH 019/168] Adds cli interface to allow reseting chain to a particular block (#9782) * added BlockChainReset trait, client impl, and cli interface * show block hashes to be deleted and new best block, update best block in db, better cli interface * delete BlockNumber from COL_EXTRA * add TODO comment * add BlockReciepts to imports * refactor block_headers_from_best_block, better cli documentation * exit gracefully if reset arg isn't supplied * fix cli usage macro * removed stray int literals * use Vec::with_capacity Co-Authored-By: seunlanlege * cast n to usize * correct imports * make db reset arg required --- ethcore/blockchain/src/blockchain.rs | 15 +++++++++ ethcore/blockchain/src/lib.rs | 2 +- ethcore/src/client/client.rs | 49 ++++++++++++++++++++++++++-- ethcore/src/client/mod.rs | 3 +- ethcore/src/client/traits.rs | 6 ++++ parity/blockchain.rs | 42 +++++++++++++++++++++++- parity/cli/mod.rs | 11 +++++++ parity/configuration.rs | 15 ++++++++- 8 files changed, 137 insertions(+), 6 deletions(-) diff --git a/ethcore/blockchain/src/blockchain.rs b/ethcore/blockchain/src/blockchain.rs index 88f1503880..de6e8c134a 100644 --- a/ethcore/blockchain/src/blockchain.rs +++ b/ethcore/blockchain/src/blockchain.rs @@ -668,6 +668,21 @@ impl BlockChain { self.db.key_value().read_with_cache(db::COL_EXTRA, &self.block_details, parent).map_or(false, |d| d.children.contains(hash)) } + /// fetches the list of blocks from best block to n, and n's parent hash + /// where n > 0 + pub fn block_headers_from_best_block(&self, n: u32) -> Option<(Vec, H256)> { + let mut blocks = Vec::with_capacity(n as usize); + let mut hash = self.best_block_hash(); + + for _ in 0..n { + let current_hash = self.block_header_data(&hash)?; + hash = current_hash.parent_hash(); + blocks.push(current_hash); + } + + Some((blocks, hash)) + } + /// Returns a tree route between `from` and `to`, which is a tuple of: /// /// - a vector of hashes of all blocks, ordered from `from` to `to`. diff --git a/ethcore/blockchain/src/lib.rs b/ethcore/blockchain/src/lib.rs index 0ee7a5c1c8..3f07a6d807 100644 --- a/ethcore/blockchain/src/lib.rs +++ b/ethcore/blockchain/src/lib.rs @@ -33,5 +33,5 @@ pub use self::cache::CacheSize; pub use self::config::Config; pub use self::import_route::ImportRoute; pub use self::update::ExtrasInsert; -pub use ethcore_db::keys::{BlockReceipts, BlockDetails, TransactionAddress}; +pub use ethcore_db::keys::{BlockReceipts, BlockDetails, TransactionAddress, BlockNumberKey}; pub use common_types::tree_route::TreeRoute; diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index 995b11520f..52aedc37c7 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -21,7 +21,7 @@ use std::sync::atomic::{AtomicUsize, AtomicBool, Ordering as AtomicOrdering}; use std::sync::{Arc, Weak}; use std::time::{Instant, Duration}; -use blockchain::{BlockReceipts, BlockChain, BlockChainDB, BlockProvider, TreeRoute, ImportRoute, TransactionAddress, ExtrasInsert}; +use blockchain::{BlockReceipts, BlockChain, BlockChainDB, BlockProvider, TreeRoute, ImportRoute, TransactionAddress, ExtrasInsert, BlockNumberKey}; use bytes::Bytes; use ethcore_miner::pool::VerifiedTransaction; use ethereum_types::{H256, Address, U256}; @@ -50,7 +50,7 @@ use client::{ RegistryInfo, ReopenBlock, PrepareOpenBlock, ScheduleInfo, ImportSealedBlock, BroadcastProposalBlock, ImportBlock, StateOrBlock, StateInfo, StateClient, Call, AccountData, BlockChain as BlockChainTrait, BlockProducer, SealedBlockImporter, - ClientIoMessage, + ClientIoMessage, BlockChainReset }; use client::{ BlockId, TransactionId, UncleId, TraceId, ClientConfig, BlockChainClient, @@ -77,12 +77,14 @@ use verification::queue::kind::BlockLike; use verification::queue::kind::blocks::Unverified; use verification::{PreverifiedBlock, Verifier, BlockQueue}; use verification; +use ansi_term::Colour; // re-export pub use types::blockchain_info::BlockChainInfo; pub use types::block_status::BlockStatus; pub use blockchain::CacheSize as BlockChainCacheSize; pub use verification::QueueInfo as BlockQueueInfo; +use db::Writable; use_contract!(registry, "res/contracts/registrar.json"); @@ -469,6 +471,7 @@ impl Importer { // it is for reconstructing the state transition. // // The header passed is from the original block data and is sealed. + // TODO: should return an error if ImportRoute is none, issue #9910 fn commit_block(&self, block: B, header: &Header, block_data: encoded::Block, client: &Client) -> ImportRoute where B: Drain { let hash = &header.hash(); let number = header.number(); @@ -1328,6 +1331,48 @@ impl snapshot::DatabaseRestore for Client { } } +impl BlockChainReset for Client { + fn reset(&self, num: u32) -> Result<(), String> { + if num as u64 > self.pruning_history() { + return Err("Attempting to reset to block with pruned state".into()) + } + + let (blocks_to_delete, best_block_hash) = self.chain.read() + .block_headers_from_best_block(num) + .ok_or("Attempted to reset past genesis block")?; + + let mut db_transaction = DBTransaction::with_capacity((num + 1) as usize); + + for hash in &blocks_to_delete { + db_transaction.delete(::db::COL_HEADERS, &hash.hash()); + db_transaction.delete(::db::COL_BODIES, &hash.hash()); + db_transaction.delete(::db::COL_EXTRA, &hash.hash()); + Writable::delete:: + (&mut db_transaction, ::db::COL_EXTRA, &hash.number()); + } + + // update the new best block hash + db_transaction.put(::db::COL_EXTRA, b"best", &*best_block_hash); + + self.db.read() + .key_value() + .write(db_transaction) + .map_err(|err| format!("could not complete reset operation; io error occured: {}", err))?; + + let hashes = blocks_to_delete.iter().map(|b| b.hash()).collect::>(); + + info!("Deleting block hashes {}", + Colour::Red + .bold() + .paint(format!("{:#?}", hashes)) + ); + + info!("New best block hash {}", Colour::Green.bold().paint(format!("{:?}", best_block_hash))); + + Ok(()) + } +} + impl Nonce for Client { fn nonce(&self, address: &Address, id: BlockId) -> Option { self.state_at(id).and_then(|s| s.nonce(address).ok()) diff --git a/ethcore/src/client/mod.rs b/ethcore/src/client/mod.rs index 9c534d470c..2d042b8741 100644 --- a/ethcore/src/client/mod.rs +++ b/ethcore/src/client/mod.rs @@ -37,7 +37,8 @@ pub use self::test_client::{TestBlockChainClient, EachBlockWith}; pub use self::chain_notify::{ChainNotify, NewBlocks, ChainRoute, ChainRouteType, ChainMessageType}; pub use self::traits::{ Nonce, Balance, ChainInfo, BlockInfo, ReopenBlock, PrepareOpenBlock, CallContract, TransactionInfo, RegistryInfo, ScheduleInfo, ImportSealedBlock, BroadcastProposalBlock, ImportBlock, - StateOrBlock, StateClient, Call, EngineInfo, AccountData, BlockChain, BlockProducer, SealedBlockImporter, BadBlocks, + StateOrBlock, StateClient, Call, EngineInfo, AccountData, BlockChain, BlockProducer, SealedBlockImporter, + BadBlocks, BlockChainReset }; pub use state::StateInfo; pub use self::traits::{BlockChainClient, EngineClient, ProvingBlockChainClient, IoClient}; diff --git a/ethcore/src/client/traits.rs b/ethcore/src/client/traits.rs index ff0148beef..03f3b09694 100644 --- a/ethcore/src/client/traits.rs +++ b/ethcore/src/client/traits.rs @@ -482,3 +482,9 @@ pub trait ProvingBlockChainClient: BlockChainClient { /// Get an epoch change signal by block hash. fn epoch_signal(&self, hash: H256) -> Option>; } + +/// resets the blockchain +pub trait BlockChainReset { + /// reset to best_block - n + fn reset(&self, num: u32) -> Result<(), String>; +} diff --git a/parity/blockchain.rs b/parity/blockchain.rs index 959de3a30b..0f9d081f6f 100644 --- a/parity/blockchain.rs +++ b/parity/blockchain.rs @@ -26,7 +26,8 @@ use ethereum_types::{U256, H256, Address}; use bytes::ToPretty; use rlp::PayloadInfo; use ethcore::account_provider::AccountProvider; -use ethcore::client::{Mode, DatabaseCompactionProfile, VMType, Nonce, Balance, BlockChainClient, BlockId, BlockInfo, ImportBlock}; +use ethcore::client::{Mode, DatabaseCompactionProfile, VMType, Nonce, Balance, BlockChainClient, BlockId, BlockInfo, + ImportBlock, BlockChainReset}; use ethcore::error::{ImportErrorKind, ErrorKind as EthcoreErrorKind, Error as EthcoreError}; use ethcore::miner::Miner; use ethcore::verification::queue::VerifierSettings; @@ -40,6 +41,7 @@ use dir::Directories; use user_defaults::UserDefaults; use ethcore_private_tx; use db; +use ansi_term::Colour; #[derive(Debug, PartialEq)] pub enum DataFormat { @@ -71,6 +73,21 @@ pub enum BlockchainCmd { Import(ImportBlockchain), Export(ExportBlockchain), ExportState(ExportState), + Reset(ResetBlockchain) +} + +#[derive(Debug, PartialEq)] +pub struct ResetBlockchain { + pub dirs: Directories, + pub spec: SpecType, + pub pruning: Pruning, + pub pruning_history: u64, + pub pruning_memory: usize, + pub tracing: Switch, + pub fat_db: Switch, + pub compaction: DatabaseCompactionProfile, + pub cache_config: CacheConfig, + pub num: u32, } #[derive(Debug, PartialEq)] @@ -153,6 +170,7 @@ pub fn execute(cmd: BlockchainCmd) -> Result<(), String> { } BlockchainCmd::Export(export_cmd) => execute_export(export_cmd), BlockchainCmd::ExportState(export_cmd) => execute_export_state(export_cmd), + BlockchainCmd::Reset(reset_cmd) => execute_reset(reset_cmd), } } @@ -709,6 +727,28 @@ fn execute_export_state(cmd: ExportState) -> Result<(), String> { Ok(()) } +fn execute_reset(cmd: ResetBlockchain) -> Result<(), String> { + let service = start_client( + cmd.dirs, + cmd.spec, + cmd.pruning, + cmd.pruning_history, + cmd.pruning_memory, + cmd.tracing, + cmd.fat_db, + cmd.compaction, + cmd.cache_config, + false, + 0, + )?; + + let client = service.client(); + client.reset(cmd.num)?; + info!("{}", Colour::Green.bold().paint("Successfully reset db!")); + + Ok(()) +} + pub fn kill_db(cmd: KillBlockchain) -> Result<(), String> { let spec = cmd.spec.spec(&cmd.dirs.cache)?; let genesis_hash = spec.genesis_header().hash(); diff --git a/parity/cli/mod.rs b/parity/cli/mod.rs index 77c1aac2ef..9ed6ed957b 100644 --- a/parity/cli/mod.rs +++ b/parity/cli/mod.rs @@ -217,6 +217,15 @@ usage! { CMD cmd_db_kill { "Clean the database of the given --chain (default: mainnet)", } + + CMD cmd_db_reset { + "Removes NUM latests blocks from the db", + + ARG arg_db_reset_num: (u32) = 10u32, + "", + "Number of blocks to revert", + } + } CMD cmd_export_hardcoded_sync @@ -1612,6 +1621,7 @@ mod tests { cmd_tools_hash: false, cmd_db: false, cmd_db_kill: false, + cmd_db_reset: false, cmd_export_hardcoded_sync: false, // Arguments @@ -1631,6 +1641,7 @@ mod tests { arg_dapp_path: None, arg_account_import_path: None, arg_wallet_import_path: None, + arg_db_reset_num: 10, // -- Operating Options arg_mode: "last".into(), diff --git a/parity/configuration.rs b/parity/configuration.rs index c0f9c35eb2..48207683eb 100644 --- a/parity/configuration.rs +++ b/parity/configuration.rs @@ -48,7 +48,7 @@ use ethcore_private_tx::{ProviderConfig, EncryptorConfig}; use secretstore::{NodeSecretKey, Configuration as SecretStoreConfiguration, ContractAddress as SecretStoreContractAddress}; use updater::{UpdatePolicy, UpdateFilter, ReleaseTrack}; use run::RunCmd; -use blockchain::{BlockchainCmd, ImportBlockchain, ExportBlockchain, KillBlockchain, ExportState, DataFormat}; +use blockchain::{BlockchainCmd, ImportBlockchain, ExportBlockchain, KillBlockchain, ExportState, DataFormat, ResetBlockchain}; use export_hardcoded_sync::ExportHsyncCmd; use presale::ImportWallet; use account::{AccountCmd, NewAccount, ListAccounts, ImportAccounts, ImportFromGethAccounts}; @@ -176,6 +176,19 @@ impl Configuration { } } else if self.args.cmd_tools && self.args.cmd_tools_hash { Cmd::Hash(self.args.arg_tools_hash_file) + } else if self.args.cmd_db && self.args.cmd_db_reset { + Cmd::Blockchain(BlockchainCmd::Reset(ResetBlockchain { + dirs, + spec, + pruning, + pruning_history, + pruning_memory: self.args.arg_pruning_memory, + tracing, + fat_db, + compaction, + cache_config, + num: self.args.arg_db_reset_num, + })) } else if self.args.cmd_db && self.args.cmd_db_kill { Cmd::Blockchain(BlockchainCmd::Kill(KillBlockchain { spec: spec, From cf505139f1ffcbf494dc09d18c1f842dba3da711 Mon Sep 17 00:00:00 2001 From: Victor Baranov Date: Wed, 16 Jan 2019 20:31:59 +0300 Subject: [PATCH 020/168] Cancel Constantinople HF on POA Core (#10198) --- ethcore/res/ethereum/poacore.json | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/ethcore/res/ethereum/poacore.json b/ethcore/res/ethereum/poacore.json index 53b3c548c5..9fc34d22a2 100644 --- a/ethcore/res/ethereum/poacore.json +++ b/ethcore/res/ethereum/poacore.json @@ -34,11 +34,7 @@ "eip140Transition": "0x0", "eip211Transition": "0x0", "eip214Transition": "0x0", - "eip658Transition": "0x0", - "eip145Transition": 6843780, - "eip1014Transition": 6843780, - "eip1052Transition": 6843780, - "eip1283Transition": 6843780 + "eip658Transition": "0x0" }, "genesis": { "seal": { From 4f1e1e88701e40aebe06aaf030be81d80a85a5e0 Mon Sep 17 00:00:00 2001 From: Afri Schoedon <5chdn@users.noreply.github.com> Date: Wed, 16 Jan 2019 18:32:53 +0100 Subject: [PATCH 021/168] Update the changelogs for 2.1.11, 2.2.6, 2.2.7, and 2.3.0 (#10197) * docs: move 2.2 changelog to docs/ * docs: mark parity 2.1 end of life * docs: add changelog for 2.1.11 * docs: add changelog for 2.2.6 * docs: add changelog for 2.2.7 * docs: add changelog for 2.3.0 * docs: add release notes for 2.3.0 --- CHANGELOG.md | 407 +++++++++++++++--------------------------- docs/CHANGELOG-2.0.md | 2 +- docs/CHANGELOG-2.1.md | 24 ++- docs/CHANGELOG-2.2.md | 317 ++++++++++++++++++++++++++++++++ 4 files changed, 486 insertions(+), 264 deletions(-) create mode 100644 docs/CHANGELOG-2.2.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 71591c5fff..649f4c167c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,276 +1,163 @@ -## Parity-Ethereum [v2.2.5](https://github.com/paritytech/parity-ethereum/releases/tag/v2.2.5) (2018-12-14) -Parity-Ethereum 2.2.5-beta is an important release that introduces Constantinople fork at block 7080000 on Mainnet. -This release also contains a fix for chains using AuRa + EmptySteps. Read carefully if this applies to you. -If you have a chain with`empty_steps` already running, some blocks most likely contain non-strict entries (unordered or duplicated empty steps). In this release`strict_empty_steps_transition` **is enabled by default at block 0** for any chain with `empty_steps`. -If your network uses `empty_steps` you **must**: -- plan a hard fork and change `strict_empty_steps_transition` to the desire fork block -- update the clients of the whole network to 2.2.5-beta / 2.1.10-stable. -If for some reason you don't want to do this please set`strict_empty_steps_transition` to `0xfffffffff` to disable it. +## Parity-Ethereum [v2.3.0](https://github.com/paritytech/parity-ethereum/releases/tag/v2.3.0) (2018-01-16) -The full list of included changes: -- Backports for beta 2.2.5 ([#10047](https://github.com/paritytech/parity-ethereum/pull/10047)) - - Bump beta to 2.2.5 ([#10047](https://github.com/paritytech/parity-ethereum/pull/10047)) - - Fix empty steps ([#9939](https://github.com/paritytech/parity-ethereum/pull/9939)) - - Prevent sending empty step message twice - - Prevent sending empty step and then block in the same step - - Don't accept double empty steps - - Do basic validation of self-sealed blocks - - Strict empty steps validation ([#10041](https://github.com/paritytech/parity-ethereum/pull/10041)) - - Enables strict verification of empty steps - there can be no duplicates and empty steps should be ordered inside the seal. - - Note that authorities won't produce invalid seals after [#9939](https://github.com/paritytech/parity-ethereum/pull/9939), this PR just adds verification to the seal to prevent forging incorrect blocks and potentially causing consensus issues. - - This features is enabled by default so any AuRa + EmptySteps chain should set strict_empty_steps_transition fork block number in their spec and upgrade to v2.2.5-beta or v2.1.10-stable. - - ethcore: enable constantinople on ethereum ([#10031](https://github.com/paritytech/parity-ethereum/pull/10031)) - - ethcore: change blockreward to 2e18 for foundation after constantinople - - ethcore: delay diff bomb by 2e6 blocks for foundation after constantinople - - ethcore: enable eip-{145,1014,1052,1283} for foundation after constantinople - - Change test miner max memory to malloc reports. ([#10024](https://github.com/paritytech/parity-ethereum/pull/10024)) - - Fix: test corpus_inaccessible panic ([#10019](https://github.com/paritytech/parity-ethereum/pull/10019)) +Parity-Ethereum 2.3.0-beta is a consensus-relevant security release that reverts Constantinople on the Ethereum network. Upgrading is mandatory for Ethereum, and strongly recommended for other networks. -## Parity-Ethereum [v2.2.2](https://github.com/paritytech/parity-ethereum/releases/tag/v2.2.2) (2018-11-29) +- **Consensus** - Ethereum Network: Pull Constantinople protocol upgrade on Ethereum (#10189) + - Read more: [Security Alert: Ethereum Constantinople Postponement](https://blog.ethereum.org/2019/01/15/security-alert-ethereum-constantinople-postponement/) +- **Networking** - All networks: Ping nodes from discovery (#10167) +- **Wasm** - Kovan Network: Update pwasm-utils to 0.6.1 (#10134) -Parity-Ethereum 2.2.2-beta is an exciting release. Among others, it improves sync performance, peering stability, block propagation, and transaction propagation times. Also, a warp-sync no longer removes existing blocks from the database, but rather reuses locally available information to decrease sync times and reduces required bandwidth. +Other notable changes: -Before upgrading to 2.2.2, please also verify the validity of your chain specs. Parity Ethereum now denies unknown fields in the specification. To do this, use the chainspec tool: +- Existing blocks in the database are now kept when restoring a Snapshot. (#8643) +- Block and transaction propagation is improved significantly. (#9954) +- The ERC-191 Signed Data Standard is now supported by `personal_sign191`. (#9701) +- Add support for ERC-191/712 `eth_signTypedData` as a standard for machine-verifiable and human-readable typed data signing with Ethereum keys. (#9631) +- Add support for ERC-1186 `eth_getProof` (#9001) +- Add experimental RPCs flag to enable ERC-191, ERC-712, and ERC-1186 APIs via `--jsonrpc-experimental` (#9928) +- Make `CALLCODE` to trace value to be the code address. (#9881) -``` -cargo build --release -p chainspec -./target/release/chainspec /path/to/spec.json -``` +Configuration changes: -Last but not least, JSONRPC APIs which are not yet accepted as an EIP in the `eth`, `personal`, or `web3` namespace, are now considere experimental as their final specification might change in future. These APIs have to be manually enabled by explicitly running `--jsonrpc-experimental`. +- The EIP-98 transition is now disabled by default. If you previously had no `eip98transition` specified in your chain specification, you would enable this now manually on block `0x0`. (#9955) +- Also, unknown fields in chain specs are now rejected. (#9972) +- The Tendermint engine was removed from Parity Ethereum and is no longer available and maintained. (#9980) +- Ropsten testnet data and keys moved from `test/` to `ropsten/` subdir. To reuse your old keys and data either copy or symlink them to the new location. (#10123) +- Strict empty steps validation (#10041) + - If you have a chain with`empty_steps` already running, some blocks most likely contain non-strict entries (unordered or duplicated empty steps). In this release `strict_empty_steps_transition` is enabled by default at block `0x0` for any chain with `empty_steps`. + - If your network uses `empty_steps` you **must** (A) plan a hard fork and change `strict_empty_steps_transition` to the desired fork block and (B) update the clients of the whole network to 2.2.7-stable / 2.3.0-beta. If for some reason you don't want to do this please set`strict_empty_steps_transition` to `0xfffffffff` to disable it. -The full list of included changes: - -- Backports For beta 2.2.2 ([#9976](https://github.com/paritytech/parity-ethereum/pull/9976)) - - Version: bump beta to 2.2.2 - - Add experimental RPCs flag ([#9928](https://github.com/paritytech/parity-ethereum/pull/9928)) - - Keep existing blocks when restoring a Snapshot ([#8643](https://github.com/paritytech/parity-ethereum/pull/8643)) - - Rename db_restore => client - - First step: make it compile! - - Second step: working implementation! - - Refactoring - - Fix tests - - Migrate ancient blocks interacting backward - - Early return in block migration if snapshot is aborted - - Remove RwLock getter (PR Grumble I) - - Remove dependency on `Client`: only used Traits - - Add test for recovering aborted snapshot recovery - - Add test for migrating old blocks - - Release RwLock earlier - - Revert Cargo.lock - - Update _update ancient block_ logic: set local in `commit` - - Update typo in ethcore/src/snapshot/service.rs - - Adjust requests costs for light client ([#9925](https://github.com/paritytech/parity-ethereum/pull/9925)) - - Pip Table Cost relative to average peers instead of max peers - - Add tracing in PIP new_cost_table - - Update stat peer_count - - Use number of leeching peers for Light serve costs - - Fix test::light_params_load_share_depends_on_max_peers (wrong type) - - Remove (now) useless test - - Remove `load_share` from LightParams.Config - - Add LEECHER_COUNT_FACTOR - - Pr Grumble: u64 to u32 for f64 casting - - Prevent u32 overflow for avg_peer_count - - Add tests for LightSync::Statistics - - Fix empty steps ([#9939](https://github.com/paritytech/parity-ethereum/pull/9939)) - - Don't send empty step twice or empty step then block. - - Perform basic validation of locally sealed blocks. - - Don't include empty step twice. - - Prevent silent errors in daemon mode, closes [#9367](https://github.com/paritytech/parity-ethereum/issues/9367) ([#9946](https://github.com/paritytech/parity-ethereum/pull/9946)) - - Fix a deadlock ([#9952](https://github.com/paritytech/parity-ethereum/pull/9952)) - - Update informant: - - Decimal in Mgas/s - - Print every 5s (not randomly between 5s and 10s) - - Fix dead-lock in `blockchain.rs` - - Update locks ordering - - Fix light client informant while syncing ([#9932](https://github.com/paritytech/parity-ethereum/pull/9932)) - - Add `is_idle` to LightSync to check importing status - - Use SyncStateWrapper to make sure is_idle gets updates - - Update is_major_import to use verified queue size as well - - Add comment for `is_idle` - - Add Debug to `SyncStateWrapper` - - `fn get` -> `fn into_inner` - - Ci: rearrange pipeline by logic ([#9970](https://github.com/paritytech/parity-ethereum/pull/9970)) - - Ci: rearrange pipeline by logic - - Ci: rename docs script - - Fix docker build ([#9971](https://github.com/paritytech/parity-ethereum/pull/9971)) - - Deny unknown fields for chainspec ([#9972](https://github.com/paritytech/parity-ethereum/pull/9972)) - - Add deny_unknown_fields to chainspec - - Add tests and fix existing one - - Remove serde_ignored dependency for chainspec - - Fix rpc test eth chain spec - - Fix starting_nonce_test spec - - Improve block and transaction propagation ([#9954](https://github.com/paritytech/parity-ethereum/pull/9954)) - - Refactor sync to add priority tasks. - - Send priority tasks notifications. - - Propagate blocks, optimize transactions. - - Implement transaction propagation. Use sync_channel. - - Tone down info. - - Prevent deadlock by not waiting forever for sync lock. - - Fix lock order. - - Don't use sync_channel to prevent deadlocks. - - Fix tests. - - Fix unstable peers and slowness in sync ([#9967](https://github.com/paritytech/parity-ethereum/pull/9967)) - - Don't sync all peers after each response - - Update formating - - Fix tests: add `continue_sync` to `Sync_step` - - Update ethcore/sync/src/chain/mod.rs - - Fix rpc middlewares - - Fix Cargo.lock - - Json: resolve merge in spec - - Rpc: fix starting_nonce_test - - Ci: allow nightl job to fail - -## Parity-Ethereum [v2.2.1](https://github.com/paritytech/parity-ethereum/releases/tag/v2.2.1) (2018-11-15) - -Parity-Ethereum 2.2.1-beta is the first v2.2 release, and might introduce features that break previous work flows, among others: - -- Prevent zero network ID ([#9763](https://github.com/paritytech/parity-ethereum/pull/9763)) and drop support for Olympic testnet ([#9801](https://github.com/paritytech/parity-ethereum/pull/9801)): The Olympic test net is dead for years and never used a chain ID but network ID zero. Parity Ethereum is now preventing the network ID to be zero, thus Olympic support is dropped. Make sure to chose positive non-zero network IDs in future. -- Multithreaded snapshot creation ([#9239](https://github.com/paritytech/parity-ethereum/pull/9239)): adds a CLI argument `--snapshot-threads` which specifies the number of threads. This helps improving the performance of full nodes that wish to provide warp-snapshots for the network. The gain in performance comes with a slight drawback in increased snapshot size. -- Expose config max-round-blocks-to-import ([#9439](https://github.com/paritytech/parity-ethereum/pull/9439)): Parity Ethereum imports blocks in rounds. If at the end of any round, the queue is not empty, we consider it to be _importing_ and won't notify pubsub. On large re-orgs (10+ blocks), this is possible. The default `max_round_blocks_to_import` is increased to 12 and configurable via the `--max-round-blocks-to-import` CLI flag. With unstable network conditions, it is advised to increase the number. This shouldn't have any noticeable performance impact unless the number is set to really large. -- Increase Gas-floor-target and Gas Cap ([#9564](https://github.com/paritytech/parity-ethereum/pull/9564)): the default values for gas floor target are `8_000_000` and gas cap `10_000_000`, similar to Geth 1.8.15+. -- Produce portable binaries ([#9725](https://github.com/paritytech/parity-ethereum/pull/9725)): we now produce portable binaries, but it may incur some performance degradation. For ultimate performance it's now better to compile Parity Ethereum from source with `PORTABLE=OFF` environment variable. -- RPC: `parity_allTransactionHashes` ([#9745](https://github.com/paritytech/parity-ethereum/pull/9745)): Get all pending transactions from the queue with the high performant `parity_allTransactionHashes` RPC method. -- Support `eth_chainId` RPC method ([#9783](https://github.com/paritytech/parity-ethereum/pull/9783)): implements EIP-695 to get the chainID via RPC. -- AuRa: finalize blocks ([#9692](https://github.com/paritytech/parity-ethereum/pull/9692)): The AuRa engine was updated to emit ancestry actions to finalize blocks. The full client stores block finality in the database, the engine builds finality from an ancestry of `ExtendedHeader`; `is_epoch_end` was updated to take a vec of recently finalized headers; `is_epoch_end_light` was added which maintains the previous interface and is used by the light client since the client itself doesn't track finality. +_Note:_ This release marks Parity 2.3 as _beta_. All versions of Parity 2.2 are now considered _stable_. The full list of included changes: -- Backport to parity 2.2.1 beta ([#9905](https://github.com/paritytech/parity-ethereum/pull/9905)) - - Bump version to 2.2.1 - - Fix: Intermittent failing CI due to addr in use ([#9885](https://github.com/paritytech/parity-ethereum/pull/9885)) - - Fix Parity not closing on Ctrl-C ([#9886](https://github.com/paritytech/parity-ethereum/pull/9886)) - - Fix json tracer overflow ([#9873](https://github.com/paritytech/parity-ethereum/pull/9873)) - - Fix docker script ([#9854](https://github.com/paritytech/parity-ethereum/pull/9854)) - - Add hardcoded headers for light client ([#9907](https://github.com/paritytech/parity-ethereum/pull/9907)) - - Gitlab-ci: make android release build succeed ([#9743](https://github.com/paritytech/parity-ethereum/pull/9743)) - - Allow to seal work on latest block ([#9876](https://github.com/paritytech/parity-ethereum/pull/9876)) - - Remove rust-toolchain file ([#9906](https://github.com/paritytech/parity-ethereum/pull/9906)) - - Light-fetch: Differentiate between out-of-gas/manual throw and use required gas from response on failure ([#9824](https://github.com/paritytech/parity-ethereum/pull/9824)) - - Eip-712 implementation ([#9631](https://github.com/paritytech/parity-ethereum/pull/9631)) - - Eip-191 implementation ([#9701](https://github.com/paritytech/parity-ethereum/pull/9701)) - - Simplify cargo audit ([#9918](https://github.com/paritytech/parity-ethereum/pull/9918)) - - Fix performance issue importing Kovan blocks ([#9914](https://github.com/paritytech/parity-ethereum/pull/9914)) - - Ci: nuke the gitlab caches ([#9855](https://github.com/paritytech/parity-ethereum/pull/9855)) -- Backports to parity beta 2.2.0 ([#9820](https://github.com/paritytech/parity-ethereum/pull/9820)) - - Ci: remove failing tests for android, windows, and macos ([#9788](https://github.com/paritytech/parity-ethereum/pull/9788)) - - Implement NoProof for json tests and update tests reference ([#9814](https://github.com/paritytech/parity-ethereum/pull/9814)) - - Move state root verification before gas used ([#9841](https://github.com/paritytech/parity-ethereum/pull/9841)) - - Classic.json Bootnode Update ([#9828](https://github.com/paritytech/parity-ethereum/pull/9828)) -- Rpc: parity_allTransactionHashes ([#9745](https://github.com/paritytech/parity-ethereum/pull/9745)) -- Revert "prevent zero networkID ([#9763](https://github.com/paritytech/parity-ethereum/pull/9763))" ([#9815](https://github.com/paritytech/parity-ethereum/pull/9815)) -- Allow zero chain id in EIP155 signing process ([#9792](https://github.com/paritytech/parity-ethereum/pull/9792)) -- Add readiness check for docker container ([#9804](https://github.com/paritytech/parity-ethereum/pull/9804)) -- Insert dev account before unlocking ([#9813](https://github.com/paritytech/parity-ethereum/pull/9813)) -- Removed "rustup" & added new runner tag ([#9731](https://github.com/paritytech/parity-ethereum/pull/9731)) -- Expose config max-round-blocks-to-import ([#9439](https://github.com/paritytech/parity-ethereum/pull/9439)) -- Aura: finalize blocks ([#9692](https://github.com/paritytech/parity-ethereum/pull/9692)) -- Sync: retry different peer after empty subchain heads response ([#9753](https://github.com/paritytech/parity-ethereum/pull/9753)) -- Fix(light-rpc/parity) : Remove unused client ([#9802](https://github.com/paritytech/parity-ethereum/pull/9802)) -- Drops support for olympic testnet, closes [#9800](https://github.com/paritytech/parity-ethereum/issues/9800) ([#9801](https://github.com/paritytech/parity-ethereum/pull/9801)) -- Replace `tokio_core` with `tokio` (`ring` -> 0.13) ([#9657](https://github.com/paritytech/parity-ethereum/pull/9657)) -- Support eth_chainId RPC method ([#9783](https://github.com/paritytech/parity-ethereum/pull/9783)) -- Ethcore: bump ropsten forkblock checkpoint ([#9775](https://github.com/paritytech/parity-ethereum/pull/9775)) -- Docs: changelogs for 2.0.8 and 2.1.3 ([#9758](https://github.com/paritytech/parity-ethereum/pull/9758)) -- Prevent zero networkID ([#9763](https://github.com/paritytech/parity-ethereum/pull/9763)) -- Skip seal fields count check when --no-seal-check is used ([#9757](https://github.com/paritytech/parity-ethereum/pull/9757)) -- Aura: fix panic on extra_info with unsealed block ([#9755](https://github.com/paritytech/parity-ethereum/pull/9755)) -- Docs: update changelogs ([#9742](https://github.com/paritytech/parity-ethereum/pull/9742)) -- Removed extra assert in generation_session_is_removed_when_succeeded ([#9738](https://github.com/paritytech/parity-ethereum/pull/9738)) -- Make checkpoint_storage_at use plain loop instead of recursion ([#9734](https://github.com/paritytech/parity-ethereum/pull/9734)) -- Use signed 256-bit integer for sstore gas refund substate ([#9746](https://github.com/paritytech/parity-ethereum/pull/9746)) -- Heads ref not present for branches beta and stable ([#9741](https://github.com/paritytech/parity-ethereum/pull/9741)) -- Add Callisto support ([#9534](https://github.com/paritytech/parity-ethereum/pull/9534)) -- Add --force to cargo audit install script ([#9735](https://github.com/paritytech/parity-ethereum/pull/9735)) -- Remove unused expired value from Handshake ([#9732](https://github.com/paritytech/parity-ethereum/pull/9732)) -- Add hardcoded headers ([#9730](https://github.com/paritytech/parity-ethereum/pull/9730)) -- Produce portable binaries ([#9725](https://github.com/paritytech/parity-ethereum/pull/9725)) -- Gitlab ci: releasable_branches: change variables condition to schedule ([#9729](https://github.com/paritytech/parity-ethereum/pull/9729)) -- Update a few parity-common dependencies ([#9663](https://github.com/paritytech/parity-ethereum/pull/9663)) -- Hf in POA Core (2018-10-22) ([#9724](https://github.com/paritytech/parity-ethereum/pull/9724)) -- Schedule nightly builds ([#9717](https://github.com/paritytech/parity-ethereum/pull/9717)) -- Fix ancient blocks sync ([#9531](https://github.com/paritytech/parity-ethereum/pull/9531)) -- Ci: Skip docs job for nightly ([#9693](https://github.com/paritytech/parity-ethereum/pull/9693)) -- Fix (light/provider) : Make `read_only executions` read-only ([#9591](https://github.com/paritytech/parity-ethereum/pull/9591)) -- Ethcore: fix detection of major import ([#9552](https://github.com/paritytech/parity-ethereum/pull/9552)) -- Return 0 on error ([#9705](https://github.com/paritytech/parity-ethereum/pull/9705)) -- Ethcore: delay ropsten hardfork ([#9704](https://github.com/paritytech/parity-ethereum/pull/9704)) -- Make instantSeal engine backwards compatible, closes [#9696](https://github.com/paritytech/parity-ethereum/issues/9696) ([#9700](https://github.com/paritytech/parity-ethereum/pull/9700)) -- Implement CREATE2 gas changes and fix some potential overflowing ([#9694](https://github.com/paritytech/parity-ethereum/pull/9694)) -- Don't hash the init_code of CREATE. ([#9688](https://github.com/paritytech/parity-ethereum/pull/9688)) -- Ethcore: minor optimization of modexp by using LR exponentiation ([#9697](https://github.com/paritytech/parity-ethereum/pull/9697)) -- Removed redundant clone before each block import ([#9683](https://github.com/paritytech/parity-ethereum/pull/9683)) -- Add Foundation Bootnodes ([#9666](https://github.com/paritytech/parity-ethereum/pull/9666)) -- Docker: run as parity user ([#9689](https://github.com/paritytech/parity-ethereum/pull/9689)) -- Ethcore: mcip3 block reward contract ([#9605](https://github.com/paritytech/parity-ethereum/pull/9605)) -- Verify block syncing responses against requests ([#9670](https://github.com/paritytech/parity-ethereum/pull/9670)) -- Add a new RPC `parity_submitWorkDetail` similar `eth_submitWork` but return block hash ([#9404](https://github.com/paritytech/parity-ethereum/pull/9404)) -- Resumable EVM and heap-allocated callstack ([#9360](https://github.com/paritytech/parity-ethereum/pull/9360)) -- Update parity-wordlist library ([#9682](https://github.com/paritytech/parity-ethereum/pull/9682)) -- Ci: Remove unnecessary pipes ([#9681](https://github.com/paritytech/parity-ethereum/pull/9681)) -- Test.sh: use cargo --target for platforms other than linux, win or mac ([#9650](https://github.com/paritytech/parity-ethereum/pull/9650)) -- Ci: fix push script ([#9679](https://github.com/paritytech/parity-ethereum/pull/9679)) -- Hardfork the testnets ([#9562](https://github.com/paritytech/parity-ethereum/pull/9562)) -- Calculate sha3 instead of sha256 for push-release. ([#9673](https://github.com/paritytech/parity-ethereum/pull/9673)) -- Ethcore-io retries failed work steal ([#9651](https://github.com/paritytech/parity-ethereum/pull/9651)) -- Fix(light_fetch): avoid race with BlockNumber::Latest ([#9665](https://github.com/paritytech/parity-ethereum/pull/9665)) -- Test fix for windows cache name... ([#9658](https://github.com/paritytech/parity-ethereum/pull/9658)) -- Refactor(fetch) : light use only one `DNS` thread ([#9647](https://github.com/paritytech/parity-ethereum/pull/9647)) -- Ethereum libfuzzer integration small change ([#9547](https://github.com/paritytech/parity-ethereum/pull/9547)) -- Cli: remove reference to --no-ui in --unlock flag help ([#9616](https://github.com/paritytech/parity-ethereum/pull/9616)) -- Remove master from releasable branches ([#9655](https://github.com/paritytech/parity-ethereum/pull/9655)) -- Ethcore/VerificationQueue don't spawn up extra `worker-threads` when explictly specified not to ([#9620](https://github.com/paritytech/parity-ethereum/pull/9620)) -- Rpc: parity_getBlockReceipts ([#9527](https://github.com/paritytech/parity-ethereum/pull/9527)) -- Remove unused dependencies ([#9589](https://github.com/paritytech/parity-ethereum/pull/9589)) -- Ignore key_server_cluster randomly failing tests ([#9639](https://github.com/paritytech/parity-ethereum/pull/9639)) -- Ethcore: handle vm exception when estimating gas ([#9615](https://github.com/paritytech/parity-ethereum/pull/9615)) -- Fix bad-block reporting no reason ([#9638](https://github.com/paritytech/parity-ethereum/pull/9638)) -- Use static call and apparent value transfer for block reward contract code ([#9603](https://github.com/paritytech/parity-ethereum/pull/9603)) -- Hf in POA Sokol (2018-09-19) ([#9607](https://github.com/paritytech/parity-ethereum/pull/9607)) -- Bump smallvec to 0.6 in ethcore-light, ethstore and whisper ([#9588](https://github.com/paritytech/parity-ethereum/pull/9588)) -- Add constantinople conf to EvmTestClient. ([#9570](https://github.com/paritytech/parity-ethereum/pull/9570)) -- Fix(network): don't disconnect reserved peers ([#9608](https://github.com/paritytech/parity-ethereum/pull/9608)) -- Fix failing node-table tests on mac os, closes [#9632](https://github.com/paritytech/parity-ethereum/issues/9632) ([#9633](https://github.com/paritytech/parity-ethereum/pull/9633)) -- Update ropsten.json ([#9602](https://github.com/paritytech/parity-ethereum/pull/9602)) -- Simplify ethcore errors by removing BlockImportError ([#9593](https://github.com/paritytech/parity-ethereum/pull/9593)) -- Fix windows compilation, replaces [#9561](https://github.com/paritytech/parity-ethereum/issues/9561) ([#9621](https://github.com/paritytech/parity-ethereum/pull/9621)) -- Master: rpc-docs set github token ([#9610](https://github.com/paritytech/parity-ethereum/pull/9610)) -- Docs: add changelogs for 1.11.10, 1.11.11, 2.0.3, 2.0.4, 2.0.5, 2.0.6, 2.1.0, and 2.1.1 ([#9554](https://github.com/paritytech/parity-ethereum/pull/9554)) -- Docs(rpc): annotate tag with the provided message ([#9601](https://github.com/paritytech/parity-ethereum/pull/9601)) -- Ci: fix regex roll_eyes ([#9597](https://github.com/paritytech/parity-ethereum/pull/9597)) -- Remove snapcraft clean ([#9585](https://github.com/paritytech/parity-ethereum/pull/9585)) -- Add snapcraft package image (master) ([#9584](https://github.com/paritytech/parity-ethereum/pull/9584)) -- Docs(rpc): push the branch along with tags ([#9578](https://github.com/paritytech/parity-ethereum/pull/9578)) -- Fix typo for jsonrpc-threads flag ([#9574](https://github.com/paritytech/parity-ethereum/pull/9574)) -- Fix informant compile ([#9571](https://github.com/paritytech/parity-ethereum/pull/9571)) -- Added ropsten bootnodes ([#9569](https://github.com/paritytech/parity-ethereum/pull/9569)) -- Increase Gas-floor-target and Gas Cap ([#9564](https://github.com/paritytech/parity-ethereum/pull/9564)) -- While working on the platform tests make them non-breaking ([#9563](https://github.com/paritytech/parity-ethereum/pull/9563)) -- Improve P2P discovery ([#9526](https://github.com/paritytech/parity-ethereum/pull/9526)) -- Move dockerfile for android build container to scripts repo ([#9560](https://github.com/paritytech/parity-ethereum/pull/9560)) -- Simultaneous platform tests WIP ([#9557](https://github.com/paritytech/parity-ethereum/pull/9557)) -- Update ethabi-derive, serde, serde_json, serde_derive, syn && quote ([#9553](https://github.com/paritytech/parity-ethereum/pull/9553)) -- Ci: fix rpc docs generation 2 ([#9550](https://github.com/paritytech/parity-ethereum/pull/9550)) -- Ci: always run build pipelines for win, mac, linux, and android ([#9537](https://github.com/paritytech/parity-ethereum/pull/9537)) -- Multithreaded snapshot creation ([#9239](https://github.com/paritytech/parity-ethereum/pull/9239)) -- New ethabi ([#9511](https://github.com/paritytech/parity-ethereum/pull/9511)) -- Remove initial token for WS. ([#9545](https://github.com/paritytech/parity-ethereum/pull/9545)) -- Net_version caches network_id to avoid redundant aquire of sync readlock ([#9544](https://github.com/paritytech/parity-ethereum/pull/9544)) -- Correct before_script for nightly build versions ([#9543](https://github.com/paritytech/parity-ethereum/pull/9543)) -- Deps: bump kvdb-rocksdb to 0.1.4 ([#9539](https://github.com/paritytech/parity-ethereum/pull/9539)) -- State: test when contract creation fails, old storage values should re-appear ([#9532](https://github.com/paritytech/parity-ethereum/pull/9532)) -- Allow dropping light client RPC query with no results ([#9318](https://github.com/paritytech/parity-ethereum/pull/9318)) -- Bump master to 2.2.0 ([#9517](https://github.com/paritytech/parity-ethereum/pull/9517)) -- Enable all Constantinople hard fork changes in constantinople_test.json ([#9505](https://github.com/paritytech/parity-ethereum/pull/9505)) -- [Light] Validate `account balance` before importing transactions ([#9417](https://github.com/paritytech/parity-ethereum/pull/9417)) -- In create memory calculation is the same for create2 because the additional parameter was popped before. ([#9522](https://github.com/paritytech/parity-ethereum/pull/9522)) -- Update patricia trie to 0.2.2 ([#9525](https://github.com/paritytech/parity-ethereum/pull/9525)) -- Replace hardcoded JSON with serde json! macro ([#9489](https://github.com/paritytech/parity-ethereum/pull/9489)) -- Fix typo in version string ([#9516](https://github.com/paritytech/parity-ethereum/pull/9516)) +- Backports for 2.3.0 beta ([#10164](https://github.com/paritytech/parity-ethereum/pull/10164)) +- Snap: fix path in script ([#10157](https://github.com/paritytech/parity-ethereum/pull/10157)) +- Make sure parent block is not in importing queue when importing ancient blocks ([#10138](https://github.com/paritytech/parity-ethereum/pull/10138)) +- Ci: re-enable snap publishing ([#10142](https://github.com/paritytech/parity-ethereum/pull/10142)) +- Hf in POA Core (2019-01-18) - Constantinople ([#10155](https://github.com/paritytech/parity-ethereum/pull/10155)) +- Update EWF's tobalaba chainspec ([#10152](https://github.com/paritytech/parity-ethereum/pull/10152)) +- Replace ethcore-logger with env-logger. ([#10102](https://github.com/paritytech/parity-ethereum/pull/10102)) +- Finality: dont require chain head to be in the chain ([#10054](https://github.com/paritytech/parity-ethereum/pull/10054)) +- Remove caching for node connections ([#10143](https://github.com/paritytech/parity-ethereum/pull/10143)) +- Blooms file iterator empty on out of range position. ([#10145](https://github.com/paritytech/parity-ethereum/pull/10145)) +- Autogen docs for the "Configuring Parity Ethereum" wiki page. ([#10067](https://github.com/paritytech/parity-ethereum/pull/10067)) +- Misc: bump license header to 2019 ([#10135](https://github.com/paritytech/parity-ethereum/pull/10135)) +- Hide most of the logs from cpp example. ([#10139](https://github.com/paritytech/parity-ethereum/pull/10139)) +- Don't try to send oversized packets ([#10042](https://github.com/paritytech/parity-ethereum/pull/10042)) +- Private tx enabled flag added into STATUS packet ([#9999](https://github.com/paritytech/parity-ethereum/pull/9999)) +- Update pwasm-utils to 0.6.1 ([#10134](https://github.com/paritytech/parity-ethereum/pull/10134)) +- Extract blockchain from ethcore ([#10114](https://github.com/paritytech/parity-ethereum/pull/10114)) +- Ethcore: update hardcoded headers ([#10123](https://github.com/paritytech/parity-ethereum/pull/10123)) +- Identity fix ([#10128](https://github.com/paritytech/parity-ethereum/pull/10128)) +- Use LenCachingMutex to optimize verification. ([#10117](https://github.com/paritytech/parity-ethereum/pull/10117)) +- Pyethereum keystore support ([#9710](https://github.com/paritytech/parity-ethereum/pull/9710)) +- Bump rocksdb-sys to 0.5.5 ([#10124](https://github.com/paritytech/parity-ethereum/pull/10124)) +- Parity-clib: `async C bindings to RPC requests` + `subscribe/unsubscribe to websocket events` ([#9920](https://github.com/paritytech/parity-ethereum/pull/9920)) +- Refactor (hardware wallet) : reduce the number of threads ([#9644](https://github.com/paritytech/parity-ethereum/pull/9644)) +- Hf in POA Sokol (2019-01-04) ([#10077](https://github.com/paritytech/parity-ethereum/pull/10077)) +- Fix broken links ([#10119](https://github.com/paritytech/parity-ethereum/pull/10119)) +- Follow-up to [#10105](https://github.com/paritytech/parity-ethereum/issues/10105) ([#10107](https://github.com/paritytech/parity-ethereum/pull/10107)) +- Move EIP-712 crate back to parity-ethereum ([#10106](https://github.com/paritytech/parity-ethereum/pull/10106)) +- Move a bunch of stuff around ([#10101](https://github.com/paritytech/parity-ethereum/pull/10101)) +- Revert "Add --frozen when running cargo ([#10081](https://github.com/paritytech/parity-ethereum/pull/10081))" ([#10105](https://github.com/paritytech/parity-ethereum/pull/10105)) +- Fix left over small grumbles on whitespaces ([#10084](https://github.com/paritytech/parity-ethereum/pull/10084)) +- Add --frozen when running cargo ([#10081](https://github.com/paritytech/parity-ethereum/pull/10081)) +- Fix pubsub new_blocks notifications to include all blocks ([#9987](https://github.com/paritytech/parity-ethereum/pull/9987)) +- Update some dependencies for compilation with pc-windows-gnu ([#10082](https://github.com/paritytech/parity-ethereum/pull/10082)) +- Fill transaction hash on ethGetLog of light client. ([#9938](https://github.com/paritytech/parity-ethereum/pull/9938)) +- Update changelog update for 2.2.5-beta and 2.1.10-stable ([#10064](https://github.com/paritytech/parity-ethereum/pull/10064)) +- Implement len caching for parking_lot RwLock ([#10032](https://github.com/paritytech/parity-ethereum/pull/10032)) +- Update parking_lot to 0.7 ([#10050](https://github.com/paritytech/parity-ethereum/pull/10050)) +- Bump crossbeam. ([#10048](https://github.com/paritytech/parity-ethereum/pull/10048)) +- Ethcore: enable constantinople on ethereum ([#10031](https://github.com/paritytech/parity-ethereum/pull/10031)) +- Strict empty steps validation ([#10041](https://github.com/paritytech/parity-ethereum/pull/10041)) +- Center the Subtitle, use some CAPS ([#10034](https://github.com/paritytech/parity-ethereum/pull/10034)) +- Change test miner max memory to malloc reports. ([#10024](https://github.com/paritytech/parity-ethereum/pull/10024)) +- Sort the storage for private state ([#10018](https://github.com/paritytech/parity-ethereum/pull/10018)) +- Fix: test corpus_inaccessible panic ([#10019](https://github.com/paritytech/parity-ethereum/pull/10019)) +- Ci: move future releases to ethereum subdir on s3 ([#10017](https://github.com/paritytech/parity-ethereum/pull/10017)) +- Light(on_demand): decrease default time window to 10 secs ([#10016](https://github.com/paritytech/parity-ethereum/pull/10016)) +- Light client : failsafe crate (circuit breaker) ([#9790](https://github.com/paritytech/parity-ethereum/pull/9790)) +- Lencachingmutex ([#9988](https://github.com/paritytech/parity-ethereum/pull/9988)) +- Version and notification for private contract wrapper added ([#9761](https://github.com/paritytech/parity-ethereum/pull/9761)) +- Handle failing case for update account cache in require ([#9989](https://github.com/paritytech/parity-ethereum/pull/9989)) +- Add tokio runtime to ethcore io worker ([#9979](https://github.com/paritytech/parity-ethereum/pull/9979)) +- Move daemonize before creating account provider ([#10003](https://github.com/paritytech/parity-ethereum/pull/10003)) +- Docs: update changelogs ([#9990](https://github.com/paritytech/parity-ethereum/pull/9990)) +- Fix daemonize ([#10000](https://github.com/paritytech/parity-ethereum/pull/10000)) +- Fix Bloom migration ([#9992](https://github.com/paritytech/parity-ethereum/pull/9992)) +- Remove tendermint engine support ([#9980](https://github.com/paritytech/parity-ethereum/pull/9980)) +- Calculate gas for deployment transaction ([#9840](https://github.com/paritytech/parity-ethereum/pull/9840)) +- Fix unstable peers and slowness in sync ([#9967](https://github.com/paritytech/parity-ethereum/pull/9967)) +- Adds parity_verifySignature RPC method ([#9507](https://github.com/paritytech/parity-ethereum/pull/9507)) +- Improve block and transaction propagation ([#9954](https://github.com/paritytech/parity-ethereum/pull/9954)) +- Deny unknown fields for chainspec ([#9972](https://github.com/paritytech/parity-ethereum/pull/9972)) +- Fix docker build ([#9971](https://github.com/paritytech/parity-ethereum/pull/9971)) +- Ci: rearrange pipeline by logic ([#9970](https://github.com/paritytech/parity-ethereum/pull/9970)) +- Add changelogs for 2.0.9, 2.1.4, 2.1.6, and 2.2.1 ([#9963](https://github.com/paritytech/parity-ethereum/pull/9963)) +- Add Error message when sync is still in progress. ([#9475](https://github.com/paritytech/parity-ethereum/pull/9475)) +- Make CALLCODE to trace value to be the code address ([#9881](https://github.com/paritytech/parity-ethereum/pull/9881)) +- Fix light client informant while syncing ([#9932](https://github.com/paritytech/parity-ethereum/pull/9932)) +- Add a optional json dump state to evm-bin ([#9706](https://github.com/paritytech/parity-ethereum/pull/9706)) +- Disable EIP-98 transition by default ([#9955](https://github.com/paritytech/parity-ethereum/pull/9955)) +- Remove secret_store runtimes. ([#9888](https://github.com/paritytech/parity-ethereum/pull/9888)) +- Fix a deadlock ([#9952](https://github.com/paritytech/parity-ethereum/pull/9952)) +- Chore(eip712): remove unused `failure-derive` ([#9958](https://github.com/paritytech/parity-ethereum/pull/9958)) +- Do not use the home directory as the working dir in docker ([#9834](https://github.com/paritytech/parity-ethereum/pull/9834)) +- Prevent silent errors in daemon mode, closes [#9367](https://github.com/paritytech/parity-ethereum/issues/9367) ([#9946](https://github.com/paritytech/parity-ethereum/pull/9946)) +- Fix empty steps ([#9939](https://github.com/paritytech/parity-ethereum/pull/9939)) +- Adjust requests costs for light client ([#9925](https://github.com/paritytech/parity-ethereum/pull/9925)) +- Eip-1186: add `eth_getProof` RPC-Method ([#9001](https://github.com/paritytech/parity-ethereum/pull/9001)) +- Missing blocks in filter_changes RPC ([#9947](https://github.com/paritytech/parity-ethereum/pull/9947)) +- Allow rust-nightly builds fail in nightly builds ([#9944](https://github.com/paritytech/parity-ethereum/pull/9944)) +- Update eth-secp256k1 to include fix for BSDs ([#9935](https://github.com/paritytech/parity-ethereum/pull/9935)) +- Unbreak build on rust -stable ([#9934](https://github.com/paritytech/parity-ethereum/pull/9934)) +- Keep existing blocks when restoring a Snapshot ([#8643](https://github.com/paritytech/parity-ethereum/pull/8643)) +- Add experimental RPCs flag ([#9928](https://github.com/paritytech/parity-ethereum/pull/9928)) +- Clarify poll lifetime ([#9922](https://github.com/paritytech/parity-ethereum/pull/9922)) +- Docs(require rust 1.30) ([#9923](https://github.com/paritytech/parity-ethereum/pull/9923)) +- Use block header for building finality ([#9914](https://github.com/paritytech/parity-ethereum/pull/9914)) +- Simplify cargo audit ([#9918](https://github.com/paritytech/parity-ethereum/pull/9918)) +- Light-fetch: Differentiate between out-of-gas/manual throw and use required gas from response on failure ([#9824](https://github.com/paritytech/parity-ethereum/pull/9824)) +- Eip 191 ([#9701](https://github.com/paritytech/parity-ethereum/pull/9701)) +- Fix(logger): `reqwest` no longer a dependency ([#9908](https://github.com/paritytech/parity-ethereum/pull/9908)) +- Remove rust-toolchain file ([#9906](https://github.com/paritytech/parity-ethereum/pull/9906)) +- Foundation: 6692865, ropsten: 4417537, kovan: 9363457 ([#9907](https://github.com/paritytech/parity-ethereum/pull/9907)) +- Ethcore: use Machine::verify_transaction on parent block ([#9900](https://github.com/paritytech/parity-ethereum/pull/9900)) +- Chore(rpc-tests): remove unused rand ([#9896](https://github.com/paritytech/parity-ethereum/pull/9896)) +- Fix: Intermittent failing CI due to addr in use ([#9885](https://github.com/paritytech/parity-ethereum/pull/9885)) +- Chore(bump docopt): 0.8 -> 1.0 ([#9889](https://github.com/paritytech/parity-ethereum/pull/9889)) +- Use expect ([#9883](https://github.com/paritytech/parity-ethereum/pull/9883)) +- Use Weak reference in PubSubClient ([#9886](https://github.com/paritytech/parity-ethereum/pull/9886)) +- Ci: nuke the gitlab caches ([#9855](https://github.com/paritytech/parity-ethereum/pull/9855)) +- Remove unused code ([#9884](https://github.com/paritytech/parity-ethereum/pull/9884)) +- Fix json tracer overflow ([#9873](https://github.com/paritytech/parity-ethereum/pull/9873)) +- Allow to seal work on latest block ([#9876](https://github.com/paritytech/parity-ethereum/pull/9876)) +- Fix docker script ([#9854](https://github.com/paritytech/parity-ethereum/pull/9854)) +- Health endpoint ([#9847](https://github.com/paritytech/parity-ethereum/pull/9847)) +- Gitlab-ci: make android release build succeed ([#9743](https://github.com/paritytech/parity-ethereum/pull/9743)) +- Clean up existing benchmarks ([#9839](https://github.com/paritytech/parity-ethereum/pull/9839)) +- Update Callisto block reward code to support HF1 ([#9811](https://github.com/paritytech/parity-ethereum/pull/9811)) +- Option to disable keep alive for JSON-RPC http transport ([#9848](https://github.com/paritytech/parity-ethereum/pull/9848)) +- Classic.json Bootnode Update ([#9828](https://github.com/paritytech/parity-ethereum/pull/9828)) +- Support MIX. ([#9767](https://github.com/paritytech/parity-ethereum/pull/9767)) +- Ci: remove failing tests for android, windows, and macos ([#9788](https://github.com/paritytech/parity-ethereum/pull/9788)) +- Implement NoProof for json tests and update tests reference (replaces [#9744](https://github.com/paritytech/parity-ethereum/issues/9744)) ([#9814](https://github.com/paritytech/parity-ethereum/pull/9814)) +- Chore(bump regex) ([#9842](https://github.com/paritytech/parity-ethereum/pull/9842)) +- Ignore global cache for patched accounts ([#9752](https://github.com/paritytech/parity-ethereum/pull/9752)) +- Move state root verification before gas used ([#9841](https://github.com/paritytech/parity-ethereum/pull/9841)) +- Fix(docker-aarch64) : cross-compile config ([#9798](https://github.com/paritytech/parity-ethereum/pull/9798)) +- Version: bump nightly to 2.3.0 ([#9819](https://github.com/paritytech/parity-ethereum/pull/9819)) +- Tests modification for windows CI ([#9671](https://github.com/paritytech/parity-ethereum/pull/9671)) +- Eip-712 implementation ([#9631](https://github.com/paritytech/parity-ethereum/pull/9631)) +- Fix typo ([#9826](https://github.com/paritytech/parity-ethereum/pull/9826)) +- Clean up serde rename and use rename_all = camelCase when possible ([#9823](https://github.com/paritytech/parity-ethereum/pull/9823)) ## Previous releases -- [CHANGELOG-2.1](docs/CHANGELOG-2.1.md) (_stable_) +- [CHANGELOG-2.1](docs/CHANGELOG-2.2.md) (_stable_) +- [CHANGELOG-2.1](docs/CHANGELOG-2.1.md) (EOL: 2019-01-16) - [CHANGELOG-2.0](docs/CHANGELOG-2.0.md) (EOL: 2018-11-15) - [CHANGELOG-1.11](docs/CHANGELOG-1.11.md) (EOL: 2018-09-19) - [CHANGELOG-1.10](docs/CHANGELOG-1.10.md) (EOL: 2018-07-18) diff --git a/docs/CHANGELOG-2.0.md b/docs/CHANGELOG-2.0.md index e0e6b0c380..ef57dc2fbb 100644 --- a/docs/CHANGELOG-2.0.md +++ b/docs/CHANGELOG-2.0.md @@ -1,4 +1,4 @@ -Note: Parity 2.0 reached End-of-Life on 2018-11-15 (EOL). +Note: Parity Ethereum 2.0 reached End-of-Life on 2018-11-15 (EOL). ## Parity-Ethereum [v2.0.9](https://github.com/paritytech/parity-ethereum/releases/tag/v2.0.9) (2018-10-29) diff --git a/docs/CHANGELOG-2.1.md b/docs/CHANGELOG-2.1.md index 3f3b229809..212370a270 100644 --- a/docs/CHANGELOG-2.1.md +++ b/docs/CHANGELOG-2.1.md @@ -1,13 +1,31 @@ +Note: Parity Ethereum 2.1 reached End-of-Life on 2019-01-16 (EOL). + +## Parity-Ethereum [v2.1.11](https://github.com/paritytech/parity-ethereum/releases/tag/v2.1.11) (2019-01-09) + +Parity-Ethereum 2.1.11-stable is a bugfix release that improves performance and stability. + +The full list of included changes: + +- Stable backports v2.1.11 ([#10112](https://github.com/paritytech/parity-ethereum/pull/10112)) + - Version: bump stable to v2.1.11 + - HF in POA Sokol (2019-01-04) ([#10077](https://github.com/paritytech/parity-ethereum/pull/10077)) + - Add --locked when running cargo ([#10107](https://github.com/paritytech/parity-ethereum/pull/10107)) + - Ethcore: update hardcoded headers ([#10123](https://github.com/paritytech/parity-ethereum/pull/10123)) + - Identity fix ([#10128](https://github.com/paritytech/parity-ethereum/pull/10128)) + - Update pwasm-utils to 0.6.1 ([#10134](https://github.com/paritytech/parity-ethereum/pull/10134)) + - Version: mark upgrade critical on kovan + ## Parity-Ethereum [v2.1.10](https://github.com/paritytech/parity-ethereum/releases/tag/v2.1.10) (2018-12-14) -Parity-Ethereum 2.1.10-stable is an important release that introduces Constantinople fork at block 7080000 on Mainnet. -This release also contains a fix for chains using AuRa + EmptySteps. Read carefully if this applies to you. + +Parity-Ethereum 2.1.10-stable is an important release that introduces Constantinople fork at block 7080000 on Mainnet. +This release also contains a fix for chains using AuRa + EmptySteps. Read carefully if this applies to you. If you have a chain with`empty_steps` already running, some blocks most likely contain non-strict entries (unordered or duplicated empty steps). In this release`strict_empty_steps_transition` **is enabled by default at block 0** for any chain with `empty_steps`. If your network uses `empty_steps` you **must**: - plan a hard fork and change `strict_empty_steps_transition` to the desire fork block - update the clients of the whole network to 2.2.5-beta / 2.1.10-stable. If for some reason you don't want to do this please set`strict_empty_steps_transition` to `0xfffffffff` to disable it. -The full list of included changes: +The full list of included changes: - Backports for stable 2.1.10 ([#10046](https://github.com/paritytech/parity-ethereum/pull/10046)) - Bump stable to 2.1.10 ([#10046](https://github.com/paritytech/parity-ethereum/pull/10046)) diff --git a/docs/CHANGELOG-2.2.md b/docs/CHANGELOG-2.2.md new file mode 100644 index 0000000000..f1e8e79020 --- /dev/null +++ b/docs/CHANGELOG-2.2.md @@ -0,0 +1,317 @@ +## Parity-Ethereum [v2.2.7](https://github.com/paritytech/parity-ethereum/releases/tag/v2.2.7) (2018-01-15) + +Parity-Ethereum 2.2.7-stable is a consensus-relevant security release that reverts Constantinople on the Ethereum network. Upgrading is mandatory for Ethereum, and strongly recommended for other networks. + +- **Consensus** - Ethereum Network: Pull Constantinople protocol upgrade on Ethereum ([#10189](https://github.com/paritytech/parity-ethereum/pull/10189)) + - Read more: [Security Alert: Ethereum Constantinople Postponement](https://blog.ethereum.org/2019/01/15/security-alert-ethereum-constantinople-postponement/) +- **Networking** - All networks: Ping nodes from discovery ([#10167](https://github.com/paritytech/parity-ethereum/pull/10167)) +- **Wasm** - Kovan Network: Update pwasm-utils to 0.6.1 ([#10134](https://github.com/paritytech/parity-ethereum/pull/10134)) + +_Note:_ This release marks Parity 2.2 as _stable_. All versions of Parity 2.1 now reached _end of life_. + +The full list of included changes: + +- Backports for stable 2.2.7 ([#10163](https://github.com/paritytech/parity-ethereum/pull/10163)) + - Version: bump stable to 2.2.7 + - Version: mark 2.2 track stable + - Version: mark update critical on all networks + - Handle the case for contract creation on an empty but exist account with storage items ([#10065](https://github.com/paritytech/parity-ethereum/pull/10065)) + - Fix _cannot recursively call into `Core`_ issue ([#10144](https://github.com/paritytech/parity-ethereum/pull/10144)) + - Snap: fix path in script ([#10157](https://github.com/paritytech/parity-ethereum/pull/10157)) + - Ping nodes from discovery ([#10167](https://github.com/paritytech/parity-ethereum/pull/10167)) + - Version: bump fork blocks for kovan and foundation, mark releases non critical + - Pull constantinople on ethereum network ([#10189](https://github.com/paritytech/parity-ethereum/pull/10189)) + +## Parity-Ethereum [v2.2.6](https://github.com/paritytech/parity-ethereum/releases/tag/v2.2.6) (2019-01-10) + +Parity-Ethereum 2.2.6-beta is a bugfix release that improves performance and stability. + +The full list of included changes: + +- Beta backports v2.2.6 ([#10113](https://github.com/paritytech/parity-ethereum/pull/10113)) + - Version: bump beta to v2.2.6 + - Fill transaction hash on ethGetLog of light client. ([#9938](https://github.com/paritytech/parity-ethereum/pull/9938)) + - Fix pubsub new_blocks notifications to include all blocks ([#9987](https://github.com/paritytech/parity-ethereum/pull/9987)) + - Finality: dont require chain head to be in the chain ([#10054](https://github.com/paritytech/parity-ethereum/pull/10054)) + - Handle the case for contract creation on an empty but exist account with storage items ([#10065](https://github.com/paritytech/parity-ethereum/pull/10065)) + - Autogen docs for the "Configuring Parity Ethereum" wiki page. ([#10067](https://github.com/paritytech/parity-ethereum/pull/10067)) + - HF in POA Sokol (2019-01-04) ([#10077](https://github.com/paritytech/parity-ethereum/pull/10077)) + - Add --locked when running cargo ([#10107](https://github.com/paritytech/parity-ethereum/pull/10107)) + - Ethcore: update hardcoded headers ([#10123](https://github.com/paritytech/parity-ethereum/pull/10123)) + - Identity fix ([#10128](https://github.com/paritytech/parity-ethereum/pull/10128)) + - Update pwasm-utils to 0.6.1 ([#10134](https://github.com/paritytech/parity-ethereum/pull/10134)) + - Make sure parent block is not in importing queue when importing ancient blocks ([#10138](https://github.com/paritytech/parity-ethereum/pull/10138)) + - CI: re-enable snap publishing ([#10142](https://github.com/paritytech/parity-ethereum/pull/10142)) + - HF in POA Core (2019-01-18) - Constantinople ([#10155](https://github.com/paritytech/parity-ethereum/pull/10155)) + - Version: mark upgrade critical on kovan + +## Parity-Ethereum [v2.2.5](https://github.com/paritytech/parity-ethereum/releases/tag/v2.2.5) (2018-12-14) + +Parity-Ethereum 2.2.5-beta is an important release that introduces Constantinople fork at block 7080000 on Mainnet. +This release also contains a fix for chains using AuRa + EmptySteps. Read carefully if this applies to you. +If you have a chain with`empty_steps` already running, some blocks most likely contain non-strict entries (unordered or duplicated empty steps). In this release`strict_empty_steps_transition` **is enabled by default at block 0** for any chain with `empty_steps`. +If your network uses `empty_steps` you **must**: +- plan a hard fork and change `strict_empty_steps_transition` to the desire fork block +- update the clients of the whole network to 2.2.5-beta / 2.1.10-stable. +If for some reason you don't want to do this please set`strict_empty_steps_transition` to `0xfffffffff` to disable it. + +The full list of included changes: +- Backports for beta 2.2.5 ([#10047](https://github.com/paritytech/parity-ethereum/pull/10047)) + - Bump beta to 2.2.5 ([#10047](https://github.com/paritytech/parity-ethereum/pull/10047)) + - Fix empty steps ([#9939](https://github.com/paritytech/parity-ethereum/pull/9939)) + - Prevent sending empty step message twice + - Prevent sending empty step and then block in the same step + - Don't accept double empty steps + - Do basic validation of self-sealed blocks + - Strict empty steps validation ([#10041](https://github.com/paritytech/parity-ethereum/pull/10041)) + - Enables strict verification of empty steps - there can be no duplicates and empty steps should be ordered inside the seal. + - Note that authorities won't produce invalid seals after [#9939](https://github.com/paritytech/parity-ethereum/pull/9939), this PR just adds verification to the seal to prevent forging incorrect blocks and potentially causing consensus issues. + - This features is enabled by default so any AuRa + EmptySteps chain should set strict_empty_steps_transition fork block number in their spec and upgrade to v2.2.5-beta or v2.1.10-stable. + - ethcore: enable constantinople on ethereum ([#10031](https://github.com/paritytech/parity-ethereum/pull/10031)) + - ethcore: change blockreward to 2e18 for foundation after constantinople + - ethcore: delay diff bomb by 2e6 blocks for foundation after constantinople + - ethcore: enable eip-{145,1014,1052,1283} for foundation after constantinople + - Change test miner max memory to malloc reports. ([#10024](https://github.com/paritytech/parity-ethereum/pull/10024)) + - Fix: test corpus_inaccessible panic ([#10019](https://github.com/paritytech/parity-ethereum/pull/10019)) + +## Parity-Ethereum [v2.2.2](https://github.com/paritytech/parity-ethereum/releases/tag/v2.2.2) (2018-11-29) + +Parity-Ethereum 2.2.2-beta is an exciting release. Among others, it improves sync performance, peering stability, block propagation, and transaction propagation times. Also, a warp-sync no longer removes existing blocks from the database, but rather reuses locally available information to decrease sync times and reduces required bandwidth. + +Before upgrading to 2.2.2, please also verify the validity of your chain specs. Parity Ethereum now denies unknown fields in the specification. To do this, use the chainspec tool: + +``` +cargo build --release -p chainspec +./target/release/chainspec /path/to/spec.json +``` + +Last but not least, JSONRPC APIs which are not yet accepted as an EIP in the `eth`, `personal`, or `web3` namespace, are now considere experimental as their final specification might change in future. These APIs have to be manually enabled by explicitly running `--jsonrpc-experimental`. + +The full list of included changes: + +- Backports For beta 2.2.2 ([#9976](https://github.com/paritytech/parity-ethereum/pull/9976)) + - Version: bump beta to 2.2.2 + - Add experimental RPCs flag ([#9928](https://github.com/paritytech/parity-ethereum/pull/9928)) + - Keep existing blocks when restoring a Snapshot ([#8643](https://github.com/paritytech/parity-ethereum/pull/8643)) + - Rename db_restore => client + - First step: make it compile! + - Second step: working implementation! + - Refactoring + - Fix tests + - Migrate ancient blocks interacting backward + - Early return in block migration if snapshot is aborted + - Remove RwLock getter (PR Grumble I) + - Remove dependency on `Client`: only used Traits + - Add test for recovering aborted snapshot recovery + - Add test for migrating old blocks + - Release RwLock earlier + - Revert Cargo.lock + - Update _update ancient block_ logic: set local in `commit` + - Update typo in ethcore/src/snapshot/service.rs + - Adjust requests costs for light client ([#9925](https://github.com/paritytech/parity-ethereum/pull/9925)) + - Pip Table Cost relative to average peers instead of max peers + - Add tracing in PIP new_cost_table + - Update stat peer_count + - Use number of leeching peers for Light serve costs + - Fix test::light_params_load_share_depends_on_max_peers (wrong type) + - Remove (now) useless test + - Remove `load_share` from LightParams.Config + - Add LEECHER_COUNT_FACTOR + - Pr Grumble: u64 to u32 for f64 casting + - Prevent u32 overflow for avg_peer_count + - Add tests for LightSync::Statistics + - Fix empty steps ([#9939](https://github.com/paritytech/parity-ethereum/pull/9939)) + - Don't send empty step twice or empty step then block. + - Perform basic validation of locally sealed blocks. + - Don't include empty step twice. + - Prevent silent errors in daemon mode, closes [#9367](https://github.com/paritytech/parity-ethereum/issues/9367) ([#9946](https://github.com/paritytech/parity-ethereum/pull/9946)) + - Fix a deadlock ([#9952](https://github.com/paritytech/parity-ethereum/pull/9952)) + - Update informant: + - Decimal in Mgas/s + - Print every 5s (not randomly between 5s and 10s) + - Fix dead-lock in `blockchain.rs` + - Update locks ordering + - Fix light client informant while syncing ([#9932](https://github.com/paritytech/parity-ethereum/pull/9932)) + - Add `is_idle` to LightSync to check importing status + - Use SyncStateWrapper to make sure is_idle gets updates + - Update is_major_import to use verified queue size as well + - Add comment for `is_idle` + - Add Debug to `SyncStateWrapper` + - `fn get` -> `fn into_inner` + - Ci: rearrange pipeline by logic ([#9970](https://github.com/paritytech/parity-ethereum/pull/9970)) + - Ci: rearrange pipeline by logic + - Ci: rename docs script + - Fix docker build ([#9971](https://github.com/paritytech/parity-ethereum/pull/9971)) + - Deny unknown fields for chainspec ([#9972](https://github.com/paritytech/parity-ethereum/pull/9972)) + - Add deny_unknown_fields to chainspec + - Add tests and fix existing one + - Remove serde_ignored dependency for chainspec + - Fix rpc test eth chain spec + - Fix starting_nonce_test spec + - Improve block and transaction propagation ([#9954](https://github.com/paritytech/parity-ethereum/pull/9954)) + - Refactor sync to add priority tasks. + - Send priority tasks notifications. + - Propagate blocks, optimize transactions. + - Implement transaction propagation. Use sync_channel. + - Tone down info. + - Prevent deadlock by not waiting forever for sync lock. + - Fix lock order. + - Don't use sync_channel to prevent deadlocks. + - Fix tests. + - Fix unstable peers and slowness in sync ([#9967](https://github.com/paritytech/parity-ethereum/pull/9967)) + - Don't sync all peers after each response + - Update formating + - Fix tests: add `continue_sync` to `Sync_step` + - Update ethcore/sync/src/chain/mod.rs + - Fix rpc middlewares + - Fix Cargo.lock + - Json: resolve merge in spec + - Rpc: fix starting_nonce_test + - Ci: allow nightl job to fail + +## Parity-Ethereum [v2.2.1](https://github.com/paritytech/parity-ethereum/releases/tag/v2.2.1) (2018-11-15) + +Parity-Ethereum 2.2.1-beta is the first v2.2 release, and might introduce features that break previous work flows, among others: + +- Prevent zero network ID ([#9763](https://github.com/paritytech/parity-ethereum/pull/9763)) and drop support for Olympic testnet ([#9801](https://github.com/paritytech/parity-ethereum/pull/9801)): The Olympic test net is dead for years and never used a chain ID but network ID zero. Parity Ethereum is now preventing the network ID to be zero, thus Olympic support is dropped. Make sure to chose positive non-zero network IDs in future. +- Multithreaded snapshot creation ([#9239](https://github.com/paritytech/parity-ethereum/pull/9239)): adds a CLI argument `--snapshot-threads` which specifies the number of threads. This helps improving the performance of full nodes that wish to provide warp-snapshots for the network. The gain in performance comes with a slight drawback in increased snapshot size. +- Expose config max-round-blocks-to-import ([#9439](https://github.com/paritytech/parity-ethereum/pull/9439)): Parity Ethereum imports blocks in rounds. If at the end of any round, the queue is not empty, we consider it to be _importing_ and won't notify pubsub. On large re-orgs (10+ blocks), this is possible. The default `max_round_blocks_to_import` is increased to 12 and configurable via the `--max-round-blocks-to-import` CLI flag. With unstable network conditions, it is advised to increase the number. This shouldn't have any noticeable performance impact unless the number is set to really large. +- Increase Gas-floor-target and Gas Cap ([#9564](https://github.com/paritytech/parity-ethereum/pull/9564)): the default values for gas floor target are `8_000_000` and gas cap `10_000_000`, similar to Geth 1.8.15+. +- Produce portable binaries ([#9725](https://github.com/paritytech/parity-ethereum/pull/9725)): we now produce portable binaries, but it may incur some performance degradation. For ultimate performance it's now better to compile Parity Ethereum from source with `PORTABLE=OFF` environment variable. +- RPC: `parity_allTransactionHashes` ([#9745](https://github.com/paritytech/parity-ethereum/pull/9745)): Get all pending transactions from the queue with the high performant `parity_allTransactionHashes` RPC method. +- Support `eth_chainId` RPC method ([#9783](https://github.com/paritytech/parity-ethereum/pull/9783)): implements EIP-695 to get the chainID via RPC. +- AuRa: finalize blocks ([#9692](https://github.com/paritytech/parity-ethereum/pull/9692)): The AuRa engine was updated to emit ancestry actions to finalize blocks. The full client stores block finality in the database, the engine builds finality from an ancestry of `ExtendedHeader`; `is_epoch_end` was updated to take a vec of recently finalized headers; `is_epoch_end_light` was added which maintains the previous interface and is used by the light client since the client itself doesn't track finality. + +The full list of included changes: + +- Backport to parity 2.2.1 beta ([#9905](https://github.com/paritytech/parity-ethereum/pull/9905)) + - Bump version to 2.2.1 + - Fix: Intermittent failing CI due to addr in use ([#9885](https://github.com/paritytech/parity-ethereum/pull/9885)) + - Fix Parity not closing on Ctrl-C ([#9886](https://github.com/paritytech/parity-ethereum/pull/9886)) + - Fix json tracer overflow ([#9873](https://github.com/paritytech/parity-ethereum/pull/9873)) + - Fix docker script ([#9854](https://github.com/paritytech/parity-ethereum/pull/9854)) + - Add hardcoded headers for light client ([#9907](https://github.com/paritytech/parity-ethereum/pull/9907)) + - Gitlab-ci: make android release build succeed ([#9743](https://github.com/paritytech/parity-ethereum/pull/9743)) + - Allow to seal work on latest block ([#9876](https://github.com/paritytech/parity-ethereum/pull/9876)) + - Remove rust-toolchain file ([#9906](https://github.com/paritytech/parity-ethereum/pull/9906)) + - Light-fetch: Differentiate between out-of-gas/manual throw and use required gas from response on failure ([#9824](https://github.com/paritytech/parity-ethereum/pull/9824)) + - Eip-712 implementation ([#9631](https://github.com/paritytech/parity-ethereum/pull/9631)) + - Eip-191 implementation ([#9701](https://github.com/paritytech/parity-ethereum/pull/9701)) + - Simplify cargo audit ([#9918](https://github.com/paritytech/parity-ethereum/pull/9918)) + - Fix performance issue importing Kovan blocks ([#9914](https://github.com/paritytech/parity-ethereum/pull/9914)) + - Ci: nuke the gitlab caches ([#9855](https://github.com/paritytech/parity-ethereum/pull/9855)) +- Backports to parity beta 2.2.0 ([#9820](https://github.com/paritytech/parity-ethereum/pull/9820)) + - Ci: remove failing tests for android, windows, and macos ([#9788](https://github.com/paritytech/parity-ethereum/pull/9788)) + - Implement NoProof for json tests and update tests reference ([#9814](https://github.com/paritytech/parity-ethereum/pull/9814)) + - Move state root verification before gas used ([#9841](https://github.com/paritytech/parity-ethereum/pull/9841)) + - Classic.json Bootnode Update ([#9828](https://github.com/paritytech/parity-ethereum/pull/9828)) +- Rpc: parity_allTransactionHashes ([#9745](https://github.com/paritytech/parity-ethereum/pull/9745)) +- Revert "prevent zero networkID ([#9763](https://github.com/paritytech/parity-ethereum/pull/9763))" ([#9815](https://github.com/paritytech/parity-ethereum/pull/9815)) +- Allow zero chain id in EIP155 signing process ([#9792](https://github.com/paritytech/parity-ethereum/pull/9792)) +- Add readiness check for docker container ([#9804](https://github.com/paritytech/parity-ethereum/pull/9804)) +- Insert dev account before unlocking ([#9813](https://github.com/paritytech/parity-ethereum/pull/9813)) +- Removed "rustup" & added new runner tag ([#9731](https://github.com/paritytech/parity-ethereum/pull/9731)) +- Expose config max-round-blocks-to-import ([#9439](https://github.com/paritytech/parity-ethereum/pull/9439)) +- Aura: finalize blocks ([#9692](https://github.com/paritytech/parity-ethereum/pull/9692)) +- Sync: retry different peer after empty subchain heads response ([#9753](https://github.com/paritytech/parity-ethereum/pull/9753)) +- Fix(light-rpc/parity) : Remove unused client ([#9802](https://github.com/paritytech/parity-ethereum/pull/9802)) +- Drops support for olympic testnet, closes [#9800](https://github.com/paritytech/parity-ethereum/issues/9800) ([#9801](https://github.com/paritytech/parity-ethereum/pull/9801)) +- Replace `tokio_core` with `tokio` (`ring` -> 0.13) ([#9657](https://github.com/paritytech/parity-ethereum/pull/9657)) +- Support eth_chainId RPC method ([#9783](https://github.com/paritytech/parity-ethereum/pull/9783)) +- Ethcore: bump ropsten forkblock checkpoint ([#9775](https://github.com/paritytech/parity-ethereum/pull/9775)) +- Docs: changelogs for 2.0.8 and 2.1.3 ([#9758](https://github.com/paritytech/parity-ethereum/pull/9758)) +- Prevent zero networkID ([#9763](https://github.com/paritytech/parity-ethereum/pull/9763)) +- Skip seal fields count check when --no-seal-check is used ([#9757](https://github.com/paritytech/parity-ethereum/pull/9757)) +- Aura: fix panic on extra_info with unsealed block ([#9755](https://github.com/paritytech/parity-ethereum/pull/9755)) +- Docs: update changelogs ([#9742](https://github.com/paritytech/parity-ethereum/pull/9742)) +- Removed extra assert in generation_session_is_removed_when_succeeded ([#9738](https://github.com/paritytech/parity-ethereum/pull/9738)) +- Make checkpoint_storage_at use plain loop instead of recursion ([#9734](https://github.com/paritytech/parity-ethereum/pull/9734)) +- Use signed 256-bit integer for sstore gas refund substate ([#9746](https://github.com/paritytech/parity-ethereum/pull/9746)) +- Heads ref not present for branches beta and stable ([#9741](https://github.com/paritytech/parity-ethereum/pull/9741)) +- Add Callisto support ([#9534](https://github.com/paritytech/parity-ethereum/pull/9534)) +- Add --force to cargo audit install script ([#9735](https://github.com/paritytech/parity-ethereum/pull/9735)) +- Remove unused expired value from Handshake ([#9732](https://github.com/paritytech/parity-ethereum/pull/9732)) +- Add hardcoded headers ([#9730](https://github.com/paritytech/parity-ethereum/pull/9730)) +- Produce portable binaries ([#9725](https://github.com/paritytech/parity-ethereum/pull/9725)) +- Gitlab ci: releasable_branches: change variables condition to schedule ([#9729](https://github.com/paritytech/parity-ethereum/pull/9729)) +- Update a few parity-common dependencies ([#9663](https://github.com/paritytech/parity-ethereum/pull/9663)) +- Hf in POA Core (2018-10-22) ([#9724](https://github.com/paritytech/parity-ethereum/pull/9724)) +- Schedule nightly builds ([#9717](https://github.com/paritytech/parity-ethereum/pull/9717)) +- Fix ancient blocks sync ([#9531](https://github.com/paritytech/parity-ethereum/pull/9531)) +- Ci: Skip docs job for nightly ([#9693](https://github.com/paritytech/parity-ethereum/pull/9693)) +- Fix (light/provider) : Make `read_only executions` read-only ([#9591](https://github.com/paritytech/parity-ethereum/pull/9591)) +- Ethcore: fix detection of major import ([#9552](https://github.com/paritytech/parity-ethereum/pull/9552)) +- Return 0 on error ([#9705](https://github.com/paritytech/parity-ethereum/pull/9705)) +- Ethcore: delay ropsten hardfork ([#9704](https://github.com/paritytech/parity-ethereum/pull/9704)) +- Make instantSeal engine backwards compatible, closes [#9696](https://github.com/paritytech/parity-ethereum/issues/9696) ([#9700](https://github.com/paritytech/parity-ethereum/pull/9700)) +- Implement CREATE2 gas changes and fix some potential overflowing ([#9694](https://github.com/paritytech/parity-ethereum/pull/9694)) +- Don't hash the init_code of CREATE. ([#9688](https://github.com/paritytech/parity-ethereum/pull/9688)) +- Ethcore: minor optimization of modexp by using LR exponentiation ([#9697](https://github.com/paritytech/parity-ethereum/pull/9697)) +- Removed redundant clone before each block import ([#9683](https://github.com/paritytech/parity-ethereum/pull/9683)) +- Add Foundation Bootnodes ([#9666](https://github.com/paritytech/parity-ethereum/pull/9666)) +- Docker: run as parity user ([#9689](https://github.com/paritytech/parity-ethereum/pull/9689)) +- Ethcore: mcip3 block reward contract ([#9605](https://github.com/paritytech/parity-ethereum/pull/9605)) +- Verify block syncing responses against requests ([#9670](https://github.com/paritytech/parity-ethereum/pull/9670)) +- Add a new RPC `parity_submitWorkDetail` similar `eth_submitWork` but return block hash ([#9404](https://github.com/paritytech/parity-ethereum/pull/9404)) +- Resumable EVM and heap-allocated callstack ([#9360](https://github.com/paritytech/parity-ethereum/pull/9360)) +- Update parity-wordlist library ([#9682](https://github.com/paritytech/parity-ethereum/pull/9682)) +- Ci: Remove unnecessary pipes ([#9681](https://github.com/paritytech/parity-ethereum/pull/9681)) +- Test.sh: use cargo --target for platforms other than linux, win or mac ([#9650](https://github.com/paritytech/parity-ethereum/pull/9650)) +- Ci: fix push script ([#9679](https://github.com/paritytech/parity-ethereum/pull/9679)) +- Hardfork the testnets ([#9562](https://github.com/paritytech/parity-ethereum/pull/9562)) +- Calculate sha3 instead of sha256 for push-release. ([#9673](https://github.com/paritytech/parity-ethereum/pull/9673)) +- Ethcore-io retries failed work steal ([#9651](https://github.com/paritytech/parity-ethereum/pull/9651)) +- Fix(light_fetch): avoid race with BlockNumber::Latest ([#9665](https://github.com/paritytech/parity-ethereum/pull/9665)) +- Test fix for windows cache name... ([#9658](https://github.com/paritytech/parity-ethereum/pull/9658)) +- Refactor(fetch) : light use only one `DNS` thread ([#9647](https://github.com/paritytech/parity-ethereum/pull/9647)) +- Ethereum libfuzzer integration small change ([#9547](https://github.com/paritytech/parity-ethereum/pull/9547)) +- Cli: remove reference to --no-ui in --unlock flag help ([#9616](https://github.com/paritytech/parity-ethereum/pull/9616)) +- Remove master from releasable branches ([#9655](https://github.com/paritytech/parity-ethereum/pull/9655)) +- Ethcore/VerificationQueue don't spawn up extra `worker-threads` when explictly specified not to ([#9620](https://github.com/paritytech/parity-ethereum/pull/9620)) +- Rpc: parity_getBlockReceipts ([#9527](https://github.com/paritytech/parity-ethereum/pull/9527)) +- Remove unused dependencies ([#9589](https://github.com/paritytech/parity-ethereum/pull/9589)) +- Ignore key_server_cluster randomly failing tests ([#9639](https://github.com/paritytech/parity-ethereum/pull/9639)) +- Ethcore: handle vm exception when estimating gas ([#9615](https://github.com/paritytech/parity-ethereum/pull/9615)) +- Fix bad-block reporting no reason ([#9638](https://github.com/paritytech/parity-ethereum/pull/9638)) +- Use static call and apparent value transfer for block reward contract code ([#9603](https://github.com/paritytech/parity-ethereum/pull/9603)) +- Hf in POA Sokol (2018-09-19) ([#9607](https://github.com/paritytech/parity-ethereum/pull/9607)) +- Bump smallvec to 0.6 in ethcore-light, ethstore and whisper ([#9588](https://github.com/paritytech/parity-ethereum/pull/9588)) +- Add constantinople conf to EvmTestClient. ([#9570](https://github.com/paritytech/parity-ethereum/pull/9570)) +- Fix(network): don't disconnect reserved peers ([#9608](https://github.com/paritytech/parity-ethereum/pull/9608)) +- Fix failing node-table tests on mac os, closes [#9632](https://github.com/paritytech/parity-ethereum/issues/9632) ([#9633](https://github.com/paritytech/parity-ethereum/pull/9633)) +- Update ropsten.json ([#9602](https://github.com/paritytech/parity-ethereum/pull/9602)) +- Simplify ethcore errors by removing BlockImportError ([#9593](https://github.com/paritytech/parity-ethereum/pull/9593)) +- Fix windows compilation, replaces [#9561](https://github.com/paritytech/parity-ethereum/issues/9561) ([#9621](https://github.com/paritytech/parity-ethereum/pull/9621)) +- Master: rpc-docs set github token ([#9610](https://github.com/paritytech/parity-ethereum/pull/9610)) +- Docs: add changelogs for 1.11.10, 1.11.11, 2.0.3, 2.0.4, 2.0.5, 2.0.6, 2.1.0, and 2.1.1 ([#9554](https://github.com/paritytech/parity-ethereum/pull/9554)) +- Docs(rpc): annotate tag with the provided message ([#9601](https://github.com/paritytech/parity-ethereum/pull/9601)) +- Ci: fix regex roll_eyes ([#9597](https://github.com/paritytech/parity-ethereum/pull/9597)) +- Remove snapcraft clean ([#9585](https://github.com/paritytech/parity-ethereum/pull/9585)) +- Add snapcraft package image (master) ([#9584](https://github.com/paritytech/parity-ethereum/pull/9584)) +- Docs(rpc): push the branch along with tags ([#9578](https://github.com/paritytech/parity-ethereum/pull/9578)) +- Fix typo for jsonrpc-threads flag ([#9574](https://github.com/paritytech/parity-ethereum/pull/9574)) +- Fix informant compile ([#9571](https://github.com/paritytech/parity-ethereum/pull/9571)) +- Added ropsten bootnodes ([#9569](https://github.com/paritytech/parity-ethereum/pull/9569)) +- Increase Gas-floor-target and Gas Cap ([#9564](https://github.com/paritytech/parity-ethereum/pull/9564)) +- While working on the platform tests make them non-breaking ([#9563](https://github.com/paritytech/parity-ethereum/pull/9563)) +- Improve P2P discovery ([#9526](https://github.com/paritytech/parity-ethereum/pull/9526)) +- Move dockerfile for android build container to scripts repo ([#9560](https://github.com/paritytech/parity-ethereum/pull/9560)) +- Simultaneous platform tests WIP ([#9557](https://github.com/paritytech/parity-ethereum/pull/9557)) +- Update ethabi-derive, serde, serde_json, serde_derive, syn && quote ([#9553](https://github.com/paritytech/parity-ethereum/pull/9553)) +- Ci: fix rpc docs generation 2 ([#9550](https://github.com/paritytech/parity-ethereum/pull/9550)) +- Ci: always run build pipelines for win, mac, linux, and android ([#9537](https://github.com/paritytech/parity-ethereum/pull/9537)) +- Multithreaded snapshot creation ([#9239](https://github.com/paritytech/parity-ethereum/pull/9239)) +- New ethabi ([#9511](https://github.com/paritytech/parity-ethereum/pull/9511)) +- Remove initial token for WS. ([#9545](https://github.com/paritytech/parity-ethereum/pull/9545)) +- Net_version caches network_id to avoid redundant aquire of sync readlock ([#9544](https://github.com/paritytech/parity-ethereum/pull/9544)) +- Correct before_script for nightly build versions ([#9543](https://github.com/paritytech/parity-ethereum/pull/9543)) +- Deps: bump kvdb-rocksdb to 0.1.4 ([#9539](https://github.com/paritytech/parity-ethereum/pull/9539)) +- State: test when contract creation fails, old storage values should re-appear ([#9532](https://github.com/paritytech/parity-ethereum/pull/9532)) +- Allow dropping light client RPC query with no results ([#9318](https://github.com/paritytech/parity-ethereum/pull/9318)) +- Bump master to 2.2.0 ([#9517](https://github.com/paritytech/parity-ethereum/pull/9517)) +- Enable all Constantinople hard fork changes in constantinople_test.json ([#9505](https://github.com/paritytech/parity-ethereum/pull/9505)) +- [Light] Validate `account balance` before importing transactions ([#9417](https://github.com/paritytech/parity-ethereum/pull/9417)) +- In create memory calculation is the same for create2 because the additional parameter was popped before. ([#9522](https://github.com/paritytech/parity-ethereum/pull/9522)) +- Update patricia trie to 0.2.2 ([#9525](https://github.com/paritytech/parity-ethereum/pull/9525)) +- Replace hardcoded JSON with serde json! macro ([#9489](https://github.com/paritytech/parity-ethereum/pull/9489)) +- Fix typo in version string ([#9516](https://github.com/paritytech/parity-ethereum/pull/9516)) From 35bbf11ba5a205eb1f5f8473f56137acd4c333d0 Mon Sep 17 00:00:00 2001 From: Hernando Castano Date: Wed, 16 Jan 2019 19:52:21 +0100 Subject: [PATCH 022/168] Extract CallContract and RegistryInfo traits into their own crate (#10178) * Create call-contract crate * Add license * First attempt at using extracted CallContract trait * Remove unneeded `extern crate` calls * Move RegistryInfo trait into call-contract crate * Move service-transaction-checker from ethcore to ethcore-miner * Update Cargo.lock file * Re-export call_contract * Merge CallContract and RegistryInfo imports * Remove commented code * Add documentation to call_contract crate * Add TODO for removal of re-exports * Update call-contract crate description Co-Authored-By: HCastano * Rename call-contract crate to ethcore-call-contract --- Cargo.lock | 14 ++++++++ ethcore/Cargo.toml | 1 + ethcore/call-contract/Cargo.toml | 11 +++++++ ethcore/call-contract/src/call_contract.rs | 33 +++++++++++++++++++ ethcore/call-contract/src/lib.rs | 27 +++++++++++++++ ethcore/src/client/client.rs | 5 +-- ethcore/src/client/mod.rs | 9 +++-- ethcore/src/client/test_client.rs | 3 +- ethcore/src/client/traits.rs | 13 +------- ethcore/src/lib.rs | 1 + ethcore/src/miner/mod.rs | 1 - ethcore/src/miner/pool_client.rs | 2 +- miner/Cargo.toml | 4 +++ .../res/contracts/service_transaction.json | 0 miner/src/lib.rs | 7 ++++ .../src}/service_transaction_checker.rs | 3 +- 16 files changed, 113 insertions(+), 21 deletions(-) create mode 100644 ethcore/call-contract/Cargo.toml create mode 100644 ethcore/call-contract/src/call_contract.rs create mode 100644 ethcore/call-contract/src/lib.rs rename {ethcore => miner}/res/contracts/service_transaction.json (100%) rename {ethcore/src/miner => miner/src}/service_transaction_checker.rs (96%) diff --git a/Cargo.lock b/Cargo.lock index 8544d62ce4..240ceaf2bc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -695,6 +695,7 @@ dependencies = [ "ethash 1.12.0", "ethcore-blockchain 0.1.0", "ethcore-bloom-journal 0.1.0", + "ethcore-call-contract 0.1.0", "ethcore-db 0.1.0", "ethcore-io 1.12.0", "ethcore-miner 1.12.0", @@ -784,6 +785,15 @@ dependencies = [ "siphasher 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "ethcore-call-contract" +version = "0.1.0" +dependencies = [ + "common-types 0.1.0", + "ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "ethcore-db" version = "0.1.0" @@ -879,7 +889,11 @@ dependencies = [ "common-types 0.1.0", "env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)", "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethabi 6.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethabi-contract 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethabi-derive 6.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "ethash 1.12.0", + "ethcore-call-contract 0.1.0", "ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethkey 0.3.0", "fetch 0.1.0", diff --git a/ethcore/Cargo.toml b/ethcore/Cargo.toml index 9a286dcb9b..538da894c7 100644 --- a/ethcore/Cargo.toml +++ b/ethcore/Cargo.toml @@ -21,6 +21,7 @@ ethabi-derive = "6.0" ethash = { path = "../ethash" } ethcore-blockchain = { path = "./blockchain" } ethcore-bloom-journal = { path = "../util/bloom" } +ethcore-call-contract = { path = "./call-contract" } ethcore-db = { path = "./db" } ethcore-io = { path = "../util/io" } ethcore-miner = { path = "../miner" } diff --git a/ethcore/call-contract/Cargo.toml b/ethcore/call-contract/Cargo.toml new file mode 100644 index 0000000000..068434a1de --- /dev/null +++ b/ethcore/call-contract/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "ethcore-call-contract" +version = "0.1.0" +license = "GPL-3.0" +authors = ["Parity Technologies "] +edition = "2018" + +[dependencies] +types = { path = "../types", package = "common-types" } +ethereum-types = "0.4" +bytes = { version = "0.1", package = "parity-bytes" } diff --git a/ethcore/call-contract/src/call_contract.rs b/ethcore/call-contract/src/call_contract.rs new file mode 100644 index 0000000000..8b042f0833 --- /dev/null +++ b/ethcore/call-contract/src/call_contract.rs @@ -0,0 +1,33 @@ +// Copyright 2015-2019 Parity Technologies (UK) Ltd. +// This file is part of Parity Ethereum. + +// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . + +//! Provides CallContract and RegistryInfo traits + +use bytes::Bytes; +use ethereum_types::Address; +use types::ids::BlockId; + +/// Provides `call_contract` method +pub trait CallContract { + /// Like `call`, but with various defaults. Designed to be used for calling contracts. + fn call_contract(&self, id: BlockId, address: Address, data: Bytes) -> Result; +} + +/// Provides information on a blockchain service and it's registry +pub trait RegistryInfo { + /// Get the address of a particular blockchain service, if available. + fn registry_address(&self, name: String, block: BlockId) -> Option
; +} diff --git a/ethcore/call-contract/src/lib.rs b/ethcore/call-contract/src/lib.rs new file mode 100644 index 0000000000..1cbfb11378 --- /dev/null +++ b/ethcore/call-contract/src/lib.rs @@ -0,0 +1,27 @@ +// Copyright 2015-2019 Parity Technologies (UK) Ltd. +// This file is part of Parity Ethereum. + +// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . + +#![warn(missing_docs)] + +//! Call Contract module +//! +//! This crate exposes traits required to call contracts at particular block. +//! All utilities that depend on on-chain data should use those traits to access it. + +pub mod call_contract; + +// Re-export +pub use self::call_contract::*; diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index 52aedc37c7..b8541470b2 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -23,6 +23,7 @@ use std::time::{Instant, Duration}; use blockchain::{BlockReceipts, BlockChain, BlockChainDB, BlockProvider, TreeRoute, ImportRoute, TransactionAddress, ExtrasInsert, BlockNumberKey}; use bytes::Bytes; +use call_contract::{CallContract, RegistryInfo}; use ethcore_miner::pool::VerifiedTransaction; use ethereum_types::{H256, Address, U256}; use evm::Schedule; @@ -46,8 +47,8 @@ use vm::{EnvInfo, LastHashes}; use block::{IsBlock, LockedBlock, Drain, ClosedBlock, OpenBlock, enact_verified, SealedBlock}; use client::ancient_import::AncientVerifier; use client::{ - Nonce, Balance, ChainInfo, BlockInfo, CallContract, TransactionInfo, - RegistryInfo, ReopenBlock, PrepareOpenBlock, ScheduleInfo, ImportSealedBlock, + Nonce, Balance, ChainInfo, BlockInfo, TransactionInfo, + ReopenBlock, PrepareOpenBlock, ScheduleInfo, ImportSealedBlock, BroadcastProposalBlock, ImportBlock, StateOrBlock, StateInfo, StateClient, Call, AccountData, BlockChain as BlockChainTrait, BlockProducer, SealedBlockImporter, ClientIoMessage, BlockChainReset diff --git a/ethcore/src/client/mod.rs b/ethcore/src/client/mod.rs index 2d042b8741..ccd0d63552 100644 --- a/ethcore/src/client/mod.rs +++ b/ethcore/src/client/mod.rs @@ -36,9 +36,9 @@ pub use self::io_message::ClientIoMessage; pub use self::test_client::{TestBlockChainClient, EachBlockWith}; pub use self::chain_notify::{ChainNotify, NewBlocks, ChainRoute, ChainRouteType, ChainMessageType}; pub use self::traits::{ - Nonce, Balance, ChainInfo, BlockInfo, ReopenBlock, PrepareOpenBlock, CallContract, TransactionInfo, RegistryInfo, ScheduleInfo, ImportSealedBlock, BroadcastProposalBlock, ImportBlock, - StateOrBlock, StateClient, Call, EngineInfo, AccountData, BlockChain, BlockProducer, SealedBlockImporter, - BadBlocks, BlockChainReset + Nonce, Balance, ChainInfo, BlockInfo, ReopenBlock, PrepareOpenBlock, TransactionInfo, ScheduleInfo, ImportSealedBlock, BroadcastProposalBlock, ImportBlock, + StateOrBlock, StateClient, Call, EngineInfo, AccountData, BlockChain, BlockProducer, SealedBlockImporter, BadBlocks, + BlockChainReset }; pub use state::StateInfo; pub use self::traits::{BlockChainClient, EngineClient, ProvingBlockChainClient, IoClient}; @@ -48,6 +48,9 @@ pub use types::trace_filter::Filter as TraceFilter; pub use types::pruning_info::PruningInfo; pub use types::call_analytics::CallAnalytics; +// TODO: Get rid of re-exports: https://github.com/paritytech/parity-ethereum/issues/10130 +pub use call_contract::{CallContract, RegistryInfo}; + pub use executive::{Executed, Executive, TransactOptions}; pub use vm::{LastHashes, EnvInfo}; diff --git a/ethcore/src/client/test_client.rs b/ethcore/src/client/test_client.rs index 1ca826097f..5236f7cd40 100644 --- a/ethcore/src/client/test_client.rs +++ b/ethcore/src/client/test_client.rs @@ -49,8 +49,9 @@ use types::views::BlockView; use vm::Schedule; use block::{OpenBlock, SealedBlock, ClosedBlock}; +use call_contract::{CallContract, RegistryInfo}; use client::{ - Nonce, Balance, ChainInfo, BlockInfo, ReopenBlock, CallContract, TransactionInfo, RegistryInfo, + Nonce, Balance, ChainInfo, BlockInfo, ReopenBlock, TransactionInfo, PrepareOpenBlock, BlockChainClient, BlockChainInfo, BlockStatus, BlockId, Mode, TransactionId, UncleId, TraceId, TraceFilter, LastHashes, CallAnalytics, ProvingBlockChainClient, ScheduleInfo, ImportSealedBlock, BroadcastProposalBlock, ImportBlock, StateOrBlock, diff --git a/ethcore/src/client/traits.rs b/ethcore/src/client/traits.rs index 03f3b09694..2bc7026220 100644 --- a/ethcore/src/client/traits.rs +++ b/ethcore/src/client/traits.rs @@ -19,6 +19,7 @@ use std::sync::Arc; use blockchain::{BlockReceipts, TreeRoute}; use bytes::Bytes; +use call_contract::{CallContract, RegistryInfo}; use ethcore_miner::pool::VerifiedTransaction; use ethereum_types::{H256, U256, Address}; use evm::Schedule; @@ -157,12 +158,6 @@ pub trait StateClient { /// Provides various blockchain information, like block header, chain state etc. pub trait BlockChain: ChainInfo + BlockInfo + TransactionInfo {} -/// Provides information on a blockchain service and it's registry -pub trait RegistryInfo { - /// Get the address of a particular blockchain service, if available. - fn registry_address(&self, name: String, block: BlockId) -> Option
; -} - // FIXME Why these methods belong to BlockChainClient and not MiningBlockChainClient? /// Provides methods to import block into blockchain pub trait ImportBlock { @@ -170,12 +165,6 @@ pub trait ImportBlock { fn import_block(&self, block: Unverified) -> EthcoreResult; } -/// Provides `call_contract` method -pub trait CallContract { - /// Like `call`, but with various defaults. Designed to be used for calling contracts. - fn call_contract(&self, id: BlockId, address: Address, data: Bytes) -> Result; -} - /// Provides `call` and `call_many` methods pub trait Call { /// Type representing chain state diff --git a/ethcore/src/lib.rs b/ethcore/src/lib.rs index 73fdb64fde..8d7a52e403 100644 --- a/ethcore/src/lib.rs +++ b/ethcore/src/lib.rs @@ -60,6 +60,7 @@ extern crate ansi_term; extern crate bn; extern crate byteorder; +extern crate ethcore_call_contract as call_contract; extern crate common_types as types; extern crate crossbeam; extern crate ethabi; diff --git a/ethcore/src/miner/mod.rs b/ethcore/src/miner/mod.rs index 2696306e71..399d66b545 100644 --- a/ethcore/src/miner/mod.rs +++ b/ethcore/src/miner/mod.rs @@ -20,7 +20,6 @@ //! Keeps track of transactions and currently sealed pending block. mod miner; -mod service_transaction_checker; pub mod pool_client; #[cfg(feature = "stratum")] diff --git a/ethcore/src/miner/pool_client.rs b/ethcore/src/miner/pool_client.rs index e748d9bc20..1bccc04f10 100644 --- a/ethcore/src/miner/pool_client.rs +++ b/ethcore/src/miner/pool_client.rs @@ -25,6 +25,7 @@ use std::{ use ethereum_types::{H256, U256, Address}; use ethcore_miner::pool; use ethcore_miner::pool::client::NonceClient; +use ethcore_miner::service_transaction_checker::ServiceTransactionChecker; use types::transaction::{ self, UnverifiedTransaction, @@ -37,7 +38,6 @@ use account_provider::AccountProvider; use client::{TransactionId, BlockInfo, CallContract, Nonce}; use engines::EthEngine; use miner; -use miner::service_transaction_checker::ServiceTransactionChecker; use transaction_ext::Transaction; /// Cache for state nonces. diff --git a/miner/Cargo.toml b/miner/Cargo.toml index d37ed692c7..02e64ad4f8 100644 --- a/miner/Cargo.toml +++ b/miner/Cargo.toml @@ -17,6 +17,10 @@ url = { version = "1", optional = true } ansi_term = "0.10" common-types = { path = "../ethcore/types" } error-chain = "0.12" +ethabi = "6.0" +ethabi-derive = "6.0" +ethabi-contract = "6.0" +ethcore-call-contract = { path = "../ethcore/call-contract" } ethereum-types = "0.4" futures = "0.1" heapsize = "0.4" diff --git a/ethcore/res/contracts/service_transaction.json b/miner/res/contracts/service_transaction.json similarity index 100% rename from ethcore/res/contracts/service_transaction.json rename to miner/res/contracts/service_transaction.json diff --git a/miner/src/lib.rs b/miner/src/lib.rs index 3b2513f678..921e6dbaad 100644 --- a/miner/src/lib.rs +++ b/miner/src/lib.rs @@ -21,6 +21,8 @@ extern crate ansi_term; extern crate common_types as types; +extern crate ethabi; +extern crate ethcore_call_contract as call_contract; extern crate ethereum_types; extern crate futures; extern crate heapsize; @@ -33,6 +35,10 @@ extern crate price_info; extern crate rlp; extern crate transaction_pool as txpool; +#[macro_use] +extern crate ethabi_contract; +#[macro_use] +extern crate ethabi_derive; #[macro_use] extern crate error_chain; #[macro_use] @@ -52,5 +58,6 @@ pub mod external; pub mod gas_price_calibrator; pub mod gas_pricer; pub mod pool; +pub mod service_transaction_checker; #[cfg(feature = "work-notify")] pub mod work_notify; diff --git a/ethcore/src/miner/service_transaction_checker.rs b/miner/src/service_transaction_checker.rs similarity index 96% rename from ethcore/src/miner/service_transaction_checker.rs rename to miner/src/service_transaction_checker.rs index 8d4c461cea..17776f1569 100644 --- a/ethcore/src/miner/service_transaction_checker.rs +++ b/miner/src/service_transaction_checker.rs @@ -16,7 +16,8 @@ //! A service transactions contract checker. -use client::{RegistryInfo, CallContract, BlockId}; +use call_contract::{CallContract, RegistryInfo}; +use types::ids::BlockId; use types::transaction::SignedTransaction; use ethabi::FunctionOutputDecoder; From 2a7ed457dc0ee335eae66403e1a95131a5ce690a Mon Sep 17 00:00:00 2001 From: Hernando Castano Date: Thu, 17 Jan 2019 16:43:08 +0100 Subject: [PATCH 023/168] Remove CallContract and RegistryInfo re-exports from `ethcore/client` (#10205) * Remove re-export of `CallContract` and `RegistryInfo` from `ethcore/client` * Remove CallContract and RegistryInfo re-exports again This was missed while fixing merge conflicts --- Cargo.lock | 3 +++ Cargo.toml | 1 + ethcore/private-tx/Cargo.toml | 1 + ethcore/private-tx/src/lib.rs | 4 +++- ethcore/src/client/mod.rs | 3 --- ethcore/src/engines/validator_set/contract.rs | 3 ++- ethcore/src/lib.rs | 2 +- ethcore/src/machine.rs | 3 ++- ethcore/src/miner/miner.rs | 3 ++- ethcore/src/miner/mod.rs | 3 ++- ethcore/src/miner/pool_client.rs | 3 ++- ethcore/src/tx_filter.rs | 3 ++- ethcore/src/verification/canon_verifier.rs | 3 ++- ethcore/src/verification/mod.rs | 3 ++- ethcore/src/verification/noop_verifier.rs | 3 ++- ethcore/src/verification/verification.rs | 3 ++- ethcore/src/verification/verifier.rs | 3 ++- parity/lib.rs | 3 ++- parity/run.rs | 3 ++- secret-store/Cargo.toml | 1 + secret-store/src/acl_storage.rs | 3 ++- secret-store/src/key_server_set.rs | 3 ++- secret-store/src/lib.rs | 1 + secret-store/src/listener/service_contract.rs | 3 ++- secret-store/src/trusted_client.rs | 3 ++- 25 files changed, 45 insertions(+), 22 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 240ceaf2bc..d4f3f45210 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -976,6 +976,7 @@ dependencies = [ "ethabi-contract 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethabi-derive 6.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore 1.12.0", + "ethcore-call-contract 0.1.0", "ethcore-io 1.12.0", "ethcore-miner 1.12.0", "ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1014,6 +1015,7 @@ dependencies = [ "ethabi-contract 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethabi-derive 6.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore 1.12.0", + "ethcore-call-contract 0.1.0", "ethcore-sync 1.12.0", "ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethkey 0.3.0", @@ -2408,6 +2410,7 @@ dependencies = [ "docopt 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore 1.12.0", "ethcore-blockchain 0.1.0", + "ethcore-call-contract 0.1.0", "ethcore-db 0.1.0", "ethcore-io 1.12.0", "ethcore-light 1.12.0", diff --git a/Cargo.toml b/Cargo.toml index 5e95600357..c5c73dc52f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,6 +34,7 @@ ethcore = { path = "ethcore", features = ["parity"] } parity-bytes = "0.1" common-types = { path = "ethcore/types" } ethcore-blockchain = { path = "ethcore/blockchain" } +ethcore-call-contract = { path = "ethcore/call-contract"} ethcore-db = { path = "ethcore/db" } ethcore-io = { path = "util/io" } ethcore-light = { path = "ethcore/light" } diff --git a/ethcore/private-tx/Cargo.toml b/ethcore/private-tx/Cargo.toml index 1dd328e11c..5151deee44 100644 --- a/ethcore/private-tx/Cargo.toml +++ b/ethcore/private-tx/Cargo.toml @@ -12,6 +12,7 @@ ethabi = "6.0" ethabi-contract = "6.0" ethabi-derive = "6.0" ethcore = { path = ".." } +ethcore-call-contract = { path = "../call-contract" } ethcore-io = { path = "../../util/io" } ethcore-miner = { path = "../../miner" } ethereum-types = "0.4" diff --git a/ethcore/private-tx/src/lib.rs b/ethcore/private-tx/src/lib.rs index f55a30334a..3ab39d9e4e 100644 --- a/ethcore/private-tx/src/lib.rs +++ b/ethcore/private-tx/src/lib.rs @@ -28,6 +28,7 @@ mod error; extern crate common_types as types; extern crate ethabi; extern crate ethcore; +extern crate ethcore_call_contract as call_contract; extern crate ethcore_io as io; extern crate ethcore_miner; extern crate ethereum_types; @@ -82,11 +83,12 @@ use types::transaction::{SignedTransaction, Transaction, Action, UnverifiedTrans use ethcore::{contract_address as ethcore_contract_address}; use ethcore::client::{ Client, ChainNotify, NewBlocks, ChainMessageType, ClientIoMessage, BlockId, - CallContract, Call, BlockInfo + Call, BlockInfo }; use ethcore::account_provider::AccountProvider; use ethcore::miner::{self, Miner, MinerService, pool_client::NonceCache}; use ethcore::trace::{Tracer, VMTracer}; +use call_contract::CallContract; use rustc_hex::FromHex; use ethkey::Password; use ethabi::FunctionOutputDecoder; diff --git a/ethcore/src/client/mod.rs b/ethcore/src/client/mod.rs index ccd0d63552..d501ba21fe 100644 --- a/ethcore/src/client/mod.rs +++ b/ethcore/src/client/mod.rs @@ -48,9 +48,6 @@ pub use types::trace_filter::Filter as TraceFilter; pub use types::pruning_info::PruningInfo; pub use types::call_analytics::CallAnalytics; -// TODO: Get rid of re-exports: https://github.com/paritytech/parity-ethereum/issues/10130 -pub use call_contract::{CallContract, RegistryInfo}; - pub use executive::{Executed, Executive, TransactOptions}; pub use vm::{LastHashes, EnvInfo}; diff --git a/ethcore/src/engines/validator_set/contract.rs b/ethcore/src/engines/validator_set/contract.rs index 714a092d7e..b13ebdd105 100644 --- a/ethcore/src/engines/validator_set/contract.rs +++ b/ethcore/src/engines/validator_set/contract.rs @@ -145,7 +145,8 @@ mod tests { use miner::MinerService; use types::ids::BlockId; use test_helpers::generate_dummy_client_with_spec_and_accounts; - use client::{BlockChainClient, ChainInfo, BlockInfo, CallContract}; + use call_contract::CallContract; + use client::{BlockChainClient, ChainInfo, BlockInfo}; use super::super::ValidatorSet; use super::ValidatorContract; diff --git a/ethcore/src/lib.rs b/ethcore/src/lib.rs index 8d7a52e403..3da2eb9521 100644 --- a/ethcore/src/lib.rs +++ b/ethcore/src/lib.rs @@ -60,13 +60,13 @@ extern crate ansi_term; extern crate bn; extern crate byteorder; -extern crate ethcore_call_contract as call_contract; extern crate common_types as types; extern crate crossbeam; extern crate ethabi; extern crate ethash; extern crate ethcore_blockchain as blockchain; extern crate ethcore_bloom_journal as bloom_journal; +extern crate ethcore_call_contract as call_contract; extern crate ethcore_db as db; extern crate ethcore_io as io; extern crate ethcore_miner; diff --git a/ethcore/src/machine.rs b/ethcore/src/machine.rs index 873262d5dc..a14cb3bd29 100644 --- a/ethcore/src/machine.rs +++ b/ethcore/src/machine.rs @@ -30,7 +30,8 @@ use vm::{EnvInfo, Schedule, CreateContractAddress}; use block::{ExecutedBlock, IsBlock}; use builtin::Builtin; -use client::{BlockInfo, CallContract}; +use call_contract::CallContract; +use client::BlockInfo; use error::Error; use executive::Executive; use spec::CommonParams; diff --git a/ethcore/src/miner/miner.rs b/ethcore/src/miner/miner.rs index d30c5a67d0..998ce62804 100644 --- a/ethcore/src/miner/miner.rs +++ b/ethcore/src/miner/miner.rs @@ -21,6 +21,7 @@ use std::sync::Arc; use ansi_term::Colour; use bytes::Bytes; +use call_contract::CallContract; use ethcore_miner::gas_pricer::GasPricer; use ethcore_miner::pool::{self, TransactionQueue, VerifiedTransaction, QueueStatus, PrioritizationStrategy}; #[cfg(feature = "work-notify")] @@ -48,7 +49,7 @@ use using_queue::{UsingQueue, GetAction}; use account_provider::{AccountProvider, SignError as AccountError}; use block::{ClosedBlock, IsBlock, SealedBlock}; use client::{ - BlockChain, ChainInfo, CallContract, BlockProducer, SealedBlockImporter, Nonce, TransactionInfo, TransactionId + BlockChain, ChainInfo, BlockProducer, SealedBlockImporter, Nonce, TransactionInfo, TransactionId }; use client::{BlockId, ClientIoMessage}; use engines::{EthEngine, Seal}; diff --git a/ethcore/src/miner/mod.rs b/ethcore/src/miner/mod.rs index 399d66b545..4f5ba4c1f8 100644 --- a/ethcore/src/miner/mod.rs +++ b/ethcore/src/miner/mod.rs @@ -42,8 +42,9 @@ use types::header::Header; use types::receipt::RichReceipt; use block::SealedBlock; +use call_contract::{CallContract, RegistryInfo}; use client::{ - CallContract, RegistryInfo, ScheduleInfo, + ScheduleInfo, BlockChain, BlockProducer, SealedBlockImporter, ChainInfo, AccountData, Nonce, }; diff --git a/ethcore/src/miner/pool_client.rs b/ethcore/src/miner/pool_client.rs index 1bccc04f10..a75454a3fd 100644 --- a/ethcore/src/miner/pool_client.rs +++ b/ethcore/src/miner/pool_client.rs @@ -35,7 +35,8 @@ use types::header::Header; use parking_lot::RwLock; use account_provider::AccountProvider; -use client::{TransactionId, BlockInfo, CallContract, Nonce}; +use call_contract::CallContract; +use client::{TransactionId, BlockInfo, Nonce}; use engines::EthEngine; use miner; use transaction_ext::Transaction; diff --git a/ethcore/src/tx_filter.rs b/ethcore/src/tx_filter.rs index 403e4f7bcb..3f32ab365a 100644 --- a/ethcore/src/tx_filter.rs +++ b/ethcore/src/tx_filter.rs @@ -20,7 +20,8 @@ use ethereum_types::{H256, U256, Address}; use lru_cache::LruCache; use ethabi::FunctionOutputDecoder; -use client::{BlockInfo, CallContract, BlockId}; +use call_contract::CallContract; +use client::{BlockInfo, BlockId}; use parking_lot::Mutex; use spec::CommonParams; use types::transaction::{Action, SignedTransaction}; diff --git a/ethcore/src/verification/canon_verifier.rs b/ethcore/src/verification/canon_verifier.rs index 4a8ed111c9..03a1c7155f 100644 --- a/ethcore/src/verification/canon_verifier.rs +++ b/ethcore/src/verification/canon_verifier.rs @@ -16,7 +16,8 @@ //! Canonical verifier. -use client::{BlockInfo, CallContract}; +use call_contract::CallContract; +use client::BlockInfo; use engines::EthEngine; use error::Error; use types::header::Header; diff --git a/ethcore/src/verification/mod.rs b/ethcore/src/verification/mod.rs index acffb8c0a5..5546bd60c9 100644 --- a/ethcore/src/verification/mod.rs +++ b/ethcore/src/verification/mod.rs @@ -28,7 +28,8 @@ pub use self::canon_verifier::CanonVerifier; pub use self::noop_verifier::NoopVerifier; pub use self::queue::{BlockQueue, Config as QueueConfig, VerificationQueue, QueueInfo}; -use client::{BlockInfo, CallContract}; +use call_contract::CallContract; +use client::BlockInfo; /// Verifier type. #[derive(Debug, PartialEq, Clone)] diff --git a/ethcore/src/verification/noop_verifier.rs b/ethcore/src/verification/noop_verifier.rs index 727e99a66c..d68f1eb885 100644 --- a/ethcore/src/verification/noop_verifier.rs +++ b/ethcore/src/verification/noop_verifier.rs @@ -16,7 +16,8 @@ //! No-op verifier. -use client::{BlockInfo, CallContract}; +use call_contract::CallContract; +use client::BlockInfo; use engines::EthEngine; use error::Error; use types::header::Header; diff --git a/ethcore/src/verification/verification.rs b/ethcore/src/verification/verification.rs index 31eb9dfa68..827b714391 100644 --- a/ethcore/src/verification/verification.rs +++ b/ethcore/src/verification/verification.rs @@ -32,7 +32,8 @@ use triehash::ordered_trie_root; use unexpected::{Mismatch, OutOfBounds}; use blockchain::*; -use client::{BlockInfo, CallContract}; +use call_contract::CallContract; +use client::BlockInfo; use engines::EthEngine; use error::{BlockError, Error}; use types::{BlockNumber, header::Header}; diff --git a/ethcore/src/verification/verifier.rs b/ethcore/src/verification/verifier.rs index a1a5d32bc9..76eb60b9a1 100644 --- a/ethcore/src/verification/verifier.rs +++ b/ethcore/src/verification/verifier.rs @@ -16,7 +16,8 @@ //! A generic verifier trait. -use client::{BlockInfo, CallContract}; +use call_contract::CallContract; +use client::BlockInfo; use engines::EthEngine; use error::Error; use types::header::Header; diff --git a/parity/lib.rs b/parity/lib.rs index 14ec8f98ed..b96995910c 100644 --- a/parity/lib.rs +++ b/parity/lib.rs @@ -43,8 +43,9 @@ extern crate toml; extern crate blooms_db; extern crate cli_signer; extern crate common_types as types; -extern crate ethcore; extern crate parity_bytes as bytes; +extern crate ethcore; +extern crate ethcore_call_contract as call_contract; extern crate ethcore_db; extern crate ethcore_io as io; extern crate ethcore_light as light; diff --git a/parity/run.rs b/parity/run.rs index 6c53e675cd..03dbe447f3 100644 --- a/parity/run.rs +++ b/parity/run.rs @@ -21,8 +21,9 @@ use std::thread; use ansi_term::Colour; use bytes::Bytes; +use call_contract::CallContract; use ethcore::account_provider::{AccountProvider, AccountProviderSettings}; -use ethcore::client::{BlockId, CallContract, Client, Mode, DatabaseCompactionProfile, VMType, BlockChainClient, BlockInfo}; +use ethcore::client::{BlockId, Client, Mode, DatabaseCompactionProfile, VMType, BlockChainClient, BlockInfo}; use ethstore::ethkey; use ethcore::miner::{stratum, Miner, MinerService, MinerOptions}; use ethcore::snapshot::{self, SnapshotConfiguration}; diff --git a/secret-store/Cargo.toml b/secret-store/Cargo.toml index 8d41d48a87..016028a0bf 100644 --- a/secret-store/Cargo.toml +++ b/secret-store/Cargo.toml @@ -8,6 +8,7 @@ authors = ["Parity Technologies "] [dependencies] byteorder = "1.0" common-types = { path = "../ethcore/types" } +ethcore-call-contract = { path = "../ethcore/call-contract" } log = "0.4" parking_lot = "0.7" hyper = { version = "0.12", default-features = false } diff --git a/secret-store/src/acl_storage.rs b/secret-store/src/acl_storage.rs index 98eab5d932..8c6656b108 100644 --- a/secret-store/src/acl_storage.rs +++ b/secret-store/src/acl_storage.rs @@ -17,7 +17,8 @@ use std::sync::Arc; use std::collections::{HashMap, HashSet}; use parking_lot::{Mutex, RwLock}; -use ethcore::client::{BlockId, ChainNotify, NewBlocks, CallContract}; +use call_contract::CallContract; +use ethcore::client::{BlockId, ChainNotify, NewBlocks}; use ethereum_types::Address; use ethabi::FunctionOutputDecoder; use trusted_client::TrustedClient; diff --git a/secret-store/src/key_server_set.rs b/secret-store/src/key_server_set.rs index 50036d04d5..5b25641aee 100644 --- a/secret-store/src/key_server_set.rs +++ b/secret-store/src/key_server_set.rs @@ -18,8 +18,9 @@ use std::sync::Arc; use std::net::SocketAddr; use std::collections::{BTreeMap, HashSet}; use parking_lot::Mutex; +use call_contract::CallContract; use ethabi::FunctionOutputDecoder; -use ethcore::client::{Client, BlockChainClient, BlockId, ChainNotify, NewBlocks, CallContract}; +use ethcore::client::{Client, BlockChainClient, BlockId, ChainNotify, NewBlocks}; use ethereum_types::{H256, Address}; use ethkey::public_to_address; use bytes::Bytes; diff --git a/secret-store/src/lib.rs b/secret-store/src/lib.rs index 76ae09ffb3..915cec5288 100644 --- a/secret-store/src/lib.rs +++ b/secret-store/src/lib.rs @@ -18,6 +18,7 @@ extern crate byteorder; extern crate common_types; extern crate ethabi; extern crate ethcore; +extern crate ethcore_call_contract as call_contract; extern crate ethcore_sync as sync; extern crate ethereum_types; extern crate ethkey; diff --git a/secret-store/src/listener/service_contract.rs b/secret-store/src/listener/service_contract.rs index 47bb996e35..795e75d2c6 100644 --- a/secret-store/src/listener/service_contract.rs +++ b/secret-store/src/listener/service_contract.rs @@ -19,7 +19,8 @@ use parking_lot::RwLock; use common_types::filter::Filter; use ethabi::RawLog; use ethabi::FunctionOutputDecoder; -use ethcore::client::{Client, BlockChainClient, BlockId, CallContract}; +use call_contract::CallContract; +use ethcore::client::{Client, BlockChainClient, BlockId}; use ethkey::{Public, public_to_address}; use hash::keccak; use bytes::Bytes; diff --git a/secret-store/src/trusted_client.rs b/secret-store/src/trusted_client.rs index d66e7f43da..a20373ad0d 100644 --- a/secret-store/src/trusted_client.rs +++ b/secret-store/src/trusted_client.rs @@ -16,9 +16,10 @@ use std::sync::{Arc, Weak}; use bytes::Bytes; +use call_contract::RegistryInfo; use common_types::transaction::{Transaction, SignedTransaction, Action}; use ethereum_types::Address; -use ethcore::client::{Client, BlockChainClient, ChainInfo, Nonce, BlockId, RegistryInfo}; +use ethcore::client::{Client, BlockChainClient, ChainInfo, Nonce, BlockId}; use ethcore::miner::{Miner, MinerService}; use sync::SyncProvider; use helpers::{get_confirmed_block_hash, REQUEST_CONFIRMATIONS_REQUIRED}; From 460681ead915ab70979578c474a8c54d184c526c Mon Sep 17 00:00:00 2001 From: "Denis S. Soldatov aka General-Beck" Date: Fri, 18 Jan 2019 14:03:18 +0300 Subject: [PATCH 024/168] perform stripping during build (#10208) * perform stripping during build * var RUSTFLAGS --- scripts/gitlab/build-unix.sh | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/scripts/gitlab/build-unix.sh b/scripts/gitlab/build-unix.sh index 9bb6cd0f3f..57c6c85858 100755 --- a/scripts/gitlab/build-unix.sh +++ b/scripts/gitlab/build-unix.sh @@ -9,6 +9,8 @@ echo "CARGO_HOME: " $CARGO_HOME echo "CARGO_TARGET: " $CARGO_TARGET echo "CC: " $CC echo "CXX: " $CXX +#strip ON +export RUSTFLAGS=" -C link-arg=-s" echo "_____ Building target: "$CARGO_TARGET" _____" if [ "${CARGO_TARGET}" = "armv7-linux-androideabi" ] @@ -41,16 +43,6 @@ else cp -v ../../target/$CARGO_TARGET/release/whisper ./whisper fi - -# stripping can also be done on release build time -# export RUSTFLAGS="${RUSTFLAGS} -C link-arg=-s" -if [ "${CARGO_TARGET}" = "armv7-linux-androideabi" ] -then - arm-linux-androideabi-strip -v ./* -else - strip -v ./* -fi - echo "_____ Calculating checksums _____" for binary in $(ls) do From 708e495c2870cdad74f2d67f3f67f14a4251a160 Mon Sep 17 00:00:00 2001 From: Bryant Eisenbach Date: Fri, 18 Jan 2019 08:00:13 -0500 Subject: [PATCH 025/168] Happy New Year! (#10211) * Happy New Year! * Happy New Year! * Update README.md --- parity/cli/usage_header.txt | 2 +- parity/cli/version.txt | 2 +- whisper/README.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/parity/cli/usage_header.txt b/parity/cli/usage_header.txt index 82a6d58b24..eaf8867001 100644 --- a/parity/cli/usage_header.txt +++ b/parity/cli/usage_header.txt @@ -1,3 +1,3 @@ Parity Ethereum Client. By Wood/Paronyan/Kotewicz/Drwięga/Volf et al. - Copyright 2015-2018 Parity Technologies (UK) Ltd. + Copyright 2015-2019 Parity Technologies (UK) Ltd. diff --git a/parity/cli/version.txt b/parity/cli/version.txt index 480fe5469c..85ef190f12 100644 --- a/parity/cli/version.txt +++ b/parity/cli/version.txt @@ -1,6 +1,6 @@ Parity Ethereum version {} -Copyright 2015-2018 Parity Technologies (UK) Ltd. +Copyright 2015-2019 Parity Technologies (UK) Ltd. License GPLv3+: GNU GPL version 3 or later . This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. diff --git a/whisper/README.md b/whisper/README.md index 8dafc48af7..dc449568aa 100644 --- a/whisper/README.md +++ b/whisper/README.md @@ -6,7 +6,7 @@ Implementation of Whisper based on the Whisper-v2 PoC. ``` Parity Whisper-v2 CLI. - Copyright 2015-2018 Parity Technologies (UK) Ltd. + Copyright 2015-2019 Parity Technologies (UK) Ltd. Usage: whisper [options] From 940a88fa4e8fd9f51998d6eb88907547636eaf79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20M=C3=BCller?= Date: Mon, 21 Jan 2019 11:30:24 +0100 Subject: [PATCH 026/168] Echo CORS request headers by default (#10221) * Echo CORS request headers by default More details in https://github.com/paritytech/parity-ethereum/issues/6616. * fixup: Single line --- ethcore/res/ethereum/tests | 2 +- rpc/src/lib.rs | 4 +++- rpc/src/tests/rpc.rs | 27 +++++++++++++++++++++++++++ 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/ethcore/res/ethereum/tests b/ethcore/res/ethereum/tests index 420f443477..2cd62aeec1 160000 --- a/ethcore/res/ethereum/tests +++ b/ethcore/res/ethereum/tests @@ -1 +1 @@ -Subproject commit 420f443477caa8516f1f9ee8122fafc3415c0f34 +Subproject commit 2cd62aeec11da29766b30d500f2b9a96f1f28cf0 diff --git a/rpc/src/lib.rs b/rpc/src/lib.rs index 001343d649..2de2f0542c 100644 --- a/rpc/src/lib.rs +++ b/rpc/src/lib.rs @@ -114,7 +114,7 @@ pub use ipc::{Server as IpcServer, MetaExtractor as IpcMetaExtractor, RequestCon pub use http::{ hyper, RequestMiddleware, RequestMiddlewareAction, - AccessControlAllowOrigin, Host, DomainsValidation + AccessControlAllowOrigin, Host, DomainsValidation, cors::AccessControlAllowHeaders }; pub use v1::{NetworkSettings, Metadata, Origin, informant, dispatch, signer}; @@ -151,6 +151,7 @@ pub fn start_http( .cors(cors_domains.into()) .allowed_hosts(allowed_hosts.into()) .health_api(("/api/health", "parity_nodeStatus")) + .cors_allow_headers(AccessControlAllowHeaders::Any) .max_request_body_size(max_payload * 1024 * 1024) .start_http(addr)?) } @@ -180,6 +181,7 @@ pub fn start_http_with_middleware( .threads(threads) .cors(cors_domains.into()) .allowed_hosts(allowed_hosts.into()) + .cors_allow_headers(AccessControlAllowHeaders::Any) .max_request_body_size(max_payload * 1024 * 1024) .request_middleware(middleware) .start_http(addr)?) diff --git a/rpc/src/tests/rpc.rs b/rpc/src/tests/rpc.rs index 761ccc4e1f..99498c3e5d 100644 --- a/rpc/src/tests/rpc.rs +++ b/rpc/src/tests/rpc.rs @@ -116,4 +116,31 @@ mod tests { res.assert_status("HTTP/1.1 200 OK"); assert_eq!(res.body, expected); } + + #[test] + fn should_respond_valid_to_any_requested_header() { + // given + let (server, address) = serve(); + let headers = "Something, Anything, Xyz, 123, _?"; + + // when + let res = request(server, + &format!("\ + OPTIONS / HTTP/1.1\r\n\ + Host: {}\r\n\ + Origin: http://parity.io\r\n\ + Content-Length: 0\r\n\ + Content-Type: application/json\r\n\ + Connection: close\r\n\ + Access-Control-Request-Headers: {}\r\n\ + \r\n\ + ", address, headers) + ); + + // then + assert_eq!(res.status, "HTTP/1.1 200 OK".to_owned()); + let expected = format!("access-control-allow-headers: {}", headers); + assert!(res.headers.contains(&expected), "Headers missing in {:?}", res.headers); + } + } From fb07ffa6760550c524ceaeb4efc9c79487defe05 Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Mon, 21 Jan 2019 12:22:29 +0100 Subject: [PATCH 027/168] Add EIP-1283 disable transition (#10214) --- ethcore/src/spec/spec.rs | 8 +++++++- json/src/spec/params.rs | 3 +++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/ethcore/src/spec/spec.rs b/ethcore/src/spec/spec.rs index 9d67bf2c15..517b69e751 100644 --- a/ethcore/src/spec/spec.rs +++ b/ethcore/src/spec/spec.rs @@ -121,6 +121,8 @@ pub struct CommonParams { pub eip1052_transition: BlockNumber, /// Number of first block where EIP-1283 rules begin. pub eip1283_transition: BlockNumber, + /// Number of first block where EIP-1283 rules end. + pub eip1283_disable_transition: BlockNumber, /// Number of first block where EIP-1014 rules begin. pub eip1014_transition: BlockNumber, /// Number of first block where dust cleanup rules (EIP-168 and EIP169) begin. @@ -189,7 +191,7 @@ impl CommonParams { schedule.have_return_data = block_number >= self.eip211_transition; schedule.have_bitwise_shifting = block_number >= self.eip145_transition; schedule.have_extcodehash = block_number >= self.eip1052_transition; - schedule.eip1283 = block_number >= self.eip1283_transition; + schedule.eip1283 = block_number >= self.eip1283_transition && !(block_number >= self.eip1283_disable_transition); if block_number >= self.eip210_transition { schedule.blockhash_gas = 800; } @@ -300,6 +302,10 @@ impl From for CommonParams { BlockNumber::max_value, Into::into, ), + eip1283_disable_transition: p.eip1283_disable_transition.map_or_else( + BlockNumber::max_value, + Into::into, + ), eip1014_transition: p.eip1014_transition.map_or_else( BlockNumber::max_value, Into::into, diff --git a/json/src/spec/params.rs b/json/src/spec/params.rs index d64f429bf8..765384a6b9 100644 --- a/json/src/spec/params.rs +++ b/json/src/spec/params.rs @@ -89,6 +89,9 @@ pub struct Params { pub eip1052_transition: Option, /// See `CommonParams` docs. pub eip1283_transition: Option, + /// See `CommonParams` docs. + pub eip1283_disable_transition: Option, + /// See `CommonParams` docs. pub eip1014_transition: Option, /// See `CommonParams` docs. pub dust_protection_transition: Option, From a9a278a6e146895cf03387f8db89c25cc031c3c2 Mon Sep 17 00:00:00 2001 From: Afri Schoedon <5chdn@users.noreply.github.com> Date: Mon, 21 Jan 2019 22:55:44 +0100 Subject: [PATCH 028/168] Enable St-Peters-Fork ("Constantinople Fix") (#10223) * ethcore: disable eip-1283 on kovan block 10255201 * ethcore: disable eip-1283 on ropsten block 4939394 * ethcore: enable st-peters-fork on mainnet block 7280000 * ethcore: fix kovan chain spec * version: update fork blocks * ethcore: disable eip-1283 on sokol block 7026400 --- ethcore/res/ethereum/foundation.json | 11 ++++++++--- ethcore/res/ethereum/kovan.json | 1 + ethcore/res/ethereum/poasokol.json | 3 ++- ethcore/res/ethereum/ropsten.json | 3 ++- util/version/Cargo.toml | 6 +++--- 5 files changed, 16 insertions(+), 8 deletions(-) diff --git a/ethcore/res/ethereum/foundation.json b/ethcore/res/ethereum/foundation.json index 69f150fad6..061c435705 100644 --- a/ethcore/res/ethereum/foundation.json +++ b/ethcore/res/ethereum/foundation.json @@ -9,7 +9,8 @@ "durationLimit": "0xd", "blockReward": { "0x0": "0x4563918244f40000", - "0x42ae50": "0x29a2241af62c0000" + "0x42ae50": "0x29a2241af62c0000", + "0x6f1580": "0x1bc16d674ec80000" }, "homesteadTransition": "0x118c30", "daoHardforkTransition": "0x1d4c00", @@ -134,7 +135,8 @@ ], "eip100bTransition": "0x42ae50", "difficultyBombDelays": { - "0x42ae50": "0x2dc6c0" + "0x42ae50": "0x2dc6c0", + "0x6f1580": "0x1e8480" } } } @@ -158,7 +160,10 @@ "eip140Transition": "0x42ae50", "eip211Transition": "0x42ae50", "eip214Transition": "0x42ae50", - "eip658Transition": "0x42ae50" + "eip658Transition": "0x42ae50", + "eip145Transition": "0x6f1580", + "eip1014Transition": "0x6f1580", + "eip1052Transition": "0x6f1580" }, "genesis": { "seal": { diff --git a/ethcore/res/ethereum/kovan.json b/ethcore/res/ethereum/kovan.json index 7e4c257c93..a2332c6466 100644 --- a/ethcore/res/ethereum/kovan.json +++ b/ethcore/res/ethereum/kovan.json @@ -49,6 +49,7 @@ "eip1014Transition": "0x8c6180", "eip1052Transition": "0x8c6180", "eip1283Transition": "0x8c6180", + "eip1283DisableTransition": "0x9c7b61", "kip4Transition": "0x8c6180", "kip6Transition": "0x8c6180" }, diff --git a/ethcore/res/ethereum/poasokol.json b/ethcore/res/ethereum/poasokol.json index 067fd69fc3..8ee91c90c0 100644 --- a/ethcore/res/ethereum/poasokol.json +++ b/ethcore/res/ethereum/poasokol.json @@ -41,7 +41,8 @@ "eip145Transition": 6464300, "eip1014Transition": 6464300, "eip1052Transition": 6464300, - "eip1283Transition": 6464300 + "eip1283Transition": 6464300, + "eip1283DisableTransition": 7026400 }, "genesis": { "seal": { diff --git a/ethcore/res/ethereum/ropsten.json b/ethcore/res/ethereum/ropsten.json index 1dee7e30f6..c3b2b96b4f 100644 --- a/ethcore/res/ethereum/ropsten.json +++ b/ethcore/res/ethereum/ropsten.json @@ -44,7 +44,8 @@ "eip145Transition": "0x408b70", "eip1014Transition": "0x408b70", "eip1052Transition": "0x408b70", - "eip1283Transition": "0x408b70" + "eip1283Transition": "0x408b70", + "eip1283DisableTransition": "0x4b5e82" }, "genesis": { "seal": { diff --git a/util/version/Cargo.toml b/util/version/Cargo.toml index f778d290ed..d663ab4834 100644 --- a/util/version/Cargo.toml +++ b/util/version/Cargo.toml @@ -16,9 +16,9 @@ track = "nightly" # Latest supported fork blocks. # Indicates a critical release in this track (i.e. consensus issue). [package.metadata.networks] -foundation = { forkBlock = 4370000, critical = true } -ropsten = { forkBlock = 4230000, critical = false } -kovan = { forkBlock = 9200000, critical = true } +foundation = { forkBlock = 7280000, critical = false } +ropsten = { forkBlock = 4939394, critical = false } +kovan = { forkBlock = 10255201, critical = false } [dependencies] parity-bytes = "0.1" From c35abe41961862234caf6ca6732dff5e605291ce Mon Sep 17 00:00:00 2001 From: Seun LanLege Date: Tue, 22 Jan 2019 12:33:56 +0400 Subject: [PATCH 029/168] import rpc transactions sequentially (#10051) * import rpc transactions sequentially * use impl trait in argument position, renamed ProspectiveDispatcher to WithPostSign * grouped imports * integrates PostSign with ProspectiveSigner * fix spaces, removed unnecessary type cast and duplicate polling * clean up code style * Apply suggestions from code review --- rpc/src/v1/helpers/dispatch.rs | 176 ++++++++++++++++++++++++--------- rpc/src/v1/impls/personal.rs | 48 +++++---- 2 files changed, 159 insertions(+), 65 deletions(-) diff --git a/rpc/src/v1/helpers/dispatch.rs b/rpc/src/v1/helpers/dispatch.rs index e6d0d3fef6..c26fde45f1 100644 --- a/rpc/src/v1/helpers/dispatch.rs +++ b/rpc/src/v1/helpers/dispatch.rs @@ -41,11 +41,11 @@ use types::basic_account::BasicAccount; use types::ids::BlockId; use jsonrpc_core::{BoxFuture, Result, Error}; -use jsonrpc_core::futures::{future, Future, Poll, Async}; +use jsonrpc_core::futures::{future, Future, Poll, Async, IntoFuture}; use jsonrpc_core::futures::future::Either; use v1::helpers::{errors, nonce, TransactionRequest, FilledTransactionRequest, ConfirmationPayload}; use v1::types::{ - H256 as RpcH256, H520 as RpcH520, Bytes as RpcBytes, + H520 as RpcH520, Bytes as RpcBytes, RichRawTransaction as RpcRichRawTransaction, ConfirmationPayload as RpcConfirmationPayload, ConfirmationResponse, @@ -69,12 +69,20 @@ pub trait Dispatcher: Send + Sync + Clone { fn fill_optional_fields(&self, request: TransactionRequest, default_sender: Address, force_nonce: bool) -> BoxFuture; - /// Sign the given transaction request without dispatching, fetching appropriate nonce. - fn sign(&self, accounts: Arc, filled: FilledTransactionRequest, password: SignWith) - -> BoxFuture>; + /// Sign the given transaction request, fetching appropriate nonce and executing the PostSign action + fn sign

( + &self, + accounts: Arc, + filled: FilledTransactionRequest, + password: SignWith, + post_sign: P + ) -> BoxFuture + where + P: PostSign + 'static, + ::Future: Send; /// Converts a `SignedTransaction` into `RichRawTransaction` - fn enrich(&self, SignedTransaction) -> RpcRichRawTransaction; + fn enrich(&self, signed: SignedTransaction) -> RpcRichRawTransaction; /// "Dispatch" a local transaction. fn dispatch_transaction(&self, signed_transaction: PendingTransaction) @@ -164,19 +172,30 @@ impl Dispatcher })) } - fn sign(&self, accounts: Arc, filled: FilledTransactionRequest, password: SignWith) - -> BoxFuture> + fn sign

( + &self, + accounts: Arc, + filled: FilledTransactionRequest, + password: SignWith, + post_sign: P + ) -> BoxFuture + where + P: PostSign + 'static, + ::Future: Send { let chain_id = self.client.signing_chain_id(); if let Some(nonce) = filled.nonce { - return Box::new(future::done(sign_transaction(&*accounts, filled, chain_id, nonce, password))); - } - - let state = self.state_nonce(&filled.from); - let reserved = self.nonces.lock().reserve(filled.from, state); + let future = sign_transaction(&*accounts, filled, chain_id, nonce, password) + .into_future() + .and_then(move |signed| post_sign.execute(signed)); + Box::new(future) + } else { + let state = self.state_nonce(&filled.from); + let reserved = self.nonces.lock().reserve(filled.from, state); - Box::new(ProspectiveSigner::new(accounts, filled, chain_id, reserved, password)) + Box::new(ProspectiveSigner::new(accounts, filled, chain_id, reserved, password, post_sign)) + } } fn enrich(&self, signed_transaction: SignedTransaction) -> RpcRichRawTransaction { @@ -396,12 +415,24 @@ impl Dispatcher for LightDispatcher { })) } - fn sign(&self, accounts: Arc, filled: FilledTransactionRequest, password: SignWith) - -> BoxFuture> + fn sign

( + &self, + accounts: Arc, + filled: FilledTransactionRequest, + password: SignWith, + post_sign: P + ) -> BoxFuture + where + P: PostSign + 'static, + ::Future: Send { let chain_id = self.client.signing_chain_id(); let nonce = filled.nonce.expect("nonce is always provided; qed"); - Box::new(future::done(sign_transaction(&*accounts, filled, chain_id, nonce, password))) + + let future = sign_transaction(&*accounts, filled, chain_id, nonce, password) + .into_future() + .and_then(move |signed| post_sign.execute(signed)); + Box::new(future) } fn enrich(&self, signed_transaction: SignedTransaction) -> RpcRichRawTransaction { @@ -449,28 +480,60 @@ fn sign_transaction( #[derive(Debug, Clone, Copy)] enum ProspectiveSignerState { TryProspectiveSign, + WaitForPostSign, WaitForNonce, - Finish, } -struct ProspectiveSigner { +struct ProspectiveSigner { accounts: Arc, filled: FilledTransactionRequest, chain_id: Option, reserved: nonce::Reserved, password: SignWith, state: ProspectiveSignerState, - prospective: Option>>, + prospective: Option>, ready: Option, + post_sign: Option

, + post_sign_future: Option<::Future> } -impl ProspectiveSigner { +/// action to execute after signing +/// e.g importing a transaction into the chain +pub trait PostSign: Send { + /// item that this PostSign returns + type Item: Send; + /// incase you need to perform async PostSign actions + type Out: IntoFuture + Send; + /// perform an action with the signed transaction + fn execute(self, signer: WithToken) -> Self::Out; +} + +impl PostSign for () { + type Item = WithToken; + type Out = Result; + fn execute(self, signed: WithToken) -> Self::Out { + Ok(signed) + } +} + +impl PostSign for F + where F: FnOnce(WithToken) -> Result +{ + type Item = T; + type Out = Result; + fn execute(self, signed: WithToken) -> Self::Out { + (self)(signed) + } +} + +impl ProspectiveSigner

{ pub fn new( accounts: Arc, filled: FilledTransactionRequest, chain_id: Option, reserved: nonce::Reserved, password: SignWith, + post_sign: P ) -> Self { // If the account is permanently unlocked we can try to sign // using prospective nonce. This should speed up sending @@ -491,6 +554,8 @@ impl ProspectiveSigner { }, prospective: None, ready: None, + post_sign: Some(post_sign), + post_sign_future: None } } @@ -509,8 +574,8 @@ impl ProspectiveSigner { } } -impl Future for ProspectiveSigner { - type Item = WithToken; +impl Future for ProspectiveSigner

{ + type Item = P::Item; type Error = Error; fn poll(&mut self) -> Poll { @@ -523,32 +588,45 @@ impl Future for ProspectiveSigner { match self.poll_reserved()? { Async::NotReady => { self.state = WaitForNonce; - self.prospective = Some(self.sign(self.reserved.prospective_value())); + self.prospective = Some(self.sign(self.reserved.prospective_value())?); }, Async::Ready(nonce) => { - self.state = Finish; - self.prospective = Some(self.sign(nonce.value())); + self.state = WaitForPostSign; + self.post_sign_future = Some(self.post_sign.take() + .expect("post_sign is set on creation; qed") + .execute(self.sign(nonce.value())?) + .into_future()); self.ready = Some(nonce); }, } }, WaitForNonce => { let nonce = try_ready!(self.poll_reserved()); - let result = match (self.prospective.take(), nonce.matches_prospective()) { + let prospective = match (self.prospective.take(), nonce.matches_prospective()) { (Some(prospective), true) => prospective, - _ => self.sign(nonce.value()), + _ => self.sign(nonce.value())?, }; - self.state = Finish; - self.prospective = Some(result); self.ready = Some(nonce); + self.state = WaitForPostSign; + self.post_sign_future = Some(self.post_sign.take() + .expect("post_sign is set on creation; qed") + .execute(prospective) + .into_future()); }, - Finish => { - if let (Some(result), Some(nonce)) = (self.prospective.take(), self.ready.take()) { - // Mark nonce as used on successful signing - return result.map(move |tx| { - nonce.mark_used(); - Async::Ready(tx) - }) + WaitForPostSign => { + if let Some(mut fut) = self.post_sign_future.as_mut() { + match fut.poll()? { + Async::Ready(item) => { + let nonce = self.ready + .take() + .expect("nonce is set before state transitions to WaitForPostSign; qed"); + nonce.mark_used(); + return Ok(Async::Ready(item)) + }, + Async::NotReady => { + return Ok(Async::NotReady) + } + } } else { panic!("Poll after ready."); } @@ -655,19 +733,21 @@ pub fn execute( match payload { ConfirmationPayload::SendTransaction(request) => { let condition = request.condition.clone().map(Into::into); - Box::new(dispatcher.sign(accounts, request, pass) - .map(move |v| v.map(move |tx| PendingTransaction::new(tx, condition))) - .map(WithToken::into_tuple) - .map(|(tx, token)| (tx, token, dispatcher)) - .and_then(|(tx, tok, dispatcher)| { - dispatcher.dispatch_transaction(tx) - .map(RpcH256::from) - .map(ConfirmationResponse::SendTransaction) - .map(move |h| WithToken::from((h, tok))) - })) + let cloned_dispatcher = dispatcher.clone(); + let post_sign = move |with_token_signed: WithToken| { + let (signed, token) = with_token_signed.into_tuple(); + let signed_transaction = PendingTransaction::new(signed, condition); + cloned_dispatcher.dispatch_transaction(signed_transaction) + .map(|hash| (hash, token)) + }; + let future = dispatcher.sign(accounts, request, pass, post_sign) + .map(|(hash, token)| { + WithToken::from((ConfirmationResponse::SendTransaction(hash.into()), token)) + }); + Box::new(future) }, ConfirmationPayload::SignTransaction(request) => { - Box::new(dispatcher.sign(accounts, request, pass) + Box::new(dispatcher.sign(accounts, request, pass, ()) .map(move |result| result .map(move |tx| dispatcher.enrich(tx)) .map(ConfirmationResponse::SignTransaction) diff --git a/rpc/src/v1/impls/personal.rs b/rpc/src/v1/impls/personal.rs index abaebc3d08..ae22077e42 100644 --- a/rpc/src/v1/impls/personal.rs +++ b/rpc/src/v1/impls/personal.rs @@ -18,7 +18,7 @@ use std::sync::Arc; use std::time::Duration; -use bytes::{Bytes, ToPretty}; +use bytes::Bytes; use ethcore::account_provider::AccountProvider; use types::transaction::PendingTransaction; use ethereum_types::{H520, U128, Address}; @@ -27,7 +27,7 @@ use ethkey::{public_to_address, recover, Signature}; use jsonrpc_core::{BoxFuture, Result}; use jsonrpc_core::futures::{future, Future}; use v1::helpers::{errors, eip191}; -use v1::helpers::dispatch::{self, eth_data_hash, Dispatcher, SignWith}; +use v1::helpers::dispatch::{self, eth_data_hash, Dispatcher, SignWith, PostSign, WithToken}; use v1::traits::Personal; use v1::types::{ H160 as RpcH160, H256 as RpcH256, H520 as RpcH520, U128 as RpcU128, @@ -41,6 +41,7 @@ use v1::types::{ use v1::metadata::Metadata; use eip_712::{EIP712, hash_structured_data}; use jsonrpc_core::types::Value; +use transaction::SignedTransaction; /// Account management (personal) rpc implementation. pub struct PersonalClient { @@ -68,7 +69,16 @@ impl PersonalClient { } impl PersonalClient { - fn do_sign_transaction(&self, _meta: Metadata, request: TransactionRequest, password: String) -> BoxFuture<(PendingTransaction, D)> { + fn do_sign_transaction

( + &self, + _meta: Metadata, + request: TransactionRequest, + password: String, + post_sign: P + ) -> BoxFuture + where P: PostSign + 'static, + ::Future: Send + { let dispatcher = self.dispatcher.clone(); let accounts = self.accounts.clone(); @@ -86,11 +96,7 @@ impl PersonalClient { Box::new(dispatcher.fill_optional_fields(request.into(), default, false) .and_then(move |filled| { - let condition = filled.condition.clone().map(Into::into); - dispatcher.sign(accounts, filled, SignWith::Password(password.into())) - .map(|tx| tx.into_value()) - .map(move |tx| PendingTransaction::new(tx, condition)) - .map(move |tx| (tx, dispatcher)) + dispatcher.sign(accounts, filled, SignWith::Password(password.into()), post_sign) }) ) } @@ -223,18 +229,26 @@ impl Personal for PersonalClient { } fn sign_transaction(&self, meta: Metadata, request: TransactionRequest, password: String) -> BoxFuture { - Box::new(self.do_sign_transaction(meta, request, password) - .map(|(pending_tx, dispatcher)| dispatcher.enrich(pending_tx.transaction))) + let condition = request.condition.clone().map(Into::into); + let dispatcher = self.dispatcher.clone(); + Box::new(self.do_sign_transaction(meta, request, password, ()) + .map(move |tx| PendingTransaction::new(tx.into_value(), condition)) + .map(move |pending_tx| dispatcher.enrich(pending_tx.transaction))) } fn send_transaction(&self, meta: Metadata, request: TransactionRequest, password: String) -> BoxFuture { - Box::new(self.do_sign_transaction(meta, request, password) - .and_then(|(pending_tx, dispatcher)| { - let chain_id = pending_tx.chain_id(); - trace!(target: "miner", "send_transaction: dispatching tx: {} for chain ID {:?}", - ::rlp::encode(&*pending_tx).pretty(), chain_id); - - dispatcher.dispatch_transaction(pending_tx).map(Into::into) + let condition = request.condition.clone().map(Into::into); + let dispatcher = self.dispatcher.clone(); + Box::new(self.do_sign_transaction(meta, request, password, move |signed: WithToken| { + dispatcher.dispatch_transaction( + PendingTransaction::new( + signed.into_value(), + condition + ) + ) + }) + .and_then(|hash| { + Ok(RpcH256::from(hash)) }) ) } From 4b11d79829d028e091b19af077767051574cd837 Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Tue, 22 Jan 2019 09:51:40 +0100 Subject: [PATCH 030/168] fix(ManageNetwork): replace Range with RangeInclusive (#10209) * fix(ManageNetwork): replace Range -> RangeIncls Fixes `TODO: Range should be changed to RangeInclusive once stable (https://github.com/rust-lang/rust/pull/50758)` * fix(tests) * fix(grumbles): off-by-one error in debug_asserts * RangeInclusive::end() is inclusive which means that if start and end is equal the `debug_assert(range.end() > range.start()` will fail which is shouldn't --- ethcore/sync/src/api.rs | 16 +++++++--------- parity/informant.rs | 4 ++-- rpc/src/v1/impls/parity.rs | 4 ++-- rpc/src/v1/tests/mocked/manage_network.rs | 4 ++-- util/network-devp2p/src/service.rs | 10 +++------- 5 files changed, 16 insertions(+), 22 deletions(-) diff --git a/ethcore/sync/src/api.rs b/ethcore/sync/src/api.rs index 253f7fe838..28565db396 100644 --- a/ethcore/sync/src/api.rs +++ b/ethcore/sync/src/api.rs @@ -17,7 +17,7 @@ use std::sync::{Arc, mpsc, atomic}; use std::collections::{HashMap, BTreeMap}; use std::io; -use std::ops::Range; +use std::ops::RangeInclusive; use std::time::Duration; use bytes::Bytes; use devp2p::NetworkService; @@ -615,9 +615,7 @@ pub trait ManageNetwork : Send + Sync { /// Stop network fn stop_network(&self); /// Returns the minimum and maximum peers. - /// Note that `range.end` is *exclusive*. - // TODO: Range should be changed to RangeInclusive once stable (https://github.com/rust-lang/rust/pull/50758) - fn num_peers_range(&self) -> Range; + fn num_peers_range(&self) -> RangeInclusive; /// Get network context for protocol. fn with_proto_context(&self, proto: ProtocolId, f: &mut FnMut(&NetworkContext)); } @@ -656,7 +654,7 @@ impl ManageNetwork for EthSync { self.stop(); } - fn num_peers_range(&self) -> Range { + fn num_peers_range(&self) -> RangeInclusive { self.network.num_peers_range() } @@ -935,7 +933,7 @@ impl ManageNetwork for LightSync { self.network.stop(); } - fn num_peers_range(&self) -> Range { + fn num_peers_range(&self) -> RangeInclusive { self.network.num_peers_range() } @@ -948,12 +946,12 @@ impl LightSyncProvider for LightSync { fn peer_numbers(&self) -> PeerNumbers { let (connected, active) = self.proto.peer_count(); let peers_range = self.num_peers_range(); - debug_assert!(peers_range.end > peers_range.start); + debug_assert!(peers_range.end() >= peers_range.start()); PeerNumbers { connected: connected, active: active, - max: peers_range.end as usize - 1, - min: peers_range.start as usize, + max: *peers_range.end() as usize, + min: *peers_range.start() as usize, } } diff --git a/parity/informant.rs b/parity/informant.rs index 0299f524f2..78d055686b 100644 --- a/parity/informant.rs +++ b/parity/informant.rs @@ -146,7 +146,7 @@ impl InformantData for FullNodeInformantData { (Some(sync), Some(net)) => { let status = sync.status(); let num_peers_range = net.num_peers_range(); - debug_assert!(num_peers_range.end > num_peers_range.start); + debug_assert!(num_peers_range.end() >= num_peers_range.start()); cache_sizes.insert("sync", status.mem_used); @@ -154,7 +154,7 @@ impl InformantData for FullNodeInformantData { last_imported_block_number: status.last_imported_block_number.unwrap_or(chain_info.best_block_number), last_imported_old_block_number: status.last_imported_old_block_number, num_peers: status.num_peers, - max_peers: status.current_max_peers(num_peers_range.start, num_peers_range.end - 1), + max_peers: status.current_max_peers(*num_peers_range.start(), *num_peers_range.end()), snapshot_sync: status.is_snapshot_syncing(), }) } diff --git a/rpc/src/v1/impls/parity.rs b/rpc/src/v1/impls/parity.rs index 39948ce1a8..46e93bc736 100644 --- a/rpc/src/v1/impls/parity.rs +++ b/rpc/src/v1/impls/parity.rs @@ -187,13 +187,13 @@ impl Parity for ParityClient where fn net_peers(&self) -> Result { let sync_status = self.sync.status(); let num_peers_range = self.net.num_peers_range(); - debug_assert!(num_peers_range.end > num_peers_range.start); + debug_assert!(num_peers_range.end() >= num_peers_range.start()); let peers = self.sync.peers().into_iter().map(Into::into).collect(); Ok(Peers { active: sync_status.num_active_peers, connected: sync_status.num_peers, - max: sync_status.current_max_peers(num_peers_range.start, num_peers_range.end - 1), + max: sync_status.current_max_peers(*num_peers_range.start(), *num_peers_range.end()), peers: peers }) } diff --git a/rpc/src/v1/tests/mocked/manage_network.rs b/rpc/src/v1/tests/mocked/manage_network.rs index 560ed89ff2..d327a8743c 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 Ethereum. If not, see . -use std::ops::Range; +use std::ops::RangeInclusive; use sync::ManageNetwork; use self::ethcore_network::{ProtocolId, NetworkContext}; @@ -30,6 +30,6 @@ impl ManageNetwork for TestManageNetwork { fn add_reserved_peer(&self, _peer: String) -> Result<(), String> { Ok(()) } fn start_network(&self) {} fn stop_network(&self) {} - fn num_peers_range(&self) -> Range { 25 .. 51 } + fn num_peers_range(&self) -> RangeInclusive { 25..=50 } fn with_proto_context(&self, _: ProtocolId, _: &mut FnMut(&NetworkContext)) { } } diff --git a/util/network-devp2p/src/service.rs b/util/network-devp2p/src/service.rs index e57f01066a..dfacec4be3 100644 --- a/util/network-devp2p/src/service.rs +++ b/util/network-devp2p/src/service.rs @@ -20,7 +20,7 @@ use host::Host; use io::*; use parking_lot::RwLock; use std::net::SocketAddr; -use std::ops::Range; +use std::ops::RangeInclusive; use std::sync::Arc; use ansi_term::Colour; use network::ConnectionFilter; @@ -95,12 +95,8 @@ impl NetworkService { } /// Returns the number of peers allowed. - /// - /// Keep in mind that `range.end` is *exclusive*. - pub fn num_peers_range(&self) -> Range { - let start = self.config.min_peers; - let end = self.config.max_peers + 1; - start .. end + pub fn num_peers_range(&self) -> RangeInclusive { + self.config.min_peers..=self.config.max_peers } /// Returns external url if available. From c2de31e58682a179adbffb0bef4d6c2d07edade9 Mon Sep 17 00:00:00 2001 From: Elder Ryan Date: Wed, 23 Jan 2019 03:03:31 +0800 Subject: [PATCH 031/168] fixed: types::transaction::SignedTransaction; (#10229) --- rpc/src/v1/impls/personal.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpc/src/v1/impls/personal.rs b/rpc/src/v1/impls/personal.rs index ae22077e42..35a304df6f 100644 --- a/rpc/src/v1/impls/personal.rs +++ b/rpc/src/v1/impls/personal.rs @@ -21,6 +21,7 @@ use std::time::Duration; use bytes::Bytes; use ethcore::account_provider::AccountProvider; use types::transaction::PendingTransaction; +use types::transaction::SignedTransaction; use ethereum_types::{H520, U128, Address}; use ethkey::{public_to_address, recover, Signature}; @@ -41,7 +42,6 @@ use v1::types::{ use v1::metadata::Metadata; use eip_712::{EIP712, hash_structured_data}; use jsonrpc_core::types::Value; -use transaction::SignedTransaction; /// Account management (personal) rpc implementation. pub struct PersonalClient { From c96d8a742bf414e73dd04c7f3e8e1526f6c38c24 Mon Sep 17 00:00:00 2001 From: Sho Sawada Date: Wed, 23 Jan 2019 18:26:36 +0900 Subject: [PATCH 032/168] Update copyright year to 2019. (#10181) * Update copyright year to 2019. Have a great year. * add `(UK)` * 2018-2019 --- accounts/ethkey/README.md | 2 +- accounts/ethkey/cli/src/main.rs | 2 +- accounts/ethstore/README.md | 2 +- accounts/ethstore/cli/src/main.rs | 2 +- evmbin/README.md | 2 +- evmbin/src/main.rs | 2 +- parity-clib/Parity.java | 2 +- parity-clib/examples/java/Main.java | 2 +- parity-clib/parity.h | 2 +- util/rlp-compress/src/common.rs | 2 +- util/rlp-compress/src/lib.rs | 2 +- whisper/cli/src/main.rs | 2 +- 12 files changed, 12 insertions(+), 12 deletions(-) diff --git a/accounts/ethkey/README.md b/accounts/ethkey/README.md index 896d38e83f..6fc98b020d 100644 --- a/accounts/ethkey/README.md +++ b/accounts/ethkey/README.md @@ -6,7 +6,7 @@ Parity Ethereum keys generator. ``` Parity Ethereum keys generator. - Copyright 2015-2018 Parity Technologies (UK) Ltd. + Copyright 2015-2019 Parity Technologies (UK) Ltd. Usage: ethkey info [options] diff --git a/accounts/ethkey/cli/src/main.rs b/accounts/ethkey/cli/src/main.rs index ecb612e069..759f5f484c 100644 --- a/accounts/ethkey/cli/src/main.rs +++ b/accounts/ethkey/cli/src/main.rs @@ -35,7 +35,7 @@ use rustc_hex::{FromHex, FromHexError}; const USAGE: &'static str = r#" Parity Ethereum keys generator. - Copyright 2015-2018 Parity Technologies (UK) Ltd. + Copyright 2015-2019 Parity Technologies (UK) Ltd. Usage: ethkey info [options] diff --git a/accounts/ethstore/README.md b/accounts/ethstore/README.md index fc988c2d31..77c37bd246 100644 --- a/accounts/ethstore/README.md +++ b/accounts/ethstore/README.md @@ -6,7 +6,7 @@ Parity Ethereum key management. ``` Parity Ethereum key management tool. - Copyright 2015-2018 Parity Technologies (UK) Ltd. + Copyright 2015-2019 Parity Technologies (UK) Ltd. Usage: ethstore insert [--dir DIR] [--vault VAULT] [--vault-pwd VAULTPWD] diff --git a/accounts/ethstore/cli/src/main.rs b/accounts/ethstore/cli/src/main.rs index 6ee1914a00..0f56440639 100644 --- a/accounts/ethstore/cli/src/main.rs +++ b/accounts/ethstore/cli/src/main.rs @@ -41,7 +41,7 @@ mod crack; pub const USAGE: &'static str = r#" Parity Ethereum key management tool. - Copyright 2015-2018 Parity Technologies (UK) Ltd. + Copyright 2015-2019 Parity Technologies (UK) Ltd. Usage: ethstore insert [--dir DIR] [--vault VAULT] [--vault-pwd VAULTPWD] diff --git a/evmbin/README.md b/evmbin/README.md index 696a84436f..e0a8c9d966 100644 --- a/evmbin/README.md +++ b/evmbin/README.md @@ -6,7 +6,7 @@ EVM implementation for Parity. ``` EVM implementation for Parity. - Copyright 2015-2018 Parity Technologies (UK) Ltd. + Copyright 2015-2019 Parity Technologies (UK) Ltd. Usage: parity-evm state-test [--json --std-json --std-dump-json --only NAME --chain CHAIN --std-out-only --std-err-only] diff --git a/evmbin/src/main.rs b/evmbin/src/main.rs index 91e38e2546..6e1260189e 100644 --- a/evmbin/src/main.rs +++ b/evmbin/src/main.rs @@ -59,7 +59,7 @@ use info::Informant; const USAGE: &'static str = r#" EVM implementation for Parity. - Copyright 2015-2018 Parity Technologies (UK) Ltd. + Copyright 2015-2019 Parity Technologies (UK) Ltd. Usage: parity-evm state-test [--json --std-json --std-dump-json --only NAME --chain CHAIN --std-out-only --std-err-only] diff --git a/parity-clib/Parity.java b/parity-clib/Parity.java index 37a6722b78..957439434b 100644 --- a/parity-clib/Parity.java +++ b/parity-clib/Parity.java @@ -1,4 +1,4 @@ -// Copyright 2018 Parity Technologies (UK) Ltd. +// Copyright 2018-2019 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/parity-clib/examples/java/Main.java b/parity-clib/examples/java/Main.java index 88189af1c5..b5f4905062 100644 --- a/parity-clib/examples/java/Main.java +++ b/parity-clib/examples/java/Main.java @@ -1,4 +1,4 @@ -// Copyright 2018 Parity Technologies (UK) Ltd. +// Copyright 2018-2019 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/parity-clib/parity.h b/parity-clib/parity.h index 71d6ca775d..b48277810f 100644 --- a/parity-clib/parity.h +++ b/parity-clib/parity.h @@ -1,4 +1,4 @@ -// Copyright 2018 Parity Technologies (UK) Ltd. +// Copyright 2018-2019 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify diff --git a/util/rlp-compress/src/common.rs b/util/rlp-compress/src/common.rs index 79f8a93c1f..81767955b6 100644 --- a/util/rlp-compress/src/common.rs +++ b/util/rlp-compress/src/common.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2017 Parity Technologies +// Copyright 2015-2019 Parity Technologies (UK) Ltd. // // Licensed under the Apache License, Version 2.0 or the MIT license diff --git a/util/rlp-compress/src/lib.rs b/util/rlp-compress/src/lib.rs index 38dabcd86b..48620ed239 100644 --- a/util/rlp-compress/src/lib.rs +++ b/util/rlp-compress/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2018 Parity Technologies +// Copyright 2015-2019 Parity Technologies (UK) Ltd. // // Licensed under the Apache License, Version 2.0 or the MIT license diff --git a/whisper/cli/src/main.rs b/whisper/cli/src/main.rs index f671b4a248..9ef2304b47 100644 --- a/whisper/cli/src/main.rs +++ b/whisper/cli/src/main.rs @@ -49,7 +49,7 @@ use jsonrpc_http_server::{AccessControlAllowOrigin, DomainsValidation}; const POOL_UNIT: usize = 1024 * 1024; const USAGE: &'static str = r#" Parity Whisper-v2 CLI. - Copyright 2015-2018 Parity Technologies (UK) Ltd. + Copyright 2015-2019 Parity Technologies (UK) Ltd. Usage: whisper [options] From 4fec2f2fc26c0daf95f4d91cbbf55eeca74888fe Mon Sep 17 00:00:00 2001 From: folex <0xdxdy@gmail.com> Date: Wed, 23 Jan 2019 13:09:40 +0300 Subject: [PATCH 033/168] Fix typo: CHANGELOG-2.1 -> CHANGELOG-2.2 (#10233) --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 649f4c167c..4de53f34c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -156,7 +156,7 @@ The full list of included changes: ## Previous releases -- [CHANGELOG-2.1](docs/CHANGELOG-2.2.md) (_stable_) +- [CHANGELOG-2.2](docs/CHANGELOG-2.2.md) (_stable_) - [CHANGELOG-2.1](docs/CHANGELOG-2.1.md) (EOL: 2019-01-16) - [CHANGELOG-2.0](docs/CHANGELOG-2.0.md) (EOL: 2018-11-15) - [CHANGELOG-1.11](docs/CHANGELOG-1.11.md) (EOL: 2018-09-19) From 38f3747cde2e5dbf2cd4418a3e1069c03d479d7c Mon Sep 17 00:00:00 2001 From: Yucong Sun Date: Mon, 28 Jan 2019 01:54:07 -0800 Subject: [PATCH 034/168] Update CHANGELOG.md (#10249) change 2018 to 2019 --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4de53f34c7..62119ce7ab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -## Parity-Ethereum [v2.3.0](https://github.com/paritytech/parity-ethereum/releases/tag/v2.3.0) (2018-01-16) +## Parity-Ethereum [v2.3.0](https://github.com/paritytech/parity-ethereum/releases/tag/v2.3.0) (2019-01-16) Parity-Ethereum 2.3.0-beta is a consensus-relevant security release that reverts Constantinople on the Ethereum network. Upgrading is mandatory for Ethereum, and strongly recommended for other networks. From 94db961975d70e61d29a8528686974e8cb646e4d Mon Sep 17 00:00:00 2001 From: Vladyslav Lupashevskyi Date: Mon, 28 Jan 2019 11:58:34 +0200 Subject: [PATCH 035/168] Take in account zero gas price certification when doing transact_contract (#10232) * Tx permission contract improvement * Take in account zero gas price certification when doing transact_contract * DRY in ServiceTransactionChecker * Fix typos and regroup mod * Fix imports * Simplify code in struct instantiation Co-Authored-By: VladLupashevskyi --- ethcore/src/client/client.rs | 8 +++++++- miner/src/service_transaction_checker.rs | 18 ++++++++++-------- rpc/src/v1/impls/personal.rs | 4 ++-- 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index b8541470b2..577829d454 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -25,6 +25,7 @@ use blockchain::{BlockReceipts, BlockChain, BlockChainDB, BlockProvider, TreeRou use bytes::Bytes; use call_contract::{CallContract, RegistryInfo}; use ethcore_miner::pool::VerifiedTransaction; +use ethcore_miner::service_transaction_checker::ServiceTransactionChecker; use ethereum_types::{H256, Address, U256}; use evm::Schedule; use hash::keccak; @@ -2156,11 +2157,16 @@ impl BlockChainClient for Client { fn transact_contract(&self, address: Address, data: Bytes) -> Result<(), transaction::Error> { let authoring_params = self.importer.miner.authoring_params(); + let service_transaction_checker = ServiceTransactionChecker::default(); + let gas_price = match service_transaction_checker.check_address(self, authoring_params.author) { + Ok(true) => U256::zero(), + _ => self.importer.miner.sensible_gas_price(), + }; let transaction = transaction::Transaction { nonce: self.latest_nonce(&authoring_params.author), action: Action::Call(address), gas: self.importer.miner.sensible_gas_limit(), - gas_price: self.importer.miner.sensible_gas_price(), + gas_price, value: U256::zero(), data: data, }; diff --git a/miner/src/service_transaction_checker.rs b/miner/src/service_transaction_checker.rs index 17776f1569..c9b3b4b238 100644 --- a/miner/src/service_transaction_checker.rs +++ b/miner/src/service_transaction_checker.rs @@ -20,6 +20,7 @@ use call_contract::{CallContract, RegistryInfo}; use types::ids::BlockId; use types::transaction::SignedTransaction; use ethabi::FunctionOutputDecoder; +use ethereum_types::Address; use_contract!(service_transaction, "res/contracts/service_transaction.json"); @@ -30,23 +31,24 @@ const SERVICE_TRANSACTION_CONTRACT_REGISTRY_NAME: &'static str = "service_transa pub struct ServiceTransactionChecker; impl ServiceTransactionChecker { - /// Checks if given address is whitelisted to send service transactions. + /// Checks if given address in tx is whitelisted to send service transactions. pub fn check(&self, client: &C, tx: &SignedTransaction) -> Result { let sender = tx.sender(); - let hash = tx.hash(); - // Skip checking the contract if the transaction does not have zero gas price if !tx.gas_price.is_zero() { return Ok(false) } - let address = client.registry_address(SERVICE_TRANSACTION_CONTRACT_REGISTRY_NAME.to_owned(), BlockId::Latest) - .ok_or_else(|| "contract is not configured")?; - - trace!(target: "txqueue", "[{:?}] Checking service transaction checker contract from {}", hash, sender); + self.check_address(client, sender) + } + /// Checks if given address is whitelisted to send service transactions. + pub fn check_address(&self, client: &C, sender: Address) -> Result { + let contract_address = client.registry_address(SERVICE_TRANSACTION_CONTRACT_REGISTRY_NAME.to_owned(), BlockId::Latest) + .ok_or_else(|| "contract is not configured")?; + trace!(target: "txqueue", "Checking service transaction checker contract from {}", sender); let (data, decoder) = service_transaction::functions::certified::call(sender); - let value = client.call_contract(BlockId::Latest, address, data)?; + let value = client.call_contract(BlockId::Latest, contract_address, data)?; decoder.decode(&value).map_err(|e| e.to_string()) } } diff --git a/rpc/src/v1/impls/personal.rs b/rpc/src/v1/impls/personal.rs index 35a304df6f..3bae576c06 100644 --- a/rpc/src/v1/impls/personal.rs +++ b/rpc/src/v1/impls/personal.rs @@ -20,8 +20,8 @@ use std::time::Duration; use bytes::Bytes; use ethcore::account_provider::AccountProvider; -use types::transaction::PendingTransaction; -use types::transaction::SignedTransaction; + +use types::transaction::{PendingTransaction, SignedTransaction}; use ethereum_types::{H520, U128, Address}; use ethkey::{public_to_address, recover, Signature}; From 50f5ccc4f2800b11a2038b0ba6730e354f652ae3 Mon Sep 17 00:00:00 2001 From: Andrew Plaza Date: Mon, 28 Jan 2019 05:26:11 -0500 Subject: [PATCH 036/168] Allow specifying local accounts via CLI (#9960) * Allow specifying local accounts via CLI * Add `tx-queue-locals` CLI option * ethcore: modify miner to check options vec before importing transaction * modify tests (ethcore/parity) Resolves #9634 * fix formatting * fixes: Make prefer HashSet over Vec<>, add test, comment formatting * Update ethcore/src/miner/miner.rs Co-Authored-By: insipx * Fix comments and add helper for set->vec conversion * remove blank line from use statement * fix helper test * formatting * fix test to pass on nightly * revert test fix for nightly --- ethcore/src/miner/miner.rs | 44 +++++++++++++++++++++++++++++-- parity/cli/mod.rs | 10 +++++++ parity/cli/tests/config.full.toml | 1 + parity/configuration.rs | 4 ++- parity/helpers.rs | 20 +++++++++++++- 5 files changed, 75 insertions(+), 4 deletions(-) diff --git a/ethcore/src/miner/miner.rs b/ethcore/src/miner/miner.rs index 998ce62804..36239a4d60 100644 --- a/ethcore/src/miner/miner.rs +++ b/ethcore/src/miner/miner.rs @@ -140,6 +140,8 @@ pub struct MinerOptions { /// will be invalid if mined. pub infinite_pending_block: bool, + /// Prioritized Local Addresses + pub tx_queue_locals: HashSet

, /// Strategy to use for prioritizing transactions in the queue. pub tx_queue_strategy: PrioritizationStrategy, /// Simple senders penalization. @@ -167,6 +169,7 @@ impl Default for MinerOptions { work_queue_size: 20, enable_resubmission: true, infinite_pending_block: false, + tx_queue_locals: HashSet::new(), tx_queue_strategy: PrioritizationStrategy::GasPriceOnly, tx_queue_penalization: Penalization::Disabled, tx_queue_no_unfamiliar_locals: false, @@ -917,11 +920,13 @@ impl miner::MinerService for Miner { pending: PendingTransaction, trusted: bool ) -> Result<(), transaction::Error> { - // treat the tx as local if the option is enabled, or if we have the account + // treat the tx as local if the option is enabled, if we have the account, or if + // the account is specified as a Prioritized Local Addresses let sender = pending.sender(); let treat_as_local = trusted || !self.options.tx_queue_no_unfamiliar_locals - || self.accounts.as_ref().map(|accts| accts.has_account(sender)).unwrap_or(false); + || self.accounts.as_ref().map(|accts| accts.has_account(sender)).unwrap_or(false) + || self.options.tx_queue_locals.contains(&sender); if treat_as_local { self.import_own_transaction(chain, pending) @@ -1284,6 +1289,8 @@ impl miner::MinerService for Miner { #[cfg(test)] mod tests { + use std::iter::FromIterator; + use super::*; use ethkey::{Generator, Random}; use hash::keccak; @@ -1342,6 +1349,7 @@ mod tests { enable_resubmission: true, infinite_pending_block: false, tx_queue_penalization: Penalization::Disabled, + tx_queue_locals: HashSet::new(), tx_queue_strategy: PrioritizationStrategy::GasPriceOnly, tx_queue_no_unfamiliar_locals: false, refuse_service_transactions: false, @@ -1510,6 +1518,38 @@ mod tests { assert_eq!(miner.prepare_pending_block(&client), BlockPreparationStatus::NotPrepared); } + #[test] + fn should_prioritize_locals() { + let keypair = Random.generate().unwrap(); + let client = TestBlockChainClient::default(); + let account_provider = AccountProvider::transient_provider(); + account_provider.insert_account(keypair.secret().clone(), &"".into()) + .expect("can add accounts to the provider we just created"); + + let transaction = transaction(); + let miner = Miner::new( + MinerOptions { + tx_queue_no_unfamiliar_locals: true, // should work even with this enabled + tx_queue_locals: HashSet::from_iter(vec![transaction.sender()].into_iter()), + ..miner().options + }, + GasPricer::new_fixed(0u64.into()), + &Spec::new_test(), + Some(Arc::new(account_provider)), + ); + let best_block = 0; + + // Miner with sender as a known local address should prioritize transactions from that address + let res2 = miner.import_claimed_local_transaction(&client, PendingTransaction::new(transaction, None), false); + + // check to make sure the prioritized transaction is pending + assert_eq!(res2.unwrap(), ()); + assert_eq!(miner.pending_transactions(best_block).unwrap().len(), 1); + assert_eq!(miner.pending_receipts(best_block).unwrap().len(), 1); + assert_eq!(miner.ready_transactions(&client, 10, PendingOrdering::Priority).len(), 1); + assert_eq!(miner.prepare_pending_block(&client), BlockPreparationStatus::NotPrepared); + } + #[test] fn should_not_seal_unless_enabled() { let miner = miner(); diff --git a/parity/cli/mod.rs b/parity/cli/mod.rs index 9ed6ed957b..873b456ad1 100644 --- a/parity/cli/mod.rs +++ b/parity/cli/mod.rs @@ -18,6 +18,9 @@ mod usage; mod presets; +use std::collections::HashSet; +use super::helpers; + usage! { { // CLI subcommands @@ -769,6 +772,10 @@ usage! { "--tx-queue-per-sender=[LIMIT]", "Maximum number of transactions per sender in the queue. By default it's 1% of the entire queue, but not less than 16.", + ARG arg_tx_queue_locals: (Option) = None, or |c: &Config| helpers::join_set(c.mining.as_ref()?.tx_queue_locals.as_ref()), + "--tx-queue-locals=[ACCOUNTS]", + "Specify local accounts for which transactions are prioritized in the queue. ACCOUNTS is a comma-delimited list of addresses.", + ARG arg_tx_queue_strategy: (String) = "gas_price", or |c: &Config| c.mining.as_ref()?.tx_queue_strategy.clone(), "--tx-queue-strategy=[S]", "Prioritization strategy used to order transactions in the queue. S may be: gas_price - Prioritize txs with high gas price", @@ -1356,6 +1363,7 @@ struct Mining { tx_queue_size: Option, tx_queue_per_sender: Option, tx_queue_mem_limit: Option, + tx_queue_locals: Option>, tx_queue_strategy: Option, tx_queue_ban_count: Option, tx_queue_ban_time: Option, @@ -1799,6 +1807,7 @@ mod tests { arg_tx_queue_size: 8192usize, arg_tx_queue_per_sender: None, arg_tx_queue_mem_limit: 4u32, + arg_tx_queue_locals: Some("0xdeadbeefcafe0000000000000000000000000000".into()), arg_tx_queue_strategy: "gas_factor".into(), arg_tx_queue_ban_count: Some(1u16), arg_tx_queue_ban_time: Some(180u16), @@ -2072,6 +2081,7 @@ mod tests { tx_queue_size: Some(8192), tx_queue_per_sender: None, tx_queue_mem_limit: None, + tx_queue_locals: None, tx_queue_strategy: None, tx_queue_ban_count: None, tx_queue_ban_time: None, diff --git a/parity/cli/tests/config.full.toml b/parity/cli/tests/config.full.toml index 99603954c8..34dd39058b 100644 --- a/parity/cli/tests/config.full.toml +++ b/parity/cli/tests/config.full.toml @@ -129,6 +129,7 @@ price_update_period = "hourly" gas_floor_target = "8000000" gas_cap = "10000000" tx_queue_size = 8192 +tx_queue_locals = ["0xdeadbeefcafe0000000000000000000000000000"] tx_queue_strategy = "gas_factor" tx_queue_ban_count = 1 tx_queue_ban_time = 180 #s diff --git a/parity/configuration.rs b/parity/configuration.rs index 48207683eb..aaa554d6af 100644 --- a/parity/configuration.rs +++ b/parity/configuration.rs @@ -18,7 +18,8 @@ use std::time::Duration; use std::io::Read; use std::net::SocketAddr; use std::path::PathBuf; -use std::collections::BTreeMap; +use std::collections::{HashSet, BTreeMap}; +use std::iter::FromIterator; use std::cmp; use cli::{Args, ArgsError}; use hash::keccak; @@ -572,6 +573,7 @@ impl Configuration { infinite_pending_block: self.args.flag_infinite_pending_block, tx_queue_penalization: to_queue_penalization(self.args.arg_tx_time_limit)?, + tx_queue_locals: HashSet::from_iter(to_addresses(&self.args.arg_tx_queue_locals)?.into_iter()), tx_queue_strategy: to_queue_strategy(&self.args.arg_tx_queue_strategy)?, tx_queue_no_unfamiliar_locals: self.args.flag_tx_queue_no_unfamiliar_locals, refuse_service_transactions: self.args.flag_refuse_service_transactions, diff --git a/parity/helpers.rs b/parity/helpers.rs index 1d018f423b..bcdace48ca 100644 --- a/parity/helpers.rs +++ b/parity/helpers.rs @@ -18,6 +18,7 @@ use std::io; use std::io::{Write, BufReader, BufRead}; use std::time::Duration; use std::fs::File; +use std::collections::HashSet; use ethereum_types::{U256, clean_0x, Address}; use journaldb::Algorithm; use ethcore::client::{Mode, BlockId, VMType, DatabaseCompactionProfile, ClientConfig, VerifierType}; @@ -134,6 +135,13 @@ pub fn to_price(s: &str) -> Result { s.parse::().map_err(|_| format!("Invalid transaciton price 's' given. Must be a decimal number.")) } +pub fn join_set(set: Option<&HashSet>) -> Option { + match set { + Some(s) => Some(s.iter().map(|s| s.as_str()).collect::>().join(",")), + None => None + } +} + /// Flush output buffer. pub fn flush_stdout() { io::stdout().flush().expect("stdout is flushable; qed"); @@ -327,12 +335,13 @@ mod tests { use std::time::Duration; use std::fs::File; use std::io::Write; + use std::collections::HashSet; use tempdir::TempDir; use ethereum_types::U256; use ethcore::client::{Mode, BlockId}; use ethcore::miner::PendingSet; use ethkey::Password; - use super::{to_duration, to_mode, to_block_id, to_u256, to_pending_set, to_address, to_addresses, to_price, geth_ipc_path, to_bootnodes, password_from_file}; + use super::{to_duration, to_mode, to_block_id, to_u256, to_pending_set, to_address, to_addresses, to_price, geth_ipc_path, to_bootnodes, join_set, password_from_file}; #[test] fn test_to_duration() { @@ -472,4 +481,13 @@ but the first password is trimmed assert_eq!(to_bootnodes(&Some(one_bootnode.into())), Ok(vec![one_bootnode.into()])); assert_eq!(to_bootnodes(&Some(two_bootnodes.into())), Ok(vec![one_bootnode.into(), one_bootnode.into()])); } + + #[test] + fn test_join_set() { + let mut test_set = HashSet::new(); + test_set.insert("0x1111111111111111111111111111111111111111".to_string()); + test_set.insert("0x0000000000000000000000000000000000000000".to_string()); + assert_eq!("0x1111111111111111111111111111111111111111,0x0000000000000000000000000000000000000000".to_string(), + join_set(Some(&test_set)).unwrap()); + } } From a139c6d2165e61a014fadf01790c6459279e0b8b Mon Sep 17 00:00:00 2001 From: cheme Date: Tue, 29 Jan 2019 09:26:22 +0100 Subject: [PATCH 037/168] Macos heapsize force jemalloc (#10234) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Switch to non prefixed malloc_size_of on macos * Fix * Testing darwin build * Fix import * conflict * switch heapsize deps commit * switch heapsize commit * Rename branch * Restore gitlab ci to origin * test for mac * mac tests? * Switch of macos CI tests. --- Cargo.lock | 62 +++++++++++++++++++++++++++++++++++++++--------------- Cargo.toml | 3 +++ 2 files changed, 48 insertions(+), 17 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d4f3f45210..e0249d76cd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -292,7 +292,7 @@ dependencies = [ "ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethjson 0.1.0", "ethkey 0.3.0", - "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "heapsize 0.4.2 (git+https://github.com/cheme/heapsize.git?branch=ec-macfix)", "keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-machine 0.1.0", @@ -583,7 +583,7 @@ name = "elastic-array" version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "heapsize 0.4.2 (git+https://github.com/cheme/heapsize.git?branch=ec-macfix)", ] [[package]] @@ -708,7 +708,7 @@ dependencies = [ "fake-hardware-wallet 0.0.1", "hardware-wallet 1.12.0", "hashdb 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "heapsize 0.4.2 (git+https://github.com/cheme/heapsize.git?branch=ec-macfix)", "itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", "journaldb 0.2.0", "keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -762,7 +762,7 @@ dependencies = [ "ethcore-db 0.1.0", "ethereum-types 0.4.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)", + "heapsize 0.4.2 (git+https://github.com/cheme/heapsize.git?branch=ec-macfix)", "itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -800,7 +800,7 @@ version = "0.1.0" dependencies = [ "common-types 0.1.0", "ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "heapsize 0.4.2 (git+https://github.com/cheme/heapsize.git?branch=ec-macfix)", "kvdb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "rlp 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -841,7 +841,7 @@ dependencies = [ "fastmap 0.1.0", "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", "hashdb 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "heapsize 0.4.2 (git+https://github.com/cheme/heapsize.git?branch=ec-macfix)", "itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hasher 0.1.1", @@ -898,7 +898,7 @@ dependencies = [ "ethkey 0.3.0", "fetch 0.1.0", "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "heapsize 0.4.2 (git+https://github.com/cheme/heapsize.git?branch=ec-macfix)", "hyper 0.12.11 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "linked-hash-map 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -984,7 +984,7 @@ dependencies = [ "ethkey 0.3.0", "fetch 0.1.0", "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "heapsize 0.4.2 (git+https://github.com/cheme/heapsize.git?branch=ec-macfix)", "keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1095,7 +1095,7 @@ dependencies = [ "ethstore 0.2.1", "fastmap 0.1.0", "hashdb 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "heapsize 0.4.2 (git+https://github.com/cheme/heapsize.git?branch=ec-macfix)", "keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hasher 0.1.1", "kvdb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1228,7 +1228,7 @@ dependencies = [ "bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "criterion 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", "ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "heapsize 0.4.2 (git+https://github.com/cheme/heapsize.git?branch=ec-macfix)", "keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1348,7 +1348,7 @@ name = "fixed-hash" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "heapsize 0.4.2 (git+https://github.com/cheme/heapsize.git?branch=ec-macfix)", "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1375,6 +1375,11 @@ dependencies = [ "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "fs_extra" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "fuchsia-zircon" version = "0.3.3" @@ -1505,8 +1510,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "heapsize" version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" +source = "git+https://github.com/cheme/heapsize.git?branch=ec-macfix#421df390a930cb523a09e5528e6fe57b534b3b26" dependencies = [ + "jemallocator 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1721,6 +1727,25 @@ name = "itoa" version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "jemalloc-sys" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", + "fs_extra 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "jemallocator" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "jemalloc-sys 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "jni" version = "0.10.2" @@ -1747,7 +1772,7 @@ dependencies = [ "ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "fastmap 0.1.0", "hashdb 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "heapsize 0.4.2 (git+https://github.com/cheme/heapsize.git?branch=ec-macfix)", "keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hasher 0.1.1", "kvdb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2074,7 +2099,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "memory-cache" version = "0.1.0" dependencies = [ - "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "heapsize 0.4.2 (git+https://github.com/cheme/heapsize.git?branch=ec-macfix)", "lru-cache 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2089,7 +2114,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "hashdb 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "heapsize 0.4.2 (git+https://github.com/cheme/heapsize.git?branch=ec-macfix)", "plain_hasher 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "rlp 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -4039,7 +4064,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "heapsize 0.4.2 (git+https://github.com/cheme/heapsize.git?branch=ec-macfix)", "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -4460,6 +4485,7 @@ dependencies = [ "checksum fixedbitset 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "86d4de0081402f5e88cdac65c8dcdcc73118c1a7a465e2a05f0da05843a8ea33" "checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3" "checksum fs-swap 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "921d332c89b3b61a826de38c61ee5b6e02c56806cade1b0e5d81bd71f57a71bb" +"checksum fs_extra 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5f2a4a2034423744d2cc7ca2068453168dcdb82c438419e639a26bd87839c674" "checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" "checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" "checksum futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)" = "49e7653e374fe0d0c12de4250f0bdb60680b8c80eed558c5c7538eec9c89e21b" @@ -4473,7 +4499,7 @@ dependencies = [ "checksum hamming 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "65043da274378d68241eb9a8f8f8aa54e349136f7b8e12f63e3ef44043cc30e1" "checksum handlebars 0.32.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d89ec99d1594f285d4590fc32bac5f75cdab383f1123d504d27862c644a807dd" "checksum hashdb 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d91261ee336dd046ac7df28306cb297b7a7228bd1ae25e9a57f4ed5e0ab628c7" -"checksum heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1679e6ea370dee694f91f1dc469bf94cf8f52051d147aec3e1f9497c6fc22461" +"checksum heapsize 0.4.2 (git+https://github.com/cheme/heapsize.git?branch=ec-macfix)" = "" "checksum heck 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ea04fa3ead4e05e51a7c806fc07271fdbde4e246a6c6d1efd52e72230b771b82" "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)" = "" @@ -4496,6 +4522,8 @@ dependencies = [ "checksum itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)" = "f58856976b776fedd95533137617a02fb25719f40e7d9b01c7043cd65474f450" "checksum itertools-num 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "83ca7b70b838f2e34bc6c2f367a1ed1cfe34fb82464adecadd31cdcc7da882fc" "checksum itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1306f3464951f30e30d12373d31c79fbd52d236e5e896fd92f96ec7babbbe60b" +"checksum jemalloc-sys 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "bfc62c8e50e381768ce8ee0428ee53741929f7ebd73e4d83f669bcf7693e00ae" +"checksum jemallocator 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "9f0cd42ac65f758063fea55126b0148b1ce0a6354ff78e07a4d6806bc65c4ab3" "checksum jni 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1ecfa3b81afc64d9a6539c4eece96ac9a93c551c713a313800dade8e33d7b5c1" "checksum jni-sys 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" "checksum jsonrpc-core 9.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-2.2)" = "" diff --git a/Cargo.toml b/Cargo.toml index c5c73dc52f..8c73e65480 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -134,3 +134,6 @@ members = [ "parity-clib", "whisper/cli", ] + +[patch.crates-io] +heapsize = { git = "https://github.com/cheme/heapsize.git", branch = "ec-macfix" } From eb3d33ed6ff2a697e9c48eb025c044e6b872f468 Mon Sep 17 00:00:00 2001 From: Gabriel Majoulet Date: Tue, 29 Jan 2019 04:13:21 -0500 Subject: [PATCH 038/168] Update CHANGELOG-2.2.md (#10254) --- docs/CHANGELOG-2.2.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/CHANGELOG-2.2.md b/docs/CHANGELOG-2.2.md index f1e8e79020..b9fce50007 100644 --- a/docs/CHANGELOG-2.2.md +++ b/docs/CHANGELOG-2.2.md @@ -1,4 +1,4 @@ -## Parity-Ethereum [v2.2.7](https://github.com/paritytech/parity-ethereum/releases/tag/v2.2.7) (2018-01-15) +## Parity-Ethereum [v2.2.7](https://github.com/paritytech/parity-ethereum/releases/tag/v2.2.7) (2019-01-15) Parity-Ethereum 2.2.7-stable is a consensus-relevant security release that reverts Constantinople on the Ethereum network. Upgrading is mandatory for Ethereum, and strongly recommended for other networks. From 12c42bce9b2cb7cce4e0a3362ef6dfd494083adb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Wed, 30 Jan 2019 13:57:38 +0100 Subject: [PATCH 039/168] Fix join-set test to be deterministic. (#10263) --- parity/helpers.rs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/parity/helpers.rs b/parity/helpers.rs index bcdace48ca..b68d854d1a 100644 --- a/parity/helpers.rs +++ b/parity/helpers.rs @@ -487,7 +487,14 @@ but the first password is trimmed let mut test_set = HashSet::new(); test_set.insert("0x1111111111111111111111111111111111111111".to_string()); test_set.insert("0x0000000000000000000000000000000000000000".to_string()); - assert_eq!("0x1111111111111111111111111111111111111111,0x0000000000000000000000000000000000000000".to_string(), - join_set(Some(&test_set)).unwrap()); + + + let res = join_set(Some(&test_set)).unwrap(); + + assert!( + res == "0x1111111111111111111111111111111111111111,0x0000000000000000000000000000000000000000" + || + res == "0x0000000000000000000000000000000000000000,0x1111111111111111111111111111111111111111" + ); } } From 0f9b2218dacb0fbf7d3a68878efdc7e87e42ca70 Mon Sep 17 00:00:00 2001 From: Seun LanLege Date: Fri, 1 Feb 2019 19:31:02 +0100 Subject: [PATCH 040/168] prevent silent errors in daemon mode (#10007) * prevent silent errors in daemon mode * change author in Cargo.toml, add preamble to pipe.rs * set the uid and gid on daemon process, fix permission errors when writing to pid file * call setup_logger before daemonize to prevent crashing when attempting to create logfile * map_err for calls to splice and ioctl, fix spaces in Cargo.toml * split out daemonize to own repo * removed util/daemonize * renamed dep to parity-daemonize * fix(parity-clib): enable `logger` * bump parity-daemonize * remove obsolete comment Co-Authored-By: seunlanlege * fix(grumbles): docs and log in ParityParams * Add FIXME comment regarding @tomaka grumbles * Unify logger with the C-API in ParityParams (less type-safety with more from_raw() conversions) * Add better documentation in the `parity.h` * Apply suggestions from code review Co-Authored-By: seunlanlege * docs(parity lib): add link to logging issue * fix(parity-clib): JNI enable `logger` * fix(parity-clib): update `Java example` * Update example to the API changes * Remove needless printouts which can be controlled via logger instead --- Cargo.lock | 24 +++++++++------- Cargo.toml | 6 +++- parity-clib/Parity.java | 6 ++-- parity-clib/examples/cpp/main.cpp | 9 ++++-- parity-clib/examples/java/Main.java | 10 ++----- parity-clib/parity.h | 30 ++++++++++++++++++++ parity-clib/src/java.rs | 18 ++++++++++-- parity-clib/src/lib.rs | 23 ++++++++++++++- parity/configuration.rs | 3 +- parity/lib.rs | 33 ++++++++++++++-------- parity/logger/src/lib.rs | 2 +- parity/main.rs | 43 +++++++++++++++++++++++++++-- parity/run.rs | 25 ----------------- 13 files changed, 162 insertions(+), 70 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e0249d76cd..6f24f667f0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -503,14 +503,6 @@ dependencies = [ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "daemonize" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "difference" version = "1.0.0" @@ -2419,6 +2411,18 @@ dependencies = [ "tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "parity-daemonize" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "parity-ethereum" version = "2.4.0" @@ -2430,7 +2434,6 @@ dependencies = [ "cli-signer 1.4.0", "common-types 0.1.0", "ctrlc 1.1.1 (git+https://github.com/paritytech/rust-ctrlc.git)", - "daemonize 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "dir 0.1.2", "docopt 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore 1.12.0", @@ -2465,6 +2468,7 @@ dependencies = [ "number_prefix 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "panic_hook 0.1.0", "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-daemonize 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "parity-hash-fetch 1.12.0", "parity-ipfs-api 1.12.0", "parity-local-store 0.1.0", @@ -4460,7 +4464,6 @@ dependencies = [ "checksum csv-core 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4dd8e6d86f7ba48b4276ef1317edc8cc36167546d8972feb4a2b5fec0b374105" "checksum ct-logs 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "95a4bf5107667e12bf6ce31a3a5066d67acc88942b6742117a41198734aaccaa" "checksum ctrlc 1.1.1 (git+https://github.com/paritytech/rust-ctrlc.git)" = "" -"checksum daemonize 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4093d27eb267d617f03c2ee25d4c3ca525b89a76154001954a11984508ffbde5" "checksum difference 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b3304d19798a8e067e48d8e69b2c37f0b5e9b4e462504ad9e27e9f3fce02bba8" "checksum digest 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "03b072242a8cbaf9c145665af9d250c59af3b958f83ed6824e13533cf76d5b90" "checksum docopt 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "db2906c2579b5b7207fc1e328796a9a8835dc44e22dbe8e460b1d636f9a7b225" @@ -4588,6 +4591,7 @@ dependencies = [ "checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37" "checksum parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fa5168b4cf41f3835e4bc6ffb32f51bc9365dc50cb351904595b3931d917fd0c" "checksum parity-crypto 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8adf489acb31f1922db0ce43803b6f48a425241a8473611be3cc625a8e4a4c47" +"checksum parity-daemonize 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c6dbaae957a3ddd307fe0ea0361251ceb651a19810b60d404080b258384da292" "checksum parity-path 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5962540f99d3895d9addf535f37ab1397886bc2c68e59efd040ef458e5f8c3f7" "checksum parity-rocksdb 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cd55d2d6d6000ec99f021cf52c9acc7d2a402e14f95ced4c5de230696fabe00b" "checksum parity-rocksdb-sys 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "5bbb241262c768522f6460f0e2672dee185c8504d4d0a5a5bab45c1147981c4f" diff --git a/Cargo.toml b/Cargo.toml index 8c73e65480..6123b55d31 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -84,7 +84,7 @@ fake-fetch = { path = "util/fake-fetch" } winapi = { version = "0.3.4", features = ["winsock2", "winuser", "shellapi"] } [target.'cfg(not(windows))'.dependencies] -daemonize = "0.3" +parity-daemonize = "0.1.1" [features] miner-debug = ["ethcore/miner-debug"] @@ -133,6 +133,10 @@ members = [ "evmbin", "parity-clib", "whisper/cli", + "util/triehash-ethereum", + "util/keccak-hasher", + "util/patricia-trie-ethereum", + "util/fastmap" ] [patch.crates-io] diff --git a/parity-clib/Parity.java b/parity-clib/Parity.java index 957439434b..3885cfb1e6 100644 --- a/parity-clib/Parity.java +++ b/parity-clib/Parity.java @@ -28,9 +28,9 @@ public class Parity { * * @param options The CLI options to start Parity with */ - public Parity(String[] options) { + public Parity(String[] options, String loggerMode, String loggerFile) { long config = configFromCli(options); - inner = build(config); + inner = build(config, loggerMode, loggerFile); } /** Performs an asynchronous RPC query by spawning a background thread that is executed until @@ -76,7 +76,7 @@ public void unsubscribeWebSocket(long session) { } private static native long configFromCli(String[] cliOptions); - private static native long build(long config); + private static native long build(long config, String loggerMode, String loggerFile); private static native void destroy(long inner); private static native void rpcQueryNative(long inner, String rpc, long timeoutMillis, Object callback); private static native long subscribeWebSocketNative(long inner, String rpc, Object callback); diff --git a/parity-clib/examples/cpp/main.cpp b/parity-clib/examples/cpp/main.cpp index d4603ceb7a..43b31d793f 100644 --- a/parity-clib/examples/cpp/main.cpp +++ b/parity-clib/examples/cpp/main.cpp @@ -53,10 +53,8 @@ const std::vector ws_subscriptions { void callback(void* user_data, const char* response, size_t _len) { Callback* cb = static_cast(user_data); if (cb->type == CALLBACK_RPC) { - printf("rpc response: %s\r\n", response); cb->counter -= 1; } else if (cb->type == CALLBACK_WS) { - printf("websocket response: %s\r\n", response); std::regex is_subscription ("\\{\"jsonrpc\":\"2.0\",\"result\":\"0[xX][a-fA-F0-9]{16}\",\"id\":1\\}"); if (std::regex_match(response, is_subscription) == true) { cb->counter -= 1; @@ -153,7 +151,8 @@ void* parity_run(std::vector args) { ParityParams cfg = { .configuration = nullptr, .on_client_restart_cb = callback, - .on_client_restart_cb_custom = nullptr + .on_client_restart_cb_custom = nullptr, + .logger = nullptr }; std::vector str_lens; @@ -173,6 +172,10 @@ void* parity_run(std::vector args) { } } + // enable logging but only the `rpc module` and don't write it to a file + char log_mode [] = "rpc=trace"; + parity_set_logger(log_mode, strlen(log_mode), nullptr, 0, &cfg.logger); + void *parity = nullptr; if (parity_start(&cfg, &parity) != 0) { return nullptr; diff --git a/parity-clib/examples/java/Main.java b/parity-clib/examples/java/Main.java index b5f4905062..c20b9e34d6 100644 --- a/parity-clib/examples/java/Main.java +++ b/parity-clib/examples/java/Main.java @@ -35,7 +35,9 @@ class Main { }; public static void runParity(String[] config) { - Parity parity = new Parity(config); + String loggerMode = "rpc=trace"; + String loggerFile = "foo.log"; + Parity parity = new Parity(config, loggerMode, loggerFile); Callback rpcCallback = new Callback(1); Callback webSocketCallback = new Callback(2); @@ -94,12 +96,6 @@ public Callback(int type) { } public void callback(Object response) { - response = (String) response; - if (callbackType == 1) { - System.out.println("rpc: " + response); - } else if (callbackType == 2) { - System.out.println("ws: " + response); - } counter.getAndIncrement(); } diff --git a/parity-clib/parity.h b/parity-clib/parity.h index b48277810f..7bba08e433 100644 --- a/parity-clib/parity.h +++ b/parity-clib/parity.h @@ -35,6 +35,9 @@ struct ParityParams { /// Custom parameter passed to the `on_client_restart_cb` callback as first parameter. void *on_client_restart_cb_custom; + + /// Logger object which must be created by the `parity_config_logger` function + void *logger; }; #ifdef __cplusplus @@ -63,6 +66,33 @@ extern "C" { /// int parity_config_from_cli(char const* const* args, size_t const* arg_lens, size_t len, void** out); +/// Builds a new logger object which should be a member of the `ParityParams struct` +/// +/// - log_mode : String representing the log mode according to `Rust LOG` or nullptr to disable logging. +/// See module documentation for `ethcore-logger` for more info. +/// - log_mode_len : Length of the log_mode or zero to disable logging +/// - log_file : String respresenting the file name to write to log to or nullptr to disable logging to a file +/// - log_mode_len : Length of the log_file or zero to disable logging to a file +/// - logger : Pointer to point to the created `Logger` object + +/// **Important**: This function must only be called exactly once otherwise it will panic. If you want to disable a +/// logging mode or logging to a file make sure that you pass the `length` as zero +/// +/// # Example +/// +/// ```no_run +/// void* cfg; +/// const char *args[] = {"--light", "--can-restart"}; +/// size_t str_lens[] = {7, 13}; +/// if (parity_config_from_cli(args, str_lens, 2, &cfg) != 0) { +/// return 1; +/// } +/// char[] logger_mode = "rpc=trace"; +/// parity_set_logger(logger_mode, strlen(logger_mode), nullptr, 0, &cfg.logger); +/// ``` +/// +int parity_set_logger(const char* log_mode, size_t log_mode_len, const char* log_file, size_t log_file_len, void** logger); + /// Destroys a configuration object created earlier. /// /// **Important**: You probably don't need to call this function. Calling `parity_start` destroys diff --git a/parity-clib/src/java.rs b/parity-clib/src/java.rs index 88f5444ea8..bb807083a4 100644 --- a/parity-clib/src/java.rs +++ b/parity-clib/src/java.rs @@ -20,7 +20,7 @@ use std::time::Duration; use std::thread; use std::os::raw::c_void; -use {parity_config_from_cli, parity_destroy, parity_start, parity_unsubscribe_ws, ParityParams, error}; +use {parity_config_from_cli, parity_destroy, parity_set_logger, parity_start, parity_unsubscribe_ws, ParityParams, error}; use futures::{Future, Stream}; use futures::sync::mpsc; @@ -96,12 +96,24 @@ pub unsafe extern "system" fn Java_io_parity_ethereum_Parity_configFromCli(env: } #[no_mangle] -pub unsafe extern "system" fn Java_io_parity_ethereum_Parity_build(env: JNIEnv, _: JClass, config: va_list) -> jlong { - let params = ParityParams { +pub unsafe extern "system" fn Java_io_parity_ethereum_Parity_build( + env: JNIEnv, + _: JClass, + config: va_list, + logger_mode: JString, + logger_file: JString +) -> jlong { + let mut params = ParityParams { configuration: config, .. mem::zeroed() }; + let logger_mode: String = env.get_string(logger_mode).expect("valid JString; qed").into(); + let logger_file: String = env.get_string(logger_file).expect("valid JString; qed").into(); + + parity_set_logger(logger_mode.as_ptr(), logger_mode.as_bytes().len(), logger_file.as_ptr(), + logger_file.as_bytes().len(), &mut params.logger); + let mut out = ptr::null_mut(); match parity_start(¶ms, &mut out) { 0 => out as jlong, diff --git a/parity-clib/src/lib.rs b/parity-clib/src/lib.rs index 3813037270..eca6edcd69 100644 --- a/parity-clib/src/lib.rs +++ b/parity-clib/src/lib.rs @@ -54,6 +54,7 @@ pub struct ParityParams { pub configuration: *mut c_void, pub on_client_restart_cb: Callback, pub on_client_restart_cb_custom: *mut c_void, + pub logger: *mut c_void } #[no_mangle] @@ -112,6 +113,7 @@ pub unsafe extern fn parity_start(cfg: *const ParityParams, output: *mut *mut c_ *output = ptr::null_mut(); let cfg: &ParityParams = &*cfg; + let logger = Arc::from_raw(cfg.logger as *mut parity_ethereum::RotatingLogger); let config = Box::from_raw(cfg.configuration as *mut parity_ethereum::Configuration); let on_client_restart_cb = { @@ -122,7 +124,7 @@ pub unsafe extern fn parity_start(cfg: *const ParityParams, output: *mut *mut c_ move |new_chain: String| { cb.call(new_chain.as_bytes()); } }; - let action = match parity_ethereum::start(*config, on_client_restart_cb, || {}) { + let action = match parity_ethereum::start(*config, logger, on_client_restart_cb, || {}) { Ok(action) => action, Err(_) => return 1, }; @@ -262,6 +264,25 @@ pub unsafe extern fn parity_set_panic_hook(callback: Callback, param: *mut c_voi }); } +#[no_mangle] +pub unsafe extern fn parity_set_logger( + logger_mode: *const u8, + logger_mode_len: usize, + log_file: *const u8, + log_file_len: usize, + logger: *mut *mut c_void) { + + let mut logger_cfg = parity_ethereum::LoggerConfig::default(); + logger_cfg.mode = String::from_utf8(slice::from_raw_parts(logger_mode, logger_mode_len).to_owned()).ok(); + + // Make sure an empty string is not constructed as file name (to prevent panic) + if log_file_len != 0 && !log_file.is_null() { + logger_cfg.file = String::from_utf8(slice::from_raw_parts(log_file, log_file_len).to_owned()).ok(); + } + + *logger = Arc::into_raw(parity_ethereum::setup_log(&logger_cfg).expect("Logger initialized only once; qed")) as *mut _; +} + // Internal structure for handling callbacks that get passed a string. struct CallbackStr { user_data: *mut c_void, diff --git a/parity/configuration.rs b/parity/configuration.rs index aaa554d6af..a32183a79e 100644 --- a/parity/configuration.rs +++ b/parity/configuration.rs @@ -473,7 +473,8 @@ impl Configuration { } } - fn logger_config(&self) -> LogConfig { + /// returns logger config + pub fn logger_config(&self) -> LogConfig { LogConfig { mode: self.args.arg_logging.clone(), color: !self.args.flag_no_color && !cfg!(windows), diff --git a/parity/lib.rs b/parity/lib.rs index b96995910c..c333c24186 100644 --- a/parity/lib.rs +++ b/parity/lib.rs @@ -111,19 +111,22 @@ mod user_defaults; mod whisper; mod db; -use std::io::BufReader; use std::fs::File; -use hash::keccak_buffer; +use std::io::BufReader; +use std::sync::Arc; + use cli::Args; use configuration::{Cmd, Execute}; use deprecated::find_deprecated; -use ethcore_logger::setup_log; +use hash::keccak_buffer; + #[cfg(feature = "memory_profiling")] use std::alloc::System; pub use self::configuration::Configuration; pub use self::run::RunningClient; pub use parity_rpc::PubSubSession; +pub use ethcore_logger::{Config as LoggerConfig, setup_log, RotatingLogger}; #[cfg(feature = "memory_profiling")] #[global_allocator] @@ -180,14 +183,13 @@ pub enum ExecutionAction { Running(RunningClient), } -fn execute(command: Execute, on_client_rq: Cr, on_updater_rq: Rr) -> Result +fn execute( + command: Execute, + logger: Arc, + on_client_rq: Cr, on_updater_rq: Rr) -> Result where Cr: Fn(String) + 'static + Send, Rr: Fn() + 'static + Send { - // TODO: move this to `main()` and expose in the C API so that users can setup logging the way - // they want - let logger = setup_log(&command.logger).expect("Logger is initialized only once; qed"); - #[cfg(feature = "deadlock_detection")] run_deadlock_detection_thread(); @@ -221,14 +223,21 @@ fn execute(command: Execute, on_client_rq: Cr, on_updater_rq: Rr) -> Res /// binary. /// /// On error, returns what to print on stderr. -pub fn start(conf: Configuration, on_client_rq: Cr, on_updater_rq: Rr) -> Result - where Cr: Fn(String) + 'static + Send, - Rr: Fn() + 'static + Send +// FIXME: totally independent logging capability, see https://github.com/paritytech/parity-ethereum/issues/10252 +pub fn start( + conf: Configuration, + logger: Arc, + on_client_rq: Cr, + on_updater_rq: Rr +) -> Result + where + Cr: Fn(String) + 'static + Send, + Rr: Fn() + 'static + Send { let deprecated = find_deprecated(&conf.args); for d in deprecated { println!("{}", d); } - execute(conf.into_command()?, on_client_rq, on_updater_rq) + execute(conf.into_command()?, logger, on_client_rq, on_updater_rq) } diff --git a/parity/logger/src/lib.rs b/parity/logger/src/lib.rs index da4a28bed1..a2e3de176a 100644 --- a/parity/logger/src/lib.rs +++ b/parity/logger/src/lib.rs @@ -94,7 +94,7 @@ pub fn setup_log(config: &Config) -> Result, String> { let maybe_file = match config.file.as_ref() { Some(f) => Some(open_options .append(true).create(true).open(f) - .map_err(|_| format!("Cannot write to log file given: {}", f))?), + .map_err(|e| format!("Cannot write to log file given: {}, {}", f, e))?), None => None, }; diff --git a/parity/main.rs b/parity/main.rs index fd94374140..5ad9de4d2d 100644 --- a/parity/main.rs +++ b/parity/main.rs @@ -26,8 +26,11 @@ extern crate log; extern crate panic_hook; extern crate parity_ethereum; extern crate parking_lot; +extern crate parity_daemonize; +extern crate ansi_term; #[cfg(windows)] extern crate winapi; +extern crate ethcore_logger; use std::ffi::OsString; use std::fs::{remove_file, metadata, File, create_dir_all}; @@ -36,12 +39,13 @@ use std::path::PathBuf; use std::sync::Arc; use std::sync::atomic::{AtomicBool, Ordering}; use std::{process, env}; - +use ansi_term::Colour; use ctrlc::CtrlC; use dir::default_hypervisor_path; use fdlimit::raise_fd_limit; use parity_ethereum::{start, ExecutionAction}; use parking_lot::{Condvar, Mutex}; +use ethcore_logger::setup_log; const PLEASE_RESTART_EXIT_CODE: i32 = 69; const PARITY_EXECUTABLE_NAME: &str = "parity"; @@ -184,11 +188,33 @@ fn main_direct(force_can_restart: bool) -> i32 { parity_ethereum::Configuration::parse_cli(&args).unwrap_or_else(|e| e.exit()) }; + let logger = setup_log(&conf.logger_config()).expect("Logger is initialized only once; qed"); + if let Some(spec_override) = take_spec_name_override() { conf.args.flag_testnet = false; conf.args.arg_chain = spec_override; } + let handle = if let Some(ref pid) = conf.args.arg_daemon_pid_file { + info!("{}", Colour::Blue.paint("starting in daemon mode").to_string()); + let _ = std::io::stdout().flush(); + + match parity_daemonize::daemonize(pid) { + Ok(h) => Some(h), + Err(e) => { + error!( + "{}", + Colour::Red.paint(format!("{}", e)) + ); + // flush before returning + let _ = std::io::stderr().flush(); + return 1; + } + } + } else { + None + }; + let can_restart = force_can_restart || conf.args.flag_can_restart; // increase max number of open files @@ -208,6 +234,7 @@ fn main_direct(force_can_restart: bool) -> i32 { let exec = if can_restart { start( conf, + logger, { let e = exit.clone(); let exiting = exiting.clone(); @@ -239,10 +266,9 @@ fn main_direct(force_can_restart: bool) -> i32 { } } ) - } else { trace!(target: "mode", "Not hypervised: not setting exit handlers."); - start(conf, move |_| {}, move || {}) + start(conf, logger, move |_| {}, move || {}) }; let res = match exec { @@ -283,6 +309,12 @@ fn main_direct(force_can_restart: bool) -> i32 { } }); + // so the client has started successfully + // if this is a daemon, detach from the parent process + if let Some(mut handle) = handle { + handle.detach() + } + // Wait for signal let mut lock = exit.0.lock(); if !lock.should_exit { @@ -306,6 +338,11 @@ fn main_direct(force_can_restart: bool) -> i32 { }, }, Err(err) => { + // error occured during start up + // if this is a daemon, detach from the parent process + if let Some(mut handle) = handle { + handle.detach_with_msg(format!("{}", Colour::Red.paint(&err))) + } writeln!(&mut stdio::stderr(), "{}", err).expect("StdErr available; qed"); 1 }, diff --git a/parity/run.rs b/parity/run.rs index 03dbe447f3..805a38c4ab 100644 --- a/parity/run.rs +++ b/parity/run.rs @@ -488,14 +488,6 @@ fn execute_impl(cmd: RunCmd, logger: Arc, on_client_rq: let passwords = passwords_from_files(&cmd.acc_conf.password_files)?; - // Run in daemon mode. - // Note, that it should be called before we leave any file descriptor open, - // since `daemonize` will close them. - if let Some(pid_file) = cmd.daemon { - info!("Running as a daemon process!"); - daemonize(pid_file)?; - } - // prepare account provider let account_provider = Arc::new(prepare_account_provider(&cmd.spec, &cmd.dirs, &spec.data_dir, cmd.acc_conf, &passwords)?); @@ -954,23 +946,6 @@ pub fn execute(cmd: RunCmd, logger: Arc, } } -#[cfg(not(windows))] -fn daemonize(pid_file: String) -> Result<(), String> { - extern crate daemonize; - - daemonize::Daemonize::new() - .pid_file(pid_file) - .chown_pid_file(true) - .start() - .map(|_| ()) - .map_err(|e| format!("Couldn't daemonize; {}", e)) -} - -#[cfg(windows)] -fn daemonize(_pid_file: String) -> Result<(), String> { - Err("daemon is no supported on windows".into()) -} - fn print_running_environment(data_dir: &str, dirs: &Directories, db_dirs: &DatabaseDirectories) { info!("Starting {}", Colour::White.bold().paint(version())); info!("Keys path {}", Colour::White.bold().paint(dirs.keys_path(data_dir).to_string_lossy().into_owned())); From 3b23c2e86d09a8a8b8cd99dfa02390177498e6b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Sun, 3 Feb 2019 12:26:25 +0100 Subject: [PATCH 041/168] Additional tests for uint deserialization. (#10279) --- rpc/src/v1/types/bytes.rs | 4 +++- rpc/src/v1/types/hash.rs | 2 +- rpc/src/v1/types/uint.rs | 4 +++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/rpc/src/v1/types/bytes.rs b/rpc/src/v1/types/bytes.rs index 12edd76bc8..837f3b5f9a 100644 --- a/rpc/src/v1/types/bytes.rs +++ b/rpc/src/v1/types/bytes.rs @@ -74,7 +74,7 @@ impl<'a> Visitor<'a> for BytesVisitor { } fn visit_str(self, value: &str) -> Result where E: Error { - if value.len() >= 2 && &value[0..2] == "0x" && value.len() & 1 == 0 { + if value.len() >= 2 && value.starts_with("0x") && value.len() & 1 == 0 { Ok(Bytes::new(FromHex::from_hex(&value[2..]).map_err(|e| Error::custom(format!("Invalid hex: {}", e)))?)) } else { Err(Error::custom("Invalid bytes format. Expected a 0x-prefixed hex string with even length")) @@ -101,6 +101,7 @@ mod tests { #[test] fn test_bytes_deserialize() { + let bytes0: Result = serde_json::from_str(r#""∀∂""#); let bytes1: Result = serde_json::from_str(r#""""#); let bytes2: Result = serde_json::from_str(r#""0x123""#); let bytes3: Result = serde_json::from_str(r#""0xgg""#); @@ -109,6 +110,7 @@ mod tests { let bytes5: Bytes = serde_json::from_str(r#""0x12""#).unwrap(); let bytes6: Bytes = serde_json::from_str(r#""0x0123""#).unwrap(); + assert!(bytes0.is_err()); assert!(bytes1.is_err()); assert!(bytes2.is_err()); assert!(bytes3.is_err()); diff --git a/rpc/src/v1/types/hash.rs b/rpc/src/v1/types/hash.rs index 9a51b06306..6cdaccf43b 100644 --- a/rpc/src/v1/types/hash.rs +++ b/rpc/src/v1/types/hash.rs @@ -129,7 +129,7 @@ macro_rules! impl_hash { fn visit_str(self, value: &str) -> Result where E: serde::de::Error { - if value.len() < 2 || &value[0..2] != "0x" { + if value.len() < 2 || !value.starts_with("0x") { return Err(E::custom("expected a hex-encoded hash with 0x prefix")); } if value.len() != 2 + $size * 2 { diff --git a/rpc/src/v1/types/uint.rs b/rpc/src/v1/types/uint.rs index 122cb2269a..3c5801c07c 100644 --- a/rpc/src/v1/types/uint.rs +++ b/rpc/src/v1/types/uint.rs @@ -72,7 +72,7 @@ macro_rules! impl_uint { } fn visit_str(self, value: &str) -> Result where E: serde::de::Error { - if value.len() < 2 || &value[0..2] != "0x" { + if value.len() < 2 || !value.starts_with("0x") { return Err(E::custom("expected a hex-encoded numbers with 0x prefix")) } @@ -140,12 +140,14 @@ mod tests { #[test] fn should_fail_to_deserialize_decimals() { + let deserialized0: Res = serde_json::from_str(r#""∀∂""#); let deserialized1: Res = serde_json::from_str(r#""""#); let deserialized2: Res = serde_json::from_str(r#""0""#); let deserialized3: Res = serde_json::from_str(r#""10""#); let deserialized4: Res = serde_json::from_str(r#""1000000""#); let deserialized5: Res = serde_json::from_str(r#""1000000000000000000""#); + assert!(deserialized0.is_err()); assert!(deserialized1.is_err()); assert!(deserialized2.is_err()); assert!(deserialized3.is_err()); From 12ac992ffb43167273da01920505414ade37a8eb Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Sun, 3 Feb 2019 13:23:07 +0100 Subject: [PATCH 042/168] Don't run the CPP example on CI (#10285) * Don't run the CPP example on CI * Add comment --- test.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test.sh b/test.sh index 1e38c2a23d..1b05194e47 100755 --- a/test.sh +++ b/test.sh @@ -57,8 +57,8 @@ cpp_test () { cd $DIR cmake .. make -j $THREADS - ./parity-example > example.logs - tail --lines 100 example.logs + # Note: we don't try to run the example because it tries to sync Kovan, and we don't want + # that to happen on CI cd - rm -rf $DIR ;; From 06cae8a53556dede67e163325657bee3fba8feda Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Sun, 3 Feb 2019 13:32:06 +0100 Subject: [PATCH 043/168] Fix Windows build (#10284) --- Cargo.toml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 6123b55d31..54b89b0f15 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -50,6 +50,7 @@ node-filter = { path = "ethcore/node-filter" } ethkey = { path = "accounts/ethkey" } rlp = { version = "0.3.0", features = ["ethereum"] } cli-signer= { path = "cli-signer" } +parity-daemonize = "0.1.1" parity-hash-fetch = { path = "updater/hash-fetch" } parity-ipfs-api = { path = "ipfs" } parity-local-store = { path = "miner/local-store" } @@ -83,9 +84,6 @@ fake-fetch = { path = "util/fake-fetch" } [target.'cfg(windows)'.dependencies] winapi = { version = "0.3.4", features = ["winsock2", "winuser", "shellapi"] } -[target.'cfg(not(windows))'.dependencies] -parity-daemonize = "0.1.1" - [features] miner-debug = ["ethcore/miner-debug"] json-tests = ["ethcore/json-tests"] From 89ae0f0ea0ddc467176f8f50d87b9c7a38e2533e Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Tue, 5 Feb 2019 13:31:19 +0000 Subject: [PATCH 044/168] Convert to jsonrpc-derive, use jsonrpc-* from crates.io (#10298) * Use jsonrpc crates on local path * Convert all RPC traits to use jsonrpc-derive * Use local jsonrpc at top level * Upgrade remaining jsonrpc dependencies * Checkout Cargo.lock to master HEAD * Use jsonrpc-* 10.0.1 from crates.io * Attribute after docs --- Cargo.lock | 186 ++++++------ Cargo.toml | 2 +- cli-signer/rpc-client/Cargo.toml | 4 +- ipfs/Cargo.toml | 4 +- miner/stratum/Cargo.toml | 5 +- miner/stratum/src/lib.rs | 4 +- rpc/Cargo.toml | 12 +- rpc/src/lib.rs | 3 +- rpc/src/v1/helpers/light_fetch.rs | 3 +- rpc/src/v1/helpers/subscribers.rs | 2 +- rpc/src/v1/impls/eth.rs | 17 +- rpc/src/v1/impls/eth_pubsub.rs | 8 +- rpc/src/v1/impls/light/eth.rs | 17 +- rpc/src/v1/impls/light/parity.rs | 13 +- rpc/src/v1/impls/light/trace.rs | 7 +- rpc/src/v1/impls/parity.rs | 13 +- rpc/src/v1/impls/pubsub.rs | 7 +- rpc/src/v1/impls/signer.rs | 5 +- rpc/src/v1/impls/traces.rs | 7 +- rpc/src/v1/traits/debug.rs | 14 +- rpc/src/v1/traits/eth.rs | 371 ++++++++++++----------- rpc/src/v1/traits/eth_pubsub.rs | 33 +- rpc/src/v1/traits/eth_signing.rs | 43 +-- rpc/src/v1/traits/net.rs | 28 +- rpc/src/v1/traits/parity.rs | 433 +++++++++++++-------------- rpc/src/v1/traits/parity_accounts.rs | 234 +++++++-------- rpc/src/v1/traits/parity_set.rs | 184 ++++++------ rpc/src/v1/traits/parity_signing.rs | 61 ++-- rpc/src/v1/traits/personal.rs | 79 ++--- rpc/src/v1/traits/private.rs | 35 +-- rpc/src/v1/traits/pubsub.rs | 35 +-- rpc/src/v1/traits/rpc.rs | 28 +- rpc/src/v1/traits/secretstore.rs | 70 ++--- rpc/src/v1/traits/signer.rs | 70 +++-- rpc/src/v1/traits/traces.rs | 66 ++-- rpc/src/v1/traits/web3.rs | 20 +- whisper/Cargo.toml | 6 +- whisper/cli/Cargo.toml | 6 +- whisper/src/lib.rs | 4 +- whisper/src/rpc/filter.rs | 2 +- whisper/src/rpc/mod.rs | 147 +++++---- 41 files changed, 1131 insertions(+), 1157 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6f24f667f0..3a16c22d9d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -637,7 +637,7 @@ dependencies = [ "heck 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.11 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1060,9 +1060,8 @@ version = "1.12.0" dependencies = [ "env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)", "ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core 9.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-2.2)", - "jsonrpc-macros 9.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-2.2)", - "jsonrpc-tcp-server 9.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-2.2)", + "jsonrpc-core 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-tcp-server 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1279,7 +1278,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.11 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)", "synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1778,8 +1777,8 @@ dependencies = [ [[package]] name = "jsonrpc-core" -version = "9.0.0" -source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-2.2#84360bf1d03821b8fd669a6a95fcdf847aaf6cca" +version = "10.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1788,14 +1787,24 @@ dependencies = [ "serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "jsonrpc-derive" +version = "10.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "jsonrpc-http-server" -version = "9.0.0" -source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-2.2#84360bf1d03821b8fd669a6a95fcdf847aaf6cca" +version = "10.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "hyper 0.12.11 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core 9.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-2.2)", - "jsonrpc-server-utils 9.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-2.2)", + "jsonrpc-core 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-server-utils 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "unicase 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1803,45 +1812,36 @@ dependencies = [ [[package]] name = "jsonrpc-ipc-server" -version = "9.0.0" -source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-2.2#84360bf1d03821b8fd669a6a95fcdf847aaf6cca" +version = "10.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "jsonrpc-core 9.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-2.2)", - "jsonrpc-server-utils 9.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-2.2)", + "jsonrpc-core 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-server-utils 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "parity-tokio-ipc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.7.0 (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 = "jsonrpc-macros" -version = "9.0.0" -source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-2.2#84360bf1d03821b8fd669a6a95fcdf847aaf6cca" -dependencies = [ - "jsonrpc-core 9.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-2.2)", - "jsonrpc-pubsub 9.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-2.2)", - "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "jsonrpc-pubsub" -version = "9.0.0" -source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-2.2#84360bf1d03821b8fd669a6a95fcdf847aaf6cca" +version = "10.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "jsonrpc-core 9.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-2.2)", + "jsonrpc-core 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "jsonrpc-server-utils" -version = "9.0.0" -source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-2.2#84360bf1d03821b8fd669a6a95fcdf847aaf6cca" +version = "10.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "globset 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core 9.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-2.2)", + "jsonrpc-core 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1852,28 +1852,28 @@ dependencies = [ [[package]] name = "jsonrpc-tcp-server" -version = "9.0.0" -source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-2.2#84360bf1d03821b8fd669a6a95fcdf847aaf6cca" +version = "10.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "jsonrpc-core 9.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-2.2)", - "jsonrpc-server-utils 9.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-2.2)", + "jsonrpc-core 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-server-utils 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.7.0 (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 = "jsonrpc-ws-server" -version = "9.0.0" -source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-2.2#84360bf1d03821b8fd669a6a95fcdf847aaf6cca" +version = "10.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core 9.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-2.2)", - "jsonrpc-server-utils 9.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-2.2)", + "jsonrpc-core 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-server-utils 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-ws 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "ws 0.7.9 (git+https://github.com/tomusdrw/ws-rs)", ] [[package]] @@ -2457,7 +2457,7 @@ dependencies = [ "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", "ipnetwork 0.12.8 (registry+https://github.com/rust-lang/crates.io-index)", "journaldb 0.2.0", - "jsonrpc-core 9.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-2.2)", + "jsonrpc-core 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb-rocksdb 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2527,8 +2527,8 @@ dependencies = [ "cid 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore 1.12.0", "ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core 9.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-2.2)", - "jsonrpc-http-server 9.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-2.2)", + "jsonrpc-core 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-http-server 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "multihash 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "rlp 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2612,12 +2612,12 @@ dependencies = [ "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", "hardware-wallet 1.12.0", "itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core 9.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-2.2)", - "jsonrpc-http-server 9.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-2.2)", - "jsonrpc-ipc-server 9.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-2.2)", - "jsonrpc-macros 9.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-2.2)", - "jsonrpc-pubsub 9.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-2.2)", - "jsonrpc-ws-server 9.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-2.2)", + "jsonrpc-core 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-derive 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-http-server 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-ipc-server 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-pubsub 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-ws-server 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb-memorydb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2653,8 +2653,8 @@ name = "parity-rpc-client" version = "1.4.0" dependencies = [ "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core 9.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-2.2)", - "jsonrpc-ws-server 9.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-2.2)", + "jsonrpc-core 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-ws-server 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2764,9 +2764,9 @@ dependencies = [ "ethereum-types 0.4.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)", - "jsonrpc-core 9.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-2.2)", - "jsonrpc-macros 9.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-2.2)", - "jsonrpc-pubsub 9.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-2.2)", + "jsonrpc-core 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-derive 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-pubsub 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "memzero 0.1.0", "ordered-float 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2792,6 +2792,23 @@ dependencies = [ "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "parity-ws" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "httparse 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", + "mio-extras 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "parking_lot" version = "0.6.4" @@ -3318,7 +3335,7 @@ dependencies = [ "proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", "rlp 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.11 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3452,7 +3469,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.11 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3592,7 +3609,7 @@ dependencies = [ [[package]] name = "syn" -version = "0.15.11" +version = "0.15.26" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3615,7 +3632,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.11 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -4181,7 +4198,7 @@ dependencies = [ "proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.11 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)", "validator 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -4306,9 +4323,9 @@ dependencies = [ "env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore-network 1.12.0", "ethcore-network-devp2p 1.12.0", - "jsonrpc-core 9.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-2.2)", - "jsonrpc-http-server 9.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-2.2)", - "jsonrpc-pubsub 9.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-2.2)", + "jsonrpc-core 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-http-server 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-pubsub 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "panic_hook 0.1.0", "parity-whisper 0.1.0", @@ -4362,23 +4379,6 @@ dependencies = [ "winapi-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "ws" -version = "0.7.9" -source = "git+https://github.com/tomusdrw/ws-rs#4baef2dc1abc8e216559af51cfc120bbcc777e21" -dependencies = [ - "byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", - "httparse 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", - "mio-extras 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "ws2_32-sys" version = "0.2.1" @@ -4529,14 +4529,14 @@ dependencies = [ "checksum jemallocator 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "9f0cd42ac65f758063fea55126b0148b1ce0a6354ff78e07a4d6806bc65c4ab3" "checksum jni 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1ecfa3b81afc64d9a6539c4eece96ac9a93c551c713a313800dade8e33d7b5c1" "checksum jni-sys 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" -"checksum jsonrpc-core 9.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-2.2)" = "" -"checksum jsonrpc-http-server 9.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-2.2)" = "" -"checksum jsonrpc-ipc-server 9.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-2.2)" = "" -"checksum jsonrpc-macros 9.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-2.2)" = "" -"checksum jsonrpc-pubsub 9.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-2.2)" = "" -"checksum jsonrpc-server-utils 9.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-2.2)" = "" -"checksum jsonrpc-tcp-server 9.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-2.2)" = "" -"checksum jsonrpc-ws-server 9.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-2.2)" = "" +"checksum jsonrpc-core 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a5152c3fda235dfd68341b3edf4121bc4428642c93acbd6de88c26bf95fc5d7" +"checksum jsonrpc-derive 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8de4e89cf0938dec51a14255556172b1f5208e4d8999d613813eceeae1405d37" +"checksum jsonrpc-http-server 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "99e1ce36c7cc9dcab398024d76849ab2cb917ee812653bce6f74fc9eb7c82d16" +"checksum jsonrpc-ipc-server 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fac6b8682243740a32bfb288880c71cc06eca29616cdf551e4136a190b11b96d" +"checksum jsonrpc-pubsub 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "56608ed54b1b2a69f4357cb8bdfbcbd99fe1179383c03a09bb428931bd35f592" +"checksum jsonrpc-server-utils 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5521613b31ea22d36d9f95ad642058dccec846a94ed8690957652d479f620707" +"checksum jsonrpc-tcp-server 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c873dac37a601fb88d40ba49eeac3f1aa60953c06b2e99ddbf0569b6f8028478" +"checksum jsonrpc-ws-server 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20b8333a5a6e6ccbcf5c90f90919de557cba4929efa164e9bd0e8e497eb20e46" "checksum keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "253bbe643c32c816bf58fa5a88248fafedeebb139705ad17a62add3517854a86" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" "checksum kvdb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "72ae89206cea31c32014b39d5a454b96135894221610dbfd19cf4d2d044fa546" @@ -4600,6 +4600,7 @@ dependencies = [ "checksum parity-tokio-ipc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "eb002c2d3539ccd3b82bd915ec060028d4ab350ad203dbffa20028c1e483af5b" "checksum parity-wasm 0.31.3 (registry+https://github.com/rust-lang/crates.io-index)" = "511379a8194230c2395d2f5fa627a5a7e108a9f976656ce723ae68fca4097bfc" "checksum parity-wordlist 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf13102febd98f4ad416a526b42deb82daf482626ba6ab10d0ebf8f45327514c" +"checksum parity-ws 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2fec5048fba72a2e01baeb0d08089db79aead4b57e2443df172fb1840075a233" "checksum parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f0802bff09003b291ba756dc7e79313e51cc31667e94afbe847def490424cde5" "checksum parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9723236a9525c757d9725b993511e3fc941e33f27751942232f0058298297edf" "checksum parking_lot_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad7f7e6ebdc79edff6fdcb87a55b620174f7a989e3eb31b65231f4af57f00b8c" @@ -4688,7 +4689,7 @@ dependencies = [ "checksum string 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00caf261d6f90f588f8450b8e1230fa0d5be49ee6140fdfbcb55335aff350970" "checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550" "checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" -"checksum syn 0.15.11 (registry+https://github.com/rust-lang/crates.io-index)" = "b036b7b35e846707c0e55c2c9441fa47867c0f87fca416921db3261b1d8c741a" +"checksum syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)" = "f92e629aa1d9c827b2bb8297046c1ccffc57c99b947a680d3ccff1f136a3bee9" "checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" "checksum synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "73687139bf99285483c96ac0add482c3776528beac1d97d444f6e91f203a2015" "checksum target_info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c63f48baada5c52e65a29eef93ab4f8982681b67f9e8d29c7b05abcfec2b9ffe" @@ -4768,7 +4769,6 @@ dependencies = [ "checksum winapi-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "afc5508759c5bf4285e61feb862b6083c8480aec864fa17a81fdec6f69b461ab" "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" "checksum wincolor 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "561ed901ae465d6185fa7864d63fbd5720d0ef718366c9a4dc83cf6170d7e9ba" -"checksum ws 0.7.9 (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.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3c1cb601d29fe2c2ac60a2b2e5e293994d87a1f6fa9687a31a15270f909be9c2" diff --git a/Cargo.toml b/Cargo.toml index 54b89b0f15..547a4af20a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,7 +29,7 @@ serde_derive = "1.0" futures = "0.1" fdlimit = "0.1" ctrlc = { git = "https://github.com/paritytech/rust-ctrlc.git" } -jsonrpc-core = { git = "https://github.com/paritytech/jsonrpc.git", branch = "parity-2.2" } +jsonrpc-core = "10.0.1" ethcore = { path = "ethcore", features = ["parity"] } parity-bytes = "0.1" common-types = { path = "ethcore/types" } diff --git a/cli-signer/rpc-client/Cargo.toml b/cli-signer/rpc-client/Cargo.toml index 0ffdae770a..e7eb354618 100644 --- a/cli-signer/rpc-client/Cargo.toml +++ b/cli-signer/rpc-client/Cargo.toml @@ -14,7 +14,7 @@ serde_json = "1.0" url = "1.2.0" matches = "0.1" parking_lot = "0.7" -jsonrpc-core = { git = "https://github.com/paritytech/jsonrpc.git", branch = "parity-2.2" } -jsonrpc-ws-server = { git = "https://github.com/paritytech/jsonrpc.git", branch = "parity-2.2" } +jsonrpc-core = "10.0.1" +jsonrpc-ws-server = "10.0.1" parity-rpc = { path = "../../rpc" } keccak-hash = "0.1" diff --git a/ipfs/Cargo.toml b/ipfs/Cargo.toml index 23ada21ea1..23dc8d6898 100644 --- a/ipfs/Cargo.toml +++ b/ipfs/Cargo.toml @@ -9,8 +9,8 @@ authors = ["Parity Technologies "] ethcore = { path = "../ethcore" } parity-bytes = "0.1" ethereum-types = "0.4" -jsonrpc-core = { git = "https://github.com/paritytech/jsonrpc.git", branch = "parity-2.2" } -jsonrpc-http-server = { git = "https://github.com/paritytech/jsonrpc.git", branch = "parity-2.2" } +jsonrpc-core = "10.0.1" +jsonrpc-http-server = "10.0.1" rlp = { version = "0.3.0", features = ["ethereum"] } cid = "0.3" multihash = "0.8" diff --git a/miner/stratum/Cargo.toml b/miner/stratum/Cargo.toml index 137604d53b..a7e13ef681 100644 --- a/miner/stratum/Cargo.toml +++ b/miner/stratum/Cargo.toml @@ -8,9 +8,8 @@ authors = ["Parity Technologies "] [dependencies] ethereum-types = "0.4" keccak-hash = "0.1" -jsonrpc-core = { git = "https://github.com/paritytech/jsonrpc.git", branch = "parity-2.2" } -jsonrpc-macros = { git = "https://github.com/paritytech/jsonrpc.git", branch = "parity-2.2" } -jsonrpc-tcp-server = { git = "https://github.com/paritytech/jsonrpc.git", branch = "parity-2.2" } +jsonrpc-core = "10.0.1" +jsonrpc-tcp-server = "10.0.1" log = "0.4" parking_lot = "0.7" diff --git a/miner/stratum/src/lib.rs b/miner/stratum/src/lib.rs index 5d2cb68a35..5ee0296dac 100644 --- a/miner/stratum/src/lib.rs +++ b/miner/stratum/src/lib.rs @@ -18,7 +18,6 @@ extern crate jsonrpc_tcp_server; extern crate jsonrpc_core; -extern crate jsonrpc_macros; extern crate ethereum_types; extern crate keccak_hash as hash; extern crate parking_lot; @@ -39,8 +38,7 @@ use jsonrpc_tcp_server::{ Server as JsonRpcServer, ServerBuilder as JsonRpcServerBuilder, RequestContext, MetaExtractor, Dispatcher, PushMessageError, }; -use jsonrpc_core::{MetaIoHandler, Params, to_value, Value, Metadata, Compatibility}; -use jsonrpc_macros::IoDelegate; +use jsonrpc_core::{MetaIoHandler, Params, to_value, Value, Metadata, Compatibility, IoDelegate}; use std::sync::Arc; use std::net::SocketAddr; diff --git a/rpc/Cargo.toml b/rpc/Cargo.toml index c3acc4664c..f64ead6b31 100644 --- a/rpc/Cargo.toml +++ b/rpc/Cargo.toml @@ -27,12 +27,12 @@ tokio-timer = "0.1" transient-hashmap = "0.4" itertools = "0.5" -jsonrpc-core = { git = "https://github.com/paritytech/jsonrpc.git", branch = "parity-2.2" } -jsonrpc-http-server = { git = "https://github.com/paritytech/jsonrpc.git", branch = "parity-2.2" } -jsonrpc-ws-server = { git = "https://github.com/paritytech/jsonrpc.git", branch = "parity-2.2" } -jsonrpc-ipc-server = { git = "https://github.com/paritytech/jsonrpc.git", branch = "parity-2.2" } -jsonrpc-macros = { git = "https://github.com/paritytech/jsonrpc.git", branch = "parity-2.2" } -jsonrpc-pubsub = { git = "https://github.com/paritytech/jsonrpc.git", branch = "parity-2.2" } +jsonrpc-core = "10.0.1" +jsonrpc-derive = "10.0.1" +jsonrpc-http-server = "10.0.1" +jsonrpc-ws-server = "10.0.1" +jsonrpc-ipc-server = "10.0.1" +jsonrpc-pubsub = "10.0.1" common-types = { path = "../ethcore/types" } ethash = { path = "../ethash" } diff --git a/rpc/src/lib.rs b/rpc/src/lib.rs index 2de2f0542c..3a98564512 100644 --- a/rpc/src/lib.rs +++ b/rpc/src/lib.rs @@ -37,6 +37,7 @@ extern crate tokio_timer; extern crate transient_hashmap; extern crate jsonrpc_core; +extern crate jsonrpc_derive; extern crate jsonrpc_http_server as http; extern crate jsonrpc_ipc_server as ipc; extern crate jsonrpc_pubsub; @@ -75,8 +76,6 @@ extern crate fake_hardware_wallet as hardware_wallet; #[macro_use] extern crate log; #[macro_use] -extern crate jsonrpc_macros; -#[macro_use] extern crate serde_derive; #[cfg(test)] diff --git a/rpc/src/v1/helpers/light_fetch.rs b/rpc/src/v1/helpers/light_fetch.rs index ba6e13b167..d026b5f0fe 100644 --- a/rpc/src/v1/helpers/light_fetch.rs +++ b/rpc/src/v1/helpers/light_fetch.rs @@ -29,7 +29,6 @@ use ethcore::executed::ExecutionError; use jsonrpc_core::{Result, Error}; use jsonrpc_core::futures::{future, Future}; use jsonrpc_core::futures::future::Either; -use jsonrpc_macros::Trailing; use light::cache::Cache; use light::client::LightChainClient; @@ -202,7 +201,7 @@ impl LightFetch { } /// Helper for getting proved execution. - pub fn proved_read_only_execution(&self, req: CallRequest, num: Trailing) -> impl Future + Send { + pub fn proved_read_only_execution(&self, req: CallRequest, num: Option) -> impl Future + Send { const DEFAULT_GAS_PRICE: u64 = 21_000; // (21000 G_transaction + 32000 G_create + some marginal to allow a few operations) const START_GAS: u64 = 60_000; diff --git a/rpc/src/v1/helpers/subscribers.rs b/rpc/src/v1/helpers/subscribers.rs index 80a6bfe8b1..5b48b67a22 100644 --- a/rpc/src/v1/helpers/subscribers.rs +++ b/rpc/src/v1/helpers/subscribers.rs @@ -18,7 +18,7 @@ use std::{ops, str}; use std::collections::HashMap; -use jsonrpc_macros::pubsub::{Subscriber, Sink, SubscriptionId}; +use jsonrpc_pubsub::{typed::{Subscriber, Sink}, SubscriptionId}; use rand::{Rng, StdRng}; use v1::types::H64; diff --git a/rpc/src/v1/impls/eth.rs b/rpc/src/v1/impls/eth.rs index bf39557d1a..15482645d7 100644 --- a/rpc/src/v1/impls/eth.rs +++ b/rpc/src/v1/impls/eth.rs @@ -39,7 +39,6 @@ use types::filter::Filter as EthcoreFilter; use jsonrpc_core::{BoxFuture, Result}; use jsonrpc_core::futures::future; -use jsonrpc_macros::Trailing; use v1::helpers::{self, errors, limit_logs, fake_sign}; use v1::helpers::dispatch::{FullDispatcher, default_gas_price}; @@ -568,7 +567,7 @@ impl Eth for EthClient< Ok(RpcU256::from(self.client.chain_info().best_block_number)) } - fn balance(&self, address: RpcH160, num: Trailing) -> BoxFuture { + fn balance(&self, address: RpcH160, num: Option) -> BoxFuture { let address = address.into(); let num = num.unwrap_or_default(); @@ -582,7 +581,7 @@ impl Eth for EthClient< Box::new(future::done(res)) } - fn proof(&self, address: RpcH160, values: Vec, num: Trailing) -> BoxFuture { + fn proof(&self, address: RpcH160, values: Vec, num: Option) -> BoxFuture { try_bf!(errors::require_experimental(self.options.allow_experimental_rpcs, "1186")); let a: H160 = address.clone().into(); @@ -625,7 +624,7 @@ impl Eth for EthClient< Box::new(future::done(res)) } - fn storage_at(&self, address: RpcH160, pos: RpcU256, num: Trailing) -> BoxFuture { + fn storage_at(&self, address: RpcH160, pos: RpcU256, num: Option) -> BoxFuture { let address: Address = RpcH160::into(address); let position: U256 = RpcU256::into(pos); @@ -640,7 +639,7 @@ impl Eth for EthClient< Box::new(future::done(res)) } - fn transaction_count(&self, address: RpcH160, num: Trailing) -> BoxFuture { + fn transaction_count(&self, address: RpcH160, num: Option) -> BoxFuture { let address: Address = RpcH160::into(address); let res = match num.unwrap_or_default() { @@ -723,7 +722,7 @@ impl Eth for EthClient< })) } - fn code_at(&self, address: RpcH160, num: Trailing) -> BoxFuture { + fn code_at(&self, address: RpcH160, num: Option) -> BoxFuture { let address: Address = RpcH160::into(address); let num = num.unwrap_or_default(); @@ -832,7 +831,7 @@ impl Eth for EthClient< base_logs(&*self.client, &*self.miner, filter.into()) } - fn work(&self, no_new_work_timeout: Trailing) -> Result { + fn work(&self, no_new_work_timeout: Option) -> Result { let no_new_work_timeout = no_new_work_timeout.unwrap_or_default(); // check if we're still syncing and return empty strings in that case @@ -918,7 +917,7 @@ impl Eth for EthClient< self.send_raw_transaction(raw) } - fn call(&self, request: CallRequest, num: Trailing) -> BoxFuture { + fn call(&self, request: CallRequest, num: Option) -> BoxFuture { let request = CallRequest::into(request); let signed = try_bf!(fake_sign::sign_call(request)); @@ -958,7 +957,7 @@ impl Eth for EthClient< )) } - fn estimate_gas(&self, request: CallRequest, num: Trailing) -> BoxFuture { + fn estimate_gas(&self, request: CallRequest, num: Option) -> BoxFuture { let request = CallRequest::into(request); let signed = try_bf!(fake_sign::sign_call(request)); let num = num.unwrap_or_default(); diff --git a/rpc/src/v1/impls/eth_pubsub.rs b/rpc/src/v1/impls/eth_pubsub.rs index 86340d73d4..4d452a4791 100644 --- a/rpc/src/v1/impls/eth_pubsub.rs +++ b/rpc/src/v1/impls/eth_pubsub.rs @@ -21,9 +21,7 @@ use std::collections::BTreeMap; use jsonrpc_core::{BoxFuture, Result, Error}; use jsonrpc_core::futures::{self, Future, IntoFuture}; -use jsonrpc_macros::Trailing; -use jsonrpc_macros::pubsub::{Sink, Subscriber}; -use jsonrpc_pubsub::SubscriptionId; +use jsonrpc_pubsub::{SubscriptionId, typed::{Sink, Subscriber}}; use v1::helpers::{errors, limit_logs, Subscribers}; use v1::helpers::light_fetch::LightFetch; @@ -262,7 +260,7 @@ impl EthPubSub for EthPubSubClient { _meta: Metadata, subscriber: Subscriber, kind: pubsub::Kind, - params: Trailing, + params: Option, ) { let error = match (kind, params.into()) { (pubsub::Kind::NewHeads, None) => { @@ -299,7 +297,7 @@ impl EthPubSub for EthPubSubClient { let _ = subscriber.reject(error); } - fn unsubscribe(&self, id: SubscriptionId) -> Result { + fn unsubscribe(&self, _: Option, id: SubscriptionId) -> Result { let res = self.heads_subscribers.write().remove(&id).is_some(); let res2 = self.logs_subscribers.write().remove(&id).is_some(); let res3 = self.transactions_subscribers.write().remove(&id).is_some(); diff --git a/rpc/src/v1/impls/light/eth.rs b/rpc/src/v1/impls/light/eth.rs index 87e87c3098..914b05f964 100644 --- a/rpc/src/v1/impls/light/eth.rs +++ b/rpc/src/v1/impls/light/eth.rs @@ -22,7 +22,6 @@ use std::sync::Arc; use jsonrpc_core::{Result, BoxFuture}; use jsonrpc_core::futures::{future, Future}; use jsonrpc_core::futures::future::Either; -use jsonrpc_macros::Trailing; use light::cache::Cache as LightDataCache; use light::client::LightChainClient; @@ -272,12 +271,12 @@ impl Eth for EthClient { Ok(self.client.chain_info().best_block_number.into()) } - fn balance(&self, address: RpcH160, num: Trailing) -> BoxFuture { + fn balance(&self, address: RpcH160, num: Option) -> BoxFuture { Box::new(self.fetcher().account(address.into(), num.unwrap_or_default().to_block_id()) .map(|acc| acc.map_or(0.into(), |a| a.balance).into())) } - fn storage_at(&self, _address: RpcH160, _key: RpcU256, _num: Trailing) -> BoxFuture { + fn storage_at(&self, _address: RpcH160, _key: RpcU256, _num: Option) -> BoxFuture { Box::new(future::err(errors::unimplemented(None))) } @@ -289,7 +288,7 @@ impl Eth for EthClient { Box::new(self.rich_block(num.to_block_id(), include_txs).map(Some)) } - fn transaction_count(&self, address: RpcH160, num: Trailing) -> BoxFuture { + fn transaction_count(&self, address: RpcH160, num: Option) -> BoxFuture { Box::new(self.fetcher().account(address.into(), num.unwrap_or_default().to_block_id()) .map(|acc| acc.map_or(0.into(), |a| a.nonce).into())) } @@ -358,7 +357,7 @@ impl Eth for EthClient { })) } - fn code_at(&self, address: RpcH160, num: Trailing) -> BoxFuture { + fn code_at(&self, address: RpcH160, num: Option) -> BoxFuture { Box::new(self.fetcher().code(address.into(), num.unwrap_or_default().to_block_id()).map(Into::into)) } @@ -385,7 +384,7 @@ impl Eth for EthClient { self.send_raw_transaction(raw) } - fn call(&self, req: CallRequest, num: Trailing) -> BoxFuture { + fn call(&self, req: CallRequest, num: Option) -> BoxFuture { Box::new(self.fetcher().proved_read_only_execution(req, num).and_then(|res| { match res { Ok(exec) => Ok(exec.output.into()), @@ -394,7 +393,7 @@ impl Eth for EthClient { })) } - fn estimate_gas(&self, req: CallRequest, num: Trailing) -> BoxFuture { + fn estimate_gas(&self, req: CallRequest, num: Option) -> BoxFuture { // TODO: binary chop for more accurate estimates. Box::new(self.fetcher().proved_read_only_execution(req, num).and_then(|res| { match res { @@ -475,7 +474,7 @@ impl Eth for EthClient { })) } - fn proof(&self, _address: RpcH160, _values:Vec, _num: Trailing) -> BoxFuture { + fn proof(&self, _address: RpcH160, _values:Vec, _num: Option) -> BoxFuture { Box::new(future::err(errors::unimplemented(None))) } @@ -505,7 +504,7 @@ impl Eth for EthClient { }).map(move |logs| limit_logs(logs, limit))) } - fn work(&self, _timeout: Trailing) -> Result { + fn work(&self, _timeout: Option) -> Result { Err(errors::light_unimplemented(None)) } diff --git a/rpc/src/v1/impls/light/parity.rs b/rpc/src/v1/impls/light/parity.rs index f179ab2367..8a19232c12 100644 --- a/rpc/src/v1/impls/light/parity.rs +++ b/rpc/src/v1/impls/light/parity.rs @@ -29,7 +29,6 @@ use ethcore_logger::RotatingLogger; use jsonrpc_core::{Result, BoxFuture}; use jsonrpc_core::futures::{future, Future}; -use jsonrpc_macros::Trailing; use v1::helpers::{self, errors, ipfs, SigningQueue, SignerService, NetworkSettings, verify_signature}; use v1::helpers::dispatch::LightDispatcher; use v1::helpers::light_fetch::{LightFetch, light_all_transactions}; @@ -232,11 +231,11 @@ impl Parity for ParityClient { Ok(Brain::new(phrase).generate().unwrap().address().into()) } - fn list_accounts(&self, _: u64, _: Option, _: Trailing) -> Result>> { + fn list_accounts(&self, _: u64, _: Option, _: Option) -> Result>> { Err(errors::light_unimplemented(None)) } - fn list_storage_keys(&self, _: H160, _: u64, _: Option, _: Trailing) -> Result>> { + fn list_storage_keys(&self, _: H160, _: u64, _: Option, _: Option) -> Result>> { Err(errors::light_unimplemented(None)) } @@ -246,7 +245,7 @@ impl Parity for ParityClient { .map(Into::into) } - fn pending_transactions(&self, limit: Trailing) -> Result> { + fn pending_transactions(&self, limit: Option) -> Result> { let txq = self.light_dispatch.transaction_queue.read(); let chain_info = self.light_dispatch.client.chain_info(); Ok( @@ -365,7 +364,7 @@ impl Parity for ParityClient { }) } - fn block_header(&self, number: Trailing) -> BoxFuture { + fn block_header(&self, number: Option) -> BoxFuture { use types::encoded; let engine = self.light_dispatch.client.engine().clone(); @@ -399,7 +398,7 @@ impl Parity for ParityClient { Box::new(self.fetcher().header(id).and_then(from_encoded)) } - fn block_receipts(&self, number: Trailing) -> BoxFuture> { + fn block_receipts(&self, number: Option) -> BoxFuture> { let id = number.unwrap_or_default().to_block_id(); Box::new(self.fetcher().receipts(id).and_then(|receipts| Ok(receipts.into_iter().map(Into::into).collect()))) } @@ -408,7 +407,7 @@ impl Parity for ParityClient { ipfs::cid(content) } - fn call(&self, _requests: Vec, _block: Trailing) -> Result> { + fn call(&self, _requests: Vec, _block: Option) -> Result> { Err(errors::light_unimplemented(None)) } diff --git a/rpc/src/v1/impls/light/trace.rs b/rpc/src/v1/impls/light/trace.rs index 092189b743..42f62e0c4f 100644 --- a/rpc/src/v1/impls/light/trace.rs +++ b/rpc/src/v1/impls/light/trace.rs @@ -17,7 +17,6 @@ //! Traces api implementation. use jsonrpc_core::Result; -use jsonrpc_macros::Trailing; use v1::Metadata; use v1::traits::Traces; use v1::helpers::errors; @@ -46,15 +45,15 @@ impl Traces for TracesClient { Err(errors::light_unimplemented(None)) } - fn call(&self, _request: CallRequest, _flags: TraceOptions, _block: Trailing) -> Result { + fn call(&self, _request: CallRequest, _flags: TraceOptions, _block: Option) -> Result { Err(errors::light_unimplemented(None)) } - fn call_many(&self, _request: Vec<(CallRequest, TraceOptions)>, _block: Trailing) -> Result> { + fn call_many(&self, _request: Vec<(CallRequest, TraceOptions)>, _block: Option) -> Result> { Err(errors::light_unimplemented(None)) } - fn raw_transaction(&self, _raw_transaction: Bytes, _flags: TraceOptions, _block: Trailing) -> Result { + fn raw_transaction(&self, _raw_transaction: Bytes, _flags: TraceOptions, _block: Option) -> Result { Err(errors::light_unimplemented(None)) } diff --git a/rpc/src/v1/impls/parity.rs b/rpc/src/v1/impls/parity.rs index 46e93bc736..60a7bd83d5 100644 --- a/rpc/src/v1/impls/parity.rs +++ b/rpc/src/v1/impls/parity.rs @@ -33,7 +33,6 @@ use ethkey::{crypto::ecies, Brain, Generator}; use ethstore::random_phrase; use jsonrpc_core::futures::future; use jsonrpc_core::{BoxFuture, Result}; -use jsonrpc_macros::Trailing; use sync::{SyncProvider, ManageNetwork}; use types::ids::BlockId; use updater::{Service as UpdateService}; @@ -252,7 +251,7 @@ impl Parity for ParityClient where Ok(Brain::new(phrase).generate().unwrap().address().into()) } - fn list_accounts(&self, count: u64, after: Option, block_number: Trailing) -> Result>> { + fn list_accounts(&self, count: u64, after: Option, block_number: Option) -> Result>> { let number = match block_number.unwrap_or_default() { BlockNumber::Pending => { warn!("BlockNumber::Pending is unsupported"); @@ -267,7 +266,7 @@ impl Parity for ParityClient where .map(|a| a.into_iter().map(Into::into).collect())) } - fn list_storage_keys(&self, address: H160, count: u64, after: Option, block_number: Trailing) -> Result>> { + fn list_storage_keys(&self, address: H160, count: u64, after: Option, block_number: Option) -> Result>> { let number = match block_number.unwrap_or_default() { BlockNumber::Pending => { warn!("BlockNumber::Pending is unsupported"); @@ -288,7 +287,7 @@ impl Parity for ParityClient where .map(Into::into) } - fn pending_transactions(&self, limit: Trailing) -> Result> { + fn pending_transactions(&self, limit: Option) -> Result> { let ready_transactions = self.miner.ready_transactions( &*self.client, limit.unwrap_or_else(usize::max_value), @@ -394,7 +393,7 @@ impl Parity for ParityClient where }) } - fn block_header(&self, number: Trailing) -> BoxFuture { + fn block_header(&self, number: Option) -> BoxFuture { const EXTRA_INFO_PROOF: &str = "Object exists in blockchain (fetched earlier), extra_info is always available if object exists; qed"; let number = number.unwrap_or_default(); @@ -424,7 +423,7 @@ impl Parity for ParityClient where })) } - fn block_receipts(&self, number: Trailing) -> BoxFuture> { + fn block_receipts(&self, number: Option) -> BoxFuture> { let number = number.unwrap_or_default(); let id = match number { @@ -449,7 +448,7 @@ impl Parity for ParityClient where ipfs::cid(content) } - fn call(&self, requests: Vec, num: Trailing) -> Result> { + fn call(&self, requests: Vec, num: Option) -> Result> { let requests = requests .into_iter() .map(|request| Ok(( diff --git a/rpc/src/v1/impls/pubsub.rs b/rpc/src/v1/impls/pubsub.rs index fb147768dd..9650fd2d07 100644 --- a/rpc/src/v1/impls/pubsub.rs +++ b/rpc/src/v1/impls/pubsub.rs @@ -22,8 +22,7 @@ use parking_lot::RwLock; use jsonrpc_core::{self as core, Result, MetaIoHandler}; use jsonrpc_core::futures::{future, Future, Stream, Sink}; -use jsonrpc_macros::Trailing; -use jsonrpc_macros::pubsub::Subscriber; +use jsonrpc_pubsub::typed::Subscriber; use jsonrpc_pubsub::SubscriptionId; use tokio_timer; @@ -81,7 +80,7 @@ impl PubSubClient { impl> PubSub for PubSubClient { type Metadata = Metadata; - fn parity_subscribe(&self, mut meta: Metadata, subscriber: Subscriber, method: String, params: Trailing) { + fn parity_subscribe(&self, mut meta: Metadata, subscriber: Subscriber, method: String, params: Option) { let params = params.unwrap_or(core::Params::Array(vec![])); // Make sure to get rid of PubSub session otherwise it will never be dropped. meta.session = None; @@ -100,7 +99,7 @@ impl> PubSub for PubSubClient { } } - fn parity_unsubscribe(&self, id: SubscriptionId) -> Result { + fn parity_unsubscribe(&self, _: Option, id: SubscriptionId) -> Result { let res = self.poll_manager.write().unsubscribe(&id); Ok(res) } diff --git a/rpc/src/v1/impls/signer.rs b/rpc/src/v1/impls/signer.rs index 8f83547ab2..64e91e09f2 100644 --- a/rpc/src/v1/impls/signer.rs +++ b/rpc/src/v1/impls/signer.rs @@ -28,8 +28,7 @@ use types::transaction::{SignedTransaction, PendingTransaction}; use jsonrpc_core::{Result, BoxFuture, Error}; use jsonrpc_core::futures::{future, Future, IntoFuture}; use jsonrpc_core::futures::future::Either; -use jsonrpc_pubsub::SubscriptionId; -use jsonrpc_macros::pubsub::{Sink, Subscriber}; +use jsonrpc_pubsub::{SubscriptionId, typed::{Sink, Subscriber}}; use v1::helpers::dispatch::{self, Dispatcher, WithToken, eth_data_hash}; use v1::helpers::{errors, SignerService, SigningQueue, ConfirmationPayload, FilledTransactionRequest, Subscribers}; use v1::metadata::Metadata; @@ -255,7 +254,7 @@ impl Signer for SignerClient { self.subscribers.lock().push(sub) } - fn unsubscribe_pending(&self, id: SubscriptionId) -> Result { + fn unsubscribe_pending(&self, _: Option, id: SubscriptionId) -> Result { let res = self.subscribers.lock().remove(&id).is_some(); Ok(res) } diff --git a/rpc/src/v1/impls/traces.rs b/rpc/src/v1/impls/traces.rs index 92bf045f4c..f2a5c83d4e 100644 --- a/rpc/src/v1/impls/traces.rs +++ b/rpc/src/v1/impls/traces.rs @@ -23,7 +23,6 @@ use rlp::Rlp; use types::transaction::SignedTransaction; use jsonrpc_core::Result; -use jsonrpc_macros::Trailing; use v1::Metadata; use v1::traits::Traces; use v1::helpers::{errors, fake_sign}; @@ -87,7 +86,7 @@ impl Traces for TracesClient where .map(LocalizedTrace::from)) } - fn call(&self, request: CallRequest, flags: TraceOptions, block: Trailing) -> Result { + fn call(&self, request: CallRequest, flags: TraceOptions, block: Option) -> Result { let block = block.unwrap_or_default(); let request = CallRequest::into(request); @@ -109,7 +108,7 @@ impl Traces for TracesClient where .map_err(errors::call) } - fn call_many(&self, requests: Vec<(CallRequest, TraceOptions)>, block: Trailing) -> Result> { + fn call_many(&self, requests: Vec<(CallRequest, TraceOptions)>, block: Option) -> Result> { let block = block.unwrap_or_default(); let requests = requests.into_iter() @@ -136,7 +135,7 @@ impl Traces for TracesClient where .map_err(errors::call) } - fn raw_transaction(&self, raw_transaction: Bytes, flags: TraceOptions, block: Trailing) -> Result { + fn raw_transaction(&self, raw_transaction: Bytes, flags: TraceOptions, block: Option) -> Result { let block = block.unwrap_or_default(); let tx = Rlp::new(&raw_transaction.into_vec()).as_val().map_err(|e| errors::invalid_params("Transaction is not valid RLP", e))?; diff --git a/rpc/src/v1/traits/debug.rs b/rpc/src/v1/traits/debug.rs index 3b490e6f2a..5d332d434a 100644 --- a/rpc/src/v1/traits/debug.rs +++ b/rpc/src/v1/traits/debug.rs @@ -17,14 +17,14 @@ //! Debug RPC interface. use jsonrpc_core::Result; +use jsonrpc_derive::rpc; use v1::types::RichBlock; -build_rpc_trait! { - /// Debug RPC interface. - pub trait Debug { - /// Returns recently seen bad blocks. - #[rpc(name = "debug_getBadBlocks")] - fn bad_blocks(&self) -> Result>; - } +/// Debug RPC interface. +#[rpc] +pub trait Debug { + /// Returns recently seen bad blocks. + #[rpc(name = "debug_getBadBlocks")] + fn bad_blocks(&self) -> Result>; } diff --git a/rpc/src/v1/traits/eth.rs b/rpc/src/v1/traits/eth.rs index cf5469773b..0f0dc48a59 100644 --- a/rpc/src/v1/traits/eth.rs +++ b/rpc/src/v1/traits/eth.rs @@ -16,203 +16,202 @@ //! Eth rpc interface. use jsonrpc_core::{Result, BoxFuture}; -use jsonrpc_macros::Trailing; +use jsonrpc_derive::rpc; use v1::types::{RichBlock, BlockNumber, Bytes, CallRequest, Filter, FilterChanges, Index, EthAccount}; use v1::types::{Log, Receipt, SyncStatus, Transaction, Work}; use v1::types::{H64, H160, H256, U256, U64}; -build_rpc_trait! { - /// Eth rpc interface. - pub trait Eth { - type Metadata; +/// Eth rpc interface. +#[rpc] +pub trait Eth { + /// RPC Metadata + type Metadata; - /// Returns protocol version encoded as a string (quotes are necessary). - #[rpc(name = "eth_protocolVersion")] - fn protocol_version(&self) -> Result; + /// Returns protocol version encoded as a string (quotes are necessary). + #[rpc(name = "eth_protocolVersion")] + fn protocol_version(&self) -> Result; - /// Returns an object with data about the sync status or false. (wtf?) - #[rpc(name = "eth_syncing")] - fn syncing(&self) -> Result; + /// Returns an object with data about the sync status or false. (wtf?) + #[rpc(name = "eth_syncing")] + fn syncing(&self) -> Result; - /// Returns the number of hashes per second that the node is mining with. - #[rpc(name = "eth_hashrate")] - fn hashrate(&self) -> Result; + /// Returns the number of hashes per second that the node is mining with. + #[rpc(name = "eth_hashrate")] + fn hashrate(&self) -> Result; - /// Returns block author. - #[rpc(name = "eth_coinbase")] - fn author(&self) -> Result; + /// Returns block author. + #[rpc(name = "eth_coinbase")] + fn author(&self) -> Result; - /// Returns true if client is actively mining new blocks. - #[rpc(name = "eth_mining")] - fn is_mining(&self) -> Result; + /// Returns true if client is actively mining new blocks. + #[rpc(name = "eth_mining")] + fn is_mining(&self) -> Result; - /// Returns the chain ID used for transaction signing at the - /// current best block. None is returned if not - /// available. - #[rpc(name = "eth_chainId")] - fn chain_id(&self) -> Result>; - - /// Returns current gas_price. - #[rpc(name = "eth_gasPrice")] - fn gas_price(&self) -> Result; - - /// Returns accounts list. - #[rpc(name = "eth_accounts")] - fn accounts(&self) -> Result>; - - /// Returns highest block number. - #[rpc(name = "eth_blockNumber")] - fn block_number(&self) -> Result; - - /// Returns balance of the given account. - #[rpc(name = "eth_getBalance")] - fn balance(&self, H160, Trailing) -> BoxFuture; - - /// Returns the account- and storage-values of the specified account including the Merkle-proof - #[rpc(name = "eth_getProof")] - fn proof(&self, H160, Vec, Trailing) -> BoxFuture; - - /// Returns content of the storage at given address. - #[rpc(name = "eth_getStorageAt")] - fn storage_at(&self, H160, U256, Trailing) -> BoxFuture; - - /// Returns block with given hash. - #[rpc(name = "eth_getBlockByHash")] - fn block_by_hash(&self, H256, bool) -> BoxFuture>; - - /// Returns block with given number. - #[rpc(name = "eth_getBlockByNumber")] - fn block_by_number(&self, BlockNumber, bool) -> BoxFuture>; - - /// Returns the number of transactions sent from given address at given time (block number). - #[rpc(name = "eth_getTransactionCount")] - fn transaction_count(&self, H160, Trailing) -> BoxFuture; - - /// Returns the number of transactions in a block with given hash. - #[rpc(name = "eth_getBlockTransactionCountByHash")] - fn block_transaction_count_by_hash(&self, H256) -> BoxFuture>; - - /// Returns the number of transactions in a block with given block number. - #[rpc(name = "eth_getBlockTransactionCountByNumber")] - fn block_transaction_count_by_number(&self, BlockNumber) -> BoxFuture>; - - /// Returns the number of uncles in a block with given hash. - #[rpc(name = "eth_getUncleCountByBlockHash")] - fn block_uncles_count_by_hash(&self, H256) -> BoxFuture>; - - /// Returns the number of uncles in a block with given block number. - #[rpc(name = "eth_getUncleCountByBlockNumber")] - fn block_uncles_count_by_number(&self, BlockNumber) -> BoxFuture>; - - /// Returns the code at given address at given time (block number). - #[rpc(name = "eth_getCode")] - fn code_at(&self, H160, Trailing) -> BoxFuture; - - /// Sends signed transaction, returning its hash. - #[rpc(name = "eth_sendRawTransaction")] - fn send_raw_transaction(&self, Bytes) -> Result; - - /// @alias of `eth_sendRawTransaction`. - #[rpc(name = "eth_submitTransaction")] - fn submit_transaction(&self, Bytes) -> Result; - - /// Call contract, returning the output data. - #[rpc(name = "eth_call")] - fn call(&self, CallRequest, Trailing) -> BoxFuture; - - /// Estimate gas needed for execution of given contract. - #[rpc(name = "eth_estimateGas")] - fn estimate_gas(&self, CallRequest, Trailing) -> BoxFuture; - - /// Get transaction by its hash. - #[rpc(name = "eth_getTransactionByHash")] - fn transaction_by_hash(&self, H256) -> BoxFuture>; - - /// Returns transaction at given block hash and index. - #[rpc(name = "eth_getTransactionByBlockHashAndIndex")] - fn transaction_by_block_hash_and_index(&self, H256, Index) -> BoxFuture>; - - /// Returns transaction by given block number and index. - #[rpc(name = "eth_getTransactionByBlockNumberAndIndex")] - fn transaction_by_block_number_and_index(&self, BlockNumber, Index) -> BoxFuture>; - - /// Returns transaction receipt by transaction hash. - #[rpc(name = "eth_getTransactionReceipt")] - fn transaction_receipt(&self, H256) -> BoxFuture>; - - /// Returns an uncles at given block and index. - #[rpc(name = "eth_getUncleByBlockHashAndIndex")] - fn uncle_by_block_hash_and_index(&self, H256, Index) -> BoxFuture>; - - /// Returns an uncles at given block and index. - #[rpc(name = "eth_getUncleByBlockNumberAndIndex")] - fn uncle_by_block_number_and_index(&self, BlockNumber, Index) -> BoxFuture>; - - /// Returns available compilers. - /// @deprecated - #[rpc(name = "eth_getCompilers")] - fn compilers(&self) -> Result>; - - /// Compiles lll code. - /// @deprecated - #[rpc(name = "eth_compileLLL")] - fn compile_lll(&self, String) -> Result; - - /// Compiles solidity. - /// @deprecated - #[rpc(name = "eth_compileSolidity")] - fn compile_solidity(&self, String) -> Result; - - /// Compiles serpent. - /// @deprecated - #[rpc(name = "eth_compileSerpent")] - fn compile_serpent(&self, String) -> Result; - - /// Returns logs matching given filter object. - #[rpc(name = "eth_getLogs")] - fn logs(&self, Filter) -> BoxFuture>; - - /// Returns the hash of the current block, the seedHash, and the boundary condition to be met. - #[rpc(name = "eth_getWork")] - fn work(&self, Trailing) -> Result; - - /// Used for submitting a proof-of-work solution. - #[rpc(name = "eth_submitWork")] - fn submit_work(&self, H64, H256, H256) -> Result; - - /// Used for submitting mining hashrate. - #[rpc(name = "eth_submitHashrate")] - fn submit_hashrate(&self, U256, H256) -> Result; - } + /// Returns the chain ID used for transaction signing at the + /// current best block. None is returned if not + /// available. + #[rpc(name = "eth_chainId")] + fn chain_id(&self) -> Result>; + + /// Returns current gas_price. + #[rpc(name = "eth_gasPrice")] + fn gas_price(&self) -> Result; + + /// Returns accounts list. + #[rpc(name = "eth_accounts")] + fn accounts(&self) -> Result>; + + /// Returns highest block number. + #[rpc(name = "eth_blockNumber")] + fn block_number(&self) -> Result; + + /// Returns balance of the given account. + #[rpc(name = "eth_getBalance")] + fn balance(&self, H160, Option) -> BoxFuture; + + /// Returns the account- and storage-values of the specified account including the Merkle-proof + #[rpc(name = "eth_getProof")] + fn proof(&self, H160, Vec, Option) -> BoxFuture; + + /// Returns content of the storage at given address. + #[rpc(name = "eth_getStorageAt")] + fn storage_at(&self, H160, U256, Option) -> BoxFuture; + + /// Returns block with given hash. + #[rpc(name = "eth_getBlockByHash")] + fn block_by_hash(&self, H256, bool) -> BoxFuture>; + + /// Returns block with given number. + #[rpc(name = "eth_getBlockByNumber")] + fn block_by_number(&self, BlockNumber, bool) -> BoxFuture>; + + /// Returns the number of transactions sent from given address at given time (block number). + #[rpc(name = "eth_getTransactionCount")] + fn transaction_count(&self, H160, Option) -> BoxFuture; + + /// Returns the number of transactions in a block with given hash. + #[rpc(name = "eth_getBlockTransactionCountByHash")] + fn block_transaction_count_by_hash(&self, H256) -> BoxFuture>; + + /// Returns the number of transactions in a block with given block number. + #[rpc(name = "eth_getBlockTransactionCountByNumber")] + fn block_transaction_count_by_number(&self, BlockNumber) -> BoxFuture>; + + /// Returns the number of uncles in a block with given hash. + #[rpc(name = "eth_getUncleCountByBlockHash")] + fn block_uncles_count_by_hash(&self, H256) -> BoxFuture>; + + /// Returns the number of uncles in a block with given block number. + #[rpc(name = "eth_getUncleCountByBlockNumber")] + fn block_uncles_count_by_number(&self, BlockNumber) -> BoxFuture>; + + /// Returns the code at given address at given time (block number). + #[rpc(name = "eth_getCode")] + fn code_at(&self, H160, Option) -> BoxFuture; + + /// Sends signed transaction, returning its hash. + #[rpc(name = "eth_sendRawTransaction")] + fn send_raw_transaction(&self, Bytes) -> Result; + + /// @alias of `eth_sendRawTransaction`. + #[rpc(name = "eth_submitTransaction")] + fn submit_transaction(&self, Bytes) -> Result; + + /// Call contract, returning the output data. + #[rpc(name = "eth_call")] + fn call(&self, CallRequest, Option) -> BoxFuture; + + /// Estimate gas needed for execution of given contract. + #[rpc(name = "eth_estimateGas")] + fn estimate_gas(&self, CallRequest, Option) -> BoxFuture; + + /// Get transaction by its hash. + #[rpc(name = "eth_getTransactionByHash")] + fn transaction_by_hash(&self, H256) -> BoxFuture>; + + /// Returns transaction at given block hash and index. + #[rpc(name = "eth_getTransactionByBlockHashAndIndex")] + fn transaction_by_block_hash_and_index(&self, H256, Index) -> BoxFuture>; + + /// Returns transaction by given block number and index. + #[rpc(name = "eth_getTransactionByBlockNumberAndIndex")] + fn transaction_by_block_number_and_index(&self, BlockNumber, Index) -> BoxFuture>; + + /// Returns transaction receipt by transaction hash. + #[rpc(name = "eth_getTransactionReceipt")] + fn transaction_receipt(&self, H256) -> BoxFuture>; + + /// Returns an uncles at given block and index. + #[rpc(name = "eth_getUncleByBlockHashAndIndex")] + fn uncle_by_block_hash_and_index(&self, H256, Index) -> BoxFuture>; + + /// Returns an uncles at given block and index. + #[rpc(name = "eth_getUncleByBlockNumberAndIndex")] + fn uncle_by_block_number_and_index(&self, BlockNumber, Index) -> BoxFuture>; + + /// Returns available compilers. + /// @deprecated + #[rpc(name = "eth_getCompilers")] + fn compilers(&self) -> Result>; + + /// Compiles lll code. + /// @deprecated + #[rpc(name = "eth_compileLLL")] + fn compile_lll(&self, String) -> Result; + + /// Compiles solidity. + /// @deprecated + #[rpc(name = "eth_compileSolidity")] + fn compile_solidity(&self, String) -> Result; + + /// Compiles serpent. + /// @deprecated + #[rpc(name = "eth_compileSerpent")] + fn compile_serpent(&self, String) -> Result; + + /// Returns logs matching given filter object. + #[rpc(name = "eth_getLogs")] + fn logs(&self, Filter) -> BoxFuture>; + + /// Returns the hash of the current block, the seedHash, and the boundary condition to be met. + #[rpc(name = "eth_getWork")] + fn work(&self, Option) -> Result; + + /// Used for submitting a proof-of-work solution. + #[rpc(name = "eth_submitWork")] + fn submit_work(&self, H64, H256, H256) -> Result; + + /// Used for submitting mining hashrate. + #[rpc(name = "eth_submitHashrate")] + fn submit_hashrate(&self, U256, H256) -> Result; } -build_rpc_trait! { - /// Eth filters rpc api (polling). - // TODO: do filters api properly - pub trait EthFilter { - /// Returns id of new filter. - #[rpc(name = "eth_newFilter")] - fn new_filter(&self, Filter) -> Result; - - /// Returns id of new block filter. - #[rpc(name = "eth_newBlockFilter")] - fn new_block_filter(&self) -> Result; - - /// Returns id of new block filter. - #[rpc(name = "eth_newPendingTransactionFilter")] - fn new_pending_transaction_filter(&self) -> Result; - - /// Returns filter changes since last poll. - #[rpc(name = "eth_getFilterChanges")] - fn filter_changes(&self, Index) -> BoxFuture; - - /// Returns all logs matching given filter (in a range 'from' - 'to'). - #[rpc(name = "eth_getFilterLogs")] - fn filter_logs(&self, Index) -> BoxFuture>; - - /// Uninstalls filter. - #[rpc(name = "eth_uninstallFilter")] - fn uninstall_filter(&self, Index) -> Result; - } +/// Eth filters rpc api (polling). +// TODO: do filters api properly +#[rpc] +pub trait EthFilter { + /// Returns id of new filter. + #[rpc(name = "eth_newFilter")] + fn new_filter(&self, Filter) -> Result; + + /// Returns id of new block filter. + #[rpc(name = "eth_newBlockFilter")] + fn new_block_filter(&self) -> Result; + + /// Returns id of new block filter. + #[rpc(name = "eth_newPendingTransactionFilter")] + fn new_pending_transaction_filter(&self) -> Result; + + /// Returns filter changes since last poll. + #[rpc(name = "eth_getFilterChanges")] + fn filter_changes(&self, Index) -> BoxFuture; + + /// Returns all logs matching given filter (in a range 'from' - 'to'). + #[rpc(name = "eth_getFilterLogs")] + fn filter_logs(&self, Index) -> BoxFuture>; + + /// Uninstalls filter. + #[rpc(name = "eth_uninstallFilter")] + fn uninstall_filter(&self, Index) -> Result; } diff --git a/rpc/src/v1/traits/eth_pubsub.rs b/rpc/src/v1/traits/eth_pubsub.rs index d584b7dbc9..0628781392 100644 --- a/rpc/src/v1/traits/eth_pubsub.rs +++ b/rpc/src/v1/traits/eth_pubsub.rs @@ -17,25 +17,22 @@ //! Eth PUB-SUB rpc interface. use jsonrpc_core::Result; -use jsonrpc_macros::Trailing; -use jsonrpc_macros::pubsub::Subscriber; -use jsonrpc_pubsub::SubscriptionId; +use jsonrpc_derive::rpc; +use jsonrpc_pubsub::{typed, SubscriptionId}; use v1::types::pubsub; -build_rpc_trait! { - /// Eth PUB-SUB rpc interface. - pub trait EthPubSub { - type Metadata; - - #[pubsub(name = "eth_subscription")] { - /// Subscribe to Eth subscription. - #[rpc(name = "eth_subscribe")] - fn subscribe(&self, Self::Metadata, Subscriber, pubsub::Kind, Trailing); - - /// Unsubscribe from existing Eth subscription. - #[rpc(name = "eth_unsubscribe")] - fn unsubscribe(&self, SubscriptionId) -> Result; - } - } +/// Eth PUB-SUB rpc interface. +#[rpc] +pub trait EthPubSub { + /// RPC Metadata + type Metadata; + + /// Subscribe to Eth subscription. + #[pubsub(subscription = "eth_subscription", subscribe, name = "eth_subscribe")] + fn subscribe(&self, Self::Metadata, typed::Subscriber, pubsub::Kind, Option); + + /// Unsubscribe from existing Eth subscription. + #[pubsub(subscription = "eth_subscription", unsubscribe, name = "eth_unsubscribe")] + fn unsubscribe(&self, Option, SubscriptionId) -> Result; } diff --git a/rpc/src/v1/traits/eth_signing.rs b/rpc/src/v1/traits/eth_signing.rs index 3b7d88446e..c272a42e40 100644 --- a/rpc/src/v1/traits/eth_signing.rs +++ b/rpc/src/v1/traits/eth_signing.rs @@ -17,28 +17,29 @@ //! Eth rpc interface. use jsonrpc_core::BoxFuture; +use jsonrpc_derive::rpc; use v1::types::{Bytes, H160, H256, H520, TransactionRequest, RichRawTransaction}; -build_rpc_trait! { - /// Signing methods implementation relying on unlocked accounts. - pub trait EthSigning { - type Metadata; - - /// Signs the hash of data with given address signature. - #[rpc(meta, name = "eth_sign")] - fn sign(&self, Self::Metadata, H160, Bytes) -> BoxFuture; - - /// Sends transaction; will block waiting for signer to return the - /// transaction hash. - /// If Signer is disable it will require the account to be unlocked. - #[rpc(meta, name = "eth_sendTransaction")] - fn send_transaction(&self, Self::Metadata, TransactionRequest) -> BoxFuture; - - /// Signs transactions without dispatching it to the network. - /// Returns signed transaction RLP representation and the transaction itself. - /// It can be later submitted using `eth_sendRawTransaction/eth_submitTransaction`. - #[rpc(meta, name = "eth_signTransaction")] - fn sign_transaction(&self, Self::Metadata, TransactionRequest) -> BoxFuture; - } +/// Signing methods implementation relying on unlocked accounts. +#[rpc] +pub trait EthSigning { + /// RPC Metadata + type Metadata; + + /// Signs the hash of data with given address signature. + #[rpc(meta, name = "eth_sign")] + fn sign(&self, Self::Metadata, H160, Bytes) -> BoxFuture; + + /// Sends transaction; will block waiting for signer to return the + /// transaction hash. + /// If Signer is disable it will require the account to be unlocked. + #[rpc(meta, name = "eth_sendTransaction")] + fn send_transaction(&self, Self::Metadata, TransactionRequest) -> BoxFuture; + + /// Signs transactions without dispatching it to the network. + /// Returns signed transaction RLP representation and the transaction itself. + /// It can be later submitted using `eth_sendRawTransaction/eth_submitTransaction`. + #[rpc(meta, name = "eth_signTransaction")] + fn sign_transaction(&self, Self::Metadata, TransactionRequest) -> BoxFuture; } diff --git a/rpc/src/v1/traits/net.rs b/rpc/src/v1/traits/net.rs index b8bdb19607..a16729294d 100644 --- a/rpc/src/v1/traits/net.rs +++ b/rpc/src/v1/traits/net.rs @@ -16,21 +16,21 @@ //! Net rpc interface. use jsonrpc_core::Result; +use jsonrpc_derive::rpc; -build_rpc_trait! { - /// Net rpc interface. - pub trait Net { - /// Returns protocol version. - #[rpc(name = "net_version")] - fn version(&self) -> Result; +/// Net rpc interface. +#[rpc] +pub trait Net { + /// Returns protocol version. + #[rpc(name = "net_version")] + fn version(&self) -> Result; - /// Returns number of peers connected to node. - #[rpc(name = "net_peerCount")] - fn peer_count(&self) -> Result; + /// Returns number of peers connected to node. + #[rpc(name = "net_peerCount")] + fn peer_count(&self) -> Result; - /// Returns true if client is actively listening for network connections. - /// Otherwise false. - #[rpc(name = "net_listening")] - fn is_listening(&self) -> Result; - } + /// Returns true if client is actively listening for network connections. + /// Otherwise false. + #[rpc(name = "net_listening")] + fn is_listening(&self) -> Result; } diff --git a/rpc/src/v1/traits/parity.rs b/rpc/src/v1/traits/parity.rs index 8333498809..836f58161b 100644 --- a/rpc/src/v1/traits/parity.rs +++ b/rpc/src/v1/traits/parity.rs @@ -19,7 +19,7 @@ use std::collections::BTreeMap; use jsonrpc_core::{BoxFuture, Result}; -use jsonrpc_macros::Trailing; +use jsonrpc_derive::rpc; use v1::types::{ H160, H256, H512, U256, U64, H64, Bytes, CallRequest, Peers, Transaction, RpcSettings, Histogram, RecoveredAccount, @@ -29,223 +29,222 @@ use v1::types::{ AccountInfo, HwAccountInfo, RichHeader, Receipt, }; -build_rpc_trait! { - /// Parity-specific rpc interface. - pub trait Parity { - type Metadata; +/// Parity-specific rpc interface. +#[rpc] +pub trait Parity { + /// RPC Metadata + type Metadata; - /// Returns accounts information. - #[rpc(name = "parity_accountsInfo")] - fn accounts_info(&self) -> Result>; + /// Returns accounts information. + #[rpc(name = "parity_accountsInfo")] + fn accounts_info(&self) -> Result>; - /// Returns hardware accounts information. - #[rpc(name = "parity_hardwareAccountsInfo")] - fn hardware_accounts_info(&self) -> Result>; + /// Returns hardware accounts information. + #[rpc(name = "parity_hardwareAccountsInfo")] + fn hardware_accounts_info(&self) -> Result>; - /// Get a list of paths to locked hardware wallets - #[rpc(name = "parity_lockedHardwareAccountsInfo")] - fn locked_hardware_accounts_info(&self) -> Result>; - - /// Returns default account for dapp. - #[rpc(name = "parity_defaultAccount")] - fn default_account(&self) -> Result; - - /// Returns current transactions limit. - #[rpc(name = "parity_transactionsLimit")] - fn transactions_limit(&self) -> Result; - - /// Returns mining extra data. - #[rpc(name = "parity_extraData")] - fn extra_data(&self) -> Result; - - /// Returns mining gas floor target. - #[rpc(name = "parity_gasFloorTarget")] - fn gas_floor_target(&self) -> Result; - - /// Returns mining gas floor cap. - #[rpc(name = "parity_gasCeilTarget")] - fn gas_ceil_target(&self) -> Result; - - /// Returns minimal gas price for transaction to be included in queue. - #[rpc(name = "parity_minGasPrice")] - fn min_gas_price(&self) -> Result; - - /// Returns latest logs - #[rpc(name = "parity_devLogs")] - fn dev_logs(&self) -> Result>; - - /// Returns logs levels - #[rpc(name = "parity_devLogsLevels")] - fn dev_logs_levels(&self) -> Result; - - /// Returns chain name - DEPRECATED. Use `parity_chainName` instead. - #[rpc(name = "parity_netChain")] - fn net_chain(&self) -> Result; - - /// Returns peers details - #[rpc(name = "parity_netPeers")] - fn net_peers(&self) -> Result; - - /// Returns network port - #[rpc(name = "parity_netPort")] - fn net_port(&self) -> Result; - - /// Returns rpc settings - #[rpc(name = "parity_rpcSettings")] - fn rpc_settings(&self) -> Result; - - /// Returns node name - #[rpc(name = "parity_nodeName")] - fn node_name(&self) -> Result; - - /// Returns default extra data - #[rpc(name = "parity_defaultExtraData")] - fn default_extra_data(&self) -> Result; - - /// Returns distribution of gas price in latest blocks. - #[rpc(name = "parity_gasPriceHistogram")] - fn gas_price_histogram(&self) -> BoxFuture; - - /// Returns number of unsigned transactions waiting in the signer queue (if signer enabled) - /// Returns error when signer is disabled - #[rpc(name = "parity_unsignedTransactionsCount")] - fn unsigned_transactions_count(&self) -> Result; - - /// Returns a cryptographically random phrase sufficient for securely seeding a secret key. - #[rpc(name = "parity_generateSecretPhrase")] - fn generate_secret_phrase(&self) -> Result; - - /// Returns whatever address would be derived from the given phrase if it were to seed a brainwallet. - #[rpc(name = "parity_phraseToAddress")] - fn phrase_to_address(&self, String) -> Result; - - /// Returns the value of the registrar for this network. - #[rpc(name = "parity_registryAddress")] - fn registry_address(&self) -> Result>; - - /// Returns all addresses if Fat DB is enabled (`--fat-db`), or null if not. - #[rpc(name = "parity_listAccounts")] - fn list_accounts(&self, u64, Option, Trailing) -> Result>>; - - /// Returns all storage keys of the given address (first parameter) if Fat DB is enabled (`--fat-db`), - /// or null if not. - #[rpc(name = "parity_listStorageKeys")] - fn list_storage_keys(&self, H160, u64, Option, Trailing) -> Result>>; - - /// Encrypt some data with a public key under ECIES. - /// First parameter is the 512-byte destination public key, second is the message. - #[rpc(name = "parity_encryptMessage")] - fn encrypt_message(&self, H512, Bytes) -> Result; - - /// Returns all pending transactions from transaction queue. - #[rpc(name = "parity_pendingTransactions")] - fn pending_transactions(&self, Trailing) -> Result>; - - /// Returns all transactions from transaction queue. - /// - /// Some of them might not be ready to be included in a block yet. - #[rpc(name = "parity_allTransactions")] - fn all_transactions(&self) -> Result>; - - /// Same as parity_allTransactions, but return only transactions hashes. - #[rpc(name = "parity_allTransactionHashes")] - fn all_transaction_hashes(&self) -> Result>; - - /// Returns all future transactions from transaction queue (deprecated) - #[rpc(name = "parity_futureTransactions")] - fn future_transactions(&self) -> Result>; - - /// Returns propagation statistics on transactions pending in the queue. - #[rpc(name = "parity_pendingTransactionsStats")] - fn pending_transactions_stats(&self) -> Result>; - - /// Returns a list of current and past local transactions with status details. - #[rpc(name = "parity_localTransactions")] - fn local_transactions(&self) -> Result>; - - /// Returns current WS Server interface and port or an error if ws server is disabled. - #[rpc(name = "parity_wsUrl")] - fn ws_url(&self) -> Result; - - /// Returns next nonce for particular sender. Should include all transactions in the queue. - #[rpc(name = "parity_nextNonce")] - fn next_nonce(&self, H160) -> BoxFuture; - - /// Get the mode. Returns one of: "active", "passive", "dark", "offline". - #[rpc(name = "parity_mode")] - fn mode(&self) -> Result; - - /// Get the chain name. Returns one of the pre-configured chain names or a filename. - #[rpc(name = "parity_chain")] - fn chain(&self) -> Result; - - /// Get the enode of this node. - #[rpc(name = "parity_enode")] - fn enode(&self) -> Result; - - /// Returns information on current consensus capability. - #[rpc(name = "parity_consensusCapability")] - fn consensus_capability(&self) -> Result; - - /// Get our version information in a nice object. - #[rpc(name = "parity_versionInfo")] - fn version_info(&self) -> Result; - - /// Get information concerning the latest releases if available. - #[rpc(name = "parity_releasesInfo")] - fn releases_info(&self) -> Result>; - - /// Get the current chain status. - #[rpc(name = "parity_chainStatus")] - fn chain_status(&self) -> Result; - - /// Get node kind info. - #[rpc(name = "parity_nodeKind")] - fn node_kind(&self) -> Result<::v1::types::NodeKind>; - - /// Get block header. - /// Same as `eth_getBlockByNumber` but without uncles and transactions. - #[rpc(name = "parity_getBlockHeaderByNumber")] - fn block_header(&self, Trailing) -> BoxFuture; - - /// Get block receipts. - /// Allows you to fetch receipts from the entire block at once. - /// If no parameter is provided defaults to `latest`. - #[rpc(name = "parity_getBlockReceipts")] - fn block_receipts(&self, Trailing) -> BoxFuture>; - - /// Get IPFS CIDv0 given protobuf encoded bytes. - #[rpc(name = "parity_cidV0")] - fn ipfs_cid(&self, Bytes) -> Result; - - /// Call contract, returning the output data. - #[rpc(name = "parity_call")] - fn call(&self, Vec, Trailing) -> Result>; - - /// Used for submitting a proof-of-work solution (similar to `eth_submitWork`, - /// but returns block hash on success, and returns an explicit error message on failure). - #[rpc(name = "parity_submitWorkDetail")] - fn submit_work_detail(&self, H64, H256, H256) -> Result; - - /// Returns the status of the node. Used as the health endpoint. - /// - /// The RPC returns successful response if: - /// - The node have a peer (unless running a dev chain) - /// - The node is not syncing. - /// - /// Otherwise the RPC returns error. - #[rpc(name = "parity_nodeStatus")] - fn status(&self) -> Result<()>; - - /// Extracts Address and public key from signature using the r, s and v params. Equivalent to Solidity erecover - /// as well as checks the signature for chain replay protection - #[rpc(name = "parity_verifySignature")] - fn verify_signature(&self, bool, Bytes, H256, H256, U64) -> Result; - - /// Returns logs matching given filter object. - /// Is allowed to skip filling transaction hash for faster query. - #[rpc(name = "parity_getLogsNoTransactionHash")] - fn logs_no_tx_hash(&self, Filter) -> BoxFuture>; - - } + /// Get a list of paths to locked hardware wallets + #[rpc(name = "parity_lockedHardwareAccountsInfo")] + fn locked_hardware_accounts_info(&self) -> Result>; + + /// Returns default account for dapp. + #[rpc(name = "parity_defaultAccount")] + fn default_account(&self) -> Result; + + /// Returns current transactions limit. + #[rpc(name = "parity_transactionsLimit")] + fn transactions_limit(&self) -> Result; + + /// Returns mining extra data. + #[rpc(name = "parity_extraData")] + fn extra_data(&self) -> Result; + + /// Returns mining gas floor target. + #[rpc(name = "parity_gasFloorTarget")] + fn gas_floor_target(&self) -> Result; + + /// Returns mining gas floor cap. + #[rpc(name = "parity_gasCeilTarget")] + fn gas_ceil_target(&self) -> Result; + + /// Returns minimal gas price for transaction to be included in queue. + #[rpc(name = "parity_minGasPrice")] + fn min_gas_price(&self) -> Result; + + /// Returns latest logs + #[rpc(name = "parity_devLogs")] + fn dev_logs(&self) -> Result>; + + /// Returns logs levels + #[rpc(name = "parity_devLogsLevels")] + fn dev_logs_levels(&self) -> Result; + + /// Returns chain name - DEPRECATED. Use `parity_chainName` instead. + #[rpc(name = "parity_netChain")] + fn net_chain(&self) -> Result; + + /// Returns peers details + #[rpc(name = "parity_netPeers")] + fn net_peers(&self) -> Result; + + /// Returns network port + #[rpc(name = "parity_netPort")] + fn net_port(&self) -> Result; + + /// Returns rpc settings + #[rpc(name = "parity_rpcSettings")] + fn rpc_settings(&self) -> Result; + + /// Returns node name + #[rpc(name = "parity_nodeName")] + fn node_name(&self) -> Result; + + /// Returns default extra data + #[rpc(name = "parity_defaultExtraData")] + fn default_extra_data(&self) -> Result; + + /// Returns distribution of gas price in latest blocks. + #[rpc(name = "parity_gasPriceHistogram")] + fn gas_price_histogram(&self) -> BoxFuture; + + /// Returns number of unsigned transactions waiting in the signer queue (if signer enabled) + /// Returns error when signer is disabled + #[rpc(name = "parity_unsignedTransactionsCount")] + fn unsigned_transactions_count(&self) -> Result; + + /// Returns a cryptographically random phrase sufficient for securely seeding a secret key. + #[rpc(name = "parity_generateSecretPhrase")] + fn generate_secret_phrase(&self) -> Result; + + /// Returns whatever address would be derived from the given phrase if it were to seed a brainwallet. + #[rpc(name = "parity_phraseToAddress")] + fn phrase_to_address(&self, String) -> Result; + + /// Returns the value of the registrar for this network. + #[rpc(name = "parity_registryAddress")] + fn registry_address(&self) -> Result>; + + /// Returns all addresses if Fat DB is enabled (`--fat-db`), or null if not. + #[rpc(name = "parity_listAccounts")] + fn list_accounts(&self, u64, Option, Option) -> Result>>; + + /// Returns all storage keys of the given address (first parameter) if Fat DB is enabled (`--fat-db`), + /// or null if not. + #[rpc(name = "parity_listStorageKeys")] + fn list_storage_keys(&self, H160, u64, Option, Option) -> Result>>; + + /// Encrypt some data with a public key under ECIES. + /// First parameter is the 512-byte destination public key, second is the message. + #[rpc(name = "parity_encryptMessage")] + fn encrypt_message(&self, H512, Bytes) -> Result; + + /// Returns all pending transactions from transaction queue. + #[rpc(name = "parity_pendingTransactions")] + fn pending_transactions(&self, Option) -> Result>; + + /// Returns all transactions from transaction queue. + /// + /// Some of them might not be ready to be included in a block yet. + #[rpc(name = "parity_allTransactions")] + fn all_transactions(&self) -> Result>; + + /// Same as parity_allTransactions, but return only transactions hashes. + #[rpc(name = "parity_allTransactionHashes")] + fn all_transaction_hashes(&self) -> Result>; + + /// Returns all future transactions from transaction queue (deprecated) + #[rpc(name = "parity_futureTransactions")] + fn future_transactions(&self) -> Result>; + + /// Returns propagation statistics on transactions pending in the queue. + #[rpc(name = "parity_pendingTransactionsStats")] + fn pending_transactions_stats(&self) -> Result>; + + /// Returns a list of current and past local transactions with status details. + #[rpc(name = "parity_localTransactions")] + fn local_transactions(&self) -> Result>; + + /// Returns current WS Server interface and port or an error if ws server is disabled. + #[rpc(name = "parity_wsUrl")] + fn ws_url(&self) -> Result; + + /// Returns next nonce for particular sender. Should include all transactions in the queue. + #[rpc(name = "parity_nextNonce")] + fn next_nonce(&self, H160) -> BoxFuture; + + /// Get the mode. Returns one of: "active", "passive", "dark", "offline". + #[rpc(name = "parity_mode")] + fn mode(&self) -> Result; + + /// Get the chain name. Returns one of the pre-configured chain names or a filename. + #[rpc(name = "parity_chain")] + fn chain(&self) -> Result; + + /// Get the enode of this node. + #[rpc(name = "parity_enode")] + fn enode(&self) -> Result; + + /// Returns information on current consensus capability. + #[rpc(name = "parity_consensusCapability")] + fn consensus_capability(&self) -> Result; + + /// Get our version information in a nice object. + #[rpc(name = "parity_versionInfo")] + fn version_info(&self) -> Result; + + /// Get information concerning the latest releases if available. + #[rpc(name = "parity_releasesInfo")] + fn releases_info(&self) -> Result>; + + /// Get the current chain status. + #[rpc(name = "parity_chainStatus")] + fn chain_status(&self) -> Result; + + /// Get node kind info. + #[rpc(name = "parity_nodeKind")] + fn node_kind(&self) -> Result<::v1::types::NodeKind>; + + /// Get block header. + /// Same as `eth_getBlockByNumber` but without uncles and transactions. + #[rpc(name = "parity_getBlockHeaderByNumber")] + fn block_header(&self, Option) -> BoxFuture; + + /// Get block receipts. + /// Allows you to fetch receipts from the entire block at once. + /// If no parameter is provided defaults to `latest`. + #[rpc(name = "parity_getBlockReceipts")] + fn block_receipts(&self, Option) -> BoxFuture>; + + /// Get IPFS CIDv0 given protobuf encoded bytes. + #[rpc(name = "parity_cidV0")] + fn ipfs_cid(&self, Bytes) -> Result; + + /// Call contract, returning the output data. + #[rpc(name = "parity_call")] + fn call(&self, Vec, Option) -> Result>; + + /// Used for submitting a proof-of-work solution (similar to `eth_submitWork`, + /// but returns block hash on success, and returns an explicit error message on failure). + #[rpc(name = "parity_submitWorkDetail")] + fn submit_work_detail(&self, H64, H256, H256) -> Result; + + /// Returns the status of the node. Used as the health endpoint. + /// + /// The RPC returns successful response if: + /// - The node have a peer (unless running a dev chain) + /// - The node is not syncing. + /// + /// Otherwise the RPC returns error. + #[rpc(name = "parity_nodeStatus")] + fn status(&self) -> Result<()>; + + /// Extracts Address and public key from signature using the r, s and v params. Equivalent to Solidity erecover + /// as well as checks the signature for chain replay protection + #[rpc(name = "parity_verifySignature")] + fn verify_signature(&self, bool, Bytes, H256, H256, U64) -> Result; + + /// Returns logs matching given filter object. + /// Is allowed to skip filling transaction hash for faster query. + #[rpc(name = "parity_getLogsNoTransactionHash")] + fn logs_no_tx_hash(&self, Filter) -> BoxFuture>; } diff --git a/rpc/src/v1/traits/parity_accounts.rs b/rpc/src/v1/traits/parity_accounts.rs index 8037161e05..f10f109715 100644 --- a/rpc/src/v1/traits/parity_accounts.rs +++ b/rpc/src/v1/traits/parity_accounts.rs @@ -18,125 +18,125 @@ use std::collections::BTreeMap; use jsonrpc_core::Result; +use jsonrpc_derive::rpc; use ethkey::Password; use ethstore::KeyFile; use v1::types::{H160, H256, H520, DeriveHash, DeriveHierarchical, ExtAccountInfo}; -build_rpc_trait! { - /// Personal Parity rpc interface. - pub trait ParityAccounts { - /// Returns accounts information. - #[rpc(name = "parity_allAccountsInfo")] - fn all_accounts_info(&self) -> Result>; - - /// Creates new account from the given phrase using standard brainwallet mechanism. - /// Second parameter is password for the new account. - #[rpc(name = "parity_newAccountFromPhrase")] - fn new_account_from_phrase(&self, String, Password) -> Result; - - /// Creates new account from the given JSON wallet. - /// Second parameter is password for the wallet and the new account. - #[rpc(name = "parity_newAccountFromWallet")] - fn new_account_from_wallet(&self, String, Password) -> Result; - - /// Creates new account from the given raw secret. - /// Second parameter is password for the new account. - #[rpc(name = "parity_newAccountFromSecret")] - fn new_account_from_secret(&self, H256, Password) -> Result; - - /// Returns true if given `password` would unlock given `account`. - /// Arguments: `account`, `password`. - #[rpc(name = "parity_testPassword")] - fn test_password(&self, H160, Password) -> Result; - - /// Changes an account's password. - /// Arguments: `account`, `password`, `new_password`. - #[rpc(name = "parity_changePassword")] - fn change_password(&self, H160, Password, Password) -> Result; - - /// Permanently deletes an account. - /// Arguments: `account`, `password`. - #[rpc(name = "parity_killAccount")] - fn kill_account(&self, H160, Password) -> Result; - - /// Permanently deletes an address from the addressbook - /// Arguments: `address` - #[rpc(name = "parity_removeAddress")] - fn remove_address(&self, H160) -> Result; - - /// Set an account's name. - #[rpc(name = "parity_setAccountName")] - fn set_account_name(&self, H160, String) -> Result; - - /// Set an account's metadata string. - #[rpc(name = "parity_setAccountMeta")] - fn set_account_meta(&self, H160, String) -> Result; - - /// Imports a number of Geth accounts, with the list provided as the argument. - #[rpc(name = "parity_importGethAccounts")] - fn import_geth_accounts(&self, Vec) -> Result>; - - /// Returns the accounts available for importing from Geth. - #[rpc(name = "parity_listGethAccounts")] - fn geth_accounts(&self) -> Result>; - - /// Create new vault. - #[rpc(name = "parity_newVault")] - fn create_vault(&self, String, Password) -> Result; - - /// Open existing vault. - #[rpc(name = "parity_openVault")] - fn open_vault(&self, String, Password) -> Result; - - /// Close previously opened vault. - #[rpc(name = "parity_closeVault")] - fn close_vault(&self, String) -> Result; - - /// List all vaults. - #[rpc(name = "parity_listVaults")] - fn list_vaults(&self) -> Result>; - - /// List all currently opened vaults. - #[rpc(name = "parity_listOpenedVaults")] - fn list_opened_vaults(&self) -> Result>; - - /// Change vault password. - #[rpc(name = "parity_changeVaultPassword")] - fn change_vault_password(&self, String, Password) -> Result; - - /// Change vault of the given address. - #[rpc(name = "parity_changeVault")] - fn change_vault(&self, H160, String) -> Result; - - /// Get vault metadata string. - #[rpc(name = "parity_getVaultMeta")] - fn get_vault_meta(&self, String) -> Result; - - /// Set vault metadata string. - #[rpc(name = "parity_setVaultMeta")] - fn set_vault_meta(&self, String, String) -> Result; - - /// Derive new address from given account address using specific hash. - /// Resulting address can be either saved as a new account (with the same password). - #[rpc(name = "parity_deriveAddressHash")] - fn derive_key_hash(&self, H160, Password, DeriveHash, bool) -> Result; - - /// Derive new address from given account address using - /// hierarchical derivation (sequence of 32-bit integer indices). - /// Resulting address can be either saved as a new account (with the same password). - #[rpc(name = "parity_deriveAddressIndex")] - fn derive_key_index(&self, H160, Password, DeriveHierarchical, bool) -> Result; - - /// Exports an account with given address if provided password matches. - #[rpc(name = "parity_exportAccount")] - fn export_account(&self, H160, Password) -> Result; - - /// Sign raw hash with the key corresponding to address and password. - #[rpc(name = "parity_signMessage")] - fn sign_message(&self, H160, Password, H256) -> Result; - - /// Send a PinMatrixAck to a hardware wallet, unlocking it - #[rpc(name = "parity_hardwarePinMatrixAck")] - fn hardware_pin_matrix_ack(&self, String, String) -> Result; - } +/// Personal Parity rpc interface. +#[rpc] +pub trait ParityAccounts { + /// Returns accounts information. + #[rpc(name = "parity_allAccountsInfo")] + fn all_accounts_info(&self) -> Result>; + + /// Creates new account from the given phrase using standard brainwallet mechanism. + /// Second parameter is password for the new account. + #[rpc(name = "parity_newAccountFromPhrase")] + fn new_account_from_phrase(&self, String, Password) -> Result; + + /// Creates new account from the given JSON wallet. + /// Second parameter is password for the wallet and the new account. + #[rpc(name = "parity_newAccountFromWallet")] + fn new_account_from_wallet(&self, String, Password) -> Result; + + /// Creates new account from the given raw secret. + /// Second parameter is password for the new account. + #[rpc(name = "parity_newAccountFromSecret")] + fn new_account_from_secret(&self, H256, Password) -> Result; + + /// Returns true if given `password` would unlock given `account`. + /// Arguments: `account`, `password`. + #[rpc(name = "parity_testPassword")] + fn test_password(&self, H160, Password) -> Result; + + /// Changes an account's password. + /// Arguments: `account`, `password`, `new_password`. + #[rpc(name = "parity_changePassword")] + fn change_password(&self, H160, Password, Password) -> Result; + + /// Permanently deletes an account. + /// Arguments: `account`, `password`. + #[rpc(name = "parity_killAccount")] + fn kill_account(&self, H160, Password) -> Result; + + /// Permanently deletes an address from the addressbook + /// Arguments: `address` + #[rpc(name = "parity_removeAddress")] + fn remove_address(&self, H160) -> Result; + + /// Set an account's name. + #[rpc(name = "parity_setAccountName")] + fn set_account_name(&self, H160, String) -> Result; + + /// Set an account's metadata string. + #[rpc(name = "parity_setAccountMeta")] + fn set_account_meta(&self, H160, String) -> Result; + + /// Imports a number of Geth accounts, with the list provided as the argument. + #[rpc(name = "parity_importGethAccounts")] + fn import_geth_accounts(&self, Vec) -> Result>; + + /// Returns the accounts available for importing from Geth. + #[rpc(name = "parity_listGethAccounts")] + fn geth_accounts(&self) -> Result>; + + /// Create new vault. + #[rpc(name = "parity_newVault")] + fn create_vault(&self, String, Password) -> Result; + + /// Open existing vault. + #[rpc(name = "parity_openVault")] + fn open_vault(&self, String, Password) -> Result; + + /// Close previously opened vault. + #[rpc(name = "parity_closeVault")] + fn close_vault(&self, String) -> Result; + + /// List all vaults. + #[rpc(name = "parity_listVaults")] + fn list_vaults(&self) -> Result>; + + /// List all currently opened vaults. + #[rpc(name = "parity_listOpenedVaults")] + fn list_opened_vaults(&self) -> Result>; + + /// Change vault password. + #[rpc(name = "parity_changeVaultPassword")] + fn change_vault_password(&self, String, Password) -> Result; + + /// Change vault of the given address. + #[rpc(name = "parity_changeVault")] + fn change_vault(&self, H160, String) -> Result; + + /// Get vault metadata string. + #[rpc(name = "parity_getVaultMeta")] + fn get_vault_meta(&self, String) -> Result; + + /// Set vault metadata string. + #[rpc(name = "parity_setVaultMeta")] + fn set_vault_meta(&self, String, String) -> Result; + + /// Derive new address from given account address using specific hash. + /// Resulting address can be either saved as a new account (with the same password). + #[rpc(name = "parity_deriveAddressHash")] + fn derive_key_hash(&self, H160, Password, DeriveHash, bool) -> Result; + + /// Derive new address from given account address using + /// hierarchical derivation (sequence of 32-bit integer indices). + /// Resulting address can be either saved as a new account (with the same password). + #[rpc(name = "parity_deriveAddressIndex")] + fn derive_key_index(&self, H160, Password, DeriveHierarchical, bool) -> Result; + + /// Exports an account with given address if provided password matches. + #[rpc(name = "parity_exportAccount")] + fn export_account(&self, H160, Password) -> Result; + + /// Sign raw hash with the key corresponding to address and password. + #[rpc(name = "parity_signMessage")] + fn sign_message(&self, H160, Password, H256) -> Result; + + /// Send a PinMatrixAck to a hardware wallet, unlocking it + #[rpc(name = "parity_hardwarePinMatrixAck")] + fn hardware_pin_matrix_ack(&self, String, String) -> Result; } diff --git a/rpc/src/v1/traits/parity_set.rs b/rpc/src/v1/traits/parity_set.rs index 66f91a524d..9a0badaa29 100644 --- a/rpc/src/v1/traits/parity_set.rs +++ b/rpc/src/v1/traits/parity_set.rs @@ -17,99 +17,99 @@ //! Parity-specific rpc interface for operations altering the settings. use jsonrpc_core::{BoxFuture, Result}; +use jsonrpc_derive::rpc; use v1::types::{Bytes, H160, H256, U256, ReleaseInfo, Transaction}; -build_rpc_trait! { - /// Parity-specific rpc interface for operations altering the settings. - pub trait ParitySet { - /// Sets new minimal gas price for mined blocks. - #[rpc(name = "parity_setMinGasPrice")] - fn set_min_gas_price(&self, U256) -> Result; - - /// Sets new gas floor target for mined blocks. - #[rpc(name = "parity_setGasFloorTarget")] - fn set_gas_floor_target(&self, U256) -> Result; - - /// Sets new gas ceiling target for mined blocks. - #[rpc(name = "parity_setGasCeilTarget")] - fn set_gas_ceil_target(&self, U256) -> Result; - - /// Sets new extra data for mined blocks. - #[rpc(name = "parity_setExtraData")] - fn set_extra_data(&self, Bytes) -> Result; - - /// Sets new author for mined block. - #[rpc(name = "parity_setAuthor")] - fn set_author(&self, H160) -> Result; - - /// Sets account for signing consensus messages. - #[rpc(name = "parity_setEngineSigner")] - fn set_engine_signer(&self, H160, String) -> Result; - - /// Sets the limits for transaction queue. - #[rpc(name = "parity_setTransactionsLimit")] - fn set_transactions_limit(&self, usize) -> Result; - - /// Sets the maximum amount of gas a single transaction may consume. - #[rpc(name = "parity_setMaxTransactionGas")] - fn set_tx_gas_limit(&self, U256) -> Result; - - /// Add a reserved peer. - #[rpc(name = "parity_addReservedPeer")] - fn add_reserved_peer(&self, String) -> Result; - - /// Remove a reserved peer. - #[rpc(name = "parity_removeReservedPeer")] - fn remove_reserved_peer(&self, String) -> Result; - - /// Drop all non-reserved peers. - #[rpc(name = "parity_dropNonReservedPeers")] - fn drop_non_reserved_peers(&self) -> Result; - - /// Accept non-reserved peers (default behavior) - #[rpc(name = "parity_acceptNonReservedPeers")] - fn accept_non_reserved_peers(&self) -> Result; - - /// Start the network. - /// - /// @deprecated - Use `set_mode("active")` instead. - #[rpc(name = "parity_startNetwork")] - fn start_network(&self) -> Result; - - /// Stop the network. - /// - /// @deprecated - Use `set_mode("offline")` instead. - #[rpc(name = "parity_stopNetwork")] - fn stop_network(&self) -> Result; - - /// Set the mode. Argument must be one of: "active", "passive", "dark", "offline". - #[rpc(name = "parity_setMode")] - fn set_mode(&self, String) -> Result; - - /// Set the network spec. Argument must be one of pre-configured chains or a filename. - #[rpc(name = "parity_setChain")] - fn set_spec_name(&self, String) -> Result; - - /// Hash a file content under given URL. - #[rpc(name = "parity_hashContent")] - fn hash_content(&self, String) -> BoxFuture; - - /// Is there a release ready for install? - #[rpc(name = "parity_upgradeReady")] - fn upgrade_ready(&self) -> Result>; - - /// Execute a release which is ready according to upgrade_ready(). - #[rpc(name = "parity_executeUpgrade")] - fn execute_upgrade(&self) -> Result; - - /// Removes transaction from transaction queue. - /// Makes sense only for transactions that were not propagated to other peers yet - /// like scheduled transactions or transactions in future. - /// It might also work for some local transactions with to low gas price - /// or excessive gas limit that are not accepted by other peers whp. - /// Returns `true` when transaction was removed, `false` if it was not found. - #[rpc(name = "parity_removeTransaction")] - fn remove_transaction(&self, H256) -> Result>; - } +/// Parity-specific rpc interface for operations altering the settings. +#[rpc] +pub trait ParitySet { + /// Sets new minimal gas price for mined blocks. + #[rpc(name = "parity_setMinGasPrice")] + fn set_min_gas_price(&self, U256) -> Result; + + /// Sets new gas floor target for mined blocks. + #[rpc(name = "parity_setGasFloorTarget")] + fn set_gas_floor_target(&self, U256) -> Result; + + /// Sets new gas ceiling target for mined blocks. + #[rpc(name = "parity_setGasCeilTarget")] + fn set_gas_ceil_target(&self, U256) -> Result; + + /// Sets new extra data for mined blocks. + #[rpc(name = "parity_setExtraData")] + fn set_extra_data(&self, Bytes) -> Result; + + /// Sets new author for mined block. + #[rpc(name = "parity_setAuthor")] + fn set_author(&self, H160) -> Result; + + /// Sets account for signing consensus messages. + #[rpc(name = "parity_setEngineSigner")] + fn set_engine_signer(&self, H160, String) -> Result; + + /// Sets the limits for transaction queue. + #[rpc(name = "parity_setTransactionsLimit")] + fn set_transactions_limit(&self, usize) -> Result; + + /// Sets the maximum amount of gas a single transaction may consume. + #[rpc(name = "parity_setMaxTransactionGas")] + fn set_tx_gas_limit(&self, U256) -> Result; + + /// Add a reserved peer. + #[rpc(name = "parity_addReservedPeer")] + fn add_reserved_peer(&self, String) -> Result; + + /// Remove a reserved peer. + #[rpc(name = "parity_removeReservedPeer")] + fn remove_reserved_peer(&self, String) -> Result; + + /// Drop all non-reserved peers. + #[rpc(name = "parity_dropNonReservedPeers")] + fn drop_non_reserved_peers(&self) -> Result; + + /// Accept non-reserved peers (default behavior) + #[rpc(name = "parity_acceptNonReservedPeers")] + fn accept_non_reserved_peers(&self) -> Result; + + /// Start the network. + /// + /// @deprecated - Use `set_mode("active")` instead. + #[rpc(name = "parity_startNetwork")] + fn start_network(&self) -> Result; + + /// Stop the network. + /// + /// @deprecated - Use `set_mode("offline")` instead. + #[rpc(name = "parity_stopNetwork")] + fn stop_network(&self) -> Result; + + /// Set the mode. Argument must be one of: "active", "passive", "dark", "offline". + #[rpc(name = "parity_setMode")] + fn set_mode(&self, String) -> Result; + + /// Set the network spec. Argument must be one of pre-configured chains or a filename. + #[rpc(name = "parity_setChain")] + fn set_spec_name(&self, String) -> Result; + + /// Hash a file content under given URL. + #[rpc(name = "parity_hashContent")] + fn hash_content(&self, String) -> BoxFuture; + + /// Is there a release ready for install? + #[rpc(name = "parity_upgradeReady")] + fn upgrade_ready(&self) -> Result>; + + /// Execute a release which is ready according to upgrade_ready(). + #[rpc(name = "parity_executeUpgrade")] + fn execute_upgrade(&self) -> Result; + + /// Removes transaction from transaction queue. + /// Makes sense only for transactions that were not propagated to other peers yet + /// like scheduled transactions or transactions in future. + /// It might also work for some local transactions with to low gas price + /// or excessive gas limit that are not accepted by other peers whp. + /// Returns `true` when transaction was removed, `false` if it was not found. + #[rpc(name = "parity_removeTransaction")] + fn remove_transaction(&self, H256) -> Result>; } diff --git a/rpc/src/v1/traits/parity_signing.rs b/rpc/src/v1/traits/parity_signing.rs index e716204be7..26495831a7 100644 --- a/rpc/src/v1/traits/parity_signing.rs +++ b/rpc/src/v1/traits/parity_signing.rs @@ -16,37 +16,38 @@ //! ParitySigning rpc interface. use jsonrpc_core::{BoxFuture, Result}; +use jsonrpc_derive::rpc; use v1::types::{U256, H160, Bytes, ConfirmationResponse, TransactionRequest, Either}; -build_rpc_trait! { - /// Signing methods implementation. - pub trait ParitySigning { - type Metadata; - - /// Given partial transaction request produces transaction with all fields filled in. - /// Such transaction can be then signed externally. - #[rpc(meta, name = "parity_composeTransaction")] - fn compose_transaction(&self, Self::Metadata, TransactionRequest) -> BoxFuture; - - /// Posts sign request asynchronously. - /// Will return a confirmation ID for later use with check_transaction. - #[rpc(meta, name = "parity_postSign")] - fn post_sign(&self, Self::Metadata, H160, Bytes) -> BoxFuture>; - - /// Posts transaction asynchronously. - /// Will return a transaction ID for later use with check_transaction. - #[rpc(meta, name = "parity_postTransaction")] - fn post_transaction(&self, Self::Metadata, TransactionRequest) -> BoxFuture>; - - /// Checks the progress of a previously posted request (transaction/sign). - /// Should be given a valid send_transaction ID. - #[rpc(name = "parity_checkRequest")] - fn check_request(&self, U256) -> Result>; - - /// Decrypt some ECIES-encrypted message. - /// First parameter is the address with which it is encrypted, second is the ciphertext. - #[rpc(meta, name = "parity_decryptMessage")] - fn decrypt_message(&self, Self::Metadata, H160, Bytes) -> BoxFuture; - } +/// Signing methods implementation. +#[rpc] +pub trait ParitySigning { + /// RPC Metadata + type Metadata; + + /// Given partial transaction request produces transaction with all fields filled in. + /// Such transaction can be then signed externally. + #[rpc(meta, name = "parity_composeTransaction")] + fn compose_transaction(&self, Self::Metadata, TransactionRequest) -> BoxFuture; + + /// Posts sign request asynchronously. + /// Will return a confirmation ID for later use with check_transaction. + #[rpc(meta, name = "parity_postSign")] + fn post_sign(&self, Self::Metadata, H160, Bytes) -> BoxFuture>; + + /// Posts transaction asynchronously. + /// Will return a transaction ID for later use with check_transaction. + #[rpc(meta, name = "parity_postTransaction")] + fn post_transaction(&self, Self::Metadata, TransactionRequest) -> BoxFuture>; + + /// Checks the progress of a previously posted request (transaction/sign). + /// Should be given a valid send_transaction ID. + #[rpc(name = "parity_checkRequest")] + fn check_request(&self, U256) -> Result>; + + /// Decrypt some ECIES-encrypted message. + /// First parameter is the address with which it is encrypted, second is the ciphertext. + #[rpc(meta, name = "parity_decryptMessage")] + fn decrypt_message(&self, Self::Metadata, H160, Bytes) -> BoxFuture; } diff --git a/rpc/src/v1/traits/personal.rs b/rpc/src/v1/traits/personal.rs index 8965564e7b..25412f6646 100644 --- a/rpc/src/v1/traits/personal.rs +++ b/rpc/src/v1/traits/personal.rs @@ -18,56 +18,57 @@ use eip_712::EIP712; use jsonrpc_core::types::Value; use jsonrpc_core::{BoxFuture, Result}; +use jsonrpc_derive::rpc; use v1::types::{Bytes, U128, H160, H256, H520, TransactionRequest, RichRawTransaction as RpcRichRawTransaction, EIP191Version}; -build_rpc_trait! { - /// Personal rpc interface. Safe (read-only) functions. - pub trait Personal { - type Metadata; +/// Personal rpc interface. Safe (read-only) functions. +#[rpc] +pub trait Personal { + /// RPC Metadata + type Metadata; - /// Lists all stored accounts - #[rpc(name = "personal_listAccounts")] - fn accounts(&self) -> Result>; + /// Lists all stored accounts + #[rpc(name = "personal_listAccounts")] + fn accounts(&self) -> Result>; - /// Creates new account (it becomes new current unlocked account) - /// Param is the password for the account. - #[rpc(name = "personal_newAccount")] - fn new_account(&self, String) -> Result; + /// Creates new account (it becomes new current unlocked account) + /// Param is the password for the account. + #[rpc(name = "personal_newAccount")] + fn new_account(&self, String) -> Result; - /// Unlocks specified account for use (can only be one unlocked account at one moment) - #[rpc(name = "personal_unlockAccount")] - fn unlock_account(&self, H160, String, Option) -> Result; + /// Unlocks specified account for use (can only be one unlocked account at one moment) + #[rpc(name = "personal_unlockAccount")] + fn unlock_account(&self, H160, String, Option) -> Result; - /// Signs the hash of data with given account signature using the given password to unlock the account during - /// the request. - #[rpc(name = "personal_sign")] - fn sign(&self, Bytes, H160, String) -> BoxFuture; + /// Signs the hash of data with given account signature using the given password to unlock the account during + /// the request. + #[rpc(name = "personal_sign")] + fn sign(&self, Bytes, H160, String) -> BoxFuture; - /// Produces an EIP-712 compliant signature with given account using the given password to unlock the - /// account during the request. - #[rpc(name = "personal_signTypedData")] - fn sign_typed_data(&self, EIP712, H160, String) -> BoxFuture; + /// Produces an EIP-712 compliant signature with given account using the given password to unlock the + /// account during the request. + #[rpc(name = "personal_signTypedData")] + fn sign_typed_data(&self, EIP712, H160, String) -> BoxFuture; - /// Signs an arbitrary message based on the version specified - #[rpc(name = "personal_sign191")] - fn sign_191(&self, EIP191Version, Value, H160, String) -> BoxFuture; + /// Signs an arbitrary message based on the version specified + #[rpc(name = "personal_sign191")] + fn sign_191(&self, EIP191Version, Value, H160, String) -> BoxFuture; - /// Returns the account associated with the private key that was used to calculate the signature in - /// `personal_sign`. - #[rpc(name = "personal_ecRecover")] - fn ec_recover(&self, Bytes, H520) -> BoxFuture; + /// Returns the account associated with the private key that was used to calculate the signature in + /// `personal_sign`. + #[rpc(name = "personal_ecRecover")] + fn ec_recover(&self, Bytes, H520) -> BoxFuture; - /// Signs transaction. The account is not unlocked in such case. - #[rpc(meta, name = "personal_signTransaction")] - fn sign_transaction(&self, Self::Metadata, TransactionRequest, String) -> BoxFuture; + /// Signs transaction. The account is not unlocked in such case. + #[rpc(meta, name = "personal_signTransaction")] + fn sign_transaction(&self, Self::Metadata, TransactionRequest, String) -> BoxFuture; - /// Sends transaction and signs it in single call. The account is not unlocked in such case. - #[rpc(meta, name = "personal_sendTransaction")] - fn send_transaction(&self, Self::Metadata, TransactionRequest, String) -> BoxFuture; + /// Sends transaction and signs it in single call. The account is not unlocked in such case. + #[rpc(meta, name = "personal_sendTransaction")] + fn send_transaction(&self, Self::Metadata, TransactionRequest, String) -> BoxFuture; - /// @deprecated alias for `personal_sendTransaction`. - #[rpc(meta, name = "personal_signAndSendTransaction")] - fn sign_and_send_transaction(&self, Self::Metadata, TransactionRequest, String) -> BoxFuture; + /// @deprecated alias for `personal_sendTransaction`. + #[rpc(meta, name = "personal_signAndSendTransaction")] + fn sign_and_send_transaction(&self, Self::Metadata, TransactionRequest, String) -> BoxFuture; - } } diff --git a/rpc/src/v1/traits/private.rs b/rpc/src/v1/traits/private.rs index f7168c06c8..b7b871df04 100644 --- a/rpc/src/v1/traits/private.rs +++ b/rpc/src/v1/traits/private.rs @@ -17,29 +17,30 @@ //! SecretStore-specific rpc interface. use jsonrpc_core::Error; +use jsonrpc_derive::rpc; use v1::types::{Bytes, PrivateTransactionReceipt, H160, H256, U256, BlockNumber, PrivateTransactionReceiptAndTransaction, CallRequest}; -build_rpc_trait! { - /// Private transaction management RPC interface. - pub trait Private { - type Metadata; +/// Private transaction management RPC interface. +#[rpc] +pub trait Private { + /// RPC Metadata + 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; + /// 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; + /// 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(name = "private_call")] - fn private_call(&self, BlockNumber, CallRequest) -> Result; + /// Make a call to the private contract + #[rpc(name = "private_call")] + fn private_call(&self, BlockNumber, CallRequest) -> Result; - /// Retrieve the id of the key associated with the contract - #[rpc(name = "private_contractKey")] - fn private_contract_key(&self, H160) -> 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/traits/pubsub.rs b/rpc/src/v1/traits/pubsub.rs index 007e1dae40..c91b335613 100644 --- a/rpc/src/v1/traits/pubsub.rs +++ b/rpc/src/v1/traits/pubsub.rs @@ -17,23 +17,20 @@ //! Parity-specific PUB-SUB rpc interface. use jsonrpc_core::{Result, Value, Params}; -use jsonrpc_pubsub::SubscriptionId; -use jsonrpc_macros::Trailing; -use jsonrpc_macros::pubsub::Subscriber; - -build_rpc_trait! { - /// Parity-specific PUB-SUB rpc interface. - pub trait PubSub { - type Metadata; - - #[pubsub(name = "parity_subscription")] { - /// Subscribe to changes of any RPC method in Parity. - #[rpc(name = "parity_subscribe")] - fn parity_subscribe(&self, Self::Metadata, Subscriber, String, Trailing); - - /// Unsubscribe from existing Parity subscription. - #[rpc(name = "parity_unsubscribe")] - fn parity_unsubscribe(&self, SubscriptionId) -> Result; - } - } +use jsonrpc_pubsub::{typed::Subscriber, SubscriptionId}; +use jsonrpc_derive::rpc; + +/// Parity-specific PUB-SUB rpc interface. +#[rpc] +pub trait PubSub { + /// Pub/Sub Metadata + type Metadata; + + /// Subscribe to changes of any RPC method in Parity. + #[pubsub(subscription = "parity_subscription", subscribe, name = "parity_subscribe")] + fn parity_subscribe(&self, Self::Metadata, Subscriber, String, Option); + + /// Unsubscribe from existing Parity subscription. + #[pubsub(subscription = "parity_subscription", unsubscribe, name = "parity_unsubscribe")] + fn parity_unsubscribe(&self, Option, SubscriptionId) -> Result; } diff --git a/rpc/src/v1/traits/rpc.rs b/rpc/src/v1/traits/rpc.rs index 4ec58b2424..9600630fec 100644 --- a/rpc/src/v1/traits/rpc.rs +++ b/rpc/src/v1/traits/rpc.rs @@ -19,18 +19,18 @@ use std::collections::BTreeMap; use jsonrpc_core::Result; - -build_rpc_trait! { - /// RPC Interface. - pub trait Rpc { - /// Returns supported modules for Geth 1.3.6 - /// @ignore - #[rpc(name = "modules")] - fn modules(&self) -> Result>; - - /// Returns supported modules for Geth 1.4.0 - /// @ignore - #[rpc(name = "rpc_modules")] - fn rpc_modules(&self) -> Result>; - } +use jsonrpc_derive::rpc; + +/// RPC Interface. +#[rpc] +pub trait Rpc { + /// Returns supported modules for Geth 1.3.6 + /// @ignore + #[rpc(name = "modules")] + fn modules(&self) -> Result>; + + /// Returns supported modules for Geth 1.4.0 + /// @ignore + #[rpc(name = "rpc_modules")] + fn rpc_modules(&self) -> Result>; } diff --git a/rpc/src/v1/traits/secretstore.rs b/rpc/src/v1/traits/secretstore.rs index 0a5216c493..8ff1c0e99e 100644 --- a/rpc/src/v1/traits/secretstore.rs +++ b/rpc/src/v1/traits/secretstore.rs @@ -18,43 +18,43 @@ use std::collections::BTreeSet; use jsonrpc_core::Result; +use jsonrpc_derive::rpc; use ethkey::Password; use v1::types::{H160, H256, H512, Bytes, EncryptedDocumentKey}; -build_rpc_trait! { - /// Parity-specific rpc interface. - pub trait SecretStore { - /// Generate document key to store in secret store. - /// Arguments: `account`, `password`, `server_key_public`. - #[rpc(name = "secretstore_generateDocumentKey")] - fn generate_document_key(&self, H160, Password, H512) -> Result; - - /// Encrypt data with key, received from secret store. - /// Arguments: `account`, `password`, `key`, `data`. - #[rpc(name = "secretstore_encrypt")] - fn encrypt(&self, H160, Password, Bytes, Bytes) -> Result; - - /// Decrypt data with key, received from secret store. - /// Arguments: `account`, `password`, `key`, `data`. - #[rpc(name = "secretstore_decrypt")] - fn decrypt(&self, H160, Password, Bytes, Bytes) -> Result; - - /// Decrypt data with shadow key, received from secret store. - /// Arguments: `account`, `password`, `decrypted_secret`, `common_point`, `decrypt_shadows`, `data`. - #[rpc(name = "secretstore_shadowDecrypt")] - fn shadow_decrypt(&self, H160, Password, H512, H512, Vec, Bytes) -> Result; - - /// Calculates the hash (keccak256) of servers set for using in ServersSetChange session. - /// Returned hash must be signed later by using `secretstore_signRawHash` method. - /// Arguments: `servers_set`. - #[rpc(name = "secretstore_serversSetHash")] - fn servers_set_hash(&self, BTreeSet) -> Result; - - /// Generate recoverable ECDSA signature of raw hash. - /// Passed hash is treated as an input to the `sign` function (no prefixes added, no hash function is applied). - /// Arguments: `account`, `password`, `raw_hash`. - #[rpc(name = "secretstore_signRawHash")] - fn sign_raw_hash(&self, H160, Password, H256) -> Result; - } +/// Parity-specific rpc interface. +#[rpc] +pub trait SecretStore { + /// Generate document key to store in secret store. + /// Arguments: `account`, `password`, `server_key_public`. + #[rpc(name = "secretstore_generateDocumentKey")] + fn generate_document_key(&self, H160, Password, H512) -> Result; + + /// Encrypt data with key, received from secret store. + /// Arguments: `account`, `password`, `key`, `data`. + #[rpc(name = "secretstore_encrypt")] + fn encrypt(&self, H160, Password, Bytes, Bytes) -> Result; + + /// Decrypt data with key, received from secret store. + /// Arguments: `account`, `password`, `key`, `data`. + #[rpc(name = "secretstore_decrypt")] + fn decrypt(&self, H160, Password, Bytes, Bytes) -> Result; + + /// Decrypt data with shadow key, received from secret store. + /// Arguments: `account`, `password`, `decrypted_secret`, `common_point`, `decrypt_shadows`, `data`. + #[rpc(name = "secretstore_shadowDecrypt")] + fn shadow_decrypt(&self, H160, Password, H512, H512, Vec, Bytes) -> Result; + + /// Calculates the hash (keccak256) of servers set for using in ServersSetChange session. + /// Returned hash must be signed later by using `secretstore_signRawHash` method. + /// Arguments: `servers_set`. + #[rpc(name = "secretstore_serversSetHash")] + fn servers_set_hash(&self, BTreeSet) -> Result; + + /// Generate recoverable ECDSA signature of raw hash. + /// Passed hash is treated as an input to the `sign` function (no prefixes added, no hash function is applied). + /// Arguments: `account`, `password`, `raw_hash`. + #[rpc(name = "secretstore_signRawHash")] + fn sign_raw_hash(&self, H160, Password, H256) -> Result; } diff --git a/rpc/src/v1/traits/signer.rs b/rpc/src/v1/traits/signer.rs index afaba5ebec..84eccf0d39 100644 --- a/rpc/src/v1/traits/signer.rs +++ b/rpc/src/v1/traits/signer.rs @@ -16,52 +16,50 @@ //! Parity Signer-related rpc interface. use jsonrpc_core::{BoxFuture, Result}; -use jsonrpc_pubsub::SubscriptionId; -use jsonrpc_macros::pubsub::Subscriber; +use jsonrpc_pubsub::{typed::Subscriber, SubscriptionId}; +use jsonrpc_derive::rpc; use v1::types::{U256, Bytes, TransactionModification, ConfirmationRequest, ConfirmationResponse, ConfirmationResponseWithToken}; -build_rpc_trait! { - /// Signer extension for confirmations rpc interface. - pub trait Signer { - type Metadata; +/// Signer extension for confirmations rpc interface. +#[rpc] +pub trait Signer { + /// RPC Metadata + type Metadata; - /// Returns a list of items to confirm. - #[rpc(name = "signer_requestsToConfirm")] - fn requests_to_confirm(&self) -> Result>; + /// Returns a list of items to confirm. + #[rpc(name = "signer_requestsToConfirm")] + fn requests_to_confirm(&self) -> Result>; - /// Confirm specific request. - #[rpc(name = "signer_confirmRequest")] - fn confirm_request(&self, U256, TransactionModification, String) -> BoxFuture; + /// Confirm specific request. + #[rpc(name = "signer_confirmRequest")] + fn confirm_request(&self, U256, TransactionModification, String) -> BoxFuture; - /// Confirm specific request with token. - #[rpc(name = "signer_confirmRequestWithToken")] - fn confirm_request_with_token(&self, U256, TransactionModification, String) -> BoxFuture; + /// Confirm specific request with token. + #[rpc(name = "signer_confirmRequestWithToken")] + fn confirm_request_with_token(&self, U256, TransactionModification, String) -> BoxFuture; - /// Confirm specific request with already signed data. - #[rpc(name = "signer_confirmRequestRaw")] - fn confirm_request_raw(&self, U256, Bytes) -> Result; + /// Confirm specific request with already signed data. + #[rpc(name = "signer_confirmRequestRaw")] + fn confirm_request_raw(&self, U256, Bytes) -> Result; - /// Reject the confirmation request. - #[rpc(name = "signer_rejectRequest")] - fn reject_request(&self, U256) -> Result; + /// Reject the confirmation request. + #[rpc(name = "signer_rejectRequest")] + fn reject_request(&self, U256) -> Result; - /// Generates new authorization token. - #[rpc(name = "signer_generateAuthorizationToken")] - fn generate_token(&self) -> Result; + /// Generates new authorization token. + #[rpc(name = "signer_generateAuthorizationToken")] + fn generate_token(&self) -> Result; - /// Generates new web proxy access token for particular domain. - #[rpc(name = "signer_generateWebProxyAccessToken")] - fn generate_web_proxy_token(&self, String) -> Result; + /// Generates new web proxy access token for particular domain. + #[rpc(name = "signer_generateWebProxyAccessToken")] + fn generate_web_proxy_token(&self, String) -> Result; - #[pubsub(name = "signer_pending")] { - /// Subscribe to new pending requests on signer interface. - #[rpc(name = "signer_subscribePending")] - fn subscribe_pending(&self, Self::Metadata, Subscriber>); + /// Subscribe to new pending requests on signer interface. + #[pubsub(subscription = "signer_pending", subscribe, name = "signer_subscribePending")] + fn subscribe_pending(&self, Self::Metadata, Subscriber>); - /// Unsubscribe from pending requests subscription. - #[rpc(name = "signer_unsubscribePending")] - fn unsubscribe_pending(&self, SubscriptionId) -> Result; - } - } + /// Unsubscribe from pending requests subscription. + #[pubsub(subscription = "signer_pending", unsubscribe, name = "signer_unsubscribePending")] + fn unsubscribe_pending(&self, Option, SubscriptionId) -> Result; } diff --git a/rpc/src/v1/traits/traces.rs b/rpc/src/v1/traits/traces.rs index f6efae7395..3ac4964bd5 100644 --- a/rpc/src/v1/traits/traces.rs +++ b/rpc/src/v1/traits/traces.rs @@ -17,48 +17,48 @@ //! Traces specific rpc interface. use jsonrpc_core::Result; -use jsonrpc_macros::Trailing; +use jsonrpc_derive::rpc; use v1::types::{TraceFilter, LocalizedTrace, BlockNumber, Index, CallRequest, Bytes, TraceResults, TraceResultsWithTransactionHash, H256, TraceOptions}; -build_rpc_trait! { - /// Traces specific rpc interface. - pub trait Traces { - type Metadata; +/// Traces specific rpc interface. +#[rpc] +pub trait Traces { + /// RPC Metadata + type Metadata; - /// Returns traces matching given filter. - #[rpc(name = "trace_filter")] - fn filter(&self, TraceFilter) -> Result>>; + /// Returns traces matching given filter. + #[rpc(name = "trace_filter")] + fn filter(&self, TraceFilter) -> Result>>; - /// Returns transaction trace at given index. - #[rpc(name = "trace_get")] - fn trace(&self, H256, Vec) -> Result>; + /// Returns transaction trace at given index. + #[rpc(name = "trace_get")] + fn trace(&self, H256, Vec) -> Result>; - /// Returns all traces of given transaction. - #[rpc(name = "trace_transaction")] - fn transaction_traces(&self, H256) -> Result>>; + /// Returns all traces of given transaction. + #[rpc(name = "trace_transaction")] + fn transaction_traces(&self, H256) -> Result>>; - /// Returns all traces produced at given block. - #[rpc(name = "trace_block")] - fn block_traces(&self, BlockNumber) -> Result>>; + /// Returns all traces produced at given block. + #[rpc(name = "trace_block")] + fn block_traces(&self, BlockNumber) -> Result>>; - /// Executes the given call and returns a number of possible traces for it. - #[rpc(name = "trace_call")] - fn call(&self, CallRequest, TraceOptions, Trailing) -> Result; + /// Executes the given call and returns a number of possible traces for it. + #[rpc(name = "trace_call")] + fn call(&self, CallRequest, TraceOptions, Option) -> Result; - /// Executes all given calls and returns a number of possible traces for each of it. - #[rpc(name = "trace_callMany")] - fn call_many(&self, Vec<(CallRequest, TraceOptions)>, Trailing) -> Result>; + /// Executes all given calls and returns a number of possible traces for each of it. + #[rpc(name = "trace_callMany")] + fn call_many(&self, Vec<(CallRequest, TraceOptions)>, Option) -> Result>; - /// Executes the given raw transaction and returns a number of possible traces for it. - #[rpc(name = "trace_rawTransaction")] - fn raw_transaction(&self, Bytes, TraceOptions, Trailing) -> Result; + /// Executes the given raw transaction and returns a number of possible traces for it. + #[rpc(name = "trace_rawTransaction")] + fn raw_transaction(&self, Bytes, TraceOptions, Option) -> Result; - /// Executes the transaction with the given hash and returns a number of possible traces for it. - #[rpc(name = "trace_replayTransaction")] - fn replay_transaction(&self, H256, TraceOptions) -> Result; + /// Executes the transaction with the given hash and returns a number of possible traces for it. + #[rpc(name = "trace_replayTransaction")] + fn replay_transaction(&self, H256, TraceOptions) -> Result; - /// Executes all the transactions at the given block and returns a number of possible traces for each transaction. - #[rpc(name = "trace_replayBlockTransactions")] - fn replay_block_transactions(&self, BlockNumber, TraceOptions) -> Result>; - } + /// Executes all the transactions at the given block and returns a number of possible traces for each transaction. + #[rpc(name = "trace_replayBlockTransactions")] + fn replay_block_transactions(&self, BlockNumber, TraceOptions) -> Result>; } diff --git a/rpc/src/v1/traits/web3.rs b/rpc/src/v1/traits/web3.rs index e50c0963a6..69d74756ea 100644 --- a/rpc/src/v1/traits/web3.rs +++ b/rpc/src/v1/traits/web3.rs @@ -16,18 +16,18 @@ //! Web3 rpc interface. use jsonrpc_core::Result; +use jsonrpc_derive::rpc; use v1::types::{H256, Bytes}; -build_rpc_trait! { - /// Web3 rpc interface. - pub trait Web3 { - /// Returns current client version. - #[rpc(name = "web3_clientVersion")] - fn client_version(&self) -> Result; +/// Web3 rpc interface. +#[rpc] +pub trait Web3 { + /// Returns current client version. + #[rpc(name = "web3_clientVersion")] + fn client_version(&self) -> Result; - /// Returns sha3 of the given data - #[rpc(name = "web3_sha3")] - fn sha3(&self, Bytes) -> Result; - } + /// Returns sha3 of the given data + #[rpc(name = "web3_sha3")] + fn sha3(&self, Bytes) -> Result; } diff --git a/whisper/Cargo.toml b/whisper/Cargo.toml index fec601586b..8bb59bb5d0 100644 --- a/whisper/Cargo.toml +++ b/whisper/Cargo.toml @@ -25,6 +25,6 @@ slab = "0.3" smallvec = "0.6" tiny-keccak = "1.4" -jsonrpc-core = { git = "https://github.com/paritytech/jsonrpc.git", branch = "parity-2.2" } -jsonrpc-macros = { git = "https://github.com/paritytech/jsonrpc.git", branch = "parity-2.2" } -jsonrpc-pubsub = { git = "https://github.com/paritytech/jsonrpc.git", branch = "parity-2.2" } +jsonrpc-core = "10.0.1" +jsonrpc-derive = "10.0.1" +jsonrpc-pubsub = "10.0.1" diff --git a/whisper/cli/Cargo.toml b/whisper/cli/Cargo.toml index 5147a6b563..4d123c09ab 100644 --- a/whisper/cli/Cargo.toml +++ b/whisper/cli/Cargo.toml @@ -10,9 +10,9 @@ docopt = "1.0" env_logger = "0.5" ethcore-network = { path = "../../util/network" } ethcore-network-devp2p = { path = "../../util/network-devp2p" } -jsonrpc-core = { git = "https://github.com/paritytech/jsonrpc.git", branch = "parity-2.2" } -jsonrpc-http-server = { git = "https://github.com/paritytech/jsonrpc.git", branch = "parity-2.2" } -jsonrpc-pubsub = { git = "https://github.com/paritytech/jsonrpc.git", branch = "parity-2.2" } +jsonrpc-core = "10.0.1" +jsonrpc-http-server = "10.0.1" +jsonrpc-pubsub = "10.0.1" log = "0.4" panic_hook = { path = "../../util/panic-hook" } parity-whisper = { path = "../" } diff --git a/whisper/src/lib.rs b/whisper/src/lib.rs index 2db7108f76..0e79946d9a 100644 --- a/whisper/src/lib.rs +++ b/whisper/src/lib.rs @@ -34,6 +34,7 @@ extern crate smallvec; extern crate tiny_keccak; extern crate jsonrpc_core; +extern crate jsonrpc_derive; extern crate jsonrpc_pubsub; #[macro_use] @@ -42,9 +43,6 @@ extern crate bitflags; #[macro_use] extern crate log; -#[macro_use] -extern crate jsonrpc_macros; - #[macro_use] extern crate serde_derive; diff --git a/whisper/src/rpc/filter.rs b/whisper/src/rpc/filter.rs index 9c091de0b9..46cefd61e0 100644 --- a/whisper/src/rpc/filter.rs +++ b/whisper/src/rpc/filter.rs @@ -21,7 +21,7 @@ use std::{sync::{Arc, atomic, atomic::AtomicBool, mpsc}, thread}; use ethereum_types::{H256, H512}; use ethkey::Public; -use jsonrpc_macros::pubsub::{Subscriber, Sink}; +use jsonrpc_pubsub::typed::{Subscriber, Sink}; use parking_lot::{Mutex, RwLock}; use rand::{Rng, OsRng}; diff --git a/whisper/src/rpc/mod.rs b/whisper/src/rpc/mod.rs index c3958f77f7..03d98b51ff 100644 --- a/whisper/src/rpc/mod.rs +++ b/whisper/src/rpc/mod.rs @@ -24,8 +24,8 @@ use std::sync::Arc; use jsonrpc_core::{Error, ErrorCode, Metadata}; -use jsonrpc_pubsub::{Session, PubSubMetadata, SubscriptionId}; -use jsonrpc_macros::pubsub; +use jsonrpc_derive::rpc; +use jsonrpc_pubsub::{Session, PubSubMetadata, SubscriptionId, typed::Subscriber}; use ethereum_types::H256; use memzero::Memzero; @@ -68,81 +68,78 @@ fn abridge_topic(topic: &[u8]) -> Topic { abridged.into() } -build_rpc_trait! { - /// Whisper RPC interface. - pub trait Whisper { - /// Info about the node. - #[rpc(name = "shh_info")] - fn info(&self) -> Result; - - /// Generate a new asymmetric key pair and return an identity. - #[rpc(name = "shh_newKeyPair")] - fn new_key_pair(&self) -> Result; - - /// Import the given SECP2561k private key and return an identity. - #[rpc(name = "shh_addPrivateKey")] - fn add_private_key(&self, types::Private) -> Result; - - /// Generate a new symmetric key and return an identity. - #[rpc(name = "shh_newSymKey")] - fn new_sym_key(&self) -> Result; - - /// Import the given symmetric key and return an identity. - #[rpc(name = "shh_addSymKey")] - fn add_sym_key(&self, types::Symmetric) -> Result; - - /// Get public key. Succeeds if identity is stored and asymmetric. - #[rpc(name = "shh_getPublicKey")] - fn get_public(&self, types::Identity) -> Result; - - /// Get private key. Succeeds if identity is stored and asymmetric. - #[rpc(name = "shh_getPrivateKey")] - fn get_private(&self, types::Identity) -> Result; - - #[rpc(name = "shh_getSymKey")] - fn get_symmetric(&self, types::Identity) -> Result; - - /// Delete key pair denoted by given identity. - /// - /// Return true if successfully removed, false if unknown, - /// and error otherwise. - #[rpc(name = "shh_deleteKey")] - fn remove_key(&self, types::Identity) -> Result; - - /// Post a message to the network with given parameters. - #[rpc(name = "shh_post")] - fn post(&self, types::PostRequest) -> Result; - - /// Create a new polled filter. - #[rpc(name = "shh_newMessageFilter")] - fn new_filter(&self, types::FilterRequest) -> Result; - - /// Poll changes on a polled filter. - #[rpc(name = "shh_getFilterMessages")] - fn poll_changes(&self, types::Identity) -> Result, Error>; - - /// Delete polled filter. Return bool indicating success. - #[rpc(name = "shh_deleteMessageFilter")] - fn delete_filter(&self, types::Identity) -> Result; - } +/// Whisper RPC interface. +#[rpc] +pub trait Whisper { + /// Info about the node. + #[rpc(name = "shh_info")] + fn info(&self) -> Result; + + /// Generate a new asymmetric key pair and return an identity. + #[rpc(name = "shh_newKeyPair")] + fn new_key_pair(&self) -> Result; + + /// Import the given SECP2561k private key and return an identity. + #[rpc(name = "shh_addPrivateKey")] + fn add_private_key(&self, types::Private) -> Result; + + /// Generate a new symmetric key and return an identity. + #[rpc(name = "shh_newSymKey")] + fn new_sym_key(&self) -> Result; + + /// Import the given symmetric key and return an identity. + #[rpc(name = "shh_addSymKey")] + fn add_sym_key(&self, types::Symmetric) -> Result; + + /// Get public key. Succeeds if identity is stored and asymmetric. + #[rpc(name = "shh_getPublicKey")] + fn get_public(&self, types::Identity) -> Result; + + /// Get private key. Succeeds if identity is stored and asymmetric. + #[rpc(name = "shh_getPrivateKey")] + fn get_private(&self, types::Identity) -> Result; + + #[rpc(name = "shh_getSymKey")] + fn get_symmetric(&self, types::Identity) -> Result; + + /// Delete key pair denoted by given identity. + /// + /// Return true if successfully removed, false if unknown, + /// and error otherwise. + #[rpc(name = "shh_deleteKey")] + fn remove_key(&self, types::Identity) -> Result; + + /// Post a message to the network with given parameters. + #[rpc(name = "shh_post")] + fn post(&self, types::PostRequest) -> Result; + + /// Create a new polled filter. + #[rpc(name = "shh_newMessageFilter")] + fn new_filter(&self, types::FilterRequest) -> Result; + + /// Poll changes on a polled filter. + #[rpc(name = "shh_getFilterMessages")] + fn poll_changes(&self, types::Identity) -> Result, Error>; + + /// Delete polled filter. Return bool indicating success. + #[rpc(name = "shh_deleteMessageFilter")] + fn delete_filter(&self, types::Identity) -> Result; } -build_rpc_trait! { - /// Whisper RPC pubsub. - pub trait WhisperPubSub { - type Metadata; +/// Whisper RPC pubsub. +#[rpc] +pub trait WhisperPubSub { + // RPC Metadata + type Metadata; - #[pubsub(name = "shh_subscription")] { - /// Subscribe to messages matching the filter. - #[rpc(name = "shh_subscribe")] - fn subscribe(&self, Self::Metadata, pubsub::Subscriber, types::FilterRequest); + /// Subscribe to messages matching the filter. + #[pubsub(subscription = "shh_subscription", subscribe, name = "shh_subscribe")] + fn subscribe(&self, Self::Metadata, Subscriber, types::FilterRequest); - /// Unsubscribe from filter matching given ID. Return - /// true on success, error otherwise. - #[rpc(name = "shh_unsubscribe")] - fn unsubscribe(&self, SubscriptionId) -> Result; - } - } + /// Unsubscribe from filter matching given ID. Return + /// true on success, error otherwise. + #[pubsub(subscription = "shh_subscription", unsubscribe, name = "shh_unsubscribe")] + fn unsubscribe(&self, Option, SubscriptionId) -> Result; } /// Something which can send messages to the network. @@ -364,7 +361,7 @@ impl WhisperPubSub for fn subscribe( &self, _meta: Self::Metadata, - subscriber: pubsub::Subscriber, + subscriber: Subscriber, req: types::FilterRequest, ) { match Filter::new(req) { @@ -377,7 +374,7 @@ impl WhisperPubSub for } } - fn unsubscribe(&self, id: SubscriptionId) -> Result { + fn unsubscribe(&self, _: Option, id: SubscriptionId) -> Result { use std::str::FromStr; let res = match id { From 1b3b9b28878155a9422f3f0fbdc032b6da5424f7 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Tue, 5 Feb 2019 14:47:25 +0000 Subject: [PATCH 045/168] Update to jsonrpc-derive 10.0.2, fixes aliases bug (#10300) --- Cargo.lock | 8 ++++---- rpc/Cargo.toml | 2 +- whisper/Cargo.toml | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3a16c22d9d..370d3bdec4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1789,7 +1789,7 @@ dependencies = [ [[package]] name = "jsonrpc-derive" -version = "10.0.1" +version = "10.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2613,7 +2613,7 @@ dependencies = [ "hardware-wallet 1.12.0", "itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-derive 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-derive 10.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-http-server 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-ipc-server 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-pubsub 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2765,7 +2765,7 @@ dependencies = [ "ethkey 0.3.0", "hex 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-derive 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-derive 10.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-pubsub 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "memzero 0.1.0", @@ -4530,7 +4530,7 @@ dependencies = [ "checksum jni 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1ecfa3b81afc64d9a6539c4eece96ac9a93c551c713a313800dade8e33d7b5c1" "checksum jni-sys 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" "checksum jsonrpc-core 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a5152c3fda235dfd68341b3edf4121bc4428642c93acbd6de88c26bf95fc5d7" -"checksum jsonrpc-derive 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8de4e89cf0938dec51a14255556172b1f5208e4d8999d613813eceeae1405d37" +"checksum jsonrpc-derive 10.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c14be84e86c75935be83a34c6765bf31f97ed6c9163bb0b83007190e9703940a" "checksum jsonrpc-http-server 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "99e1ce36c7cc9dcab398024d76849ab2cb917ee812653bce6f74fc9eb7c82d16" "checksum jsonrpc-ipc-server 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fac6b8682243740a32bfb288880c71cc06eca29616cdf551e4136a190b11b96d" "checksum jsonrpc-pubsub 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "56608ed54b1b2a69f4357cb8bdfbcbd99fe1179383c03a09bb428931bd35f592" diff --git a/rpc/Cargo.toml b/rpc/Cargo.toml index f64ead6b31..9fabb8578a 100644 --- a/rpc/Cargo.toml +++ b/rpc/Cargo.toml @@ -28,7 +28,7 @@ transient-hashmap = "0.4" itertools = "0.5" jsonrpc-core = "10.0.1" -jsonrpc-derive = "10.0.1" +jsonrpc-derive = "10.0.2" jsonrpc-http-server = "10.0.1" jsonrpc-ws-server = "10.0.1" jsonrpc-ipc-server = "10.0.1" diff --git a/whisper/Cargo.toml b/whisper/Cargo.toml index 8bb59bb5d0..e29abd982f 100644 --- a/whisper/Cargo.toml +++ b/whisper/Cargo.toml @@ -26,5 +26,5 @@ smallvec = "0.6" tiny-keccak = "1.4" jsonrpc-core = "10.0.1" -jsonrpc-derive = "10.0.1" +jsonrpc-derive = "10.0.2" jsonrpc-pubsub = "10.0.1" From 8ab6d8981027426dd5a6d4de6c2ed301d0a724ae Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Wed, 6 Feb 2019 14:54:35 +0100 Subject: [PATCH 046/168] fix(secret-store): deprecation warning (#10301) use of deprecated item 'core::str::::trim_left_matches': superseded by `trim_start_matches` --- secret-store/src/listener/http_listener.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/secret-store/src/listener/http_listener.rs b/secret-store/src/listener/http_listener.rs index cbe6c42d3a..aa67ec5c66 100644 --- a/secret-store/src/listener/http_listener.rs +++ b/secret-store/src/listener/http_listener.rs @@ -334,7 +334,7 @@ fn parse_request(method: &HttpMethod, uri_path: &str, body: &[u8]) -> Request { Err(_) => return Request::Invalid, }; - let path: Vec = uri_path.trim_left_matches('/').split('/').map(Into::into).collect(); + let path: Vec = uri_path.trim_start_matches('/').split('/').map(Into::into).collect(); if path.len() == 0 { return Request::Invalid; } From a3e39c9858c088791b07bfd5ba3b7f9c8e80f179 Mon Sep 17 00:00:00 2001 From: Andronik Ordian Date: Wed, 6 Feb 2019 19:53:34 +0300 Subject: [PATCH 047/168] update ring to 0.14 (#10262) * cargo upgrade hyper-rustls --all * cargo upgrade parity-crypto --all * update Cargo.lock * propagate NonZeroU32 * use NonZeroU32::new_unchecked for crypto::KEY_ITERATIONS * update Cargo.lock * replace unsafe code with lazy_static --- Cargo.lock | 245 +++++++++--------- Cargo.toml | 1 + accounts/ethkey/Cargo.toml | 2 +- accounts/ethstore/Cargo.toml | 3 +- accounts/ethstore/src/account/crypto.rs | 21 +- accounts/ethstore/src/account/kdf.rs | 3 +- accounts/ethstore/src/account/safe_account.rs | 21 +- accounts/ethstore/src/accounts_dir/disk.rs | 20 +- accounts/ethstore/src/accounts_dir/mod.rs | 5 +- accounts/ethstore/src/accounts_dir/vault.rs | 18 +- accounts/ethstore/src/ethstore.rs | 18 +- accounts/ethstore/src/json/kdf.rs | 3 +- accounts/ethstore/src/json/vault_file.rs | 9 +- accounts/ethstore/src/json/vault_key_file.rs | 9 +- accounts/ethstore/src/lib.rs | 2 + accounts/ethstore/src/presale.rs | 4 +- ethcore/Cargo.toml | 2 +- ethcore/private-tx/Cargo.toml | 2 +- parity/account.rs | 5 +- parity/configuration.rs | 19 +- parity/lib.rs | 4 + parity/params.rs | 5 +- parity/presale.rs | 3 +- rpc/Cargo.toml | 2 +- secret-store/Cargo.toml | 2 +- util/fetch/Cargo.toml | 2 +- util/network-devp2p/Cargo.toml | 2 +- util/network/Cargo.toml | 2 +- whisper/Cargo.toml | 2 +- 29 files changed, 256 insertions(+), 180 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 370d3bdec4..6a77fb3b72 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -58,7 +58,7 @@ name = "atty" version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.48 (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.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -70,7 +70,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "backtrace-sys 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-demangle 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -80,8 +80,8 @@ name = "backtrace-sys" version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -98,6 +98,14 @@ dependencies = [ "safemem 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "base64" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "bincode" version = "0.8.0" @@ -192,7 +200,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "cc" -version = "1.0.25" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -270,7 +278,7 @@ name = "cmake" version = "0.1.35" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -487,10 +495,10 @@ dependencies = [ [[package]] name = "ct-logs" -version = "0.4.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "sct 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sct 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -499,7 +507,7 @@ version = "1.1.1" source = "git+https://github.com/paritytech/rust-ctrlc.git#b523017108bb2d571a7a69bd97bc406e63bc7a9d" dependencies = [ "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -604,7 +612,7 @@ version = "0.5.7" source = "git+https://github.com/paritytech/rust-secp256k1#ccc06e7480148b723eb44ac56cf4d20eec380b6f" dependencies = [ "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -718,7 +726,7 @@ dependencies = [ "num 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-crypto 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-crypto 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-machine 0.1.0", "parity-snappy 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -891,7 +899,7 @@ dependencies = [ "fetch 0.1.0", "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.4.2 (git+https://github.com/cheme/heapsize.git?branch=ec-macfix)", - "hyper 0.12.11 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.12.19 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "linked-hash-map 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -915,8 +923,8 @@ dependencies = [ "ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethkey 0.3.0", "ipnetwork 0.12.8 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-crypto 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-crypto 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-snappy 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "rlp 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -937,11 +945,11 @@ dependencies = [ "igd 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "ipnetwork 0.12.8 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-crypto 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-crypto 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-path 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "parity-snappy 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -980,7 +988,7 @@ dependencies = [ "keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-crypto 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-crypto 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "patricia-trie 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "patricia-trie-ethereum 0.1.0", @@ -1012,14 +1020,14 @@ dependencies = [ "ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethkey 0.3.0", "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper 0.12.11 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.12.19 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb-rocksdb 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-crypto 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-crypto 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-runtime 0.1.0", "parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1145,7 +1153,7 @@ dependencies = [ "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "memzero 0.1.0", - "parity-crypto 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-crypto 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-wordlist 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1178,10 +1186,11 @@ dependencies = [ "ethereum-types 0.4.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)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-crypto 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-crypto 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-wordlist 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1288,7 +1297,7 @@ version = "0.0.1" dependencies = [ "fetch 0.1.0", "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper 0.12.11 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.12.19 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1317,7 +1326,7 @@ name = "fdlimit" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1326,9 +1335,9 @@ version = "0.1.0" dependencies = [ "bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "http 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper 0.12.11 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper-rustls 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)", + "http 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.12.19 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper-rustls 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1340,7 +1349,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "heapsize 0.4.2 (git+https://github.com/cheme/heapsize.git?branch=ec-macfix)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1361,7 +1370,7 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", "libloading 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1449,7 +1458,7 @@ dependencies = [ "bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "http 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", + "http 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", "indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1525,8 +1534,8 @@ name = "hidapi" version = "0.3.1" source = "git+https://github.com/paritytech/hidapi-rs#d4d323767d6f27cf5a3d73fbae0b0f2134d579bf" dependencies = [ - "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1540,7 +1549,7 @@ dependencies = [ [[package]] name = "http" -version = "0.1.13" +version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1588,14 +1597,14 @@ dependencies = [ [[package]] name = "hyper" -version = "0.12.11" +version = "0.12.19" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", "futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "h2 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "http 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", + "http 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", "httparse 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1607,26 +1616,27 @@ dependencies = [ "tokio-io 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-reactor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-tcp 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-threadpool 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-timer 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", "want 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "hyper-rustls" -version = "0.14.0" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "ct-logs 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "ct-logs 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "http 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper 0.12.11 (registry+https://github.com/rust-lang/crates.io-index)", - "rustls 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "http 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.12.19 (registry+https://github.com/rust-lang/crates.io-index)", + "rustls 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-rustls 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-rustls 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-tcp 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "webpki 0.18.1 (registry+https://github.com/rust-lang/crates.io-index)", - "webpki-roots 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "webpki 0.19.1 (registry+https://github.com/rust-lang/crates.io-index)", + "webpki-roots 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1680,7 +1690,7 @@ name = "iovec" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1723,9 +1733,9 @@ name = "jemalloc-sys" version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)", "fs_extra 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1734,7 +1744,7 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "jemalloc-sys 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1802,7 +1812,7 @@ name = "jsonrpc-http-server" version = "10.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "hyper 0.12.11 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.12.19 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-server-utils 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1962,7 +1972,7 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.43" +version = "0.2.48" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1970,7 +1980,7 @@ name = "libloading" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1980,7 +1990,7 @@ version = "0.3.0" source = "git+https://github.com/paritytech/libusb-rs#442708954a720bc89a9cf41e7be021a778bdbc27" dependencies = [ "bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", "libusb-sys 0.2.4 (git+https://github.com/paritytech/libusb-sys)", ] @@ -1989,8 +1999,8 @@ name = "libusb-sys" version = "0.2.4" source = "git+https://github.com/paritytech/libusb-sys#1d33d9840a82adaf4d6a1a0f5141f022e5676802" dependencies = [ - "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2069,7 +2079,7 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2078,7 +2088,7 @@ name = "memmap" version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2155,7 +2165,7 @@ dependencies = [ "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazycell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2191,7 +2201,7 @@ version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2244,7 +2254,7 @@ version = "0.2.33" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2329,7 +2339,7 @@ name = "num_cpus" version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2402,11 +2412,11 @@ dependencies = [ [[package]] name = "parity-crypto" -version = "0.2.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "ring 0.13.5 (registry+https://github.com/rust-lang/crates.io-index)", + "ring 0.14.3 (registry+https://github.com/rust-lang/crates.io-index)", "rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", "tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2418,7 +2428,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2461,6 +2471,7 @@ dependencies = [ "keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb-rocksdb 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "migration-rocksdb 0.1.0", "node-filter 1.12.0", @@ -2568,7 +2579,7 @@ name = "parity-rocksdb" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", "local-encoding 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-rocksdb-sys 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2579,7 +2590,7 @@ version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cmake 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", "local-encoding 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-snappy-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2625,7 +2636,7 @@ dependencies = [ "multihash 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "order-stat 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-crypto 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-crypto 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-runtime 0.1.0", "parity-updater 1.12.0", "parity-version 2.4.0", @@ -2678,7 +2689,7 @@ name = "parity-snappy" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", "parity-snappy-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2688,7 +2699,7 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cmake 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2770,7 +2781,7 @@ dependencies = [ "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "memzero 0.1.0", "ordered-float 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-crypto 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-crypto 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "rlp 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2832,7 +2843,7 @@ name = "parking_lot_core" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2845,7 +2856,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", "petgraph 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3087,7 +3098,7 @@ version = "0.3.22" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3097,7 +3108,7 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3108,7 +3119,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3120,7 +3131,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", "rand_chacha 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3203,7 +3214,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3289,12 +3300,12 @@ dependencies = [ [[package]] name = "ring" -version = "0.13.5" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", "untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3344,7 +3355,7 @@ version = "1.0.2" 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.43 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", "rprompt 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3360,7 +3371,7 @@ version = "0.2.36" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3396,15 +3407,15 @@ dependencies = [ [[package]] name = "rustls" -version = "0.13.1" +version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", + "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "ring 0.13.5 (registry+https://github.com/rust-lang/crates.io-index)", - "sct 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ring 0.14.3 (registry+https://github.com/rust-lang/crates.io-index)", + "sct 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "webpki 0.18.1 (registry+https://github.com/rust-lang/crates.io-index)", + "webpki 0.19.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3437,10 +3448,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "sct" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "ring 0.13.5 (registry+https://github.com/rust-lang/crates.io-index)", + "ring 0.14.3 (registry+https://github.com/rust-lang/crates.io-index)", "untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3570,7 +3581,7 @@ version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3665,7 +3676,7 @@ version = "0.3.1" 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.43 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3682,7 +3693,7 @@ name = "termion" version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", "redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3708,7 +3719,7 @@ name = "thread-id" version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3739,7 +3750,7 @@ name = "time" version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3888,12 +3899,13 @@ dependencies = [ [[package]] name = "tokio-rustls" -version = "0.7.2" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rustls 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", - "webpki 0.18.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "rustls 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "webpki 0.19.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3973,7 +3985,7 @@ dependencies = [ "bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", "mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4278,7 +4290,7 @@ dependencies = [ "byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)", "ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "parity-wasm 0.31.3 (registry+https://github.com/rust-lang/crates.io-index)", "pwasm-utils 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4299,20 +4311,20 @@ dependencies = [ [[package]] name = "webpki" -version = "0.18.1" +version = "0.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "ring 0.13.5 (registry+https://github.com/rust-lang/crates.io-index)", + "ring 0.14.3 (registry+https://github.com/rust-lang/crates.io-index)", "untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "webpki-roots" -version = "0.15.0" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "webpki 0.18.1 (registry+https://github.com/rust-lang/crates.io-index)", + "webpki 0.19.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4422,6 +4434,7 @@ dependencies = [ "checksum backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "89a47830402e9981c5c41223151efcced65a0510c13097c769cede7efb34782a" "checksum backtrace-sys 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)" = "c66d56ac8dabd07f6aacdaf633f4b8262f5b3601a810a0dcddffd5c22c69daa0" "checksum base-x 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "5cda5d0f5584d129112ad8bf4775b9fd2b9f1e30738c7b1a25314ba2244d6a51" +"checksum base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e" "checksum base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "489d6c0ed21b11d038c31b6ceccca973e65d73ba3bd8ecb9a2babf5546164643" "checksum bincode 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e103c8b299b28a9c6990458b7013dc4a8356a9b854c51b9883241f5866fac36e" "checksum bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d9bf6104718e80d7b26a68fdbacff3481cfc05df670821affc7e9cbc1884400c" @@ -4435,7 +4448,7 @@ dependencies = [ "checksum byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "90492c5858dd7d2e78691cfb89f90d273a2800fc11d98f60786e5d87e2f83781" "checksum bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "0ce55bd354b095246fc34caf4e9e242f5297a7fd938b090cadfea6eee614aa62" "checksum cast 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "926013f2860c46252efceabb19f4a6b308197505082c609025aa6706c011d427" -"checksum cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "f159dfd43363c4d08055a07703eb7a3406b0dac4d0584d96965a3262db3c9d16" +"checksum cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4a8b715cb4597106ea87c7c84b2f1d452c7492033765df7f32651e66fcf749" "checksum cesu8 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" "checksum cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0c4e7bb64a8ebb0d856483e1e682ea3422f883c5f5615a90d51a2c82fe87fdd3" "checksum chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "45912881121cb26fad7c38c17ba7daa18764771836b34fab7d3fbd93ed633878" @@ -4462,7 +4475,7 @@ dependencies = [ "checksum crunchy 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c240f247c278fa08a6d4820a6a222bfc6e0d999e51ba67be94f44c905b2161f2" "checksum csv 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6d54f6b0fd69128a2894b1a3e57af5849a0963c1cc77b165d30b896e40296452" "checksum csv-core 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4dd8e6d86f7ba48b4276ef1317edc8cc36167546d8972feb4a2b5fec0b374105" -"checksum ct-logs 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "95a4bf5107667e12bf6ce31a3a5066d67acc88942b6742117a41198734aaccaa" +"checksum ct-logs 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1b4660f8b07a560a88c02d76286edb9f0d5d64e495d2b0f233186155aa51be1f" "checksum ctrlc 1.1.1 (git+https://github.com/paritytech/rust-ctrlc.git)" = "" "checksum difference 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b3304d19798a8e067e48d8e69b2c37f0b5e9b4e462504ad9e27e9f3fce02bba8" "checksum digest 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "03b072242a8cbaf9c145665af9d250c59af3b958f83ed6824e13533cf76d5b90" @@ -4507,12 +4520,12 @@ 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 home 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "80dff82fb58cfbbc617fb9a9184b010be0529201553cda50ad04372bc2333aff" -"checksum http 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "24f58e8c2d8e886055c3ead7b28793e1455270b5fb39650984c224bc538ba581" +"checksum http 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "1a10e5b573b9a0146545010f50772b9e8b1dd0a256564cc4307694c68832a2f5" "checksum httparse 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e8734b0cfd3bc3e101ec59100e101c2eecd19282202e87808b3037b442777a83" "checksum humantime 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0484fda3e7007f2a4a0d9c3a703ca38c71c54c55602ce4660c419fd32e188c9e" "checksum hyper 0.11.27 (registry+https://github.com/rust-lang/crates.io-index)" = "34a590ca09d341e94cddf8e5af0bbccde205d5fbc2fa3c09dd67c7f85cea59d7" -"checksum hyper 0.12.11 (registry+https://github.com/rust-lang/crates.io-index)" = "78d50abbd1790e0f4c74cb1d4a2211b439bac661d54107ad5564c55e77906762" -"checksum hyper-rustls 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "68f2aa6b1681795bf4da8063f718cd23145aa0c9a5143d9787b345aa60d38ee4" +"checksum hyper 0.12.19 (registry+https://github.com/rust-lang/crates.io-index)" = "f1ebec079129e43af5e234ef36ee3d7e6085687d145b7ea653b262d16c6b65f1" +"checksum hyper-rustls 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ff2c61fbda2bc72e793e329190a3e8f0ae74cb896905c8b301304c4c93f2755" "checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e" "checksum if_chain 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4bac95d9aa0624e7b78187d6fb8ab012b41d9f6f54b1bcb61e61c4845f8357ec" "checksum igd 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8a254e265e8810deb357a9de757f784787ec415d056ededf410c0aa460afee9e" @@ -4545,7 +4558,7 @@ dependencies = [ "checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" "checksum lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a374c89b9db55895453a74c1e38861d9deec0b01b405a82516e9d5de4820dea1" "checksum lazycell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ddba4c30a78328befecec92fc94970e53b3ae385827d28620f0f5bb2493081e0" -"checksum libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)" = "76e3a3ef172f1a0b9a9ff0dd1491ae5e6c948b94479a3021819ba7d860c8645d" +"checksum libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)" = "e962c7641008ac010fa60a7dfdc1712449f29c44ef2d4702394aea943ee75047" "checksum libloading 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9c3ad660d7cb8c5822cd83d10897b0f1f1526792737a179e73896152f85b88c2" "checksum libusb 0.3.0 (git+https://github.com/paritytech/libusb-rs)" = "" "checksum libusb-sys 0.2.4 (git+https://github.com/paritytech/libusb-sys)" = "" @@ -4590,7 +4603,7 @@ dependencies = [ "checksum ordermap 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a86ed3f5f244b372d6b1a00b72ef7f8876d0bc6a78a4c9985c53614041512063" "checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37" "checksum parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fa5168b4cf41f3835e4bc6ffb32f51bc9365dc50cb351904595b3931d917fd0c" -"checksum parity-crypto 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8adf489acb31f1922db0ce43803b6f48a425241a8473611be3cc625a8e4a4c47" +"checksum parity-crypto 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b9db194dfbcfe3b398d63d765437a5c7232d59906e203055f0e993f6458ff1" "checksum parity-daemonize 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c6dbaae957a3ddd307fe0ea0361251ceb651a19810b60d404080b258384da292" "checksum parity-path 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5962540f99d3895d9addf535f37ab1397886bc2c68e59efd040ef458e5f8c3f7" "checksum parity-rocksdb 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cd55d2d6d6000ec99f021cf52c9acc7d2a402e14f95ced4c5de230696fabe00b" @@ -4649,7 +4662,7 @@ dependencies = [ "checksum regex-syntax 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "747ba3b235651f6e2f67dfa8bcdcd073ddb7c243cb21c442fc12395dfcac212d" "checksum relay 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1576e382688d7e9deecea24417e350d3062d97e32e45d70b1cde65994ff1489a" "checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5" -"checksum ring 0.13.5 (registry+https://github.com/rust-lang/crates.io-index)" = "2c4db68a2e35f3497146b7e4563df7d4773a2433230c5e4b448328e31740458a" +"checksum ring 0.14.3 (registry+https://github.com/rust-lang/crates.io-index)" = "be5386a5f59e5f5bcaea38b50ad26c09e3918a0abc0610640b3be5cfd85d6894" "checksum rlp 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "524c5ad554859785dfc8469df3ed5e0b5784d4d335877ed47c8d90fc0eb238fe" "checksum rlp 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "16d1effe9845d54f90e7be8420ee49e5c94623140b97ee4bc6fb5bfddb745720" "checksum rpassword 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b273c91bd242ca03ad6d71c143b6f17a48790e61f21a6c78568fa2b6774a24a4" @@ -4660,13 +4673,13 @@ dependencies = [ "checksum rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "403bb3a286107a04825a5f82e1270acc1e14028d3d554d7a1e08914549575ab8" "checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" "checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" -"checksum rustls 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)" = "942b71057b31981152970d57399c25f72e27a6ee0d207a669d8304cabf44705b" +"checksum rustls 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)" = "38af00e78b66109e7184a0ee16940f41583161b7ec0518af258e4bcaed15db25" "checksum ryu 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7153dd96dade874ab973e098cb62fcdbb89a03682e46b144fd09550998d4a4a7" "checksum safemem 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8dca453248a96cb0749e36ccdfe2b0b4e54a61bfef89fb97ec621eb8e0a93dd9" "checksum same-file 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "10f7794e2fda7f594866840e95f5c5962e886e228e68b6505885811a94dd728c" "checksum scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "332ffa32bf586782a3efaeb58f127980944bbc8c4d6913a86107ac2a5ab24b28" "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" -"checksum sct 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cb8f61f9e6eadd062a71c380043d28036304a4706b3c4dd001ff3387ed00745a" +"checksum sct 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2f5adf8fbd58e1b1b52699dc8bed2630faecb6d8c7bee77d009d6bbe4af569b9" "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" "checksum serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)" = "15c141fc7027dd265a47c090bf864cf62b42c4d228bbcf4e51a0c9e2b0d3f7ef" @@ -4717,7 +4730,7 @@ dependencies = [ "checksum tokio-named-pipes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9d282d483052288b2308ba5ee795f5673b159c9bdf63c385a05609da782a5eae" "checksum tokio-reactor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "4b26fd37f1125738b2170c80b551f69ff6fecb277e6e5ca885e53eec2b005018" "checksum tokio-retry 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f05746ae87dca83a2016b4f5dba5b237b897dd12fd324f60afe282112f16969a" -"checksum tokio-rustls 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "208d62fa3e015426e3c64039d9d20adf054a3c9b4d9445560f1c41c75bef3eab" +"checksum tokio-rustls 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7223fa02f4b2d9f3736f13cc3dea3723aaec57ca4b3dded922126ebbb2cb8ce9" "checksum tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "24da22d077e0f15f55162bdbdc661228c1581892f52074fb242678d015b45162" "checksum tokio-tcp 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7ad235e9dadd126b2d47f6736f65aa1fdcd6420e66ca63f44177bc78df89f912" "checksum tokio-threadpool 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "bbd8a8b911301c60cbfaa2a6588fb210e5c1038375b8bdecc47aa09a94c3c05f" @@ -4760,8 +4773,8 @@ dependencies = [ "checksum want 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a05d9d966753fa4b5c8db73fcab5eed4549cfe0e1e4e66911e5564a0085c35d1" "checksum want 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "797464475f30ddb8830cc529aaaae648d581f99e2036a928877dfde027ddf6b3" "checksum wasmi 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9b4a6d379e9332b1b1f52c5a87f2481c85c7c931d8ec411963dfb8f26b1ec1e3" -"checksum webpki 0.18.1 (registry+https://github.com/rust-lang/crates.io-index)" = "17d7967316d8411ca3b01821ee6c332bde138ba4363becdb492f12e514daa17f" -"checksum webpki-roots 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "85d1f408918fd590908a70d36b7ac388db2edc221470333e4d6e5b598e44cabf" +"checksum webpki 0.19.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4f7e1cd7900a3a6b65a3e8780c51a3e6b59c0e2c55c6dc69578c288d69f7d082" +"checksum webpki-roots 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c10fa4212003ba19a564f25cd8ab572c6791f99a03cc219c13ed35ccab00de0e" "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" "checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0" "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" diff --git a/Cargo.toml b/Cargo.toml index 547a4af20a..6ef02c124a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -80,6 +80,7 @@ pretty_assertions = "0.1" ipnetwork = "0.12.6" tempdir = "0.3" fake-fetch = { path = "util/fake-fetch" } +lazy_static = "1.2.0" [target.'cfg(windows)'.dependencies] winapi = { version = "0.3.4", features = ["winsock2", "winuser", "shellapi"] } diff --git a/accounts/ethkey/Cargo.toml b/accounts/ethkey/Cargo.toml index 3dddcc1ce1..ec784bd11d 100644 --- a/accounts/ethkey/Cargo.toml +++ b/accounts/ethkey/Cargo.toml @@ -6,7 +6,7 @@ authors = ["Parity Technologies "] [dependencies] byteorder = "1.0" edit-distance = "2.0" -parity-crypto = "0.2" +parity-crypto = "0.3.0" eth-secp256k1 = { git = "https://github.com/paritytech/rust-secp256k1" } ethereum-types = "0.4" lazy_static = "1.0" diff --git a/accounts/ethstore/Cargo.toml b/accounts/ethstore/Cargo.toml index 96d24d8c31..4563a80327 100644 --- a/accounts/ethstore/Cargo.toml +++ b/accounts/ethstore/Cargo.toml @@ -16,12 +16,13 @@ tiny-keccak = "1.4" time = "0.1.34" itertools = "0.5" parking_lot = "0.7" -parity-crypto = "0.2" +parity-crypto = "0.3.0" ethereum-types = "0.4" dir = { path = "../../util/dir" } smallvec = "0.6" parity-wordlist = "1.0" tempdir = "0.3" +lazy_static = "1.2.0" [dev-dependencies] matches = "0.1" diff --git a/accounts/ethstore/src/account/crypto.rs b/accounts/ethstore/src/account/crypto.rs index e2cc5dc515..a3f6f9e9a3 100644 --- a/accounts/ethstore/src/account/crypto.rs +++ b/accounts/ethstore/src/account/crypto.rs @@ -15,6 +15,7 @@ // along with Parity Ethereum. If not, see . use std::str; +use std::num::NonZeroU32; use ethkey::{Password, Secret}; use {json, Error, crypto}; use crypto::Keccak256; @@ -73,12 +74,12 @@ impl From for String { impl Crypto { /// Encrypt account secret - pub fn with_secret(secret: &Secret, password: &Password, iterations: u32) -> Result { + pub fn with_secret(secret: &Secret, password: &Password, iterations: NonZeroU32) -> Result { Crypto::with_plain(&*secret, password, iterations) } /// Encrypt custom plain data - pub fn with_plain(plain: &[u8], password: &Password, iterations: u32) -> Result { + pub fn with_plain(plain: &[u8], password: &Password, iterations: NonZeroU32) -> Result { let salt: [u8; 32] = Random::random(); let iv: [u8; 16] = Random::random(); @@ -159,13 +160,17 @@ impl Crypto { #[cfg(test)] mod tests { use ethkey::{Generator, Random}; - use super::{Crypto, Error}; + use super::{Crypto, Error, NonZeroU32}; + + lazy_static! { + static ref ITERATIONS: NonZeroU32 = NonZeroU32::new(10240).expect("10240 > 0; qed"); + } #[test] fn crypto_with_secret_create() { let keypair = Random.generate().unwrap(); let passwd = "this is sparta".into(); - let crypto = Crypto::with_secret(keypair.secret(), &passwd, 10240).unwrap(); + let crypto = Crypto::with_secret(keypair.secret(), &passwd, *ITERATIONS).unwrap(); let secret = crypto.secret(&passwd).unwrap(); assert_eq!(keypair.secret(), &secret); } @@ -173,7 +178,7 @@ mod tests { #[test] fn crypto_with_secret_invalid_password() { let keypair = Random.generate().unwrap(); - let crypto = Crypto::with_secret(keypair.secret(), &"this is sparta".into(), 10240).unwrap(); + let crypto = Crypto::with_secret(keypair.secret(), &"this is sparta".into(), *ITERATIONS).unwrap(); assert_matches!(crypto.secret(&"this is sparta!".into()), Err(Error::InvalidPassword)) } @@ -181,7 +186,7 @@ mod tests { fn crypto_with_null_plain_data() { let original_data = b""; let passwd = "this is sparta".into(); - let crypto = Crypto::with_plain(&original_data[..], &passwd, 10240).unwrap(); + let crypto = Crypto::with_plain(&original_data[..], &passwd, *ITERATIONS).unwrap(); let decrypted_data = crypto.decrypt(&passwd).unwrap(); assert_eq!(original_data[..], *decrypted_data); } @@ -190,7 +195,7 @@ mod tests { fn crypto_with_tiny_plain_data() { let original_data = b"{}"; let passwd = "this is sparta".into(); - let crypto = Crypto::with_plain(&original_data[..], &passwd, 10240).unwrap(); + let crypto = Crypto::with_plain(&original_data[..], &passwd, *ITERATIONS).unwrap(); let decrypted_data = crypto.decrypt(&passwd).unwrap(); assert_eq!(original_data[..], *decrypted_data); } @@ -199,7 +204,7 @@ mod tests { fn crypto_with_huge_plain_data() { let original_data: Vec<_> = (1..65536).map(|i| (i % 256) as u8).collect(); let passwd = "this is sparta".into(); - let crypto = Crypto::with_plain(&original_data, &passwd, 10240).unwrap(); + let crypto = Crypto::with_plain(&original_data, &passwd, *ITERATIONS).unwrap(); let decrypted_data = crypto.decrypt(&passwd).unwrap(); assert_eq!(&original_data, &decrypted_data); } diff --git a/accounts/ethstore/src/account/kdf.rs b/accounts/ethstore/src/account/kdf.rs index dfa1dea496..06b361cdca 100644 --- a/accounts/ethstore/src/account/kdf.rs +++ b/accounts/ethstore/src/account/kdf.rs @@ -15,6 +15,7 @@ // along with Parity Ethereum. If not, see . use json; +use std::num::NonZeroU32; #[derive(Debug, PartialEq, Clone)] pub enum Prf { @@ -23,7 +24,7 @@ pub enum Prf { #[derive(Debug, PartialEq, Clone)] pub struct Pbkdf2 { - pub c: u32, + pub c: NonZeroU32, pub dklen: u32, pub prf: Prf, pub salt: Vec, diff --git a/accounts/ethstore/src/account/safe_account.rs b/accounts/ethstore/src/account/safe_account.rs index 7a38e79fa2..63971ef6a2 100644 --- a/accounts/ethstore/src/account/safe_account.rs +++ b/accounts/ethstore/src/account/safe_account.rs @@ -20,6 +20,7 @@ use {json, Error}; use account::Version; use crypto; use super::crypto::Crypto; +use std::num::NonZeroU32; /// Account representation. #[derive(Debug, PartialEq, Clone)] @@ -59,7 +60,7 @@ impl SafeAccount { keypair: &KeyPair, id: [u8; 16], password: &Password, - iterations: u32, + iterations: NonZeroU32, name: String, meta: String ) -> Result { @@ -135,7 +136,7 @@ impl SafeAccount { } /// Create a new `VaultKeyFile` from the given `self` - pub fn into_vault_file(self, iterations: u32, password: &Password) -> Result { + pub fn into_vault_file(self, iterations: NonZeroU32, password: &Password) -> Result { let meta_plain = json::VaultKeyMeta { address: self.address.into(), name: Some(self.name), @@ -177,7 +178,7 @@ impl SafeAccount { } /// Change account's password. - pub fn change_password(&self, old_password: &Password, new_password: &Password, iterations: u32) -> Result { + pub fn change_password(&self, old_password: &Password, new_password: &Password, iterations: NonZeroU32) -> Result { let secret = self.crypto.secret(old_password)?; let result = SafeAccount { id: self.id.clone(), @@ -200,14 +201,19 @@ impl SafeAccount { #[cfg(test)] mod tests { use ethkey::{Generator, Random, verify_public, Message}; - use super::SafeAccount; + use super::{SafeAccount, NonZeroU32}; + + lazy_static! { + static ref ITERATIONS: NonZeroU32 = NonZeroU32::new(10240).expect("10240 > 0; qed"); + } + #[test] fn sign_and_verify_public() { let keypair = Random.generate().unwrap(); let password = "hello world".into(); let message = Message::default(); - let account = SafeAccount::create(&keypair, [0u8; 16], &password, 10240, "Test".to_owned(), "{}".to_owned()); + let account = SafeAccount::create(&keypair, [0u8; 16], &password, *ITERATIONS, "Test".to_owned(), "{}".to_owned()); let signature = account.unwrap().sign(&password, &message).unwrap(); assert!(verify_public(keypair.public(), &signature, &message).unwrap()); } @@ -217,10 +223,9 @@ mod tests { let keypair = Random.generate().unwrap(); let first_password = "hello world".into(); let sec_password = "this is sparta".into(); - let i = 10240; let message = Message::default(); - let account = SafeAccount::create(&keypair, [0u8; 16], &first_password, i, "Test".to_owned(), "{}".to_owned()).unwrap(); - let new_account = account.change_password(&first_password, &sec_password, i).unwrap(); + let account = SafeAccount::create(&keypair, [0u8; 16], &first_password, *ITERATIONS, "Test".to_owned(), "{}".to_owned()).unwrap(); + let new_account = account.change_password(&first_password, &sec_password, *ITERATIONS).unwrap(); assert!(account.sign(&first_password, &message).is_ok()); assert!(account.sign(&sec_password, &message).is_err()); assert!(new_account.sign(&first_password, &message).is_err()); diff --git a/accounts/ethstore/src/accounts_dir/disk.rs b/accounts/ethstore/src/accounts_dir/disk.rs index 2bbb766773..00c59b254d 100644 --- a/accounts/ethstore/src/accounts_dir/disk.rs +++ b/accounts/ethstore/src/accounts_dir/disk.rs @@ -356,11 +356,16 @@ mod test { extern crate tempdir; use std::{env, fs}; + use std::num::NonZeroU32; use super::{KeyDirectory, RootDiskDirectory, VaultKey}; use account::SafeAccount; use ethkey::{Random, Generator}; use self::tempdir::TempDir; + lazy_static! { + static ref ITERATIONS: NonZeroU32 = NonZeroU32::new(1024).expect("1024 > 0; qed"); + } + #[test] fn should_create_new_account() { // given @@ -371,7 +376,7 @@ mod test { let directory = RootDiskDirectory::create(dir.clone()).unwrap(); // when - let account = SafeAccount::create(&keypair, [0u8; 16], &password, 1024, "Test".to_owned(), "{}".to_owned()); + let account = SafeAccount::create(&keypair, [0u8; 16], &password, *ITERATIONS, "Test".to_owned(), "{}".to_owned()); let res = directory.insert(account.unwrap()); // then @@ -392,7 +397,7 @@ mod test { let directory = RootDiskDirectory::create(dir.clone()).unwrap(); // when - let account = SafeAccount::create(&keypair, [0u8; 16], &password, 1024, "Test".to_owned(), "{}".to_owned()).unwrap(); + let account = SafeAccount::create(&keypair, [0u8; 16], &password, *ITERATIONS, "Test".to_owned(), "{}".to_owned()).unwrap(); let filename = "test".to_string(); let dedup = true; @@ -428,7 +433,7 @@ mod test { // and when let before_root_items_count = fs::read_dir(&dir).unwrap().count(); - let vault = directory.as_vault_provider().unwrap().create(vault_name, VaultKey::new(&password, 1024)); + let vault = directory.as_vault_provider().unwrap().create(vault_name, VaultKey::new(&password, *ITERATIONS)); // then assert!(vault.is_ok()); @@ -436,7 +441,7 @@ mod test { assert!(after_root_items_count > before_root_items_count); // and when - let vault = directory.as_vault_provider().unwrap().open(vault_name, VaultKey::new(&password, 1024)); + let vault = directory.as_vault_provider().unwrap().open(vault_name, VaultKey::new(&password, *ITERATIONS)); // then assert!(vault.is_ok()); @@ -453,8 +458,9 @@ mod test { let temp_path = TempDir::new("").unwrap(); let directory = RootDiskDirectory::create(&temp_path).unwrap(); let vault_provider = directory.as_vault_provider().unwrap(); - vault_provider.create("vault1", VaultKey::new(&"password1".into(), 1)).unwrap(); - vault_provider.create("vault2", VaultKey::new(&"password2".into(), 1)).unwrap(); + let iter = NonZeroU32::new(1).expect("1 > 0; qed"); + vault_provider.create("vault1", VaultKey::new(&"password1".into(), iter)).unwrap(); + vault_provider.create("vault2", VaultKey::new(&"password2".into(), iter)).unwrap(); // then let vaults = vault_provider.list_vaults().unwrap(); @@ -476,7 +482,7 @@ mod test { let keypair = Random.generate().unwrap(); let password = "test pass".into(); - let account = SafeAccount::create(&keypair, [0u8; 16], &password, 1024, "Test".to_owned(), "{}".to_owned()); + let account = SafeAccount::create(&keypair, [0u8; 16], &password, *ITERATIONS, "Test".to_owned(), "{}".to_owned()); directory.insert(account.unwrap()).expect("Account should be inserted ok"); let new_hash = directory.files_hash().expect("New files hash should be calculated ok"); diff --git a/accounts/ethstore/src/accounts_dir/mod.rs b/accounts/ethstore/src/accounts_dir/mod.rs index 300c395222..9b1328e115 100644 --- a/accounts/ethstore/src/accounts_dir/mod.rs +++ b/accounts/ethstore/src/accounts_dir/mod.rs @@ -17,6 +17,7 @@ //! Accounts Directory use ethkey::Password; +use std::num::NonZeroU32; use std::path::{PathBuf}; use {SafeAccount, Error}; @@ -41,7 +42,7 @@ pub struct VaultKey { /// Vault password pub password: Password, /// Number of iterations to produce a derived key from password - pub iterations: u32, + pub iterations: NonZeroU32, } /// Keys directory @@ -96,7 +97,7 @@ pub use self::vault::VaultDiskDirectory; impl VaultKey { /// Create new vault key - pub fn new(password: &Password, iterations: u32) -> Self { + pub fn new(password: &Password, iterations: NonZeroU32) -> Self { VaultKey { password: password.clone(), iterations: iterations, diff --git a/accounts/ethstore/src/accounts_dir/vault.rs b/accounts/ethstore/src/accounts_dir/vault.rs index 1aea7e104c..c54de7c12c 100644 --- a/accounts/ethstore/src/accounts_dir/vault.rs +++ b/accounts/ethstore/src/accounts_dir/vault.rs @@ -282,11 +282,17 @@ mod test { use std::fs; use std::io::Write; + use std::num::NonZeroU32; use std::path::PathBuf; use super::VaultKey; use super::{VAULT_FILE_NAME, check_vault_name, make_vault_dir_path, create_vault_file, read_vault_file, VaultDiskDirectory}; use self::tempdir::TempDir; + + lazy_static! { + static ref ITERATIONS: NonZeroU32 = NonZeroU32::new(1024).expect("1024 > 0; qed"); + } + #[test] fn check_vault_name_succeeds() { assert!(check_vault_name("vault")); @@ -325,7 +331,7 @@ mod test { fn create_vault_file_succeeds() { // given let temp_path = TempDir::new("").unwrap(); - let key = VaultKey::new(&"password".into(), 1024); + let key = VaultKey::new(&"password".into(), *ITERATIONS); let mut vault_dir: PathBuf = temp_path.path().into(); vault_dir.push("vault"); fs::create_dir_all(&vault_dir).unwrap(); @@ -344,7 +350,7 @@ mod test { fn read_vault_file_succeeds() { // given let temp_path = TempDir::new("").unwrap(); - let key = VaultKey::new(&"password".into(), 1024); + let key = VaultKey::new(&"password".into(), *ITERATIONS); let vault_file_contents = r#"{"crypto":{"cipher":"aes-128-ctr","cipherparams":{"iv":"758696c8dc6378ab9b25bb42790da2f5"},"ciphertext":"54eb50683717d41caaeb12ea969f2c159daada5907383f26f327606a37dc7168","kdf":"pbkdf2","kdfparams":{"c":1024,"dklen":32,"prf":"hmac-sha256","salt":"3c320fa566a1a7963ac8df68a19548d27c8f40bf92ef87c84594dcd5bbc402b6"},"mac":"9e5c2314c2a0781962db85611417c614bd6756666b6b1e93840f5b6ed895f003"}}"#; let dir: PathBuf = temp_path.path().into(); let mut vault_file_path: PathBuf = dir.clone(); @@ -365,7 +371,7 @@ mod test { fn read_vault_file_fails() { // given let temp_path = TempDir::new("").unwrap(); - let key = VaultKey::new(&"password1".into(), 1024); + let key = VaultKey::new(&"password1".into(), *ITERATIONS); let dir: PathBuf = temp_path.path().into(); let mut vault_file_path: PathBuf = dir.clone(); vault_file_path.push(VAULT_FILE_NAME); @@ -394,7 +400,7 @@ mod test { fn vault_directory_can_be_created() { // given let temp_path = TempDir::new("").unwrap(); - let key = VaultKey::new(&"password".into(), 1024); + let key = VaultKey::new(&"password".into(), *ITERATIONS); let dir: PathBuf = temp_path.path().into(); // when @@ -414,7 +420,7 @@ mod test { fn vault_directory_cannot_be_created_if_already_exists() { // given let temp_path = TempDir::new("").unwrap(); - let key = VaultKey::new(&"password".into(), 1024); + let key = VaultKey::new(&"password".into(), *ITERATIONS); let dir: PathBuf = temp_path.path().into(); let mut vault_dir = dir.clone(); vault_dir.push("vault"); @@ -431,7 +437,7 @@ mod test { fn vault_directory_cannot_be_opened_if_not_exists() { // given let temp_path = TempDir::new("").unwrap(); - let key = VaultKey::new(&"password".into(), 1024); + let key = VaultKey::new(&"password".into(), *ITERATIONS); let dir: PathBuf = temp_path.path().into(); // when diff --git a/accounts/ethstore/src/ethstore.rs b/accounts/ethstore/src/ethstore.rs index 7207db7260..92eb949673 100644 --- a/accounts/ethstore/src/ethstore.rs +++ b/accounts/ethstore/src/ethstore.rs @@ -15,12 +15,12 @@ // along with Parity Ethereum. If not, see . use std::collections::{BTreeMap, HashMap}; +use std::num::NonZeroU32; use std::mem; use std::path::PathBuf; use parking_lot::{Mutex, RwLock}; use std::time::{Instant, Duration}; -use crypto::KEY_ITERATIONS; use random::Random; use ethkey::{self, Signature, Password, Address, Message, Secret, Public, KeyPair, ExtendedKeyPair}; use accounts_dir::{KeyDirectory, VaultKeyDirectory, VaultKey, SetKeyError}; @@ -29,6 +29,12 @@ use presale::PresaleWallet; use json::{self, Uuid, OpaqueKeyFile}; use {import, Error, SimpleSecretStore, SecretStore, SecretVaultRef, StoreAccountRef, Derivation, OpaqueSecret}; + +lazy_static! { + static ref KEY_ITERATIONS: NonZeroU32 = + NonZeroU32::new(crypto::KEY_ITERATIONS as u32).expect("KEY_ITERATIONS > 0; qed"); +} + /// Accounts store. pub struct EthStore { store: EthMultiStore, @@ -37,11 +43,11 @@ pub struct EthStore { impl EthStore { /// Open a new accounts store with given key directory backend. pub fn open(directory: Box) -> Result { - Self::open_with_iterations(directory, KEY_ITERATIONS as u32) + Self::open_with_iterations(directory, *KEY_ITERATIONS) } /// Open a new account store with given key directory backend and custom number of iterations. - pub fn open_with_iterations(directory: Box, iterations: u32) -> Result { + pub fn open_with_iterations(directory: Box, iterations: NonZeroU32) -> Result { Ok(EthStore { store: EthMultiStore::open_with_iterations(directory, iterations)?, }) @@ -257,7 +263,7 @@ impl SecretStore for EthStore { /// Similar to `EthStore` but may store many accounts (with different passwords) for the same `Address` pub struct EthMultiStore { dir: Box, - iterations: u32, + iterations: NonZeroU32, // order lock: cache, then vaults cache: RwLock>>, vaults: Mutex>>, @@ -273,11 +279,11 @@ struct Timestamp { impl EthMultiStore { /// Open new multi-accounts store with given key directory backend. pub fn open(directory: Box) -> Result { - Self::open_with_iterations(directory, KEY_ITERATIONS as u32) + Self::open_with_iterations(directory, *KEY_ITERATIONS) } /// Open new multi-accounts store with given key directory backend and custom number of iterations for new keys. - pub fn open_with_iterations(directory: Box, iterations: u32) -> Result { + pub fn open_with_iterations(directory: Box, iterations: NonZeroU32) -> Result { let store = EthMultiStore { dir: directory, vaults: Mutex::new(HashMap::new()), diff --git a/accounts/ethstore/src/json/kdf.rs b/accounts/ethstore/src/json/kdf.rs index 0ea1d9f31c..a8bb8b261c 100644 --- a/accounts/ethstore/src/json/kdf.rs +++ b/accounts/ethstore/src/json/kdf.rs @@ -15,6 +15,7 @@ // along with Parity Ethereum. If not, see . use std::fmt; +use std::num::NonZeroU32; use serde::{Serialize, Serializer, Deserialize, Deserializer}; use serde::de::{Visitor, Error as SerdeError}; use super::{Error, Bytes}; @@ -108,7 +109,7 @@ impl<'a> Visitor<'a> for PrfVisitor { #[derive(Debug, PartialEq, Serialize, Deserialize)] pub struct Pbkdf2 { - pub c: u32, + pub c: NonZeroU32, pub dklen: u32, pub prf: Prf, pub salt: Bytes, diff --git a/accounts/ethstore/src/json/vault_file.rs b/accounts/ethstore/src/json/vault_file.rs index 52e98cd250..0da870931d 100644 --- a/accounts/ethstore/src/json/vault_file.rs +++ b/accounts/ethstore/src/json/vault_file.rs @@ -41,6 +41,11 @@ impl VaultFile { mod test { use serde_json; use json::{VaultFile, Crypto, Cipher, Aes128Ctr, Kdf, Pbkdf2, Prf}; + use std::num::NonZeroU32; + + lazy_static! { + static ref ITERATIONS: NonZeroU32 = NonZeroU32::new(1024).expect("1024 > 0; qed"); + } #[test] fn to_and_from_json() { @@ -51,7 +56,7 @@ mod test { }), ciphertext: "4d6938a1f49b7782".into(), kdf: Kdf::Pbkdf2(Pbkdf2 { - c: 1024, + c: *ITERATIONS, dklen: 32, prf: Prf::HmacSha256, salt: "b6a9338a7ccd39288a86dba73bfecd9101b4f3db9c9830e7c76afdbd4f6872e5".into(), @@ -76,7 +81,7 @@ mod test { }), ciphertext: "4d6938a1f49b7782".into(), kdf: Kdf::Pbkdf2(Pbkdf2 { - c: 1024, + c: *ITERATIONS, dklen: 32, prf: Prf::HmacSha256, salt: "b6a9338a7ccd39288a86dba73bfecd9101b4f3db9c9830e7c76afdbd4f6872e5".into(), diff --git a/accounts/ethstore/src/json/vault_key_file.rs b/accounts/ethstore/src/json/vault_key_file.rs index a29d5fe7f6..dd4ba49798 100644 --- a/accounts/ethstore/src/json/vault_key_file.rs +++ b/accounts/ethstore/src/json/vault_key_file.rs @@ -106,6 +106,11 @@ mod test { use serde_json; use json::{VaultKeyFile, Version, Crypto, Cipher, Aes128Ctr, Kdf, Pbkdf2, Prf, insert_vault_name_to_json_meta, remove_vault_name_from_json_meta}; + use std::num::NonZeroU32; + + lazy_static! { + static ref ITERATIONS: NonZeroU32 = NonZeroU32::new(10240).expect("10240 > 0; qed"); + } #[test] fn to_and_from_json() { @@ -118,7 +123,7 @@ mod test { }), ciphertext: "4befe0a66d9a4b6fec8e39eb5c90ac5dafdeaab005fff1af665fd1f9af925c91".into(), kdf: Kdf::Pbkdf2(Pbkdf2 { - c: 10240, + c: *ITERATIONS, dklen: 32, prf: Prf::HmacSha256, salt: "f17731e84ecac390546692dbd4ccf6a3a2720dc9652984978381e61c28a471b2".into(), @@ -131,7 +136,7 @@ mod test { }), ciphertext: "fef0d113d7576c1702daf380ad6f4c5408389e57991cae2a174facd74bd549338e1014850bddbab7eb486ff5f5c9c5532800c6a6d4db2be2212cd5cd3769244ab230e1f369e8382a9e6d7c0a".into(), kdf: Kdf::Pbkdf2(Pbkdf2 { - c: 10240, + c: *ITERATIONS, dklen: 32, prf: Prf::HmacSha256, salt: "aca82865174a82249a198814b263f43a631f272cbf7ed329d0f0839d259c652a".into(), diff --git a/accounts/ethstore/src/lib.rs b/accounts/ethstore/src/lib.rs index aa2bb86a47..c0955caeb0 100644 --- a/accounts/ethstore/src/lib.rs +++ b/accounts/ethstore/src/lib.rs @@ -36,6 +36,8 @@ extern crate ethereum_types; extern crate ethkey as _ethkey; extern crate parity_wordlist; +#[macro_use] +extern crate lazy_static; #[macro_use] extern crate log; #[macro_use] diff --git a/accounts/ethstore/src/presale.rs b/accounts/ethstore/src/presale.rs index c1be05f0f0..8ca5d0b98b 100644 --- a/accounts/ethstore/src/presale.rs +++ b/accounts/ethstore/src/presale.rs @@ -15,6 +15,7 @@ // along with Parity Ethereum. If not, see . use std::fs; +use std::num::NonZeroU32; use std::path::Path; use json; use ethkey::{Address, Secret, KeyPair, Password}; @@ -58,7 +59,8 @@ impl PresaleWallet { let mut derived_key = [0u8; 32]; let salt = pbkdf2::Salt(password.as_bytes()); let sec = pbkdf2::Secret(password.as_bytes()); - pbkdf2::sha256(2000, salt, sec, &mut derived_key); + let iter = NonZeroU32::new(2000).expect("2000 > 0; qed"); + pbkdf2::sha256(iter, salt, sec, &mut derived_key); let mut key = vec![0; self.ciphertext.len()]; let len = crypto::aes::decrypt_128_cbc(&derived_key[0..16], &self.iv, &self.ciphertext, &mut key) diff --git a/ethcore/Cargo.toml b/ethcore/Cargo.toml index 538da894c7..3572b56394 100644 --- a/ethcore/Cargo.toml +++ b/ethcore/Cargo.toml @@ -50,7 +50,7 @@ memorydb = "0.3.0" num = { version = "0.1", default-features = false, features = ["bigint"] } num_cpus = "1.2" parity-bytes = "0.1" -parity-crypto = "0.2" +parity-crypto = "0.3.0" parity-machine = { path = "../machine" } parity-snappy = "0.1" parking_lot = "0.7" diff --git a/ethcore/private-tx/Cargo.toml b/ethcore/private-tx/Cargo.toml index 5151deee44..74883ca970 100644 --- a/ethcore/private-tx/Cargo.toml +++ b/ethcore/private-tx/Cargo.toml @@ -24,7 +24,7 @@ heapsize = "0.4" keccak-hash = "0.1.2" log = "0.4" parity-bytes = "0.1" -parity-crypto = "0.2" +parity-crypto = "0.3.0" parking_lot = "0.7" patricia-trie = "0.3.0" patricia-trie-ethereum = { path = "../../util/patricia-trie-ethereum" } diff --git a/parity/account.rs b/parity/account.rs index 79681fda7e..389f288647 100644 --- a/parity/account.rs +++ b/parity/account.rs @@ -14,6 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Parity Ethereum. If not, see . +use std::num::NonZeroU32; use std::path::PathBuf; use ethstore::{EthStore, SecretStore, import_account, import_accounts, read_geth_accounts}; use ethstore::accounts_dir::RootDiskDirectory; @@ -38,7 +39,7 @@ pub struct ListAccounts { #[derive(Debug, PartialEq)] pub struct NewAccount { - pub iterations: u32, + pub iterations: NonZeroU32, pub path: String, pub spec: SpecType, pub password_file: Option, @@ -77,7 +78,7 @@ fn keys_dir(path: String, spec: SpecType) -> Result { RootDiskDirectory::create(path).map_err(|e| format!("Could not open keys directory: {}", e)) } -fn secret_store(dir: Box, iterations: Option) -> Result { +fn secret_store(dir: Box, iterations: Option) -> Result { match iterations { Some(i) => EthStore::open_with_iterations(dir, i), _ => EthStore::open(dir) diff --git a/parity/configuration.rs b/parity/configuration.rs index a32183a79e..087537ff1e 100644 --- a/parity/configuration.rs +++ b/parity/configuration.rs @@ -17,6 +17,7 @@ use std::time::Duration; use std::io::Read; use std::net::SocketAddr; +use std::num::NonZeroU32; use std::path::PathBuf; use std::collections::{HashSet, BTreeMap}; use std::iter::FromIterator; @@ -143,6 +144,8 @@ impl Configuration { let ipfs_conf = self.ipfs_config(); let secretstore_conf = self.secretstore_config()?; let format = self.format()?; + let keys_iterations = NonZeroU32::new(self.args.arg_keys_iterations) + .ok_or_else(|| "--keys-iterations must be non-zero")?; let cmd = if self.args.flag_version { Cmd::Version @@ -199,7 +202,7 @@ impl Configuration { } else if self.args.cmd_account { let account_cmd = if self.args.cmd_account_new { let new_acc = NewAccount { - iterations: self.args.arg_keys_iterations, + iterations: keys_iterations, path: dirs.keys, spec: spec, password_file: self.accounts_config()?.password_files.first().map(|x| x.to_owned()), @@ -233,7 +236,7 @@ impl Configuration { Cmd::Account(account_cmd) } else if self.args.cmd_wallet { let presale_cmd = ImportWallet { - iterations: self.args.arg_keys_iterations, + iterations: keys_iterations, path: dirs.keys, spec: spec, wallet_path: self.args.arg_wallet_import_path.clone().unwrap(), @@ -528,8 +531,10 @@ impl Configuration { } fn accounts_config(&self) -> Result { + let keys_iterations = NonZeroU32::new(self.args.arg_keys_iterations) + .ok_or_else(|| "--keys-iterations must be non-zero")?; let cfg = AccountsConfig { - iterations: self.args.arg_keys_iterations, + iterations: keys_iterations, refresh_time: self.args.arg_accounts_refresh, testnet: self.args.flag_testnet, password_files: self.args.arg_password.iter().map(|s| replace_home(&self.directories().base, s)).collect(), @@ -1212,6 +1217,10 @@ mod tests { use super::*; + lazy_static! { + static ref ITERATIONS: NonZeroU32 = NonZeroU32::new(10240).expect("10240 > 0; qed"); + } + #[derive(Debug, PartialEq)] struct TestPasswordReader(&'static str); @@ -1233,7 +1242,7 @@ mod tests { let args = vec!["parity", "account", "new"]; let conf = parse(&args); assert_eq!(conf.into_command().unwrap().cmd, Cmd::Account(AccountCmd::New(NewAccount { - iterations: 10240, + iterations: *ITERATIONS, path: Directories::default().keys, password_file: None, spec: SpecType::default(), @@ -1268,7 +1277,7 @@ mod tests { let args = vec!["parity", "wallet", "import", "my_wallet.json", "--password", "pwd"]; let conf = parse(&args); assert_eq!(conf.into_command().unwrap().cmd, Cmd::ImportPresaleWallet(ImportWallet { - iterations: 10240, + iterations: *ITERATIONS, path: Directories::default().keys, wallet_path: "my_wallet.json".into(), password_file: Some("pwd".into()), diff --git a/parity/lib.rs b/parity/lib.rs index c333c24186..f3a7941293 100644 --- a/parity/lib.rs +++ b/parity/lib.rs @@ -86,6 +86,10 @@ extern crate pretty_assertions; #[cfg(test)] extern crate tempdir; +#[cfg(test)] +#[macro_use] +extern crate lazy_static; + mod account; mod blockchain; mod cache; diff --git a/parity/params.rs b/parity/params.rs index 11414edf00..f609fa07c0 100644 --- a/parity/params.rs +++ b/parity/params.rs @@ -15,6 +15,7 @@ // along with Parity Ethereum. If not, see . use std::{str, fs, fmt}; +use std::num::NonZeroU32; use std::time::Duration; use ethcore::client::Mode; @@ -214,7 +215,7 @@ impl str::FromStr for ResealPolicy { #[derive(Debug, PartialEq)] pub struct AccountsConfig { - pub iterations: u32, + pub iterations: NonZeroU32, pub refresh_time: u64, pub testnet: bool, pub password_files: Vec, @@ -226,7 +227,7 @@ pub struct AccountsConfig { impl Default for AccountsConfig { fn default() -> Self { AccountsConfig { - iterations: 10240, + iterations: NonZeroU32::new(10240).expect("10240 > 0; qed"), refresh_time: 5, testnet: false, password_files: Vec::new(), diff --git a/parity/presale.rs b/parity/presale.rs index da5bef369e..07087b9ef2 100644 --- a/parity/presale.rs +++ b/parity/presale.rs @@ -19,10 +19,11 @@ use ethstore::accounts_dir::RootDiskDirectory; use ethcore::account_provider::{AccountProvider, AccountProviderSettings}; use helpers::{password_prompt, password_from_file}; use params::SpecType; +use std::num::NonZeroU32; #[derive(Debug, PartialEq)] pub struct ImportWallet { - pub iterations: u32, + pub iterations: NonZeroU32, pub path: String, pub spec: SpecType, pub wallet_path: String, diff --git a/rpc/Cargo.toml b/rpc/Cargo.toml index 9fabb8578a..a766b25f88 100644 --- a/rpc/Cargo.toml +++ b/rpc/Cargo.toml @@ -39,7 +39,7 @@ ethash = { path = "../ethash" } ethcore = { path = "../ethcore", features = ["test-helpers"] } fastmap = { path = "../util/fastmap" } parity-bytes = "0.1" -parity-crypto = "0.2" +parity-crypto = "0.3.0" ethcore-io = { path = "../util/io" } ethcore-light = { path = "../ethcore/light" } ethcore-logger = { path = "../parity/logger" } diff --git a/secret-store/Cargo.toml b/secret-store/Cargo.toml index 016028a0bf..a53d90e22b 100644 --- a/secret-store/Cargo.toml +++ b/secret-store/Cargo.toml @@ -25,7 +25,7 @@ tokio-service = "0.1" url = "1.0" ethcore = { path = "../ethcore" } parity-bytes = "0.1" -parity-crypto = "0.2" +parity-crypto = "0.3.0" ethcore-sync = { path = "../ethcore/sync" } ethereum-types = "0.4" kvdb = "0.1" diff --git a/util/fetch/Cargo.toml b/util/fetch/Cargo.toml index d5df1034bc..c45c2ca4f4 100644 --- a/util/fetch/Cargo.toml +++ b/util/fetch/Cargo.toml @@ -9,7 +9,7 @@ authors = ["Parity Technologies "] [dependencies] futures = "0.1" hyper = "~0.12.9" -hyper-rustls = "0.14" +hyper-rustls = "0.16.0" http = "0.1" log = "0.4" tokio = "~0.1.8" diff --git a/util/network-devp2p/Cargo.toml b/util/network-devp2p/Cargo.toml index 5254e8a65d..5f1a5d3397 100644 --- a/util/network-devp2p/Cargo.toml +++ b/util/network-devp2p/Cargo.toml @@ -21,7 +21,7 @@ ansi_term = "0.10" rustc-hex = "1.0" ethcore-io = { path = "../io", features = ["mio"] } parity-bytes = "0.1" -parity-crypto = "0.2" +parity-crypto = "0.3.0" ethcore-network = { path = "../network" } ethereum-types = "0.4" ethkey = { path = "../../accounts/ethkey" } diff --git a/util/network/Cargo.toml b/util/network/Cargo.toml index b24249cd5d..cdd321dd72 100644 --- a/util/network/Cargo.toml +++ b/util/network/Cargo.toml @@ -8,7 +8,7 @@ authors = ["Parity Technologies "] [dependencies] error-chain = { version = "0.12", default-features = false } -parity-crypto = "0.2" +parity-crypto = "0.3.0" ethcore-io = { path = "../io" } ethereum-types = "0.4" ethkey = { path = "../../accounts/ethkey" } diff --git a/whisper/Cargo.toml b/whisper/Cargo.toml index e29abd982f..5c3548a50c 100644 --- a/whisper/Cargo.toml +++ b/whisper/Cargo.toml @@ -9,7 +9,7 @@ bitflags = "0.9" byteorder = "1.0.0" ethereum-types = "0.4" ethcore-network = { path = "../util/network" } -parity-crypto = "0.2" +parity-crypto = "0.3.0" ethkey = { path = "../accounts/ethkey" } hex = "0.2" log = "0.4" From 45d7c60608301a5a622f12fd9185fdb149b0152d Mon Sep 17 00:00:00 2001 From: Anton Gavrilov Date: Thu, 7 Feb 2019 12:39:04 +0100 Subject: [PATCH 048/168] Call private contract methods from another private contract (read-only) (#10086) * Patch available private contracts during private transaction * Key acl ABI added * Work with secret store keys moved to the separate struct * Private tx test refactored * Revert "Private tx test refactored" This reverts commit 476c132d692c7a886bc7b7cd7fe47b3d7692bd63. * Test for calling private contract from another one added * Test fixed * Redundant tab removed * ACL contract processing fixed, test added * Merge with head * Expect replaced with closure --- ethcore/private-tx/res/keys_acl.json | 43 +++++ ethcore/private-tx/src/encryptor.rs | 5 +- ethcore/private-tx/src/key_server_keys.rs | 173 +++++++++++++++++++ ethcore/private-tx/src/lib.rs | 78 +++++---- ethcore/private-tx/tests/private_contract.rs | 130 +++++++++++++- ethcore/service/src/service.rs | 19 +- ethcore/sync/src/tests/private.rs | 6 +- parity/blockchain.rs | 2 + parity/run.rs | 3 +- parity/snapshot.rs | 1 + rpc/src/v1/impls/private.rs | 2 +- rpc/src/v1/types/private_receipt.rs | 4 +- 12 files changed, 421 insertions(+), 45 deletions(-) create mode 100644 ethcore/private-tx/res/keys_acl.json create mode 100644 ethcore/private-tx/src/key_server_keys.rs diff --git a/ethcore/private-tx/res/keys_acl.json b/ethcore/private-tx/res/keys_acl.json new file mode 100644 index 0000000000..3ec2daf9e9 --- /dev/null +++ b/ethcore/private-tx/res/keys_acl.json @@ -0,0 +1,43 @@ +[ + { + "constant": true, + "inputs": [ + { + "name":"user", + "type":"address" + } + ], + "name": "availableKeys", + "outputs": [ + { + "name": "", + "type": "bytes32[]" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant":true, + "inputs": [ + { + "name":"user", + "type":"address" + }, + { + "name":"document", + "type":"bytes32" + } + ], + "name":"checkPermissions", + "outputs": [ + { + "name":"", + "type":"bool" + } + ], + "payable":false, + "type":"function" + } +] diff --git a/ethcore/private-tx/src/encryptor.rs b/ethcore/private-tx/src/encryptor.rs index b19a53d29a..2d8b47e63a 100644 --- a/ethcore/private-tx/src/encryptor.rs +++ b/ethcore/private-tx/src/encryptor.rs @@ -34,6 +34,7 @@ use bytes::{Bytes, ToPretty}; use error::{Error, ErrorKind}; use url::Url; use super::find_account_password; +use super::key_server_keys::address_to_key; /// Initialization vector length. const INIT_VEC_LEN: usize = 16; @@ -188,11 +189,9 @@ impl SecretStoreEncryptor { } 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))?) + Ok(accounts.sign(key_server_account, password, address_to_key(contract_address))?) } } diff --git a/ethcore/private-tx/src/key_server_keys.rs b/ethcore/private-tx/src/key_server_keys.rs new file mode 100644 index 0000000000..28d9b3cb91 --- /dev/null +++ b/ethcore/private-tx/src/key_server_keys.rs @@ -0,0 +1,173 @@ +// 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 . + +//! Wrapper around key server responsible for access keys processing. + +use std::sync::Arc; +use parking_lot::RwLock; +use ethereum_types::{H256, Address}; +use call_contract::{CallContract, RegistryInfo}; +use ethcore::client::BlockId; +use ethabi::FunctionOutputDecoder; + +const ACL_CHECKER_CONTRACT_REGISTRY_NAME: &'static str = "secretstore_acl_checker"; + +use_contract!(keys_acl_contract, "res/keys_acl.json"); + +/// Returns the address (of the contract), that corresponds to the key +pub fn key_to_address(key: &H256) -> Address { + Address::from_slice(&key.to_vec()[..10]) +} + +/// Returns the key from the key server associated with the contract +pub fn address_to_key(contract_address: &Address) -> H256 { + // Current solution uses contract address extended with 0 as id + let contract_address_extended: H256 = contract_address.into(); + + H256::from_slice(&contract_address_extended) +} + +/// Trait for keys server keys provider. +pub trait KeyProvider: Send + Sync + 'static { + /// Account, that is used for communication with key server + fn key_server_account(&self) -> Option
; + + /// List of keys available for the account + fn available_keys(&self, block: BlockId, account: &Address) -> Option>; + + /// Update permissioning contract + fn update_acl_contract(&self); +} + +/// Secret Store keys provider +pub struct SecretStoreKeys where C: CallContract + RegistryInfo + Send + Sync + 'static { + client: Arc, + key_server_account: Option
, + keys_acl_contract: RwLock>, +} + +impl SecretStoreKeys where C: CallContract + RegistryInfo + Send + Sync + 'static { + /// Create provider + pub fn new(client: Arc, key_server_account: Option
) -> Self { + SecretStoreKeys { + client, + key_server_account, + keys_acl_contract: RwLock::new(None), + } + } +} + +impl KeyProvider for SecretStoreKeys where C: CallContract + RegistryInfo + Send + Sync + 'static { + fn key_server_account(&self) -> Option
{ + self.key_server_account + } + + fn available_keys(&self, block: BlockId, account: &Address) -> Option> { + match *self.keys_acl_contract.read() { + Some(acl_contract_address) => { + let (data, decoder) = keys_acl_contract::functions::available_keys::call(*account); + if let Ok(value) = self.client.call_contract(block, acl_contract_address, data) { + decoder.decode(&value).ok().map(|key_values| { + key_values.iter().map(key_to_address).collect() + }) + } else { + None + } + } + None => None, + } + } + + fn update_acl_contract(&self) { + let contract_address = self.client.registry_address(ACL_CHECKER_CONTRACT_REGISTRY_NAME.into(), BlockId::Latest); + if *self.keys_acl_contract.read() != contract_address { + trace!(target: "privatetx", "Configuring for ACL checker contract from address {:?}", + contract_address); + *self.keys_acl_contract.write() = contract_address; + } + } +} + +/// Dummy keys provider. +pub struct StoringKeyProvider { + available_keys: RwLock>>, + key_server_account: Option
, +} + +impl StoringKeyProvider { + /// Store available keys + pub fn set_available_keys(&self, keys: &Vec
) { + *self.available_keys.write() = Some(keys.clone()) + } +} + +impl Default for StoringKeyProvider { + fn default() -> Self { + StoringKeyProvider { + available_keys: RwLock::new(None), + key_server_account: Some(Address::default()), + } + } +} + +impl KeyProvider for StoringKeyProvider { + fn key_server_account(&self) -> Option
{ + self.key_server_account + } + + fn available_keys(&self, _block: BlockId, _account: &Address) -> Option> { + self.available_keys.read().clone() + } + + fn update_acl_contract(&self) {} +} + +#[cfg(test)] +mod tests { + use std::sync::Arc; + use ethkey::{Secret, KeyPair}; + use bytes::Bytes; + use super::*; + + struct DummyRegistryClient { + registry_address: Option
, + } + + impl DummyRegistryClient { + pub fn new(registry_address: Option
) -> Self { + DummyRegistryClient { + registry_address + } + } + } + + impl RegistryInfo for DummyRegistryClient { + fn registry_address(&self, _name: String, _block: BlockId) -> Option
{ self.registry_address } + } + + impl CallContract for DummyRegistryClient { + fn call_contract(&self, _id: BlockId, _address: Address, _data: Bytes) -> Result { Ok(vec![]) } + } + + #[test] + fn should_update_acl_contract() { + let key = KeyPair::from_secret(Secret::from("0000000000000000000000000000000000000000000000000000000000000011")).unwrap(); + let client = DummyRegistryClient::new(Some(key.address())); + let keys_data = SecretStoreKeys::new(Arc::new(client), None); + keys_data.update_acl_contract(); + assert_eq!(keys_data.keys_acl_contract.read().unwrap(), key.address()); + } +} \ No newline at end of file diff --git a/ethcore/private-tx/src/lib.rs b/ethcore/private-tx/src/lib.rs index 3ab39d9e4e..cda80fb071 100644 --- a/ethcore/private-tx/src/lib.rs +++ b/ethcore/private-tx/src/lib.rs @@ -21,6 +21,7 @@ #![recursion_limit="256"] mod encryptor; +mod key_server_keys; mod private_transactions; mod messages; mod error; @@ -64,6 +65,7 @@ extern crate rand; extern crate env_logger; pub use encryptor::{Encryptor, SecretStoreEncryptor, EncryptorConfig, NoopEncryptor}; +pub use key_server_keys::{KeyProvider, SecretStoreKeys, StoringKeyProvider}; pub use private_transactions::{VerifiedPrivateTransaction, VerificationStore, PrivateTransactionSigningDesc, SigningStore}; pub use messages::{PrivateTransaction, SignedPrivateTransaction}; pub use error::{Error, ErrorKind}; @@ -87,6 +89,7 @@ use ethcore::client::{ }; use ethcore::account_provider::AccountProvider; use ethcore::miner::{self, Miner, MinerService, pool_client::NonceCache}; +use ethcore::{state, state_db}; use ethcore::trace::{Tracer, VMTracer}; use call_contract::CallContract; use rustc_hex::FromHex; @@ -126,8 +129,8 @@ pub struct ProviderConfig { pub struct Receipt { /// Private transaction hash. pub hash: H256, - /// Created contract address if any. - pub contract_address: Option
, + /// Contract address. + pub contract_address: Address, /// Execution status. pub status_code: u8, } @@ -145,13 +148,14 @@ pub struct Provider { miner: Arc, accounts: Arc, channel: IoChannel, + keys_provider: Arc, } #[derive(Debug)] pub struct PrivateExecutionResult where T: Tracer, V: VMTracer { code: Option, state: Bytes, - contract_address: Option
, + contract_address: Address, result: Executed, } @@ -164,7 +168,9 @@ impl Provider where { encryptor: Box, config: ProviderConfig, channel: IoChannel, + keys_provider: Arc, ) -> Self { + keys_provider.update_acl_contract(); Provider { encryptor, validator_accounts: config.validator_accounts.into_iter().collect(), @@ -177,6 +183,7 @@ impl Provider where { miner, accounts, channel, + keys_provider, } } @@ -227,7 +234,7 @@ impl Provider where { self.broadcast_private_transaction(private.hash(), private.rlp_bytes()); Ok(Receipt { hash: tx_hash, - contract_address: Some(contract), + contract_address: contract, status_code: 0, }) } @@ -484,6 +491,14 @@ impl Provider where { raw } + fn patch_account_state(&self, contract_address: &Address, block: BlockId, state: &mut state::State) -> Result<(), Error> { + let contract_code = Arc::new(self.get_decrypted_code(contract_address, block)?); + let contract_state = self.get_decrypted_state(contract_address, block)?; + trace!(target: "privatetx", "Patching contract at {:?}, code: {:?}, state: {:?}", contract_address, contract_code, contract_state); + state.patch_account(contract_address, contract_code, Self::snapshot_to_storage(contract_state))?; + Ok(()) + } + pub fn execute_private(&self, transaction: &SignedTransaction, options: TransactOptions, block: BlockId) -> Result, Error> where T: Tracer, @@ -496,41 +511,48 @@ impl Provider where { // TODO #9825 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!(target: "privatetx", "Patching contract at {:?}, code: {:?}, state: {:?}", contract_address, contract_code, contract_state); - state.patch_account(contract_address, contract_code, Self::snapshot_to_storage(contract_state))?; + // Patch current contract state + self.patch_account_state(contract_address, block, &mut 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 sender = transaction.sender(); + let nonce = state.nonce(&sender)?; + let contract_address = contract_address.unwrap_or_else(|| { let (new_address, _) = ethcore_contract_address(engine.create_address_scheme(env_info.number), &sender, &nonce, &transaction.data); - Some(new_address) + new_address }); + // Patch other available private contracts' states as well + // TODO: #10133 patch only required for the contract states + if let Some(key_server_account) = self.keys_provider.key_server_account() { + if let Some(available_contracts) = self.keys_provider.available_keys(block, &key_server_account) { + for private_contract in available_contracts { + if private_contract == contract_address { + continue; + } + self.patch_account_state(&private_contract, block, &mut state)?; + } + } + } let machine = engine.machine(); let schedule = machine.schedule(env_info.number); let result = Executive::new(&mut state, &env_info, &machine, &schedule).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)?; - trace!(target: "privatetx", "Private contract executed. code: {:?}, state: {:?}, result: {:?}", code, storage, result.output); - 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))?) - }, + let (encrypted_code, encrypted_storage) = { + let (code, storage) = state.into_account(&contract_address)?; + trace!(target: "privatetx", "Private contract executed. code: {:?}, state: {:?}, result: {:?}", code, storage, result.output); + let enc_code = match code { + Some(c) => Some(self.encrypt(&contract_address, &Self::iv_from_address(&contract_address), &c)?), + None => None, + }; + (enc_code, self.encrypt(&contract_address, &Self::iv_from_transaction(transaction), &Self::snapshot_from_storage(&storage))?) }; Ok(PrivateExecutionResult { code: encrypted_code, state: encrypted_storage, - contract_address, + contract_address: contract_address, result, }) } @@ -555,14 +577,11 @@ impl Provider where { /// 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)) + Ok(key_server_keys::address_to_key(contract_address)) } /// 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> { + pub fn public_creation_transaction(&self, block: BlockId, source: &SignedTransaction, validators: &[Address], gas_price: U256) -> Result<(Transaction, Address), Error> { if let Action::Call(_) = source.action { bail!(ErrorKind::BadTransactonType); } @@ -740,5 +759,6 @@ impl ChainNotify for Provider { if let Err(err) = self.process_verification_queue() { warn!(target: "privatetx", "Cannot prune private transactions queue. error: {:?}", err); } + self.keys_provider.update_acl_contract(); } } diff --git a/ethcore/private-tx/tests/private_contract.rs b/ethcore/private-tx/tests/private_contract.rs index b681a03800..0492191b63 100644 --- a/ethcore/private-tx/tests/private_contract.rs +++ b/ethcore/private-tx/tests/private_contract.rs @@ -29,7 +29,7 @@ extern crate rustc_hex; extern crate log; use std::sync::Arc; -use rustc_hex::FromHex; +use rustc_hex::{FromHex, ToHex}; use types::ids::BlockId; use types::transaction::{Transaction, Action}; @@ -42,7 +42,7 @@ use ethcore::test_helpers::{generate_dummy_client, push_block_with_transactions} use ethkey::{Secret, KeyPair, Signature}; use hash::keccak; -use ethcore_private_tx::{NoopEncryptor, Provider, ProviderConfig}; +use ethcore_private_tx::{NoopEncryptor, Provider, ProviderConfig, StoringKeyProvider}; #[test] fn private_contract() { @@ -67,6 +67,7 @@ fn private_contract() { let io = ethcore_io::IoChannel::disconnected(); let miner = Arc::new(Miner::new_for_tests(&::ethcore::spec::Spec::new_test(), None)); + let private_keys = Arc::new(StoringKeyProvider::default()); let pm = Arc::new(Provider::new( client.clone(), miner, @@ -74,6 +75,7 @@ fn private_contract() { Box::new(NoopEncryptor::default()), config, io, + private_keys, )); let (address, _) = contract_address(CreateContractAddress::FromSenderAndNonce, &key1.address(), &0.into(), &[]); @@ -155,3 +157,127 @@ fn private_contract() { let result = pm.private_call(BlockId::Latest, &query_tx).unwrap(); assert_eq!(result.output, "2a00000000000000000000000000000000000000000000000000000000000000".from_hex().unwrap()); } + +#[test] +fn call_other_private_contract() { + // This test verifies calls private contract methods from another one + // Two contract will be deployed + // The same contract A: + // contract Test1 { + // bytes32 public x; + // function setX(bytes32 _x) { + // x = _x; + // } + // } + // And the following contract B: + // contract Deployed { + // function setX(uint) {} + // function x() returns (uint) {} + //} + // contract Existing { + // Deployed dc; + // function Existing(address t) { + // dc = Deployed(t); + // } + // function getX() returns (uint) { + // return dc.x(); + // } + // } + //ethcore_logger::init_log(); + + // Create client and provider + 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(), &"".into()).unwrap(); + ap.insert_account(key3.secret().clone(), &"".into()).unwrap(); + ap.insert_account(key4.secret().clone(), &"".into()).unwrap(); + + let config = ProviderConfig{ + validator_accounts: vec![key3.address(), key4.address()], + signer_account: None, + passwords: vec!["".into()], + }; + + let io = ethcore_io::IoChannel::disconnected(); + let miner = Arc::new(Miner::new_for_tests(&::ethcore::spec::Spec::new_test(), None)); + let private_keys = Arc::new(StoringKeyProvider::default()); + let pm = Arc::new(Provider::new( + client.clone(), + miner, + ap.clone(), + Box::new(NoopEncryptor::default()), + config, + io, + private_keys.clone(), + )); + + // Deploy contract A + let (address_a, _) = contract_address(CreateContractAddress::FromSenderAndNonce, &key1.address(), &0.into(), &[]); + trace!("Creating private contract A"); + let private_contract_a_test = "6060604052341561000f57600080fd5b60d88061001d6000396000f30060606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680630c55699c146046578063bc64b76d14607457600080fd5b3415605057600080fd5b60566098565b60405180826000191660001916815260200191505060405180910390f35b3415607e57600080fd5b6096600480803560001916906020019091905050609e565b005b60005481565b8060008160001916905550505600a165627a7a723058206acbdf4b15ca4c2d43e1b1879b830451a34f1e9d02ff1f2f394d8d857e79d2080029".from_hex().unwrap(); + let mut private_create_tx1 = Transaction::default(); + private_create_tx1.action = Action::Create; + private_create_tx1.data = private_contract_a_test; + private_create_tx1.gas = 200000.into(); + private_create_tx1.nonce = 0.into(); + let private_create_tx_signed = private_create_tx1.sign(&key1.secret(), None); + let validators = vec![key3.address(), key4.address()]; + let (public_tx1, _) = pm.public_creation_transaction(BlockId::Latest, &private_create_tx_signed, &validators, 0.into()).unwrap(); + let public_tx1 = public_tx1.sign(&key1.secret(), chain_id); + trace!("Transaction created. Pushing block"); + push_block_with_transactions(&client, &[public_tx1]); + + // Deploy contract B + let (address_b, _) = contract_address(CreateContractAddress::FromSenderAndNonce, &key1.address(), &1.into(), &[]); + trace!("Creating private contract B"); + // Build constructor data + let mut deploy_data = "6060604052341561000f57600080fd5b6040516020806101c583398101604052808051906020019091905050806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505061014a8061007b6000396000f300606060405260043610610041576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680635197c7aa14610046575b600080fd5b341561005157600080fd5b61005961006f565b6040518082815260200191505060405180910390f35b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630c55699c6000604051602001526040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b15156100fe57600080fd5b6102c65a03f1151561010f57600080fd5b505050604051805190509050905600a165627a7a723058207f8994e02725b47d76ec73e5c54a338d27b306dd1c830276bff2d75fcd1a5c920029000000000000000000000000".to_string(); + deploy_data.push_str(&address_a.to_vec().to_hex()); + let private_contract_b_test = deploy_data.from_hex().unwrap(); + let mut private_create_tx2 = Transaction::default(); + private_create_tx2.action = Action::Create; + private_create_tx2.data = private_contract_b_test; + private_create_tx2.gas = 200000.into(); + private_create_tx2.nonce = 1.into(); + let private_create_tx_signed = private_create_tx2.sign(&key1.secret(), None); + let (public_tx2, _) = pm.public_creation_transaction(BlockId::Latest, &private_create_tx_signed, &validators, 0.into()).unwrap(); + let public_tx2 = public_tx2.sign(&key1.secret(), chain_id); + trace!("Transaction created. Pushing block"); + push_block_with_transactions(&client, &[public_tx2]); + + // Let provider know, that it has access to both keys for A and B + private_keys.set_available_keys(&vec![address_a, address_b]); + + // Call A.setx(42) + trace!("Modifying private state"); + let mut private_tx = Transaction::default(); + private_tx.action = Action::Call(address_a.clone()); + private_tx.data = "bc64b76d2a00000000000000000000000000000000000000000000000000000000000000".from_hex().unwrap(); //setX(42) + private_tx.gas = 120000.into(); + private_tx.nonce = 2.into(); + let private_tx = private_tx.sign(&key1.secret(), None); + let private_contract_nonce = pm.get_contract_nonce(&address_b, 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, 2.into(), 0.into()).unwrap(); + let public_tx = public_tx.sign(&key1.secret(), chain_id); + push_block_with_transactions(&client, &[public_tx]); + + // Call B.getX() + trace!("Querying private state"); + let mut query_tx = Transaction::default(); + query_tx.action = Action::Call(address_b.clone()); + query_tx.data = "5197c7aa".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()[..])); +} \ No newline at end of file diff --git a/ethcore/service/src/service.rs b/ethcore/service/src/service.rs index 831d1f0e45..c2137cfc6d 100644 --- a/ethcore/service/src/service.rs +++ b/ethcore/service/src/service.rs @@ -99,6 +99,7 @@ impl ClientService { account_provider: Arc, encryptor: Box, private_tx_conf: ethcore_private_tx::ProviderConfig, + private_encryptor_conf: ethcore_private_tx::EncryptorConfig, ) -> Result { let io_service = IoService::::start()?; @@ -127,13 +128,18 @@ impl ClientService { }; let snapshot = Arc::new(SnapshotService::new(snapshot_params)?); + let private_keys = Arc::new(ethcore_private_tx::SecretStoreKeys::new( + client.clone(), + private_encryptor_conf.key_server_account, + )); let provider = Arc::new(ethcore_private_tx::Provider::new( - client.clone(), - miner, - account_provider, - encryptor, - private_tx_conf, - io_service.channel(), + client.clone(), + miner, + account_provider, + encryptor, + private_tx_conf, + io_service.channel(), + private_keys, )); let private_tx = Arc::new(PrivateTxService::new(provider)); @@ -314,6 +320,7 @@ mod tests { Arc::new(AccountProvider::transient_provider()), Box::new(ethcore_private_tx::NoopEncryptor), Default::default(), + Default::default(), ); assert!(service.is_ok()); drop(service.unwrap()); diff --git a/ethcore/sync/src/tests/private.rs b/ethcore/sync/src/tests/private.rs index 10bd7d1f3d..221caf77c5 100644 --- a/ethcore/sync/src/tests/private.rs +++ b/ethcore/sync/src/tests/private.rs @@ -24,7 +24,7 @@ use ethcore::CreateContractAddress; use types::transaction::{Transaction, Action}; use ethcore::executive::{contract_address}; use ethcore::test_helpers::{push_block_with_transactions}; -use ethcore_private_tx::{Provider, ProviderConfig, NoopEncryptor, Importer, SignedPrivateTransaction}; +use ethcore_private_tx::{Provider, ProviderConfig, NoopEncryptor, Importer, SignedPrivateTransaction, StoringKeyProvider}; use ethcore::account_provider::AccountProvider; use ethkey::{KeyPair}; use tests::helpers::{TestNet, TestIoHandler}; @@ -78,6 +78,8 @@ fn send_private_transaction() { passwords: vec!["".into()], }; + let private_keys = Arc::new(StoringKeyProvider::default()); + let pm0 = Arc::new(Provider::new( client0.clone(), net.peer(0).miner.clone(), @@ -85,6 +87,7 @@ fn send_private_transaction() { Box::new(NoopEncryptor::default()), signer_config, IoChannel::to_handler(Arc::downgrade(&io_handler0)), + private_keys.clone(), )); pm0.add_notify(net.peers[0].clone()); @@ -95,6 +98,7 @@ fn send_private_transaction() { Box::new(NoopEncryptor::default()), validator_config, IoChannel::to_handler(Arc::downgrade(&io_handler1)), + private_keys.clone(), )); pm1.add_notify(net.peers[1].clone()); diff --git a/parity/blockchain.rs b/parity/blockchain.rs index 0f9d081f6f..65c43a27c5 100644 --- a/parity/blockchain.rs +++ b/parity/blockchain.rs @@ -398,6 +398,7 @@ fn execute_import(cmd: ImportBlockchain) -> Result<(), String> { Arc::new(AccountProvider::transient_provider()), Box::new(ethcore_private_tx::NoopEncryptor), Default::default(), + Default::default(), ).map_err(|e| format!("Client service error: {:?}", e))?; // free up the spec in memory. @@ -589,6 +590,7 @@ fn start_client( Arc::new(AccountProvider::transient_provider()), Box::new(ethcore_private_tx::NoopEncryptor), Default::default(), + Default::default(), ).map_err(|e| format!("Client service error: {:?}", e))?; drop(spec); diff --git a/parity/run.rs b/parity/run.rs index 805a38c4ab..df14372324 100644 --- a/parity/run.rs +++ b/parity/run.rs @@ -582,8 +582,9 @@ fn execute_impl(cmd: RunCmd, logger: Arc, on_client_rq: &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())?), + Box::new(SecretStoreEncryptor::new(cmd.private_encryptor_conf.clone(), fetch.clone()).map_err(|e| e.to_string())?), cmd.private_provider_conf, + cmd.private_encryptor_conf, ).map_err(|e| format!("Client service error: {:?}", e))?; let connection_filter_address = spec.params().node_permission_contract; diff --git a/parity/snapshot.rs b/parity/snapshot.rs index 0be4ce15f7..e0b8097a25 100644 --- a/parity/snapshot.rs +++ b/parity/snapshot.rs @@ -202,6 +202,7 @@ impl SnapshotCommand { Arc::new(AccountProvider::transient_provider()), Box::new(ethcore_private_tx::NoopEncryptor), Default::default(), + Default::default(), ).map_err(|e| format!("Client service error: {:?}", e))?; Ok(service) diff --git a/rpc/src/v1/impls/private.rs b/rpc/src/v1/impls/private.rs index 8744390ba2..e9c8c239cd 100644 --- a/rpc/src/v1/impls/private.rs +++ b/rpc/src/v1/impls/private.rs @@ -94,7 +94,7 @@ impl Private for PrivateClient { transaction: request, receipt: PrivateTransactionReceipt { transaction_hash: tx_hash.into(), - contract_address: contract_address.map(|address| address.into()), + contract_address: contract_address.into(), status_code: 0, } }) diff --git a/rpc/src/v1/types/private_receipt.rs b/rpc/src/v1/types/private_receipt.rs index a9e1eef01e..e6170314f7 100644 --- a/rpc/src/v1/types/private_receipt.rs +++ b/rpc/src/v1/types/private_receipt.rs @@ -24,7 +24,7 @@ pub struct PrivateTransactionReceipt { /// Transaction Hash pub transaction_hash: H256, /// Private contract address - pub contract_address: Option, + pub contract_address: H160, /// Status code #[serde(rename = "status")] pub status_code: u8, @@ -34,7 +34,7 @@ impl From for PrivateTransactionReceipt { fn from(r: EthPrivateReceipt) -> Self { PrivateTransactionReceipt { transaction_hash: r.hash.into(), - contract_address: r.contract_address.map(Into::into), + contract_address: r.contract_address.into(), status_code: r.status_code.into(), } } From e344286c3238592a513eb7f3117e675b56341355 Mon Sep 17 00:00:00 2001 From: Julien Bouteloup Date: Thu, 7 Feb 2019 12:50:15 +0100 Subject: [PATCH 049/168] Add missing step for Using `systemd` service file (#10175) * Add missing step for Using `systemd` service file Copy Parity release from target folder to bin, write `cp -R ./target/release/parity /usr/bin/` to match `ExecStart=/usr/bin/parity --config /etc/parity/config.toml` from `https://github.com/paritytech/parity-ethereum/blob/master/scripts/parity.service` * Copy release to bin folder using sudo install `sudo install ./target/release/parity /usr/bin/parity` --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index efb2d28518..1c0302535f 100644 --- a/README.md +++ b/README.md @@ -125,7 +125,8 @@ To start Parity Ethereum as a regular user using `systemd` init: 1. Copy `./scripts/parity.service` to your `systemd` user directory (usually `~/.config/systemd/user`). -2. To configure Parity Ethereum, write a `/etc/parity/config.toml` config file, see [Configuring Parity Ethereum](https://paritytech.github.io/wiki/Configuring-Parity) for details. +2. Copy release to bin folder, write `sudo install ./target/release/parity /usr/bin/parity` +3. To configure Parity Ethereum, write a `/etc/parity/config.toml` config file, see [Configuring Parity Ethereum](https://paritytech.github.io/wiki/Configuring-Parity) for details. ## Parity Ethereum toolchain From e45ee6cd723486da3d056f1ff295a73a903af859 Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Thu, 7 Feb 2019 12:53:12 +0100 Subject: [PATCH 050/168] fix(osx and windows builds): bump parity-daemonize (#10291) --- Cargo.lock | 6 +++--- Cargo.toml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6a77fb3b72..4b49c18f4f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2423,7 +2423,7 @@ dependencies = [ [[package]] name = "parity-daemonize" -version = "0.1.1" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2479,7 +2479,7 @@ dependencies = [ "number_prefix 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "panic_hook 0.1.0", "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-daemonize 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-daemonize 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-hash-fetch 1.12.0", "parity-ipfs-api 1.12.0", "parity-local-store 0.1.0", @@ -4604,7 +4604,7 @@ dependencies = [ "checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37" "checksum parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fa5168b4cf41f3835e4bc6ffb32f51bc9365dc50cb351904595b3931d917fd0c" "checksum parity-crypto 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b9db194dfbcfe3b398d63d765437a5c7232d59906e203055f0e993f6458ff1" -"checksum parity-daemonize 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c6dbaae957a3ddd307fe0ea0361251ceb651a19810b60d404080b258384da292" +"checksum parity-daemonize 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9b337f62998c855fe263e504fcf883c6a0f94370ba0afc731922e8bc23419cfb" "checksum parity-path 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5962540f99d3895d9addf535f37ab1397886bc2c68e59efd040ef458e5f8c3f7" "checksum parity-rocksdb 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cd55d2d6d6000ec99f021cf52c9acc7d2a402e14f95ced4c5de230696fabe00b" "checksum parity-rocksdb-sys 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "5bbb241262c768522f6460f0e2672dee185c8504d4d0a5a5bab45c1147981c4f" diff --git a/Cargo.toml b/Cargo.toml index 6ef02c124a..8fb048f76b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -50,7 +50,7 @@ node-filter = { path = "ethcore/node-filter" } ethkey = { path = "accounts/ethkey" } rlp = { version = "0.3.0", features = ["ethereum"] } cli-signer= { path = "cli-signer" } -parity-daemonize = "0.1.1" +parity-daemonize = "0.2" parity-hash-fetch = { path = "updater/hash-fetch" } parity-ipfs-api = { path = "ipfs" } parity-local-store = { path = "miner/local-store" } From 8fa56add471f77bb165d66c836363fc0d70b2ec4 Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Thu, 7 Feb 2019 14:34:07 +0100 Subject: [PATCH 051/168] Properly handle check_epoch_end_signal errors (#10015) * Make check_epoch_end_signal to only use immutable data * Move check_epoch_end_signals out of commit_block * Make check_epoch_end_signals possible to fail * Actually return the error from check_epoch_end_signals * Remove a clone * Fix import error --- ethcore/src/client/client.rs | 67 +++++++++++++++++++++--------------- ethcore/src/engines/mod.rs | 3 ++ ethcore/src/state/mod.rs | 7 ++++ 3 files changed, 49 insertions(+), 28 deletions(-) diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index 577829d454..b1f2f0d794 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -61,7 +61,8 @@ use client::{ IoClient, BadBlocks, }; use client::bad_blocks; -use engines::{EthEngine, EpochTransition, ForkChoice}; +use engines::{EthEngine, EpochTransition, ForkChoice, EngineError}; +use engines::epoch::PendingTransition; use error::{ ImportErrorKind, ExecutionError, CallError, BlockError, QueueError, QueueErrorKind, Error as EthcoreError, EthcoreResult, ErrorKind as EthcoreErrorKind @@ -295,8 +296,8 @@ impl Importer { continue; } - match self.check_and_lock_block(block, client) { - Ok(closed_block) => { + match self.check_and_lock_block(&bytes, block, client) { + Ok((closed_block, pending)) => { if self.engine.is_proposal(&header) { self.block_queue.mark_as_good(&[hash]); proposed_blocks.push(bytes); @@ -305,7 +306,7 @@ impl Importer { let transactions_len = closed_block.transactions().len(); - let route = self.commit_block(closed_block, &header, encoded::Block::new(bytes), client); + let route = self.commit_block(closed_block, &header, encoded::Block::new(bytes), pending, client); import_results.push(route); client.report.write().accrue_block(&header, transactions_len); @@ -357,7 +358,7 @@ impl Importer { imported } - fn check_and_lock_block(&self, block: PreverifiedBlock, client: &Client) -> EthcoreResult { + fn check_and_lock_block(&self, bytes: &[u8], block: PreverifiedBlock, client: &Client) -> EthcoreResult<(LockedBlock, Option)> { let engine = &*self.engine; let header = block.header.clone(); @@ -441,7 +442,15 @@ impl Importer { bail!(e); } - Ok(locked_block) + let pending = self.check_epoch_end_signal( + &header, + bytes, + locked_block.receipts(), + locked_block.state().db(), + client + )?; + + Ok((locked_block, pending)) } /// Import a block with transaction receipts. @@ -474,7 +483,7 @@ impl Importer { // // The header passed is from the original block data and is sealed. // TODO: should return an error if ImportRoute is none, issue #9910 - fn commit_block(&self, block: B, header: &Header, block_data: encoded::Block, client: &Client) -> ImportRoute where B: Drain { + fn commit_block(&self, block: B, header: &Header, block_data: encoded::Block, pending: Option, client: &Client) -> ImportRoute where B: Drain { let hash = &header.hash(); let number = header.number(); let parent = header.parent_hash(); @@ -529,15 +538,9 @@ impl Importer { // check epoch end signal, potentially generating a proof on the current // state. - self.check_epoch_end_signal( - &header, - block_data.raw(), - &receipts, - &state, - &chain, - &mut batch, - client - ); + if let Some(pending) = pending { + chain.insert_pending_transition(&mut batch, header.hash(), pending); + } state.journal_under(&mut batch, number, hash).expect("DB commit failed"); @@ -592,10 +595,8 @@ impl Importer { block_bytes: &[u8], receipts: &[Receipt], state_db: &StateDB, - chain: &BlockChain, - batch: &mut DBTransaction, client: &Client, - ) { + ) -> EthcoreResult> { use engines::EpochChange; let hash = header.hash(); @@ -606,7 +607,6 @@ impl Importer { match self.engine.signals_epoch_end(header, auxiliary) { EpochChange::Yes(proof) => { - use engines::epoch::PendingTransition; use engines::Proof; let proof = match proof { @@ -643,11 +643,9 @@ impl Importer { .transact(&transaction, options); let res = match res { - Err(ExecutionError::Internal(e)) => - Err(format!("Internal error: {}", e)), Err(e) => { trace!(target: "client", "Proved call failed: {}", e); - Ok((Vec::new(), state.drop().1.extract_proof())) + Err(e.to_string()) } Ok(res) => Ok((res.output, state.drop().1.extract_proof())), }; @@ -660,7 +658,7 @@ impl Importer { Err(e) => { warn!(target: "client", "Failed to generate transition proof for block {}: {}", hash, e); warn!(target: "client", "Snapshots produced by this client may be incomplete"); - Vec::new() + return Err(EngineError::FailedSystemCall(e).into()) } } } @@ -668,13 +666,13 @@ impl Importer { debug!(target: "client", "Block {} signals epoch end.", hash); - let pending = PendingTransition { proof: proof }; - chain.insert_pending_transition(batch, hash, pending); + Ok(Some(PendingTransition { proof: proof })) }, - EpochChange::No => {}, + EpochChange::No => Ok(None), EpochChange::Unsure(_) => { warn!(target: "client", "Detected invalid engine implementation."); warn!(target: "client", "Engine claims to require more block data, but everything provided."); + Err(EngineError::InvalidEngine.into()) } } } @@ -2380,7 +2378,20 @@ impl ImportSealedBlock for Client { let block_data = block.rlp_bytes(); - let route = self.importer.commit_block(block, &header, encoded::Block::new(block_data), self); + let pending = self.importer.check_epoch_end_signal( + &header, + &block_data, + block.receipts(), + block.state().db(), + self + )?; + let route = self.importer.commit_block( + block, + &header, + encoded::Block::new(block_data), + pending, + self + ); trace!(target: "client", "Imported sealed block #{} ({})", header.number(), hash); self.state_db.write().sync_cache(&route.enacted, &route.retracted, false); route diff --git a/ethcore/src/engines/mod.rs b/ethcore/src/engines/mod.rs index 64d05e5c46..deb85cd35f 100644 --- a/ethcore/src/engines/mod.rs +++ b/ethcore/src/engines/mod.rs @@ -81,6 +81,8 @@ pub enum EngineError { MalformedMessage(String), /// Requires client ref, but none registered. RequiresClient, + /// Invalid engine specification or implementation. + InvalidEngine, } impl fmt::Display for EngineError { @@ -96,6 +98,7 @@ impl fmt::Display for EngineError { FailedSystemCall(ref msg) => format!("Failed to make system call: {}", msg), MalformedMessage(ref msg) => format!("Received malformed consensus message: {}", msg), RequiresClient => format!("Call requires client but none registered"), + InvalidEngine => format!("Invalid engine specification or implementation"), }; f.write_fmt(format_args!("Engine error ({})", msg)) diff --git a/ethcore/src/state/mod.rs b/ethcore/src/state/mod.rs index 2939c97297..4d24a1b157 100644 --- a/ethcore/src/state/mod.rs +++ b/ethcore/src/state/mod.rs @@ -1284,6 +1284,13 @@ impl fmt::Debug for State { } } +impl State { + /// Get a reference to the underlying state DB. + pub fn db(&self) -> &StateDB { + &self.db + } +} + // TODO: cloning for `State` shouldn't be possible in general; Remove this and use // checkpoints where possible. impl Clone for State { From d5c19f8719dbcaeabafe1ed99cd0486c52ea0c48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Thu, 7 Feb 2019 14:34:24 +0100 Subject: [PATCH 052/168] Deprecate account management (#10213) * Extract accounts from ethcore. * Fix ethcore. * Get rid of AccountProvider in test_helpers * Fix rest of the code. * Re-use EngineSigner, fix tests. * Simplify EngineSigner to always have an Address. * Fix RPC tests. * Add deprecation notice to RPCs. * Feature to disable accounts. * extract accounts in RPC * Run with accounts in tests. * Fix RPC compilation and tests. * Fix compilation of the binary. * Fix compilation of the binary. * Fix compilation with accounts enabled. * Fix tests. * Update submodule. * Remove android. * Use derive for Default * Don't build secretstore by default. * Add link to issue. * Refresh Cargo.lock. * Fix miner tests. * Update rpc/Cargo.toml Co-Authored-By: tomusdrw * Fix private tests. --- Cargo.lock | 27 +- Cargo.toml | 11 +- accounts/Cargo.toml | 28 + .../src/account_data.rs | 47 +- accounts/src/error.rs | 56 ++ .../mod.rs => accounts/src/lib.rs | 126 +-- .../src}/stores.rs | 20 +- ethcore/Cargo.toml | 8 +- ethcore/private-tx/src/encryptor.rs | 39 +- ethcore/private-tx/src/error.rs | 15 +- ethcore/private-tx/src/lib.rs | 78 +- ethcore/private-tx/tests/private_contract.rs | 20 +- ethcore/service/src/service.rs | 10 +- ethcore/src/engines/authority_round/mod.rs | 80 +- ethcore/src/engines/basic_authority.rs | 29 +- ethcore/src/engines/block_reward.rs | 7 +- ethcore/src/engines/mod.rs | 10 +- ethcore/src/engines/signer.rs | 83 +- ethcore/src/engines/validator_set/contract.rs | 13 +- ethcore/src/engines/validator_set/multi.rs | 17 +- .../engines/validator_set/safe_contract.rs | 23 +- ethcore/src/error.rs | 15 +- ethcore/src/lib.rs | 19 +- ethcore/src/miner/miner.rs | 100 +- ethcore/src/miner/mod.rs | 8 +- ethcore/src/miner/pool_client.rs | 10 +- ethcore/src/snapshot/service.rs | 4 +- .../src/snapshot/tests/proof_of_authority.rs | 12 +- ethcore/src/test_helpers.rs | 18 +- ethcore/sync/Cargo.toml | 7 +- ethcore/sync/src/api.rs | 2 +- ethcore/sync/src/lib.rs | 2 +- ethcore/sync/src/tests/consensus.rs | 13 +- ethcore/sync/src/tests/helpers.rs | 10 +- ethcore/sync/src/tests/private.rs | 30 +- json/src/lib.rs | 1 - json/src/misc/mod.rs | 52 -- miner/src/lib.rs | 1 + .../src/local_accounts.rs | 34 +- parity/account.rs | 161 ++-- parity/account_utils.rs | 244 +++++ parity/blockchain.rs | 10 +- parity/configuration.rs | 15 +- parity/lib.rs | 18 +- parity/params.rs | 5 +- parity/presale.rs | 31 +- parity/rpc_apis.rs | 148 ++- parity/run.rs | 132 +-- parity/secretstore.rs | 7 +- parity/snapshot.rs | 3 +- rpc/Cargo.toml | 19 +- rpc/src/lib.rs | 6 +- rpc/src/v1/helpers/deprecated.rs | 111 +++ rpc/src/v1/helpers/dispatch.rs | 879 ------------------ rpc/src/v1/helpers/dispatch/full.rs | 151 +++ rpc/src/v1/helpers/dispatch/light.rs | 266 ++++++ rpc/src/v1/helpers/dispatch/mod.rs | 381 ++++++++ .../v1/helpers/dispatch/prospective_signer.rs | 152 +++ rpc/src/v1/helpers/dispatch/signing.rs | 156 ++++ rpc/src/v1/helpers/engine_signer.rs | 51 + rpc/src/v1/helpers/errors.rs | 21 +- .../{signer.rs => external_signer/mod.rs} | 30 +- .../helpers/{ => external_signer}/oneshot.rs | 0 .../{ => external_signer}/signing_queue.rs | 26 +- rpc/src/v1/helpers/light_fetch.rs | 2 +- rpc/src/v1/helpers/mod.rs | 15 +- rpc/src/v1/helpers/requests.rs | 3 +- rpc/src/v1/helpers/signature.rs | 9 +- rpc/src/v1/impls/eth.rs | 21 +- rpc/src/v1/impls/light/eth.rs | 26 +- rpc/src/v1/impls/light/parity.rs | 54 +- rpc/src/v1/impls/light/parity_set.rs | 2 +- rpc/src/v1/impls/mod.rs | 8 + rpc/src/v1/impls/parity.rs | 53 +- rpc/src/v1/impls/parity_accounts.rs | 122 ++- rpc/src/v1/impls/parity_set.rs | 63 +- rpc/src/v1/impls/personal.rs | 74 +- rpc/src/v1/impls/secretstore.rs | 2 +- rpc/src/v1/impls/signer.rs | 35 +- rpc/src/v1/impls/signing.rs | 49 +- rpc/src/v1/impls/signing_unsafe.rs | 36 +- rpc/src/v1/mod.rs | 6 +- rpc/src/v1/tests/eth.rs | 30 +- rpc/src/v1/tests/helpers/miner_service.rs | 19 +- rpc/src/v1/tests/mocked/eth.rs | 200 +--- rpc/src/v1/tests/mocked/mod.rs | 6 + rpc/src/v1/tests/mocked/parity.rs | 48 +- rpc/src/v1/tests/mocked/parity_accounts.rs | 50 +- rpc/src/v1/tests/mocked/parity_set.rs | 51 +- rpc/src/v1/tests/mocked/personal.rs | 2 +- rpc/src/v1/tests/mocked/secretstore.rs | 2 +- rpc/src/v1/tests/mocked/signer.rs | 36 +- rpc/src/v1/tests/mocked/signing.rs | 36 +- rpc/src/v1/tests/mocked/signing_unsafe.rs | 237 +++++ rpc/src/v1/traits/mod.rs | 4 +- rpc/src/v1/traits/parity.rs | 18 +- rpc/src/v1/traits/parity_accounts.rs | 21 + rpc/src/v1/traits/parity_set.rs | 14 +- rpc/src/v1/traits/signer.rs | 4 - secret-store/Cargo.toml | 38 +- secret-store/src/lib.rs | 7 +- secret-store/src/node_key_pair.rs | 74 +- 102 files changed, 3207 insertions(+), 2378 deletions(-) create mode 100644 accounts/Cargo.toml rename json/src/misc/account_meta.rs => accounts/src/account_data.rs (51%) create mode 100644 accounts/src/error.rs rename ethcore/src/account_provider/mod.rs => accounts/src/lib.rs (92%) rename {ethcore/src/account_provider => accounts/src}/stores.rs (89%) delete mode 100644 json/src/misc/mod.rs rename rpc/src/v1/helpers/accounts.rs => miner/src/local_accounts.rs (56%) create mode 100644 parity/account_utils.rs create mode 100644 rpc/src/v1/helpers/deprecated.rs delete mode 100644 rpc/src/v1/helpers/dispatch.rs create mode 100644 rpc/src/v1/helpers/dispatch/full.rs create mode 100644 rpc/src/v1/helpers/dispatch/light.rs create mode 100644 rpc/src/v1/helpers/dispatch/mod.rs create mode 100644 rpc/src/v1/helpers/dispatch/prospective_signer.rs create mode 100644 rpc/src/v1/helpers/dispatch/signing.rs create mode 100644 rpc/src/v1/helpers/engine_signer.rs rename rpc/src/v1/helpers/{signer.rs => external_signer/mod.rs} (71%) rename rpc/src/v1/helpers/{ => external_signer}/oneshot.rs (100%) rename rpc/src/v1/helpers/{ => external_signer}/signing_queue.rs (94%) create mode 100644 rpc/src/v1/tests/mocked/signing_unsafe.rs diff --git a/Cargo.lock b/Cargo.lock index 4b49c18f4f..5e631b2eb1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -693,6 +693,7 @@ dependencies = [ "ethabi-contract 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethabi-derive 6.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "ethash 1.12.0", + "ethcore-accounts 0.1.0", "ethcore-blockchain 0.1.0", "ethcore-bloom-journal 0.1.0", "ethcore-call-contract 0.1.0", @@ -703,10 +704,7 @@ dependencies = [ "ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethjson 0.1.0", "ethkey 0.3.0", - "ethstore 0.2.1", "evm 0.1.0", - "fake-hardware-wallet 0.0.1", - "hardware-wallet 1.12.0", "hashdb 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.4.2 (git+https://github.com/cheme/heapsize.git?branch=ec-macfix)", "itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", @@ -751,6 +749,24 @@ dependencies = [ "wasm 0.1.0", ] +[[package]] +name = "ethcore-accounts" +version = "0.1.0" +dependencies = [ + "common-types 0.1.0", + "ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethkey 0.3.0", + "ethstore 0.2.1", + "fake-hardware-wallet 0.0.1", + "hardware-wallet 1.12.0", + "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)", + "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "ethcore-blockchain" version = "0.1.0" @@ -1015,6 +1031,7 @@ dependencies = [ "ethabi-contract 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethabi-derive 6.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore 1.12.0", + "ethcore-accounts 0.1.0", "ethcore-call-contract 0.1.0", "ethcore-sync 1.12.0", "ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2447,6 +2464,7 @@ dependencies = [ "dir 0.1.2", "docopt 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore 1.12.0", + "ethcore-accounts 0.1.0", "ethcore-blockchain 0.1.0", "ethcore-call-contract 0.1.0", "ethcore-db 0.1.0", @@ -2605,6 +2623,7 @@ dependencies = [ "eip-712 0.1.0", "ethash 1.12.0", "ethcore 1.12.0", + "ethcore-accounts 0.1.0", "ethcore-io 1.12.0", "ethcore-light 1.12.0", "ethcore-logger 1.12.0", @@ -2617,11 +2636,9 @@ dependencies = [ "ethkey 0.3.0", "ethstore 0.2.1", "fake-fetch 0.0.1", - "fake-hardware-wallet 0.0.1", "fastmap 0.1.0", "fetch 0.1.0", "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "hardware-wallet 1.12.0", "itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-derive 10.0.2 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index 8fb048f76b..d639d1d790 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,9 +30,10 @@ futures = "0.1" fdlimit = "0.1" ctrlc = { git = "https://github.com/paritytech/rust-ctrlc.git" } jsonrpc-core = "10.0.1" -ethcore = { path = "ethcore", features = ["parity"] } parity-bytes = "0.1" common-types = { path = "ethcore/types" } +ethcore = { path = "ethcore", features = ["parity"] } +ethcore-accounts = { path = "accounts", optional = true } ethcore-blockchain = { path = "ethcore/blockchain" } ethcore-call-contract = { path = "ethcore/call-contract"} ethcore-db = { path = "ethcore/db" } @@ -44,10 +45,10 @@ ethcore-network = { path = "util/network" } ethcore-private-tx = { path = "ethcore/private-tx" } ethcore-service = { path = "ethcore/service" } ethcore-sync = { path = "ethcore/sync" } -ethstore = { path = "accounts/ethstore" } ethereum-types = "0.4" -node-filter = { path = "ethcore/node-filter" } ethkey = { path = "accounts/ethkey" } +ethstore = { path = "accounts/ethstore" } +node-filter = { path = "ethcore/node-filter" } rlp = { version = "0.3.0", features = ["ethereum"] } cli-signer= { path = "cli-signer" } parity-daemonize = "0.2" @@ -86,6 +87,8 @@ lazy_static = "1.2.0" winapi = { version = "0.3.4", features = ["winsock2", "winuser", "shellapi"] } [features] +default = ["accounts"] +accounts = ["ethcore-accounts", "parity-rpc/accounts"] miner-debug = ["ethcore/miner-debug"] json-tests = ["ethcore/json-tests"] ci-skip-issue = ["ethcore/ci-skip-issue"] @@ -93,7 +96,7 @@ test-heavy = ["ethcore/test-heavy"] evm-debug = ["ethcore/evm-debug"] evm-debug-tests = ["ethcore/evm-debug-tests"] slow-blocks = ["ethcore/slow-blocks"] -secretstore = ["ethcore-secretstore"] +secretstore = ["ethcore-secretstore", "ethcore-secretstore/accounts"] final = ["parity-version/final"] deadlock_detection = ["parking_lot/deadlock_detection"] # to create a memory profile (requires nightly rust), use e.g. diff --git a/accounts/Cargo.toml b/accounts/Cargo.toml new file mode 100644 index 0000000000..072593cd10 --- /dev/null +++ b/accounts/Cargo.toml @@ -0,0 +1,28 @@ +[package] +description = "Account management for Parity Ethereum" +homepage = "http://parity.io" +license = "GPL-3.0" +name = "ethcore-accounts" +version = "0.1.0" +authors = ["Parity Technologies "] +edition = "2018" + +[dependencies] +common-types = { path = "../ethcore/types" } +ethkey = { path = "ethkey" } +ethstore = { path = "ethstore" } +log = "0.4" +parking_lot = "0.7" +serde = "1.0" +serde_derive = "1.0" +serde_json = "1.0" + +[target.'cfg(any(target_os = "linux", target_os = "macos", target_os = "windows"))'.dependencies] +hardware-wallet = { path = "hw" } + +[target.'cfg(not(any(target_os = "linux", target_os = "macos", target_os = "windows")))'.dependencies] +fake-hardware-wallet = { path = "fake-hardware-wallet" } + +[dev-dependencies] +ethereum-types = "0.4" +tempdir = "0.3" diff --git a/json/src/misc/account_meta.rs b/accounts/src/account_data.rs similarity index 51% rename from json/src/misc/account_meta.rs rename to accounts/src/account_data.rs index f6f8c0c637..a36d38740e 100644 --- a/json/src/misc/account_meta.rs +++ b/accounts/src/account_data.rs @@ -14,9 +14,35 @@ // You should have received a copy of the GNU General Public License // along with Parity Ethereum. If not, see . -//! Misc deserialization. +//! Account Metadata -use hash; +use std::{ + collections::HashMap, + time::Instant, +}; + +use ethkey::{Address, Password}; +use serde_derive::{Serialize, Deserialize}; +use serde_json; + +/// Type of unlock. +#[derive(Clone, PartialEq)] +pub enum Unlock { + /// If account is unlocked temporarily, it should be locked after first usage. + OneTime, + /// Account unlocked permanently can always sign message. + /// Use with caution. + Perm, + /// Account unlocked with a timeout + Timed(Instant), +} + +/// Data associated with account. +#[derive(Clone)] +pub struct AccountData { + pub unlock: Unlock, + pub password: Password, +} /// Collected account metadata #[derive(Default, Clone, Debug, PartialEq, Serialize, Deserialize)] @@ -29,4 +55,19 @@ pub struct AccountMeta { pub uuid: Option, } -impl_serialization!(hash::Address => AccountMeta); +impl AccountMeta { + /// Read a hash map of Address -> AccountMeta + pub fn read(reader: R) -> Result, serde_json::Error> where + R: ::std::io::Read, + { + serde_json::from_reader(reader) + } + + /// Write a hash map of Address -> AccountMeta + pub fn write(m: &HashMap, writer: &mut W) -> Result<(), serde_json::Error> where + W: ::std::io::Write, + { + serde_json::to_writer(writer, m) + } +} + diff --git a/accounts/src/error.rs b/accounts/src/error.rs new file mode 100644 index 0000000000..2aa3564efd --- /dev/null +++ b/accounts/src/error.rs @@ -0,0 +1,56 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +use std::fmt; + +use ethstore::{Error as SSError}; +use hardware_wallet::{Error as HardwareError}; + +/// Signing error +#[derive(Debug)] +pub enum SignError { + /// Account is not unlocked + NotUnlocked, + /// Account does not exist. + NotFound, + /// Low-level hardware device error. + Hardware(HardwareError), + /// Low-level error from store + SStore(SSError), +} + +impl fmt::Display for SignError { + fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { + match *self { + SignError::NotUnlocked => write!(f, "Account is locked"), + SignError::NotFound => write!(f, "Account does not exist"), + SignError::Hardware(ref e) => write!(f, "{}", e), + SignError::SStore(ref e) => write!(f, "{}", e), + } + } +} + +impl From for SignError { + fn from(e: HardwareError) -> Self { + SignError::Hardware(e) + } +} + +impl From for SignError { + fn from(e: SSError) -> Self { + SignError::SStore(e) + } +} diff --git a/ethcore/src/account_provider/mod.rs b/accounts/src/lib.rs similarity index 92% rename from ethcore/src/account_provider/mod.rs rename to accounts/src/lib.rs index 0414c42468..0107eadad0 100644 --- a/ethcore/src/account_provider/mod.rs +++ b/accounts/src/lib.rs @@ -14,94 +14,55 @@ // You should have received a copy of the GNU General Public License // along with Parity Ethereum. If not, see . +#![warn(missing_docs)] + //! Account management. +mod account_data; +mod error; mod stores; +#[cfg(not(any(target_os = "linux", target_os = "macos", target_os = "windows")))] +extern crate fake_hardware_wallet as hardware_wallet; + +use self::account_data::{Unlock, AccountData}; use self::stores::AddressBook; use std::collections::HashMap; -use std::fmt; use std::time::{Instant, Duration}; +use common_types::transaction::{Action, Transaction}; +use ethkey::{Address, Message, Public, Secret, Password, Random, Generator}; use ethstore::accounts_dir::MemoryDirectory; -use ethstore::ethkey::{Address, Message, Public, Secret, Password, Random, Generator}; -use ethjson::misc::AccountMeta; use ethstore::{ - SimpleSecretStore, SecretStore, Error as SSError, EthStore, EthMultiStore, + SimpleSecretStore, SecretStore, EthStore, EthMultiStore, random_string, SecretVaultRef, StoreAccountRef, OpaqueSecret, }; +use log::{warn, debug}; use parking_lot::RwLock; -use types::transaction::{Action, Transaction}; -pub use ethstore::ethkey::Signature; -pub use ethstore::{Derivation, IndexDerivation, KeyFile}; +pub use ethkey::Signature; +pub use ethstore::{Derivation, IndexDerivation, KeyFile, Error}; pub use hardware_wallet::{Error as HardwareError, HardwareWalletManager, KeyPath, TransactionInfo}; -/// Type of unlock. -#[derive(Clone, PartialEq)] -enum Unlock { - /// If account is unlocked temporarily, it should be locked after first usage. - OneTime, - /// Account unlocked permanently can always sign message. - /// Use with caution. - Perm, - /// Account unlocked with a timeout - Timed(Instant), -} - -/// Data associated with account. -#[derive(Clone)] -struct AccountData { - unlock: Unlock, - password: Password, -} - -/// Signing error -#[derive(Debug)] -pub enum SignError { - /// Account is not unlocked - NotUnlocked, - /// Account does not exist. - NotFound, - /// Low-level hardware device error. - Hardware(HardwareError), - /// Low-level error from store - SStore(SSError), -} +pub use self::account_data::AccountMeta; +pub use self::error::SignError; -impl fmt::Display for SignError { - fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { - match *self { - SignError::NotUnlocked => write!(f, "Account is locked"), - SignError::NotFound => write!(f, "Account does not exist"), - SignError::Hardware(ref e) => write!(f, "{}", e), - SignError::SStore(ref e) => write!(f, "{}", e), - } - } -} - -impl From for SignError { - fn from(e: HardwareError) -> Self { - SignError::Hardware(e) - } -} - -impl From for SignError { - fn from(e: SSError) -> Self { - SignError::SStore(e) - } -} - -/// `AccountProvider` errors. -pub type Error = SSError; +type AccountToken = Password; -fn transient_sstore() -> EthMultiStore { - EthMultiStore::open(Box::new(MemoryDirectory::default())).expect("MemoryDirectory load always succeeds; qed") +/// Account management settings. +#[derive(Debug, Default)] +pub struct AccountProviderSettings { + /// Enable hardware wallet support. + pub enable_hardware_wallets: bool, + /// Use the classic chain key on the hardware wallet. + pub hardware_wallet_classic_key: bool, + /// Store raw account secret when unlocking the account permanently. + pub unlock_keep_secret: bool, + /// Disallowed accounts. + pub blacklisted_accounts: Vec
, } -type AccountToken = Password; - /// Account management. /// Responsible for unlocking accounts. pub struct AccountProvider { @@ -124,27 +85,8 @@ pub struct AccountProvider { blacklisted_accounts: Vec
, } -/// Account management settings. -pub struct AccountProviderSettings { - /// Enable hardware wallet support. - pub enable_hardware_wallets: bool, - /// Use the classic chain key on the hardware wallet. - pub hardware_wallet_classic_key: bool, - /// Store raw account secret when unlocking the account permanently. - pub unlock_keep_secret: bool, - /// Disallowed accounts. - pub blacklisted_accounts: Vec
, -} - -impl Default for AccountProviderSettings { - fn default() -> Self { - AccountProviderSettings { - enable_hardware_wallets: false, - hardware_wallet_classic_key: false, - unlock_keep_secret: false, - blacklisted_accounts: vec![], - } - } +fn transient_sstore() -> EthMultiStore { + EthMultiStore::open(Box::new(MemoryDirectory::default())).expect("MemoryDirectory load always succeeds; qed") } impl AccountProvider { @@ -221,7 +163,7 @@ impl AccountProvider { let account = self.sstore.insert_account(SecretVaultRef::Root, secret, password)?; if self.blacklisted_accounts.contains(&account.address) { self.sstore.remove_account(&account, password)?; - return Err(SSError::InvalidAccount.into()); + return Err(Error::InvalidAccount.into()); } Ok(account.address) } @@ -251,7 +193,7 @@ impl AccountProvider { let account = self.sstore.import_wallet(SecretVaultRef::Root, json, password, gen_id)?; if self.blacklisted_accounts.contains(&account.address) { self.sstore.remove_account(&account, password)?; - return Err(SSError::InvalidAccount.into()); + return Err(Error::InvalidAccount.into()); } Ok(Address::from(account.address).into()) } @@ -284,7 +226,7 @@ impl AccountProvider { return Ok(accounts.into_iter().map(|a| a.address).collect()); } } - Err(SSError::Custom("No hardware wallet accounts were found".into())) + Err(Error::Custom("No hardware wallet accounts were found".into())) } /// Get a list of paths to locked hardware wallets @@ -669,7 +611,7 @@ impl AccountProvider { mod tests { use super::{AccountProvider, Unlock}; use std::time::{Duration, Instant}; - use ethstore::ethkey::{Generator, Random, Address}; + use ethkey::{Generator, Random, Address}; use ethstore::{StoreAccountRef, Derivation}; use ethereum_types::H256; diff --git a/ethcore/src/account_provider/stores.rs b/accounts/src/stores.rs similarity index 89% rename from ethcore/src/account_provider/stores.rs rename to accounts/src/stores.rs index 10d7ffde88..baa26cc48b 100644 --- a/ethcore/src/account_provider/stores.rs +++ b/accounts/src/stores.rs @@ -20,8 +20,10 @@ use std::{fs, fmt, hash, ops}; use std::collections::HashMap; use std::path::{Path, PathBuf}; -use ethstore::ethkey::Address; -use ethjson::misc::AccountMeta; +use ethkey::Address; +use log::{trace, warn}; + +use crate::AccountMeta; /// Disk-backed map from Address to String. Uses JSON. pub struct AddressBook { @@ -153,8 +155,8 @@ impl DiskMap { mod tests { use super::AddressBook; use std::collections::HashMap; - use ethjson::misc::AccountMeta; use tempdir::TempDir; + use crate::account_data::AccountMeta; #[test] fn should_save_and_reload_address_book() { @@ -163,7 +165,9 @@ mod tests { b.set_name(1.into(), "One".to_owned()); b.set_meta(1.into(), "{1:1}".to_owned()); let b = AddressBook::new(tempdir.path()); - assert_eq!(b.get(), hash_map![1.into() => AccountMeta{name: "One".to_owned(), meta: "{1:1}".to_owned(), uuid: None}]); + assert_eq!(b.get(), vec![ + (1, AccountMeta {name: "One".to_owned(), meta: "{1:1}".to_owned(), uuid: None}) + ].into_iter().map(|(a, b)| (a.into(), b)).collect::>()); } #[test] @@ -177,9 +181,9 @@ mod tests { b.remove(2.into()); let b = AddressBook::new(tempdir.path()); - assert_eq!(b.get(), hash_map![ - 1.into() => AccountMeta{name: "One".to_owned(), meta: "{}".to_owned(), uuid: None}, - 3.into() => AccountMeta{name: "Three".to_owned(), meta: "{}".to_owned(), uuid: None} - ]); + assert_eq!(b.get(), vec![ + (1, AccountMeta{name: "One".to_owned(), meta: "{}".to_owned(), uuid: None}), + (3, AccountMeta{name: "Three".to_owned(), meta: "{}".to_owned(), uuid: None}), + ].into_iter().map(|(a, b)| (a.into(), b)).collect::>()); } } diff --git a/ethcore/Cargo.toml b/ethcore/Cargo.toml index 3572b56394..bd030c174d 100644 --- a/ethcore/Cargo.toml +++ b/ethcore/Cargo.toml @@ -29,7 +29,6 @@ ethcore-stratum = { path = "../miner/stratum", optional = true } ethereum-types = "0.4" ethjson = { path = "../json" } ethkey = { path = "../accounts/ethkey" } -ethstore = { path = "../accounts/ethstore" } evm = { path = "evm" } hashdb = "0.3.0" heapsize = "0.4" @@ -72,16 +71,11 @@ using_queue = { path = "../miner/using-queue" } vm = { path = "vm" } wasm = { path = "wasm" } -[target.'cfg(any(target_os = "linux", target_os = "macos", target_os = "windows"))'.dependencies] -hardware-wallet = { path = "../accounts/hw" } - -[target.'cfg(not(any(target_os = "linux", target_os = "macos", target_os = "windows")))'.dependencies] -fake-hardware-wallet = { path = "../accounts/fake-hardware-wallet" } - [dev-dependencies] blooms-db = { path = "../util/blooms-db" } criterion = "0.2" env_logger = "0.5" +ethcore-accounts = { path = "../accounts" } kvdb-rocksdb = "0.1.3" rlp_compress = { path = "../util/rlp-compress" } tempdir = "0.3" diff --git a/ethcore/private-tx/src/encryptor.rs b/ethcore/private-tx/src/encryptor.rs index 2d8b47e63a..2d284dd38a 100644 --- a/ethcore/private-tx/src/encryptor.rs +++ b/ethcore/private-tx/src/encryptor.rs @@ -18,22 +18,22 @@ use std::io::Read; use std::str::FromStr; +use std::sync::Arc; 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, Password, Public}; +use ethkey::{Signature, Public}; use crypto; use futures::Future; 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; +use super::Signer; use super::key_server_keys::address_to_key; /// Initialization vector length. @@ -48,7 +48,6 @@ pub trait Encryptor: Send + Sync + 'static { fn encrypt( &self, contract_address: &Address, - accounts: &AccountProvider, initialisation_vector: &H128, plain_data: &[u8], ) -> Result; @@ -57,7 +56,6 @@ pub trait Encryptor: Send + Sync + 'static { fn decrypt( &self, contract_address: &Address, - accounts: &AccountProvider, cypher: &[u8], ) -> Result; } @@ -71,8 +69,6 @@ pub struct EncryptorConfig { 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 { @@ -85,14 +81,20 @@ pub struct SecretStoreEncryptor { config: EncryptorConfig, client: FetchClient, sessions: Mutex>, + signer: Arc, } impl SecretStoreEncryptor { /// Create new encryptor - pub fn new(config: EncryptorConfig, client: FetchClient) -> Result { + pub fn new( + config: EncryptorConfig, + client: FetchClient, + signer: Arc, + ) -> Result { Ok(SecretStoreEncryptor { config, client, + signer, sessions: Mutex::default(), }) } @@ -103,13 +105,12 @@ impl SecretStoreEncryptor { 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 contract_address_signature = self.sign_contract_address(contract_address)?; 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 @@ -149,10 +150,9 @@ impl SecretStoreEncryptor { // 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_bytes = self.signer.decrypt(requester, &crypto::DEFAULT_MAC, &encrypted_bytes)?; let decrypted_key = Public::from_slice(&decrypted_bytes); // and now take x coordinate of Public as a key @@ -188,10 +188,9 @@ impl SecretStoreEncryptor { } } - fn sign_contract_address(&self, contract_address: &Address, accounts: &AccountProvider) -> Result { + fn sign_contract_address(&self, contract_address: &Address) -> Result { 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, address_to_key(contract_address))?) + Ok(self.signer.sign(key_server_account, address_to_key(contract_address))?) } } @@ -199,16 +198,15 @@ 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) { + let key = match self.retrieve_key("", false, contract_address) { Ok(key) => Ok(key), Err(Error(ErrorKind::EncryptionKeyNotFound(_), _)) => { trace!(target: "privatetx", "Key for account wasnt found in sstore. Creating. Address: {:?}", contract_address); - self.retrieve_key(&format!("/{}", self.config.threshold), true, contract_address, &*accounts) + self.retrieve_key(&format!("/{}", self.config.threshold), true, contract_address) } Err(err) => Err(err), }?; @@ -227,7 +225,6 @@ impl Encryptor for SecretStoreEncryptor { fn decrypt( &self, contract_address: &Address, - accounts: &AccountProvider, cypher: &[u8], ) -> Result { // initialization vector takes INIT_VEC_LEN bytes @@ -237,7 +234,7 @@ impl Encryptor for SecretStoreEncryptor { } // retrieve existing key - let key = self.retrieve_key("", false, contract_address, accounts)?; + let key = self.retrieve_key("", false, contract_address)?; // use symmetric decryption to decrypt document let (cypher, iv) = cypher.split_at(cypher_len - INIT_VEC_LEN); @@ -257,7 +254,6 @@ impl Encryptor for NoopEncryptor { fn encrypt( &self, _contract_address: &Address, - _accounts: &AccountProvider, _initialisation_vector: &H128, data: &[u8], ) -> Result { @@ -267,7 +263,6 @@ impl Encryptor for NoopEncryptor { 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 index 76a34f9023..325b561b76 100644 --- a/ethcore/private-tx/src/error.rs +++ b/ethcore/private-tx/src/error.rs @@ -17,10 +17,10 @@ use ethereum_types::Address; use rlp::DecoderError; use ethtrie::TrieError; -use ethcore::account_provider::SignError; use ethcore::error::{Error as EthcoreError, ExecutionError}; use types::transaction::Error as TransactionError; use ethkey::Error as KeyError; +use ethkey::crypto::Error as CryptoError; use txpool::Error as TxPoolError; error_chain! { @@ -29,6 +29,7 @@ error_chain! { Decoder(DecoderError) #[doc = "RLP decoding error."]; Trie(TrieError) #[doc = "Error concerning TrieDBs."]; Txpool(TxPoolError) #[doc = "Tx pool error."]; + Crypto(CryptoError) #[doc = "Crypto error."]; } errors { @@ -152,12 +153,6 @@ error_chain! { 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."), @@ -172,12 +167,6 @@ error_chain! { } } -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() diff --git a/ethcore/private-tx/src/lib.rs b/ethcore/private-tx/src/lib.rs index cda80fb071..71a97d6a04 100644 --- a/ethcore/private-tx/src/lib.rs +++ b/ethcore/private-tx/src/lib.rs @@ -87,13 +87,11 @@ use ethcore::client::{ Client, ChainNotify, NewBlocks, ChainMessageType, ClientIoMessage, BlockId, Call, BlockInfo }; -use ethcore::account_provider::AccountProvider; use ethcore::miner::{self, Miner, MinerService, pool_client::NonceCache}; use ethcore::{state, state_db}; use ethcore::trace::{Tracer, VMTracer}; use call_contract::CallContract; use rustc_hex::FromHex; -use ethkey::Password; use ethabi::FunctionOutputDecoder; // Source avaiable at https://github.com/parity-contracts/private-tx/blob/master/contracts/PrivateContract.sol @@ -120,8 +118,6 @@ pub struct ProviderConfig { 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)] @@ -135,18 +131,51 @@ pub struct Receipt { pub status_code: u8, } +/// Payload signing and decrypting capabilities. +pub trait Signer: Send + Sync { + /// Decrypt payload using private key of given address. + fn decrypt(&self, account: Address, shared_mac: &[u8], payload: &[u8]) -> Result, Error>; + /// Sign given hash using provided account. + fn sign(&self, account: Address, hash: ethkey::Message) -> Result; +} + +/// Signer implementation that errors on any request. +pub struct DummySigner; +impl Signer for DummySigner { + fn decrypt(&self, _account: Address, _shared_mac: &[u8], _payload: &[u8]) -> Result, Error> { + Err("Decrypting is not supported.".to_owned())? + } + + fn sign(&self, _account: Address, _hash: ethkey::Message) -> Result { + Err("Signing is not supported.".to_owned())? + } +} + +/// Signer implementation using multiple keypairs +pub struct KeyPairSigner(pub Vec); +impl Signer for KeyPairSigner { + fn decrypt(&self, account: Address, shared_mac: &[u8], payload: &[u8]) -> Result, Error> { + let kp = self.0.iter().find(|k| k.address() == account).ok_or(ethkey::Error::InvalidAddress)?; + Ok(ethkey::crypto::ecies::decrypt(kp.secret(), shared_mac, payload)?) + } + + fn sign(&self, account: Address, hash: ethkey::Message) -> Result { + let kp = self.0.iter().find(|k| k.address() == account).ok_or(ethkey::Error::InvalidAddress)?; + Ok(ethkey::sign(kp.secret(), &hash)?) + } +} + /// Manager of private transactions pub struct Provider { encryptor: Box, validator_accounts: HashSet
, signer_account: Option
, - passwords: Vec, notify: RwLock>>, transactions_for_signing: RwLock, transactions_for_verification: VerificationStore, client: Arc, miner: Arc, - accounts: Arc, + accounts: Arc, channel: IoChannel, keys_provider: Arc, } @@ -159,12 +188,12 @@ pub struct PrivateExecutionResult where T: Tracer, V: VMTracer { result: Executed, } -impl Provider where { +impl Provider { /// Create a new provider. pub fn new( client: Arc, miner: Arc, - accounts: Arc, + accounts: Arc, encryptor: Box, config: ProviderConfig, channel: IoChannel, @@ -175,7 +204,6 @@ impl Provider where { encryptor, validator_accounts: config.validator_accounts.into_iter().collect(), signer_account: config.signer_account, - passwords: config.passwords, notify: RwLock::default(), transactions_for_signing: RwLock::default(), transactions_for_verification: VerificationStore::default(), @@ -248,21 +276,20 @@ impl Provider where { keccak(&state_buf.as_ref()) } - fn pool_client<'a>(&'a self, nonce_cache: &'a NonceCache) -> miner::pool_client::PoolClient<'a, Client> { + fn pool_client<'a>(&'a self, nonce_cache: &'a NonceCache, local_accounts: &'a HashSet
) -> miner::pool_client::PoolClient<'a, Client> { let engine = self.client.engine(); let refuse_service_transactions = true; miner::pool_client::PoolClient::new( &*self.client, nonce_cache, engine, - Some(&*self.accounts), + local_accounts, refuse_service_transactions, ) } /// Retrieve and verify the first available private transaction for every sender fn process_verification_queue(&self) -> Result<(), Error> { - let nonce_cache = NonceCache::new(NONCE_CACHE_SIZE); let process_transaction = |transaction: &VerifiedPrivateTransaction| -> Result<_, String> { let private_hash = transaction.private_transaction.hash(); match transaction.validator_account { @@ -292,8 +319,7 @@ impl Provider where { let private_state = private_state.expect("Error was checked before"); let private_state_hash = self.calculate_state_hash(&private_state, contract_nonce); trace!(target: "privatetx", "Hashed effective private state for validator: {:?}", private_state_hash); - let password = find_account_password(&self.passwords, &*self.accounts, &validator_account); - let signed_state = self.accounts.sign(validator_account, password, private_state_hash); + let signed_state = self.accounts.sign(validator_account, private_state_hash); if let Err(e) = signed_state { bail!("Cannot sign the state: {:?}", e); } @@ -305,7 +331,9 @@ impl Provider where { } Ok(()) }; - let ready_transactions = self.transactions_for_verification.drain(self.pool_client(&nonce_cache)); + let nonce_cache = NonceCache::new(NONCE_CACHE_SIZE); + let local_accounts = HashSet::new(); + let ready_transactions = self.transactions_for_verification.drain(self.pool_client(&nonce_cache, &local_accounts)); for transaction in ready_transactions { if let Err(e) = process_transaction(&transaction) { warn!(target: "privatetx", "Error: {:?}", e); @@ -346,8 +374,7 @@ impl Provider where { 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 signature = self.accounts.sign(signer_account, hash)?; let signed = SignedTransaction::new(public_tx.with_signature(signature, chain_id))?; match self.miner.import_own_transaction(&*self.client, signed.into()) { Ok(_) => trace!(target: "privatetx", "Public transaction added to queue"), @@ -442,12 +469,12 @@ impl Provider where { fn encrypt(&self, contract_address: &Address, initialisation_vector: &H128, data: &[u8]) -> Result { trace!(target: "privatetx", "Encrypt data using key(address): {:?}", contract_address); - Ok(self.encryptor.encrypt(contract_address, &*self.accounts, initialisation_vector, data)?) + Ok(self.encryptor.encrypt(contract_address, initialisation_vector, data)?) } fn decrypt(&self, contract_address: &Address, data: &[u8]) -> Result { trace!(target: "privatetx", "Decrypt data using key(address): {:?}", contract_address); - Ok(self.encryptor.decrypt(contract_address, &*self.accounts, data)?) + Ok(self.encryptor.decrypt(contract_address, data)?) } fn get_decrypted_state(&self, address: &Address, block: BlockId) -> Result { @@ -702,12 +729,13 @@ impl Importer for Arc { let transaction_bytes = self.decrypt(&contract, &encrypted_data)?; let original_tx: UnverifiedTransaction = Rlp::new(&transaction_bytes).as_val()?; let nonce_cache = NonceCache::new(NONCE_CACHE_SIZE); + let local_accounts = HashSet::new(); // Add to the queue for further verification self.transactions_for_verification.add_transaction( original_tx, validation_account.map(|&account| account), private_tx, - self.pool_client(&nonce_cache), + self.pool_client(&nonce_cache, &local_accounts), )?; let provider = Arc::downgrade(self); let result = self.channel.send(ClientIoMessage::execute(move |_| { @@ -742,16 +770,6 @@ impl Importer for Arc { } } -/// 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, new_blocks: NewBlocks) { if new_blocks.imported.is_empty() || new_blocks.has_more_blocks_to_import { return } diff --git a/ethcore/private-tx/tests/private_contract.rs b/ethcore/private-tx/tests/private_contract.rs index 0492191b63..6365b10eec 100644 --- a/ethcore/private-tx/tests/private_contract.rs +++ b/ethcore/private-tx/tests/private_contract.rs @@ -34,7 +34,6 @@ use rustc_hex::{FromHex, ToHex}; use types::ids::BlockId; use types::transaction::{Transaction, Action}; use ethcore::CreateContractAddress; -use ethcore::account_provider::AccountProvider; use ethcore::client::BlockChainClient; use ethcore::executive::{contract_address}; use ethcore::miner::Miner; @@ -54,15 +53,12 @@ fn private_contract() { 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(), &"".into()).unwrap(); - ap.insert_account(key3.secret().clone(), &"".into()).unwrap(); - ap.insert_account(key4.secret().clone(), &"".into()).unwrap(); + + let signer = Arc::new(ethcore_private_tx::KeyPairSigner(vec![key1.clone(), key3.clone(), key4.clone()])); let config = ProviderConfig{ validator_accounts: vec![key3.address(), key4.address()], signer_account: None, - passwords: vec!["".into()], }; let io = ethcore_io::IoChannel::disconnected(); @@ -71,7 +67,7 @@ fn private_contract() { let pm = Arc::new(Provider::new( client.clone(), miner, - ap.clone(), + signer.clone(), Box::new(NoopEncryptor::default()), config, io, @@ -192,15 +188,11 @@ fn call_other_private_contract() { 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(), &"".into()).unwrap(); - ap.insert_account(key3.secret().clone(), &"".into()).unwrap(); - ap.insert_account(key4.secret().clone(), &"".into()).unwrap(); + let signer = Arc::new(ethcore_private_tx::KeyPairSigner(vec![key1.clone(), key3.clone(), key4.clone()])); let config = ProviderConfig{ validator_accounts: vec![key3.address(), key4.address()], signer_account: None, - passwords: vec!["".into()], }; let io = ethcore_io::IoChannel::disconnected(); @@ -209,7 +201,7 @@ fn call_other_private_contract() { let pm = Arc::new(Provider::new( client.clone(), miner, - ap.clone(), + signer.clone(), Box::new(NoopEncryptor::default()), config, io, @@ -280,4 +272,4 @@ fn call_other_private_contract() { 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()[..])); -} \ No newline at end of file +} diff --git a/ethcore/service/src/service.rs b/ethcore/service/src/service.rs index c2137cfc6d..c16a071892 100644 --- a/ethcore/service/src/service.rs +++ b/ethcore/service/src/service.rs @@ -32,9 +32,8 @@ use ethcore::miner::Miner; use ethcore::snapshot::service::{Service as SnapshotService, ServiceParams as SnapServiceParams}; use ethcore::snapshot::{SnapshotService as _SnapshotService, RestorationStatus}; use ethcore::spec::Spec; -use ethcore::account_provider::AccountProvider; -use ethcore_private_tx::{self, Importer}; +use ethcore_private_tx::{self, Importer, Signer}; use Error; pub struct PrivateTxService { @@ -96,7 +95,7 @@ impl ClientService { restoration_db_handler: Box, _ipc_path: &Path, miner: Arc, - account_provider: Arc, + signer: Arc, encryptor: Box, private_tx_conf: ethcore_private_tx::ProviderConfig, private_encryptor_conf: ethcore_private_tx::EncryptorConfig, @@ -135,7 +134,7 @@ impl ClientService { let provider = Arc::new(ethcore_private_tx::Provider::new( client.clone(), miner, - account_provider, + signer, encryptor, private_tx_conf, io_service.channel(), @@ -282,7 +281,6 @@ mod tests { use tempdir::TempDir; use ethcore_db::NUM_COLUMNS; - use ethcore::account_provider::AccountProvider; use ethcore::client::ClientConfig; use ethcore::miner::Miner; use ethcore::spec::Spec; @@ -317,7 +315,7 @@ mod tests { restoration_db_handler, tempdir.path(), Arc::new(Miner::new_for_tests(&spec, None)), - Arc::new(AccountProvider::transient_provider()), + Arc::new(ethcore_private_tx::DummySigner), Box::new(ethcore_private_tx::NoopEncryptor), Default::default(), Default::default(), diff --git a/ethcore/src/engines/authority_round/mod.rs b/ethcore/src/engines/authority_round/mod.rs index 1404e58fef..2a42acfe23 100644 --- a/ethcore/src/engines/authority_round/mod.rs +++ b/ethcore/src/engines/authority_round/mod.rs @@ -24,7 +24,6 @@ use std::sync::atomic::{AtomicUsize, AtomicBool, Ordering as AtomicOrdering}; use std::sync::{Weak, Arc}; use std::time::{UNIX_EPOCH, SystemTime, Duration}; -use account_provider::AccountProvider; use block::*; use client::EngineClient; use engines::{Engine, Seal, EngineError, ConstructedVerifier}; @@ -37,7 +36,7 @@ use hash::keccak; use super::signer::EngineSigner; use super::validator_set::{ValidatorSet, SimpleList, new_validator_set}; use self::finality::RollingFinality; -use ethkey::{self, Password, Signature}; +use ethkey::{self, Signature}; use io::{IoContext, IoHandler, TimerToken, IoService}; use itertools::{self, Itertools}; use rlp::{encode, Decodable, DecoderError, Encodable, RlpStream, Rlp}; @@ -412,7 +411,7 @@ pub struct AuthorityRound { transition_service: IoService<()>, step: Arc, client: Arc>>>, - signer: RwLock, + signer: RwLock>>, validators: Box, validate_score_transition: u64, validate_step_transition: u64, @@ -665,7 +664,7 @@ impl AuthorityRound { can_propose: AtomicBool::new(true), }), client: Arc::new(RwLock::new(None)), - signer: Default::default(), + signer: RwLock::new(None), validators: our_params.validators, validate_score_transition: our_params.validate_score_transition, validate_step_transition: our_params.validate_step_transition, @@ -788,7 +787,7 @@ impl AuthorityRound { return; } - if let (true, Some(me)) = (current_step > parent_step + 1, self.signer.read().address()) { + if let (true, Some(me)) = (current_step > parent_step + 1, self.signer.read().as_ref().map(|s| s.address())) { debug!(target: "engine", "Author {} built block with step gap. current step: {}, parent step: {}", header.author(), current_step, parent_step); let mut reported = HashSet::new(); @@ -1492,12 +1491,16 @@ impl Engine for AuthorityRound { self.validators.register_client(client); } - fn set_signer(&self, ap: Arc, address: Address, password: Password) { - self.signer.write().set(ap, address, password); + fn set_signer(&self, signer: Box) { + *self.signer.write() = Some(signer); } fn sign(&self, hash: H256) -> Result { - Ok(self.signer.read().sign(hash)?) + Ok(self.signer.read() + .as_ref() + .ok_or(ethkey::Error::InvalidAddress)? + .sign(hash)? + ) } fn snapshot_components(&self) -> Option> { @@ -1532,16 +1535,16 @@ mod tests { use std::sync::Arc; use std::sync::atomic::{AtomicUsize, Ordering as AtomicOrdering}; use hash::keccak; + use accounts::AccountProvider; use ethereum_types::{Address, H520, H256, U256}; use ethkey::Signature; use types::header::Header; use rlp::encode; use block::*; use test_helpers::{ - generate_dummy_client_with_spec_and_accounts, get_temp_state_db, + generate_dummy_client_with_spec, get_temp_state_db, TestNotify }; - use account_provider::AccountProvider; use spec::Spec; use types::transaction::{Action, Transaction}; use engines::{Seal, Engine, EngineError, EthEngine}; @@ -1620,14 +1623,14 @@ mod tests { let b2 = OpenBlock::new(engine, Default::default(), false, db2, &genesis_header, last_hashes, addr2, (3141562.into(), 31415620.into()), vec![], false, &mut Vec::new().into_iter()).unwrap(); let b2 = b2.close_and_lock().unwrap(); - engine.set_signer(tap.clone(), addr1, "1".into()); + engine.set_signer(Box::new((tap.clone(), addr1, "1".into()))); if let Seal::Regular(seal) = engine.generate_seal(b1.block(), &genesis_header) { assert!(b1.clone().try_seal(engine, seal).is_ok()); // Second proposal is forbidden. assert!(engine.generate_seal(b1.block(), &genesis_header) == Seal::None); } - engine.set_signer(tap, addr2, "2".into()); + engine.set_signer(Box::new((tap, addr2, "2".into()))); if let Seal::Regular(seal) = engine.generate_seal(b2.block(), &genesis_header) { assert!(b2.clone().try_seal(engine, seal).is_ok()); // Second proposal is forbidden. @@ -1654,13 +1657,13 @@ mod tests { let b2 = OpenBlock::new(engine, Default::default(), false, db2, &genesis_header, last_hashes, addr2, (3141562.into(), 31415620.into()), vec![], false, &mut Vec::new().into_iter()).unwrap(); let b2 = b2.close_and_lock().unwrap(); - engine.set_signer(tap.clone(), addr1, "1".into()); + engine.set_signer(Box::new((tap.clone(), addr1, "1".into()))); match engine.generate_seal(b1.block(), &genesis_header) { Seal::None | Seal::Proposal(_) => panic!("wrong seal"), Seal::Regular(_) => { engine.step(); - engine.set_signer(tap.clone(), addr2, "0".into()); + engine.set_signer(Box::new((tap.clone(), addr2, "0".into()))); match engine.generate_seal(b2.block(), &genesis_header) { Seal::Regular(_) | Seal::Proposal(_) => panic!("sealed despite wrong difficulty"), Seal::None => {} @@ -1768,7 +1771,7 @@ mod tests { assert!(aura.verify_block_family(&header, &parent_header).is_ok()); assert_eq!(last_benign.load(AtomicOrdering::SeqCst), 0); - aura.set_signer(Arc::new(AccountProvider::transient_provider()), Default::default(), "".into()); + aura.set_signer(Box::new((Arc::new(AccountProvider::transient_provider()), Default::default(), "".into()))); // Do not report on steps skipped between genesis and first block. header.set_number(1); @@ -1878,12 +1881,12 @@ mod tests { let last_hashes = Arc::new(vec![genesis_header.hash()]); - let client = generate_dummy_client_with_spec_and_accounts(Spec::new_test_round_empty_steps, None); + let client = generate_dummy_client_with_spec(Spec::new_test_round_empty_steps); let notify = Arc::new(TestNotify::default()); client.add_notify(notify.clone()); engine.register_client(Arc::downgrade(&client) as _); - engine.set_signer(tap.clone(), addr1, "1".into()); + engine.set_signer(Box::new((tap.clone(), addr1, "1".into()))); let b1 = OpenBlock::new(engine, Default::default(), false, db1, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![], false, &mut Vec::new().into_iter()).unwrap(); let b1 = b1.close_and_lock().unwrap(); @@ -1917,7 +1920,7 @@ mod tests { let last_hashes = Arc::new(vec![genesis_header.hash()]); - let client = generate_dummy_client_with_spec_and_accounts(Spec::new_test_round_empty_steps, None); + let client = generate_dummy_client_with_spec(Spec::new_test_round_empty_steps); let notify = Arc::new(TestNotify::default()); client.add_notify(notify.clone()); engine.register_client(Arc::downgrade(&client) as _); @@ -1927,7 +1930,7 @@ mod tests { let b1 = b1.close_and_lock().unwrap(); // since the block is empty it isn't sealed and we generate empty steps - engine.set_signer(tap.clone(), addr1, "1".into()); + engine.set_signer(Box::new((tap.clone(), addr1, "1".into()))); assert_eq!(engine.generate_seal(b1.block(), &genesis_header), Seal::None); engine.step(); @@ -1944,9 +1947,9 @@ mod tests { let b2 = b2.close_and_lock().unwrap(); // we will now seal a block with 1tx and include the accumulated empty step message - engine.set_signer(tap.clone(), addr2, "0".into()); + engine.set_signer(Box::new((tap.clone(), addr2, "0".into()))); if let Seal::Regular(seal) = engine.generate_seal(b2.block(), &genesis_header) { - engine.set_signer(tap.clone(), addr1, "1".into()); + engine.set_signer(Box::new((tap.clone(), addr1, "1".into()))); let empty_step2 = sealed_empty_step(engine, 2, &genesis_header.hash()); let empty_steps = ::rlp::encode_list(&vec![empty_step2]); @@ -1970,7 +1973,7 @@ mod tests { let last_hashes = Arc::new(vec![genesis_header.hash()]); - let client = generate_dummy_client_with_spec_and_accounts(Spec::new_test_round_empty_steps, None); + let client = generate_dummy_client_with_spec(Spec::new_test_round_empty_steps); let notify = Arc::new(TestNotify::default()); client.add_notify(notify.clone()); engine.register_client(Arc::downgrade(&client) as _); @@ -1980,14 +1983,14 @@ mod tests { let b1 = b1.close_and_lock().unwrap(); // since the block is empty it isn't sealed and we generate empty steps - engine.set_signer(tap.clone(), addr1, "1".into()); + engine.set_signer(Box::new((tap.clone(), addr1, "1".into()))); assert_eq!(engine.generate_seal(b1.block(), &genesis_header), Seal::None); engine.step(); // step 3 let b2 = OpenBlock::new(engine, Default::default(), false, db2, &genesis_header, last_hashes.clone(), addr2, (3141562.into(), 31415620.into()), vec![], false, &mut Vec::new().into_iter()).unwrap(); let b2 = b2.close_and_lock().unwrap(); - engine.set_signer(tap.clone(), addr2, "0".into()); + engine.set_signer(Box::new((tap.clone(), addr2, "0".into()))); assert_eq!(engine.generate_seal(b2.block(), &genesis_header), Seal::None); engine.step(); @@ -1996,10 +1999,10 @@ mod tests { let b3 = OpenBlock::new(engine, Default::default(), false, db3, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![], false, &mut Vec::new().into_iter()).unwrap(); let b3 = b3.close_and_lock().unwrap(); - engine.set_signer(tap.clone(), addr1, "1".into()); + engine.set_signer(Box::new((tap.clone(), addr1, "1".into()))); if let Seal::Regular(seal) = engine.generate_seal(b3.block(), &genesis_header) { let empty_step2 = sealed_empty_step(engine, 2, &genesis_header.hash()); - engine.set_signer(tap.clone(), addr2, "0".into()); + engine.set_signer(Box::new((tap.clone(), addr2, "0".into()))); let empty_step3 = sealed_empty_step(engine, 3, &genesis_header.hash()); let empty_steps = ::rlp::encode_list(&vec![empty_step2, empty_step3]); @@ -2022,7 +2025,7 @@ mod tests { let last_hashes = Arc::new(vec![genesis_header.hash()]); - let client = generate_dummy_client_with_spec_and_accounts(Spec::new_test_round_empty_steps, None); + let client = generate_dummy_client_with_spec(Spec::new_test_round_empty_steps); engine.register_client(Arc::downgrade(&client) as _); // step 2 @@ -2030,7 +2033,7 @@ mod tests { let b1 = b1.close_and_lock().unwrap(); // since the block is empty it isn't sealed and we generate empty steps - engine.set_signer(tap.clone(), addr1, "1".into()); + engine.set_signer(Box::new((tap.clone(), addr1, "1".into()))); assert_eq!(engine.generate_seal(b1.block(), &genesis_header), Seal::None); engine.step(); @@ -2084,7 +2087,7 @@ mod tests { ); // empty step with valid signature from incorrect proposer for step - engine.set_signer(tap.clone(), addr1, "1".into()); + engine.set_signer(Box::new((tap.clone(), addr1, "1".into()))); let empty_steps = vec![sealed_empty_step(engine, 1, &parent_header.hash())]; set_empty_steps_seal(&mut header, 2, &signature, &empty_steps); @@ -2094,9 +2097,9 @@ mod tests { ); // valid empty steps - engine.set_signer(tap.clone(), addr1, "1".into()); + engine.set_signer(Box::new((tap.clone(), addr1, "1".into()))); let empty_step2 = sealed_empty_step(engine, 2, &parent_header.hash()); - engine.set_signer(tap.clone(), addr2, "0".into()); + engine.set_signer(Box::new((tap.clone(), addr2, "0".into()))); let empty_step3 = sealed_empty_step(engine, 3, &parent_header.hash()); let empty_steps = vec![empty_step2, empty_step3]; @@ -2121,10 +2124,7 @@ mod tests { let last_hashes = Arc::new(vec![genesis_header.hash()]); - let client = generate_dummy_client_with_spec_and_accounts( - Spec::new_test_round_block_reward_contract, - None, - ); + let client = generate_dummy_client_with_spec(Spec::new_test_round_block_reward_contract); engine.register_client(Arc::downgrade(&client) as _); // step 2 @@ -2144,7 +2144,7 @@ mod tests { let b1 = b1.close_and_lock().unwrap(); // since the block is empty it isn't sealed and we generate empty steps - engine.set_signer(tap.clone(), addr1, "1".into()); + engine.set_signer(Box::new((tap.clone(), addr1, "1".into()))); assert_eq!(engine.generate_seal(b1.block(), &genesis_header), Seal::None); engine.step(); @@ -2182,7 +2182,7 @@ mod tests { let engine = &*spec.engine; let addr1 = accounts[0]; - engine.set_signer(tap.clone(), addr1, "1".into()); + engine.set_signer(Box::new((tap.clone(), addr1, "1".into()))); let mut header: Header = Header::default(); let empty_step = empty_step(engine, 1, &header.parent_hash()); @@ -2263,7 +2263,7 @@ mod tests { header.set_author(accounts[0]); // when - engine.set_signer(tap.clone(), accounts[1], "0".into()); + engine.set_signer(Box::new((tap.clone(), accounts[1], "0".into()))); let empty_steps = vec![ sealed_empty_step(&*engine, 1, &parent.hash()), sealed_empty_step(&*engine, 1, &parent.hash()), @@ -2300,9 +2300,9 @@ mod tests { header.set_author(accounts[0]); // when - engine.set_signer(tap.clone(), accounts[1], "0".into()); + engine.set_signer(Box::new((tap.clone(), accounts[1], "0".into()))); let es1 = sealed_empty_step(&*engine, 1, &parent.hash()); - engine.set_signer(tap.clone(), accounts[0], "1".into()); + engine.set_signer(Box::new((tap.clone(), accounts[0], "1".into()))); let es2 = sealed_empty_step(&*engine, 2, &parent.hash()); let mut empty_steps = vec![es2, es1]; diff --git a/ethcore/src/engines/basic_authority.rs b/ethcore/src/engines/basic_authority.rs index 4a57544adf..1a4bdb55a9 100644 --- a/ethcore/src/engines/basic_authority.rs +++ b/ethcore/src/engines/basic_authority.rs @@ -16,19 +16,18 @@ //! A blockchain engine that supports a basic, non-BFT proof-of-authority. -use std::sync::{Weak, Arc}; -use ethereum_types::{H256, H520, Address}; +use std::sync::Weak; +use ethereum_types::{H256, H520}; use parking_lot::RwLock; -use ethkey::{self, Password, Signature}; -use account_provider::AccountProvider; +use ethkey::{self, Signature}; use block::*; use engines::{Engine, Seal, ConstructedVerifier, EngineError}; +use engines::signer::EngineSigner; use error::{BlockError, Error}; use ethjson; use client::EngineClient; use machine::{AuxiliaryData, Call, EthereumMachine}; use types::header::{Header, ExtendedHeader}; -use super::signer::EngineSigner; use super::validator_set::{ValidatorSet, SimpleList, new_validator_set}; /// `BasicAuthority` params. @@ -76,7 +75,7 @@ fn verify_external(header: &Header, validators: &ValidatorSet) -> Result<(), Err /// Engine using `BasicAuthority`, trivial proof-of-authority consensus. pub struct BasicAuthority { machine: EthereumMachine, - signer: RwLock, + signer: RwLock>>, validators: Box, } @@ -85,7 +84,7 @@ impl BasicAuthority { pub fn new(our_params: BasicAuthorityParams, machine: EthereumMachine) -> Self { BasicAuthority { machine: machine, - signer: Default::default(), + signer: RwLock::new(None), validators: new_validator_set(our_params.validators), } } @@ -190,12 +189,16 @@ impl Engine for BasicAuthority { self.validators.register_client(client); } - fn set_signer(&self, ap: Arc, address: Address, password: Password) { - self.signer.write().set(ap, address, password); + fn set_signer(&self, signer: Box) { + *self.signer.write() = Some(signer); } fn sign(&self, hash: H256) -> Result { - Ok(self.signer.read().sign(hash)?) + Ok(self.signer.read() + .as_ref() + .ok_or_else(|| ethkey::Error::InvalidAddress)? + .sign(hash)? + ) } fn snapshot_components(&self) -> Option> { @@ -214,7 +217,7 @@ mod tests { use ethereum_types::H520; use block::*; use test_helpers::get_temp_state_db; - use account_provider::AccountProvider; + use accounts::AccountProvider; use types::header::Header; use spec::Spec; use engines::Seal; @@ -257,7 +260,7 @@ mod tests { let spec = new_test_authority(); let engine = &*spec.engine; - engine.set_signer(Arc::new(tap), addr, "".into()); + engine.set_signer(Box::new((Arc::new(tap), addr, "".into()))); let genesis_header = spec.genesis_header(); let db = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap(); let last_hashes = Arc::new(vec![genesis_header.hash()]); @@ -275,7 +278,7 @@ mod tests { let engine = new_test_authority().engine; assert!(!engine.seals_internally().unwrap()); - engine.set_signer(Arc::new(tap), authority, "".into()); + engine.set_signer(Box::new((Arc::new(tap), authority, "".into()))); assert!(engine.seals_internally().unwrap()); } } diff --git a/ethcore/src/engines/block_reward.rs b/ethcore/src/engines/block_reward.rs index 42db6889c8..a95e3820ef 100644 --- a/ethcore/src/engines/block_reward.rs +++ b/ethcore/src/engines/block_reward.rs @@ -170,17 +170,14 @@ mod test { use client::PrepareOpenBlock; use ethereum_types::U256; use spec::Spec; - use test_helpers::generate_dummy_client_with_spec_and_accounts; + use test_helpers::generate_dummy_client_with_spec; use engines::SystemOrCodeCallKind; use super::{BlockRewardContract, RewardKind}; #[test] fn block_reward_contract() { - let client = generate_dummy_client_with_spec_and_accounts( - Spec::new_test_round_block_reward_contract, - None, - ); + let client = generate_dummy_client_with_spec(Spec::new_test_round_block_reward_contract); let machine = Spec::new_test_machine(); diff --git a/ethcore/src/engines/mod.rs b/ethcore/src/engines/mod.rs index deb85cd35f..9cced0a0da 100644 --- a/ethcore/src/engines/mod.rs +++ b/ethcore/src/engines/mod.rs @@ -20,16 +20,17 @@ mod authority_round; mod basic_authority; mod instant_seal; mod null_engine; -mod signer; mod validator_set; pub mod block_reward; +pub mod signer; pub use self::authority_round::AuthorityRound; pub use self::basic_authority::BasicAuthority; pub use self::epoch::{EpochVerifier, Transition as EpochTransition}; pub use self::instant_seal::{InstantSeal, InstantSealParams}; pub use self::null_engine::NullEngine; +pub use self::signer::EngineSigner; // TODO [ToDr] Remove re-export (#10130) pub use types::engines::ForkChoice; @@ -39,7 +40,6 @@ use std::sync::{Weak, Arc}; use std::collections::{BTreeMap, HashMap}; use std::{fmt, error}; -use account_provider::AccountProvider; use builtin::Builtin; use vm::{EnvInfo, Schedule, CreateContractAddress, CallType, ActionValue}; use error::Error; @@ -49,7 +49,7 @@ use snapshot::SnapshotComponents; use spec::CommonParams; use types::transaction::{self, UnverifiedTransaction, SignedTransaction}; -use ethkey::{Password, Signature}; +use ethkey::{Signature}; use parity_machine::{Machine, LocalizedMachine as Localized, TotalScoredHeader}; use ethereum_types::{H256, U256, Address}; use unexpected::{Mismatch, OutOfBounds}; @@ -380,8 +380,8 @@ pub trait Engine: Sync + Send { /// Takes a header of a fully verified block. fn is_proposal(&self, _verified_header: &M::Header) -> bool { false } - /// Register an account which signs consensus messages. - fn set_signer(&self, _account_provider: Arc, _address: Address, _password: Password) {} + /// Register a component which signs consensus messages. + fn set_signer(&self, _signer: Box) {} /// Sign using the EngineSigner, to be used for consensus tx signing. fn sign(&self, _hash: H256) -> Result { unimplemented!() } diff --git a/ethcore/src/engines/signer.rs b/ethcore/src/engines/signer.rs index 68a88745bc..bccaca1915 100644 --- a/ethcore/src/engines/signer.rs +++ b/ethcore/src/engines/signer.rs @@ -16,49 +16,68 @@ //! A signer used by Engines which need to sign messages. -use std::sync::Arc; use ethereum_types::{H256, Address}; -use ethkey::{Password, Signature}; -use account_provider::{self, AccountProvider}; +use ethkey::{self, Signature}; /// Everything that an Engine needs to sign messages. -pub struct EngineSigner { - account_provider: Arc, - address: Option
, - password: Option, +pub trait EngineSigner: Send + Sync { + /// Sign a consensus message hash. + fn sign(&self, hash: H256) -> Result; + + /// Signing address + fn address(&self) -> Address; } -impl Default for EngineSigner { - fn default() -> Self { - EngineSigner { - account_provider: Arc::new(AccountProvider::transient_provider()), - address: Default::default(), - password: Default::default(), - } - } +/// Creates a new `EngineSigner` from given key pair. +pub fn from_keypair(keypair: ethkey::KeyPair) -> Box { + Box::new(Signer(keypair)) } -impl EngineSigner { - /// Set up the signer to sign with given address and password. - pub fn set(&mut self, ap: Arc, address: Address, password: Password) { - self.account_provider = ap; - self.address = Some(address); - self.password = Some(password); - debug!(target: "poa", "Setting Engine signer to {}", address); - } +struct Signer(ethkey::KeyPair); - /// Sign a consensus message hash. - pub fn sign(&self, hash: H256) -> Result { - self.account_provider.sign(self.address.unwrap_or_else(Default::default), self.password.clone(), hash) +impl EngineSigner for Signer { + fn sign(&self, hash: H256) -> Result { + ethkey::sign(self.0.secret(), &hash) } - /// Signing address. - pub fn address(&self) -> Option
{ - self.address.clone() + fn address(&self) -> Address { + self.0.address() } +} - /// Check if the signing address was set. - pub fn is_some(&self) -> bool { - self.address.is_some() +#[cfg(test)] +mod test_signer { + use std::sync::Arc; + + use ethkey::Password; + use accounts::{self, AccountProvider, SignError}; + + use super::*; + + impl EngineSigner for (Arc, Address, Password) { + fn sign(&self, hash: H256) -> Result { + match self.0.sign(self.1, Some(self.2.clone()), hash) { + Err(SignError::NotUnlocked) => unreachable!(), + Err(SignError::NotFound) => Err(ethkey::Error::InvalidAddress), + Err(SignError::Hardware(err)) => { + warn!("Error using hardware wallet for engine: {:?}", err); + Err(ethkey::Error::InvalidSecret) + }, + Err(SignError::SStore(accounts::Error::EthKey(err))) => Err(err), + Err(SignError::SStore(accounts::Error::EthKeyCrypto(err))) => { + warn!("Low level crypto error: {:?}", err); + Err(ethkey::Error::InvalidSecret) + }, + Err(SignError::SStore(err)) => { + warn!("Error signing for engine: {:?}", err); + Err(ethkey::Error::InvalidSignature) + }, + Ok(ok) => Ok(ok), + } + } + + fn address(&self) -> Address { + self.1 + } } } diff --git a/ethcore/src/engines/validator_set/contract.rs b/ethcore/src/engines/validator_set/contract.rs index b13ebdd105..f0064a8c20 100644 --- a/ethcore/src/engines/validator_set/contract.rs +++ b/ethcore/src/engines/validator_set/contract.rs @@ -141,10 +141,10 @@ mod tests { use rlp::encode; use spec::Spec; use types::header::Header; - use account_provider::AccountProvider; - use miner::MinerService; + use accounts::AccountProvider; + use miner::{self, MinerService}; use types::ids::BlockId; - use test_helpers::generate_dummy_client_with_spec_and_accounts; + use test_helpers::generate_dummy_client_with_spec; use call_contract::CallContract; use client::{BlockChainClient, ChainInfo, BlockInfo}; use super::super::ValidatorSet; @@ -152,7 +152,7 @@ mod tests { #[test] fn fetches_validators() { - let client = generate_dummy_client_with_spec_and_accounts(Spec::new_validator_contract, None); + let client = generate_dummy_client_with_spec(Spec::new_validator_contract); let vc = Arc::new(ValidatorContract::new("0000000000000000000000000000000000000005".parse::
().unwrap())); vc.register_client(Arc::downgrade(&client) as _); let last_hash = client.best_block_header().hash(); @@ -164,13 +164,14 @@ mod tests { fn reports_validators() { let tap = Arc::new(AccountProvider::transient_provider()); let v1 = tap.insert_account(keccak("1").into(), &"".into()).unwrap(); - let client = generate_dummy_client_with_spec_and_accounts(Spec::new_validator_contract, Some(tap.clone())); + let client = generate_dummy_client_with_spec(Spec::new_validator_contract); client.engine().register_client(Arc::downgrade(&client) as _); let validator_contract = "0000000000000000000000000000000000000005".parse::
().unwrap(); // Make sure reporting can be done. client.miner().set_gas_range_target((1_000_000.into(), 1_000_000.into())); - client.miner().set_author(v1, Some("".into())).unwrap(); + let signer = Box::new((tap.clone(), v1, "".into())); + client.miner().set_author(miner::Author::Sealer(signer)); // Check a block that is a bit in future, reject it but don't report the validator. let mut header = Header::default(); diff --git a/ethcore/src/engines/validator_set/multi.rs b/ethcore/src/engines/validator_set/multi.rs index 4b3c33abac..8aa7aa3dee 100644 --- a/ethcore/src/engines/validator_set/multi.rs +++ b/ethcore/src/engines/validator_set/multi.rs @@ -150,15 +150,15 @@ mod tests { use std::sync::Arc; use std::collections::BTreeMap; use hash::keccak; - use account_provider::AccountProvider; + use accounts::AccountProvider; use client::{BlockChainClient, ChainInfo, BlockInfo, ImportBlock}; use engines::EpochChange; use engines::validator_set::ValidatorSet; use ethkey::Secret; use types::header::Header; - use miner::MinerService; + use miner::{self, MinerService}; use spec::Spec; - use test_helpers::{generate_dummy_client_with_spec_and_accounts, generate_dummy_client_with_spec_and_data}; + use test_helpers::{generate_dummy_client_with_spec, generate_dummy_client_with_spec_and_data}; use types::ids::BlockId; use ethereum_types::Address; use verification::queue::kind::blocks::Unverified; @@ -171,26 +171,29 @@ mod tests { let s0: Secret = keccak("0").into(); let v0 = tap.insert_account(s0.clone(), &"".into()).unwrap(); let v1 = tap.insert_account(keccak("1").into(), &"".into()).unwrap(); - let client = generate_dummy_client_with_spec_and_accounts(Spec::new_validator_multi, Some(tap)); + let client = generate_dummy_client_with_spec(Spec::new_validator_multi); client.engine().register_client(Arc::downgrade(&client) as _); // Make sure txs go through. client.miner().set_gas_range_target((1_000_000.into(), 1_000_000.into())); // Wrong signer for the first block. - client.miner().set_author(v1, Some("".into())).unwrap(); + let signer = Box::new((tap.clone(), v1, "".into())); + client.miner().set_author(miner::Author::Sealer(signer)); client.transact_contract(Default::default(), Default::default()).unwrap(); ::client::EngineClient::update_sealing(&*client); assert_eq!(client.chain_info().best_block_number, 0); // Right signer for the first block. - client.miner().set_author(v0, Some("".into())).unwrap(); + let signer = Box::new((tap.clone(), v0, "".into())); + client.miner().set_author(miner::Author::Sealer(signer)); ::client::EngineClient::update_sealing(&*client); assert_eq!(client.chain_info().best_block_number, 1); // This time v0 is wrong. client.transact_contract(Default::default(), Default::default()).unwrap(); ::client::EngineClient::update_sealing(&*client); assert_eq!(client.chain_info().best_block_number, 1); - client.miner().set_author(v1, Some("".into())).unwrap(); + let signer = Box::new((tap.clone(), v1, "".into())); + client.miner().set_author(miner::Author::Sealer(signer)); ::client::EngineClient::update_sealing(&*client); assert_eq!(client.chain_info().best_block_number, 2); // v1 is still good. diff --git a/ethcore/src/engines/validator_set/safe_contract.rs b/ethcore/src/engines/validator_set/safe_contract.rs index a5f94d4127..49d539df3f 100644 --- a/ethcore/src/engines/validator_set/safe_contract.rs +++ b/ethcore/src/engines/validator_set/safe_contract.rs @@ -445,19 +445,19 @@ mod tests { use ethereum_types::Address; use types::ids::BlockId; use spec::Spec; - use account_provider::AccountProvider; + use accounts::AccountProvider; use types::transaction::{Transaction, Action}; use client::{ChainInfo, BlockInfo, ImportBlock}; use ethkey::Secret; - use miner::MinerService; - use test_helpers::{generate_dummy_client_with_spec_and_accounts, generate_dummy_client_with_spec_and_data}; + use miner::{self, MinerService}; + use test_helpers::{generate_dummy_client_with_spec, generate_dummy_client_with_spec_and_data}; use super::super::ValidatorSet; use super::{ValidatorSafeContract, EVENT_NAME_HASH}; use verification::queue::kind::blocks::Unverified; #[test] fn fetches_validators() { - let client = generate_dummy_client_with_spec_and_accounts(Spec::new_validator_safe_contract, None); + let client = generate_dummy_client_with_spec(Spec::new_validator_safe_contract); let vc = Arc::new(ValidatorSafeContract::new("0000000000000000000000000000000000000005".parse::
().unwrap())); vc.register_client(Arc::downgrade(&client) as _); let last_hash = client.best_block_header().hash(); @@ -472,11 +472,12 @@ mod tests { let v0 = tap.insert_account(s0.clone(), &"".into()).unwrap(); let v1 = tap.insert_account(keccak("0").into(), &"".into()).unwrap(); let chain_id = Spec::new_validator_safe_contract().chain_id(); - let client = generate_dummy_client_with_spec_and_accounts(Spec::new_validator_safe_contract, Some(tap)); + let client = generate_dummy_client_with_spec(Spec::new_validator_safe_contract); client.engine().register_client(Arc::downgrade(&client) as _); let validator_contract = "0000000000000000000000000000000000000005".parse::
().unwrap(); + let signer = Box::new((tap.clone(), v1, "".into())); - client.miner().set_author(v1, Some("".into())).unwrap(); + client.miner().set_author(miner::Author::Sealer(signer)); // Remove "1" validator. let tx = Transaction { nonce: 0.into(), @@ -504,11 +505,13 @@ mod tests { assert_eq!(client.chain_info().best_block_number, 1); // Switch to the validator that is still there. - client.miner().set_author(v0, Some("".into())).unwrap(); + let signer = Box::new((tap.clone(), v0, "".into())); + client.miner().set_author(miner::Author::Sealer(signer)); ::client::EngineClient::update_sealing(&*client); assert_eq!(client.chain_info().best_block_number, 2); // Switch back to the added validator, since the state is updated. - client.miner().set_author(v1, Some("".into())).unwrap(); + let signer = Box::new((tap.clone(), v1, "".into())); + client.miner().set_author(miner::Author::Sealer(signer)); let tx = Transaction { nonce: 2.into(), gas_price: 0.into(), @@ -539,7 +542,7 @@ mod tests { use types::header::Header; use types::log_entry::LogEntry; - let client = generate_dummy_client_with_spec_and_accounts(Spec::new_validator_safe_contract, None); + let client = generate_dummy_client_with_spec(Spec::new_validator_safe_contract); let engine = client.engine().clone(); let validator_contract = "0000000000000000000000000000000000000005".parse::
().unwrap(); @@ -576,7 +579,7 @@ mod tests { use types::header::Header; use engines::{EpochChange, Proof}; - let client = generate_dummy_client_with_spec_and_accounts(Spec::new_validator_safe_contract, None); + let client = generate_dummy_client_with_spec(Spec::new_validator_safe_contract); let engine = client.engine().clone(); let mut new_header = Header::default(); diff --git a/ethcore/src/error.rs b/ethcore/src/error.rs index 5c434d4870..2984dcdea8 100644 --- a/ethcore/src/error.rs +++ b/ethcore/src/error.rs @@ -25,11 +25,10 @@ use ethtrie::TrieError; use rlp; use snappy::InvalidInput; use snapshot::Error as SnapshotError; -use types::transaction::Error as TransactionError; use types::BlockNumber; +use types::transaction::Error as TransactionError; use unexpected::{Mismatch, OutOfBounds}; -use account_provider::SignError as AccountsError; use engines::EngineError; pub use executed::{ExecutionError, CallError}; @@ -244,12 +243,6 @@ error_chain! { display("Snapshot error {}", err) } - #[doc = "Account Provider error"] - AccountProvider(err: AccountsError) { - description("Accounts Provider error") - display("Accounts Provider error {}", err) - } - #[doc = "PoW hash is invalid or out of date."] PowHashInvalid { description("PoW hash is invalid or out of date.") @@ -270,12 +263,6 @@ error_chain! { } } -impl From for Error { - fn from(err: AccountsError) -> Error { - ErrorKind::AccountProvider(err).into() - } -} - impl From for Error { fn from(err: SnapshotError) -> Error { match err { diff --git a/ethcore/src/lib.rs b/ethcore/src/lib.rs index 3da2eb9521..633254683e 100644 --- a/ethcore/src/lib.rs +++ b/ethcore/src/lib.rs @@ -73,7 +73,6 @@ extern crate ethcore_miner; extern crate ethereum_types; extern crate ethjson; extern crate ethkey; -extern crate ethstore; extern crate hashdb; extern crate heapsize; extern crate itertools; @@ -107,6 +106,8 @@ extern crate using_queue; extern crate vm; extern crate wasm; +#[cfg(test)] +extern crate ethcore_accounts as accounts; #[cfg(feature = "stratum")] extern crate ethcore_stratum; #[cfg(any(test, feature = "tempdir"))] @@ -115,12 +116,10 @@ extern crate tempdir; extern crate kvdb_rocksdb; #[cfg(any(test, feature = "blooms-db"))] extern crate blooms_db; - -#[cfg(any(target_os = "linux", target_os = "macos", target_os = "windows"))] -extern crate hardware_wallet; - -#[cfg(not(any(target_os = "linux", target_os = "macos", target_os = "windows")))] -extern crate fake_hardware_wallet as hardware_wallet; +#[cfg(any(test, feature = "env_logger"))] +extern crate env_logger; +#[cfg(test)] +extern crate rlp_compress; #[macro_use] extern crate ethabi_derive; @@ -144,12 +143,6 @@ extern crate serde_derive; #[cfg_attr(test, macro_use)] extern crate evm; -#[cfg(any(test, feature = "env_logger"))] -extern crate env_logger; -#[cfg(test)] -extern crate rlp_compress; - -pub mod account_provider; pub mod block; pub mod builtin; pub mod client; diff --git a/ethcore/src/miner/miner.rs b/ethcore/src/miner/miner.rs index 36239a4d60..82e0e4bb0b 100644 --- a/ethcore/src/miner/miner.rs +++ b/ethcore/src/miner/miner.rs @@ -23,11 +23,11 @@ use ansi_term::Colour; use bytes::Bytes; use call_contract::CallContract; use ethcore_miner::gas_pricer::GasPricer; +use ethcore_miner::local_accounts::LocalAccounts; use ethcore_miner::pool::{self, TransactionQueue, VerifiedTransaction, QueueStatus, PrioritizationStrategy}; #[cfg(feature = "work-notify")] use ethcore_miner::work_notify::NotifyWork; use ethereum_types::{H256, U256, Address}; -use ethkey::Password; use io::IoChannel; use miner::pool_client::{PoolClient, CachedNonceClient, NonceCache}; use miner; @@ -46,13 +46,12 @@ use types::header::Header; use types::receipt::RichReceipt; use using_queue::{UsingQueue, GetAction}; -use account_provider::{AccountProvider, SignError as AccountError}; use block::{ClosedBlock, IsBlock, SealedBlock}; use client::{ BlockChain, ChainInfo, BlockProducer, SealedBlockImporter, Nonce, TransactionInfo, TransactionId }; use client::{BlockId, ClientIoMessage}; -use engines::{EthEngine, Seal}; +use engines::{EthEngine, Seal, EngineSigner}; use error::{Error, ErrorKind}; use executed::ExecutionError; use executive::contract_address; @@ -140,8 +139,6 @@ pub struct MinerOptions { /// will be invalid if mined. pub infinite_pending_block: bool, - /// Prioritized Local Addresses - pub tx_queue_locals: HashSet
, /// Strategy to use for prioritizing transactions in the queue. pub tx_queue_strategy: PrioritizationStrategy, /// Simple senders penalization. @@ -169,7 +166,6 @@ impl Default for MinerOptions { work_queue_size: 20, enable_resubmission: true, infinite_pending_block: false, - tx_queue_locals: HashSet::new(), tx_queue_strategy: PrioritizationStrategy::GasPriceOnly, tx_queue_penalization: Penalization::Disabled, tx_queue_no_unfamiliar_locals: false, @@ -200,6 +196,25 @@ pub struct AuthoringParams { pub extra_data: Bytes, } +/// Block sealing mechanism +pub enum Author { + /// Sealing block is external and we only need a reward beneficiary (i.e. PoW) + External(Address), + /// Sealing is done internally, we need a way to create signatures to seal block (i.e. PoA) + Sealer(Box), +} + +impl Author { + /// Get author's address. + pub fn address(&self) -> Address { + match *self { + Author::External(address) => address, + Author::Sealer(ref sealer) => sealer.address(), + } + } +} + + struct SealingWork { queue: UsingQueue, enabled: bool, @@ -230,7 +245,7 @@ pub struct Miner { // TODO [ToDr] Arc is only required because of price updater transaction_queue: Arc, engine: Arc, - accounts: Option>, + accounts: Arc, io_channel: RwLock>>, } @@ -248,11 +263,11 @@ impl Miner { } /// Creates new instance of miner Arc. - pub fn new( + pub fn new( options: MinerOptions, gas_pricer: GasPricer, spec: &Spec, - accounts: Option>, + accounts: A, ) -> Self { let limits = options.pool_limits.clone(); let verifier_options = options.pool_verification_options.clone(); @@ -275,7 +290,7 @@ impl Miner { nonce_cache: NonceCache::new(nonce_cache_size), options, transaction_queue: Arc::new(TransactionQueue::new(limits, verifier_options, tx_queue_strategy)), - accounts, + accounts: Arc::new(accounts), engine: spec.engine.clone(), io_channel: RwLock::new(None), } @@ -284,7 +299,7 @@ impl Miner { /// Creates new instance of miner with given spec and accounts. /// /// NOTE This should be only used for tests. - pub fn new_for_tests(spec: &Spec, accounts: Option>) -> Miner { + pub fn new_for_tests(spec: &Spec, accounts: Option>) -> Miner { let minimal_gas_price = 0.into(); Miner::new(MinerOptions { pool_verification_options: pool::verifier::Options { @@ -295,7 +310,7 @@ impl Miner { }, reseal_min_period: Duration::from_secs(0), ..Default::default() - }, GasPricer::new_fixed(minimal_gas_price), spec, accounts) + }, GasPricer::new_fixed(minimal_gas_price), spec, accounts.unwrap_or_default()) } /// Sets `IoChannel` @@ -362,7 +377,7 @@ impl Miner { chain, &self.nonce_cache, &*self.engine, - self.accounts.as_ref().map(|x| &**x), + &*self.accounts, self.options.refuse_service_transactions, ) } @@ -830,14 +845,11 @@ impl miner::MinerService for Miner { self.params.write().extra_data = extra_data; } - fn set_author(&self, address: Address, password: Option) -> Result<(), AccountError> { - self.params.write().author = address; + fn set_author(&self, author: Author) { + self.params.write().author = author.address(); - if self.engine.seals_internally().is_some() && password.is_some() { - if let Some(ref ap) = self.accounts { - let password = password.unwrap_or_else(|| Password::from(String::new())); - // Sign test message - ap.sign(address.clone(), Some(password.clone()), Default::default())?; + if let Author::Sealer(signer) = author { + if self.engine.seals_internally().is_some() { // Enable sealing self.sealing.lock().enabled = true; // -------------------------------------------------------------------------- @@ -845,14 +857,10 @@ impl miner::MinerService for Miner { // | (some `Engine`s call `EngineClient.update_sealing()`) | // | Make sure to release the locks before calling that method. | // -------------------------------------------------------------------------- - self.engine.set_signer(ap.clone(), address, password); - Ok(()) + self.engine.set_signer(signer); } else { - warn!(target: "miner", "No account provider"); - Err(AccountError::NotFound) + warn!("Setting an EngineSigner while Engine does not require one."); } - } else { - Ok(()) } } @@ -925,8 +933,7 @@ impl miner::MinerService for Miner { let sender = pending.sender(); let treat_as_local = trusted || !self.options.tx_queue_no_unfamiliar_locals - || self.accounts.as_ref().map(|accts| accts.has_account(sender)).unwrap_or(false) - || self.options.tx_queue_locals.contains(&sender); + || self.accounts.is_local(&sender); if treat_as_local { self.import_own_transaction(chain, pending) @@ -1255,7 +1262,7 @@ impl miner::MinerService for Miner { chain, &nonce_cache, &*engine, - accounts.as_ref().map(|x| &**x), + &*accounts, refuse_service_transactions, ); queue.cull(client); @@ -1292,6 +1299,7 @@ mod tests { use std::iter::FromIterator; use super::*; + use accounts::AccountProvider; use ethkey::{Generator, Random}; use hash::keccak; use rustc_hex::FromHex; @@ -1299,7 +1307,7 @@ mod tests { use client::{TestBlockChainClient, EachBlockWith, ChainInfo, ImportSealedBlock}; use miner::{MinerService, PendingOrdering}; - use test_helpers::{generate_dummy_client, generate_dummy_client_with_spec_and_accounts}; + use test_helpers::{generate_dummy_client, generate_dummy_client_with_spec}; use types::transaction::{Transaction}; #[test] @@ -1349,7 +1357,6 @@ mod tests { enable_resubmission: true, infinite_pending_block: false, tx_queue_penalization: Penalization::Disabled, - tx_queue_locals: HashSet::new(), tx_queue_strategy: PrioritizationStrategy::GasPriceOnly, tx_queue_no_unfamiliar_locals: false, refuse_service_transactions: false, @@ -1363,7 +1370,7 @@ mod tests { }, GasPricer::new_fixed(0u64.into()), &Spec::new_test(), - None, // accounts provider + ::std::collections::HashSet::new(), // local accounts ) } @@ -1476,8 +1483,8 @@ mod tests { // given let keypair = Random.generate().unwrap(); let client = TestBlockChainClient::default(); - let account_provider = AccountProvider::transient_provider(); - account_provider.insert_account(keypair.secret().clone(), &"".into()).expect("can add accounts to the provider we just created"); + let mut local_accounts = ::std::collections::HashSet::new(); + local_accounts.insert(keypair.address()); let miner = Miner::new( MinerOptions { @@ -1486,7 +1493,7 @@ mod tests { }, GasPricer::new_fixed(0u64.into()), &Spec::new_test(), - Some(Arc::new(account_provider)), + local_accounts, ); let transaction = transaction(); let best_block = 0; @@ -1520,22 +1527,16 @@ mod tests { #[test] fn should_prioritize_locals() { - let keypair = Random.generate().unwrap(); let client = TestBlockChainClient::default(); - let account_provider = AccountProvider::transient_provider(); - account_provider.insert_account(keypair.secret().clone(), &"".into()) - .expect("can add accounts to the provider we just created"); - let transaction = transaction(); let miner = Miner::new( MinerOptions { tx_queue_no_unfamiliar_locals: true, // should work even with this enabled - tx_queue_locals: HashSet::from_iter(vec![transaction.sender()].into_iter()), ..miner().options }, GasPricer::new_fixed(0u64.into()), &Spec::new_test(), - Some(Arc::new(account_provider)), + HashSet::from_iter(vec![transaction.sender()].into_iter()), ); let best_block = 0; @@ -1587,12 +1588,19 @@ mod tests { } #[test] - fn should_fail_setting_engine_signer_without_account_provider() { - let spec = Spec::new_instant; + fn should_not_fail_setting_engine_signer_without_account_provider() { + let spec = Spec::new_test_round; let tap = Arc::new(AccountProvider::transient_provider()); let addr = tap.insert_account(keccak("1").into(), &"".into()).unwrap(); - let client = generate_dummy_client_with_spec_and_accounts(spec, None); - assert!(match client.miner().set_author(addr, Some("".into())) { Err(AccountError::NotFound) => true, _ => false }); + let client = generate_dummy_client_with_spec(spec); + let engine_signer = Box::new((tap.clone(), addr, "".into())); + let msg = Default::default(); + assert!(client.engine().sign(msg).is_err()); + + // should set engine signer and miner author + client.miner().set_author(Author::Sealer(engine_signer)); + assert_eq!(client.miner().authoring_params().author, addr); + assert!(client.engine().sign(msg).is_ok()); } #[test] diff --git a/ethcore/src/miner/mod.rs b/ethcore/src/miner/mod.rs index 4f5ba4c1f8..5156b60401 100644 --- a/ethcore/src/miner/mod.rs +++ b/ethcore/src/miner/mod.rs @@ -25,7 +25,8 @@ pub mod pool_client; #[cfg(feature = "stratum")] pub mod stratum; -pub use self::miner::{Miner, MinerOptions, Penalization, PendingSet, AuthoringParams}; +pub use self::miner::{Miner, MinerOptions, Penalization, PendingSet, AuthoringParams, Author}; +pub use ethcore_miner::local_accounts::LocalAccounts; pub use ethcore_miner::pool::PendingOrdering; use std::sync::Arc; @@ -34,7 +35,6 @@ use std::collections::{BTreeSet, BTreeMap}; use bytes::Bytes; use ethcore_miner::pool::{VerifiedTransaction, QueueStatus, local_transactions}; use ethereum_types::{H256, U256, Address}; -use ethkey::Password; use types::transaction::{self, UnverifiedTransaction, SignedTransaction, PendingTransaction}; use types::BlockNumber; use types::block::Block; @@ -130,8 +130,8 @@ pub trait MinerService : Send + Sync { /// Set info necessary to sign consensus messages and block authoring. /// - /// On PoW password is optional. - fn set_author(&self, address: Address, password: Option) -> Result<(), ::account_provider::SignError>; + /// On chains where sealing is done externally (e.g. PoW) we provide only reward beneficiary. + fn set_author(&self, author: Author); // Transaction Pool diff --git a/ethcore/src/miner/pool_client.rs b/ethcore/src/miner/pool_client.rs index a75454a3fd..df364d4464 100644 --- a/ethcore/src/miner/pool_client.rs +++ b/ethcore/src/miner/pool_client.rs @@ -23,6 +23,7 @@ use std::{ }; use ethereum_types::{H256, U256, Address}; +use ethcore_miner::local_accounts::LocalAccounts; use ethcore_miner::pool; use ethcore_miner::pool::client::NonceClient; use ethcore_miner::service_transaction_checker::ServiceTransactionChecker; @@ -34,7 +35,6 @@ use types::transaction::{ use types::header::Header; use parking_lot::RwLock; -use account_provider::AccountProvider; use call_contract::CallContract; use client::{TransactionId, BlockInfo, Nonce}; use engines::EthEngine; @@ -73,7 +73,7 @@ pub struct PoolClient<'a, C: 'a> { chain: &'a C, cached_nonces: CachedNonceClient<'a, C>, engine: &'a EthEngine, - accounts: Option<&'a AccountProvider>, + accounts: &'a LocalAccounts, best_block_header: Header, service_transaction_checker: Option, } @@ -92,14 +92,14 @@ impl<'a, C: 'a> Clone for PoolClient<'a, C> { } impl<'a, C: 'a> PoolClient<'a, C> where -C: BlockInfo + CallContract, + C: BlockInfo + CallContract, { /// Creates new client given chain, nonce cache, accounts and service transaction verifier. pub fn new( chain: &'a C, cache: &'a NonceCache, engine: &'a EthEngine, - accounts: Option<&'a AccountProvider>, + accounts: &'a LocalAccounts, refuse_service_transactions: bool, ) -> Self { let best_block_header = chain.best_block_header(); @@ -151,7 +151,7 @@ impl<'a, C: 'a> pool::client::Client for PoolClient<'a, C> where pool::client::AccountDetails { nonce: self.cached_nonces.account_nonce(address), balance: self.chain.latest_balance(address), - is_local: self.accounts.map_or(false, |accounts| accounts.has_account(*address)), + is_local: self.accounts.is_local(address), } } diff --git a/ethcore/src/snapshot/service.rs b/ethcore/src/snapshot/service.rs index 0da3f919fe..4b3f196cb1 100644 --- a/ethcore/src/snapshot/service.rs +++ b/ethcore/src/snapshot/service.rs @@ -340,7 +340,7 @@ impl Service { // replace one the client's database with our own. fn replace_client_db(&self) -> Result<(), Error> { let migrated_blocks = self.migrate_blocks()?; - trace!(target: "snapshot", "Migrated {} ancient blocks", migrated_blocks); + info!(target: "snapshot", "Migrated {} ancient blocks", migrated_blocks); let rest_db = self.restoration_db(); self.client.restore_db(&*rest_db.to_string_lossy())?; @@ -424,7 +424,7 @@ impl Service { } if block_number % 10_000 == 0 { - trace!(target: "snapshot", "Block restoration at #{}", block_number); + info!(target: "snapshot", "Block restoration at #{}", block_number); } } diff --git a/ethcore/src/snapshot/tests/proof_of_authority.rs b/ethcore/src/snapshot/tests/proof_of_authority.rs index 5ffcdab1b7..f1610e6ccd 100644 --- a/ethcore/src/snapshot/tests/proof_of_authority.rs +++ b/ethcore/src/snapshot/tests/proof_of_authority.rs @@ -20,12 +20,12 @@ use std::cell::RefCell; use std::sync::Arc; use std::str::FromStr; -use account_provider::AccountProvider; +use accounts::AccountProvider; use client::{Client, BlockChainClient, ChainInfo}; use ethkey::Secret; use snapshot::tests::helpers as snapshot_helpers; use spec::Spec; -use test_helpers::generate_dummy_client_with_spec_and_accounts; +use test_helpers::generate_dummy_client_with_spec; use types::transaction::{Transaction, Action, SignedTransaction}; use tempdir::TempDir; @@ -88,8 +88,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 = generate_dummy_client_with_spec_and_accounts( - spec_fixed_to_contract, Some(accounts.clone())); + let client = generate_dummy_client_with_spec(spec_fixed_to_contract); let mut cur_signers = vec![*RICH_ADDR]; { @@ -100,13 +99,14 @@ fn make_chain(accounts: Arc, blocks_beyond: usize, transitions: { // push a block with given number, signed by one of the signers, with given transactions. let push_block = |signers: &[Address], n, txs: Vec| { - use miner::MinerService; + use miner::{self, MinerService}; let idx = n as usize % signers.len(); trace!(target: "snapshot", "Pushing block #{}, {} txs, author={}", n, txs.len(), signers[idx]); - client.miner().set_author(signers[idx], Some(PASS.into())).unwrap(); + let signer = Box::new((accounts.clone(), signers[idx], PASS.into())); + client.miner().set_author(miner::Author::Sealer(signer)); client.miner().import_external_transactions(&*client, txs.into_iter().map(Into::into).collect()); diff --git a/ethcore/src/test_helpers.rs b/ethcore/src/test_helpers.rs index 939c4e5e1d..ae4968080b 100644 --- a/ethcore/src/test_helpers.rs +++ b/ethcore/src/test_helpers.rs @@ -39,7 +39,6 @@ use types::header::Header; use types::view; use types::views::BlockView; -use account_provider::AccountProvider; use block::{OpenBlock, Drain}; use client::{Client, ClientConfig, ChainInfo, ImportBlock, ChainNotify, ChainMessageType, PrepareOpenBlock}; use factory::Factories; @@ -109,18 +108,15 @@ pub fn generate_dummy_client_with_data(block_number: u32, txs_per_block: usize, 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, &[]) +pub fn generate_dummy_client_with_spec(test_spec: F) -> Arc where F: Fn()->Spec { + generate_dummy_client_with_spec_and_data(test_spec, 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 { +/// 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 +{ let test_spec = test_spec(); let client_db = new_db(); @@ -128,7 +124,7 @@ pub fn generate_dummy_client_with_spec_accounts_and_data(test_spec: F, accoun ClientConfig::default(), &test_spec, client_db, - Arc::new(Miner::new_for_tests(&test_spec, accounts)), + Arc::new(Miner::new_for_tests(&test_spec, None)), IoChannel::disconnected(), ).unwrap(); let test_engine = &*test_spec.engine; diff --git a/ethcore/sync/Cargo.toml b/ethcore/sync/Cargo.toml index c8545c00f0..37417cd0a3 100644 --- a/ethcore/sync/Cargo.toml +++ b/ethcore/sync/Cargo.toml @@ -9,13 +9,13 @@ authors = ["Parity Technologies "] [dependencies] common-types = { path = "../types" } -env_logger = "0.5" ethcore = { path = ".." } ethcore-io = { path = "../../util/io" } ethcore-light = { path = "../light" } ethcore-network = { path = "../../util/network" } ethcore-network-devp2p = { path = "../../util/network-devp2p" } ethereum-types = "0.4" +ethkey = { path = "../../accounts/ethkey" } ethstore = { path = "../../accounts/ethstore" } fastmap = { path = "../../util/fastmap" } hashdb = "0.3.0" @@ -34,9 +34,8 @@ triehash-ethereum = {version = "0.2", path = "../../util/triehash-ethereum" } [dev-dependencies] env_logger = "0.5" +ethcore = { path = "..", features = ["test-helpers"] } ethcore-io = { path = "../../util/io", features = ["mio"] } -ethkey = { path = "../../accounts/ethkey" } -kvdb-memorydb = "0.1" ethcore-private-tx = { path = "../private-tx" } -ethcore = { path = "..", features = ["test-helpers"] } +kvdb-memorydb = "0.1" rustc-hex = "1.0" diff --git a/ethcore/sync/src/api.rs b/ethcore/sync/src/api.rs index 28565db396..dda3393add 100644 --- a/ethcore/sync/src/api.rs +++ b/ethcore/sync/src/api.rs @@ -28,7 +28,7 @@ use network::{NetworkProtocolHandler, NetworkContext, PeerId, ProtocolId, use types::pruning_info::PruningInfo; use ethereum_types::{H256, H512, U256}; use io::{TimerToken}; -use ethstore::ethkey::Secret; +use ethkey::Secret; use ethcore::client::{BlockChainClient, ChainNotify, NewBlocks, ChainMessageType}; use ethcore::snapshot::SnapshotService; use types::BlockNumber; diff --git a/ethcore/sync/src/lib.rs b/ethcore/sync/src/lib.rs index 72fc11cd7a..e5bb2c4a76 100644 --- a/ethcore/sync/src/lib.rs +++ b/ethcore/sync/src/lib.rs @@ -27,6 +27,7 @@ extern crate ethcore_io as io; extern crate ethcore_network as network; extern crate ethcore_network_devp2p as devp2p; extern crate ethereum_types; +extern crate ethkey; extern crate ethstore; extern crate fastmap; extern crate keccak_hash as hash; @@ -40,7 +41,6 @@ extern crate ethcore_light as light; #[cfg(test)] extern crate env_logger; #[cfg(test)] extern crate ethcore_private_tx; -#[cfg(test)] extern crate ethkey; #[cfg(test)] extern crate kvdb_memorydb; #[cfg(test)] extern crate rustc_hex; diff --git a/ethcore/sync/src/tests/consensus.rs b/ethcore/sync/src/tests/consensus.rs index 6545652961..df09366338 100644 --- a/ethcore/sync/src/tests/consensus.rs +++ b/ethcore/sync/src/tests/consensus.rs @@ -19,9 +19,9 @@ use hash::keccak; use ethereum_types::{U256, Address}; use io::{IoHandler, IoChannel}; use ethcore::client::{ChainInfo, ClientIoMessage}; +use ethcore::engines; use ethcore::spec::Spec; -use ethcore::miner::MinerService; -use ethcore::account_provider::AccountProvider; +use ethcore::miner::{self, MinerService}; use ethkey::{KeyPair, Secret}; use types::transaction::{Action, PendingTransaction, Transaction}; use super::helpers::*; @@ -43,17 +43,14 @@ fn new_tx(secret: &Secret, nonce: U256, chain_id: u64) -> PendingTransaction { fn authority_round() { let s0 = KeyPair::from_secret_slice(&keccak("1")).unwrap(); let s1 = KeyPair::from_secret_slice(&keccak("0")).unwrap(); - let ap = Arc::new(AccountProvider::transient_provider()); - ap.insert_account(s0.secret().clone(), &"".into()).unwrap(); - ap.insert_account(s1.secret().clone(), &"".into()).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 mut net = TestNet::with_spec(2, SyncConfig::default(), Spec::new_test_round); 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).miner.set_author(s0.address(), Some("".into())).unwrap(); - net.peer(1).miner.set_author(s1.address(), Some("".into())).unwrap(); + net.peer(0).miner.set_author(miner::Author::Sealer(engines::signer::from_keypair(s0.clone()))); + net.peer(1).miner.set_author(miner::Author::Sealer(engines::signer::from_keypair(s1.clone()))); net.peer(0).chain.engine().register_client(Arc::downgrade(&net.peer(0).chain) as _); net.peer(1).chain.engine().register_client(Arc::downgrade(&net.peer(1).chain) as _); net.peer(0).chain.set_io_channel(IoChannel::to_handler(Arc::downgrade(&io_handler1))); diff --git a/ethcore/sync/src/tests/helpers.rs b/ethcore/sync/src/tests/helpers.rs index 85c2038457..f7207c6788 100644 --- a/ethcore/sync/src/tests/helpers.rs +++ b/ethcore/sync/src/tests/helpers.rs @@ -25,7 +25,6 @@ use ethcore::client::{TestBlockChainClient, BlockChainClient, Client as EthcoreC ClientConfig, ChainNotify, NewBlocks, ChainMessageType, ClientIoMessage}; use ethcore::snapshot::SnapshotService; use ethcore::spec::Spec; -use ethcore::account_provider::AccountProvider; use ethcore::miner::Miner; use ethcore::test_helpers; use sync_io::SyncIo; @@ -367,11 +366,10 @@ impl TestNet> { } impl TestNet> { - pub fn with_spec_and_accounts( + pub fn with_spec( n: usize, config: SyncConfig, spec_factory: F, - accounts: Option> ) -> Self where F: Fn() -> Spec { @@ -381,14 +379,14 @@ impl TestNet> { disconnect_events: Vec::new(), }; for _ in 0..n { - net.add_peer_with_private_config(config.clone(), spec_factory(), accounts.clone()); + net.add_peer_with_private_config(config.clone(), spec_factory()); } net } - pub fn add_peer_with_private_config(&mut self, config: SyncConfig, spec: Spec, accounts: Option>) { + pub fn add_peer_with_private_config(&mut self, config: SyncConfig, spec: Spec) { let channel = IoChannel::disconnected(); - let miner = Arc::new(Miner::new_for_tests(&spec, accounts.clone())); + let miner = Arc::new(Miner::new_for_tests(&spec, None)); let client = EthcoreClient::new( ClientConfig::default(), &spec, diff --git a/ethcore/sync/src/tests/private.rs b/ethcore/sync/src/tests/private.rs index 221caf77c5..24de14d936 100644 --- a/ethcore/sync/src/tests/private.rs +++ b/ethcore/sync/src/tests/private.rs @@ -17,16 +17,17 @@ use std::sync::Arc; use hash::keccak; use io::{IoHandler, IoChannel}; -use ethcore::client::{BlockChainClient, BlockId, ClientIoMessage}; -use ethcore::spec::Spec; -use ethcore::miner::MinerService; -use ethcore::CreateContractAddress; use types::transaction::{Transaction, Action}; +use types::ids::BlockId; +use ethcore::CreateContractAddress; +use ethcore::client::{ClientIoMessage, BlockChainClient}; use ethcore::executive::{contract_address}; +use ethcore::engines; +use ethcore::miner::{self, MinerService}; +use ethcore::spec::Spec; use ethcore::test_helpers::{push_block_with_transactions}; use ethcore_private_tx::{Provider, ProviderConfig, NoopEncryptor, Importer, SignedPrivateTransaction, StoringKeyProvider}; -use ethcore::account_provider::AccountProvider; -use ethkey::{KeyPair}; +use ethkey::KeyPair; use tests::helpers::{TestNet, TestIoHandler}; use rustc_hex::FromHex; use rlp::Rlp; @@ -42,18 +43,17 @@ fn send_private_transaction() { // Setup two clients let s0 = KeyPair::from_secret_slice(&keccak("1")).unwrap(); let s1 = KeyPair::from_secret_slice(&keccak("0")).unwrap(); - let ap = Arc::new(AccountProvider::transient_provider()); - ap.insert_account(s0.secret().clone(), &"".into()).unwrap(); - ap.insert_account(s1.secret().clone(), &"".into()).unwrap(); - let mut net = TestNet::with_spec_and_accounts(2, SyncConfig::default(), seal_spec, Some(ap.clone())); + let signer = Arc::new(ethcore_private_tx::KeyPairSigner(vec![s0.clone(), s1.clone()])); + + let mut net = TestNet::with_spec(2, SyncConfig::default(), seal_spec); let client0 = net.peer(0).chain.clone(); let client1 = net.peer(1).chain.clone(); 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())); - net.peer(0).miner.set_author(s0.address(), Some("".into())).unwrap(); - net.peer(1).miner.set_author(s1.address(), Some("".into())).unwrap(); + net.peer(0).miner.set_author(miner::Author::Sealer(engines::signer::from_keypair(s0.clone()))); + net.peer(1).miner.set_author(miner::Author::Sealer(engines::signer::from_keypair(s1.clone()))); net.peer(0).chain.engine().register_client(Arc::downgrade(&net.peer(0).chain) as _); net.peer(1).chain.engine().register_client(Arc::downgrade(&net.peer(1).chain) as _); net.peer(0).chain.set_io_channel(IoChannel::to_handler(Arc::downgrade(&io_handler0))); @@ -69,13 +69,11 @@ fn send_private_transaction() { let validator_config = ProviderConfig{ validator_accounts: vec![s1.address()], signer_account: None, - passwords: vec!["".into()], }; let signer_config = ProviderConfig{ validator_accounts: Vec::new(), signer_account: Some(s0.address()), - passwords: vec!["".into()], }; let private_keys = Arc::new(StoringKeyProvider::default()); @@ -83,7 +81,7 @@ fn send_private_transaction() { let pm0 = Arc::new(Provider::new( client0.clone(), net.peer(0).miner.clone(), - ap.clone(), + signer.clone(), Box::new(NoopEncryptor::default()), signer_config, IoChannel::to_handler(Arc::downgrade(&io_handler0)), @@ -94,7 +92,7 @@ fn send_private_transaction() { let pm1 = Arc::new(Provider::new( client1.clone(), net.peer(1).miner.clone(), - ap.clone(), + signer.clone(), Box::new(NoopEncryptor::default()), validator_config, IoChannel::to_handler(Arc::downgrade(&io_handler1)), diff --git a/json/src/lib.rs b/json/src/lib.rs index b8fa463d42..af5d93edfa 100644 --- a/json/src/lib.rs +++ b/json/src/lib.rs @@ -30,5 +30,4 @@ pub mod vm; pub mod maybe; pub mod state; pub mod transaction; -pub mod misc; pub mod test; diff --git a/json/src/misc/mod.rs b/json/src/misc/mod.rs deleted file mode 100644 index 52bbfc03af..0000000000 --- a/json/src/misc/mod.rs +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright 2015-2019 Parity Technologies (UK) Ltd. -// This file is part of Parity Ethereum. - -// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . - -//! Misc deserialization. - -macro_rules! impl_serialization { - ($key: ty => $name: ty) => { - impl $name { - /// Read a hash map of DappId -> $name - pub fn read(reader: R) -> Result<::std::collections::HashMap, ::serde_json::Error> where - R: ::std::io::Read, - D: From<$key> + ::std::hash::Hash + Eq, - S: From<$name> + Clone, - { - ::serde_json::from_reader(reader).map(|ok: ::std::collections::HashMap<$key, $name>| - ok.into_iter().map(|(a, m)| (a.into(), m.into())).collect() - ) - } - - /// Write a hash map of DappId -> $name - pub fn write(m: &::std::collections::HashMap, writer: &mut W) -> Result<(), ::serde_json::Error> where - W: ::std::io::Write, - D: Into<$key> + ::std::hash::Hash + Eq + Clone, - S: Into<$name> + Clone, - { - ::serde_json::to_writer( - writer, - &m.iter() - .map(|(a, m)| (a.clone().into(), m.clone().into())) - .collect::<::std::collections::HashMap<$key, $name>>() - ) - } - } - } -} - -mod account_meta; - -pub use self::account_meta::AccountMeta; diff --git a/miner/src/lib.rs b/miner/src/lib.rs index 921e6dbaad..55091093ac 100644 --- a/miner/src/lib.rs +++ b/miner/src/lib.rs @@ -57,6 +57,7 @@ pub mod external; #[cfg(feature = "price-info")] pub mod gas_price_calibrator; pub mod gas_pricer; +pub mod local_accounts; pub mod pool; pub mod service_transaction_checker; #[cfg(feature = "work-notify")] diff --git a/rpc/src/v1/helpers/accounts.rs b/miner/src/local_accounts.rs similarity index 56% rename from rpc/src/v1/helpers/accounts.rs rename to miner/src/local_accounts.rs index 544c47883c..23bcf81442 100644 --- a/rpc/src/v1/helpers/accounts.rs +++ b/miner/src/local_accounts.rs @@ -14,14 +14,30 @@ // You should have received a copy of the GNU General Public License // along with Parity Ethereum. If not, see . -use std::sync::Arc; -use ethcore::account_provider::AccountProvider; -use jsonrpc_core::Error; -use v1::helpers::errors; - -pub fn unwrap_provider(provider: &Option>) -> Result, Error> { - match *provider { - Some(ref arc) => Ok(arc.clone()), - None => Err(errors::public_unsupported(None)), +//! Local Accounts checker + +use std::collections::HashSet; + +use ethereum_types::Address; + +/// Local accounts checker +pub trait LocalAccounts: Send + Sync { + /// Returns true if given address should be considered local account. + fn is_local(&self, &Address) -> bool; +} + +impl LocalAccounts for HashSet
{ + fn is_local(&self, address: &Address) -> bool { + self.contains(address) } } + +impl LocalAccounts for (A, B) where + A: LocalAccounts, + B: LocalAccounts, +{ + fn is_local(&self, address: &Address) -> bool { + self.0.is_local(address) || self.1.is_local(address) + } +} + diff --git a/parity/account.rs b/parity/account.rs index 389f288647..578e9e7ef8 100644 --- a/parity/account.rs +++ b/parity/account.rs @@ -15,12 +15,6 @@ // along with Parity Ethereum. If not, see . use std::num::NonZeroU32; -use std::path::PathBuf; -use ethstore::{EthStore, SecretStore, import_account, import_accounts, read_geth_accounts}; -use ethstore::accounts_dir::RootDiskDirectory; -use ethstore::SecretVaultRef; -use ethcore::account_provider::{AccountProvider, AccountProviderSettings}; -use helpers::{password_prompt, password_from_file}; use params::SpecType; #[derive(Debug, PartialEq)] @@ -62,83 +56,102 @@ pub struct ImportFromGethAccounts { pub spec: SpecType, } + +#[cfg(not(feature = "accounts"))] pub fn execute(cmd: AccountCmd) -> Result { - match cmd { - AccountCmd::New(new_cmd) => new(new_cmd), - AccountCmd::List(list_cmd) => list(list_cmd), - AccountCmd::Import(import_cmd) => import(import_cmd), - AccountCmd::ImportFromGeth(import_geth_cmd) => import_geth(import_geth_cmd) - } + Err("Account management is deprecated. Please see #9997 for alternatives:\nhttps://github.com/paritytech/parity-ethereum/issues/9997".into()) } -fn keys_dir(path: String, spec: SpecType) -> Result { - let spec = spec.spec(&::std::env::temp_dir())?; - let mut path = PathBuf::from(&path); - path.push(spec.data_dir); - RootDiskDirectory::create(path).map_err(|e| format!("Could not open keys directory: {}", e)) -} +#[cfg(feature = "accounts")] +mod command { + use super::*; + use std::path::PathBuf; + use accounts::{AccountProvider, AccountProviderSettings}; + use ethstore::{EthStore, SecretStore, SecretVaultRef, import_account, import_accounts, read_geth_accounts}; + use ethstore::accounts_dir::RootDiskDirectory; + use helpers::{password_prompt, password_from_file}; + + pub fn execute(cmd: AccountCmd) -> Result { + match cmd { + AccountCmd::New(new_cmd) => new(new_cmd), + AccountCmd::List(list_cmd) => list(list_cmd), + AccountCmd::Import(import_cmd) => import(import_cmd), + AccountCmd::ImportFromGeth(import_geth_cmd) => import_geth(import_geth_cmd) + } + } -fn secret_store(dir: Box, iterations: Option) -> Result { - match iterations { - Some(i) => EthStore::open_with_iterations(dir, i), - _ => EthStore::open(dir) - }.map_err(|e| format!("Could not open keys store: {}", e)) -} + fn keys_dir(path: String, spec: SpecType) -> Result { + let spec = spec.spec(&::std::env::temp_dir())?; + let mut path = PathBuf::from(&path); + path.push(spec.data_dir); + RootDiskDirectory::create(path).map_err(|e| format!("Could not open keys directory: {}", e)) + } -fn new(n: NewAccount) -> Result { - let password = match n.password_file { - Some(file) => password_from_file(file)?, - None => password_prompt()?, - }; - - let dir = Box::new(keys_dir(n.path, n.spec)?); - let secret_store = Box::new(secret_store(dir, Some(n.iterations))?); - let acc_provider = AccountProvider::new(secret_store, AccountProviderSettings::default()); - let new_account = acc_provider.new_account(&password).map_err(|e| format!("Could not create new account: {}", e))?; - Ok(format!("0x{:x}", new_account)) -} + fn secret_store(dir: Box, iterations: Option) -> Result { + match iterations { + Some(i) => EthStore::open_with_iterations(dir, i), + _ => EthStore::open(dir) + }.map_err(|e| format!("Could not open keys store: {}", e)) + } -fn list(list_cmd: ListAccounts) -> Result { - let dir = Box::new(keys_dir(list_cmd.path, list_cmd.spec)?); - let secret_store = Box::new(secret_store(dir, None)?); - let acc_provider = AccountProvider::new(secret_store, AccountProviderSettings::default()); - let accounts = acc_provider.accounts().map_err(|e| format!("{}", e))?; - let result = accounts.into_iter() - .map(|a| format!("0x{:x}", a)) - .collect::>() - .join("\n"); - - Ok(result) -} + fn new(n: NewAccount) -> Result { + let password = match n.password_file { + Some(file) => password_from_file(file)?, + None => password_prompt()?, + }; + + let dir = Box::new(keys_dir(n.path, n.spec)?); + let secret_store = Box::new(secret_store(dir, Some(n.iterations))?); + let acc_provider = AccountProvider::new(secret_store, AccountProviderSettings::default()); + let new_account = acc_provider.new_account(&password).map_err(|e| format!("Could not create new account: {}", e))?; + Ok(format!("0x{:x}", new_account)) + } -fn import(i: ImportAccounts) -> Result { - let to = keys_dir(i.to, i.spec)?; - let mut imported = 0; - - for path in &i.from { - let path = PathBuf::from(path); - if path.is_dir() { - let from = RootDiskDirectory::at(&path); - imported += import_accounts(&from, &to).map_err(|e| format!("Importing accounts from {:?} failed: {}", path, e))?.len(); - } else if path.is_file() { - import_account(&path, &to).map_err(|e| format!("Importing account from {:?} failed: {}", path, e))?; - imported += 1; - } + fn list(list_cmd: ListAccounts) -> Result { + let dir = Box::new(keys_dir(list_cmd.path, list_cmd.spec)?); + let secret_store = Box::new(secret_store(dir, None)?); + let acc_provider = AccountProvider::new(secret_store, AccountProviderSettings::default()); + let accounts = acc_provider.accounts().map_err(|e| format!("{}", e))?; + let result = accounts.into_iter() + .map(|a| format!("0x{:x}", a)) + .collect::>() + .join("\n"); + + Ok(result) } - Ok(format!("{} account(s) imported", imported)) -} + fn import(i: ImportAccounts) -> Result { + let to = keys_dir(i.to, i.spec)?; + let mut imported = 0; + + for path in &i.from { + let path = PathBuf::from(path); + if path.is_dir() { + let from = RootDiskDirectory::at(&path); + imported += import_accounts(&from, &to).map_err(|e| format!("Importing accounts from {:?} failed: {}", path, e))?.len(); + } else if path.is_file() { + import_account(&path, &to).map_err(|e| format!("Importing account from {:?} failed: {}", path, e))?; + imported += 1; + } + } -fn import_geth(i: ImportFromGethAccounts) -> Result { - use std::io::ErrorKind; - use ethstore::Error; - - let dir = Box::new(keys_dir(i.to, i.spec)?); - let secret_store = Box::new(secret_store(dir, None)?); - let geth_accounts = read_geth_accounts(i.testnet); - match secret_store.import_geth_accounts(SecretVaultRef::Root, geth_accounts, i.testnet) { - Ok(v) => Ok(format!("Successfully imported {} account(s) from geth.", v.len())), - Err(Error::Io(ref io_err)) if io_err.kind() == ErrorKind::NotFound => Err("Failed to find geth keys folder.".into()), - Err(err) => Err(format!("Import geth accounts failed. {}", err)) + Ok(format!("{} account(s) imported", imported)) + } + + fn import_geth(i: ImportFromGethAccounts) -> Result { + use std::io::ErrorKind; + use ethstore::Error; + + let dir = Box::new(keys_dir(i.to, i.spec)?); + let secret_store = Box::new(secret_store(dir, None)?); + let geth_accounts = read_geth_accounts(i.testnet); + match secret_store.import_geth_accounts(SecretVaultRef::Root, geth_accounts, i.testnet) { + Ok(v) => Ok(format!("Successfully imported {} account(s) from geth.", v.len())), + Err(Error::Io(ref io_err)) if io_err.kind() == ErrorKind::NotFound => Err("Failed to find geth keys folder.".into()), + Err(err) => Err(format!("Import geth accounts failed. {}", err)) + } } } + +#[cfg(feature = "accounts")] +pub use self::command::execute; diff --git a/parity/account_utils.rs b/parity/account_utils.rs new file mode 100644 index 0000000000..caaad53e17 --- /dev/null +++ b/parity/account_utils.rs @@ -0,0 +1,244 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +use std::sync::Arc; + +use dir::Directories; +use ethereum_types::Address; +use ethkey::Password; + +use params::{SpecType, AccountsConfig}; + +#[cfg(not(feature = "accounts"))] +mod accounts { + use super::*; + + /// Dummy AccountProvider + pub struct AccountProvider; + + impl ::ethcore::miner::LocalAccounts for AccountProvider { + fn is_local(&self, address: &Address) -> bool { + false + } + } + + pub fn prepare_account_provider(_spec: &SpecType, _dirs: &Directories, _data_dir: &str, cfg: AccountsConfig, _passwords: &[Password]) -> Result { + warn!("Note: Your instance of Parity Ethereum is running without account support. Some CLI options are ignored."); + Ok(AccountProvider) + } + + pub fn miner_local_accounts(_: Arc) -> AccountProvider { + AccountProvider + } + + pub fn miner_author(_spec: &SpecType, _dirs: &Directories, _account_provider: &Arc, _engine_signer: Address, _passwords: &[Password]) -> Result, String> { + Ok(None) + } + + pub fn private_tx_signer(_account_provider: Arc, _passwords: &[Password]) -> Result, String> { + Ok(Arc::new(::ethcore_private_tx::DummySigner)) + } + + pub fn accounts_list(_account_provider: Arc) -> Arc Vec
+ Send + Sync> { + Arc::new(|| vec![]) + } +} + +#[cfg(feature = "accounts")] +mod accounts { + use super::*; + use upgrade::upgrade_key_location; + + pub use accounts::AccountProvider; + + /// Pops along with error messages when a password is missing or invalid. + const VERIFY_PASSWORD_HINT: &str = "Make sure valid password is present in files passed using `--password` or in the configuration file."; + + /// Initialize account provider + pub fn prepare_account_provider(spec: &SpecType, dirs: &Directories, data_dir: &str, cfg: AccountsConfig, passwords: &[Password]) -> Result { + use ethstore::EthStore; + use ethstore::accounts_dir::RootDiskDirectory; + use accounts::AccountProviderSettings; + + let path = dirs.keys_path(data_dir); + upgrade_key_location(&dirs.legacy_keys_path(cfg.testnet), &path); + let dir = Box::new(RootDiskDirectory::create(&path).map_err(|e| format!("Could not open keys directory: {}", e))?); + let account_settings = AccountProviderSettings { + enable_hardware_wallets: cfg.enable_hardware_wallets, + hardware_wallet_classic_key: spec == &SpecType::Classic, + unlock_keep_secret: cfg.enable_fast_unlock, + blacklisted_accounts: match *spec { + SpecType::Morden | SpecType::Ropsten | SpecType::Kovan | SpecType::Sokol | SpecType::Dev => vec![], + _ => vec![ + "00a329c0648769a73afac7f9381e08fb43dbea72".into() + ], + }, + }; + + let ethstore = EthStore::open_with_iterations(dir, cfg.iterations).map_err(|e| format!("Could not open keys directory: {}", e))?; + if cfg.refresh_time > 0 { + ethstore.set_refresh_time(::std::time::Duration::from_secs(cfg.refresh_time)); + } + let account_provider = AccountProvider::new( + Box::new(ethstore), + account_settings, + ); + + // Add development account if running dev chain: + if let SpecType::Dev = *spec { + insert_dev_account(&account_provider); + } + + for a in cfg.unlocked_accounts { + // Check if the account exists + if !account_provider.has_account(a) { + return Err(format!("Account {} not found for the current chain. {}", a, build_create_account_hint(spec, &dirs.keys))); + } + + // Check if any passwords have been read from the password file(s) + if passwords.is_empty() { + return Err(format!("No password found to unlock account {}. {}", a, VERIFY_PASSWORD_HINT)); + } + + if !passwords.iter().any(|p| account_provider.unlock_account_permanently(a, (*p).clone()).is_ok()) { + return Err(format!("No valid password to unlock account {}. {}", a, VERIFY_PASSWORD_HINT)); + } + } + + Ok(account_provider) + } + + pub struct LocalAccounts(Arc); + impl ::ethcore::miner::LocalAccounts for LocalAccounts { + fn is_local(&self, address: &Address) -> bool { + self.0.has_account(*address) + } + } + + pub fn miner_local_accounts(account_provider: Arc) -> LocalAccounts { + LocalAccounts(account_provider) + } + + pub fn miner_author(spec: &SpecType, dirs: &Directories, account_provider: &Arc, engine_signer: Address, passwords: &[Password]) -> Result, String> { + use ethcore::engines::EngineSigner; + + // Check if engine signer exists + if !account_provider.has_account(engine_signer) { + return Err(format!("Consensus signer account not found for the current chain. {}", build_create_account_hint(spec, &dirs.keys))); + } + + // Check if any passwords have been read from the password file(s) + if passwords.is_empty() { + return Err(format!("No password found for the consensus signer {}. {}", engine_signer, VERIFY_PASSWORD_HINT)); + } + + let mut author = None; + for password in passwords { + let signer = parity_rpc::signer::EngineSigner::new( + account_provider.clone(), + engine_signer, + password.clone(), + ); + if signer.sign(Default::default()).is_ok() { + author = Some(::ethcore::miner::Author::Sealer(Box::new(signer))); + } + } + if author.is_none() { + return Err(format!("No valid password for the consensus signer {}. {}", engine_signer, VERIFY_PASSWORD_HINT)); + } + + Ok(author) + } + + + mod private_tx { + use super::*; + use ethkey::{Signature, Message}; + use ethcore_private_tx::{Error}; + + pub struct AccountSigner { + pub accounts: Arc, + pub passwords: Vec, + } + + impl ::ethcore_private_tx::Signer for AccountSigner { + fn decrypt(&self, account: Address, shared_mac: &[u8], payload: &[u8]) -> Result, Error> { + let password = self.find_account_password(&account); + Ok(self.accounts.decrypt(account, password, shared_mac, payload).map_err(|e| e.to_string())?) + } + + fn sign(&self, account: Address, hash: Message) -> Result { + let password = self.find_account_password(&account); + Ok(self.accounts.sign(account, password, hash).map_err(|e| e.to_string())?) + } + } + + impl AccountSigner { + /// Try to unlock account using stored password, return found password if any + fn find_account_password(&self, account: &Address) -> Option { + for password in &self.passwords { + if let Ok(true) = self.accounts.test_password(account, password) { + return Some(password.clone()); + } + } + None + } + } + } + + pub fn private_tx_signer(accounts: Arc, passwords: &[Password]) -> Result, String> { + Ok(Arc::new(self::private_tx::AccountSigner { + accounts, + passwords: passwords.to_vec(), + })) + } + + pub fn accounts_list(account_provider: Arc) -> Arc Vec
+ Send + Sync> { + Arc::new(move || account_provider.accounts().unwrap_or_default()) + } + + fn insert_dev_account(account_provider: &AccountProvider) { + let secret: ethkey::Secret = "4d5db4107d237df6a3d58ee5f70ae63d73d7658d4026f2eefd2f204c81682cb7".into(); + let dev_account = ethkey::KeyPair::from_secret(secret.clone()).expect("Valid secret produces valid key;qed"); + if !account_provider.has_account(dev_account.address()) { + match account_provider.insert_account(secret, &Password::from(String::new())) { + Err(e) => warn!("Unable to add development account: {}", e), + Ok(address) => { + let _ = account_provider.set_account_name(address.clone(), "Development Account".into()); + let _ = account_provider.set_account_meta(address, ::serde_json::to_string(&(vec![ + ("description", "Never use this account outside of development chain!"), + ("passwordHint","Password is empty string"), + ].into_iter().collect::<::std::collections::HashMap<_,_>>())).expect("Serialization of hashmap does not fail.")); + }, + } + } + } + + // Construct an error `String` with an adaptive hint on how to create an account. + fn build_create_account_hint(spec: &SpecType, keys: &str) -> String { + format!("You can create an account via RPC, UI or `parity account new --chain {} --keys-path {}`.", spec, keys) + } +} + +pub use self::accounts::{ + AccountProvider, + prepare_account_provider, + miner_local_accounts, + miner_author, + private_tx_signer, + accounts_list, +}; + diff --git a/parity/blockchain.rs b/parity/blockchain.rs index 65c43a27c5..262b98ae2c 100644 --- a/parity/blockchain.rs +++ b/parity/blockchain.rs @@ -25,9 +25,9 @@ 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, Nonce, Balance, BlockChainClient, BlockId, BlockInfo, - ImportBlock, BlockChainReset}; +use ethcore::client::{ + Mode, DatabaseCompactionProfile, VMType, Nonce, Balance, BlockChainClient, BlockId, BlockInfo, ImportBlock, BlockChainReset +}; use ethcore::error::{ImportErrorKind, ErrorKind as EthcoreErrorKind, Error as EthcoreError}; use ethcore::miner::Miner; use ethcore::verification::queue::VerifierSettings; @@ -395,7 +395,7 @@ fn execute_import(cmd: ImportBlockchain) -> Result<(), String> { // TODO [ToDr] don't use test miner here // (actually don't require miner at all) Arc::new(Miner::new_for_tests(&spec, None)), - Arc::new(AccountProvider::transient_provider()), + Arc::new(ethcore_private_tx::DummySigner), Box::new(ethcore_private_tx::NoopEncryptor), Default::default(), Default::default(), @@ -587,7 +587,7 @@ fn start_client( // It's fine to use test version here, // since we don't care about miner parameters at all Arc::new(Miner::new_for_tests(&spec, None)), - Arc::new(AccountProvider::transient_provider()), + Arc::new(ethcore_private_tx::DummySigner), Box::new(ethcore_private_tx::NoopEncryptor), Default::default(), Default::default(), diff --git a/parity/configuration.rs b/parity/configuration.rs index 087537ff1e..198a58c3f9 100644 --- a/parity/configuration.rs +++ b/parity/configuration.rs @@ -29,7 +29,7 @@ use parity_version::{version_data, version}; use bytes::Bytes; use ansi_term::Colour; use sync::{NetworkConfiguration, validate_node_url, self}; -use ethstore::ethkey::{Secret, Public}; +use ethkey::{Secret, Public}; use ethcore::client::{VMType}; use ethcore::miner::{stratum, MinerOptions}; use ethcore::snapshot::SnapshotConfiguration; @@ -40,7 +40,7 @@ use num_cpus; use rpc::{IpcConfiguration, HttpConfiguration, WsConfiguration}; use parity_rpc::NetworkSettings; use cache::CacheConfig; -use helpers::{to_duration, to_mode, to_block_id, to_u256, to_pending_set, to_price, geth_ipc_path, parity_ipc_path, to_bootnodes, to_addresses, to_address, to_queue_strategy, to_queue_penalization, passwords_from_files}; +use helpers::{to_duration, to_mode, to_block_id, to_u256, to_pending_set, to_price, geth_ipc_path, parity_ipc_path, to_bootnodes, to_addresses, to_address, to_queue_strategy, to_queue_penalization}; use dir::helpers::{replace_home, replace_home_and_local}; use params::{ResealPolicy, AccountsConfig, GasPricerConfig, MinerExtras, SpecType}; use ethcore_logger::Config as LogConfig; @@ -442,6 +442,7 @@ impl Configuration { gas_range_target: (floor, ceil), engine_signer: self.engine_signer()?, work_notify: self.work_notify(), + local_accounts: HashSet::from_iter(to_addresses(&self.args.arg_tx_queue_locals)?.into_iter()), }; Ok(extras) @@ -579,7 +580,6 @@ impl Configuration { infinite_pending_block: self.args.flag_infinite_pending_block, tx_queue_penalization: to_queue_penalization(self.args.arg_tx_time_limit)?, - tx_queue_locals: HashSet::from_iter(to_addresses(&self.args.arg_tx_queue_locals)?.into_iter()), tx_queue_strategy: to_queue_strategy(&self.args.arg_tx_queue_strategy)?, tx_queue_no_unfamiliar_locals: self.args.flag_tx_queue_no_unfamiliar_locals, refuse_service_transactions: self.args.flag_refuse_service_transactions, @@ -916,20 +916,12 @@ impl Configuration { 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)) @@ -1070,6 +1062,7 @@ impl Configuration { match self.args.arg_secretstore_secret { Some(ref s) if s.len() == 64 => Ok(Some(NodeSecretKey::Plain(s.parse() .map_err(|e| format!("Invalid secret store secret: {}. Error: {:?}", s, e))?))), + #[cfg(feature = "accounts")] Some(ref s) if s.len() == 40 => Ok(Some(NodeSecretKey::KeyStore(s.parse() .map_err(|e| format!("Invalid secret store secret address: {}. Error: {:?}", s, e))?))), Some(_) => Err(format!("Invalid secret store secret. Must be either existing account address, or hex-encoded private key")), diff --git a/parity/lib.rs b/parity/lib.rs index f3a7941293..9141bdcade 100644 --- a/parity/lib.rs +++ b/parity/lib.rs @@ -43,7 +43,6 @@ extern crate toml; extern crate blooms_db; extern crate cli_signer; extern crate common_types as types; -extern crate parity_bytes as bytes; extern crate ethcore; extern crate ethcore_call_contract as call_contract; extern crate ethcore_db; @@ -56,26 +55,30 @@ extern crate ethcore_private_tx; extern crate ethcore_service; extern crate ethcore_sync as sync; extern crate ethereum_types; -extern crate ethstore; extern crate ethkey; +extern crate ethstore; +extern crate journaldb; +extern crate keccak_hash as hash; extern crate kvdb; +extern crate node_filter; +extern crate parity_bytes as bytes; extern crate parity_hash_fetch as hash_fetch; extern crate parity_ipfs_api; extern crate parity_local_store as local_store; -extern crate parity_runtime; +extern crate parity_path as path; extern crate parity_rpc; +extern crate parity_runtime; extern crate parity_updater as updater; extern crate parity_version; extern crate parity_whisper; -extern crate parity_path as path; -extern crate node_filter; -extern crate keccak_hash as hash; -extern crate journaldb; extern crate registrar; #[macro_use] extern crate log as rlog; +#[cfg(feature = "ethcore-accounts")] +extern crate ethcore_accounts as accounts; + #[cfg(feature = "secretstore")] extern crate ethcore_secretstore; @@ -91,6 +94,7 @@ extern crate tempdir; extern crate lazy_static; mod account; +mod account_utils; mod blockchain; mod cache; mod cli; diff --git a/parity/params.rs b/parity/params.rs index f609fa07c0..a916d05a78 100644 --- a/parity/params.rs +++ b/parity/params.rs @@ -14,9 +14,10 @@ // You should have received a copy of the GNU General Public License // along with Parity Ethereum. If not, see . +use std::collections::HashSet; +use std::time::Duration; use std::{str, fs, fmt}; use std::num::NonZeroU32; -use std::time::Duration; use ethcore::client::Mode; use ethcore::ethereum; @@ -283,6 +284,7 @@ pub struct MinerExtras { pub extra_data: Vec, pub gas_range_target: (U256, U256), pub work_notify: Vec, + pub local_accounts: HashSet
, } impl Default for MinerExtras { @@ -293,6 +295,7 @@ impl Default for MinerExtras { extra_data: version_data(), gas_range_target: (8_000_000.into(), 10_000_000.into()), work_notify: Default::default(), + local_accounts: Default::default(), } } } diff --git a/parity/presale.rs b/parity/presale.rs index 07087b9ef2..162d149b54 100644 --- a/parity/presale.rs +++ b/parity/presale.rs @@ -14,9 +14,9 @@ // You should have received a copy of the GNU General Public License // along with Parity Ethereum. If not, see . -use ethstore::{PresaleWallet, EthStore}; -use ethstore::accounts_dir::RootDiskDirectory; -use ethcore::account_provider::{AccountProvider, AccountProviderSettings}; + +use ethkey::Password; +use ethstore::PresaleWallet; use helpers::{password_prompt, password_from_file}; use params::SpecType; use std::num::NonZeroU32; @@ -31,16 +31,29 @@ pub struct ImportWallet { } pub fn execute(cmd: ImportWallet) -> Result { - let password = match cmd.password_file { + let password = match cmd.password_file.clone() { Some(file) => password_from_file(file)?, None => password_prompt()?, }; - let dir = Box::new(RootDiskDirectory::create(cmd.path).unwrap()); - let secret_store = Box::new(EthStore::open_with_iterations(dir, cmd.iterations).unwrap()); - let acc_provider = AccountProvider::new(secret_store, AccountProviderSettings::default()); - let wallet = PresaleWallet::open(cmd.wallet_path).map_err(|_| "Unable to open presale wallet.")?; + let wallet = PresaleWallet::open(cmd.wallet_path.clone()).map_err(|_| "Unable to open presale wallet.")?; let kp = wallet.decrypt(&password).map_err(|_| "Invalid password.")?; - let address = acc_provider.insert_account(kp.secret().clone(), &password).unwrap(); + let address = kp.address(); + import_account(&cmd, kp, password); Ok(format!("{:?}", address)) } + +#[cfg(feature = "accounts")] +pub fn import_account(cmd: &ImportWallet, kp: ethkey::KeyPair, password: Password) { + use accounts::{AccountProvider, AccountProviderSettings}; + use ethstore::EthStore; + use ethstore::accounts_dir::RootDiskDirectory; + + let dir = Box::new(RootDiskDirectory::create(cmd.path.clone()).unwrap()); + let secret_store = Box::new(EthStore::open_with_iterations(dir, cmd.iterations).unwrap()); + let acc_provider = AccountProvider::new(secret_store, AccountProviderSettings::default()); + acc_provider.insert_account(kp.secret().clone(), &password).unwrap(); +} + +#[cfg(not(feature = "accounts"))] +pub fn import_account(_cmd: &ImportWallet, _kp: ethkey::KeyPair, _password: Password) {} diff --git a/parity/rpc_apis.rs b/parity/rpc_apis.rs index 10eaa55448..951a4dec4b 100644 --- a/parity/rpc_apis.rs +++ b/parity/rpc_apis.rs @@ -21,7 +21,7 @@ use std::sync::{Arc, Weak}; pub use parity_rpc::signer::SignerService; -use ethcore::account_provider::AccountProvider; +use account_utils::{self, AccountProvider}; use ethcore::client::Client; use ethcore::miner::Miner; use ethcore::snapshot::SnapshotService; @@ -197,6 +197,26 @@ fn to_modules(apis: &HashSet) -> BTreeMap { modules } +macro_rules! add_signing_methods { + ($namespace:ident, $handler:expr, $deps:expr, $dispatch:expr) => {{ + let deps = &$deps; + let (dispatcher, accounts) = $dispatch; + if deps.signer_service.is_enabled() { + $handler.extend_with($namespace::to_delegate(SigningQueueClient::new( + &deps.signer_service, + dispatcher.clone(), + deps.executor.clone(), + accounts, + ))) + } else { + $handler.extend_with($namespace::to_delegate(SigningUnsafeClient::new( + accounts, + dispatcher.clone(), + ))) + } + }}; +} + /// RPC dependencies can be used to initialize RPC endpoints from APIs. pub trait Dependencies { type Notifier: ActivityNotifier; @@ -217,7 +237,7 @@ pub struct FullDependencies { pub snapshot: Arc, pub sync: Arc, pub net: Arc, - pub secret_store: Arc, + pub accounts: Arc, pub private_tx_service: Option>, pub miner: Arc, pub external_miner: Arc, @@ -247,31 +267,6 @@ impl FullDependencies { { use parity_rpc::v1::*; - macro_rules! add_signing_methods { - ($namespace:ident, $handler:expr, $deps:expr, $nonces:expr) => {{ - let deps = &$deps; - let dispatcher = FullDispatcher::new( - deps.client.clone(), - deps.miner.clone(), - $nonces, - deps.gas_price_percentile, - ); - if deps.signer_service.is_enabled() { - $handler.extend_with($namespace::to_delegate(SigningQueueClient::new( - &deps.signer_service, - dispatcher, - deps.executor.clone(), - &deps.secret_store, - ))) - } else { - $handler.extend_with($namespace::to_delegate(SigningUnsafeClient::new( - &deps.secret_store, - dispatcher, - ))) - } - }}; - } - let nonces = Arc::new(Mutex::new(dispatch::Reservations::new( self.executor.clone(), ))); @@ -281,6 +276,9 @@ impl FullDependencies { nonces.clone(), self.gas_price_percentile, ); + let account_signer = Arc::new(dispatch::Signer::new(self.accounts.clone())) as _; + let accounts = account_utils::accounts_list(self.accounts.clone()); + for api in apis { match *api { Api::Debug => { @@ -297,7 +295,7 @@ impl FullDependencies { &self.client, &self.snapshot, &self.sync, - &self.secret_store, + &accounts, &self.miner, &self.external_miner, EthClientOptions { @@ -319,7 +317,7 @@ impl FullDependencies { ); handler.extend_with(filter_client.to_delegate()); - add_signing_methods!(EthSigning, handler, self, nonces.clone()); + add_signing_methods!(EthSigning, handler, self, (&dispatcher, &account_signer)); } } Api::EthPubSub => { @@ -341,9 +339,10 @@ impl FullDependencies { } } Api::Personal => { + #[cfg(feature = "accounts")] handler.extend_with( PersonalClient::new( - &self.secret_store, + &self.accounts, dispatcher.clone(), self.geth_compatibility, self.experimental_rpcs, @@ -353,7 +352,7 @@ impl FullDependencies { Api::Signer => { handler.extend_with( SignerClient::new( - &self.secret_store, + account_signer.clone(), dispatcher.clone(), &self.signer_service, self.executor.clone(), @@ -372,7 +371,6 @@ impl FullDependencies { self.sync.clone(), self.updater.clone(), self.net_service.clone(), - self.secret_store.clone(), self.logger.clone(), self.settings.clone(), signer, @@ -380,9 +378,11 @@ impl FullDependencies { self.snapshot.clone().into(), ).to_delegate(), ); + #[cfg(feature = "accounts")] + handler.extend_with(ParityAccountsInfo::to_delegate(ParityAccountsClient::new(&self.accounts))); if !for_generic_pubsub { - add_signing_methods!(ParitySigning, handler, self, nonces.clone()); + add_signing_methods!(ParitySigning, handler, self, (&dispatcher, &account_signer)); } } Api::ParityPubSub => { @@ -398,25 +398,35 @@ impl FullDependencies { } } Api::ParityAccounts => { - handler - .extend_with(ParityAccountsClient::new(&self.secret_store).to_delegate()); + #[cfg(feature = "accounts")] + handler.extend_with(ParityAccounts::to_delegate(ParityAccountsClient::new(&self.accounts))); + } + Api::ParitySet => { + handler.extend_with( + ParitySetClient::new( + &self.client, + &self.miner, + &self.updater, + &self.net_service, + self.fetch.clone(), + ).to_delegate(), + ); + #[cfg(feature = "accounts")] + handler.extend_with( + ParitySetAccountsClient::new( + &self.accounts, + &self.miner, + ).to_delegate(), + ); } - Api::ParitySet => handler.extend_with( - ParitySetClient::new( - &self.client, - &self.miner, - &self.updater, - &self.net_service, - self.fetch.clone(), - ).to_delegate(), - ), Api::Traces => handler.extend_with(TracesClient::new(&self.client).to_delegate()), Api::Rpc => { let modules = to_modules(&apis); handler.extend_with(RpcClient::new(modules).to_delegate()); } Api::SecretStore => { - handler.extend_with(SecretStoreClient::new(&self.secret_store).to_delegate()); + #[cfg(feature = "accounts")] + handler.extend_with(SecretStoreClient::new(&self.accounts).to_delegate()); } Api::Whisper => { if let Some(ref whisper_rpc) = self.whisper_rpc { @@ -475,7 +485,7 @@ pub struct LightDependencies { pub client: Arc, pub sync: Arc, pub net: Arc, - pub secret_store: Arc, + pub accounts: Arc, pub logger: Arc, pub settings: Arc, pub on_demand: Arc<::light::on_demand::OnDemand>, @@ -512,27 +522,8 @@ impl LightDependencies { ))), self.gas_price_percentile, ); - - macro_rules! add_signing_methods { - ($namespace:ident, $handler:expr, $deps:expr) => {{ - let deps = &$deps; - let dispatcher = dispatcher.clone(); - let secret_store = deps.secret_store.clone(); - if deps.signer_service.is_enabled() { - $handler.extend_with($namespace::to_delegate(SigningQueueClient::new( - &deps.signer_service, - dispatcher, - deps.executor.clone(), - &secret_store, - ))) - } else { - $handler.extend_with($namespace::to_delegate(SigningUnsafeClient::new( - &secret_store, - dispatcher, - ))) - } - }}; - } + let account_signer = Arc::new(dispatch::Signer::new(self.accounts.clone())) as _; + let accounts = account_utils::accounts_list(self.accounts.clone()); for api in apis { match *api { @@ -551,7 +542,7 @@ impl LightDependencies { self.client.clone(), self.on_demand.clone(), self.transaction_queue.clone(), - self.secret_store.clone(), + accounts.clone(), self.cache.clone(), self.gas_price_percentile, self.poll_lifetime, @@ -560,7 +551,7 @@ impl LightDependencies { if !for_generic_pubsub { handler.extend_with(EthFilter::to_delegate(client)); - add_signing_methods!(EthSigning, handler, self); + add_signing_methods!(EthSigning, handler, self, (&dispatcher, &account_signer)); } } Api::EthPubSub => { @@ -584,9 +575,10 @@ impl LightDependencies { handler.extend_with(EthPubSub::to_delegate(client)); } Api::Personal => { + #[cfg(feature = "accounts")] handler.extend_with( PersonalClient::new( - &self.secret_store, + &self.accounts, dispatcher.clone(), self.geth_compatibility, self.experimental_rpcs, @@ -596,7 +588,7 @@ impl LightDependencies { Api::Signer => { handler.extend_with( SignerClient::new( - &self.secret_store, + account_signer.clone(), dispatcher.clone(), &self.signer_service, self.executor.clone(), @@ -611,7 +603,6 @@ impl LightDependencies { handler.extend_with( light::ParityClient::new( Arc::new(dispatcher.clone()), - self.secret_store.clone(), self.logger.clone(), self.settings.clone(), signer, @@ -619,9 +610,13 @@ impl LightDependencies { self.gas_price_percentile, ).to_delegate(), ); + #[cfg(feature = "accounts")] + handler.extend_with( + ParityAccountsInfo::to_delegate(ParityAccountsClient::new(&self.accounts)) + ); if !for_generic_pubsub { - add_signing_methods!(ParitySigning, handler, self); + add_signing_methods!(ParitySigning, handler, self, (&dispatcher, &account_signer)); } } Api::ParityPubSub => { @@ -637,8 +632,8 @@ impl LightDependencies { } } Api::ParityAccounts => { - handler - .extend_with(ParityAccountsClient::new(&self.secret_store).to_delegate()); + #[cfg(feature = "accounts")] + handler.extend_with(ParityAccounts::to_delegate(ParityAccountsClient::new(&self.accounts))); } Api::ParitySet => handler.extend_with( light::ParitySetClient::new(self.sync.clone(), self.fetch.clone()) @@ -650,7 +645,8 @@ impl LightDependencies { handler.extend_with(RpcClient::new(modules).to_delegate()); } Api::SecretStore => { - handler.extend_with(SecretStoreClient::new(&self.secret_store).to_delegate()); + #[cfg(feature = "accounts")] + handler.extend_with(SecretStoreClient::new(&self.accounts).to_delegate()); } Api::Whisper => { if let Some(ref whisper_rpc) = self.whisper_rpc { diff --git a/parity/run.rs b/parity/run.rs index df14372324..13e93c1e21 100644 --- a/parity/run.rs +++ b/parity/run.rs @@ -22,28 +22,27 @@ use std::thread; use ansi_term::Colour; use bytes::Bytes; use call_contract::CallContract; -use ethcore::account_provider::{AccountProvider, AccountProviderSettings}; use ethcore::client::{BlockId, Client, Mode, DatabaseCompactionProfile, VMType, BlockChainClient, BlockInfo}; -use ethstore::ethkey; -use ethcore::miner::{stratum, Miner, MinerService, MinerOptions}; +use ethcore::miner::{self, stratum, Miner, MinerService, MinerOptions}; use ethcore::snapshot::{self, SnapshotConfiguration}; use ethcore::spec::{SpecParams, OptimizeFor}; use ethcore::verification::queue::VerifierSettings; use ethcore_logger::{Config as LogConfig, RotatingLogger}; use ethcore_service::ClientService; use ethereum_types::Address; -use sync::{self, SyncConfig, PrivateTxHandler}; -use miner::work_notify::WorkPoster; use futures::IntoFuture; use hash_fetch::{self, fetch}; use informant::{Informant, LightNodeInformantData, FullNodeInformantData}; use journaldb::Algorithm; use light::Cache as LightDataCache; use miner::external::ExternalMiner; +use miner::work_notify::WorkPoster; use node_filter::NodeFilter; use parity_runtime::Runtime; -use parity_rpc::{Origin, Metadata, NetworkSettings, informant, is_major_importing, PubSubSession, FutureResult, - FutureResponse, FutureOutput}; +use sync::{self, SyncConfig, PrivateTxHandler}; +use parity_rpc::{ + Origin, Metadata, NetworkSettings, informant, is_major_importing, PubSubSession, FutureResult, FutureResponse, FutureOutput +}; use updater::{UpdatePolicy, Updater}; use parity_version::version; use ethcore_private_tx::{ProviderConfig, EncryptorConfig, SecretStoreEncryptor}; @@ -51,8 +50,8 @@ use params::{ SpecType, Pruning, AccountsConfig, GasPricerConfig, MinerExtras, Switch, tracing_switch_to_bool, fatdb_switch_to_bool, mode_switch_to_bool }; +use account_utils; use helpers::{to_client_config, execute_upgrades, passwords_from_files}; -use upgrade::upgrade_key_location; use dir::{Directories, DatabaseDirectories}; use cache::CacheConfig; use user_defaults::UserDefaults; @@ -65,7 +64,6 @@ use rpc_apis; use secretstore; use signer; use db; -use ethkey::Password; // how often to take periodic snapshots. const SNAPSHOT_PERIOD: u64 = 5000; @@ -77,9 +75,6 @@ const SNAPSHOT_HISTORY: u64 = 100; // Light client only. const GAS_CORPUS_EXPIRATION_MINUTES: u64 = 60 * 6; -// Pops along with error messages when a password is missing or invalid. -const VERIFY_PASSWORD_HINT: &str = "Make sure valid password is present in files passed using `--password` or in the configuration file."; - // Full client number of DNS threads const FETCH_FULL_NUM_DNS_THREADS: usize = 4; @@ -317,7 +312,7 @@ fn execute_light_impl(cmd: RunCmd, logger: Arc) -> Result) -> Result(cmd: RunCmd, logger: Arc, on_client_rq: let passwords = passwords_from_files(&cmd.acc_conf.password_files)?; // prepare account provider - let account_provider = Arc::new(prepare_account_provider(&cmd.spec, &cmd.dirs, &spec.data_dir, cmd.acc_conf, &passwords)?); + let account_provider = Arc::new(account_utils::prepare_account_provider(&cmd.spec, &cmd.dirs, &spec.data_dir, cmd.acc_conf, &passwords)?); // spin up event loop let runtime = Runtime::with_default_thread_count(); @@ -503,9 +498,12 @@ fn execute_impl(cmd: RunCmd, logger: Arc, on_client_rq: cmd.miner_options, cmd.gas_pricer_conf.to_gas_pricer(fetch.clone(), runtime.executor()), &spec, - Some(account_provider.clone()), + ( + cmd.miner_extras.local_accounts, + account_utils::miner_local_accounts(account_provider.clone()), + ) )); - miner.set_author(cmd.miner_extras.author, None).expect("Fails only if password is Some; password is None; qed"); + miner.set_author(miner::Author::External(cmd.miner_extras.author)); miner.set_gas_range_target(cmd.miner_extras.gas_range_target); miner.set_extra_data(cmd.miner_extras.extra_data); @@ -517,19 +515,8 @@ fn execute_impl(cmd: RunCmd, logger: Arc, on_client_rq: let engine_signer = cmd.miner_extras.engine_signer; if engine_signer != Default::default() { - // Check if engine signer exists - if !account_provider.has_account(engine_signer) { - return Err(format!("Consensus signer account not found for the current chain. {}", build_create_account_hint(&cmd.spec, &cmd.dirs.keys))); - } - - // Check if any passwords have been read from the password file(s) - if passwords.is_empty() { - return Err(format!("No password found for the consensus signer {}. {}", engine_signer, VERIFY_PASSWORD_HINT)); - } - - // Attempt to sign in the engine signer. - if !passwords.iter().any(|p| miner.set_author(engine_signer, Some(p.to_owned())).is_ok()) { - return Err(format!("No valid password for the consensus signer {}. {}", engine_signer, VERIFY_PASSWORD_HINT)); + if let Some(author) = account_utils::miner_author(&cmd.spec, &cmd.dirs, &account_provider, engine_signer, &passwords)? { + miner.set_author(author); } } @@ -572,6 +559,8 @@ fn execute_impl(cmd: RunCmd, logger: Arc, on_client_rq: let client_db = restoration_db_handler.open(&client_path) .map_err(|e| format!("Failed to open database {:?}", e))?; + let private_tx_signer = account_utils::private_tx_signer(account_provider.clone(), &passwords)?; + // create client service. let service = ClientService::start( client_config, @@ -581,8 +570,8 @@ fn execute_impl(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.clone(), fetch.clone()).map_err(|e| e.to_string())?), + private_tx_signer.clone(), + Box::new(SecretStoreEncryptor::new(cmd.private_encryptor_conf.clone(), fetch.clone(), private_tx_signer).map_err(|e| e.to_string())?), cmd.private_provider_conf, cmd.private_encryptor_conf, ).map_err(|e| format!("Client service error: {:?}", e))?; @@ -743,7 +732,7 @@ fn execute_impl(cmd: RunCmd, logger: Arc, on_client_rq: client: client.clone(), sync: sync_provider.clone(), net: manage_network.clone(), - secret_store: secret_store, + accounts: secret_store, miner: miner.clone(), external_miner: external_miner.clone(), logger: logger.clone(), @@ -779,7 +768,7 @@ fn execute_impl(cmd: RunCmd, logger: Arc, on_client_rq: client: client.clone(), sync: sync_provider.clone(), miner: miner.clone(), - account_provider: account_provider, + account_provider, accounts_passwords: &passwords, }; let secretstore_key_server = secretstore::start(cmd.secretstore_conf.clone(), secretstore_deps, runtime.executor())?; @@ -953,80 +942,6 @@ fn print_running_environment(data_dir: &str, dirs: &Directories, db_dirs: &Datab info!("DB path {}", Colour::White.bold().paint(db_dirs.db_root_path().to_string_lossy().into_owned())); } -fn prepare_account_provider(spec: &SpecType, dirs: &Directories, data_dir: &str, cfg: AccountsConfig, passwords: &[Password]) -> Result { - use ethstore::EthStore; - use ethstore::accounts_dir::RootDiskDirectory; - - let path = dirs.keys_path(data_dir); - upgrade_key_location(&dirs.legacy_keys_path(cfg.testnet), &path); - let dir = Box::new(RootDiskDirectory::create(&path).map_err(|e| format!("Could not open keys directory: {}", e))?); - let account_settings = AccountProviderSettings { - enable_hardware_wallets: cfg.enable_hardware_wallets, - hardware_wallet_classic_key: spec == &SpecType::Classic, - unlock_keep_secret: cfg.enable_fast_unlock, - blacklisted_accounts: match *spec { - SpecType::Morden | SpecType::Ropsten | SpecType::Kovan | SpecType::Sokol | SpecType::Dev => vec![], - _ => vec![ - "00a329c0648769a73afac7f9381e08fb43dbea72".into() - ], - }, - }; - - let ethstore = EthStore::open_with_iterations(dir, cfg.iterations).map_err(|e| format!("Could not open keys directory: {}", e))?; - if cfg.refresh_time > 0 { - ethstore.set_refresh_time(::std::time::Duration::from_secs(cfg.refresh_time)); - } - let account_provider = AccountProvider::new( - Box::new(ethstore), - account_settings, - ); - - // Add development account if running dev chain: - if let SpecType::Dev = *spec { - insert_dev_account(&account_provider); - } - - for a in cfg.unlocked_accounts { - // Check if the account exists - if !account_provider.has_account(a) { - return Err(format!("Account {} not found for the current chain. {}", a, build_create_account_hint(spec, &dirs.keys))); - } - - // Check if any passwords have been read from the password file(s) - if passwords.is_empty() { - return Err(format!("No password found to unlock account {}. {}", a, VERIFY_PASSWORD_HINT)); - } - - if !passwords.iter().any(|p| account_provider.unlock_account_permanently(a, (*p).clone()).is_ok()) { - return Err(format!("No valid password to unlock account {}. {}", a, VERIFY_PASSWORD_HINT)); - } - } - - Ok(account_provider) -} - -fn insert_dev_account(account_provider: &AccountProvider) { - let secret: ethkey::Secret = "4d5db4107d237df6a3d58ee5f70ae63d73d7658d4026f2eefd2f204c81682cb7".into(); - let dev_account = ethkey::KeyPair::from_secret(secret.clone()).expect("Valid secret produces valid key;qed"); - if !account_provider.has_account(dev_account.address()) { - match account_provider.insert_account(secret, &Password::from(String::new())) { - Err(e) => warn!("Unable to add development account: {}", e), - Ok(address) => { - let _ = account_provider.set_account_name(address.clone(), "Development Account".into()); - let _ = account_provider.set_account_meta(address, ::serde_json::to_string(&(vec![ - ("description", "Never use this account outside of development chain!"), - ("passwordHint","Password is empty string"), - ].into_iter().collect::<::std::collections::HashMap<_,_>>())).expect("Serialization of hashmap does not fail.")); - }, - } - } -} - -// Construct an error `String` with an adaptive hint on how to create an account. -fn build_create_account_hint(spec: &SpecType, keys: &str) -> String { - format!("You can create an account via RPC, UI or `parity account new --chain {} --keys-path {}`.", spec, keys) -} - fn wait_for_drop(w: Weak) { let sleep_duration = Duration::from_secs(1); let warn_timeout = Duration::from_secs(60); @@ -1050,3 +965,4 @@ fn wait_for_drop(w: Weak) { warn!("Shutdown timeout reached, exiting uncleanly."); } + diff --git a/parity/secretstore.rs b/parity/secretstore.rs index c61d4b76cb..d9075edec8 100644 --- a/parity/secretstore.rs +++ b/parity/secretstore.rs @@ -16,12 +16,12 @@ use std::collections::BTreeMap; use std::sync::Arc; +use account_utils::AccountProvider; 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 ethkey::{Secret, Public, Password}; use sync::SyncProvider; use ethereum_types::Address; use parity_runtime::Executor; @@ -32,6 +32,7 @@ pub enum NodeSecretKey { /// Stored as plain text in configuration file. Plain(Secret), /// Stored as account in key store. + #[cfg(feature = "accounts")] KeyStore(Address), } @@ -141,6 +142,7 @@ mod server { let self_secret: Arc = match conf.self_secret.take() { Some(NodeSecretKey::Plain(secret)) => Arc::new(ethcore_secretstore::PlainNodeKeyPair::new( KeyPair::from_secret(secret).map_err(|e| format!("invalid secret: {}", e))?)), + #[cfg(feature = "accounts")] Some(NodeSecretKey::KeyStore(account)) => { // Check if account exists if !deps.account_provider.has_account(account.clone()) { @@ -209,7 +211,6 @@ mod server { } pub use self::server::KeyServer; -use ethkey::Password; impl Default for Configuration { fn default() -> Self { diff --git a/parity/snapshot.rs b/parity/snapshot.rs index e0b8097a25..70957762f5 100644 --- a/parity/snapshot.rs +++ b/parity/snapshot.rs @@ -21,7 +21,6 @@ use std::path::{Path, PathBuf}; use std::sync::Arc; use hash::keccak; -use ethcore::account_provider::AccountProvider; use ethcore::snapshot::{Progress, RestorationStatus, SnapshotConfiguration, SnapshotService as SS}; use ethcore::snapshot::io::{SnapshotReader, PackedReader, PackedWriter}; use ethcore::snapshot::service::Service as SnapshotService; @@ -199,7 +198,7 @@ impl SnapshotCommand { // TODO [ToDr] don't use test miner here // (actually don't require miner at all) Arc::new(Miner::new_for_tests(&spec, None)), - Arc::new(AccountProvider::transient_provider()), + Arc::new(ethcore_private_tx::DummySigner), Box::new(ethcore_private_tx::NoopEncryptor), Default::default(), Default::default(), diff --git a/rpc/Cargo.toml b/rpc/Cargo.toml index a766b25f88..b90d33e7f5 100644 --- a/rpc/Cargo.toml +++ b/rpc/Cargo.toml @@ -37,9 +37,7 @@ jsonrpc-pubsub = "10.0.1" common-types = { path = "../ethcore/types" } ethash = { path = "../ethash" } ethcore = { path = "../ethcore", features = ["test-helpers"] } -fastmap = { path = "../util/fastmap" } -parity-bytes = "0.1" -parity-crypto = "0.3.0" +ethcore-accounts = { path = "../accounts", optional = true } ethcore-io = { path = "../util/io" } ethcore-light = { path = "../ethcore/light" } ethcore-logger = { path = "../parity/logger" } @@ -47,7 +45,11 @@ ethcore-miner = { path = "../miner" } ethcore-private-tx = { path = "../ethcore/private-tx" } ethcore-sync = { path = "../ethcore/sync" } ethereum-types = "0.4" +fastmap = { path = "../util/fastmap" } +parity-bytes = "0.1" +parity-crypto = "0.3.0" +eip-712 = { path = "../util/EIP-712" } ethjson = { path = "../json" } ethkey = { path = "../accounts/ethkey" } ethstore = { path = "../accounts/ethstore" } @@ -58,21 +60,18 @@ parity-updater = { path = "../updater" } parity-version = { path = "../util/version" } patricia-trie = "0.3.0" rlp = { version = "0.3.0", features = ["ethereum"] } -eip-712 = { path = "../util/EIP-712" } stats = { path = "../util/stats" } vm = { path = "../ethcore/vm" } -[target.'cfg(any(target_os = "linux", target_os = "macos", target_os = "windows"))'.dependencies] -hardware-wallet = { path = "../accounts/hw" } - -[target.'cfg(not(any(target_os = "linux", target_os = "macos", target_os = "windows")))'.dependencies] -fake-hardware-wallet = { path = "../accounts/fake-hardware-wallet" } - [dev-dependencies] ethcore = { path = "../ethcore", features = ["test-helpers"] } +ethcore-accounts = { path = "../accounts" } ethcore-network = { path = "../util/network" } fake-fetch = { path = "../util/fake-fetch" } kvdb-memorydb = "0.1" macros = { path = "../util/macros" } pretty_assertions = "0.1" transaction-pool = "1.13" + +[features] +accounts = ["ethcore-accounts"] diff --git a/rpc/src/lib.rs b/rpc/src/lib.rs index 3a98564512..f8e16ae6bb 100644 --- a/rpc/src/lib.rs +++ b/rpc/src/lib.rs @@ -68,10 +68,8 @@ extern crate rlp; extern crate stats; extern crate vm; -#[cfg(any(target_os = "linux", target_os = "macos", target_os = "windows"))] -extern crate hardware_wallet; -#[cfg(not(any(target_os = "linux", target_os = "macos", target_os = "windows")))] -extern crate fake_hardware_wallet as hardware_wallet; +#[cfg(any(test, feature = "ethcore-accounts"))] +extern crate ethcore_accounts as accounts; #[macro_use] extern crate log; diff --git a/rpc/src/v1/helpers/deprecated.rs b/rpc/src/v1/helpers/deprecated.rs new file mode 100644 index 0000000000..eb754c01ac --- /dev/null +++ b/rpc/src/v1/helpers/deprecated.rs @@ -0,0 +1,111 @@ +// 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 . + +//! Deprecation notice for RPC methods. +//! +//! Displays a warning but avoids spamming the log. + +use std::{ + collections::HashMap, + time::{Duration, Instant}, +}; + +use parking_lot::RwLock; + +/// Deprecation messages +pub mod msgs { + pub const ACCOUNTS: Option<&str> = Some("Account management is being phased out see #9997 for alternatives."); +} + +type MethodName = &'static str; + +const PRINT_INTERVAL: Duration = Duration::from_secs(60); + +/// Displays a deprecation notice without spamming the log. +pub struct DeprecationNotice Instant> { + now: T, + next_warning_at: RwLock>, + printer: Box) + Send + Sync>, +} + +impl Default for DeprecationNotice { + fn default() -> Self { + Self::new(Instant::now, |method, more| { + let more = more.map(|x| format!(": {}", x)).unwrap_or_else(|| ".".into()); + warn!(target: "rpc", "{} is deprecated and will be removed in future versions{}", method, more); + }) + } +} + +impl Instant> DeprecationNotice { + /// Create new deprecation notice printer with custom display and interval. + pub fn new(now: N, printer: T) -> Self where + T: Fn(MethodName, Option<&str>) + Send + Sync + 'static, + { + DeprecationNotice { + now, + next_warning_at: Default::default(), + printer: Box::new(printer), + } + } + + /// Print deprecation notice for given method and with some additional details (explanations). + pub fn print<'a, T: Into>>(&self, method: MethodName, details: T) { + let now = (self.now)(); + match self.next_warning_at.read().get(method) { + Some(next) if next > &now => return, + _ => {}, + } + + self.next_warning_at.write().insert(method.to_owned(), now + PRINT_INTERVAL); + (self.printer)(method, details.into()); + } +} + +#[cfg(test)] +mod tests { + use super::*; + + use std::sync::Arc; + + #[test] + fn should_throttle_printing() { + let saved = Arc::new(RwLock::new(None)); + let s = saved.clone(); + let printer = move |method: MethodName, more: Option<&str>| { + *s.write() = Some((method, more.map(|s| s.to_owned()))); + }; + + let now = Arc::new(RwLock::new(Instant::now())); + let n = now.clone(); + let get_now = || n.read().clone(); + let notice = DeprecationNotice::new(get_now, printer); + + let details = Some("See issue #123456"); + notice.print("eth_test", details.clone()); + // printer shouldn't be called + notice.print("eth_test", None); + assert_eq!(saved.read().clone().unwrap(), ("eth_test", details.as_ref().map(|x| x.to_string()))); + // but calling a different method is fine + notice.print("eth_test2", None); + assert_eq!(saved.read().clone().unwrap(), ("eth_test2", None)); + + // wait and call again + *now.write() = Instant::now() + PRINT_INTERVAL; + notice.print("eth_test", None); + assert_eq!(saved.read().clone().unwrap(), ("eth_test", None)); + } +} diff --git a/rpc/src/v1/helpers/dispatch.rs b/rpc/src/v1/helpers/dispatch.rs deleted file mode 100644 index c26fde45f1..0000000000 --- a/rpc/src/v1/helpers/dispatch.rs +++ /dev/null @@ -1,879 +0,0 @@ -// Copyright 2015-2019 Parity Technologies (UK) Ltd. -// This file is part of Parity Ethereum. - -// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . - -//! Utilities and helpers for transaction dispatch. - -use std::fmt::Debug; -use std::ops::Deref; -use std::sync::Arc; - -use light::cache::Cache as LightDataCache; -use light::client::LightChainClient; -use light::on_demand::{request, OnDemand}; -use light::TransactionQueue as LightTransactionQueue; -use hash::keccak; -use ethereum_types::{H256, H520, Address, U256}; -use bytes::Bytes; -use parking_lot::{Mutex, RwLock}; -use stats::Corpus; - -use crypto::DEFAULT_MAC; -use ethcore::account_provider::AccountProvider; -use ethcore::client::BlockChainClient; -use ethcore::miner::{self, MinerService}; -use ethkey::{Password, Signature}; -use sync::LightSync; -use types::transaction::{Action, SignedTransaction, PendingTransaction, Transaction, Error as TransactionError}; -use types::basic_account::BasicAccount; -use types::ids::BlockId; - -use jsonrpc_core::{BoxFuture, Result, Error}; -use jsonrpc_core::futures::{future, Future, Poll, Async, IntoFuture}; -use jsonrpc_core::futures::future::Either; -use v1::helpers::{errors, nonce, TransactionRequest, FilledTransactionRequest, ConfirmationPayload}; -use v1::types::{ - H520 as RpcH520, Bytes as RpcBytes, - RichRawTransaction as RpcRichRawTransaction, - ConfirmationPayload as RpcConfirmationPayload, - ConfirmationResponse, - EthSignRequest as RpcEthSignRequest, - EIP191SignRequest as RpcSignRequest, - DecryptRequest as RpcDecryptRequest, -}; -use rlp; - -pub use self::nonce::Reservations; - -/// Has the capability to dispatch, sign, and decrypt. -/// -/// Requires a clone implementation, with the implication that it be cheap; -/// usually just bumping a reference count or two. -pub trait Dispatcher: Send + Sync + Clone { - // TODO: when ATC exist, use zero-cost - // type Out: IntoFuture - - /// Fill optional fields of a transaction request, fetching gas price but not nonce. - fn fill_optional_fields(&self, request: TransactionRequest, default_sender: Address, force_nonce: bool) - -> BoxFuture; - - /// Sign the given transaction request, fetching appropriate nonce and executing the PostSign action - fn sign

( - &self, - accounts: Arc, - filled: FilledTransactionRequest, - password: SignWith, - post_sign: P - ) -> BoxFuture - where - P: PostSign + 'static, - ::Future: Send; - - /// Converts a `SignedTransaction` into `RichRawTransaction` - fn enrich(&self, signed: SignedTransaction) -> RpcRichRawTransaction; - - /// "Dispatch" a local transaction. - fn dispatch_transaction(&self, signed_transaction: PendingTransaction) - -> Result; -} - -/// A dispatcher which uses references to a client and miner in order to sign -/// requests locally. -#[derive(Debug)] -pub struct FullDispatcher { - client: Arc, - miner: Arc, - nonces: Arc>, - gas_price_percentile: usize, -} - -impl FullDispatcher { - /// Create a `FullDispatcher` from Arc references to a client and miner. - pub fn new( - client: Arc, - miner: Arc, - nonces: Arc>, - gas_price_percentile: usize, - ) -> Self { - FullDispatcher { - client, - miner, - nonces, - gas_price_percentile, - } - } -} - -impl Clone for FullDispatcher { - fn clone(&self) -> Self { - FullDispatcher { - client: self.client.clone(), - miner: self.miner.clone(), - nonces: self.nonces.clone(), - gas_price_percentile: self.gas_price_percentile, - } - } -} - -impl FullDispatcher { - fn state_nonce(&self, from: &Address) -> U256 { - self.miner.next_nonce(&*self.client, from) - } - - /// Imports transaction to the miner's queue. - pub fn dispatch_transaction(client: &C, miner: &M, signed_transaction: PendingTransaction, trusted: bool) -> Result { - let hash = signed_transaction.transaction.hash(); - - // use `import_claimed_local_transaction` so we can decide (based on config flags) if we want to treat - // it as local or not. Nodes with public RPC interfaces will want these transactions to be treated like - // external transactions. - miner.import_claimed_local_transaction(client, signed_transaction, trusted) - .map_err(errors::transaction) - .map(|_| hash) - } -} - -impl Dispatcher for FullDispatcher { - fn fill_optional_fields(&self, request: TransactionRequest, default_sender: Address, force_nonce: bool) - -> BoxFuture - { - let request = request; - let from = request.from.unwrap_or(default_sender); - let nonce = if force_nonce { - request.nonce.or_else(|| Some(self.state_nonce(&from))) - } else { - request.nonce - }; - - Box::new(future::ok(FilledTransactionRequest { - from, - used_default_from: request.from.is_none(), - to: request.to, - nonce, - gas_price: request.gas_price.unwrap_or_else(|| { - default_gas_price(&*self.client, &*self.miner, self.gas_price_percentile) - }), - gas: request.gas.unwrap_or_else(|| self.miner.sensible_gas_limit()), - value: request.value.unwrap_or_else(|| 0.into()), - data: request.data.unwrap_or_else(Vec::new), - condition: request.condition, - })) - } - - fn sign

( - &self, - accounts: Arc, - filled: FilledTransactionRequest, - password: SignWith, - post_sign: P - ) -> BoxFuture - where - P: PostSign + 'static, - ::Future: Send - { - let chain_id = self.client.signing_chain_id(); - - if let Some(nonce) = filled.nonce { - let future = sign_transaction(&*accounts, filled, chain_id, nonce, password) - .into_future() - .and_then(move |signed| post_sign.execute(signed)); - Box::new(future) - } else { - let state = self.state_nonce(&filled.from); - let reserved = self.nonces.lock().reserve(filled.from, state); - - Box::new(ProspectiveSigner::new(accounts, filled, chain_id, reserved, password, post_sign)) - } - } - - fn enrich(&self, signed_transaction: SignedTransaction) -> RpcRichRawTransaction { - RpcRichRawTransaction::from_signed(signed_transaction) - } - - fn dispatch_transaction(&self, signed_transaction: PendingTransaction) -> Result { - Self::dispatch_transaction(&*self.client, &*self.miner, signed_transaction, true) - } -} - -/// Get a recent gas price corpus. -// TODO: this could be `impl Trait`. -pub fn fetch_gas_price_corpus( - sync: Arc, - client: Arc, - on_demand: Arc, - cache: Arc>, -) -> BoxFuture> { - const GAS_PRICE_SAMPLE_SIZE: usize = 100; - - if let Some(cached) = { cache.lock().gas_price_corpus() } { - return Box::new(future::ok(cached)) - } - - let cache = cache.clone(); - let eventual_corpus = sync.with_context(|ctx| { - // get some recent headers with gas used, - // and request each of the blocks from the network. - let block_requests = client.ancestry_iter(BlockId::Latest) - .filter(|hdr| hdr.gas_used() != U256::default()) - .take(GAS_PRICE_SAMPLE_SIZE) - .map(|hdr| request::Body(hdr.into())) - .collect::>(); - - // when the blocks come in, collect gas prices into a vector - on_demand.request(ctx, block_requests) - .expect("no back-references; therefore all back-references are valid; qed") - .map(|bodies| { - bodies.into_iter().fold(Vec::new(), |mut v, block| { - for t in block.transaction_views().iter() { - v.push(t.gas_price()) - } - v - }) - }) - .map(move |prices| { - // produce a corpus from the vector and cache it. - // It's later used to get a percentile for default gas price. - let corpus: ::stats::Corpus<_> = prices.into(); - cache.lock().set_gas_price_corpus(corpus.clone()); - corpus - }) - }); - - match eventual_corpus { - Some(corp) => Box::new(corp.map_err(|_| errors::no_light_peers())), - None => Box::new(future::err(errors::network_disabled())), - } -} - -/// Returns a eth_sign-compatible hash of data to sign. -/// The data is prepended with special message to prevent -/// malicious DApps from using the function to sign forged transactions. -pub fn eth_data_hash(mut data: Bytes) -> H256 { - let mut message_data = - format!("\x19Ethereum Signed Message:\n{}", data.len()) - .into_bytes(); - message_data.append(&mut data); - keccak(message_data) -} - -/// Dispatcher for light clients -- fetches default gas price, next nonce, etc. from network. -#[derive(Clone)] -pub struct LightDispatcher { - /// Sync service. - pub sync: Arc, - /// Header chain client. - pub client: Arc, - /// On-demand request service. - pub on_demand: Arc, - /// Data cache. - pub cache: Arc>, - /// Transaction queue. - pub transaction_queue: Arc>, - /// Nonce reservations - pub nonces: Arc>, - /// Gas Price percentile value used as default gas price. - pub gas_price_percentile: usize, -} - -impl LightDispatcher { - /// Create a new `LightDispatcher` from its requisite parts. - /// - /// For correct operation, the OnDemand service is assumed to be registered as a network handler, - pub fn new( - sync: Arc, - client: Arc, - on_demand: Arc, - cache: Arc>, - transaction_queue: Arc>, - nonces: Arc>, - gas_price_percentile: usize, - ) -> Self { - LightDispatcher { - sync, - client, - on_demand, - cache, - transaction_queue, - nonces, - gas_price_percentile, - } - } - - /// Get a recent gas price corpus. - // TODO: this could be `impl Trait`. - pub fn gas_price_corpus(&self) -> BoxFuture> { - fetch_gas_price_corpus( - self.sync.clone(), - self.client.clone(), - self.on_demand.clone(), - self.cache.clone(), - ) - } - - /// Get an account's state - fn account(&self, addr: Address) -> BoxFuture> { - let best_header = self.client.best_block_header(); - let account_future = self.sync.with_context(|ctx| self.on_demand.request(ctx, request::Account { - header: best_header.into(), - address: addr, - }).expect("no back-references; therefore all back-references valid; qed")); - - match account_future { - Some(response) => Box::new(response.map_err(|_| errors::no_light_peers())), - None => Box::new(future::err(errors::network_disabled())), - } - } - - /// Get an account's next nonce. - pub fn next_nonce(&self, addr: Address) -> BoxFuture { - let account_start_nonce = self.client.engine().account_start_nonce(self.client.best_block_header().number()); - Box::new(self.account(addr) - .and_then(move |maybe_account| { - future::ok(maybe_account.map_or(account_start_nonce, |account| account.nonce)) - }) - ) - } -} - -impl Dispatcher for LightDispatcher { - // Ignore the `force_nonce` flag in order to always query the network when fetching the nonce and - // the account state. If the nonce is specified in the transaction use that nonce instead but do the - // network request anyway to the account state (balance) - fn fill_optional_fields(&self, request: TransactionRequest, default_sender: Address, _force_nonce: bool) - -> BoxFuture - { - const DEFAULT_GAS_PRICE: U256 = U256([0, 0, 0, 21_000_000]); - - let gas_limit = self.client.best_block_header().gas_limit(); - let request_gas_price = request.gas_price.clone(); - let from = request.from.unwrap_or(default_sender); - - let with_gas_price = move |gas_price| { - let request = request; - FilledTransactionRequest { - from: from.clone(), - used_default_from: request.from.is_none(), - to: request.to, - nonce: request.nonce, - gas_price: gas_price, - gas: request.gas.unwrap_or_else(|| gas_limit / 3), - value: request.value.unwrap_or_else(|| 0.into()), - data: request.data.unwrap_or_else(Vec::new), - condition: request.condition, - } - }; - - // fast path for known gas price. - let gas_price_percentile = self.gas_price_percentile; - let gas_price = match request_gas_price { - Some(gas_price) => Either::A(future::ok(with_gas_price(gas_price))), - None => Either::B(fetch_gas_price_corpus( - self.sync.clone(), - self.client.clone(), - self.on_demand.clone(), - self.cache.clone() - ).and_then(move |corp| match corp.percentile(gas_price_percentile) { - Some(percentile) => Ok(*percentile), - None => Ok(DEFAULT_GAS_PRICE), // fall back to default on error. - }).map(with_gas_price)) - }; - - let future_account = self.account(from); - - Box::new(gas_price.and_then(move |mut filled| { - future_account - .and_then(move |maybe_account| { - let cost = filled.value.saturating_add(filled.gas.saturating_mul(filled.gas_price)); - match maybe_account { - Some(ref account) if cost > account.balance => { - Err(errors::transaction(TransactionError::InsufficientBalance { - balance: account.balance, - cost, - })) - } - Some(account) => { - if filled.nonce.is_none() { - filled.nonce = Some(account.nonce); - } - Ok(filled) - } - None => Err(errors::account("Account not found", "")), - } - }) - })) - } - - fn sign

( - &self, - accounts: Arc, - filled: FilledTransactionRequest, - password: SignWith, - post_sign: P - ) -> BoxFuture - where - P: PostSign + 'static, - ::Future: Send - { - let chain_id = self.client.signing_chain_id(); - let nonce = filled.nonce.expect("nonce is always provided; qed"); - - let future = sign_transaction(&*accounts, filled, chain_id, nonce, password) - .into_future() - .and_then(move |signed| post_sign.execute(signed)); - Box::new(future) - } - - fn enrich(&self, signed_transaction: SignedTransaction) -> RpcRichRawTransaction { - RpcRichRawTransaction::from_signed(signed_transaction) - } - - fn dispatch_transaction(&self, signed_transaction: PendingTransaction) -> Result { - let hash = signed_transaction.transaction.hash(); - - self.transaction_queue.write().import(signed_transaction) - .map_err(errors::transaction) - .map(|_| hash) - } -} - -fn sign_transaction( - accounts: &AccountProvider, - filled: FilledTransactionRequest, - chain_id: Option, - nonce: U256, - password: SignWith, -) -> Result> { - let t = Transaction { - nonce: nonce, - action: filled.to.map_or(Action::Create, Action::Call), - gas: filled.gas, - gas_price: filled.gas_price, - value: filled.value, - data: filled.data, - }; - - if accounts.is_hardware_address(&filled.from) { - return hardware_signature(accounts, filled.from, t, chain_id).map(WithToken::No) - } - - let hash = t.hash(chain_id); - let signature = signature(accounts, filled.from, hash, password)?; - - Ok(signature.map(|sig| { - SignedTransaction::new(t.with_signature(sig, chain_id)) - .expect("Transaction was signed by AccountsProvider; it never produces invalid signatures; qed") - })) -} - -#[derive(Debug, Clone, Copy)] -enum ProspectiveSignerState { - TryProspectiveSign, - WaitForPostSign, - WaitForNonce, -} - -struct ProspectiveSigner { - accounts: Arc, - filled: FilledTransactionRequest, - chain_id: Option, - reserved: nonce::Reserved, - password: SignWith, - state: ProspectiveSignerState, - prospective: Option>, - ready: Option, - post_sign: Option

, - post_sign_future: Option<::Future> -} - -/// action to execute after signing -/// e.g importing a transaction into the chain -pub trait PostSign: Send { - /// item that this PostSign returns - type Item: Send; - /// incase you need to perform async PostSign actions - type Out: IntoFuture + Send; - /// perform an action with the signed transaction - fn execute(self, signer: WithToken) -> Self::Out; -} - -impl PostSign for () { - type Item = WithToken; - type Out = Result; - fn execute(self, signed: WithToken) -> Self::Out { - Ok(signed) - } -} - -impl PostSign for F - where F: FnOnce(WithToken) -> Result -{ - type Item = T; - type Out = Result; - fn execute(self, signed: WithToken) -> Self::Out { - (self)(signed) - } -} - -impl ProspectiveSigner

{ - pub fn new( - accounts: Arc, - filled: FilledTransactionRequest, - chain_id: Option, - reserved: nonce::Reserved, - password: SignWith, - post_sign: P - ) -> Self { - // If the account is permanently unlocked we can try to sign - // using prospective nonce. This should speed up sending - // multiple subsequent transactions in multi-threaded RPC environment. - let is_unlocked_permanently = accounts.is_unlocked_permanently(&filled.from); - let has_password = password.is_password(); - - ProspectiveSigner { - accounts, - filled, - chain_id, - reserved, - password, - state: if is_unlocked_permanently || has_password { - ProspectiveSignerState::TryProspectiveSign - } else { - ProspectiveSignerState::WaitForNonce - }, - prospective: None, - ready: None, - post_sign: Some(post_sign), - post_sign_future: None - } - } - - fn sign(&self, nonce: &U256) -> Result> { - sign_transaction( - &*self.accounts, - self.filled.clone(), - self.chain_id, - *nonce, - self.password.clone() - ) - } - - fn poll_reserved(&mut self) -> Poll { - self.reserved.poll().map_err(|_| errors::internal("Nonce reservation failure", "")) - } -} - -impl Future for ProspectiveSigner

{ - type Item = P::Item; - type Error = Error; - - fn poll(&mut self) -> Poll { - use self::ProspectiveSignerState::*; - - loop { - match self.state { - TryProspectiveSign => { - // Try to poll reserved, it might be ready. - match self.poll_reserved()? { - Async::NotReady => { - self.state = WaitForNonce; - self.prospective = Some(self.sign(self.reserved.prospective_value())?); - }, - Async::Ready(nonce) => { - self.state = WaitForPostSign; - self.post_sign_future = Some(self.post_sign.take() - .expect("post_sign is set on creation; qed") - .execute(self.sign(nonce.value())?) - .into_future()); - self.ready = Some(nonce); - }, - } - }, - WaitForNonce => { - let nonce = try_ready!(self.poll_reserved()); - let prospective = match (self.prospective.take(), nonce.matches_prospective()) { - (Some(prospective), true) => prospective, - _ => self.sign(nonce.value())?, - }; - self.ready = Some(nonce); - self.state = WaitForPostSign; - self.post_sign_future = Some(self.post_sign.take() - .expect("post_sign is set on creation; qed") - .execute(prospective) - .into_future()); - }, - WaitForPostSign => { - if let Some(mut fut) = self.post_sign_future.as_mut() { - match fut.poll()? { - Async::Ready(item) => { - let nonce = self.ready - .take() - .expect("nonce is set before state transitions to WaitForPostSign; qed"); - nonce.mark_used(); - return Ok(Async::Ready(item)) - }, - Async::NotReady => { - return Ok(Async::NotReady) - } - } - } else { - panic!("Poll after ready."); - } - } - } - } - } -} - -/// Single-use account token. -pub type AccountToken = Password; - -/// Values used to unlock accounts for signing. -#[derive(Clone, PartialEq)] -pub enum SignWith { - /// Nothing -- implies the account is already unlocked. - Nothing, - /// Unlock with password. - Password(Password), - /// Unlock with single-use token. - Token(AccountToken), -} - -impl SignWith { - fn is_password(&self) -> bool { - if let SignWith::Password(_) = *self { - true - } else { - false - } - } -} - -/// A value, potentially accompanied by a signing token. -pub enum WithToken { - /// No token. - No(T), - /// With token. - Yes(T, AccountToken), -} - -impl Deref for WithToken { - type Target = T; - - fn deref(&self) -> &Self::Target { - match *self { - WithToken::No(ref v) => v, - WithToken::Yes(ref v, _) => v, - } - } -} - -impl WithToken { - /// Map the value with the given closure, preserving the token. - pub fn map(self, f: F) -> WithToken where - S: Debug, - F: FnOnce(T) -> S, - { - match self { - WithToken::No(v) => WithToken::No(f(v)), - WithToken::Yes(v, token) => WithToken::Yes(f(v), token), - } - } - - /// Convert into inner value, ignoring possible token. - pub fn into_value(self) -> T { - match self { - WithToken::No(v) => v, - WithToken::Yes(v, _) => v, - } - } - - /// Convert the `WithToken` into a tuple. - pub fn into_tuple(self) -> (T, Option) { - match self { - WithToken::No(v) => (v, None), - WithToken::Yes(v, token) => (v, Some(token)) - } - } -} - -impl From<(T, AccountToken)> for WithToken { - fn from(tuple: (T, AccountToken)) -> Self { - WithToken::Yes(tuple.0, tuple.1) - } -} - -impl From<(T, Option)> for WithToken { - fn from(tuple: (T, Option)) -> Self { - match tuple.1 { - Some(token) => WithToken::Yes(tuple.0, token), - None => WithToken::No(tuple.0), - } - } -} - -/// Execute a confirmation payload. -pub fn execute( - dispatcher: D, - accounts: Arc, - payload: ConfirmationPayload, - pass: SignWith -) -> BoxFuture> { - match payload { - ConfirmationPayload::SendTransaction(request) => { - let condition = request.condition.clone().map(Into::into); - let cloned_dispatcher = dispatcher.clone(); - let post_sign = move |with_token_signed: WithToken| { - let (signed, token) = with_token_signed.into_tuple(); - let signed_transaction = PendingTransaction::new(signed, condition); - cloned_dispatcher.dispatch_transaction(signed_transaction) - .map(|hash| (hash, token)) - }; - let future = dispatcher.sign(accounts, request, pass, post_sign) - .map(|(hash, token)| { - WithToken::from((ConfirmationResponse::SendTransaction(hash.into()), token)) - }); - Box::new(future) - }, - ConfirmationPayload::SignTransaction(request) => { - Box::new(dispatcher.sign(accounts, request, pass, ()) - .map(move |result| result - .map(move |tx| dispatcher.enrich(tx)) - .map(ConfirmationResponse::SignTransaction) - )) - }, - ConfirmationPayload::EthSignMessage(address, data) => { - if accounts.is_hardware_address(&address) { - let signature = accounts.sign_message_with_hardware(&address, &data) - .map(|s| H520(s.into_electrum())) - .map(RpcH520::from) - .map(ConfirmationResponse::Signature) - // TODO: is this correct? I guess the `token` is the wallet in this context - .map(WithToken::No) - .map_err(|e| errors::account("Error signing message with hardware_wallet", e)); - - return Box::new(future::done(signature)); - } - let hash = eth_data_hash(data); - let res = signature(&accounts, address, hash, pass) - .map(|result| result - .map(|rsv| H520(rsv.into_electrum())) - .map(RpcH520::from) - .map(ConfirmationResponse::Signature) - ); - Box::new(future::done(res)) - }, - ConfirmationPayload::SignMessage(address, data) => { - if accounts.is_hardware_address(&address) { - return Box::new(future::err(errors::account("Error signing message with hardware_wallet", - "Message signing is unsupported"))); - } - let res = signature(&accounts, address, data, pass) - .map(|result| result - .map(|rsv| H520(rsv.into_electrum())) - .map(RpcH520::from) - .map(ConfirmationResponse::Signature) - ); - Box::new(future::done(res)) - }, - ConfirmationPayload::Decrypt(address, data) => { - if accounts.is_hardware_address(&address) { - return Box::new(future::err(errors::unsupported("Decrypting via hardware wallets is not supported.", None))); - } - let res = decrypt(&accounts, address, data, pass) - .map(|result| result - .map(RpcBytes) - .map(ConfirmationResponse::Decrypt) - ); - Box::new(future::done(res)) - }, - } -} - -fn signature(accounts: &AccountProvider, address: Address, hash: H256, password: SignWith) -> Result> { - match password.clone() { - SignWith::Nothing => accounts.sign(address, None, hash).map(WithToken::No), - SignWith::Password(pass) => accounts.sign(address, Some(pass), hash).map(WithToken::No), - SignWith::Token(token) => accounts.sign_with_token(address, token, hash).map(Into::into), - }.map_err(|e| match password { - SignWith::Nothing => errors::signing(e), - _ => errors::password(e), - }) -} - -// obtain a hardware signature from the given account. -fn hardware_signature(accounts: &AccountProvider, address: Address, t: Transaction, chain_id: Option) - -> Result -{ - debug_assert!(accounts.is_hardware_address(&address)); - - let mut stream = rlp::RlpStream::new(); - t.rlp_append_unsigned_transaction(&mut stream, chain_id); - let signature = accounts.sign_transaction_with_hardware(&address, &t, chain_id, &stream.as_raw()) - .map_err(|e| { - debug!(target: "miner", "Error signing transaction with hardware wallet: {}", e); - errors::account("Error signing transaction with hardware wallet", e) - })?; - - SignedTransaction::new(t.with_signature(signature, chain_id)) - .map_err(|e| { - debug!(target: "miner", "Hardware wallet has produced invalid signature: {}", e); - errors::account("Invalid signature generated", e) - }) -} - -fn decrypt(accounts: &AccountProvider, address: Address, msg: Bytes, password: SignWith) -> Result> { - match password.clone() { - SignWith::Nothing => accounts.decrypt(address, None, &DEFAULT_MAC, &msg).map(WithToken::No), - SignWith::Password(pass) => accounts.decrypt(address, Some(pass), &DEFAULT_MAC, &msg).map(WithToken::No), - SignWith::Token(token) => accounts.decrypt_with_token(address, token, &DEFAULT_MAC, &msg).map(Into::into), - }.map_err(|e| match password { - SignWith::Nothing => errors::signing(e), - _ => errors::password(e), - }) -} - -/// Extract the default gas price from a client and miner. -pub fn default_gas_price(client: &C, miner: &M, percentile: usize) -> U256 where - C: BlockChainClient, - M: MinerService, -{ - client.gas_price_corpus(100).percentile(percentile).cloned().unwrap_or_else(|| miner.sensible_gas_price()) -} - -/// Convert RPC confirmation payload to signer confirmation payload. -/// May need to resolve in the future to fetch things like gas price. -pub fn from_rpc(payload: RpcConfirmationPayload, default_account: Address, dispatcher: &D) -> BoxFuture - where D: Dispatcher -{ - match payload { - RpcConfirmationPayload::SendTransaction(request) => { - Box::new(dispatcher.fill_optional_fields(request.into(), default_account, false) - .map(ConfirmationPayload::SendTransaction)) - }, - RpcConfirmationPayload::SignTransaction(request) => { - Box::new(dispatcher.fill_optional_fields(request.into(), default_account, false) - .map(ConfirmationPayload::SignTransaction)) - }, - RpcConfirmationPayload::Decrypt(RpcDecryptRequest { address, msg }) => { - Box::new(future::ok(ConfirmationPayload::Decrypt(address.into(), msg.into()))) - }, - RpcConfirmationPayload::EthSignMessage(RpcEthSignRequest { address, data }) => { - Box::new(future::ok(ConfirmationPayload::EthSignMessage(address.into(), data.into()))) - }, - RpcConfirmationPayload::EIP191SignMessage(RpcSignRequest { address, data }) => { - Box::new(future::ok(ConfirmationPayload::SignMessage(address.into(), data.into()))) - }, - } -} diff --git a/rpc/src/v1/helpers/dispatch/full.rs b/rpc/src/v1/helpers/dispatch/full.rs new file mode 100644 index 0000000000..d958416cbf --- /dev/null +++ b/rpc/src/v1/helpers/dispatch/full.rs @@ -0,0 +1,151 @@ +// Copyright 2015-2019 Parity Technologies (UK) Ltd. +// This file is part of Parity Ethereum. + +// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . + +use std::sync::Arc; + +use ethcore::client::BlockChainClient; +use ethcore::miner::{self, MinerService}; +use ethereum_types::{H256, U256, Address}; +use types::transaction::{SignedTransaction, PendingTransaction}; +use parking_lot::Mutex; + +use jsonrpc_core::{BoxFuture, Result}; +use jsonrpc_core::futures::{future, Future, IntoFuture}; +use v1::helpers::{errors, nonce, TransactionRequest, FilledTransactionRequest}; +use v1::types::{RichRawTransaction as RpcRichRawTransaction}; + +use super::prospective_signer::ProspectiveSigner; +use super::{Dispatcher, Accounts, SignWith, PostSign, default_gas_price}; + +/// A dispatcher which uses references to a client and miner in order to sign +/// requests locally. +#[derive(Debug)] +pub struct FullDispatcher { + client: Arc, + miner: Arc, + nonces: Arc>, + gas_price_percentile: usize, +} + +impl FullDispatcher { + /// Create a `FullDispatcher` from Arc references to a client and miner. + pub fn new( + client: Arc, + miner: Arc, + nonces: Arc>, + gas_price_percentile: usize, + ) -> Self { + FullDispatcher { + client, + miner, + nonces, + gas_price_percentile, + } + } +} + +impl Clone for FullDispatcher { + fn clone(&self) -> Self { + FullDispatcher { + client: self.client.clone(), + miner: self.miner.clone(), + nonces: self.nonces.clone(), + gas_price_percentile: self.gas_price_percentile, + } + } +} + +impl FullDispatcher { + fn state_nonce(&self, from: &Address) -> U256 { + self.miner.next_nonce(&*self.client, from) + } + + /// Post transaction to the network. + /// + /// If transaction is trusted we are more likely to assume it is coming from a local account. + pub fn dispatch_transaction(client: &C, miner: &M, signed_transaction: PendingTransaction, trusted: bool) -> Result { + let hash = signed_transaction.transaction.hash(); + + // use `import_claimed_local_transaction` so we can decide (based on config flags) if we want to treat + // it as local or not. Nodes with public RPC interfaces will want these transactions to be treated like + // external transactions. + miner.import_claimed_local_transaction(client, signed_transaction, trusted) + .map_err(errors::transaction) + .map(|_| hash) + } +} + +impl Dispatcher for FullDispatcher { + fn fill_optional_fields(&self, request: TransactionRequest, default_sender: Address, force_nonce: bool) + -> BoxFuture + { + let request = request; + let from = request.from.unwrap_or(default_sender); + let nonce = if force_nonce { + request.nonce.or_else(|| Some(self.state_nonce(&from))) + } else { + request.nonce + }; + + Box::new(future::ok(FilledTransactionRequest { + from, + used_default_from: request.from.is_none(), + to: request.to, + nonce, + gas_price: request.gas_price.unwrap_or_else(|| { + default_gas_price(&*self.client, &*self.miner, self.gas_price_percentile) + }), + gas: request.gas.unwrap_or_else(|| self.miner.sensible_gas_limit()), + value: request.value.unwrap_or_else(|| 0.into()), + data: request.data.unwrap_or_else(Vec::new), + condition: request.condition, + })) + } + + fn sign

( + &self, + filled: FilledTransactionRequest, + signer: &Arc, + password: SignWith, + post_sign: P, + ) -> BoxFuture + where + P: PostSign + 'static, + ::Future: Send, + { + let chain_id = self.client.signing_chain_id(); + + if let Some(nonce) = filled.nonce { + let future = signer.sign_transaction(filled, chain_id, nonce, password) + .into_future() + .and_then(move |signed| post_sign.execute(signed)); + Box::new(future) + } else { + let state = self.state_nonce(&filled.from); + let reserved = self.nonces.lock().reserve(filled.from, state); + + Box::new(ProspectiveSigner::new(signer.clone(), filled, chain_id, reserved, password, post_sign)) + } + } + + fn enrich(&self, signed_transaction: SignedTransaction) -> RpcRichRawTransaction { + RpcRichRawTransaction::from_signed(signed_transaction) + } + + fn dispatch_transaction(&self, signed_transaction: PendingTransaction) -> Result { + Self::dispatch_transaction(&*self.client, &*self.miner, signed_transaction, true) + } +} diff --git a/rpc/src/v1/helpers/dispatch/light.rs b/rpc/src/v1/helpers/dispatch/light.rs new file mode 100644 index 0000000000..ff47eaa7ac --- /dev/null +++ b/rpc/src/v1/helpers/dispatch/light.rs @@ -0,0 +1,266 @@ +// Copyright 2015-2019 Parity Technologies (UK) Ltd. +// This file is part of Parity Ethereum. + +// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . + +use std::sync::Arc; + +use ethereum_types::{H256, Address, U256}; +use light::TransactionQueue as LightTransactionQueue; +use light::cache::Cache as LightDataCache; +use light::client::LightChainClient; +use light::on_demand::{request, OnDemand}; +use parking_lot::{Mutex, RwLock}; +use stats::Corpus; +use sync::LightSync; +use types::basic_account::BasicAccount; +use types::ids::BlockId; +use types::transaction::{SignedTransaction, PendingTransaction, Error as TransactionError}; + +use jsonrpc_core::{BoxFuture, Result}; +use jsonrpc_core::futures::{future, Future, IntoFuture}; +use jsonrpc_core::futures::future::Either; +use v1::helpers::{errors, nonce, TransactionRequest, FilledTransactionRequest}; +use v1::types::{RichRawTransaction as RpcRichRawTransaction,}; + +use super::{Dispatcher, Accounts, SignWith, PostSign}; + +/// Dispatcher for light clients -- fetches default gas price, next nonce, etc. from network. +#[derive(Clone)] +pub struct LightDispatcher { + /// Sync service. + pub sync: Arc, + /// Header chain client. + pub client: Arc, + /// On-demand request service. + pub on_demand: Arc, + /// Data cache. + pub cache: Arc>, + /// Transaction queue. + pub transaction_queue: Arc>, + /// Nonce reservations + pub nonces: Arc>, + /// Gas Price percentile value used as default gas price. + pub gas_price_percentile: usize, +} + +impl LightDispatcher { + /// Create a new `LightDispatcher` from its requisite parts. + /// + /// For correct operation, the OnDemand service is assumed to be registered as a network handler, + pub fn new( + sync: Arc, + client: Arc, + on_demand: Arc, + cache: Arc>, + transaction_queue: Arc>, + nonces: Arc>, + gas_price_percentile: usize, + ) -> Self { + LightDispatcher { + sync, + client, + on_demand, + cache, + transaction_queue, + nonces, + gas_price_percentile, + } + } + + /// Get a recent gas price corpus. + // TODO: this could be `impl Trait`. + pub fn gas_price_corpus(&self) -> BoxFuture> { + fetch_gas_price_corpus( + self.sync.clone(), + self.client.clone(), + self.on_demand.clone(), + self.cache.clone(), + ) + } + + /// Get an account's state + fn account(&self, addr: Address) -> BoxFuture> { + let best_header = self.client.best_block_header(); + let account_future = self.sync.with_context(|ctx| self.on_demand.request(ctx, request::Account { + header: best_header.into(), + address: addr, + }).expect("no back-references; therefore all back-references valid; qed")); + + match account_future { + Some(response) => Box::new(response.map_err(|_| errors::no_light_peers())), + None => Box::new(future::err(errors::network_disabled())), + } + } + + /// Get an account's next nonce. + pub fn next_nonce(&self, addr: Address) -> BoxFuture { + let account_start_nonce = self.client.engine().account_start_nonce(self.client.best_block_header().number()); + Box::new(self.account(addr) + .and_then(move |maybe_account| { + future::ok(maybe_account.map_or(account_start_nonce, |account| account.nonce)) + }) + ) + } +} + +impl Dispatcher for LightDispatcher { + // Ignore the `force_nonce` flag in order to always query the network when fetching the nonce and + // the account state. If the nonce is specified in the transaction use that nonce instead but do the + // network request anyway to the account state (balance) + fn fill_optional_fields(&self, request: TransactionRequest, default_sender: Address, _force_nonce: bool) + -> BoxFuture + { + const DEFAULT_GAS_PRICE: U256 = U256([0, 0, 0, 21_000_000]); + + let gas_limit = self.client.best_block_header().gas_limit(); + let request_gas_price = request.gas_price.clone(); + let from = request.from.unwrap_or(default_sender); + + let with_gas_price = move |gas_price| { + let request = request; + FilledTransactionRequest { + from: from.clone(), + used_default_from: request.from.is_none(), + to: request.to, + nonce: request.nonce, + gas_price: gas_price, + gas: request.gas.unwrap_or_else(|| gas_limit / 3), + value: request.value.unwrap_or_else(|| 0.into()), + data: request.data.unwrap_or_else(Vec::new), + condition: request.condition, + } + }; + + // fast path for known gas price. + let gas_price_percentile = self.gas_price_percentile; + let gas_price = match request_gas_price { + Some(gas_price) => Either::A(future::ok(with_gas_price(gas_price))), + None => Either::B(fetch_gas_price_corpus( + self.sync.clone(), + self.client.clone(), + self.on_demand.clone(), + self.cache.clone() + ).and_then(move |corp| match corp.percentile(gas_price_percentile) { + Some(percentile) => Ok(*percentile), + None => Ok(DEFAULT_GAS_PRICE), // fall back to default on error. + }).map(with_gas_price)) + }; + + let future_account = self.account(from); + + Box::new(gas_price.and_then(move |mut filled| { + future_account + .and_then(move |maybe_account| { + let cost = filled.value.saturating_add(filled.gas.saturating_mul(filled.gas_price)); + match maybe_account { + Some(ref account) if cost > account.balance => { + Err(errors::transaction(TransactionError::InsufficientBalance { + balance: account.balance, + cost, + })) + } + Some(account) => { + if filled.nonce.is_none() { + filled.nonce = Some(account.nonce); + } + Ok(filled) + } + None => Err(errors::account("Account not found", "")), + } + }) + })) + } + + fn sign

( + &self, + filled: FilledTransactionRequest, + signer: &Arc, + password: SignWith, + post_sign: P + ) -> BoxFuture + where + P: PostSign + 'static, + ::Future: Send, + { + let chain_id = self.client.signing_chain_id(); + let nonce = filled.nonce.expect("nonce is always provided; qed"); + let future = signer.sign_transaction(filled, chain_id, nonce, password) + .into_future() + .and_then(move |signed| post_sign.execute(signed)); + Box::new(future) + } + + fn enrich(&self, signed_transaction: SignedTransaction) -> RpcRichRawTransaction { + RpcRichRawTransaction::from_signed(signed_transaction) + } + + fn dispatch_transaction(&self, signed_transaction: PendingTransaction) -> Result { + let hash = signed_transaction.transaction.hash(); + + self.transaction_queue.write().import(signed_transaction) + .map_err(errors::transaction) + .map(|_| hash) + } +} + +/// Get a recent gas price corpus. +// TODO: this could be `impl Trait`. +pub fn fetch_gas_price_corpus( + sync: Arc, + client: Arc, + on_demand: Arc, + cache: Arc>, +) -> BoxFuture> { + const GAS_PRICE_SAMPLE_SIZE: usize = 100; + + if let Some(cached) = { cache.lock().gas_price_corpus() } { + return Box::new(future::ok(cached)) + } + + let cache = cache.clone(); + let eventual_corpus = sync.with_context(|ctx| { + // get some recent headers with gas used, + // and request each of the blocks from the network. + let block_requests = client.ancestry_iter(BlockId::Latest) + .filter(|hdr| hdr.gas_used() != U256::default()) + .take(GAS_PRICE_SAMPLE_SIZE) + .map(|hdr| request::Body(hdr.into())) + .collect::>(); + + // when the blocks come in, collect gas prices into a vector + on_demand.request(ctx, block_requests) + .expect("no back-references; therefore all back-references are valid; qed") + .map(|bodies| { + bodies.into_iter().fold(Vec::new(), |mut v, block| { + for t in block.transaction_views().iter() { + v.push(t.gas_price()) + } + v + }) + }) + .map(move |prices| { + // produce a corpus from the vector and cache it. + // It's later used to get a percentile for default gas price. + let corpus: ::stats::Corpus<_> = prices.into(); + cache.lock().set_gas_price_corpus(corpus.clone()); + corpus + }) + }); + + match eventual_corpus { + Some(corp) => Box::new(corp.map_err(|_| errors::no_light_peers())), + None => Box::new(future::err(errors::network_disabled())), + } +} diff --git a/rpc/src/v1/helpers/dispatch/mod.rs b/rpc/src/v1/helpers/dispatch/mod.rs new file mode 100644 index 0000000000..6df1e88480 --- /dev/null +++ b/rpc/src/v1/helpers/dispatch/mod.rs @@ -0,0 +1,381 @@ +// Copyright 2015-2019 Parity Technologies (UK) Ltd. +// This file is part of Parity Ethereum. + +// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . + +//! Utilities and helpers for transaction dispatch. + +pub(crate) mod light; +mod full; +mod prospective_signer; + +#[cfg(any(test, feature = "accounts"))] +mod signing; +#[cfg(not(any(test, feature = "accounts")))] +mod signing { + use super::*; + use v1::helpers::errors; + + /// Dummy signer implementation + #[derive(Debug, Clone)] + pub struct Signer; + + impl Signer { + /// Create new instance of dummy signer (accept any AccountProvider) + pub fn new(_ap: T) -> Self { + Signer + } + } + + impl super::Accounts for Signer { + fn sign_transaction(&self, _filled: FilledTransactionRequest, _chain_id: Option, _nonce: U256, _password: SignWith) -> Result> { + Err(errors::account("Signing unsupported", "See #9997")) + } + + fn sign_message(&self, _address: Address, _password: SignWith, _hash: SignMessage) -> Result> { + Err(errors::account("Signing unsupported", "See #9997")) + } + + fn decrypt(&self, _address: Address, _password: SignWith, _data: Bytes) -> Result> { + Err(errors::account("Signing unsupported", "See #9997")) + } + + fn supports_prospective_signing(&self, _address: &Address, _password: &SignWith) -> bool { + false + } + + fn default_account(&self) -> Address { + Default::default() + } + + fn is_unlocked(&self, _address: &Address) -> bool { + false + } + } +} + +pub use self::light::LightDispatcher; +pub use self::full::FullDispatcher; +pub use self::signing::Signer; +pub use v1::helpers::nonce::Reservations; + +use std::fmt::Debug; +use std::ops::Deref; +use std::sync::Arc; + +use bytes::Bytes; +use ethcore::client::BlockChainClient; +use ethcore::miner::MinerService; +use ethereum_types::{H520, H256, U256, Address}; +use ethkey::{Password, Signature}; +use hash::keccak; +use types::transaction::{SignedTransaction, PendingTransaction}; + +use jsonrpc_core::{BoxFuture, Result, Error}; +use jsonrpc_core::futures::{future, Future, IntoFuture}; +use v1::helpers::{TransactionRequest, FilledTransactionRequest, ConfirmationPayload}; +use v1::types::{ + H520 as RpcH520, Bytes as RpcBytes, + RichRawTransaction as RpcRichRawTransaction, + ConfirmationPayload as RpcConfirmationPayload, + ConfirmationResponse, + EthSignRequest as RpcEthSignRequest, + EIP191SignRequest as RpcSignRequest, + DecryptRequest as RpcDecryptRequest, +}; + +/// Has the capability to dispatch, sign, and decrypt. +/// +/// Requires a clone implementation, with the implication that it be cheap; +/// usually just bumping a reference count or two. +pub trait Dispatcher: Send + Sync + Clone { + // TODO: when ATC exist, use zero-cost + // type Out: IntoFuture + + /// Fill optional fields of a transaction request, fetching gas price but not nonce. + fn fill_optional_fields(&self, request: TransactionRequest, default_sender: Address, force_nonce: bool) + -> BoxFuture; + + /// Sign the given transaction request without dispatching, fetching appropriate nonce. + fn sign

( + &self, + filled: FilledTransactionRequest, + signer: &Arc, + password: SignWith, + post_sign: P, + ) -> BoxFuture where + P: PostSign + 'static, + ::Future: Send; + + /// Converts a `SignedTransaction` into `RichRawTransaction` + fn enrich(&self, SignedTransaction) -> RpcRichRawTransaction; + + /// "Dispatch" a local transaction. + fn dispatch_transaction(&self, signed_transaction: PendingTransaction) -> Result; +} + +/// Payload to sign +pub enum SignMessage { + /// Eth-sign kind data (requires prefixing) + Data(Bytes), + /// Prefixed data hash + Hash(H256), +} + +/// Abstract transaction signer. +/// +/// NOTE This signer is semi-correct, it's a temporary measure to avoid moving too much code. +/// If accounts are ultimately removed all password-dealing endpoints will be wiped out. +pub trait Accounts: Send + Sync { + /// Sign given filled transaction request for the specified chain_id. + fn sign_transaction(&self, filled: FilledTransactionRequest, chain_id: Option, nonce: U256, password: SignWith) -> Result>; + + /// Sign given message. + fn sign_message(&self, address: Address, password: SignWith, hash: SignMessage) -> Result>; + + /// Decrypt given message. + fn decrypt(&self, address: Address, password: SignWith, data: Bytes) -> Result>; + + /// Returns `true` if the accounts can sign multiple times. + fn supports_prospective_signing(&self, address: &Address, password: &SignWith) -> bool; + + /// Returns default account. + fn default_account(&self) -> Address; + + /// Returns true if account is unlocked (i.e. can sign without a password) + fn is_unlocked(&self, address: &Address) -> bool; +} + +/// action to execute after signing +/// e.g importing a transaction into the chain +pub trait PostSign: Send { + /// item that this PostSign returns + type Item: Send; + /// incase you need to perform async PostSign actions + type Out: IntoFuture + Send; + /// perform an action with the signed transaction + fn execute(self, signer: WithToken) -> Self::Out; +} + +impl PostSign for () { + type Item = WithToken; + type Out = Result; + fn execute(self, signed: WithToken) -> Self::Out { + Ok(signed) + } +} + +impl PostSign for F + where F: FnOnce(WithToken) -> Result +{ + type Item = T; + type Out = Result; + fn execute(self, signed: WithToken) -> Self::Out { + (self)(signed) + } +} + +/// Single-use account token. +pub type AccountToken = Password; + +/// Values used to unlock accounts for signing. +#[derive(Clone, PartialEq)] +pub enum SignWith { + /// Nothing -- implies the account is already unlocked. + Nothing, + /// Unlock with password. + Password(Password), + /// Unlock with single-use token. + Token(AccountToken), +} + +impl SignWith { + fn is_password(&self) -> bool { + if let SignWith::Password(_) = *self { + true + } else { + false + } + } +} + +/// A value, potentially accompanied by a signing token. +pub enum WithToken { + /// No token. + No(T), + /// With token. + Yes(T, AccountToken), +} + +impl Deref for WithToken { + type Target = T; + + fn deref(&self) -> &Self::Target { + match *self { + WithToken::No(ref v) => v, + WithToken::Yes(ref v, _) => v, + } + } +} + +impl WithToken { + /// Map the value with the given closure, preserving the token. + pub fn map(self, f: F) -> WithToken where + S: Debug, + F: FnOnce(T) -> S, + { + match self { + WithToken::No(v) => WithToken::No(f(v)), + WithToken::Yes(v, token) => WithToken::Yes(f(v), token), + } + } + + /// Convert into inner value, ignoring possible token. + pub fn into_value(self) -> T { + match self { + WithToken::No(v) => v, + WithToken::Yes(v, _) => v, + } + } + + /// Convert the `WithToken` into a tuple. + pub fn into_tuple(self) -> (T, Option) { + match self { + WithToken::No(v) => (v, None), + WithToken::Yes(v, token) => (v, Some(token)) + } + } +} + +impl From<(T, AccountToken)> for WithToken { + fn from(tuple: (T, AccountToken)) -> Self { + WithToken::Yes(tuple.0, tuple.1) + } +} + +impl From<(T, Option)> for WithToken { + fn from(tuple: (T, Option)) -> Self { + match tuple.1 { + Some(token) => WithToken::Yes(tuple.0, token), + None => WithToken::No(tuple.0), + } + } +} + +/// Execute a confirmation payload. +pub fn execute( + dispatcher: D, + signer: &Arc, + payload: ConfirmationPayload, + pass: SignWith +) -> BoxFuture> { + match payload { + ConfirmationPayload::SendTransaction(request) => { + let condition = request.condition.clone().map(Into::into); + let cloned_dispatcher = dispatcher.clone(); + let post_sign = move |with_token_signed: WithToken| { + let (signed, token) = with_token_signed.into_tuple(); + let signed_transaction = PendingTransaction::new(signed, condition); + cloned_dispatcher.dispatch_transaction(signed_transaction) + .map(|hash| (hash, token)) + }; + + Box::new( + dispatcher.sign(request, &signer, pass, post_sign).map(|(hash, token)| { + WithToken::from((ConfirmationResponse::SendTransaction(hash.into()), token)) + }) + ) + }, + ConfirmationPayload::SignTransaction(request) => { + Box::new(dispatcher.sign(request, &signer, pass, ()) + .map(move |result| result + .map(move |tx| dispatcher.enrich(tx)) + .map(ConfirmationResponse::SignTransaction) + )) + }, + ConfirmationPayload::EthSignMessage(address, data) => { + let res = signer.sign_message(address, pass, SignMessage::Data(data)) + .map(|result| result + .map(|s| H520(s.into_electrum())) + .map(RpcH520::from) + .map(ConfirmationResponse::Signature) + ); + + Box::new(future::done(res)) + }, + ConfirmationPayload::SignMessage(address, data) => { + let res = signer.sign_message(address, pass, SignMessage::Hash(data)) + .map(|result| result + .map(|rsv| H520(rsv.into_electrum())) + .map(RpcH520::from) + .map(ConfirmationResponse::Signature) + ); + + Box::new(future::done(res)) + }, + ConfirmationPayload::Decrypt(address, data) => { + let res = signer.decrypt(address, pass, data) + .map(|result| result + .map(RpcBytes) + .map(ConfirmationResponse::Decrypt) + ); + Box::new(future::done(res)) + }, + } +} + +/// Returns a eth_sign-compatible hash of data to sign. +/// The data is prepended with special message to prevent +/// malicious DApps from using the function to sign forged transactions. +pub fn eth_data_hash(mut data: Bytes) -> H256 { + let mut message_data = + format!("\x19Ethereum Signed Message:\n{}", data.len()) + .into_bytes(); + message_data.append(&mut data); + keccak(message_data) +} + +/// Extract the default gas price from a client and miner. +pub fn default_gas_price(client: &C, miner: &M, percentile: usize) -> U256 where + C: BlockChainClient, + M: MinerService, +{ + client.gas_price_corpus(100).percentile(percentile).cloned().unwrap_or_else(|| miner.sensible_gas_price()) +} + +/// Convert RPC confirmation payload to signer confirmation payload. +/// May need to resolve in the future to fetch things like gas price. +pub fn from_rpc(payload: RpcConfirmationPayload, default_account: Address, dispatcher: &D) -> BoxFuture + where D: Dispatcher +{ + match payload { + RpcConfirmationPayload::SendTransaction(request) => { + Box::new(dispatcher.fill_optional_fields(request.into(), default_account, false) + .map(ConfirmationPayload::SendTransaction)) + }, + RpcConfirmationPayload::SignTransaction(request) => { + Box::new(dispatcher.fill_optional_fields(request.into(), default_account, false) + .map(ConfirmationPayload::SignTransaction)) + }, + RpcConfirmationPayload::Decrypt(RpcDecryptRequest { address, msg }) => { + Box::new(future::ok(ConfirmationPayload::Decrypt(address.into(), msg.into()))) + }, + RpcConfirmationPayload::EthSignMessage(RpcEthSignRequest { address, data }) => { + Box::new(future::ok(ConfirmationPayload::EthSignMessage(address.into(), data.into()))) + }, + RpcConfirmationPayload::EIP191SignMessage(RpcSignRequest { address, data }) => { + Box::new(future::ok(ConfirmationPayload::SignMessage(address.into(), data.into()))) + }, + } +} diff --git a/rpc/src/v1/helpers/dispatch/prospective_signer.rs b/rpc/src/v1/helpers/dispatch/prospective_signer.rs new file mode 100644 index 0000000000..034d19dc65 --- /dev/null +++ b/rpc/src/v1/helpers/dispatch/prospective_signer.rs @@ -0,0 +1,152 @@ +// Copyright 2015-2019 Parity Technologies (UK) Ltd. +// This file is part of Parity Ethereum. + +// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . + +use std::sync::Arc; + +use ethereum_types::U256; +use jsonrpc_core::{Result, Error}; +use jsonrpc_core::futures::{Future, Poll, Async, IntoFuture}; +use types::transaction::SignedTransaction; + +use v1::helpers::{errors, nonce, FilledTransactionRequest}; +use super::{Accounts, SignWith, WithToken, PostSign}; + +#[derive(Debug, Clone, Copy)] +enum ProspectiveSignerState { + TryProspectiveSign, + WaitForPostSign, + WaitForNonce, +} + +pub struct ProspectiveSigner { + signer: Arc, + filled: FilledTransactionRequest, + chain_id: Option, + reserved: nonce::Reserved, + password: SignWith, + state: ProspectiveSignerState, + prospective: Option>, + ready: Option, + post_sign: Option

, + post_sign_future: Option<::Future> +} + +impl ProspectiveSigner

{ + pub fn new( + signer: Arc, + filled: FilledTransactionRequest, + chain_id: Option, + reserved: nonce::Reserved, + password: SignWith, + post_sign: P + ) -> Self { + let supports_prospective = signer.supports_prospective_signing(&filled.from, &password); + + ProspectiveSigner { + signer, + filled, + chain_id, + reserved, + password, + state: if supports_prospective { + ProspectiveSignerState::TryProspectiveSign + } else { + ProspectiveSignerState::WaitForNonce + }, + prospective: None, + ready: None, + post_sign: Some(post_sign), + post_sign_future: None + } + } + + fn sign(&self, nonce: &U256) -> Result> { + self.signer.sign_transaction( + self.filled.clone(), + self.chain_id, + *nonce, + self.password.clone() + ) + } + + fn poll_reserved(&mut self) -> Poll { + self.reserved.poll().map_err(|_| errors::internal("Nonce reservation failure", "")) + } +} + +impl Future for ProspectiveSigner

{ + type Item = P::Item; + type Error = Error; + + fn poll(&mut self) -> Poll { + use self::ProspectiveSignerState::*; + + loop { + match self.state { + TryProspectiveSign => { + // Try to poll reserved, it might be ready. + match self.poll_reserved()? { + Async::NotReady => { + self.state = WaitForNonce; + self.prospective = Some(self.sign(self.reserved.prospective_value())?); + }, + Async::Ready(nonce) => { + self.state = WaitForPostSign; + self.post_sign_future = Some( + self.post_sign.take() + .expect("post_sign is set on creation; qed") + .execute(self.sign(nonce.value())?) + .into_future() + ); + self.ready = Some(nonce); + }, + } + }, + WaitForNonce => { + let nonce = try_ready!(self.poll_reserved()); + let prospective = match (self.prospective.take(), nonce.matches_prospective()) { + (Some(prospective), true) => prospective, + _ => self.sign(nonce.value())?, + }; + self.ready = Some(nonce); + self.state = WaitForPostSign; + self.post_sign_future = Some(self.post_sign.take() + .expect("post_sign is set on creation; qed") + .execute(prospective) + .into_future()); + }, + WaitForPostSign => { + if let Some(mut fut) = self.post_sign_future.as_mut() { + match fut.poll()? { + Async::Ready(item) => { + let nonce = self.ready + .take() + .expect("nonce is set before state transitions to WaitForPostSign; qed"); + nonce.mark_used(); + return Ok(Async::Ready(item)) + }, + Async::NotReady => { + return Ok(Async::NotReady) + } + } + } else { + panic!("Poll after ready."); + } + } + } + } + } +} diff --git a/rpc/src/v1/helpers/dispatch/signing.rs b/rpc/src/v1/helpers/dispatch/signing.rs new file mode 100644 index 0000000000..8243dcbdf8 --- /dev/null +++ b/rpc/src/v1/helpers/dispatch/signing.rs @@ -0,0 +1,156 @@ +// Copyright 2015-2019 Parity Technologies (UK) Ltd. +// This file is part of Parity Ethereum. + +// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . + +use std::sync::Arc; + +use accounts::AccountProvider; +use bytes::Bytes; +use crypto::DEFAULT_MAC; +use ethereum_types::{H256, U256, Address}; +use ethkey::{Signature}; +use types::transaction::{Transaction, Action, SignedTransaction}; + +use jsonrpc_core::Result; +use v1::helpers::{errors, FilledTransactionRequest}; + +use super::{eth_data_hash, WithToken, SignWith, SignMessage}; + +/// Account-aware signer +pub struct Signer { + accounts: Arc, +} + +impl Signer { + /// Create new instance of signer + pub fn new(accounts: Arc) -> Self { + Signer { accounts } + } +} + +impl super::Accounts for Signer { + fn sign_transaction(&self, filled: FilledTransactionRequest, chain_id: Option, nonce: U256, password: SignWith) -> Result> { + let t = Transaction { + nonce: nonce, + action: filled.to.map_or(Action::Create, Action::Call), + gas: filled.gas, + gas_price: filled.gas_price, + value: filled.value, + data: filled.data, + }; + + if self.accounts.is_hardware_address(&filled.from) { + return hardware_signature(&*self.accounts, filled.from, t, chain_id).map(WithToken::No) + } + + let hash = t.hash(chain_id); + let signature = signature(&*self.accounts, filled.from, hash, password)?; + + Ok(signature.map(|sig| { + SignedTransaction::new(t.with_signature(sig, chain_id)) + .expect("Transaction was signed by AccountsProvider; it never produces invalid signatures; qed") + })) + } + + fn sign_message(&self, address: Address, password: SignWith, hash: SignMessage) -> Result> { + if self.accounts.is_hardware_address(&address) { + return if let SignMessage::Data(data) = hash { + let signature = self.accounts.sign_message_with_hardware(&address, &data) + // TODO: is this correct? I guess the `token` is the wallet in this context + .map(WithToken::No) + .map_err(|e| errors::account("Error signing message with hardware_wallet", e)); + + signature + } else { + Err(errors::account("Error signing message with hardware_wallet", "Message signing is unsupported")) + } + } + + match hash { + SignMessage::Data(data) => { + let hash = eth_data_hash(data); + signature(&self.accounts, address, hash, password) + }, + SignMessage::Hash(hash) => { + signature(&self.accounts, address, hash, password) + } + } + } + + fn decrypt(&self, address: Address, password: SignWith, data: Bytes) -> Result> { + if self.accounts.is_hardware_address(&address) { + return Err(errors::unsupported("Decrypting via hardware wallets is not supported.", None)); + } + + match password.clone() { + SignWith::Nothing => self.accounts.decrypt(address, None, &DEFAULT_MAC, &data).map(WithToken::No), + SignWith::Password(pass) => self.accounts.decrypt(address, Some(pass), &DEFAULT_MAC, &data).map(WithToken::No), + SignWith::Token(token) => self.accounts.decrypt_with_token(address, token, &DEFAULT_MAC, &data).map(Into::into), + }.map_err(|e| match password { + SignWith::Nothing => errors::signing(e), + _ => errors::password(e), + }) + } + + fn supports_prospective_signing(&self, address: &Address, password: &SignWith) -> bool { + // If the account is permanently unlocked we can try to sign + // using prospective nonce. This should speed up sending + // multiple subsequent transactions in multi-threaded RPC environment. + let is_unlocked_permanently = self.accounts.is_unlocked_permanently(address); + let has_password = password.is_password(); + + is_unlocked_permanently || has_password + } + + fn default_account(&self) -> Address { + self.accounts.default_account().ok().unwrap_or_default() + } + + fn is_unlocked(&self, address: &Address) -> bool { + self.accounts.is_unlocked(address) + } +} + +fn signature(accounts: &AccountProvider, address: Address, hash: H256, password: SignWith) -> Result> { + match password.clone() { + SignWith::Nothing => accounts.sign(address, None, hash).map(WithToken::No), + SignWith::Password(pass) => accounts.sign(address, Some(pass), hash).map(WithToken::No), + SignWith::Token(token) => accounts.sign_with_token(address, token, hash).map(Into::into), + }.map_err(|e| match password { + SignWith::Nothing => errors::signing(e), + _ => errors::password(e), + }) +} + +// obtain a hardware signature from the given account. +fn hardware_signature(accounts: &AccountProvider, address: Address, t: Transaction, chain_id: Option) + -> Result +{ + debug_assert!(accounts.is_hardware_address(&address)); + + let mut stream = rlp::RlpStream::new(); + t.rlp_append_unsigned_transaction(&mut stream, chain_id); + let signature = accounts.sign_transaction_with_hardware(&address, &t, chain_id, &stream.as_raw()) + .map_err(|e| { + debug!(target: "miner", "Error signing transaction with hardware wallet: {}", e); + errors::account("Error signing transaction with hardware wallet", e) + })?; + + SignedTransaction::new(t.with_signature(signature, chain_id)) + .map_err(|e| { + debug!(target: "miner", "Hardware wallet has produced invalid signature: {}", e); + errors::account("Invalid signature generated", e) + }) +} diff --git a/rpc/src/v1/helpers/engine_signer.rs b/rpc/src/v1/helpers/engine_signer.rs new file mode 100644 index 0000000000..f993d15f23 --- /dev/null +++ b/rpc/src/v1/helpers/engine_signer.rs @@ -0,0 +1,51 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +use std::sync::Arc; + +use accounts::AccountProvider; +use ethkey::{self, Address, Password}; + +/// An implementation of EngineSigner using internal account management. +pub struct EngineSigner { + accounts: Arc, + address: Address, + password: Password, +} + +impl EngineSigner { + /// Creates new `EngineSigner` given account manager and account details. + pub fn new(accounts: Arc, address: Address, password: Password) -> Self { + EngineSigner { accounts, address, password } + } +} + +impl ethcore::engines::EngineSigner for EngineSigner { + fn sign(&self, message: ethkey::Message) -> Result { + match self.accounts.sign(self.address, Some(self.password.clone()), message) { + Ok(ok) => Ok(ok), + Err(e) => { + warn!("Unable to sign consensus message: {:?}", e); + Err(ethkey::Error::InvalidSecret) + }, + } + } + + fn address(&self) -> Address { + self.address + } +} + diff --git a/rpc/src/v1/helpers/errors.rs b/rpc/src/v1/helpers/errors.rs index 4695682e3c..30607fde6c 100644 --- a/rpc/src/v1/helpers/errors.rs +++ b/rpc/src/v1/helpers/errors.rs @@ -18,7 +18,6 @@ use std::fmt; -use ethcore::account_provider::SignError as AccountError; use ethcore::error::{Error as EthcoreError, ErrorKind, CallError}; use ethcore::client::BlockId; use jsonrpc_core::{futures, Result as RpcResult, Error, ErrorCode, Value}; @@ -337,14 +336,6 @@ pub fn fetch(error: T) -> Error { } } -pub fn signing(error: AccountError) -> Error { - Error { - code: ErrorCode::ServerError(codes::ACCOUNT_LOCKED), - message: "Your account is locked. Unlock the account via CLI, personal_unlockAccount or use Trusted Signer.".into(), - data: Some(Value::String(format!("{:?}", error))), - } -} - pub fn invalid_call_data(error: T) -> Error { Error { code: ErrorCode::ServerError(codes::ENCODING_ERROR), @@ -353,7 +344,17 @@ pub fn invalid_call_data(error: T) -> Error { } } -pub fn password(error: AccountError) -> Error { +#[cfg(any(test, feature = "accounts"))] +pub fn signing(error: ::accounts::SignError) -> Error { + Error { + code: ErrorCode::ServerError(codes::ACCOUNT_LOCKED), + message: "Your account is locked. Unlock the account via CLI, personal_unlockAccount or use Trusted Signer.".into(), + data: Some(Value::String(format!("{:?}", error))), + } +} + +#[cfg(any(test, feature = "accounts"))] +pub fn password(error: ::accounts::SignError) -> Error { Error { code: ErrorCode::ServerError(codes::PASSWORD_INVALID), message: "Account password is invalid or account does not exist.".into(), diff --git a/rpc/src/v1/helpers/signer.rs b/rpc/src/v1/helpers/external_signer/mod.rs similarity index 71% rename from rpc/src/v1/helpers/signer.rs rename to rpc/src/v1/helpers/external_signer/mod.rs index 0cb13bd7f5..49bbaafe59 100644 --- a/rpc/src/v1/helpers/signer.rs +++ b/rpc/src/v1/helpers/external_signer/mod.rs @@ -14,23 +14,22 @@ // You should have received a copy of the GNU General Public License // along with Parity Ethereum. If not, see . +//! An list of requests to be confirmed or signed by an external approver/signer. + use std::sync::Arc; use std::ops::Deref; -use http::Origin; -use parking_lot::Mutex; -use transient_hashmap::TransientHashMap; - -use ethstore::random_string; -use v1::helpers::signing_queue::{ConfirmationsQueue}; +mod oneshot; +mod signing_queue; -const TOKEN_LIFETIME_SECS: u32 = 3600; +pub use self::signing_queue::{SigningQueue, ConfirmationsQueue, ConfirmationReceiver, ConfirmationResult}; +#[cfg(test)] +pub use self::signing_queue::QueueEvent; /// Manages communication with Signer crate pub struct SignerService { is_enabled: bool, queue: Arc, - web_proxy_tokens: Mutex>, generate_new_token: Box Result + Send + Sync + 'static>, } @@ -40,26 +39,11 @@ impl SignerService { where F: Fn() -> Result + Send + Sync + 'static { SignerService { queue: Arc::new(ConfirmationsQueue::default()), - web_proxy_tokens: Mutex::new(TransientHashMap::new(TOKEN_LIFETIME_SECS)), generate_new_token: Box::new(new_token), is_enabled: is_enabled, } } - /// Checks if the token is valid web proxy access token. - pub fn web_proxy_access_token_domain(&self, token: &String) -> Option { - self.web_proxy_tokens.lock().get(token).cloned() - } - - /// Generates a new web proxy access token. - pub fn generate_web_proxy_access_token(&self, domain: Origin) -> String { - let token = random_string(16); - let mut tokens = self.web_proxy_tokens.lock(); - tokens.prune(); - tokens.insert(token.clone(), domain); - token - } - /// Generates new signer authorization token. pub fn generate_token(&self) -> Result { (self.generate_new_token)() diff --git a/rpc/src/v1/helpers/oneshot.rs b/rpc/src/v1/helpers/external_signer/oneshot.rs similarity index 100% rename from rpc/src/v1/helpers/oneshot.rs rename to rpc/src/v1/helpers/external_signer/oneshot.rs diff --git a/rpc/src/v1/helpers/signing_queue.rs b/rpc/src/v1/helpers/external_signer/signing_queue.rs similarity index 94% rename from rpc/src/v1/helpers/signing_queue.rs rename to rpc/src/v1/helpers/external_signer/signing_queue.rs index 3429f2fa2b..7640500529 100644 --- a/rpc/src/v1/helpers/signing_queue.rs +++ b/rpc/src/v1/helpers/external_signer/signing_queue.rs @@ -15,28 +15,18 @@ // along with Parity Ethereum. If not, see . use std::collections::BTreeMap; -use ethereum_types::{U256, Address}; +use ethereum_types::U256; use parking_lot::{Mutex, RwLock}; -use v1::helpers::{ConfirmationRequest, ConfirmationPayload, oneshot, errors}; -use v1::types::{ConfirmationResponse, H160 as RpcH160, Origin}; +use super::oneshot; +use v1::helpers::errors; +use v1::helpers::requests::{ConfirmationRequest, ConfirmationPayload}; +use v1::types::{ConfirmationResponse, Origin}; use jsonrpc_core::Error; /// Result that can be returned from JSON RPC. pub type ConfirmationResult = Result; -/// Type of default account -pub enum DefaultAccount { - /// Default account is known - Provided(Address), -} - -impl From for DefaultAccount { - fn from(address: RpcH160) -> Self { - DefaultAccount::Provided(address.into()) - } -} - /// Possible events happening in the queue that can be listened to. #[derive(Debug, PartialEq, Clone)] pub enum QueueEvent { @@ -225,9 +215,8 @@ mod test { use ethereum_types::{U256, Address}; use parking_lot::Mutex; use jsonrpc_core::futures::Future; - use v1::helpers::{ - SigningQueue, ConfirmationsQueue, QueueEvent, FilledTransactionRequest, ConfirmationPayload, - }; + use v1::helpers::external_signer::{SigningQueue, ConfirmationsQueue, QueueEvent}; + use v1::helpers::{FilledTransactionRequest, ConfirmationPayload}; use v1::types::ConfirmationResponse; fn request() -> ConfirmationPayload { @@ -299,3 +288,4 @@ mod test { assert_eq!(el.payload, request); } } + diff --git a/rpc/src/v1/helpers/light_fetch.rs b/rpc/src/v1/helpers/light_fetch.rs index d026b5f0fe..5a73c04be0 100644 --- a/rpc/src/v1/helpers/light_fetch.rs +++ b/rpc/src/v1/helpers/light_fetch.rs @@ -231,7 +231,7 @@ impl LightFetch { let gas_price_percentile = self.gas_price_percentile; let gas_price_fut = match req.gas_price { Some(price) => Either::A(future::ok(price)), - None => Either::B(dispatch::fetch_gas_price_corpus( + None => Either::B(dispatch::light::fetch_gas_price_corpus( self.sync.clone(), self.client.clone(), self.on_demand.clone(), diff --git a/rpc/src/v1/helpers/mod.rs b/rpc/src/v1/helpers/mod.rs index 547a3ebd85..59a62deb74 100644 --- a/rpc/src/v1/helpers/mod.rs +++ b/rpc/src/v1/helpers/mod.rs @@ -18,21 +18,22 @@ pub mod errors; pub mod block_import; +pub mod deprecated; pub mod dispatch; +pub mod eip191; +#[cfg(any(test, feature = "accounts"))] +pub mod engine_signer; +pub mod external_signer; pub mod fake_sign; pub mod ipfs; pub mod light_fetch; pub mod nonce; -pub mod oneshot; pub mod secretstore; -pub mod eip191; mod network_settings; mod poll_filter; mod poll_manager; mod requests; -mod signer; -mod signing_queue; mod subscribers; mod subscription_manager; mod work; @@ -46,12 +47,6 @@ pub use self::poll_filter::{PollFilter, SyncPollFilter, limit_logs}; pub use self::requests::{ TransactionRequest, FilledTransactionRequest, ConfirmationRequest, ConfirmationPayload, CallRequest, }; -pub use self::signing_queue::{ - ConfirmationsQueue, ConfirmationReceiver, ConfirmationResult, ConfirmationSender, - SigningQueue, QueueEvent, DefaultAccount, - QUEUE_LIMIT as SIGNING_QUEUE_LIMIT, -}; -pub use self::signer::SignerService; pub use self::subscribers::Subscribers; pub use self::subscription_manager::GenericPollManager; pub use self::work::submit_work_detail; diff --git a/rpc/src/v1/helpers/requests.rs b/rpc/src/v1/helpers/requests.rs index db02c58675..e71d104449 100644 --- a/rpc/src/v1/helpers/requests.rs +++ b/rpc/src/v1/helpers/requests.rs @@ -14,11 +14,10 @@ // You should have received a copy of the GNU General Public License // along with Parity Ethereum. If not, see . -use ethereum_types::{U256, Address}; +use ethereum_types::{U256, H256, Address}; use bytes::Bytes; use v1::types::{Origin, TransactionCondition}; -use ethereum_types::H256; /// Transaction request coming from RPC #[derive(Debug, Clone, Default, Eq, PartialEq, Hash)] diff --git a/rpc/src/v1/helpers/signature.rs b/rpc/src/v1/helpers/signature.rs index c684523fea..b2bea2588f 100644 --- a/rpc/src/v1/helpers/signature.rs +++ b/rpc/src/v1/helpers/signature.rs @@ -53,8 +53,7 @@ pub fn verify_signature( #[cfg(test)] mod tests { use super::*; - use std::sync::Arc; - use ethcore::account_provider::AccountProvider; + use ethkey::Generator; use v1::types::H160; pub fn add_chain_replay_protection(v: u64, chain_id: Option) -> u64 { @@ -71,9 +70,9 @@ mod tests { /// mocked signer fn sign(should_prefix: bool, data: Vec, signing_chain_id: Option) -> (H160, [u8; 32], [u8; 32], U64) { let hash = if should_prefix { eth_data_hash(data) } else { keccak(data) }; - let accounts = Arc::new(AccountProvider::transient_provider()); - let address = accounts.new_account(&"password123".into()).unwrap(); - let sig = accounts.sign(address, Some("password123".into()), hash).unwrap(); + let account = ethkey::Random.generate().unwrap(); + let address = account.address(); + let sig = ethkey::sign(account.secret(), &hash).unwrap(); let (r, s, v) = (sig.r(), sig.s(), sig.v()); let v = add_chain_replay_protection(v as u64, signing_chain_id); let (r_buf, s_buf) = { diff --git a/rpc/src/v1/impls/eth.rs b/rpc/src/v1/impls/eth.rs index 15482645d7..8d47b9b7b5 100644 --- a/rpc/src/v1/impls/eth.rs +++ b/rpc/src/v1/impls/eth.rs @@ -25,7 +25,6 @@ use ethereum_types::{U256, H256, H160, Address}; use parking_lot::Mutex; use ethash::{self, SeedHashCompute}; -use ethcore::account_provider::AccountProvider; use ethcore::client::{BlockChainClient, BlockId, TransactionId, UncleId, StateOrBlock, StateClient, StateInfo, Call, EngineInfo, ProvingBlockChainClient}; use ethcore::miner::{self, MinerService}; use ethcore::snapshot::SnapshotService; @@ -41,6 +40,7 @@ use jsonrpc_core::{BoxFuture, Result}; use jsonrpc_core::futures::future; use v1::helpers::{self, errors, limit_logs, fake_sign}; +use v1::helpers::deprecated::{self, DeprecationNotice}; use v1::helpers::dispatch::{FullDispatcher, default_gas_price}; use v1::helpers::block_import::is_major_importing; use v1::traits::Eth; @@ -105,11 +105,12 @@ pub struct EthClient where client: Arc, snapshot: Arc, sync: Arc, - accounts: Arc, + accounts: Arc Vec

+ Send + Sync>, miner: Arc, external_miner: Arc, seed_compute: Mutex, options: EthClientOptions, + deprecation_notice: DeprecationNotice, } #[derive(Debug)] @@ -184,7 +185,7 @@ impl EthClient, snapshot: &Arc, sync: &Arc, - accounts: &Arc, + accounts: &Arc Vec
+ Send + Sync>, miner: &Arc, em: &Arc, options: EthClientOptions @@ -198,6 +199,7 @@ impl EthClient Eth for EthClient< fn author(&self) -> Result { let miner = self.miner.authoring_params().author; if miner == 0.into() { - self.accounts.accounts() - .ok() - .and_then(|a| a.first().cloned()) + (self.accounts)() + .first() + .cloned() .map(From::from) .ok_or_else(|| errors::account("No accounts were found", "")) } else { @@ -558,8 +560,9 @@ impl Eth for EthClient< } fn accounts(&self) -> Result> { - let accounts = self.accounts.accounts() - .map_err(|e| errors::account("Could not fetch accounts.", e))?; + self.deprecation_notice.print("eth_accounts", deprecated::msgs::ACCOUNTS); + + let accounts = (self.accounts)(); Ok(accounts.into_iter().map(Into::into).collect()) } @@ -593,7 +596,7 @@ impl Eth for EthClient< BlockNumber::Earliest => BlockId::Earliest, BlockNumber::Latest => BlockId::Latest, BlockNumber::Pending => { - warn!("`Pending` is deprecated and may be removed in future versions. Falling back to `Latest`"); + self.deprecation_notice.print("`Pending`", Some("falling back to `Latest`")); BlockId::Latest } }; diff --git a/rpc/src/v1/impls/light/eth.rs b/rpc/src/v1/impls/light/eth.rs index 914b05f964..2dd1943bee 100644 --- a/rpc/src/v1/impls/light/eth.rs +++ b/rpc/src/v1/impls/light/eth.rs @@ -28,8 +28,7 @@ use light::client::LightChainClient; use light::{cht, TransactionQueue}; use light::on_demand::{request, OnDemand}; -use ethcore::account_provider::AccountProvider; -use ethereum_types::U256; +use ethereum_types::{U256, Address}; use hash::{KECCAK_NULL_RLP, KECCAK_EMPTY_LIST_RLP}; use parking_lot::{RwLock, Mutex}; use rlp::Rlp; @@ -42,6 +41,7 @@ use types::ids::BlockId; use v1::impls::eth_filter::Filterable; use v1::helpers::{errors, limit_logs}; use v1::helpers::{SyncPollFilter, PollManager}; +use v1::helpers::deprecated::{self, DeprecationNotice}; use v1::helpers::light_fetch::{self, LightFetch}; use v1::traits::Eth; use v1::types::{ @@ -60,11 +60,12 @@ pub struct EthClient { client: Arc, on_demand: Arc, transaction_queue: Arc>, - accounts: Arc, + accounts: Arc Vec
+ Send + Sync>, cache: Arc>, polls: Mutex>, poll_lifetime: u32, gas_price_percentile: usize, + deprecation_notice: DeprecationNotice, } impl Clone for EthClient { @@ -80,6 +81,7 @@ impl Clone for EthClient { polls: Mutex::new(PollManager::new(self.poll_lifetime)), poll_lifetime: self.poll_lifetime, gas_price_percentile: self.gas_price_percentile, + deprecation_notice: Default::default(), } } } @@ -92,7 +94,7 @@ impl EthClient { client: Arc, on_demand: Arc, transaction_queue: Arc>, - accounts: Arc, + accounts: Arc Vec
+ Send + Sync>, cache: Arc>, gas_price_percentile: usize, poll_lifetime: u32 @@ -107,6 +109,7 @@ impl EthClient { polls: Mutex::new(PollManager::new(poll_lifetime)), poll_lifetime, gas_price_percentile, + deprecation_notice: Default::default(), } } @@ -235,9 +238,9 @@ impl Eth for EthClient { } fn author(&self) -> Result { - self.accounts.accounts() - .ok() - .and_then(|a| a.first().cloned()) + (self.accounts)() + .first() + .cloned() .map(From::from) .ok_or_else(|| errors::account("No accounts were found", "")) } @@ -262,9 +265,12 @@ impl Eth for EthClient { } fn accounts(&self) -> Result> { - self.accounts.accounts() - .map_err(|e| errors::account("Could not fetch accounts.", e)) - .map(|accs| accs.into_iter().map(Into::::into).collect()) + self.deprecation_notice.print("eth_accounts", deprecated::msgs::ACCOUNTS); + + Ok((self.accounts)() + .into_iter() + .map(Into::into) + .collect()) } fn block_number(&self) -> Result { diff --git a/rpc/src/v1/impls/light/parity.rs b/rpc/src/v1/impls/light/parity.rs index 8a19232c12..3bb88b509e 100644 --- a/rpc/src/v1/impls/light/parity.rs +++ b/rpc/src/v1/impls/light/parity.rs @@ -16,7 +16,7 @@ //! Parity-specific rpc implementation. use std::sync::Arc; -use std::collections::{BTreeMap, HashSet}; +use std::collections::BTreeMap; use version::version_data; @@ -24,12 +24,12 @@ use crypto::DEFAULT_MAC; use ethkey::{crypto::ecies, Brain, Generator}; use ethstore::random_phrase; use sync::LightSyncProvider; -use ethcore::account_provider::AccountProvider; use ethcore_logger::RotatingLogger; use jsonrpc_core::{Result, BoxFuture}; use jsonrpc_core::futures::{future, Future}; -use v1::helpers::{self, errors, ipfs, SigningQueue, SignerService, NetworkSettings, verify_signature}; +use v1::helpers::{self, errors, ipfs, NetworkSettings, verify_signature}; +use v1::helpers::external_signer::{SignerService, SigningQueue}; use v1::helpers::dispatch::LightDispatcher; use v1::helpers::light_fetch::{LightFetch, light_all_transactions}; use v1::metadata::Metadata; @@ -40,7 +40,7 @@ use v1::types::{ TransactionStats, LocalTransactionStatus, LightBlockNumber, ChainStatus, Receipt, BlockNumber, ConsensusCapability, VersionInfo, - OperationsInfo, AccountInfo, HwAccountInfo, Header, RichHeader, RecoveredAccount, + OperationsInfo, Header, RichHeader, RecoveredAccount, Log, Filter, }; use Host; @@ -48,7 +48,6 @@ use Host; /// Parity implementation for light client. pub struct ParityClient { light_dispatch: Arc, - accounts: Arc, logger: Arc, settings: Arc, signer: Option>, @@ -60,7 +59,6 @@ impl ParityClient { /// Creates new `ParityClient`. pub fn new( light_dispatch: Arc, - accounts: Arc, logger: Arc, settings: Arc, signer: Option>, @@ -69,7 +67,6 @@ impl ParityClient { ) -> Self { ParityClient { light_dispatch, - accounts, logger, settings, signer, @@ -93,49 +90,6 @@ impl ParityClient { impl Parity for ParityClient { type Metadata = Metadata; - fn accounts_info(&self) -> Result> { - let store = &self.accounts; - let dapp_accounts = store - .accounts() - .map_err(|e| errors::account("Could not fetch accounts.", e))? - .into_iter().collect::>(); - - let info = store.accounts_info().map_err(|e| errors::account("Could not fetch account info.", e))?; - let other = store.addresses_info(); - - Ok(info - .into_iter() - .chain(other.into_iter()) - .filter(|&(ref a, _)| dapp_accounts.contains(a)) - .map(|(a, v)| (H160::from(a), AccountInfo { name: v.name })) - .collect() - ) - } - - fn hardware_accounts_info(&self) -> Result> { - let store = &self.accounts; - let info = store.hardware_accounts_info().map_err(|e| errors::account("Could not fetch account info.", e))?; - Ok(info - .into_iter() - .map(|(a, v)| (H160::from(a), HwAccountInfo { name: v.name, manufacturer: v.meta })) - .collect() - ) - } - - fn locked_hardware_accounts_info(&self) -> Result> { - let store = &self.accounts; - Ok(store.locked_hardware_accounts().map_err(|e| errors::account("Error communicating with hardware wallet.", e))?) - } - - fn default_account(&self) -> Result { - Ok(self.accounts - .accounts() - .ok() - .and_then(|accounts| accounts.get(0).cloned()) - .map(|acc| acc.into()) - .unwrap_or_default()) - } - fn transactions_limit(&self) -> Result { Ok(usize::max_value()) } diff --git a/rpc/src/v1/impls/light/parity_set.rs b/rpc/src/v1/impls/light/parity_set.rs index 08e386fe5d..c7bd7da17a 100644 --- a/rpc/src/v1/impls/light/parity_set.rs +++ b/rpc/src/v1/impls/light/parity_set.rs @@ -67,7 +67,7 @@ impl ParitySet for ParitySetClient { Err(errors::light_unimplemented(None)) } - fn set_engine_signer(&self, _address: H160, _password: String) -> Result { + fn set_engine_signer_secret(&self, _secret: H256) -> Result { Err(errors::light_unimplemented(None)) } diff --git a/rpc/src/v1/impls/mod.rs b/rpc/src/v1/impls/mod.rs index 5e334a3b6d..ba1cc100e8 100644 --- a/rpc/src/v1/impls/mod.rs +++ b/rpc/src/v1/impls/mod.rs @@ -22,12 +22,15 @@ mod eth_filter; mod eth_pubsub; mod net; mod parity; +#[cfg(any(test, feature = "accounts"))] mod parity_accounts; mod parity_set; +#[cfg(any(test, feature = "accounts"))] mod personal; mod private; mod pubsub; mod rpc; +#[cfg(any(test, feature = "accounts"))] mod secretstore; mod signer; mod signing; @@ -43,12 +46,17 @@ pub use self::eth_filter::EthFilterClient; pub use self::eth_pubsub::EthPubSubClient; pub use self::net::NetClient; pub use self::parity::ParityClient; +#[cfg(any(test, feature = "accounts"))] pub use self::parity_accounts::ParityAccountsClient; pub use self::parity_set::ParitySetClient; +#[cfg(any(test, feature = "accounts"))] +pub use self::parity_set::accounts::ParitySetAccountsClient; +#[cfg(any(test, feature = "accounts"))] pub use self::personal::PersonalClient; pub use self::private::PrivateClient; pub use self::pubsub::PubSubClient; pub use self::rpc::RpcClient; +#[cfg(any(test, feature = "accounts"))] pub use self::secretstore::SecretStoreClient; pub use self::signer::SignerClient; pub use self::signing::SigningQueueClient; diff --git a/rpc/src/v1/impls/parity.rs b/rpc/src/v1/impls/parity.rs index 60a7bd83d5..648b410694 100644 --- a/rpc/src/v1/impls/parity.rs +++ b/rpc/src/v1/impls/parity.rs @@ -17,18 +17,15 @@ //! Parity-specific rpc implementation. use std::sync::Arc; use std::str::FromStr; -use std::collections::{BTreeMap, HashSet}; - -use ethereum_types::Address; -use version::version_data; +use std::collections::BTreeMap; use crypto::DEFAULT_MAC; -use ethcore::account_provider::AccountProvider; use ethcore::client::{BlockChainClient, StateClient, Call}; use ethcore::miner::{self, MinerService}; use ethcore::snapshot::{SnapshotService, RestorationStatus}; use ethcore::state::StateInfo; use ethcore_logger::RotatingLogger; +use ethereum_types::Address; use ethkey::{crypto::ecies, Brain, Generator}; use ethstore::random_phrase; use jsonrpc_core::futures::future; @@ -36,9 +33,11 @@ use jsonrpc_core::{BoxFuture, Result}; use sync::{SyncProvider, ManageNetwork}; use types::ids::BlockId; use updater::{Service as UpdateService}; +use version::version_data; use v1::helpers::block_import::is_major_importing; -use v1::helpers::{self, errors, fake_sign, ipfs, SigningQueue, SignerService, NetworkSettings, verify_signature}; +use v1::helpers::{self, errors, fake_sign, ipfs, NetworkSettings, verify_signature}; +use v1::helpers::external_signer::{SigningQueue, SignerService}; use v1::metadata::Metadata; use v1::traits::Parity; use v1::types::{ @@ -47,7 +46,7 @@ use v1::types::{ TransactionStats, LocalTransactionStatus, BlockNumber, ConsensusCapability, VersionInfo, OperationsInfo, ChainStatus, Log, Filter, - AccountInfo, HwAccountInfo, RichHeader, Receipt, RecoveredAccount, + RichHeader, Receipt, RecoveredAccount, block_number_to_id }; use Host; @@ -59,7 +58,6 @@ pub struct ParityClient { updater: Arc, sync: Arc, net: Arc, - accounts: Arc, logger: Arc, settings: Arc, signer: Option>, @@ -77,7 +75,6 @@ impl ParityClient where sync: Arc, updater: Arc, net: Arc, - accounts: Arc, logger: Arc, settings: Arc, signer: Option>, @@ -90,7 +87,6 @@ impl ParityClient where sync, updater, net, - accounts, logger, settings, signer, @@ -108,43 +104,6 @@ impl Parity for ParityClient where { type Metadata = Metadata; - fn accounts_info(&self) -> Result> { - let dapp_accounts = self.accounts.accounts() - .map_err(|e| errors::account("Could not fetch accounts.", e))? - .into_iter().collect::>(); - - let info = self.accounts.accounts_info().map_err(|e| errors::account("Could not fetch account info.", e))?; - let other = self.accounts.addresses_info(); - - Ok(info - .into_iter() - .chain(other.into_iter()) - .filter(|&(ref a, _)| dapp_accounts.contains(a)) - .map(|(a, v)| (H160::from(a), AccountInfo { name: v.name })) - .collect() - ) - } - - fn hardware_accounts_info(&self) -> Result> { - let info = self.accounts.hardware_accounts_info().map_err(|e| errors::account("Could not fetch account info.", e))?; - Ok(info - .into_iter() - .map(|(a, v)| (H160::from(a), HwAccountInfo { name: v.name, manufacturer: v.meta })) - .collect() - ) - } - - fn locked_hardware_accounts_info(&self) -> Result> { - self.accounts.locked_hardware_accounts().map_err(|e| errors::account("Error communicating with hardware wallet.", e)) - } - - fn default_account(&self) -> Result { - Ok(self.accounts.default_account() - .map(Into::into) - .ok() - .unwrap_or_default()) - } - fn transactions_limit(&self) -> Result { Ok(self.miner.queue_status().limits.max_count) } diff --git a/rpc/src/v1/impls/parity_accounts.rs b/rpc/src/v1/impls/parity_accounts.rs index f1038077e3..55f23dded7 100644 --- a/rpc/src/v1/impls/parity_accounts.rs +++ b/rpc/src/v1/impls/parity_accounts.rs @@ -16,21 +16,29 @@ //! Account management (personal) rpc implementation use std::sync::Arc; -use std::collections::btree_map::{BTreeMap, Entry}; +use std::collections::{ + btree_map::{BTreeMap, Entry}, + HashSet, +}; use ethereum_types::Address; use ethkey::{Brain, Generator, Secret}; use ethstore::KeyFile; -use ethcore::account_provider::AccountProvider; +use accounts::AccountProvider; use jsonrpc_core::Result; +use v1::helpers::deprecated::{self, DeprecationNotice}; use v1::helpers::errors; -use v1::traits::ParityAccounts; -use v1::types::{H160 as RpcH160, H256 as RpcH256, H520 as RpcH520, Derive, DeriveHierarchical, DeriveHash, ExtAccountInfo}; +use v1::traits::{ParityAccounts, ParityAccountsInfo}; +use v1::types::{ + H160 as RpcH160, H256 as RpcH256, H520 as RpcH520, Derive, DeriveHierarchical, DeriveHash, + ExtAccountInfo, AccountInfo, HwAccountInfo, +}; use ethkey::Password; /// Account management (personal) rpc implementation. pub struct ParityAccountsClient { accounts: Arc, + deprecation_notice: DeprecationNotice, } impl ParityAccountsClient { @@ -38,12 +46,68 @@ impl ParityAccountsClient { pub fn new(store: &Arc) -> Self { ParityAccountsClient { accounts: store.clone(), + deprecation_notice: Default::default(), } } } +impl ParityAccountsClient { + fn deprecation_notice(&self, method: &'static str) { + self.deprecation_notice.print(method, deprecated::msgs::ACCOUNTS); + } +} + +impl ParityAccountsInfo for ParityAccountsClient { + fn accounts_info(&self) -> Result> { + self.deprecation_notice("parity_accountsInfo"); + + let dapp_accounts = self.accounts.accounts() + .map_err(|e| errors::account("Could not fetch accounts.", e))? + .into_iter().collect::>(); + + let info = self.accounts.accounts_info().map_err(|e| errors::account("Could not fetch account info.", e))?; + let other = self.accounts.addresses_info(); + + Ok(info + .into_iter() + .chain(other.into_iter()) + .filter(|&(ref a, _)| dapp_accounts.contains(a)) + .map(|(a, v)| (RpcH160::from(a), AccountInfo { name: v.name })) + .collect() + ) + } + + fn hardware_accounts_info(&self) -> Result> { + self.deprecation_notice("parity_hardwareAccountsInfo"); + + let info = self.accounts.hardware_accounts_info().map_err(|e| errors::account("Could not fetch account info.", e))?; + Ok(info + .into_iter() + .map(|(a, v)| (RpcH160::from(a), HwAccountInfo { name: v.name, manufacturer: v.meta })) + .collect() + ) + } + + fn locked_hardware_accounts_info(&self) -> Result> { + self.deprecation_notice("parity_lockedHardwareAccountsInfo"); + + self.accounts.locked_hardware_accounts().map_err(|e| errors::account("Error communicating with hardware wallet.", e)) + } + + fn default_account(&self) -> Result { + self.deprecation_notice("parity_defaultAccount"); + + Ok(self.accounts.default_account() + .map(Into::into) + .ok() + .unwrap_or_default()) + } +} + impl ParityAccounts for ParityAccountsClient { fn all_accounts_info(&self) -> Result> { + self.deprecation_notice("parity_allAccountsInfo"); + let info = self.accounts.accounts_info().map_err(|e| errors::account("Could not fetch account info.", e))?; let other = self.accounts.addresses_info(); @@ -75,6 +139,8 @@ impl ParityAccounts for ParityAccountsClient { } fn new_account_from_phrase(&self, phrase: String, pass: Password) -> Result { + self.deprecation_notice("parity_newAccountFromPhrase"); + let brain = Brain::new(phrase).generate().unwrap(); self.accounts.insert_account(brain.secret().clone(), &pass) .map(Into::into) @@ -82,6 +148,8 @@ impl ParityAccounts for ParityAccountsClient { } fn new_account_from_wallet(&self, json: String, pass: Password) -> Result { + self.deprecation_notice("parity_newAccountFromWallet"); + self.accounts.import_presale(json.as_bytes(), &pass) .or_else(|_| self.accounts.import_wallet(json.as_bytes(), &pass, true)) .map(Into::into) @@ -89,6 +157,8 @@ impl ParityAccounts for ParityAccountsClient { } fn new_account_from_secret(&self, secret: RpcH256, pass: Password) -> Result { + self.deprecation_notice("parity_newAccountFromSecret"); + let secret = Secret::from_unsafe_slice(&secret.0) .map_err(|e| errors::account("Could not create account.", e))?; self.accounts.insert_account(secret, &pass) @@ -97,6 +167,8 @@ impl ParityAccounts for ParityAccountsClient { } fn test_password(&self, account: RpcH160, password: Password) -> Result { + self.deprecation_notice("parity_testPassword"); + let account: Address = account.into(); self.accounts @@ -105,6 +177,8 @@ impl ParityAccounts for ParityAccountsClient { } fn change_password(&self, account: RpcH160, password: Password, new_password: Password) -> Result { + self.deprecation_notice("parity_changePassword"); + let account: Address = account.into(); self.accounts .change_password(&account, password, new_password) @@ -113,6 +187,8 @@ impl ParityAccounts for ParityAccountsClient { } fn kill_account(&self, account: RpcH160, password: Password) -> Result { + self.deprecation_notice("parity_killAccount"); + let account: Address = account.into(); self.accounts .kill_account(&account, &password) @@ -121,6 +197,8 @@ impl ParityAccounts for ParityAccountsClient { } fn remove_address(&self, addr: RpcH160) -> Result { + self.deprecation_notice("parity_removeAddresss"); + let addr: Address = addr.into(); self.accounts.remove_address(addr); @@ -128,6 +206,8 @@ impl ParityAccounts for ParityAccountsClient { } fn set_account_name(&self, addr: RpcH160, name: String) -> Result { + self.deprecation_notice("parity_setAccountName"); + let addr: Address = addr.into(); self.accounts.set_account_name(addr.clone(), name.clone()) @@ -136,6 +216,8 @@ impl ParityAccounts for ParityAccountsClient { } fn set_account_meta(&self, addr: RpcH160, meta: String) -> Result { + self.deprecation_notice("parity_setAccountMeta"); + let addr: Address = addr.into(); self.accounts.set_account_meta(addr.clone(), meta.clone()) @@ -144,6 +226,8 @@ impl ParityAccounts for ParityAccountsClient { } fn import_geth_accounts(&self, addresses: Vec) -> Result> { + self.deprecation_notice("parity_importGethAccounts"); + self.accounts .import_geth_accounts(into_vec(addresses), false) .map(into_vec) @@ -151,10 +235,14 @@ impl ParityAccounts for ParityAccountsClient { } fn geth_accounts(&self) -> Result> { + self.deprecation_notice("parity_listGethAccounts"); + Ok(into_vec(self.accounts.list_geth_accounts(false))) } fn create_vault(&self, name: String, password: Password) -> Result { + self.deprecation_notice("parity_newVault"); + self.accounts .create_vault(&name, &password) .map_err(|e| errors::account("Could not create vault.", e)) @@ -162,6 +250,8 @@ impl ParityAccounts for ParityAccountsClient { } fn open_vault(&self, name: String, password: Password) -> Result { + self.deprecation_notice("parity_openVault"); + self.accounts .open_vault(&name, &password) .map_err(|e| errors::account("Could not open vault.", e)) @@ -169,6 +259,8 @@ impl ParityAccounts for ParityAccountsClient { } fn close_vault(&self, name: String) -> Result { + self.deprecation_notice("parity_closeVault"); + self.accounts .close_vault(&name) .map_err(|e| errors::account("Could not close vault.", e)) @@ -176,18 +268,24 @@ impl ParityAccounts for ParityAccountsClient { } fn list_vaults(&self) -> Result> { + self.deprecation_notice("parity_listVaults"); + self.accounts .list_vaults() .map_err(|e| errors::account("Could not list vaults.", e)) } fn list_opened_vaults(&self) -> Result> { + self.deprecation_notice("parity_listOpenedVaults"); + self.accounts .list_opened_vaults() .map_err(|e| errors::account("Could not list vaults.", e)) } fn change_vault_password(&self, name: String, new_password: Password) -> Result { + self.deprecation_notice("parity_changeVaultPassword"); + self.accounts .change_vault_password(&name, &new_password) .map_err(|e| errors::account("Could not change vault password.", e)) @@ -195,6 +293,8 @@ impl ParityAccounts for ParityAccountsClient { } fn change_vault(&self, address: RpcH160, new_vault: String) -> Result { + self.deprecation_notice("parity_changeVault"); + self.accounts .change_vault(address.into(), &new_vault) .map_err(|e| errors::account("Could not change vault.", e)) @@ -202,12 +302,16 @@ impl ParityAccounts for ParityAccountsClient { } fn get_vault_meta(&self, name: String) -> Result { + self.deprecation_notice("parity_getVaultMeta"); + self.accounts .get_vault_meta(&name) .map_err(|e| errors::account("Could not get vault metadata.", e)) } fn set_vault_meta(&self, name: String, meta: String) -> Result { + self.deprecation_notice("parity_setVaultMeta"); + self.accounts .set_vault_meta(&name, &meta) .map_err(|e| errors::account("Could not update vault metadata.", e)) @@ -215,6 +319,8 @@ impl ParityAccounts for ParityAccountsClient { } fn derive_key_index(&self, addr: RpcH160, password: Password, derivation: DeriveHierarchical, save_as_account: bool) -> Result { + self.deprecation_notice("parity_deriveAddressIndex"); + let addr: Address = addr.into(); self.accounts .derive_account( @@ -228,6 +334,8 @@ impl ParityAccounts for ParityAccountsClient { } fn derive_key_hash(&self, addr: RpcH160, password: Password, derivation: DeriveHash, save_as_account: bool) -> Result { + self.deprecation_notice("parity_deriveAddressHash"); + let addr: Address = addr.into(); self.accounts .derive_account( @@ -241,6 +349,8 @@ impl ParityAccounts for ParityAccountsClient { } fn export_account(&self, addr: RpcH160, password: Password) -> Result { + self.deprecation_notice("parity_exportAccount"); + let addr = addr.into(); self.accounts .export_account( @@ -252,6 +362,8 @@ impl ParityAccounts for ParityAccountsClient { } fn sign_message(&self, addr: RpcH160, password: Password, message: RpcH256) -> Result { + self.deprecation_notice("parity_signMessage"); + self.accounts .sign( addr.into(), @@ -263,6 +375,8 @@ impl ParityAccounts for ParityAccountsClient { } fn hardware_pin_matrix_ack(&self, path: String, pin: String) -> Result { + self.deprecation_notice("parity_hardwarePinMatrixAck"); + self.accounts.hardware_pin_matrix_ack(&path, &pin).map_err(|e| errors::account("Error communicating with hardware wallet.", e)) } } diff --git a/rpc/src/v1/impls/parity_set.rs b/rpc/src/v1/impls/parity_set.rs index fbd69230aa..fc839d621a 100644 --- a/rpc/src/v1/impls/parity_set.rs +++ b/rpc/src/v1/impls/parity_set.rs @@ -20,10 +20,12 @@ use std::sync::Arc; use std::time::Duration; use ethcore::client::{BlockChainClient, Mode}; -use ethcore::miner::MinerService; -use sync::ManageNetwork; +use ethcore::miner::{self, MinerService}; +use ethereum_types::H256 as EthH256; +use ethkey; use fetch::{self, Fetch}; use hash::keccak_buffer; +use sync::ManageNetwork; use updater::{Service as UpdateService}; use jsonrpc_core::{BoxFuture, Result}; @@ -32,6 +34,53 @@ use v1::helpers::errors; use v1::traits::ParitySet; use v1::types::{Bytes, H160, H256, U256, ReleaseInfo, Transaction}; +#[cfg(any(test, feature = "accounts"))] +pub mod accounts { + use super::*; + use accounts::AccountProvider; + use v1::traits::ParitySetAccounts; + use v1::helpers::deprecated::DeprecationNotice; + use v1::helpers::engine_signer::EngineSigner; + + /// Parity-specific account-touching RPC interfaces. + pub struct ParitySetAccountsClient { + miner: Arc, + accounts: Arc, + deprecation_notice: DeprecationNotice, + } + + impl ParitySetAccountsClient { + /// Creates new ParitySetAccountsClient + pub fn new( + accounts: &Arc, + miner: &Arc, + ) -> Self { + ParitySetAccountsClient { + accounts: accounts.clone(), + miner: miner.clone(), + deprecation_notice: Default::default(), + } + } + } + + impl ParitySetAccounts for ParitySetAccountsClient { + fn set_engine_signer(&self, address: H160, password: String) -> Result { + self.deprecation_notice.print( + "parity_setEngineSigner", + "use `parity_setEngineSignerSecret` instead. See #9997 for context." + ); + + let signer = Box::new(EngineSigner::new( + self.accounts.clone(), + address.clone().into(), + password.into(), + )); + self.miner.set_author(miner::Author::Sealer(signer)); + Ok(true) + } + } +} + /// Parity-specific rpc interface for operations altering the settings. pub struct ParitySetClient { client: Arc, @@ -57,7 +106,7 @@ impl ParitySetClient miner: miner.clone(), updater: updater.clone(), net: net.clone(), - fetch: fetch, + fetch, } } } @@ -104,12 +153,14 @@ impl ParitySet for ParitySetClient where } fn set_author(&self, address: H160) -> Result { - self.miner.set_author(address.into(), None).map_err(Into::into).map_err(errors::password)?; + self.miner.set_author(miner::Author::External(address.into())); Ok(true) } - fn set_engine_signer(&self, address: H160, password: String) -> Result { - self.miner.set_author(address.into(), Some(password.into())).map_err(Into::into).map_err(errors::password)?; + fn set_engine_signer_secret(&self, secret: H256) -> Result { + let secret: EthH256 = secret.into(); + let keypair = ethkey::KeyPair::from_secret(secret.into()).map_err(|e| errors::account("Invalid secret", e))?; + self.miner.set_author(miner::Author::Sealer(ethcore::engines::signer::from_keypair(keypair))); Ok(true) } diff --git a/rpc/src/v1/impls/personal.rs b/rpc/src/v1/impls/personal.rs index 3bae576c06..92886cbe31 100644 --- a/rpc/src/v1/impls/personal.rs +++ b/rpc/src/v1/impls/personal.rs @@ -18,17 +18,20 @@ use std::sync::Arc; use std::time::Duration; +use accounts::AccountProvider; use bytes::Bytes; -use ethcore::account_provider::AccountProvider; - -use types::transaction::{PendingTransaction, SignedTransaction}; +use eip_712::{EIP712, hash_structured_data}; use ethereum_types::{H520, U128, Address}; use ethkey::{public_to_address, recover, Signature}; +use types::transaction::{PendingTransaction, SignedTransaction}; -use jsonrpc_core::{BoxFuture, Result}; use jsonrpc_core::futures::{future, Future}; -use v1::helpers::{errors, eip191}; +use jsonrpc_core::types::Value; +use jsonrpc_core::{BoxFuture, Result}; +use v1::helpers::deprecated::{self, DeprecationNotice}; use v1::helpers::dispatch::{self, eth_data_hash, Dispatcher, SignWith, PostSign, WithToken}; +use v1::helpers::{errors, eip191}; +use v1::metadata::Metadata; use v1::traits::Personal; use v1::types::{ H160 as RpcH160, H256 as RpcH256, H520 as RpcH520, U128 as RpcU128, @@ -39,9 +42,6 @@ use v1::types::{ RichRawTransaction as RpcRichRawTransaction, EIP191Version, }; -use v1::metadata::Metadata; -use eip_712::{EIP712, hash_structured_data}; -use jsonrpc_core::types::Value; /// Account management (personal) rpc implementation. pub struct PersonalClient { @@ -49,6 +49,7 @@ pub struct PersonalClient { dispatcher: D, allow_perm_unlock: bool, allow_experimental_rpcs: bool, + deprecation_notice: DeprecationNotice, } impl PersonalClient { @@ -64,6 +65,7 @@ impl PersonalClient { dispatcher, allow_perm_unlock, allow_experimental_rpcs, + deprecation_notice: DeprecationNotice::default(), } } } @@ -94,9 +96,10 @@ impl PersonalClient { Err(e) => return Box::new(future::err(e)), }; + let accounts = Arc::new(dispatch::Signer::new(accounts)) as _; Box::new(dispatcher.fill_optional_fields(request.into(), default, false) .and_then(move |filled| { - dispatcher.sign(accounts, filled, SignWith::Password(password.into()), post_sign) + dispatcher.sign(filled, &accounts, SignWith::Password(password.into()), post_sign) }) ) } @@ -106,17 +109,23 @@ impl Personal for PersonalClient { type Metadata = Metadata; fn accounts(&self) -> Result> { + self.deprecation_notice.print("personal_accounts", deprecated::msgs::ACCOUNTS); + let accounts = self.accounts.accounts().map_err(|e| errors::account("Could not fetch accounts.", e))?; Ok(accounts.into_iter().map(Into::into).collect::>()) } fn new_account(&self, pass: String) -> Result { + self.deprecation_notice.print("personal_newAccount", deprecated::msgs::ACCOUNTS); + self.accounts.new_account(&pass.into()) .map(Into::into) .map_err(|e| errors::account("Could not create account.", e)) } fn unlock_account(&self, account: RpcH160, account_pass: String, duration: Option) -> Result { + self.deprecation_notice.print("personal_unlockAccount", deprecated::msgs::ACCOUNTS); + let account: Address = account.into(); let store = self.accounts.clone(); let duration = match duration { @@ -149,14 +158,16 @@ impl Personal for PersonalClient { } fn sign(&self, data: RpcBytes, account: RpcH160, password: String) -> BoxFuture { + self.deprecation_notice.print("personal_sign", deprecated::msgs::ACCOUNTS); + let dispatcher = self.dispatcher.clone(); - let accounts = self.accounts.clone(); + let accounts = Arc::new(dispatch::Signer::new(self.accounts.clone())) as _; let payload = RpcConfirmationPayload::EthSignMessage((account.clone(), data).into()); Box::new(dispatch::from_rpc(payload, account.into(), &dispatcher) - .and_then(|payload| { - dispatch::execute(dispatcher, accounts, payload, dispatch::SignWith::Password(password.into())) + .and_then(move |payload| { + dispatch::execute(dispatcher, &accounts, payload, dispatch::SignWith::Password(password.into())) }) .map(|v| v.into_value()) .then(|res| match res { @@ -167,17 +178,19 @@ impl Personal for PersonalClient { } fn sign_191(&self, version: EIP191Version, data: Value, account: RpcH160, password: String) -> BoxFuture { + self.deprecation_notice.print("personal_sign191", deprecated::msgs::ACCOUNTS); + try_bf!(errors::require_experimental(self.allow_experimental_rpcs, "191")); let data = try_bf!(eip191::hash_message(version, data)); let dispatcher = self.dispatcher.clone(); - let accounts = self.accounts.clone(); + let accounts = Arc::new(dispatch::Signer::new(self.accounts.clone())) as _; let payload = RpcConfirmationPayload::EIP191SignMessage((account.clone(), data.into()).into()); Box::new(dispatch::from_rpc(payload, account.into(), &dispatcher) - .and_then(|payload| { - dispatch::execute(dispatcher, accounts, payload, dispatch::SignWith::Password(password.into())) + .and_then(move |payload| { + dispatch::execute(dispatcher, &accounts, payload, dispatch::SignWith::Password(password.into())) }) .map(|v| v.into_value()) .then(|res| match res { @@ -189,6 +202,8 @@ impl Personal for PersonalClient { } fn sign_typed_data(&self, typed_data: EIP712, account: RpcH160, password: String) -> BoxFuture { + self.deprecation_notice.print("personal_signTypedData", deprecated::msgs::ACCOUNTS); + try_bf!(errors::require_experimental(self.allow_experimental_rpcs, "712")); let data = match hash_structured_data(typed_data) { @@ -196,13 +211,13 @@ impl Personal for PersonalClient { Err(err) => return Box::new(future::err(errors::invalid_call_data(err.kind()))), }; let dispatcher = self.dispatcher.clone(); - let accounts = self.accounts.clone(); + let accounts = Arc::new(dispatch::Signer::new(self.accounts.clone())) as _; let payload = RpcConfirmationPayload::EIP191SignMessage((account.clone(), data.into()).into()); Box::new(dispatch::from_rpc(payload, account.into(), &dispatcher) - .and_then(|payload| { - dispatch::execute(dispatcher, accounts, payload, dispatch::SignWith::Password(password.into())) + .and_then(move |payload| { + dispatch::execute(dispatcher, &accounts, payload, dispatch::SignWith::Password(password.into())) }) .map(|v| v.into_value()) .then(|res| match res { @@ -229,6 +244,8 @@ impl Personal for PersonalClient { } fn sign_transaction(&self, meta: Metadata, request: TransactionRequest, password: String) -> BoxFuture { + self.deprecation_notice.print("personal_signTransaction", deprecated::msgs::ACCOUNTS); + let condition = request.condition.clone().map(Into::into); let dispatcher = self.dispatcher.clone(); Box::new(self.do_sign_transaction(meta, request, password, ()) @@ -237,24 +254,27 @@ impl Personal for PersonalClient { } fn send_transaction(&self, meta: Metadata, request: TransactionRequest, password: String) -> BoxFuture { + self.deprecation_notice.print("personal_sendTransaction", deprecated::msgs::ACCOUNTS); + let condition = request.condition.clone().map(Into::into); let dispatcher = self.dispatcher.clone(); - Box::new(self.do_sign_transaction(meta, request, password, move |signed: WithToken| { - dispatcher.dispatch_transaction( - PendingTransaction::new( - signed.into_value(), - condition + Box::new( + self.do_sign_transaction(meta, request, password, move |signed: WithToken| { + dispatcher.dispatch_transaction( + PendingTransaction::new( + signed.into_value(), + condition + ) ) - ) - }) - .and_then(|hash| { + }).and_then(|hash| { Ok(RpcH256::from(hash)) }) ) } fn sign_and_send_transaction(&self, meta: Metadata, request: TransactionRequest, password: String) -> BoxFuture { - warn!("Using deprecated personal_signAndSendTransaction, use personal_sendTransaction instead."); + self.deprecation_notice.print("personal_signAndSendTransaction", Some("use personal_sendTransaction instead.")); + self.send_transaction(meta, request, password) } } diff --git a/rpc/src/v1/impls/secretstore.rs b/rpc/src/v1/impls/secretstore.rs index f71de4e19f..8eb1c3d112 100644 --- a/rpc/src/v1/impls/secretstore.rs +++ b/rpc/src/v1/impls/secretstore.rs @@ -21,7 +21,7 @@ use std::sync::Arc; use crypto::DEFAULT_MAC; use ethkey::Secret; -use ethcore::account_provider::AccountProvider; +use accounts::AccountProvider; use jsonrpc_core::Result; use v1::helpers::errors; diff --git a/rpc/src/v1/impls/signer.rs b/rpc/src/v1/impls/signer.rs index 64e91e09f2..152a16d4b3 100644 --- a/rpc/src/v1/impls/signer.rs +++ b/rpc/src/v1/impls/signer.rs @@ -18,7 +18,6 @@ use std::sync::Arc; -use ethcore::account_provider::AccountProvider; use ethkey; use parity_runtime::Executor; use parking_lot::Mutex; @@ -29,8 +28,10 @@ use jsonrpc_core::{Result, BoxFuture, Error}; use jsonrpc_core::futures::{future, Future, IntoFuture}; use jsonrpc_core::futures::future::Either; use jsonrpc_pubsub::{SubscriptionId, typed::{Sink, Subscriber}}; +use v1::helpers::deprecated::{self, DeprecationNotice}; use v1::helpers::dispatch::{self, Dispatcher, WithToken, eth_data_hash}; -use v1::helpers::{errors, SignerService, SigningQueue, ConfirmationPayload, FilledTransactionRequest, Subscribers}; +use v1::helpers::{errors, ConfirmationPayload, FilledTransactionRequest, Subscribers}; +use v1::helpers::external_signer::{SigningQueue, SignerService}; use v1::metadata::Metadata; use v1::traits::Signer; use v1::types::{TransactionModification, ConfirmationRequest, ConfirmationResponse, ConfirmationResponseWithToken, U256, Bytes}; @@ -38,15 +39,16 @@ use v1::types::{TransactionModification, ConfirmationRequest, ConfirmationRespon /// Transactions confirmation (personal) rpc implementation. pub struct SignerClient { signer: Arc, - accounts: Arc, + accounts: Arc, dispatcher: D, subscribers: Arc>>>>, + deprecation_notice: DeprecationNotice, } impl SignerClient { /// Create new instance of signer client. pub fn new( - store: &Arc, + accounts: Arc, dispatcher: D, signer: &Arc, executor: Executor, @@ -70,14 +72,15 @@ impl SignerClient { SignerClient { signer: signer.clone(), - accounts: store.clone(), + accounts: accounts.clone(), dispatcher, subscribers, + deprecation_notice: Default::default(), } } fn confirm_internal(&self, id: U256, modification: TransactionModification, f: F) -> BoxFuture> where - F: FnOnce(D, Arc, ConfirmationPayload) -> T, + F: FnOnce(D, &Arc, ConfirmationPayload) -> T, T: IntoFuture, Error=Error>, T::Future: Send + 'static { @@ -104,7 +107,7 @@ impl SignerClient { request.condition = condition.clone().map(Into::into); } } - let fut = f(dispatcher, self.accounts.clone(), payload); + let fut = f(dispatcher, &self.accounts, payload); Either::A(fut.into_future().then(move |result| { // Execute if let Ok(ref response) = result { @@ -155,6 +158,8 @@ impl Signer for SignerClient { type Metadata = Metadata; fn requests_to_confirm(&self) -> Result> { + self.deprecation_notice.print("signer_requestsToConfirm", deprecated::msgs::ACCOUNTS); + Ok(self.signer.requests() .into_iter() .map(Into::into) @@ -167,6 +172,8 @@ impl Signer for SignerClient { fn confirm_request(&self, id: U256, modification: TransactionModification, pass: String) -> BoxFuture { + self.deprecation_notice.print("signer_confirmRequest", deprecated::msgs::ACCOUNTS); + Box::new(self.confirm_internal(id, modification, move |dis, accounts, payload| { dispatch::execute(dis, accounts, payload, dispatch::SignWith::Password(pass.into())) }).map(|v| v.into_value())) @@ -175,6 +182,8 @@ impl Signer for SignerClient { fn confirm_request_with_token(&self, id: U256, modification: TransactionModification, token: String) -> BoxFuture { + self.deprecation_notice.print("signer_confirmRequestWithToken", deprecated::msgs::ACCOUNTS); + Box::new(self.confirm_internal(id, modification, move |dis, accounts, payload| { dispatch::execute(dis, accounts, payload, dispatch::SignWith::Token(token.into())) }).and_then(|v| match v { @@ -187,6 +196,8 @@ impl Signer for SignerClient { } fn confirm_request_raw(&self, id: U256, bytes: Bytes) -> Result { + self.deprecation_notice.print("signer_confirmRequestRaw", deprecated::msgs::ACCOUNTS); + let id = id.into(); self.signer.take(&id).map(|sender| { @@ -237,20 +248,22 @@ impl Signer for SignerClient { } fn reject_request(&self, id: U256) -> Result { + self.deprecation_notice.print("signer_rejectRequest", deprecated::msgs::ACCOUNTS); + let res = self.signer.take(&id.into()).map(|sender| self.signer.request_rejected(sender)); Ok(res.is_some()) } fn generate_token(&self) -> Result { + self.deprecation_notice.print("signer_generateAuthorizationToken", deprecated::msgs::ACCOUNTS); + self.signer.generate_token() .map_err(|e| errors::token(e)) } - fn generate_web_proxy_token(&self, domain: String) -> Result { - Ok(self.signer.generate_web_proxy_access_token(domain.into())) - } - fn subscribe_pending(&self, _meta: Self::Metadata, sub: Subscriber>) { + self.deprecation_notice.print("signer_subscribePending", deprecated::msgs::ACCOUNTS); + self.subscribers.lock().push(sub) } diff --git a/rpc/src/v1/impls/signing.rs b/rpc/src/v1/impls/signing.rs index c0ba955b7e..96d4059aa2 100644 --- a/rpc/src/v1/impls/signing.rs +++ b/rpc/src/v1/impls/signing.rs @@ -21,17 +21,18 @@ use transient_hashmap::TransientHashMap; use ethereum_types::U256; use parking_lot::Mutex; -use ethcore::account_provider::AccountProvider; - use jsonrpc_core::{BoxFuture, Result, Error}; use jsonrpc_core::futures::{future, Future, Poll, Async}; use jsonrpc_core::futures::future::Either; -use v1::helpers::{ - errors, DefaultAccount, SignerService, SigningQueue, + +use v1::helpers::deprecated::{self, DeprecationNotice}; +use v1::helpers::dispatch::{self, Dispatcher}; +use v1::helpers::errors; +use v1::helpers::external_signer::{ + SignerService, SigningQueue, ConfirmationReceiver as RpcConfirmationReceiver, ConfirmationResult as RpcConfirmationResult, }; -use v1::helpers::dispatch::{self, Dispatcher}; use v1::metadata::Metadata; use v1::traits::{EthSigning, ParitySigning}; use v1::types::{ @@ -89,38 +90,37 @@ fn schedule(executor: Executor, /// Implementation of functions that require signing when no trusted signer is used. pub struct SigningQueueClient { signer: Arc, - accounts: Arc, + accounts: Arc, dispatcher: D, executor: Executor, // None here means that the request hasn't yet been confirmed confirmations: Arc>>>, + deprecation_notice: DeprecationNotice, } impl SigningQueueClient { /// Creates a new signing queue client given shared signing queue. - pub fn new(signer: &Arc, dispatcher: D, executor: Executor, accounts: &Arc) -> Self { + pub fn new(signer: &Arc, dispatcher: D, executor: Executor, accounts: &Arc) -> Self { SigningQueueClient { signer: signer.clone(), accounts: accounts.clone(), dispatcher, executor, confirmations: Arc::new(Mutex::new(TransientHashMap::new(MAX_PENDING_DURATION_SEC))), + deprecation_notice: Default::default(), } } - fn dispatch(&self, payload: RpcConfirmationPayload, default_account: DefaultAccount, origin: Origin) -> BoxFuture { + fn dispatch(&self, payload: RpcConfirmationPayload, origin: Origin) -> BoxFuture { + let default_account = self.accounts.default_account(); let accounts = self.accounts.clone(); - let default_account = match default_account { - DefaultAccount::Provided(acc) => acc, - }; - let dispatcher = self.dispatcher.clone(); let signer = self.signer.clone(); Box::new(dispatch::from_rpc(payload, default_account, &dispatcher) .and_then(move |payload| { let sender = payload.sender(); if accounts.is_unlocked(&sender) { - Either::A(dispatch::execute(dispatcher, accounts, payload, dispatch::SignWith::Nothing) + Either::A(dispatch::execute(dispatcher, &accounts, payload, dispatch::SignWith::Nothing) .map(|v| v.into_value()) .map(DispatchResult::Value)) } else { @@ -138,17 +138,18 @@ impl ParitySigning for SigningQueueClient { type Metadata = Metadata; fn compose_transaction(&self, _meta: Metadata, transaction: RpcTransactionRequest) -> BoxFuture { - let default_account = self.accounts.default_account().ok().unwrap_or_default(); + let default_account = self.accounts.default_account(); Box::new(self.dispatcher.fill_optional_fields(transaction.into(), default_account, true).map(Into::into)) } fn post_sign(&self, meta: Metadata, address: RpcH160, data: RpcBytes) -> BoxFuture> { + self.deprecation_notice.print("parity_postSign", deprecated::msgs::ACCOUNTS); + let executor = self.executor.clone(); let confirmations = self.confirmations.clone(); Box::new(self.dispatch( RpcConfirmationPayload::EthSignMessage((address.clone(), data).into()), - DefaultAccount::Provided(address.into()), meta.origin ).map(move |result| match result { DispatchResult::Value(v) => RpcEither::Or(v), @@ -160,10 +161,12 @@ impl ParitySigning for SigningQueueClient { } fn post_transaction(&self, meta: Metadata, request: RpcTransactionRequest) -> BoxFuture> { + self.deprecation_notice.print("parity_postTransaction", deprecated::msgs::ACCOUNTS); + let executor = self.executor.clone(); let confirmations = self.confirmations.clone(); - Box::new(self.dispatch(RpcConfirmationPayload::SendTransaction(request), DefaultAccount::Provided(self.accounts.default_account().ok().unwrap_or_default()), meta.origin) + Box::new(self.dispatch(RpcConfirmationPayload::SendTransaction(request), meta.origin) .map(|result| match result { DispatchResult::Value(v) => RpcEither::Or(v), DispatchResult::Future(id, future) => { @@ -174,6 +177,8 @@ impl ParitySigning for SigningQueueClient { } fn check_request(&self, id: RpcU256) -> Result> { + self.deprecation_notice.print("parity_checkRequest", deprecated::msgs::ACCOUNTS); + let id: U256 = id.into(); match self.confirmations.lock().get(&id) { None => Err(errors::request_not_found()), // Request info has been dropped, or even never been there @@ -183,9 +188,10 @@ impl ParitySigning for SigningQueueClient { } fn decrypt_message(&self, meta: Metadata, address: RpcH160, data: RpcBytes) -> BoxFuture { + self.deprecation_notice.print("parity_decryptMessage", deprecated::msgs::ACCOUNTS); + let res = self.dispatch( RpcConfirmationPayload::Decrypt((address.clone(), data).into()), - address.into(), meta.origin, ); @@ -203,9 +209,10 @@ impl EthSigning for SigningQueueClient { type Metadata = Metadata; fn sign(&self, meta: Metadata, address: RpcH160, data: RpcBytes) -> BoxFuture { + self.deprecation_notice.print("eth_sign", deprecated::msgs::ACCOUNTS); + let res = self.dispatch( RpcConfirmationPayload::EthSignMessage((address.clone(), data).into()), - address.into(), meta.origin, ); @@ -218,9 +225,10 @@ impl EthSigning for SigningQueueClient { } fn send_transaction(&self, meta: Metadata, request: RpcTransactionRequest) -> BoxFuture { + self.deprecation_notice.print("eth_sendTransaction", deprecated::msgs::ACCOUNTS); + let res = self.dispatch( RpcConfirmationPayload::SendTransaction(request), - DefaultAccount::Provided(self.accounts.default_account().ok().unwrap_or_default()), meta.origin, ); @@ -233,9 +241,10 @@ impl EthSigning for SigningQueueClient { } fn sign_transaction(&self, meta: Metadata, request: RpcTransactionRequest) -> BoxFuture { + self.deprecation_notice.print("eth_signTransaction", deprecated::msgs::ACCOUNTS); + let res = self.dispatch( RpcConfirmationPayload::SignTransaction(request), - DefaultAccount::Provided(self.accounts.default_account().ok().unwrap_or_default()), meta.origin, ); diff --git a/rpc/src/v1/impls/signing_unsafe.rs b/rpc/src/v1/impls/signing_unsafe.rs index eab2489f12..59b8d5e9dc 100644 --- a/rpc/src/v1/impls/signing_unsafe.rs +++ b/rpc/src/v1/impls/signing_unsafe.rs @@ -18,11 +18,12 @@ use std::sync::Arc; -use ethcore::account_provider::AccountProvider; +use ethereum_types::Address; use jsonrpc_core::{BoxFuture, Result}; use jsonrpc_core::futures::{future, Future}; -use v1::helpers::{errors, DefaultAccount}; +use v1::helpers::{errors}; +use v1::helpers::deprecated::{self, DeprecationNotice}; use v1::helpers::dispatch::{self, Dispatcher}; use v1::metadata::Metadata; use v1::traits::{EthSigning, ParitySigning}; @@ -38,29 +39,28 @@ use v1::types::{ /// Implementation of functions that require signing when no trusted signer is used. pub struct SigningUnsafeClient { - accounts: Arc, + accounts: Arc, dispatcher: D, + deprecation_notice: DeprecationNotice, } impl SigningUnsafeClient { /// Creates new SigningUnsafeClient. - pub fn new(accounts: &Arc, dispatcher: D) -> Self { + pub fn new(accounts: &Arc, dispatcher: D) -> Self { SigningUnsafeClient { accounts: accounts.clone(), - dispatcher: dispatcher, + dispatcher, + deprecation_notice: Default::default(), } } - fn handle(&self, payload: RpcConfirmationPayload, account: DefaultAccount) -> BoxFuture { + fn handle(&self, payload: RpcConfirmationPayload, account: Address) -> BoxFuture { let accounts = self.accounts.clone(); - let default = match account { - DefaultAccount::Provided(acc) => acc, - }; let dis = self.dispatcher.clone(); - Box::new(dispatch::from_rpc(payload, default, &dis) + Box::new(dispatch::from_rpc(payload, account, &dis) .and_then(move |payload| { - dispatch::execute(dis, accounts, payload, dispatch::SignWith::Nothing) + dispatch::execute(dis, &accounts, payload, dispatch::SignWith::Nothing) }) .map(|v| v.into_value())) } @@ -71,6 +71,8 @@ impl EthSigning for SigningUnsafeClient type Metadata = Metadata; fn sign(&self, _: Metadata, address: RpcH160, data: RpcBytes) -> BoxFuture { + self.deprecation_notice.print("eth_sign", deprecated::msgs::ACCOUNTS); + Box::new(self.handle(RpcConfirmationPayload::EthSignMessage((address.clone(), data).into()), address.into()) .then(|res| match res { Ok(RpcConfirmationResponse::Signature(signature)) => Ok(signature), @@ -80,7 +82,9 @@ impl EthSigning for SigningUnsafeClient } fn send_transaction(&self, _meta: Metadata, request: RpcTransactionRequest) -> BoxFuture { - Box::new(self.handle(RpcConfirmationPayload::SendTransaction(request), DefaultAccount::Provided(self.accounts.default_account().ok().unwrap_or_default())) + self.deprecation_notice.print("eth_sendTransaction", deprecated::msgs::ACCOUNTS); + + Box::new(self.handle(RpcConfirmationPayload::SendTransaction(request), self.accounts.default_account()) .then(|res| match res { Ok(RpcConfirmationResponse::SendTransaction(hash)) => Ok(hash), Err(e) => Err(e), @@ -89,7 +93,9 @@ impl EthSigning for SigningUnsafeClient } fn sign_transaction(&self, _meta: Metadata, request: RpcTransactionRequest) -> BoxFuture { - Box::new(self.handle(RpcConfirmationPayload::SignTransaction(request), DefaultAccount::Provided(self.accounts.default_account().ok().unwrap_or_default())) + self.deprecation_notice.print("eth_signTransaction", deprecated::msgs::ACCOUNTS); + + Box::new(self.handle(RpcConfirmationPayload::SignTransaction(request), self.accounts.default_account()) .then(|res| match res { Ok(RpcConfirmationResponse::SignTransaction(tx)) => Ok(tx), Err(e) => Err(e), @@ -103,11 +109,13 @@ impl ParitySigning for SigningUnsafeClient { fn compose_transaction(&self, _meta: Metadata, transaction: RpcTransactionRequest) -> BoxFuture { let accounts = self.accounts.clone(); - let default_account = accounts.default_account().ok().unwrap_or_default(); + let default_account = accounts.default_account(); Box::new(self.dispatcher.fill_optional_fields(transaction.into(), default_account, true).map(Into::into)) } fn decrypt_message(&self, _: Metadata, address: RpcH160, data: RpcBytes) -> BoxFuture { + self.deprecation_notice.print("parity_decryptMessage", deprecated::msgs::ACCOUNTS); + Box::new(self.handle(RpcConfirmationPayload::Decrypt((address.clone(), data).into()), address.into()) .then(|res| match res { Ok(RpcConfirmationResponse::Decrypt(data)) => Ok(data), diff --git a/rpc/src/v1/mod.rs b/rpc/src/v1/mod.rs index 91915cacc6..67b25bffbf 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::{Debug, Eth, EthFilter, EthPubSub, EthSigning, Net, Parity, ParityAccounts, ParitySet, ParitySigning, Personal, PubSub, Private, Rpc, SecretStore, Signer, Traces, Web3}; +pub use self::traits::{Debug, Eth, EthFilter, EthPubSub, EthSigning, Net, Parity, ParityAccountsInfo, ParityAccounts, ParitySet, ParitySetAccounts, ParitySigning, Personal, PubSub, Private, Rpc, SecretStore, Signer, Traces, Web3}; pub use self::impls::*; pub use self::helpers::{NetworkSettings, block_import, dispatch}; pub use self::metadata::Metadata; @@ -50,6 +50,8 @@ pub use self::extractors::{RpcExtractor, WsExtractor, WsStats, WsDispatcher}; /// Signer utilities pub mod signer { - pub use super::helpers::{SigningQueue, SignerService, ConfirmationsQueue}; + #[cfg(any(test, feature = "accounts"))] + pub use super::helpers::engine_signer::EngineSigner; + pub use super::helpers::external_signer::{SignerService, ConfirmationsQueue}; pub use super::types::{ConfirmationRequest, TransactionModification, U256, TransactionCondition}; } diff --git a/rpc/src/v1/tests/eth.rs b/rpc/src/v1/tests/eth.rs index ed9d39b604..56398add1e 100644 --- a/rpc/src/v1/tests/eth.rs +++ b/rpc/src/v1/tests/eth.rs @@ -18,7 +18,7 @@ use std::env; use std::sync::Arc; -use ethcore::account_provider::AccountProvider; +use accounts::AccountProvider; use ethcore::client::{BlockChainClient, Client, ClientConfig, ChainInfo, ImportBlock}; use ethcore::ethereum; use ethcore::miner::Miner; @@ -36,13 +36,12 @@ use parking_lot::Mutex; use types::ids::BlockId; use jsonrpc_core::IoHandler; -use v1::helpers::dispatch::FullDispatcher; +use v1::helpers::dispatch::{self, FullDispatcher}; use v1::helpers::nonce; use v1::impls::{EthClient, EthClientOptions, SigningUnsafeClient}; use v1::metadata::Metadata; use v1::tests::helpers::{TestSnapshotService, TestSyncProvider, Config}; -use v1::traits::eth::Eth; -use v1::traits::eth_signing::EthSigning; +use v1::traits::{Eth, EthSigning}; use v1::types::U256 as NU256; fn account_provider() -> Arc { @@ -56,8 +55,8 @@ fn sync_provider() -> Arc { })) } -fn miner_service(spec: &Spec, accounts: Arc) -> Arc { - Arc::new(Miner::new_for_tests(spec, Some(accounts))) +fn miner_service(spec: &Spec) -> Arc { + Arc::new(Miner::new_for_tests(spec, None)) } fn snapshot_service() -> Arc { @@ -75,11 +74,11 @@ fn make_spec(chain: &BlockChain) -> Spec { } struct EthTester { - _runtime: Runtime, - client: Arc, _miner: Arc, + _runtime: Runtime, _snapshot: Arc, accounts: Arc, + client: Arc, handler: IoHandler, } @@ -115,11 +114,11 @@ impl EthTester { } fn from_spec_conf(spec: Spec, config: ClientConfig) -> Self { - let runtime = Runtime::with_thread_count(1); let account_provider = account_provider(); - let opt_account_provider = account_provider.clone(); - let miner_service = miner_service(&spec, account_provider.clone()); + let ap = account_provider.clone(); + let accounts = Arc::new(move || ap.accounts().unwrap_or_default()) as _; + let miner_service = miner_service(&spec); let snapshot_service = snapshot_service(); let client = Client::new( @@ -136,7 +135,7 @@ impl EthTester { &client, &snapshot_service, &sync_provider, - &opt_account_provider, + &accounts, &miner_service, &external_miner, EthClientOptions { @@ -152,8 +151,9 @@ impl EthTester { let reservations = Arc::new(Mutex::new(nonce::Reservations::new(runtime.executor()))); let dispatcher = FullDispatcher::new(client.clone(), miner_service.clone(), reservations, 50); + let signer = Arc::new(dispatch::Signer::new(account_provider.clone())) as _; let eth_sign = SigningUnsafeClient::new( - &opt_account_provider, + &signer, dispatcher, ); @@ -162,11 +162,11 @@ impl EthTester { handler.extend_with(eth_sign.to_delegate()); EthTester { - _runtime: runtime, _miner: miner_service, + _runtime: runtime, _snapshot: snapshot_service, - client: client, accounts: account_provider, + client: client, handler: handler, } } diff --git a/rpc/src/v1/tests/helpers/miner_service.rs b/rpc/src/v1/tests/helpers/miner_service.rs index 4392716548..f9b649fa62 100644 --- a/rpc/src/v1/tests/helpers/miner_service.rs +++ b/rpc/src/v1/tests/helpers/miner_service.rs @@ -20,14 +20,12 @@ use std::sync::Arc; use std::collections::{BTreeMap, BTreeSet, HashMap}; use bytes::Bytes; -use ethcore::account_provider::SignError as AccountError; use ethcore::block::{SealedBlock, IsBlock}; use ethcore::client::{Nonce, PrepareOpenBlock, StateClient, EngineInfo}; -use ethcore::engines::EthEngine; +use ethcore::engines::{EthEngine, signer::EngineSigner}; use ethcore::error::Error; use ethcore::miner::{self, MinerService, AuthoringParams}; use ethereum_types::{H256, U256, Address}; -use ethkey::Password; use miner::pool::local_transactions::Status as LocalTransactionStatus; use miner::pool::{verifier, VerifiedTransaction, QueueStatus}; use parking_lot::{RwLock, Mutex}; @@ -51,8 +49,8 @@ pub struct TestMinerService { pub pending_receipts: Mutex>, /// Next nonces. pub next_nonces: RwLock>, - /// Password held by Engine. - pub password: RwLock, + /// Signer (if any) + pub signer: RwLock>>, authoring_params: RwLock, } @@ -65,12 +63,12 @@ impl Default for TestMinerService { local_transactions: Default::default(), pending_receipts: Default::default(), next_nonces: Default::default(), - password: RwLock::new("".into()), authoring_params: RwLock::new(AuthoringParams { author: Address::zero(), gas_range_target: (12345.into(), 54321.into()), extra_data: vec![1, 2, 3, 4], }), + signer: RwLock::new(None), } } } @@ -122,12 +120,11 @@ impl MinerService for TestMinerService { self.authoring_params.read().clone() } - fn set_author(&self, author: Address, password: Option) -> Result<(), AccountError> { - self.authoring_params.write().author = author; - if let Some(password) = password { - *self.password.write() = password; + fn set_author(&self, author: miner::Author) { + self.authoring_params.write().author = author.address(); + if let miner::Author::Sealer(signer) = author { + *self.signer.write() = Some(signer); } - Ok(()) } fn set_extra_data(&self, extra_data: Bytes) { diff --git a/rpc/src/v1/tests/mocked/eth.rs b/rpc/src/v1/tests/mocked/eth.rs index f920996d1a..75e05ce467 100644 --- a/rpc/src/v1/tests/mocked/eth.rs +++ b/rpc/src/v1/tests/mocked/eth.rs @@ -19,11 +19,10 @@ use std::collections::HashMap; use std::sync::Arc; use std::time::{Instant, Duration, SystemTime, UNIX_EPOCH}; -use ethcore::account_provider::AccountProvider; +use accounts::AccountProvider; use ethcore::client::{BlockChainClient, BlockId, EachBlockWith, Executed, TestBlockChainClient, TransactionId}; -use ethcore::miner::MinerService; +use ethcore::miner::{self, MinerService}; use ethereum_types::{H160, H256, U256, Address}; -use ethkey::Secret; use miner::external::ExternalMiner; use parity_runtime::Runtime; use parking_lot::Mutex; @@ -35,9 +34,7 @@ use types::log_entry::{LocalizedLogEntry, LogEntry}; use types::receipt::{LocalizedReceipt, TransactionOutcome}; use jsonrpc_core::IoHandler; -use v1::{Eth, EthClient, EthClientOptions, EthFilter, EthFilterClient, EthSigning, SigningUnsafeClient}; -use v1::helpers::nonce; -use v1::helpers::dispatch::FullDispatcher; +use v1::{Eth, EthClient, EthClientOptions, EthFilter, EthFilterClient}; use v1::tests::helpers::{TestSyncProvider, Config, TestMinerService, TestSnapshotService}; use v1::metadata::Metadata; @@ -88,21 +85,17 @@ impl EthTester { let client = blockchain_client(); let sync = sync_provider(); let ap = accounts_provider(); - let opt_ap = ap.clone(); + let ap2 = ap.clone(); + let opt_ap = Arc::new(move || ap2.accounts().unwrap_or_default()) as _; let miner = miner_service(); let snapshot = snapshot_service(); let hashrates = Arc::new(Mutex::new(HashMap::new())); let external_miner = Arc::new(ExternalMiner::new(hashrates.clone())); - let gas_price_percentile = options.gas_price_percentile; let eth = EthClient::new(&client, &snapshot, &sync, &opt_ap, &miner, &external_miner, options).to_delegate(); let filter = EthFilterClient::new(client.clone(), miner.clone(), 60).to_delegate(); - let reservations = Arc::new(Mutex::new(nonce::Reservations::new(runtime.executor()))); - let dispatcher = FullDispatcher::new(client.clone(), miner.clone(), reservations, gas_price_percentile); - let sign = SigningUnsafeClient::new(&opt_ap, dispatcher).to_delegate(); let mut io: IoHandler = IoHandler::default(); io.extend_with(eth); - io.extend_with(sign); io.extend_with(filter); EthTester { @@ -360,28 +353,6 @@ fn rpc_eth_submit_hashrate() { U256::from(0x500_000)); } -#[test] -fn rpc_eth_sign() { - let tester = EthTester::default(); - - let account = tester.accounts_provider.insert_account(Secret::from([69u8; 32]), &"abcd".into()).unwrap(); - tester.accounts_provider.unlock_account_permanently(account, "abcd".into()).unwrap(); - let _message = "0cc175b9c0f1b6a831c399e26977266192eb5ffee6ae2fec3ad71c777531578f".from_hex().unwrap(); - - let req = r#"{ - "jsonrpc": "2.0", - "method": "eth_sign", - "params": [ - ""#.to_owned() + &format!("0x{:x}", account) + r#"", - "0x0cc175b9c0f1b6a831c399e26977266192eb5ffee6ae2fec3ad71c777531578f" - ], - "id": 1 - }"#; - let res = r#"{"jsonrpc":"2.0","result":"0xa2870db1d0c26ef93c7b72d2a0830fa6b841e0593f7186bc6c7cc317af8cf3a42fda03bd589a49949aa05db83300cdb553116274518dbe9d90c65d0213f4af491b","id":1}"#; - - assert_eq!(tester.io.handle_request_sync(&req), Some(res.into())); -} - #[test] fn rpc_eth_author() { let make_res = |addr| r#"{"jsonrpc":"2.0","result":""#.to_owned() + &format!("0x{:x}", addr) + r#"","id":1}"#; @@ -405,7 +376,7 @@ fn rpc_eth_author() { for i in 0..20 { let addr = tester.accounts_provider.new_account(&format!("{}", i).into()).unwrap(); - tester.miner.set_author(addr.clone(), None).unwrap(); + tester.miner.set_author(miner::Author::External(addr)); assert_eq!(tester.io.handle_request_sync(request), Some(make_res(addr))); } @@ -414,7 +385,7 @@ fn rpc_eth_author() { #[test] fn rpc_eth_mining() { let tester = EthTester::default(); - tester.miner.set_author(Address::from_str("d46e8dd67c5d32be8058bb8eb970870f07244567").unwrap(), None).unwrap(); + tester.miner.set_author(miner::Author::External(Address::from_str("d46e8dd67c5d32be8058bb8eb970870f07244567").unwrap())); let request = r#"{"jsonrpc": "2.0", "method": "eth_mining", "params": [], "id": 1}"#; let response = r#"{"jsonrpc":"2.0","result":false,"id":1}"#; @@ -824,157 +795,6 @@ fn rpc_eth_estimate_gas_default_block() { assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned())); } -#[test] -fn rpc_eth_send_transaction() { - let tester = EthTester::default(); - let address = tester.accounts_provider.new_account(&"".into()).unwrap(); - tester.accounts_provider.unlock_account_permanently(address, "".into()).unwrap(); - let request = r#"{ - "jsonrpc": "2.0", - "method": "eth_sendTransaction", - "params": [{ - "from": ""#.to_owned() + format!("0x{:x}", address).as_ref() + r#"", - "to": "0xd46e8dd67c5d32be8058bb8eb970870f07244567", - "gas": "0x76c0", - "gasPrice": "0x9184e72a000", - "value": "0x9184e72a" - }], - "id": 1 - }"#; - - let t = Transaction { - nonce: U256::zero(), - gas_price: U256::from(0x9184e72a000u64), - gas: U256::from(0x76c0), - action: Action::Call(Address::from_str("d46e8dd67c5d32be8058bb8eb970870f07244567").unwrap()), - value: U256::from(0x9184e72au64), - data: vec![] - }; - let signature = tester.accounts_provider.sign(address, None, t.hash(None)).unwrap(); - let t = t.with_signature(signature, None); - - let response = r#"{"jsonrpc":"2.0","result":""#.to_owned() + format!("0x{:x}", t.hash()).as_ref() + r#"","id":1}"#; - - assert_eq!(tester.io.handle_request_sync(&request), Some(response)); - - tester.miner.increment_nonce(&address); - - let t = Transaction { - nonce: U256::one(), - gas_price: U256::from(0x9184e72a000u64), - gas: U256::from(0x76c0), - action: Action::Call(Address::from_str("d46e8dd67c5d32be8058bb8eb970870f07244567").unwrap()), - value: U256::from(0x9184e72au64), - data: vec![] - }; - let signature = tester.accounts_provider.sign(address, None, t.hash(None)).unwrap(); - let t = t.with_signature(signature, None); - - let response = r#"{"jsonrpc":"2.0","result":""#.to_owned() + format!("0x{:x}", t.hash()).as_ref() + r#"","id":1}"#; - - assert_eq!(tester.io.handle_request_sync(&request), Some(response)); -} - -#[test] -fn rpc_eth_sign_transaction() { - let tester = EthTester::default(); - let address = tester.accounts_provider.new_account(&"".into()).unwrap(); - tester.accounts_provider.unlock_account_permanently(address, "".into()).unwrap(); - let request = r#"{ - "jsonrpc": "2.0", - "method": "eth_signTransaction", - "params": [{ - "from": ""#.to_owned() + format!("0x{:x}", address).as_ref() + r#"", - "to": "0xd46e8dd67c5d32be8058bb8eb970870f07244567", - "gas": "0x76c0", - "gasPrice": "0x9184e72a000", - "value": "0x9184e72a" - }], - "id": 1 - }"#; - - let t = Transaction { - nonce: U256::one(), - gas_price: U256::from(0x9184e72a000u64), - gas: U256::from(0x76c0), - action: Action::Call(Address::from_str("d46e8dd67c5d32be8058bb8eb970870f07244567").unwrap()), - value: U256::from(0x9184e72au64), - data: vec![] - }; - let signature = tester.accounts_provider.sign(address, None, t.hash(None)).unwrap(); - let t = t.with_signature(signature, None); - let signature = t.signature(); - let rlp = rlp::encode(&t); - - let response = r#"{"jsonrpc":"2.0","result":{"#.to_owned() + - r#""raw":"0x"# + &rlp.to_hex() + r#"","# + - r#""tx":{"# + - r#""blockHash":null,"blockNumber":null,"# + - &format!("\"chainId\":{},", t.chain_id().map_or("null".to_owned(), |n| format!("{}", n))) + - r#""condition":null,"creates":null,"# + - &format!("\"from\":\"0x{:x}\",", &address) + - r#""gas":"0x76c0","gasPrice":"0x9184e72a000","# + - &format!("\"hash\":\"0x{:x}\",", t.hash()) + - r#""input":"0x","# + - r#""nonce":"0x1","# + - &format!("\"publicKey\":\"0x{:x}\",", t.recover_public().unwrap()) + - &format!("\"r\":\"0x{:x}\",", U256::from(signature.r())) + - &format!("\"raw\":\"0x{}\",", rlp.to_hex()) + - &format!("\"s\":\"0x{:x}\",", U256::from(signature.s())) + - &format!("\"standardV\":\"0x{:x}\",", U256::from(t.standard_v())) + - r#""to":"0xd46e8dd67c5d32be8058bb8eb970870f07244567","transactionIndex":null,"# + - &format!("\"v\":\"0x{:x}\",", U256::from(t.original_v())) + - r#""value":"0x9184e72a""# + - r#"}},"id":1}"#; - - tester.miner.increment_nonce(&address); - - assert_eq!(tester.io.handle_request_sync(&request), Some(response)); -} - -#[test] -fn rpc_eth_send_transaction_with_bad_to() { - let tester = EthTester::default(); - let address = tester.accounts_provider.new_account(&"".into()).unwrap(); - let request = r#"{ - "jsonrpc": "2.0", - "method": "eth_sendTransaction", - "params": [{ - "from": ""#.to_owned() + format!("0x{:x}", address).as_ref() + r#"", - "to": "", - "gas": "0x76c0", - "gasPrice": "0x9184e72a000", - "value": "0x9184e72a" - }], - "id": 1 - }"#; - - let response = r#"{"jsonrpc":"2.0","error":{"code":-32602,"message":"Invalid params: expected a hex-encoded hash with 0x prefix."},"id":1}"#; - - assert_eq!(tester.io.handle_request_sync(&request), Some(response.into())); -} - -#[test] -fn rpc_eth_send_transaction_error() { - let tester = EthTester::default(); - let address = tester.accounts_provider.new_account(&"".into()).unwrap(); - let request = r#"{ - "jsonrpc": "2.0", - "method": "eth_sendTransaction", - "params": [{ - "from": ""#.to_owned() + format!("0x{:x}", address).as_ref() + r#"", - "to": "0xd46e8dd67c5d32be8058bb8eb970870f07244567", - "gas": "0x76c0", - "gasPrice": "0x9184e72a000", - "value": "0x9184e72a" - }], - "id": 1 - }"#; - - let response = r#"{"jsonrpc":"2.0","error":{"code":-32020,"message":"Your account is locked. Unlock the account via CLI, personal_unlockAccount or use Trusted Signer.","data":"NotUnlocked"},"id":1}"#; - assert_eq!(tester.io.handle_request_sync(&request), Some(response.into())); -} - #[test] fn rpc_eth_send_raw_transaction_error() { let tester = EthTester::default(); @@ -1141,7 +961,7 @@ fn rpc_get_work_returns_no_work_if_cant_mine() { #[test] fn rpc_get_work_returns_correct_work_package() { let eth_tester = EthTester::default(); - eth_tester.miner.set_author(Address::from_str("d46e8dd67c5d32be8058bb8eb970870f07244567").unwrap(), None).unwrap(); + eth_tester.miner.set_author(miner::Author::External(Address::from_str("d46e8dd67c5d32be8058bb8eb970870f07244567").unwrap())); let request = r#"{"jsonrpc": "2.0", "method": "eth_getWork", "params": [], "id": 1}"#; let response = r#"{"jsonrpc":"2.0","result":["0x76c7bd86693aee93d1a80a408a09a0585b1a1292afcb56192f171d925ea18e2d","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000800000000000000000000000000000000000000000000000000000000000","0x1"],"id":1}"#; @@ -1154,7 +974,7 @@ fn rpc_get_work_should_not_return_block_number() { let eth_tester = EthTester::new_with_options(EthClientOptions::with(|options| { options.send_block_number_in_get_work = false; })); - eth_tester.miner.set_author(Address::from_str("d46e8dd67c5d32be8058bb8eb970870f07244567").unwrap(), None).unwrap(); + eth_tester.miner.set_author(miner::Author::External(Address::from_str("d46e8dd67c5d32be8058bb8eb970870f07244567").unwrap())); let request = r#"{"jsonrpc": "2.0", "method": "eth_getWork", "params": [], "id": 1}"#; let response = r#"{"jsonrpc":"2.0","result":["0x76c7bd86693aee93d1a80a408a09a0585b1a1292afcb56192f171d925ea18e2d","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000800000000000000000000000000000000000000000000000000000000000"],"id":1}"#; @@ -1165,7 +985,7 @@ fn rpc_get_work_should_not_return_block_number() { #[test] fn rpc_get_work_should_timeout() { let eth_tester = EthTester::default(); - eth_tester.miner.set_author(Address::from_str("d46e8dd67c5d32be8058bb8eb970870f07244567").unwrap(), None).unwrap(); + eth_tester.miner.set_author(miner::Author::External(Address::from_str("d46e8dd67c5d32be8058bb8eb970870f07244567").unwrap())); let timestamp = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs() - 1000; // Set latest block to 1000 seconds ago eth_tester.client.set_latest_block_timestamp(timestamp); let hash = eth_tester.miner.work_package(&*eth_tester.client).unwrap().0; diff --git a/rpc/src/v1/tests/mocked/mod.rs b/rpc/src/v1/tests/mocked/mod.rs index 80766ca437..35d109b171 100644 --- a/rpc/src/v1/tests/mocked/mod.rs +++ b/rpc/src/v1/tests/mocked/mod.rs @@ -23,13 +23,19 @@ mod eth_pubsub; mod manage_network; mod net; mod parity; +#[cfg(any(test, feature = "accounts"))] mod parity_accounts; mod parity_set; +#[cfg(any(test, feature = "accounts"))] mod personal; mod pubsub; mod rpc; +#[cfg(any(test, feature = "accounts"))] mod secretstore; mod signer; +#[cfg(any(test, feature = "accounts"))] mod signing; +#[cfg(any(test, feature = "accounts"))] +mod signing_unsafe; mod traces; mod web3; diff --git a/rpc/src/v1/tests/mocked/parity.rs b/rpc/src/v1/tests/mocked/parity.rs index f83ded550d..f97db6509d 100644 --- a/rpc/src/v1/tests/mocked/parity.rs +++ b/rpc/src/v1/tests/mocked/parity.rs @@ -15,7 +15,6 @@ // along with Parity Ethereum. If not, see . use std::sync::Arc; -use ethcore::account_provider::AccountProvider; use ethcore::client::{TestBlockChainClient, Executed, TransactionId}; use ethcore_logger::RotatingLogger; use ethereum_types::{Address, U256, H256}; @@ -27,7 +26,8 @@ use types::receipt::{LocalizedReceipt, TransactionOutcome}; use jsonrpc_core::IoHandler; use v1::{Parity, ParityClient}; use v1::metadata::Metadata; -use v1::helpers::{SignerService, NetworkSettings}; +use v1::helpers::NetworkSettings; +use v1::helpers::external_signer::SignerService; use v1::tests::helpers::{TestSyncProvider, Config, TestMinerService, TestUpdater}; use super::manage_network::TestManageNetwork; use Host; @@ -42,7 +42,6 @@ pub struct Dependencies { pub logger: Arc, pub settings: Arc, pub network: Arc, - pub accounts: Arc, pub ws_address: Option, } @@ -67,7 +66,6 @@ impl Dependencies { rpc_port: 8545, }), network: Arc::new(TestManageNetwork), - accounts: Arc::new(AccountProvider::transient_provider()), ws_address: Some("127.0.0.1:18546".into()), } } @@ -79,7 +77,6 @@ impl Dependencies { self.sync.clone(), self.updater.clone(), self.network.clone(), - self.accounts.clone(), self.logger.clone(), self.settings.clone(), signer, @@ -101,47 +98,6 @@ impl Dependencies { } } -#[test] -fn rpc_parity_accounts_info() { - let deps = Dependencies::new(); - let io = deps.default_client(); - - deps.accounts.new_account(&"".into()).unwrap(); - let accounts = deps.accounts.accounts().unwrap(); - assert_eq!(accounts.len(), 1); - let address = accounts[0]; - - deps.accounts.set_address_name(1.into(), "XX".into()); - deps.accounts.set_account_name(address.clone(), "Test".into()).unwrap(); - deps.accounts.set_account_meta(address.clone(), "{foo: 69}".into()).unwrap(); - - let request = r#"{"jsonrpc": "2.0", "method": "parity_accountsInfo", "params": [], "id": 1}"#; - let response = format!("{{\"jsonrpc\":\"2.0\",\"result\":{{\"0x{:x}\":{{\"name\":\"Test\"}}}},\"id\":1}}", address); - assert_eq!(io.handle_request_sync(request), Some(response)); -} - -#[test] -fn rpc_parity_default_account() { - let deps = Dependencies::new(); - let io = deps.default_client(); - - // Check empty - let address = Address::default(); - let request = r#"{"jsonrpc": "2.0", "method": "parity_defaultAccount", "params": [], "id": 1}"#; - let response = format!("{{\"jsonrpc\":\"2.0\",\"result\":\"0x{:x}\",\"id\":1}}", address); - assert_eq!(io.handle_request_sync(request), Some(response)); - - // With account - deps.accounts.new_account(&"".into()).unwrap(); - let accounts = deps.accounts.accounts().unwrap(); - assert_eq!(accounts.len(), 1); - let address = accounts[0]; - - let request = r#"{"jsonrpc": "2.0", "method": "parity_defaultAccount", "params": [], "id": 1}"#; - let response = format!("{{\"jsonrpc\":\"2.0\",\"result\":\"0x{:x}\",\"id\":1}}", address); - assert_eq!(io.handle_request_sync(request), Some(response)); -} - #[test] fn rpc_parity_consensus_capability() { let deps = Dependencies::new(); diff --git a/rpc/src/v1/tests/mocked/parity_accounts.rs b/rpc/src/v1/tests/mocked/parity_accounts.rs index 794d7f9cad..5b2e0762b1 100644 --- a/rpc/src/v1/tests/mocked/parity_accounts.rs +++ b/rpc/src/v1/tests/mocked/parity_accounts.rs @@ -16,13 +16,14 @@ use std::sync::Arc; -use ethcore::account_provider::{AccountProvider, AccountProviderSettings}; +use accounts::{AccountProvider, AccountProviderSettings}; +use ethereum_types::Address; use ethstore::EthStore; use ethstore::accounts_dir::RootDiskDirectory; use tempdir::TempDir; use jsonrpc_core::IoHandler; -use v1::{ParityAccounts, ParityAccountsClient}; +use v1::{ParityAccounts, ParityAccountsInfo, ParityAccountsClient}; struct ParityAccountsTester { accounts: Arc, @@ -42,8 +43,10 @@ fn accounts_provider_with_vaults_support(temp_path: &str) -> Arc) -> ParityAccountsTester { let opt_ap = accounts_provider.clone(); let parity_accounts = ParityAccountsClient::new(&opt_ap); + let parity_accounts2 = ParityAccountsClient::new(&opt_ap); let mut io = IoHandler::default(); - io.extend_with(parity_accounts.to_delegate()); + io.extend_with(ParityAccounts::to_delegate(parity_accounts)); + io.extend_with(ParityAccountsInfo::to_delegate(parity_accounts2)); let tester = ParityAccountsTester { accounts: accounts_provider, @@ -61,6 +64,47 @@ fn setup_with_vaults_support(temp_path: &str) -> ParityAccountsTester { setup_with_accounts_provider(accounts_provider_with_vaults_support(temp_path)) } +#[test] +fn rpc_parity_accounts_info() { + let tester = setup(); + let io = tester.io; + + tester.accounts.new_account(&"".into()).unwrap(); + let accounts = tester.accounts.accounts().unwrap(); + assert_eq!(accounts.len(), 1); + let address = accounts[0]; + + tester.accounts.set_address_name(1.into(), "XX".into()); + tester.accounts.set_account_name(address.clone(), "Test".into()).unwrap(); + tester.accounts.set_account_meta(address.clone(), "{foo: 69}".into()).unwrap(); + + let request = r#"{"jsonrpc": "2.0", "method": "parity_accountsInfo", "params": [], "id": 1}"#; + let response = format!("{{\"jsonrpc\":\"2.0\",\"result\":{{\"0x{:x}\":{{\"name\":\"Test\"}}}},\"id\":1}}", address); + assert_eq!(io.handle_request_sync(request), Some(response)); +} + +#[test] +fn rpc_parity_default_account() { + let tester = setup(); + let io = tester.io; + + // Check empty + let address = Address::default(); + let request = r#"{"jsonrpc": "2.0", "method": "parity_defaultAccount", "params": [], "id": 1}"#; + let response = format!("{{\"jsonrpc\":\"2.0\",\"result\":\"0x{:x}\",\"id\":1}}", address); + assert_eq!(io.handle_request_sync(request), Some(response)); + + // With account + tester.accounts.new_account(&"".into()).unwrap(); + let accounts = tester.accounts.accounts().unwrap(); + assert_eq!(accounts.len(), 1); + let address = accounts[0]; + + let request = r#"{"jsonrpc": "2.0", "method": "parity_defaultAccount", "params": [], "id": 1}"#; + let response = format!("{{\"jsonrpc\":\"2.0\",\"result\":\"0x{:x}\",\"id\":1}}", address); + assert_eq!(io.handle_request_sync(request), Some(response)); +} + #[test] fn should_be_able_to_get_account_info() { let tester = setup(); diff --git a/rpc/src/v1/tests/mocked/parity_set.rs b/rpc/src/v1/tests/mocked/parity_set.rs index 91a4c6c95a..13473fbdf8 100644 --- a/rpc/src/v1/tests/mocked/parity_set.rs +++ b/rpc/src/v1/tests/mocked/parity_set.rs @@ -54,7 +54,13 @@ fn parity_set_client( updater: &Arc, net: &Arc, ) -> TestParitySetClient { - ParitySetClient::new(client, miner, updater, &(net.clone() as Arc), FakeFetch::new(Some(1))) + ParitySetClient::new( + client, + miner, + updater, + &(net.clone() as Arc), + FakeFetch::new(Some(1)), + ) } #[test] @@ -161,23 +167,6 @@ fn rpc_parity_set_author() { assert_eq!(miner.authoring_params().author, Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap()); } -#[test] -fn rpc_parity_set_engine_signer() { - let miner = miner_service(); - let client = client_service(); - let network = network_service(); - let updater = updater_service(); - let mut io = IoHandler::new(); - io.extend_with(parity_set_client(&client, &miner, &updater, &network).to_delegate()); - - let request = r#"{"jsonrpc": "2.0", "method": "parity_setEngineSigner", "params":["0xcd1722f3947def4cf144679da39c4c32bdc35681", "password"], "id": 1}"#; - let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#; - - assert_eq!(io.handle_request_sync(request), Some(response.to_owned())); - assert_eq!(miner.authoring_params().author, Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap()); - assert_eq!(*miner.password.read(), "password".into()); -} - #[test] fn rpc_parity_set_transactions_limit() { let miner = miner_service(); @@ -236,3 +225,29 @@ fn rpc_parity_remove_transaction() { miner.pending_transactions.lock().insert(hash, signed); assert_eq!(io.handle_request_sync(&request), Some(response.to_owned())); } + +#[test] +fn rpc_parity_set_engine_signer() { + use accounts::AccountProvider; + use bytes::ToPretty; + use v1::impls::ParitySetAccountsClient; + use v1::traits::ParitySetAccounts; + + let account_provider = Arc::new(AccountProvider::transient_provider()); + account_provider.insert_account(::hash::keccak("cow").into(), &"password".into()).unwrap(); + + let miner = miner_service(); + let mut io = IoHandler::new(); + io.extend_with( + ParitySetAccountsClient::new(&account_provider, &miner).to_delegate() + ); + + let request = r#"{"jsonrpc": "2.0", "method": "parity_setEngineSigner", "params":["0xcd2a3d9f938e13cd947ec05abc7fe734df8dd826", "password"], "id": 1}"#; + let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#; + + assert_eq!(io.handle_request_sync(request), Some(response.to_owned())); + assert_eq!(miner.authoring_params().author, Address::from_str("cd2a3d9f938e13cd947ec05abc7fe734df8dd826").unwrap()); + let signature = miner.signer.read().as_ref().unwrap().sign(::hash::keccak("x")).unwrap().to_vec(); + assert_eq!(&format!("{}", signature.pretty()), "6f46069ded2154af6e806706e4f7f6fd310ac45f3c6dccb85f11c0059ee20a09245df0a0008bb84a10882b1298284bc93058e7bc5938ea728e77620061687a6401"); +} + diff --git a/rpc/src/v1/tests/mocked/personal.rs b/rpc/src/v1/tests/mocked/personal.rs index bdf6067418..771abe24ef 100644 --- a/rpc/src/v1/tests/mocked/personal.rs +++ b/rpc/src/v1/tests/mocked/personal.rs @@ -19,7 +19,7 @@ use std::str::FromStr; use bytes::ToPretty; use ethereum_types::{U256, Address}; -use ethcore::account_provider::AccountProvider; +use accounts::AccountProvider; use ethcore::client::TestBlockChainClient; use jsonrpc_core::IoHandler; use parking_lot::Mutex; diff --git a/rpc/src/v1/tests/mocked/secretstore.rs b/rpc/src/v1/tests/mocked/secretstore.rs index 3e4f284a2f..fa3cba58fd 100644 --- a/rpc/src/v1/tests/mocked/secretstore.rs +++ b/rpc/src/v1/tests/mocked/secretstore.rs @@ -17,7 +17,7 @@ use std::sync::Arc; use crypto::DEFAULT_MAC; -use ethcore::account_provider::AccountProvider; +use accounts::AccountProvider; use ethkey::{KeyPair, Signature, verify_public}; use serde_json; diff --git a/rpc/src/v1/tests/mocked/signer.rs b/rpc/src/v1/tests/mocked/signer.rs index 78f2e00098..dea1f1fb7f 100644 --- a/rpc/src/v1/tests/mocked/signer.rs +++ b/rpc/src/v1/tests/mocked/signer.rs @@ -19,7 +19,7 @@ use std::str::FromStr; use ethereum_types::{U256, Address}; use bytes::ToPretty; -use ethcore::account_provider::AccountProvider; +use accounts::AccountProvider; use ethcore::client::TestBlockChainClient; use parity_runtime::Runtime; use parking_lot::Mutex; @@ -32,8 +32,9 @@ use v1::{SignerClient, Signer, Origin}; use v1::metadata::Metadata; use v1::tests::helpers::TestMinerService; use v1::types::{Bytes as RpcBytes, H520}; -use v1::helpers::{nonce, SigningQueue, SignerService, FilledTransactionRequest, ConfirmationPayload}; -use v1::helpers::dispatch::{FullDispatcher, eth_data_hash}; +use v1::helpers::{nonce, FilledTransactionRequest, ConfirmationPayload}; +use v1::helpers::external_signer::{SigningQueue, SignerService}; +use v1::helpers::dispatch::{self, FullDispatcher, eth_data_hash}; struct SignerTester { _runtime: Runtime, @@ -60,13 +61,14 @@ fn signer_tester() -> SignerTester { let runtime = Runtime::with_thread_count(1); let signer = Arc::new(SignerService::new_test(false)); let accounts = accounts_provider(); + let account_signer = Arc::new(dispatch::Signer::new(accounts.clone())); let client = blockchain_client(); let miner = miner_service(); let reservations = Arc::new(Mutex::new(nonce::Reservations::new(runtime.executor()))); let dispatcher = FullDispatcher::new(client, miner.clone(), reservations, 50); let mut io = IoHandler::default(); - io.extend_with(SignerClient::new(&accounts, dispatcher, &signer, runtime.executor()).to_delegate()); + io.extend_with(SignerClient::new(account_signer, dispatcher, &signer, runtime.executor()).to_delegate()); SignerTester { _runtime: runtime, @@ -555,29 +557,3 @@ fn should_generate_new_token() { // then assert_eq!(tester.io.handle_request_sync(&request), Some(response.to_owned())); } - -#[test] -fn should_generate_new_web_proxy_token() { - use jsonrpc_core::{Response, Output, Value}; - // given - let tester = signer_tester(); - - // when - let request = r#"{ - "jsonrpc":"2.0", - "method":"signer_generateWebProxyAccessToken", - "params":["https://parity.io"], - "id":1 - }"#; - let response = tester.io.handle_request_sync(&request).unwrap(); - let result = serde_json::from_str(&response).unwrap(); - - if let Response::Single(Output::Success(ref success)) = result { - if let Value::String(ref token) = success.result { - assert_eq!(tester.signer.web_proxy_access_token_domain(&token), Some("https://parity.io".into())); - return; - } - } - - assert!(false, "Expected successful response, got: {:?}", result); -} diff --git a/rpc/src/v1/tests/mocked/signing.rs b/rpc/src/v1/tests/mocked/signing.rs index a142a40a53..39385d19bd 100644 --- a/rpc/src/v1/tests/mocked/signing.rs +++ b/rpc/src/v1/tests/mocked/signing.rs @@ -25,14 +25,15 @@ use jsonrpc_core::futures::Future; use v1::impls::SigningQueueClient; use v1::metadata::Metadata; use v1::traits::{EthSigning, ParitySigning, Parity}; -use v1::helpers::{nonce, SignerService, SigningQueue, FullDispatcher}; +use v1::helpers::{nonce, dispatch, FullDispatcher}; +use v1::helpers::external_signer::{SignerService, SigningQueue}; use v1::types::{ConfirmationResponse, RichRawTransaction}; use v1::tests::helpers::TestMinerService; use v1::tests::mocked::parity; -use ethereum_types::{U256, Address}; +use accounts::AccountProvider; use bytes::ToPretty; -use ethcore::account_provider::AccountProvider; +use ethereum_types::{U256, Address}; use ethcore::client::TestBlockChainClient; use ethkey::Secret; use ethstore::ethkey::{Generator, Random}; @@ -57,6 +58,7 @@ impl Default for SigningTester { let client = Arc::new(TestBlockChainClient::default()); let miner = Arc::new(TestMinerService::default()); let accounts = Arc::new(AccountProvider::transient_provider()); + let account_signer = Arc::new(dispatch::Signer::new(accounts.clone())) as _; let reservations = Arc::new(Mutex::new(nonce::Reservations::new(runtime.executor()))); let mut io = IoHandler::default(); @@ -64,9 +66,9 @@ impl Default for SigningTester { let executor = Executor::new_thread_per_future(); - let rpc = SigningQueueClient::new(&signer, dispatcher.clone(), executor.clone(), &accounts); + let rpc = SigningQueueClient::new(&signer, dispatcher.clone(), executor.clone(), &account_signer); io.extend_with(EthSigning::to_delegate(rpc)); - let rpc = SigningQueueClient::new(&signer, dispatcher, executor, &accounts); + let rpc = SigningQueueClient::new(&signer, dispatcher, executor, &account_signer); io.extend_with(ParitySigning::to_delegate(rpc)); SigningTester { @@ -84,6 +86,30 @@ fn eth_signing() -> SigningTester { SigningTester::default() } +#[test] +fn rpc_eth_sign() { + use rustc_hex::FromHex; + + let tester = eth_signing(); + + let account = tester.accounts.insert_account(Secret::from([69u8; 32]), &"abcd".into()).unwrap(); + tester.accounts.unlock_account_permanently(account, "abcd".into()).unwrap(); + let _message = "0cc175b9c0f1b6a831c399e26977266192eb5ffee6ae2fec3ad71c777531578f".from_hex().unwrap(); + + let req = r#"{ + "jsonrpc": "2.0", + "method": "eth_sign", + "params": [ + ""#.to_owned() + &format!("0x{:x}", account) + r#"", + "0x0cc175b9c0f1b6a831c399e26977266192eb5ffee6ae2fec3ad71c777531578f" + ], + "id": 1 + }"#; + let res = r#"{"jsonrpc":"2.0","result":"0xa2870db1d0c26ef93c7b72d2a0830fa6b841e0593f7186bc6c7cc317af8cf3a42fda03bd589a49949aa05db83300cdb553116274518dbe9d90c65d0213f4af491b","id":1}"#; + + assert_eq!(tester.io.handle_request_sync(&req), Some(res.into())); +} + #[test] fn should_add_sign_to_queue() { // given diff --git a/rpc/src/v1/tests/mocked/signing_unsafe.rs b/rpc/src/v1/tests/mocked/signing_unsafe.rs new file mode 100644 index 0000000000..7e82038571 --- /dev/null +++ b/rpc/src/v1/tests/mocked/signing_unsafe.rs @@ -0,0 +1,237 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +use std::str::FromStr; +use std::sync::Arc; + +use accounts::AccountProvider; +use ethcore::client::TestBlockChainClient; +use ethereum_types::{U256, Address}; +use parity_runtime::Runtime; +use parking_lot::Mutex; +use rlp; +use rustc_hex::ToHex; +use types::transaction::{Transaction, Action}; + +use jsonrpc_core::IoHandler; +use v1::{EthClientOptions, EthSigning, SigningUnsafeClient}; +use v1::helpers::nonce; +use v1::helpers::dispatch::{self, FullDispatcher}; +use v1::tests::helpers::{TestMinerService}; +use v1::metadata::Metadata; + +fn blockchain_client() -> Arc { + let client = TestBlockChainClient::new(); + Arc::new(client) +} + +fn accounts_provider() -> Arc { + Arc::new(AccountProvider::transient_provider()) +} + +fn miner_service() -> Arc { + Arc::new(TestMinerService::default()) +} + +struct EthTester { + pub runtime: Runtime, + pub client: Arc, + pub accounts_provider: Arc, + pub miner: Arc, + pub io: IoHandler, +} + +impl Default for EthTester { + fn default() -> Self { + Self::new_with_options(Default::default()) + } +} + +impl EthTester { + pub fn new_with_options(options: EthClientOptions) -> Self { + let runtime = Runtime::with_thread_count(1); + let client = blockchain_client(); + let accounts_provider = accounts_provider(); + let ap = Arc::new(dispatch::Signer::new(accounts_provider.clone())) as _; + let miner = miner_service(); + let gas_price_percentile = options.gas_price_percentile; + let reservations = Arc::new(Mutex::new(nonce::Reservations::new(runtime.executor()))); + + let dispatcher = FullDispatcher::new(client.clone(), miner.clone(), reservations, gas_price_percentile); + let sign = SigningUnsafeClient::new(&ap, dispatcher).to_delegate(); + let mut io: IoHandler = IoHandler::default(); + io.extend_with(sign); + + EthTester { + runtime, + client, + miner, + io, + accounts_provider, + } + } +} + +#[test] +fn rpc_eth_send_transaction() { + let tester = EthTester::default(); + let address = tester.accounts_provider.new_account(&"".into()).unwrap(); + tester.accounts_provider.unlock_account_permanently(address, "".into()).unwrap(); + let request = r#"{ + "jsonrpc": "2.0", + "method": "eth_sendTransaction", + "params": [{ + "from": ""#.to_owned() + format!("0x{:x}", address).as_ref() + r#"", + "to": "0xd46e8dd67c5d32be8058bb8eb970870f07244567", + "gas": "0x76c0", + "gasPrice": "0x9184e72a000", + "value": "0x9184e72a" + }], + "id": 1 + }"#; + + let t = Transaction { + nonce: U256::zero(), + gas_price: U256::from(0x9184e72a000u64), + gas: U256::from(0x76c0), + action: Action::Call(Address::from_str("d46e8dd67c5d32be8058bb8eb970870f07244567").unwrap()), + value: U256::from(0x9184e72au64), + data: vec![] + }; + let signature = tester.accounts_provider.sign(address, None, t.hash(None)).unwrap(); + let t = t.with_signature(signature, None); + + let response = r#"{"jsonrpc":"2.0","result":""#.to_owned() + format!("0x{:x}", t.hash()).as_ref() + r#"","id":1}"#; + + assert_eq!(tester.io.handle_request_sync(&request), Some(response)); + + tester.miner.increment_nonce(&address); + + let t = Transaction { + nonce: U256::one(), + gas_price: U256::from(0x9184e72a000u64), + gas: U256::from(0x76c0), + action: Action::Call(Address::from_str("d46e8dd67c5d32be8058bb8eb970870f07244567").unwrap()), + value: U256::from(0x9184e72au64), + data: vec![] + }; + let signature = tester.accounts_provider.sign(address, None, t.hash(None)).unwrap(); + let t = t.with_signature(signature, None); + + let response = r#"{"jsonrpc":"2.0","result":""#.to_owned() + format!("0x{:x}", t.hash()).as_ref() + r#"","id":1}"#; + + assert_eq!(tester.io.handle_request_sync(&request), Some(response)); +} + +#[test] +fn rpc_eth_sign_transaction() { + let tester = EthTester::default(); + let address = tester.accounts_provider.new_account(&"".into()).unwrap(); + tester.accounts_provider.unlock_account_permanently(address, "".into()).unwrap(); + let request = r#"{ + "jsonrpc": "2.0", + "method": "eth_signTransaction", + "params": [{ + "from": ""#.to_owned() + format!("0x{:x}", address).as_ref() + r#"", + "to": "0xd46e8dd67c5d32be8058bb8eb970870f07244567", + "gas": "0x76c0", + "gasPrice": "0x9184e72a000", + "value": "0x9184e72a" + }], + "id": 1 + }"#; + + let t = Transaction { + nonce: U256::one(), + gas_price: U256::from(0x9184e72a000u64), + gas: U256::from(0x76c0), + action: Action::Call(Address::from_str("d46e8dd67c5d32be8058bb8eb970870f07244567").unwrap()), + value: U256::from(0x9184e72au64), + data: vec![] + }; + let signature = tester.accounts_provider.sign(address, None, t.hash(None)).unwrap(); + let t = t.with_signature(signature, None); + let signature = t.signature(); + let rlp = rlp::encode(&t); + + let response = r#"{"jsonrpc":"2.0","result":{"#.to_owned() + + r#""raw":"0x"# + &rlp.to_hex() + r#"","# + + r#""tx":{"# + + r#""blockHash":null,"blockNumber":null,"# + + &format!("\"chainId\":{},", t.chain_id().map_or("null".to_owned(), |n| format!("{}", n))) + + r#""condition":null,"creates":null,"# + + &format!("\"from\":\"0x{:x}\",", &address) + + r#""gas":"0x76c0","gasPrice":"0x9184e72a000","# + + &format!("\"hash\":\"0x{:x}\",", t.hash()) + + r#""input":"0x","# + + r#""nonce":"0x1","# + + &format!("\"publicKey\":\"0x{:x}\",", t.recover_public().unwrap()) + + &format!("\"r\":\"0x{:x}\",", U256::from(signature.r())) + + &format!("\"raw\":\"0x{}\",", rlp.to_hex()) + + &format!("\"s\":\"0x{:x}\",", U256::from(signature.s())) + + &format!("\"standardV\":\"0x{:x}\",", U256::from(t.standard_v())) + + r#""to":"0xd46e8dd67c5d32be8058bb8eb970870f07244567","transactionIndex":null,"# + + &format!("\"v\":\"0x{:x}\",", U256::from(t.original_v())) + + r#""value":"0x9184e72a""# + + r#"}},"id":1}"#; + + tester.miner.increment_nonce(&address); + + assert_eq!(tester.io.handle_request_sync(&request), Some(response)); +} + +#[test] +fn rpc_eth_send_transaction_with_bad_to() { + let tester = EthTester::default(); + let address = tester.accounts_provider.new_account(&"".into()).unwrap(); + let request = r#"{ + "jsonrpc": "2.0", + "method": "eth_sendTransaction", + "params": [{ + "from": ""#.to_owned() + format!("0x{:x}", address).as_ref() + r#"", + "to": "", + "gas": "0x76c0", + "gasPrice": "0x9184e72a000", + "value": "0x9184e72a" + }], + "id": 1 + }"#; + + let response = r#"{"jsonrpc":"2.0","error":{"code":-32602,"message":"Invalid params: expected a hex-encoded hash with 0x prefix."},"id":1}"#; + + assert_eq!(tester.io.handle_request_sync(&request), Some(response.into())); +} + +#[test] +fn rpc_eth_send_transaction_error() { + let tester = EthTester::default(); + let address = tester.accounts_provider.new_account(&"".into()).unwrap(); + let request = r#"{ + "jsonrpc": "2.0", + "method": "eth_sendTransaction", + "params": [{ + "from": ""#.to_owned() + format!("0x{:x}", address).as_ref() + r#"", + "to": "0xd46e8dd67c5d32be8058bb8eb970870f07244567", + "gas": "0x76c0", + "gasPrice": "0x9184e72a000", + "value": "0x9184e72a" + }], + "id": 1 + }"#; + + let response = r#"{"jsonrpc":"2.0","error":{"code":-32020,"message":"Your account is locked. Unlock the account via CLI, personal_unlockAccount or use Trusted Signer.","data":"NotUnlocked"},"id":1}"#; + assert_eq!(tester.io.handle_request_sync(&request), Some(response.into())); +} diff --git a/rpc/src/v1/traits/mod.rs b/rpc/src/v1/traits/mod.rs index 130fcae105..e25ca76ac4 100644 --- a/rpc/src/v1/traits/mod.rs +++ b/rpc/src/v1/traits/mod.rs @@ -40,8 +40,8 @@ pub use self::eth_pubsub::EthPubSub; pub use self::eth_signing::EthSigning; pub use self::net::Net; pub use self::parity::Parity; -pub use self::parity_accounts::ParityAccounts; -pub use self::parity_set::ParitySet; +pub use self::parity_accounts::{ParityAccounts, ParityAccountsInfo}; +pub use self::parity_set::{ParitySet, ParitySetAccounts}; pub use self::parity_signing::ParitySigning; pub use self::personal::Personal; pub use self::private::Private; diff --git a/rpc/src/v1/traits/parity.rs b/rpc/src/v1/traits/parity.rs index 836f58161b..4303af3d6f 100644 --- a/rpc/src/v1/traits/parity.rs +++ b/rpc/src/v1/traits/parity.rs @@ -26,7 +26,7 @@ use v1::types::{ TransactionStats, LocalTransactionStatus, BlockNumber, ConsensusCapability, VersionInfo, OperationsInfo, ChainStatus, Log, Filter, - AccountInfo, HwAccountInfo, RichHeader, Receipt, + RichHeader, Receipt, }; /// Parity-specific rpc interface. @@ -35,22 +35,6 @@ pub trait Parity { /// RPC Metadata type Metadata; - /// Returns accounts information. - #[rpc(name = "parity_accountsInfo")] - fn accounts_info(&self) -> Result>; - - /// Returns hardware accounts information. - #[rpc(name = "parity_hardwareAccountsInfo")] - fn hardware_accounts_info(&self) -> Result>; - - /// Get a list of paths to locked hardware wallets - #[rpc(name = "parity_lockedHardwareAccountsInfo")] - fn locked_hardware_accounts_info(&self) -> Result>; - - /// Returns default account for dapp. - #[rpc(name = "parity_defaultAccount")] - fn default_account(&self) -> Result; - /// Returns current transactions limit. #[rpc(name = "parity_transactionsLimit")] fn transactions_limit(&self) -> Result; diff --git a/rpc/src/v1/traits/parity_accounts.rs b/rpc/src/v1/traits/parity_accounts.rs index f10f109715..b17e4b8dfc 100644 --- a/rpc/src/v1/traits/parity_accounts.rs +++ b/rpc/src/v1/traits/parity_accounts.rs @@ -22,6 +22,27 @@ use jsonrpc_derive::rpc; use ethkey::Password; use ethstore::KeyFile; use v1::types::{H160, H256, H520, DeriveHash, DeriveHierarchical, ExtAccountInfo}; +use v1::types::{AccountInfo, HwAccountInfo}; + +/// Parity-specific read-only accounts rpc interface. +#[rpc] +pub trait ParityAccountsInfo { + /// Returns accounts information. + #[rpc(name = "parity_accountsInfo")] + fn accounts_info(&self) -> Result>; + + /// Returns hardware accounts information. + #[rpc(name = "parity_hardwareAccountsInfo")] + fn hardware_accounts_info(&self) -> Result>; + + /// Get a list of paths to locked hardware wallets + #[rpc(name = "parity_lockedHardwareAccountsInfo")] + fn locked_hardware_accounts_info(&self) -> Result>; + + /// Returns default account for dapp. + #[rpc(name = "parity_defaultAccount")] + fn default_account(&self) -> Result; +} /// Personal Parity rpc interface. #[rpc] diff --git a/rpc/src/v1/traits/parity_set.rs b/rpc/src/v1/traits/parity_set.rs index 9a0badaa29..b2628f364c 100644 --- a/rpc/src/v1/traits/parity_set.rs +++ b/rpc/src/v1/traits/parity_set.rs @@ -21,6 +21,14 @@ use jsonrpc_derive::rpc; use v1::types::{Bytes, H160, H256, U256, ReleaseInfo, Transaction}; +/// Parity-specific rpc interface for operations altering the account-related settings. +#[rpc] +pub trait ParitySetAccounts { + /// Sets account for signing consensus messages. + #[rpc(name = "parity_setEngineSigner")] + fn set_engine_signer(&self, H160, String) -> Result; +} + /// Parity-specific rpc interface for operations altering the settings. #[rpc] pub trait ParitySet { @@ -44,9 +52,9 @@ pub trait ParitySet { #[rpc(name = "parity_setAuthor")] fn set_author(&self, H160) -> Result; - /// Sets account for signing consensus messages. - #[rpc(name = "parity_setEngineSigner")] - fn set_engine_signer(&self, H160, String) -> Result; + /// Sets the secret of engine signer account. + #[rpc(name = "parity_setEngineSignerSecret")] + fn set_engine_signer_secret(&self, H256) -> Result; /// Sets the limits for transaction queue. #[rpc(name = "parity_setTransactionsLimit")] diff --git a/rpc/src/v1/traits/signer.rs b/rpc/src/v1/traits/signer.rs index 84eccf0d39..675808a980 100644 --- a/rpc/src/v1/traits/signer.rs +++ b/rpc/src/v1/traits/signer.rs @@ -51,10 +51,6 @@ pub trait Signer { #[rpc(name = "signer_generateAuthorizationToken")] fn generate_token(&self) -> Result; - /// Generates new web proxy access token for particular domain. - #[rpc(name = "signer_generateWebProxyAccessToken")] - fn generate_web_proxy_token(&self, String) -> Result; - /// Subscribe to new pending requests on signer interface. #[pubsub(subscription = "signer_pending", subscribe, name = "signer_subscribePending")] fn subscribe_pending(&self, Self::Metadata, Subscriber>); diff --git a/secret-store/Cargo.toml b/secret-store/Cargo.toml index a53d90e22b..0303472fe4 100644 --- a/secret-store/Cargo.toml +++ b/secret-store/Cargo.toml @@ -8,36 +8,40 @@ authors = ["Parity Technologies "] [dependencies] byteorder = "1.0" common-types = { path = "../ethcore/types" } +ethabi = "6.0" +ethabi-contract = "6.0" +ethabi-derive = "6.0" +ethcore = { path = "../ethcore" } +ethcore-accounts = { path = "../accounts", optional = true} ethcore-call-contract = { path = "../ethcore/call-contract" } +ethcore-sync = { path = "../ethcore/sync" } +ethereum-types = "0.4" +ethkey = { path = "../accounts/ethkey" } +futures = "0.1" +hyper = { version = "0.12", default-features = false } +keccak-hash = "0.1" +kvdb = "0.1" +lazy_static = "1.0" log = "0.4" +parity-bytes = "0.1" +parity-crypto = "0.3" +parity-runtime = { path = "../util/runtime" } parking_lot = "0.7" -hyper = { version = "0.12", default-features = false } +rustc-hex = "1.0" serde = "1.0" -serde_json = "1.0" serde_derive = "1.0" -futures = "0.1" -rustc-hex = "1.0" +serde_json = "1.0" tiny-keccak = "1.4" tokio = "~0.1.11" -parity-runtime = { path = "../util/runtime" } tokio-io = "0.1" tokio-service = "0.1" url = "1.0" -ethcore = { path = "../ethcore" } -parity-bytes = "0.1" -parity-crypto = "0.3.0" -ethcore-sync = { path = "../ethcore/sync" } -ethereum-types = "0.4" -kvdb = "0.1" -keccak-hash = "0.1" -ethkey = { path = "../accounts/ethkey" } -lazy_static = "1.0" -ethabi = "6.0" -ethabi-derive = "6.0" -ethabi-contract = "6.0" [dev-dependencies] env_logger = "0.5" ethcore = { path = "../ethcore", features = ["test-helpers"] } tempdir = "0.3" kvdb-rocksdb = "0.1.3" + +[features] +accounts = ["ethcore-accounts"] diff --git a/secret-store/src/lib.rs b/secret-store/src/lib.rs index 915cec5288..a3c82991b1 100644 --- a/secret-store/src/lib.rs +++ b/secret-store/src/lib.rs @@ -56,6 +56,9 @@ extern crate env_logger; #[cfg(test)] extern crate kvdb_rocksdb; +#[cfg(feature = "accounts")] +extern crate ethcore_accounts as accounts; + mod key_server_cluster; mod types; mod helpers; @@ -80,7 +83,9 @@ use parity_runtime::Executor; pub use types::{ServerKeyId, EncryptedDocumentKey, RequestSignature, Public, Error, NodeAddress, ContractAddress, ServiceConfiguration, ClusterConfiguration}; pub use traits::{NodeKeyPair, KeyServer}; -pub use self::node_key_pair::{PlainNodeKeyPair, KeyStoreNodeKeyPair}; +pub use self::node_key_pair::PlainNodeKeyPair; +#[cfg(feature = "accounts")] +pub use self::node_key_pair::KeyStoreNodeKeyPair; /// Start new key server instance pub fn start(client: Arc, sync: Arc, miner: Arc, self_key_pair: Arc, mut config: ServiceConfiguration, diff --git a/secret-store/src/node_key_pair.rs b/secret-store/src/node_key_pair.rs index 6293858891..e7227d7540 100644 --- a/secret-store/src/node_key_pair.rs +++ b/secret-store/src/node_key_pair.rs @@ -14,25 +14,15 @@ // You should have received a copy of the GNU General Public License // along with Parity Ethereum. If not, see . -use std::sync::Arc; use ethkey::crypto::ecdh::agree; use ethkey::{KeyPair, Public, Signature, Error as EthKeyError, sign, public_to_address}; -use ethcore::account_provider::AccountProvider; use ethereum_types::{H256, Address}; use traits::NodeKeyPair; -use ethkey::Password; pub struct PlainNodeKeyPair { key_pair: KeyPair, } -pub struct KeyStoreNodeKeyPair { - account_provider: Arc, - address: Address, - public: Public, - password: Password, -} - impl PlainNodeKeyPair { pub fn new(key_pair: KeyPair) -> Self { PlainNodeKeyPair { @@ -61,34 +51,52 @@ impl NodeKeyPair for PlainNodeKeyPair { } } -impl KeyStoreNodeKeyPair { - pub fn new(account_provider: Arc, address: Address, password: Password) -> Result { - let public = account_provider.account_public(address.clone(), &password).map_err(|e| EthKeyError::Custom(format!("{}", e)))?; - Ok(KeyStoreNodeKeyPair { - account_provider: account_provider, - address: address, - public: public, - password: password, - }) +#[cfg(feature = "accounts")] +mod accounts { + use super::*; + use std::sync::Arc; + use ethkey::Password; + use accounts::AccountProvider; + + pub struct KeyStoreNodeKeyPair { + account_provider: Arc, + address: Address, + public: Public, + password: Password, } -} -impl NodeKeyPair for KeyStoreNodeKeyPair { - fn public(&self) -> &Public { - &self.public + impl KeyStoreNodeKeyPair { + pub fn new(account_provider: Arc, address: Address, password: Password) -> Result { + let public = account_provider.account_public(address.clone(), &password).map_err(|e| EthKeyError::Custom(format!("{}", e)))?; + Ok(KeyStoreNodeKeyPair { + account_provider: account_provider, + address: address, + public: public, + password: password, + }) + } } - fn address(&self) -> Address { - public_to_address(&self.public) - } + impl NodeKeyPair for KeyStoreNodeKeyPair { + fn public(&self) -> &Public { + &self.public + } - fn sign(&self, data: &H256) -> Result { - self.account_provider.sign(self.address.clone(), Some(self.password.clone()), data.clone()) - .map_err(|e| EthKeyError::Custom(format!("{}", e))) - } + fn address(&self) -> Address { + public_to_address(&self.public) + } - fn compute_shared_key(&self, peer_public: &Public) -> Result { - KeyPair::from_secret(self.account_provider.agree(self.address.clone(), Some(self.password.clone()), peer_public) - .map_err(|e| EthKeyError::Custom(format!("{}", e)))?) + fn sign(&self, data: &H256) -> Result { + self.account_provider.sign(self.address.clone(), Some(self.password.clone()), data.clone()) + .map_err(|e| EthKeyError::Custom(format!("{}", e))) + } + + fn compute_shared_key(&self, peer_public: &Public) -> Result { + KeyPair::from_secret(self.account_provider.agree(self.address.clone(), Some(self.password.clone()), peer_public) + .map_err(|e| EthKeyError::Custom(format!("{}", e)))?) + } } } + +#[cfg(feature = "accounts")] +pub use self::accounts::KeyStoreNodeKeyPair; From b7e8621846a19cc05e124e4d204b5bd57efadd84 Mon Sep 17 00:00:00 2001 From: elferdo Date: Thu, 7 Feb 2019 15:27:09 +0100 Subject: [PATCH 053/168] Increase number of requested block bodies in chain sync (#10247) * Increase the number of block bodies requested during Sync. * Increase the number of block bodies requested during Sync. * Check if our peer is an older parity client with the bug of not handling large requests properly * Add a ClientVersion struct and a ClientCapabilites trait * Make ClientVersion its own module * Refactor and extend use of ClientVersion * Replace strings with ClientVersion in PeerInfo * Group further functionality in ClientCapabilities * Move parity client version data from tuple to its own struct. * Implement accessor methods for ParityClientData and remove them from ClientVersion. * Minor fixes * Make functions specific to parity return types specific to parity. * Test for shorter ID strings * Fix formatting and remove unneeded dependencies. * Roll back Cargo.lock * Commit last Cargo.lock * Convert from string to ClientVersion * * When checking if peer accepts service transactions just check if it's parity, remove version check. * Remove dependency on semver in ethcore-sync * Remove unnecessary String instantiation * Rename peer_info to peer_version * Update RPC test helpers * Simplify From * Parse static version string only once * Update RPC tests to new ClientVersion struct * Document public members * More robust parsing of ID string * Minor changes. * Update version in which large block bodies requests appear. * Update ethcore/sync/src/block_sync.rs Co-Authored-By: elferdo * Update util/network/src/client_version.rs Co-Authored-By: elferdo * Update util/network/src/client_version.rs Co-Authored-By: elferdo * Update tests. * Minor fixes. --- Cargo.lock | 5 + ethcore/sync/src/api.rs | 3 +- ethcore/sync/src/block_sync.rs | 21 +- ethcore/sync/src/chain/handler.rs | 12 +- ethcore/sync/src/chain/mod.rs | 8 +- ethcore/sync/src/chain/propagator.rs | 41 +- ethcore/sync/src/chain/requester.rs | 1 + ethcore/sync/src/chain/supplier.rs | 2 +- ethcore/sync/src/sync_io.rs | 9 +- ethcore/sync/src/tests/helpers.rs | 9 +- rpc/Cargo.toml | 1 + rpc/src/lib.rs | 1 + rpc/src/v1/tests/helpers/sync_provider.rs | 5 +- rpc/src/v1/tests/mocked/parity.rs | 2 +- rpc/src/v1/types/sync.rs | 3 +- util/network-devp2p/src/host.rs | 5 +- util/network-devp2p/src/session.rs | 6 +- util/network-devp2p/tests/tests.rs | 2 +- util/network/Cargo.toml | 4 + util/network/src/client_version.rs | 515 ++++++++++++++++++++++ util/network/src/lib.rs | 17 +- 21 files changed, 607 insertions(+), 65 deletions(-) create mode 100644 util/network/src/client_version.rs diff --git a/Cargo.lock b/Cargo.lock index 5e631b2eb1..abf4b735c9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -939,10 +939,14 @@ dependencies = [ "ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethkey 0.3.0", "ipnetwork 0.12.8 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", "parity-crypto 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-snappy 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "rlp 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3478,6 +3482,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] diff --git a/ethcore/sync/src/api.rs b/ethcore/sync/src/api.rs index dda3393add..9374b3ff25 100644 --- a/ethcore/sync/src/api.rs +++ b/ethcore/sync/src/api.rs @@ -24,6 +24,7 @@ use devp2p::NetworkService; use network::{NetworkProtocolHandler, NetworkContext, PeerId, ProtocolId, NetworkConfiguration as BasicNetworkConfiguration, NonReservedPeerMode, Error, ErrorKind, ConnectionFilter}; +use network::client_version::ClientVersion; use types::pruning_info::PruningInfo; use ethereum_types::{H256, H512, U256}; @@ -158,7 +159,7 @@ pub struct PeerInfo { /// Public node id pub id: Option, /// Node client ID - pub client_version: String, + pub client_version: ClientVersion, /// Capabilities pub capabilities: Vec, /// Remote endpoint address diff --git a/ethcore/sync/src/block_sync.rs b/ethcore/sync/src/block_sync.rs index 2331e214c5..04ffa5f18d 100644 --- a/ethcore/sync/src/block_sync.rs +++ b/ethcore/sync/src/block_sync.rs @@ -29,10 +29,13 @@ use ethcore::error::{ImportErrorKind, QueueErrorKind, BlockError, Error as Ethco use sync_io::SyncIo; use blocks::{BlockCollection, SyncBody, SyncHeader}; use chain::BlockSet; +use network::PeerId; +use network::client_version::ClientCapabilities; const MAX_HEADERS_TO_REQUEST: usize = 128; -const MAX_BODIES_TO_REQUEST: usize = 32; -const MAX_RECEPITS_TO_REQUEST: usize = 128; +const MAX_BODIES_TO_REQUEST_LARGE: usize = 128; +const MAX_BODIES_TO_REQUEST_SMALL: usize = 32; // Size request for parity clients prior to 2.4.0 +const MAX_RECEPITS_TO_REQUEST: usize = 256; const SUBCHAIN_SIZE: u64 = 256; const MAX_ROUND_PARENTS: usize = 16; const MAX_PARALLEL_SUBCHAIN_DOWNLOAD: usize = 5; @@ -464,12 +467,12 @@ impl BlockDownloader { } /// Find some headers or blocks to download for a peer. - pub fn request_blocks(&mut self, io: &mut SyncIo, num_active_peers: usize) -> Option { + pub fn request_blocks(&mut self, peer_id: PeerId, io: &mut SyncIo, num_active_peers: usize) -> Option { match self.state { State::Idle => { self.start_sync_round(io); if self.state == State::ChainHead { - return self.request_blocks(io, num_active_peers); + return self.request_blocks(peer_id, io, num_active_peers); } }, State::ChainHead => { @@ -487,7 +490,15 @@ impl BlockDownloader { }, State::Blocks => { // check to see if we need to download any block bodies first - let needed_bodies = self.blocks.needed_bodies(MAX_BODIES_TO_REQUEST, false); + let client_version = io.peer_version(peer_id); + + let number_of_bodies_to_request = if client_version.can_handle_large_requests() { + MAX_BODIES_TO_REQUEST_LARGE + } else { + MAX_BODIES_TO_REQUEST_SMALL + }; + + let needed_bodies = self.blocks.needed_bodies(number_of_bodies_to_request, false); if !needed_bodies.is_empty() { return Some(BlockRequest::Bodies { hashes: needed_bodies, diff --git a/ethcore/sync/src/chain/handler.rs b/ethcore/sync/src/chain/handler.rs index 5630ea2563..83323ba996 100644 --- a/ethcore/sync/src/chain/handler.rs +++ b/ethcore/sync/src/chain/handler.rs @@ -23,6 +23,7 @@ use ethcore::verification::queue::kind::blocks::Unverified; use ethereum_types::{H256, U256}; use hash::keccak; use network::PeerId; +use network::client_version::ClientVersion; use rlp::Rlp; use snapshot::ChunkType; use std::time::Instant; @@ -107,7 +108,7 @@ impl SyncHandler { /// Called by peer when it is disconnecting pub fn on_peer_aborting(sync: &mut ChainSync, io: &mut SyncIo, peer_id: PeerId) { - trace!(target: "sync", "== Disconnecting {}: {}", peer_id, io.peer_info(peer_id)); + trace!(target: "sync", "== Disconnecting {}: {}", peer_id, io.peer_version(peer_id)); sync.handshaking_peers.remove(&peer_id); if sync.peers.contains_key(&peer_id) { debug!(target: "sync", "Disconnected {}", peer_id); @@ -133,7 +134,7 @@ impl SyncHandler { /// Called when a new peer is connected pub fn on_peer_connected(sync: &mut ChainSync, io: &mut SyncIo, peer: PeerId) { - trace!(target: "sync", "== Connected {}: {}", peer, io.peer_info(peer)); + trace!(target: "sync", "== Connected {}: {}", peer, io.peer_version(peer)); if let Err(e) = sync.send_status(io, peer) { debug!(target:"sync", "Error sending status request: {:?}", e); io.disconnect_peer(peer); @@ -579,6 +580,7 @@ impl SyncHandler { snapshot_number: if warp_protocol { Some(r.val_at(6)?) } else { None }, block_set: None, private_tx_enabled: if private_tx_protocol { r.val_at(7).unwrap_or(false) } else { false }, + client_version: ClientVersion::from(io.peer_version(peer_id)), }; trace!(target: "sync", "New peer {} (\ @@ -599,12 +601,12 @@ impl SyncHandler { peer.private_tx_enabled ); if io.is_expired() { - trace!(target: "sync", "Status packet from expired session {}:{}", peer_id, io.peer_info(peer_id)); + trace!(target: "sync", "Status packet from expired session {}:{}", peer_id, io.peer_version(peer_id)); return Ok(()); } if sync.peers.contains_key(&peer_id) { - debug!(target: "sync", "Unexpected status packet from {}:{}", peer_id, io.peer_info(peer_id)); + debug!(target: "sync", "Unexpected status packet from {}:{}", peer_id, io.peer_version(peer_id)); return Ok(()); } let chain_info = io.chain().chain_info(); @@ -633,7 +635,7 @@ impl SyncHandler { // Don't activate peer immediatelly when searching for common block. // Let the current sync round complete first. sync.active_peers.insert(peer_id.clone()); - debug!(target: "sync", "Connected {}:{}", peer_id, io.peer_info(peer_id)); + debug!(target: "sync", "Connected {}:{}", peer_id, io.peer_version(peer_id)); if let Some((fork_block, _)) = sync.fork_block { SyncRequester::request_fork_header(sync, io, peer_id, fork_block); diff --git a/ethcore/sync/src/chain/mod.rs b/ethcore/sync/src/chain/mod.rs index 3a8c0a19bc..5a144853d6 100644 --- a/ethcore/sync/src/chain/mod.rs +++ b/ethcore/sync/src/chain/mod.rs @@ -104,6 +104,7 @@ use parking_lot::{Mutex, RwLock, RwLockWriteGuard}; use bytes::Bytes; use rlp::{RlpStream, DecoderError}; use network::{self, PeerId, PacketId}; +use network::client_version::ClientVersion; use ethcore::client::{BlockChainClient, BlockStatus, BlockId, BlockChainInfo, BlockQueueInfo}; use ethcore::snapshot::{RestorationStatus}; use sync_io::SyncIo; @@ -342,6 +343,8 @@ pub struct PeerInfo { snapshot_number: Option, /// Block set requested block_set: Option, + /// Version of the software the peer is running + client_version: ClientVersion, } impl PeerInfo { @@ -964,7 +967,7 @@ impl ChainSync { if !have_latest && (higher_difficulty || force || self.state == SyncState::NewBlocks) { // check if got new blocks to download trace!(target: "sync", "Syncing with peer {}, force={}, td={:?}, our td={}, state={:?}", peer_id, force, peer_difficulty, syncing_difficulty, self.state); - if let Some(request) = self.new_blocks.request_blocks(io, num_active_peers) { + if let Some(request) = self.new_blocks.request_blocks(peer_id, io, num_active_peers) { SyncRequester::request_blocks(self, io, peer_id, request, BlockSet::NewBlocks); if self.state == SyncState::Idle { self.state = SyncState::Blocks; @@ -977,7 +980,7 @@ impl ChainSync { let equal_or_higher_difficulty = peer_difficulty.map_or(false, |pd| pd >= syncing_difficulty); if force || equal_or_higher_difficulty { - if let Some(request) = self.old_blocks.as_mut().and_then(|d| d.request_blocks(io, num_active_peers)) { + if let Some(request) = self.old_blocks.as_mut().and_then(|d| d.request_blocks(peer_id, io, num_active_peers)) { SyncRequester::request_blocks(self, io, peer_id, request, BlockSet::OldBlocks); return; } @@ -1459,6 +1462,7 @@ pub mod tests { snapshot_hash: None, asking_snapshot_data: None, block_set: None, + client_version: ClientVersion::from(""), }); } diff --git a/ethcore/sync/src/chain/propagator.rs b/ethcore/sync/src/chain/propagator.rs index 74ef27e887..9d50fafc14 100644 --- a/ethcore/sync/src/chain/propagator.rs +++ b/ethcore/sync/src/chain/propagator.rs @@ -21,6 +21,7 @@ use bytes::Bytes; use ethereum_types::H256; use fastmap::H256FastSet; use network::{PeerId, PacketId}; +use network::client_version::ClientCapabilities; use rand::Rng; use rlp::{Encodable, RlpStream}; use sync_io::SyncIo; @@ -41,28 +42,6 @@ use super::{ TRANSACTIONS_PACKET, }; -/// Checks if peer is able to process service transactions -fn accepts_service_transaction(client_id: &str) -> bool { - // Parity versions starting from this will accept service-transactions - const SERVICE_TRANSACTIONS_VERSION: (u32, u32) = (1u32, 6u32); - // Parity client string prefix - const LEGACY_CLIENT_ID_PREFIX: &'static str = "Parity/"; - const PARITY_CLIENT_ID_PREFIX: &'static str = "Parity-Ethereum/"; - const VERSION_PREFIX: &'static str = "/v"; - - let idx = client_id.rfind(VERSION_PREFIX).map(|idx| idx + VERSION_PREFIX.len()).unwrap_or(client_id.len()); - let splitted = if client_id.starts_with(LEGACY_CLIENT_ID_PREFIX) || client_id.starts_with(PARITY_CLIENT_ID_PREFIX) { - client_id[idx..].split('.') - } else { - return false; - }; - - let ver: Vec = splitted - .take(2) - .filter_map(|s| s.parse().ok()) - .collect(); - ver.len() == 2 && (ver[0] > SERVICE_TRANSACTIONS_VERSION.0 || (ver[0] == SERVICE_TRANSACTIONS_VERSION.0 && ver[1] >= SERVICE_TRANSACTIONS_VERSION.1)) -} /// The Chain Sync Propagator: propagates data to peers pub struct SyncPropagator; @@ -146,7 +125,7 @@ impl SyncPropagator { // most of times service_transactions will be empty // => there's no need to merge packets if !service_transactions.is_empty() { - let service_transactions_peers = SyncPropagator::select_peers_for_transactions(sync, |peer_id| accepts_service_transaction(&io.peer_info(*peer_id))); + let service_transactions_peers = SyncPropagator::select_peers_for_transactions(sync, |peer_id| io.peer_version(*peer_id).accepts_service_transaction()); let service_transactions_affected_peers = SyncPropagator::propagate_transactions_to_peers( sync, io, service_transactions_peers, service_transactions, &mut should_continue ); @@ -451,6 +430,7 @@ mod tests { snapshot_hash: None, asking_snapshot_data: None, block_set: None, + client_version: ClientVersion::from(""), }); let ss = TestSnapshotService::new(); let mut io = TestIo::new(&mut client, &ss, &queue, None); @@ -598,20 +578,17 @@ mod tests { io.peers_info.insert(1, "Geth".to_owned()); // and peer#2 is Parity, accepting service transactions insert_dummy_peer(&mut sync, 2, block_hash); - io.peers_info.insert(2, "Parity-Ethereum/v2.6".to_owned()); - // and peer#3 is Parity, discarding service transactions + io.peers_info.insert(2, "Parity-Ethereum/v2.6.0/linux/rustc".to_owned()); + // and peer#3 is Parity, accepting service transactions insert_dummy_peer(&mut sync, 3, block_hash); - io.peers_info.insert(3, "Parity/v1.5".to_owned()); - // and peer#4 is Parity, accepting service transactions - insert_dummy_peer(&mut sync, 4, block_hash); - io.peers_info.insert(4, "Parity-Ethereum/ABCDEFGH/v2.7.3".to_owned()); + io.peers_info.insert(3, "Parity-Ethereum/ABCDEFGH/v2.7.3/linux/rustc".to_owned()); // and new service transaction is propagated to peers SyncPropagator::propagate_new_transactions(&mut sync, &mut io, || true); - // peer#2 && peer#4 are receiving service transaction + // peer#2 && peer#3 are receiving service transaction assert!(io.packets.iter().any(|p| p.packet_id == 0x02 && p.recipient == 2)); // TRANSACTIONS_PACKET - assert!(io.packets.iter().any(|p| p.packet_id == 0x02 && p.recipient == 4)); // TRANSACTIONS_PACKET + assert!(io.packets.iter().any(|p| p.packet_id == 0x02 && p.recipient == 3)); // TRANSACTIONS_PACKET assert_eq!(io.packets.len(), 2); } @@ -628,7 +605,7 @@ mod tests { // when peer#1 is Parity, accepting service transactions insert_dummy_peer(&mut sync, 1, block_hash); - io.peers_info.insert(1, "Parity-Ethereum/v2.6".to_owned()); + io.peers_info.insert(1, "Parity-Ethereum/v2.6.0/linux/rustc".to_owned()); // and service + non-service transactions are propagated to peers SyncPropagator::propagate_new_transactions(&mut sync, &mut io, || true); diff --git a/ethcore/sync/src/chain/requester.rs b/ethcore/sync/src/chain/requester.rs index 7307ffc448..09eec748ec 100644 --- a/ethcore/sync/src/chain/requester.rs +++ b/ethcore/sync/src/chain/requester.rs @@ -62,6 +62,7 @@ impl SyncRequester { for h in &hashes { rlp.append(&h.clone()); } + SyncRequester::send_request(sync, io, peer_id, PeerAsking::BlockBodies, GET_BLOCK_BODIES_PACKET, rlp.out()); let peer = sync.peers.get_mut(&peer_id).expect("peer_id may originate either from on_packet, where it is already validated or from enumerating self.peers. qed"); peer.asking_blocks = hashes; diff --git a/ethcore/sync/src/chain/supplier.rs b/ethcore/sync/src/chain/supplier.rs index 8656abcffd..d691cb35af 100644 --- a/ethcore/sync/src/chain/supplier.rs +++ b/ethcore/sync/src/chain/supplier.rs @@ -91,7 +91,7 @@ impl SyncSupplier { // Packets that require the peer to be confirmed _ => { if !sync.read().peers.contains_key(&peer) { - debug!(target:"sync", "Unexpected packet {} from unregistered peer: {}:{}", packet_id, peer, io.peer_info(peer)); + debug!(target:"sync", "Unexpected packet {} from unregistered peer: {}:{}", packet_id, peer, io.peer_version(peer)); return; } debug!(target: "sync", "{} -> Dispatching packet: {}", peer, packet_id); diff --git a/ethcore/sync/src/sync_io.rs b/ethcore/sync/src/sync_io.rs index 81dc9cf90c..b4cd9a08fd 100644 --- a/ethcore/sync/src/sync_io.rs +++ b/ethcore/sync/src/sync_io.rs @@ -16,6 +16,7 @@ use std::collections::HashMap; use network::{NetworkContext, PeerId, PacketId, Error, SessionInfo, ProtocolId}; +use network::client_version::ClientVersion; use bytes::Bytes; use ethcore::client::BlockChainClient; use types::BlockNumber; @@ -40,9 +41,9 @@ pub trait SyncIo { fn chain(&self) -> &BlockChainClient; /// Get the snapshot service. fn snapshot_service(&self) -> &SnapshotService; - /// Returns peer identifier string - fn peer_info(&self, peer_id: PeerId) -> String { - peer_id.to_string() + /// Returns peer version identifier + fn peer_version(&self, peer_id: PeerId) -> ClientVersion { + ClientVersion::from(peer_id.to_string()) } /// Returns information on p2p session fn peer_session_info(&self, peer_id: PeerId) -> Option; @@ -134,7 +135,7 @@ impl<'s> SyncIo for NetSyncIo<'s> { self.network.protocol_version(*protocol, peer_id).unwrap_or(0) } - fn peer_info(&self, peer_id: PeerId) -> String { + fn peer_version(&self, peer_id: PeerId) -> ClientVersion { self.network.peer_client_version(peer_id) } diff --git a/ethcore/sync/src/tests/helpers.rs b/ethcore/sync/src/tests/helpers.rs index f7207c6788..cdc55fba06 100644 --- a/ethcore/sync/src/tests/helpers.rs +++ b/ethcore/sync/src/tests/helpers.rs @@ -20,6 +20,7 @@ use ethereum_types::H256; use parking_lot::{RwLock, Mutex}; use bytes::Bytes; use network::{self, PeerId, ProtocolId, PacketId, SessionInfo}; +use network::client_version::ClientVersion; use tests::snapshot::*; use ethcore::client::{TestBlockChainClient, BlockChainClient, Client as EthcoreClient, ClientConfig, ChainNotify, NewBlocks, ChainMessageType, ClientIoMessage}; @@ -118,10 +119,12 @@ impl<'p, C> SyncIo for TestIo<'p, C> where C: FlushingBlockChainClient, C: 'p { &*self.chain } - fn peer_info(&self, peer_id: PeerId) -> String { - self.peers_info.get(&peer_id) + fn peer_version(&self, peer_id: PeerId) -> ClientVersion { + let client_id = self.peers_info.get(&peer_id) .cloned() - .unwrap_or_else(|| peer_id.to_string()) + .unwrap_or_else(|| peer_id.to_string()); + + ClientVersion::from(client_id) } fn snapshot_service(&self) -> &SnapshotService { diff --git a/rpc/Cargo.toml b/rpc/Cargo.toml index b90d33e7f5..765e868de2 100644 --- a/rpc/Cargo.toml +++ b/rpc/Cargo.toml @@ -42,6 +42,7 @@ ethcore-io = { path = "../util/io" } ethcore-light = { path = "../ethcore/light" } ethcore-logger = { path = "../parity/logger" } ethcore-miner = { path = "../miner" } +ethcore-network = { path = "../util/network" } ethcore-private-tx = { path = "../ethcore/private-tx" } ethcore-sync = { path = "../ethcore/sync" } ethereum-types = "0.4" diff --git a/rpc/src/lib.rs b/rpc/src/lib.rs index f8e16ae6bb..c7f0ad09d4 100644 --- a/rpc/src/lib.rs +++ b/rpc/src/lib.rs @@ -52,6 +52,7 @@ extern crate ethcore_io as io; extern crate ethcore_light as light; extern crate ethcore_logger; extern crate ethcore_miner as miner; +extern crate ethcore_network as network; extern crate ethcore_private_tx; extern crate ethcore_sync as sync; extern crate ethereum_types; diff --git a/rpc/src/v1/tests/helpers/sync_provider.rs b/rpc/src/v1/tests/helpers/sync_provider.rs index 0ef87cd8fb..37c2f93553 100644 --- a/rpc/src/v1/tests/helpers/sync_provider.rs +++ b/rpc/src/v1/tests/helpers/sync_provider.rs @@ -20,6 +20,7 @@ use std::collections::BTreeMap; use ethereum_types::H256; use parking_lot::RwLock; use sync::{SyncProvider, EthProtocolInfo, SyncStatus, SyncState, PeerInfo, TransactionStats}; +use network::client_version::ClientVersion; /// TestSyncProvider config. pub struct Config { @@ -75,7 +76,7 @@ impl SyncProvider for TestSyncProvider { vec![ PeerInfo { id: Some("node1".to_owned()), - client_version: "Parity-Ethereum/1".to_owned(), + client_version: ClientVersion::from("Parity-Ethereum/1/v2.4.0/linux/rustc"), capabilities: vec!["eth/62".to_owned(), "eth/63".to_owned()], remote_address: "127.0.0.1:7777".to_owned(), local_address: "127.0.0.1:8888".to_owned(), @@ -88,7 +89,7 @@ impl SyncProvider for TestSyncProvider { }, PeerInfo { id: None, - client_version: "Parity-Ethereum/2".to_owned(), + client_version: ClientVersion::from("Parity-Ethereum/2/v2.4.0/linux/rustc"), capabilities: vec!["eth/63".to_owned(), "eth/64".to_owned()], remote_address: "Handshake".to_owned(), local_address: "127.0.0.1:3333".to_owned(), diff --git a/rpc/src/v1/tests/mocked/parity.rs b/rpc/src/v1/tests/mocked/parity.rs index f97db6509d..6608589f55 100644 --- a/rpc/src/v1/tests/mocked/parity.rs +++ b/rpc/src/v1/tests/mocked/parity.rs @@ -251,7 +251,7 @@ fn rpc_parity_net_peers() { let io = deps.default_client(); let request = r#"{"jsonrpc": "2.0", "method": "parity_netPeers", "params":[], "id": 1}"#; - let response = r#"{"jsonrpc":"2.0","result":{"active":0,"connected":120,"max":50,"peers":[{"caps":["eth/62","eth/63"],"id":"node1","name":"Parity-Ethereum/1","network":{"localAddress":"127.0.0.1:8888","remoteAddress":"127.0.0.1:7777"},"protocols":{"eth":{"difficulty":"0x28","head":"0000000000000000000000000000000000000000000000000000000000000032","version":62},"pip":null}},{"caps":["eth/63","eth/64"],"id":null,"name":"Parity-Ethereum/2","network":{"localAddress":"127.0.0.1:3333","remoteAddress":"Handshake"},"protocols":{"eth":{"difficulty":null,"head":"000000000000000000000000000000000000000000000000000000000000003c","version":64},"pip":null}}]},"id":1}"#; + let response = r#"{"jsonrpc":"2.0","result":{"active":0,"connected":120,"max":50,"peers":[{"caps":["eth/62","eth/63"],"id":"node1","name":{"ParityClient":{"can_handle_large_requests":true,"compiler":"rustc","identity":"1","name":"Parity-Ethereum","os":"linux","semver":"2.4.0"}},"network":{"localAddress":"127.0.0.1:8888","remoteAddress":"127.0.0.1:7777"},"protocols":{"eth":{"difficulty":"0x28","head":"0000000000000000000000000000000000000000000000000000000000000032","version":62},"pip":null}},{"caps":["eth/63","eth/64"],"id":null,"name":{"ParityClient":{"can_handle_large_requests":true,"compiler":"rustc","identity":"2","name":"Parity-Ethereum","os":"linux","semver":"2.4.0"}},"network":{"localAddress":"127.0.0.1:3333","remoteAddress":"Handshake"},"protocols":{"eth":{"difficulty":null,"head":"000000000000000000000000000000000000000000000000000000000000003c","version":64},"pip":null}}]},"id":1}"#; assert_eq!(io.handle_request_sync(request), Some(response.to_owned())); } diff --git a/rpc/src/v1/types/sync.rs b/rpc/src/v1/types/sync.rs index b56d1f9ccb..e51c853ad9 100644 --- a/rpc/src/v1/types/sync.rs +++ b/rpc/src/v1/types/sync.rs @@ -14,6 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Parity Ethereum. If not, see . +use network::client_version::ClientVersion; use std::collections::BTreeMap; use sync::{self, PeerInfo as SyncPeerInfo, TransactionStats as SyncTransactionStats}; use serde::{Serialize, Serializer}; @@ -54,7 +55,7 @@ pub struct PeerInfo { /// Public node id pub id: Option, /// Node client ID - pub name: String, + pub name: ClientVersion, /// Capabilities pub caps: Vec, /// Network information diff --git a/util/network-devp2p/src/host.rs b/util/network-devp2p/src/host.rs index 672fd30fbf..f067260ceb 100644 --- a/util/network-devp2p/src/host.rs +++ b/util/network-devp2p/src/host.rs @@ -42,6 +42,7 @@ use network::{NetworkConfiguration, NetworkIoMessage, ProtocolId, PeerId, Packet use network::{NonReservedPeerMode, NetworkContext as NetworkContextTrait}; use network::{SessionInfo, Error, ErrorKind, DisconnectReason, NetworkProtocolHandler}; use discovery::{Discovery, TableUpdates, NodeEntry, MAX_DATAGRAM_SIZE}; +use network::client_version::ClientVersion; use ip_utils::{map_external_address, select_public_address}; use parity_path::restrict_permissions_owner; use parking_lot::{Mutex, RwLock}; @@ -180,8 +181,8 @@ impl<'s> NetworkContextTrait for NetworkContext<'s> { Ok(()) } - fn peer_client_version(&self, peer: PeerId) -> String { - self.resolve_session(peer).map_or("unknown".to_owned(), |s| s.lock().info.client_version.clone()) + fn peer_client_version(&self, peer: PeerId) -> ClientVersion { + self.resolve_session(peer).map_or(ClientVersion::from("unknown").to_owned(), |s| s.lock().info.client_version.clone()) } fn session_info(&self, peer: PeerId) -> Option { diff --git a/util/network-devp2p/src/session.rs b/util/network-devp2p/src/session.rs index 6ba982bb11..6cecaf3610 100644 --- a/util/network-devp2p/src/session.rs +++ b/util/network-devp2p/src/session.rs @@ -29,6 +29,7 @@ use handshake::Handshake; use io::{IoContext, StreamToken}; use network::{Error, ErrorKind, DisconnectReason, SessionInfo, ProtocolId, PeerCapabilityInfo}; use network::SessionCapabilityInfo; +use network::client_version::ClientVersion; use host::*; use node_table::NodeId; use snappy; @@ -112,7 +113,7 @@ impl Session { had_hello: false, info: SessionInfo { id: id.cloned(), - client_version: String::new(), + client_version: ClientVersion::from(""), protocol_version: 0, capabilities: Vec::new(), peer_capabilities: Vec::new(), @@ -419,7 +420,8 @@ impl Session { fn read_hello(&mut self, io: &IoContext, rlp: &Rlp, host: &HostInfo) -> Result<(), Error> where Message: Send + Sync + Clone { let protocol = rlp.val_at::(0)?; - let client_version = rlp.val_at::(1)?; + let client_version_string = rlp.val_at::(1)?; + let client_version = ClientVersion::from(client_version_string); let peer_caps: Vec = rlp.list_at(2)?; let id = rlp.val_at::(4)?; diff --git a/util/network-devp2p/tests/tests.rs b/util/network-devp2p/tests/tests.rs index adc55b791d..00f811e463 100644 --- a/util/network-devp2p/tests/tests.rs +++ b/util/network-devp2p/tests/tests.rs @@ -80,7 +80,7 @@ impl NetworkProtocolHandler for TestProtocol { } fn connected(&self, io: &NetworkContext, peer: &PeerId) { - assert!(io.peer_client_version(*peer).contains("Parity")); + assert!(io.peer_client_version(*peer).to_string().contains("Parity")); if self.drop_session { io.disconnect_peer(*peer) } else { diff --git a/util/network/Cargo.toml b/util/network/Cargo.toml index cdd321dd72..b7077f7aea 100644 --- a/util/network/Cargo.toml +++ b/util/network/Cargo.toml @@ -13,9 +13,13 @@ ethcore-io = { path = "../io" } ethereum-types = "0.4" ethkey = { path = "../../accounts/ethkey" } ipnetwork = "0.12.6" +lazy_static = "1.0" rlp = { version = "0.3.0", features = ["ethereum"] } libc = "0.2" parity-snappy = "0.1" +semver = {version="0.9.0", features=["serde"]} +serde = "1.0" +serde_derive = "1.0" [dev-dependencies] assert_matches = "1.2" diff --git a/util/network/src/client_version.rs b/util/network/src/client_version.rs new file mode 100644 index 0000000000..47d81fad86 --- /dev/null +++ b/util/network/src/client_version.rs @@ -0,0 +1,515 @@ +// Copyright 2015-2019 Parity Technologies (UK) Ltd. +// This file is part of Parity Ethereum. + +// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . + +#![warn(missing_docs)] + +//! Parse ethereum client ID strings and provide querying functionality + +use semver::Version; +use std::fmt; + +/// Parity client string prefix +const LEGACY_CLIENT_ID_PREFIX: &str = "Parity"; +const PARITY_CLIENT_ID_PREFIX: &str = "Parity-Ethereum"; + +lazy_static! { +/// Parity versions starting from this will accept block bodies requests +/// of 256 bodies + static ref PARITY_CLIENT_LARGE_REQUESTS_VERSION: Version = Version::parse("2.4.0").unwrap(); +} + +/// Description of the software version running in a peer +/// according to https://github.com/ethereum/wiki/wiki/Client-Version-Strings +/// This structure as it is represents the format used by Parity clients. Other +/// vendors may provide additional fields. +#[derive(Clone,Debug,PartialEq,Eq,Serialize)] +pub struct ParityClientData { + name: String, + identity: Option, + semver: Version, + os: String, + compiler: String, + + // Capability flags, should be calculated in constructor + can_handle_large_requests: bool, +} + +/// Accessor methods for ParityClientData. This will probably +/// need to be abstracted away into a trait. +impl ParityClientData { + fn new( + name: String, + identity: Option, + semver: Version, + os: String, + compiler: String, + ) -> Self { + // Flags logic + let can_handle_large_requests = &semver >= &PARITY_CLIENT_LARGE_REQUESTS_VERSION; + + // Instantiate and return + ParityClientData { + name: name, + identity: identity, + semver: semver, + os: os, + compiler: compiler, + + can_handle_large_requests: can_handle_large_requests, + } + } + + fn name(&self) -> &str { + self.name.as_str() + } + + fn identity(&self) -> Option<&str> { + self.identity.as_ref().map(String::as_str) + } + + fn semver(&self) -> &Version { + &self.semver + } + + fn os(&self) -> &str { + self.os.as_str() + } + + fn compiler(&self) -> &str { + self.compiler.as_str() + } + + fn can_handle_large_requests(&self) -> bool { + self.can_handle_large_requests + } +} + +/// Enum describing the version of the software running on a peer. +#[derive(Clone,Debug,Eq,PartialEq,Serialize)] +pub enum ClientVersion { + /// The peer runs software from parity and the string format is known + ParityClient( + /// The actual information fields: name, version, os, ... + ParityClientData + ), + /// The string ID is recognized as Parity but the overall format + /// could not be parsed + ParityUnknownFormat(String), + /// Other software vendors than Parity + Other(String), +} + +impl Default for ClientVersion { + fn default() -> Self { + ClientVersion::Other("".to_owned()) + } +} + +/// Provide information about what a particular version of a +/// peer software can do +pub trait ClientCapabilities { + /// Parity versions before PARITY_CLIENT_LARGE_REQUESTS_VERSION would not + /// check the accumulated size of a packet when building a response to a + /// GET_BLOCK_BODIES request. If the packet was larger than a given limit, + /// instead of sending fewer blocks no packet would get sent at all. Query + /// if this version can handle requests for a large number of block bodies. + fn can_handle_large_requests(&self) -> bool; + + /// Service transactions are specific to parity. Query if this version + /// accepts them. + fn accepts_service_transaction(&self) -> bool; +} + +impl ClientCapabilities for ClientVersion { + fn can_handle_large_requests(&self) -> bool { + match self { + ClientVersion::ParityClient(data) => data.can_handle_large_requests(), + ClientVersion::ParityUnknownFormat(_) => false, // Play it safe + ClientVersion::Other(_) => true // As far as we know + } + } + + fn accepts_service_transaction(&self) -> bool { + match self { + ClientVersion::ParityClient(_) => true, + ClientVersion::ParityUnknownFormat(_) => true, + ClientVersion::Other(_) => false + } + } + +} + +fn is_parity(client_id: &str) -> bool { + client_id.starts_with(LEGACY_CLIENT_ID_PREFIX) || client_id.starts_with(PARITY_CLIENT_ID_PREFIX) +} + +/// Parse known parity formats. Recognizes either a short format with four fields +/// or a long format which includes the same fields and an identity one. +fn parse_parity_format(client_version: &str) -> Result { + const PARITY_ID_STRING_MINIMUM_TOKENS: usize = 4; + + let tokens: Vec<&str> = client_version.split("/").collect(); + + if tokens.len() < PARITY_ID_STRING_MINIMUM_TOKENS { + return Err(()) + } + + let name = tokens[0]; + + let identity = if tokens.len() - 3 > 1 { + Some(tokens[1..(tokens.len() - 3)].join("/")) + } else { + None + }; + + let compiler = tokens[tokens.len() - 1]; + let os = tokens[tokens.len() - 2]; + + // If version is in the right position and valid format return a valid + // result. Otherwise return an error. + get_number_from_version(tokens[tokens.len() - 3]) + .and_then(|v| Version::parse(v).ok()) + .map(|semver| ParityClientData::new( + name.to_owned(), + identity, + semver, + os.to_owned(), + compiler.to_owned(), + )) + .ok_or(()) +} + +/// Parse a version string and return the corresponding +/// ClientVersion. Only Parity clients are destructured right now, other +/// strings will just get wrapped in a variant so that the information is +/// not lost. +/// The parsing for parity may still fail, in which case return a ParityUnknownFormat with +/// the original version string. TryFrom would be a better trait to implement. +impl From for ClientVersion +where T: AsRef { + fn from(client_version: T) -> Self { + let client_version_str: &str = client_version.as_ref(); + + if !is_parity(client_version_str) { + return ClientVersion::Other(client_version_str.to_owned()); + } + + if let Ok(data) = parse_parity_format(client_version_str) { + ClientVersion::ParityClient(data) + } else { + ClientVersion::ParityUnknownFormat(client_version_str.to_owned()) + } + } +} + +fn format_parity_version_string(client_version: &ParityClientData, f: &mut fmt::Formatter) -> std::fmt::Result { + let name = client_version.name(); + let semver = client_version.semver(); + let os = client_version.os(); + let compiler = client_version.compiler(); + + match client_version.identity() { + None => write!(f, "{}/v{}/{}/{}", name, semver, os, compiler), + Some(identity) => write!(f, "{}/{}/v{}/{}/{}", name, identity, semver, os, compiler), + } +} + +impl fmt::Display for ClientVersion { + fn fmt(&self, f: &mut fmt::Formatter) -> std::fmt::Result { + match self { + ClientVersion::ParityClient(data) => format_parity_version_string(data, f), + ClientVersion::ParityUnknownFormat(id) => write!(f, "{}", id), + ClientVersion::Other(id) => write!(f, "{}", id) + } + } +} + +fn get_number_from_version(version: &str) -> Option<&str> { + if version.starts_with("v") { + return version.get(1..); + } + + None +} + +#[cfg(test)] +pub mod tests { + use super::*; + + const PARITY_CLIENT_SEMVER: &str = "2.4.0"; + const PARITY_CLIENT_OLD_SEMVER: &str = "2.2.0"; + const PARITY_CLIENT_OS: &str = "linux"; + const PARITY_CLIENT_COMPILER: &str = "rustc"; + const PARITY_CLIENT_IDENTITY: &str = "ExpanseSOLO"; + const PARITY_CLIENT_MULTITOKEN_IDENTITY: &str = "ExpanseSOLO/abc/v1.2.3"; + + + fn make_default_version_string() -> String { + format!( + "{}/v{}/{}/{}", + PARITY_CLIENT_ID_PREFIX, + PARITY_CLIENT_SEMVER, + PARITY_CLIENT_OS, + PARITY_CLIENT_COMPILER + ) + } + + fn make_default_long_version_string() -> String { + format!( + "{}/{}/v{}/{}/{}", + PARITY_CLIENT_ID_PREFIX, + PARITY_CLIENT_IDENTITY, + PARITY_CLIENT_SEMVER, + PARITY_CLIENT_OS, + PARITY_CLIENT_COMPILER + ) + } + + fn make_multitoken_identity_long_version_string() -> String { + format!( + "{}/{}/v{}/{}/{}", + PARITY_CLIENT_ID_PREFIX, + PARITY_CLIENT_MULTITOKEN_IDENTITY, + PARITY_CLIENT_SEMVER, + PARITY_CLIENT_OS, + PARITY_CLIENT_COMPILER + ) + } + + fn make_old_semver_version_string() -> String { + format!( + "{}/v{}/{}/{}", + PARITY_CLIENT_ID_PREFIX, + PARITY_CLIENT_OLD_SEMVER, + PARITY_CLIENT_OS, + PARITY_CLIENT_COMPILER + ) + } + + #[test] + pub fn client_version_when_from_empty_string_then_default() { + let default = ClientVersion::default(); + + assert_eq!(ClientVersion::from(""), default); + } + + #[test] + pub fn get_number_from_version_when_valid_then_number() { + let version_string = format!("v{}", PARITY_CLIENT_SEMVER); + + assert_eq!(get_number_from_version(&version_string).unwrap(), PARITY_CLIENT_SEMVER); + } + + #[test] + pub fn client_version_when_str_parity_format_and_valid_then_all_fields_match() { + let client_version_string = make_default_version_string(); + + if let ClientVersion::ParityClient(client_version) = ClientVersion::from(client_version_string.as_str()) { + assert_eq!(client_version.name(), PARITY_CLIENT_ID_PREFIX); + assert_eq!(*client_version.semver(), Version::parse(PARITY_CLIENT_SEMVER).unwrap()); + assert_eq!(client_version.os(), PARITY_CLIENT_OS); + assert_eq!(client_version.compiler(), PARITY_CLIENT_COMPILER); + } else { + panic!("shouldn't be here"); + } + } + + #[test] + pub fn client_version_when_str_parity_long_format_and_valid_then_all_fields_match() { + let client_version_string = make_default_long_version_string(); + + if let ClientVersion::ParityClient(client_version) = ClientVersion::from(client_version_string.as_str()) { + assert_eq!(client_version.name(), PARITY_CLIENT_ID_PREFIX); + assert_eq!(client_version.identity().unwrap(), PARITY_CLIENT_IDENTITY); + assert_eq!(*client_version.semver(), Version::parse(PARITY_CLIENT_SEMVER).unwrap()); + assert_eq!(client_version.os(), PARITY_CLIENT_OS); + assert_eq!(client_version.compiler(), PARITY_CLIENT_COMPILER); + } else { + panic!("shouldnt be here"); + } + } + + #[test] + pub fn client_version_when_str_parity_long_format_and_valid_and_identity_multiple_tokens_then_all_fields_match() { + let client_version_string = make_multitoken_identity_long_version_string(); + + if let ClientVersion::ParityClient(client_version) = ClientVersion::from(client_version_string.as_str()) { + assert_eq!(client_version.name(), PARITY_CLIENT_ID_PREFIX); + assert_eq!(client_version.identity().unwrap(), PARITY_CLIENT_MULTITOKEN_IDENTITY); + assert_eq!(*client_version.semver(), Version::parse(PARITY_CLIENT_SEMVER).unwrap()); + assert_eq!(client_version.os(), PARITY_CLIENT_OS); + assert_eq!(client_version.compiler(), PARITY_CLIENT_COMPILER); + } else { + panic!("shouldnt be here"); + } + } + + #[test] + pub fn client_version_when_string_parity_format_and_valid_then_all_fields_match() { + let client_version_string: String = make_default_version_string(); + + if let ClientVersion::ParityClient(client_version) = ClientVersion::from(client_version_string.as_str()) { + assert_eq!(client_version.name(), PARITY_CLIENT_ID_PREFIX); + assert_eq!(*client_version.semver(), Version::parse(PARITY_CLIENT_SEMVER).unwrap()); + assert_eq!(client_version.os(), PARITY_CLIENT_OS); + assert_eq!(client_version.compiler(), PARITY_CLIENT_COMPILER); + } else { + panic!("shouldn't be here"); + } + } + + #[test] + pub fn client_version_when_parity_format_and_invalid_then_equals_parity_unknown_client_version_string() { + // This is invalid because version has no leading 'v' + let client_version_string = format!( + "{}/{}/{}/{}", + PARITY_CLIENT_ID_PREFIX, + PARITY_CLIENT_SEMVER, + PARITY_CLIENT_OS, + PARITY_CLIENT_COMPILER); + + let client_version = ClientVersion::from(client_version_string.as_str()); + + let parity_unknown = ClientVersion::ParityUnknownFormat(client_version_string.to_string()); + + assert_eq!(client_version, parity_unknown); + } + + #[test] + pub fn client_version_when_parity_format_without_identity_and_missing_compiler_field_then_equals_parity_unknown_client_version_string() { + let client_version_string = format!( + "{}/v{}/{}", + PARITY_CLIENT_ID_PREFIX, + PARITY_CLIENT_SEMVER, + PARITY_CLIENT_OS, + ); + + let client_version = ClientVersion::from(client_version_string.as_str()); + + let parity_unknown = ClientVersion::ParityUnknownFormat(client_version_string.to_string()); + + assert_eq!(client_version, parity_unknown); + } + + #[test] + pub fn client_version_when_parity_format_with_identity_and_missing_compiler_field_then_equals_parity_unknown_client_version_string() { + let client_version_string = format!( + "{}/{}/v{}/{}", + PARITY_CLIENT_ID_PREFIX, + PARITY_CLIENT_IDENTITY, + PARITY_CLIENT_SEMVER, + PARITY_CLIENT_OS, + ); + + let client_version = ClientVersion::from(client_version_string.as_str()); + + let parity_unknown = ClientVersion::ParityUnknownFormat(client_version_string.to_string()); + + assert_eq!(client_version, parity_unknown); + } + + #[test] + pub fn client_version_when_not_parity_format_and_valid_then_other_with_client_version_string() { + let client_version_string = "Geth/main.jnode.network/v1.8.21-stable-9dc5d1a9/linux"; + + let client_version = ClientVersion::from(client_version_string); + + assert_eq!(client_version, ClientVersion::Other(client_version_string.to_string())); + } + + #[test] + pub fn client_version_when_parity_format_and_valid_then_to_string_equal() { + let client_version_string: String = make_default_version_string(); + + let client_version = ClientVersion::from(client_version_string.as_str()); + + assert_eq!(client_version.to_string(), client_version_string); + } + + #[test] + pub fn client_version_when_other_then_to_string_equal_input_string() { + let client_version_string: String = "Other".to_string(); + + let client_version = ClientVersion::from("Other"); + + assert_eq!(client_version.to_string(), client_version_string); + } + + #[test] + pub fn client_capabilities_when_parity_old_version_then_handles_large_requests_false() { + let client_version_string: String = make_old_semver_version_string(); + + let client_version = ClientVersion::from(client_version_string.as_str()); + + assert!(!client_version.can_handle_large_requests()); + } + + #[test] + pub fn client_capabilities_when_parity_beta_version_then_not_handles_large_requests_true() { + let client_version_string: String = format!( + "{}/v{}/{}/{}", + "Parity-Ethereum", + "2.4.0-beta", + "x86_64-linux-gnu", + "rustc1.31.1") + .to_string(); + + let client_version = ClientVersion::from(client_version_string.as_str()); + + assert!(!client_version.can_handle_large_requests()); + } + + #[test] + pub fn client_version_when_to_owned_then_both_objects_equal() { + let client_version_string: String = make_old_semver_version_string(); + + let origin = ClientVersion::from(client_version_string.as_str()); + + let borrowed = &origin; + + let owned = origin.to_owned(); + + assert_eq!(*borrowed, owned); + } + + #[test] + fn client_version_accepts_service_transaction_for_different_versions() { + assert!(!ClientVersion::from("Geth").accepts_service_transaction()); + assert!(ClientVersion::from("Parity-Ethereum/v2.6.0/linux/rustc").accepts_service_transaction()); + assert!(ClientVersion::from("Parity-Ethereum/ABCDEFGH/v2.7.3/linux/rustc").accepts_service_transaction()); + } + + #[test] + fn is_parity_when_parity_then_true() { + let client_id = format!("{}/", PARITY_CLIENT_ID_PREFIX); + + assert!(is_parity(&client_id)); + } + + #[test] + fn is_parity_when_empty_then_false() { + let client_id = ""; + + assert!(!is_parity(&client_id)); + } + + #[test] + fn is_parity_when_other_then_false() { + let client_id = "other"; + + assert!(!is_parity(&client_id)); + } +} diff --git a/util/network/src/lib.rs b/util/network/src/lib.rs index dd7c5c073d..9e6f71fdd1 100644 --- a/util/network/src/lib.rs +++ b/util/network/src/lib.rs @@ -24,6 +24,11 @@ extern crate rlp; extern crate ipnetwork; extern crate parity_snappy as snappy; extern crate libc; +extern crate semver; +extern crate serde; + +#[macro_use] +extern crate serde_derive; #[cfg(test)] #[macro_use] extern crate assert_matches; @@ -31,6 +36,11 @@ extern crate assert_matches; #[macro_use] extern crate error_chain; +#[macro_use] +extern crate lazy_static; + +pub mod client_version; + mod connection_filter; mod error; @@ -38,6 +48,7 @@ pub use connection_filter::{ConnectionFilter, ConnectionDirection}; pub use io::TimerToken; pub use error::{Error, ErrorKind, DisconnectReason}; +use client_version::ClientVersion; use std::cmp::Ordering; use std::collections::HashMap; use std::net::{SocketAddr, SocketAddrV4, Ipv4Addr}; @@ -97,7 +108,7 @@ pub struct SessionInfo { /// Peer public key pub id: Option, /// Peer client ID - pub client_version: String, + pub client_version: ClientVersion, /// Peer RLPx protocol version pub protocol_version: u32, /// Session protocol capabilities @@ -275,7 +286,7 @@ pub trait NetworkContext { fn register_timer(&self, token: TimerToken, delay: Duration) -> Result<(), Error>; /// Returns peer identification string - fn peer_client_version(&self, peer: PeerId) -> String; + fn peer_client_version(&self, peer: PeerId) -> ClientVersion; /// Returns information on p2p session fn session_info(&self, peer: PeerId) -> Option; @@ -322,7 +333,7 @@ impl<'a, T> NetworkContext for &'a T where T: ?Sized + NetworkContext { (**self).register_timer(token, delay) } - fn peer_client_version(&self, peer: PeerId) -> String { + fn peer_client_version(&self, peer: PeerId) -> ClientVersion { (**self).peer_client_version(peer) } From 83bcb819da65c4dcc3ce2d89758fec014781c150 Mon Sep 17 00:00:00 2001 From: TriplEight Date: Thu, 7 Feb 2019 18:49:50 +0100 Subject: [PATCH 054/168] CI optimizations (#10297) * CI optimizations * fix stripping * new dockerfile * no need n submodule upd * review * moved dockerfile * it becomes large * onchain update depends on s3 * fix dependency * fix cache status * fix cache status * new cache status --- .gitlab-ci.yml | 94 +++++++++++++------ scripts/gitlab/build-unix.sh | 11 +-- scripts/gitlab/cargo-audit.sh | 7 -- ...blish-awss3.sh => publish-onnet-update.sh} | 16 ---- scripts/gitlab/test-all.sh | 5 - test.sh | 23 +---- 6 files changed, 68 insertions(+), 88 deletions(-) delete mode 100755 scripts/gitlab/cargo-audit.sh rename scripts/gitlab/{publish-awss3.sh => publish-onnet-update.sh} (73%) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index a1a1c97998..90097a763e 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -2,11 +2,14 @@ stages: - test - build - publish + - publish-onchain - optional -image: parity/rust:gitlab-ci +image: parity/rust-parity-ethereum-build:stretch variables: + GIT_STRATEGY: fetch + GIT_SUBMODULE_STRATEGY: recursive CI_SERVER_NAME: "GitLab CI" CARGO_HOME: "${CI_PROJECT_DIR}/.cargo" CARGO_TARGET: x86_64-unknown-linux-gnu @@ -40,25 +43,28 @@ test-linux: variables: RUN_TESTS: all script: - - scripts/gitlab/test-all.sh stable + - scripts/gitlab/test-all.sh tags: - - rust-stable + - linux-docker test-audit: stage: test script: - - scripts/gitlab/cargo-audit.sh + - set -e + - set -u + - cargo audit tags: - - rust-stable + - linux-docker build-linux: stage: build only: *releaseable_branches script: - scripts/gitlab/build-unix.sh + - sccache -s <<: *collect_artifacts tags: - - rust-stable + - linux-docker build-darwin: stage: build @@ -112,19 +118,66 @@ publish-snap: allow_failure: true <<: *collect_artifacts -publish-awss3: - stage: publish +publish:onnet:update: + stage: publish-onchain only: *releaseable_branches - cache: {} + cache: {} dependencies: - build-linux - build-darwin - build-windows + - publish:awss3:release before_script: *determine_version script: - - scripts/gitlab/publish-awss3.sh + - scripts/gitlab/publish-onnet-update.sh tags: - - shell + - linux-docker + +# configures aws for fast uploads/syncs +.s3_before_script: &s3_before_script + before_script: + - mkdir -p ${HOME}/.aws + - | + cat > ${HOME}/.aws/config < $binary.sha3 fi done - diff --git a/scripts/gitlab/cargo-audit.sh b/scripts/gitlab/cargo-audit.sh deleted file mode 100755 index 16f0dc934a..0000000000 --- a/scripts/gitlab/cargo-audit.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash - -set -e # fail on any error -set -u # treat unset variables as error - -cargo install cargo-audit -cargo audit diff --git a/scripts/gitlab/publish-awss3.sh b/scripts/gitlab/publish-onnet-update.sh similarity index 73% rename from scripts/gitlab/publish-awss3.sh rename to scripts/gitlab/publish-onnet-update.sh index af768a6328..588cbdfb57 100755 --- a/scripts/gitlab/publish-awss3.sh +++ b/scripts/gitlab/publish-onnet-update.sh @@ -36,19 +36,3 @@ do esac cd .. done - -echo "__________Push binaries to AWS S3____________" -aws configure set aws_access_key_id $s3_key -aws configure set aws_secret_access_key $s3_secret - -case "${SCHEDULE_TAG:-${CI_COMMIT_REF_NAME}}" in - (beta|stable|nightly) - export S3_BUCKET=releases.parity.io/ethereum; - ;; - (*) - export S3_BUCKET=builds-parity; - ;; -esac - -aws s3 sync ./ s3://$S3_BUCKET/${SCHEDULE_TAG:-${CI_COMMIT_REF_NAME}}/ - diff --git a/scripts/gitlab/test-all.sh b/scripts/gitlab/test-all.sh index 15c2287062..925124b7ac 100755 --- a/scripts/gitlab/test-all.sh +++ b/scripts/gitlab/test-all.sh @@ -1,6 +1,4 @@ #!/bin/bash -# ARGUMENT $1 Rust flavor to test with (stable/beta/nightly) - set -e # fail on any error set -u # treat unset variables as error @@ -27,9 +25,6 @@ then exit 0 fi -rustup default $1 - -git submodule update --init --recursive rustup show exec ./test.sh diff --git a/test.sh b/test.sh index 1b05194e47..a25f41d9a9 100755 --- a/test.sh +++ b/test.sh @@ -1,33 +1,12 @@ #!/bin/sh # Running Parity Full Test Suite +echo "________Running test.sh________" FEATURES="json-tests,ci-skip-issue" OPTIONS="--release" VALIDATE=1 THREADS=8 -case $1 in - --no-json) - FEATURES="ipc" - shift # past argument=value - ;; - --no-release) - OPTIONS="" - shift - ;; - --no-validate) - VALIDATE=0 - shift - ;; - --no-run) - OPTIONS="--no-run" - shift - ;; - *) - # unknown option - ;; -esac - set -e From 6fa4b2dec5bbf7202f40bfdda2be1933c6cadf6d Mon Sep 17 00:00:00 2001 From: Alexander Arlt Date: Fri, 8 Feb 2019 10:01:29 +0100 Subject: [PATCH 055/168] fix: parity-clib/examples/cpp/CMakeLists.txt (#10313) * use of ${CMAKE_SHARED_LIBRARY_PREFIX} & ${CMAKE_SHARED_LIBRARY_SUFFIX} to support other operating systems. --- parity-clib/examples/cpp/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/parity-clib/examples/cpp/CMakeLists.txt b/parity-clib/examples/cpp/CMakeLists.txt index d3aaf457b3..8cc6aef8f5 100644 --- a/parity-clib/examples/cpp/CMakeLists.txt +++ b/parity-clib/examples/cpp/CMakeLists.txt @@ -15,4 +15,4 @@ ExternalProject_Add( LOG_BUILD ON) add_dependencies(parity-example libparity) -target_link_libraries(parity-example "${CMAKE_SOURCE_DIR}/../../../target/debug/libparity.so") +target_link_libraries(parity-example "${CMAKE_SOURCE_DIR}/../../../target/debug/${CMAKE_SHARED_LIBRARY_PREFIX}parity${CMAKE_SHARED_LIBRARY_SUFFIX}") From 046b8bbc8a3a34ec7289e2e25bb934e308abb014 Mon Sep 17 00:00:00 2001 From: elferdo Date: Fri, 8 Feb 2019 13:01:29 +0100 Subject: [PATCH 056/168] Make specification of protocol in SyncRequester::send_request explicit (#10295) * Make the specification of the protocol to which a packet_id belongs to explicit when calling "SyncRequester::send_packet". * Remove "SyncIO::send" and leave only "SyncIO::send_protocol" * Adapt tests to new code. * Strengthen tests to check if packet_id and protocol match when sending a devp2p packet. --- ethcore/sync/src/api.rs | 4 ++-- ethcore/sync/src/chain/mod.rs | 12 ++++++------ ethcore/sync/src/chain/propagator.rs | 22 ++++++++++----------- ethcore/sync/src/chain/requester.rs | 29 +++++++++++++--------------- ethcore/sync/src/sync_io.rs | 6 ------ ethcore/sync/src/tests/helpers.rs | 26 ++++++++++++++++--------- 6 files changed, 49 insertions(+), 50 deletions(-) diff --git a/ethcore/sync/src/api.rs b/ethcore/sync/src/api.rs index 9374b3ff25..24f6a718ad 100644 --- a/ethcore/sync/src/api.rs +++ b/ethcore/sync/src/api.rs @@ -577,9 +577,9 @@ impl ChainNotify for EthSync { match message_type { ChainMessageType::Consensus(message) => self.eth_handler.sync.write().propagate_consensus_packet(&mut sync_io, message), ChainMessageType::PrivateTransaction(transaction_hash, message) => - self.eth_handler.sync.write().propagate_private_transaction(&mut sync_io, transaction_hash, PRIVATE_TRANSACTION_PACKET, message), + self.eth_handler.sync.write().propagate_private_transaction(&mut sync_io, transaction_hash, WARP_SYNC_PROTOCOL_ID, PRIVATE_TRANSACTION_PACKET, message), ChainMessageType::SignedPrivateTransaction(transaction_hash, message) => - self.eth_handler.sync.write().propagate_private_transaction(&mut sync_io, transaction_hash, SIGNED_PRIVATE_TRANSACTION_PACKET, message), + self.eth_handler.sync.write().propagate_private_transaction(&mut sync_io, transaction_hash, WARP_SYNC_PROTOCOL_ID, SIGNED_PRIVATE_TRANSACTION_PACKET, message), } }); } diff --git a/ethcore/sync/src/chain/mod.rs b/ethcore/sync/src/chain/mod.rs index 5a144853d6..123f2b9c85 100644 --- a/ethcore/sync/src/chain/mod.rs +++ b/ethcore/sync/src/chain/mod.rs @@ -103,7 +103,7 @@ use fastmap::{H256FastMap, H256FastSet}; use parking_lot::{Mutex, RwLock, RwLockWriteGuard}; use bytes::Bytes; use rlp::{RlpStream, DecoderError}; -use network::{self, PeerId, PacketId}; +use network::{self, PeerId, PacketId, ProtocolId}; use network::client_version::ClientVersion; use ethcore::client::{BlockChainClient, BlockStatus, BlockId, BlockChainInfo, BlockQueueInfo}; use ethcore::snapshot::{RestorationStatus}; @@ -112,7 +112,7 @@ use super::{WarpSync, SyncConfig}; use block_sync::{BlockDownloader, DownloadAction}; use rand::Rng; use snapshot::{Snapshot}; -use api::{EthProtocolInfo as PeerInfoDigest, WARP_SYNC_PROTOCOL_ID, PriorityTask}; +use api::{EthProtocolInfo as PeerInfoDigest, ETH_PROTOCOL, WARP_SYNC_PROTOCOL_ID, PriorityTask}; use private_tx::PrivateTxHandler; use transactions_stats::{TransactionsStats, Stats as TransactionStats}; use types::transaction::UnverifiedTransaction; @@ -154,7 +154,7 @@ const MAX_TRANSACTION_PACKET_SIZE: usize = 5 * 1024 * 1024; const SNAPSHOT_RESTORE_THRESHOLD: BlockNumber = 30000; const SNAPSHOT_MIN_PEERS: usize = 3; -const STATUS_PACKET: u8 = 0x00; +pub const STATUS_PACKET: u8 = 0x00; const NEW_BLOCK_HASHES_PACKET: u8 = 0x01; const TRANSACTIONS_PACKET: u8 = 0x02; pub const GET_BLOCK_HEADERS_PACKET: u8 = 0x03; @@ -484,7 +484,7 @@ impl ChainSyncApi { for peers in sync.get_peers(&chain_info, PeerState::SameBlock).chunks(10) { check_deadline(deadline)?; for peer in peers { - SyncPropagator::send_packet(io, *peer, NEW_BLOCK_PACKET, rlp.clone()); + SyncPropagator::send_packet(io, ETH_PROTOCOL, *peer, NEW_BLOCK_PACKET, rlp.clone()); if let Some(ref mut peer) = sync.peers.get_mut(peer) { peer.latest_hash = hash; } @@ -1331,8 +1331,8 @@ impl ChainSync { } /// Broadcast private transaction message to peers. - pub fn propagate_private_transaction(&mut self, io: &mut SyncIo, transaction_hash: H256, packet_id: PacketId, packet: Bytes) { - SyncPropagator::propagate_private_transaction(self, io, transaction_hash, packet_id, packet); + pub fn propagate_private_transaction(&mut self, io: &mut SyncIo, transaction_hash: H256, protocol: ProtocolId, packet_id: PacketId, packet: Bytes) { + SyncPropagator::propagate_private_transaction(self, io, transaction_hash, protocol, packet_id, packet); } } diff --git a/ethcore/sync/src/chain/propagator.rs b/ethcore/sync/src/chain/propagator.rs index 9d50fafc14..77035387ec 100644 --- a/ethcore/sync/src/chain/propagator.rs +++ b/ethcore/sync/src/chain/propagator.rs @@ -17,10 +17,11 @@ use std::cmp; use std::collections::HashSet; +use api::{ETH_PROTOCOL, WARP_SYNC_PROTOCOL_ID}; use bytes::Bytes; use ethereum_types::H256; use fastmap::H256FastSet; -use network::{PeerId, PacketId}; +use network::{PeerId, PacketId, ProtocolId}; use network::client_version::ClientCapabilities; use rand::Rng; use rlp::{Encodable, RlpStream}; @@ -42,7 +43,6 @@ use super::{ TRANSACTIONS_PACKET, }; - /// The Chain Sync Propagator: propagates data to peers pub struct SyncPropagator; @@ -53,7 +53,7 @@ impl SyncPropagator { let sent = peers.len(); let mut send_packet = |io: &mut SyncIo, rlp: Bytes| { for peer_id in peers { - SyncPropagator::send_packet(io, *peer_id, NEW_BLOCK_PACKET, rlp.clone()); + SyncPropagator::send_packet(io, ETH_PROTOCOL, *peer_id, NEW_BLOCK_PACKET, rlp.clone()); if let Some(ref mut peer) = sync.peers.get_mut(peer_id) { peer.latest_hash = chain_info.best_block_hash.clone(); } @@ -88,7 +88,7 @@ impl SyncPropagator { if let Some(ref mut peer) = sync.peers.get_mut(peer_id) { peer.latest_hash = best_block_hash; } - SyncPropagator::send_packet(io, *peer_id, NEW_BLOCK_HASHES_PACKET, rlp.clone()); + SyncPropagator::send_packet(io, ETH_PROTOCOL, *peer_id, NEW_BLOCK_HASHES_PACKET, rlp.clone()); } sent } @@ -156,7 +156,7 @@ impl SyncPropagator { let send_packet = |io: &mut SyncIo, peer_id: PeerId, sent: usize, rlp: Bytes| { let size = rlp.len(); - SyncPropagator::send_packet(io, peer_id, TRANSACTIONS_PACKET, rlp); + SyncPropagator::send_packet(io, ETH_PROTOCOL, peer_id, TRANSACTIONS_PACKET, rlp); trace!(target: "sync", "{:02} <- Transactions ({} entries; {} bytes)", peer_id, sent, size); }; @@ -275,7 +275,7 @@ impl SyncPropagator { io.chain().chain_info().total_difficulty ); for peer_id in &peers { - SyncPropagator::send_packet(io, *peer_id, NEW_BLOCK_PACKET, rlp.clone()); + SyncPropagator::send_packet(io, ETH_PROTOCOL, *peer_id, NEW_BLOCK_PACKET, rlp.clone()); } } } @@ -285,12 +285,12 @@ impl SyncPropagator { let lucky_peers = ChainSync::select_random_peers(&sync.get_consensus_peers()); trace!(target: "sync", "Sending consensus packet to {:?}", lucky_peers); for peer_id in lucky_peers { - SyncPropagator::send_packet(io, peer_id, CONSENSUS_DATA_PACKET, packet.clone()); + SyncPropagator::send_packet(io, WARP_SYNC_PROTOCOL_ID, peer_id, CONSENSUS_DATA_PACKET, packet.clone()); } } /// Broadcast private transaction message to peers. - pub fn propagate_private_transaction(sync: &mut ChainSync, io: &mut SyncIo, transaction_hash: H256, packet_id: PacketId, packet: Bytes) { + pub fn propagate_private_transaction(sync: &mut ChainSync, io: &mut SyncIo, transaction_hash: H256, protocol: ProtocolId, packet_id: PacketId, packet: Bytes) { let lucky_peers = ChainSync::select_random_peers(&sync.get_private_transaction_peers(&transaction_hash)); if lucky_peers.is_empty() { error!(target: "privatetx", "Cannot propagate the packet, no peers with private tx enabled connected"); @@ -300,7 +300,7 @@ impl SyncPropagator { if let Some(ref mut peer) = sync.peers.get_mut(&peer_id) { peer.last_sent_private_transactions.insert(transaction_hash); } - SyncPropagator::send_packet(io, peer_id, packet_id, packet.clone()); + SyncPropagator::send_packet(io, protocol, peer_id, packet_id, packet.clone()); } } } @@ -321,8 +321,8 @@ impl SyncPropagator { } /// Generic packet sender - pub fn send_packet(sync: &mut SyncIo, peer_id: PeerId, packet_id: PacketId, packet: Bytes) { - if let Err(e) = sync.send(peer_id, packet_id, packet) { + pub fn send_packet(sync: &mut SyncIo, protocol: ProtocolId, peer_id: PeerId, packet_id: PacketId, packet: Bytes) { + if let Err(e) = sync.send_protocol(protocol, peer_id, packet_id, packet) { debug!(target:"sync", "Error sending packet: {:?}", e); sync.disconnect_peer(peer_id); } diff --git a/ethcore/sync/src/chain/requester.rs b/ethcore/sync/src/chain/requester.rs index 09eec748ec..85f622ec86 100644 --- a/ethcore/sync/src/chain/requester.rs +++ b/ethcore/sync/src/chain/requester.rs @@ -14,11 +14,11 @@ // You should have received a copy of the GNU General Public License // along with Parity Ethereum. If not, see . -use api::WARP_SYNC_PROTOCOL_ID; +use api::{ETH_PROTOCOL, WARP_SYNC_PROTOCOL_ID}; use block_sync::BlockRequest; use bytes::Bytes; use ethereum_types::H256; -use network::{PeerId, PacketId}; +use network::{PeerId, PacketId, ProtocolId}; use rlp::RlpStream; use std::time::Instant; use sync_io::SyncIo; @@ -28,7 +28,6 @@ use super::{ BlockSet, ChainSync, PeerAsking, - ETH_PROTOCOL_VERSION_63, GET_BLOCK_BODIES_PACKET, GET_BLOCK_HEADERS_PACKET, GET_RECEIPTS_PACKET, @@ -63,7 +62,8 @@ impl SyncRequester { rlp.append(&h.clone()); } - SyncRequester::send_request(sync, io, peer_id, PeerAsking::BlockBodies, GET_BLOCK_BODIES_PACKET, rlp.out()); + SyncRequester::send_request(sync, io, peer_id, PeerAsking::BlockBodies, ETH_PROTOCOL, GET_BLOCK_BODIES_PACKET, rlp.out()); + let peer = sync.peers.get_mut(&peer_id).expect("peer_id may originate either from on_packet, where it is already validated or from enumerating self.peers. qed"); peer.asking_blocks = hashes; peer.block_set = Some(set); @@ -77,7 +77,7 @@ impl SyncRequester { rlp.append(&1u32); rlp.append(&0u32); rlp.append(&0u32); - SyncRequester::send_request(sync, io, peer_id, PeerAsking::ForkHeader, GET_BLOCK_HEADERS_PACKET, rlp.out()); + SyncRequester::send_request(sync, io, peer_id, PeerAsking::ForkHeader, ETH_PROTOCOL, GET_BLOCK_HEADERS_PACKET, rlp.out()); } /// Find some headers or blocks to download for a peer. @@ -95,7 +95,7 @@ impl SyncRequester { pub fn request_snapshot_manifest(sync: &mut ChainSync, io: &mut SyncIo, peer_id: PeerId) { trace!(target: "sync", "{} <- GetSnapshotManifest", peer_id); let rlp = RlpStream::new_list(0); - SyncRequester::send_request(sync, io, peer_id, PeerAsking::SnapshotManifest, GET_SNAPSHOT_MANIFEST_PACKET, rlp.out()); + SyncRequester::send_request(sync, io, peer_id, PeerAsking::SnapshotManifest, WARP_SYNC_PROTOCOL_ID, GET_SNAPSHOT_MANIFEST_PACKET, rlp.out()); } /// Request headers from a peer by block hash @@ -106,7 +106,7 @@ impl SyncRequester { rlp.append(&count); rlp.append(&skip); rlp.append(&if reverse {1u32} else {0u32}); - SyncRequester::send_request(sync, io, peer_id, PeerAsking::BlockHeaders, GET_BLOCK_HEADERS_PACKET, rlp.out()); + SyncRequester::send_request(sync, io, peer_id, PeerAsking::BlockHeaders, ETH_PROTOCOL, GET_BLOCK_HEADERS_PACKET, rlp.out()); let peer = sync.peers.get_mut(&peer_id).expect("peer_id may originate either from on_packet, where it is already validated or from enumerating self.peers. qed"); peer.asking_hash = Some(h.clone()); peer.block_set = Some(set); @@ -119,7 +119,7 @@ impl SyncRequester { for h in &hashes { rlp.append(&h.clone()); } - SyncRequester::send_request(sync, io, peer_id, PeerAsking::BlockReceipts, GET_RECEIPTS_PACKET, rlp.out()); + SyncRequester::send_request(sync, io, peer_id, PeerAsking::BlockReceipts, ETH_PROTOCOL, GET_RECEIPTS_PACKET, rlp.out()); let peer = sync.peers.get_mut(&peer_id).expect("peer_id may originate either from on_packet, where it is already validated or from enumerating self.peers. qed"); peer.asking_blocks = hashes; peer.block_set = Some(set); @@ -130,23 +130,20 @@ impl SyncRequester { trace!(target: "sync", "{} <- GetSnapshotData {:?}", peer_id, chunk); let mut rlp = RlpStream::new_list(1); rlp.append(chunk); - SyncRequester::send_request(sync, io, peer_id, PeerAsking::SnapshotData, GET_SNAPSHOT_DATA_PACKET, rlp.out()); + SyncRequester::send_request(sync, io, peer_id, PeerAsking::SnapshotData, WARP_SYNC_PROTOCOL_ID, GET_SNAPSHOT_DATA_PACKET, rlp.out()); } /// Generic request sender - fn send_request(sync: &mut ChainSync, io: &mut SyncIo, peer_id: PeerId, asking: PeerAsking, packet_id: PacketId, packet: Bytes) { + fn send_request(sync: &mut ChainSync, io: &mut SyncIo, peer_id: PeerId, asking: PeerAsking, protocol: ProtocolId, packet_id: PacketId, packet: Bytes) { if let Some(ref mut peer) = sync.peers.get_mut(&peer_id) { if peer.asking != PeerAsking::Nothing { warn!(target:"sync", "Asking {:?} while requesting {:?}", peer.asking, asking); } peer.asking = asking; peer.ask_time = Instant::now(); - // TODO [ToDr] This seems quite fragile. Be careful when protocol is updated. - let result = if packet_id >= ETH_PROTOCOL_VERSION_63.1 { - io.send_protocol(WARP_SYNC_PROTOCOL_ID, peer_id, packet_id, packet) - } else { - io.send(peer_id, packet_id, packet) - }; + + let result = io.send_protocol(protocol, peer_id, packet_id, packet); + if let Err(e) = result { debug!(target:"sync", "Error sending request: {:?}", e); io.disconnect_peer(peer_id); diff --git a/ethcore/sync/src/sync_io.rs b/ethcore/sync/src/sync_io.rs index b4cd9a08fd..1bf892e474 100644 --- a/ethcore/sync/src/sync_io.rs +++ b/ethcore/sync/src/sync_io.rs @@ -33,8 +33,6 @@ pub trait SyncIo { fn disconnect_peer(&mut self, peer_id: PeerId); /// Respond to current request with a packet. Can be called from an IO handler for incoming packet. fn respond(&mut self, packet_id: PacketId, data: Vec) -> Result<(), Error>; - /// Send a packet to a peer. - fn send(&mut self, peer_id: PeerId, packet_id: PacketId, data: Vec) -> Result<(), Error>; /// Send a packet to a peer using specified protocol. fn send_protocol(&mut self, protocol: ProtocolId, peer_id: PeerId, packet_id: PacketId, data: Vec) -> Result<(), Error>; /// Get the blockchain @@ -99,10 +97,6 @@ impl<'s> SyncIo for NetSyncIo<'s> { self.network.respond(packet_id, data) } - fn send(&mut self, peer_id: PeerId, packet_id: PacketId, data: Vec) -> Result<(), Error>{ - self.network.send(peer_id, packet_id, data) - } - fn send_protocol(&mut self, protocol: ProtocolId, peer_id: PeerId, packet_id: PacketId, data: Vec) -> Result<(), Error>{ self.network.send_protocol(protocol, peer_id, packet_id, data) } diff --git a/ethcore/sync/src/tests/helpers.rs b/ethcore/sync/src/tests/helpers.rs index cdc55fba06..04ceb3dd3e 100644 --- a/ethcore/sync/src/tests/helpers.rs +++ b/ethcore/sync/src/tests/helpers.rs @@ -30,8 +30,8 @@ use ethcore::miner::Miner; use ethcore::test_helpers; use sync_io::SyncIo; use io::{IoChannel, IoContext, IoHandler}; -use api::WARP_SYNC_PROTOCOL_ID; -use chain::{ChainSync, ETH_PROTOCOL_VERSION_63, PAR_PROTOCOL_VERSION_3, PRIVATE_TRANSACTION_PACKET, SIGNED_PRIVATE_TRANSACTION_PACKET, SyncSupplier}; +use api::{ETH_PROTOCOL, WARP_SYNC_PROTOCOL_ID}; +use chain::{ChainSync, ETH_PROTOCOL_VERSION_63, PAR_PROTOCOL_VERSION_3, PRIVATE_TRANSACTION_PACKET, SyncSupplier, STATUS_PACKET, RECEIPTS_PACKET, GET_SNAPSHOT_MANIFEST_PACKET, SIGNED_PRIVATE_TRANSACTION_PACKET}; use SyncConfig; use private_tx::SimplePrivateTxHandler; use types::BlockNumber; @@ -80,6 +80,16 @@ impl<'p, C> Drop for TestIo<'p, C> where C: FlushingBlockChainClient, C: 'p { } } +fn assert_packet_id_matches_protocol(protocol: &ProtocolId, packet_id: &PacketId) { + match packet_id { + STATUS_PACKET ... RECEIPTS_PACKET => assert_eq!(*protocol, ETH_PROTOCOL), + GET_SNAPSHOT_MANIFEST_PACKET ... SIGNED_PRIVATE_TRANSACTION_PACKET => assert_eq!(*protocol, WARP_SYNC_PROTOCOL_ID), + // What about light? + _ => assert!(false) + } +} + + impl<'p, C> SyncIo for TestIo<'p, C> where C: FlushingBlockChainClient, C: 'p { fn disable_peer(&mut self, peer_id: PeerId) { self.disconnect_peer(peer_id); @@ -102,7 +112,9 @@ impl<'p, C> SyncIo for TestIo<'p, C> where C: FlushingBlockChainClient, C: 'p { Ok(()) } - fn send(&mut self, peer_id: PeerId, packet_id: PacketId, data: Vec) -> Result<(), network::Error> { + fn send_protocol(&mut self, protocol: ProtocolId, peer_id: PeerId, packet_id: PacketId, data: Vec) -> Result<(), network::Error> { + assert_packet_id_matches_protocol(&protocol, &packet_id); + self.packets.push(TestPacket { data: data, packet_id: packet_id, @@ -111,10 +123,6 @@ impl<'p, C> SyncIo for TestIo<'p, C> where C: FlushingBlockChainClient, C: 'p { Ok(()) } - fn send_protocol(&mut self, _protocol: ProtocolId, peer_id: PeerId, packet_id: PacketId, data: Vec) -> Result<(), network::Error> { - self.send(peer_id, packet_id, data) - } - fn chain(&self) -> &BlockChainClient { &*self.chain } @@ -236,9 +244,9 @@ impl EthPeer where C: FlushingBlockChainClient { match message { ChainMessageType::Consensus(data) => self.sync.write().propagate_consensus_packet(&mut io, data), ChainMessageType::PrivateTransaction(transaction_hash, data) => - self.sync.write().propagate_private_transaction(&mut io, transaction_hash, PRIVATE_TRANSACTION_PACKET, data), + self.sync.write().propagate_private_transaction(&mut io, transaction_hash, WARP_SYNC_PROTOCOL_ID, PRIVATE_TRANSACTION_PACKET, data), ChainMessageType::SignedPrivateTransaction(transaction_hash, data) => - self.sync.write().propagate_private_transaction(&mut io, transaction_hash, SIGNED_PRIVATE_TRANSACTION_PACKET, data), + self.sync.write().propagate_private_transaction(&mut io, transaction_hash, WARP_SYNC_PROTOCOL_ID, SIGNED_PRIVATE_TRANSACTION_PACKET, data), } } From 3502b36232aa1748f633aaccba8ef0a0efb1d297 Mon Sep 17 00:00:00 2001 From: Axel Chalon Date: Fri, 8 Feb 2019 14:11:55 +0100 Subject: [PATCH 057/168] Secure WS-RPC: grant access to all apis (#10246) --- parity/rpc.rs | 2 +- parity/rpc_apis.rs | 41 +---------------------------------------- 2 files changed, 2 insertions(+), 41 deletions(-) diff --git a/parity/rpc.rs b/parity/rpc.rs index 57bb584775..b07ca3f3e4 100644 --- a/parity/rpc.rs +++ b/parity/rpc.rs @@ -151,7 +151,7 @@ pub fn new_ws( let url = format!("{}:{}", conf.interface, conf.port); let addr = url.parse().map_err(|_| format!("Invalid WebSockets listen host/port given: {}", url))?; - let full_handler = setup_apis(rpc_apis::ApiSet::SafeContext, deps); + let full_handler = setup_apis(rpc_apis::ApiSet::All, deps); let handler = { let mut handler = MetaIoHandler::with_middleware(( rpc::WsDispatcher::new(full_handler), diff --git a/parity/rpc_apis.rs b/parity/rpc_apis.rs index 951a4dec4b..4413e6a779 100644 --- a/parity/rpc_apis.rs +++ b/parity/rpc_apis.rs @@ -113,11 +113,9 @@ impl FromStr for Api { #[derive(Debug, Clone)] pub enum ApiSet { - // Safe context (like token-protected WS interface) - SafeContext, // Unsafe context (like jsonrpc over http) UnsafeContext, - // All possible APIs + // All possible APIs (safe context like token-protected WS interface) All, // Local "unsafe" context and accounts access IpcContext, @@ -723,16 +721,6 @@ impl ApiSet { public_list.insert(Api::ParityAccounts); public_list } - ApiSet::SafeContext => { - public_list.insert(Api::Debug); - public_list.insert(Api::Traces); - public_list.insert(Api::ParityPubSub); - public_list.insert(Api::ParityAccounts); - public_list.insert(Api::ParitySet); - public_list.insert(Api::Signer); - public_list.insert(Api::SecretStore); - public_list - } ApiSet::All => { public_list.insert(Api::Debug); public_list.insert(Api::Traces); @@ -838,33 +826,6 @@ mod test { assert_eq!(ApiSet::IpcContext.list_apis(), expected); } - #[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::Private, - // semi-safe - Api::ParityAccounts, - // Unsafe - Api::ParitySet, - Api::Signer, - Api::Debug, - ].into_iter() - .collect(); - assert_eq!(ApiSet::SafeContext.list_apis(), expected); - } - #[test] fn test_all_apis() { assert_eq!( From 8b6c5be6a9bef3f1d5c735975949ea36b1688a78 Mon Sep 17 00:00:00 2001 From: TriplEight Date: Fri, 8 Feb 2019 18:22:08 +0100 Subject: [PATCH 058/168] fix publish job (#10317) * fix publish job * dashes and colonels --- .gitlab-ci.yml | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 90097a763e..1d0b934a25 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -44,6 +44,7 @@ test-linux: RUN_TESTS: all script: - scripts/gitlab/test-all.sh + - sccache -s tags: - linux-docker @@ -118,7 +119,7 @@ publish-snap: allow_failure: true <<: *collect_artifacts -publish:onnet:update: +publish-onnet-update: stage: publish-onchain only: *releaseable_branches cache: {} @@ -126,7 +127,7 @@ publish:onnet:update: - build-linux - build-darwin - build-windows - - publish:awss3:release + - publish-awss3-release before_script: *determine_version script: - scripts/gitlab/publish-onnet-update.sh @@ -134,7 +135,7 @@ publish:onnet:update: - linux-docker # configures aws for fast uploads/syncs -.s3_before_script: &s3_before_script +.s3-before-script: &s3-before-script before_script: - mkdir -p ${HOME}/.aws - | @@ -150,7 +151,7 @@ publish:onnet:update: addressing_style = path EOC -publish:awss3:release: +publish-awss3-release: image: parity/awscli:latest stage: publish only: *releaseable_branches @@ -161,7 +162,7 @@ publish:awss3:release: - build-windows variables: GIT_STRATEGY: none - <<: *s3_before_script + <<: *s3-before-script script: - echo "__________Push binaries to AWS S3____________" - case "${SCHEDULE_TAG:-${CI_COMMIT_REF_NAME}}" in @@ -174,7 +175,7 @@ publish:awss3:release: esac - aws s3 sync ./artifacts s3://${BUCKET}/${SCHEDULE_TAG:-${CI_COMMIT_REF_NAME}}/ after_script: - - aws s3 ls s3://${BUCKET}/latest/ + - aws s3 ls s3://${BUCKET}/${SCHEDULE_TAG:-${CI_COMMIT_REF_NAME}}/ --recursive --human-readable --summarize tags: - linux-docker From 751d15e4be7b08a21f562c2e5ed646f37830c69b Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Mon, 11 Feb 2019 11:33:16 +0100 Subject: [PATCH 059/168] fix(light-rpc): Make `light_sync` generic (#10238) * fix(light-rpc): Make `light_sync` generic The motivation behind this change is to easily mock `light-sync` to make it possible to enable `rpc-integration` tests for the light-client. Currently the `rpc's` requires the concrete type `sync::LightSync` which makes it very hard to do so * fix(bad merge) --- Cargo.lock | 2 + ethcore/sync/src/api.rs | 55 ++++++++++++++++++---- parity/light_helpers/epoch_fetch.rs | 2 +- parity/light_helpers/queue_cull.rs | 2 +- rpc/src/v1/helpers/dispatch/light.rs | 40 ++++++++++++---- rpc/src/v1/helpers/light_fetch.rs | 68 +++++++++++++++++++++++----- rpc/src/v1/impls/eth_pubsub.rs | 21 +++++---- rpc/src/v1/impls/light/eth.rs | 48 ++++++++++++++------ rpc/src/v1/impls/light/parity.rs | 23 ++++++---- 9 files changed, 198 insertions(+), 63 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index abf4b735c9..1868d889c2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,3 +1,5 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. [[package]] name = "aho-corasick" version = "0.6.8" diff --git a/ethcore/sync/src/api.rs b/ethcore/sync/src/api.rs index 24f6a718ad..cc7a304920 100644 --- a/ethcore/sync/src/api.rs +++ b/ethcore/sync/src/api.rs @@ -51,6 +51,8 @@ use network::IpFilter; use private_tx::PrivateTxHandler; use types::transaction::UnverifiedTransaction; +use super::light_sync::SyncInfo; + /// Parity sync protocol pub const WARP_SYNC_PROTOCOL_ID: ProtocolId = *b"par"; /// Ethereum sync protocol @@ -804,6 +806,24 @@ pub trait LightSyncProvider { fn transactions_stats(&self) -> BTreeMap; } +/// Wrapper around `light_sync::SyncInfo` to expose those methods without the concrete type `LightSync` +pub trait LightSyncInfo: Send + Sync { + /// Get the highest block advertised on the network. + fn highest_block(&self) -> Option; + + /// Get the block number at the time of sync start. + fn start_block(&self) -> u64; + + /// Whether major sync is underway. + fn is_major_importing(&self) -> bool; +} + +/// Execute a closure with a protocol context. +pub trait LightNetworkDispatcher { + /// Execute a closure with a protocol context. + fn with_context(&self, f: F) -> Option where F: FnOnce(&::light::net::BasicContext) -> T; +} + /// Configuration for the light sync. pub struct LightSyncParams { /// Network configuration. @@ -823,7 +843,7 @@ pub struct LightSyncParams { /// Service for light synchronization. pub struct LightSync { proto: Arc, - sync: Arc<::light_sync::SyncInfo + Sync + Send>, + sync: Arc, attached_protos: Vec, network: NetworkService, subprotocol_name: [u8; 3], @@ -874,15 +894,6 @@ impl LightSync { }) } - /// Execute a closure with a protocol context. - pub fn with_context(&self, f: F) -> Option - where F: FnOnce(&::light::net::BasicContext) -> T - { - self.network.with_context_eval( - self.subprotocol_name, - move |ctx| self.proto.with_context(&ctx, f), - ) - } } impl ::std::ops::Deref for LightSync { @@ -891,6 +902,16 @@ impl ::std::ops::Deref for LightSync { fn deref(&self) -> &Self::Target { &*self.sync } } + +impl LightNetworkDispatcher for LightSync { + fn with_context(&self, f: F) -> Option where F: FnOnce(&::light::net::BasicContext) -> T { + self.network.with_context_eval( + self.subprotocol_name, + move |ctx| self.proto.with_context(&ctx, f), + ) + } +} + impl ManageNetwork for LightSync { fn accept_unreserved_peers(&self) { self.network.set_non_reserved_mode(NonReservedPeerMode::Accept); @@ -991,3 +1012,17 @@ impl LightSyncProvider for LightSync { Default::default() // TODO } } + +impl LightSyncInfo for LightSync { + fn highest_block(&self) -> Option { + (*self.sync).highest_block() + } + + fn start_block(&self) -> u64 { + (*self.sync).start_block() + } + + fn is_major_importing(&self) -> bool { + (*self.sync).is_major_importing() + } +} diff --git a/parity/light_helpers/epoch_fetch.rs b/parity/light_helpers/epoch_fetch.rs index ecf9486089..01e74059ea 100644 --- a/parity/light_helpers/epoch_fetch.rs +++ b/parity/light_helpers/epoch_fetch.rs @@ -18,7 +18,7 @@ use std::sync::{Arc, Weak}; use ethcore::engines::{EthEngine, StateDependentProof}; use ethcore::machine::EthereumMachine; -use sync::LightSync; +use sync::{LightSync, LightNetworkDispatcher}; use types::encoded; use types::header::Header; use types::receipt::Receipt; diff --git a/parity/light_helpers/queue_cull.rs b/parity/light_helpers/queue_cull.rs index c919511ba5..ec1ca612b8 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 sync::LightSync; +use sync::{LightSync, LightNetworkDispatcher}; use io::{IoContext, IoHandler, TimerToken}; use light::client::LightChainClient; diff --git a/rpc/src/v1/helpers/dispatch/light.rs b/rpc/src/v1/helpers/dispatch/light.rs index ff47eaa7ac..2913e52c85 100644 --- a/rpc/src/v1/helpers/dispatch/light.rs +++ b/rpc/src/v1/helpers/dispatch/light.rs @@ -23,7 +23,7 @@ use light::client::LightChainClient; use light::on_demand::{request, OnDemand}; use parking_lot::{Mutex, RwLock}; use stats::Corpus; -use sync::LightSync; +use sync::{LightSyncProvider, LightNetworkDispatcher, ManageNetwork}; use types::basic_account::BasicAccount; use types::ids::BlockId; use types::transaction::{SignedTransaction, PendingTransaction, Error as TransactionError}; @@ -37,10 +37,9 @@ use v1::types::{RichRawTransaction as RpcRichRawTransaction,}; use super::{Dispatcher, Accounts, SignWith, PostSign}; /// Dispatcher for light clients -- fetches default gas price, next nonce, etc. from network. -#[derive(Clone)] -pub struct LightDispatcher { +pub struct LightDispatcher { /// Sync service. - pub sync: Arc, + pub sync: Arc, /// Header chain client. pub client: Arc, /// On-demand request service. @@ -55,12 +54,15 @@ pub struct LightDispatcher { pub gas_price_percentile: usize, } -impl LightDispatcher { +impl LightDispatcher +where + S: LightSyncProvider + LightNetworkDispatcher + ManageNetwork + 'static +{ /// Create a new `LightDispatcher` from its requisite parts. /// /// For correct operation, the OnDemand service is assumed to be registered as a network handler, pub fn new( - sync: Arc, + sync: Arc, client: Arc, on_demand: Arc, cache: Arc>, @@ -115,7 +117,27 @@ impl LightDispatcher { } } -impl Dispatcher for LightDispatcher { +impl Clone for LightDispatcher +where + S: LightSyncProvider + LightNetworkDispatcher + ManageNetwork + 'static +{ + fn clone(&self) -> Self { + Self { + sync: self.sync.clone(), + client: self.client.clone(), + on_demand: self.on_demand.clone(), + cache: self.cache.clone(), + transaction_queue: self.transaction_queue.clone(), + nonces: self.nonces.clone(), + gas_price_percentile: self.gas_price_percentile + } + } +} + +impl Dispatcher for LightDispatcher +where + S: LightSyncProvider + LightNetworkDispatcher + ManageNetwork + 'static +{ // Ignore the `force_nonce` flag in order to always query the network when fetching the nonce and // the account state. If the nonce is specified in the transaction use that nonce instead but do the // network request anyway to the account state (balance) @@ -217,8 +239,8 @@ impl Dispatcher for LightDispatcher { /// Get a recent gas price corpus. // TODO: this could be `impl Trait`. -pub fn fetch_gas_price_corpus( - sync: Arc, +pub fn fetch_gas_price_corpus( + sync: Arc, client: Arc, on_demand: Arc, cache: Arc>, diff --git a/rpc/src/v1/helpers/light_fetch.rs b/rpc/src/v1/helpers/light_fetch.rs index 5a73c04be0..3ac17c2fd8 100644 --- a/rpc/src/v1/helpers/light_fetch.rs +++ b/rpc/src/v1/helpers/light_fetch.rs @@ -17,6 +17,7 @@ //! Helpers for fetching blockchain data either from the light client or the network. use std::cmp; +use std::clone::Clone; use std::sync::Arc; use types::basic_account::BasicAccount; @@ -40,7 +41,9 @@ use light::on_demand::{ use light::on_demand::error::Error as OnDemandError; use light::request::Field; -use sync::LightSync; + +use sync::{LightNetworkDispatcher, ManageNetwork, LightSyncProvider}; + use ethereum_types::{U256, Address}; use hash::H256; use parking_lot::Mutex; @@ -52,10 +55,12 @@ use v1::helpers::{CallRequest as CallRequestHelper, errors, dispatch}; use v1::types::{BlockNumber, CallRequest, Log, Transaction}; const NO_INVALID_BACK_REFS_PROOF: &str = "Fails only on invalid back-references; back-references here known to be valid; qed"; - const WRONG_RESPONSE_AMOUNT_TYPE_PROOF: &str = "responses correspond directly with requests in amount and type; qed"; -pub fn light_all_transactions(dispatch: &Arc) -> impl Iterator { +pub fn light_all_transactions(dispatch: &Arc>) -> impl Iterator +where + S: LightSyncProvider + LightNetworkDispatcher + ManageNetwork + 'static +{ let txq = dispatch.transaction_queue.read(); let chain_info = dispatch.client.chain_info(); @@ -66,20 +71,36 @@ pub fn light_all_transactions(dispatch: &Arc) -> impl /// Helper for fetching blockchain data either from the light client or the network /// as necessary. -#[derive(Clone)] -pub struct LightFetch { +pub struct LightFetch +{ /// The light client. pub client: Arc, /// The on-demand request service. pub on_demand: Arc, /// Handle to the network. - pub sync: Arc, + pub sync: Arc, /// The light data cache. pub cache: Arc>, /// Gas Price percentile pub gas_price_percentile: usize, } +impl Clone for LightFetch +where + S: LightSyncProvider + LightNetworkDispatcher + ManageNetwork + 'static +{ + fn clone(&self) -> Self { + Self { + client: self.client.clone(), + on_demand: self.on_demand.clone(), + sync: self.sync.clone(), + cache: self.cache.clone(), + gas_price_percentile: self.gas_price_percentile + } + } +} + + /// Extract a transaction at given index. pub fn extract_transaction_at_index(block: encoded::Block, index: usize) -> Option { block.transactions().into_iter().nth(index) @@ -115,7 +136,10 @@ fn extract_header(res: &[OnDemandResponse], header: HeaderRef) -> Option LightFetch +where + S: LightSyncProvider + LightNetworkDispatcher + ManageNetwork + 'static +{ // push the necessary requests onto the request chain to get the header by the given ID. // yield a header reference which other requests can use. fn make_header_requests(&self, id: BlockId, reqs: &mut Vec) -> Result { @@ -635,20 +659,42 @@ impl LightFetch { } } -#[derive(Clone)] -struct ExecuteParams { +struct ExecuteParams +where + S: LightSyncProvider + LightNetworkDispatcher + ManageNetwork + 'static +{ from: Address, tx: EthTransaction, hdr: encoded::Header, env_info: ::vm::EnvInfo, engine: Arc<::ethcore::engines::EthEngine>, on_demand: Arc, - sync: Arc, + sync: Arc, +} + +impl Clone for ExecuteParams +where + S: LightSyncProvider + LightNetworkDispatcher + ManageNetwork + 'static +{ + fn clone(&self) -> Self { + Self { + from: self.from.clone(), + tx: self.tx.clone(), + hdr: self.hdr.clone(), + env_info: self.env_info.clone(), + engine: self.engine.clone(), + on_demand: self.on_demand.clone(), + sync: self.sync.clone() + } + } } // Has a peer execute the transaction with given params. If `gas_known` is false, this will set the `gas value` to the // `required gas value` unless it exceeds the block gas limit -fn execute_read_only_tx(gas_known: bool, params: ExecuteParams) -> impl Future + Send { +fn execute_read_only_tx(gas_known: bool, params: ExecuteParams) -> impl Future + Send +where + S: LightSyncProvider + LightNetworkDispatcher + ManageNetwork + 'static +{ if !gas_known { Box::new(future::loop_fn(params, |mut params| { execute_read_only_tx(true, params.clone()).and_then(move |res| { diff --git a/rpc/src/v1/impls/eth_pubsub.rs b/rpc/src/v1/impls/eth_pubsub.rs index 4d452a4791..b4baf5aa4d 100644 --- a/rpc/src/v1/impls/eth_pubsub.rs +++ b/rpc/src/v1/impls/eth_pubsub.rs @@ -36,7 +36,9 @@ use light::client::{LightChainClient, LightChainNotify}; use light::on_demand::OnDemand; use parity_runtime::Executor; use parking_lot::{RwLock, Mutex}; -use sync::LightSync; + +use sync::{LightSyncProvider, LightNetworkDispatcher, ManageNetwork}; + use types::encoded; use types::filter::Filter as EthFilter; @@ -87,12 +89,15 @@ impl EthPubSubClient { } } -impl EthPubSubClient { +impl EthPubSubClient> +where + S: LightSyncProvider + LightNetworkDispatcher + ManageNetwork + 'static +{ /// Creates a new `EthPubSubClient` for `LightClient`. pub fn light( client: Arc, on_demand: Arc, - sync: Arc, + sync: Arc, cache: Arc>, executor: Executor, gas_price_percentile: usize, @@ -189,7 +194,10 @@ pub trait LightClient: Send + Sync { fn logs(&self, filter: EthFilter) -> BoxFuture>; } -impl LightClient for LightFetch { +impl LightClient for LightFetch +where + S: LightSyncProvider + LightNetworkDispatcher + ManageNetwork + 'static +{ fn block_header(&self, id: BlockId) -> Option { self.client.block_header(id) } @@ -200,10 +208,7 @@ impl LightClient for LightFetch { } impl LightChainNotify for ChainNotificationHandler { - fn new_headers( - &self, - enacted: &[H256], - ) { + fn new_headers(&self, enacted: &[H256]) { let headers = enacted .iter() .filter_map(|hash| self.client.block_header(BlockId::Hash(*hash))) diff --git a/rpc/src/v1/impls/light/eth.rs b/rpc/src/v1/impls/light/eth.rs index 2dd1943bee..e13f562194 100644 --- a/rpc/src/v1/impls/light/eth.rs +++ b/rpc/src/v1/impls/light/eth.rs @@ -32,7 +32,6 @@ use ethereum_types::{U256, Address}; use hash::{KECCAK_NULL_RLP, KECCAK_EMPTY_LIST_RLP}; use parking_lot::{RwLock, Mutex}; use rlp::Rlp; -use sync::LightSync; use types::transaction::SignedTransaction; use types::encoded; use types::filter::Filter as EthcoreFilter; @@ -45,19 +44,22 @@ use v1::helpers::deprecated::{self, DeprecationNotice}; use v1::helpers::light_fetch::{self, LightFetch}; use v1::traits::Eth; use v1::types::{ - RichBlock, Block, BlockTransactions, BlockNumber, LightBlockNumber, Bytes, SyncStatus, SyncInfo, + RichBlock, Block, BlockTransactions, BlockNumber, LightBlockNumber, Bytes, + SyncStatus as RpcSyncStatus, SyncInfo as RpcSyncInfo, Transaction, CallRequest, Index, Filter, Log, Receipt, Work, EthAccount, H64 as RpcH64, H256 as RpcH256, H160 as RpcH160, U256 as RpcU256, U64 as RpcU64, }; use v1::metadata::Metadata; +use sync::{LightSyncInfo, LightSyncProvider, LightNetworkDispatcher, ManageNetwork}; + const NO_INVALID_BACK_REFS: &str = "Fails only on invalid back-references; back-references here known to be valid; qed"; /// Light client `ETH` (and filter) RPC. -pub struct EthClient { - sync: Arc, - client: Arc, +pub struct EthClient { + sync: Arc, + client: Arc, on_demand: Arc, transaction_queue: Arc>, accounts: Arc Vec
+ Send + Sync>, @@ -68,7 +70,10 @@ pub struct EthClient { deprecation_notice: DeprecationNotice, } -impl Clone for EthClient { +impl Clone for EthClient +where + S: LightSyncProvider + LightNetworkDispatcher + 'static +{ fn clone(&self) -> Self { // each instance should have its own poll manager. EthClient { @@ -86,12 +91,16 @@ impl Clone for EthClient { } } -impl EthClient { +impl EthClient +where + C: LightChainClient + 'static, + S: LightSyncProvider + LightNetworkDispatcher + ManageNetwork + 'static +{ /// Create a new `EthClient` with a handle to the light sync instance, client, /// and on-demand request service, which is assumed to be attached as a handler. pub fn new( - sync: Arc, - client: Arc, + sync: Arc, + client: Arc, on_demand: Arc, transaction_queue: Arc>, accounts: Arc Vec
+ Send + Sync>, @@ -114,7 +123,8 @@ impl EthClient { } /// Create a light data fetcher instance. - fn fetcher(&self) -> LightFetch { + fn fetcher(&self) -> LightFetch + { LightFetch { client: self.client.clone(), on_demand: self.on_demand.clone(), @@ -211,21 +221,25 @@ impl EthClient { } } -impl Eth for EthClient { +impl Eth for EthClient +where + C: LightChainClient + 'static, + S: LightSyncInfo + LightSyncProvider + LightNetworkDispatcher + ManageNetwork + 'static +{ type Metadata = Metadata; fn protocol_version(&self) -> Result { Ok(format!("{}", ::light::net::MAX_PROTOCOL_VERSION)) } - fn syncing(&self) -> Result { + fn syncing(&self) -> Result { if self.sync.is_major_importing() { let chain_info = self.client.chain_info(); let current_block = U256::from(chain_info.best_block_number); let highest_block = self.sync.highest_block().map(U256::from) .unwrap_or_else(|| current_block); - Ok(SyncStatus::Info(SyncInfo { + Ok(RpcSyncStatus::Info(RpcSyncInfo { starting_block: U256::from(self.sync.start_block()).into(), current_block: current_block.into(), highest_block: highest_block.into(), @@ -233,7 +247,7 @@ impl Eth for EthClient { warp_chunks_processed: None, })) } else { - Ok(SyncStatus::None) + Ok(RpcSyncStatus::None) } } @@ -524,7 +538,11 @@ impl Eth for EthClient { } // This trait implementation triggers a blanked impl of `EthFilter`. -impl Filterable for EthClient { +impl Filterable for EthClient +where + C: LightChainClient + 'static, + S: LightSyncProvider + LightNetworkDispatcher + ManageNetwork + 'static +{ fn best_block_number(&self) -> u64 { self.client.chain_info().best_block_number } fn block_hash(&self, id: BlockId) -> Option<::ethereum_types::H256> { diff --git a/rpc/src/v1/impls/light/parity.rs b/rpc/src/v1/impls/light/parity.rs index 3bb88b509e..f744095cba 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::DEFAULT_MAC; use ethkey::{crypto::ecies, Brain, Generator}; use ethstore::random_phrase; -use sync::LightSyncProvider; +use sync::{LightSyncInfo, LightSyncProvider, LightNetworkDispatcher, ManageNetwork}; use ethcore_logger::RotatingLogger; use jsonrpc_core::{Result, BoxFuture}; @@ -46,8 +46,8 @@ use v1::types::{ use Host; /// Parity implementation for light client. -pub struct ParityClient { - light_dispatch: Arc, +pub struct ParityClient { + light_dispatch: Arc>, logger: Arc, settings: Arc, signer: Option>, @@ -55,10 +55,13 @@ pub struct ParityClient { gas_price_percentile: usize, } -impl ParityClient { +impl ParityClient +where + S: LightSyncProvider + LightNetworkDispatcher + ManageNetwork + 'static +{ /// Creates new `ParityClient`. pub fn new( - light_dispatch: Arc, + light_dispatch: Arc>, logger: Arc, settings: Arc, signer: Option>, @@ -76,7 +79,8 @@ impl ParityClient { } /// Create a light blockchain data fetcher. - fn fetcher(&self) -> LightFetch { + fn fetcher(&self) -> LightFetch + { LightFetch { client: self.light_dispatch.client.clone(), on_demand: self.light_dispatch.on_demand.clone(), @@ -87,7 +91,10 @@ impl ParityClient { } } -impl Parity for ParityClient { +impl Parity for ParityClient +where + S: LightSyncInfo + LightSyncProvider + LightNetworkDispatcher + ManageNetwork + 'static +{ type Metadata = Metadata; fn transactions_limit(&self) -> Result { @@ -371,7 +378,7 @@ impl Parity for ParityClient { fn status(&self) -> Result<()> { let has_peers = self.settings.is_dev_chain || self.light_dispatch.sync.peer_numbers().connected > 0; - let is_importing = self.light_dispatch.sync.is_major_importing(); + let is_importing = (*self.light_dispatch.sync).is_major_importing(); if has_peers && !is_importing { Ok(()) From c84e5745fa72c1744c1108ae30ea1eadc3c6ce37 Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Mon, 11 Feb 2019 15:27:46 +0100 Subject: [PATCH 060/168] fix(parity-clib): grumbles that were not addressed in #9920 (#10154) * fix(remove needless unsafe blocks) * style(nits) * fix(parity-clib): eliminate repetitive event loops * revert(java bindings): safe rust -> unsafe rust These functions can still end up with `UB` thus should be unsafe * fix(grumbles): make Callback trait `pub (crate)` --- parity-clib/src/java.rs | 102 ++++++----------------- parity-clib/src/lib.rs | 177 ++++++++++++++++++++-------------------- 2 files changed, 116 insertions(+), 163 deletions(-) diff --git a/parity-clib/src/java.rs b/parity-clib/src/java.rs index bb807083a4..ba86e5c88d 100644 --- a/parity-clib/src/java.rs +++ b/parity-clib/src/java.rs @@ -15,34 +15,31 @@ // along with Parity Ethereum. If not, see . use std::{mem, ptr}; +use std::ffi::c_void; use std::sync::Arc; -use std::time::Duration; -use std::thread; -use std::os::raw::c_void; -use {parity_config_from_cli, parity_destroy, parity_set_logger, parity_start, parity_unsubscribe_ws, ParityParams, error}; +use {Callback, parity_config_from_cli, parity_destroy, parity_rpc_worker, parity_start, parity_set_logger, + parity_unsubscribe_ws, parity_ws_worker, ParityParams}; -use futures::{Future, Stream}; -use futures::sync::mpsc; use jni::{JavaVM, JNIEnv}; use jni::objects::{JClass, JString, JObject, JValue, GlobalRef}; use jni::sys::{jlong, jobjectArray, va_list}; -use tokio_current_thread::CurrentThread; -use parity_ethereum::{RunningClient, PubSubSession}; +use parity_ethereum::RunningClient; type CheckedQuery<'a> = (&'a RunningClient, String, JavaVM, GlobalRef); // Creates a Java callback to a static method named `void callback(Object)` -struct Callback<'a> { +struct JavaCallback<'a> { jvm: JavaVM, callback: GlobalRef, method_name: &'a str, method_descriptor: &'a str, } -unsafe impl<'a> Send for Callback<'a> {} -unsafe impl<'a> Sync for Callback<'a> {} -impl<'a> Callback<'a> { +unsafe impl<'a> Send for JavaCallback<'a> {} +unsafe impl<'a> Sync for JavaCallback<'a> {} + +impl<'a> JavaCallback<'a> { fn new(jvm: JavaVM, callback: GlobalRef) -> Self { Self { jvm, @@ -51,7 +48,9 @@ impl<'a> Callback<'a> { method_descriptor: "(Ljava/lang/Object;)V", } } +} +impl<'a> Callback for JavaCallback<'a> { fn call(&self, msg: &str) { let env = self.jvm.attach_current_thread().expect("JavaVM should have an environment; qed"); let java_str = env.new_string(msg.to_string()).expect("Rust String is valid JString; qed"); @@ -63,13 +62,13 @@ impl<'a> Callback<'a> { #[no_mangle] pub unsafe extern "system" fn Java_io_parity_ethereum_Parity_configFromCli(env: JNIEnv, _: JClass, cli: jobjectArray) -> jlong { - let cli_len = env.get_array_length(cli).expect("invalid Java bindings"); + let cli_len = env.get_array_length(cli).expect("invalid Java bindings") as usize; - let mut jni_strings = Vec::with_capacity(cli_len as usize); - let mut opts = Vec::with_capacity(cli_len as usize); - let mut opts_lens = Vec::with_capacity(cli_len as usize); + let mut jni_strings = Vec::with_capacity(cli_len); + let mut opts = Vec::with_capacity(cli_len); + let mut opts_lens = Vec::with_capacity(cli_len); - for n in 0..cli_len { + for n in 0..cli_len as i32 { let elem = env.get_object_array_element(cli, n).expect("invalid Java bindings"); let elem_str: JString = elem.into(); match env.get_string(elem_str) { @@ -77,7 +76,7 @@ pub unsafe extern "system" fn Java_io_parity_ethereum_Parity_configFromCli(env: opts.push(s.as_ptr()); opts_lens.push(s.to_bytes().len()); jni_strings.push(s); - }, + } Err(err) => { let _ = env.throw_new("java/lang/Exception", err.to_string()); return 0 @@ -86,7 +85,7 @@ pub unsafe extern "system" fn Java_io_parity_ethereum_Parity_configFromCli(env: } let mut out = ptr::null_mut(); - match parity_config_from_cli(opts.as_ptr(), opts_lens.as_ptr(), cli_len as usize, &mut out) { + match parity_config_from_cli(opts.as_ptr(), opts_lens.as_ptr(), cli_len, &mut out) { 0 => out as jlong, _ => { let _ = env.throw_new("java/lang/Exception", "failed to create config object"); @@ -120,7 +119,7 @@ pub unsafe extern "system" fn Java_io_parity_ethereum_Parity_build( _ => { let _ = env.throw_new("java/lang/Exception", "failed to start Parity"); 0 - }, + } } } @@ -129,7 +128,7 @@ pub unsafe extern "system" fn Java_io_parity_ethereum_Parity_destroy(_env: JNIEn parity_destroy(parity); } -unsafe fn async_checker<'a>(client: va_list, rpc: JString, callback: JObject, env: &JNIEnv<'a>) +unsafe fn java_query_checker<'a>(client: va_list, rpc: JString, callback: JObject, env: &JNIEnv<'a>) -> Result, String> { let query: String = env.get_string(rpc) .map(Into::into) @@ -151,26 +150,10 @@ pub unsafe extern "system" fn Java_io_parity_ethereum_Parity_rpcQueryNative( callback: JObject, ) { - let _ = async_checker(parity, rpc, callback, &env) + let _ = java_query_checker(parity, rpc, callback, &env) .map(|(client, query, jvm, global_ref)| { - let callback = Arc::new(Callback::new(jvm, global_ref)); - let cb = callback.clone(); - let future = client.rpc_query(&query, None).map(move |response| { - let response = response.unwrap_or_else(|| error::EMPTY.to_string()); - callback.call(&response); - }); - - let _handle = thread::Builder::new() - .name("rpc_query".to_string()) - .spawn(move || { - let mut current_thread = CurrentThread::new(); - current_thread.spawn(future); - let _ = current_thread.run_timeout(Duration::from_millis(timeout_ms as u64)) - .map_err(|_e| { - cb.call(error::TIMEOUT); - }); - }) - .expect("rpc-query thread shouldn't fail; qed"); + let callback = Arc::new(JavaCallback::new(jvm, global_ref)); + parity_rpc_worker(client, &query, callback, timeout_ms as u64); }) .map_err(|e| { let _ = env.throw_new("java/lang/Exception", e); @@ -186,43 +169,10 @@ pub unsafe extern "system" fn Java_io_parity_ethereum_Parity_subscribeWebSocketN callback: JObject, ) -> va_list { - async_checker(parity, rpc, callback, &env) + java_query_checker(parity, rpc, callback, &env) .map(move |(client, query, jvm, global_ref)| { - let callback = Arc::new(Callback::new(jvm, global_ref)); - let (tx, mut rx) = mpsc::channel(1); - let session = Arc::new(PubSubSession::new(tx)); - let weak_session = Arc::downgrade(&session); - let query_future = client.rpc_query(&query, Some(session.clone()));; - - let _handle = thread::Builder::new() - .name("ws-subscriber".into()) - .spawn(move || { - // Wait for subscription ID - // Note this may block forever and can't be destroyed using the session object - // However, this will likely timeout or be catched the RPC layer - if let Ok(Some(response)) = query_future.wait() { - callback.call(&response); - } else { - callback.call(error::SUBSCRIBE); - return; - }; - - loop { - for response in rx.by_ref().wait() { - if let Ok(r) = response { - callback.call(&r); - } - } - - let rc = weak_session.upgrade().map_or(0,|session| Arc::strong_count(&session)); - // No subscription left, then terminate - if rc <= 1 { - break; - } - } - }) - .expect("rpc-subscriber thread shouldn't fail; qed"); - Arc::into_raw(session) as va_list + let callback = Arc::new(JavaCallback::new(jvm, global_ref)); + parity_ws_worker(client, &query, callback) as va_list }) .unwrap_or_else(|e| { let _ = env.throw_new("java/lang/Exception", e); diff --git a/parity-clib/src/lib.rs b/parity-clib/src/lib.rs index eca6edcd69..bbb60ec2d2 100644 --- a/parity-clib/src/lib.rs +++ b/parity-clib/src/lib.rs @@ -40,7 +40,7 @@ use futures::sync::mpsc; use parity_ethereum::{PubSubSession, RunningClient}; use tokio_current_thread::CurrentThread; -type Callback = Option; +type CCallback = Option; type CheckedQuery<'a> = (&'a RunningClient, &'static str); pub mod error { @@ -52,11 +52,33 @@ pub mod error { #[repr(C)] pub struct ParityParams { pub configuration: *mut c_void, - pub on_client_restart_cb: Callback, + pub on_client_restart_cb: CCallback, pub on_client_restart_cb_custom: *mut c_void, pub logger: *mut c_void } +/// Trait representing a callback that passes a string +pub(crate) trait Callback: Send + Sync { + fn call(&self, msg: &str); +} + +// Internal structure for handling callbacks that get passed a string. +struct CallbackStr { + user_data: *mut c_void, + function: CCallback, +} + +unsafe impl Send for CallbackStr {} +unsafe impl Sync for CallbackStr {} +impl Callback for CallbackStr { + fn call(&self, msg: &str) { + if let Some(ref cb) = self.function { + let cstr = CString::new(msg).expect("valid string with no nul bytes in the middle; qed").into_raw(); + cb(self.user_data, cstr, msg.len()) + } + } +} + #[no_mangle] pub unsafe extern fn parity_config_from_cli( args: *const *const c_char, @@ -112,7 +134,6 @@ pub unsafe extern fn parity_start(cfg: *const ParityParams, output: *mut *mut c_ panic::catch_unwind(|| { *output = ptr::null_mut(); let cfg: &ParityParams = &*cfg; - let logger = Arc::from_raw(cfg.logger as *mut parity_ethereum::RotatingLogger); let config = Box::from_raw(cfg.configuration as *mut parity_ethereum::Configuration); @@ -121,7 +142,7 @@ pub unsafe extern fn parity_start(cfg: *const ParityParams, output: *mut *mut c_ user_data: cfg.on_client_restart_cb_custom, function: cfg.on_client_restart_cb, }; - move |new_chain: String| { cb.call(new_chain.as_bytes()); } + move |new_chain: String| { cb.call(&new_chain); } }; let action = match parity_ethereum::start(*config, logger, on_client_restart_cb, || {}) { @@ -133,7 +154,7 @@ pub unsafe extern fn parity_start(cfg: *const ParityParams, output: *mut *mut c_ parity_ethereum::ExecutionAction::Instant(Some(s)) => { println!("{}", s); 0 }, parity_ethereum::ExecutionAction::Instant(None) => 0, parity_ethereum::ExecutionAction::Running(client) => { - *output = Box::into_raw(Box::::new(client)) as *mut c_void; + *output = Box::into_raw(Box::new(client)) as *mut c_void; 0 } } @@ -148,47 +169,19 @@ pub unsafe extern fn parity_destroy(client: *mut c_void) { }); } -unsafe fn parity_rpc_query_checker<'a>(client: *const c_void, query: *const c_char, len: usize) - -> Option> -{ - let query_str = { - let string = slice::from_raw_parts(query as *const u8, len); - str::from_utf8(string).ok()? - }; - let client: &RunningClient = &*(client as *const RunningClient); - Some((client, query_str)) -} - #[no_mangle] pub unsafe extern fn parity_rpc( client: *const c_void, query: *const c_char, len: usize, timeout_ms: usize, - callback: Callback, + callback: CCallback, user_data: *mut c_void, ) -> c_int { panic::catch_unwind(|| { if let Some((client, query)) = parity_rpc_query_checker(client, query, len) { - let client = client as &RunningClient; let callback = Arc::new(CallbackStr {user_data, function: callback} ); - let cb = callback.clone(); - let query = client.rpc_query(query, None).map(move |response| { - let response = response.unwrap_or_else(|| error::EMPTY.to_string()); - callback.call(response.as_bytes()); - }); - - let _handle = thread::Builder::new() - .name("rpc_query".to_string()) - .spawn(move || { - let mut current_thread = CurrentThread::new(); - current_thread.spawn(query); - let _ = current_thread.run_timeout(Duration::from_millis(timeout_ms as u64)) - .map_err(|_e| { - cb.call(error::TIMEOUT.as_bytes()); - }); - }) - .expect("rpc-query thread shouldn't fail; qed"); + parity_rpc_worker(client, query, callback, timeout_ms as u64); 0 } else { 1 @@ -201,47 +194,13 @@ pub unsafe extern fn parity_subscribe_ws( client: *const c_void, query: *const c_char, len: usize, - callback: Callback, + callback: CCallback, user_data: *mut c_void, ) -> *const c_void { - panic::catch_unwind(|| { if let Some((client, query)) = parity_rpc_query_checker(client, query, len) { - let (tx, mut rx) = mpsc::channel(1); - let session = Arc::new(PubSubSession::new(tx)); - let query_future = client.rpc_query(query, Some(session.clone())); - let weak_session = Arc::downgrade(&session); - let cb = CallbackStr { user_data, function: callback}; - - let _handle = thread::Builder::new() - .name("ws-subscriber".into()) - .spawn(move || { - // Wait for subscription ID - // Note this may block forever and be can't destroyed using the session object - // However, this will likely timeout or be catched the RPC layer - if let Ok(Some(response)) = query_future.wait() { - cb.call(response.as_bytes()); - } else { - cb.call(error::SUBSCRIBE.as_bytes()); - return; - } - - loop { - for response in rx.by_ref().wait() { - if let Ok(r) = response { - cb.call(r.as_bytes()); - } - } - - let rc = weak_session.upgrade().map_or(0,|session| Arc::strong_count(&session)); - // No subscription left, then terminate - if rc <= 1 { - break; - } - } - }) - .expect("rpc-subscriber thread shouldn't fail; qed"); - Arc::into_raw(session) as *const c_void + let callback = Arc::new(CallbackStr { user_data, function: callback}); + parity_ws_worker(client, query, callback) } else { ptr::null() } @@ -257,10 +216,10 @@ pub unsafe extern fn parity_unsubscribe_ws(session: *const c_void) { } #[no_mangle] -pub unsafe extern fn parity_set_panic_hook(callback: Callback, param: *mut c_void) { +pub extern fn parity_set_panic_hook(callback: CCallback, param: *mut c_void) { let cb = CallbackStr {user_data: param, function: callback}; panic_hook::set_with(move |panic_msg| { - cb.call(panic_msg.as_bytes()); + cb.call(panic_msg); }); } @@ -283,19 +242,63 @@ pub unsafe extern fn parity_set_logger( *logger = Arc::into_raw(parity_ethereum::setup_log(&logger_cfg).expect("Logger initialized only once; qed")) as *mut _; } -// Internal structure for handling callbacks that get passed a string. -struct CallbackStr { - user_data: *mut c_void, - function: Callback, +// WebSocket event loop +fn parity_ws_worker(client: &RunningClient, query: &str, callback: Arc) -> *const c_void { + let (tx, mut rx) = mpsc::channel(1); + let session = Arc::new(PubSubSession::new(tx)); + let query_future = client.rpc_query(query, Some(session.clone())); + let weak_session = Arc::downgrade(&session); + let _handle = thread::Builder::new() + .name("ws-subscriber".into()) + .spawn(move || { + // Wait for subscription ID + // Note this may block forever and be can't destroyed using the session object + // However, this will likely timeout or be catched the RPC layer + if let Ok(Some(response)) = query_future.wait() { + callback.call(&response); + } else { + callback.call(error::SUBSCRIBE); + return; + } + + while weak_session.upgrade().map_or(0, |session| Arc::strong_count(&session)) > 1 { + for response in rx.by_ref().wait() { + if let Ok(r) = response { + callback.call(&r); + } + } + } + }) + .expect("rpc-subscriber thread shouldn't fail; qed"); + Arc::into_raw(session) as *const c_void } -unsafe impl Send for CallbackStr {} -unsafe impl Sync for CallbackStr {} -impl CallbackStr { - fn call(&self, msg: &[u8]) { - if let Some(ref cb) = self.function { - let cstr = CString::new(msg).expect("valid string with no null bytes in the middle; qed").into_raw(); - cb(self.user_data, cstr, msg.len()) - } - } +// RPC event loop that runs for at most `timeout_ms` +fn parity_rpc_worker(client: &RunningClient, query: &str, callback: Arc, timeout_ms: u64) { + let cb = callback.clone(); + let query = client.rpc_query(query, None).map(move |response| { + let response = response.unwrap_or_else(|| error::EMPTY.to_string()); + callback.call(&response); + }); + + let _handle = thread::Builder::new() + .name("rpc_query".to_string()) + .spawn(move || { + let mut current_thread = CurrentThread::new(); + current_thread.spawn(query); + let _ = current_thread + .run_timeout(Duration::from_millis(timeout_ms)) + .map_err(|_e| { + cb.call(error::TIMEOUT); + }); + }) + .expect("rpc-query thread shouldn't fail; qed"); +} + +unsafe fn parity_rpc_query_checker<'a>(client: *const c_void, query: *const c_char, len: usize) + -> Option> +{ + let query_str = str::from_utf8(slice::from_raw_parts(query as *const u8, len)).ok()?; + let client: &RunningClient = &*(client as *const RunningClient); + Some((client, query_str)) } From 6dfc1bd4749e7e77ebeabbc32655787855637401 Mon Sep 17 00:00:00 2001 From: Hernando Castano Date: Mon, 11 Feb 2019 17:13:36 +0100 Subject: [PATCH 061/168] Add Statetest support for Constantinople Fix (#10323) * Update Ethereum tests repo to v6.0.0-beta.3 tag * Add spec for St.Peter's / ConstantinopleFix statetests --- ethcore/res/ethereum/st_peters_test.json | 65 ++++++++++++++++++++++++ ethcore/res/ethereum/tests | 2 +- ethcore/src/client/evm_test_client.rs | 1 + ethcore/src/ethereum/mod.rs | 6 +++ ethcore/src/json_tests/state.rs | 2 +- json/src/spec/spec.rs | 1 + 6 files changed, 75 insertions(+), 2 deletions(-) create mode 100644 ethcore/res/ethereum/st_peters_test.json diff --git a/ethcore/res/ethereum/st_peters_test.json b/ethcore/res/ethereum/st_peters_test.json new file mode 100644 index 0000000000..ee88008f66 --- /dev/null +++ b/ethcore/res/ethereum/st_peters_test.json @@ -0,0 +1,65 @@ +{ + "name": "St. Peter's (test)", + "engine": { + "Ethash": { + "params": { + "minimumDifficulty": "0x020000", + "difficultyBoundDivisor": "0x0800", + "durationLimit": "0x0d", + "blockReward": "0x1BC16D674EC80000", + "homesteadTransition": "0x0", + "eip100bTransition": "0x0", + "difficultyBombDelays": { + "0": 5000000 + } + } + } + }, + "params": { + "gasLimitBoundDivisor": "0x0400", + "registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b", + "accountStartNonce": "0x00", + "maximumExtraDataSize": "0x20", + "minGasLimit": "0x1388", + "networkID" : "0x1", + "maxCodeSize": 24576, + "maxCodeSizeTransition": "0x0", + "eip150Transition": "0x0", + "eip160Transition": "0x0", + "eip161abcTransition": "0x0", + "eip161dTransition": "0x0", + "eip140Transition": "0x0", + "eip211Transition": "0x0", + "eip214Transition": "0x0", + "eip155Transition": "0x0", + "eip658Transition": "0x0", + "eip145Transition": "0x0", + "eip1014Transition": "0x0", + "eip1052Transition": "0x0", + "eip1283DisableTransition": "0x0" + }, + "genesis": { + "seal": { + "ethereum": { + "nonce": "0x0000000000000042", + "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + }, + "difficulty": "0x400000000", + "author": "0x0000000000000000000000000000000000000000", + "timestamp": "0x00", + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "extraData": "0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa", + "gasLimit": "0x1388" + }, + "accounts": { + "0000000000000000000000000000000000000001": { "balance": "1", "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } }, + "0000000000000000000000000000000000000002": { "balance": "1", "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } }, + "0000000000000000000000000000000000000003": { "balance": "1", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } }, + "0000000000000000000000000000000000000004": { "balance": "1", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } }, + "0000000000000000000000000000000000000005": { "builtin": { "name": "modexp", "activate_at": "0x00", "pricing": { "modexp": { "divisor": 20 } } } }, + "0000000000000000000000000000000000000006": { "builtin": { "name": "alt_bn128_add", "activate_at": "0x00", "pricing": { "linear": { "base": 500, "word": 0 } } } }, + "0000000000000000000000000000000000000007": { "builtin": { "name": "alt_bn128_mul", "activate_at": "0x00", "pricing": { "linear": { "base": 40000, "word": 0 } } } }, + "0000000000000000000000000000000000000008": { "builtin": { "name": "alt_bn128_pairing", "activate_at": "0x00", "pricing": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 } } } } + } +} diff --git a/ethcore/res/ethereum/tests b/ethcore/res/ethereum/tests index 2cd62aeec1..725dbc73a5 160000 --- a/ethcore/res/ethereum/tests +++ b/ethcore/res/ethereum/tests @@ -1 +1 @@ -Subproject commit 2cd62aeec11da29766b30d500f2b9a96f1f28cf0 +Subproject commit 725dbc73a54649e22a00330bd0f4d6699a5060e5 diff --git a/ethcore/src/client/evm_test_client.rs b/ethcore/src/client/evm_test_client.rs index 7a2158209b..a65e2b313e 100644 --- a/ethcore/src/client/evm_test_client.rs +++ b/ethcore/src/client/evm_test_client.rs @@ -93,6 +93,7 @@ impl<'a> EvmTestClient<'a> { ForkSpec::EIP158 => Some(ethereum::new_eip161_test()), ForkSpec::Byzantium => Some(ethereum::new_byzantium_test()), ForkSpec::Constantinople => Some(ethereum::new_constantinople_test()), + ForkSpec::ConstantinopleFix => Some(ethereum::new_constantinople_fix_test()), ForkSpec::EIP158ToByzantiumAt5 => Some(ethereum::new_transition_test()), ForkSpec::FrontierToHomesteadAt5 | ForkSpec::HomesteadToDaoAt5 | ForkSpec::HomesteadToEIP150At5 => None, } diff --git a/ethcore/src/ethereum/mod.rs b/ethcore/src/ethereum/mod.rs index 104155532c..b7c60789a3 100644 --- a/ethcore/src/ethereum/mod.rs +++ b/ethcore/src/ethereum/mod.rs @@ -148,6 +148,9 @@ pub fn new_byzantium_test() -> Spec { load(None, include_bytes!("../../res/ether /// Create a new Foundation Constantinople era spec. pub fn new_constantinople_test() -> Spec { load(None, include_bytes!("../../res/ethereum/constantinople_test.json")) } +/// Create a new Foundation St. Peter's (Contantinople Fix) era spec. +pub fn new_constantinople_fix_test() -> Spec { load(None, include_bytes!("../../res/ethereum/st_peters_test.json")) } + /// Create a new Musicoin-MCIP3-era spec. pub fn new_mcip3_test() -> Spec { load(None, include_bytes!("../../res/ethereum/mcip3_test.json")) } @@ -168,6 +171,9 @@ pub fn new_byzantium_test_machine() -> EthereumMachine { load_machine(include_by /// Create a new Foundation Constantinople era spec. pub fn new_constantinople_test_machine() -> EthereumMachine { load_machine(include_bytes!("../../res/ethereum/constantinople_test.json")) } +/// Create a new Foundation St. Peter's (Contantinople Fix) era spec. +pub fn new_constantinople_fix_test_machine() -> EthereumMachine { load_machine(include_bytes!("../../res/ethereum/st_peters_test.json")) } + /// Create a new Musicoin-MCIP3-era spec. pub fn new_mcip3_test_machine() -> EthereumMachine { load_machine(include_bytes!("../../res/ethereum/mcip3_test.json")) } diff --git a/ethcore/src/json_tests/state.rs b/ethcore/src/json_tests/state.rs index 45d9c035f6..33fc6d522d 100644 --- a/ethcore/src/json_tests/state.rs +++ b/ethcore/src/json_tests/state.rs @@ -165,6 +165,7 @@ mod state_tests { declare_test!{GeneralStateTest_stRefundTest, "GeneralStateTests/stRefundTest/"} declare_test!{GeneralStateTest_stReturnDataTest, "GeneralStateTests/stReturnDataTest/"} declare_test!{GeneralStateTest_stRevertTest, "GeneralStateTests/stRevertTest/"} + declare_test!{GeneralStateTest_stSStoreTest, "GeneralStateTests/stSStoreTest/"} declare_test!{GeneralStateTest_stShift, "GeneralStateTests/stShift/"} declare_test!{GeneralStateTest_stSolidityTest, "GeneralStateTests/stSolidityTest/"} declare_test!{GeneralStateTest_stSpecialTest, "GeneralStateTests/stSpecialTest/"} @@ -177,7 +178,6 @@ mod state_tests { declare_test!{GeneralStateTest_stZeroCallsRevert, "GeneralStateTests/stZeroCallsRevert/"} declare_test!{GeneralStateTest_stZeroCallsTest, "GeneralStateTests/stZeroCallsTest/"} declare_test!{GeneralStateTest_stZeroKnowledge, "GeneralStateTests/stZeroKnowledge/"} - declare_test!{GeneralStateTest_stSStoreTest, "GeneralStateTests/stSStoreTest/"} // Attempts to send a transaction that requires more than current balance: // Tx: diff --git a/json/src/spec/spec.rs b/json/src/spec/spec.rs index f8f1217b47..68824cad99 100644 --- a/json/src/spec/spec.rs +++ b/json/src/spec/spec.rs @@ -30,6 +30,7 @@ pub enum ForkSpec { Homestead, Byzantium, Constantinople, + ConstantinopleFix, EIP158ToByzantiumAt5, FrontierToHomesteadAt5, HomesteadToDaoAt5, From 8e866ee5512cad7e733c42b7b8dfad87a5482a69 Mon Sep 17 00:00:00 2001 From: Hernando Castano Date: Mon, 11 Feb 2019 18:08:12 +0100 Subject: [PATCH 062/168] Revive parity_setMinGasPrice RPC call (#10294) * Add function to update minimum gas price * Update TestMinerService to handle min_gas_price changes * Place minimum gas price test behind feature flag * Update check for fixed gas pricer to be more explicit * Use errors::unsupported instead of errors::request_rejected * Add test that fails to set minimum gas price * Fix test that should fail when setting new gas price * Put dev dependencies behind feature flag * Fix deadlock in set_minimal_gas_price() * Update RPC tests with mocked error response * Remove unnecessary cfg flag * Remove duplicate crate imports --- Cargo.lock | 2 + ethcore/Cargo.toml | 2 + ethcore/src/lib.rs | 6 ++ ethcore/src/miner/miner.rs | 82 +++++++++++++++++++++++ ethcore/src/miner/mod.rs | 4 ++ miner/src/gas_pricer.rs | 2 +- rpc/src/v1/impls/parity_set.rs | 8 ++- rpc/src/v1/tests/helpers/miner_service.rs | 17 +++++ rpc/src/v1/tests/mocked/parity_set.rs | 20 +++++- 9 files changed, 138 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1868d889c2..6e1f6bbc9c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -707,6 +707,7 @@ dependencies = [ "ethjson 0.1.0", "ethkey 0.3.0", "evm 0.1.0", + "fetch 0.1.0", "hashdb 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.4.2 (git+https://github.com/cheme/heapsize.git?branch=ec-macfix)", "itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", @@ -728,6 +729,7 @@ dependencies = [ "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-crypto 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-machine 0.1.0", + "parity-runtime 0.1.0", "parity-snappy 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "patricia-trie 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/ethcore/Cargo.toml b/ethcore/Cargo.toml index bd030c174d..b617498443 100644 --- a/ethcore/Cargo.toml +++ b/ethcore/Cargo.toml @@ -76,7 +76,9 @@ blooms-db = { path = "../util/blooms-db" } criterion = "0.2" env_logger = "0.5" ethcore-accounts = { path = "../accounts" } +fetch = { path = "../util/fetch" } kvdb-rocksdb = "0.1.3" +parity-runtime = { path = "../util/runtime" } rlp_compress = { path = "../util/rlp-compress" } tempdir = "0.3" trie-standardmap = "0.1" diff --git a/ethcore/src/lib.rs b/ethcore/src/lib.rs index 633254683e..0fe2e0db19 100644 --- a/ethcore/src/lib.rs +++ b/ethcore/src/lib.rs @@ -143,6 +143,12 @@ extern crate serde_derive; #[cfg_attr(test, macro_use)] extern crate evm; +#[cfg(all(test, feature = "price-info"))] +extern crate fetch; + +#[cfg(all(test, feature = "price-info"))] +extern crate parity_runtime; + pub mod block; pub mod builtin; pub mod client; diff --git a/ethcore/src/miner/miner.rs b/ethcore/src/miner/miner.rs index 82e0e4bb0b..7d6bcbe496 100644 --- a/ethcore/src/miner/miner.rs +++ b/ethcore/src/miner/miner.rs @@ -873,6 +873,32 @@ impl miner::MinerService for Miner { self.params.read().gas_range_target.0 / 5 } + fn set_minimal_gas_price(&self, new_price: U256) -> Result { + match *self.gas_pricer.lock() { + // Binding the gas pricer to `gp` here to prevent + // a deadlock when calling recalibrate() + ref mut gp @ GasPricer::Fixed(_) => { + trace!(target: "miner", "minimal_gas_price: recalibrating fixed..."); + *gp = GasPricer::new_fixed(new_price); + + let txq = self.transaction_queue.clone(); + let mut options = self.options.pool_verification_options.clone(); + gp.recalibrate(move |gas_price| { + debug!(target: "miner", "minimal_gas_price: Got gas price! {}", gas_price); + options.minimal_gas_price = gas_price; + txq.set_verifier_options(options); + }); + + Ok(true) + }, + #[cfg(feature = "price-info")] + GasPricer::Calibrated(_) => { + let error_msg = "Can't update fixed gas price while automatic gas calibration is enabled."; + return Err(error_msg); + }, + } + } + fn import_external_transactions( &self, chain: &C, @@ -1654,4 +1680,60 @@ mod tests { assert!(miner.is_currently_sealing()); } + + #[test] + fn should_set_new_minimum_gas_price() { + // Creates a new GasPricer::Fixed behind the scenes + let miner = Miner::new_for_tests(&Spec::new_test(), None); + + let expected_minimum_gas_price: U256 = 0x1337.into(); + miner.set_minimal_gas_price(expected_minimum_gas_price).unwrap(); + + let txq_options = miner.transaction_queue.status().options; + let current_minimum_gas_price = txq_options.minimal_gas_price; + + assert!(current_minimum_gas_price == expected_minimum_gas_price); + } + + #[cfg(feature = "price-info")] + fn dynamic_gas_pricer() -> GasPricer { + use std::time::Duration; + use parity_runtime::Executor; + use fetch::Client as FetchClient; + use ethcore_miner::gas_price_calibrator::{GasPriceCalibrator, GasPriceCalibratorOptions}; + + // Don't really care about any of these settings since + // the gas pricer is never actually going to be used + let fetch = FetchClient::new(1).unwrap(); + let p = Executor::new_sync(); + + GasPricer::new_calibrated( + GasPriceCalibrator::new( + GasPriceCalibratorOptions { + usd_per_tx: 0.0, + recalibration_period: Duration::from_secs(0), + }, + fetch, + p, + ) + ) + } + + #[test] + #[cfg(feature = "price-info")] + fn should_fail_to_set_new_minimum_gas_price() { + // We get a fixed gas pricer by default, need to change that + let miner = Miner::new_for_tests(&Spec::new_test(), None); + let calibrated_gas_pricer = dynamic_gas_pricer(); + *miner.gas_pricer.lock() = calibrated_gas_pricer; + + let expected_minimum_gas_price: U256 = 0x1337.into(); + let result = miner.set_minimal_gas_price(expected_minimum_gas_price); + assert!(result.is_err()); + + let received_error_msg = result.unwrap_err(); + let expected_error_msg = "Can't update fixed gas price while automatic gas calibration is enabled."; + + assert!(received_error_msg == expected_error_msg); + } } diff --git a/ethcore/src/miner/mod.rs b/ethcore/src/miner/mod.rs index 5156b60401..fd7ab96513 100644 --- a/ethcore/src/miner/mod.rs +++ b/ethcore/src/miner/mod.rs @@ -205,4 +205,8 @@ pub trait MinerService : Send + Sync { /// Suggested gas limit. fn sensible_gas_limit(&self) -> U256; + + /// Set a new minimum gas limit. + /// Will not work if dynamic gas calibration is set. + fn set_minimal_gas_price(&self, gas_price: U256) -> Result; } diff --git a/miner/src/gas_pricer.rs b/miner/src/gas_pricer.rs index 0f851a9f86..c4e04442f1 100644 --- a/miner/src/gas_pricer.rs +++ b/miner/src/gas_pricer.rs @@ -45,7 +45,7 @@ impl GasPricer { /// Recalibrate current gas price. pub fn recalibrate(&mut self, set_price: F) { match *self { - GasPricer::Fixed(ref max) => set_price(max.clone()), + GasPricer::Fixed(ref curr) => set_price(curr.clone()), #[cfg(feature = "price-info")] GasPricer::Calibrated(ref mut cal) => cal.recalibrate(set_price), } diff --git a/rpc/src/v1/impls/parity_set.rs b/rpc/src/v1/impls/parity_set.rs index fc839d621a..3e0d269745 100644 --- a/rpc/src/v1/impls/parity_set.rs +++ b/rpc/src/v1/impls/parity_set.rs @@ -118,9 +118,11 @@ impl ParitySet for ParitySetClient where F: Fetch + 'static, { - fn set_min_gas_price(&self, _gas_price: U256) -> Result { - warn!("setMinGasPrice is deprecated. Ignoring request."); - Ok(false) + fn set_min_gas_price(&self, gas_price: U256) -> Result { + match self.miner.set_minimal_gas_price(gas_price.into()) { + Ok(success) => Ok(success), + Err(e) => Err(errors::unsupported(e, None)), + } } fn set_transactions_limit(&self, _limit: usize) -> Result { diff --git a/rpc/src/v1/tests/helpers/miner_service.rs b/rpc/src/v1/tests/helpers/miner_service.rs index f9b649fa62..77618c8532 100644 --- a/rpc/src/v1/tests/helpers/miner_service.rs +++ b/rpc/src/v1/tests/helpers/miner_service.rs @@ -49,6 +49,8 @@ pub struct TestMinerService { pub pending_receipts: Mutex>, /// Next nonces. pub next_nonces: RwLock>, + /// Minimum gas price + pub min_gas_price: RwLock>, /// Signer (if any) pub signer: RwLock>>, @@ -63,6 +65,7 @@ impl Default for TestMinerService { local_transactions: Default::default(), pending_receipts: Default::default(), next_nonces: Default::default(), + min_gas_price: RwLock::new(Some(0.into())), authoring_params: RwLock::new(AuthoringParams { author: Address::zero(), gas_range_target: (12345.into(), 54321.into()), @@ -279,4 +282,18 @@ impl MinerService for TestMinerService { fn sensible_gas_limit(&self) -> U256 { 0x5208.into() } + + fn set_minimal_gas_price(&self, gas_price: U256) -> Result { + let mut new_price = self.min_gas_price.write(); + match *new_price { + Some(ref mut v) => { + *v = gas_price; + Ok(true) + }, + None => { + let error_msg = "Can't update fixed gas price while automatic gas calibration is enabled."; + Err(error_msg) + }, + } + } } diff --git a/rpc/src/v1/tests/mocked/parity_set.rs b/rpc/src/v1/tests/mocked/parity_set.rs index 13473fbdf8..25c13fb1cb 100644 --- a/rpc/src/v1/tests/mocked/parity_set.rs +++ b/rpc/src/v1/tests/mocked/parity_set.rs @@ -112,7 +112,25 @@ fn rpc_parity_set_min_gas_price() { io.extend_with(parity_set_client(&client, &miner, &updater, &network).to_delegate()); let request = r#"{"jsonrpc": "2.0", "method": "parity_setMinGasPrice", "params":["0xcd1722f3947def4cf144679da39c4c32bdc35681"], "id": 1}"#; - let response = r#"{"jsonrpc":"2.0","result":false,"id":1}"#; + let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#; + + assert_eq!(io.handle_request_sync(request), Some(response.to_owned())); +} + +#[test] +fn rpc_parity_set_min_gas_price_with_automated_calibration_enabled() { + let miner = miner_service(); + *miner.min_gas_price.write() = None; + + let client = client_service(); + let network = network_service(); + let updater = updater_service(); + + let mut io = IoHandler::new(); + io.extend_with(parity_set_client(&client, &miner, &updater, &network).to_delegate()); + + let request = r#"{"jsonrpc": "2.0", "method": "parity_setMinGasPrice", "params":["0xdeadbeef"], "id": 1}"#; + let response = r#"{"jsonrpc":"2.0","error":{"code":-32000,"message":"Can't update fixed gas price while automatic gas calibration is enabled."},"id":1}"#; assert_eq!(io.handle_request_sync(request), Some(response.to_owned())); } From d89b8d904ff28382d3692290a936706304627255 Mon Sep 17 00:00:00 2001 From: cheme Date: Mon, 11 Feb 2019 23:20:51 +0100 Subject: [PATCH 063/168] Additional error for invalid gas (#10327) * Tag sensible place (ECHECH) * Additional overflows checks. --- ethcore/evm/src/interpreter/mod.rs | 4 ++-- ethcore/light/src/transaction_queue.rs | 4 ++-- ethcore/src/executive.rs | 14 +++++++++----- ethcore/src/state/account.rs | 4 ++-- ethcore/src/state/mod.rs | 7 ++++++- miner/src/pool/queue.rs | 2 +- miner/src/pool/ready.rs | 4 ++-- miner/src/pool/verifier.rs | 14 +++++++++++++- 8 files changed, 37 insertions(+), 16 deletions(-) diff --git a/ethcore/evm/src/interpreter/mod.rs b/ethcore/evm/src/interpreter/mod.rs index bd47c7ed71..d699e61cbe 100644 --- a/ethcore/evm/src/interpreter/mod.rs +++ b/ethcore/evm/src/interpreter/mod.rs @@ -571,10 +571,10 @@ impl Interpreter { let out_size = self.stack.pop_back(); // Add stipend (only CALL|CALLCODE when value > 0) - let call_gas = call_gas + value.map_or_else(|| Cost::from(0), |val| match val.is_zero() { + let call_gas = call_gas.overflow_add(value.map_or_else(|| Cost::from(0), |val| match val.is_zero() { false => Cost::from(ext.schedule().call_stipend), true => Cost::from(0), - }); + })).0; // Get sender & receive addresses, check if we have balance let (sender_address, receive_address, has_balance, call_type) = match instruction { diff --git a/ethcore/light/src/transaction_queue.rs b/ethcore/light/src/transaction_queue.rs index 53359368da..65e646d846 100644 --- a/ethcore/light/src/transaction_queue.rs +++ b/ethcore/light/src/transaction_queue.rs @@ -95,7 +95,7 @@ impl AccountTransactions { } fn next_nonce(&self) -> U256 { - self.current.last().map(|last| last.nonce + 1) + self.current.last().map(|last| last.nonce.saturating_add(1.into())) .unwrap_or_else(|| *self.cur_nonce.value()) } @@ -107,7 +107,7 @@ impl AccountTransactions { while let Some(tx) = self.future.remove(&next_nonce) { promoted.push(tx.hash); self.current.push(tx); - next_nonce = next_nonce + 1; + next_nonce = next_nonce.saturating_add(1.into()); } promoted diff --git a/ethcore/src/executive.rs b/ethcore/src/executive.rs index 97758994a1..68d4edc794 100644 --- a/ethcore/src/executive.rs +++ b/ethcore/src/executive.rs @@ -312,7 +312,7 @@ impl<'a> CallCreateExecutive<'a> { let prev_bal = state.balance(¶ms.address)?; if let ActionValue::Transfer(val) = params.value { state.sub_balance(¶ms.sender, &val, &mut substate.to_cleanup_mode(&schedule))?; - state.new_contract(¶ms.address, val + prev_bal, nonce_offset)?; + state.new_contract(¶ms.address, val.saturating_add(prev_bal), nonce_offset)?; } else { state.new_contract(¶ms.address, prev_bal, nonce_offset)?; } @@ -1103,9 +1103,13 @@ impl<'a, B: 'a + StateBackend> Executive<'a, B> { let refunded = cmp::min(refunds_bound, (t.gas - gas_left_prerefund) >> 1); let gas_left = gas_left_prerefund + refunded; - let gas_used = t.gas - gas_left; - let refund_value = gas_left * t.gas_price; - let fees_value = gas_used * t.gas_price; + let gas_used = t.gas.saturating_sub(gas_left); + let (refund_value, overflow_1) = gas_left.overflowing_mul(t.gas_price); + let (fees_value, overflow_2) = gas_used.overflowing_mul(t.gas_price); + if overflow_1 || overflow_2 { + return Err(ExecutionError::TransactionMalformed("U256 Overflow".to_string())); + } + trace!("exec::finalize: t.gas={}, sstore_refunds={}, suicide_refunds={}, refunds_bound={}, gas_left_prerefund={}, refunded={}, gas_left={}, gas_used={}, refund_value={}, fees_value={}\n", t.gas, sstore_refunds, suicide_refunds, refunds_bound, gas_left_prerefund, refunded, gas_left, gas_used, refund_value, fees_value); @@ -1123,7 +1127,7 @@ impl<'a, B: 'a + StateBackend> Executive<'a, B> { } // perform garbage-collection - let min_balance = if schedule.kill_dust != CleanDustMode::Off { Some(U256::from(schedule.tx_gas) * t.gas_price) } else { None }; + let min_balance = if schedule.kill_dust != CleanDustMode::Off { Some(U256::from(schedule.tx_gas).overflowing_mul(t.gas_price).0) } else { None }; self.state.kill_garbage(&substate.touched, schedule.kill_empty, &min_balance, schedule.kill_dust == CleanDustMode::WithCodeAndStorage)?; match result { diff --git a/ethcore/src/state/account.rs b/ethcore/src/state/account.rs index e4553b906f..483df7ba19 100644 --- a/ethcore/src/state/account.rs +++ b/ethcore/src/state/account.rs @@ -466,12 +466,12 @@ impl Account { /// Increment the nonce of the account by one. pub fn inc_nonce(&mut self) { - self.nonce = self.nonce + U256::from(1u8); + self.nonce = self.nonce.saturating_add(U256::from(1u8)); } /// Increase account balance. pub fn add_balance(&mut self, x: &U256) { - self.balance = self.balance + *x; + self.balance = self.balance.saturating_add(*x); } /// Decrease account balance. diff --git a/ethcore/src/state/mod.rs b/ethcore/src/state/mod.rs index 4d24a1b157..8cc06fa83c 100644 --- a/ethcore/src/state/mod.rs +++ b/ethcore/src/state/mod.rs @@ -500,7 +500,12 @@ impl State { /// it will have its code reset, ready for `init_code()`. pub fn new_contract(&mut self, contract: &Address, balance: U256, nonce_offset: U256) -> TrieResult<()> { let original_storage_root = self.original_storage_root(contract)?; - self.insert_cache(contract, AccountEntry::new_dirty(Some(Account::new_contract(balance, self.account_start_nonce + nonce_offset, original_storage_root)))); + let (nonce, overflow) = self.account_start_nonce.overflowing_add(nonce_offset); + if overflow { + return Err(Box::new(TrieError::DecoderError(H256::from(contract), + rlp::DecoderError::Custom("Nonce overflow".into())))); + } + self.insert_cache(contract, AccountEntry::new_dirty(Some(Account::new_contract(balance, nonce, original_storage_root)))); Ok(()) } diff --git a/miner/src/pool/queue.rs b/miner/src/pool/queue.rs index 22278c3e85..51c46ad823 100644 --- a/miner/src/pool/queue.rs +++ b/miner/src/pool/queue.rs @@ -474,7 +474,7 @@ impl TransactionQueue { self.pool.read().pending_from_sender(state_readiness, address) .last() - .map(|tx| tx.signed().nonce + 1) + .map(|tx| tx.signed().nonce.saturating_add(U256::from(1))) } /// Retrieve a transaction from the pool. diff --git a/miner/src/pool/ready.rs b/miner/src/pool/ready.rs index 20507186e7..3accba1390 100644 --- a/miner/src/pool/ready.rs +++ b/miner/src/pool/ready.rs @@ -95,7 +95,7 @@ impl txpool::Ready for State { }, cmp::Ordering::Less => txpool::Readiness::Stale, cmp::Ordering::Equal => { - *nonce = *nonce + 1; + *nonce = nonce.saturating_add(U256::from(1)); txpool::Readiness::Ready }, } @@ -159,7 +159,7 @@ impl Option> txpool::Ready for Opt cmp::Ordering::Greater => txpool::Readiness::Future, cmp::Ordering::Less => txpool::Readiness::Stale, cmp::Ordering::Equal => { - *nonce = *nonce + 1; + *nonce = nonce.saturating_add(U256::from(1)); txpool::Readiness::Ready }, } diff --git a/miner/src/pool/verifier.rs b/miner/src/pool/verifier.rs index 65835230d8..1fded37630 100644 --- a/miner/src/pool/verifier.rs +++ b/miner/src/pool/verifier.rs @@ -283,7 +283,19 @@ impl txpool::Verifier for Verifier Date: Tue, 12 Feb 2019 15:16:23 +0100 Subject: [PATCH 064/168] fix(add helper for timestamp overflows) (#10330) * fix(add helper timestamp overflows) * fix(simplify code) * fix(make helper private) --- ethcore/src/error.rs | 3 ++ ethcore/src/verification/verification.rs | 35 +++++++++++++++++++++--- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/ethcore/src/error.rs b/ethcore/src/error.rs index 2984dcdea8..32cfe057a0 100644 --- a/ethcore/src/error.rs +++ b/ethcore/src/error.rs @@ -89,6 +89,8 @@ pub enum BlockError { InvalidNumber(Mismatch), /// Block number isn't sensible. RidiculousNumber(OutOfBounds), + /// Timestamp header overflowed + TimestampOverflow, /// Too many transactions from a particular address. TooManyTransactions(Address), /// Parent given is unknown. @@ -138,6 +140,7 @@ impl fmt::Display for BlockError { UnknownParent(ref hash) => format!("Unknown parent: {}", hash), UnknownUncleParent(ref hash) => format!("Unknown uncle parent: {}", hash), UnknownEpochTransition(ref num) => format!("Unknown transition to epoch number: {}", num), + TimestampOverflow => format!("Timestamp overflow"), TooManyTransactions(ref address) => format!("Too many transactions from: {}", address), }; diff --git a/ethcore/src/verification/verification.rs b/ethcore/src/verification/verification.rs index 827b714391..3f5008a2b8 100644 --- a/ethcore/src/verification/verification.rs +++ b/ethcore/src/verification/verification.rs @@ -40,6 +40,25 @@ use types::{BlockNumber, header::Header}; use types::transaction::SignedTransaction; use verification::queue::kind::blocks::Unverified; + +/// Returns `Ok` when the result less or equal to `i32::max_value` to prevent `SystemTime` to panic because +/// it is platform specific, may be i32 or i64. +/// +/// `Err Result { + let d1 = sys.duration_since(UNIX_EPOCH).map_err(|_| BlockError::TimestampOverflow)?; + let total_time = d1.checked_add(d2).ok_or(BlockError::TimestampOverflow)?; + + if total_time.as_secs() <= i32::max_value() as u64 { + Ok(sys + d2) + } else { + Err(BlockError::TimestampOverflow) + } +} + /// Preprocessed block data gathered in `verify_block_unordered` call pub struct PreverifiedBlock { /// Populated block header @@ -306,7 +325,7 @@ pub fn verify_header_params(header: &Header, engine: &EthEngine, is_full: bool, const ACCEPTABLE_DRIFT: Duration = Duration::from_secs(15); let max_time = SystemTime::now() + ACCEPTABLE_DRIFT; let invalid_threshold = max_time + ACCEPTABLE_DRIFT * 9; - let timestamp = UNIX_EPOCH + Duration::from_secs(header.timestamp()); + let timestamp = timestamp_checked_add(UNIX_EPOCH, Duration::from_secs(header.timestamp()))?; if timestamp > invalid_threshold { return Err(From::from(BlockError::InvalidTimestamp(OutOfBounds { max: Some(max_time), min: None, found: timestamp }))) @@ -328,8 +347,8 @@ fn verify_parent(header: &Header, parent: &Header, engine: &EthEngine) -> Result let gas_limit_divisor = engine.params().gas_limit_bound_divisor; if !engine.is_timestamp_valid(header.timestamp(), parent.timestamp()) { - let min = SystemTime::now() + Duration::from_secs(parent.timestamp() + 1); - let found = SystemTime::now() + Duration::from_secs(header.timestamp()); + let min = timestamp_checked_add(SystemTime::now(), Duration::from_secs(parent.timestamp().saturating_add(1)))?; + let found = timestamp_checked_add(SystemTime::now(), Duration::from_secs(header.timestamp()))?; return Err(From::from(BlockError::InvalidTimestamp(OutOfBounds { max: None, min: Some(min), found }))) } if header.number() != parent.number() + 1 { @@ -743,7 +762,8 @@ mod tests { check_fail_timestamp(family_test(&create_test_block_with_data(&header, &good_transactions, &good_uncles), engine, &bc), false); header = good.clone(); - header.set_timestamp(2450000000); + // will return `BlockError::TimestampOverflow` when timestamp > `i32::max_value()` + header.set_timestamp(i32::max_value() as u64); check_fail_timestamp(basic_test(&create_test_block_with_data(&header, &good_transactions, &good_uncles), engine), false); header = good.clone(); @@ -815,4 +835,11 @@ mod tests { check_fail(unordered_test(&create_test_block_with_data(&header, &bad_transactions, &[]), &engine), TooManyTransactions(keypair.address())); unordered_test(&create_test_block_with_data(&header, &good_transactions, &[]), &engine).unwrap(); } + + #[test] + fn checked_add_systime_dur() { + assert!(timestamp_checked_add(UNIX_EPOCH, Duration::new(i32::max_value() as u64 + 1, 0)).is_err()); + assert!(timestamp_checked_add(UNIX_EPOCH, Duration::new(i32::max_value() as u64, 0)).is_ok()); + assert!(timestamp_checked_add(UNIX_EPOCH, Duration::new(i32::max_value() as u64 - 1, 1_000_000_000)).is_ok()); + } } From a4dc85543bba19d3f1e6adda91b2302b2860f36e Mon Sep 17 00:00:00 2001 From: TriplEight Date: Tue, 12 Feb 2019 15:37:54 +0100 Subject: [PATCH 065/168] snap: official image / test (#10168) * official image / test * fix / test * bit more necromancy * fix paths * add source bin/df /test * add source bin/df /test2 * something w paths /test * something w paths /test * add source-type /test * show paths /test * copy plugin /test * plugin -> nil * install rhash * no questions while installing rhash * publish snap only for release --- .gitlab-ci.yml | 4 ++-- scripts/gitlab/publish-snap.sh | 14 +++++++++++++- scripts/snap/snapcraft.template.yaml | 6 +----- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 1d0b934a25..2b1162d651 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -103,9 +103,9 @@ publish-docker: - scripts/gitlab/publish-docker.sh parity publish-snap: - stage: publish + stage: optional #publish only: *releaseable_branches - image: parity/snapcraft:gitlab-ci + image: snapcore/snapcraft variables: BUILD_ARCH: amd64 cache: {} diff --git a/scripts/gitlab/publish-snap.sh b/scripts/gitlab/publish-snap.sh index f001bbff0d..386abdf370 100755 --- a/scripts/gitlab/publish-snap.sh +++ b/scripts/gitlab/publish-snap.sh @@ -21,7 +21,19 @@ SNAP_PACKAGE="parity_"$VERSION"_"$BUILD_ARCH".snap" echo "__________Create snap package__________" echo "Release channel :" $GRADE " Branch/tag: " $CI_COMMIT_REF_NAME echo $VERSION:$GRADE:$BUILD_ARCH -cat scripts/snap/snapcraft.template.yaml | envsubst '$VERSION:$GRADE:$BUILD_ARCH:$CARGO_TARGET' > snapcraft.yaml +# cat scripts/snap/snapcraft.template.yaml | envsubst '$VERSION:$GRADE:$BUILD_ARCH:$CARGO_TARGET' > snapcraft.yaml +# a bit more necromancy (substitutions): +pwd +cd /builds/$CI_PROJECT_PATH/scripts/snap/ +sed -e 's/$VERSION/'"$VERSION"'/g' \ + -e 's/$GRADE/'"$GRADE"'/g' \ + -e 's/$BUILD_ARCH/'"$BUILD_ARCH"'/g' \ + -e 's/$CARGO_TARGET/'"$CARGO_TARGET"'/g' \ + snapcraft.template.yaml > /builds/$CI_PROJECT_PATH/snapcraft.yaml +cd /builds/$CI_PROJECT_PATH +pwd +apt update +apt install -y --no-install-recommends rhash cat snapcraft.yaml snapcraft --target-arch=$BUILD_ARCH ls *.snap diff --git a/scripts/snap/snapcraft.template.yaml b/scripts/snap/snapcraft.template.yaml index eb67ba1282..d170241dbe 100644 --- a/scripts/snap/snapcraft.template.yaml +++ b/scripts/snap/snapcraft.template.yaml @@ -50,8 +50,4 @@ parts: cp -v ethkey $SNAPCRAFT_PART_INSTALL/usr/bin/ethkey cp -v ethstore $SNAPCRAFT_PART_INSTALL/usr/bin/ethstore cp -v whisper $SNAPCRAFT_PART_INSTALL/usr/bin/whisper - stage-packages: [libc6, libudev1, libstdc++6, cmake, libdb] - df: - plugin: nil - stage-packages: [coreutils] - stage: [bin/df] + stage-packages: [libc6, libudev1, libstdc++6, cmake, libdb5.3] From 55454b2f2df450590d611443d8390e5645623f59 Mon Sep 17 00:00:00 2001 From: Shude Li Date: Tue, 12 Feb 2019 23:57:07 +0800 Subject: [PATCH 066/168] fix(docker): fix not receives SIGINT (#10059) * fix(docker): fix not receives SIGINT * fix: update with reviews * update with review * update * update --- scripts/docker/hub/Dockerfile | 29 +++++++++++------------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/scripts/docker/hub/Dockerfile b/scripts/docker/hub/Dockerfile index d40a662111..e402859527 100644 --- a/scripts/docker/hub/Dockerfile +++ b/scripts/docker/hub/Dockerfile @@ -1,8 +1,5 @@ FROM ubuntu:xenial -MAINTAINER Parity Technologies -#set ENVIROMENT -ARG TARGET -ENV TARGET ${TARGET} +LABEL MAINTAINER="Parity Technologies devops-team@parity.io" # install tools and dependencies RUN apt update && apt install -y --no-install-recommends openssl libudev-dev file curl jq @@ -10,27 +7,23 @@ RUN apt update && apt install -y --no-install-recommends openssl libudev-dev fil # show backtraces ENV RUST_BACKTRACE 1 -#cleanup Docker image -RUN apt autoremove -y -RUN apt clean -y -RUN rm -rf /tmp/* /var/tmp/* /var/lib/apt/lists/* +# cleanup Docker image +RUN apt autoremove -y \ + && apt clean -y \ + && rm -rf /tmp/* /var/tmp/* /var/lib/apt/lists/* RUN groupadd -g 1000 parity \ && useradd -m -u 1000 -g parity -s /bin/sh parity - -#add TARGET to docker image -COPY artifacts/x86_64-unknown-linux-gnu/$TARGET /bin/$TARGET - -# Build a shell script because the ENTRYPOINT command doesn't like using ENV -RUN echo "#!/bin/bash \n ${TARGET} \$@" > ./entrypoint.sh -RUN chmod +x ./entrypoint.sh - +# add parity to docker image +COPY artifacts/x86_64-unknown-linux-gnu/parity /bin/parity +RUN echo "#!/bin/bash \n /bin/parity \$@" > ./entrypoint.sh COPY scripts/docker/hub/check_sync.sh /check_sync.sh # switch to user parity here USER parity -# setup ENTRYPOINT +VOLUME [ "/home/parity/.local/share/io.parity.ethereum" ] EXPOSE 5001 8080 8082 8083 8545 8546 8180 30303/tcp 30303/udp -ENTRYPOINT ["./entrypoint.sh"] +# setup ENTRYPOINT +ENTRYPOINT ["/bin/parity"] From 5be0163cdead589bbe1f03d1473bc23e33d4596d Mon Sep 17 00:00:00 2001 From: Kirill Pimenov Date: Tue, 12 Feb 2019 15:57:53 +0000 Subject: [PATCH 067/168] Don't add discovery initiators to the node table (#10305) * Don't add discovery initiators to the node table * Use enums for tracking state of the nodes in discovery * Dont try to ping ourselves * Fix minor nits * Update timeouts when observing an outdated node * Extracted update_bucket_record from update_node * Fixed typo * Fix two final nits from @todr --- Cargo.lock | 1 + util/network-devp2p/Cargo.toml | 1 + util/network-devp2p/src/discovery.rs | 138 ++++++++++++++++++++------- util/network-devp2p/src/lib.rs | 1 + 4 files changed, 107 insertions(+), 34 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6e1f6bbc9c..5eef2e2768 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -971,6 +971,7 @@ dependencies = [ "keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "lru-cache 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-crypto 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/util/network-devp2p/Cargo.toml b/util/network-devp2p/Cargo.toml index 5f1a5d3397..8bf402e206 100644 --- a/util/network-devp2p/Cargo.toml +++ b/util/network-devp2p/Cargo.toml @@ -34,6 +34,7 @@ serde = "1.0" serde_json = "1.0" serde_derive = "1.0" error-chain = { version = "0.12", default-features = false } +lru-cache = "0.1" [dev-dependencies] env_logger = "0.5" diff --git a/util/network-devp2p/src/discovery.rs b/util/network-devp2p/src/discovery.rs index f6eaf494b9..7bf8dc62e5 100644 --- a/util/network-devp2p/src/discovery.rs +++ b/util/network-devp2p/src/discovery.rs @@ -20,6 +20,7 @@ use std::collections::{HashSet, HashMap, VecDeque}; use std::collections::hash_map::Entry; use std::default::Default; use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH}; +use lru_cache::LruCache; use hash::keccak; use ethereum_types::{H256, H520}; use rlp::{Rlp, RlpStream}; @@ -55,6 +56,8 @@ const REQUEST_BACKOFF: [Duration; 4] = [ const NODE_LAST_SEEN_TIMEOUT: Duration = Duration::from_secs(24*60*60); +const OBSERVED_NODES_MAX_SIZE: usize = 10_000; + #[derive(Clone, Debug)] pub struct NodeEntry { pub id: NodeId, @@ -95,7 +98,27 @@ struct FindNodeRequest { #[derive(Clone, Copy)] enum PingReason { Default, - FromDiscoveryRequest(NodeId) + FromDiscoveryRequest(NodeId, NodeValidity), +} + +#[derive(Clone, Copy, PartialEq)] +enum NodeCategory { + Bucket, + Observed +} + +#[derive(Clone, Copy, PartialEq)] +enum NodeValidity { + Ourselves, + ValidNode(NodeCategory), + ExpiredNode(NodeCategory), + UnknownNode +} + +#[derive(Debug)] +enum BucketError { + Ourselves, + NotInTheBucket{node_entry: NodeEntry, bucket_distance: usize}, } struct PingRequest { @@ -145,6 +168,12 @@ pub struct Discovery<'a> { discovery_id: NodeId, discovery_nodes: HashSet, node_buckets: Vec, + + // Sometimes we don't want to add nodes to the NodeTable, but still want to + // keep track of them to avoid excessive pinging (happens when an unknown node sends + // a discovery request to us -- the node might be on a different net). + other_observed_nodes: LruCache, + in_flight_pings: HashMap, in_flight_find_nodes: HashMap, send_queue: VecDeque, @@ -171,6 +200,7 @@ impl<'a> Discovery<'a> { discovery_id: NodeId::new(), discovery_nodes: HashSet::new(), node_buckets: (0..ADDRESS_BITS).map(|_| NodeBucket::new()).collect(), + other_observed_nodes: LruCache::new(OBSERVED_NODES_MAX_SIZE), in_flight_pings: HashMap::new(), in_flight_find_nodes: HashMap::new(), send_queue: VecDeque::new(), @@ -200,41 +230,53 @@ impl<'a> Discovery<'a> { } } - fn update_node(&mut self, e: NodeEntry) -> Option { - trace!(target: "discovery", "Inserting {:?}", &e); + fn update_bucket_record(&mut self, e: NodeEntry) -> Result<(), BucketError> { let id_hash = keccak(e.id); let dist = match Discovery::distance(&self.id_hash, &id_hash) { Some(dist) => dist, None => { debug!(target: "discovery", "Attempted to update own entry: {:?}", e); - return None; + return Err(BucketError::Ourselves); } }; + let bucket = &mut self.node_buckets[dist]; + bucket.nodes.iter_mut().find(|n| n.address.id == e.id) + .map_or(Err(BucketError::NotInTheBucket{node_entry: e.clone(), bucket_distance: dist}.into()), |entry| { + entry.address = e; + entry.last_seen = Instant::now(); + entry.backoff_until = Instant::now(); + entry.fail_count = 0; + Ok(()) + }) + } - let mut added_map = HashMap::new(); - let ping = { - let bucket = &mut self.node_buckets[dist]; - let updated = if let Some(node) = bucket.nodes.iter_mut().find(|n| n.address.id == e.id) { - node.address = e.clone(); - node.last_seen = Instant::now(); - node.backoff_until = Instant::now(); - node.fail_count = 0; - true - } else { false }; + fn update_node(&mut self, e: NodeEntry) -> Option { + trace!(target: "discovery", "Inserting {:?}", &e); + + match self.update_bucket_record(e) { + Ok(()) => None, + Err(BucketError::Ourselves) => None, + Err(BucketError::NotInTheBucket{node_entry, bucket_distance}) => Some((node_entry, bucket_distance)) + }.map(|(node_entry, bucket_distance)| { + trace!(target: "discovery", "Adding a new node {:?} into our bucket {}", &node_entry, bucket_distance); - if !updated { - added_map.insert(e.id, e.clone()); - bucket.nodes.push_front(BucketEntry::new(e)); + let mut added = HashMap::with_capacity(1); + added.insert(node_entry.id, node_entry.clone()); + let node_to_ping = { + let bucket = &mut self.node_buckets[bucket_distance]; + bucket.nodes.push_front(BucketEntry::new(node_entry)); if bucket.nodes.len() > BUCKET_SIZE { select_bucket_ping(bucket.nodes.iter()) - } else { None } - } else { None } - }; - if let Some(node) = ping { - self.try_ping(node, PingReason::Default); - } - Some(TableUpdates { added: added_map, removed: HashSet::new() }) + } else { + None + } + }; + if let Some(node) = node_to_ping { + self.try_ping(node, PingReason::Default); + }; + TableUpdates{added, removed: HashSet::new()} + }) } /// Starts the discovery process at round 0 @@ -541,10 +583,28 @@ impl<'a> Discovery<'a> { }; if let Some((node, ping_reason)) = expected_node { - if let PingReason::FromDiscoveryRequest(target) = ping_reason { + if let PingReason::FromDiscoveryRequest(target, validity) = ping_reason { self.respond_with_discovery(target, &node)?; + // kirushik: I would prefer to probe the network id of the remote node here, and add it to the nodes list if it's on "our" net -- + // but `on_packet` happens synchronously, so doing the full TCP handshake ceremony here is a bad idea. + // So instead we just LRU-caching most recently seen nodes to avoid unnecessary pinging + match validity { + NodeValidity::ValidNode(NodeCategory::Bucket) | NodeValidity::ExpiredNode(NodeCategory::Bucket) => { + trace!(target: "discovery", "Updating node {:?} in our Kad buckets", &node); + self.update_bucket_record(node).unwrap_or_else(|error| { + debug!(target: "discovery", "Error occured when processing ping from a bucket node: {:?}", &error); + }); + }, + NodeValidity::UnknownNode | NodeValidity::ExpiredNode(NodeCategory::Observed) | NodeValidity::ValidNode(NodeCategory::Observed)=> { + trace!(target: "discovery", "Updating node {:?} in the list of other_observed_nodes", &node); + self.other_observed_nodes.insert(node.id, (node.endpoint, Instant::now())); + }, + NodeValidity::Ourselves => (), + } + Ok(None) + } else { + Ok(self.update_node(node)) } - Ok(self.update_node(node)) } else { debug!(target: "discovery", "Got unexpected Pong from {:?} ; request not found", &from); Ok(None) @@ -565,31 +625,41 @@ impl<'a> Discovery<'a> { } }; - if self.is_a_valid_known_node(&node) { - self.respond_with_discovery(target, &node)?; - } else { + match self.check_validity(&node) { + NodeValidity::Ourselves => (), // It makes no sense to respond to the discovery request from ourselves + NodeValidity::ValidNode(_) => self.respond_with_discovery(target, &node)?, // Make sure the request source is actually there and responds to pings before actually responding - self.try_ping(node, PingReason::FromDiscoveryRequest(target)); + invalidity_reason => self.try_ping(node, PingReason::FromDiscoveryRequest(target, invalidity_reason)) } Ok(None) } - fn is_a_valid_known_node(&self, node: &NodeEntry) -> bool { + fn check_validity(&mut self, node: &NodeEntry) -> NodeValidity { let id_hash = keccak(node.id); let dist = match Discovery::distance(&self.id_hash, &id_hash) { Some(dist) => dist, None => { debug!(target: "discovery", "Got an incoming discovery request from self: {:?}", node); - return false; + return NodeValidity::Ourselves; } }; let bucket = &self.node_buckets[dist]; if let Some(known_node) = bucket.nodes.iter().find(|n| n.address.id == node.id) { debug!(target: "discovery", "Found a known node in a bucket when processing discovery: {:?}/{:?}", known_node, node); - (known_node.address.endpoint == node.endpoint) && (known_node.last_seen.elapsed() < NODE_LAST_SEEN_TIMEOUT) + match ((known_node.address.endpoint == node.endpoint), (known_node.last_seen.elapsed() < NODE_LAST_SEEN_TIMEOUT)) { + (true, true) => NodeValidity::ValidNode(NodeCategory::Bucket), + (true, false) => NodeValidity::ExpiredNode(NodeCategory::Bucket), + _ => NodeValidity::UnknownNode + } } else { - false + self.other_observed_nodes.get_mut(&node.id).map_or(NodeValidity::UnknownNode, |(endpoint, observed_at)| { + match ((node.endpoint==*endpoint), (observed_at.elapsed() < NODE_LAST_SEEN_TIMEOUT)) { + (true, true) => NodeValidity::ValidNode(NodeCategory::Observed), + (true, false) => NodeValidity::ExpiredNode(NodeCategory::Observed), + _ => NodeValidity::UnknownNode + } + }) } } diff --git a/util/network-devp2p/src/lib.rs b/util/network-devp2p/src/lib.rs index 531c6ee506..6082049e89 100644 --- a/util/network-devp2p/src/lib.rs +++ b/util/network-devp2p/src/lib.rs @@ -84,6 +84,7 @@ extern crate keccak_hash as hash; extern crate serde; extern crate serde_json; extern crate parity_snappy as snappy; +extern crate lru_cache; #[macro_use] extern crate error_chain; From a3883ca5d9c70139a8d66918923b79b43138f780 Mon Sep 17 00:00:00 2001 From: gabriel klawitter Date: Tue, 12 Feb 2019 19:00:52 +0100 Subject: [PATCH 068/168] =?UTF-8?q?change=20docker=20image=20based=20on=20?= =?UTF-8?q?debian=20instead=20of=20ubuntu=20due=20to=20the=20chan=E2=80=A6?= =?UTF-8?q?=20(#10336)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * change docker image based on debian instead of ubuntu due to the changes of the build container --- scripts/docker/hub/Dockerfile | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/scripts/docker/hub/Dockerfile b/scripts/docker/hub/Dockerfile index e402859527..cd5b948a3b 100644 --- a/scripts/docker/hub/Dockerfile +++ b/scripts/docker/hub/Dockerfile @@ -1,5 +1,5 @@ -FROM ubuntu:xenial -LABEL MAINTAINER="Parity Technologies devops-team@parity.io" +FROM debian:stretch +LABEL MAINTAINER="Parity Technologies " # install tools and dependencies RUN apt update && apt install -y --no-install-recommends openssl libudev-dev file curl jq @@ -15,9 +15,11 @@ RUN apt autoremove -y \ RUN groupadd -g 1000 parity \ && useradd -m -u 1000 -g parity -s /bin/sh parity -# add parity to docker image +WORKDIR /home/parity + +# add parity-ethereum to docker image COPY artifacts/x86_64-unknown-linux-gnu/parity /bin/parity -RUN echo "#!/bin/bash \n /bin/parity \$@" > ./entrypoint.sh + COPY scripts/docker/hub/check_sync.sh /check_sync.sh # switch to user parity here @@ -25,5 +27,5 @@ USER parity VOLUME [ "/home/parity/.local/share/io.parity.ethereum" ] EXPOSE 5001 8080 8082 8083 8545 8546 8180 30303/tcp 30303/udp -# setup ENTRYPOINT + ENTRYPOINT ["/bin/parity"] From ea589a17a412c0a908f88531c596dd21faebe339 Mon Sep 17 00:00:00 2001 From: gabriel klawitter Date: Tue, 12 Feb 2019 20:52:30 +0100 Subject: [PATCH 069/168] role back docker build image and docker deploy image to ubuntu:xenial based (#10338) --- .gitlab-ci.yml | 2 +- scripts/docker/hub/Dockerfile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 2b1162d651..a4109ad859 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -5,7 +5,7 @@ stages: - publish-onchain - optional -image: parity/rust-parity-ethereum-build:stretch +image: parity/rust:gitlab-ci variables: GIT_STRATEGY: fetch diff --git a/scripts/docker/hub/Dockerfile b/scripts/docker/hub/Dockerfile index cd5b948a3b..c2249a56d4 100644 --- a/scripts/docker/hub/Dockerfile +++ b/scripts/docker/hub/Dockerfile @@ -1,4 +1,4 @@ -FROM debian:stretch +FROM ubuntu:xenial LABEL MAINTAINER="Parity Technologies " # install tools and dependencies From 3adb640d2b121ecb8ee875da729c9473a597e7e1 Mon Sep 17 00:00:00 2001 From: elferdo Date: Wed, 13 Feb 2019 09:20:33 +0100 Subject: [PATCH 070/168] Bundle protocol and packet_id together in chain sync (#10315) Define a new `enum` where devp2p subprotocol packet ids (currently eth and par) are defined. Additionally provide functionality to query id value and protocol of a given id object. --- Cargo.lock | 10 ++ ethcore/sync/Cargo.toml | 1 + ethcore/sync/src/api.rs | 8 +- ethcore/sync/src/chain/handler.rs | 87 ++++++------ ethcore/sync/src/chain/mod.rs | 41 ++---- ethcore/sync/src/chain/propagator.rs | 34 ++--- ethcore/sync/src/chain/requester.rs | 35 ++--- ethcore/sync/src/chain/supplier.rs | 184 ++++++++++++++------------ ethcore/sync/src/chain/sync_packet.rs | 141 ++++++++++++++++++++ ethcore/sync/src/lib.rs | 2 + ethcore/sync/src/sync_io.rs | 7 +- ethcore/sync/src/tests/helpers.rs | 27 ++-- 12 files changed, 369 insertions(+), 208 deletions(-) create mode 100644 ethcore/sync/src/chain/sync_packet.rs diff --git a/Cargo.lock b/Cargo.lock index 5eef2e2768..d4f20132d5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -588,6 +588,14 @@ dependencies = [ "heapsize 0.4.2 (git+https://github.com/cheme/heapsize.git?branch=ec-macfix)", ] +[[package]] +name = "enum_primitive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "env_logger" version = "0.5.13" @@ -1108,6 +1116,7 @@ name = "ethcore-sync" version = "1.12.0" dependencies = [ "common-types 0.1.0", + "enum_primitive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore 1.12.0", "ethcore-io 1.12.0", @@ -4510,6 +4519,7 @@ dependencies = [ "checksum edit-distance 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3bd26878c3d921f89797a4e1a1711919f999a9f6946bb6f5a4ffda126d297b7e" "checksum either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3be565ca5c557d7f59e7cfcf1844f9e3033650c929c6566f511e8005f205c1d0" "checksum elastic-array 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "88d4851b005ef16de812ea9acdb7bece2f0a40dd86c07b85631d7dafa54537bb" +"checksum enum_primitive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "be4551092f4d519593039259a9ed8daedf0da12e5109c5280338073eaeb81180" "checksum env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)" = "15b0a4d2e39f8420210be8b27eeda28029729e2fd4291019455016c348240c38" "checksum error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "07e791d3be96241c77c43846b665ef1384606da2cd2a48730abe606a12906e02" "checksum eth-secp256k1 0.5.7 (git+https://github.com/paritytech/rust-secp256k1)" = "" diff --git a/ethcore/sync/Cargo.toml b/ethcore/sync/Cargo.toml index 37417cd0a3..9db9331626 100644 --- a/ethcore/sync/Cargo.toml +++ b/ethcore/sync/Cargo.toml @@ -9,6 +9,7 @@ authors = ["Parity Technologies "] [dependencies] common-types = { path = "../types" } +enum_primitive = "0.1.1" ethcore = { path = ".." } ethcore-io = { path = "../../util/io" } ethcore-light = { path = "../light" } diff --git a/ethcore/sync/src/api.rs b/ethcore/sync/src/api.rs index cc7a304920..4a66f468d5 100644 --- a/ethcore/sync/src/api.rs +++ b/ethcore/sync/src/api.rs @@ -39,8 +39,8 @@ use std::net::{SocketAddr, AddrParseError}; use std::str::FromStr; use parking_lot::{RwLock, Mutex}; use chain::{ETH_PROTOCOL_VERSION_63, ETH_PROTOCOL_VERSION_62, - PAR_PROTOCOL_VERSION_1, PAR_PROTOCOL_VERSION_2, PAR_PROTOCOL_VERSION_3, - PRIVATE_TRANSACTION_PACKET, SIGNED_PRIVATE_TRANSACTION_PACKET}; + PAR_PROTOCOL_VERSION_1, PAR_PROTOCOL_VERSION_2, PAR_PROTOCOL_VERSION_3}; +use chain::sync_packet::SyncPacket::{PrivateTransactionPacket, SignedPrivateTransactionPacket}; use light::client::AsLightClient; use light::Provider; use light::net::{ @@ -579,9 +579,9 @@ impl ChainNotify for EthSync { match message_type { ChainMessageType::Consensus(message) => self.eth_handler.sync.write().propagate_consensus_packet(&mut sync_io, message), ChainMessageType::PrivateTransaction(transaction_hash, message) => - self.eth_handler.sync.write().propagate_private_transaction(&mut sync_io, transaction_hash, WARP_SYNC_PROTOCOL_ID, PRIVATE_TRANSACTION_PACKET, message), + self.eth_handler.sync.write().propagate_private_transaction(&mut sync_io, transaction_hash, PrivateTransactionPacket, message), ChainMessageType::SignedPrivateTransaction(transaction_hash, message) => - self.eth_handler.sync.write().propagate_private_transaction(&mut sync_io, transaction_hash, WARP_SYNC_PROTOCOL_ID, SIGNED_PRIVATE_TRANSACTION_PACKET, message), + self.eth_handler.sync.write().propagate_private_transaction(&mut sync_io, transaction_hash, SignedPrivateTransactionPacket, message), } }); } diff --git a/ethcore/sync/src/chain/handler.rs b/ethcore/sync/src/chain/handler.rs index 83323ba996..63ab891613 100644 --- a/ethcore/sync/src/chain/handler.rs +++ b/ethcore/sync/src/chain/handler.rs @@ -17,6 +17,7 @@ use api::WARP_SYNC_PROTOCOL_ID; use block_sync::{BlockDownloaderImportError as DownloaderImportError, DownloadAction}; use bytes::Bytes; +use enum_primitive::FromPrimitive; use ethcore::error::{Error as EthcoreError, ErrorKind as EthcoreErrorKind, ImportErrorKind, BlockError}; use ethcore::snapshot::{ManifestData, RestorationStatus}; use ethcore::verification::queue::kind::blocks::Unverified; @@ -33,6 +34,20 @@ use types::BlockNumber; use types::block_status::BlockStatus; use types::ids::BlockId; +use super::sync_packet::{PacketInfo, SyncPacket}; +use super::sync_packet::SyncPacket::{ + StatusPacket, + NewBlockHashesPacket, + BlockHeadersPacket, + BlockBodiesPacket, + NewBlockPacket, + ReceiptsPacket, + SnapshotManifestPacket, + SnapshotDataPacket, + PrivateTransactionPacket, + SignedPrivateTransactionPacket, +}; + use super::{ BlockSet, ChainSync, @@ -48,16 +63,6 @@ use super::{ MAX_NEW_HASHES, PAR_PROTOCOL_VERSION_1, PAR_PROTOCOL_VERSION_3, - BLOCK_BODIES_PACKET, - BLOCK_HEADERS_PACKET, - NEW_BLOCK_HASHES_PACKET, - NEW_BLOCK_PACKET, - PRIVATE_TRANSACTION_PACKET, - RECEIPTS_PACKET, - SIGNED_PRIVATE_TRANSACTION_PACKET, - SNAPSHOT_DATA_PACKET, - SNAPSHOT_MANIFEST_PACKET, - STATUS_PACKET, }; /// The Chain Sync Handler: handles responses from peers @@ -67,36 +72,40 @@ impl SyncHandler { /// Handle incoming packet from peer pub fn on_packet(sync: &mut ChainSync, io: &mut SyncIo, peer: PeerId, packet_id: u8, data: &[u8]) { let rlp = Rlp::new(data); - let result = match packet_id { - STATUS_PACKET => SyncHandler::on_peer_status(sync, io, peer, &rlp), - BLOCK_HEADERS_PACKET => SyncHandler::on_peer_block_headers(sync, io, peer, &rlp), - BLOCK_BODIES_PACKET => SyncHandler::on_peer_block_bodies(sync, io, peer, &rlp), - RECEIPTS_PACKET => SyncHandler::on_peer_block_receipts(sync, io, peer, &rlp), - NEW_BLOCK_PACKET => SyncHandler::on_peer_new_block(sync, io, peer, &rlp), - NEW_BLOCK_HASHES_PACKET => SyncHandler::on_peer_new_hashes(sync, io, peer, &rlp), - SNAPSHOT_MANIFEST_PACKET => SyncHandler::on_snapshot_manifest(sync, io, peer, &rlp), - SNAPSHOT_DATA_PACKET => SyncHandler::on_snapshot_data(sync, io, peer, &rlp), - PRIVATE_TRANSACTION_PACKET => SyncHandler::on_private_transaction(sync, io, peer, &rlp), - SIGNED_PRIVATE_TRANSACTION_PACKET => SyncHandler::on_signed_private_transaction(sync, io, peer, &rlp), - _ => { - debug!(target: "sync", "{}: Unknown packet {}", peer, packet_id); - Ok(()) - } - }; + if let Some(packet_id) = SyncPacket::from_u8(packet_id) { + let result = match packet_id { + StatusPacket => SyncHandler::on_peer_status(sync, io, peer, &rlp), + BlockHeadersPacket => SyncHandler::on_peer_block_headers(sync, io, peer, &rlp), + BlockBodiesPacket => SyncHandler::on_peer_block_bodies(sync, io, peer, &rlp), + ReceiptsPacket => SyncHandler::on_peer_block_receipts(sync, io, peer, &rlp), + NewBlockPacket => SyncHandler::on_peer_new_block(sync, io, peer, &rlp), + NewBlockHashesPacket => SyncHandler::on_peer_new_hashes(sync, io, peer, &rlp), + SnapshotManifestPacket => SyncHandler::on_snapshot_manifest(sync, io, peer, &rlp), + SnapshotDataPacket => SyncHandler::on_snapshot_data(sync, io, peer, &rlp), + PrivateTransactionPacket => SyncHandler::on_private_transaction(sync, io, peer, &rlp), + SignedPrivateTransactionPacket => SyncHandler::on_signed_private_transaction(sync, io, peer, &rlp), + _ => { + debug!(target: "sync", "{}: Unknown packet {}", peer, packet_id.id()); + Ok(()) + } + }; - match result { - Err(DownloaderImportError::Invalid) => { - debug!(target:"sync", "{} -> Invalid packet {}", peer, packet_id); - io.disable_peer(peer); - sync.deactivate_peer(io, peer); - }, - Err(DownloaderImportError::Useless) => { - sync.deactivate_peer(io, peer); - }, - Ok(()) => { - // give a task to the same peer first - sync.sync_peer(io, peer, false); - }, + match result { + Err(DownloaderImportError::Invalid) => { + debug!(target:"sync", "{} -> Invalid packet {}", peer, packet_id.id()); + io.disable_peer(peer); + sync.deactivate_peer(io, peer); + }, + Err(DownloaderImportError::Useless) => { + sync.deactivate_peer(io, peer); + }, + Ok(()) => { + // give a task to the same peer first + sync.sync_peer(io, peer, false); + }, + } + } else { + debug!(target: "sync", "{}: Unknown packet {}", peer, packet_id); } } diff --git a/ethcore/sync/src/chain/mod.rs b/ethcore/sync/src/chain/mod.rs index 123f2b9c85..81f1ccffe9 100644 --- a/ethcore/sync/src/chain/mod.rs +++ b/ethcore/sync/src/chain/mod.rs @@ -88,6 +88,7 @@ //! All other messages are ignored. mod handler; +pub mod sync_packet; mod propagator; mod requester; mod supplier; @@ -103,7 +104,7 @@ use fastmap::{H256FastMap, H256FastSet}; use parking_lot::{Mutex, RwLock, RwLockWriteGuard}; use bytes::Bytes; use rlp::{RlpStream, DecoderError}; -use network::{self, PeerId, PacketId, ProtocolId}; +use network::{self, PeerId, PacketId}; use network::client_version::ClientVersion; use ethcore::client::{BlockChainClient, BlockStatus, BlockId, BlockChainInfo, BlockQueueInfo}; use ethcore::snapshot::{RestorationStatus}; @@ -112,13 +113,19 @@ use super::{WarpSync, SyncConfig}; use block_sync::{BlockDownloader, DownloadAction}; use rand::Rng; use snapshot::{Snapshot}; -use api::{EthProtocolInfo as PeerInfoDigest, ETH_PROTOCOL, WARP_SYNC_PROTOCOL_ID, PriorityTask}; +use api::{EthProtocolInfo as PeerInfoDigest, WARP_SYNC_PROTOCOL_ID, PriorityTask}; use private_tx::PrivateTxHandler; use transactions_stats::{TransactionsStats, Stats as TransactionStats}; use types::transaction::UnverifiedTransaction; use types::BlockNumber; use self::handler::SyncHandler; +use self::sync_packet::{PacketInfo, SyncPacket}; +use self::sync_packet::SyncPacket::{ + NewBlockPacket, + StatusPacket, +}; + use self::propagator::SyncPropagator; use self::requester::SyncRequester; pub(crate) use self::supplier::SyncSupplier; @@ -154,28 +161,6 @@ const MAX_TRANSACTION_PACKET_SIZE: usize = 5 * 1024 * 1024; const SNAPSHOT_RESTORE_THRESHOLD: BlockNumber = 30000; const SNAPSHOT_MIN_PEERS: usize = 3; -pub const STATUS_PACKET: u8 = 0x00; -const NEW_BLOCK_HASHES_PACKET: u8 = 0x01; -const TRANSACTIONS_PACKET: u8 = 0x02; -pub const GET_BLOCK_HEADERS_PACKET: u8 = 0x03; -pub const BLOCK_HEADERS_PACKET: u8 = 0x04; -pub const GET_BLOCK_BODIES_PACKET: u8 = 0x05; -const BLOCK_BODIES_PACKET: u8 = 0x06; -const NEW_BLOCK_PACKET: u8 = 0x07; - -pub const GET_NODE_DATA_PACKET: u8 = 0x0d; -pub const NODE_DATA_PACKET: u8 = 0x0e; -pub const GET_RECEIPTS_PACKET: u8 = 0x0f; -pub const RECEIPTS_PACKET: u8 = 0x10; - -pub const GET_SNAPSHOT_MANIFEST_PACKET: u8 = 0x11; -pub const SNAPSHOT_MANIFEST_PACKET: u8 = 0x12; -pub const GET_SNAPSHOT_DATA_PACKET: u8 = 0x13; -pub const SNAPSHOT_DATA_PACKET: u8 = 0x14; -pub const CONSENSUS_DATA_PACKET: u8 = 0x15; -pub const PRIVATE_TRANSACTION_PACKET: u8 = 0x16; -pub const SIGNED_PRIVATE_TRANSACTION_PACKET: u8 = 0x17; - const MAX_SNAPSHOT_CHUNKS_DOWNLOAD_AHEAD: usize = 3; const WAIT_PEERS_TIMEOUT: Duration = Duration::from_secs(5); @@ -484,7 +469,7 @@ impl ChainSyncApi { for peers in sync.get_peers(&chain_info, PeerState::SameBlock).chunks(10) { check_deadline(deadline)?; for peer in peers { - SyncPropagator::send_packet(io, ETH_PROTOCOL, *peer, NEW_BLOCK_PACKET, rlp.clone()); + SyncPropagator::send_packet(io, *peer, NewBlockPacket, rlp.clone()); if let Some(ref mut peer) = sync.peers.get_mut(peer) { peer.latest_hash = hash; } @@ -1146,7 +1131,7 @@ impl ChainSync { } } packet.complete_unbounded_list(); - io.respond(STATUS_PACKET, packet.out()) + io.respond(StatusPacket.id(), packet.out()) } pub fn maintain_peers(&mut self, io: &mut SyncIo) { @@ -1331,8 +1316,8 @@ impl ChainSync { } /// Broadcast private transaction message to peers. - pub fn propagate_private_transaction(&mut self, io: &mut SyncIo, transaction_hash: H256, protocol: ProtocolId, packet_id: PacketId, packet: Bytes) { - SyncPropagator::propagate_private_transaction(self, io, transaction_hash, protocol, packet_id, packet); + pub fn propagate_private_transaction(&mut self, io: &mut SyncIo, transaction_hash: H256, packet_id: SyncPacket, packet: Bytes) { + SyncPropagator::propagate_private_transaction(self, io, transaction_hash, packet_id, packet); } } diff --git a/ethcore/sync/src/chain/propagator.rs b/ethcore/sync/src/chain/propagator.rs index 77035387ec..c3654553ff 100644 --- a/ethcore/sync/src/chain/propagator.rs +++ b/ethcore/sync/src/chain/propagator.rs @@ -17,12 +17,11 @@ use std::cmp; use std::collections::HashSet; -use api::{ETH_PROTOCOL, WARP_SYNC_PROTOCOL_ID}; use bytes::Bytes; use ethereum_types::H256; use fastmap::H256FastSet; -use network::{PeerId, PacketId, ProtocolId}; use network::client_version::ClientCapabilities; +use network::PeerId; use rand::Rng; use rlp::{Encodable, RlpStream}; use sync_io::SyncIo; @@ -30,6 +29,14 @@ use types::transaction::SignedTransaction; use types::BlockNumber; use types::blockchain_info::BlockChainInfo; +use super::sync_packet::SyncPacket; +use super::sync_packet::SyncPacket::{ + NewBlockHashesPacket, + TransactionsPacket, + NewBlockPacket, + ConsensusDataPacket, +}; + use super::{ random, ChainSync, @@ -37,10 +44,6 @@ use super::{ MAX_PEER_LAG_PROPAGATION, MAX_PEERS_PROPAGATION, MIN_PEERS_PROPAGATION, - CONSENSUS_DATA_PACKET, - NEW_BLOCK_HASHES_PACKET, - NEW_BLOCK_PACKET, - TRANSACTIONS_PACKET, }; /// The Chain Sync Propagator: propagates data to peers @@ -53,7 +56,8 @@ impl SyncPropagator { let sent = peers.len(); let mut send_packet = |io: &mut SyncIo, rlp: Bytes| { for peer_id in peers { - SyncPropagator::send_packet(io, ETH_PROTOCOL, *peer_id, NEW_BLOCK_PACKET, rlp.clone()); + SyncPropagator::send_packet(io, *peer_id, NewBlockPacket, rlp.clone()); + if let Some(ref mut peer) = sync.peers.get_mut(peer_id) { peer.latest_hash = chain_info.best_block_hash.clone(); } @@ -88,7 +92,7 @@ impl SyncPropagator { if let Some(ref mut peer) = sync.peers.get_mut(peer_id) { peer.latest_hash = best_block_hash; } - SyncPropagator::send_packet(io, ETH_PROTOCOL, *peer_id, NEW_BLOCK_HASHES_PACKET, rlp.clone()); + SyncPropagator::send_packet(io, *peer_id, NewBlockHashesPacket, rlp.clone()); } sent } @@ -156,7 +160,7 @@ impl SyncPropagator { let send_packet = |io: &mut SyncIo, peer_id: PeerId, sent: usize, rlp: Bytes| { let size = rlp.len(); - SyncPropagator::send_packet(io, ETH_PROTOCOL, peer_id, TRANSACTIONS_PACKET, rlp); + SyncPropagator::send_packet(io, peer_id, TransactionsPacket, rlp); trace!(target: "sync", "{:02} <- Transactions ({} entries; {} bytes)", peer_id, sent, size); }; @@ -275,7 +279,7 @@ impl SyncPropagator { io.chain().chain_info().total_difficulty ); for peer_id in &peers { - SyncPropagator::send_packet(io, ETH_PROTOCOL, *peer_id, NEW_BLOCK_PACKET, rlp.clone()); + SyncPropagator::send_packet(io, *peer_id, NewBlockPacket, rlp.clone()); } } } @@ -285,12 +289,12 @@ impl SyncPropagator { let lucky_peers = ChainSync::select_random_peers(&sync.get_consensus_peers()); trace!(target: "sync", "Sending consensus packet to {:?}", lucky_peers); for peer_id in lucky_peers { - SyncPropagator::send_packet(io, WARP_SYNC_PROTOCOL_ID, peer_id, CONSENSUS_DATA_PACKET, packet.clone()); + SyncPropagator::send_packet(io, peer_id, ConsensusDataPacket, packet.clone()); } } /// Broadcast private transaction message to peers. - pub fn propagate_private_transaction(sync: &mut ChainSync, io: &mut SyncIo, transaction_hash: H256, protocol: ProtocolId, packet_id: PacketId, packet: Bytes) { + pub fn propagate_private_transaction(sync: &mut ChainSync, io: &mut SyncIo, transaction_hash: H256, packet_id: SyncPacket, packet: Bytes) { let lucky_peers = ChainSync::select_random_peers(&sync.get_private_transaction_peers(&transaction_hash)); if lucky_peers.is_empty() { error!(target: "privatetx", "Cannot propagate the packet, no peers with private tx enabled connected"); @@ -300,7 +304,7 @@ impl SyncPropagator { if let Some(ref mut peer) = sync.peers.get_mut(&peer_id) { peer.last_sent_private_transactions.insert(transaction_hash); } - SyncPropagator::send_packet(io, protocol, peer_id, packet_id, packet.clone()); + SyncPropagator::send_packet(io, peer_id, packet_id, packet.clone()); } } } @@ -321,8 +325,8 @@ impl SyncPropagator { } /// Generic packet sender - pub fn send_packet(sync: &mut SyncIo, protocol: ProtocolId, peer_id: PeerId, packet_id: PacketId, packet: Bytes) { - if let Err(e) = sync.send_protocol(protocol, peer_id, packet_id, packet) { + pub fn send_packet(sync: &mut SyncIo, peer_id: PeerId, packet_id: SyncPacket, packet: Bytes) { + if let Err(e) = sync.send(peer_id, packet_id, packet) { debug!(target:"sync", "Error sending packet: {:?}", e); sync.disconnect_peer(peer_id); } diff --git a/ethcore/sync/src/chain/requester.rs b/ethcore/sync/src/chain/requester.rs index 85f622ec86..31d3ce5900 100644 --- a/ethcore/sync/src/chain/requester.rs +++ b/ethcore/sync/src/chain/requester.rs @@ -14,25 +14,28 @@ // You should have received a copy of the GNU General Public License // along with Parity Ethereum. If not, see . -use api::{ETH_PROTOCOL, WARP_SYNC_PROTOCOL_ID}; use block_sync::BlockRequest; use bytes::Bytes; use ethereum_types::H256; -use network::{PeerId, PacketId, ProtocolId}; +use network::{PeerId}; use rlp::RlpStream; use std::time::Instant; use sync_io::SyncIo; use types::BlockNumber; +use super::sync_packet::SyncPacket; +use super::sync_packet::SyncPacket::{ + GetBlockHeadersPacket, + GetBlockBodiesPacket, + GetReceiptsPacket, + GetSnapshotManifestPacket, + GetSnapshotDataPacket, +}; + use super::{ BlockSet, ChainSync, PeerAsking, - GET_BLOCK_BODIES_PACKET, - GET_BLOCK_HEADERS_PACKET, - GET_RECEIPTS_PACKET, - GET_SNAPSHOT_DATA_PACKET, - GET_SNAPSHOT_MANIFEST_PACKET, }; /// The Chain Sync Requester: requesting data to other peers @@ -61,9 +64,7 @@ impl SyncRequester { for h in &hashes { rlp.append(&h.clone()); } - - SyncRequester::send_request(sync, io, peer_id, PeerAsking::BlockBodies, ETH_PROTOCOL, GET_BLOCK_BODIES_PACKET, rlp.out()); - + SyncRequester::send_request(sync, io, peer_id, PeerAsking::BlockBodies, GetBlockBodiesPacket, rlp.out()); let peer = sync.peers.get_mut(&peer_id).expect("peer_id may originate either from on_packet, where it is already validated or from enumerating self.peers. qed"); peer.asking_blocks = hashes; peer.block_set = Some(set); @@ -77,7 +78,7 @@ impl SyncRequester { rlp.append(&1u32); rlp.append(&0u32); rlp.append(&0u32); - SyncRequester::send_request(sync, io, peer_id, PeerAsking::ForkHeader, ETH_PROTOCOL, GET_BLOCK_HEADERS_PACKET, rlp.out()); + SyncRequester::send_request(sync, io, peer_id, PeerAsking::ForkHeader, GetBlockHeadersPacket, rlp.out()); } /// Find some headers or blocks to download for a peer. @@ -95,7 +96,7 @@ impl SyncRequester { pub fn request_snapshot_manifest(sync: &mut ChainSync, io: &mut SyncIo, peer_id: PeerId) { trace!(target: "sync", "{} <- GetSnapshotManifest", peer_id); let rlp = RlpStream::new_list(0); - SyncRequester::send_request(sync, io, peer_id, PeerAsking::SnapshotManifest, WARP_SYNC_PROTOCOL_ID, GET_SNAPSHOT_MANIFEST_PACKET, rlp.out()); + SyncRequester::send_request(sync, io, peer_id, PeerAsking::SnapshotManifest, GetSnapshotManifestPacket, rlp.out()); } /// Request headers from a peer by block hash @@ -106,7 +107,7 @@ impl SyncRequester { rlp.append(&count); rlp.append(&skip); rlp.append(&if reverse {1u32} else {0u32}); - SyncRequester::send_request(sync, io, peer_id, PeerAsking::BlockHeaders, ETH_PROTOCOL, GET_BLOCK_HEADERS_PACKET, rlp.out()); + SyncRequester::send_request(sync, io, peer_id, PeerAsking::BlockHeaders, GetBlockHeadersPacket, rlp.out()); let peer = sync.peers.get_mut(&peer_id).expect("peer_id may originate either from on_packet, where it is already validated or from enumerating self.peers. qed"); peer.asking_hash = Some(h.clone()); peer.block_set = Some(set); @@ -119,7 +120,7 @@ impl SyncRequester { for h in &hashes { rlp.append(&h.clone()); } - SyncRequester::send_request(sync, io, peer_id, PeerAsking::BlockReceipts, ETH_PROTOCOL, GET_RECEIPTS_PACKET, rlp.out()); + SyncRequester::send_request(sync, io, peer_id, PeerAsking::BlockReceipts, GetReceiptsPacket, rlp.out()); let peer = sync.peers.get_mut(&peer_id).expect("peer_id may originate either from on_packet, where it is already validated or from enumerating self.peers. qed"); peer.asking_blocks = hashes; peer.block_set = Some(set); @@ -130,11 +131,11 @@ impl SyncRequester { trace!(target: "sync", "{} <- GetSnapshotData {:?}", peer_id, chunk); let mut rlp = RlpStream::new_list(1); rlp.append(chunk); - SyncRequester::send_request(sync, io, peer_id, PeerAsking::SnapshotData, WARP_SYNC_PROTOCOL_ID, GET_SNAPSHOT_DATA_PACKET, rlp.out()); + SyncRequester::send_request(sync, io, peer_id, PeerAsking::SnapshotData, GetSnapshotDataPacket, rlp.out()); } /// Generic request sender - fn send_request(sync: &mut ChainSync, io: &mut SyncIo, peer_id: PeerId, asking: PeerAsking, protocol: ProtocolId, packet_id: PacketId, packet: Bytes) { + fn send_request(sync: &mut ChainSync, io: &mut SyncIo, peer_id: PeerId, asking: PeerAsking, packet_id: SyncPacket, packet: Bytes) { if let Some(ref mut peer) = sync.peers.get_mut(&peer_id) { if peer.asking != PeerAsking::Nothing { warn!(target:"sync", "Asking {:?} while requesting {:?}", peer.asking, asking); @@ -142,7 +143,7 @@ impl SyncRequester { peer.asking = asking; peer.ask_time = Instant::now(); - let result = io.send_protocol(protocol, peer_id, packet_id, packet); + let result = io.send(peer_id, packet_id, packet); if let Err(e) = result { debug!(target:"sync", "Error sending request: {:?}", e); diff --git a/ethcore/sync/src/chain/supplier.rs b/ethcore/sync/src/chain/supplier.rs index d691cb35af..7e71e6aeec 100644 --- a/ethcore/sync/src/chain/supplier.rs +++ b/ethcore/sync/src/chain/supplier.rs @@ -15,6 +15,7 @@ // along with Parity Ethereum. If not, see . use bytes::Bytes; +use enum_primitive::FromPrimitive; use ethereum_types::H256; use network::{self, PeerId}; use parking_lot::RwLock; @@ -25,30 +26,34 @@ use types::ids::BlockId; use sync_io::SyncIo; +use super::sync_packet::{PacketInfo, SyncPacket}; +use super::sync_packet::SyncPacket::{ + StatusPacket, + TransactionsPacket, + GetBlockHeadersPacket, + BlockHeadersPacket, + GetBlockBodiesPacket, + BlockBodiesPacket, + GetNodeDataPacket, + NodeDataPacket, + GetReceiptsPacket, + ReceiptsPacket, + GetSnapshotManifestPacket, + SnapshotManifestPacket, + GetSnapshotDataPacket, + SnapshotDataPacket, + ConsensusDataPacket, +}; + use super::{ ChainSync, SyncHandler, RlpResponseResult, PacketDecodeError, - BLOCK_BODIES_PACKET, - BLOCK_HEADERS_PACKET, - CONSENSUS_DATA_PACKET, - GET_BLOCK_BODIES_PACKET, - GET_BLOCK_HEADERS_PACKET, - GET_NODE_DATA_PACKET, - GET_RECEIPTS_PACKET, - GET_SNAPSHOT_DATA_PACKET, - GET_SNAPSHOT_MANIFEST_PACKET, MAX_BODIES_TO_SEND, MAX_HEADERS_TO_SEND, MAX_NODE_DATA_TO_SEND, MAX_RECEIPTS_HEADERS_TO_SEND, - NODE_DATA_PACKET, - RECEIPTS_PACKET, - SNAPSHOT_DATA_PACKET, - SNAPSHOT_MANIFEST_PACKET, - STATUS_PACKET, - TRANSACTIONS_PACKET, }; /// The Chain Sync Supplier: answers requests from peers with available data @@ -56,72 +61,83 @@ pub struct SyncSupplier; impl SyncSupplier { /// Dispatch incoming requests and responses + // Take a u8 and not a SyncPacketId because this is the entry point + // to chain sync from the outside world. pub fn dispatch_packet(sync: &RwLock, io: &mut SyncIo, peer: PeerId, packet_id: u8, data: &[u8]) { let rlp = Rlp::new(data); - let result = match packet_id { - GET_BLOCK_BODIES_PACKET => SyncSupplier::return_rlp(io, &rlp, peer, - SyncSupplier::return_block_bodies, - |e| format!("Error sending block bodies: {:?}", e)), - - GET_BLOCK_HEADERS_PACKET => SyncSupplier::return_rlp(io, &rlp, peer, - SyncSupplier::return_block_headers, - |e| format!("Error sending block headers: {:?}", e)), - - GET_RECEIPTS_PACKET => SyncSupplier::return_rlp(io, &rlp, peer, - SyncSupplier::return_receipts, - |e| format!("Error sending receipts: {:?}", e)), - - GET_NODE_DATA_PACKET => SyncSupplier::return_rlp(io, &rlp, peer, - SyncSupplier::return_node_data, - |e| format!("Error sending nodes: {:?}", e)), - - GET_SNAPSHOT_MANIFEST_PACKET => SyncSupplier::return_rlp(io, &rlp, peer, - SyncSupplier::return_snapshot_manifest, - |e| format!("Error sending snapshot manifest: {:?}", e)), - - GET_SNAPSHOT_DATA_PACKET => SyncSupplier::return_rlp(io, &rlp, peer, - SyncSupplier::return_snapshot_data, - |e| format!("Error sending snapshot data: {:?}", e)), - - STATUS_PACKET => { - sync.write().on_packet(io, peer, packet_id, data); - Ok(()) - }, - // Packets that require the peer to be confirmed - _ => { - if !sync.read().peers.contains_key(&peer) { - debug!(target:"sync", "Unexpected packet {} from unregistered peer: {}:{}", packet_id, peer, io.peer_version(peer)); - return; - } - debug!(target: "sync", "{} -> Dispatching packet: {}", peer, packet_id); - - match packet_id { - CONSENSUS_DATA_PACKET => { - SyncHandler::on_consensus_packet(io, peer, &rlp) - }, - TRANSACTIONS_PACKET => { - let res = { - let sync_ro = sync.read(); - SyncHandler::on_peer_transactions(&*sync_ro, io, peer, &rlp) - }; - if res.is_err() { - // peer sent invalid data, disconnect. - io.disable_peer(peer); - sync.write().deactivate_peer(io, peer); + if let Some(id) = SyncPacket::from_u8(packet_id) { + let result = match id { + GetBlockBodiesPacket => SyncSupplier::return_rlp( + io, &rlp, peer, + SyncSupplier::return_block_bodies, + |e| format!("Error sending block bodies: {:?}", e)), + + GetBlockHeadersPacket => SyncSupplier::return_rlp( + io, &rlp, peer, + SyncSupplier::return_block_headers, + |e| format!("Error sending block headers: {:?}", e)), + + GetReceiptsPacket => SyncSupplier::return_rlp( + io, &rlp, peer, + SyncSupplier::return_receipts, + |e| format!("Error sending receipts: {:?}", e)), + + GetNodeDataPacket => SyncSupplier::return_rlp( + io, &rlp, peer, + SyncSupplier::return_node_data, + |e| format!("Error sending nodes: {:?}", e)), + + GetSnapshotManifestPacket => SyncSupplier::return_rlp( + io, &rlp, peer, + SyncSupplier::return_snapshot_manifest, + |e| format!("Error sending snapshot manifest: {:?}", e)), + + GetSnapshotDataPacket => SyncSupplier::return_rlp( + io, &rlp, peer, + SyncSupplier::return_snapshot_data, + |e| format!("Error sending snapshot data: {:?}", e)), + + StatusPacket => { + sync.write().on_packet(io, peer, packet_id, data); + Ok(()) + }, + // Packets that require the peer to be confirmed + _ => { + if !sync.read().peers.contains_key(&peer) { + debug!(target:"sync", "Unexpected packet {} from unregistered peer: {}:{}", packet_id, peer, io.peer_version(peer)); + return; + } + debug!(target: "sync", "{} -> Dispatching packet: {}", peer, packet_id); + + match id { + ConsensusDataPacket => { + SyncHandler::on_consensus_packet(io, peer, &rlp) + }, + TransactionsPacket => { + let res = { + let sync_ro = sync.read(); + SyncHandler::on_peer_transactions(&*sync_ro, io, peer, &rlp) + }; + if res.is_err() { + // peer sent invalid data, disconnect. + io.disable_peer(peer); + sync.write().deactivate_peer(io, peer); + } + }, + _ => { + sync.write().on_packet(io, peer, packet_id, data); } - }, - _ => { - sync.write().on_packet(io, peer, packet_id, data); } + + Ok(()) } + }; - Ok(()) - } - }; - result.unwrap_or_else(|e| { - debug!(target:"sync", "{} -> Malformed packet {} : {}", peer, packet_id, e); - }) + result.unwrap_or_else(|e| { + debug!(target:"sync", "{} -> Malformed packet {} : {}", peer, packet_id, e); + }) + } } /// Respond to GetBlockHeaders request @@ -148,11 +164,11 @@ impl SyncSupplier { trace!(target:"sync", "Returning single header: {:?}", hash); let mut rlp = RlpStream::new_list(1); rlp.append_raw(&hdr.into_inner(), 1); - return Ok(Some((BLOCK_HEADERS_PACKET, rlp))); + return Ok(Some((BlockHeadersPacket.id(), rlp))); } number } - None => return Ok(Some((BLOCK_HEADERS_PACKET, RlpStream::new_list(0)))) //no such header, return nothing + None => return Ok(Some((BlockHeadersPacket.id(), RlpStream::new_list(0)))) //no such header, return nothing } } else { let number = r.val_at::(0)?; @@ -202,7 +218,7 @@ impl SyncSupplier { let mut rlp = RlpStream::new_list(count as usize); rlp.append_raw(&data, count as usize); trace!(target: "sync", "{} -> GetBlockHeaders: returned {} entries", peer_id, count); - Ok(Some((BLOCK_HEADERS_PACKET, rlp))) + Ok(Some((BlockHeadersPacket.id(), rlp))) } /// Respond to GetBlockBodies request @@ -229,7 +245,7 @@ impl SyncSupplier { let mut rlp = RlpStream::new_list(added); rlp.append_raw(&data, added); trace!(target: "sync", "{} -> GetBlockBodies: returned {} entries", peer_id, added); - Ok(Some((BLOCK_BODIES_PACKET, rlp))) + Ok(Some((BlockBodiesPacket.id(), rlp))) } /// Respond to GetNodeData request @@ -261,7 +277,7 @@ impl SyncSupplier { for d in data { rlp.append(&d); } - Ok(Some((NODE_DATA_PACKET, rlp))) + Ok(Some((NodeDataPacket.id(), rlp))) } fn return_receipts(io: &SyncIo, rlp: &Rlp, peer_id: PeerId) -> RlpResponseResult { @@ -287,7 +303,7 @@ impl SyncSupplier { } let mut rlp_result = RlpStream::new_list(added_headers); rlp_result.append_raw(&data, added_headers); - Ok(Some((RECEIPTS_PACKET, rlp_result))) + Ok(Some((ReceiptsPacket.id(), rlp_result))) } /// Respond to GetSnapshotManifest request @@ -310,7 +326,7 @@ impl SyncSupplier { RlpStream::new_list(0) } }; - Ok(Some((SNAPSHOT_MANIFEST_PACKET, rlp))) + Ok(Some((SnapshotManifestPacket.id(), rlp))) } /// Respond to GetSnapshotData request @@ -329,7 +345,7 @@ impl SyncSupplier { RlpStream::new_list(0) } }; - Ok(Some((SNAPSHOT_DATA_PACKET, rlp))) + Ok(Some((SnapshotDataPacket.id(), rlp))) } fn return_rlp(io: &mut SyncIo, rlp: &Rlp, peer: PeerId, rlp_func: FRlp, error_func: FError) -> Result<(), PacketDecodeError> @@ -491,7 +507,7 @@ mod test { io.sender = Some(2usize); - SyncSupplier::dispatch_packet(&RwLock::new(sync), &mut io, 0usize, GET_NODE_DATA_PACKET, &node_request); + SyncSupplier::dispatch_packet(&RwLock::new(sync), &mut io, 0usize, GetNodeDataPacket.id(), &node_request); assert_eq!(1, io.packets.len()); } @@ -533,7 +549,7 @@ mod test { assert_eq!(603, rlp_result.unwrap().1.out().len()); io.sender = Some(2usize); - SyncSupplier::dispatch_packet(&RwLock::new(sync), &mut io, 0usize, GET_RECEIPTS_PACKET, &receipts_request); + SyncSupplier::dispatch_packet(&RwLock::new(sync), &mut io, 0usize, GetReceiptsPacket.id(), &receipts_request); assert_eq!(1, io.packets.len()); } } diff --git a/ethcore/sync/src/chain/sync_packet.rs b/ethcore/sync/src/chain/sync_packet.rs new file mode 100644 index 0000000000..3891090f65 --- /dev/null +++ b/ethcore/sync/src/chain/sync_packet.rs @@ -0,0 +1,141 @@ +// Copyright 2015-2019 Parity Technologies (UK) Ltd. +// This file is part of Parity Ethereum. + +// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . + +//! When sending packets over p2p we specify both which subprotocol +//! to use and what kind of packet we are sending (through a packet id). +//! Likewise when receiving packets from other peers we decode the +//! subprotocol and the packet id. This module helps coupling both +//! pieces of information together and provides an easy mechanism +//! to convert to/from the packet id values transmitted over the +//! wire. + +use api::{ETH_PROTOCOL, WARP_SYNC_PROTOCOL_ID}; +use network::{PacketId, ProtocolId}; + +/// An enum that defines all known packet ids in the context of +/// synchronization and provides a mechanism to convert from +/// packet ids (of type PacketId or u8) directly read from the network +/// to enum variants. This implicitly provides a mechanism to +/// check whether a given packet id is known, and to prevent +/// packet id clashes when defining new ids. +enum_from_primitive! { +#[derive(Clone, Copy, Debug, PartialEq)] +pub enum SyncPacket { + StatusPacket = 0x00, + NewBlockHashesPacket = 0x01, + TransactionsPacket = 0x02, + GetBlockHeadersPacket = 0x03, + BlockHeadersPacket = 0x04, + GetBlockBodiesPacket = 0x05, + BlockBodiesPacket = 0x06, + NewBlockPacket = 0x07, + + GetNodeDataPacket = 0x0d, + NodeDataPacket = 0x0e, + GetReceiptsPacket = 0x0f, + ReceiptsPacket = 0x10, + + GetSnapshotManifestPacket = 0x11, + SnapshotManifestPacket = 0x12, + GetSnapshotDataPacket = 0x13, + SnapshotDataPacket = 0x14, + ConsensusDataPacket = 0x15, + PrivateTransactionPacket = 0x16, + SignedPrivateTransactionPacket = 0x17, +} +} + +use self::SyncPacket::*; + +/// Provide both subprotocol and packet id information within the +/// same object. +pub trait PacketInfo { + fn id(&self) -> PacketId; + fn protocol(&self) -> ProtocolId; +} + +// The mechanism to match packet ids and protocol may be improved +// through some macro magic, but for now this works. +impl PacketInfo for SyncPacket { + fn protocol(&self) -> ProtocolId { + match self { + StatusPacket | + NewBlockHashesPacket | + TransactionsPacket | + GetBlockHeadersPacket | + BlockHeadersPacket | + GetBlockBodiesPacket | + BlockBodiesPacket | + NewBlockPacket | + + GetNodeDataPacket| + NodeDataPacket | + GetReceiptsPacket | + ReceiptsPacket + + => ETH_PROTOCOL, + + GetSnapshotManifestPacket| + SnapshotManifestPacket | + GetSnapshotDataPacket | + SnapshotDataPacket | + ConsensusDataPacket | + PrivateTransactionPacket | + SignedPrivateTransactionPacket + + => WARP_SYNC_PROTOCOL_ID, + } + } + + fn id(&self) -> PacketId { + (*self) as PacketId + } +} + + +#[cfg(test)] +mod tests { + use super::*; + + use enum_primitive::FromPrimitive; + + #[test] + fn packet_ids_from_u8_when_from_primitive_zero_then_equals_status_packet() { + assert_eq!(SyncPacket::from_u8(0x00), Some(StatusPacket)); + } + + #[test] + fn packet_ids_from_u8_when_from_primitive_eleven_then_equals_get_snapshot_manifest_packet() { + assert_eq!(SyncPacket::from_u8(0x11), Some(GetSnapshotManifestPacket)); + } + + #[test] + fn packet_ids_from_u8_when_invalid_packet_id_then_none() { + assert!(SyncPacket::from_u8(0x99).is_none()); + } + + #[test] + fn when_status_packet_then_id_and_protocol_match() { + assert_eq!(StatusPacket.id(), StatusPacket as PacketId); + assert_eq!(StatusPacket.protocol(), ETH_PROTOCOL); + } + + #[test] + fn when_consensus_data_packet_then_id_and_protocol_match() { + assert_eq!(ConsensusDataPacket.id(), ConsensusDataPacket as PacketId); + assert_eq!(ConsensusDataPacket.protocol(), WARP_SYNC_PROTOCOL_ID); + } +} diff --git a/ethcore/sync/src/lib.rs b/ethcore/sync/src/lib.rs index e5bb2c4a76..8a1e19569a 100644 --- a/ethcore/sync/src/lib.rs +++ b/ethcore/sync/src/lib.rs @@ -44,6 +44,8 @@ extern crate ethcore_light as light; #[cfg(test)] extern crate kvdb_memorydb; #[cfg(test)] extern crate rustc_hex; +#[macro_use] +extern crate enum_primitive; #[macro_use] extern crate macros; #[macro_use] diff --git a/ethcore/sync/src/sync_io.rs b/ethcore/sync/src/sync_io.rs index 1bf892e474..56bf98ab2e 100644 --- a/ethcore/sync/src/sync_io.rs +++ b/ethcore/sync/src/sync_io.rs @@ -15,6 +15,7 @@ // along with Parity Ethereum. If not, see . use std::collections::HashMap; +use chain::sync_packet::{PacketInfo, SyncPacket}; use network::{NetworkContext, PeerId, PacketId, Error, SessionInfo, ProtocolId}; use network::client_version::ClientVersion; use bytes::Bytes; @@ -34,7 +35,7 @@ pub trait SyncIo { /// Respond to current request with a packet. Can be called from an IO handler for incoming packet. fn respond(&mut self, packet_id: PacketId, data: Vec) -> Result<(), Error>; /// Send a packet to a peer using specified protocol. - fn send_protocol(&mut self, protocol: ProtocolId, peer_id: PeerId, packet_id: PacketId, data: Vec) -> Result<(), Error>; + fn send(&mut self, peer_id: PeerId, packet_id: SyncPacket, data: Vec) -> Result<(), Error>; /// Get the blockchain fn chain(&self) -> &BlockChainClient; /// Get the snapshot service. @@ -97,8 +98,8 @@ impl<'s> SyncIo for NetSyncIo<'s> { self.network.respond(packet_id, data) } - fn send_protocol(&mut self, protocol: ProtocolId, peer_id: PeerId, packet_id: PacketId, data: Vec) -> Result<(), Error>{ - self.network.send_protocol(protocol, peer_id, packet_id, data) + fn send(&mut self, peer_id: PeerId, packet_id: SyncPacket, data: Vec) -> Result<(), Error>{ + self.network.send_protocol(packet_id.protocol(), peer_id, packet_id.id(), data) } fn chain(&self) -> &BlockChainClient { diff --git a/ethcore/sync/src/tests/helpers.rs b/ethcore/sync/src/tests/helpers.rs index 04ceb3dd3e..8bc4b542e2 100644 --- a/ethcore/sync/src/tests/helpers.rs +++ b/ethcore/sync/src/tests/helpers.rs @@ -30,8 +30,11 @@ use ethcore::miner::Miner; use ethcore::test_helpers; use sync_io::SyncIo; use io::{IoChannel, IoContext, IoHandler}; -use api::{ETH_PROTOCOL, WARP_SYNC_PROTOCOL_ID}; -use chain::{ChainSync, ETH_PROTOCOL_VERSION_63, PAR_PROTOCOL_VERSION_3, PRIVATE_TRANSACTION_PACKET, SyncSupplier, STATUS_PACKET, RECEIPTS_PACKET, GET_SNAPSHOT_MANIFEST_PACKET, SIGNED_PRIVATE_TRANSACTION_PACKET}; +use api::WARP_SYNC_PROTOCOL_ID; +use chain::{ChainSync, SyncSupplier, ETH_PROTOCOL_VERSION_63, PAR_PROTOCOL_VERSION_3}; +use chain::sync_packet::{PacketInfo, SyncPacket}; +use chain::sync_packet::SyncPacket::{PrivateTransactionPacket, SignedPrivateTransactionPacket}; + use SyncConfig; use private_tx::SimplePrivateTxHandler; use types::BlockNumber; @@ -80,16 +83,6 @@ impl<'p, C> Drop for TestIo<'p, C> where C: FlushingBlockChainClient, C: 'p { } } -fn assert_packet_id_matches_protocol(protocol: &ProtocolId, packet_id: &PacketId) { - match packet_id { - STATUS_PACKET ... RECEIPTS_PACKET => assert_eq!(*protocol, ETH_PROTOCOL), - GET_SNAPSHOT_MANIFEST_PACKET ... SIGNED_PRIVATE_TRANSACTION_PACKET => assert_eq!(*protocol, WARP_SYNC_PROTOCOL_ID), - // What about light? - _ => assert!(false) - } -} - - impl<'p, C> SyncIo for TestIo<'p, C> where C: FlushingBlockChainClient, C: 'p { fn disable_peer(&mut self, peer_id: PeerId) { self.disconnect_peer(peer_id); @@ -112,12 +105,10 @@ impl<'p, C> SyncIo for TestIo<'p, C> where C: FlushingBlockChainClient, C: 'p { Ok(()) } - fn send_protocol(&mut self, protocol: ProtocolId, peer_id: PeerId, packet_id: PacketId, data: Vec) -> Result<(), network::Error> { - assert_packet_id_matches_protocol(&protocol, &packet_id); - + fn send(&mut self,peer_id: PeerId, packet_id: SyncPacket, data: Vec) -> Result<(), network::Error> { self.packets.push(TestPacket { data: data, - packet_id: packet_id, + packet_id: packet_id.id(), recipient: peer_id, }); Ok(()) @@ -244,9 +235,9 @@ impl EthPeer where C: FlushingBlockChainClient { match message { ChainMessageType::Consensus(data) => self.sync.write().propagate_consensus_packet(&mut io, data), ChainMessageType::PrivateTransaction(transaction_hash, data) => - self.sync.write().propagate_private_transaction(&mut io, transaction_hash, WARP_SYNC_PROTOCOL_ID, PRIVATE_TRANSACTION_PACKET, data), + self.sync.write().propagate_private_transaction(&mut io, transaction_hash, PrivateTransactionPacket, data), ChainMessageType::SignedPrivateTransaction(transaction_hash, data) => - self.sync.write().propagate_private_transaction(&mut io, transaction_hash, WARP_SYNC_PROTOCOL_ID, SIGNED_PRIVATE_TRANSACTION_PACKET, data), + self.sync.write().propagate_private_transaction(&mut io, transaction_hash, SignedPrivateTransactionPacket, data), } } From 512343003d062d51f105cf07db5bade78bd4a5f4 Mon Sep 17 00:00:00 2001 From: Afri Schoedon <5chdn@users.noreply.github.com> Date: Wed, 13 Feb 2019 15:50:02 +0100 Subject: [PATCH 071/168] snap: prefix version and populate candidate channel (#10343) * snap: populate candidate releases with beta snaps to avoid stale channel * snap: prefix version with v* --- scripts/gitlab/publish-snap.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/scripts/gitlab/publish-snap.sh b/scripts/gitlab/publish-snap.sh index 386abdf370..19cbfa2e6b 100755 --- a/scripts/gitlab/publish-snap.sh +++ b/scripts/gitlab/publish-snap.sh @@ -4,7 +4,7 @@ set -e # fail on any error set -u # treat unset variables as error # some necromancy: -# gsub(/"/, "", $2) deletes "qoutes" +# gsub(/"/, "", $2) deletes "qoutes" # gsub(/ /, "", $2) deletes whitespaces TRACK=`awk -F '=' '/^track/ {gsub(/"/, "", $2); gsub(/ /, "", $2); print $2}' ./util/version/Cargo.toml` echo Track is: $TRACK @@ -16,6 +16,7 @@ case ${TRACK} in *) echo "No release" && exit 0;; esac +VERSION="v"$VERSION SNAP_PACKAGE="parity_"$VERSION"_"$BUILD_ARCH".snap" echo "__________Create snap package__________" @@ -48,5 +49,8 @@ echo "Release channel :" $CHANNEL " Branch/tag: " $CI_COMMIT_REF_NAME echo $SNAPCRAFT_LOGIN_PARITY_BASE64 | base64 --decode > snapcraft.login snapcraft login --with snapcraft.login snapcraft push --release $CHANNEL $SNAP_PACKAGE +case ${CHANNEL} in + beta) snapcraft push --release candidate $SNAP_PACKAGE;; +esac snapcraft status parity snapcraft logout From d6c80c16726eb1015134458bbf6d7d67be583dfa Mon Sep 17 00:00:00 2001 From: Dan Acristinii Date: Thu, 14 Feb 2019 12:25:44 +0100 Subject: [PATCH 072/168] Fixed misstype (#10351) * Fixed misstype BadTransactonType => BadTransactionType * fixed other insances of transacton --- ethcore/private-tx/src/error.rs | 2 +- ethcore/private-tx/src/lib.rs | 8 ++++---- miner/src/pool/tests/mod.rs | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/ethcore/private-tx/src/error.rs b/ethcore/private-tx/src/error.rs index 325b561b76..b3465883f4 100644 --- a/ethcore/private-tx/src/error.rs +++ b/ethcore/private-tx/src/error.rs @@ -76,7 +76,7 @@ error_chain! { } #[doc = "Wrong private transaction type."] - BadTransactonType { + BadTransactionType { description("Wrong private transaction type."), display("Wrong private transaction type"), } diff --git a/ethcore/private-tx/src/lib.rs b/ethcore/private-tx/src/lib.rs index 71a97d6a04..f536e22fbd 100644 --- a/ethcore/private-tx/src/lib.rs +++ b/ethcore/private-tx/src/lib.rs @@ -241,7 +241,7 @@ impl Provider { bail!(ErrorKind::SignerAccountNotSet); } let tx_hash = signed_transaction.hash(); - let contract = Self::contract_address_from_transaction(&signed_transaction).map_err(|_| ErrorKind::BadTransactonType)?; + let contract = Self::contract_address_from_transaction(&signed_transaction).map_err(|_| ErrorKind::BadTransactionType)?; let data = signed_transaction.rlp_bytes(); let encrypted_transaction = self.encrypt(&contract, &Self::iv_from_transaction(&signed_transaction), &data)?; let private = PrivateTransaction::new(encrypted_transaction, contract); @@ -415,7 +415,7 @@ impl Provider { Action::Call(contract) => Ok(contract), _ => { warn!(target: "privatetx", "Incorrect type of action for the transaction"); - bail!(ErrorKind::BadTransactonType); + bail!(ErrorKind::BadTransactionType); } } } @@ -610,7 +610,7 @@ impl Provider { /// Create encrypted public contract deployment transaction. pub fn public_creation_transaction(&self, block: BlockId, source: &SignedTransaction, validators: &[Address], gas_price: U256) -> Result<(Transaction, Address), Error> { if let Action::Call(_) = source.action { - bail!(ErrorKind::BadTransactonType); + bail!(ErrorKind::BadTransactionType); } let sender = source.sender(); let state = self.client.state_at(block).ok_or(ErrorKind::StatePruned)?; @@ -649,7 +649,7 @@ impl Provider { /// 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); + bail!(ErrorKind::BadTransactionType); } let result = self.execute_private(source, TransactOptions::with_no_tracing(), block)?; Ok(result.state) diff --git a/miner/src/pool/tests/mod.rs b/miner/src/pool/tests/mod.rs index ad9f6824fa..0eb223dba0 100644 --- a/miner/src/pool/tests/mod.rs +++ b/miner/src/pool/tests/mod.rs @@ -97,7 +97,7 @@ fn should_return_correct_nonces_when_dropped_because_of_limit() { Ok(()) ]); assert_eq!(txq.status().status.transaction_count, 3); - // tx2 transacton got dropped because of limit + // tx2 transaction got dropped because of limit // tx1 and tx1' are kept, because they have lower insertion_ids so they are preferred. assert_eq!(txq.next_nonce(TestClient::new(), &sender), None); } From bff0bedfa930cd626ebb3a501c5634bcf22d1a77 Mon Sep 17 00:00:00 2001 From: TriplEight Date: Thu, 14 Feb 2019 12:45:56 +0100 Subject: [PATCH 073/168] no volumes are needed, just run -v volume:/path/in/the/container (#10345) --- scripts/docker/hub/Dockerfile | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/docker/hub/Dockerfile b/scripts/docker/hub/Dockerfile index c2249a56d4..a18cacf9cc 100644 --- a/scripts/docker/hub/Dockerfile +++ b/scripts/docker/hub/Dockerfile @@ -25,7 +25,6 @@ COPY scripts/docker/hub/check_sync.sh /check_sync.sh # switch to user parity here USER parity -VOLUME [ "/home/parity/.local/share/io.parity.ethereum" ] EXPOSE 5001 8080 8082 8083 8545 8546 8180 30303/tcp 30303/udp ENTRYPOINT ["/bin/parity"] From 9cce6a47d487988f513cac35c11b1b241fe8e035 Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Thu, 14 Feb 2019 15:54:44 +0100 Subject: [PATCH 074/168] fix(compilation warns): `no-default-features` (#10346) --- parity/account.rs | 2 +- parity/account_utils.rs | 4 ++-- parity/upgrade.rs | 1 + rpc/src/v1/helpers/dispatch/mod.rs | 1 + rpc/src/v1/helpers/errors.rs | 3 +++ rpc/src/v1/helpers/mod.rs | 2 ++ rpc/src/v1/types/derivation.rs | 2 ++ 7 files changed, 12 insertions(+), 3 deletions(-) diff --git a/parity/account.rs b/parity/account.rs index 578e9e7ef8..118c06fdda 100644 --- a/parity/account.rs +++ b/parity/account.rs @@ -58,7 +58,7 @@ pub struct ImportFromGethAccounts { #[cfg(not(feature = "accounts"))] -pub fn execute(cmd: AccountCmd) -> Result { +pub fn execute(_cmd: AccountCmd) -> Result { Err("Account management is deprecated. Please see #9997 for alternatives:\nhttps://github.com/paritytech/parity-ethereum/issues/9997".into()) } diff --git a/parity/account_utils.rs b/parity/account_utils.rs index caaad53e17..6c11ae23b3 100644 --- a/parity/account_utils.rs +++ b/parity/account_utils.rs @@ -30,12 +30,12 @@ mod accounts { pub struct AccountProvider; impl ::ethcore::miner::LocalAccounts for AccountProvider { - fn is_local(&self, address: &Address) -> bool { + fn is_local(&self, _address: &Address) -> bool { false } } - pub fn prepare_account_provider(_spec: &SpecType, _dirs: &Directories, _data_dir: &str, cfg: AccountsConfig, _passwords: &[Password]) -> Result { + pub fn prepare_account_provider(_spec: &SpecType, _dirs: &Directories, _data_dir: &str, _cfg: AccountsConfig, _passwords: &[Password]) -> Result { warn!("Note: Your instance of Parity Ethereum is running without account support. Some CLI options are ignored."); Ok(AccountProvider) } diff --git a/parity/upgrade.rs b/parity/upgrade.rs index 3406e573c7..aa3f6eba13 100644 --- a/parity/upgrade.rs +++ b/parity/upgrade.rs @@ -139,6 +139,7 @@ fn file_exists(path: &Path) -> bool { } } +#[cfg(any(test, feature = "accounts"))] pub fn upgrade_key_location(from: &PathBuf, to: &PathBuf) { match fs::create_dir_all(&to).and_then(|()| fs::read_dir(from)) { Ok(entries) => { diff --git a/rpc/src/v1/helpers/dispatch/mod.rs b/rpc/src/v1/helpers/dispatch/mod.rs index 6df1e88480..d23619f417 100644 --- a/rpc/src/v1/helpers/dispatch/mod.rs +++ b/rpc/src/v1/helpers/dispatch/mod.rs @@ -201,6 +201,7 @@ pub enum SignWith { } impl SignWith { + #[cfg(any(test, feature = "accounts"))] fn is_password(&self) -> bool { if let SignWith::Password(_) = *self { true diff --git a/rpc/src/v1/helpers/errors.rs b/rpc/src/v1/helpers/errors.rs index 30607fde6c..eebd76dbe3 100644 --- a/rpc/src/v1/helpers/errors.rs +++ b/rpc/src/v1/helpers/errors.rs @@ -43,7 +43,9 @@ mod codes { pub const EXECUTION_ERROR: i64 = -32015; pub const EXCEPTION_ERROR: i64 = -32016; pub const DATABASE_ERROR: i64 = -32017; + #[cfg(any(test, feature = "accounts"))] pub const ACCOUNT_LOCKED: i64 = -32020; + #[cfg(any(test, feature = "accounts"))] pub const PASSWORD_INVALID: i64 = -32021; pub const ACCOUNT_ERROR: i64 = -32023; pub const PRIVATE_ERROR: i64 = -32024; @@ -336,6 +338,7 @@ pub fn fetch(error: T) -> Error { } } +#[cfg(any(test, feature = "accounts"))] pub fn invalid_call_data(error: T) -> Error { Error { code: ErrorCode::ServerError(codes::ENCODING_ERROR), diff --git a/rpc/src/v1/helpers/mod.rs b/rpc/src/v1/helpers/mod.rs index 59a62deb74..8a25f93056 100644 --- a/rpc/src/v1/helpers/mod.rs +++ b/rpc/src/v1/helpers/mod.rs @@ -20,6 +20,7 @@ pub mod errors; pub mod block_import; pub mod deprecated; pub mod dispatch; +#[cfg(any(test, feature = "accounts"))] pub mod eip191; #[cfg(any(test, feature = "accounts"))] pub mod engine_signer; @@ -28,6 +29,7 @@ pub mod fake_sign; pub mod ipfs; pub mod light_fetch; pub mod nonce; +#[cfg(any(test, feature = "accounts"))] pub mod secretstore; mod network_settings; diff --git a/rpc/src/v1/types/derivation.rs b/rpc/src/v1/types/derivation.rs index a2947a89f7..4c2f665121 100644 --- a/rpc/src/v1/types/derivation.rs +++ b/rpc/src/v1/types/derivation.rs @@ -70,6 +70,7 @@ impl From for Derive { } /// Error converting request data +#[cfg(any(test, feature = "accounts"))] #[derive(Debug)] pub enum ConvertError { IndexOverlfow(u64), @@ -77,6 +78,7 @@ pub enum ConvertError { impl Derive { /// Convert to account provider struct dealing with possible overflows + #[cfg(any(test, feature = "accounts"))] pub fn to_derivation(self) -> Result { Ok(match self { Derive::Hierarchical(drv) => { From fa570f297ebc27fddab1bbfdaa89d48761a81ef8 Mon Sep 17 00:00:00 2001 From: Afri Schoedon <5chdn@users.noreply.github.com> Date: Thu, 14 Feb 2019 17:24:52 +0100 Subject: [PATCH 075/168] snap: release untagged versions from branches to the candidate snap channel (#10357) --- scripts/gitlab/publish-snap.sh | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/scripts/gitlab/publish-snap.sh b/scripts/gitlab/publish-snap.sh index 19cbfa2e6b..36d5c5d169 100755 --- a/scripts/gitlab/publish-snap.sh +++ b/scripts/gitlab/publish-snap.sh @@ -9,6 +9,7 @@ set -u # treat unset variables as error TRACK=`awk -F '=' '/^track/ {gsub(/"/, "", $2); gsub(/ /, "", $2); print $2}' ./util/version/Cargo.toml` echo Track is: $TRACK +# Choose snap release channel based on parity ethereum version track case ${TRACK} in nightly) export GRADE="devel" CHANNEL="edge";; beta) export GRADE="stable" CHANNEL="beta";; @@ -16,6 +17,11 @@ case ${TRACK} in *) echo "No release" && exit 0;; esac +# Release untagged versions from branches to the candidate snap channel +case ${CI_COMMIT_REF_NAME} in + beta|stable) export GRADE="stable" CHANNEL="candidate";; +esac + VERSION="v"$VERSION SNAP_PACKAGE="parity_"$VERSION"_"$BUILD_ARCH".snap" @@ -49,8 +55,5 @@ echo "Release channel :" $CHANNEL " Branch/tag: " $CI_COMMIT_REF_NAME echo $SNAPCRAFT_LOGIN_PARITY_BASE64 | base64 --decode > snapcraft.login snapcraft login --with snapcraft.login snapcraft push --release $CHANNEL $SNAP_PACKAGE -case ${CHANNEL} in - beta) snapcraft push --release candidate $SNAP_PACKAGE;; -esac snapcraft status parity snapcraft logout From af7dc3676b68a09f3024dbe4e2fc6237e40711a4 Mon Sep 17 00:00:00 2001 From: Hernando Castano Date: Fri, 15 Feb 2019 12:32:33 +0100 Subject: [PATCH 076/168] Add fields to `memzero`'s Cargo.toml (#10362) * Add fields to Cargo.toml before publishing to crates.io * Change license from MIT to GPL-3.0 * Add docs page --- util/memzero/Cargo.toml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/util/memzero/Cargo.toml b/util/memzero/Cargo.toml index 4b62e7adc1..be2e627ffb 100644 --- a/util/memzero/Cargo.toml +++ b/util/memzero/Cargo.toml @@ -1,4 +1,10 @@ [package] name = "memzero" version = "0.1.0" +description = "A wrapper for zero-ing out memory when dropped" +license = "GPL-3.0" +homepage = "https://parity.io" +repository = "https://github.com/paritytech/parity-ethereum" +docs = "https://docs.rs/crate/memzero" authors = ["Parity Technologies "] +edition = "2018" From ef0eda0c39c25938d5523c56b69d9a3622d008b3 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Mon, 18 Feb 2019 15:38:19 +0300 Subject: [PATCH 077/168] SecretStore: use in-memory transport in cluster tests (#9850) * fixing SS tests * removed some redundant clones * fixed grumbles * replaced hash.clone() with *hash + fixed comment * lost files --- secret-store/src/key_server.rs | 37 +- .../servers_set_change_session.rs | 432 +++-- .../admin_sessions/share_add_session.rs | 522 ++---- .../client_sessions/generation_session.rs | 490 ++--- .../client_sessions/signing_session_ecdsa.rs | 243 +-- .../signing_session_schnorr.rs | 443 ++--- .../src/key_server_cluster/cluster.rs | 1569 ++++++----------- .../key_server_cluster/cluster_connections.rs | 176 ++ .../cluster_connections_net.rs | 539 ++++++ .../cluster_message_processor.rs | 357 ++++ .../key_server_cluster/cluster_sessions.rs | 44 +- .../key_server_cluster/connection_trigger.rs | 36 +- .../connection_trigger_with_migration.rs | 76 +- secret-store/src/key_server_cluster/mod.rs | 6 +- secret-store/src/node_key_pair.rs | 5 + .../key_server_cluster/cluster_connections.rs | 176 ++ .../cluster_connections_net.rs | 539 ++++++ .../cluster_message_processor.rs | 357 ++++ 18 files changed, 3562 insertions(+), 2485 deletions(-) create mode 100644 secret-store/src/key_server_cluster/cluster_connections.rs create mode 100644 secret-store/src/key_server_cluster/cluster_connections_net.rs create mode 100644 secret-store/src/key_server_cluster/cluster_message_processor.rs create mode 100644 secret_store/src/key_server_cluster/cluster_connections.rs create mode 100644 secret_store/src/key_server_cluster/cluster_connections_net.rs create mode 100644 secret_store/src/key_server_cluster/cluster_message_processor.rs diff --git a/secret-store/src/key_server.rs b/secret-store/src/key_server.rs index 24d8c8f9e0..3f03e7e259 100644 --- a/secret-store/src/key_server.rs +++ b/secret-store/src/key_server.rs @@ -23,11 +23,11 @@ use parity_runtime::Executor; use super::acl_storage::AclStorage; use super::key_storage::KeyStorage; use super::key_server_set::KeyServerSet; -use key_server_cluster::{math, ClusterCore}; +use key_server_cluster::{math, new_network_cluster}; use traits::{AdminSessionsServer, ServerKeyGenerator, DocumentKeyServer, MessageSigner, KeyServer, NodeKeyPair}; use types::{Error, Public, RequestSignature, Requester, ServerKeyId, EncryptedDocumentKey, EncryptedDocumentKeyShadow, ClusterConfiguration, MessageHash, EncryptedMessageSignature, NodeId}; -use key_server_cluster::{ClusterClient, ClusterConfiguration as NetClusterConfiguration}; +use key_server_cluster::{ClusterClient, ClusterConfiguration as NetClusterConfiguration, NetConnectionsManagerConfig}; /// Secret store key server implementation pub struct KeyServerImpl { @@ -175,20 +175,23 @@ impl KeyServerCore { pub fn new(config: &ClusterConfiguration, key_server_set: Arc, self_key_pair: Arc, acl_storage: Arc, key_storage: Arc, executor: Executor) -> Result { - let config = NetClusterConfiguration { + let cconfig = NetClusterConfiguration { self_key_pair: self_key_pair.clone(), - listen_address: (config.listener_address.address.clone(), config.listener_address.port), key_server_set: key_server_set, - allow_connecting_to_higher_nodes: config.allow_connecting_to_higher_nodes, acl_storage: acl_storage, key_storage: key_storage, - admin_public: config.admin_public.clone(), + admin_public: config.admin_public, + preserve_sessions: false, + }; + let net_config = NetConnectionsManagerConfig { + listen_address: (config.listener_address.address.clone(), config.listener_address.port), + allow_connecting_to_higher_nodes: config.allow_connecting_to_higher_nodes, auto_migrate_enabled: config.auto_migrate_enabled, }; - let cluster = ClusterCore::new(executor, config) - .and_then(|c| c.run().map(|_| c.client())) - .map_err(|err| Error::from(err))?; + let core = new_network_cluster(executor, cconfig, net_config)?; + let cluster = core.client(); + core.run()?; Ok(KeyServerCore { cluster, @@ -297,14 +300,14 @@ pub mod tests { let start = time::Instant::now(); let mut tried_reconnections = false; loop { - if key_servers.iter().all(|ks| ks.cluster().cluster_state().connected.len() == num_nodes - 1) { + if key_servers.iter().all(|ks| ks.cluster().is_fully_connected()) { break; } let old_tried_reconnections = tried_reconnections; let mut fully_connected = true; for key_server in &key_servers { - if key_server.cluster().cluster_state().connected.len() != num_nodes - 1 { + if !key_server.cluster().is_fully_connected() { fully_connected = false; if !old_tried_reconnections { tried_reconnections = true; @@ -434,7 +437,7 @@ pub mod tests { #[test] fn decryption_session_is_delegated_when_node_does_not_have_key_share() { let _ = ::env_logger::try_init(); - let (key_servers, _, runtime) = make_key_servers(6110, 3); + let (key_servers, key_storages, runtime) = make_key_servers(6110, 3); // generate document key let threshold = 0; @@ -445,7 +448,7 @@ pub mod tests { let generated_key = crypto::ecies::decrypt(&secret, &DEFAULT_MAC, &generated_key).unwrap(); // remove key from node0 - key_servers[0].cluster().key_storage().remove(&document).unwrap(); + key_storages[0].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(); @@ -457,7 +460,7 @@ pub mod tests { #[test] fn schnorr_signing_session_is_delegated_when_node_does_not_have_key_share() { let _ = ::env_logger::try_init(); - let (key_servers, _, runtime) = make_key_servers(6114, 3); + let (key_servers, key_storages, runtime) = make_key_servers(6114, 3); let threshold = 1; // generate server key @@ -467,7 +470,7 @@ pub mod tests { let server_public = key_servers[0].generate_key(&server_key_id, &signature.clone().into(), threshold).unwrap(); // remove key from node0 - key_servers[0].cluster().key_storage().remove(&server_key_id).unwrap(); + key_storages[0].remove(&server_key_id).unwrap(); // sign message let message_hash = H256::from(42); @@ -484,7 +487,7 @@ pub mod tests { #[test] fn ecdsa_signing_session_is_delegated_when_node_does_not_have_key_share() { let _ = ::env_logger::try_init(); - let (key_servers, _, runtime) = make_key_servers(6117, 4); + let (key_servers, key_storages, runtime) = make_key_servers(6117, 4); let threshold = 1; // generate server key @@ -494,7 +497,7 @@ pub mod tests { let server_public = key_servers[0].generate_key(&server_key_id, &signature.clone().into(), threshold).unwrap(); // remove key from node0 - key_servers[0].cluster().key_storage().remove(&server_key_id).unwrap(); + key_storages[0].remove(&server_key_id).unwrap(); // sign message let message_hash = H256::random(); diff --git a/secret-store/src/key_server_cluster/admin_sessions/servers_set_change_session.rs b/secret-store/src/key_server_cluster/admin_sessions/servers_set_change_session.rs index 4d3de95005..18c6358795 100644 --- a/secret-store/src/key_server_cluster/admin_sessions/servers_set_change_session.rs +++ b/secret-store/src/key_server_cluster/admin_sessions/servers_set_change_session.rs @@ -1045,148 +1045,204 @@ fn check_nodes_set(all_nodes_set: &BTreeSet, new_nodes_set: &BTreeSet, - pub key_storage: Arc, - pub session: SessionImpl, + pub trait AdminSessionAdapter { + const SIGN_NEW_NODES: bool; + + fn create( + meta: ShareChangeSessionMeta, + admin_public: Public, + all_nodes_set: BTreeSet, + ml: &ClusterMessageLoop, + idx: usize + ) -> S; } - struct MessageLoop { + pub struct MessageLoop { + pub ml: ClusterMessageLoop, pub admin_key_pair: KeyPair, pub original_key_pair: KeyPair, + pub original_key_version: H256, pub all_nodes_set: BTreeSet, pub new_nodes_set: BTreeSet, pub all_set_signature: Signature, pub new_set_signature: Signature, - pub nodes: BTreeMap, + pub sessions: BTreeMap, pub queue: VecDeque<(NodeId, NodeId, Message)>, } - fn create_session(mut meta: ShareChangeSessionMeta, self_node_id: NodeId, admin_public: Public, all_nodes_set: BTreeSet, cluster: Arc, key_storage: Arc) -> SessionImpl { - meta.self_node_id = self_node_id; - SessionImpl::new(SessionParams { - meta: meta, - all_nodes_set: all_nodes_set, - cluster: cluster, - key_storage: key_storage, - nonce: 1, - admin_public: admin_public, - migration_id: None, - }).unwrap() + impl ::std::fmt::Debug for MessageLoop { + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + write!(f, "{:?}", self.ml) + } } - 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()); + struct Adapter; + + impl AdminSessionAdapter for Adapter { + const SIGN_NEW_NODES: bool = true; + + fn create( + mut meta: ShareChangeSessionMeta, + admin_public: Public, + all_nodes_set: BTreeSet, + ml: &ClusterMessageLoop, + idx: usize + ) -> SessionImpl { + meta.self_node_id = *ml.node_key_pair(idx).public(); + SessionImpl::new(SessionParams { + meta: meta, + all_nodes_set: all_nodes_set, + cluster: ml.cluster(idx).view().unwrap(), + key_storage: ml.key_storage(idx).clone(), + nonce: 1, + admin_public: admin_public, + migration_id: None, + }).unwrap() } + } - 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.clone(), node.key_storage.clone()), + impl MessageLoop { + pub fn with_gml>( + gml: GenerationMessageLoop, + master: NodeId, + add: Option>, + removed_nodes_ids: Option>, + isolated_nodes_ids: Option>, + ) -> Self { + // read generated key data + let original_key_pair = gml.compute_key_pair(); + let original_key_version = gml.key_version(); + Self::with_ml::( + gml.0, + original_key_pair, + original_key_version, + master, + add, + removed_nodes_ids, + isolated_nodes_ids) } - } - impl MessageLoop { - 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 { + pub fn and_then>( + self, + master: NodeId, + add: Option>, + removed_nodes_ids: Option>, + isolated_nodes_ids: Option>, + ) -> Self { + Self::with_ml::( + self.ml, + self.original_key_pair, + self.original_key_version, + master, + add, + removed_nodes_ids, + isolated_nodes_ids, + ) + } + + pub fn with_ml>( + mut ml: ClusterMessageLoop, + original_key_pair: KeyPair, + original_key_version: H256, + master: NodeId, + add: Option>, + removed_nodes_ids: Option>, + isolated_nodes_ids: Option>, + ) -> Self { + let add = add.unwrap_or_default(); + let removed_nodes_ids = removed_nodes_ids.unwrap_or_default(); + let isolated_nodes_ids = isolated_nodes_ids.unwrap_or_default(); + // 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 = original_key_pair.unwrap_or_else(|| gml.compute_key_pair(1)); - // all active nodes set - let mut all_nodes_set: BTreeSet<_> = gml.nodes.keys() + let mut all_nodes_set: BTreeSet<_> = ml.nodes().into_iter() .filter(|n| !isolated_nodes_ids.contains(n)) - .cloned() .collect(); // new nodes set includes all old nodes, except nodes being removed + all nodes being added let new_nodes_set: BTreeSet = all_nodes_set.iter().cloned() - .chain(new_nodes_ids.iter().cloned()) + .chain(add.iter().map(|kp| *kp.public())) .filter(|n| !removed_nodes_ids.contains(n)) .collect(); - all_nodes_set.extend(new_nodes_ids.iter().cloned()); + let mut old_set_to_sign = all_nodes_set.clone(); + all_nodes_set.extend(add.iter().map(|kp| *kp.public())); + if C::SIGN_NEW_NODES { + old_set_to_sign.extend(add.iter().map(|kp| *kp.public())); + } for isolated_node_id in &isolated_nodes_ids { all_nodes_set.remove(isolated_node_id); } let meta = ShareChangeSessionMeta { - self_node_id: master_node_id.clone(), - master_node_id: master_node_id.clone(), + self_node_id: master, + master_node_id: master, id: SessionId::default(), configured_nodes_count: all_nodes_set.len(), connected_nodes_count: all_nodes_set.len(), }; - 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 { - new_node_cluster.add_node(node.clone()); - } - - let new_node_key_storage = Arc::new(DummyKeyStorage::default()); - let new_node_session = create_session(meta.clone(), new_node_id, admin_public.clone(), all_nodes_set.clone(), new_node_cluster.clone(), new_node_key_storage.clone()); - Node { - cluster: new_node_cluster, - key_storage: new_node_key_storage, - session: new_node_session, - } - }); - let nodes: BTreeMap<_, _> = old_nodes.chain(new_nodes).map(|n| (n.session.core.meta.self_node_id.clone(), n)).collect(); - - for node in nodes.values() { - for isolated_node_id in &isolated_nodes_ids { - node.cluster.remove_node(isolated_node_id); - } + // include new nodes in the cluster + for node_key_pair in &add { + ml.include(Arc::new(PlainNodeKeyPair::new(node_key_pair.clone()))); } + // isolate nodes from the cluster + for isolated_node_id in &isolated_nodes_ids { + let idx = ml.nodes().iter().position(|n| n == isolated_node_id).unwrap(); + ml.exclude(idx); + } + + // prepare set of nodes + let sessions: BTreeMap<_, _> = (0..ml.nodes().len()) + .map(|idx| (ml.node(idx), C::create(meta.clone(), admin_public, all_nodes_set.clone(), &ml, idx))) + .collect(); - let all_set_signature = sign(admin_key_pair.secret(), &ordered_nodes_hash(&all_nodes_set)).unwrap(); + let all_set_signature = sign(admin_key_pair.secret(), &ordered_nodes_hash(&old_set_to_sign)).unwrap(); let new_set_signature = sign(admin_key_pair.secret(), &ordered_nodes_hash(&new_nodes_set)).unwrap(); MessageLoop { + ml, admin_key_pair: admin_key_pair, - original_key_pair: original_key_pair, + original_key_pair, + original_key_version, all_nodes_set: all_nodes_set.clone(), new_nodes_set: new_nodes_set, all_set_signature: all_set_signature, new_set_signature: new_set_signature, - nodes: nodes, + sessions, queue: Default::default(), } } pub fn run(&mut self) { + // run session until completion while let Some((from, to, message)) = self.take_message() { self.process_message((from, to, message)).unwrap(); } + + // check that all sessions have finished + assert!(self.sessions.values().all(|s| s.is_finished())); } pub fn take_message(&mut self) -> Option<(NodeId, NodeId, Message)> { - self.nodes.values() - .filter_map(|n| n.cluster.take_message().map(|m| (n.session.core.meta.self_node_id.clone(), m.0, m.1))) - .nth(0) - .or_else(|| self.queue.pop_front()) + self.ml.take_message().or_else(|| self.queue.pop_front()) } pub fn process_message(&mut self, msg: (NodeId, NodeId, Message)) -> Result<(), Error> { - match { match msg.2 { - Message::ServersSetChange(ref message) => self.nodes[&msg.1].session.process_message(&msg.0, message), - _ => unreachable!("only servers set change messages are expected"), - } } { + match self.sessions[&msg.1].on_message(&msg.0, &msg.2) { Ok(_) => Ok(()), Err(Error::TooEarlyForRequest) => { self.queue.push_back(msg); @@ -1195,213 +1251,201 @@ pub mod tests { Err(err) => Err(err), } } + + /// This only works for schemes where threshold = 1 + pub fn check_secret_is_preserved<'a, I: IntoIterator>(&self, nodes: I) { + let nodes: Vec<_> = nodes.into_iter().collect(); + let key_storages: Vec<_> = nodes.iter().map(|n| self.ml.key_storage_of(n)).collect(); + let n = nodes.len(); + let document_secret_plain = math::generate_random_point().unwrap(); + for n1 in 0..n { + for n2 in n1+1..n { + let share1 = key_storages[n1].get(&SessionId::default()).unwrap(); + let share2 = key_storages[n2].get(&SessionId::default()).unwrap(); + + let id_number1 = share1.as_ref().unwrap().last_version().unwrap().id_numbers[nodes[n1]].clone(); + let id_number2 = share1.as_ref().unwrap().last_version().unwrap().id_numbers[nodes[n2]].clone(); + // now encrypt and decrypt data + let (document_secret_decrypted, document_secret_decrypted_test) = + math::tests::do_encryption_and_decryption(1, + self.original_key_pair.public(), + &[id_number1, id_number2], + &[share1.unwrap().last_version().unwrap().secret_share.clone(), + share2.unwrap().last_version().unwrap().secret_share.clone()], + Some(self.original_key_pair.secret()), + document_secret_plain.clone()); + + assert_eq!(document_secret_plain, document_secret_decrypted_test); + assert_eq!(document_secret_plain, document_secret_decrypted); + } + } + } } - pub fn generate_key(threshold: usize, nodes_ids: BTreeSet) -> GenerationMessageLoop { - let mut gml = GenerationMessageLoop::with_nodes_ids(nodes_ids); - gml.master().initialize(Default::default(), Default::default(), false, threshold, gml.nodes.keys().cloned().collect::>().into()).unwrap(); - while let Some((from, to, message)) = gml.take_message() { - gml.process_message((from, to, message)).unwrap(); + impl MessageLoop { + pub fn run_at(mut self, master: NodeId) -> Self { + self.sessions[&master].initialize( + self.new_nodes_set.clone(), + self.all_set_signature.clone(), + self.new_set_signature.clone()).unwrap(); + self.run(); + self } + } + + pub fn generate_key(num_nodes: usize, threshold: usize) -> GenerationMessageLoop { + let gml = GenerationMessageLoop::new(num_nodes).init(threshold).unwrap(); + gml.0.loop_until(|| gml.0.is_empty()); gml } #[test] fn node_added_using_servers_set_change() { // 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(); + let gml = generate_key(3, 1); - // 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, 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(); + // add 1 node so that it becames 2-of-4 session + let add = vec![Random.generate().unwrap()]; + let master = gml.0.node(0); + let ml = MessageLoop::with_gml::(gml, master, Some(add), None, None).run_at(master); // try to recover secret for every possible combination of nodes && check that secret is the same - check_secret_is_preserved(ml.original_key_pair.clone(), ml.nodes.iter().map(|(k, v)| (k.clone(), v.key_storage.clone())).collect()); - - // check that all sessions have finished - assert!(ml.nodes.values().all(|n| n.session.is_finished())); + ml.check_secret_is_preserved(ml.sessions.keys()); } #[test] fn node_added_using_server_set_change_from_this_node() { // initial 2-of-3 session - let gml = generate_key(1, generate_nodes_ids(3)); + let gml = generate_key(3, 1); // insert 1 node so that it becames 2-of-4 session // master node is the node we are adding => // 1) add session is delegated to one of old nodes // 2) key share is pushed to new node // 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, 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(); - - // check that all sessions have finished - assert!(ml.nodes.values().all(|n| n.session.is_finished())); + let add = vec![Random.generate().unwrap()]; + let master = add[0].public().clone(); + let ml = MessageLoop::with_gml::(gml, master, Some(add), None, None).run_at(master); + + // try to recover secret for every possible combination of nodes && check that secret is the same + ml.check_secret_is_preserved(ml.sessions.keys()); } #[test] fn node_moved_using_servers_set_change() { // 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(); + let gml = generate_key(3, 1); // 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, 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(); + let master = gml.0.node(0); + let remove: BTreeSet<_> = ::std::iter::once(gml.0.node(1)).collect(); + let add = vec![Random.generate().unwrap()]; + let ml = MessageLoop::with_gml::(gml, master, Some(add), Some(remove.clone()), None).run_at(master); // check that secret is still the same as before moving the share - check_secret_is_preserved(ml.original_key_pair.clone(), ml.nodes.iter() - .filter(|&(k, _)| !nodes_to_remove.contains(k)) - .map(|(k, v)| (k.clone(), v.key_storage.clone())) - .collect()); + ml.check_secret_is_preserved(ml.sessions.keys() + .filter(|k| !remove.contains(k))); // 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())); + assert!(ml.sessions.keys().filter(|k| remove.contains(k)) + .all(|k| ml.ml.key_storage_of(k).get(&SessionId::default()).unwrap().is_none())); } #[test] fn node_removed_using_servers_set_change() { // 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(); + let gml = generate_key(3, 1); // 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, 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(); + let remove: BTreeSet<_> = ::std::iter::once(gml.0.node(0)).collect(); + let master = gml.0.node(0); + let ml = MessageLoop::with_gml::(gml, master, None, Some(remove.clone()), None).run_at(master); // try to recover secret for every possible combination of nodes && check that secret is the same - check_secret_is_preserved(ml.original_key_pair.clone(), ml.nodes.iter() - .filter(|&(k, _)| !nodes_to_remove.contains(k)) - .map(|(k, v)| (k.clone(), v.key_storage.clone())) - .collect()); + ml.check_secret_is_preserved(ml.sessions.keys() + .filter(|k| !remove.contains(k))); // 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())); + assert!(ml.sessions.keys().filter(|k| remove.contains(k)) + .all(|k| ml.ml.key_storage_of(k).get(&SessionId::default()).unwrap().is_none())); } #[test] fn isolated_node_removed_using_servers_set_change() { // 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(); + let gml = generate_key(3, 1); // 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, 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(); + let isolate: BTreeSet<_> = ::std::iter::once(gml.0.node(1)).collect(); + let master = gml.0.node(0); + let ml = MessageLoop::with_gml::(gml, master, None, None, Some(isolate.clone())) + .run_at(master); // try to recover secret for every possible combination of nodes && check that secret is the same - check_secret_is_preserved(ml.original_key_pair.clone(), ml.nodes.iter() - .filter(|&(k, _)| !nodes_to_isolate.contains(k)) - .map(|(k, v)| (k.clone(), v.key_storage.clone())) - .collect()); + ml.check_secret_is_preserved(ml.sessions.keys() + .filter(|k| !isolate.contains(k))); // check that all isolated nodes still OWN key share - assert!(ml.nodes.iter().filter(|&(k, _)| nodes_to_isolate.contains(k)).all(|(_, v)| v.key_storage.get(&SessionId::default()).unwrap().is_some())); - - // check that all sessions have finished - assert!(ml.nodes.iter().filter(|&(k, _)| !nodes_to_isolate.contains(k)).all(|(_, v)| v.session.is_finished())); + assert!(ml.sessions.keys().filter(|k| isolate.contains(k)) + .all(|k| ml.ml.key_storage_of(k).get(&SessionId::default()).unwrap().is_some())); } #[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(); + let gml = generate_key(3, 1); - // 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(); + // remove 2 nodes so that key becomes irrecoverable (make sure the session is completed + // even though key is irrecoverable) + let remove: BTreeSet<_> = gml.0.nodes().into_iter().skip(1).take(2).collect(); + let master = gml.0.node(0); + let ml = MessageLoop::with_gml::(gml, master, None, Some(remove.clone()), None).run_at(master); // 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())); + assert!(ml.sessions.keys().filter(|k| remove.contains(k)) + .all(|k| ml.ml.key_storage_of(k).get(&SessionId::default()).unwrap().is_none())); // 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(); + let add = vec![Random.generate().unwrap()]; + let master = add[0].public().clone(); + let ml = ml.and_then::(master, Some(add.clone()), None, Some(remove)).run_at(master); // 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())); + assert!(ml.sessions.keys().filter(|k| add.iter().any(|n| n.public() == *k)) + .all(|k| ml.ml.key_storage_of(k).get(&SessionId::default()).unwrap().is_none())); } #[test] fn removing_node_from_cluster_of_2_works() { // initial 2-of-2 session - let gml = generate_key(1, generate_nodes_ids(2)); - let master_node_id = gml.nodes.keys().cloned().nth(0).unwrap(); - - // make 2nd node isolated so that key becomes irrecoverable (make sure the session is completed, even though key is irrecoverable) - 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, 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(); - - // check that session on master node has completed (session on 2nd node is not even started in network mode) - assert!(ml.nodes.values().take(1).all(|n| n.session.is_finished())); + let gml = generate_key(2, 1); + + // make 2nd node isolated so that key becomes irrecoverable (make sure the session is completed, + // even though key is irrecoverable) + let isolate: BTreeSet<_> = gml.0.nodes().into_iter().skip(1).take(1).collect(); + let master = gml.0.node(0); + MessageLoop::with_gml::(gml, master, None, None, Some(isolate)).run_at(master); } #[test] fn adding_node_that_has_lost_its_database_works() { // initial 2-of-2 session - let gml = generate_key(1, generate_nodes_ids(2)); - let master_node_id = gml.nodes.keys().cloned().nth(0).unwrap(); + let gml = generate_key(2, 1); // insert 1 node so that it becames 2-of-3 session - let nodes_to_add: BTreeSet<_> = (0..1).map(|_| Random.generate().unwrap().public().clone()).collect(); - let mut ml = MessageLoop::new(&gml, master_node_id, None, nodes_to_add.clone(), 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(); + let add = vec![Random.generate().unwrap()]; + let master = gml.0.node(0); + let ml = MessageLoop::with_gml::(gml, master, Some(add.clone()), None, None) + .run_at(master); // now let's say new node has lost its db and we're trying to join it again - ml.nodes[nodes_to_add.iter().nth(0).unwrap()].key_storage.clear().unwrap(); + ml.ml.key_storage_of(add[0].public()).clear().unwrap(); // this time old nodes have version, where new node is mentioned, but it doesn't report it when negotiating - 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(); + let ml = ml.and_then::(master, Some(add), None, None).run_at(master); // try to recover secret for every possible combination of nodes && check that secret is the same - check_secret_is_preserved(ml.original_key_pair.clone(), ml.nodes.iter().map(|(k, v)| (k.clone(), v.key_storage.clone())).collect()); - - // check that all sessions have finished - assert!(ml.nodes.values().all(|n| n.session.is_finished())); + ml.check_secret_is_preserved(ml.sessions.keys()); } } diff --git a/secret-store/src/key_server_cluster/admin_sessions/share_add_session.rs b/secret-store/src/key_server_cluster/admin_sessions/share_add_session.rs index 0c771006a5..e2af7bc7fa 100644 --- a/secret-store/src/key_server_cluster/admin_sessions/share_add_session.rs +++ b/secret-store/src/key_server_cluster/admin_sessions/share_add_session.rs @@ -318,6 +318,7 @@ impl SessionImpl where T: SessionTransport { new_set_signature), consensus_transport: consensus_transport, })?; + consensus_session.initialize(new_nodes_map.keys().cloned().collect())?; // update data @@ -881,405 +882,197 @@ impl SessionTransport for IsolatedSessionTransport { #[cfg(test)] pub mod tests { - use std::sync::Arc; - use std::collections::{VecDeque, BTreeMap, BTreeSet, HashSet}; - use ethkey::{Random, Generator, Public, KeyPair, Signature, sign}; - use ethereum_types::H256; - use key_server_cluster::{NodeId, SessionId, Error, KeyStorage, DummyKeyStorage}; - use key_server_cluster::cluster::Cluster; - use key_server_cluster::cluster::tests::DummyCluster; - use key_server_cluster::cluster_sessions::ClusterSession; - use key_server_cluster::generation_session::tests::{Node as GenerationNode, generate_nodes_ids}; - use key_server_cluster::math; - use key_server_cluster::message::Message; - use key_server_cluster::servers_set_change_session::tests::generate_key; - use key_server_cluster::jobs::servers_set_change_access_job::ordered_nodes_hash; + use std::collections::BTreeSet; + use ethkey::{Random, Generator, Public}; + use key_server_cluster::{NodeId, Error, KeyStorage, NodeKeyPair}; + use key_server_cluster::cluster::tests::MessageLoop as ClusterMessageLoop; + use key_server_cluster::servers_set_change_session::tests::{MessageLoop, AdminSessionAdapter, generate_key}; use key_server_cluster::admin_sessions::ShareChangeSessionMeta; use super::{SessionImpl, SessionParams, IsolatedSessionTransport}; - struct Node { - pub cluster: Arc, - pub key_storage: Arc, - pub session: SessionImpl, - } - - struct MessageLoop { - pub admin_key_pair: KeyPair, - pub original_key_pair: KeyPair, - pub old_nodes_set: BTreeSet, - pub new_nodes_set: BTreeSet, - pub old_set_signature: Signature, - pub new_set_signature: Signature, - pub nodes: BTreeMap, - pub queue: VecDeque<(NodeId, NodeId, Message)>, - pub version: H256, - } - - fn create_session(mut meta: ShareChangeSessionMeta, admin_public: Public, self_node_id: NodeId, cluster: Arc, key_storage: Arc) -> SessionImpl { - let session_id = meta.id.clone(); - meta.self_node_id = self_node_id; - let key_version = key_storage.get(&session_id).unwrap().map(|ks| ks.versions.iter().last().unwrap().hash.clone()); - - SessionImpl::new(SessionParams { - meta: meta.clone(), - transport: IsolatedSessionTransport::new(session_id, key_version, 1, cluster), - key_storage: key_storage, - admin_public: Some(admin_public), - nonce: 1, - }).unwrap() - } - - fn create_node(meta: ShareChangeSessionMeta, admin_public: Public, node: GenerationNode, added_nodes: &BTreeSet) -> Node { - node.cluster.add_nodes(added_nodes.iter().cloned()); - Node { - cluster: node.cluster.clone(), - key_storage: node.key_storage.clone(), - session: create_session(meta, admin_public, node.session.node().clone(), node.cluster, node.key_storage), - } - } - - /// This only works for schemes where threshold = 1 - pub fn check_secret_is_preserved(joint_key_pair: KeyPair, nodes: BTreeMap>) { - let n = nodes.len(); - let document_secret_plain = math::generate_random_point().unwrap(); - for n1 in 0..n { - for n2 in n1+1..n { - let share1 = nodes.values().nth(n1).unwrap().get(&SessionId::default()).unwrap(); - let share2 = nodes.values().nth(n2).unwrap().get(&SessionId::default()).unwrap(); - let id_number1 = share1.as_ref().unwrap().last_version().unwrap().id_numbers[nodes.keys().nth(n1).unwrap()].clone(); - let id_number2 = share1.as_ref().unwrap().last_version().unwrap().id_numbers[nodes.keys().nth(n2).unwrap()].clone(); - - // now encrypt and decrypt data - let (document_secret_decrypted, document_secret_decrypted_test) = - math::tests::do_encryption_and_decryption(1, - joint_key_pair.public(), - &[id_number1, id_number2], - &[share1.unwrap().last_version().unwrap().secret_share.clone(), - share2.unwrap().last_version().unwrap().secret_share.clone()], - Some(joint_key_pair.secret()), - document_secret_plain.clone()); - - assert_eq!(document_secret_plain, document_secret_decrypted_test); - assert_eq!(document_secret_plain, document_secret_decrypted); - } + struct Adapter; + + impl AdminSessionAdapter> for Adapter { + const SIGN_NEW_NODES: bool = false; + + fn create( + mut meta: ShareChangeSessionMeta, + admin_public: Public, + _: BTreeSet, + ml: &ClusterMessageLoop, + idx: usize + ) -> SessionImpl { + let key_storage = ml.key_storage(idx).clone(); + let key_version = key_storage.get(&meta.id).unwrap().map(|ks| ks.last_version().unwrap().hash); + + meta.self_node_id = *ml.node_key_pair(idx).public(); + SessionImpl::new(SessionParams { + meta: meta.clone(), + transport: IsolatedSessionTransport::new(meta.id, key_version, 1, ml.cluster(idx).view().unwrap()), + key_storage, + admin_public: Some(admin_public), + nonce: 1, + }).unwrap() } } - impl MessageLoop { - pub fn new(t: usize, master_node_id: NodeId, old_nodes_set: BTreeSet, new_nodes_set: BTreeSet) -> Self { - // generate admin key pair - let admin_key_pair = Random.generate().unwrap(); - let admin_public = admin_key_pair.public().clone(); - - // run initial generation session - let gml = generate_key(t, old_nodes_set.clone()); - - // compute original secret key - let version = gml.nodes.values().nth(0).unwrap().key_storage.get(&Default::default()).unwrap().unwrap().versions[0].hash.clone(); - let original_key_pair = gml.compute_key_pair(t); - - // prepare sessions on all nodes - let meta = ShareChangeSessionMeta { - id: SessionId::default(), - self_node_id: NodeId::default(), - master_node_id: master_node_id, - configured_nodes_count: new_nodes_set.iter().chain(old_nodes_set.iter()).collect::>().len(), - connected_nodes_count: new_nodes_set.iter().chain(old_nodes_set.iter()).collect::>().len(), - }; - let new_nodes = new_nodes_set.iter() - .filter(|n| !old_nodes_set.contains(&n)) - .map(|new_node_id| { - let new_node_cluster = Arc::new(DummyCluster::new(new_node_id.clone())); - let new_node_key_storage = Arc::new(DummyKeyStorage::default()); - let new_node_session = create_session(meta.clone(), admin_public.clone(), new_node_id.clone(), new_node_cluster.clone(), new_node_key_storage.clone()); - new_node_cluster.add_nodes(new_nodes_set.iter().cloned()); - Node { - cluster: new_node_cluster, - key_storage: new_node_key_storage, - session: new_node_session, - } - }); - let old_nodes = gml.nodes.into_iter().map(|gn| create_node(meta.clone(), admin_public.clone(), gn.1, &new_nodes_set)); - let nodes = old_nodes.chain(new_nodes).map(|n| (n.session.core.meta.self_node_id.clone(), n)).collect(); - - let old_set_signature = sign(admin_key_pair.secret(), &ordered_nodes_hash(&old_nodes_set)).unwrap(); - let new_set_signature = sign(admin_key_pair.secret(), &ordered_nodes_hash(&new_nodes_set)).unwrap(); - MessageLoop { - admin_key_pair: admin_key_pair, - original_key_pair: original_key_pair, - version: version, - old_nodes_set: old_nodes_set.clone(), - new_nodes_set: new_nodes_set.clone(), - old_set_signature: old_set_signature, - new_set_signature: new_set_signature, - nodes: nodes, - queue: Default::default(), - } - } - - pub fn new_additional(master_node_id: NodeId, ml: MessageLoop, new_nodes_set: BTreeSet) -> Self { - let version = ml.nodes.values().nth(0).unwrap().key_storage.get(&Default::default()).unwrap().unwrap().versions.last().unwrap().hash.clone(); - - // prepare sessions on all nodes - let meta = ShareChangeSessionMeta { - id: SessionId::default(), - self_node_id: NodeId::default(), - master_node_id: master_node_id, - configured_nodes_count: new_nodes_set.iter().chain(ml.nodes.keys()).collect::>().len(), - connected_nodes_count: new_nodes_set.iter().chain(ml.nodes.keys()).collect::>().len(), - }; - let old_nodes_set = ml.nodes.keys().cloned().collect(); - let nodes = ml.nodes.iter() - .map(|(n, nd)| { - let node_cluster = nd.cluster.clone(); - let node_key_storage = nd.key_storage.clone(); - let node_session = create_session(meta.clone(), ml.admin_key_pair.public().clone(), n.clone(), node_cluster.clone(), node_key_storage.clone()); - node_cluster.add_nodes(new_nodes_set.iter().cloned()); - (n.clone(), Node { - cluster: node_cluster, - key_storage: node_key_storage, - session: node_session, - }) - }).chain(new_nodes_set.difference(&old_nodes_set).map(|n| { - let new_node_cluster = Arc::new(DummyCluster::new(n.clone())); - let new_node_key_storage = Arc::new(DummyKeyStorage::default()); - let new_node_session = create_session(meta.clone(), ml.admin_key_pair.public().clone(), n.clone(), new_node_cluster.clone(), new_node_key_storage.clone()); - new_node_cluster.add_nodes(new_nodes_set.iter().cloned()); - (n.clone(), Node { - cluster: new_node_cluster, - key_storage: new_node_key_storage, - session: new_node_session, - }) - })).collect(); - - let old_set_signature = sign(ml.admin_key_pair.secret(), &ordered_nodes_hash(&old_nodes_set)).unwrap(); - let new_set_signature = sign(ml.admin_key_pair.secret(), &ordered_nodes_hash(&new_nodes_set)).unwrap(); - MessageLoop { - admin_key_pair: ml.admin_key_pair, - original_key_pair: ml.original_key_pair, - version: version, - old_nodes_set: old_nodes_set.clone(), - new_nodes_set: new_nodes_set.clone(), - old_set_signature: old_set_signature, - new_set_signature: new_set_signature, - nodes: nodes, - queue: Default::default(), - } + impl MessageLoop> { + pub fn init_at(self, master: NodeId) -> Result { + self.sessions[&master].initialize( + Some(self.original_key_version), + Some(self.new_nodes_set.clone()), + Some(self.all_set_signature.clone()), + Some(self.new_set_signature.clone()))?; + Ok(self) } - pub fn update_signature(&mut self) { - self.old_set_signature = sign(self.admin_key_pair.secret(), &ordered_nodes_hash(&self.old_nodes_set)).unwrap(); - self.new_set_signature = sign(self.admin_key_pair.secret(), &ordered_nodes_hash(&self.new_nodes_set)).unwrap(); - } - - pub fn run(&mut self) { - while let Some((from, to, message)) = self.take_message() { - self.process_message((from, to, message)).unwrap(); - } - } - - pub fn take_message(&mut self) -> Option<(NodeId, NodeId, Message)> { - self.nodes.values() - .filter_map(|n| n.cluster.take_message().map(|m| (n.session.core.meta.self_node_id.clone(), m.0, m.1))) - .nth(0) - .or_else(|| self.queue.pop_front()) - } - - pub fn process_message(&mut self, msg: (NodeId, NodeId, Message)) -> Result<(), Error> { - match { match msg.2 { - Message::ShareAdd(ref message) => - self.nodes[&msg.1].session.process_message(&msg.0, message), - _ => unreachable!("only servers set change messages are expected"), - } } { - Ok(_) => Ok(()), - Err(Error::TooEarlyForRequest) => { - self.queue.push_back(msg); - Ok(()) - }, - Err(err) => Err(err), - } + pub fn run_at(self, master: NodeId) -> Result { + let mut ml = self.init_at(master)?; + ml.run(); + Ok(ml) } } #[test] fn node_add_fails_if_nodes_removed() { - let old_nodes_set = generate_nodes_ids(3); - let master_node_id = old_nodes_set.iter().cloned().nth(0).unwrap(); - let node_to_remove_id = old_nodes_set.iter().cloned().nth(1).unwrap(); - let mut new_nodes_set: BTreeSet<_> = old_nodes_set.clone().into_iter().chain(generate_nodes_ids(1)).collect(); - new_nodes_set.remove(&node_to_remove_id); - let ml = MessageLoop::new(1, master_node_id.clone(), old_nodes_set, new_nodes_set.clone()); - assert_eq!(ml.nodes[&master_node_id].session.initialize(Some(ml.version), Some(new_nodes_set), - Some(ml.old_set_signature.clone()), - Some(ml.new_set_signature.clone()) - ).unwrap_err(), Error::ConsensusUnreachable); + // initial 2-of-3 session + let gml = generate_key(3, 1); + + // try to remove 1 node + let add = vec![Random.generate().unwrap()]; + let remove: BTreeSet<_> = ::std::iter::once(gml.0.node(1)).collect(); + let master = gml.0.node(0); + assert_eq!(MessageLoop::with_gml::(gml, master, Some(add), Some(remove), None) + .run_at(master).unwrap_err(), Error::ConsensusUnreachable); } #[test] fn node_add_fails_if_no_nodes_added() { - let old_nodes_set = generate_nodes_ids(3); - let master_node_id = old_nodes_set.iter().cloned().nth(0).unwrap(); - let new_nodes_set = old_nodes_set.clone(); - let ml = MessageLoop::new(1, master_node_id.clone(), old_nodes_set, new_nodes_set.clone()); - assert_eq!(ml.nodes[&master_node_id].session.initialize(Some(ml.version), Some(new_nodes_set), - Some(ml.old_set_signature.clone()), - Some(ml.new_set_signature.clone()) - ).unwrap_err(), Error::ConsensusUnreachable); + // initial 2-of-3 session + let gml = generate_key(3, 1); + + // try to add 0 nodes + let add = vec![]; + let master = gml.0.node(0); + assert_eq!(MessageLoop::with_gml::(gml, master, Some(add), None, None) + .run_at(master).unwrap_err(), Error::ConsensusUnreachable); } #[test] fn node_add_fails_if_started_on_adding_node() { - let old_nodes_set = generate_nodes_ids(3); - let nodes_to_add_set = generate_nodes_ids(1); - let master_node_id = nodes_to_add_set.iter().cloned().nth(0).unwrap(); - let new_nodes_set: BTreeSet<_> = old_nodes_set.clone().into_iter().chain(nodes_to_add_set.into_iter()).collect(); - let ml = MessageLoop::new(1, master_node_id.clone(), old_nodes_set, new_nodes_set.clone()); - assert_eq!(ml.nodes[&master_node_id].session.initialize(Some(ml.version), Some(new_nodes_set), - Some(ml.old_set_signature.clone()), - Some(ml.new_set_signature.clone()) - ).unwrap_err(), Error::ServerKeyIsNotFound); + // initial 2-of-3 session + let gml = generate_key(3, 1); + + // try to add 1 node using this node as a master node + let add = vec![Random.generate().unwrap()]; + let master = *add[0].public(); + assert_eq!(MessageLoop::with_gml::(gml, master, Some(add), None, None) + .run_at(master).unwrap_err(), Error::ServerKeyIsNotFound); } #[test] fn node_add_fails_if_initialized_twice() { - let old_nodes_set = generate_nodes_ids(3); - let master_node_id = old_nodes_set.iter().cloned().nth(0).unwrap(); - let new_nodes_set: BTreeSet<_> = old_nodes_set.clone().into_iter().chain(generate_nodes_ids(1)).collect(); - let ml = MessageLoop::new(1, master_node_id.clone(), old_nodes_set, new_nodes_set.clone()); - assert_eq!(ml.nodes[&master_node_id].session.initialize(Some(ml.version), Some(new_nodes_set.clone()), - Some(ml.old_set_signature.clone()), - Some(ml.new_set_signature.clone()) - ), Ok(())); - assert_eq!(ml.nodes[&master_node_id].session.initialize(Some(ml.version), Some(new_nodes_set), - Some(ml.old_set_signature.clone()), - Some(ml.new_set_signature.clone()) - ), Err(Error::InvalidStateForRequest)); + // initial 2-of-3 session + let gml = generate_key(3, 1); + + // try to add 1 node using this node as a master node + let add = vec![Random.generate().unwrap()]; + let master = gml.0.node(0); + assert_eq!(MessageLoop::with_gml::(gml, master, Some(add), None, None) + .init_at(master).unwrap() + .init_at(master).unwrap_err(), Error::InvalidStateForRequest); } #[test] fn node_add_fails_if_started_without_signatures() { - let old_nodes_set = generate_nodes_ids(3); - let master_node_id = old_nodes_set.iter().cloned().nth(0).unwrap(); - let new_nodes_set: BTreeSet<_> = old_nodes_set.clone().into_iter().chain(generate_nodes_ids(1)).collect(); - let ml = MessageLoop::new(1, master_node_id.clone(), old_nodes_set, new_nodes_set.clone()); - assert_eq!(ml.nodes[&master_node_id].session.initialize(None, None, None, None), Err(Error::InvalidMessage)); + // initial 2-of-3 session + let gml = generate_key(3, 1); + + // try to add 1 node using this node as a master node + let add = vec![Random.generate().unwrap()]; + let master = gml.0.node(0); + assert_eq!(MessageLoop::with_gml::(gml, master, Some(add), None, None) + .sessions[&master] + .initialize(None, None, None, None).unwrap_err(), Error::InvalidMessage); } #[test] fn nodes_added_using_share_add() { let test_cases = vec![(3, 1), (3, 3)]; - for (n, nodes_to_add) in test_cases { - // generate key && prepare ShareAdd sessions - let old_nodes_set = generate_nodes_ids(n); - let new_nodes_set: BTreeSet<_> = old_nodes_set.clone().into_iter().chain(generate_nodes_ids(nodes_to_add)).collect(); - let master_node_id = old_nodes_set.iter().cloned().nth(0).unwrap(); - let mut ml = MessageLoop::new(1, master_node_id.clone(), old_nodes_set, new_nodes_set.clone()); - - // initialize session on master node && run to completion - ml.nodes[&master_node_id].session.initialize(Some(ml.version), Some(new_nodes_set), - Some(ml.old_set_signature.clone()), - Some(ml.new_set_signature.clone())).unwrap(); - ml.run(); + for (n, add) in test_cases { + // generate key + let gml = generate_key(n, 1); - // check that session has completed on all nodes - assert!(ml.nodes.values().all(|n| n.session.is_finished())); + // run share add session + let add = (0..add).map(|_| Random.generate().unwrap()).collect(); + let master = gml.0.node(0); + let ml = MessageLoop::with_gml::(gml, master, Some(add), None, None) + .run_at(master).unwrap(); // check that secret is still the same as before adding the share - check_secret_is_preserved(ml.original_key_pair.clone(), ml.nodes.iter().map(|(k, v)| (k.clone(), v.key_storage.clone())).collect()); + ml.check_secret_is_preserved(ml.sessions.keys()); } } #[test] fn nodes_added_using_share_add_with_isolated_nodes() { - let (n, nodes_to_add) = (3, 3); - - // generate key && prepare ShareAdd sessions - let old_nodes_set = generate_nodes_ids(n); - let new_nodes_set: BTreeSet<_> = old_nodes_set.clone().into_iter().chain(generate_nodes_ids(nodes_to_add)).collect(); - let master_node_id = old_nodes_set.iter().cloned().nth(0).unwrap(); - let isolated_node_id = old_nodes_set.iter().cloned().nth(1).unwrap(); - let mut ml = MessageLoop::new(1, master_node_id.clone(), old_nodes_set, new_nodes_set.clone()); - - // now let's isolate 1 of 3 nodes owning key share - ml.nodes.remove(&isolated_node_id); - ml.old_nodes_set.remove(&isolated_node_id); - ml.new_nodes_set.remove(&isolated_node_id); - for (_, node) in ml.nodes.iter_mut() { - node.cluster.remove_node(&isolated_node_id); - } - ml.update_signature(); + let (n, add) = (3, 3); - // initialize session on master node && run to completion - ml.nodes[&master_node_id].session.initialize(Some(ml.version), Some(new_nodes_set), - Some(ml.old_set_signature.clone()), - Some(ml.new_set_signature.clone())).unwrap(); - ml.run(); + // generate key + let gml = generate_key(n, 1); - // check that session has completed on all nodes - assert!(ml.nodes.values().all(|n| n.session.is_finished())); + // run share add session + let master = gml.0.node(0); + let node_to_isolate = gml.0.node(1); + let add = (0..add).map(|_| Random.generate().unwrap()).collect(); + let isolate = ::std::iter::once(node_to_isolate).collect(); + let ml = MessageLoop::with_gml::(gml, master, Some(add), None, Some(isolate)) + .run_at(master).unwrap(); // check that secret is still the same as before adding the share - check_secret_is_preserved(ml.original_key_pair.clone(), ml.nodes - .iter() - .map(|(k, v)| (k.clone(), v.key_storage.clone())) - .collect()); + ml.check_secret_is_preserved(ml.sessions.keys()); } #[test] fn nodes_add_to_the_node_with_obsolete_version() { - let (n, nodes_to_add) = (3, 3); - - // generate key (2-of-3) && prepare ShareAdd sessions - let old_nodes_set = generate_nodes_ids(n); - let newest_nodes_set = generate_nodes_ids(nodes_to_add); - let new_nodes_set: BTreeSet<_> = old_nodes_set.clone().into_iter().chain(newest_nodes_set.clone()).collect(); - let master_node_id = old_nodes_set.iter().cloned().nth(0).unwrap(); - let isolated_node_id = old_nodes_set.iter().cloned().nth(1).unwrap(); - let oldest_nodes_set: BTreeSet<_> = old_nodes_set.iter().filter(|n| **n != isolated_node_id).cloned().collect(); - let mut ml = MessageLoop::new(1, master_node_id.clone(), old_nodes_set.clone(), new_nodes_set.clone()); - let isolated_key_storage = ml.nodes[&isolated_node_id].key_storage.clone(); - - // now let's isolate 1 of 3 nodes owning key share - ml.nodes.remove(&isolated_node_id); - ml.old_nodes_set.remove(&isolated_node_id); - ml.new_nodes_set.remove(&isolated_node_id); - for (_, node) in ml.nodes.iter_mut() { - node.cluster.remove_node(&isolated_node_id); - } - ml.update_signature(); - - // initialize session on master node && run to completion (2-of-5) - ml.nodes[&master_node_id].session.initialize(Some(ml.version), Some(new_nodes_set), - Some(ml.old_set_signature.clone()), - Some(ml.new_set_signature.clone())).unwrap(); - ml.run(); + let (n, add) = (3, 3); + + // generate key + let gml = generate_key(n, 1); + + // run share add session + let master = gml.0.node(0); + let node_to_isolate_key_pair = gml.0.node_key_pair(1).clone(); + let node_to_isolate = gml.0.node(1); + let isolated_key_storage = gml.0.key_storage(1).clone(); + let mut oldest_nodes_set = gml.0.nodes(); + oldest_nodes_set.remove(&node_to_isolate); + let add = (0..add).map(|_| Random.generate().unwrap()).collect::>(); + let newest_nodes_set = add.iter().map(|kp| *kp.public()).collect::>(); + let isolate = ::std::iter::once(node_to_isolate).collect(); + let ml = MessageLoop::with_gml::(gml, master, Some(add), None, Some(isolate)) + .run_at(master).unwrap(); + let new_key_version = ml.ml.key_storage(0).get(&Default::default()) + .unwrap().unwrap().last_version().unwrap().hash; // now let's add back old node so that key becames 2-of-6 - let new_nodes_set: BTreeSet<_> = ml.nodes.keys().cloned().chain(::std::iter::once(isolated_node_id.clone())).collect(); - let mut ml = MessageLoop::new_additional(master_node_id.clone(), ml, new_nodes_set.clone()); - ml.nodes.get_mut(&isolated_node_id).unwrap().key_storage = isolated_key_storage.clone(); - ml.nodes.get_mut(&isolated_node_id).unwrap().session.core.key_share = isolated_key_storage.get(&Default::default()).unwrap(); - ml.nodes.get_mut(&isolated_node_id).unwrap().session.core.key_storage = isolated_key_storage; - - // initialize session on master node && run to completion (2-of65) - ml.nodes[&master_node_id].session.initialize(Some(ml.version), Some(new_nodes_set), - Some(ml.old_set_signature.clone()), - Some(ml.new_set_signature.clone())).unwrap(); - ml.run(); - - // check that session has completed on all nodes - assert!(ml.nodes.values().all(|n| n.session.is_finished())); + let add = vec![node_to_isolate_key_pair.key_pair().clone()]; + let mut ml = ml.and_then::(master.clone(), Some(add), None, None); + ml.original_key_version = new_key_version; + ml.ml.replace_key_storage_of(&node_to_isolate, isolated_key_storage.clone()); + ml.sessions.get_mut(&node_to_isolate).unwrap().core.key_share = + isolated_key_storage.get(&Default::default()).unwrap(); + ml.sessions.get_mut(&node_to_isolate).unwrap().core.key_storage = isolated_key_storage; + let ml = ml.run_at(master).unwrap(); // check that secret is still the same as before adding the share - check_secret_is_preserved(ml.original_key_pair.clone(), ml.nodes - .iter() - .map(|(k, v)| (k.clone(), v.key_storage.clone())) - .collect()); + ml.check_secret_is_preserved(ml.sessions.keys()); // check that all oldest nodes have versions A, B, C // isolated node has version A, C // new nodes have versions B, C - let oldest_key_share = ml.nodes[oldest_nodes_set.iter().nth(0).unwrap()].key_storage.get(&Default::default()).unwrap().unwrap(); + let oldest_key_share = ml.ml.key_storage_of(oldest_nodes_set.iter().nth(0).unwrap()) + .get(&Default::default()).unwrap().unwrap(); debug_assert_eq!(oldest_key_share.versions.len(), 3); let version_a = oldest_key_share.versions[0].hash.clone(); let version_b = oldest_key_share.versions[1].hash.clone(); @@ -1287,41 +1080,28 @@ pub mod tests { debug_assert!(version_a != version_b && version_b != version_c); debug_assert!(oldest_nodes_set.iter().all(|n| vec![version_a.clone(), version_b.clone(), version_c.clone()] == - ml.nodes[n].key_storage.get(&Default::default()).unwrap().unwrap().versions.iter().map(|v| v.hash.clone()).collect::>())); - debug_assert!(::std::iter::once(&isolated_node_id).all(|n| vec![version_a.clone(), version_c.clone()] == - ml.nodes[n].key_storage.get(&Default::default()).unwrap().unwrap().versions.iter().map(|v| v.hash.clone()).collect::>())); + ml.ml.key_storage_of(n).get(&Default::default()).unwrap().unwrap() + .versions.iter().map(|v| v.hash).collect::>())); + debug_assert!(::std::iter::once(&node_to_isolate).all(|n| vec![version_a.clone(), version_c.clone()] == + ml.ml.key_storage_of(n).get(&Default::default()).unwrap().unwrap() + .versions.iter().map(|v| v.hash).collect::>())); debug_assert!(newest_nodes_set.iter().all(|n| vec![version_b.clone(), version_c.clone()] == - ml.nodes[n].key_storage.get(&Default::default()).unwrap().unwrap().versions.iter().map(|v| v.hash.clone()).collect::>())); + ml.ml.key_storage_of(n).get(&Default::default()).unwrap().unwrap() + .versions.iter().map(|v| v.hash).collect::>())); } #[test] fn nodes_add_fails_when_not_enough_share_owners_are_connected() { - let (n, nodes_to_add) = (3, 3); - - // generate key (2-of-3) && prepare ShareAdd sessions - let old_nodes_set = generate_nodes_ids(n); - let new_nodes_set: BTreeSet<_> = old_nodes_set.clone().into_iter().chain(generate_nodes_ids(nodes_to_add)).collect(); - let master_node_id = old_nodes_set.iter().cloned().nth(0).unwrap(); - let isolated_node_id1 = old_nodes_set.iter().cloned().nth(1).unwrap(); - let isolated_node_id2 = old_nodes_set.iter().cloned().nth(2).unwrap(); - let mut ml = MessageLoop::new(1, master_node_id.clone(), old_nodes_set.clone(), new_nodes_set.clone()); - - // now let's isolate 2 of 3 nodes owning key share - ml.nodes.remove(&isolated_node_id1); - ml.nodes.remove(&isolated_node_id2); - ml.old_nodes_set.remove(&isolated_node_id1); - ml.new_nodes_set.remove(&isolated_node_id1); - ml.old_nodes_set.remove(&isolated_node_id2); - ml.new_nodes_set.remove(&isolated_node_id2); - for (_, node) in ml.nodes.iter_mut() { - node.cluster.remove_node(&isolated_node_id1); - node.cluster.remove_node(&isolated_node_id2); - } - ml.update_signature(); + let (n, add) = (3, 3); + + // generate key + let gml = generate_key(n, 1); - // initialize session on master node && run to completion (2-of-5) - assert_eq!(ml.nodes[&master_node_id].session.initialize(Some(ml.version), Some(new_nodes_set), - Some(ml.old_set_signature.clone()), - Some(ml.new_set_signature.clone())).map(|_| ()), Err(Error::ConsensusUnreachable)); + // run share add session + let master = gml.0.node(0); + let add = (0..add).map(|_| Random.generate().unwrap()).collect::>(); + let isolate = vec![gml.0.node(1), gml.0.node(2)].into_iter().collect(); + assert_eq!(MessageLoop::with_gml::(gml, master, Some(add), None, Some(isolate)) + .run_at(master).unwrap_err(), Error::ConsensusUnreachable); } } 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 da2ffebc72..0fa805f571 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 @@ -940,406 +940,315 @@ fn check_threshold(threshold: usize, nodes: &BTreeSet) -> Result<(), Err #[cfg(test)] pub mod tests { use std::sync::Arc; - use std::collections::{BTreeSet, BTreeMap, VecDeque}; - use std::time::Duration; - use ethereum_types::Address; - use ethkey::{Random, Generator, KeyPair}; - use key_server_cluster::{NodeId, SessionId, Error, KeyStorage, DummyKeyStorage}; - use key_server_cluster::message::{self, Message, GenerationMessage}; - use key_server_cluster::cluster::tests::{DummyCluster, make_clusters, run_clusters, loop_until, - all_connections_established, new_runtime}; + use ethereum_types::H256; + use ethkey::{Random, Generator, KeyPair, Secret}; + use key_server_cluster::{NodeId, Error, KeyStorage}; + use key_server_cluster::message::{self, Message, GenerationMessage, KeysDissemination, + PublicKeyShare, ConfirmInitialization}; + use key_server_cluster::cluster::tests::{MessageLoop as ClusterMessageLoop, make_clusters_and_preserve_sessions}; use key_server_cluster::cluster_sessions::ClusterSession; - use key_server_cluster::generation_session::{SessionImpl, SessionState, SessionParams}; + use key_server_cluster::generation_session::{SessionImpl, SessionState}; use key_server_cluster::math; use key_server_cluster::math::tests::do_encryption_and_decryption; - pub struct Node { - pub cluster: Arc, - pub key_storage: Arc, - pub session: SessionImpl, - } - - pub struct MessageLoop { - pub session_id: SessionId, - pub nodes: BTreeMap, - pub queue: VecDeque<(NodeId, NodeId, Message)>, - } - - pub fn generate_nodes_ids(n: usize) -> BTreeSet { - (0..n).map(|_| math::generate_random_point().unwrap()).collect() - } + #[derive(Debug)] + pub struct MessageLoop(pub ClusterMessageLoop); impl MessageLoop { - pub fn new(nodes_num: usize) -> Self { - Self::with_nodes_ids(generate_nodes_ids(nodes_num)) + pub fn new(num_nodes: usize) -> Self { + MessageLoop(make_clusters_and_preserve_sessions(num_nodes)) } - pub fn with_nodes_ids(nodes_ids: BTreeSet) -> Self { - let mut nodes = BTreeMap::new(); - let session_id = SessionId::default(); - for node_id in nodes_ids { - let cluster = Arc::new(DummyCluster::new(node_id.clone())); - let key_storage = Arc::new(DummyKeyStorage::default()); - let session = SessionImpl::new(SessionParams { - id: session_id.clone(), - self_node_id: node_id.clone(), - key_storage: Some(key_storage.clone()), - cluster: cluster.clone(), - nonce: Some(0), - }); - nodes.insert(node_id, Node { cluster: cluster, key_storage: key_storage, session: session }); - } - - let nodes_ids: Vec<_> = nodes.keys().cloned().collect(); - for node in nodes.values() { - for node_id in &nodes_ids { - node.cluster.add_node(node_id.clone()); - } - } - - MessageLoop { - session_id: session_id, - nodes: nodes, - queue: VecDeque::new(), - } + pub fn init(self, threshold: usize) -> Result { + self.0.cluster(0).client().new_generation_session(Default::default(), None, Default::default(), threshold) + .map(|_| self) } - pub fn master(&self) -> &SessionImpl { - &self.nodes.values().nth(0).unwrap().session + pub fn session_at(&self, idx: usize) -> Arc { + self.0.sessions(idx).generation_sessions.first().unwrap() } - pub fn first_slave(&self) -> &SessionImpl { - &self.nodes.values().nth(1).unwrap().session + pub fn session_of(&self, node: &NodeId) -> Arc { + self.0.sessions_of(node).generation_sessions.first().unwrap() } - pub fn second_slave(&self) -> &SessionImpl { - &self.nodes.values().nth(2).unwrap().session + pub fn take_message_confirm_initialization(&self) -> (NodeId, NodeId, ConfirmInitialization) { + match self.0.take_message() { + Some((from, to, Message::Generation(GenerationMessage::ConfirmInitialization(msg)))) => + (from, to, msg), + _ => panic!("unexpected"), + } } - pub fn take_message(&mut self) -> Option<(NodeId, NodeId, Message)> { - self.nodes.values() - .filter_map(|n| n.cluster.take_message().map(|m| (n.session.node().clone(), m.0, m.1))) - .nth(0) - .or_else(|| self.queue.pop_front()) + pub fn take_message_keys_dissemination(&self) -> (NodeId, NodeId, KeysDissemination) { + match self.0.take_message() { + Some((from, to, Message::Generation(GenerationMessage::KeysDissemination(msg)))) => + (from, to, msg), + _ => panic!("unexpected"), + } } - pub fn process_message(&mut self, msg: (NodeId, NodeId, Message)) -> Result<(), Error> { - match { - match msg.2 { - Message::Generation(GenerationMessage::InitializeSession(ref message)) => self.nodes[&msg.1].session.on_initialize_session(msg.0.clone(), &message), - Message::Generation(GenerationMessage::ConfirmInitialization(ref message)) => self.nodes[&msg.1].session.on_confirm_initialization(msg.0.clone(), &message), - Message::Generation(GenerationMessage::CompleteInitialization(ref message)) => self.nodes[&msg.1].session.on_complete_initialization(msg.0.clone(), &message), - Message::Generation(GenerationMessage::KeysDissemination(ref message)) => self.nodes[&msg.1].session.on_keys_dissemination(msg.0.clone(), &message), - Message::Generation(GenerationMessage::PublicKeyShare(ref message)) => self.nodes[&msg.1].session.on_public_key_share(msg.0.clone(), &message), - Message::Generation(GenerationMessage::SessionCompleted(ref message)) => self.nodes[&msg.1].session.on_session_completed(msg.0.clone(), &message), - _ => panic!("unexpected"), - } - } { - Ok(_) => Ok(()), - Err(Error::TooEarlyForRequest) => { - self.queue.push_back(msg); - Ok(()) - }, - Err(err) => Err(err), + pub fn take_message_public_key_share(&self) -> (NodeId, NodeId, PublicKeyShare) { + match self.0.take_message() { + Some((from, to, Message::Generation(GenerationMessage::PublicKeyShare(msg)))) => + (from, to, msg), + _ => panic!("unexpected"), } } - pub fn take_and_process_message(&mut self) -> Result<(), Error> { - let msg = self.take_message().unwrap(); - self.process_message(msg) + pub fn nodes_id_numbers(&self) -> Vec { + let session = self.session_at(0); + let session_data = session.data.lock(); + session_data.nodes.values().map(|n| n.id_number.clone()).collect() } - pub fn compute_key_pair(&self, t: usize) -> KeyPair { - let secret_shares = self.nodes.values() - .map(|nd| nd.key_storage.get(&SessionId::default()).unwrap().unwrap().last_version().unwrap().secret_share.clone()) - .take(t + 1) - .collect::>(); - let secret_shares = secret_shares.iter().collect::>(); - let id_numbers = self.nodes.iter() - .map(|(n, nd)| nd.key_storage.get(&SessionId::default()).unwrap().unwrap().last_version().unwrap().id_numbers[n].clone()) - .take(t + 1) - .collect::>(); - let id_numbers = id_numbers.iter().collect::>(); - let joint_secret1 = math::compute_joint_secret_from_shares(t, &secret_shares, &id_numbers).unwrap(); - - let secret_values: Vec<_> = self.nodes.values().map(|s| s.session.joint_public_and_secret().unwrap().unwrap().1).collect(); - let joint_secret2 = math::compute_joint_secret(secret_values.iter()).unwrap(); - assert_eq!(joint_secret1, joint_secret2); - - KeyPair::from_secret(joint_secret1).unwrap() + pub fn nodes_secret_shares(&self) -> Vec { + (0..self.0.nodes().len()).map(|i| { + let session = self.session_at(i); + let session_data = session.data.lock(); + session_data.secret_share.as_ref().unwrap().clone() + }).collect() } - } - fn make_simple_cluster(threshold: usize, num_nodes: usize) -> Result<(SessionId, NodeId, NodeId, MessageLoop), Error> { - let l = MessageLoop::new(num_nodes); - l.master().initialize(Default::default(), Default::default(), false, threshold, l.nodes.keys().cloned().collect::>().into())?; + pub fn compute_key_pair(&self) -> KeyPair { + let t = self.0.key_storage(0).get(&Default::default()).unwrap().unwrap().threshold; + let secret_shares = self.nodes_secret_shares(); + let id_numbers = self.nodes_id_numbers(); + let secret_shares = secret_shares.iter().take(t + 1).collect::>(); + let id_numbers = id_numbers.iter().take(t + 1).collect::>(); + let joint_secret = math::compute_joint_secret_from_shares(t, &secret_shares, &id_numbers).unwrap(); + + KeyPair::from_secret(joint_secret).unwrap() + } - let session_id = l.session_id.clone(); - let master_id = l.master().node().clone(); - let slave_id = l.first_slave().node().clone(); - Ok((session_id, master_id, slave_id, l)) + pub fn key_version(&self) -> H256 { + self.0.key_storage(0).get(&Default::default()) + .unwrap().unwrap().versions.iter().last().unwrap().hash + } } #[test] fn initializes_in_cluster_of_single_node() { - let l = MessageLoop::new(1); - assert!(l.master().initialize(Default::default(), Default::default(), false, 0, l.nodes.keys().cloned().collect::>().into()).is_ok()); + MessageLoop::new(1).init(0).unwrap(); } #[test] fn fails_to_initialize_if_threshold_is_wrong() { - match make_simple_cluster(2, 2) { - Err(Error::NotEnoughNodesForThreshold) => (), - _ => panic!("unexpected"), - } + assert_eq!(MessageLoop::new(2).init(2).unwrap_err(), Error::NotEnoughNodesForThreshold); } #[test] fn fails_to_initialize_when_already_initialized() { - let (_, _, _, l) = make_simple_cluster(0, 2).unwrap(); - assert_eq!(l.master().initialize(Default::default(), Default::default(), false, 0, l.nodes.keys().cloned().collect::>().into()).unwrap_err(), - Error::InvalidStateForRequest); + let ml = MessageLoop::new(2).init(0).unwrap(); + assert_eq!( + ml.session_at(0).initialize(Default::default(), Default::default(), false, 0, ml.0.nodes().into()), + Err(Error::InvalidStateForRequest), + ); } #[test] fn fails_to_accept_initialization_when_already_initialized() { - let (_, _, _, mut l) = make_simple_cluster(0, 2).unwrap(); - let message = l.take_message().unwrap(); - l.process_message(message.clone()).unwrap(); - assert_eq!(l.process_message(message.clone()).unwrap_err(), Error::InvalidStateForRequest); + let ml = MessageLoop::new(2).init(0).unwrap(); + let (from, to, msg) = ml.0.take_message().unwrap(); + ml.0.process_message(from, to, msg.clone()); + assert_eq!( + ml.session_of(&to).on_message(&from, &msg), + Err(Error::InvalidStateForRequest), + ); } #[test] fn slave_updates_derived_point_on_initialization() { - let (_, _, _, mut l) = make_simple_cluster(0, 2).unwrap(); - let passed_point = match l.take_message().unwrap() { - (f, t, Message::Generation(GenerationMessage::InitializeSession(message))) => { - let point = message.derived_point.clone(); - l.process_message((f, t, Message::Generation(GenerationMessage::InitializeSession(message)))).unwrap(); - point + let ml = MessageLoop::new(2).init(0).unwrap(); + let original_point = match ml.0.take_message().unwrap() { + (from, to, Message::Generation(GenerationMessage::InitializeSession(msg))) => { + let original_point = msg.derived_point.clone(); + let msg = Message::Generation(GenerationMessage::InitializeSession(msg)); + ml.0.process_message(from, to, msg); + original_point }, _ => panic!("unexpected"), }; - match l.take_message().unwrap() { - (_, _, Message::Generation(GenerationMessage::ConfirmInitialization(message))) => assert!(passed_point != message.derived_point), + match ml.0.take_message().unwrap() { + (_, _, Message::Generation(GenerationMessage::ConfirmInitialization(msg))) => + assert!(original_point != msg.derived_point), _ => panic!("unexpected"), } } #[test] fn fails_to_accept_initialization_confirmation_if_already_accepted_from_the_same_node() { - let (sid, _, s, mut l) = make_simple_cluster(0, 3).unwrap(); - l.take_and_process_message().unwrap(); - l.take_and_process_message().unwrap(); - l.take_and_process_message().unwrap(); - assert_eq!(l.master().on_confirm_initialization(s, &message::ConfirmInitialization { - session: sid.into(), - session_nonce: 0, - derived_point: math::generate_random_point().unwrap().into(), - }).unwrap_err(), Error::InvalidStateForRequest); + let ml = MessageLoop::new(3).init(0).unwrap(); + ml.0.take_and_process_message(); + + let (from, to, msg) = ml.take_message_confirm_initialization(); + ml.0.process_message(from, to, Message::Generation(GenerationMessage::ConfirmInitialization(msg.clone()))); + assert_eq!(ml.session_of(&to).on_confirm_initialization(from, &msg), Err(Error::InvalidStateForRequest)); } #[test] fn fails_to_accept_initialization_confirmation_if_initialization_already_completed() { - let (sid, _, s, mut l) = make_simple_cluster(0, 2).unwrap(); - l.take_and_process_message().unwrap(); - l.take_and_process_message().unwrap(); - assert_eq!(l.master().on_confirm_initialization(s, &message::ConfirmInitialization { - session: sid.into(), + let ml = MessageLoop::new(2).init(0).unwrap(); + ml.0.take_and_process_message(); + ml.0.take_and_process_message(); + assert_eq!(ml.session_at(0).on_confirm_initialization(ml.0.node(1), &message::ConfirmInitialization { + session: Default::default(), session_nonce: 0, derived_point: math::generate_random_point().unwrap().into(), - }).unwrap_err(), Error::InvalidStateForRequest); + }), Err(Error::InvalidStateForRequest)); } #[test] fn master_updates_derived_point_on_initialization_completion() { - let (_, _, _, mut l) = make_simple_cluster(0, 2).unwrap(); - l.take_and_process_message().unwrap(); - let passed_point = match l.take_message().unwrap() { - (f, t, Message::Generation(GenerationMessage::ConfirmInitialization(message))) => { - let point = message.derived_point.clone(); - l.process_message((f, t, Message::Generation(GenerationMessage::ConfirmInitialization(message)))).unwrap(); - point + let ml = MessageLoop::new(2).init(0).unwrap(); + ml.0.take_and_process_message(); + let original_point = match ml.0.take_message().unwrap() { + (from, to, Message::Generation(GenerationMessage::ConfirmInitialization(msg))) => { + let original_point = msg.derived_point.clone(); + let msg = Message::Generation(GenerationMessage::ConfirmInitialization(msg)); + ml.session_of(&to).on_message(&from, &msg).unwrap(); + original_point }, _ => panic!("unexpected"), }; - assert!(l.master().derived_point().unwrap() != passed_point.into()); - } - - #[test] - fn fails_to_complete_initialization_if_threshold_is_wrong() { - let (sid, m, s, l) = make_simple_cluster(0, 2).unwrap(); - let mut nodes = BTreeMap::new(); - nodes.insert(m, math::generate_random_scalar().unwrap()); - nodes.insert(s, math::generate_random_scalar().unwrap()); - assert_eq!(l.first_slave().on_initialize_session(m, &message::InitializeSession { - session: sid.into(), - session_nonce: 0, - origin: None, - author: Address::default().into(), - nodes: nodes.into_iter().map(|(k, v)| (k.into(), v.into())).collect(), - is_zero: false, - threshold: 2, - derived_point: math::generate_random_point().unwrap().into(), - }).unwrap_err(), Error::NotEnoughNodesForThreshold); + assert!(ml.session_at(0).derived_point().unwrap() != original_point.into()); } #[test] fn fails_to_complete_initialization_if_not_waiting_for_it() { - let (sid, m, _, l) = make_simple_cluster(0, 2).unwrap(); - assert_eq!(l.first_slave().on_complete_initialization(m, &message::CompleteInitialization { - session: sid.into(), + let ml = MessageLoop::new(2).init(0).unwrap(); + ml.0.take_and_process_message(); + assert_eq!(ml.session_at(0).on_complete_initialization(ml.0.node(1), &message::CompleteInitialization { + session: Default::default(), session_nonce: 0, derived_point: math::generate_random_point().unwrap().into(), - }).unwrap_err(), Error::InvalidStateForRequest); + }), Err(Error::InvalidStateForRequest)); } #[test] fn fails_to_complete_initialization_from_non_master_node() { - let (sid, _, _, mut l) = make_simple_cluster(0, 3).unwrap(); - l.take_and_process_message().unwrap(); - l.take_and_process_message().unwrap(); - l.take_and_process_message().unwrap(); - l.take_and_process_message().unwrap(); - assert_eq!(l.first_slave().on_complete_initialization(l.second_slave().node().clone(), &message::CompleteInitialization { - session: sid.into(), + let ml = MessageLoop::new(3).init(0).unwrap(); + ml.0.take_and_process_message(); + ml.0.take_and_process_message(); + ml.0.take_and_process_message(); + ml.0.take_and_process_message(); + assert_eq!(ml.session_at(1).on_complete_initialization(ml.0.node(2), &message::CompleteInitialization { + session: Default::default(), session_nonce: 0, derived_point: math::generate_random_point().unwrap().into(), - }).unwrap_err(), Error::InvalidMessage); + }), Err(Error::InvalidMessage)); } #[test] fn fails_to_accept_keys_dissemination_if_not_waiting_for_it() { - let (sid, _, s, l) = make_simple_cluster(0, 2).unwrap(); - assert_eq!(l.master().on_keys_dissemination(s, &message::KeysDissemination { - session: sid.into(), + let ml = MessageLoop::new(2).init(0).unwrap(); + assert_eq!(ml.session_at(0).on_keys_dissemination(ml.0.node(1), &message::KeysDissemination { + session: Default::default(), session_nonce: 0, secret1: math::generate_random_scalar().unwrap().into(), secret2: math::generate_random_scalar().unwrap().into(), publics: vec![math::generate_random_point().unwrap().into()], - }).unwrap_err(), Error::TooEarlyForRequest); + }), Err(Error::TooEarlyForRequest)); } #[test] fn fails_to_accept_keys_dissemination_if_wrong_number_of_publics_passed() { - let (sid, m, _, mut l) = make_simple_cluster(0, 3).unwrap(); - l.take_and_process_message().unwrap(); // m -> s1: InitializeSession - l.take_and_process_message().unwrap(); // m -> s2: InitializeSession - l.take_and_process_message().unwrap(); // s1 -> m: ConfirmInitialization - l.take_and_process_message().unwrap(); // s2 -> m: ConfirmInitialization - l.take_and_process_message().unwrap(); // m -> s1: CompleteInitialization - l.take_and_process_message().unwrap(); // m -> s2: CompleteInitialization - l.take_and_process_message().unwrap(); // m -> s1: KeysDissemination - assert_eq!(l.first_slave().on_keys_dissemination(m, &message::KeysDissemination { - session: sid.into(), - session_nonce: 0, - secret1: math::generate_random_scalar().unwrap().into(), - secret2: math::generate_random_scalar().unwrap().into(), - publics: vec![math::generate_random_point().unwrap().into(), math::generate_random_point().unwrap().into()], - }).unwrap_err(), Error::InvalidMessage); + let ml = MessageLoop::new(3).init(0).unwrap(); + ml.0.take_and_process_message(); // m -> s1: InitializeSession + ml.0.take_and_process_message(); // m -> s2: InitializeSession + ml.0.take_and_process_message(); // s1 -> m: ConfirmInitialization + ml.0.take_and_process_message(); // s2 -> m: ConfirmInitialization + ml.0.take_and_process_message(); // m -> s1: CompleteInitialization + ml.0.take_and_process_message(); // m -> s2: CompleteInitialization + + let (from, to, mut msg) = ml.take_message_keys_dissemination(); + msg.publics.clear(); + assert_eq!(ml.session_of(&to).on_keys_dissemination(from, &msg), Err(Error::InvalidMessage)); } #[test] fn fails_to_accept_keys_dissemination_second_time_from_the_same_node() { - let (sid, m, _, mut l) = make_simple_cluster(0, 3).unwrap(); - l.take_and_process_message().unwrap(); // m -> s1: InitializeSession - l.take_and_process_message().unwrap(); // m -> s2: InitializeSession - l.take_and_process_message().unwrap(); // s1 -> m: ConfirmInitialization - l.take_and_process_message().unwrap(); // s2 -> m: ConfirmInitialization - l.take_and_process_message().unwrap(); // m -> s1: CompleteInitialization - l.take_and_process_message().unwrap(); // m -> s2: CompleteInitialization - l.take_and_process_message().unwrap(); // m -> s1: KeysDissemination - assert_eq!(l.first_slave().on_keys_dissemination(m, &message::KeysDissemination { - session: sid.into(), - session_nonce: 0, - secret1: math::generate_random_scalar().unwrap().into(), - secret2: math::generate_random_scalar().unwrap().into(), - publics: vec![math::generate_random_point().unwrap().into()], - }).unwrap_err(), Error::InvalidStateForRequest); + let ml = MessageLoop::new(3).init(0).unwrap(); + ml.0.take_and_process_message(); // m -> s1: InitializeSession + ml.0.take_and_process_message(); // m -> s2: InitializeSession + ml.0.take_and_process_message(); // s1 -> m: ConfirmInitialization + ml.0.take_and_process_message(); // s2 -> m: ConfirmInitialization + ml.0.take_and_process_message(); // m -> s1: CompleteInitialization + ml.0.take_and_process_message(); // m -> s2: CompleteInitialization + + let (from, to, msg) = ml.take_message_keys_dissemination(); + ml.0.process_message(from, to, Message::Generation(GenerationMessage::KeysDissemination(msg.clone()))); + assert_eq!(ml.session_of(&to).on_keys_dissemination(from, &msg), Err(Error::InvalidStateForRequest)); } #[test] fn should_not_accept_public_key_share_when_is_not_waiting_for_it() { - let (sid, _, s, l) = make_simple_cluster(1, 3).unwrap(); - assert_eq!(l.master().on_public_key_share(s, &message::PublicKeyShare { - session: sid.into(), + let ml = MessageLoop::new(3).init(1).unwrap(); + assert_eq!(ml.session_at(0).on_public_key_share(ml.0.node(1), &message::PublicKeyShare { + session: Default::default(), session_nonce: 0, public_share: math::generate_random_point().unwrap().into(), - }).unwrap_err(), Error::InvalidStateForRequest); + }), Err(Error::InvalidStateForRequest)); } #[test] fn should_not_accept_public_key_share_when_receiving_twice() { - let (sid, m, _, mut l) = make_simple_cluster(0, 3).unwrap(); - l.take_and_process_message().unwrap(); // m -> s1: InitializeSession - l.take_and_process_message().unwrap(); // m -> s2: InitializeSession - l.take_and_process_message().unwrap(); // s1 -> m: ConfirmInitialization - l.take_and_process_message().unwrap(); // s2 -> m: ConfirmInitialization - l.take_and_process_message().unwrap(); // m -> s1: CompleteInitialization - l.take_and_process_message().unwrap(); // m -> s2: CompleteInitialization - l.take_and_process_message().unwrap(); // m -> s1: KeysDissemination - l.take_and_process_message().unwrap(); // m -> s2: KeysDissemination - l.take_and_process_message().unwrap(); // s1 -> m: KeysDissemination - l.take_and_process_message().unwrap(); // s1 -> s2: KeysDissemination - l.take_and_process_message().unwrap(); // s2 -> m: KeysDissemination - l.take_and_process_message().unwrap(); // s2 -> s1: KeysDissemination - let (f, t, msg) = match l.take_message() { - Some((f, t, Message::Generation(GenerationMessage::PublicKeyShare(msg)))) => (f, t, msg), - _ => panic!("unexpected"), - }; - assert_eq!(&f, l.master().node()); - assert_eq!(&t, l.second_slave().node()); - l.process_message((f, t, Message::Generation(GenerationMessage::PublicKeyShare(msg.clone())))).unwrap(); - assert_eq!(l.second_slave().on_public_key_share(m, &message::PublicKeyShare { - session: sid.into(), - session_nonce: 0, - public_share: math::generate_random_point().unwrap().into(), - }).unwrap_err(), Error::InvalidMessage); + let ml = MessageLoop::new(3).init(0).unwrap(); + ml.0.take_and_process_message(); // m -> s1: InitializeSession + ml.0.take_and_process_message(); // m -> s2: InitializeSession + ml.0.take_and_process_message(); // s1 -> m: ConfirmInitialization + ml.0.take_and_process_message(); // s2 -> m: ConfirmInitialization + ml.0.take_and_process_message(); // m -> s1: CompleteInitialization + ml.0.take_and_process_message(); // m -> s2: CompleteInitialization + ml.0.take_and_process_message(); // m -> s1: KeysDissemination + ml.0.take_and_process_message(); // m -> s2: KeysDissemination + ml.0.take_and_process_message(); // s1 -> m: KeysDissemination + ml.0.take_and_process_message(); // s1 -> s2: KeysDissemination + ml.0.take_and_process_message(); // s2 -> m: KeysDissemination + ml.0.take_and_process_message(); // s2 -> s1: KeysDissemination + + let (from, to, msg) = ml.take_message_public_key_share(); + ml.0.process_message(from, to, Message::Generation(GenerationMessage::PublicKeyShare(msg.clone()))); + assert_eq!(ml.session_of(&to).on_public_key_share(from, &msg), Err(Error::InvalidMessage)); } #[test] fn encryption_fails_on_session_timeout() { - let (_, _, _, l) = make_simple_cluster(0, 2).unwrap(); - assert!(l.master().joint_public_and_secret().is_none()); - l.master().on_session_timeout(); - assert!(l.master().joint_public_and_secret().unwrap().unwrap_err() == Error::NodeDisconnected); + let ml = MessageLoop::new(2).init(0).unwrap(); + assert!(ml.session_at(0).joint_public_and_secret().is_none()); + ml.session_at(0).on_session_timeout(); + assert_eq!(ml.session_at(0).joint_public_and_secret().unwrap(), Err(Error::NodeDisconnected)); } #[test] fn encryption_fails_on_node_timeout() { - let (_, _, _, l) = make_simple_cluster(0, 2).unwrap(); - assert!(l.master().joint_public_and_secret().is_none()); - l.master().on_node_timeout(l.first_slave().node()); - assert!(l.master().joint_public_and_secret().unwrap().unwrap_err() == Error::NodeDisconnected); + let ml = MessageLoop::new(2).init(0).unwrap(); + assert!(ml.session_at(0).joint_public_and_secret().is_none()); + ml.session_at(0).on_node_timeout(&ml.0.node(1)); + assert_eq!(ml.session_at(0).joint_public_and_secret().unwrap(), Err(Error::NodeDisconnected)); } #[test] fn complete_enc_dec_session() { let test_cases = [(0, 5), (2, 5), (3, 5)]; for &(threshold, num_nodes) in &test_cases { - let mut l = MessageLoop::new(num_nodes); - l.master().initialize(Default::default(), Default::default(), false, threshold, l.nodes.keys().cloned().collect::>().into()).unwrap(); - assert_eq!(l.nodes.len(), num_nodes); - - // let nodes do initialization + keys dissemination - while let Some((from, to, message)) = l.take_message() { - l.process_message((from, to, message)).unwrap(); - } + let ml = MessageLoop::new(num_nodes).init(threshold).unwrap(); + ml.0.loop_until(|| ml.0.is_empty()); // check that all nodes has finished joint public generation - let joint_public_key = l.master().joint_public_and_secret().unwrap().unwrap().0; - for node in l.nodes.values() { - let state = node.session.state(); - assert_eq!(state, SessionState::Finished); - assert_eq!(node.session.joint_public_and_secret().map(|p| p.map(|p| p.0)), Some(Ok(joint_public_key))); + let joint_public_key = ml.session_at(0).joint_public_and_secret().unwrap().unwrap().0; + for i in 0..num_nodes { + let session = ml.session_at(i); + assert_eq!(session.state(), SessionState::Finished); + assert_eq!(session.joint_public_and_secret().map(|p| p.map(|p| p.0)), Some(Ok(joint_public_key))); } // now let's encrypt some secret (which is a point on EC) let document_secret_plain = Random.generate().unwrap().public().clone(); - let all_nodes_id_numbers: Vec<_> = l.master().data.lock().nodes.values().map(|n| n.id_number.clone()).collect(); - let all_nodes_secret_shares: Vec<_> = l.nodes.values().map(|n| n.session.data.lock().secret_share.as_ref().unwrap().clone()).collect(); + let all_nodes_id_numbers = ml.nodes_id_numbers(); + let all_nodes_secret_shares = ml.nodes_secret_shares(); let document_secret_decrypted = do_encryption_and_decryption(threshold, &joint_public_key, &all_nodes_id_numbers, &all_nodes_secret_shares, @@ -1350,41 +1259,18 @@ pub mod tests { } } - #[test] - fn encryption_session_works_over_network() { - const CONN_TIMEOUT: Duration = Duration::from_millis(300); - const SESSION_TIMEOUT: Duration = Duration::from_millis(1000); - - let test_cases = [(1, 3)]; - for &(threshold, num_nodes) in &test_cases { - let mut core = new_runtime(); - - // prepare cluster objects for each node - let clusters = make_clusters(&core, 6031, num_nodes); - run_clusters(&clusters); - - // `clusters` contains `Arc` and clones will refer to the same cores. - let clusters_clone = clusters.clone(); - - // establish connections - loop_until(&core.executor(), CONN_TIMEOUT, move || clusters_clone.iter().all(all_connections_established)); - - // run session to completion - let session_id = SessionId::default(); - let session = clusters[0].client().new_generation_session(session_id, Default::default(), Default::default(), threshold).unwrap(); - loop_until(&core.executor(), SESSION_TIMEOUT, move || session.joint_public_and_secret().is_some()); - } - } - #[test] fn generation_message_fails_when_nonce_is_wrong() { - let (sid, m, _, l) = make_simple_cluster(0, 2).unwrap(); - assert_eq!(l.first_slave().process_message(&m, &message::GenerationMessage::KeysDissemination(message::KeysDissemination { - session: sid.into(), + let ml = MessageLoop::new(2).init(0).unwrap(); + ml.0.take_and_process_message(); + + let msg = message::GenerationMessage::KeysDissemination(message::KeysDissemination { + session: Default::default(), session_nonce: 10, secret1: math::generate_random_scalar().unwrap().into(), secret2: math::generate_random_scalar().unwrap().into(), publics: vec![math::generate_random_point().unwrap().into()], - })).unwrap_err(), Error::ReplayProtection); + }); + assert_eq!(ml.session_at(1).process_message(&ml.0.node(0), &msg).unwrap_err(), Error::ReplayProtection); } } diff --git a/secret-store/src/key_server_cluster/client_sessions/signing_session_ecdsa.rs b/secret-store/src/key_server_cluster/client_sessions/signing_session_ecdsa.rs index 3744f6c204..fe3bd4f114 100644 --- a/secret-store/src/key_server_cluster/client_sessions/signing_session_ecdsa.rs +++ b/secret-store/src/key_server_cluster/client_sessions/signing_session_ecdsa.rs @@ -1061,140 +1061,65 @@ impl JobTransport for SigningJobTransport { #[cfg(test)] mod tests { use std::sync::Arc; - use std::collections::{BTreeSet, BTreeMap, VecDeque}; use ethereum_types::H256; - use ethkey::{self, Random, Generator, KeyPair, verify_public, public_to_address}; - use acl_storage::DummyAclStorage; - use key_server_cluster::{NodeId, DummyKeyStorage, SessionId, SessionMeta, Error, KeyStorage}; - use key_server_cluster::cluster_sessions::ClusterSession; - use key_server_cluster::cluster::tests::DummyCluster; - use key_server_cluster::generation_session::tests::MessageLoop as KeyGenerationMessageLoop; - use key_server_cluster::message::Message; - use key_server_cluster::signing_session_ecdsa::{SessionImpl, SessionParams}; - - struct Node { - pub node_id: NodeId, - pub cluster: Arc, - pub key_storage: Arc, - pub session: SessionImpl, - } + use ethkey::{self, Random, Generator, Public, verify_public, public_to_address}; + use key_server_cluster::{SessionId, Error, KeyStorage}; + use key_server_cluster::cluster::tests::{MessageLoop as ClusterMessageLoop}; + use key_server_cluster::signing_session_ecdsa::SessionImpl; + use key_server_cluster::generation_session::tests::MessageLoop as GenerationMessageLoop; - struct MessageLoop { - pub session_id: SessionId, - pub requester: KeyPair, - pub nodes: BTreeMap, - pub queue: VecDeque<(NodeId, NodeId, Message)>, - pub acl_storages: Vec>, - pub version: H256, - } + #[derive(Debug)] + pub struct MessageLoop(pub ClusterMessageLoop); impl MessageLoop { - pub fn new(gl: &KeyGenerationMessageLoop) -> Self { - let version = gl.nodes.values().nth(0).unwrap().key_storage.get(&Default::default()).unwrap().unwrap().versions.iter().last().unwrap().hash; - let mut nodes = BTreeMap::new(); - let session_id = gl.session_id.clone(); - let requester = Random.generate().unwrap(); - let signature = Some(ethkey::sign(requester.secret(), &SessionId::default()).unwrap()); - let master_node_id = gl.nodes.keys().nth(0).unwrap().clone(); - let mut acl_storages = Vec::new(); - for (i, (gl_node_id, gl_node)) in gl.nodes.iter().enumerate() { - let acl_storage = Arc::new(DummyAclStorage::default()); - acl_storages.push(acl_storage.clone()); - let cluster = Arc::new(DummyCluster::new(gl_node_id.clone())); - let session = SessionImpl::new(SessionParams { - meta: SessionMeta { - id: session_id.clone(), - self_node_id: gl_node_id.clone(), - master_node_id: master_node_id.clone(), - threshold: gl_node.key_storage.get(&session_id).unwrap().unwrap().threshold, - configured_nodes_count: gl.nodes.len(), - connected_nodes_count: gl.nodes.len(), - }, - access_key: "834cb736f02d9c968dfaf0c37658a1d86ff140554fc8b59c9fdad5a8cf810eec".parse().unwrap(), - key_share: Some(gl_node.key_storage.get(&session_id).unwrap().unwrap()), - acl_storage: acl_storage, - cluster: cluster.clone(), - nonce: 0, - }, if i == 0 { signature.clone().map(Into::into) } else { None }).unwrap(); - nodes.insert(gl_node_id.clone(), Node { node_id: gl_node_id.clone(), cluster: cluster, key_storage: gl_node.key_storage.clone(), session: session }); - } + pub fn new(num_nodes: usize, threshold: usize) -> Result { + let ml = GenerationMessageLoop::new(num_nodes).init(threshold)?; + ml.0.loop_until(|| ml.0.is_empty()); // complete generation session - let nodes_ids: Vec<_> = nodes.keys().cloned().collect(); - for node in nodes.values() { - for node_id in &nodes_ids { - node.cluster.add_node(node_id.clone()); - } - } + Ok(MessageLoop(ml.0)) + } - MessageLoop { - session_id: session_id, - requester: requester, - nodes: nodes, - queue: VecDeque::new(), - acl_storages: acl_storages, - version: version, - } + pub fn init_with_version(self, key_version: Option) -> Result<(Self, Public, H256), Error> { + let message_hash = H256::random(); + let requester = Random.generate().unwrap(); + let signature = ethkey::sign(requester.secret(), &SessionId::default()).unwrap(); + self.0.cluster(0).client() + .new_ecdsa_signing_session(Default::default(), signature.into(), key_version, message_hash) + .map(|_| (self, *requester.public(), message_hash)) } - pub fn master(&self) -> &SessionImpl { - &self.nodes.values().nth(0).unwrap().session + pub fn init(self) -> Result<(Self, Public, H256), Error> { + let key_version = self.0.key_storage(0).get(&Default::default()) + .unwrap().unwrap().versions.iter().last().unwrap().hash; + self.init_with_version(Some(key_version)) } - pub fn take_message(&mut self) -> Option<(NodeId, NodeId, Message)> { - self.nodes.values() - .filter_map(|n| n.cluster.take_message().map(|m| (n.node_id.clone(), m.0, m.1))) - .nth(0) - .or_else(|| self.queue.pop_front()) + pub fn init_delegated(self) -> Result<(Self, Public, H256), Error> { + self.0.key_storage(0).remove(&Default::default()).unwrap(); + self.init_with_version(None) } - pub fn process_message(&mut self, mut msg: (NodeId, NodeId, Message)) -> Result<(), Error> { - let mut is_queued_message = false; - loop { - match self.nodes[&msg.1].session.on_message(&msg.0, &msg.2) { - Ok(_) => { - if let Some(message) = self.queue.pop_front() { - msg = message; - is_queued_message = true; - continue; - } - return Ok(()); - }, - Err(Error::TooEarlyForRequest) => { - if is_queued_message { - self.queue.push_front(msg); - } else { - self.queue.push_back(msg); - } - return Ok(()); - }, - Err(err) => return Err(err), - } - } + pub fn init_with_isolated(self) -> Result<(Self, Public, H256), Error> { + self.0.isolate(1); + self.init() } - } - fn prepare_signing_sessions(threshold: usize, num_nodes: usize) -> (KeyGenerationMessageLoop, MessageLoop) { - // run key generation sessions - let mut gl = KeyGenerationMessageLoop::new(num_nodes); - gl.master().initialize(Default::default(), Default::default(), false, threshold, gl.nodes.keys().cloned().collect::>().into()).unwrap(); - while let Some((from, to, message)) = gl.take_message() { - gl.process_message((from, to, message)).unwrap(); + pub fn session_at(&self, idx: usize) -> Arc { + self.0.sessions(idx).ecdsa_signing_sessions.first().unwrap() } - // run signing session - let sl = MessageLoop::new(&gl); - (gl, sl) + pub fn ensure_completed(&self) { + self.0.loop_until(|| self.0.is_empty()); + assert!(self.session_at(0).wait().is_ok()); + } } #[test] fn failed_gen_ecdsa_sign_session_when_threshold_is_too_low() { let test_cases = [(1, 2), (2, 4), (3, 6), (4, 6)]; for &(threshold, num_nodes) in &test_cases { - let (_, sl) = prepare_signing_sessions(threshold, num_nodes); - - // run signing session - let message_hash = H256::random(); - assert_eq!(sl.master().initialize(sl.version.clone(), message_hash).unwrap_err(), Error::ConsensusUnreachable); + assert_eq!(MessageLoop::new(num_nodes, threshold).unwrap().init().unwrap_err(), + Error::ConsensusUnreachable); } } @@ -1202,112 +1127,46 @@ mod tests { fn complete_gen_ecdsa_sign_session() { let test_cases = [(0, 1), (2, 5), (2, 6), (3, 11), (4, 11)]; for &(threshold, num_nodes) in &test_cases { - let (gl, mut sl) = prepare_signing_sessions(threshold, num_nodes); - let key_pair = gl.compute_key_pair(threshold); - - // run signing session - let message_hash = H256::random(); - sl.master().initialize(sl.version.clone(), message_hash).unwrap(); - while let Some((from, to, message)) = sl.take_message() { - sl.process_message((from, to, message)).unwrap(); - } + let (ml, _, message) = MessageLoop::new(num_nodes, threshold).unwrap().init().unwrap(); + ml.0.loop_until(|| ml.0.is_empty()); - // verify signature - let signature = sl.master().wait().unwrap(); - assert!(verify_public(key_pair.public(), &signature, &message_hash).unwrap()); + let signer_public = ml.0.key_storage(0).get(&Default::default()).unwrap().unwrap().public; + let signature = ml.session_at(0).wait().unwrap(); + assert!(verify_public(&signer_public, &signature, &message).unwrap()); } } #[test] fn ecdsa_complete_signing_session_with_single_node_failing() { - let (_, mut sl) = prepare_signing_sessions(1, 4); - sl.master().initialize(sl.version.clone(), 777.into()).unwrap(); + let (ml, requester, _) = MessageLoop::new(4, 1).unwrap().init().unwrap(); // we need at least 3-of-4 nodes to agree to reach consensus // let's say 1 of 4 nodes disagee - sl.acl_storages[1].prohibit(public_to_address(sl.requester.public()), SessionId::default()); + ml.0.acl_storage(1).prohibit(public_to_address(&requester), Default::default()); // then consensus reachable, but single node will disagree - while let Some((from, to, message)) = sl.take_message() { - sl.process_message((from, to, message)).unwrap(); - } - - let data = sl.master().data.lock(); - match data.result { - Some(Ok(_)) => (), - _ => unreachable!(), - } + ml.ensure_completed(); } #[test] fn ecdsa_complete_signing_session_with_acl_check_failed_on_master() { - let (_, mut sl) = prepare_signing_sessions(1, 4); - sl.master().initialize(sl.version.clone(), 777.into()).unwrap(); + let (ml, requester, _) = MessageLoop::new(4, 1).unwrap().init().unwrap(); // we need at least 3-of-4 nodes to agree to reach consensus - // let's say 1 of 4 nodes disagee - sl.acl_storages[0].prohibit(public_to_address(sl.requester.public()), SessionId::default()); + // let's say 1 of 4 nodes (here: master) disagee + ml.0.acl_storage(0).prohibit(public_to_address(&requester), Default::default()); // then consensus reachable, but single node will disagree - while let Some((from, to, message)) = sl.take_message() { - sl.process_message((from, to, message)).unwrap(); - } - - let data = sl.master().data.lock(); - match data.result { - Some(Ok(_)) => (), - _ => unreachable!(), - } + ml.ensure_completed(); } #[test] fn ecdsa_signing_works_when_delegated_to_other_node() { - let (_, mut sl) = prepare_signing_sessions(1, 4); - - // let's say node1 doesn't have a share && delegates decryption request to node0 - // initially session is created on node1 => node1 is master for itself, but for other nodes node0 is still master - let actual_master = sl.nodes.keys().nth(0).cloned().unwrap(); - let requested_node = sl.nodes.keys().skip(1).nth(0).cloned().unwrap(); - let version = sl.nodes[&actual_master].key_storage.get(&Default::default()).unwrap().unwrap().last_version().unwrap().hash.clone(); - sl.nodes[&requested_node].key_storage.remove(&Default::default()).unwrap(); - sl.nodes.get_mut(&requested_node).unwrap().session.core.key_share = None; - sl.nodes.get_mut(&requested_node).unwrap().session.core.meta.master_node_id = sl.nodes[&requested_node].session.core.meta.self_node_id.clone(); - sl.nodes[&requested_node].session.data.lock().consensus_session.consensus_job_mut().executor_mut().set_requester( - sl.nodes[&actual_master].session.data.lock().consensus_session.consensus_job().executor().requester().unwrap().clone() - ); - - // now let's try to do a decryption - sl.nodes[&requested_node].session.delegate(actual_master, version, H256::random()).unwrap(); - - // then consensus reachable, but single node will disagree - while let Some((from, to, message)) = sl.take_message() { - sl.process_message((from, to, message)).unwrap(); - } + MessageLoop::new(4, 1).unwrap().init_delegated().unwrap().0.ensure_completed(); } #[test] fn ecdsa_signing_works_when_share_owners_are_isolated() { - let (_, mut sl) = prepare_signing_sessions(2, 6); - - // we need 5 out of 6 nodes to agree to do a decryption - // let's say that 1 of these nodes (master) is isolated - let isolated_node_id = sl.nodes.keys().skip(2).nth(0).cloned().unwrap(); - for node in sl.nodes.values() { - node.cluster.remove_node(&isolated_node_id); - } - - // now let's try to do a signing - sl.master().initialize(sl.version.clone(), H256::random()).unwrap(); - - // then consensus reachable, but single node will disagree - while let Some((from, to, message)) = sl.take_message() { - sl.process_message((from, to, message)).unwrap(); - } - - let data = sl.master().data.lock(); - match data.result { - Some(Ok(_)) => (), - _ => unreachable!(), - } + MessageLoop::new(6, 2).unwrap().init_with_isolated().unwrap().0.ensure_completed(); } } 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 075e456fdb..0b0619f967 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 @@ -809,279 +809,150 @@ impl JobTransport for SigningJobTransport { mod tests { use std::sync::Arc; use std::str::FromStr; - use std::collections::{BTreeSet, BTreeMap, VecDeque}; + use std::collections::BTreeMap; use ethereum_types::{Address, H256}; - use ethkey::{self, Random, Generator, Public, Secret, KeyPair, public_to_address}; + use ethkey::{self, Random, Generator, Public, Secret, public_to_address}; use acl_storage::DummyAclStorage; - use key_server_cluster::{NodeId, DummyKeyStorage, DocumentKeyShare, DocumentKeyShareVersion, SessionId, - Requester, SessionMeta, Error, KeyStorage}; - use key_server_cluster::cluster_sessions::ClusterSession; - use key_server_cluster::cluster::tests::DummyCluster; - use key_server_cluster::generation_session::tests::MessageLoop as KeyGenerationMessageLoop; + use key_server_cluster::{SessionId, Requester, SessionMeta, Error, KeyStorage}; + use key_server_cluster::cluster::tests::MessageLoop as ClusterMessageLoop; + use key_server_cluster::generation_session::tests::MessageLoop as GenerationMessageLoop; use key_server_cluster::math; - use key_server_cluster::message::{Message, SchnorrSigningMessage, SchnorrSigningConsensusMessage, ConsensusMessage, ConfirmConsensusInitialization, - SchnorrSigningGenerationMessage, GenerationMessage, ConfirmInitialization, InitializeSession, SchnorrRequestPartialSignature}; + use key_server_cluster::message::{SchnorrSigningMessage, SchnorrSigningConsensusMessage, + ConsensusMessage, ConfirmConsensusInitialization, SchnorrSigningGenerationMessage, GenerationMessage, + ConfirmInitialization, InitializeSession, SchnorrRequestPartialSignature}; use key_server_cluster::signing_session_schnorr::{SessionImpl, SessionState, SessionParams}; - struct Node { - pub node_id: NodeId, - pub cluster: Arc, - pub key_storage: Arc, - pub session: SessionImpl, - } - - struct MessageLoop { - pub session_id: SessionId, - pub requester: KeyPair, - pub nodes: BTreeMap, - pub queue: VecDeque<(NodeId, NodeId, Message)>, - pub acl_storages: Vec>, - pub version: H256, - } + #[derive(Debug)] + pub struct MessageLoop(pub ClusterMessageLoop); impl MessageLoop { - pub fn new(gl: &KeyGenerationMessageLoop) -> Self { - let version = gl.nodes.values().nth(0).unwrap().key_storage.get(&Default::default()).unwrap().unwrap().versions.iter().last().unwrap().hash; - let mut nodes = BTreeMap::new(); - let session_id = gl.session_id.clone(); - let requester = Random.generate().unwrap(); - let signature = Some(ethkey::sign(requester.secret(), &SessionId::default()).unwrap()); - let master_node_id = gl.nodes.keys().nth(0).unwrap().clone(); - let mut acl_storages = Vec::new(); - for (i, (gl_node_id, gl_node)) in gl.nodes.iter().enumerate() { - let acl_storage = Arc::new(DummyAclStorage::default()); - acl_storages.push(acl_storage.clone()); - let cluster = Arc::new(DummyCluster::new(gl_node_id.clone())); - let session = SessionImpl::new(SessionParams { - meta: SessionMeta { - id: session_id.clone(), - self_node_id: gl_node_id.clone(), - master_node_id: master_node_id.clone(), - threshold: gl_node.key_storage.get(&session_id).unwrap().unwrap().threshold, - configured_nodes_count: gl.nodes.len(), - connected_nodes_count: gl.nodes.len(), - }, - access_key: "834cb736f02d9c968dfaf0c37658a1d86ff140554fc8b59c9fdad5a8cf810eec".parse().unwrap(), - key_share: Some(gl_node.key_storage.get(&session_id).unwrap().unwrap()), - acl_storage: acl_storage, - cluster: cluster.clone(), - nonce: 0, - }, if i == 0 { signature.clone().map(Into::into) } else { None }).unwrap(); - nodes.insert(gl_node_id.clone(), Node { node_id: gl_node_id.clone(), cluster: cluster, key_storage: gl_node.key_storage.clone(), session: session }); - } + pub fn new(num_nodes: usize, threshold: usize) -> Result { + let ml = GenerationMessageLoop::new(num_nodes).init(threshold)?; + ml.0.loop_until(|| ml.0.is_empty()); // complete generation session - let nodes_ids: Vec<_> = nodes.keys().cloned().collect(); - for node in nodes.values() { - for node_id in &nodes_ids { - node.cluster.add_node(node_id.clone()); - } - } + Ok(MessageLoop(ml.0)) + } - MessageLoop { - session_id: session_id, - requester: requester, - nodes: nodes, - queue: VecDeque::new(), - acl_storages: acl_storages, - version: version, - } + pub fn into_session(&self, at_node: usize) -> SessionImpl { + let requester = Some(Requester::Signature(ethkey::sign(Random.generate().unwrap().secret(), + &SessionId::default()).unwrap())); + SessionImpl::new(SessionParams { + meta: SessionMeta { + id: SessionId::default(), + self_node_id: self.0.node(at_node), + master_node_id: self.0.node(0), + threshold: self.0.key_storage(at_node).get(&Default::default()).unwrap().unwrap().threshold, + configured_nodes_count: self.0.nodes().len(), + connected_nodes_count: self.0.nodes().len(), + }, + access_key: Random.generate().unwrap().secret().clone(), + key_share: self.0.key_storage(at_node).get(&Default::default()).unwrap(), + acl_storage: Arc::new(DummyAclStorage::default()), + cluster: self.0.cluster(0).view().unwrap(), + nonce: 0, + }, requester).unwrap() } - pub fn master(&self) -> &SessionImpl { - &self.nodes.values().nth(0).unwrap().session + pub fn init_with_version(self, key_version: Option) -> Result<(Self, Public, H256), Error> { + let message_hash = H256::random(); + let requester = Random.generate().unwrap(); + let signature = ethkey::sign(requester.secret(), &SessionId::default()).unwrap(); + self.0.cluster(0).client().new_schnorr_signing_session( + Default::default(), + signature.into(), + key_version, + message_hash).map(|_| (self, *requester.public(), message_hash)) } - pub fn take_message(&mut self) -> Option<(NodeId, NodeId, Message)> { - self.nodes.values() - .filter_map(|n| n.cluster.take_message().map(|m| (n.node_id.clone(), m.0, m.1))) - .nth(0) - .or_else(|| self.queue.pop_front()) + pub fn init(self) -> Result<(Self, Public, H256), Error> { + let key_version = self.key_version(); + self.init_with_version(Some(key_version)) } - pub fn process_message(&mut self, mut msg: (NodeId, NodeId, Message)) -> Result<(), Error> { - let mut is_queued_message = false; - loop { - match self.nodes[&msg.1].session.on_message(&msg.0, &msg.2) { - Ok(_) => { - if let Some(message) = self.queue.pop_front() { - msg = message; - is_queued_message = true; - continue; - } - return Ok(()); - }, - Err(Error::TooEarlyForRequest) => { - if is_queued_message { - self.queue.push_front(msg); - } else { - self.queue.push_back(msg); - } - return Ok(()); - }, - Err(err) => return Err(err), - } - } + pub fn init_delegated(self) -> Result<(Self, Public, H256), Error> { + self.0.key_storage(0).remove(&Default::default()).unwrap(); + self.init_with_version(None) } - pub fn run_until bool>(&mut self, predicate: F) -> Result<(), Error> { - while let Some((from, to, message)) = self.take_message() { - if predicate(self) { - return Ok(()); - } + pub fn init_with_isolated(self) -> Result<(Self, Public, H256), Error> { + self.0.isolate(1); + self.init() + } - self.process_message((from, to, message))?; - } + pub fn init_without_share(self) -> Result<(Self, Public, H256), Error> { + let key_version = self.key_version(); + self.0.key_storage(0).remove(&Default::default()).unwrap(); + self.init_with_version(Some(key_version)) + } - unreachable!("either wrong predicate, or failing test") + pub fn session_at(&self, idx: usize) -> Arc { + self.0.sessions(idx).schnorr_signing_sessions.first().unwrap() } - } - fn prepare_signing_sessions(threshold: usize, num_nodes: usize) -> (KeyGenerationMessageLoop, MessageLoop) { - // run key generation sessions - let mut gl = KeyGenerationMessageLoop::new(num_nodes); - gl.master().initialize(Default::default(), Default::default(), false, threshold, gl.nodes.keys().cloned().collect::>().into()).unwrap(); - while let Some((from, to, message)) = gl.take_message() { - gl.process_message((from, to, message)).unwrap(); + pub fn ensure_completed(&self) { + self.0.loop_until(|| self.0.is_empty()); + assert!(self.session_at(0).wait().is_ok()); } - // run signing session - let sl = MessageLoop::new(&gl); - (gl, sl) + pub fn key_version(&self) -> H256 { + self.0.key_storage(0).get(&Default::default()) + .unwrap().unwrap().versions.iter().last().unwrap().hash + } } #[test] fn schnorr_complete_gen_sign_session() { let test_cases = [(0, 1), (0, 5), (2, 5), (3, 5)]; for &(threshold, num_nodes) in &test_cases { - let (gl, mut sl) = prepare_signing_sessions(threshold, num_nodes); + let (ml, _, message) = MessageLoop::new(num_nodes, threshold).unwrap().init().unwrap(); + ml.0.loop_until(|| ml.0.is_empty()); - // run signing session - let message_hash = H256::from(777); - sl.master().initialize(sl.version.clone(), message_hash).unwrap(); - while let Some((from, to, message)) = sl.take_message() { - sl.process_message((from, to, message)).unwrap(); - } - - // verify signature - let public = gl.master().joint_public_and_secret().unwrap().unwrap().0; - let signature = sl.master().wait().unwrap(); - assert!(math::verify_schnorr_signature(&public, &signature, &message_hash).unwrap()); + let signer_public = ml.0.key_storage(0).get(&Default::default()).unwrap().unwrap().public; + let signature = ml.session_at(0).wait().unwrap(); + assert!(math::verify_schnorr_signature(&signer_public, &signature, &message).unwrap()); } } #[test] fn schnorr_constructs_in_cluster_of_single_node() { - let mut nodes = BTreeMap::new(); - let self_node_id = Random.generate().unwrap().public().clone(); - nodes.insert(self_node_id, Random.generate().unwrap().secret().clone()); - match SessionImpl::new(SessionParams { - meta: SessionMeta { - id: SessionId::default(), - self_node_id: self_node_id.clone(), - master_node_id: self_node_id.clone(), - threshold: 0, - configured_nodes_count: 1, - connected_nodes_count: 1, - }, - access_key: Random.generate().unwrap().secret().clone(), - key_share: Some(DocumentKeyShare { - author: Default::default(), - threshold: 0, - public: Default::default(), - common_point: Some(Random.generate().unwrap().public().clone()), - encrypted_point: Some(Random.generate().unwrap().public().clone()), - versions: vec![DocumentKeyShareVersion { - hash: Default::default(), - id_numbers: nodes, - secret_share: Random.generate().unwrap().secret().clone(), - }], - }), - acl_storage: Arc::new(DummyAclStorage::default()), - cluster: Arc::new(DummyCluster::new(self_node_id.clone())), - nonce: 0, - }, Some(Requester::Signature(ethkey::sign(Random.generate().unwrap().secret(), &SessionId::default()).unwrap()))) { - Ok(_) => (), - _ => panic!("unexpected"), - } + MessageLoop::new(1, 0).unwrap().init().unwrap(); } #[test] fn schnorr_fails_to_initialize_if_does_not_have_a_share() { - let self_node_id = Random.generate().unwrap().public().clone(); - let session = SessionImpl::new(SessionParams { - meta: SessionMeta { - id: SessionId::default(), - self_node_id: self_node_id.clone(), - master_node_id: self_node_id.clone(), - threshold: 0, - configured_nodes_count: 1, - connected_nodes_count: 1, - }, - access_key: Random.generate().unwrap().secret().clone(), - key_share: None, - acl_storage: Arc::new(DummyAclStorage::default()), - cluster: Arc::new(DummyCluster::new(self_node_id.clone())), - nonce: 0, - }, Some(Requester::Signature(ethkey::sign(Random.generate().unwrap().secret(), &SessionId::default()).unwrap()))).unwrap(); - assert_eq!(session.initialize(Default::default(), Default::default()), Err(Error::InvalidMessage)); + assert!(MessageLoop::new(2, 1).unwrap().init_without_share().is_err()); } #[test] fn schnorr_fails_to_initialize_if_threshold_is_wrong() { - let mut nodes = BTreeMap::new(); - let self_node_id = Random.generate().unwrap().public().clone(); - nodes.insert(self_node_id.clone(), Random.generate().unwrap().secret().clone()); - nodes.insert(Random.generate().unwrap().public().clone(), Random.generate().unwrap().secret().clone()); - let session = SessionImpl::new(SessionParams { - meta: SessionMeta { - id: SessionId::default(), - self_node_id: self_node_id.clone(), - master_node_id: self_node_id.clone(), - threshold: 2, - configured_nodes_count: 1, - connected_nodes_count: 1, - }, - access_key: Random.generate().unwrap().secret().clone(), - key_share: Some(DocumentKeyShare { - author: Default::default(), - threshold: 2, - public: Default::default(), - common_point: Some(Random.generate().unwrap().public().clone()), - encrypted_point: Some(Random.generate().unwrap().public().clone()), - versions: vec![DocumentKeyShareVersion { - hash: Default::default(), - id_numbers: nodes, - secret_share: Random.generate().unwrap().secret().clone(), - }], - }), - acl_storage: Arc::new(DummyAclStorage::default()), - cluster: Arc::new(DummyCluster::new(self_node_id.clone())), - nonce: 0, - }, Some(Requester::Signature(ethkey::sign(Random.generate().unwrap().secret(), &SessionId::default()).unwrap()))).unwrap(); - assert_eq!(session.initialize(Default::default(), Default::default()), Err(Error::ConsensusUnreachable)); + let mut ml = MessageLoop::new(3, 2).unwrap(); + ml.0.exclude(2); + assert_eq!(ml.init().unwrap_err(), Error::ConsensusUnreachable); } #[test] fn schnorr_fails_to_initialize_when_already_initialized() { - let (_, sl) = prepare_signing_sessions(1, 3); - assert_eq!(sl.master().initialize(sl.version.clone(), 777.into()), Ok(())); - assert_eq!(sl.master().initialize(sl.version.clone(), 777.into()), Err(Error::InvalidStateForRequest)); + let (ml, _, _) = MessageLoop::new(1, 0).unwrap().init().unwrap(); + assert_eq!(ml.session_at(0).initialize(ml.key_version(), 777.into()), + Err(Error::InvalidStateForRequest)); } #[test] fn schnorr_does_not_fail_when_consensus_message_received_after_consensus_established() { - let (_, mut sl) = prepare_signing_sessions(1, 3); - sl.master().initialize(sl.version.clone(), 777.into()).unwrap(); + let (ml, _, _) = MessageLoop::new(3, 1).unwrap().init().unwrap(); + // consensus is established - sl.run_until(|sl| sl.master().state() == SessionState::SessionKeyGeneration).unwrap(); + let session = ml.session_at(0); + ml.0.loop_until(|| session.state() == SessionState::SessionKeyGeneration); + // but 3rd node continues to send its messages // this should not fail session - let consensus_group = sl.master().data.lock().consensus_session.select_consensus_group().unwrap().clone(); + let consensus_group = session.data.lock().consensus_session.select_consensus_group().unwrap().clone(); let mut had_3rd_message = false; - while let Some((from, to, message)) = sl.take_message() { + while let Some((from, to, message)) = ml.0.take_message() { if !consensus_group.contains(&from) { had_3rd_message = true; - sl.process_message((from, to, message)).unwrap(); + ml.0.process_message(from, to, message); } } assert!(had_3rd_message); @@ -1089,10 +960,11 @@ mod tests { #[test] fn schnorr_fails_when_consensus_message_is_received_when_not_initialized() { - let (_, sl) = prepare_signing_sessions(1, 3); - assert_eq!(sl.master().on_consensus_message(sl.nodes.keys().nth(1).unwrap(), &SchnorrSigningConsensusMessage { + let ml = MessageLoop::new(3, 1).unwrap(); + let session = ml.into_session(0); + assert_eq!(session.on_consensus_message(&ml.0.node(1), &SchnorrSigningConsensusMessage { session: SessionId::default().into(), - sub_session: sl.master().core.access_key.clone().into(), + sub_session: session.core.access_key.clone().into(), session_nonce: 0, message: ConsensusMessage::ConfirmConsensusInitialization(ConfirmConsensusInitialization { is_confirmed: true, @@ -1102,10 +974,11 @@ mod tests { #[test] fn schnorr_fails_when_generation_message_is_received_when_not_initialized() { - let (_, sl) = prepare_signing_sessions(1, 3); - assert_eq!(sl.master().on_generation_message(sl.nodes.keys().nth(1).unwrap(), &SchnorrSigningGenerationMessage { + let ml = MessageLoop::new(3, 1).unwrap(); + let session = ml.into_session(0); + assert_eq!(session.on_generation_message(&ml.0.node(1), &SchnorrSigningGenerationMessage { session: SessionId::default().into(), - sub_session: sl.master().core.access_key.clone().into(), + sub_session: session.core.access_key.clone().into(), session_nonce: 0, message: GenerationMessage::ConfirmInitialization(ConfirmInitialization { session: SessionId::default().into(), @@ -1117,16 +990,16 @@ mod tests { #[test] fn schnorr_fails_when_generation_sesson_is_initialized_by_slave_node() { - let (_, mut sl) = prepare_signing_sessions(1, 3); - sl.master().initialize(sl.version.clone(), 777.into()).unwrap(); - sl.run_until(|sl| sl.master().state() == SessionState::SessionKeyGeneration).unwrap(); + let (ml, _, _) = MessageLoop::new(3, 1).unwrap().init().unwrap(); + let session = ml.session_at(0); + ml.0.loop_until(|| session.state() == SessionState::SessionKeyGeneration); - let slave2_id = sl.nodes.keys().nth(2).unwrap().clone(); - let slave1 = &sl.nodes.values().nth(1).unwrap().session; + let slave2_id = ml.0.node(2); + let slave1_session = ml.session_at(1); - assert_eq!(slave1.on_generation_message(&slave2_id, &SchnorrSigningGenerationMessage { + assert_eq!(slave1_session.on_generation_message(&slave2_id, &SchnorrSigningGenerationMessage { session: SessionId::default().into(), - sub_session: sl.master().core.access_key.clone().into(), + sub_session: session.core.access_key.clone().into(), session_nonce: 0, message: GenerationMessage::InitializeSession(InitializeSession { session: SessionId::default().into(), @@ -1143,11 +1016,11 @@ mod tests { #[test] fn schnorr_fails_when_signature_requested_when_not_initialized() { - let (_, sl) = prepare_signing_sessions(1, 3); - let slave1 = &sl.nodes.values().nth(1).unwrap().session; - assert_eq!(slave1.on_partial_signature_requested(sl.nodes.keys().nth(0).unwrap(), &SchnorrRequestPartialSignature { + let ml = MessageLoop::new(3, 1).unwrap(); + let session = ml.into_session(1); + assert_eq!(session.on_partial_signature_requested(&ml.0.node(0), &SchnorrRequestPartialSignature { session: SessionId::default().into(), - sub_session: sl.master().core.access_key.clone().into(), + sub_session: session.core.access_key.clone().into(), session_nonce: 0, request_id: Secret::from_str("0000000000000000000000000000000000000000000000000000000000000001").unwrap().into(), message_hash: H256::default().into(), @@ -1157,10 +1030,11 @@ mod tests { #[test] fn schnorr_fails_when_signature_requested_by_slave_node() { - let (_, sl) = prepare_signing_sessions(1, 3); - assert_eq!(sl.master().on_partial_signature_requested(sl.nodes.keys().nth(1).unwrap(), &SchnorrRequestPartialSignature { + let ml = MessageLoop::new(3, 1).unwrap(); + let session = ml.into_session(0); + assert_eq!(session.on_partial_signature_requested(&ml.0.node(1), &SchnorrRequestPartialSignature { session: SessionId::default().into(), - sub_session: sl.master().core.access_key.clone().into(), + sub_session: session.core.access_key.clone().into(), session_nonce: 0, request_id: Secret::from_str("0000000000000000000000000000000000000000000000000000000000000001").unwrap().into(), message_hash: H256::default().into(), @@ -1170,123 +1044,68 @@ mod tests { #[test] fn schnorr_failed_signing_session() { - let (_, mut sl) = prepare_signing_sessions(1, 3); - sl.master().initialize(sl.version.clone(), 777.into()).unwrap(); + let (ml, requester, _) = MessageLoop::new(3, 1).unwrap().init().unwrap(); // we need at least 2-of-3 nodes to agree to reach consensus // let's say 2 of 3 nodes disagee - sl.acl_storages[1].prohibit(public_to_address(sl.requester.public()), SessionId::default()); - sl.acl_storages[2].prohibit(public_to_address(sl.requester.public()), SessionId::default()); + ml.0.acl_storage(1).prohibit(public_to_address(&requester), SessionId::default()); + ml.0.acl_storage(2).prohibit(public_to_address(&requester), SessionId::default()); // then consensus is unreachable - assert_eq!(sl.run_until(|_| false), Err(Error::ConsensusUnreachable)); + ml.0.loop_until(|| ml.0.is_empty()); + assert_eq!(ml.session_at(0).wait().unwrap_err(), Error::ConsensusUnreachable); } #[test] fn schnorr_complete_signing_session_with_single_node_failing() { - let (_, mut sl) = prepare_signing_sessions(1, 3); - sl.master().initialize(sl.version.clone(), 777.into()).unwrap(); + let (ml, requester, _) = MessageLoop::new(3, 1).unwrap().init().unwrap(); // we need at least 2-of-3 nodes to agree to reach consensus // let's say 1 of 3 nodes disagee - sl.acl_storages[1].prohibit(public_to_address(sl.requester.public()), SessionId::default()); + ml.0.acl_storage(1).prohibit(public_to_address(&requester), SessionId::default()); // then consensus reachable, but single node will disagree - while let Some((from, to, message)) = sl.take_message() { - sl.process_message((from, to, message)).unwrap(); - } - - let data = sl.master().data.lock(); - match data.result { - Some(Ok(_)) => (), - _ => unreachable!(), - } + ml.ensure_completed(); } #[test] fn schnorr_complete_signing_session_with_acl_check_failed_on_master() { - let (_, mut sl) = prepare_signing_sessions(1, 3); - sl.master().initialize(sl.version.clone(), 777.into()).unwrap(); + let (ml, requester, _) = MessageLoop::new(3, 1).unwrap().init().unwrap(); // we need at least 2-of-3 nodes to agree to reach consensus // let's say 1 of 3 nodes disagee - sl.acl_storages[0].prohibit(public_to_address(sl.requester.public()), SessionId::default()); + ml.0.acl_storage(0).prohibit(public_to_address(&requester), SessionId::default()); // then consensus reachable, but single node will disagree - while let Some((from, to, message)) = sl.take_message() { - sl.process_message((from, to, message)).unwrap(); - } - - let data = sl.master().data.lock(); - match data.result { - Some(Ok(_)) => (), - _ => unreachable!(), - } + ml.ensure_completed(); } #[test] fn schnorr_signing_message_fails_when_nonce_is_wrong() { - let (_, sl) = prepare_signing_sessions(1, 3); - assert_eq!(sl.master().process_message(sl.nodes.keys().nth(1).unwrap(), &SchnorrSigningMessage::SchnorrSigningGenerationMessage(SchnorrSigningGenerationMessage { + let ml = MessageLoop::new(3, 1).unwrap(); + let session = ml.into_session(1); + let msg = SchnorrSigningMessage::SchnorrSigningGenerationMessage(SchnorrSigningGenerationMessage { session: SessionId::default().into(), - sub_session: sl.master().core.access_key.clone().into(), + sub_session: session.core.access_key.clone().into(), session_nonce: 10, message: GenerationMessage::ConfirmInitialization(ConfirmInitialization { session: SessionId::default().into(), session_nonce: 0, derived_point: Public::default().into(), }), - })), Err(Error::ReplayProtection)); + }); + assert_eq!(session.process_message(&ml.0.node(1), &msg), Err(Error::ReplayProtection)); } #[test] fn schnorr_signing_works_when_delegated_to_other_node() { - let (_, mut sl) = prepare_signing_sessions(1, 3); - - // let's say node1 doesn't have a share && delegates decryption request to node0 - // initially session is created on node1 => node1 is master for itself, but for other nodes node0 is still master - let actual_master = sl.nodes.keys().nth(0).cloned().unwrap(); - let requested_node = sl.nodes.keys().skip(1).nth(0).cloned().unwrap(); - let version = sl.nodes[&actual_master].key_storage.get(&Default::default()).unwrap().unwrap().last_version().unwrap().hash.clone(); - sl.nodes[&requested_node].key_storage.remove(&Default::default()).unwrap(); - sl.nodes.get_mut(&requested_node).unwrap().session.core.key_share = None; - sl.nodes.get_mut(&requested_node).unwrap().session.core.meta.master_node_id = sl.nodes[&requested_node].session.core.meta.self_node_id.clone(); - sl.nodes[&requested_node].session.data.lock().consensus_session.consensus_job_mut().executor_mut().set_requester( - sl.nodes[&actual_master].session.data.lock().consensus_session.consensus_job().executor().requester().unwrap().clone() - ); - - // now let's try to do a decryption - sl.nodes[&requested_node].session.delegate(actual_master, version, Default::default()).unwrap(); - - // then consensus reachable, but single node will disagree - while let Some((from, to, message)) = sl.take_message() { - sl.process_message((from, to, message)).unwrap(); - } + let (ml, _, _) = MessageLoop::new(3, 1).unwrap().init_delegated().unwrap(); + ml.ensure_completed(); } #[test] fn schnorr_signing_works_when_share_owners_are_isolated() { - let (_, mut sl) = prepare_signing_sessions(1, 3); - - // we need 2 out of 3 nodes to agree to do a decryption - // let's say that 1 of these nodes (master) is isolated - let isolated_node_id = sl.nodes.keys().skip(2).nth(0).cloned().unwrap(); - for node in sl.nodes.values() { - node.cluster.remove_node(&isolated_node_id); - } - - // now let's try to do a signing - sl.master().initialize(sl.version.clone(), 777.into()).unwrap(); - - // then consensus reachable, but single node will disagree - while let Some((from, to, message)) = sl.take_message() { - sl.process_message((from, to, message)).unwrap(); - } - - let data = sl.master().data.lock(); - match data.result { - Some(Ok(_)) => (), - _ => unreachable!(), - } + let (ml, _, _) = MessageLoop::new(3, 1).unwrap().init_with_isolated().unwrap(); + ml.ensure_completed(); } } diff --git a/secret-store/src/key_server_cluster/cluster.rs b/secret-store/src/key_server_cluster/cluster.rs index 09a1a6a5a8..a8416a8f70 100644 --- a/secret-store/src/key_server_cluster/cluster.rs +++ b/secret-store/src/key_server_cluster/cluster.rs @@ -14,26 +14,22 @@ // You should have received a copy of the GNU General Public License // along with Parity Ethereum. If not, see . -use std::io; -use std::time::{Duration, Instant}; use std::sync::Arc; -use std::sync::atomic::{AtomicBool, Ordering}; use std::collections::{BTreeMap, BTreeSet}; -use std::collections::btree_map::Entry; -use std::net::{SocketAddr, IpAddr}; -use futures::{future, Future, Stream}; -use parking_lot::{Mutex, RwLock}; -use tokio_io::IoFuture; -use tokio::timer::{Interval, timeout::Error as TimeoutError}; -use tokio::net::{TcpListener, TcpStream}; -use ethkey::{Public, KeyPair, Signature, Random, Generator}; +use parking_lot::RwLock; +use ethkey::{Public, Signature, Random, Generator}; use ethereum_types::{Address, H256}; use parity_runtime::Executor; use key_server_cluster::{Error, NodeId, SessionId, Requester, AclStorage, KeyStorage, KeyServerSet, NodeKeyPair}; use key_server_cluster::cluster_sessions::{ClusterSession, AdminSession, ClusterSessions, SessionIdWithSubSession, - ClusterSessionsContainer, SERVERS_SET_CHANGE_SESSION_ID, create_cluster_view, AdminSessionCreationData, ClusterSessionsListener}; -use key_server_cluster::cluster_sessions_creator::{ClusterSessionCreator, IntoSessionId}; -use key_server_cluster::message::{self, Message, ClusterMessage}; + ClusterSessionsContainer, SERVERS_SET_CHANGE_SESSION_ID, create_cluster_view, + AdminSessionCreationData, ClusterSessionsListener}; +use key_server_cluster::cluster_sessions_creator::ClusterSessionCreator; +use key_server_cluster::cluster_connections::{ConnectionProvider, ConnectionManager}; +use key_server_cluster::cluster_connections_net::{NetConnectionsManager, + NetConnectionsContainer, NetConnectionsManagerConfig}; +use key_server_cluster::cluster_message_processor::{MessageProcessor, SessionsMessageProcessor}; +use key_server_cluster::message::Message; use key_server_cluster::generation_session::{SessionImpl as GenerationSession}; use key_server_cluster::decryption_session::{SessionImpl as DecryptionSession}; use key_server_cluster::encryption_session::{SessionImpl as EncryptionSession}; @@ -41,31 +37,15 @@ use key_server_cluster::signing_session_ecdsa::{SessionImpl as EcdsaSigningSessi use key_server_cluster::signing_session_schnorr::{SessionImpl as SchnorrSigningSession}; use key_server_cluster::key_version_negotiation_session::{SessionImpl as KeyVersionNegotiationSession, IsolatedSessionTransport as KeyVersionNegotiationSessionTransport, ContinueAction}; -use key_server_cluster::io::{DeadlineStatus, ReadMessage, SharedTcpStream, read_encrypted_message, WriteMessage, write_encrypted_message}; -use key_server_cluster::net::{accept_connection as net_accept_connection, connect as net_connect, Connection as NetConnection}; -use key_server_cluster::connection_trigger::{Maintain, ConnectionTrigger, SimpleConnectionTrigger, ServersSetChangeSessionCreatorConnector}; +use key_server_cluster::connection_trigger::{ConnectionTrigger, + SimpleConnectionTrigger, ServersSetChangeSessionCreatorConnector}; use key_server_cluster::connection_trigger_with_migration::ConnectionTriggerWithMigration; -/// Maintain interval (seconds). Every MAINTAIN_INTERVAL seconds node: -/// 1) checks if connected nodes are responding to KeepAlive messages -/// 2) tries to connect to disconnected nodes -/// 3) checks if enc/dec sessions are time-outed -const MAINTAIN_INTERVAL: u64 = 10; - -/// When no messages have been received from node within KEEP_ALIVE_SEND_INTERVAL seconds, -/// we must send KeepAlive message to the node to check if it still responds to messages. -const KEEP_ALIVE_SEND_INTERVAL: Duration = Duration::from_secs(30); -/// When no messages have been received from node within KEEP_ALIVE_DISCONNECT_INTERVAL seconds, -/// we must treat this node as non-responding && disconnect from it. -const KEEP_ALIVE_DISCONNECT_INTERVAL: Duration = Duration::from_secs(60); - -/// Empty future. -pub type BoxedEmptyFuture = Box + Send>; +#[cfg(test)] +use key_server_cluster::cluster_connections::tests::{MessagesQueue, TestConnections, new_test_connections}; /// Cluster interface for external clients. pub trait ClusterClient: Send + Sync { - /// Get cluster state. - fn cluster_state(&self) -> ClusterState; /// Start new generation session. fn new_generation_session(&self, session_id: SessionId, origin: Option
, author: Address, threshold: usize) -> Result, Error>; /// Start new encryption session. @@ -94,12 +74,11 @@ pub trait ClusterClient: Send + Sync { /// Get active generation session with given id. #[cfg(test)] fn generation_session(&self, session_id: &SessionId) -> Option>; + #[cfg(test)] + fn is_fully_connected(&self) -> bool; /// Try connect to disconnected nodes. #[cfg(test)] fn connect(&self); - /// Get key storage. - #[cfg(test)] - fn key_storage(&self) -> Arc; } /// Cluster access for single session participant. @@ -121,12 +100,8 @@ pub trait Cluster: Send + Sync { /// Cluster initialization parameters. #[derive(Clone)] pub struct ClusterConfiguration { - /// Allow connecting to 'higher' nodes. - pub allow_connecting_to_higher_nodes: bool, /// KeyPair this node holds. pub self_key_pair: Arc, - /// Interface to listen to. - pub listen_address: (String, u16), /// Cluster nodes set. pub key_server_set: Arc, /// Reference to key storage @@ -135,114 +110,132 @@ pub struct ClusterConfiguration { pub acl_storage: Arc, /// Administrator public key. pub admin_public: Option, - /// Should key servers set change session when servers set changes? This - /// will only work when servers set is configured using KeyServerSet - /// contract. - pub auto_migrate_enabled: bool, -} - -/// Cluster state. -pub struct ClusterState { - /// Nodes, to which connections are established. - pub connected: BTreeSet, + /// Do not remove sessions from container. + pub preserve_sessions: bool, } /// Network cluster implementation. -pub struct ClusterCore { - /// Listen address. - listen_address: SocketAddr, +pub struct ClusterCore { /// Cluster data. - data: Arc, + data: Arc>, } /// Network cluster client interface implementation. -pub struct ClusterClientImpl { +pub struct ClusterClientImpl { /// Cluster data. - data: Arc, + data: Arc>, } /// Network cluster view. It is a communication channel, required in single session. pub struct ClusterView { - core: Arc>, configured_nodes_count: usize, - connected_nodes_count: usize, + connected_nodes: BTreeSet, + connections: Arc, + self_key_pair: Arc, } /// Cross-thread shareable cluster data. -pub struct ClusterData { +pub struct ClusterData { /// Cluster configuration. pub config: ClusterConfiguration, - /// Handle to the event loop. - pub executor: Executor, /// KeyPair this node holds. pub self_key_pair: Arc, /// Connections data. - pub connections: ClusterConnections, + pub connections: C, /// Active sessions data. - pub sessions: ClusterSessions, - /// A shutdown flag. - pub is_shutdown: Arc, -} - -/// Connections that are forming the cluster. Lock order: trigger.lock() -> data.lock(). -pub struct ClusterConnections { - /// Self node id. - pub self_node_id: NodeId, - /// All known other key servers. - pub key_server_set: Arc, - /// Connections trigger. - pub trigger: Mutex>, - /// Servers set change session creator connector. - pub connector: Arc, - /// Connections data. - pub data: RwLock, + pub sessions: Arc, + // Messages processor. + pub message_processor: Arc, + /// Link between servers set chnage session and the connections manager. + pub servers_set_change_creator_connector: Arc, } -/// Cluster connections data. -pub struct ClusterConnectionsData { - /// Is this node isolated from cluster? - pub is_isolated: bool, - /// Active key servers set. - pub nodes: BTreeMap, - /// Active connections to key servers. - pub connections: BTreeMap>, -} +/// Create new network-backed cluster. +pub fn new_network_cluster( + executor: Executor, + config: ClusterConfiguration, + net_config: NetConnectionsManagerConfig +) -> Result>, Error> { + let mut nodes = config.key_server_set.snapshot().current_set; + let is_isolated = nodes.remove(config.self_key_pair.public()).is_none(); + let connections_data = Arc::new(RwLock::new(NetConnectionsContainer { + is_isolated, + nodes, + connections: BTreeMap::new(), + })); + + let connection_trigger: Box = match net_config.auto_migrate_enabled { + false => Box::new(SimpleConnectionTrigger::with_config(&config)), + true if config.admin_public.is_none() => Box::new(ConnectionTriggerWithMigration::with_config(&config)), + true => return Err(Error::Internal( + "secret store admininstrator public key is specified with auto-migration enabled".into() + )), + }; -/// Cluster view core. -struct ClusterViewCore { - /// Cluster reference. - cluster: Arc, - /// Subset of nodes, required for this session. - nodes: BTreeSet, + let servers_set_change_creator_connector = connection_trigger.servers_set_change_creator_connector(); + let sessions = Arc::new(ClusterSessions::new(&config, servers_set_change_creator_connector.clone())); + let message_processor = Arc::new(SessionsMessageProcessor::new( + config.self_key_pair.clone(), + servers_set_change_creator_connector.clone(), + sessions.clone(), + connections_data.clone())); + + let connections = NetConnectionsManager::new( + executor, + message_processor.clone(), + connection_trigger, + connections_data, + &config, + net_config)?; + connections.start()?; + + ClusterCore::new(sessions, message_processor, connections, servers_set_change_creator_connector, config) } -/// Connection to single node. -pub struct Connection { - /// Node id. - node_id: NodeId, - /// Node address. - node_address: SocketAddr, - /// Is inbound connection? - is_inbound: bool, - /// Tcp stream. - stream: SharedTcpStream, - /// Connection key. - key: KeyPair, - /// Last message time. - last_message_time: RwLock, +/// Create new in-memory backed cluster +#[cfg(test)] +pub fn new_test_cluster( + messages: MessagesQueue, + config: ClusterConfiguration, +) -> Result>>, Error> { + let nodes = config.key_server_set.snapshot().current_set; + let connections = new_test_connections(messages, *config.self_key_pair.public(), nodes.keys().cloned().collect()); + + let connection_trigger = Box::new(SimpleConnectionTrigger::with_config(&config)); + let servers_set_change_creator_connector = connection_trigger.servers_set_change_creator_connector(); + let mut sessions = ClusterSessions::new(&config, servers_set_change_creator_connector.clone()); + if config.preserve_sessions { + sessions.preserve_sessions(); + } + let sessions = Arc::new(sessions); + + let message_processor = Arc::new(SessionsMessageProcessor::new( + config.self_key_pair.clone(), + servers_set_change_creator_connector.clone(), + sessions.clone(), + connections.provider(), + )); + + ClusterCore::new(sessions, message_processor, connections, servers_set_change_creator_connector, config) } -impl ClusterCore { - pub fn new(executor: Executor, config: ClusterConfiguration) -> Result, Error> { - let listen_address = make_socket_address(&config.listen_address.0, config.listen_address.1)?; - let connections = ClusterConnections::new(&config)?; - let servers_set_change_creator_connector = connections.connector.clone(); - let sessions = ClusterSessions::new(&config, servers_set_change_creator_connector); - let data = ClusterData::new(&executor, config, connections, sessions); - +impl ClusterCore { + pub fn new( + sessions: Arc, + message_processor: Arc, + connections: C, + servers_set_change_creator_connector: Arc, + config: ClusterConfiguration, + ) -> Result, Error> { Ok(Arc::new(ClusterCore { - listen_address: listen_address, - data: data, + data: Arc::new(ClusterData { + self_key_pair: config.self_key_pair.clone(), + connections, + sessions: sessions.clone(), + config, + message_processor, + servers_set_change_creator_connector + }), })) } @@ -251,657 +244,68 @@ impl ClusterCore { Arc::new(ClusterClientImpl::new(self.data.clone())) } - /// Get cluster configuration. - #[cfg(test)] - pub fn config(&self) -> &ClusterConfiguration { - &self.data.config - } - - /// Get connection to given node. - #[cfg(test)] - pub fn connection(&self, node: &NodeId) -> Option> { - self.data.connection(node) - } - /// Run cluster. pub fn run(&self) -> Result<(), Error> { - self.run_listener() - .and_then(|_| self.run_connections())?; - - // schedule maintain procedures - ClusterCore::schedule_maintain(self.data.clone()); - - Ok(()) - } - - /// Start listening for incoming connections. - pub fn run_listener(&self) -> Result<(), Error> { - // start listeining for incoming connections - self.data.spawn(ClusterCore::listen(self.data.clone(), self.listen_address.clone())?); + self.data.connections.connect(); Ok(()) } - /// Start connecting to other nodes. - pub fn run_connections(&self) -> Result<(), Error> { - // try to connect to every other peer - ClusterCore::connect_disconnected_nodes(self.data.clone()); - Ok(()) - } - - /// Connect to peer. - fn connect(data: Arc, node_address: SocketAddr) { - data.clone().spawn(ClusterCore::connect_future(data, node_address)); - } - - /// Connect to socket using given context and executor. - fn connect_future(data: Arc, node_address: SocketAddr) -> BoxedEmptyFuture { - let disconnected_nodes = data.connections.disconnected_nodes().keys().cloned().collect(); - Box::new(net_connect(&node_address, data.self_key_pair.clone(), disconnected_nodes) - .then(move |result| ClusterCore::process_connection_result(data, Some(node_address), result)) - .then(|_| future::ok(()))) - } - - /// Start listening for incoming connections. - fn listen(data: Arc, listen_address: SocketAddr) -> Result { - Ok(Box::new(TcpListener::bind(&listen_address)? - .incoming() - .and_then(move |stream| { - ClusterCore::accept_connection(data.clone(), stream); - Ok(()) - }) - .for_each(|_| Ok(())) - .then(|_| future::ok(())))) - } - - /// Accept connection. - fn accept_connection(data: Arc, stream: TcpStream) { - data.clone().spawn(ClusterCore::accept_connection_future(data, stream)) - } - - /// Accept connection future. - fn accept_connection_future(data: Arc, stream: TcpStream) -> BoxedEmptyFuture { - Box::new(net_accept_connection(stream, data.self_key_pair.clone()) - .then(move |result| ClusterCore::process_connection_result(data, None, result)) - .then(|_| future::ok(()))) - } - - /// Schedule mainatain procedures. - fn schedule_maintain(data: Arc) { - let d = data.clone(); - - let interval = Interval::new_interval(Duration::new(MAINTAIN_INTERVAL, 0)) - .and_then(move |_| Ok(ClusterCore::maintain(data.clone()))) - .for_each(|_| Ok(())) - .then(|_| future::ok(())); - - d.spawn(interval); - } - - /// Execute maintain procedures. - fn maintain(data: Arc) { - trace!(target: "secretstore_net", "{}: executing maintain procedures", data.self_key_pair.public()); - - ClusterCore::keep_alive(data.clone()); - ClusterCore::connect_disconnected_nodes(data.clone()); - data.sessions.stop_stalled_sessions(); - } - - /// Called for every incomming mesage. - fn process_connection_messages(data: Arc, connection: Arc) -> IoFuture> { - Box::new(connection - .read_message() - .then(move |result| - match result { - Ok((_, Ok(message))) => { - ClusterCore::process_connection_message(data.clone(), connection.clone(), message); - // continue serving connection - data.spawn(ClusterCore::process_connection_messages(data.clone(), connection).then(|_| Ok(()))); - Box::new(future::ok(Ok(()))) - }, - Ok((_, Err(err))) => { - warn!(target: "secretstore_net", "{}: protocol error '{}' when reading message from node {}", data.self_key_pair.public(), err, connection.node_id()); - // continue serving connection - data.spawn(ClusterCore::process_connection_messages(data.clone(), connection).then(|_| Ok(()))); - Box::new(future::ok(Err(err))) - }, - Err(err) => { - warn!(target: "secretstore_net", "{}: network error '{}' when reading message from node {}", data.self_key_pair.public(), err, connection.node_id()); - // close connection - data.connections.remove(data.clone(), connection.node_id(), connection.is_inbound()); - Box::new(future::err(err)) - }, - } - )) - } - - /// Send keepalive messages to every othe node. - fn keep_alive(data: Arc) { - data.sessions.sessions_keep_alive(); - for connection in data.connections.active_connections() { - let last_message_diff = Instant::now() - connection.last_message_time(); - if last_message_diff > KEEP_ALIVE_DISCONNECT_INTERVAL { - warn!(target: "secretstore_net", "{}: keep alive timeout for node {}", - data.self_key_pair.public(), connection.node_id()); - - data.connections.remove(data.clone(), connection.node_id(), connection.is_inbound()); - data.sessions.on_connection_timeout(connection.node_id()); - } - else if last_message_diff > KEEP_ALIVE_SEND_INTERVAL { - data.spawn(connection.send_message(Message::Cluster(ClusterMessage::KeepAlive(message::KeepAlive {}))).then(|_| Ok(()))); - } - } - } - - /// Try to connect to every disconnected node. - fn connect_disconnected_nodes(data: Arc) { - let r = data.connections.update_nodes_set(data.clone()); - if let Some(r) = r { - data.spawn(r); - } - - // connect to disconnected nodes - for (node_id, node_address) in data.connections.disconnected_nodes() { - if data.config.allow_connecting_to_higher_nodes || data.self_key_pair.public() < &node_id { - ClusterCore::connect(data.clone(), node_address); - } - } - } - - /// Process connection future result. - fn process_connection_result(data: Arc, outbound_addr: Option, - result: Result>, TimeoutError>) -> IoFuture> - { - match result { - Ok(DeadlineStatus::Meet(Ok(connection))) => { - let connection = Connection::new(outbound_addr.is_none(), connection); - if data.connections.insert(data.clone(), connection.clone()) { - ClusterCore::process_connection_messages(data.clone(), connection) - } else { - Box::new(future::ok(Ok(()))) - } - }, - Ok(DeadlineStatus::Meet(Err(err))) => { - warn!(target: "secretstore_net", "{}: protocol error '{}' when establishing {} connection{}", - data.self_key_pair.public(), err, if outbound_addr.is_some() { "outbound" } else { "inbound" }, - outbound_addr.map(|a| format!(" with {}", a)).unwrap_or_default()); - Box::new(future::ok(Ok(()))) - }, - Ok(DeadlineStatus::Timeout) => { - warn!(target: "secretstore_net", "{}: timeout when establishing {} connection{}", - data.self_key_pair.public(), if outbound_addr.is_some() { "outbound" } else { "inbound" }, - outbound_addr.map(|a| format!(" with {}", a)).unwrap_or_default()); - Box::new(future::ok(Ok(()))) - }, - Err(err) => { - warn!(target: "secretstore_net", "{}: network error '{}' when establishing {} connection{}", - data.self_key_pair.public(), err, if outbound_addr.is_some() { "outbound" } else { "inbound" }, - outbound_addr.map(|a| format!(" with {}", a)).unwrap_or_default()); - Box::new(future::ok(Ok(()))) - }, - } - } - - /// Process single message from the connection. - fn process_connection_message(data: Arc, connection: Arc, message: Message) { - connection.set_last_message_time(Instant::now()); - trace!(target: "secretstore_net", "{}: received message {} from {}", data.self_key_pair.public(), message, connection.node_id()); - // error is ignored as we only process errors on session level - match message { - Message::Generation(message) => Self::process_message(&data, &data.sessions.generation_sessions, connection, Message::Generation(message)) - .map(|_| ()).unwrap_or_default(), - Message::Encryption(message) => Self::process_message(&data, &data.sessions.encryption_sessions, connection, Message::Encryption(message)) - .map(|_| ()).unwrap_or_default(), - Message::Decryption(message) => Self::process_message(&data, &data.sessions.decryption_sessions, connection, Message::Decryption(message)) - .map(|_| ()).unwrap_or_default(), - Message::SchnorrSigning(message) => Self::process_message(&data, &data.sessions.schnorr_signing_sessions, connection, Message::SchnorrSigning(message)) - .map(|_| ()).unwrap_or_default(), - Message::EcdsaSigning(message) => Self::process_message(&data, &data.sessions.ecdsa_signing_sessions, connection, Message::EcdsaSigning(message)) - .map(|_| ()).unwrap_or_default(), - Message::ServersSetChange(message) => { - let message = Message::ServersSetChange(message); - let is_initialization_message = message.is_initialization_message(); - let session = Self::process_message(&data, &data.sessions.admin_sessions, connection, message); - if is_initialization_message { - if let Some(session) = session { - data.connections.servers_set_change_creator_connector().set_key_servers_set_change_session(session.clone()); - } - } - } - Message::KeyVersionNegotiation(message) => { - let session = Self::process_message(&data, &data.sessions.negotiation_sessions, connection, Message::KeyVersionNegotiation(message)); - Self::try_continue_session(&data, session); - }, - Message::ShareAdd(message) => Self::process_message(&data, &data.sessions.admin_sessions, connection, Message::ShareAdd(message)) - .map(|_| ()).unwrap_or_default(), - Message::Cluster(message) => ClusterCore::process_cluster_message(data, connection, message), - } - } - - /// Try to contnue session. - fn try_continue_session(data: &Arc, session: Option>>) { - if let Some(session) = session { - let meta = session.meta(); - let is_master_node = meta.self_node_id == meta.master_node_id; - if is_master_node && session.is_finished() { - data.sessions.negotiation_sessions.remove(&session.id()); - match session.wait() { - Ok(Some((version, master))) => match session.take_continue_action() { - Some(ContinueAction::Decrypt(session, origin, is_shadow_decryption, is_broadcast_decryption)) => { - let initialization_error = if data.self_key_pair.public() == &master { - session.initialize(origin, version, is_shadow_decryption, is_broadcast_decryption) - } else { - session.delegate(master, origin, version, is_shadow_decryption, is_broadcast_decryption) - }; - - if let Err(error) = initialization_error { - session.on_session_error(&meta.self_node_id, error); - data.sessions.decryption_sessions.remove(&session.id()); - } - }, - Some(ContinueAction::SchnorrSign(session, message_hash)) => { - let initialization_error = if data.self_key_pair.public() == &master { - session.initialize(version, message_hash) - } else { - session.delegate(master, version, message_hash) - }; - - if let Err(error) = initialization_error { - session.on_session_error(&meta.self_node_id, error); - data.sessions.schnorr_signing_sessions.remove(&session.id()); - } - }, - Some(ContinueAction::EcdsaSign(session, message_hash)) => { - let initialization_error = if data.self_key_pair.public() == &master { - session.initialize(version, message_hash) - } else { - session.delegate(master, version, message_hash) - }; - - if let Err(error) = initialization_error { - session.on_session_error(&meta.self_node_id, error); - data.sessions.ecdsa_signing_sessions.remove(&session.id()); - } - }, - None => (), - }, - Ok(None) => unreachable!("is_master_node; session is finished; negotiation version always finished with result on master; qed"), - Err(error) => match session.take_continue_action() { - Some(ContinueAction::Decrypt(session, _, _, _)) => { - session.on_session_error(&meta.self_node_id, error); - data.sessions.decryption_sessions.remove(&session.id()); - }, - Some(ContinueAction::SchnorrSign(session, _)) => { - session.on_session_error(&meta.self_node_id, error); - data.sessions.schnorr_signing_sessions.remove(&session.id()); - }, - Some(ContinueAction::EcdsaSign(session, _)) => { - session.on_session_error(&meta.self_node_id, error); - data.sessions.ecdsa_signing_sessions.remove(&session.id()); - }, - None => (), - }, - } - } - } - } - - /// Get or insert new session. - fn prepare_session, D>(data: &Arc, sessions: &ClusterSessionsContainer, sender: &NodeId, message: &Message) -> Result, Error> - where Message: IntoSessionId { - fn requires_all_connections(message: &Message) -> bool { - match *message { - Message::Generation(_) => true, - Message::ShareAdd(_) => true, - Message::ServersSetChange(_) => true, - _ => false, - } - } - - // get or create new session, if required - let session_id = message.into_session_id().expect("into_session_id fails for cluster messages only; only session messages are passed to prepare_session; qed"); - let is_initialization_message = message.is_initialization_message(); - let is_delegation_message = message.is_delegation_message(); - match is_initialization_message || is_delegation_message { - false => sessions.get(&session_id, true).ok_or(Error::NoActiveSessionWithId), - true => { - let creation_data = SC::creation_data_from_message(&message)?; - let master = if is_initialization_message { sender.clone() } else { data.self_key_pair.public().clone() }; - let cluster = create_cluster_view(data, requires_all_connections(&message))?; - - sessions.insert(cluster, master, session_id, Some(message.session_nonce().ok_or(Error::InvalidMessage)?), message.is_exclusive_session_message(), creation_data) - }, - } - } - - /// Process single session message from connection. - fn process_message, D>(data: &Arc, sessions: &ClusterSessionsContainer, connection: Arc, mut message: Message) -> Option> - where Message: IntoSessionId { - - // get or create new session, if required - let mut sender = connection.node_id().clone(); - let session = Self::prepare_session(data, sessions, &sender, &message); - // send error if session is not found, or failed to create - let session = match session { - Ok(session) => session, - Err(error) => { - // this is new session => it is not yet in container - warn!(target: "secretstore_net", "{}: {} session read error '{}' when requested for session from node {}", - data.self_key_pair.public(), S::type_name(), error, sender); - if !message.is_error_message() { - let session_id = message.into_session_id().expect("session_id only fails for cluster messages; only session messages are passed to process_message; qed"); - let session_nonce = message.session_nonce().expect("session_nonce only fails for cluster messages; only session messages are passed to process_message; qed"); - data.spawn(connection.send_message(SC::make_error_message(session_id, session_nonce, error)).then(|_| Ok(()))); - } - return None; - }, - }; - - let session_id = session.id(); - let mut is_queued_message = false; - loop { - let message_result = session.on_message(&sender, &message); - match message_result { - Ok(_) => { - // if session is completed => stop - if session.is_finished() { - info!(target: "secretstore_net", "{}: {} session completed", data.self_key_pair.public(), S::type_name()); - sessions.remove(&session_id); - return Some(session); - } - - // try to dequeue message - match sessions.dequeue_message(&session_id) { - Some((msg_sender, msg)) => { - is_queued_message = true; - sender = msg_sender; - message = msg; - }, - None => return Some(session), - } - }, - Err(Error::TooEarlyForRequest) => { - sessions.enqueue_message(&session_id, sender, message, is_queued_message); - return Some(session); - }, - Err(err) => { - warn!(target: "secretstore_net", "{}: {} session error '{}' when processing message {} from node {}", - data.self_key_pair.public(), - S::type_name(), - err, - message, - sender); - session.on_session_error(data.self_key_pair.public(), err); - sessions.remove(&session_id); - return Some(session); - }, - } - } - } - - /// Process single cluster message from the connection. - fn process_cluster_message(data: Arc, connection: Arc, message: ClusterMessage) { - match message { - ClusterMessage::KeepAlive(_) => data.spawn(connection.send_message(Message::Cluster(ClusterMessage::KeepAliveResponse(message::KeepAliveResponse { - session_id: None, - }))).then(|_| Ok(()))), - ClusterMessage::KeepAliveResponse(msg) => if let Some(session_id) = msg.session_id { - data.sessions.on_session_keep_alive(connection.node_id(), session_id.into()); - }, - _ => warn!(target: "secretstore_net", "{}: received unexpected message {} from node {} at {}", data.self_key_pair.public(), message, connection.node_id(), connection.node_address()), - } - } - - /// Prevents new tasks from being spawned. #[cfg(test)] - pub fn shutdown(&self) { - self.data.shutdown() - } -} - -impl ClusterConnections { - pub fn new(config: &ClusterConfiguration) -> Result { - let mut nodes = config.key_server_set.snapshot().current_set; - let is_isolated = nodes.remove(config.self_key_pair.public()).is_none(); - - let trigger: Box = match config.auto_migrate_enabled { - false => Box::new(SimpleConnectionTrigger::new(config.key_server_set.clone(), config.self_key_pair.clone(), config.admin_public.clone())), - true if config.admin_public.is_none() => Box::new(ConnectionTriggerWithMigration::new(config.key_server_set.clone(), config.self_key_pair.clone())), - true => return Err(Error::Internal("secret store admininstrator public key is specified with auto-migration enabled".into())), - }; - let connector = trigger.servers_set_change_creator_connector(); - - Ok(ClusterConnections { - self_node_id: config.self_key_pair.public().clone(), - key_server_set: config.key_server_set.clone(), - trigger: Mutex::new(trigger), - connector: connector, - data: RwLock::new(ClusterConnectionsData { - is_isolated: is_isolated, - nodes: nodes, - connections: BTreeMap::new(), - }), - }) - } - - pub fn cluster_state(&self) -> ClusterState { - ClusterState { - connected: self.data.read().connections.keys().cloned().collect(), - } - } - - pub fn get(&self, node: &NodeId) -> Option> { - self.data.read().connections.get(node).cloned() - } - - pub fn insert(&self, data: Arc, connection: Arc) -> bool { - { - let mut data = self.data.write(); - if !data.nodes.contains_key(connection.node_id()) { - // incoming connections are checked here - trace!(target: "secretstore_net", "{}: ignoring unknown connection from {} at {}", self.self_node_id, connection.node_id(), connection.node_address()); - debug_assert!(connection.is_inbound()); - return false; - } - - if data.connections.contains_key(connection.node_id()) { - // we have already connected to the same node - // the agreement is that node with lower id must establish connection to node with higher id - if (&self.self_node_id < connection.node_id() && connection.is_inbound()) - || (&self.self_node_id > connection.node_id() && !connection.is_inbound()) { - return false; - } - } - - let node = connection.node_id().clone(); - trace!(target: "secretstore_net", "{}: inserting connection to {} at {}. Connected to {} of {} nodes", - self.self_node_id, node, connection.node_address(), data.connections.len() + 1, data.nodes.len()); - data.connections.insert(node.clone(), connection.clone()); - } - - let maintain_action = self.trigger.lock().on_connection_established(connection.node_id()); - self.maintain_connection_trigger(maintain_action, data); - - true - } - - pub fn remove(&self, data: Arc, node: &NodeId, is_inbound: bool) { - { - let mut data = self.data.write(); - if let Entry::Occupied(entry) = data.connections.entry(node.clone()) { - if entry.get().is_inbound() != is_inbound { - return; - } - - trace!(target: "secretstore_net", "{}: removing connection to {} at {}", self.self_node_id, entry.get().node_id(), entry.get().node_address()); - entry.remove_entry(); - } else { - return; - } - } - - let maintain_action = self.trigger.lock().on_connection_closed(node); - self.maintain_connection_trigger(maintain_action, data); - } - - pub fn connected_nodes(&self) -> Result, Error> { - let data = self.data.read(); - if data.is_isolated { - return Err(Error::NodeDisconnected); - } - - Ok(data.connections.keys().cloned().collect()) - } - - pub fn active_connections(&self)-> Vec> { - self.data.read().connections.values().cloned().collect() - } - - pub fn disconnected_nodes(&self) -> BTreeMap { - let data = self.data.read(); - data.nodes.iter() - .filter(|&(node_id, _)| !data.connections.contains_key(node_id)) - .map(|(node_id, node_address)| (node_id.clone(), node_address.clone())) - .collect() - } - - pub fn servers_set_change_creator_connector(&self) -> Arc { - self.connector.clone() - } - - pub fn update_nodes_set(&self, data: Arc) -> Option { - let maintain_action = self.trigger.lock().on_maintain(); - self.maintain_connection_trigger(maintain_action, data); - None - } - - fn maintain_connection_trigger(&self, maintain_action: Option, data: Arc) { - if maintain_action == Some(Maintain::SessionAndConnections) || maintain_action == Some(Maintain::Session) { - let client = ClusterClientImpl::new(data); - self.trigger.lock().maintain_session(&client); - } - if maintain_action == Some(Maintain::SessionAndConnections) || maintain_action == Some(Maintain::Connections) { - let mut trigger = self.trigger.lock(); - let mut data = self.data.write(); - trigger.maintain_connections(&mut *data); - } - } -} - -impl ClusterData { - pub fn new(executor: &Executor, config: ClusterConfiguration, connections: ClusterConnections, sessions: ClusterSessions) -> Arc { - Arc::new(ClusterData { - executor: executor.clone(), - self_key_pair: config.self_key_pair.clone(), - connections: connections, - sessions: sessions, - config: config, - is_shutdown: Arc::new(AtomicBool::new(false)), - }) - } - - /// Get connection to given node. - pub fn connection(&self, node: &NodeId) -> Option> { - self.connections.get(node) - } - - /// Spawns a future on the runtime. - pub fn spawn(&self, f: F) where F: Future + Send + 'static { - if self.is_shutdown.load(Ordering::Acquire) == false { - if let Err(err) = future::Executor::execute(&self.executor, Box::new(f)) { - error!("Secret store runtime unable to spawn task. Runtime is shutting down. ({:?})", err); - } - } else { - error!("Secret store runtime unable to spawn task. Shutdown has been started."); - } - } - - /// Sets the `is_shutdown` flag which prevents future tasks from being - /// spawned via `::spawn`. - #[cfg(test)] - pub fn shutdown(&self) { - self.is_shutdown.store(true, Ordering::Release); - } -} - -impl Connection { - pub fn new(is_inbound: bool, connection: NetConnection) -> Arc { - Arc::new(Connection { - node_id: connection.node_id, - node_address: connection.address, - is_inbound: is_inbound, - stream: connection.stream, - key: connection.key, - last_message_time: RwLock::new(Instant::now()), - }) - } - - pub fn is_inbound(&self) -> bool { - self.is_inbound - } - - pub fn node_id(&self) -> &NodeId { - &self.node_id - } - - pub fn last_message_time(&self) -> Instant { - *self.last_message_time.read() - } - - pub fn set_last_message_time(&self, last_message_time: Instant) { - *self.last_message_time.write() = last_message_time; - } - - pub fn node_address(&self) -> &SocketAddr { - &self.node_address - } - - pub fn send_message(&self, message: Message) -> WriteMessage { - write_encrypted_message(self.stream.clone(), &self.key, message) - } + pub fn view(&self) -> Result, Error> { + let connections = self.data.connections.provider(); + let mut connected_nodes = connections.connected_nodes()?; + let disconnected_nodes = connections.disconnected_nodes(); + connected_nodes.insert(self.data.self_key_pair.public().clone()); - pub fn read_message(&self) -> ReadMessage { - read_encrypted_message(self.stream.clone(), self.key.clone()) + let connected_nodes_count = connected_nodes.len(); + let disconnected_nodes_count = disconnected_nodes.len(); + Ok(Arc::new(ClusterView::new( + self.data.self_key_pair.clone(), + connections, + connected_nodes, + connected_nodes_count + disconnected_nodes_count))) } } impl ClusterView { - pub fn new(cluster: Arc, nodes: BTreeSet, configured_nodes_count: usize) -> Self { + pub fn new( + self_key_pair: Arc, + connections: Arc, + nodes: BTreeSet, + configured_nodes_count: usize + ) -> Self { ClusterView { configured_nodes_count: configured_nodes_count, - connected_nodes_count: nodes.len(), - core: Arc::new(RwLock::new(ClusterViewCore { - cluster: cluster, - nodes: nodes, - })), + connected_nodes: nodes, + connections, + self_key_pair, } } } impl Cluster for ClusterView { fn broadcast(&self, message: Message) -> Result<(), Error> { - let core = self.core.read(); - for node in core.nodes.iter().filter(|n| *n != core.cluster.self_key_pair.public()) { - trace!(target: "secretstore_net", "{}: sent message {} to {}", core.cluster.self_key_pair.public(), message, node); - let connection = core.cluster.connection(node).ok_or(Error::NodeDisconnected)?; - core.cluster.spawn(connection.send_message(message.clone()).then(|_| Ok(()))) + for node in self.connected_nodes.iter().filter(|n| *n != self.self_key_pair.public()) { + trace!(target: "secretstore_net", "{}: sent message {} to {}", self.self_key_pair.public(), message, node); + let connection = self.connections.connection(node).ok_or(Error::NodeDisconnected)?; + connection.send_message(message.clone()); } Ok(()) } fn send(&self, to: &NodeId, message: Message) -> Result<(), Error> { - let core = self.core.read(); - trace!(target: "secretstore_net", "{}: sent message {} to {}", core.cluster.self_key_pair.public(), message, to); - let connection = core.cluster.connection(to).ok_or(Error::NodeDisconnected)?; - core.cluster.spawn(connection.send_message(message).then(|_| Ok(()))); + trace!(target: "secretstore_net", "{}: sent message {} to {}", self.self_key_pair.public(), message, to); + let connection = self.connections.connection(to).ok_or(Error::NodeDisconnected)?; + connection.send_message(message); Ok(()) } fn is_connected(&self, node: &NodeId) -> bool { - self.core.read().nodes.contains(node) + self.connected_nodes.contains(node) } fn nodes(&self) -> BTreeSet { - self.core.read().nodes.clone() + self.connected_nodes.clone() } fn configured_nodes_count(&self) -> usize { @@ -909,24 +313,24 @@ impl Cluster for ClusterView { } fn connected_nodes_count(&self) -> usize { - self.connected_nodes_count + self.connected_nodes.len() } } -impl ClusterClientImpl { - pub fn new(data: Arc) -> Self { +impl ClusterClientImpl { + pub fn new(data: Arc>) -> Self { ClusterClientImpl { data: data, } } fn create_key_version_negotiation_session(&self, session_id: SessionId) -> Result>, Error> { - let mut connected_nodes = self.data.connections.connected_nodes()?; + let mut connected_nodes = self.data.connections.provider().connected_nodes()?; connected_nodes.insert(self.data.self_key_pair.public().clone()); let access_key = Random.generate()?.secret().clone(); let session_id = SessionIdWithSubSession::new(session_id, access_key); - let cluster = create_cluster_view(&self.data, false)?; + let cluster = create_cluster_view(self.data.self_key_pair.clone(), self.data.connections.provider(), false)?; let session = self.data.sessions.negotiation_sessions.insert(cluster, self.data.self_key_pair.public().clone(), session_id.clone(), None, false, None)?; match session.initialize(connected_nodes) { Ok(()) => Ok(session), @@ -936,56 +340,38 @@ 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 { - fn cluster_state(&self) -> ClusterState { - self.data.connections.cluster_state() - } - +impl ClusterClient for ClusterClientImpl { fn new_generation_session(&self, session_id: SessionId, origin: Option
, author: Address, threshold: usize) -> Result, Error> { - let mut connected_nodes = self.data.connections.connected_nodes()?; + let mut connected_nodes = self.data.connections.provider().connected_nodes()?; connected_nodes.insert(self.data.self_key_pair.public().clone()); - let cluster = create_cluster_view(&self.data, true)?; + let cluster = create_cluster_view(self.data.self_key_pair.clone(), self.data.connections.provider(), true)?; let session = self.data.sessions.generation_sessions.insert(cluster, self.data.self_key_pair.public().clone(), session_id, None, false, None)?; - Self::process_initialization_result( + 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> { - let mut connected_nodes = self.data.connections.connected_nodes()?; + let mut connected_nodes = self.data.connections.provider().connected_nodes()?; connected_nodes.insert(self.data.self_key_pair.public().clone()); - let cluster = create_cluster_view(&self.data, true)?; + let cluster = create_cluster_view(self.data.self_key_pair.clone(), self.data.connections.provider(), true)?; let session = self.data.sessions.encryption_sessions.insert(cluster, self.data.self_key_pair.public().clone(), session_id, None, false, None)?; - Self::process_initialization_result( + 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> { - let mut connected_nodes = self.data.connections.connected_nodes()?; + let mut connected_nodes = self.data.connections.provider().connected_nodes()?; connected_nodes.insert(self.data.self_key_pair.public().clone()); let access_key = Random.generate()?.secret().clone(); let session_id = SessionIdWithSubSession::new(session_id, access_key); - let cluster = create_cluster_view(&self.data, false)?; + let cluster = create_cluster_view(self.data.self_key_pair.clone(), self.data.connections.provider(), false)?; let session = self.data.sessions.decryption_sessions.insert(cluster, self.data.self_key_pair.public().clone(), session_id.clone(), None, false, Some(requester))?; @@ -995,23 +381,23 @@ impl ClusterClient for ClusterClientImpl { self.create_key_version_negotiation_session(session_id.id.clone()) .map(|version_session| { version_session.set_continue_action(ContinueAction::Decrypt(session.clone(), origin, is_shadow_decryption, is_broadcast_decryption)); - ClusterCore::try_continue_session(&self.data, Some(version_session)); + self.data.message_processor.try_continue_session(Some(version_session)); }) }, }; - Self::process_initialization_result( + 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> { - let mut connected_nodes = self.data.connections.connected_nodes()?; + let mut connected_nodes = self.data.connections.provider().connected_nodes()?; connected_nodes.insert(self.data.self_key_pair.public().clone()); let access_key = Random.generate()?.secret().clone(); let session_id = SessionIdWithSubSession::new(session_id, access_key); - let cluster = create_cluster_view(&self.data, false)?; + let cluster = create_cluster_view(self.data.self_key_pair.clone(), self.data.connections.provider(), false)?; let session = self.data.sessions.schnorr_signing_sessions.insert(cluster, self.data.self_key_pair.public().clone(), session_id.clone(), None, false, Some(requester))?; let initialization_result = match version { @@ -1020,23 +406,23 @@ impl ClusterClient for ClusterClientImpl { self.create_key_version_negotiation_session(session_id.id.clone()) .map(|version_session| { version_session.set_continue_action(ContinueAction::SchnorrSign(session.clone(), message_hash)); - ClusterCore::try_continue_session(&self.data, Some(version_session)); + self.data.message_processor.try_continue_session(Some(version_session)); }) }, }; - Self::process_initialization_result( + 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> { - let mut connected_nodes = self.data.connections.connected_nodes()?; + let mut connected_nodes = self.data.connections.provider().connected_nodes()?; connected_nodes.insert(self.data.self_key_pair.public().clone()); let access_key = Random.generate()?.secret().clone(); let session_id = SessionIdWithSubSession::new(session_id, access_key); - let cluster = create_cluster_view(&self.data, false)?; + let cluster = create_cluster_view(self.data.self_key_pair.clone(), self.data.connections.provider(), false)?; let session = self.data.sessions.ecdsa_signing_sessions.insert(cluster, self.data.self_key_pair.public().clone(), session_id.clone(), None, false, Some(requester))?; let initialization_result = match version { @@ -1045,12 +431,12 @@ impl ClusterClient for ClusterClientImpl { self.create_key_version_negotiation_session(session_id.id.clone()) .map(|version_session| { version_session.set_continue_action(ContinueAction::EcdsaSign(session.clone(), message_hash)); - ClusterCore::try_continue_session(&self.data, Some(version_session)); + self.data.message_processor.try_continue_session(Some(version_session)); }) }, }; - Self::process_initialization_result( + process_initialization_result( initialization_result, session, &self.data.sessions.ecdsa_signing_sessions) } @@ -1061,28 +447,18 @@ impl ClusterClient for ClusterClientImpl { } fn new_servers_set_change_session(&self, session_id: Option, migration_id: Option, new_nodes_set: BTreeSet, old_set_signature: Signature, new_set_signature: Signature) -> Result, Error> { - let mut connected_nodes = self.data.connections.connected_nodes()?; - connected_nodes.insert(self.data.self_key_pair.public().clone()); - - let session_id = match session_id { - Some(session_id) if session_id == *SERVERS_SET_CHANGE_SESSION_ID => session_id, - Some(_) => return Err(Error::InvalidMessage), - None => *SERVERS_SET_CHANGE_SESSION_ID, - }; - - let cluster = create_cluster_view(&self.data, true)?; - let creation_data = Some(AdminSessionCreationData::ServersSetChange(migration_id, new_nodes_set.clone())); - let session = self.data.sessions.admin_sessions.insert(cluster, self.data.self_key_pair.public().clone(), session_id, None, true, creation_data)?; - 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); - - 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) + new_servers_set_change_session( + self.data.self_key_pair.clone(), + &self.data.sessions, + self.data.connections.provider(), + self.data.servers_set_change_creator_connector.clone(), + ServersSetChangeParams { + session_id, + migration_id, + new_nodes_set, + old_set_signature, + new_set_signature, + }) } fn add_generation_listener(&self, listener: Arc>) { @@ -1097,11 +473,6 @@ impl ClusterClient for ClusterClientImpl { self.data.sessions.negotiation_sessions.add_listener(listener); } - #[cfg(test)] - fn connect(&self) { - ClusterCore::connect_disconnected_nodes(self.data.clone()); - } - #[cfg(test)] fn make_faulty_generation_sessions(&self) { self.data.sessions.make_faulty_generation_sessions(); @@ -1113,38 +484,92 @@ impl ClusterClient for ClusterClientImpl { } #[cfg(test)] - fn key_storage(&self) -> Arc { - self.data.config.key_storage.clone() + fn is_fully_connected(&self) -> bool { + self.data.connections.provider().disconnected_nodes().is_empty() + } + + #[cfg(test)] + fn connect(&self) { + self.data.connections.connect() } } -fn make_socket_address(address: &str, port: u16) -> Result { - let ip_address: IpAddr = address.parse().map_err(|_| Error::InvalidNodeAddress)?; - Ok(SocketAddr::new(ip_address, port)) +pub struct ServersSetChangeParams { + pub session_id: Option, + pub migration_id: Option, + pub new_nodes_set: BTreeSet, + pub old_set_signature: Signature, + pub new_set_signature: Signature, +} + +pub fn new_servers_set_change_session( + self_key_pair: Arc, + sessions: &ClusterSessions, + connections: Arc, + servers_set_change_creator_connector: Arc, + params: ServersSetChangeParams, +) -> Result, Error> { + let session_id = match params.session_id { + Some(session_id) if session_id == *SERVERS_SET_CHANGE_SESSION_ID => session_id, + Some(_) => return Err(Error::InvalidMessage), + None => *SERVERS_SET_CHANGE_SESSION_ID, + }; + + let cluster = create_cluster_view(self_key_pair.clone(), connections, true)?; + let creation_data = AdminSessionCreationData::ServersSetChange(params.migration_id, params.new_nodes_set.clone()); + let session = sessions.admin_sessions + .insert(cluster, *self_key_pair.public(), session_id, None, true, Some(creation_data))?; + let initialization_result = session.as_servers_set_change().expect("servers set change session is created; qed") + .initialize(params.new_nodes_set, params.old_set_signature, params.new_set_signature); + + if initialization_result.is_ok() { + servers_set_change_creator_connector.set_key_servers_set_change_session(session.clone()); + } + + process_initialization_result( + initialization_result, + session, &sessions.admin_sessions) +} + +fn process_initialization_result( + result: Result<(), Error>, + session: Arc, + sessions: &ClusterSessionsContainer +) -> Result, Error> + where + S: ClusterSession, + SC: ClusterSessionCreator +{ + match result { + Ok(()) if session.is_finished() => { + sessions.remove(&session.id()); + Ok(session) + }, + Ok(()) => Ok(session), + Err(error) => { + sessions.remove(&session.id()); + Err(error) + }, + } } #[cfg(test)] pub mod tests { use std::sync::Arc; use std::sync::atomic::{AtomicUsize, Ordering}; - use std::time::{Duration, Instant}; - use std::collections::{BTreeSet, VecDeque}; - use parking_lot::RwLock; - use tokio::{ - prelude::{future, Future}, - }; - use parity_runtime::{ - futures::sync::oneshot, - Runtime, Executor, - }; + use std::collections::{BTreeMap, BTreeSet, VecDeque}; + use parking_lot::{Mutex, RwLock}; use ethereum_types::{Address, H256}; use ethkey::{Random, Generator, Public, Signature, sign}; use key_server_cluster::{NodeId, SessionId, Requester, Error, DummyAclStorage, DummyKeyStorage, - MapKeyServerSet, PlainNodeKeyPair, KeyStorage}; + MapKeyServerSet, PlainNodeKeyPair, NodeKeyPair}; use key_server_cluster::message::Message; - use key_server_cluster::cluster::{Cluster, ClusterCore, ClusterConfiguration, ClusterClient, ClusterState}; - use key_server_cluster::cluster_sessions::{ClusterSession, AdminSession, ClusterSessionsListener}; - use key_server_cluster::generation_session::{SessionImpl as GenerationSession, SessionState as GenerationSessionState}; + use key_server_cluster::cluster::{new_test_cluster, Cluster, ClusterCore, ClusterConfiguration, ClusterClient}; + use key_server_cluster::cluster_connections::ConnectionManager; + use key_server_cluster::cluster_connections::tests::{MessagesQueue, TestConnections}; + use key_server_cluster::cluster_sessions::{ClusterSession, ClusterSessions, AdminSession, ClusterSessionsListener}; + use key_server_cluster::generation_session::{SessionImpl as GenerationSession, + SessionState as GenerationSessionState}; use key_server_cluster::decryption_session::{SessionImpl as DecryptionSession}; use key_server_cluster::encryption_session::{SessionImpl as EncryptionSession}; use key_server_cluster::signing_session_ecdsa::{SessionImpl as EcdsaSigningSession}; @@ -1152,8 +577,6 @@ pub mod tests { use key_server_cluster::key_version_negotiation_session::{SessionImpl as KeyVersionNegotiationSession, IsolatedSessionTransport as KeyVersionNegotiationSessionTransport}; - const TIMEOUT: Duration = Duration::from_millis(1000); - #[derive(Default)] pub struct DummyClusterClient { pub generation_requests_count: AtomicUsize, @@ -1172,7 +595,6 @@ pub mod tests { } impl ClusterClient for DummyClusterClient { - fn cluster_state(&self) -> ClusterState { unimplemented!("test-only") } fn new_generation_session(&self, _session_id: SessionId, _origin: Option
, _author: Address, _threshold: usize) -> Result, Error> { self.generation_requests_count.fetch_add(1, Ordering::Relaxed); Err(Error::Internal("test-error".into())) @@ -1191,8 +613,8 @@ pub mod tests { fn make_faulty_generation_sessions(&self) { unimplemented!("test-only") } fn generation_session(&self, _session_id: &SessionId) -> Option> { unimplemented!("test-only") } - fn connect(&self) { unimplemented!("test-only") } - fn key_storage(&self) -> Arc { unimplemented!("test-only") } + fn is_fully_connected(&self) -> bool { true } + fn connect(&self) {} } impl DummyCluster { @@ -1258,366 +680,431 @@ pub mod tests { } } - /// Blocks the calling thread, looping until `predicate` returns `true` or - /// `timeout` has elapsed. - pub fn loop_until(executor: &Executor, timeout: Duration, predicate: F) - where F: Send + 'static + Fn() -> bool - { - use futures::Stream; - use tokio::timer::Interval; - - let start = Instant::now(); - let (complete_tx, complete_rx) = oneshot::channel(); - - executor.spawn(Interval::new_interval(Duration::from_millis(1)) - .and_then(move |_| { - if Instant::now() - start > timeout { - panic!("no result in {:?}", timeout); + /// Test message loop. + pub struct MessageLoop { + messages: MessagesQueue, + preserve_sessions: bool, + key_pairs_map: BTreeMap>, + acl_storages_map: BTreeMap>, + key_storages_map: BTreeMap>, + clusters_map: BTreeMap>>>, + } + + impl ::std::fmt::Debug for MessageLoop { + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + write!(f, "MessageLoop({})", self.clusters_map.len()) + } + } + + impl MessageLoop { + /// Returns set of all nodes ids. + pub fn nodes(&self) -> BTreeSet { + self.clusters_map.keys().cloned().collect() + } + + /// Returns nodes id by its index. + pub fn node(&self, idx: usize) -> NodeId { + *self.clusters_map.keys().nth(idx).unwrap() + } + + /// Returns key pair of the node by its idx. + pub fn node_key_pair(&self, idx: usize) -> &Arc { + self.key_pairs_map.values().nth(idx).unwrap() + } + + /// Get cluster reference by its index. + pub fn cluster(&self, idx: usize) -> &Arc>> { + self.clusters_map.values().nth(idx).unwrap() + } + + /// Get keys storage reference by its index. + pub fn key_storage(&self, idx: usize) -> &Arc { + self.key_storages_map.values().nth(idx).unwrap() + } + + /// Get keys storage reference by node id. + pub fn key_storage_of(&self, node: &NodeId) -> &Arc { + &self.key_storages_map[node] + } + + /// Replace key storage of the node by its id. + pub fn replace_key_storage_of(&mut self, node: &NodeId, key_storage: Arc) { + *self.key_storages_map.get_mut(node).unwrap() = key_storage; + } + + /// Get ACL storage reference by its index. + pub fn acl_storage(&self, idx: usize) -> &Arc { + self.acl_storages_map.values().nth(idx).unwrap() + } + + /// Get sessions container reference by its index. + pub fn sessions(&self, idx: usize) -> &Arc { + &self.cluster(idx).data.sessions + } + + /// Get sessions container reference by node id. + pub fn sessions_of(&self, node: &NodeId) -> &Arc { + &self.clusters_map[node].data.sessions + } + + /// Isolate node from others. + pub fn isolate(&self, idx: usize) { + let node = self.node(idx); + for (i, cluster) in self.clusters_map.values().enumerate() { + if i == idx { + cluster.data.connections.isolate(); + } else { + cluster.data.connections.disconnect(node); } + } + } - Ok(()) - }) - .take_while(move |_| future::ok(!predicate())) - .for_each(|_| Ok(())) - .then(|_| { - complete_tx.send(()).expect("receiver dropped"); - future::ok::<(), ()>(()) - }) - ); + /// Exclude node from cluster. + pub fn exclude(&mut self, idx: usize) { + let node = self.node(idx); + for (i, cluster) in self.clusters_map.values().enumerate() { + if i != idx { + cluster.data.connections.exclude(node); + } + } + self.key_storages_map.remove(&node); + self.acl_storages_map.remove(&node); + self.key_pairs_map.remove(&node); + self.clusters_map.remove(&node); + } - complete_rx.wait().unwrap(); - } + /// Include new node to the cluster. + pub fn include(&mut self, node_key_pair: Arc) -> usize { + let key_storage = Arc::new(DummyKeyStorage::default()); + let acl_storage = Arc::new(DummyAclStorage::default()); + let cluster_params = ClusterConfiguration { + self_key_pair: node_key_pair.clone(), + key_server_set: Arc::new(MapKeyServerSet::new(false, self.nodes().iter() + .chain(::std::iter::once(node_key_pair.public())) + .map(|n| (*n, format!("127.0.0.1:{}", 13).parse().unwrap())) + .collect())), + key_storage: key_storage.clone(), + acl_storage: acl_storage.clone(), + admin_public: None, + preserve_sessions: self.preserve_sessions, + }; + let cluster = new_test_cluster(self.messages.clone(), cluster_params).unwrap(); + + for cluster in self.clusters_map.values(){ + cluster.data.connections.include(node_key_pair.public().clone()); + } + self.acl_storages_map.insert(*node_key_pair.public(), acl_storage); + self.key_storages_map.insert(*node_key_pair.public(), key_storage); + self.clusters_map.insert(*node_key_pair.public(), cluster); + self.key_pairs_map.insert(*node_key_pair.public(), node_key_pair.clone()); + self.clusters_map.keys().position(|k| k == node_key_pair.public()).unwrap() + } - pub fn all_connections_established(cluster: &Arc) -> bool { - cluster.config().key_server_set.snapshot().new_set.keys() - .filter(|p| *p != cluster.config().self_key_pair.public()) - .all(|p| cluster.connection(p).is_some()) - } + /// Is empty message queue? + pub fn is_empty(&self) -> bool { + self.messages.lock().is_empty() + } - pub fn make_clusters(runtime: &Runtime, ports_begin: u16, num_nodes: usize) -> Vec> { - let key_pairs: Vec<_> = (0..num_nodes).map(|_| Random.generate().unwrap()).collect(); - let cluster_params: Vec<_> = (0..num_nodes).map(|i| ClusterConfiguration { - self_key_pair: Arc::new(PlainNodeKeyPair::new(key_pairs[i].clone())), - listen_address: ("127.0.0.1".to_owned(), ports_begin + i as u16), - key_server_set: Arc::new(MapKeyServerSet::new(false, key_pairs.iter().enumerate() - .map(|(j, kp)| (kp.public().clone(), format!("127.0.0.1:{}", ports_begin + j as u16).parse().unwrap())) - .collect())), - allow_connecting_to_higher_nodes: false, - key_storage: Arc::new(DummyKeyStorage::default()), - acl_storage: Arc::new(DummyAclStorage::default()), - admin_public: None, - auto_migrate_enabled: false, - }).collect(); - let clusters: Vec<_> = cluster_params.into_iter().enumerate() - .map(|(_, params)| ClusterCore::new(runtime.executor(), params).unwrap()) - .collect(); + /// Takes next message from the queue. + pub fn take_message(&self) -> Option<(NodeId, NodeId, Message)> { + self.messages.lock().pop_front() + } - clusters - } + /// Process single message. + pub fn process_message(&self, from: NodeId, to: NodeId, message: Message) { + let cluster_data = &self.clusters_map[&to].data; + let connection = cluster_data.connections.provider().connection(&from).unwrap(); + cluster_data.message_processor.process_connection_message(connection, message); + } + + /// Take next message and process it. + pub fn take_and_process_message(&self) -> bool { + let (from, to, message) = match self.take_message() { + Some((from, to, message)) => (from, to, message), + None => return false, + }; - pub fn run_clusters(clusters: &[Arc]) { - for cluster in clusters { - cluster.run_listener().unwrap(); + self.process_message(from, to, message); + true } - for cluster in clusters { - cluster.run_connections().unwrap(); + + /// Loops until `predicate` returns `true` or there are no messages in the queue. + pub fn loop_until(&self, predicate: F) where F: Fn() -> bool { + while !predicate() { + if !self.take_and_process_message() { + panic!("message queue is empty but goal is not achieved"); + } + } } } - pub fn shutdown_clusters(clusters: &[Arc]) { - for cluster in clusters { - cluster.shutdown() - } + pub fn make_clusters(num_nodes: usize) -> MessageLoop { + do_make_clusters(num_nodes, false) } - /// Returns a new runtime with a static number of threads. - pub fn new_runtime() -> Runtime { - Runtime::with_thread_count(4) + pub fn make_clusters_and_preserve_sessions(num_nodes: usize) -> MessageLoop { + do_make_clusters(num_nodes, true) } - #[test] - fn cluster_connects_to_other_nodes() { - let runtime = new_runtime(); - let clusters = make_clusters(&runtime, 6010, 3); - run_clusters(&clusters); - let clusters_clone = clusters.clone(); - loop_until(&runtime.executor(), TIMEOUT, move || clusters_clone.iter().all(all_connections_established)); - shutdown_clusters(&clusters); + fn do_make_clusters(num_nodes: usize, preserve_sessions: bool) -> MessageLoop { + let ports_begin = 0; + let messages = Arc::new(Mutex::new(VecDeque::new())); + let key_pairs: Vec<_> = (0..num_nodes) + .map(|_| Arc::new(PlainNodeKeyPair::new(Random.generate().unwrap()))).collect(); + let key_storages: Vec<_> = (0..num_nodes).map(|_| Arc::new(DummyKeyStorage::default())).collect(); + let acl_storages: Vec<_> = (0..num_nodes).map(|_| Arc::new(DummyAclStorage::default())).collect(); + let cluster_params: Vec<_> = (0..num_nodes).map(|i| ClusterConfiguration { + self_key_pair: key_pairs[i].clone(), + key_server_set: Arc::new(MapKeyServerSet::new(false, key_pairs.iter().enumerate() + .map(|(j, kp)| (*kp.public(), format!("127.0.0.1:{}", ports_begin + j as u16).parse().unwrap())) + .collect())), + key_storage: key_storages[i].clone(), + acl_storage: acl_storages[i].clone(), + admin_public: None, + preserve_sessions, + }).collect(); + let clusters: Vec<_> = cluster_params.into_iter() + .map(|params| new_test_cluster(messages.clone(), params).unwrap()) + .collect(); + + let clusters_map = clusters.iter().map(|c| (*c.data.config.self_key_pair.public(), c.clone())).collect(); + let key_pairs_map = key_pairs.into_iter().map(|kp| (*kp.public(), kp)).collect(); + let key_storages_map = clusters.iter().zip(key_storages.into_iter()) + .map(|(c, ks)| (*c.data.config.self_key_pair.public(), ks)).collect(); + let acl_storages_map = clusters.iter().zip(acl_storages.into_iter()) + .map(|(c, acls)| (*c.data.config.self_key_pair.public(), acls)).collect(); + MessageLoop { preserve_sessions, messages, key_pairs_map, acl_storages_map, key_storages_map, clusters_map } } #[test] fn cluster_wont_start_generation_session_if_not_fully_connected() { - let runtime = new_runtime(); - let clusters = make_clusters(&runtime, 6013, 3); - clusters[0].run().unwrap(); - match clusters[0].client().new_generation_session(SessionId::default(), Default::default(), Default::default(), 1) { + let ml = make_clusters(3); + ml.cluster(0).data.connections.disconnect(*ml.cluster(0).data.self_key_pair.public()); + match ml.cluster(0).client().new_generation_session(SessionId::default(), Default::default(), Default::default(), 1) { Err(Error::NodeDisconnected) => (), Err(e) => panic!("unexpected error {:?}", e), _ => panic!("unexpected success"), } - shutdown_clusters(&clusters); } #[test] fn error_in_generation_session_broadcasted_to_all_other_nodes() { let _ = ::env_logger::try_init(); - let runtime = new_runtime(); - let clusters = make_clusters(&runtime, 6016, 3); - run_clusters(&clusters); - let clusters_clone = clusters.clone(); - loop_until(&runtime.executor(), TIMEOUT, move || clusters_clone.iter().all(all_connections_established)); + let ml = make_clusters(3); // ask one of nodes to produce faulty generation sessions - clusters[1].client().make_faulty_generation_sessions(); + ml.cluster(1).client().make_faulty_generation_sessions(); // start && wait for generation session to fail - let session = clusters[0].client().new_generation_session(SessionId::default(), Default::default(), Default::default(), 1).unwrap(); - let session_clone = session.clone(); - let clusters_clone = clusters.clone(); - loop_until(&runtime.executor(), TIMEOUT, move || session_clone.joint_public_and_secret().is_some() - && clusters_clone[0].client().generation_session(&SessionId::default()).is_none()); + let session = ml.cluster(0).client() + .new_generation_session(SessionId::default(), Default::default(), Default::default(), 1).unwrap(); + ml.loop_until(|| session.joint_public_and_secret().is_some() + && ml.cluster(0).client().generation_session(&SessionId::default()).is_none()); assert!(session.joint_public_and_secret().unwrap().is_err()); // check that faulty session is either removed from all nodes, or nonexistent (already removed) for i in 1..3 { - if let Some(session) = clusters[i].client().generation_session(&SessionId::default()) { - let session_clone = session.clone(); - let clusters_clone = clusters.clone(); + if let Some(session) = ml.cluster(i).client().generation_session(&SessionId::default()) { // wait for both session completion && session removal (session completion event is fired // before session is removed from its own container by cluster) - loop_until(&runtime.executor(), TIMEOUT, move || session_clone.joint_public_and_secret().is_some() - && clusters_clone[i].client().generation_session(&SessionId::default()).is_none()); + ml.loop_until(|| session.joint_public_and_secret().is_some() + && ml.cluster(i).client().generation_session(&SessionId::default()).is_none()); assert!(session.joint_public_and_secret().unwrap().is_err()); } } - shutdown_clusters(&clusters); } #[test] fn generation_session_completion_signalled_if_failed_on_master() { let _ = ::env_logger::try_init(); - let runtime = new_runtime(); - let clusters = make_clusters(&runtime, 6025, 3); - run_clusters(&clusters); - let clusters_clone = clusters.clone(); - loop_until(&runtime.executor(), TIMEOUT, move || clusters_clone.iter().all(all_connections_established)); + let ml = make_clusters(3); // ask one of nodes to produce faulty generation sessions - clusters[0].client().make_faulty_generation_sessions(); + ml.cluster(0).client().make_faulty_generation_sessions(); // start && wait for generation session to fail - let session = clusters[0].client().new_generation_session(SessionId::default(), Default::default(), Default::default(), 1).unwrap(); - let session_clone = session.clone(); - let clusters_clone = clusters.clone(); - loop_until(&runtime.executor(), TIMEOUT, move || session_clone.joint_public_and_secret().is_some() - && clusters_clone[0].client().generation_session(&SessionId::default()).is_none()); + let session = ml.cluster(0).client() + .new_generation_session(SessionId::default(), Default::default(), Default::default(), 1).unwrap(); + ml.loop_until(|| session.joint_public_and_secret().is_some() + && ml.cluster(0).client().generation_session(&SessionId::default()).is_none()); assert!(session.joint_public_and_secret().unwrap().is_err()); // check that faulty session is either removed from all nodes, or nonexistent (already removed) for i in 1..3 { - if let Some(session) = clusters[i].client().generation_session(&SessionId::default()) { - let session_clone = session.clone(); - let clusters_clone = clusters.clone(); + if let Some(session) = ml.cluster(i).client().generation_session(&SessionId::default()) { + let session = session.clone(); // wait for both session completion && session removal (session completion event is fired // before session is removed from its own container by cluster) - loop_until(&runtime.executor(), TIMEOUT, move || session_clone.joint_public_and_secret().is_some() - && clusters_clone[i].client().generation_session(&SessionId::default()).is_none()); + ml.loop_until(|| session.joint_public_and_secret().is_some() + && ml.cluster(i).client().generation_session(&SessionId::default()).is_none()); assert!(session.joint_public_and_secret().unwrap().is_err()); } } - shutdown_clusters(&clusters); } #[test] fn generation_session_is_removed_when_succeeded() { let _ = ::env_logger::try_init(); - let runtime = new_runtime(); - let clusters = make_clusters(&runtime, 6019, 3); - run_clusters(&clusters); - let clusters_clone = clusters.clone(); - loop_until(&runtime.executor(), TIMEOUT, move || clusters_clone.iter().all(all_connections_established)); + let ml = make_clusters(3); // start && wait for generation session to complete - let session = clusters[0].client().new_generation_session(SessionId::default(), Default::default(), Default::default(), 1).unwrap(); - let session_clone = session.clone(); - let clusters_clone = clusters.clone(); - loop_until(&runtime.executor(), TIMEOUT, move || (session_clone.state() == GenerationSessionState::Finished - || session_clone.state() == GenerationSessionState::Failed) - && clusters_clone[0].client().generation_session(&SessionId::default()).is_none()); + let session = ml.cluster(0).client() + .new_generation_session(SessionId::default(), Default::default(), Default::default(), 1).unwrap(); + ml.loop_until(|| (session.state() == GenerationSessionState::Finished + || session.state() == GenerationSessionState::Failed) + && ml.cluster(0).client().generation_session(&SessionId::default()).is_none()); assert!(session.joint_public_and_secret().unwrap().is_ok()); // check that on non-master nodes session is either: // already removed // or it is removed right after completion for i in 1..3 { - if let Some(session) = clusters[i].client().generation_session(&SessionId::default()) { + if let Some(session) = ml.cluster(i).client().generation_session(&SessionId::default()) { // run to completion if completion message is still on the way // AND check that it is actually removed from cluster sessions - let session_clone = session.clone(); - let clusters_clone = clusters.clone(); - loop_until(&runtime.executor(), TIMEOUT, move || (session_clone.state() == GenerationSessionState::Finished - || session_clone.state() == GenerationSessionState::Failed) - && clusters_clone[i].client().generation_session(&SessionId::default()).is_none()); + ml.loop_until(|| (session.state() == GenerationSessionState::Finished + || session.state() == GenerationSessionState::Failed) + && ml.cluster(i).client().generation_session(&SessionId::default()).is_none()); } } - shutdown_clusters(&clusters); } #[test] fn sessions_are_removed_when_initialization_fails() { - let runtime = new_runtime(); - let clusters = make_clusters(&runtime, 6022, 3); - run_clusters(&clusters); - let clusters_clone = clusters.clone(); - loop_until(&runtime.executor(), TIMEOUT, move || clusters_clone.iter().all(all_connections_established)); + let ml = make_clusters(3); + let client = ml.cluster(0).client(); // generation session { // try to start generation session => fail in initialization - assert_eq!(clusters[0].client().new_generation_session(SessionId::default(), Default::default(), Default::default(), 100).map(|_| ()), + assert_eq!( + client.new_generation_session(SessionId::default(), None, Default::default(), 100).map(|_| ()), Err(Error::NotEnoughNodesForThreshold)); // try to start generation session => fails in initialization - assert_eq!(clusters[0].client().new_generation_session(SessionId::default(), Default::default(), Default::default(), 100).map(|_| ()), + assert_eq!( + client.new_generation_session(SessionId::default(), None, Default::default(), 100).map(|_| ()), Err(Error::NotEnoughNodesForThreshold)); - assert!(clusters[0].data.sessions.generation_sessions.is_empty()); + assert!(ml.cluster(0).data.sessions.generation_sessions.is_empty()); } // decryption session { // try to start decryption session => fails in initialization - assert_eq!(clusters[0].client().new_decryption_session(Default::default(), Default::default(), Default::default(), Some(Default::default()), false, false).map(|_| ()), + assert_eq!( + client.new_decryption_session( + Default::default(), Default::default(), Default::default(), Some(Default::default()), false, false + ).map(|_| ()), Err(Error::InvalidMessage)); // try to start generation session => fails in initialization - assert_eq!(clusters[0].client().new_decryption_session(Default::default(), Default::default(), Default::default(), Some(Default::default()), false, false).map(|_| ()), + assert_eq!( + client.new_decryption_session( + Default::default(), Default::default(), Default::default(), Some(Default::default()), false, false + ).map(|_| ()), Err(Error::InvalidMessage)); - assert!(clusters[0].data.sessions.decryption_sessions.is_empty()); - assert!(clusters[0].data.sessions.negotiation_sessions.is_empty()); + assert!(ml.cluster(0).data.sessions.decryption_sessions.is_empty()); + assert!(ml.cluster(0).data.sessions.negotiation_sessions.is_empty()); } - shutdown_clusters(&clusters); } - // test ignored because of - // - // https://github.com/paritytech/parity-ethereum/issues/9635 #[test] - #[ignore] fn schnorr_signing_session_completes_if_node_does_not_have_a_share() { let _ = ::env_logger::try_init(); - let runtime = new_runtime(); - let clusters = make_clusters(&runtime, 6028, 3); - run_clusters(&clusters); - let clusters_clone = clusters.clone(); - loop_until(&runtime.executor(), TIMEOUT, move || clusters_clone.iter().all(all_connections_established)); + let ml = make_clusters(3); // start && wait for generation session to complete - let session = clusters[0].client().new_generation_session(SessionId::default(), Default::default(), Default::default(), 1).unwrap(); - let session_clone = session.clone(); - let clusters_clone = clusters.clone(); - loop_until(&runtime.executor(), TIMEOUT, move || (session_clone.state() == GenerationSessionState::Finished - || session_clone.state() == GenerationSessionState::Failed) - && clusters_clone[0].client().generation_session(&SessionId::default()).is_none()); + let session = ml.cluster(0).client(). + new_generation_session(SessionId::default(), Default::default(), Default::default(), 1).unwrap(); + ml.loop_until(|| (session.state() == GenerationSessionState::Finished + || session.state() == GenerationSessionState::Failed) + && ml.cluster(0).client().generation_session(&SessionId::default()).is_none()); assert!(session.joint_public_and_secret().unwrap().is_ok()); // now remove share from node2 - assert!((0..3).all(|i| clusters[i].data.sessions.generation_sessions.is_empty())); - clusters[2].data.config.key_storage.remove(&Default::default()).unwrap(); + assert!((0..3).all(|i| ml.cluster(i).data.sessions.generation_sessions.is_empty())); + ml.cluster(2).data.config.key_storage.remove(&Default::default()).unwrap(); // and try to sign message with generated key let signature = sign(Random.generate().unwrap().secret(), &Default::default()).unwrap(); - let session0 = clusters[0].client().new_schnorr_signing_session(Default::default(), signature.into(), None, Default::default()).unwrap(); - let session = clusters[0].data.sessions.schnorr_signing_sessions.first().unwrap(); + let session0 = ml.cluster(0).client() + .new_schnorr_signing_session(Default::default(), signature.into(), None, Default::default()).unwrap(); + let session = ml.cluster(0).data.sessions.schnorr_signing_sessions.first().unwrap(); - let session_clone = session.clone(); - let clusters_clone = clusters.clone(); - loop_until(&runtime.executor(), TIMEOUT, move || session_clone.is_finished() && (0..3).all(|i| - clusters_clone[i].data.sessions.schnorr_signing_sessions.is_empty())); + ml.loop_until(|| session.is_finished() && (0..3).all(|i| + ml.cluster(i).data.sessions.schnorr_signing_sessions.is_empty())); session0.wait().unwrap(); // and try to sign message with generated key using node that has no key share let signature = sign(Random.generate().unwrap().secret(), &Default::default()).unwrap(); - let session2 = clusters[2].client().new_schnorr_signing_session(Default::default(), signature.into(), None, Default::default()).unwrap(); - let session = clusters[2].data.sessions.schnorr_signing_sessions.first().unwrap(); + let session2 = ml.cluster(2).client() + .new_schnorr_signing_session(Default::default(), signature.into(), None, Default::default()).unwrap(); + let session = ml.cluster(2).data.sessions.schnorr_signing_sessions.first().unwrap(); - let session_clone = session.clone(); - let clusters_clone = clusters.clone(); - loop_until(&runtime.executor(), TIMEOUT, move || session_clone.is_finished() && (0..3).all(|i| - clusters_clone[i].data.sessions.schnorr_signing_sessions.is_empty())); + ml.loop_until(|| session.is_finished() && (0..3).all(|i| + ml.cluster(i).data.sessions.schnorr_signing_sessions.is_empty())); session2.wait().unwrap(); // now remove share from node1 - clusters[1].data.config.key_storage.remove(&Default::default()).unwrap(); + ml.cluster(1).data.config.key_storage.remove(&Default::default()).unwrap(); // and try to sign message with generated key let signature = sign(Random.generate().unwrap().secret(), &Default::default()).unwrap(); - let session1 = clusters[0].client().new_schnorr_signing_session(Default::default(), signature.into(), None, Default::default()).unwrap(); - let session = clusters[0].data.sessions.schnorr_signing_sessions.first().unwrap(); + let session1 = ml.cluster(0).client() + .new_schnorr_signing_session(Default::default(), signature.into(), None, Default::default()).unwrap(); + let session = ml.cluster(0).data.sessions.schnorr_signing_sessions.first().unwrap(); - let session = session.clone(); - loop_until(&runtime.executor(), TIMEOUT, move || session.is_finished()); + ml.loop_until(|| session.is_finished()); session1.wait().unwrap_err(); - shutdown_clusters(&clusters); } - // test ignored because of - // - // https://github.com/paritytech/parity-ethereum/issues/9635 #[test] - #[ignore] fn ecdsa_signing_session_completes_if_node_does_not_have_a_share() { let _ = ::env_logger::try_init(); - let runtime = new_runtime(); - let clusters = make_clusters(&runtime, 6041, 4); - run_clusters(&clusters); - let clusters_clone = clusters.clone(); - loop_until(&runtime.executor(), TIMEOUT, move || clusters_clone.iter().all(all_connections_established)); + let ml = make_clusters(4); // start && wait for generation session to complete - let session = clusters[0].client().new_generation_session(SessionId::default(), Default::default(), Default::default(), 1).unwrap(); - let session_clone = session.clone(); - let clusters_clone = clusters.clone(); - loop_until(&runtime.executor(), TIMEOUT, move || (session_clone.state() == GenerationSessionState::Finished - || session_clone.state() == GenerationSessionState::Failed) - && clusters_clone[0].client().generation_session(&SessionId::default()).is_none()); + let session = ml.cluster(0).client() + .new_generation_session(SessionId::default(), Default::default(), Default::default(), 1).unwrap(); + ml.loop_until(|| (session.state() == GenerationSessionState::Finished + || session.state() == GenerationSessionState::Failed) + && ml.cluster(0).client().generation_session(&SessionId::default()).is_none()); assert!(session.joint_public_and_secret().unwrap().is_ok()); // now remove share from node2 - assert!((0..3).all(|i| clusters[i].data.sessions.generation_sessions.is_empty())); - clusters[2].data.config.key_storage.remove(&Default::default()).unwrap(); + assert!((0..3).all(|i| ml.cluster(i).data.sessions.generation_sessions.is_empty())); + ml.cluster(2).data.config.key_storage.remove(&Default::default()).unwrap(); // and try to sign message with generated key let signature = sign(Random.generate().unwrap().secret(), &Default::default()).unwrap(); - let session0 = clusters[0].client().new_ecdsa_signing_session(Default::default(), signature.into(), None, H256::random()).unwrap(); - let session = clusters[0].data.sessions.ecdsa_signing_sessions.first().unwrap(); + let session0 = ml.cluster(0).client() + .new_ecdsa_signing_session(Default::default(), signature.into(), None, H256::random()).unwrap(); + let session = ml.cluster(0).data.sessions.ecdsa_signing_sessions.first().unwrap(); - let session_clone = session.clone(); - let clusters_clone = clusters.clone(); - loop_until(&runtime.executor(), Duration::from_millis(1000), move || session_clone.is_finished() && (0..3).all(|i| - clusters_clone[i].data.sessions.ecdsa_signing_sessions.is_empty())); + ml.loop_until(|| session.is_finished() && (0..3).all(|i| + ml.cluster(i).data.sessions.ecdsa_signing_sessions.is_empty())); session0.wait().unwrap(); // and try to sign message with generated key using node that has no key share let signature = sign(Random.generate().unwrap().secret(), &Default::default()).unwrap(); - let session2 = clusters[2].client().new_ecdsa_signing_session(Default::default(), signature.into(), None, H256::random()).unwrap(); - let session = clusters[2].data.sessions.ecdsa_signing_sessions.first().unwrap(); - let session_clone = session.clone(); - let clusters_clone = clusters.clone(); - loop_until(&runtime.executor(), Duration::from_millis(1000), move || session_clone.is_finished() && (0..3).all(|i| - clusters_clone[i].data.sessions.ecdsa_signing_sessions.is_empty())); + let session2 = ml.cluster(2).client() + .new_ecdsa_signing_session(Default::default(), signature.into(), None, H256::random()).unwrap(); + let session = ml.cluster(2).data.sessions.ecdsa_signing_sessions.first().unwrap(); + ml.loop_until(|| session.is_finished() && (0..3).all(|i| + ml.cluster(i).data.sessions.ecdsa_signing_sessions.is_empty())); session2.wait().unwrap(); // now remove share from node1 - clusters[1].data.config.key_storage.remove(&Default::default()).unwrap(); + ml.cluster(1).data.config.key_storage.remove(&Default::default()).unwrap(); // and try to sign message with generated key let signature = sign(Random.generate().unwrap().secret(), &Default::default()).unwrap(); - let session1 = clusters[0].client().new_ecdsa_signing_session(Default::default(), signature.into(), None, H256::random()).unwrap(); - let session = clusters[0].data.sessions.ecdsa_signing_sessions.first().unwrap(); - loop_until(&runtime.executor(), Duration::from_millis(1000), move || session.is_finished()); + let session1 = ml.cluster(0).client() + .new_ecdsa_signing_session(Default::default(), signature.into(), None, H256::random()).unwrap(); + let session = ml.cluster(0).data.sessions.ecdsa_signing_sessions.first().unwrap(); + ml.loop_until(|| session.is_finished()); session1.wait().unwrap_err(); - shutdown_clusters(&clusters); } } diff --git a/secret-store/src/key_server_cluster/cluster_connections.rs b/secret-store/src/key_server_cluster/cluster_connections.rs new file mode 100644 index 0000000000..b484e6d8e0 --- /dev/null +++ b/secret-store/src/key_server_cluster/cluster_connections.rs @@ -0,0 +1,176 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +use std::collections::BTreeSet; +use std::sync::Arc; +use key_server_cluster::{Error, NodeId}; +use key_server_cluster::message::Message; + +/// Connection to the single node. Provides basic information about connected node and +/// allows sending messages to this node. +pub trait Connection: Send + Sync { + /// Is this inbound connection? This only matters when both nodes are simultaneously establishing + /// two connections to each other. The agreement is that the inbound connection from the node with + /// lower NodeId is used and the other connection is closed. + fn is_inbound(&self) -> bool; + /// Returns id of the connected node. + fn node_id(&self) -> &NodeId; + /// Returns 'address' of the node to use in traces. + fn node_address(&self) -> String; + /// Send message to the connected node. + fn send_message(&self, message: Message); +} + +/// Connections manager. Responsible for keeping us connected to all required nodes. +pub trait ConnectionManager: 'static + Send + Sync { + /// Returns shared reference to connections provider. + fn provider(&self) -> Arc; + /// Try to reach all disconnected nodes immediately. This method is exposed mostly for + /// tests, where all 'nodes' are starting listening for incoming connections first and + /// only after this, they're actually start connecting to each other. + fn connect(&self); +} + +/// Connections provider. Holds all active connections and the set of nodes that we need to +/// connect to. At any moment connection could be lost and the set of connected/disconnected +/// nodes could change (at behalf of the connection manager). +/// Clone operation should be cheap (Arc). +pub trait ConnectionProvider: Send + Sync { + /// Returns the set of currently connected nodes. Error is returned when our node is + /// not a part of the cluster ('isolated' node). + fn connected_nodes(&self) -> Result, Error>; + /// Returns the set of currently disconnected nodes. + fn disconnected_nodes(&self) -> BTreeSet; + /// Returns the reference to the active node connection or None if the node is not connected. + fn connection(&self, node: &NodeId) -> Option>; +} + +#[cfg(test)] +pub mod tests { + use std::collections::{BTreeSet, VecDeque}; + use std::sync::Arc; + use std::sync::atomic::{AtomicBool, Ordering}; + use parking_lot::Mutex; + use key_server_cluster::{Error, NodeId}; + use key_server_cluster::message::Message; + use super::{ConnectionManager, Connection, ConnectionProvider}; + + /// Shared messages queue. + pub type MessagesQueue = Arc>>; + + /// Single node connections. + pub struct TestConnections { + node: NodeId, + is_isolated: AtomicBool, + connected_nodes: Mutex>, + disconnected_nodes: Mutex>, + messages: MessagesQueue, + } + + /// Single connection. + pub struct TestConnection { + from: NodeId, + to: NodeId, + messages: MessagesQueue, + } + + impl TestConnections { + pub fn isolate(&self) { + let connected_nodes = ::std::mem::replace(&mut *self.connected_nodes.lock(), Default::default()); + self.is_isolated.store(true, Ordering::Relaxed); + self.disconnected_nodes.lock().extend(connected_nodes) + } + + pub fn disconnect(&self, node: NodeId) { + self.connected_nodes.lock().remove(&node); + self.disconnected_nodes.lock().insert(node); + } + + pub fn exclude(&self, node: NodeId) { + self.connected_nodes.lock().remove(&node); + self.disconnected_nodes.lock().remove(&node); + } + + pub fn include(&self, node: NodeId) { + self.connected_nodes.lock().insert(node); + } + } + + impl ConnectionManager for Arc { + fn provider(&self) -> Arc { + self.clone() + } + + fn connect(&self) {} + } + + impl ConnectionProvider for TestConnections { + fn connected_nodes(&self) -> Result, Error> { + match self.is_isolated.load(Ordering::Relaxed) { + false => Ok(self.connected_nodes.lock().clone()), + true => Err(Error::NodeDisconnected), + } + } + + fn disconnected_nodes(&self) -> BTreeSet { + self.disconnected_nodes.lock().clone() + } + + fn connection(&self, node: &NodeId) -> Option> { + match self.connected_nodes.lock().contains(node) { + true => Some(Arc::new(TestConnection { + from: self.node, + to: *node, + messages: self.messages.clone(), + })), + false => None, + } + } + } + + impl Connection for TestConnection { + fn is_inbound(&self) -> bool { + false + } + + fn node_id(&self) -> &NodeId { + &self.to + } + + fn node_address(&self) -> String { + format!("{}", self.to) + } + + fn send_message(&self, message: Message) { + self.messages.lock().push_back((self.from, self.to, message)) + } + } + + pub fn new_test_connections( + messages: MessagesQueue, + node: NodeId, + mut nodes: BTreeSet + ) -> Arc { + let is_isolated = !nodes.remove(&node); + Arc::new(TestConnections { + node, + is_isolated: AtomicBool::new(is_isolated), + connected_nodes: Mutex::new(nodes), + disconnected_nodes: Default::default(), + messages, + }) + } +} diff --git a/secret-store/src/key_server_cluster/cluster_connections_net.rs b/secret-store/src/key_server_cluster/cluster_connections_net.rs new file mode 100644 index 0000000000..bda7f7dd28 --- /dev/null +++ b/secret-store/src/key_server_cluster/cluster_connections_net.rs @@ -0,0 +1,539 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +use std::collections::{BTreeMap, BTreeSet}; +use std::collections::btree_map::Entry; +use std::io; +use std::net::{SocketAddr, IpAddr}; +use std::sync::Arc; +use std::time::{Duration, Instant}; +use futures::{future, Future, Stream}; +use parking_lot::{Mutex, RwLock}; +use tokio::net::{TcpListener, TcpStream}; +use tokio::timer::{Interval, timeout::Error as TimeoutError}; +use tokio_io::IoFuture; +use ethkey::KeyPair; +use parity_runtime::Executor; +use key_server_cluster::{Error, NodeId, ClusterConfiguration, NodeKeyPair}; +use key_server_cluster::cluster_connections::{ConnectionProvider, Connection, ConnectionManager}; +use key_server_cluster::connection_trigger::{Maintain, ConnectionTrigger}; +use key_server_cluster::cluster_message_processor::MessageProcessor; +use key_server_cluster::io::{DeadlineStatus, ReadMessage, SharedTcpStream, + read_encrypted_message, WriteMessage, write_encrypted_message}; +use key_server_cluster::message::{self, ClusterMessage, Message}; +use key_server_cluster::net::{accept_connection as io_accept_connection, + connect as io_connect, Connection as IoConnection}; + +/// Empty future. +pub type BoxedEmptyFuture = Box + Send>; + +/// Maintain interval (seconds). Every MAINTAIN_INTERVAL seconds node: +/// 1) checks if connected nodes are responding to KeepAlive messages +/// 2) tries to connect to disconnected nodes +/// 3) checks if enc/dec sessions are time-outed +const MAINTAIN_INTERVAL: u64 = 10; + +/// When no messages have been received from node within KEEP_ALIVE_SEND_INTERVAL seconds, +/// we must send KeepAlive message to the node to check if it still responds to messages. +const KEEP_ALIVE_SEND_INTERVAL: Duration = Duration::from_secs(30); +/// When no messages have been received from node within KEEP_ALIVE_DISCONNECT_INTERVAL seconds, +/// we must treat this node as non-responding && disconnect from it. +const KEEP_ALIVE_DISCONNECT_INTERVAL: Duration = Duration::from_secs(60); + +/// Network connection manager configuration. +pub struct NetConnectionsManagerConfig { + /// Allow connecting to 'higher' nodes. + pub allow_connecting_to_higher_nodes: bool, + /// Interface to listen to. + pub listen_address: (String, u16), + /// True if we should autostart key servers set change session when servers set changes? + /// This will only work when servers set is configured using KeyServerSet contract. + pub auto_migrate_enabled: bool, +} + +/// Network connections manager. +pub struct NetConnectionsManager { + /// Address we're listening for incoming connections. + listen_address: SocketAddr, + /// Shared cluster connections data reference. + data: Arc, +} + +/// Network connections data. Shared among NetConnectionsManager and spawned futures. +struct NetConnectionsData { + /// Allow connecting to 'higher' nodes. + allow_connecting_to_higher_nodes: bool, + /// Reference to tokio task executor. + executor: Executor, + /// Key pair of this node. + self_key_pair: Arc, + /// Network messages processor. + message_processor: Arc, + /// Connections trigger. + trigger: Mutex>, + /// Mutable connection data. + container: Arc>, +} + +/// Network connections container. This is the only mutable data of NetConnectionsManager. +/// The set of nodes is mutated by the connection trigger and the connections set is also +/// mutated by spawned futures. +pub struct NetConnectionsContainer { + /// Is this node isolated from cluster? + pub is_isolated: bool, + /// Current key servers set. + pub nodes: BTreeMap, + /// Active connections to key servers. + pub connections: BTreeMap>, +} + +/// Network connection to single key server node. +pub struct NetConnection { + executor: Executor, + /// Id of the peer node. + node_id: NodeId, + /// Address of the peer node. + node_address: SocketAddr, + /// Is this inbound (true) or outbound (false) connection? + is_inbound: bool, + /// Key pair that is used to encrypt connection' messages. + key: KeyPair, + /// Last message time. + last_message_time: RwLock, + /// Underlying TCP stream. + stream: SharedTcpStream, +} + +impl NetConnectionsManager { + /// Create new network connections manager. + pub fn new( + executor: Executor, + message_processor: Arc, + trigger: Box, + container: Arc>, + config: &ClusterConfiguration, + net_config: NetConnectionsManagerConfig, + ) -> Result { + let listen_address = make_socket_address( + &net_config.listen_address.0, + net_config.listen_address.1)?; + + Ok(NetConnectionsManager { + listen_address, + data: Arc::new(NetConnectionsData { + allow_connecting_to_higher_nodes: net_config.allow_connecting_to_higher_nodes, + executor, + message_processor, + self_key_pair: config.self_key_pair.clone(), + trigger: Mutex::new(trigger), + container, + }), + }) + } + + /// Start listening for connections and schedule connections maintenance. + pub fn start(&self) -> Result<(), Error> { + net_listen(&self.listen_address, self.data.clone())?; + net_schedule_maintain(self.data.clone()); + Ok(()) + } +} + +impl ConnectionManager for NetConnectionsManager { + fn provider(&self) -> Arc { + self.data.container.clone() + } + + fn connect(&self) { + net_connect_disconnected(self.data.clone()); + } +} + +impl ConnectionProvider for RwLock { + fn connected_nodes(&self) -> Result, Error> { + let connections = self.read(); + if connections.is_isolated { + return Err(Error::NodeDisconnected); + } + + Ok(connections.connections.keys().cloned().collect()) + } + + fn disconnected_nodes(&self) -> BTreeSet { + let connections = self.read(); + connections.nodes.keys() + .filter(|node_id| !connections.connections.contains_key(node_id)) + .cloned() + .collect() + } + + fn connection(&self, node: &NodeId) -> Option> { + match self.read().connections.get(node).cloned() { + Some(connection) => Some(connection), + None => None, + } + } +} + +impl NetConnection { + /// Create new connection. + pub fn new(executor: Executor, is_inbound: bool, connection: IoConnection) -> NetConnection { + NetConnection { + executor, + node_id: connection.node_id, + node_address: connection.address, + is_inbound: is_inbound, + stream: connection.stream, + key: connection.key, + last_message_time: RwLock::new(Instant::now()), + } + } + + /// Get last message time. + pub fn last_message_time(&self) -> Instant { + *self.last_message_time.read() + } + + /// Update last message time + pub fn set_last_message_time(&self, last_message_time: Instant) { + *self.last_message_time.write() = last_message_time + } + + /// Returns future that sends encrypted message over this connection. + pub fn send_message_future(&self, message: Message) -> WriteMessage { + write_encrypted_message(self.stream.clone(), &self.key, message) + } + + /// Returns future that reads encrypted message from this connection. + pub fn read_message_future(&self) -> ReadMessage { + read_encrypted_message(self.stream.clone(), self.key.clone()) + } +} + +impl Connection for NetConnection { + fn is_inbound(&self) -> bool { + self.is_inbound + } + + fn node_id(&self) -> &NodeId { + &self.node_id + } + + fn node_address(&self) -> String { + format!("{}", self.node_address) + } + + fn send_message(&self, message: Message) { + execute(&self.executor, self.send_message_future(message).then(|_| Ok(()))); + } +} + +impl NetConnectionsData { + /// Executes closure for each active connection. + pub fn active_connections(&self) -> Vec> { + self.container.read().connections.values().cloned().collect() + } + + /// Executes closure for each disconnected node. + pub fn disconnected_nodes(&self) -> Vec<(NodeId, SocketAddr)> { + let container = self.container.read(); + container.nodes.iter() + .filter(|(node_id, _)| !container.connections.contains_key(node_id)) + .map(|(node_id, addr)| (*node_id, *addr)) + .collect() + } + + /// Try to insert new connection. Returns true if connection has been inserted. + /// Returns false (and ignores connections) if: + /// - we do not expect connection from this node + /// - we are already connected to the node and existing connection 'supersede' + /// new connection by agreement + pub fn insert(&self, connection: Arc) -> bool { + let node = *connection.node_id(); + let mut container = self.container.write(); + if !container.nodes.contains_key(&node) { + trace!(target: "secretstore_net", "{}: ignoring unknown connection from {} at {}", + self.self_key_pair.public(), node, connection.node_address()); + return false; + } + + if container.connections.contains_key(&node) { + // we have already connected to the same node + // the agreement is that node with lower id must establish connection to node with higher id + if (*self.self_key_pair.public() < node && connection.is_inbound()) + || (*self.self_key_pair.public() > node && !connection.is_inbound()) { + return false; + } + } + + trace!(target: "secretstore_net", + "{}: inserting connection to {} at {}. Connected to {} of {} nodes", + self.self_key_pair.public(), node, connection.node_address(), + container.connections.len() + 1, container.nodes.len()); + container.connections.insert(node, connection); + + true + } + + /// Tries to remove connection. Returns true if connection has been removed. + /// Returns false if we do not know this connection. + pub fn remove(&self, connection: &NetConnection) -> bool { + let node_id = *connection.node_id(); + let is_inbound = connection.is_inbound(); + let mut container = self.container.write(); + if let Entry::Occupied(entry) = container.connections.entry(node_id) { + if entry.get().is_inbound() != is_inbound { + return false; + } + + trace!(target: "secretstore_net", "{}: removing connection to {} at {}", + self.self_key_pair.public(), node_id, entry.get().node_address()); + entry.remove_entry(); + + true + } else { + false + } + } +} + +/// Listen incoming connections. +fn net_listen( + listen_address: &SocketAddr, + data: Arc, +) -> Result<(), Error> { + execute(&data.executor, net_listen_future(listen_address, data.clone())?); + Ok(()) +} + +/// Listen incoming connections future. +fn net_listen_future( + listen_address: &SocketAddr, + data: Arc, +) -> Result { + Ok(Box::new(TcpListener::bind(listen_address)? + .incoming() + .and_then(move |stream| { + net_accept_connection(data.clone(), stream); + Ok(()) + }) + .for_each(|_| Ok(())) + .then(|_| future::ok(())))) +} + +/// Accept incoming connection. +fn net_accept_connection( + data: Arc, + stream: TcpStream, +) { + execute(&data.executor, net_accept_connection_future(data.clone(), stream)); +} + +/// Accept incoming connection future. +fn net_accept_connection_future(data: Arc, stream: TcpStream) -> BoxedEmptyFuture { + Box::new(io_accept_connection(stream, data.self_key_pair.clone()) + .then(move |result| net_process_connection_result(data, None, result)) + .then(|_| future::ok(()))) +} + +/// Connect to remote node. +fn net_connect( + data: Arc, + remote: SocketAddr, +) { + execute(&data.executor, net_connect_future(data.clone(), remote)); +} + +/// Connect to remote node future. +fn net_connect_future( + data: Arc, + remote: SocketAddr, +) -> BoxedEmptyFuture { + let disconnected_nodes = data.container.disconnected_nodes(); + Box::new(io_connect(&remote, data.self_key_pair.clone(), disconnected_nodes) + .then(move |result| net_process_connection_result(data, Some(remote), result)) + .then(|_| future::ok(()))) +} + +/// Process network connection result. +fn net_process_connection_result( + data: Arc, + outbound_addr: Option, + result: Result>, TimeoutError>, +) -> IoFuture> { + match result { + Ok(DeadlineStatus::Meet(Ok(connection))) => { + let connection = Arc::new(NetConnection::new(data.executor.clone(), outbound_addr.is_none(), connection)); + if data.insert(connection.clone()) { + let maintain_action = data.trigger.lock().on_connection_established(connection.node_id()); + maintain_connection_trigger(data.clone(), maintain_action); + + return net_process_connection_messages(data, connection); + } + }, + Ok(DeadlineStatus::Meet(Err(err))) => { + warn!(target: "secretstore_net", "{}: protocol error '{}' when establishing {} connection{}", + data.self_key_pair.public(), err, if outbound_addr.is_some() { "outbound" } else { "inbound" }, + outbound_addr.map(|a| format!(" with {}", a)).unwrap_or_default()); + }, + Ok(DeadlineStatus::Timeout) => { + warn!(target: "secretstore_net", "{}: timeout when establishing {} connection{}", + data.self_key_pair.public(), if outbound_addr.is_some() { "outbound" } else { "inbound" }, + outbound_addr.map(|a| format!(" with {}", a)).unwrap_or_default()); + }, + Err(err) => { + warn!(target: "secretstore_net", "{}: network error '{}' when establishing {} connection{}", + data.self_key_pair.public(), err, if outbound_addr.is_some() { "outbound" } else { "inbound" }, + outbound_addr.map(|a| format!(" with {}", a)).unwrap_or_default()); + }, + } + + Box::new(future::ok(Ok(()))) +} + +/// Process connection messages. +fn net_process_connection_messages( + data: Arc, + connection: Arc, +) -> IoFuture> { + Box::new(connection + .read_message_future() + .then(move |result| + match result { + Ok((_, Ok(message))) => { + connection.set_last_message_time(Instant::now()); + data.message_processor.process_connection_message(connection.clone(), message); + // continue serving connection + let process_messages_future = net_process_connection_messages( + data.clone(), connection).then(|_| Ok(())); + execute(&data.executor, process_messages_future); + Box::new(future::ok(Ok(()))) + }, + Ok((_, Err(err))) => { + warn!(target: "secretstore_net", "{}: protocol error '{}' when reading message from node {}", + data.self_key_pair.public(), err, connection.node_id()); + // continue serving connection + let process_messages_future = net_process_connection_messages( + data.clone(), connection).then(|_| Ok(())); + execute(&data.executor, process_messages_future); + Box::new(future::ok(Err(err))) + }, + Err(err) => { + let node_id = *connection.node_id(); + warn!(target: "secretstore_net", "{}: network error '{}' when reading message from node {}", + data.self_key_pair.public(), err, node_id); + // close connection + if data.remove(&*connection) { + let maintain_action = data.trigger.lock().on_connection_closed(&node_id); + maintain_connection_trigger(data, maintain_action); + } + Box::new(future::err(err)) + }, + } + )) +} + +/// Schedule connections. maintain. +fn net_schedule_maintain(data: Arc) { + let closure_data = data.clone(); + execute(&data.executor, Interval::new_interval(Duration::new(MAINTAIN_INTERVAL, 0)) + .and_then(move |_| Ok(net_maintain(closure_data.clone()))) + .for_each(|_| Ok(())) + .then(|_| future::ok(()))); +} + +/// Maintain network connections. +fn net_maintain(data: Arc) { + trace!(target: "secretstore_net", "{}: executing maintain procedures", data.self_key_pair.public()); + + update_nodes_set(data.clone()); + data.message_processor.maintain_sessions(); + net_keep_alive(data.clone()); + net_connect_disconnected(data); +} + +/// Send keep alive messages to remote nodes. +fn net_keep_alive(data: Arc) { + let now = Instant::now(); + let active_connections = data.active_connections(); + for connection in active_connections { + let last_message_diff = now - connection.last_message_time(); + if last_message_diff > KEEP_ALIVE_DISCONNECT_INTERVAL { + warn!(target: "secretstore_net", "{}: keep alive timeout for node {}", + data.self_key_pair.public(), connection.node_id()); + + let node_id = *connection.node_id(); + if data.remove(&*connection) { + let maintain_action = data.trigger.lock().on_connection_closed(&node_id); + maintain_connection_trigger(data.clone(), maintain_action); + } + data.message_processor.process_disconnect(&node_id); + } + else if last_message_diff > KEEP_ALIVE_SEND_INTERVAL { + connection.send_message(Message::Cluster(ClusterMessage::KeepAlive(message::KeepAlive {}))); + } + } +} + +/// Connect disconnected nodes. +fn net_connect_disconnected(data: Arc) { + let disconnected_nodes = data.disconnected_nodes(); + for (node_id, address) in disconnected_nodes { + if data.allow_connecting_to_higher_nodes || *data.self_key_pair.public() < node_id { + net_connect(data.clone(), address); + } + } +} + +/// Schedule future execution. +fn execute + Send + 'static>(executor: &Executor, f: F) { + if let Err(err) = future::Executor::execute(executor, Box::new(f)) { + error!("Secret store runtime unable to spawn task. Runtime is shutting down. ({:?})", err); + } +} + +/// Try to update active nodes set from connection trigger. +fn update_nodes_set(data: Arc) { + let maintain_action = data.trigger.lock().on_maintain(); + maintain_connection_trigger(data, maintain_action); +} + +/// Execute maintain procedures of connections trigger. +fn maintain_connection_trigger(data: Arc, maintain_action: Option) { + if maintain_action == Some(Maintain::SessionAndConnections) || maintain_action == Some(Maintain::Session) { + let session_params = data.trigger.lock().maintain_session(); + if let Some(session_params) = session_params { + let session = data.message_processor.start_servers_set_change_session(session_params); + match session { + Ok(_) => trace!(target: "secretstore_net", "{}: started auto-migrate session", + data.self_key_pair.public()), + Err(err) => trace!(target: "secretstore_net", "{}: failed to start auto-migrate session with: {}", + data.self_key_pair.public(), err), + } + } + } + if maintain_action == Some(Maintain::SessionAndConnections) || maintain_action == Some(Maintain::Connections) { + let mut trigger = data.trigger.lock(); + let mut data = data.container.write(); + trigger.maintain_connections(&mut *data); + } +} + +/// Compose SocketAddr from configuration' address and port. +fn make_socket_address(address: &str, port: u16) -> Result { + let ip_address: IpAddr = address.parse().map_err(|_| Error::InvalidNodeAddress)?; + Ok(SocketAddr::new(ip_address, port)) +} diff --git a/secret-store/src/key_server_cluster/cluster_message_processor.rs b/secret-store/src/key_server_cluster/cluster_message_processor.rs new file mode 100644 index 0000000000..b4ba5ef03b --- /dev/null +++ b/secret-store/src/key_server_cluster/cluster_message_processor.rs @@ -0,0 +1,357 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +use std::sync::Arc; +use key_server_cluster::{Error, NodeId, NodeKeyPair}; +use key_server_cluster::cluster::{ServersSetChangeParams, new_servers_set_change_session}; +use key_server_cluster::cluster_sessions::{AdminSession}; +use key_server_cluster::cluster_connections::{ConnectionProvider, Connection}; +use key_server_cluster::cluster_sessions::{ClusterSession, ClusterSessions, ClusterSessionsContainer, + create_cluster_view}; +use key_server_cluster::cluster_sessions_creator::{ClusterSessionCreator, IntoSessionId}; +use key_server_cluster::message::{self, Message, ClusterMessage}; +use key_server_cluster::key_version_negotiation_session::{SessionImpl as KeyVersionNegotiationSession, + IsolatedSessionTransport as KeyVersionNegotiationSessionTransport, ContinueAction}; +use key_server_cluster::connection_trigger::ServersSetChangeSessionCreatorConnector; + +/// Something that is able to process signals/messages from other nodes. +pub trait MessageProcessor: Send + Sync { + /// Process disconnect from the remote node. + fn process_disconnect(&self, node: &NodeId); + /// Process single message from the connection. + fn process_connection_message(&self, connection: Arc, message: Message); + + /// Start servers set change session. This is typically used by ConnectionManager when + /// it detects that auto-migration session needs to be started. + fn start_servers_set_change_session(&self, params: ServersSetChangeParams) -> Result, Error>; + /// Try to continue session after key version negotiation session is completed. + fn try_continue_session( + &self, + session: Option>> + ); + /// Maintain active sessions. Typically called by the ConnectionManager at some intervals. + /// Should cancel stalled sessions and send keep-alive messages for sessions that support it. + fn maintain_sessions(&self); +} + +/// Bridge between ConnectionManager and ClusterSessions. +pub struct SessionsMessageProcessor { + self_key_pair: Arc, + servers_set_change_creator_connector: Arc, + sessions: Arc, + connections: Arc, +} + +impl SessionsMessageProcessor { + /// Create new instance of SessionsMessageProcessor. + pub fn new( + self_key_pair: Arc, + servers_set_change_creator_connector: Arc, + sessions: Arc, + connections: Arc, + ) -> Self { + SessionsMessageProcessor { + self_key_pair, + servers_set_change_creator_connector, + sessions, + connections, + } + } + + /// Process single session message from connection. + fn process_message, D>( + &self, + sessions: &ClusterSessionsContainer, + connection: Arc, + mut message: Message, + ) -> Option> + where + Message: IntoSessionId + { + // get or create new session, if required + let mut sender = *connection.node_id(); + let session = self.prepare_session(sessions, &sender, &message); + // send error if session is not found, or failed to create + let session = match session { + Ok(session) => session, + Err(error) => { + // this is new session => it is not yet in container + warn!(target: "secretstore_net", + "{}: {} session read error '{}' when requested for session from node {}", + self.self_key_pair.public(), S::type_name(), error, sender); + if !message.is_error_message() { + let qed = "session_id only fails for cluster messages; + only session messages are passed to process_message; + qed"; + let session_id = message.into_session_id().expect(qed); + let session_nonce = message.session_nonce().expect(qed); + + connection.send_message(SC::make_error_message(session_id, session_nonce, error)); + } + return None; + }, + }; + + let session_id = session.id(); + let mut is_queued_message = false; + loop { + let message_result = session.on_message(&sender, &message); + match message_result { + Ok(_) => { + // if session is completed => stop + if session.is_finished() { + info!(target: "secretstore_net", + "{}: {} session completed", self.self_key_pair.public(), S::type_name()); + sessions.remove(&session_id); + return Some(session); + } + + // try to dequeue message + match sessions.dequeue_message(&session_id) { + Some((msg_sender, msg)) => { + is_queued_message = true; + sender = msg_sender; + message = msg; + }, + None => return Some(session), + } + }, + Err(Error::TooEarlyForRequest) => { + sessions.enqueue_message(&session_id, sender, message, is_queued_message); + return Some(session); + }, + Err(err) => { + warn!( + target: "secretstore_net", + "{}: {} session error '{}' when processing message {} from node {}", + self.self_key_pair.public(), + S::type_name(), + err, + message, + sender); + session.on_session_error(self.self_key_pair.public(), err); + sessions.remove(&session_id); + return Some(session); + }, + } + } + } + + /// Get or insert new session. + fn prepare_session, D>( + &self, + sessions: &ClusterSessionsContainer, + sender: &NodeId, + message: &Message + ) -> Result, Error> + where + Message: IntoSessionId + { + fn requires_all_connections(message: &Message) -> bool { + match *message { + Message::Generation(_) => true, + Message::ShareAdd(_) => true, + Message::ServersSetChange(_) => true, + _ => false, + } + } + + // get or create new session, if required + let session_id = message.into_session_id() + .expect("into_session_id fails for cluster messages only; + only session messages are passed to prepare_session; + qed"); + let is_initialization_message = message.is_initialization_message(); + let is_delegation_message = message.is_delegation_message(); + match is_initialization_message || is_delegation_message { + false => sessions.get(&session_id, true).ok_or(Error::NoActiveSessionWithId), + true => { + let creation_data = SC::creation_data_from_message(&message)?; + let master = if is_initialization_message { + *sender + } else { + *self.self_key_pair.public() + }; + let cluster = create_cluster_view( + self.self_key_pair.clone(), + self.connections.clone(), + requires_all_connections(&message))?; + + let nonce = Some(message.session_nonce().ok_or(Error::InvalidMessage)?); + let exclusive = message.is_exclusive_session_message(); + sessions.insert(cluster, master, session_id, nonce, exclusive, creation_data) + }, + } + } + + /// Process single cluster message from the connection. + fn process_cluster_message(&self, connection: Arc, message: ClusterMessage) { + match message { + ClusterMessage::KeepAlive(_) => { + let msg = Message::Cluster(ClusterMessage::KeepAliveResponse(message::KeepAliveResponse { + session_id: None, + })); + connection.send_message(msg) + }, + ClusterMessage::KeepAliveResponse(msg) => if let Some(session_id) = msg.session_id { + self.sessions.on_session_keep_alive(connection.node_id(), session_id.into()); + }, + _ => warn!(target: "secretstore_net", "{}: received unexpected message {} from node {} at {}", + self.self_key_pair.public(), message, connection.node_id(), connection.node_address()), + } + } +} + +impl MessageProcessor for SessionsMessageProcessor { + fn process_disconnect(&self, node: &NodeId) { + self.sessions.on_connection_timeout(node); + } + + fn process_connection_message(&self, connection: Arc, message: Message) { + trace!(target: "secretstore_net", "{}: received message {} from {}", + self.self_key_pair.public(), message, connection.node_id()); + + // error is ignored as we only process errors on session level + match message { + Message::Generation(message) => self + .process_message(&self.sessions.generation_sessions, connection, Message::Generation(message)) + .map(|_| ()).unwrap_or_default(), + Message::Encryption(message) => self + .process_message(&self.sessions.encryption_sessions, connection, Message::Encryption(message)) + .map(|_| ()).unwrap_or_default(), + Message::Decryption(message) => self + .process_message(&self.sessions.decryption_sessions, connection, Message::Decryption(message)) + .map(|_| ()).unwrap_or_default(), + Message::SchnorrSigning(message) => self + .process_message(&self.sessions.schnorr_signing_sessions, connection, Message::SchnorrSigning(message)) + .map(|_| ()).unwrap_or_default(), + Message::EcdsaSigning(message) => self + .process_message(&self.sessions.ecdsa_signing_sessions, connection, Message::EcdsaSigning(message)) + .map(|_| ()).unwrap_or_default(), + Message::ServersSetChange(message) => { + let message = Message::ServersSetChange(message); + let is_initialization_message = message.is_initialization_message(); + let session = self.process_message(&self.sessions.admin_sessions, connection, message); + if is_initialization_message { + if let Some(session) = session { + self.servers_set_change_creator_connector + .set_key_servers_set_change_session(session.clone()); + } + } + }, + Message::KeyVersionNegotiation(message) => { + let session = self.process_message( + &self.sessions.negotiation_sessions, connection, Message::KeyVersionNegotiation(message)); + self.try_continue_session(session); + }, + Message::ShareAdd(message) => self.process_message( + &self.sessions.admin_sessions, connection, Message::ShareAdd(message)) + .map(|_| ()).unwrap_or_default(), + Message::Cluster(message) => self.process_cluster_message(connection, message), + } + } + + fn try_continue_session( + &self, + session: Option>> + ) { + if let Some(session) = session { + let meta = session.meta(); + let is_master_node = meta.self_node_id == meta.master_node_id; + if is_master_node && session.is_finished() { + self.sessions.negotiation_sessions.remove(&session.id()); + match session.wait() { + Ok(Some((version, master))) => match session.take_continue_action() { + Some(ContinueAction::Decrypt( + session, origin, is_shadow_decryption, is_broadcast_decryption + )) => { + let initialization_error = if self.self_key_pair.public() == &master { + session.initialize( + origin, version, is_shadow_decryption, is_broadcast_decryption) + } else { + session.delegate( + master, origin, version, is_shadow_decryption, is_broadcast_decryption) + }; + + if let Err(error) = initialization_error { + session.on_session_error(&meta.self_node_id, error); + self.sessions.decryption_sessions.remove(&session.id()); + } + }, + Some(ContinueAction::SchnorrSign(session, message_hash)) => { + let initialization_error = if self.self_key_pair.public() == &master { + session.initialize(version, message_hash) + } else { + session.delegate(master, version, message_hash) + }; + + if let Err(error) = initialization_error { + session.on_session_error(&meta.self_node_id, error); + self.sessions.schnorr_signing_sessions.remove(&session.id()); + } + }, + Some(ContinueAction::EcdsaSign(session, message_hash)) => { + let initialization_error = if self.self_key_pair.public() == &master { + session.initialize(version, message_hash) + } else { + session.delegate(master, version, message_hash) + }; + + if let Err(error) = initialization_error { + session.on_session_error(&meta.self_node_id, error); + self.sessions.ecdsa_signing_sessions.remove(&session.id()); + } + }, + None => (), + }, + Ok(None) => unreachable!("is_master_node; session is finished; + negotiation version always finished with result on master; + qed"), + Err(error) => match session.take_continue_action() { + Some(ContinueAction::Decrypt(session, _, _, _)) => { + session.on_session_error(&meta.self_node_id, error); + self.sessions.decryption_sessions.remove(&session.id()); + }, + Some(ContinueAction::SchnorrSign(session, _)) => { + session.on_session_error(&meta.self_node_id, error); + self.sessions.schnorr_signing_sessions.remove(&session.id()); + }, + Some(ContinueAction::EcdsaSign(session, _)) => { + session.on_session_error(&meta.self_node_id, error); + self.sessions.ecdsa_signing_sessions.remove(&session.id()); + }, + None => (), + }, + } + } + } + } + + fn maintain_sessions(&self) { + self.sessions.stop_stalled_sessions(); + self.sessions.sessions_keep_alive(); + } + + fn start_servers_set_change_session(&self, params: ServersSetChangeParams) -> Result, Error> { + new_servers_set_change_session( + self.self_key_pair.clone(), + &*self.sessions, + self.connections.clone(), + self.servers_set_change_creator_connector.clone(), + params, + ) + } +} diff --git a/secret-store/src/key_server_cluster/cluster_sessions.rs b/secret-store/src/key_server_cluster/cluster_sessions.rs index cce4b18c3b..53eec13346 100644 --- a/secret-store/src/key_server_cluster/cluster_sessions.rs +++ b/secret-store/src/key_server_cluster/cluster_sessions.rs @@ -21,8 +21,9 @@ use std::collections::{VecDeque, BTreeMap, BTreeSet}; use parking_lot::{Mutex, RwLock, Condvar}; use ethereum_types::H256; use ethkey::Secret; -use key_server_cluster::{Error, NodeId, SessionId, Requester}; -use key_server_cluster::cluster::{Cluster, ClusterData, ClusterConfiguration, ClusterView}; +use key_server_cluster::{Error, NodeId, SessionId, Requester, NodeKeyPair}; +use key_server_cluster::cluster::{Cluster, ClusterConfiguration, ClusterView}; +use key_server_cluster::cluster_connections::ConnectionProvider; use key_server_cluster::connection_trigger::ServersSetChangeSessionCreatorConnector; use key_server_cluster::message::{self, Message}; use key_server_cluster::generation_session::{SessionImpl as GenerationSessionImpl}; @@ -158,6 +159,8 @@ pub struct ClusterSessionsContainer>>>, /// Sessions container state. container_state: Arc>, + /// Do not actually remove sessions. + preserve_sessions: bool, /// Phantom data. _pd: ::std::marker::PhantomData, } @@ -229,6 +232,17 @@ impl ClusterSessions { self.generation_sessions.creator.make_faulty_generation_sessions(); } + #[cfg(test)] + pub fn preserve_sessions(&mut self) { + self.generation_sessions.preserve_sessions = true; + self.encryption_sessions.preserve_sessions = true; + self.decryption_sessions.preserve_sessions = true; + self.schnorr_signing_sessions.preserve_sessions = true; + self.ecdsa_signing_sessions.preserve_sessions = true; + self.negotiation_sessions.preserve_sessions = true; + self.admin_sessions.preserve_sessions = true; + } + /// Send session-level keep-alive messages. pub fn sessions_keep_alive(&self) { self.admin_sessions.send_keep_alive(&*SERVERS_SET_CHANGE_SESSION_ID, &self.self_node_id); @@ -272,6 +286,7 @@ impl ClusterSessionsContainer where S: ClusterSession, SC: C sessions: RwLock::new(BTreeMap::new()), listeners: Mutex::new(Vec::new()), container_state: container_state, + preserve_sessions: false, _pd: Default::default(), } } @@ -379,9 +394,11 @@ impl ClusterSessionsContainer where S: ClusterSession, SC: C } fn do_remove(&self, session_id: &S::Id, sessions: &mut BTreeMap>) { - if let Some(session) = sessions.remove(session_id) { - self.container_state.lock().on_session_completed(); - self.notify_listeners(|l| l.on_session_removed(session.session.clone())); + if !self.preserve_sessions { + if let Some(session) = sessions.remove(session_id) { + self.container_state.lock().on_session_completed(); + self.notify_listeners(|l| l.on_session_removed(session.session.clone())); + } } } @@ -551,19 +568,22 @@ impl ClusterSession for AdminSession { } } } -pub fn create_cluster_view(data: &Arc, requires_all_connections: bool) -> Result, Error> { - let disconnected_nodes_count = data.connections.disconnected_nodes().len(); + +pub fn create_cluster_view(self_key_pair: Arc, connections: Arc, requires_all_connections: bool) -> Result, Error> { + let mut connected_nodes = connections.connected_nodes()?; + let disconnected_nodes = connections.disconnected_nodes(); + + let disconnected_nodes_count = disconnected_nodes.len(); if requires_all_connections { if disconnected_nodes_count != 0 { return Err(Error::NodeDisconnected); } } - let mut connected_nodes = data.connections.connected_nodes()?; - connected_nodes.insert(data.self_key_pair.public().clone()); + connected_nodes.insert(self_key_pair.public().clone()); let connected_nodes_count = connected_nodes.len(); - Ok(Arc::new(ClusterView::new(data.clone(), connected_nodes, connected_nodes_count + disconnected_nodes_count))) + Ok(Arc::new(ClusterView::new(self_key_pair, connections, connected_nodes, connected_nodes_count + disconnected_nodes_count))) } #[cfg(test)] @@ -583,13 +603,11 @@ mod tests { let key_pair = Random.generate().unwrap(); let config = ClusterConfiguration { self_key_pair: Arc::new(PlainNodeKeyPair::new(key_pair.clone())), - listen_address: ("127.0.0.1".to_owned(), 100_u16), key_server_set: Arc::new(MapKeyServerSet::new(false, vec![(key_pair.public().clone(), format!("127.0.0.1:{}", 100).parse().unwrap())].into_iter().collect())), - allow_connecting_to_higher_nodes: false, key_storage: Arc::new(DummyKeyStorage::default()), acl_storage: Arc::new(DummyAclStorage::default()), admin_public: Some(Random.generate().unwrap().public().clone()), - auto_migrate_enabled: false, + preserve_sessions: false, }; ClusterSessions::new(&config, Arc::new(SimpleServersSetChangeSessionCreatorConnector { admin_public: Some(Random.generate().unwrap().public().clone()), diff --git a/secret-store/src/key_server_cluster/connection_trigger.rs b/secret-store/src/key_server_cluster/connection_trigger.rs index 3ea1a0a302..7b3649861f 100644 --- a/secret-store/src/key_server_cluster/connection_trigger.rs +++ b/secret-store/src/key_server_cluster/connection_trigger.rs @@ -21,10 +21,12 @@ use std::sync::Arc; use ethereum_types::H256; use ethkey::Public; use key_server_cluster::{KeyServerSet, KeyServerSetSnapshot}; -use key_server_cluster::cluster::{ClusterClient, ClusterConnectionsData}; +use key_server_cluster::cluster::{ClusterConfiguration, ServersSetChangeParams}; use key_server_cluster::cluster_sessions::AdminSession; +use key_server_cluster::cluster_connections::{Connection}; +use key_server_cluster::cluster_connections_net::{NetConnectionsContainer}; use types::{Error, NodeId}; -use {NodeKeyPair}; +use NodeKeyPair; #[derive(Debug, Clone, Copy, PartialEq)] /// Describes which maintain() call is required. @@ -45,10 +47,10 @@ pub trait ConnectionTrigger: Send + Sync { fn on_connection_established(&mut self, node: &NodeId) -> Option; /// When connection is closed. fn on_connection_closed(&mut self, node: &NodeId) -> Option; - /// Maintain active sessions. - fn maintain_session(&mut self, sessions: &ClusterClient); + /// Maintain active sessions. Returns Some if servers set session creation required. + fn maintain_session(&mut self) -> Option; /// Maintain active connections. - fn maintain_connections(&mut self, connections: &mut ClusterConnectionsData); + fn maintain_connections(&mut self, connections: &mut NetConnectionsContainer); /// Return connector for the servers set change session creator. fn servers_set_change_creator_connector(&self) -> Arc; } @@ -95,6 +97,11 @@ pub struct TriggerConnections { } impl SimpleConnectionTrigger { + /// Create new simple from cluster configuration. + pub fn with_config(config: &ClusterConfiguration) -> Self { + Self::new(config.key_server_set.clone(), config.self_key_pair.clone(), config.admin_public) + } + /// Create new simple connection trigger. pub fn new(key_server_set: Arc, self_key_pair: Arc, admin_public: Option) -> Self { SimpleConnectionTrigger { @@ -124,10 +131,11 @@ impl ConnectionTrigger for SimpleConnectionTrigger { None } - fn maintain_session(&mut self, _sessions: &ClusterClient) { + fn maintain_session(&mut self) -> Option { + None } - fn maintain_connections(&mut self, connections: &mut ClusterConnectionsData) { + fn maintain_connections(&mut self, connections: &mut NetConnectionsContainer) { self.connections.maintain(ConnectionsAction::ConnectToCurrentSet, connections, &self.key_server_set.snapshot()) } @@ -146,7 +154,7 @@ impl ServersSetChangeSessionCreatorConnector for SimpleServersSetChangeSessionCr } impl TriggerConnections { - pub fn maintain(&self, action: ConnectionsAction, data: &mut ClusterConnectionsData, server_set: &KeyServerSetSnapshot) { + pub fn maintain(&self, action: ConnectionsAction, data: &mut NetConnectionsContainer, server_set: &KeyServerSetSnapshot) { match action { ConnectionsAction::ConnectToCurrentSet => { adjust_connections(self.self_key_pair.public(), data, &server_set.current_set); @@ -159,7 +167,11 @@ impl TriggerConnections { } } -fn adjust_connections(self_node_id: &NodeId, data: &mut ClusterConnectionsData, required_set: &BTreeMap) { +fn adjust_connections( + self_node_id: &NodeId, + data: &mut NetConnectionsContainer, + required_set: &BTreeMap +) { if !required_set.contains_key(self_node_id) { if !data.is_isolated { trace!(target: "secretstore_net", "{}: isolated from cluser", self_node_id); @@ -204,13 +216,13 @@ mod tests { use std::collections::BTreeSet; use std::sync::Arc; use ethkey::{Random, Generator}; - use key_server_cluster::cluster::ClusterConnectionsData; use key_server_cluster::{MapKeyServerSet, PlainNodeKeyPair, KeyServerSetSnapshot, KeyServerSetMigration}; + use key_server_cluster::cluster_connections_net::NetConnectionsContainer; use super::{Maintain, TriggerConnections, ConnectionsAction, ConnectionTrigger, SimpleConnectionTrigger, select_nodes_to_disconnect, adjust_connections}; - fn default_connection_data() -> ClusterConnectionsData { - ClusterConnectionsData { + fn default_connection_data() -> NetConnectionsContainer { + NetConnectionsContainer { is_isolated: false, nodes: Default::default(), connections: Default::default(), diff --git a/secret-store/src/key_server_cluster/connection_trigger_with_migration.rs b/secret-store/src/key_server_cluster/connection_trigger_with_migration.rs index 9607949c5a..559bab18c1 100644 --- a/secret-store/src/key_server_cluster/connection_trigger_with_migration.rs +++ b/secret-store/src/key_server_cluster/connection_trigger_with_migration.rs @@ -21,7 +21,8 @@ use ethereum_types::H256; use ethkey::Public; use parking_lot::Mutex; use key_server_cluster::{KeyServerSet, KeyServerSetSnapshot, KeyServerSetMigration, is_migration_required}; -use key_server_cluster::cluster::{ClusterClient, ClusterConnectionsData}; +use key_server_cluster::cluster::{ClusterConfiguration, ServersSetChangeParams}; +use key_server_cluster::cluster_connections_net::NetConnectionsContainer; use key_server_cluster::cluster_sessions::{AdminSession, ClusterSession}; use key_server_cluster::jobs::servers_set_change_access_job::ordered_nodes_hash; use key_server_cluster::connection_trigger::{Maintain, ConnectionsAction, ConnectionTrigger, @@ -110,6 +111,11 @@ struct TriggerSession { } impl ConnectionTriggerWithMigration { + /// Create new simple from cluster configuration. + pub fn with_config(config: &ClusterConfiguration) -> Self { + Self::new(config.key_server_set.clone(), config.self_key_pair.clone()) + } + /// Create new trigge with migration. pub fn new(key_server_set: Arc, self_key_pair: Arc) -> Self { let snapshot = key_server_set.snapshot(); @@ -187,13 +193,11 @@ impl ConnectionTrigger for ConnectionTriggerWithMigration { self.do_maintain() } - fn maintain_session(&mut self, sessions: &ClusterClient) { - if let Some(action) = self.session_action { - self.session.maintain(action, sessions, &self.snapshot); - } + fn maintain_session(&mut self) -> Option { + self.session_action.and_then(|action| self.session.maintain(action, &self.snapshot)) } - fn maintain_connections(&mut self, connections: &mut ClusterConnectionsData) { + fn maintain_connections(&mut self, connections: &mut NetConnectionsContainer) { if let Some(action) = self.connections_action { self.connections.maintain(action, connections, &self.snapshot); } @@ -255,30 +259,42 @@ impl TriggerSession { } /// Maintain session. - pub fn maintain(&mut self, action: SessionAction, sessions: &ClusterClient, server_set: &KeyServerSetSnapshot) { - if action == SessionAction::Start { // all other actions are processed in maintain - let migration = server_set.migration.as_ref() - .expect("action is Start only when migration is started (see maintain_session); qed"); - - // we assume that authorities that are removed from the servers set are either offline, or malicious - // => they're not involved in ServersSetChangeSession - // => both sets are the same - let old_set: BTreeSet<_> = migration.set.keys().cloned().collect(); - let new_set = old_set.clone(); - - let signatures = self.self_key_pair.sign(&ordered_nodes_hash(&old_set)) - .and_then(|old_set_signature| self.self_key_pair.sign(&ordered_nodes_hash(&new_set)) - .map(|new_set_signature| (old_set_signature, new_set_signature))) - .map_err(Into::into); - let session = signatures.and_then(|(old_set_signature, new_set_signature)| - sessions.new_servers_set_change_session(None, Some(migration.id.clone()), new_set, old_set_signature, new_set_signature)); - - match session { - Ok(_) => trace!(target: "secretstore_net", "{}: started auto-migrate session", - self.self_key_pair.public()), - Err(err) => trace!(target: "secretstore_net", "{}: failed to start auto-migrate session with: {}", - self.self_key_pair.public(), err), - } + pub fn maintain( + &mut self, + action: SessionAction, + server_set: &KeyServerSetSnapshot + ) -> Option { + if action != SessionAction::Start { // all other actions are processed in maintain + return None; + } + let migration = server_set.migration.as_ref() + .expect("action is Start only when migration is started (see maintain_session); qed"); + + // we assume that authorities that are removed from the servers set are either offline, or malicious + // => they're not involved in ServersSetChangeSession + // => both sets are the same + let old_set: BTreeSet<_> = migration.set.keys().cloned().collect(); + let new_set = old_set.clone(); + + let signatures = self.self_key_pair.sign(&ordered_nodes_hash(&old_set)) + .and_then(|old_set_signature| self.self_key_pair.sign(&ordered_nodes_hash(&new_set)) + .map(|new_set_signature| (old_set_signature, new_set_signature))); + + match signatures { + Ok((old_set_signature, new_set_signature)) => Some(ServersSetChangeParams { + session_id: None, + migration_id: Some(migration.id), + new_nodes_set: new_set, + old_set_signature, + new_set_signature, + }), + Err(err) => { + trace!( + target: "secretstore_net", + "{}: failed to sign servers set for auto-migrate session with: {}", + self.self_key_pair.public(), err); + None + }, } } } diff --git a/secret-store/src/key_server_cluster/mod.rs b/secret-store/src/key_server_cluster/mod.rs index 3db29ba7ed..fc46e10318 100644 --- a/secret-store/src/key_server_cluster/mod.rs +++ b/secret-store/src/key_server_cluster/mod.rs @@ -23,7 +23,8 @@ pub use super::key_storage::{KeyStorage, DocumentKeyShare, DocumentKeyShareVersi pub use super::key_server_set::{is_migration_required, KeyServerSet, KeyServerSetSnapshot, KeyServerSetMigration}; pub use super::serialization::{SerializableSignature, SerializableH256, SerializableSecret, SerializablePublic, SerializableRequester, SerializableMessageHash, SerializableAddress}; -pub use self::cluster::{ClusterCore, ClusterConfiguration, ClusterClient}; +pub use self::cluster::{new_network_cluster, ClusterCore, ClusterConfiguration, ClusterClient}; +pub use self::cluster_connections_net::NetConnectionsManagerConfig; pub use self::cluster_sessions::{ClusterSession, ClusterSessionsListener}; #[cfg(test)] pub use self::cluster::tests::DummyClusterClient; @@ -70,6 +71,9 @@ pub use self::client_sessions::signing_session_ecdsa; pub use self::client_sessions::signing_session_schnorr; mod cluster; +mod cluster_connections; +mod cluster_connections_net; +mod cluster_message_processor; mod cluster_sessions; mod cluster_sessions_creator; mod connection_trigger; diff --git a/secret-store/src/node_key_pair.rs b/secret-store/src/node_key_pair.rs index e7227d7540..f50f75ad1b 100644 --- a/secret-store/src/node_key_pair.rs +++ b/secret-store/src/node_key_pair.rs @@ -29,6 +29,11 @@ impl PlainNodeKeyPair { key_pair: key_pair, } } + + #[cfg(test)] + pub fn key_pair(&self) -> &KeyPair { + &self.key_pair + } } impl NodeKeyPair for PlainNodeKeyPair { diff --git a/secret_store/src/key_server_cluster/cluster_connections.rs b/secret_store/src/key_server_cluster/cluster_connections.rs new file mode 100644 index 0000000000..b484e6d8e0 --- /dev/null +++ b/secret_store/src/key_server_cluster/cluster_connections.rs @@ -0,0 +1,176 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +use std::collections::BTreeSet; +use std::sync::Arc; +use key_server_cluster::{Error, NodeId}; +use key_server_cluster::message::Message; + +/// Connection to the single node. Provides basic information about connected node and +/// allows sending messages to this node. +pub trait Connection: Send + Sync { + /// Is this inbound connection? This only matters when both nodes are simultaneously establishing + /// two connections to each other. The agreement is that the inbound connection from the node with + /// lower NodeId is used and the other connection is closed. + fn is_inbound(&self) -> bool; + /// Returns id of the connected node. + fn node_id(&self) -> &NodeId; + /// Returns 'address' of the node to use in traces. + fn node_address(&self) -> String; + /// Send message to the connected node. + fn send_message(&self, message: Message); +} + +/// Connections manager. Responsible for keeping us connected to all required nodes. +pub trait ConnectionManager: 'static + Send + Sync { + /// Returns shared reference to connections provider. + fn provider(&self) -> Arc; + /// Try to reach all disconnected nodes immediately. This method is exposed mostly for + /// tests, where all 'nodes' are starting listening for incoming connections first and + /// only after this, they're actually start connecting to each other. + fn connect(&self); +} + +/// Connections provider. Holds all active connections and the set of nodes that we need to +/// connect to. At any moment connection could be lost and the set of connected/disconnected +/// nodes could change (at behalf of the connection manager). +/// Clone operation should be cheap (Arc). +pub trait ConnectionProvider: Send + Sync { + /// Returns the set of currently connected nodes. Error is returned when our node is + /// not a part of the cluster ('isolated' node). + fn connected_nodes(&self) -> Result, Error>; + /// Returns the set of currently disconnected nodes. + fn disconnected_nodes(&self) -> BTreeSet; + /// Returns the reference to the active node connection or None if the node is not connected. + fn connection(&self, node: &NodeId) -> Option>; +} + +#[cfg(test)] +pub mod tests { + use std::collections::{BTreeSet, VecDeque}; + use std::sync::Arc; + use std::sync::atomic::{AtomicBool, Ordering}; + use parking_lot::Mutex; + use key_server_cluster::{Error, NodeId}; + use key_server_cluster::message::Message; + use super::{ConnectionManager, Connection, ConnectionProvider}; + + /// Shared messages queue. + pub type MessagesQueue = Arc>>; + + /// Single node connections. + pub struct TestConnections { + node: NodeId, + is_isolated: AtomicBool, + connected_nodes: Mutex>, + disconnected_nodes: Mutex>, + messages: MessagesQueue, + } + + /// Single connection. + pub struct TestConnection { + from: NodeId, + to: NodeId, + messages: MessagesQueue, + } + + impl TestConnections { + pub fn isolate(&self) { + let connected_nodes = ::std::mem::replace(&mut *self.connected_nodes.lock(), Default::default()); + self.is_isolated.store(true, Ordering::Relaxed); + self.disconnected_nodes.lock().extend(connected_nodes) + } + + pub fn disconnect(&self, node: NodeId) { + self.connected_nodes.lock().remove(&node); + self.disconnected_nodes.lock().insert(node); + } + + pub fn exclude(&self, node: NodeId) { + self.connected_nodes.lock().remove(&node); + self.disconnected_nodes.lock().remove(&node); + } + + pub fn include(&self, node: NodeId) { + self.connected_nodes.lock().insert(node); + } + } + + impl ConnectionManager for Arc { + fn provider(&self) -> Arc { + self.clone() + } + + fn connect(&self) {} + } + + impl ConnectionProvider for TestConnections { + fn connected_nodes(&self) -> Result, Error> { + match self.is_isolated.load(Ordering::Relaxed) { + false => Ok(self.connected_nodes.lock().clone()), + true => Err(Error::NodeDisconnected), + } + } + + fn disconnected_nodes(&self) -> BTreeSet { + self.disconnected_nodes.lock().clone() + } + + fn connection(&self, node: &NodeId) -> Option> { + match self.connected_nodes.lock().contains(node) { + true => Some(Arc::new(TestConnection { + from: self.node, + to: *node, + messages: self.messages.clone(), + })), + false => None, + } + } + } + + impl Connection for TestConnection { + fn is_inbound(&self) -> bool { + false + } + + fn node_id(&self) -> &NodeId { + &self.to + } + + fn node_address(&self) -> String { + format!("{}", self.to) + } + + fn send_message(&self, message: Message) { + self.messages.lock().push_back((self.from, self.to, message)) + } + } + + pub fn new_test_connections( + messages: MessagesQueue, + node: NodeId, + mut nodes: BTreeSet + ) -> Arc { + let is_isolated = !nodes.remove(&node); + Arc::new(TestConnections { + node, + is_isolated: AtomicBool::new(is_isolated), + connected_nodes: Mutex::new(nodes), + disconnected_nodes: Default::default(), + messages, + }) + } +} diff --git a/secret_store/src/key_server_cluster/cluster_connections_net.rs b/secret_store/src/key_server_cluster/cluster_connections_net.rs new file mode 100644 index 0000000000..bda7f7dd28 --- /dev/null +++ b/secret_store/src/key_server_cluster/cluster_connections_net.rs @@ -0,0 +1,539 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +use std::collections::{BTreeMap, BTreeSet}; +use std::collections::btree_map::Entry; +use std::io; +use std::net::{SocketAddr, IpAddr}; +use std::sync::Arc; +use std::time::{Duration, Instant}; +use futures::{future, Future, Stream}; +use parking_lot::{Mutex, RwLock}; +use tokio::net::{TcpListener, TcpStream}; +use tokio::timer::{Interval, timeout::Error as TimeoutError}; +use tokio_io::IoFuture; +use ethkey::KeyPair; +use parity_runtime::Executor; +use key_server_cluster::{Error, NodeId, ClusterConfiguration, NodeKeyPair}; +use key_server_cluster::cluster_connections::{ConnectionProvider, Connection, ConnectionManager}; +use key_server_cluster::connection_trigger::{Maintain, ConnectionTrigger}; +use key_server_cluster::cluster_message_processor::MessageProcessor; +use key_server_cluster::io::{DeadlineStatus, ReadMessage, SharedTcpStream, + read_encrypted_message, WriteMessage, write_encrypted_message}; +use key_server_cluster::message::{self, ClusterMessage, Message}; +use key_server_cluster::net::{accept_connection as io_accept_connection, + connect as io_connect, Connection as IoConnection}; + +/// Empty future. +pub type BoxedEmptyFuture = Box + Send>; + +/// Maintain interval (seconds). Every MAINTAIN_INTERVAL seconds node: +/// 1) checks if connected nodes are responding to KeepAlive messages +/// 2) tries to connect to disconnected nodes +/// 3) checks if enc/dec sessions are time-outed +const MAINTAIN_INTERVAL: u64 = 10; + +/// When no messages have been received from node within KEEP_ALIVE_SEND_INTERVAL seconds, +/// we must send KeepAlive message to the node to check if it still responds to messages. +const KEEP_ALIVE_SEND_INTERVAL: Duration = Duration::from_secs(30); +/// When no messages have been received from node within KEEP_ALIVE_DISCONNECT_INTERVAL seconds, +/// we must treat this node as non-responding && disconnect from it. +const KEEP_ALIVE_DISCONNECT_INTERVAL: Duration = Duration::from_secs(60); + +/// Network connection manager configuration. +pub struct NetConnectionsManagerConfig { + /// Allow connecting to 'higher' nodes. + pub allow_connecting_to_higher_nodes: bool, + /// Interface to listen to. + pub listen_address: (String, u16), + /// True if we should autostart key servers set change session when servers set changes? + /// This will only work when servers set is configured using KeyServerSet contract. + pub auto_migrate_enabled: bool, +} + +/// Network connections manager. +pub struct NetConnectionsManager { + /// Address we're listening for incoming connections. + listen_address: SocketAddr, + /// Shared cluster connections data reference. + data: Arc, +} + +/// Network connections data. Shared among NetConnectionsManager and spawned futures. +struct NetConnectionsData { + /// Allow connecting to 'higher' nodes. + allow_connecting_to_higher_nodes: bool, + /// Reference to tokio task executor. + executor: Executor, + /// Key pair of this node. + self_key_pair: Arc, + /// Network messages processor. + message_processor: Arc, + /// Connections trigger. + trigger: Mutex>, + /// Mutable connection data. + container: Arc>, +} + +/// Network connections container. This is the only mutable data of NetConnectionsManager. +/// The set of nodes is mutated by the connection trigger and the connections set is also +/// mutated by spawned futures. +pub struct NetConnectionsContainer { + /// Is this node isolated from cluster? + pub is_isolated: bool, + /// Current key servers set. + pub nodes: BTreeMap, + /// Active connections to key servers. + pub connections: BTreeMap>, +} + +/// Network connection to single key server node. +pub struct NetConnection { + executor: Executor, + /// Id of the peer node. + node_id: NodeId, + /// Address of the peer node. + node_address: SocketAddr, + /// Is this inbound (true) or outbound (false) connection? + is_inbound: bool, + /// Key pair that is used to encrypt connection' messages. + key: KeyPair, + /// Last message time. + last_message_time: RwLock, + /// Underlying TCP stream. + stream: SharedTcpStream, +} + +impl NetConnectionsManager { + /// Create new network connections manager. + pub fn new( + executor: Executor, + message_processor: Arc, + trigger: Box, + container: Arc>, + config: &ClusterConfiguration, + net_config: NetConnectionsManagerConfig, + ) -> Result { + let listen_address = make_socket_address( + &net_config.listen_address.0, + net_config.listen_address.1)?; + + Ok(NetConnectionsManager { + listen_address, + data: Arc::new(NetConnectionsData { + allow_connecting_to_higher_nodes: net_config.allow_connecting_to_higher_nodes, + executor, + message_processor, + self_key_pair: config.self_key_pair.clone(), + trigger: Mutex::new(trigger), + container, + }), + }) + } + + /// Start listening for connections and schedule connections maintenance. + pub fn start(&self) -> Result<(), Error> { + net_listen(&self.listen_address, self.data.clone())?; + net_schedule_maintain(self.data.clone()); + Ok(()) + } +} + +impl ConnectionManager for NetConnectionsManager { + fn provider(&self) -> Arc { + self.data.container.clone() + } + + fn connect(&self) { + net_connect_disconnected(self.data.clone()); + } +} + +impl ConnectionProvider for RwLock { + fn connected_nodes(&self) -> Result, Error> { + let connections = self.read(); + if connections.is_isolated { + return Err(Error::NodeDisconnected); + } + + Ok(connections.connections.keys().cloned().collect()) + } + + fn disconnected_nodes(&self) -> BTreeSet { + let connections = self.read(); + connections.nodes.keys() + .filter(|node_id| !connections.connections.contains_key(node_id)) + .cloned() + .collect() + } + + fn connection(&self, node: &NodeId) -> Option> { + match self.read().connections.get(node).cloned() { + Some(connection) => Some(connection), + None => None, + } + } +} + +impl NetConnection { + /// Create new connection. + pub fn new(executor: Executor, is_inbound: bool, connection: IoConnection) -> NetConnection { + NetConnection { + executor, + node_id: connection.node_id, + node_address: connection.address, + is_inbound: is_inbound, + stream: connection.stream, + key: connection.key, + last_message_time: RwLock::new(Instant::now()), + } + } + + /// Get last message time. + pub fn last_message_time(&self) -> Instant { + *self.last_message_time.read() + } + + /// Update last message time + pub fn set_last_message_time(&self, last_message_time: Instant) { + *self.last_message_time.write() = last_message_time + } + + /// Returns future that sends encrypted message over this connection. + pub fn send_message_future(&self, message: Message) -> WriteMessage { + write_encrypted_message(self.stream.clone(), &self.key, message) + } + + /// Returns future that reads encrypted message from this connection. + pub fn read_message_future(&self) -> ReadMessage { + read_encrypted_message(self.stream.clone(), self.key.clone()) + } +} + +impl Connection for NetConnection { + fn is_inbound(&self) -> bool { + self.is_inbound + } + + fn node_id(&self) -> &NodeId { + &self.node_id + } + + fn node_address(&self) -> String { + format!("{}", self.node_address) + } + + fn send_message(&self, message: Message) { + execute(&self.executor, self.send_message_future(message).then(|_| Ok(()))); + } +} + +impl NetConnectionsData { + /// Executes closure for each active connection. + pub fn active_connections(&self) -> Vec> { + self.container.read().connections.values().cloned().collect() + } + + /// Executes closure for each disconnected node. + pub fn disconnected_nodes(&self) -> Vec<(NodeId, SocketAddr)> { + let container = self.container.read(); + container.nodes.iter() + .filter(|(node_id, _)| !container.connections.contains_key(node_id)) + .map(|(node_id, addr)| (*node_id, *addr)) + .collect() + } + + /// Try to insert new connection. Returns true if connection has been inserted. + /// Returns false (and ignores connections) if: + /// - we do not expect connection from this node + /// - we are already connected to the node and existing connection 'supersede' + /// new connection by agreement + pub fn insert(&self, connection: Arc) -> bool { + let node = *connection.node_id(); + let mut container = self.container.write(); + if !container.nodes.contains_key(&node) { + trace!(target: "secretstore_net", "{}: ignoring unknown connection from {} at {}", + self.self_key_pair.public(), node, connection.node_address()); + return false; + } + + if container.connections.contains_key(&node) { + // we have already connected to the same node + // the agreement is that node with lower id must establish connection to node with higher id + if (*self.self_key_pair.public() < node && connection.is_inbound()) + || (*self.self_key_pair.public() > node && !connection.is_inbound()) { + return false; + } + } + + trace!(target: "secretstore_net", + "{}: inserting connection to {} at {}. Connected to {} of {} nodes", + self.self_key_pair.public(), node, connection.node_address(), + container.connections.len() + 1, container.nodes.len()); + container.connections.insert(node, connection); + + true + } + + /// Tries to remove connection. Returns true if connection has been removed. + /// Returns false if we do not know this connection. + pub fn remove(&self, connection: &NetConnection) -> bool { + let node_id = *connection.node_id(); + let is_inbound = connection.is_inbound(); + let mut container = self.container.write(); + if let Entry::Occupied(entry) = container.connections.entry(node_id) { + if entry.get().is_inbound() != is_inbound { + return false; + } + + trace!(target: "secretstore_net", "{}: removing connection to {} at {}", + self.self_key_pair.public(), node_id, entry.get().node_address()); + entry.remove_entry(); + + true + } else { + false + } + } +} + +/// Listen incoming connections. +fn net_listen( + listen_address: &SocketAddr, + data: Arc, +) -> Result<(), Error> { + execute(&data.executor, net_listen_future(listen_address, data.clone())?); + Ok(()) +} + +/// Listen incoming connections future. +fn net_listen_future( + listen_address: &SocketAddr, + data: Arc, +) -> Result { + Ok(Box::new(TcpListener::bind(listen_address)? + .incoming() + .and_then(move |stream| { + net_accept_connection(data.clone(), stream); + Ok(()) + }) + .for_each(|_| Ok(())) + .then(|_| future::ok(())))) +} + +/// Accept incoming connection. +fn net_accept_connection( + data: Arc, + stream: TcpStream, +) { + execute(&data.executor, net_accept_connection_future(data.clone(), stream)); +} + +/// Accept incoming connection future. +fn net_accept_connection_future(data: Arc, stream: TcpStream) -> BoxedEmptyFuture { + Box::new(io_accept_connection(stream, data.self_key_pair.clone()) + .then(move |result| net_process_connection_result(data, None, result)) + .then(|_| future::ok(()))) +} + +/// Connect to remote node. +fn net_connect( + data: Arc, + remote: SocketAddr, +) { + execute(&data.executor, net_connect_future(data.clone(), remote)); +} + +/// Connect to remote node future. +fn net_connect_future( + data: Arc, + remote: SocketAddr, +) -> BoxedEmptyFuture { + let disconnected_nodes = data.container.disconnected_nodes(); + Box::new(io_connect(&remote, data.self_key_pair.clone(), disconnected_nodes) + .then(move |result| net_process_connection_result(data, Some(remote), result)) + .then(|_| future::ok(()))) +} + +/// Process network connection result. +fn net_process_connection_result( + data: Arc, + outbound_addr: Option, + result: Result>, TimeoutError>, +) -> IoFuture> { + match result { + Ok(DeadlineStatus::Meet(Ok(connection))) => { + let connection = Arc::new(NetConnection::new(data.executor.clone(), outbound_addr.is_none(), connection)); + if data.insert(connection.clone()) { + let maintain_action = data.trigger.lock().on_connection_established(connection.node_id()); + maintain_connection_trigger(data.clone(), maintain_action); + + return net_process_connection_messages(data, connection); + } + }, + Ok(DeadlineStatus::Meet(Err(err))) => { + warn!(target: "secretstore_net", "{}: protocol error '{}' when establishing {} connection{}", + data.self_key_pair.public(), err, if outbound_addr.is_some() { "outbound" } else { "inbound" }, + outbound_addr.map(|a| format!(" with {}", a)).unwrap_or_default()); + }, + Ok(DeadlineStatus::Timeout) => { + warn!(target: "secretstore_net", "{}: timeout when establishing {} connection{}", + data.self_key_pair.public(), if outbound_addr.is_some() { "outbound" } else { "inbound" }, + outbound_addr.map(|a| format!(" with {}", a)).unwrap_or_default()); + }, + Err(err) => { + warn!(target: "secretstore_net", "{}: network error '{}' when establishing {} connection{}", + data.self_key_pair.public(), err, if outbound_addr.is_some() { "outbound" } else { "inbound" }, + outbound_addr.map(|a| format!(" with {}", a)).unwrap_or_default()); + }, + } + + Box::new(future::ok(Ok(()))) +} + +/// Process connection messages. +fn net_process_connection_messages( + data: Arc, + connection: Arc, +) -> IoFuture> { + Box::new(connection + .read_message_future() + .then(move |result| + match result { + Ok((_, Ok(message))) => { + connection.set_last_message_time(Instant::now()); + data.message_processor.process_connection_message(connection.clone(), message); + // continue serving connection + let process_messages_future = net_process_connection_messages( + data.clone(), connection).then(|_| Ok(())); + execute(&data.executor, process_messages_future); + Box::new(future::ok(Ok(()))) + }, + Ok((_, Err(err))) => { + warn!(target: "secretstore_net", "{}: protocol error '{}' when reading message from node {}", + data.self_key_pair.public(), err, connection.node_id()); + // continue serving connection + let process_messages_future = net_process_connection_messages( + data.clone(), connection).then(|_| Ok(())); + execute(&data.executor, process_messages_future); + Box::new(future::ok(Err(err))) + }, + Err(err) => { + let node_id = *connection.node_id(); + warn!(target: "secretstore_net", "{}: network error '{}' when reading message from node {}", + data.self_key_pair.public(), err, node_id); + // close connection + if data.remove(&*connection) { + let maintain_action = data.trigger.lock().on_connection_closed(&node_id); + maintain_connection_trigger(data, maintain_action); + } + Box::new(future::err(err)) + }, + } + )) +} + +/// Schedule connections. maintain. +fn net_schedule_maintain(data: Arc) { + let closure_data = data.clone(); + execute(&data.executor, Interval::new_interval(Duration::new(MAINTAIN_INTERVAL, 0)) + .and_then(move |_| Ok(net_maintain(closure_data.clone()))) + .for_each(|_| Ok(())) + .then(|_| future::ok(()))); +} + +/// Maintain network connections. +fn net_maintain(data: Arc) { + trace!(target: "secretstore_net", "{}: executing maintain procedures", data.self_key_pair.public()); + + update_nodes_set(data.clone()); + data.message_processor.maintain_sessions(); + net_keep_alive(data.clone()); + net_connect_disconnected(data); +} + +/// Send keep alive messages to remote nodes. +fn net_keep_alive(data: Arc) { + let now = Instant::now(); + let active_connections = data.active_connections(); + for connection in active_connections { + let last_message_diff = now - connection.last_message_time(); + if last_message_diff > KEEP_ALIVE_DISCONNECT_INTERVAL { + warn!(target: "secretstore_net", "{}: keep alive timeout for node {}", + data.self_key_pair.public(), connection.node_id()); + + let node_id = *connection.node_id(); + if data.remove(&*connection) { + let maintain_action = data.trigger.lock().on_connection_closed(&node_id); + maintain_connection_trigger(data.clone(), maintain_action); + } + data.message_processor.process_disconnect(&node_id); + } + else if last_message_diff > KEEP_ALIVE_SEND_INTERVAL { + connection.send_message(Message::Cluster(ClusterMessage::KeepAlive(message::KeepAlive {}))); + } + } +} + +/// Connect disconnected nodes. +fn net_connect_disconnected(data: Arc) { + let disconnected_nodes = data.disconnected_nodes(); + for (node_id, address) in disconnected_nodes { + if data.allow_connecting_to_higher_nodes || *data.self_key_pair.public() < node_id { + net_connect(data.clone(), address); + } + } +} + +/// Schedule future execution. +fn execute + Send + 'static>(executor: &Executor, f: F) { + if let Err(err) = future::Executor::execute(executor, Box::new(f)) { + error!("Secret store runtime unable to spawn task. Runtime is shutting down. ({:?})", err); + } +} + +/// Try to update active nodes set from connection trigger. +fn update_nodes_set(data: Arc) { + let maintain_action = data.trigger.lock().on_maintain(); + maintain_connection_trigger(data, maintain_action); +} + +/// Execute maintain procedures of connections trigger. +fn maintain_connection_trigger(data: Arc, maintain_action: Option) { + if maintain_action == Some(Maintain::SessionAndConnections) || maintain_action == Some(Maintain::Session) { + let session_params = data.trigger.lock().maintain_session(); + if let Some(session_params) = session_params { + let session = data.message_processor.start_servers_set_change_session(session_params); + match session { + Ok(_) => trace!(target: "secretstore_net", "{}: started auto-migrate session", + data.self_key_pair.public()), + Err(err) => trace!(target: "secretstore_net", "{}: failed to start auto-migrate session with: {}", + data.self_key_pair.public(), err), + } + } + } + if maintain_action == Some(Maintain::SessionAndConnections) || maintain_action == Some(Maintain::Connections) { + let mut trigger = data.trigger.lock(); + let mut data = data.container.write(); + trigger.maintain_connections(&mut *data); + } +} + +/// Compose SocketAddr from configuration' address and port. +fn make_socket_address(address: &str, port: u16) -> Result { + let ip_address: IpAddr = address.parse().map_err(|_| Error::InvalidNodeAddress)?; + Ok(SocketAddr::new(ip_address, port)) +} diff --git a/secret_store/src/key_server_cluster/cluster_message_processor.rs b/secret_store/src/key_server_cluster/cluster_message_processor.rs new file mode 100644 index 0000000000..b4ba5ef03b --- /dev/null +++ b/secret_store/src/key_server_cluster/cluster_message_processor.rs @@ -0,0 +1,357 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +use std::sync::Arc; +use key_server_cluster::{Error, NodeId, NodeKeyPair}; +use key_server_cluster::cluster::{ServersSetChangeParams, new_servers_set_change_session}; +use key_server_cluster::cluster_sessions::{AdminSession}; +use key_server_cluster::cluster_connections::{ConnectionProvider, Connection}; +use key_server_cluster::cluster_sessions::{ClusterSession, ClusterSessions, ClusterSessionsContainer, + create_cluster_view}; +use key_server_cluster::cluster_sessions_creator::{ClusterSessionCreator, IntoSessionId}; +use key_server_cluster::message::{self, Message, ClusterMessage}; +use key_server_cluster::key_version_negotiation_session::{SessionImpl as KeyVersionNegotiationSession, + IsolatedSessionTransport as KeyVersionNegotiationSessionTransport, ContinueAction}; +use key_server_cluster::connection_trigger::ServersSetChangeSessionCreatorConnector; + +/// Something that is able to process signals/messages from other nodes. +pub trait MessageProcessor: Send + Sync { + /// Process disconnect from the remote node. + fn process_disconnect(&self, node: &NodeId); + /// Process single message from the connection. + fn process_connection_message(&self, connection: Arc, message: Message); + + /// Start servers set change session. This is typically used by ConnectionManager when + /// it detects that auto-migration session needs to be started. + fn start_servers_set_change_session(&self, params: ServersSetChangeParams) -> Result, Error>; + /// Try to continue session after key version negotiation session is completed. + fn try_continue_session( + &self, + session: Option>> + ); + /// Maintain active sessions. Typically called by the ConnectionManager at some intervals. + /// Should cancel stalled sessions and send keep-alive messages for sessions that support it. + fn maintain_sessions(&self); +} + +/// Bridge between ConnectionManager and ClusterSessions. +pub struct SessionsMessageProcessor { + self_key_pair: Arc, + servers_set_change_creator_connector: Arc, + sessions: Arc, + connections: Arc, +} + +impl SessionsMessageProcessor { + /// Create new instance of SessionsMessageProcessor. + pub fn new( + self_key_pair: Arc, + servers_set_change_creator_connector: Arc, + sessions: Arc, + connections: Arc, + ) -> Self { + SessionsMessageProcessor { + self_key_pair, + servers_set_change_creator_connector, + sessions, + connections, + } + } + + /// Process single session message from connection. + fn process_message, D>( + &self, + sessions: &ClusterSessionsContainer, + connection: Arc, + mut message: Message, + ) -> Option> + where + Message: IntoSessionId + { + // get or create new session, if required + let mut sender = *connection.node_id(); + let session = self.prepare_session(sessions, &sender, &message); + // send error if session is not found, or failed to create + let session = match session { + Ok(session) => session, + Err(error) => { + // this is new session => it is not yet in container + warn!(target: "secretstore_net", + "{}: {} session read error '{}' when requested for session from node {}", + self.self_key_pair.public(), S::type_name(), error, sender); + if !message.is_error_message() { + let qed = "session_id only fails for cluster messages; + only session messages are passed to process_message; + qed"; + let session_id = message.into_session_id().expect(qed); + let session_nonce = message.session_nonce().expect(qed); + + connection.send_message(SC::make_error_message(session_id, session_nonce, error)); + } + return None; + }, + }; + + let session_id = session.id(); + let mut is_queued_message = false; + loop { + let message_result = session.on_message(&sender, &message); + match message_result { + Ok(_) => { + // if session is completed => stop + if session.is_finished() { + info!(target: "secretstore_net", + "{}: {} session completed", self.self_key_pair.public(), S::type_name()); + sessions.remove(&session_id); + return Some(session); + } + + // try to dequeue message + match sessions.dequeue_message(&session_id) { + Some((msg_sender, msg)) => { + is_queued_message = true; + sender = msg_sender; + message = msg; + }, + None => return Some(session), + } + }, + Err(Error::TooEarlyForRequest) => { + sessions.enqueue_message(&session_id, sender, message, is_queued_message); + return Some(session); + }, + Err(err) => { + warn!( + target: "secretstore_net", + "{}: {} session error '{}' when processing message {} from node {}", + self.self_key_pair.public(), + S::type_name(), + err, + message, + sender); + session.on_session_error(self.self_key_pair.public(), err); + sessions.remove(&session_id); + return Some(session); + }, + } + } + } + + /// Get or insert new session. + fn prepare_session, D>( + &self, + sessions: &ClusterSessionsContainer, + sender: &NodeId, + message: &Message + ) -> Result, Error> + where + Message: IntoSessionId + { + fn requires_all_connections(message: &Message) -> bool { + match *message { + Message::Generation(_) => true, + Message::ShareAdd(_) => true, + Message::ServersSetChange(_) => true, + _ => false, + } + } + + // get or create new session, if required + let session_id = message.into_session_id() + .expect("into_session_id fails for cluster messages only; + only session messages are passed to prepare_session; + qed"); + let is_initialization_message = message.is_initialization_message(); + let is_delegation_message = message.is_delegation_message(); + match is_initialization_message || is_delegation_message { + false => sessions.get(&session_id, true).ok_or(Error::NoActiveSessionWithId), + true => { + let creation_data = SC::creation_data_from_message(&message)?; + let master = if is_initialization_message { + *sender + } else { + *self.self_key_pair.public() + }; + let cluster = create_cluster_view( + self.self_key_pair.clone(), + self.connections.clone(), + requires_all_connections(&message))?; + + let nonce = Some(message.session_nonce().ok_or(Error::InvalidMessage)?); + let exclusive = message.is_exclusive_session_message(); + sessions.insert(cluster, master, session_id, nonce, exclusive, creation_data) + }, + } + } + + /// Process single cluster message from the connection. + fn process_cluster_message(&self, connection: Arc, message: ClusterMessage) { + match message { + ClusterMessage::KeepAlive(_) => { + let msg = Message::Cluster(ClusterMessage::KeepAliveResponse(message::KeepAliveResponse { + session_id: None, + })); + connection.send_message(msg) + }, + ClusterMessage::KeepAliveResponse(msg) => if let Some(session_id) = msg.session_id { + self.sessions.on_session_keep_alive(connection.node_id(), session_id.into()); + }, + _ => warn!(target: "secretstore_net", "{}: received unexpected message {} from node {} at {}", + self.self_key_pair.public(), message, connection.node_id(), connection.node_address()), + } + } +} + +impl MessageProcessor for SessionsMessageProcessor { + fn process_disconnect(&self, node: &NodeId) { + self.sessions.on_connection_timeout(node); + } + + fn process_connection_message(&self, connection: Arc, message: Message) { + trace!(target: "secretstore_net", "{}: received message {} from {}", + self.self_key_pair.public(), message, connection.node_id()); + + // error is ignored as we only process errors on session level + match message { + Message::Generation(message) => self + .process_message(&self.sessions.generation_sessions, connection, Message::Generation(message)) + .map(|_| ()).unwrap_or_default(), + Message::Encryption(message) => self + .process_message(&self.sessions.encryption_sessions, connection, Message::Encryption(message)) + .map(|_| ()).unwrap_or_default(), + Message::Decryption(message) => self + .process_message(&self.sessions.decryption_sessions, connection, Message::Decryption(message)) + .map(|_| ()).unwrap_or_default(), + Message::SchnorrSigning(message) => self + .process_message(&self.sessions.schnorr_signing_sessions, connection, Message::SchnorrSigning(message)) + .map(|_| ()).unwrap_or_default(), + Message::EcdsaSigning(message) => self + .process_message(&self.sessions.ecdsa_signing_sessions, connection, Message::EcdsaSigning(message)) + .map(|_| ()).unwrap_or_default(), + Message::ServersSetChange(message) => { + let message = Message::ServersSetChange(message); + let is_initialization_message = message.is_initialization_message(); + let session = self.process_message(&self.sessions.admin_sessions, connection, message); + if is_initialization_message { + if let Some(session) = session { + self.servers_set_change_creator_connector + .set_key_servers_set_change_session(session.clone()); + } + } + }, + Message::KeyVersionNegotiation(message) => { + let session = self.process_message( + &self.sessions.negotiation_sessions, connection, Message::KeyVersionNegotiation(message)); + self.try_continue_session(session); + }, + Message::ShareAdd(message) => self.process_message( + &self.sessions.admin_sessions, connection, Message::ShareAdd(message)) + .map(|_| ()).unwrap_or_default(), + Message::Cluster(message) => self.process_cluster_message(connection, message), + } + } + + fn try_continue_session( + &self, + session: Option>> + ) { + if let Some(session) = session { + let meta = session.meta(); + let is_master_node = meta.self_node_id == meta.master_node_id; + if is_master_node && session.is_finished() { + self.sessions.negotiation_sessions.remove(&session.id()); + match session.wait() { + Ok(Some((version, master))) => match session.take_continue_action() { + Some(ContinueAction::Decrypt( + session, origin, is_shadow_decryption, is_broadcast_decryption + )) => { + let initialization_error = if self.self_key_pair.public() == &master { + session.initialize( + origin, version, is_shadow_decryption, is_broadcast_decryption) + } else { + session.delegate( + master, origin, version, is_shadow_decryption, is_broadcast_decryption) + }; + + if let Err(error) = initialization_error { + session.on_session_error(&meta.self_node_id, error); + self.sessions.decryption_sessions.remove(&session.id()); + } + }, + Some(ContinueAction::SchnorrSign(session, message_hash)) => { + let initialization_error = if self.self_key_pair.public() == &master { + session.initialize(version, message_hash) + } else { + session.delegate(master, version, message_hash) + }; + + if let Err(error) = initialization_error { + session.on_session_error(&meta.self_node_id, error); + self.sessions.schnorr_signing_sessions.remove(&session.id()); + } + }, + Some(ContinueAction::EcdsaSign(session, message_hash)) => { + let initialization_error = if self.self_key_pair.public() == &master { + session.initialize(version, message_hash) + } else { + session.delegate(master, version, message_hash) + }; + + if let Err(error) = initialization_error { + session.on_session_error(&meta.self_node_id, error); + self.sessions.ecdsa_signing_sessions.remove(&session.id()); + } + }, + None => (), + }, + Ok(None) => unreachable!("is_master_node; session is finished; + negotiation version always finished with result on master; + qed"), + Err(error) => match session.take_continue_action() { + Some(ContinueAction::Decrypt(session, _, _, _)) => { + session.on_session_error(&meta.self_node_id, error); + self.sessions.decryption_sessions.remove(&session.id()); + }, + Some(ContinueAction::SchnorrSign(session, _)) => { + session.on_session_error(&meta.self_node_id, error); + self.sessions.schnorr_signing_sessions.remove(&session.id()); + }, + Some(ContinueAction::EcdsaSign(session, _)) => { + session.on_session_error(&meta.self_node_id, error); + self.sessions.ecdsa_signing_sessions.remove(&session.id()); + }, + None => (), + }, + } + } + } + } + + fn maintain_sessions(&self) { + self.sessions.stop_stalled_sessions(); + self.sessions.sessions_keep_alive(); + } + + fn start_servers_set_change_session(&self, params: ServersSetChangeParams) -> Result, Error> { + new_servers_set_change_session( + self.self_key_pair.clone(), + &*self.sessions, + self.connections.clone(), + self.servers_set_change_creator_connector.clone(), + params, + ) + } +} From aea289e79e839932c5b215ed258a8517765db2b7 Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Mon, 18 Feb 2019 13:38:46 +0100 Subject: [PATCH 078/168] chore(bump parity-daemonize): require rust >= 1.31 (#10359) --- Cargo.lock | 6 +++--- Cargo.toml | 2 +- parity/main.rs | 8 ++++++-- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d4f20132d5..569e99065a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2458,7 +2458,7 @@ dependencies = [ [[package]] name = "parity-daemonize" -version = "0.2.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2515,7 +2515,7 @@ dependencies = [ "number_prefix 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "panic_hook 0.1.0", "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-daemonize 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-daemonize 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-hash-fetch 1.12.0", "parity-ipfs-api 1.12.0", "parity-local-store 0.1.0", @@ -4641,7 +4641,7 @@ dependencies = [ "checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37" "checksum parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fa5168b4cf41f3835e4bc6ffb32f51bc9365dc50cb351904595b3931d917fd0c" "checksum parity-crypto 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b9db194dfbcfe3b398d63d765437a5c7232d59906e203055f0e993f6458ff1" -"checksum parity-daemonize 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9b337f62998c855fe263e504fcf883c6a0f94370ba0afc731922e8bc23419cfb" +"checksum parity-daemonize 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "69b1910b2793ff52713fca0a4ee92544ebec59ccd218ea74560be6f947b4ca77" "checksum parity-path 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5962540f99d3895d9addf535f37ab1397886bc2c68e59efd040ef458e5f8c3f7" "checksum parity-rocksdb 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cd55d2d6d6000ec99f021cf52c9acc7d2a402e14f95ced4c5de230696fabe00b" "checksum parity-rocksdb-sys 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "5bbb241262c768522f6460f0e2672dee185c8504d4d0a5a5bab45c1147981c4f" diff --git a/Cargo.toml b/Cargo.toml index d639d1d790..18a9f55e1a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -51,7 +51,7 @@ ethstore = { path = "accounts/ethstore" } node-filter = { path = "ethcore/node-filter" } rlp = { version = "0.3.0", features = ["ethereum"] } cli-signer= { path = "cli-signer" } -parity-daemonize = "0.2" +parity-daemonize = "0.3" parity-hash-fetch = { path = "updater/hash-fetch" } parity-ipfs-api = { path = "ipfs" } parity-local-store = { path = "miner/local-store" } diff --git a/parity/main.rs b/parity/main.rs index 5ad9de4d2d..a2bf112070 100644 --- a/parity/main.rs +++ b/parity/main.rs @@ -39,13 +39,15 @@ use std::path::PathBuf; use std::sync::Arc; use std::sync::atomic::{AtomicBool, Ordering}; use std::{process, env}; + use ansi_term::Colour; use ctrlc::CtrlC; use dir::default_hypervisor_path; use fdlimit::raise_fd_limit; +use ethcore_logger::setup_log; use parity_ethereum::{start, ExecutionAction}; +use parity_daemonize::AsHandle; use parking_lot::{Condvar, Mutex}; -use ethcore_logger::setup_log; const PLEASE_RESTART_EXIT_CODE: i32 = 69; const PARITY_EXECUTABLE_NAME: &str = "parity"; @@ -195,7 +197,9 @@ fn main_direct(force_can_restart: bool) -> i32 { conf.args.arg_chain = spec_override; } - let handle = if let Some(ref pid) = conf.args.arg_daemon_pid_file { + // FIXME: `pid_file` shouldn't need to cloned here + // see: `https://github.com/paritytech/parity-daemonize/pull/13` for more info + let handle = if let Some(pid) = conf.args.arg_daemon_pid_file.clone() { info!("{}", Colour::Blue.paint("starting in daemon mode").to_string()); let _ = std::io::stdout().flush(); From ca67dc251f2fa1aa7e67171533ee78a11e31785d Mon Sep 17 00:00:00 2001 From: Psilon Date: Mon, 18 Feb 2019 20:39:38 +0300 Subject: [PATCH 079/168] Add message to IO errors (#10324) --- parity/upgrade.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/parity/upgrade.rs b/parity/upgrade.rs index aa3f6eba13..ecd9beff16 100644 --- a/parity/upgrade.rs +++ b/parity/upgrade.rs @@ -28,9 +28,9 @@ use journaldb::Algorithm; #[derive(Debug)] pub enum Error { - CannotCreateConfigPath, - CannotWriteVersionFile, - CannotUpdateVersionFile, + CannotCreateConfigPath(io::Error), + CannotWriteVersionFile(io::Error), + CannotUpdateVersionFile(io::Error), SemVer(SemVerError), } @@ -105,7 +105,7 @@ fn with_locked_version(db_path: &str, script: F) -> Result where F: Fn(&Version) -> Result { let mut path = PathBuf::from(db_path); - create_dir_all(&path).map_err(|_| Error::CannotCreateConfigPath)?; + create_dir_all(&path).map_err(Error::CannotCreateConfigPath)?; path.push("ver.lock"); let version = @@ -118,11 +118,11 @@ fn with_locked_version(db_path: &str, script: F) -> Result }) .unwrap_or(Version::new(0, 9, 0)); - let mut lock = File::create(&path).map_err(|_| Error::CannotWriteVersionFile)?; + let mut lock = File::create(&path).map_err(Error::CannotWriteVersionFile)?; let result = script(&version); let written_version = Version::parse(CURRENT_VERSION)?; - lock.write_all(written_version.to_string().as_bytes()).map_err(|_| Error::CannotUpdateVersionFile)?; + lock.write_all(written_version.to_string().as_bytes()).map_err(Error::CannotUpdateVersionFile)?; result } From b4520c5886a0f8e157b6a7e29c47c9327ac5d265 Mon Sep 17 00:00:00 2001 From: Leo Arias Date: Wed, 20 Feb 2019 02:49:54 -0600 Subject: [PATCH 080/168] snap: add the removable-media plug (#10377) This interface allows the snap to access the directories in /media. This is needed when the storage is in a separate disk, not part of home. --- scripts/snap/snapcraft.template.yaml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/scripts/snap/snapcraft.template.yaml b/scripts/snap/snapcraft.template.yaml index d170241dbe..b5f370bacf 100644 --- a/scripts/snap/snapcraft.template.yaml +++ b/scripts/snap/snapcraft.template.yaml @@ -14,20 +14,20 @@ description: | apps: parity: command: parity - plugs: [home, network, network-bind, mount-observe, x11, unity7, desktop, desktop-legacy, wayland] + plugs: [home, network, network-bind, mount-observe, removable-media, x11, unity7, desktop, desktop-legacy, wayland] desktop: ./usr/share/applications/parity.desktop parity-evm: command: parity-evm - plugs: [home, network, network-bind] + plugs: [home, network, network-bind, removable-media] ethkey: command: ethkey - plugs: [home] + plugs: [home, removable-media] ethstore: command: ethstore - plugs: [home] + plugs: [home, removable-media] whisper: command: whisper - plugs: [home, network-bind] + plugs: [home, network-bind, removable-media] icon: ./scripts/snap/icon.png From b457f46c81dca55155d63d501b236bfc0d2ff5ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Silva?= Date: Wed, 20 Feb 2019 09:05:11 +0000 Subject: [PATCH 081/168] ethash: implement Progpow (#9762) * ethash: initial implementation of progpow * progpow: use wrapping arithmetic * progpow: cleanup comments * progpow: fix keccak_f800 * progpow: reorder definitions * progpow: general fixing * progpow: add basic tests from geth * progpow: generate c_dag and add test * progpow: fix progpow_init and progpow_loop * progpow: fix and add new test * progpow: tabify * progpow: add shared testvectors from geth and aleth * progpow: add benchmarks * progpow: don't read bytes from dag * ethash: use criterion for progpow benchmarks * progpow: dont borrow hash on fnv1a_hash * progpow: don't borrow operand on progpow merge * progpow: hardcode dag lookup function we only support light verification anyway * progpow: read double words directly from the dag * progpow: inline some small functions * progpow: remove some bounds checking from the main loop * progpow: remove unreachable match cases * progpow: remove bounds check in keccak_f800_round * progpow: fix ptr::swap * progpow: force loop unroll in keccak_f800_round * progpow: remove unnecessary branching in progpow_loop * progpow: force loop unroll in fill_mix * progpow: silence unused warning * progpow: dont run last keccak_f800_round out of the loop rustc generates the same assembly, it unrolls the loop * progpow: fix output of keccak_f800_short * ethcore: support progpow in ethash engine * ethash: fix typo * ethcore, ethash: fix tests * json: fix ethash spec tests * ethash: update quick_get_difficulty for progpow * ethash: drop light cache on progpow transition block * ethash: fix quick_get_difficulty tests * progpow: update to spec v0.9.0 * progpow: update to spec v0.9.1 * progpow: update to spec v0.9.2 * ethash: rename progpow benchmarks * fix Cargo.lock bad merge * ethash: only export modules for benchmarks * ethash: progpow: remove unsafe unchecked indexing * ethash: create enum for pow algorithm * ethash: box the progpow cdag * ethash: skip slow progpow test vectors on ci * ethash: don't skip progpow test vectors they don't take too long when running in release mode which is the case for CI. * ethash: progpow: update copyright date Co-Authored-By: andresilva * ethcore: remove verification of ci-skip-tests on non-test builds --- Cargo.lock | 2 + Cargo.toml | 2 +- ethash/Cargo.toml | 12 +- ethash/benches/basic.rs | 28 +- ethash/benches/progpow.rs | 86 ++++ ethash/res/progpow_testvectors.json | 86 ++++ ethash/src/cache.rs | 8 +- ethash/src/compute.rs | 109 +++-- ethash/src/lib.rs | 69 ++-- ethash/src/progpow.rs | 595 ++++++++++++++++++++++++++++ ethcore/Cargo.toml | 2 +- ethcore/src/ethereum/ethash.rs | 11 +- ethcore/src/json_tests/skip.rs | 7 +- json/src/spec/ethash.rs | 5 + test.sh | 2 +- 15 files changed, 936 insertions(+), 88 deletions(-) create mode 100644 ethash/benches/progpow.rs create mode 100644 ethash/res/progpow_testvectors.json create mode 100644 ethash/src/progpow.rs diff --git a/Cargo.lock b/Cargo.lock index 569e99065a..2154e13b80 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -671,6 +671,8 @@ dependencies = [ "memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "primal 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)", "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/Cargo.toml b/Cargo.toml index 18a9f55e1a..a6b1c005da 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -91,7 +91,7 @@ default = ["accounts"] accounts = ["ethcore-accounts", "parity-rpc/accounts"] miner-debug = ["ethcore/miner-debug"] json-tests = ["ethcore/json-tests"] -ci-skip-issue = ["ethcore/ci-skip-issue"] +ci-skip-tests = ["ethcore/ci-skip-tests"] test-heavy = ["ethcore/test-heavy"] evm-debug = ["ethcore/evm-debug"] evm-debug-tests = ["ethcore/evm-debug-tests"] diff --git a/ethash/Cargo.toml b/ethash/Cargo.toml index 5ebafb4537..929895aca7 100644 --- a/ethash/Cargo.toml +++ b/ethash/Cargo.toml @@ -14,9 +14,19 @@ parking_lot = "0.7" primal = "0.2.3" [dev-dependencies] -tempdir = "0.3" criterion = "0.2" +rustc-hex = "1.0" +serde_json = "1.0" +tempdir = "0.3" + +[features] +default = [] +bench = [] [[bench]] name = "basic" harness = false + +[[bench]] +name = "progpow" +harness = false diff --git a/ethash/benches/basic.rs b/ethash/benches/basic.rs index dcfc266b39..5bc10e948e 100644 --- a/ethash/benches/basic.rs +++ b/ethash/benches/basic.rs @@ -40,28 +40,28 @@ criterion_main!(basic); fn bench_light_compute_memmap(b: &mut Criterion) { use std::env; - let builder = NodeCacheBuilder::new(OptimizeFor::Memory); + let builder = NodeCacheBuilder::new(OptimizeFor::Memory, u64::max_value()); let light = builder.light(&env::temp_dir(), 486382); - b.bench_function("bench_light_compute_memmap", move |b| b.iter(|| light.compute(&HASH, NONCE))); + b.bench_function("bench_light_compute_memmap", move |b| b.iter(|| light.compute(&HASH, NONCE, u64::max_value()))); } fn bench_light_compute_memory(b: &mut Criterion) { use std::env; - let builder = NodeCacheBuilder::new(OptimizeFor::Cpu); + let builder = NodeCacheBuilder::new(OptimizeFor::Cpu, u64::max_value()); let light = builder.light(&env::temp_dir(), 486382); - b.bench_function("bench_light_compute_memmap", move |b| b.iter(|| light.compute(&HASH, NONCE))); + b.bench_function("bench_light_compute_memmap", move |b| b.iter(|| light.compute(&HASH, NONCE, u64::max_value()))); } fn bench_light_new_round_trip_memmap(b: &mut Criterion) { use std::env; b.bench_function("bench_light_compute_memmap", move |b| b.iter(|| { - let builder = NodeCacheBuilder::new(OptimizeFor::Memory); + let builder = NodeCacheBuilder::new(OptimizeFor::Memory, u64::max_value()); let light = builder.light(&env::temp_dir(), 486382); - light.compute(&HASH, NONCE); + light.compute(&HASH, NONCE, u64::max_value()); })); } @@ -69,9 +69,9 @@ fn bench_light_new_round_trip_memory(b: &mut Criterion) { use std::env; b.bench_function("bench_light_compute_memmap", move |b| b.iter(|| { - let builder = NodeCacheBuilder::new(OptimizeFor::Cpu); + let builder = NodeCacheBuilder::new(OptimizeFor::Cpu, u64::max_value()); let light = builder.light(&env::temp_dir(), 486382); - light.compute(&HASH, NONCE); + light.compute(&HASH, NONCE, u64::max_value()); })); } @@ -81,15 +81,15 @@ fn bench_light_from_file_round_trip_memory(b: &mut Criterion) { let dir = env::temp_dir(); let height = 486382; { - let builder = NodeCacheBuilder::new(OptimizeFor::Cpu); + let builder = NodeCacheBuilder::new(OptimizeFor::Cpu, u64::max_value()); let mut dummy = builder.light(&dir, height); dummy.to_file().unwrap(); } b.bench_function("bench_light_compute_memmap", move |b| b.iter(|| { - let builder = NodeCacheBuilder::new(OptimizeFor::Cpu); + let builder = NodeCacheBuilder::new(OptimizeFor::Cpu, u64::max_value()); let light = builder.light_from_file(&dir, 486382).unwrap(); - light.compute(&HASH, NONCE); + light.compute(&HASH, NONCE, u64::max_value()); })); } @@ -100,14 +100,14 @@ fn bench_light_from_file_round_trip_memmap(b: &mut Criterion) { let height = 486382; { - let builder = NodeCacheBuilder::new(OptimizeFor::Memory); + let builder = NodeCacheBuilder::new(OptimizeFor::Memory, u64::max_value()); let mut dummy = builder.light(&dir, height); dummy.to_file().unwrap(); } b.bench_function("bench_light_compute_memmap", move |b| b.iter(|| { - let builder = NodeCacheBuilder::new(OptimizeFor::Memory); + let builder = NodeCacheBuilder::new(OptimizeFor::Memory, u64::max_value()); let light = builder.light_from_file(&dir, 486382).unwrap(); - light.compute(&HASH, NONCE); + light.compute(&HASH, NONCE, u64::max_value()); })); } diff --git a/ethash/benches/progpow.rs b/ethash/benches/progpow.rs new file mode 100644 index 0000000000..e086a14b42 --- /dev/null +++ b/ethash/benches/progpow.rs @@ -0,0 +1,86 @@ +#[macro_use] +extern crate criterion; +extern crate ethash; +extern crate rustc_hex; +extern crate tempdir; + +use criterion::Criterion; +use ethash::progpow; + +use tempdir::TempDir; +use rustc_hex::FromHex; +use ethash::{NodeCacheBuilder, OptimizeFor}; +use ethash::compute::light_compute; + +fn bench_hashimoto_light(c: &mut Criterion) { + let builder = NodeCacheBuilder::new(OptimizeFor::Memory, u64::max_value()); + let tempdir = TempDir::new("").unwrap(); + let light = builder.light(&tempdir.path(), 1); + let h = FromHex::from_hex("c9149cc0386e689d789a1c2f3d5d169a61a6218ed30e74414dc736e442ef3d1f").unwrap(); + let mut hash = [0; 32]; + hash.copy_from_slice(&h); + + c.bench_function("hashimoto_light", move |b| { + b.iter(|| light_compute(&light, &hash, 0)) + }); +} + +fn bench_progpow_light(c: &mut Criterion) { + let builder = NodeCacheBuilder::new(OptimizeFor::Memory, u64::max_value()); + let tempdir = TempDir::new("").unwrap(); + let cache = builder.new_cache(tempdir.into_path(), 0); + + let h = FromHex::from_hex("c9149cc0386e689d789a1c2f3d5d169a61a6218ed30e74414dc736e442ef3d1f").unwrap(); + let mut hash = [0; 32]; + hash.copy_from_slice(&h); + + c.bench_function("progpow_light", move |b| { + b.iter(|| { + let c_dag = progpow::generate_cdag(cache.as_ref()); + progpow::progpow( + hash, + 0, + 0, + cache.as_ref(), + &c_dag, + ); + }) + }); +} + +fn bench_progpow_optimal_light(c: &mut Criterion) { + let builder = NodeCacheBuilder::new(OptimizeFor::Memory, u64::max_value()); + let tempdir = TempDir::new("").unwrap(); + let cache = builder.new_cache(tempdir.into_path(), 0); + let c_dag = progpow::generate_cdag(cache.as_ref()); + + let h = FromHex::from_hex("c9149cc0386e689d789a1c2f3d5d169a61a6218ed30e74414dc736e442ef3d1f").unwrap(); + let mut hash = [0; 32]; + hash.copy_from_slice(&h); + + c.bench_function("progpow_optimal_light", move |b| { + b.iter(|| { + progpow::progpow( + hash, + 0, + 0, + cache.as_ref(), + &c_dag, + ); + }) + }); +} + +fn bench_keccak_f800_long(c: &mut Criterion) { + c.bench_function("keccak_f800_long(0, 0, 0)", |b| { + b.iter(|| progpow::keccak_f800_long([0; 32], 0, [0; 8])) + }); +} + +criterion_group!(benches, + bench_hashimoto_light, + bench_progpow_light, + bench_progpow_optimal_light, + bench_keccak_f800_long, +); +criterion_main!(benches); diff --git a/ethash/res/progpow_testvectors.json b/ethash/res/progpow_testvectors.json new file mode 100644 index 0000000000..2939f7106c --- /dev/null +++ b/ethash/res/progpow_testvectors.json @@ -0,0 +1,86 @@ +[ + [ + 0, + "0000000000000000000000000000000000000000000000000000000000000000", + "0000000000000000", + "faeb1be51075b03a4ff44b335067951ead07a3b078539ace76fd56fc410557a3", + "63155f732f2bf556967f906155b510c917e48e99685ead76ea83f4eca03ab12b" + ], + [ + 49, + "63155f732f2bf556967f906155b510c917e48e99685ead76ea83f4eca03ab12b", + "0000000006ff2c47", + "c789c1180f890ec555ff42042913465481e8e6bc512cb981e1c1108dc3f2227d", + "9e7248f20914913a73d80a70174c331b1d34f260535ac3631d770e656b5dd922" + ], + [ + 50, + "9e7248f20914913a73d80a70174c331b1d34f260535ac3631d770e656b5dd922", + "00000000076e482e", + "c7340542c2a06b3a7dc7222635f7cd402abf8b528ae971ddac6bbe2b0c7cb518", + "de37e1824c86d35d154cf65a88de6d9286aec4f7f10c3fc9f0fa1bcc2687188d" + ], + [ + 99, + "de37e1824c86d35d154cf65a88de6d9286aec4f7f10c3fc9f0fa1bcc2687188d", + "000000003917afab", + "f5e60b2c5bfddd136167a30cbc3c8dbdbd15a512257dee7964e0bc6daa9f8ba7", + "ac7b55e801511b77e11d52e9599206101550144525b5679f2dab19386f23dcce" + ], + [ + 29950, + "ac7b55e801511b77e11d52e9599206101550144525b5679f2dab19386f23dcce", + "005d409dbc23a62a", + "07393d15805eb08ee6fc6cb3ad4ad1010533bd0ff92d6006850246829f18fd6e", + "e43d7e0bdc8a4a3f6e291a5ed790b9fa1a0948a2b9e33c844888690847de19f5" + ], + [ + 29999, + "e43d7e0bdc8a4a3f6e291a5ed790b9fa1a0948a2b9e33c844888690847de19f5", + "005db5fa4c2a3d03", + "7551bddf977491da2f6cfc1679299544b23483e8f8ee0931c4c16a796558a0b8", + "d34519f72c97cae8892c277776259db3320820cb5279a299d0ef1e155e5c6454" + ], + [ + 30000, + "d34519f72c97cae8892c277776259db3320820cb5279a299d0ef1e155e5c6454", + "005db8607994ff30", + "f1c2c7c32266af9635462e6ce1c98ebe4e7e3ecab7a38aaabfbf2e731e0fbff4", + "8b6ce5da0b06d18db7bd8492d9e5717f8b53e7e098d9fef7886d58a6e913ef64" + ], + [ + 30049, + "8b6ce5da0b06d18db7bd8492d9e5717f8b53e7e098d9fef7886d58a6e913ef64", + "005e2e215a8ca2e7", + "57fe6a9fbf920b4e91deeb66cb0efa971e08229d1a160330e08da54af0689add", + "c2c46173481b9ced61123d2e293b42ede5a1b323210eb2a684df0874ffe09047" + ], + [ + 30050, + "c2c46173481b9ced61123d2e293b42ede5a1b323210eb2a684df0874ffe09047", + "005e30899481055e", + "ba30c61cc5a2c74a5ecaf505965140a08f24a296d687e78720f0b48baf712f2d", + "ea42197eb2ba79c63cb5e655b8b1f612c5f08aae1a49ff236795a3516d87bc71" + ], + [ + 30099, + "ea42197eb2ba79c63cb5e655b8b1f612c5f08aae1a49ff236795a3516d87bc71", + "005ea6aef136f88b", + "cfd5e46048cd133d40f261fe8704e51d3f497fc14203ac6a9ef6a0841780b1cd", + "49e15ba4bf501ce8fe8876101c808e24c69a859be15de554bf85dbc095491bd6" + ], + [ + 59950, + "49e15ba4bf501ce8fe8876101c808e24c69a859be15de554bf85dbc095491bd6", + "02ebe0503bd7b1da", + "21511fbaa31fb9f5fc4998a754e97b3083a866f4de86fa7500a633346f56d773", + "f5c50ba5c0d6210ddb16250ec3efda178de857b2b1703d8d5403bd0f848e19cf" + ], + [ + 59999, + "f5c50ba5c0d6210ddb16250ec3efda178de857b2b1703d8d5403bd0f848e19cf", + "02edb6275bd221e3", + "653eda37d337e39d311d22be9bbd3458d3abee4e643bee4a7280a6d08106ef98", + "341562d10d4afb706ec2c8d5537cb0c810de02b4ebb0a0eea5ae335af6fb2e88" + ] +] diff --git a/ethash/src/cache.rs b/ethash/src/cache.rs index 57dbd8cdab..b16d273145 100644 --- a/ethash/src/cache.rs +++ b/ethash/src/cache.rs @@ -69,6 +69,7 @@ pub struct NodeCacheBuilder { // TODO: Remove this locking and just use an `Rc`? seedhash: Arc>, optimize_for: OptimizeFor, + progpow_transition: u64, } // TODO: Abstract the "optimize for" logic @@ -82,17 +83,18 @@ pub struct NodeCache { impl NodeCacheBuilder { pub fn light(&self, cache_dir: &Path, block_number: u64) -> Light { - Light::new_with_builder(self, cache_dir, block_number) + Light::new_with_builder(self, cache_dir, block_number, self.progpow_transition) } pub fn light_from_file(&self, cache_dir: &Path, block_number: u64) -> io::Result { - Light::from_file_with_builder(self, cache_dir, block_number) + Light::from_file_with_builder(self, cache_dir, block_number, self.progpow_transition) } - pub fn new>>(optimize_for: T) -> Self { + pub fn new>>(optimize_for: T, progpow_transition: u64) -> Self { NodeCacheBuilder { seedhash: Arc::new(Mutex::new(SeedHashCompute::default())), optimize_for: optimize_for.into().unwrap_or_default(), + progpow_transition } } diff --git a/ethash/src/compute.rs b/ethash/src/compute.rs index 63762f3a82..36826121db 100644 --- a/ethash/src/compute.rs +++ b/ethash/src/compute.rs @@ -21,6 +21,7 @@ use keccak::{keccak_512, keccak_256, H256}; use cache::{NodeCache, NodeCacheBuilder}; +use progpow::{CDag, generate_cdag, progpow, keccak_f800_short, keccak_f800_long}; use seed_compute::SeedHashCompute; use shared::*; use std::io; @@ -30,7 +31,7 @@ use std::path::Path; const MIX_WORDS: usize = ETHASH_MIX_BYTES / 4; const MIX_NODES: usize = MIX_WORDS / NODE_WORDS; -const FNV_PRIME: u32 = 0x01000193; +pub const FNV_PRIME: u32 = 0x01000193; /// Computation result pub struct ProofOfWork { @@ -40,9 +41,15 @@ pub struct ProofOfWork { pub mix_hash: H256, } +enum Algorithm { + Hashimoto, + Progpow(Box), +} + pub struct Light { block_number: u64, cache: NodeCache, + algorithm: Algorithm, } /// Light cache structure @@ -51,32 +58,55 @@ impl Light { builder: &NodeCacheBuilder, cache_dir: &Path, block_number: u64, + progpow_transition: u64, ) -> Self { let cache = builder.new_cache(cache_dir.to_path_buf(), block_number); - Light { - block_number: block_number, - cache: cache, - } + let algorithm = if block_number >= progpow_transition { + Algorithm::Progpow(Box::new(generate_cdag(cache.as_ref()))) + } else { + Algorithm::Hashimoto + }; + + Light { block_number, cache, algorithm } } /// Calculate the light boundary data /// `header_hash` - The header hash to pack into the mix /// `nonce` - The nonce to pack into the mix - pub fn compute(&self, header_hash: &H256, nonce: u64) -> ProofOfWork { - light_compute(self, header_hash, nonce) + pub fn compute(&self, header_hash: &H256, nonce: u64, block_number: u64) -> ProofOfWork { + match self.algorithm { + Algorithm::Progpow(ref c_dag) => { + let (value, mix_hash) = progpow( + *header_hash, + nonce, + block_number, + self.cache.as_ref(), + c_dag, + ); + + ProofOfWork { value, mix_hash } + }, + Algorithm::Hashimoto => light_compute(self, header_hash, nonce), + } + } pub fn from_file_with_builder( builder: &NodeCacheBuilder, cache_dir: &Path, block_number: u64, + progpow_transition: u64, ) -> io::Result { let cache = builder.from_file(cache_dir.to_path_buf(), block_number)?; - Ok(Light { - block_number: block_number, - cache: cache, - }) + + let algorithm = if block_number >= progpow_transition { + Algorithm::Progpow(Box::new(generate_cdag(cache.as_ref()))) + } else { + Algorithm::Hashimoto + }; + + Ok(Light { block_number, cache, algorithm }) } pub fn to_file(&mut self) -> io::Result<&Path> { @@ -99,27 +129,32 @@ fn fnv_hash(x: u32, y: u32) -> u32 { /// `nonce` The block's nonce /// `mix_hash` The mix digest hash /// Boundary recovered from mix hash -pub fn quick_get_difficulty(header_hash: &H256, nonce: u64, mix_hash: &H256) -> H256 { +pub fn quick_get_difficulty(header_hash: &H256, nonce: u64, mix_hash: &H256, progpow: bool) -> H256 { unsafe { - // This is safe - the `keccak_512` call below reads the first 40 bytes (which we explicitly set - // with two `copy_nonoverlapping` calls) but writes the first 64, and then we explicitly write - // the next 32 bytes before we read the whole thing with `keccak_256`. - // - // This cannot be elided by the compiler as it doesn't know the implementation of - // `keccak_512`. - let mut buf: [u8; 64 + 32] = mem::uninitialized(); - - ptr::copy_nonoverlapping(header_hash.as_ptr(), buf.as_mut_ptr(), 32); - ptr::copy_nonoverlapping(&nonce as *const u64 as *const u8, buf[32..].as_mut_ptr(), 8); - - keccak_512::unchecked(buf.as_mut_ptr(), 64, buf.as_ptr(), 40); - ptr::copy_nonoverlapping(mix_hash.as_ptr(), buf[64..].as_mut_ptr(), 32); - - // This is initialized in `keccak_256` - let mut hash: [u8; 32] = mem::uninitialized(); - keccak_256::unchecked(hash.as_mut_ptr(), hash.len(), buf.as_ptr(), buf.len()); - - hash + if progpow { + let seed = keccak_f800_short(*header_hash, nonce, [0u32; 8]); + keccak_f800_long(*header_hash, seed, mem::transmute(*mix_hash)) + } else { + // This is safe - the `keccak_512` call below reads the first 40 bytes (which we explicitly set + // with two `copy_nonoverlapping` calls) but writes the first 64, and then we explicitly write + // the next 32 bytes before we read the whole thing with `keccak_256`. + // + // This cannot be elided by the compiler as it doesn't know the implementation of + // `keccak_512`. + let mut buf: [u8; 64 + 32] = mem::uninitialized(); + + ptr::copy_nonoverlapping(header_hash.as_ptr(), buf.as_mut_ptr(), 32); + ptr::copy_nonoverlapping(&nonce as *const u64 as *const u8, buf[32..].as_mut_ptr(), 8); + + keccak_512::unchecked(buf.as_mut_ptr(), 64, buf.as_ptr(), 40); + ptr::copy_nonoverlapping(mix_hash.as_ptr(), buf[64..].as_mut_ptr(), 32); + + // This is initialized in `keccak_256` + let mut hash: [u8; 32] = mem::uninitialized(); + keccak_256::unchecked(hash.as_mut_ptr(), hash.len(), buf.as_ptr(), buf.len()); + + hash + } } } @@ -272,7 +307,7 @@ fn hash_compute(light: &Light, full_size: usize, header_hash: &H256, nonce: u64) // We overwrite the second half since `keccak_256` has an internal buffer and so allows // overlapping arrays as input. let write_ptr: *mut u8 = &mut buf.compress_bytes as *mut [u8; 32] as *mut u8; - unsafe { + unsafe { keccak_256::unchecked( write_ptr, buf.compress_bytes.len(), @@ -287,7 +322,7 @@ fn hash_compute(light: &Light, full_size: usize, header_hash: &H256, nonce: u64) } // TODO: Use the `simd` crate -fn calculate_dag_item(node_index: u32, cache: &[Node]) -> Node { +pub fn calculate_dag_item(node_index: u32, cache: &[Node]) -> Node { let num_parent_nodes = cache.len(); let mut ret = cache[node_index as usize % num_parent_nodes].clone(); ret.as_words_mut()[0] ^= node_index; @@ -361,13 +396,13 @@ mod test { 0x4a, 0x8e, 0x95, 0x69, 0xef, 0xc7, 0xd7, 0x1b, 0x33, 0x35, 0xdf, 0x36, 0x8c, 0x9a, 0xe9, 0x7e, 0x53, 0x84, ]; - assert_eq!(quick_get_difficulty(&hash, nonce, &mix_hash)[..], boundary_good[..]); + assert_eq!(quick_get_difficulty(&hash, nonce, &mix_hash, false)[..], boundary_good[..]); let boundary_bad = [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x3a, 0x9b, 0x6c, 0x69, 0xbc, 0x2c, 0xe2, 0xa2, 0x4a, 0x8e, 0x95, 0x69, 0xef, 0xc7, 0xd7, 0x1b, 0x33, 0x35, 0xdf, 0x36, 0x8c, 0x9a, 0xe9, 0x7e, 0x53, 0x84, ]; - assert!(quick_get_difficulty(&hash, nonce, &mix_hash)[..] != boundary_bad[..]); + assert!(quick_get_difficulty(&hash, nonce, &mix_hash, false)[..] != boundary_bad[..]); } #[test] @@ -391,7 +426,7 @@ mod test { let tempdir = TempDir::new("").unwrap(); // difficulty = 0x085657254bd9u64; - let light = NodeCacheBuilder::new(None).light(tempdir.path(), 486382); + let light = NodeCacheBuilder::new(None, u64::max_value()).light(tempdir.path(), 486382); let result = light_compute(&light, &hash, nonce); assert_eq!(result.mix_hash[..], mix_hash[..]); assert_eq!(result.value[..], boundary[..]); @@ -400,7 +435,7 @@ mod test { #[test] fn test_drop_old_data() { let tempdir = TempDir::new("").unwrap(); - let builder = NodeCacheBuilder::new(None); + let builder = NodeCacheBuilder::new(None, u64::max_value()); let first = builder.light(tempdir.path(), 0).to_file().unwrap().to_owned(); let second = builder.light(tempdir.path(), ETHASH_EPOCH_LENGTH).to_file().unwrap().to_owned(); diff --git a/ethash/src/lib.rs b/ethash/src/lib.rs index d6cfa04572..e40c08920c 100644 --- a/ethash/src/lib.rs +++ b/ethash/src/lib.rs @@ -25,15 +25,30 @@ extern crate crunchy; #[macro_use] extern crate log; +#[cfg(test)] +extern crate rustc_hex; + +#[cfg(test)] +extern crate serde_json; + #[cfg(test)] extern crate tempdir; +#[cfg(feature = "bench")] +pub mod compute; +#[cfg(not(feature = "bench"))] mod compute; + mod seed_compute; mod cache; mod keccak; mod shared; +#[cfg(feature = "bench")] +pub mod progpow; +#[cfg(not(feature = "bench"))] +mod progpow; + pub use cache::{NodeCacheBuilder, OptimizeFor}; pub use compute::{ProofOfWork, quick_get_difficulty, slow_hash_block_number}; use compute::Light; @@ -59,14 +74,16 @@ pub struct EthashManager { nodecache_builder: NodeCacheBuilder, cache: Mutex, cache_dir: PathBuf, + progpow_transition: u64, } impl EthashManager { /// Create a new new instance of ethash manager - pub fn new>>(cache_dir: &Path, optimize_for: T) -> EthashManager { + pub fn new>>(cache_dir: &Path, optimize_for: T, progpow_transition: u64) -> EthashManager { EthashManager { cache_dir: cache_dir.to_path_buf(), - nodecache_builder: NodeCacheBuilder::new(optimize_for.into().unwrap_or_default()), + nodecache_builder: NodeCacheBuilder::new(optimize_for.into().unwrap_or_default(), progpow_transition), + progpow_transition: progpow_transition, cache: Mutex::new(LightCache { recent_epoch: None, recent: None, @@ -85,27 +102,33 @@ impl EthashManager { let epoch = block_number / ETHASH_EPOCH_LENGTH; let light = { let mut lights = self.cache.lock(); - let light = match lights.recent_epoch.clone() { - Some(ref e) if *e == epoch => lights.recent.clone(), - _ => match lights.prev_epoch.clone() { - Some(e) if e == epoch => { - // don't swap if recent is newer. - if lights.recent_epoch > lights.prev_epoch { - None - } else { - // swap - let t = lights.prev_epoch; - lights.prev_epoch = lights.recent_epoch; - lights.recent_epoch = t; - let t = lights.prev.clone(); - lights.prev = lights.recent.clone(); - lights.recent = t; - lights.recent.clone() + let light = if block_number == self.progpow_transition { + // we need to regenerate the cache to trigger algorithm change to progpow inside `Light` + None + } else { + match lights.recent_epoch.clone() { + Some(ref e) if *e == epoch => lights.recent.clone(), + _ => match lights.prev_epoch.clone() { + Some(e) if e == epoch => { + // don't swap if recent is newer. + if lights.recent_epoch > lights.prev_epoch { + None + } else { + // swap + let t = lights.prev_epoch; + lights.prev_epoch = lights.recent_epoch; + lights.recent_epoch = t; + let t = lights.prev.clone(); + lights.prev = lights.recent.clone(); + lights.recent = t; + lights.recent.clone() + } } - } - _ => None, - }, + _ => None, + }, + } }; + match light { None => { let light = match self.nodecache_builder.light_from_file( @@ -132,7 +155,7 @@ impl EthashManager { Some(light) => light, } }; - light.compute(header_hash, nonce) + light.compute(header_hash, nonce, block_number) } } @@ -164,7 +187,7 @@ fn test_lru() { use tempdir::TempDir; let tempdir = TempDir::new("").unwrap(); - let ethash = EthashManager::new(tempdir.path(), None); + let ethash = EthashManager::new(tempdir.path(), None, u64::max_value()); let hash = [0u8; 32]; ethash.compute_light(1, &hash, 1); ethash.compute_light(50000, &hash, 1); diff --git a/ethash/src/progpow.rs b/ethash/src/progpow.rs new file mode 100644 index 0000000000..038f38c225 --- /dev/null +++ b/ethash/src/progpow.rs @@ -0,0 +1,595 @@ +// Copyright 2015-2019 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 compute::{FNV_PRIME, calculate_dag_item}; +use keccak::H256; +use shared::{ETHASH_ACCESSES, ETHASH_MIX_BYTES, Node, get_data_size}; + +const PROGPOW_CACHE_BYTES: usize = 16 * 1024; +const PROGPOW_CACHE_WORDS: usize = PROGPOW_CACHE_BYTES / 4; +const PROGPOW_CNT_CACHE: usize = 12; +const PROGPOW_CNT_MATH: usize = 20; +const PROGPOW_CNT_DAG: usize = ETHASH_ACCESSES; +const PROGPOW_DAG_LOADS: usize = 4; +const PROGPOW_MIX_BYTES: usize = 2 * ETHASH_MIX_BYTES; +const PROGPOW_PERIOD_LENGTH: usize = 50; // blocks per progpow epoch (N) +const PROGPOW_LANES: usize = 16; +const PROGPOW_REGS: usize = 32; + +const FNV_HASH: u32 = 0x811c9dc5; + +const KECCAKF_RNDC: [u32; 24] = [ + 0x00000001, 0x00008082, 0x0000808a, 0x80008000, 0x0000808b, 0x80000001, + 0x80008081, 0x00008009, 0x0000008a, 0x00000088, 0x80008009, 0x8000000a, + 0x8000808b, 0x0000008b, 0x00008089, 0x00008003, 0x00008002, 0x00000080, + 0x0000800a, 0x8000000a, 0x80008081, 0x00008080, 0x80000001, 0x80008008 +]; + +const KECCAKF_ROTC: [u32; 24] = [ + 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 2, 14, + 27, 41, 56, 8, 25, 43, 62, 18, 39, 61, 20, 44 +]; + +const KECCAKF_PILN: [usize; 24] = [ + 10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4, + 15, 23, 19, 13, 12, 2, 20, 14, 22, 9, 6, 1 +]; + +fn keccak_f800_round(st: &mut [u32; 25], r: usize) { + // Theta + let mut bc = [0u32; 5]; + for i in 0..bc.len() { + bc[i] = st[i] ^ st[i + 5] ^ st[i + 10] ^ st[i + 15] ^ st[i + 20]; + } + + for i in 0..bc.len() { + let t = bc[(i + 4) % 5] ^ bc[(i + 1) % 5].rotate_left(1); + for j in (0..st.len()).step_by(5) { + st[j + i] ^= t; + } + } + + // Rho Pi + let mut t = st[1]; + + debug_assert_eq!(KECCAKF_ROTC.len(), 24); + for i in 0..24 { + let j = KECCAKF_PILN[i]; + bc[0] = st[j]; + st[j] = t.rotate_left(KECCAKF_ROTC[i]); + t = bc[0]; + } + + // Chi + for j in (0..st.len()).step_by(5) { + for i in 0..bc.len() { + bc[i] = st[j + i]; + } + for i in 0..bc.len() { + st[j + i] ^= (!bc[(i + 1) % 5]) & bc[(i + 2) % 5]; + } + } + + // Iota + debug_assert!(r < KECCAKF_RNDC.len()); + st[0] ^= KECCAKF_RNDC[r]; +} + +fn keccak_f800(header_hash: H256, nonce: u64, result: [u32; 8], st: &mut [u32; 25]) { + for i in 0..8 { + st[i] = (header_hash[4 * i] as u32) + + ((header_hash[4 * i + 1] as u32) << 8) + + ((header_hash[4 * i + 2] as u32) << 16) + + ((header_hash[4 * i + 3] as u32) << 24); + } + + st[8] = nonce as u32; + st[9] = (nonce >> 32) as u32; + + for i in 0..8 { + st[10 + i] = result[i]; + } + + for r in 0..22 { + keccak_f800_round(st, r); + } +} + +pub fn keccak_f800_short(header_hash: H256, nonce: u64, result: [u32; 8]) -> u64 { + let mut st = [0u32; 25]; + keccak_f800(header_hash, nonce, result, &mut st); + (st[0].swap_bytes() as u64) << 32 | st[1].swap_bytes() as u64 +} + +pub fn keccak_f800_long(header_hash: H256, nonce: u64, result: [u32; 8]) -> H256 { + let mut st = [0u32; 25]; + keccak_f800(header_hash, nonce, result, &mut st); + + // NOTE: transmute from `[u32; 8]` to `[u8; 32]` + unsafe { + std::mem::transmute( + [st[0], st[1], st[2], st[3], st[4], st[5], st[6], st[7]] + ) + } +} + +#[inline] +fn fnv1a_hash(h: u32, d: u32) -> u32 { + (h ^ d).wrapping_mul(FNV_PRIME) +} + +#[derive(Clone)] +struct Kiss99 { + z: u32, + w: u32, + jsr: u32, + jcong: u32, +} + +impl Kiss99 { + fn new(z: u32, w: u32, jsr: u32, jcong: u32) -> Kiss99 { + Kiss99 { z, w, jsr, jcong } + } + + #[inline] + fn next_u32(&mut self) -> u32 { + self.z = 36969u32.wrapping_mul(self.z & 65535).wrapping_add(self.z >> 16); + self.w = 18000u32.wrapping_mul(self.w & 65535).wrapping_add(self.w >> 16); + let mwc = (self.z << 16).wrapping_add(self.w); + self.jsr ^= self.jsr << 17; + self.jsr ^= self.jsr >> 13; + self.jsr ^= self.jsr << 5; + self.jcong = 69069u32.wrapping_mul(self.jcong).wrapping_add(1234567); + + (mwc ^ self.jcong).wrapping_add(self.jsr) + } +} + +fn fill_mix(seed: u64, lane_id: u32) -> [u32; PROGPOW_REGS] { + // Use FNV to expand the per-warp seed to per-lane + // Use KISS to expand the per-lane seed to fill mix + let z = fnv1a_hash(FNV_HASH, seed as u32); + let w = fnv1a_hash(z, (seed >> 32) as u32); + let jsr = fnv1a_hash(w, lane_id); + let jcong = fnv1a_hash(jsr, lane_id); + + let mut rnd = Kiss99::new(z, w, jsr, jcong); + + let mut mix = [0; PROGPOW_REGS]; + + debug_assert_eq!(PROGPOW_REGS, 32); + for i in 0..32 { + mix[i] = rnd.next_u32(); + } + + mix +} + +// Merge new data from b into the value in a. Assuming A has high entropy only +// do ops that retain entropy even if B is low entropy (IE don't do A&B) +fn merge(a: u32, b: u32, r: u32) -> u32 { + match r % 4 { + 0 => a.wrapping_mul(33).wrapping_add(b), + 1 => (a ^ b).wrapping_mul(33), + 2 => a.rotate_left(((r >> 16) % 31) + 1) ^ b, + _ => a.rotate_right(((r >> 16) % 31) + 1) ^ b, + } +} + +fn math(a: u32, b: u32, r: u32) -> u32 { + match r % 11 { + 0 => a.wrapping_add(b), + 1 => a.wrapping_mul(b), + 2 => ((a as u64).wrapping_mul(b as u64) >> 32) as u32, + 3 => a.min(b), + 4 => a.rotate_left(b), + 5 => a.rotate_right(b), + 6 => a & b, + 7 => a | b, + 8 => a ^ b, + 9 => a.leading_zeros() + b.leading_zeros(), + _ => a.count_ones() + b.count_ones(), + } +} + +fn progpow_init(seed: u64) -> (Kiss99, [u32; PROGPOW_REGS], [u32; PROGPOW_REGS]) { + let z = fnv1a_hash(FNV_HASH, seed as u32); + let w = fnv1a_hash(z, (seed >> 32) as u32); + let jsr = fnv1a_hash(w, seed as u32); + let jcong = fnv1a_hash(jsr, (seed >> 32) as u32); + + let mut rnd = Kiss99::new(z, w, jsr, jcong); + + // Create a random sequence of mix destinations for merge() and mix sources + // for cache reads guarantees every destination merged once and guarantees + // no duplicate cache reads, which could be optimized away. Uses + // Fisher-Yates shuffle. + let mut mix_seq_dst = [0u32; PROGPOW_REGS]; + let mut mix_seq_cache = [0u32; PROGPOW_REGS]; + for i in 0..mix_seq_dst.len() { + mix_seq_dst[i] = i as u32; + mix_seq_cache[i] = i as u32; + } + + for i in (1..mix_seq_dst.len()).rev() { + let j = rnd.next_u32() as usize % (i + 1); + mix_seq_dst.swap(i, j); + + let j = rnd.next_u32() as usize % (i + 1); + mix_seq_cache.swap(i, j); + } + + (rnd, mix_seq_dst, mix_seq_cache) +} + +pub type CDag = [u32; PROGPOW_CACHE_WORDS]; + +fn progpow_loop( + seed: u64, + loop_: usize, + mix: &mut [[u32; PROGPOW_REGS]; PROGPOW_LANES], + cache: &[Node], + c_dag: &CDag, + data_size: usize, +) { + // All lanes share a base address for the global load. Global offset uses + // mix[0] to guarantee it depends on the load result. + let g_offset = mix[loop_ % PROGPOW_LANES][0] as usize % + (64 * data_size / (PROGPOW_LANES * PROGPOW_DAG_LOADS)); + + // 256 bytes of dag data + let mut dag_item = [0u32; 64]; + + // Fetch DAG nodes (64 bytes each) + for l in 0..PROGPOW_DAG_LOADS { + let index = g_offset * PROGPOW_LANES * PROGPOW_DAG_LOADS + l * 16; + let node = calculate_dag_item(index as u32 / 16, cache); + dag_item[l * 16..(l + 1) * 16].clone_from_slice(node.as_words()); + } + + let (rnd, mix_seq_dst, mix_seq_cache) = progpow_init(seed); + + // Lanes can execute in parallel and will be convergent + for l in 0..mix.len() { + let mut rnd = rnd.clone(); + + // Initialize the seed and mix destination sequence + let mut mix_seq_dst_cnt = 0; + let mut mix_seq_cache_cnt = 0; + + let mut mix_dst = || { + let res = mix_seq_dst[mix_seq_dst_cnt % PROGPOW_REGS] as usize; + mix_seq_dst_cnt += 1; + res + }; + let mut mix_cache = || { + let res = mix_seq_cache[mix_seq_cache_cnt % PROGPOW_REGS] as usize; + mix_seq_cache_cnt += 1; + res + }; + + for i in 0..PROGPOW_CNT_CACHE.max(PROGPOW_CNT_MATH) { + if i < PROGPOW_CNT_CACHE { + // Cached memory access, lanes access random 32-bit locations + // within the first portion of the DAG + let offset = mix[l][mix_cache()] as usize % PROGPOW_CACHE_WORDS; + let data = c_dag[offset]; + let dst = mix_dst(); + + mix[l][dst] = merge(mix[l][dst], data, rnd.next_u32()); + } + + if i < PROGPOW_CNT_MATH { + // Random math + // Generate 2 unique sources + let src_rnd = rnd.next_u32() % (PROGPOW_REGS * (PROGPOW_REGS - 1)) as u32; + let src1 = src_rnd % PROGPOW_REGS as u32; // 0 <= src1 < PROGPOW_REGS + let mut src2 = src_rnd / PROGPOW_REGS as u32; // 0 <= src2 < PROGPOW_REGS - 1 + if src2 >= src1 { + src2 += 1; // src2 is now any reg other than src1 + } + + let data = math(mix[l][src1 as usize], mix[l][src2 as usize], rnd.next_u32()); + let dst = mix_dst(); + + mix[l][dst] = merge(mix[l][dst], data, rnd.next_u32()); + } + } + + // Global load to sequential locations + let mut data_g = [0u32; PROGPOW_DAG_LOADS]; + let index = ((l ^ loop_) % PROGPOW_LANES) * PROGPOW_DAG_LOADS; + for i in 0..PROGPOW_DAG_LOADS { + data_g[i] = dag_item[index + i]; + } + + // Consume the global load data at the very end of the loop to allow + // full latency hiding. Always merge into `mix[0]` to feed the offset + // calculation. + mix[l][0] = merge(mix[l][0], data_g[0], rnd.next_u32()); + for i in 1..PROGPOW_DAG_LOADS { + let dst = mix_dst(); + mix[l][dst] = merge(mix[l][dst], data_g[i], rnd.next_u32()); + } + } +} + +pub fn progpow( + header_hash: H256, + nonce: u64, + block_number: u64, + cache: &[Node], + c_dag: &CDag, +) -> (H256, H256) { + let mut mix = [[0u32; PROGPOW_REGS]; PROGPOW_LANES]; + let mut lane_results = [0u32; PROGPOW_LANES]; + let mut result = [0u32; 8]; + + let data_size = get_data_size(block_number) / PROGPOW_MIX_BYTES; + + // NOTE: This assert is required to aid the optimizer elide the non-zero + // remainder check in `progpow_loop`. + assert!(data_size > 0); + + // Initialize mix for all lanes + let seed = keccak_f800_short(header_hash, nonce, result); + + for l in 0..mix.len() { + mix[l] = fill_mix(seed, l as u32); + } + + // Execute the randomly generated inner loop + let period = block_number / PROGPOW_PERIOD_LENGTH as u64; + for i in 0..PROGPOW_CNT_DAG { + progpow_loop( + period, + i, + &mut mix, + cache, + c_dag, + data_size, + ); + } + + // Reduce mix data to a single per-lane result + for l in 0..lane_results.len() { + lane_results[l] = FNV_HASH; + for i in 0..PROGPOW_REGS { + lane_results[l] = fnv1a_hash(lane_results[l], mix[l][i]); + } + } + + // Reduce all lanes to a single 128-bit result + result = [FNV_HASH; 8]; + for l in 0..PROGPOW_LANES { + result[l % 8] = fnv1a_hash(result[l % 8], lane_results[l]); + } + + let digest = keccak_f800_long(header_hash, seed, result); + + // NOTE: transmute from `[u32; 8]` to `[u8; 32]` + let result = unsafe { ::std::mem::transmute(result) }; + + (digest, result) +} + +pub fn generate_cdag(cache: &[Node]) -> CDag { + let mut c_dag = [0u32; PROGPOW_CACHE_WORDS]; + + for i in 0..PROGPOW_CACHE_WORDS / 16 { + let node = calculate_dag_item(i as u32, cache); + for j in 0..16 { + c_dag[i * 16 + j] = node.as_words()[j]; + } + } + + c_dag +} + +#[cfg(test)] +mod test { + use tempdir::TempDir; + + use cache::{NodeCacheBuilder, OptimizeFor}; + use keccak::H256; + use rustc_hex::FromHex; + use serde_json::{self, Value}; + use std::collections::VecDeque; + use super::*; + + fn h256(hex: &str) -> H256 { + let bytes = FromHex::from_hex(hex).unwrap(); + let mut res = [0; 32]; + res.copy_from_slice(&bytes); + res + } + + #[test] + fn test_cdag() { + let builder = NodeCacheBuilder::new(OptimizeFor::Memory, u64::max_value()); + let tempdir = TempDir::new("").unwrap(); + let cache = builder.new_cache(tempdir.into_path(), 0); + + let c_dag = generate_cdag(cache.as_ref()); + + let expected = vec![ + 690150178u32, 1181503948, 2248155602, 2118233073, 2193871115, + 1791778428, 1067701239, 724807309, 530799275, 3480325829, 3899029234, + 1998124059, 2541974622, 1100859971, 1297211151, 3268320000, 2217813733, + 2690422980, 3172863319, 2651064309 + ]; + + assert_eq!( + c_dag.iter().take(20).cloned().collect::>(), + expected, + ); + } + + #[test] + fn test_random_merge() { + let tests = [ + (1000000u32, 101u32, 33000101u32), + (2000000, 102, 66003366), + (3000000, 103, 6000103), + (4000000, 104, 2000104), + (1000000, 0, 33000000), + (2000000, 0, 66000000), + (3000000, 0, 6000000), + (4000000, 0, 2000000), + ]; + + for (i, &(a, b, expected)) in tests.iter().enumerate() { + assert_eq!( + merge(a, b, i as u32), + expected, + ); + } + } + + #[test] + fn test_random_math() { + let tests = [ + (20u32, 22u32, 42u32), + (70000, 80000, 1305032704), + (70000, 80000, 1), + (1, 2, 1), + (3, 10000, 196608), + (3, 0, 3), + (3, 6, 2), + (3, 6, 7), + (3, 6, 5), + (0, 0xffffffff, 32), + (3 << 13, 1 << 5, 3), + (22, 20, 42), + (80000, 70000, 1305032704), + (80000, 70000, 1), + (2, 1, 1), + (10000, 3, 80000), + (0, 3, 0), + (6, 3, 2), + (6, 3, 7), + (6, 3, 5), + (0, 0xffffffff, 32), + (3 << 13, 1 << 5, 3), + ]; + + for (i, &(a, b, expected)) in tests.iter().enumerate() { + assert_eq!( + math(a, b, i as u32), + expected, + ); + } + } + + #[test] + fn test_keccak_256() { + let expected = "5dd431e5fbc604f499bfa0232f45f8f142d0ff5178f539e5a7800bf0643697af"; + assert_eq!( + keccak_f800_long([0; 32], 0, [0; 8]), + h256(expected), + ); + } + + #[test] + fn test_keccak_64() { + let expected: u64 = 0x5dd431e5fbc604f4; + assert_eq!( + keccak_f800_short([0; 32], 0, [0; 8]), + expected, + ); + } + + #[test] + fn test_progpow_hash() { + let builder = NodeCacheBuilder::new(OptimizeFor::Memory, u64::max_value()); + let tempdir = TempDir::new("").unwrap(); + let cache = builder.new_cache(tempdir.into_path(), 0); + let c_dag = generate_cdag(cache.as_ref()); + + let header_hash = [0; 32]; + + let (digest, result) = progpow( + header_hash, + 0, + 0, + cache.as_ref(), + &c_dag, + ); + + let expected_digest = FromHex::from_hex("63155f732f2bf556967f906155b510c917e48e99685ead76ea83f4eca03ab12b").unwrap(); + let expected_result = FromHex::from_hex("faeb1be51075b03a4ff44b335067951ead07a3b078539ace76fd56fc410557a3").unwrap(); + + assert_eq!( + digest.to_vec(), + expected_digest, + ); + + assert_eq!( + result.to_vec(), + expected_result, + ); + } + + #[test] + fn test_progpow_testvectors() { + struct ProgpowTest { + block_number: u64, + header_hash: H256, + nonce: u64, + mix_hash: H256, + final_hash: H256, + } + + let tests: Vec> = + serde_json::from_slice(include_bytes!("../res/progpow_testvectors.json")).unwrap(); + + let tests: Vec = tests.into_iter().map(|mut test: VecDeque| { + assert!(test.len() == 5); + + let block_number: u64 = serde_json::from_value(test.pop_front().unwrap()).unwrap(); + let header_hash: String = serde_json::from_value(test.pop_front().unwrap()).unwrap(); + let nonce: String = serde_json::from_value(test.pop_front().unwrap()).unwrap(); + let mix_hash: String = serde_json::from_value(test.pop_front().unwrap()).unwrap(); + let final_hash: String = serde_json::from_value(test.pop_front().unwrap()).unwrap(); + + ProgpowTest { + block_number, + header_hash: h256(&header_hash), + nonce: u64::from_str_radix(&nonce, 16).unwrap(), + mix_hash: h256(&mix_hash), + final_hash: h256(&final_hash), + } + }).collect(); + + for test in tests { + let builder = NodeCacheBuilder::new(OptimizeFor::Memory, u64::max_value()); + let tempdir = TempDir::new("").unwrap(); + let cache = builder.new_cache(tempdir.path().to_owned(), test.block_number); + let c_dag = generate_cdag(cache.as_ref()); + + let (digest, result) = progpow( + test.header_hash, + test.nonce, + test.block_number, + cache.as_ref(), + &c_dag, + ); + + assert_eq!(digest, test.final_hash); + assert_eq!(result, test.mix_hash); + } + } +} diff --git a/ethcore/Cargo.toml b/ethcore/Cargo.toml index b617498443..cf0fc95200 100644 --- a/ethcore/Cargo.toml +++ b/ethcore/Cargo.toml @@ -107,7 +107,7 @@ slow-blocks = [] # Run JSON consensus tests. json-tests = ["env_logger", "test-helpers", "to-pod-full"] # Skip JSON consensus tests with pending issues. -ci-skip-issue = [] +ci-skip-tests = [] # Run memory/cpu heavy tests. test-heavy = [] # Compile test helpers diff --git a/ethcore/src/ethereum/ethash.rs b/ethcore/src/ethereum/ethash.rs index 5c4365cb24..293009fdec 100644 --- a/ethcore/src/ethereum/ethash.rs +++ b/ethcore/src/ethereum/ethash.rs @@ -113,6 +113,8 @@ pub struct EthashParams { pub block_reward_contract: Option, /// Difficulty bomb delays. pub difficulty_bomb_delays: BTreeMap, + /// Block to transition to progpow + pub progpow_transition: u64, } impl From for EthashParams { @@ -153,6 +155,7 @@ impl From for EthashParams { }), expip2_transition: p.expip2_transition.map_or(u64::max_value(), Into::into), expip2_duration_limit: p.expip2_duration_limit.map_or(30, Into::into), + progpow_transition: p.progpow_transition.map_or(u64::max_value(), Into::into), block_reward_contract_transition: p.block_reward_contract_transition.map_or(0, Into::into), block_reward_contract: match (p.block_reward_contract_code, p.block_reward_contract_address) { (Some(code), _) => Some(BlockRewardContract::new_from_code(Arc::new(code.into()))), @@ -182,10 +185,12 @@ impl Ethash { machine: EthereumMachine, optimize_for: T, ) -> Arc { + let progpow_transition = ethash_params.progpow_transition; + Arc::new(Ethash { ethash_params, machine, - pow: EthashManager::new(cache_dir.as_ref(), optimize_for.into()), + pow: EthashManager::new(cache_dir.as_ref(), optimize_for.into(), progpow_transition), }) } } @@ -320,7 +325,8 @@ impl Engine for Arc { let difficulty = ethash::boundary_to_difficulty(&H256(quick_get_difficulty( &header.bare_hash().0, seal.nonce.low_u64(), - &seal.mix_hash.0 + &seal.mix_hash.0, + header.number() >= self.ethash_params.progpow_transition ))); if &difficulty < header.difficulty() { @@ -523,6 +529,7 @@ mod tests { block_reward_contract: None, block_reward_contract_transition: 0, difficulty_bomb_delays: BTreeMap::new(), + progpow_transition: u64::max_value(), } } diff --git a/ethcore/src/json_tests/skip.rs b/ethcore/src/json_tests/skip.rs index 06538bc2aa..b6ef9795f6 100644 --- a/ethcore/src/json_tests/skip.rs +++ b/ethcore/src/json_tests/skip.rs @@ -18,10 +18,7 @@ use ethjson; -#[cfg(all(not(test), feature = "ci-skip-tests"))] -compile_error!("ci-skip-tests can only be enabled for testing builds."); - -#[cfg(feature="ci-skip-issue")] +#[cfg(feature="ci-skip-tests")] lazy_static!{ pub static ref SKIP_TEST_STATE: ethjson::test::SkipStates = { let skip_data = include_bytes!("../../res/ethereum/tests-issues/currents.json"); @@ -29,7 +26,7 @@ lazy_static!{ }; } -#[cfg(not(feature="ci-skip-issue"))] +#[cfg(not(feature="ci-skip-tests"))] lazy_static!{ pub static ref SKIP_TEST_STATE: ethjson::test::SkipStates = { ethjson::test::SkipStates::empty() diff --git a/json/src/spec/ethash.rs b/json/src/spec/ethash.rs index 6f9dd77068..6051ac90d8 100644 --- a/json/src/spec/ethash.rs +++ b/json/src/spec/ethash.rs @@ -95,6 +95,9 @@ pub struct EthashParams { pub expip2_transition: Option, /// EXPIP-2 duration limit pub expip2_duration_limit: Option, + /// Block to transition to progpow + #[serde(rename="progpowTransition")] + pub progpow_transition: Option, } /// Ethash engine deserialization. @@ -200,6 +203,7 @@ mod tests { ecip1017_era_rounds: None, expip2_transition: None, expip2_duration_limit: None, + progpow_transition: None, difficulty_bomb_delays: None, } }); @@ -239,6 +243,7 @@ mod tests { ecip1017_era_rounds: None, expip2_transition: None, expip2_duration_limit: None, + progpow_transition: None, difficulty_bomb_delays: None, } }); diff --git a/test.sh b/test.sh index a25f41d9a9..e7d8e2a789 100755 --- a/test.sh +++ b/test.sh @@ -2,7 +2,7 @@ # Running Parity Full Test Suite echo "________Running test.sh________" -FEATURES="json-tests,ci-skip-issue" +FEATURES="json-tests,ci-skip-tests" OPTIONS="--release" VALIDATE=1 THREADS=8 From b803f57db6dedadd4949c2fb5cc1bc35a0ff1e27 Mon Sep 17 00:00:00 2001 From: felix <32549900+fevo1971@users.noreply.github.com> Date: Wed, 20 Feb 2019 10:06:26 +0100 Subject: [PATCH 082/168] exchanged old(azure) bootnodes with new(ovh) ones (#10309) * exchanged old(azure) bootnodes with new(ovh) ones * Fix indent --- ethcore/res/ethereum/kovan.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ethcore/res/ethereum/kovan.json b/ethcore/res/ethereum/kovan.json index a2332c6466..fc12ba608d 100644 --- a/ethcore/res/ethereum/kovan.json +++ b/ethcore/res/ethereum/kovan.json @@ -5015,8 +5015,8 @@ "nodes": [ "enode://56abaf065581a5985b8c5f4f88bd202526482761ba10be9bfdcd14846dd01f652ec33fde0f8c0fd1db19b59a4c04465681fcef50e11380ca88d25996191c52de@40.71.221.215:30303", "enode://d07827483dc47b368eaf88454fb04b41b7452cf454e194e2bd4c14f98a3278fed5d819dbecd0d010407fc7688d941ee1e58d4f9c6354d3da3be92f55c17d7ce3@52.166.117.77:30303", - "enode://8fa162563a8e5a05eef3e1cd5abc5828c71344f7277bb788a395cce4a0e30baf2b34b92fe0b2dbbba2313ee40236bae2aab3c9811941b9f5a7e8e90aaa27ecba@52.165.239.18:30303", - "enode://7e2e7f00784f516939f94e22bdc6cf96153603ca2b5df1c7cc0f90a38e7a2f218ffb1c05b156835e8b49086d11fdd1b3e2965be16baa55204167aa9bf536a4d9@52.243.47.56:30303", - "enode://0518a3d35d4a7b3e8c433e7ffd2355d84a1304ceb5ef349787b556197f0c87fad09daed760635b97d52179d645d3e6d16a37d2cc0a9945c2ddf585684beb39ac@40.68.248.100:30303" + "enode://38e6e7fd416293ed120d567a2675fe078c0205ab0671abf16982ce969823bd1f3443d590c18b321dfae7dcbe1f6ba98ef8702f255c3c9822a188abb82c53adca@51.77.66.187:30303", + "enode://6f289111f7c77c68651b0f4803c3a47bcec801f9c618bb41231a1a24a6dbb9c76f2fdb63ba7a21357c41ebb7f6922c17397c1b5c8f71f7d3ef7965505d4945de@144.217.72.209:30303", + "enode://b6340eb94c3db1362ee517801389fe21cce6354275376b1006f8ce84f8a5cfa2b836268b3727be9db7cd3e581f356f39da39418c4ec1d63d959abc235d99cd86@145.239.7.213:30303" ] } From b58a3ed0ad746b6e7d92e119f75058cdf895c897 Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Wed, 20 Feb 2019 10:52:28 +0100 Subject: [PATCH 083/168] fix(trace_main! macro): don't re-export (#10384) --- parity/main.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/parity/main.rs b/parity/main.rs index a2bf112070..461908b2c8 100644 --- a/parity/main.rs +++ b/parity/main.rs @@ -362,7 +362,6 @@ fn println_trace_main(s: String) { } } -#[macro_export] macro_rules! trace_main { ($arg:expr) => (println_trace_main($arg.into())); ($($arg:tt)*) => (println_trace_main(format!("{}", format_args!($($arg)*)))); From 4e0ec4e66b99933ecafd11c1b83cbbf8de655126 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Wed, 20 Feb 2019 16:49:39 +0000 Subject: [PATCH 084/168] tx pool: always accept local transactions (#10375) * tx pool: always accept local transactions * tx pool: `choose` local txs with same sender and nonce --- miner/src/pool/scoring.rs | 66 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 61 insertions(+), 5 deletions(-) diff --git a/miner/src/pool/scoring.rs b/miner/src/pool/scoring.rs index 89ab6eb8f2..aff7ac49ef 100644 --- a/miner/src/pool/scoring.rs +++ b/miner/src/pool/scoring.rs @@ -123,15 +123,16 @@ impl

txpool::Scoring

for NonceAndGasPrice where P: ScoredTransaction + txp } fn should_replace(&self, old: &P, new: &P) -> scoring::Choice { + let both_local = old.priority().is_local() && new.priority().is_local(); if old.sender() == new.sender() { // prefer earliest transaction match new.nonce().cmp(&old.nonce()) { + cmp::Ordering::Equal => self.choose(old, new), + _ if both_local => scoring::Choice::InsertNew, cmp::Ordering::Less => scoring::Choice::ReplaceOld, cmp::Ordering::Greater => scoring::Choice::RejectNew, - cmp::Ordering::Equal => self.choose(old, new), } - } else if old.priority().is_local() && new.priority().is_local() { - // accept local transactions over the limit + } else if both_local { scoring::Choice::InsertNew } else { let old_score = (old.priority(), old.gas_price()); @@ -141,7 +142,7 @@ impl

txpool::Scoring

for NonceAndGasPrice where P: ScoredTransaction + txp } else { scoring::Choice::RejectNew } - } + } } fn should_ignore_sender_limit(&self, new: &P) -> bool { @@ -154,11 +155,66 @@ mod tests { use super::*; use std::sync::Arc; - use ethkey::{Random, Generator}; + use ethkey::{Random, Generator, KeyPair}; use pool::tests::tx::{Tx, TxExt}; use txpool::Scoring; use txpool::scoring::Choice::*; + fn local_tx_verified(tx: Tx, keypair: &KeyPair) -> VerifiedTransaction { + let mut verified_tx = tx.unsigned().sign(keypair.secret(), None).verified(); + verified_tx.priority = ::pool::Priority::Local; + verified_tx + } + + #[test] + fn should_always_accept_local_transactions_unless_same_sender_and_nonce() { + let scoring = NonceAndGasPrice(PrioritizationStrategy::GasPriceOnly); + + // same sender txs + let keypair = Random.generate().unwrap(); + + let same_sender_tx1 = local_tx_verified(Tx { + nonce: 1, + gas_price: 1, + ..Default::default() + }, &keypair); + + let same_sender_tx2 = local_tx_verified(Tx { + nonce: 2, + gas_price: 100, + ..Default::default() + }, &keypair); + + let same_sender_tx3 = local_tx_verified(Tx { + nonce: 2, + gas_price: 200, + ..Default::default() + }, &keypair); + + // different sender txs + let different_sender_tx1 = local_tx_verified(Tx { + nonce: 2, + gas_price: 1, + ..Default::default() + }, &Random.generate().unwrap()); + + let different_sender_tx2 = local_tx_verified(Tx { + nonce: 1, + gas_price: 10, + ..Default::default() + }, &Random.generate().unwrap()); + + assert_eq!(scoring.should_replace(&same_sender_tx1, &same_sender_tx2), InsertNew); + assert_eq!(scoring.should_replace(&same_sender_tx2, &same_sender_tx1), InsertNew); + + assert_eq!(scoring.should_replace(&different_sender_tx1, &different_sender_tx2), InsertNew); + assert_eq!(scoring.should_replace(&different_sender_tx2, &different_sender_tx1), InsertNew); + + // txs with same sender and nonce + assert_eq!(scoring.should_replace(&same_sender_tx2, &same_sender_tx3), ReplaceOld); + assert_eq!(scoring.should_replace(&same_sender_tx3, &same_sender_tx2), RejectNew); + } + #[test] fn should_replace_same_sender_by_nonce() { let scoring = NonceAndGasPrice(PrioritizationStrategy::GasPriceOnly); From 6bb106a784678cc2cadabfd621981371f477c48d Mon Sep 17 00:00:00 2001 From: cheme Date: Wed, 20 Feb 2019 19:09:34 +0100 Subject: [PATCH 085/168] Update to latest mem-db, hash-db and trie-db. (#10314) * Switch to 'trie' crates, there is an unpublished deps to staging parity-common triehash still. * Use crates.io dependency. * indentation * Update util/journaldb/src/traits.rs indentation Co-Authored-By: cheme * Update ethcore/src/snapshot/tests/state.rs Co-Authored-By: cheme --- Cargo.lock | 91 +++++++++-------- ethcore/Cargo.toml | 6 +- ethcore/light/Cargo.toml | 7 +- ethcore/light/src/cht.rs | 12 ++- ethcore/light/src/lib.rs | 7 +- ethcore/light/src/on_demand/request.rs | 8 +- ethcore/private-tx/Cargo.toml | 2 +- ethcore/private-tx/src/lib.rs | 2 +- ethcore/src/account_db.rs | 35 ++----- ethcore/src/client/client.rs | 14 +-- ethcore/src/json_tests/trie.rs | 5 +- ethcore/src/lib.rs | 6 +- ethcore/src/pod_account.rs | 2 +- ethcore/src/snapshot/account.rs | 41 ++++---- ethcore/src/snapshot/mod.rs | 12 +-- ethcore/src/snapshot/tests/helpers.rs | 13 +-- ethcore/src/snapshot/tests/service.rs | 2 +- ethcore/src/snapshot/tests/state.rs | 17 ++-- ethcore/src/spec/spec.rs | 15 ++- ethcore/src/state/account.rs | 20 ++-- ethcore/src/state/backend.rs | 56 ++++++----- ethcore/src/state/mod.rs | 69 +++++++------ ethcore/src/state_db.rs | 16 +-- ethcore/sync/Cargo.toml | 2 +- ethcore/vm/Cargo.toml | 2 +- ethcore/vm/src/lib.rs | 2 +- rpc/Cargo.toml | 2 +- rpc/src/lib.rs | 2 +- util/journaldb/Cargo.toml | 4 +- util/journaldb/src/archivedb.rs | 50 +++++----- util/journaldb/src/as_hash_db_impls.rs | 43 +++++--- util/journaldb/src/earlymergedb.rs | 49 ++++----- util/journaldb/src/lib.rs | 13 ++- util/journaldb/src/overlaydb.rs | 14 ++- util/journaldb/src/overlayrecentdb.rs | 54 +++++----- util/journaldb/src/refcounteddb.rs | 11 ++- util/journaldb/src/traits.rs | 21 +++- util/keccak-hasher/Cargo.toml | 2 +- util/keccak-hasher/src/lib.rs | 4 +- util/patricia-trie-ethereum/Cargo.toml | 7 +- util/patricia-trie-ethereum/src/lib.rs | 28 +++--- .../src/rlp_node_codec.rs | 99 ++++++++++--------- util/triehash-ethereum/Cargo.toml | 2 +- 43 files changed, 469 insertions(+), 400 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2154e13b80..dac4a7da34 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -718,7 +718,7 @@ dependencies = [ "ethkey 0.3.0", "evm 0.1.0", "fetch 0.1.0", - "hashdb 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hash-db 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.4.2 (git+https://github.com/cheme/heapsize.git?branch=ec-macfix)", "itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", "journaldb 0.2.0", @@ -733,7 +733,7 @@ dependencies = [ "lru-cache 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "macros 0.1.0", "memory-cache 0.1.0", - "memorydb 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "memory-db 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "num 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -742,7 +742,6 @@ dependencies = [ "parity-runtime 0.1.0", "parity-snappy 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "patricia-trie 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "patricia-trie-ethereum 0.1.0", "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "rayon 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -755,6 +754,7 @@ dependencies = [ "stats 0.1.0", "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "trace-time 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "trie-db 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "trie-standardmap 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "triehash-ethereum 0.2.0", "unexpected 0.1.0", @@ -870,19 +870,19 @@ dependencies = [ "failsafe 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "fastmap 0.1.0", "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "hashdb 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hash-db 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.4.2 (git+https://github.com/cheme/heapsize.git?branch=ec-macfix)", "itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", + "journaldb 0.2.0", "keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hasher 0.1.1", "kvdb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb-memorydb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "memory-cache 0.1.0", - "memorydb 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "memory-db 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "patricia-trie 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "patricia-trie-ethereum 0.1.0", "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "rlp 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -892,6 +892,7 @@ dependencies = [ "smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "stats 0.1.0", "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "trie-db 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "triehash-ethereum 0.2.0", "vm 0.1.0", ] @@ -1025,7 +1026,6 @@ dependencies = [ "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-crypto 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "patricia-trie 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "patricia-trie-ethereum 0.1.0", "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", "rlp 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1036,6 +1036,7 @@ dependencies = [ "serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)", "tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "transaction-pool 1.13.3 (registry+https://github.com/rust-lang/crates.io-index)", + "trie-db 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1130,7 +1131,7 @@ dependencies = [ "ethkey 0.3.0", "ethstore 0.2.1", "fastmap 0.1.0", - "hashdb 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hash-db 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.4.2 (git+https://github.com/cheme/heapsize.git?branch=ec-macfix)", "keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hasher 0.1.1", @@ -1540,8 +1541,8 @@ dependencies = [ ] [[package]] -name = "hashdb" -version = "0.3.0" +name = "hash-db" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1809,14 +1810,14 @@ dependencies = [ "env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)", "ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "fastmap 0.1.0", - "hashdb 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hash-db 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.4.2 (git+https://github.com/cheme/heapsize.git?branch=ec-macfix)", "keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hasher 0.1.1", "kvdb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb-memorydb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "memorydb 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "memory-db 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "rlp 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1937,7 +1938,7 @@ name = "keccak-hasher" version = "0.1.1" dependencies = [ "ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "hashdb 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hash-db 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "plain_hasher 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2143,20 +2144,18 @@ dependencies = [ ] [[package]] -name = "memory_units" -version = "0.3.0" +name = "memory-db" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "hash-db 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "heapsize 0.4.2 (git+https://github.com/cheme/heapsize.git?branch=ec-macfix)", +] [[package]] -name = "memorydb" +name = "memory_units" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "hashdb 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "heapsize 0.4.2 (git+https://github.com/cheme/heapsize.git?branch=ec-macfix)", - "plain_hasher 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rlp 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", -] [[package]] name = "memzero" @@ -2678,7 +2677,6 @@ dependencies = [ "parity-updater 1.12.0", "parity-version 2.4.0", "parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "patricia-trie 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "rlp 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2693,6 +2691,7 @@ dependencies = [ "tokio-timer 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "transaction-pool 1.13.3 (registry+https://github.com/rust-lang/crates.io-index)", "transient-hashmap 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "trie-db 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "vm 0.1.0", ] @@ -2902,31 +2901,20 @@ dependencies = [ "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "patricia-trie" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "elastic-array 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "hashdb 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "patricia-trie-ethereum" version = "0.1.0" dependencies = [ "elastic-array 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "hashdb 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hash-db 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "journaldb 0.2.0", "keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hasher 0.1.1", - "memorydb 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "memory-db 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "patricia-trie 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "rlp 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "trie-db 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4079,6 +4067,17 @@ dependencies = [ "protobuf 1.7.4 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "trie-db" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "elastic-array 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hash-db 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "trie-standardmap" version = "0.1.1" @@ -4092,10 +4091,10 @@ dependencies = [ [[package]] name = "triehash" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "hashdb 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hash-db 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "rlp 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -4105,7 +4104,7 @@ version = "0.2.0" dependencies = [ "ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hasher 0.1.1", - "triehash 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "triehash 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4281,9 +4280,9 @@ dependencies = [ "keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "patricia-trie 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "patricia-trie-ethereum 0.1.0", "rlp 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "trie-db 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4553,7 +4552,7 @@ dependencies = [ "checksum h2 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "a27e7ed946e8335bdf9a191bc1b9b14a03ba822d013d2f58437f4fabcbd7fc2c" "checksum hamming 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "65043da274378d68241eb9a8f8f8aa54e349136f7b8e12f63e3ef44043cc30e1" "checksum handlebars 0.32.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d89ec99d1594f285d4590fc32bac5f75cdab383f1123d504d27862c644a807dd" -"checksum hashdb 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d91261ee336dd046ac7df28306cb297b7a7228bd1ae25e9a57f4ed5e0ab628c7" +"checksum hash-db 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1b03501f6e1a2a97f1618879aba3156f14ca2847faa530c4e28859638bd11483" "checksum heapsize 0.4.2 (git+https://github.com/cheme/heapsize.git?branch=ec-macfix)" = "" "checksum heck 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ea04fa3ead4e05e51a7c806fc07271fdbde4e246a6c6d1efd52e72230b771b82" "checksum hex 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d6a22814455d41612f41161581c2883c0c6a1c41852729b17d5ed88f01e153aa" @@ -4613,8 +4612,8 @@ dependencies = [ "checksum memchr 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4b3629fe9fdbff6daa6c33b90f7c08355c1aca05a3d01fa8063b822fcf185f3b" "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-db 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94da53143d45f6bad3753f532e56ad57a6a26c0ca6881794583310c7cb4c885f" "checksum memory_units 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "71d96e3f3c0b6325d8ccd83c33b28acb183edcb6c67938ba104ec546854b0882" -"checksum memorydb 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e143fbad9f90d2158bca3c4b09015276a6de6f085a77088943901cb26828780f" "checksum mime 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)" = "0a907b83e7b9e987032439a387e187119cddafc92d5c2aaeb1d92580a793f630" "checksum mime_guess 2.0.0-alpha.6 (registry+https://github.com/rust-lang/crates.io-index)" = "30de2e4613efcba1ec63d8133f344076952090c122992a903359be5a4f99c3ed" "checksum mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)" = "71646331f2619b1026cc302f87a2b8b648d5c6dd6937846a16cc8ce0f347f432" @@ -4657,7 +4656,6 @@ dependencies = [ "checksum parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9723236a9525c757d9725b993511e3fc941e33f27751942232f0058298297edf" "checksum parking_lot_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad7f7e6ebdc79edff6fdcb87a55b620174f7a989e3eb31b65231f4af57f00b8c" "checksum parking_lot_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94c8c7923936b28d546dfd14d4472eaf34c99b14e1c973a32b3e6d4eb04298c9" -"checksum patricia-trie 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "10438ba40c2f6e9ceca55277d8e7f6a5dafd58cabd802e6d97e16f02aab83a03" "checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" "checksum pest 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0fce5d8b5cc33983fc74f78ad552b5522ab41442c4ca91606e4236eb4b5ceefc" "checksum pest_derive 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "ca3294f437119209b084c797604295f40227cffa35c57220b1e99a6ff3bf8ee4" @@ -4783,8 +4781,9 @@ dependencies = [ "checksum transaction-pool 1.13.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e5866e5126b14358f1d7af4bf51a0be677a363799b90e655edcec8254edef1d2" "checksum transient-hashmap 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "aeb4b191d033a35edfce392a38cdcf9790b6cebcb30fa690c312c29da4dc433e" "checksum trezor-sys 1.0.0 (git+https://github.com/paritytech/trezor-sys)" = "" +"checksum trie-db 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3c7319e28ca295f27359d944a682f7f65b419158bf1590c92cadc0000258d788" "checksum trie-standardmap 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0e26f52976a57a0859616d6fcec87092ac35d08eabbd78dc3dabee93b480ea5f" -"checksum triehash 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cd9cb3a626dd9a19a1b5f84087143b19409db793d902c5ddee4b6212020713f1" +"checksum triehash 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0d26efb4ddf87870fc08dc9a6580dc3061be350d7b9d0eb30aef1c8b4227aa46" "checksum try-lock 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee2aa4715743892880f70885373966c83d73ef1b0838a664ef0c76fffd35e7c2" "checksum try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382" "checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169" diff --git a/ethcore/Cargo.toml b/ethcore/Cargo.toml index cf0fc95200..0e3cea0fc6 100644 --- a/ethcore/Cargo.toml +++ b/ethcore/Cargo.toml @@ -30,7 +30,7 @@ ethereum-types = "0.4" ethjson = { path = "../json" } ethkey = { path = "../accounts/ethkey" } evm = { path = "evm" } -hashdb = "0.3.0" +hash-db = "0.11.0" heapsize = "0.4" itertools = "0.5" journaldb = { path = "../util/journaldb" } @@ -45,7 +45,7 @@ log = "0.4" lru-cache = "0.1" macros = { path = "../util/macros" } memory-cache = { path = "../util/memory-cache" } -memorydb = "0.3.0" +memory-db = "0.11.0" num = { version = "0.1", default-features = false, features = ["bigint"] } num_cpus = "1.2" parity-bytes = "0.1" @@ -53,7 +53,7 @@ parity-crypto = "0.3.0" parity-machine = { path = "../machine" } parity-snappy = "0.1" parking_lot = "0.7" -patricia-trie = "0.3.0" +trie-db = "0.11.0" patricia-trie-ethereum = { path = "../util/patricia-trie-ethereum" } rand = "0.4" rayon = "1.0" diff --git a/ethcore/light/Cargo.toml b/ethcore/light/Cargo.toml index 7e0c8aaebf..756b76f1f5 100644 --- a/ethcore/light/Cargo.toml +++ b/ethcore/light/Cargo.toml @@ -14,12 +14,12 @@ ethcore = { path = ".."} ethcore-db = { path = "../db" } ethcore-blockchain = { path = "../blockchain" } ethereum-types = "0.4" -memorydb = "0.3.0" -patricia-trie = "0.3.0" +memory-db = "0.11.0" +trie-db = "0.11.0" patricia-trie-ethereum = { path = "../../util/patricia-trie-ethereum" } ethcore-network = { path = "../../util/network" } ethcore-io = { path = "../../util/io" } -hashdb = "0.3.0" +hash-db = "0.11.0" heapsize = "0.4" vm = { path = "../vm" } fastmap = { path = "../../util/fastmap" } @@ -41,6 +41,7 @@ triehash-ethereum = { version = "0.2", path = "../../util/triehash-ethereum" } kvdb = "0.1" memory-cache = { path = "../../util/memory-cache" } error-chain = { version = "0.12", default-features = false } +journaldb = { path = "../../util/journaldb" } [dev-dependencies] ethcore = { path = "..", features = ["test-helpers"] } diff --git a/ethcore/light/src/cht.rs b/ethcore/light/src/cht.rs index b1a5049ab0..a9bc5d7f26 100644 --- a/ethcore/light/src/cht.rs +++ b/ethcore/light/src/cht.rs @@ -25,10 +25,11 @@ use common_types::ids::BlockId; use ethereum_types::{H256, U256}; -use hashdb::HashDB; +use hash_db::HashDB; use keccak_hasher::KeccakHasher; use kvdb::DBValue; -use memorydb::MemoryDB; +use memory_db::MemoryDB; +use journaldb::new_memory_db; use bytes::Bytes; use trie::{TrieMut, Trie, Recorder}; use ethtrie::{self, TrieDB, TrieDBMut}; @@ -73,7 +74,8 @@ impl> CHT { if block_to_cht_number(num) != Some(self.number) { return Ok(None) } let mut recorder = Recorder::with_depth(from_level); - let t = TrieDB::new(&self.db, &self.root)?; + let db: &HashDB<_,_> = &self.db; + let t = TrieDB::new(&db, &self.root)?; t.get_with(&key!(num), &mut recorder)?; Ok(Some(recorder.drain().into_iter().map(|x| x.data).collect())) @@ -96,7 +98,7 @@ pub struct BlockInfo { pub fn build(cht_num: u64, mut fetcher: F) -> Option>> where F: FnMut(BlockId) -> Option { - let mut db = MemoryDB::::new(); + let mut db = new_memory_db(); // start from the last block by number and work backwards. let last_num = start_number(cht_num + 1) - 1; @@ -150,7 +152,7 @@ pub fn compute_root(cht_num: u64, iterable: I) -> Option /// verify the given trie branch and extract the canonical hash and total difficulty. // TODO: better support for partially-checked queries. pub fn check_proof(proof: &[Bytes], num: u64, root: H256) -> Option<(H256, U256)> { - let mut db = MemoryDB::::new(); + let mut db = new_memory_db(); for node in proof { db.insert(&node[..]); } let res = match TrieDB::new(&db, &root) { diff --git a/ethcore/light/src/lib.rs b/ethcore/light/src/lib.rs index db52b95482..93e912e1d6 100644 --- a/ethcore/light/src/lib.rs +++ b/ethcore/light/src/lib.rs @@ -62,14 +62,14 @@ extern crate ethcore_network as network; extern crate parity_bytes as bytes; extern crate ethereum_types; extern crate ethcore; -extern crate hashdb; +extern crate hash_db; extern crate heapsize; extern crate failsafe; extern crate futures; extern crate itertools; extern crate keccak_hasher; -extern crate memorydb; -extern crate patricia_trie as trie; +extern crate memory_db; +extern crate trie_db as trie; extern crate patricia_trie_ethereum as ethtrie; extern crate fastmap; extern crate rand; @@ -92,3 +92,4 @@ extern crate error_chain; extern crate kvdb_memorydb; #[cfg(test)] extern crate tempdir; +extern crate journaldb; diff --git a/ethcore/light/src/on_demand/request.rs b/ethcore/light/src/on_demand/request.rs index a2167fa38d..a183dcbcab 100644 --- a/ethcore/light/src/on_demand/request.rs +++ b/ethcore/light/src/on_demand/request.rs @@ -30,9 +30,8 @@ use ethcore::state::{self, ProvedExecution}; use ethereum_types::{H256, U256, Address}; use ethtrie::{TrieError, TrieDB}; use hash::{KECCAK_NULL_RLP, KECCAK_EMPTY, KECCAK_EMPTY_LIST_RLP, keccak}; -use hashdb::HashDB; +use hash_db::HashDB; use kvdb::DBValue; -use memorydb::MemoryDB; use parking_lot::Mutex; use request::{self as net_request, IncompleteRequest, CompleteRequest, Output, OutputKind, Field}; use rlp::{RlpStream, Rlp}; @@ -981,7 +980,7 @@ impl Account { let header = self.header.as_ref()?; let state_root = header.state_root(); - let mut db = MemoryDB::new(); + let mut db = journaldb::new_memory_db(); for node in proof { db.insert(&node[..]); } match TrieDB::new(&db, &state_root).and_then(|t| t.get(&keccak(&self.address)))? { @@ -1101,7 +1100,6 @@ mod tests { use super::*; use std::time::Duration; use ethereum_types::{H256, Address}; - use memorydb::MemoryDB; use parking_lot::Mutex; use trie::{Trie, TrieMut}; use ethtrie::{SecTrieDB, SecTrieDBMut}; @@ -1281,7 +1279,7 @@ mod tests { use rlp::RlpStream; let mut root = H256::default(); - let mut db = MemoryDB::new(); + let mut db = journaldb::new_memory_db(); let mut header = Header::new(); header.set_number(123_456); header.set_extra_data(b"test_header".to_vec()); diff --git a/ethcore/private-tx/Cargo.toml b/ethcore/private-tx/Cargo.toml index 74883ca970..fdf6e52baa 100644 --- a/ethcore/private-tx/Cargo.toml +++ b/ethcore/private-tx/Cargo.toml @@ -26,7 +26,7 @@ log = "0.4" parity-bytes = "0.1" parity-crypto = "0.3.0" parking_lot = "0.7" -patricia-trie = "0.3.0" +trie-db = "0.11.0" patricia-trie-ethereum = { path = "../../util/patricia-trie-ethereum" } rand = "0.3" rlp = { version = "0.3.0", features = ["ethereum"] } diff --git a/ethcore/private-tx/src/lib.rs b/ethcore/private-tx/src/lib.rs index f536e22fbd..711bdc6126 100644 --- a/ethcore/private-tx/src/lib.rs +++ b/ethcore/private-tx/src/lib.rs @@ -42,7 +42,7 @@ extern crate keccak_hash as hash; extern crate parity_bytes as bytes; extern crate parity_crypto as crypto; extern crate parking_lot; -extern crate patricia_trie as trie; +extern crate trie_db as trie; extern crate patricia_trie_ethereum as ethtrie; extern crate rlp; extern crate rustc_hex; diff --git a/ethcore/src/account_db.rs b/ethcore/src/account_db.rs index 5b7bd52753..a389c009bf 100644 --- a/ethcore/src/account_db.rs +++ b/ethcore/src/account_db.rs @@ -17,11 +17,10 @@ //! DB backend wrapper for Account trie use ethereum_types::H256; use hash::{KECCAK_NULL_RLP, keccak}; -use hashdb::{HashDB, AsHashDB}; +use hash_db::{HashDB, AsHashDB}; use keccak_hasher::KeccakHasher; use kvdb::DBValue; use rlp::NULL_RLP; -use std::collections::HashMap; #[cfg(test)] use ethereum_types::Address; @@ -99,15 +98,11 @@ impl<'db> AccountDB<'db> { } impl<'db> AsHashDB for AccountDB<'db> { - fn as_hashdb(&self) -> &HashDB { self } - fn as_hashdb_mut(&mut self) -> &mut HashDB { self } + fn as_hash_db(&self) -> &HashDB { self } + fn as_hash_db_mut(&mut self) -> &mut HashDB { self } } impl<'db> HashDB for AccountDB<'db> { - fn keys(&self) -> HashMap { - unimplemented!() - } - fn get(&self, key: &H256) -> Option { if key == &KECCAK_NULL_RLP { return Some(DBValue::from_slice(&NULL_RLP)); @@ -163,10 +158,6 @@ impl<'db> AccountDBMut<'db> { } impl<'db> HashDB for AccountDBMut<'db>{ - fn keys(&self) -> HashMap { - unimplemented!() - } - fn get(&self, key: &H256) -> Option { if key == &KECCAK_NULL_RLP { return Some(DBValue::from_slice(&NULL_RLP)); @@ -209,22 +200,18 @@ impl<'db> HashDB for AccountDBMut<'db>{ } impl<'db> AsHashDB for AccountDBMut<'db> { - fn as_hashdb(&self) -> &HashDB { self } - fn as_hashdb_mut(&mut self) -> &mut HashDB { self } + fn as_hash_db(&self) -> &HashDB { self } + fn as_hash_db_mut(&mut self) -> &mut HashDB { self } } struct Wrapping<'db>(&'db HashDB); impl<'db> AsHashDB for Wrapping<'db> { - fn as_hashdb(&self) -> &HashDB { self } - fn as_hashdb_mut(&mut self) -> &mut HashDB { self } + fn as_hash_db(&self) -> &HashDB { self } + fn as_hash_db_mut(&mut self) -> &mut HashDB { self } } impl<'db> HashDB for Wrapping<'db> { - fn keys(&self) -> HashMap { - unimplemented!() - } - fn get(&self, key: &H256) -> Option { if key == &KECCAK_NULL_RLP { return Some(DBValue::from_slice(&NULL_RLP)); @@ -254,15 +241,11 @@ impl<'db> HashDB for Wrapping<'db> { struct WrappingMut<'db>(&'db mut HashDB); impl<'db> AsHashDB for WrappingMut<'db> { - fn as_hashdb(&self) -> &HashDB { self } - fn as_hashdb_mut(&mut self) -> &mut HashDB { self } + fn as_hash_db(&self) -> &HashDB { self } + fn as_hash_db_mut(&mut self) -> &mut HashDB { self } } impl<'db> HashDB for WrappingMut<'db>{ - fn keys(&self) -> HashMap { - unimplemented!() - } - fn get(&self, key: &H256) -> Option { if key == &KECCAK_NULL_RLP { return Some(DBValue::from_slice(&NULL_RLP)); diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index b1f2f0d794..d40fc30330 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -624,7 +624,7 @@ impl Importer { let call = move |addr, data| { let mut state_db = state_db.boxed_clone(); - let backend = ::state::backend::Proving::new(state_db.as_hashdb_mut()); + let backend = ::state::backend::Proving::new(state_db.as_hash_db_mut()); let transaction = client.contract_call_tx(BlockId::Hash(*header.parent_hash()), addr, data); @@ -1176,7 +1176,7 @@ impl Client { }; let processing_threads = self.config.snapshot.processing_threads; - snapshot::take_snapshot(&*self.engine, &self.chain.read(), start_hash, db.as_hashdb(), writer, p, processing_threads)?; + snapshot::take_snapshot(&*self.engine, &self.chain.read(), start_hash, db.as_hash_db(), writer, p, processing_threads)?; Ok(()) } @@ -1781,7 +1781,8 @@ impl BlockChainClient for Client { }; let (root, db) = state.drop(); - let trie = match self.factories.trie.readonly(db.as_hashdb(), &root) { + let db = &db.as_hash_db(); + let trie = match self.factories.trie.readonly(db, &root) { Ok(trie) => trie, _ => { trace!(target: "fatdb", "list_accounts: Couldn't open the DB"); @@ -1827,8 +1828,9 @@ impl BlockChainClient for Client { }; let (_, db) = state.drop(); - let account_db = self.factories.accountdb.readonly(db.as_hashdb(), keccak(account)); - let trie = match self.factories.trie.readonly(account_db.as_hashdb(), &root) { + let account_db = &self.factories.accountdb.readonly(db.as_hash_db(), keccak(account)); + let account_db = &account_db.as_hash_db(); + let trie = match self.factories.trie.readonly(account_db, &root) { Ok(trie) => trie, _ => { trace!(target: "fatdb", "list_storage: Couldn't open the DB"); @@ -2499,7 +2501,7 @@ impl ProvingBlockChainClient for Client { let mut jdb = self.state_db.read().journal_db().boxed_clone(); state::prove_transaction_virtual( - jdb.as_hashdb_mut(), + jdb.as_hash_db_mut(), header.state_root().clone(), &transaction, self.engine.machine(), diff --git a/ethcore/src/json_tests/trie.rs b/ethcore/src/json_tests/trie.rs index 6d367f2083..d56490ec7e 100644 --- a/ethcore/src/json_tests/trie.rs +++ b/ethcore/src/json_tests/trie.rs @@ -18,9 +18,6 @@ use ethjson; use trie::{TrieFactory, TrieSpec}; use ethtrie::RlpCodec; use ethereum_types::H256; -use memorydb::MemoryDB; -use keccak_hasher::KeccakHasher; -use kvdb::DBValue; use super::HookType; @@ -37,7 +34,7 @@ fn test_trie(json: &[u8], trie: TrieSpec, start_stop_h for (name, test) in tests.into_iter() { start_stop_hook(&name, HookType::OnStart); - let mut memdb = MemoryDB::::new(); + let mut memdb = journaldb::new_memory_db(); let mut root = H256::default(); let mut t = factory.create(&mut memdb, &mut root); diff --git a/ethcore/src/lib.rs b/ethcore/src/lib.rs index 0fe2e0db19..5ba6a26d01 100644 --- a/ethcore/src/lib.rs +++ b/ethcore/src/lib.rs @@ -73,7 +73,7 @@ extern crate ethcore_miner; extern crate ethereum_types; extern crate ethjson; extern crate ethkey; -extern crate hashdb; +extern crate hash_db; extern crate heapsize; extern crate itertools; extern crate journaldb; @@ -84,7 +84,7 @@ extern crate kvdb_memorydb; extern crate len_caching_lock; extern crate lru_cache; extern crate memory_cache; -extern crate memorydb; +extern crate memory_db; extern crate num; extern crate num_cpus; extern crate parity_bytes as bytes; @@ -92,7 +92,7 @@ extern crate parity_crypto; extern crate parity_machine; extern crate parity_snappy as snappy; extern crate parking_lot; -extern crate patricia_trie as trie; +extern crate trie_db as trie; extern crate patricia_trie_ethereum as ethtrie; extern crate rand; extern crate rayon; diff --git a/ethcore/src/pod_account.rs b/ethcore/src/pod_account.rs index 9f5f3a237b..39dce6e36d 100644 --- a/ethcore/src/pod_account.rs +++ b/ethcore/src/pod_account.rs @@ -21,7 +21,7 @@ use std::collections::BTreeMap; use itertools::Itertools; use hash::{keccak}; use ethereum_types::{H256, U256}; -use hashdb::HashDB; +use hash_db::HashDB; use kvdb::DBValue; use keccak_hasher::KeccakHasher; use triehash::sec_trie_root; diff --git a/ethcore/src/snapshot/account.rs b/ethcore/src/snapshot/account.rs index 81e4d4a0e2..ed56e2435b 100644 --- a/ethcore/src/snapshot/account.rs +++ b/ethcore/src/snapshot/account.rs @@ -22,7 +22,7 @@ use bytes::Bytes; use ethereum_types::{H256, U256}; use ethtrie::{TrieDB, TrieDBMut}; use hash::{KECCAK_EMPTY, KECCAK_NULL_RLP}; -use hashdb::HashDB; +use hash_db::HashDB; use rlp::{RlpStream, Rlp}; use snapshot::Error; use std::collections::HashSet; @@ -66,7 +66,8 @@ impl CodeState { // account address hash, account properties and the storage. Each item contains at most `max_storage_items` // storage records split according to snapshot format definition. pub fn to_fat_rlps(account_hash: &H256, acc: &BasicAccount, acct_db: &AccountDB, used_code: &mut HashSet, first_chunk_size: usize, max_chunk_size: usize) -> Result, Error> { - let db = TrieDB::new(acct_db, &acc.storage_root)?; + let db = &(acct_db as &HashDB<_,_>); + let db = TrieDB::new(db, &acc.storage_root)?; let mut chunks = Vec::new(); let mut db_iter = db.iter()?; let mut target_chunk_size = first_chunk_size; @@ -77,7 +78,7 @@ pub fn to_fat_rlps(account_hash: &H256, acc: &BasicAccount, acct_db: &AccountDB, account_stream.begin_list(5); account_stream.append(&acc.nonce) - .append(&acc.balance); + .append(&acc.balance); // [has_code, code_hash]. if acc.code_hash == KECCAK_EMPTY { @@ -187,7 +188,7 @@ pub fn from_fat_rlp( }; let pairs = rlp.at(4)?; for pair_rlp in pairs.iter() { - let k: Bytes = pair_rlp.val_at(0)?; + let k: Bytes = pair_rlp.val_at(0)?; let v: Bytes = pair_rlp.val_at(1)?; storage_trie.insert(&k, &v)?; @@ -213,7 +214,7 @@ mod tests { use hash::{KECCAK_EMPTY, KECCAK_NULL_RLP, keccak}; use ethereum_types::{H256, Address}; - use hashdb::HashDB; + use hash_db::HashDB; use kvdb::DBValue; use rlp::Rlp; @@ -236,9 +237,9 @@ mod tests { let thin_rlp = ::rlp::encode(&account); assert_eq!(::rlp::decode::(&thin_rlp).unwrap(), account); - let fat_rlps = to_fat_rlps(&keccak(&addr), &account, &AccountDB::new(db.as_hashdb(), &addr), &mut Default::default(), usize::max_value(), usize::max_value()).unwrap(); + let fat_rlps = to_fat_rlps(&keccak(&addr), &account, &AccountDB::new(db.as_hash_db(), &addr), &mut Default::default(), usize::max_value(), usize::max_value()).unwrap(); let fat_rlp = Rlp::new(&fat_rlps[0]).at(1).unwrap(); - assert_eq!(from_fat_rlp(&mut AccountDBMut::new(db.as_hashdb_mut(), &addr), fat_rlp, H256::zero()).unwrap().0, account); + assert_eq!(from_fat_rlp(&mut AccountDBMut::new(db.as_hash_db_mut(), &addr), fat_rlp, H256::zero()).unwrap().0, account); } #[test] @@ -247,7 +248,7 @@ mod tests { let addr = Address::random(); let account = { - let acct_db = AccountDBMut::new(db.as_hashdb_mut(), &addr); + let acct_db = AccountDBMut::new(db.as_hash_db_mut(), &addr); let mut root = KECCAK_NULL_RLP; fill_storage(acct_db, &mut root, &mut H256::zero()); BasicAccount { @@ -261,9 +262,9 @@ mod tests { let thin_rlp = ::rlp::encode(&account); assert_eq!(::rlp::decode::(&thin_rlp).unwrap(), account); - let fat_rlp = to_fat_rlps(&keccak(&addr), &account, &AccountDB::new(db.as_hashdb(), &addr), &mut Default::default(), usize::max_value(), usize::max_value()).unwrap(); + let fat_rlp = to_fat_rlps(&keccak(&addr), &account, &AccountDB::new(db.as_hash_db(), &addr), &mut Default::default(), usize::max_value(), usize::max_value()).unwrap(); let fat_rlp = Rlp::new(&fat_rlp[0]).at(1).unwrap(); - assert_eq!(from_fat_rlp(&mut AccountDBMut::new(db.as_hashdb_mut(), &addr), fat_rlp, H256::zero()).unwrap().0, account); + assert_eq!(from_fat_rlp(&mut AccountDBMut::new(db.as_hash_db_mut(), &addr), fat_rlp, H256::zero()).unwrap().0, account); } #[test] @@ -272,7 +273,7 @@ mod tests { let addr = Address::random(); let account = { - let acct_db = AccountDBMut::new(db.as_hashdb_mut(), &addr); + let acct_db = AccountDBMut::new(db.as_hash_db_mut(), &addr); let mut root = KECCAK_NULL_RLP; fill_storage(acct_db, &mut root, &mut H256::zero()); BasicAccount { @@ -286,12 +287,12 @@ mod tests { let thin_rlp = ::rlp::encode(&account); assert_eq!(::rlp::decode::(&thin_rlp).unwrap(), account); - let fat_rlps = to_fat_rlps(&keccak(addr), &account, &AccountDB::new(db.as_hashdb(), &addr), &mut Default::default(), 500, 1000).unwrap(); + let fat_rlps = to_fat_rlps(&keccak(addr), &account, &AccountDB::new(db.as_hash_db(), &addr), &mut Default::default(), 500, 1000).unwrap(); let mut root = KECCAK_NULL_RLP; let mut restored_account = None; for rlp in fat_rlps { let fat_rlp = Rlp::new(&rlp).at(1).unwrap(); - restored_account = Some(from_fat_rlp(&mut AccountDBMut::new(db.as_hashdb_mut(), &addr), fat_rlp, root).unwrap().0); + restored_account = Some(from_fat_rlp(&mut AccountDBMut::new(db.as_hash_db_mut(), &addr), fat_rlp, root).unwrap().0); root = restored_account.as_ref().unwrap().storage_root.clone(); } assert_eq!(restored_account, Some(account)); @@ -305,12 +306,12 @@ mod tests { let addr2 = Address::random(); let code_hash = { - let mut acct_db = AccountDBMut::new(db.as_hashdb_mut(), &addr1); + let mut acct_db = AccountDBMut::new(db.as_hash_db_mut(), &addr1); acct_db.insert(b"this is definitely code") }; { - let mut acct_db = AccountDBMut::new(db.as_hashdb_mut(), &addr2); + let mut acct_db = AccountDBMut::new(db.as_hash_db_mut(), &addr2); acct_db.emplace(code_hash.clone(), DBValue::from_slice(b"this is definitely code")); } @@ -330,18 +331,18 @@ mod tests { let mut used_code = HashSet::new(); - let fat_rlp1 = to_fat_rlps(&keccak(&addr1), &account1, &AccountDB::new(db.as_hashdb(), &addr1), &mut used_code, usize::max_value(), usize::max_value()).unwrap(); - let fat_rlp2 = to_fat_rlps(&keccak(&addr2), &account2, &AccountDB::new(db.as_hashdb(), &addr2), &mut used_code, usize::max_value(), usize::max_value()).unwrap(); + let fat_rlp1 = to_fat_rlps(&keccak(&addr1), &account1, &AccountDB::new(db.as_hash_db(), &addr1), &mut used_code, usize::max_value(), usize::max_value()).unwrap(); + let fat_rlp2 = to_fat_rlps(&keccak(&addr2), &account2, &AccountDB::new(db.as_hash_db(), &addr2), &mut used_code, usize::max_value(), usize::max_value()).unwrap(); assert_eq!(used_code.len(), 1); let fat_rlp1 = Rlp::new(&fat_rlp1[0]).at(1).unwrap(); let fat_rlp2 = Rlp::new(&fat_rlp2[0]).at(1).unwrap(); - let (acc, maybe_code) = from_fat_rlp(&mut AccountDBMut::new(db.as_hashdb_mut(), &addr2), fat_rlp2, H256::zero()).unwrap(); + let (acc, maybe_code) = from_fat_rlp(&mut AccountDBMut::new(db.as_hash_db_mut(), &addr2), fat_rlp2, H256::zero()).unwrap(); assert!(maybe_code.is_none()); assert_eq!(acc, account2); - let (acc, maybe_code) = from_fat_rlp(&mut AccountDBMut::new(db.as_hashdb_mut(), &addr1), fat_rlp1, H256::zero()).unwrap(); + let (acc, maybe_code) = from_fat_rlp(&mut AccountDBMut::new(db.as_hash_db_mut(), &addr1), fat_rlp1, H256::zero()).unwrap(); assert_eq!(maybe_code, Some(b"this is definitely code".to_vec())); assert_eq!(acc, account1); } @@ -349,6 +350,6 @@ mod tests { #[test] fn encoding_empty_acc() { let mut db = get_temp_state_db(); - assert_eq!(from_fat_rlp(&mut AccountDBMut::new(db.as_hashdb_mut(), &Address::default()), Rlp::new(&::rlp::NULL_RLP), H256::zero()).unwrap(), (ACC_EMPTY, None)); + assert_eq!(from_fat_rlp(&mut AccountDBMut::new(db.as_hash_db_mut(), &Address::default()), Rlp::new(&::rlp::NULL_RLP), H256::zero()).unwrap(), (ACC_EMPTY, None)); } } diff --git a/ethcore/src/snapshot/mod.rs b/ethcore/src/snapshot/mod.rs index f054e54198..c05d0de6a3 100644 --- a/ethcore/src/snapshot/mod.rs +++ b/ethcore/src/snapshot/mod.rs @@ -32,7 +32,7 @@ use types::header::Header; use types::ids::BlockId; use ethereum_types::{H256, U256}; -use hashdb::HashDB; +use hash_db::HashDB; use keccak_hasher::KeccakHasher; use snappy; use bytes::Bytes; @@ -322,7 +322,7 @@ impl<'a> StateChunker<'a> { /// Returns a list of hashes of chunks created, or any error it may /// have encountered. pub fn chunk_state<'a>(db: &HashDB, root: &H256, writer: &Mutex, progress: &'a Progress, part: Option) -> Result, Error> { - let account_trie = TrieDB::new(db, &root)?; + let account_trie = TrieDB::new(&db, &root)?; let mut chunker = StateChunker { hashes: Vec::new(), @@ -414,7 +414,7 @@ impl StateRebuilder { pairs.resize(rlp.item_count()?, (H256::new(), Vec::new())); let status = rebuild_accounts( - self.db.as_hashdb_mut(), + self.db.as_hash_db_mut(), rlp, &mut pairs, &self.known_code, @@ -429,7 +429,7 @@ impl StateRebuilder { // patch up all missing code. must be done after collecting all new missing code entries. for (code_hash, code, first_with) in status.new_code { for addr_hash in self.missing_code.remove(&code_hash).unwrap_or_else(Vec::new) { - let mut db = AccountDBMut::from_hash(self.db.as_hashdb_mut(), addr_hash); + let mut db = AccountDBMut::from_hash(self.db.as_hash_db_mut(), addr_hash); db.emplace(code_hash, DBValue::from_slice(&code)); } @@ -441,9 +441,9 @@ impl StateRebuilder { // batch trie writes { let mut account_trie = if self.state_root != KECCAK_NULL_RLP { - TrieDBMut::from_existing(self.db.as_hashdb_mut(), &mut self.state_root)? + TrieDBMut::from_existing(self.db.as_hash_db_mut(), &mut self.state_root)? } else { - TrieDBMut::new(self.db.as_hashdb_mut(), &mut self.state_root) + TrieDBMut::new(self.db.as_hash_db_mut(), &mut self.state_root) }; for (hash, thin_rlp) in pairs { diff --git a/ethcore/src/snapshot/tests/helpers.rs b/ethcore/src/snapshot/tests/helpers.rs index 31913c2f40..817e024998 100644 --- a/ethcore/src/snapshot/tests/helpers.rs +++ b/ethcore/src/snapshot/tests/helpers.rs @@ -35,7 +35,7 @@ use rand::Rng; use kvdb::DBValue; use ethereum_types::H256; -use hashdb::HashDB; +use hash_db::HashDB; use keccak_hasher::KeccakHasher; use journaldb; use trie::{TrieMut, Trie}; @@ -65,7 +65,7 @@ impl StateProducer { pub fn tick(&mut self, rng: &mut R, db: &mut HashDB) { // modify existing accounts. let mut accounts_to_modify: Vec<_> = { - let trie = TrieDB::new(&*db, &self.state_root).unwrap(); + let trie = TrieDB::new(&db, &self.state_root).unwrap(); let temp = trie.iter().unwrap() // binding required due to complicated lifetime stuff .filter(|_| rng.gen::() < ACCOUNT_CHURN) .map(Result::unwrap) @@ -130,15 +130,6 @@ pub fn fill_storage(mut db: AccountDBMut, root: &mut H256, seed: &mut H256) { } } -/// Compare two state dbs. -pub fn compare_dbs(one: &HashDB, two: &HashDB) { - let keys = one.keys(); - - for key in keys.keys() { - assert_eq!(one.get(&key).unwrap(), two.get(&key).unwrap()); - } -} - /// Take a snapshot from the given client into a temporary file. /// Return a snapshot reader for it. pub fn snap(client: &Client) -> (Box, TempDir) { diff --git a/ethcore/src/snapshot/tests/service.rs b/ethcore/src/snapshot/tests/service.rs index 535e7c2993..37a10048ab 100644 --- a/ethcore/src/snapshot/tests/service.rs +++ b/ethcore/src/snapshot/tests/service.rs @@ -184,7 +184,7 @@ fn keep_ancient_blocks() { let start_header = bc.block_header_data(&best_hash).unwrap(); let state_root = start_header.state_root(); let state_hashes = chunk_state( - state_db.as_hashdb(), + state_db.as_hash_db(), &state_root, &writer, &Progress::default(), diff --git a/ethcore/src/snapshot/tests/state.rs b/ethcore/src/snapshot/tests/state.rs index 44a624715e..fa7df6b619 100644 --- a/ethcore/src/snapshot/tests/state.rs +++ b/ethcore/src/snapshot/tests/state.rs @@ -24,7 +24,7 @@ use types::basic_account::BasicAccount; use snapshot::account; use snapshot::{chunk_state, Error as SnapshotError, Progress, StateRebuilder, SNAPSHOT_SUBPARTS}; use snapshot::io::{PackedReader, PackedWriter, SnapshotReader, SnapshotWriter}; -use super::helpers::{compare_dbs, StateProducer}; +use super::helpers::StateProducer; use error::{Error, ErrorKind}; @@ -32,15 +32,15 @@ use rand::{XorShiftRng, SeedableRng}; use ethereum_types::H256; use journaldb::{self, Algorithm}; use kvdb_rocksdb::{Database, DatabaseConfig}; -use memorydb::MemoryDB; use parking_lot::Mutex; use tempdir::TempDir; #[test] fn snap_and_restore() { + use hash_db::HashDB; let mut producer = StateProducer::new(); let mut rng = XorShiftRng::from_seed([1, 2, 3, 4]); - let mut old_db = MemoryDB::new(); + let mut old_db = journaldb::new_memory_db(); let db_cfg = DatabaseConfig::with_columns(::db::NUM_COLUMNS); for _ in 0..150 { @@ -91,8 +91,11 @@ fn snap_and_restore() { let new_db = journaldb::new(db, Algorithm::OverlayRecent, ::db::COL_STATE); assert_eq!(new_db.earliest_era(), Some(1000)); + let keys = old_db.keys(); - compare_dbs(&old_db, new_db.as_hashdb()); + for key in keys.keys() { + assert_eq!(old_db.get(&key).unwrap(), new_db.as_hash_db().get(&key).unwrap()); + } } #[test] @@ -100,7 +103,7 @@ fn get_code_from_prev_chunk() { use std::collections::HashSet; use rlp::RlpStream; use ethereum_types::{H256, U256}; - use hashdb::HashDB; + use hash_db::HashDB; use account_db::{AccountDBMut, AccountDB}; @@ -121,7 +124,7 @@ fn get_code_from_prev_chunk() { let acc: BasicAccount = ::rlp::decode(&thin_rlp).expect("error decoding basic account"); let mut make_chunk = |acc, hash| { - let mut db = MemoryDB::new(); + let mut db = journaldb::new_memory_db(); AccountDBMut::from_hash(&mut db, hash).insert(&code[..]); let fat_rlp = account::to_fat_rlps(&hash, &acc, &AccountDB::from_hash(&db, hash), &mut used_code, usize::max_value(), usize::max_value()).unwrap(); @@ -155,7 +158,7 @@ fn get_code_from_prev_chunk() { fn checks_flag() { let mut producer = StateProducer::new(); let mut rng = XorShiftRng::from_seed([5, 6, 7, 8]); - let mut old_db = MemoryDB::new(); + let mut old_db = journaldb::new_memory_db(); let db_cfg = DatabaseConfig::with_columns(::db::NUM_COLUMNS); for _ in 0..10 { diff --git a/ethcore/src/spec/spec.rs b/ethcore/src/spec/spec.rs index 517b69e751..4bd46b2bb6 100644 --- a/ethcore/src/spec/spec.rs +++ b/ethcore/src/spec/spec.rs @@ -25,7 +25,6 @@ use bytes::Bytes; use ethereum_types::{H256, Bloom, U256, Address}; use ethjson; use hash::{KECCAK_NULL_RLP, keccak}; -use memorydb::MemoryDB; use parking_lot::RwLock; use rlp::{Rlp, RlpStream}; use rustc_hex::{FromHex, ToHex}; @@ -556,7 +555,7 @@ fn load_from(spec_params: SpecParams, s: ethjson::spec::Spec) -> Result { let _ = s.run_constructors( &Default::default(), - BasicBackend(MemoryDB::new()), + BasicBackend(journaldb::new_memory_db()), )?; } } @@ -624,7 +623,7 @@ impl Spec { // basic accounts in spec. { - let mut t = factories.trie.create(db.as_hashdb_mut(), &mut root); + let mut t = factories.trie.create(db.as_hash_db_mut(), &mut root); for (address, account) in self.genesis_state.get().iter() { t.insert(&**address, &account.rlp())?; @@ -635,7 +634,7 @@ impl Spec { db.note_non_null_account(address); account.insert_additional( &mut *factories.accountdb.create( - db.as_hashdb_mut(), + db.as_hash_db_mut(), keccak(address), ), &factories.trie, @@ -792,7 +791,7 @@ impl Spec { self.genesis_state = s; let _ = self.run_constructors( &Default::default(), - BasicBackend(MemoryDB::new()), + BasicBackend(journaldb::new_memory_db()), )?; Ok(()) @@ -813,7 +812,7 @@ impl Spec { /// Ensure that the given state DB has the trie nodes in for the genesis state. pub fn ensure_db_good(&self, db: T, factories: &Factories) -> Result { - if db.as_hashdb().contains(&self.state_root()) { + if db.as_hash_db().contains(&self.state_root()) { return Ok(db); } @@ -860,7 +859,7 @@ impl Spec { None, ); - self.ensure_db_good(BasicBackend(db.as_hashdb_mut()), &factories) + self.ensure_db_good(BasicBackend(db.as_hash_db_mut()), &factories) .map_err(|e| format!("Unable to initialize genesis state: {}", e))?; let call = |a, d| { @@ -886,7 +885,7 @@ impl Spec { }.fake_sign(from); let res = ::state::prove_transaction_virtual( - db.as_hashdb_mut(), + db.as_hash_db_mut(), *genesis.state_root(), &tx, self.engine.machine(), diff --git a/ethcore/src/state/account.rs b/ethcore/src/state/account.rs index 483df7ba19..5f718a944e 100644 --- a/ethcore/src/state/account.rs +++ b/ethcore/src/state/account.rs @@ -22,7 +22,7 @@ use std::collections::{HashMap, BTreeMap}; use hash::{KECCAK_EMPTY, KECCAK_NULL_RLP, keccak}; use ethereum_types::{H256, U256, Address}; use error::Error; -use hashdb::HashDB; +use hash_db::HashDB; use keccak_hasher::KeccakHasher; use kvdb::DBValue; use bytes::{Bytes, ToPretty}; @@ -253,7 +253,7 @@ impl Account { } fn get_and_cache_storage(storage_root: &H256, storage_cache: &mut LruCache, db: &HashDB, key: &H256) -> TrieResult { - let db = SecTrieDB::new(db, storage_root)?; + let db = SecTrieDB::new(&db, storage_root)?; let panicky_decoder = |bytes:&[u8]| ::rlp::decode(&bytes).expect("decoding db value failed"); let item: U256 = db.get_with(key, panicky_decoder)?.unwrap_or_else(U256::zero); let value: H256 = item.into(); @@ -591,7 +591,7 @@ impl Account { pub fn prove_storage(&self, db: &HashDB, storage_key: H256) -> TrieResult<(Vec, H256)> { let mut recorder = Recorder::new(); - let trie = TrieDB::new(db, &self.storage_root)?; + let trie = TrieDB::new(&db, &self.storage_root)?; let item: U256 = { let panicky_decoder = |bytes:&[u8]| ::rlp::decode(bytes).expect("decoding db value failed"); let query = (&mut recorder, panicky_decoder); @@ -617,7 +617,7 @@ impl fmt::Debug for Account { mod tests { use rlp_compress::{compress, decompress, snapshot_swapper}; use ethereum_types::{H256, Address}; - use memorydb::MemoryDB; + use journaldb::new_memory_db; use bytes::Bytes; use super::*; use account_db::*; @@ -633,7 +633,7 @@ mod tests { #[test] fn storage_at() { - let mut db = MemoryDB::new(); + let mut db = new_memory_db(); let mut db = AccountDBMut::new(&mut db, &Address::new()); let rlp = { let mut a = Account::new_contract(69.into(), 0.into(), KECCAK_NULL_RLP); @@ -652,7 +652,7 @@ mod tests { #[test] fn note_code() { - let mut db = MemoryDB::new(); + let mut db = new_memory_db(); let mut db = AccountDBMut::new(&mut db, &Address::new()); let rlp = { @@ -672,7 +672,7 @@ mod tests { #[test] fn commit_storage() { let mut a = Account::new_contract(69.into(), 0.into(), KECCAK_NULL_RLP); - let mut db = MemoryDB::new(); + let mut db = new_memory_db(); let mut db = AccountDBMut::new(&mut db, &Address::new()); a.set_storage(0.into(), 0x1234.into()); assert_eq!(a.storage_root(), None); @@ -683,7 +683,7 @@ mod tests { #[test] fn commit_remove_commit_storage() { let mut a = Account::new_contract(69.into(), 0.into(), KECCAK_NULL_RLP); - let mut db = MemoryDB::new(); + let mut db = new_memory_db(); let mut db = AccountDBMut::new(&mut db, &Address::new()); a.set_storage(0.into(), 0x1234.into()); a.commit_storage(&Default::default(), &mut db).unwrap(); @@ -697,7 +697,7 @@ mod tests { #[test] fn commit_code() { let mut a = Account::new_contract(69.into(), 0.into(), KECCAK_NULL_RLP); - let mut db = MemoryDB::new(); + let mut db = new_memory_db(); let mut db = AccountDBMut::new(&mut db, &Address::new()); a.init_code(vec![0x55, 0x44, 0xffu8]); assert_eq!(a.code_filth, Filth::Dirty); @@ -709,7 +709,7 @@ mod tests { #[test] fn reset_code() { let mut a = Account::new_contract(69.into(), 0.into(), KECCAK_NULL_RLP); - let mut db = MemoryDB::new(); + let mut db = new_memory_db(); let mut db = AccountDBMut::new(&mut db, &Address::new()); a.init_code(vec![0x55, 0x44, 0xffu8]); assert_eq!(a.code_filth, Filth::Dirty); diff --git a/ethcore/src/state/backend.rs b/ethcore/src/state/backend.rs index 2593f9a5d7..11e73edb3a 100644 --- a/ethcore/src/state/backend.rs +++ b/ethcore/src/state/backend.rs @@ -27,18 +27,19 @@ use std::sync::Arc; use state::Account; use parking_lot::Mutex; use ethereum_types::{Address, H256}; -use memorydb::MemoryDB; -use hashdb::{AsHashDB, HashDB}; +use memory_db::MemoryDB; +use hash_db::{AsHashDB, HashDB}; use kvdb::DBValue; use keccak_hasher::KeccakHasher; +use journaldb::AsKeyedHashDB; /// State backend. See module docs for more details. pub trait Backend: Send { /// Treat the backend as a read-only hashdb. - fn as_hashdb(&self) -> &HashDB; + fn as_hash_db(&self) -> &HashDB; /// Treat the backend as a writeable hashdb. - fn as_hashdb_mut(&mut self) -> &mut HashDB; + fn as_hash_db_mut(&mut self) -> &mut HashDB; /// Add an account entry to the cache. fn add_to_account_cache(&mut self, addr: Address, data: Option, modified: bool); @@ -82,14 +83,17 @@ pub struct ProofCheck(MemoryDB); impl ProofCheck { /// Create a new `ProofCheck` backend from the given state items. pub fn new(proof: &[DBValue]) -> Self { - let mut db = MemoryDB::::new(); + let mut db = journaldb::new_memory_db(); for item in proof { db.insert(item); } ProofCheck(db) } } -impl HashDB for ProofCheck { +impl journaldb::KeyedHashDB for ProofCheck { fn keys(&self) -> HashMap { self.0.keys() } +} + +impl HashDB for ProofCheck { fn get(&self, key: &H256) -> Option { self.0.get(key) } @@ -110,13 +114,13 @@ impl HashDB for ProofCheck { } impl AsHashDB for ProofCheck { - fn as_hashdb(&self) -> &HashDB { self } - fn as_hashdb_mut(&mut self) -> &mut HashDB { self } + fn as_hash_db(&self) -> &HashDB { self } + fn as_hash_db_mut(&mut self) -> &mut HashDB { self } } impl Backend for ProofCheck { - fn as_hashdb(&self) -> &HashDB { self } - fn as_hashdb_mut(&mut self) -> &mut HashDB { self } + fn as_hash_db(&self) -> &HashDB { self } + fn as_hash_db_mut(&mut self) -> &mut HashDB { self } fn add_to_account_cache(&mut self, _addr: Address, _data: Option, _modified: bool) {} fn cache_code(&self, _hash: H256, _code: Arc>) {} fn get_cached_account(&self, _addr: &Address) -> Option> { None } @@ -135,26 +139,32 @@ impl Backend for ProofCheck { /// The proof-of-execution can be extracted with `extract_proof`. /// /// This doesn't cache anything or rely on the canonical state caches. -pub struct Proving> { +pub struct Proving { base: H, // state we're proving values from. changed: MemoryDB, // changed state via insertions. proof: Mutex>, } +impl AsKeyedHashDB for Proving { + fn as_keyed_hash_db(&self) -> &journaldb::KeyedHashDB { self } +} + impl + Send + Sync> AsHashDB for Proving { - fn as_hashdb(&self) -> &HashDB { self } - fn as_hashdb_mut(&mut self) -> &mut HashDB { self } + fn as_hash_db(&self) -> &HashDB { self } + fn as_hash_db_mut(&mut self) -> &mut HashDB { self } } -impl + Send + Sync> HashDB for Proving { +impl journaldb::KeyedHashDB for Proving { fn keys(&self) -> HashMap { - let mut keys = self.base.as_hashdb().keys(); + let mut keys = self.base.as_keyed_hash_db().keys(); keys.extend(self.changed.keys()); keys } +} +impl + Send + Sync> HashDB for Proving { fn get(&self, key: &H256) -> Option { - match self.base.as_hashdb().get(key) { + match self.base.as_hash_db().get(key) { Some(val) => { self.proof.lock().insert(val.clone()); Some(val) @@ -184,9 +194,9 @@ impl + Send + Sync> HashDB + Send + Sync> Backend for Proving { - fn as_hashdb(&self) -> &HashDB { self } + fn as_hash_db(&self) -> &HashDB { self } - fn as_hashdb_mut(&mut self) -> &mut HashDB { self } + fn as_hash_db_mut(&mut self) -> &mut HashDB { self } fn add_to_account_cache(&mut self, _: Address, _: Option, _: bool) { } @@ -211,7 +221,7 @@ impl> Proving { pub fn new(base: H) -> Self { Proving { base: base, - changed: MemoryDB::::new(), + changed: journaldb::new_memory_db(), proof: Mutex::new(HashSet::new()), } } @@ -238,12 +248,12 @@ impl + Clone> Clone for Proving { pub struct Basic(pub H); impl + Send + Sync> Backend for Basic { - fn as_hashdb(&self) -> &HashDB { - self.0.as_hashdb() + fn as_hash_db(&self) -> &HashDB { + self.0.as_hash_db() } - fn as_hashdb_mut(&mut self) -> &mut HashDB { - self.0.as_hashdb_mut() + fn as_hash_db_mut(&mut self) -> &mut HashDB { + self.0.as_hash_db_mut() } fn add_to_account_cache(&mut self, _: Address, _: Option, _: bool) { } diff --git a/ethcore/src/state/mod.rs b/ethcore/src/state/mod.rs index 8cc06fa83c..a585d34865 100644 --- a/ethcore/src/state/mod.rs +++ b/ethcore/src/state/mod.rs @@ -43,7 +43,7 @@ use state_db::StateDB; use factory::VmFactory; use ethereum_types::{H256, U256, Address}; -use hashdb::{HashDB, AsHashDB}; +use hash_db::{HashDB, AsHashDB}; use keccak_hasher::KeccakHasher; use kvdb::DBValue; use bytes::Bytes; @@ -366,7 +366,7 @@ impl State { let mut root = H256::new(); { // init trie and reset root to null - let _ = factories.trie.create(db.as_hashdb_mut(), &mut root); + let _ = factories.trie.create(db.as_hash_db_mut(), &mut root); } State { @@ -381,7 +381,7 @@ impl State { /// Creates new state with existing state root pub fn from_existing(db: B, root: H256, account_start_nonce: U256, factories: Factories) -> TrieResult> { - if !db.as_hashdb().contains(&root) { + if !db.as_hash_db().contains(&root) { return Err(Box::new(TrieError::InvalidStateRoot(root))); } @@ -665,8 +665,8 @@ impl State { let trie_res = self.db.get_cached(address, |acc| match acc { None => Ok(H256::new()), Some(a) => { - let account_db = self.factories.accountdb.readonly(self.db.as_hashdb(), a.address_hash(address)); - f_at(a, account_db.as_hashdb(), key) + let account_db = self.factories.accountdb.readonly(self.db.as_hash_db(), a.address_hash(address)); + f_at(a, account_db.as_hash_db(), key) } }); @@ -677,8 +677,8 @@ impl State { // otherwise cache the account localy and cache storage key there. if let Some(ref mut acc) = local_account { if let Some(ref account) = acc.account { - let account_db = self.factories.accountdb.readonly(self.db.as_hashdb(), account.address_hash(address)); - return f_at(account, account_db.as_hashdb(), key) + let account_db = self.factories.accountdb.readonly(self.db.as_hash_db(), account.address_hash(address)); + return f_at(account, account_db.as_hash_db(), key) } else { return Ok(H256::new()) } @@ -689,12 +689,13 @@ impl State { if self.db.is_known_null(address) { return Ok(H256::zero()) } // account is not found in the global cache, get from the DB and insert into local - let db = self.factories.trie.readonly(self.db.as_hashdb(), &self.root).expect(SEC_TRIE_DB_UNWRAP_STR); + let db = &self.db.as_hash_db(); + let db = self.factories.trie.readonly(db, &self.root).expect(SEC_TRIE_DB_UNWRAP_STR); let from_rlp = |b: &[u8]| Account::from_rlp(b).expect("decoding db value failed"); let maybe_acc = db.get_with(address, from_rlp)?; let r = maybe_acc.as_ref().map_or(Ok(H256::new()), |a| { - let account_db = self.factories.accountdb.readonly(self.db.as_hashdb(), a.address_hash(address)); - f_at(a, account_db.as_hashdb(), key) + let account_db = self.factories.accountdb.readonly(self.db.as_hash_db(), a.address_hash(address)); + f_at(a, account_db.as_hash_db(), key) }); self.insert_cache(address, AccountEntry::new_clean(maybe_acc)); r @@ -887,9 +888,9 @@ impl State { if let Some(ref mut account) = a.account { let addr_hash = account.address_hash(address); { - let mut account_db = self.factories.accountdb.create(self.db.as_hashdb_mut(), addr_hash); - account.commit_storage(&self.factories.trie, account_db.as_hashdb_mut())?; - account.commit_code(account_db.as_hashdb_mut()); + let mut account_db = self.factories.accountdb.create(self.db.as_hash_db_mut(), addr_hash); + account.commit_storage(&self.factories.trie, account_db.as_hash_db_mut())?; + account.commit_code(account_db.as_hash_db_mut()); } if !account.is_empty() { self.db.note_non_null_account(address); @@ -898,7 +899,7 @@ impl State { } { - let mut trie = self.factories.trie.from_existing(self.db.as_hashdb_mut(), &mut self.root)?; + let mut trie = self.factories.trie.from_existing(self.db.as_hash_db_mut(), &mut self.root)?; for (address, ref mut a) in accounts.iter_mut().filter(|&(_, ref a)| a.is_dirty()) { a.state = AccountState::Committed; match a.account { @@ -981,7 +982,8 @@ impl State { let mut result = BTreeMap::new(); - let trie = self.factories.trie.readonly(self.db.as_hashdb(), &self.root)?; + let db = &self.db.as_hash_db(); + let trie = self.factories.trie.readonly(db, &self.root)?; // put trie in cache for item in trie.iter()? { @@ -1011,10 +1013,11 @@ impl State { fn account_to_pod_account(&self, account: &Account, address: &Address) -> Result { let mut pod_storage = BTreeMap::new(); let addr_hash = account.address_hash(address); - let accountdb = self.factories.accountdb.readonly(self.db.as_hashdb(), addr_hash); + let accountdb = self.factories.accountdb.readonly(self.db.as_hash_db(), addr_hash); let root = account.base_storage_root(); - let trie = self.factories.trie.readonly(accountdb.as_hashdb(), &root)?; + let accountdb = &accountdb.as_hash_db(); + let trie = self.factories.trie.readonly(accountdb, &root)?; for o_kv in trie.iter()? { if let Ok((key, val)) = o_kv { pod_storage.insert(key[..].into(), U256::from(&val[..]).into()); @@ -1134,8 +1137,8 @@ impl State { // check local cache first if let Some(ref mut maybe_acc) = self.cache.borrow_mut().get_mut(a) { if let Some(ref mut account) = maybe_acc.account { - let accountdb = self.factories.accountdb.readonly(self.db.as_hashdb(), account.address_hash(a)); - if Self::update_account_cache(require, account, &self.db, accountdb.as_hashdb()) { + let accountdb = self.factories.accountdb.readonly(self.db.as_hash_db(), account.address_hash(a)); + if Self::update_account_cache(require, account, &self.db, accountdb.as_hash_db()) { return Ok(f(Some(account))); } else { return Err(Box::new(TrieError::IncompleteDatabase(H256::from(a)))); @@ -1146,8 +1149,8 @@ impl State { // check global cache let result = self.db.get_cached(a, |mut acc| { if let Some(ref mut account) = acc { - let accountdb = self.factories.accountdb.readonly(self.db.as_hashdb(), account.address_hash(a)); - if !Self::update_account_cache(require, account, &self.db, accountdb.as_hashdb()) { + let accountdb = self.factories.accountdb.readonly(self.db.as_hash_db(), account.address_hash(a)); + if !Self::update_account_cache(require, account, &self.db, accountdb.as_hash_db()) { return Err(Box::new(TrieError::IncompleteDatabase(H256::from(a)))); } } @@ -1160,12 +1163,13 @@ impl State { if check_null && self.db.is_known_null(a) { return Ok(f(None)); } // not found in the global cache, get from the DB and insert into local - let db = self.factories.trie.readonly(self.db.as_hashdb(), &self.root)?; + let db = &self.db.as_hash_db(); + let db = self.factories.trie.readonly(db, &self.root)?; let from_rlp = |b: &[u8]| Account::from_rlp(b).expect("decoding db value failed"); let mut maybe_acc = db.get_with(a, from_rlp)?; if let Some(ref mut account) = maybe_acc.as_mut() { - let accountdb = self.factories.accountdb.readonly(self.db.as_hashdb(), account.address_hash(a)); - if !Self::update_account_cache(require, account, &self.db, accountdb.as_hashdb()) { + let accountdb = self.factories.accountdb.readonly(self.db.as_hash_db(), account.address_hash(a)); + if !Self::update_account_cache(require, account, &self.db, accountdb.as_hash_db()) { return Err(Box::new(TrieError::IncompleteDatabase(H256::from(a)))); } } @@ -1192,7 +1196,8 @@ impl State { Some(acc) => self.insert_cache(a, AccountEntry::new_clean_cached(acc)), None => { let maybe_acc = if !self.db.is_known_null(a) { - let db = self.factories.trie.readonly(self.db.as_hashdb(), &self.root)?; + let db = &self.db.as_hash_db(); + let db = self.factories.trie.readonly(db, &self.root)?; let from_rlp = |b:&[u8]| { Account::from_rlp(b).expect("decoding db value failed") }; AccountEntry::new_clean(db.get_with(a, from_rlp)?) } else { @@ -1220,9 +1225,9 @@ impl State { if require_code { let addr_hash = account.address_hash(a); - let accountdb = self.factories.accountdb.readonly(self.db.as_hashdb(), addr_hash); + let accountdb = self.factories.accountdb.readonly(self.db.as_hash_db(), addr_hash); - if !Self::update_account_cache(RequireCache::Code, &mut account, &self.db, accountdb.as_hashdb()) { + if !Self::update_account_cache(RequireCache::Code, &mut account, &self.db, accountdb.as_hash_db()) { return Err(Box::new(TrieError::IncompleteDatabase(H256::from(a)))) } } @@ -1245,7 +1250,8 @@ impl State { /// `account_key` == keccak(address) pub fn prove_account(&self, account_key: H256) -> TrieResult<(Vec, BasicAccount)> { let mut recorder = Recorder::new(); - let trie = TrieDB::new(self.db.as_hashdb(), &self.root)?; + let db = &self.db.as_hash_db(); + let trie = TrieDB::new(db, &self.root)?; let maybe_account: Option = { let panicky_decoder = |bytes: &[u8]| { ::rlp::decode(bytes).expect(&format!("prove_account, could not query trie for account key={}", &account_key)) @@ -1271,15 +1277,16 @@ impl State { pub fn prove_storage(&self, account_key: H256, storage_key: H256) -> TrieResult<(Vec, H256)> { // TODO: probably could look into cache somehow but it's keyed by // address, not keccak(address). - let trie = TrieDB::new(self.db.as_hashdb(), &self.root)?; + let db = &self.db.as_hash_db(); + let trie = TrieDB::new(db, &self.root)?; let from_rlp = |b: &[u8]| Account::from_rlp(b).expect("decoding db value failed"); let acc = match trie.get_with(&account_key, from_rlp)? { Some(acc) => acc, None => return Ok((Vec::new(), H256::new())), }; - let account_db = self.factories.accountdb.readonly(self.db.as_hashdb(), account_key); - acc.prove_storage(account_db.as_hashdb(), storage_key) + let account_db = self.factories.accountdb.readonly(self.db.as_hash_db(), account_key); + acc.prove_storage(account_db.as_hash_db(), storage_key) } } diff --git a/ethcore/src/state_db.rs b/ethcore/src/state_db.rs index 1ceb8ff0c5..066a4f6162 100644 --- a/ethcore/src/state_db.rs +++ b/ethcore/src/state_db.rs @@ -25,7 +25,7 @@ use byteorder::{LittleEndian, ByteOrder}; use db::COL_ACCOUNT_BLOOM; use ethereum_types::{H256, Address}; use hash::keccak; -use hashdb::HashDB; +use hash_db::HashDB; use journaldb::JournalDB; use keccak_hasher::KeccakHasher; use kvdb::{KeyValueDB, DBTransaction, DBValue}; @@ -313,13 +313,13 @@ impl StateDB { } /// Conversion method to interpret self as `HashDB` reference - pub fn as_hashdb(&self) -> &HashDB { - self.db.as_hashdb() + pub fn as_hash_db(&self) -> &HashDB { + self.db.as_hash_db() } /// Conversion method to interpret self as mutable `HashDB` reference - pub fn as_hashdb_mut(&mut self) -> &mut HashDB { - self.db.as_hashdb_mut() + pub fn as_hash_db_mut(&mut self) -> &mut HashDB { + self.db.as_hash_db_mut() } /// Clone the database. @@ -407,10 +407,10 @@ impl StateDB { } impl state::Backend for StateDB { - fn as_hashdb(&self) -> &HashDB { self.db.as_hashdb() } + fn as_hash_db(&self) -> &HashDB { self.db.as_hash_db() } - fn as_hashdb_mut(&mut self) -> &mut HashDB { - self.db.as_hashdb_mut() + fn as_hash_db_mut(&mut self) -> &mut HashDB { + self.db.as_hash_db_mut() } fn add_to_account_cache(&mut self, addr: Address, data: Option, modified: bool) { diff --git a/ethcore/sync/Cargo.toml b/ethcore/sync/Cargo.toml index 9db9331626..bc7a80e670 100644 --- a/ethcore/sync/Cargo.toml +++ b/ethcore/sync/Cargo.toml @@ -19,7 +19,7 @@ ethereum-types = "0.4" ethkey = { path = "../../accounts/ethkey" } ethstore = { path = "../../accounts/ethstore" } fastmap = { path = "../../util/fastmap" } -hashdb = "0.3.0" +hash-db = "0.11.0" heapsize = "0.4" keccak-hash = "0.1" keccak-hasher = { path = "../../util/keccak-hasher" } diff --git a/ethcore/vm/Cargo.toml b/ethcore/vm/Cargo.toml index bd5fb238fb..19b84a6ecc 100644 --- a/ethcore/vm/Cargo.toml +++ b/ethcore/vm/Cargo.toml @@ -7,7 +7,7 @@ authors = ["Parity Technologies "] byteorder = "1.0" parity-bytes = "0.1" ethereum-types = "0.4" -patricia-trie = "0.3.0" +trie-db = "0.11.0" patricia-trie-ethereum = { path = "../../util/patricia-trie-ethereum" } log = "0.4" ethjson = { path = "../../json" } diff --git a/ethcore/vm/src/lib.rs b/ethcore/vm/src/lib.rs index a8bb440412..f239e40568 100644 --- a/ethcore/vm/src/lib.rs +++ b/ethcore/vm/src/lib.rs @@ -22,7 +22,7 @@ extern crate ethjson; extern crate rlp; extern crate keccak_hash as hash; extern crate patricia_trie_ethereum as ethtrie; -extern crate patricia_trie as trie; +extern crate trie_db as trie; mod action_params; mod call_type; diff --git a/rpc/Cargo.toml b/rpc/Cargo.toml index 765e868de2..c6c59dc15a 100644 --- a/rpc/Cargo.toml +++ b/rpc/Cargo.toml @@ -59,7 +59,7 @@ keccak-hash = "0.1.2" parity-runtime = { path = "../util/runtime" } parity-updater = { path = "../updater" } parity-version = { path = "../util/version" } -patricia-trie = "0.3.0" +trie-db = "0.11.0" rlp = { version = "0.3.0", features = ["ethereum"] } stats = { path = "../util/stats" } vm = { path = "../ethcore/vm" } diff --git a/rpc/src/lib.rs b/rpc/src/lib.rs index c7f0ad09d4..4a90fbe693 100644 --- a/rpc/src/lib.rs +++ b/rpc/src/lib.rs @@ -63,7 +63,7 @@ extern crate keccak_hash as hash; extern crate parity_runtime; extern crate parity_updater as updater; extern crate parity_version as version; -extern crate patricia_trie as trie; +extern crate trie_db as trie; extern crate eip_712; extern crate rlp; extern crate stats; diff --git a/util/journaldb/Cargo.toml b/util/journaldb/Cargo.toml index 20657f2ca4..045b42d662 100644 --- a/util/journaldb/Cargo.toml +++ b/util/journaldb/Cargo.toml @@ -8,12 +8,12 @@ license = "GPL3" [dependencies] parity-bytes = "0.1" ethereum-types = "0.4" -hashdb = "0.3.0" +hash-db = "0.11.0" heapsize = "0.4" keccak-hasher = { path = "../keccak-hasher" } kvdb = "0.1" log = "0.4" -memorydb = "0.3.0" +memory-db = "0.11.0" parking_lot = "0.7" fastmap = { path = "../../util/fastmap" } rlp = { version = "0.3.0", features = ["ethereum"] } diff --git a/util/journaldb/src/archivedb.rs b/util/journaldb/src/archivedb.rs index a6dcd29377..a068919a78 100644 --- a/util/journaldb/src/archivedb.rs +++ b/util/journaldb/src/archivedb.rs @@ -23,12 +23,12 @@ use std::sync::Arc; use bytes::Bytes; use ethereum_types::H256; -use hashdb::*; +use hash_db::{HashDB}; use keccak_hasher::KeccakHasher; use kvdb::{KeyValueDB, DBTransaction, DBValue}; use rlp::{encode, decode}; use super::{DB_PREFIX_LEN, LATEST_ERA_KEY, error_key_already_exists, error_negatively_reference_hash}; -use super::memorydb::*; +use super::memory_db::*; use traits::JournalDB; /// Implementation of the `HashDB` trait for a disk-backed database with a memory overlay @@ -52,7 +52,7 @@ impl ArchiveDB { .expect("Low-level database error.") .map(|val| decode::(&val).expect("decoding db value failed")); ArchiveDB { - overlay: MemoryDB::new(), + overlay: ::new_memory_db(), backing, latest_era, column, @@ -62,31 +62,14 @@ impl ArchiveDB { fn payload(&self, key: &H256) -> Option { self.backing.get(self.column, key).expect("Low-level database error. Some issue with your hard disk?") } + } impl HashDB for ArchiveDB { - fn keys(&self) -> HashMap { - let mut ret: HashMap = self.backing.iter(self.column) - .map(|(key, _)| (H256::from_slice(&*key), 1)) - .collect(); - - for (key, refs) in self.overlay.keys() { - match ret.entry(key) { - Entry::Occupied(mut entry) => { - *entry.get_mut() += refs; - }, - Entry::Vacant(entry) => { - entry.insert(refs); - } - } - } - ret - } - fn get(&self, key: &H256) -> Option { if let Some((d, rc)) = self.overlay.raw(key) { if rc > 0 { - return Some(d); + return Some(d.clone()); } } self.payload(key) @@ -109,7 +92,28 @@ impl HashDB for ArchiveDB { } } +impl ::traits::KeyedHashDB for ArchiveDB { + fn keys(&self) -> HashMap { + let mut ret: HashMap = self.backing.iter(self.column) + .map(|(key, _)| (H256::from_slice(&*key), 1)) + .collect(); + + for (key, refs) in self.overlay.keys() { + match ret.entry(key) { + Entry::Occupied(mut entry) => { + *entry.get_mut() += refs; + }, + Entry::Vacant(entry) => { + entry.insert(refs); + } + } + } + ret + } +} + impl JournalDB for ArchiveDB { + fn boxed_clone(&self) -> Box { Box::new(ArchiveDB { overlay: self.overlay.clone(), @@ -202,7 +206,7 @@ impl JournalDB for ArchiveDB { mod tests { use keccak::keccak; - use hashdb::HashDB; + use hash_db::HashDB; use super::*; use {kvdb_memorydb, JournalDB}; diff --git a/util/journaldb/src/as_hash_db_impls.rs b/util/journaldb/src/as_hash_db_impls.rs index 203a5be676..8a380ea56a 100644 --- a/util/journaldb/src/as_hash_db_impls.rs +++ b/util/journaldb/src/as_hash_db_impls.rs @@ -15,7 +15,7 @@ // along with Parity Ethereum. If not, see . //! Impls of the `AsHashDB` upcast trait for all different variants of DB -use hashdb::{HashDB, AsHashDB}; +use hash_db::{HashDB, AsHashDB}; use keccak_hasher::KeccakHasher; use archivedb::ArchiveDB; use earlymergedb::EarlyMergeDB; @@ -23,28 +23,49 @@ use overlayrecentdb::OverlayRecentDB; use refcounteddb::RefCountedDB; use overlaydb::OverlayDB; use kvdb::DBValue; +use crate::{KeyedHashDB, AsKeyedHashDB}; impl AsHashDB for ArchiveDB { - fn as_hashdb(&self) -> &HashDB { self } - fn as_hashdb_mut(&mut self) -> &mut HashDB { self } + fn as_hash_db(&self) -> &HashDB { self } + fn as_hash_db_mut(&mut self) -> &mut HashDB { self } } impl AsHashDB for EarlyMergeDB { - fn as_hashdb(&self) -> &HashDB { self } - fn as_hashdb_mut(&mut self) -> &mut HashDB { self } + fn as_hash_db(&self) -> &HashDB { self } + fn as_hash_db_mut(&mut self) -> &mut HashDB { self } } impl AsHashDB for OverlayRecentDB { - fn as_hashdb(&self) -> &HashDB { self } - fn as_hashdb_mut(&mut self) -> &mut HashDB { self } + fn as_hash_db(&self) -> &HashDB { self } + fn as_hash_db_mut(&mut self) -> &mut HashDB { self } } impl AsHashDB for RefCountedDB { - fn as_hashdb(&self) -> &HashDB { self } - fn as_hashdb_mut(&mut self) -> &mut HashDB { self } + fn as_hash_db(&self) -> &HashDB { self } + fn as_hash_db_mut(&mut self) -> &mut HashDB { self } } impl AsHashDB for OverlayDB { - fn as_hashdb(&self) -> &HashDB { self } - fn as_hashdb_mut(&mut self) -> &mut HashDB { self } + fn as_hash_db(&self) -> &HashDB { self } + fn as_hash_db_mut(&mut self) -> &mut HashDB { self } +} + +impl AsKeyedHashDB for ArchiveDB { + fn as_keyed_hash_db(&self) -> &KeyedHashDB { self } +} + +impl AsKeyedHashDB for EarlyMergeDB { + fn as_keyed_hash_db(&self) -> &KeyedHashDB { self } +} + +impl AsKeyedHashDB for OverlayRecentDB { + fn as_keyed_hash_db(&self) -> &KeyedHashDB { self } +} + +impl AsKeyedHashDB for RefCountedDB { + fn as_keyed_hash_db(&self) -> &KeyedHashDB { self } +} + +impl AsKeyedHashDB for OverlayDB { + fn as_keyed_hash_db(&self) -> &KeyedHashDB { self } } diff --git a/util/journaldb/src/earlymergedb.rs b/util/journaldb/src/earlymergedb.rs index aac1af0169..2a55200c49 100644 --- a/util/journaldb/src/earlymergedb.rs +++ b/util/journaldb/src/earlymergedb.rs @@ -23,11 +23,11 @@ use std::sync::Arc; use bytes::Bytes; use ethereum_types::H256; -use hashdb::*; +use hash_db::{HashDB}; use heapsize::HeapSizeOf; use keccak_hasher::KeccakHasher; use kvdb::{KeyValueDB, DBTransaction, DBValue}; -use memorydb::*; +use memory_db::*; use parking_lot::RwLock; use rlp::{encode, decode}; use super::{DB_PREFIX_LEN, LATEST_ERA_KEY, error_negatively_reference_hash, error_key_already_exists}; @@ -120,7 +120,7 @@ impl EarlyMergeDB { let (latest_era, refs) = EarlyMergeDB::read_refs(&*backing, col); let refs = Some(Arc::new(RwLock::new(refs))); EarlyMergeDB { - overlay: MemoryDB::new(), + overlay: ::new_memory_db(), backing: backing, refs: refs, latest_era: latest_era, @@ -285,31 +285,14 @@ impl EarlyMergeDB { } (latest_era, refs) } + } impl HashDB for EarlyMergeDB { - fn keys(&self) -> HashMap { - let mut ret: HashMap = self.backing.iter(self.column) - .map(|(key, _)| (H256::from_slice(&*key), 1)) - .collect(); - - for (key, refs) in self.overlay.keys() { - match ret.entry(key) { - Entry::Occupied(mut entry) => { - *entry.get_mut() += refs; - }, - Entry::Vacant(entry) => { - entry.insert(refs); - } - } - } - ret - } - fn get(&self, key: &H256) -> Option { if let Some((d, rc)) = self.overlay.raw(key) { if rc > 0 { - return Some(d) + return Some(d.clone()) } } self.payload(key) @@ -330,6 +313,26 @@ impl HashDB for EarlyMergeDB { } } +impl ::traits::KeyedHashDB for EarlyMergeDB { + fn keys(&self) -> HashMap { + let mut ret: HashMap = self.backing.iter(self.column) + .map(|(key, _)| (H256::from_slice(&*key), 1)) + .collect(); + + for (key, refs) in self.overlay.keys() { + match ret.entry(key) { + Entry::Occupied(mut entry) => { + *entry.get_mut() += refs; + }, + Entry::Vacant(entry) => { + entry.insert(refs); + } + } + } + ret + } +} + impl JournalDB for EarlyMergeDB { fn boxed_clone(&self) -> Box { Box::new(EarlyMergeDB { @@ -523,7 +526,7 @@ impl JournalDB for EarlyMergeDB { mod tests { use keccak::keccak; - use hashdb::HashDB; + use hash_db::HashDB; use super::*; use super::super::traits::JournalDB; use kvdb_memorydb; diff --git a/util/journaldb/src/lib.rs b/util/journaldb/src/lib.rs index 67ceeb848a..3eb6ee38c8 100644 --- a/util/journaldb/src/lib.rs +++ b/util/journaldb/src/lib.rs @@ -22,10 +22,10 @@ extern crate log; extern crate ethereum_types; extern crate parity_bytes as bytes; -extern crate hashdb; +extern crate hash_db; extern crate keccak_hasher; extern crate kvdb; -extern crate memorydb; +extern crate memory_db; extern crate parking_lot; extern crate fastmap; extern crate rlp; @@ -54,6 +54,11 @@ pub mod overlaydb; /// Export the `JournalDB` trait. pub use self::traits::JournalDB; +/// Export keyed hash trait +pub use self::traits::KeyedHashDB; +/// Export as keyed hash trait +pub use self::traits::AsKeyedHashDB; + /// Journal database operating strategy. #[derive(Debug, PartialEq, Clone, Copy)] pub enum Algorithm { @@ -158,6 +163,10 @@ fn error_negatively_reference_hash(hash: ðereum_types::H256) -> io::Error { io::Error::new(io::ErrorKind::Other, format!("Entry {} removed from database more times than it was added.", hash)) } +pub fn new_memory_db() -> memory_db::MemoryDB { + memory_db::MemoryDB::from_null_node(&rlp::NULL_RLP, rlp::NULL_RLP.as_ref().into()) +} + #[cfg(test)] mod tests { use super::Algorithm; diff --git a/util/journaldb/src/overlaydb.rs b/util/journaldb/src/overlaydb.rs index d7018d1edb..757a92e621 100644 --- a/util/journaldb/src/overlaydb.rs +++ b/util/journaldb/src/overlaydb.rs @@ -23,9 +23,9 @@ use std::sync::Arc; use ethereum_types::H256; use rlp::{Rlp, RlpStream, Encodable, DecoderError, Decodable, encode, decode}; -use hashdb::*; +use hash_db::{HashDB}; use keccak_hasher::KeccakHasher; -use memorydb::*; +use memory_db::*; use kvdb::{KeyValueDB, DBTransaction, DBValue}; use super::{error_negatively_reference_hash}; @@ -80,7 +80,7 @@ impl Decodable for Payload { impl OverlayDB { /// Create a new instance of OverlayDB given a `backing` database. pub fn new(backing: Arc, col: Option) -> OverlayDB { - OverlayDB{ overlay: MemoryDB::new(), backing: backing, column: col } + OverlayDB{ overlay: ::new_memory_db(), backing: backing, column: col } } /// Create a new instance of OverlayDB with an anonymous temporary database. @@ -153,9 +153,10 @@ impl OverlayDB { true } } + } -impl HashDB for OverlayDB { +impl crate::KeyedHashDB for OverlayDB { fn keys(&self) -> HashMap { let mut ret: HashMap = self.backing.iter(self.column) .map(|(key, _)| { @@ -178,13 +179,16 @@ impl HashDB for OverlayDB { ret } +} + +impl HashDB for OverlayDB { fn get(&self, key: &H256) -> Option { // return ok if positive; if negative, check backing - might be enough references there to make // it positive again. let k = self.overlay.raw(key); let memrc = { if let Some((d, rc)) = k { - if rc > 0 { return Some(d); } + if rc > 0 { return Some(d.clone()); } rc } else { 0 diff --git a/util/journaldb/src/overlayrecentdb.rs b/util/journaldb/src/overlayrecentdb.rs index 67f5ab8890..a48e59d91f 100644 --- a/util/journaldb/src/overlayrecentdb.rs +++ b/util/journaldb/src/overlayrecentdb.rs @@ -23,11 +23,11 @@ use std::sync::Arc; use bytes::Bytes; use ethereum_types::H256; -use hashdb::*; +use hash_db::{HashDB}; use heapsize::HeapSizeOf; use keccak_hasher::KeccakHasher; use kvdb::{KeyValueDB, DBTransaction, DBValue}; -use memorydb::*; +use memory_db::*; use parking_lot::RwLock; use fastmap::H256FastMap; use rlp::{Rlp, RlpStream, encode, decode, DecoderError, Decodable, Encodable}; @@ -157,7 +157,7 @@ impl OverlayRecentDB { pub fn new(backing: Arc, col: Option) -> OverlayRecentDB { let journal_overlay = Arc::new(RwLock::new(OverlayRecentDB::read_overlay(&*backing, col))); OverlayRecentDB { - transaction_overlay: MemoryDB::new(), + transaction_overlay: ::new_memory_db(), backing: backing, journal_overlay: journal_overlay, column: col, @@ -181,7 +181,7 @@ impl OverlayRecentDB { fn read_overlay(db: &KeyValueDB, col: Option) -> JournalOverlay { let mut journal = HashMap::new(); - let mut overlay = MemoryDB::new(); + let mut overlay = ::new_memory_db(); let mut count = 0; let mut latest_era = None; let mut earliest_era = None; @@ -233,6 +233,7 @@ impl OverlayRecentDB { cumulative_size: cumulative_size, } } + } #[inline] @@ -242,7 +243,28 @@ fn to_short_key(key: &H256) -> H256 { k } +impl ::traits::KeyedHashDB for OverlayRecentDB { + fn keys(&self) -> HashMap { + let mut ret: HashMap = self.backing.iter(self.column) + .map(|(key, _)| (H256::from_slice(&*key), 1)) + .collect(); + + for (key, refs) in self.transaction_overlay.keys() { + match ret.entry(key) { + Entry::Occupied(mut entry) => { + *entry.get_mut() += refs; + }, + Entry::Vacant(entry) => { + entry.insert(refs); + } + } + } + ret + } +} + impl JournalDB for OverlayRecentDB { + fn boxed_clone(&self) -> Box { Box::new(self.clone()) } @@ -365,7 +387,7 @@ impl JournalDB for OverlayRecentDB { for h in &journal.insertions { if let Some((d, rc)) = journal_overlay.backing_overlay.raw(&to_short_key(h)) { if rc > 0 { - canon_insertions.push((h.clone(), d)); //TODO: optimize this to avoid data copy + canon_insertions.push((h.clone(), d.clone())); //TODO: optimize this to avoid data copy } } } @@ -440,28 +462,10 @@ impl JournalDB for OverlayRecentDB { } impl HashDB for OverlayRecentDB { - fn keys(&self) -> HashMap { - let mut ret: HashMap = self.backing.iter(self.column) - .map(|(key, _)| (H256::from_slice(&*key), 1)) - .collect(); - - for (key, refs) in self.transaction_overlay.keys() { - match ret.entry(key) { - Entry::Occupied(mut entry) => { - *entry.get_mut() += refs; - }, - Entry::Vacant(entry) => { - entry.insert(refs); - } - } - } - ret - } - fn get(&self, key: &H256) -> Option { if let Some((d, rc)) = self.transaction_overlay.raw(key) { if rc > 0 { - return Some(d) + return Some(d.clone()) } } let v = { @@ -493,7 +497,7 @@ mod tests { use keccak::keccak; use super::*; - use hashdb::HashDB; + use hash_db::HashDB; use {kvdb_memorydb, JournalDB}; fn new_db() -> OverlayRecentDB { diff --git a/util/journaldb/src/refcounteddb.rs b/util/journaldb/src/refcounteddb.rs index 36cac3201a..bdd396a481 100644 --- a/util/journaldb/src/refcounteddb.rs +++ b/util/journaldb/src/refcounteddb.rs @@ -22,11 +22,11 @@ use std::sync::Arc; use bytes::Bytes; use ethereum_types::H256; -use hashdb::*; +use hash_db::{HashDB}; use heapsize::HeapSizeOf; use keccak_hasher::KeccakHasher; use kvdb::{KeyValueDB, DBTransaction, DBValue}; -use memorydb::MemoryDB; +use memory_db::MemoryDB; use overlaydb::OverlayDB; use rlp::{encode, decode}; use super::{DB_PREFIX_LEN, LATEST_ERA_KEY}; @@ -81,7 +81,6 @@ impl RefCountedDB { } impl HashDB for RefCountedDB { - fn keys(&self) -> HashMap { self.forward.keys() } fn get(&self, key: &H256) -> Option { self.forward.get(key) } fn contains(&self, key: &H256) -> bool { self.forward.contains(key) } fn insert(&mut self, value: &[u8]) -> H256 { let r = self.forward.insert(value); self.inserts.push(r.clone()); r } @@ -89,6 +88,10 @@ impl HashDB for RefCountedDB { fn remove(&mut self, key: &H256) { self.removes.push(key.clone()); } } +impl ::traits::KeyedHashDB for RefCountedDB { + fn keys(&self) -> HashMap { self.forward.keys() } +} + impl JournalDB for RefCountedDB { fn boxed_clone(&self) -> Box { Box::new(RefCountedDB { @@ -216,7 +219,7 @@ impl JournalDB for RefCountedDB { mod tests { use keccak::keccak; - use hashdb::HashDB; + use hash_db::HashDB; use super::*; use {JournalDB, kvdb_memorydb}; diff --git a/util/journaldb/src/traits.rs b/util/journaldb/src/traits.rs index 68ca57b96a..e6ce8acb04 100644 --- a/util/journaldb/src/traits.rs +++ b/util/journaldb/src/traits.rs @@ -21,13 +21,28 @@ use std::sync::Arc; use bytes::Bytes; use ethereum_types::H256; -use hashdb::HashDB; +use hash_db::{HashDB, AsHashDB}; use keccak_hasher::KeccakHasher; use kvdb::{self, DBTransaction, DBValue}; +use std::collections::HashMap; + + +/// expose keys of a hashDB for debugging or tests (slow). +pub trait KeyedHashDB: HashDB { + /// Primarily use for tests, highly inefficient. + fn keys(&self) -> HashMap; +} + +/// Upcast to `KeyedHashDB` +pub trait AsKeyedHashDB: AsHashDB { + /// Perform upcast to KeyedHashDB. + fn as_keyed_hash_db(&self) -> &KeyedHashDB; +} /// A `HashDB` which can manage a short-term journal potentially containing many forks of mutually /// exclusive actions. -pub trait JournalDB: HashDB { +pub trait JournalDB: KeyedHashDB { + /// Return a copy of ourself, in a box. fn boxed_clone(&self) -> Box; @@ -78,7 +93,7 @@ pub trait JournalDB: HashDB { fn flush(&self) {} /// Consolidate all the insertions and deletions in the given memory overlay. - fn consolidate(&mut self, overlay: ::memorydb::MemoryDB); + fn consolidate(&mut self, overlay: ::memory_db::MemoryDB); /// Commit all changes in a single batch #[cfg(test)] diff --git a/util/keccak-hasher/Cargo.toml b/util/keccak-hasher/Cargo.toml index f61e461e29..edeecda833 100644 --- a/util/keccak-hasher/Cargo.toml +++ b/util/keccak-hasher/Cargo.toml @@ -8,5 +8,5 @@ license = "GPL-3.0" [dependencies] ethereum-types = "0.4" tiny-keccak = "1.4.2" -hashdb = "0.3.0" +hash-db = "0.11.0" plain_hasher = "0.2" diff --git a/util/keccak-hasher/src/lib.rs b/util/keccak-hasher/src/lib.rs index e37b03ee7d..d9c9be5454 100644 --- a/util/keccak-hasher/src/lib.rs +++ b/util/keccak-hasher/src/lib.rs @@ -15,12 +15,12 @@ // along with Parity Ethereum. If not, see . //! Hasher implementation for the Keccak-256 hash -extern crate hashdb; +extern crate hash_db; extern crate ethereum_types; extern crate tiny_keccak; extern crate plain_hasher; -use hashdb::Hasher; +use hash_db::Hasher; use ethereum_types::H256; use tiny_keccak::Keccak; use plain_hasher::PlainHasher; diff --git a/util/patricia-trie-ethereum/Cargo.toml b/util/patricia-trie-ethereum/Cargo.toml index e6880691a1..8cb8664a5e 100644 --- a/util/patricia-trie-ethereum/Cargo.toml +++ b/util/patricia-trie-ethereum/Cargo.toml @@ -6,14 +6,15 @@ description = "Merkle-Patricia Trie (Ethereum Style)" license = "GPL-3.0" [dependencies] -patricia-trie = "0.3.0" +trie-db = "0.11.0" keccak-hasher = { version = "0.1.1", path = "../keccak-hasher" } -hashdb = "0.3.0" +hash-db = "0.11.0" rlp = "0.3.0" parity-bytes = "0.1" ethereum-types = "0.4" elastic-array = "0.10" [dev-dependencies] -memorydb = "0.3.0" +memory-db = "0.11.0" keccak-hash = "0.1.2" +journaldb = { path = "../journaldb" } diff --git a/util/patricia-trie-ethereum/src/lib.rs b/util/patricia-trie-ethereum/src/lib.rs index 7b48257662..ab44f4e837 100644 --- a/util/patricia-trie-ethereum/src/lib.rs +++ b/util/patricia-trie-ethereum/src/lib.rs @@ -16,11 +16,11 @@ //! Façade crate for `patricia_trie` for Ethereum specific impls -pub extern crate patricia_trie as trie; // `pub` because we need to import this crate for the tests in `patricia_trie` and there were issues: https://gist.github.com/dvdplm/869251ee557a1b4bd53adc7c971979aa +pub extern crate trie_db as trie; // `pub` because we need to import this crate for the tests in `patricia_trie` and there were issues: https://gist.github.com/dvdplm/869251ee557a1b4bd53adc7c971979aa extern crate elastic_array; extern crate parity_bytes; extern crate ethereum_types; -extern crate hashdb; +extern crate hash_db; extern crate keccak_hasher; extern crate rlp; @@ -42,18 +42,19 @@ pub type RlpCodec = RlpNodeCodec; /// /// # Example /// ``` -/// extern crate patricia_trie as trie; +/// extern crate trie_db as trie; /// extern crate patricia_trie_ethereum as ethtrie; -/// extern crate hashdb; +/// extern crate hash_db; /// extern crate keccak_hasher; -/// extern crate memorydb; +/// extern crate memory_db; /// extern crate ethereum_types; /// extern crate elastic_array; +/// extern crate journaldb; /// /// use trie::*; -/// use hashdb::*; +/// use hash_db::*; /// use keccak_hasher::KeccakHasher; -/// use memorydb::*; +/// use memory_db::*; /// use ethereum_types::H256; /// use ethtrie::{TrieDB, TrieDBMut}; /// use elastic_array::ElasticArray128; @@ -61,7 +62,7 @@ pub type RlpCodec = RlpNodeCodec; /// type DBValue = ElasticArray128; /// /// fn main() { -/// let mut memdb = MemoryDB::::new(); +/// let mut memdb = journaldb::new_memory_db(); /// let mut root = H256::new(); /// TrieDBMut::new(&mut memdb, &mut root).insert(b"foo", b"bar").unwrap(); /// let t = TrieDB::new(&memdb, &root).unwrap(); @@ -85,26 +86,27 @@ pub type FatDB<'db> = trie::FatDB<'db, KeccakHasher, RlpCodec>; /// # Example /// ``` -/// extern crate patricia_trie as trie; +/// extern crate trie_db as trie; /// extern crate patricia_trie_ethereum as ethtrie; -/// extern crate hashdb; +/// extern crate hash_db; /// extern crate keccak_hash; /// extern crate keccak_hasher; -/// extern crate memorydb; +/// extern crate memory_db; /// extern crate ethereum_types; /// extern crate elastic_array; +/// extern crate journaldb; /// /// use keccak_hash::KECCAK_NULL_RLP; /// use ethtrie::{TrieDBMut, trie::TrieMut}; /// use keccak_hasher::KeccakHasher; -/// use memorydb::*; +/// use memory_db::*; /// use ethereum_types::H256; /// use elastic_array::ElasticArray128; /// /// type DBValue = ElasticArray128; /// /// fn main() { -/// let mut memdb = MemoryDB::::new(); +/// let mut memdb = journaldb::new_memory_db(); /// let mut root = H256::new(); /// let mut t = TrieDBMut::new(&mut memdb, &mut root); /// assert!(t.is_empty()); diff --git a/util/patricia-trie-ethereum/src/rlp_node_codec.rs b/util/patricia-trie-ethereum/src/rlp_node_codec.rs index e9d1d74586..ea8aea8a77 100644 --- a/util/patricia-trie-ethereum/src/rlp_node_codec.rs +++ b/util/patricia-trie-ethereum/src/rlp_node_codec.rs @@ -18,7 +18,7 @@ use elastic_array::ElasticArray128; use ethereum_types::H256; -use hashdb::Hasher; +use hash_db::Hasher; use keccak_hasher::KeccakHasher; use rlp::{DecoderError, RlpStream, Rlp, Prototype}; use std::marker::PhantomData; @@ -28,13 +28,17 @@ use trie::{NibbleSlice, NodeCodec, node::Node, ChildReference}; #[derive(Default, Clone)] pub struct RlpNodeCodec {mark: PhantomData} +const HASHED_NULL_NODE_BYTES : [u8;32] = [0x56, 0xe8, 0x1f, 0x17, 0x1b, 0xcc, 0x55, 0xa6, 0xff, 0x83, 0x45, 0xe6, 0x92, 0xc0, 0xf8, 0x6e, 0x5b, 0x48, 0xe0, 0x1b, 0x99, 0x6c, 0xad, 0xc0, 0x01, 0x62, 0x2f, 0xb5, 0xe3, 0x63, 0xb4, 0x21]; +const HASHED_NULL_NODE : H256 = H256( HASHED_NULL_NODE_BYTES ); // NOTE: what we'd really like here is: // `impl NodeCodec for RlpNodeCodec where H::Out: Decodable` // but due to the current limitations of Rust const evaluation we can't // do `const HASHED_NULL_NODE: H::Out = H::Out( … … )`. Perhaps one day soon? impl NodeCodec for RlpNodeCodec { type Error = DecoderError; - const HASHED_NULL_NODE : H256 = H256( [0x56, 0xe8, 0x1f, 0x17, 0x1b, 0xcc, 0x55, 0xa6, 0xff, 0x83, 0x45, 0xe6, 0x92, 0xc0, 0xf8, 0x6e, 0x5b, 0x48, 0xe0, 0x1b, 0x99, 0x6c, 0xad, 0xc0, 0x01, 0x62, 0x2f, 0xb5, 0xe3, 0x63, 0xb4, 0x21] ); + fn hashed_null_node() -> ::Out { + HASHED_NULL_NODE + } fn decode(data: &[u8]) -> ::std::result::Result { let r = Rlp::new(data); match r.prototype()? { @@ -49,9 +53,14 @@ impl NodeCodec for RlpNodeCodec { }, // branch - first 16 are nodes, 17th is a value (or empty). Prototype::List(17) => { - let mut nodes = [&[] as &[u8]; 16]; + let mut nodes = [None as Option<&[u8]>; 16]; for i in 0..16 { - nodes[i] = r.at(i)?.as_raw(); + let v = r.at(i)?; + if v.is_empty() { + nodes[i] = None; + } else { + nodes[i] = Some(v.as_raw()); + } } Ok(Node::Branch(nodes, if r.at(16)?.is_empty() { None } else { Some(r.at(16)?.data()?) })) }, @@ -72,54 +81,54 @@ impl NodeCodec for RlpNodeCodec { fn is_empty_node(data: &[u8]) -> bool { Rlp::new(data).is_empty() } - fn empty_node() -> Vec { - let mut stream = RlpStream::new(); - stream.append_empty_data(); - stream.drain() - } + fn empty_node() -> Vec { + let mut stream = RlpStream::new(); + stream.append_empty_data(); + stream.drain() + } - fn leaf_node(partial: &[u8], value: &[u8]) -> Vec { - let mut stream = RlpStream::new_list(2); - stream.append(&partial); - stream.append(&value); + fn leaf_node(partial: &[u8], value: &[u8]) -> Vec { + let mut stream = RlpStream::new_list(2); + stream.append(&partial); + stream.append(&value); stream.drain() - } + } fn ext_node(partial: &[u8], child_ref: ChildReference<::Out>) -> Vec { - let mut stream = RlpStream::new_list(2); - stream.append(&partial); - match child_ref { - ChildReference::Hash(h) => stream.append(&h), - ChildReference::Inline(inline_data, len) => { - let bytes = &AsRef::<[u8]>::as_ref(&inline_data)[..len]; - stream.append_raw(bytes, 1) - }, - }; - stream.drain() + let mut stream = RlpStream::new_list(2); + stream.append(&partial); + match child_ref { + ChildReference::Hash(h) => stream.append(&h), + ChildReference::Inline(inline_data, len) => { + let bytes = &AsRef::<[u8]>::as_ref(&inline_data)[..len]; + stream.append_raw(bytes, 1) + }, + }; + stream.drain() } // fn branch_node(children: I, value: Option>) -> Vec fn branch_node(children: I, value: Option>) -> Vec where I: IntoIterator::Out>>> - { - let mut stream = RlpStream::new_list(17); - for child_ref in children { - match child_ref { - Some(c) => match c { - ChildReference::Hash(h) => stream.append(&h), - ChildReference::Inline(inline_data, len) => { - let bytes = &AsRef::<[u8]>::as_ref(&inline_data)[..len]; - stream.append_raw(bytes, 1) - }, - }, - None => stream.append_empty_data() - }; - } - if let Some(value) = value { - stream.append(&&*value); - } else { - stream.append_empty_data(); - } - stream.drain() - } + { + let mut stream = RlpStream::new_list(17); + for child_ref in children { + match child_ref { + Some(c) => match c { + ChildReference::Hash(h) => stream.append(&h), + ChildReference::Inline(inline_data, len) => { + let bytes = &AsRef::<[u8]>::as_ref(&inline_data)[..len]; + stream.append_raw(bytes, 1) + }, + }, + None => stream.append_empty_data() + }; + } + if let Some(value) = value { + stream.append(&&*value); + } else { + stream.append_empty_data(); + } + stream.drain() + } } diff --git a/util/triehash-ethereum/Cargo.toml b/util/triehash-ethereum/Cargo.toml index e46d5d6907..5b63642975 100644 --- a/util/triehash-ethereum/Cargo.toml +++ b/util/triehash-ethereum/Cargo.toml @@ -6,6 +6,6 @@ description = "Trie-root helpers, ethereum style" license = "GPL-3.0" [dependencies] -triehash = { version = "0.3.0", features = ["ethereum"] } +triehash = { version = "0.4.0", features = ["ethereum"] } ethereum-types = "0.4" keccak-hasher = { path = "../keccak-hasher" } From 2cbffe36e2124aab6c83a01ecf7198bc8819bbe9 Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Thu, 21 Feb 2019 16:34:42 +0100 Subject: [PATCH 086/168] chore(bump ethereum-types) (#10396) Fixes a de-serialization bug in `ethereum-tyes` --- Cargo.lock | 106 ++++++++++++++++++++++++++--------------------------- 1 file changed, 53 insertions(+), 53 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index dac4a7da34..449818812d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -299,7 +299,7 @@ dependencies = [ name = "common-types" version = "0.1.0" dependencies = [ - "ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "ethjson 0.1.0", "ethkey 0.3.0", "heapsize 0.4.2 (git+https://github.com/cheme/heapsize.git?branch=ec-macfix)", @@ -531,7 +531,7 @@ name = "dir" version = "0.1.2" dependencies = [ "app_dirs 1.2.1 (git+https://github.com/paritytech/app-dirs-rs)", - "ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "home 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "journaldb 0.2.0", ] @@ -558,7 +558,7 @@ name = "eip-712" version = "0.1.0" dependencies = [ "ethabi 6.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -633,7 +633,7 @@ version = "6.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", @@ -665,7 +665,7 @@ dependencies = [ "criterion 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", "crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -682,7 +682,7 @@ version = "0.5.0" 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)", + "ethereum-types-serialize 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "fixed-hash 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", "tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -713,7 +713,7 @@ dependencies = [ "ethcore-io 1.12.0", "ethcore-miner 1.12.0", "ethcore-stratum 1.12.0", - "ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "ethjson 0.1.0", "ethkey 0.3.0", "evm 0.1.0", @@ -768,7 +768,7 @@ name = "ethcore-accounts" version = "0.1.0" dependencies = [ "common-types 0.1.0", - "ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "ethkey 0.3.0", "ethstore 0.2.1", "fake-hardware-wallet 0.0.1", @@ -790,7 +790,7 @@ dependencies = [ "common-types 0.1.0", "env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore-db 0.1.0", - "ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "ethkey 0.3.0", "heapsize 0.4.2 (git+https://github.com/cheme/heapsize.git?branch=ec-macfix)", "itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", @@ -820,7 +820,7 @@ name = "ethcore-call-contract" version = "0.1.0" dependencies = [ "common-types 0.1.0", - "ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -829,7 +829,7 @@ name = "ethcore-db" version = "0.1.0" dependencies = [ "common-types 0.1.0", - "ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.4.2 (git+https://github.com/cheme/heapsize.git?branch=ec-macfix)", "kvdb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -866,7 +866,7 @@ dependencies = [ "ethcore-db 0.1.0", "ethcore-io 1.12.0", "ethcore-network 1.12.0", - "ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "failsafe 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "fastmap 0.1.0", "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", @@ -925,7 +925,7 @@ dependencies = [ "ethabi-derive 6.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "ethash 1.12.0", "ethcore-call-contract 0.1.0", - "ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "ethkey 0.3.0", "fetch 0.1.0", "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", @@ -951,7 +951,7 @@ dependencies = [ "assert_matches 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore-io 1.12.0", - "ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "ethkey 0.3.0", "ipnetwork 0.12.8 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -975,7 +975,7 @@ dependencies = [ "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore-io 1.12.0", "ethcore-network 1.12.0", - "ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "ethkey 0.3.0", "igd 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "ipnetwork 0.12.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1015,7 +1015,7 @@ dependencies = [ "ethcore-call-contract 0.1.0", "ethcore-io 1.12.0", "ethcore-miner 1.12.0", - "ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "ethjson 0.1.0", "ethkey 0.3.0", "fetch 0.1.0", @@ -1054,7 +1054,7 @@ dependencies = [ "ethcore-accounts 0.1.0", "ethcore-call-contract 0.1.0", "ethcore-sync 1.12.0", - "ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "ethkey 0.3.0", "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.12.19 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1091,7 +1091,7 @@ dependencies = [ "ethcore-io 1.12.0", "ethcore-private-tx 1.0.0", "ethcore-sync 1.12.0", - "ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb-rocksdb 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1104,7 +1104,7 @@ name = "ethcore-stratum" version = "1.12.0" dependencies = [ "env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)", - "ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-tcp-server 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1127,7 +1127,7 @@ dependencies = [ "ethcore-network 1.12.0", "ethcore-network-devp2p 1.12.0", "ethcore-private-tx 1.0.0", - "ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "ethkey 0.3.0", "ethstore 0.2.1", "fastmap 0.1.0", @@ -1150,12 +1150,12 @@ dependencies = [ [[package]] name = "ethereum-types" -version = "0.4.0" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "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)", + "ethereum-types-serialize 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "fixed-hash 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", "uint 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1163,7 +1163,7 @@ dependencies = [ [[package]] name = "ethereum-types-serialize" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1173,7 +1173,7 @@ dependencies = [ name = "ethjson" version = "0.1.0" dependencies = [ - "ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1187,7 +1187,7 @@ dependencies = [ "byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "edit-distance 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "eth-secp256k1 0.5.7 (git+https://github.com/paritytech/rust-secp256k1)", - "ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "memzero 0.1.0", @@ -1221,7 +1221,7 @@ name = "ethstore" version = "0.2.1" dependencies = [ "dir 0.1.2", - "ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "ethkey 0.3.0", "itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1265,7 +1265,7 @@ version = "0.1.0" dependencies = [ "bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "criterion 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", - "ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.4.2 (git+https://github.com/cheme/heapsize.git?branch=ec-macfix)", "keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1285,7 +1285,7 @@ dependencies = [ "docopt 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore 1.12.0", - "ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "ethjson 0.1.0", "evm 0.1.0", "panic_hook 0.1.0", @@ -1342,7 +1342,7 @@ dependencies = [ name = "fake-hardware-wallet" version = "0.0.1" dependencies = [ - "ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "ethkey 0.3.0", ] @@ -1355,7 +1355,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "fastmap" version = "0.1.0" dependencies = [ - "ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "plain_hasher 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1528,7 +1528,7 @@ dependencies = [ name = "hardware-wallet" version = "1.12.0" dependencies = [ - "ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "ethkey 0.3.0", "hidapi 0.3.1 (git+https://github.com/paritytech/hidapi-rs)", "libusb 0.3.0 (git+https://github.com/paritytech/libusb-rs)", @@ -1808,7 +1808,7 @@ name = "journaldb" version = "0.2.0" dependencies = [ "env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)", - "ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "fastmap 0.1.0", "hash-db 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.4.2 (git+https://github.com/cheme/heapsize.git?branch=ec-macfix)", @@ -1929,7 +1929,7 @@ name = "keccak-hash" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1937,7 +1937,7 @@ dependencies = [ name = "keccak-hasher" version = "0.1.1" dependencies = [ - "ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "hash-db 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "plain_hasher 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2305,7 +2305,7 @@ dependencies = [ "ethcore-io 1.12.0", "ethcore-network 1.12.0", "ethcore-network-devp2p 1.12.0", - "ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb-memorydb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "lru-cache 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2336,7 +2336,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2496,7 +2496,7 @@ dependencies = [ "ethcore-secretstore 1.0.0", "ethcore-service 0.1.0", "ethcore-sync 1.12.0", - "ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "ethkey 0.3.0", "ethstore 0.2.1", "fake-fetch 0.0.1", @@ -2552,7 +2552,7 @@ dependencies = [ "ethabi 6.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethabi-contract 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethabi-derive 6.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "fake-fetch 0.0.1", "fetch 0.1.0", "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2574,7 +2574,7 @@ version = "1.12.0" dependencies = [ "cid 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore 1.12.0", - "ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-http-server 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "multihash 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2603,7 +2603,7 @@ dependencies = [ name = "parity-machine" version = "0.1.0" dependencies = [ - "ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2650,7 +2650,7 @@ dependencies = [ "ethcore-network 1.12.0", "ethcore-private-tx 1.0.0", "ethcore-sync 1.12.0", - "ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "ethjson 0.1.0", "ethkey 0.3.0", "ethstore 0.2.1", @@ -2765,7 +2765,7 @@ dependencies = [ "ethabi-derive 6.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore 1.12.0", "ethcore-sync 1.12.0", - "ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2808,7 +2808,7 @@ dependencies = [ "bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore-network 1.12.0", - "ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "ethkey 0.3.0", "hex 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2906,7 +2906,7 @@ name = "patricia-trie-ethereum" version = "0.1.0" dependencies = [ "elastic-array 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "hash-db 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "journaldb 0.2.0", "keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3079,7 +3079,7 @@ version = "0.1.0" dependencies = [ "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)", - "ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "ethjson 0.1.0", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3341,7 +3341,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 1.2.6 (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.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3351,7 +3351,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)", - "ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -4083,7 +4083,7 @@ name = "trie-standardmap" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "rlp 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4102,7 +4102,7 @@ dependencies = [ name = "triehash-ethereum" version = "0.2.0" dependencies = [ - "ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hasher 0.1.1", "triehash 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -4275,7 +4275,7 @@ name = "vm" version = "0.1.0" dependencies = [ "byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)", - "ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "ethjson 0.1.0", "keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4326,7 +4326,7 @@ version = "0.1.0" dependencies = [ "byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)", - "ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "parity-wasm 0.31.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4528,8 +4528,8 @@ dependencies = [ "checksum ethabi-contract 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "795e25fd868e12a59ca235dbe1f6cc8f1eba8f67d6a39438b29535e0126e0c27" "checksum ethabi-derive 6.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "66a587250c8190be9d6ae28d67b8957ed97cb9eee2e272173a20593ab054a075" "checksum ethbloom 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1a93a43ce2e9f09071449da36bfa7a1b20b950ee344b6904ff23de493b03b386" -"checksum ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "35b3c5a18bc5e73a32a110ac743ec04b02bbbcd3b71d3118d40a6113d509378a" -"checksum ethereum-types-serialize 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4ac59a21a9ce98e188f3dace9eb67a6c4a3c67ec7fbc7218cb827852679dc002" +"checksum ethereum-types 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6e742184dc63a01c8ea0637369f8faa27c40f537949908a237f95c05e68d2c96" +"checksum ethereum-types-serialize 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1873d77b32bc1891a79dad925f2acbc318ee942b38b9110f9dbc5fbeffcea350" "checksum failsafe 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ad3bf1642583ea2f1fa38a1e8546613a7488816941b33e5f0fccceac61879118" "checksum failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6dd377bcc1b1b7ce911967e3ec24fa19c3224394ec05b54aa7b083d498341ac7" "checksum failure_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "64c2d913fe8ed3b6c6518eedf4538255b989945c14c2a7d5cbff62a5e2120596" From f825048efaa116cf1d7c6f0b4676f971dc3b44c4 Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Thu, 21 Feb 2019 17:26:01 +0100 Subject: [PATCH 087/168] fix(jni): bump to jni to 0.11 & remove unsafe impl (#10394) --- Cargo.lock | 6 +++--- parity-clib/Cargo.toml | 2 +- parity-clib/src/java.rs | 3 --- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 449818812d..79ea45c12e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1787,7 +1787,7 @@ dependencies = [ [[package]] name = "jni" -version = "0.10.2" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cesu8 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2439,7 +2439,7 @@ name = "parity-clib" version = "1.12.0" dependencies = [ "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "jni 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", + "jni 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "panic_hook 0.1.0", "parity-ethereum 2.4.0", "tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4578,7 +4578,7 @@ dependencies = [ "checksum itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1306f3464951f30e30d12373d31c79fbd52d236e5e896fd92f96ec7babbbe60b" "checksum jemalloc-sys 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "bfc62c8e50e381768ce8ee0428ee53741929f7ebd73e4d83f669bcf7693e00ae" "checksum jemallocator 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "9f0cd42ac65f758063fea55126b0148b1ce0a6354ff78e07a4d6806bc65c4ab3" -"checksum jni 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1ecfa3b81afc64d9a6539c4eece96ac9a93c551c713a313800dade8e33d7b5c1" +"checksum jni 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "294eca097d1dc0bf59de5ab9f7eafa5f77129e9f6464c957ed3ddeb705fb4292" "checksum jni-sys 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" "checksum jsonrpc-core 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a5152c3fda235dfd68341b3edf4121bc4428642c93acbd6de88c26bf95fc5d7" "checksum jsonrpc-derive 10.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c14be84e86c75935be83a34c6765bf31f97ed6c9163bb0b83007190e9703940a" diff --git a/parity-clib/Cargo.toml b/parity-clib/Cargo.toml index b3635c6e08..f57e503dea 100644 --- a/parity-clib/Cargo.toml +++ b/parity-clib/Cargo.toml @@ -11,7 +11,7 @@ crate-type = ["cdylib", "staticlib"] [dependencies] futures = "0.1.6" -jni = { version = "0.10.1", optional = true } +jni = { version = "0.11", optional = true } panic_hook = { path = "../util/panic-hook" } parity-ethereum = { path = "../", default-features = false } tokio = "0.1.11" diff --git a/parity-clib/src/java.rs b/parity-clib/src/java.rs index ba86e5c88d..98969b1d10 100644 --- a/parity-clib/src/java.rs +++ b/parity-clib/src/java.rs @@ -36,9 +36,6 @@ struct JavaCallback<'a> { method_descriptor: &'a str, } -unsafe impl<'a> Send for JavaCallback<'a> {} -unsafe impl<'a> Sync for JavaCallback<'a> {} - impl<'a> JavaCallback<'a> { fn new(jvm: JavaVM, callback: GlobalRef) -> Self { Self { From b21844b371c593881ecb40e35a5d2d0271ac11b9 Mon Sep 17 00:00:00 2001 From: TriplEight Date: Thu, 21 Feb 2019 19:14:59 +0100 Subject: [PATCH 088/168] no-git for publish jobs, empty artifacts dir (#10393) * no-git for publish jobs, empty artifacts dir * fix syntax * prettiness * fix prettiness * should get rid of git in publishing --- .gitlab-ci.yml | 23 ++++++++++++------- scripts/gitlab/build-unix.sh | 1 + ...ish-onnet-update.sh => publish-onchain.sh} | 0 3 files changed, 16 insertions(+), 8 deletions(-) rename scripts/gitlab/{publish-onnet-update.sh => publish-onchain.sh} (100%) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index a4109ad859..52b16d7cb7 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -2,7 +2,6 @@ stages: - test - build - publish - - publish-onchain - optional image: parity/rust:gitlab-ci @@ -14,6 +13,12 @@ variables: CARGO_HOME: "${CI_PROJECT_DIR}/.cargo" CARGO_TARGET: x86_64-unknown-linux-gnu +.no_git: &no_git + variables: + GIT_STRATEGY: none + GIT_SUBMODULE_STRATEGY: none + + .releaseable_branches: # list of git refs for building GitLab artifacts (think "pre-release binaries") only: &releaseable_branches - stable @@ -94,6 +99,7 @@ build-windows: publish-docker: stage: publish only: *releaseable_branches + <<: *no_git cache: {} dependencies: - build-linux @@ -103,11 +109,12 @@ publish-docker: - scripts/gitlab/publish-docker.sh parity publish-snap: - stage: optional #publish + stage: publish only: *releaseable_branches + # <<: *no_git image: snapcore/snapcraft variables: - BUILD_ARCH: amd64 + BUILD_ARCH: amd64 cache: {} before_script: *determine_version dependencies: @@ -119,18 +126,17 @@ publish-snap: allow_failure: true <<: *collect_artifacts -publish-onnet-update: - stage: publish-onchain +publish-onchain: + stage: publish only: *releaseable_branches + <<: *no_git cache: {} dependencies: - build-linux - build-darwin - build-windows - - publish-awss3-release - before_script: *determine_version script: - - scripts/gitlab/publish-onnet-update.sh + - scripts/gitlab/publish-onchain.sh tags: - linux-docker @@ -155,6 +161,7 @@ publish-awss3-release: image: parity/awscli:latest stage: publish only: *releaseable_branches + <<: *no_git cache: {} dependencies: - build-linux diff --git a/scripts/gitlab/build-unix.sh b/scripts/gitlab/build-unix.sh index 6244dc8460..592bbd54e5 100755 --- a/scripts/gitlab/build-unix.sh +++ b/scripts/gitlab/build-unix.sh @@ -25,6 +25,7 @@ else fi echo "_____ Post-processing binaries _____" +rm -rf artifacts/* mkdir -p artifacts/$CARGO_TARGET cd artifacts/$CARGO_TARGET diff --git a/scripts/gitlab/publish-onnet-update.sh b/scripts/gitlab/publish-onchain.sh similarity index 100% rename from scripts/gitlab/publish-onnet-update.sh rename to scripts/gitlab/publish-onchain.sh From 0815cc3b8377ac6b0b95ffb4440488eab877ba25 Mon Sep 17 00:00:00 2001 From: 5chdn <5chdn@users.noreply.github.com> Date: Thu, 21 Feb 2019 20:03:34 +0100 Subject: [PATCH 089/168] version: bump nightly to 2.5 (#10392) * version: bump nightly to 2.5 * revert(rand 0.3.22) --- Cargo.lock | 12 ++++++------ Cargo.toml | 2 +- util/version/Cargo.toml | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 79ea45c12e..f67f3b610c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2441,7 +2441,7 @@ dependencies = [ "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", "jni 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "panic_hook 0.1.0", - "parity-ethereum 2.4.0", + "parity-ethereum 2.5.0", "tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-current-thread 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2471,7 +2471,7 @@ dependencies = [ [[package]] name = "parity-ethereum" -version = "2.4.0" +version = "2.5.0" dependencies = [ "ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2524,7 +2524,7 @@ dependencies = [ "parity-rpc 1.12.0", "parity-runtime 0.1.0", "parity-updater 1.12.0", - "parity-version 2.4.0", + "parity-version 2.5.0", "parity-whisper 0.1.0", "parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2675,7 +2675,7 @@ dependencies = [ "parity-crypto 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-runtime 0.1.0", "parity-updater 1.12.0", - "parity-version 2.4.0", + "parity-version 2.5.0", "parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2773,7 +2773,7 @@ dependencies = [ "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-hash-fetch 1.12.0", "parity-path 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-version 2.4.0", + "parity-version 2.5.0", "parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2783,7 +2783,7 @@ dependencies = [ [[package]] name = "parity-version" -version = "2.4.0" +version = "2.5.0" dependencies = [ "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "rlp 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index a6b1c005da..ee4440dd01 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ description = "Parity Ethereum client" name = "parity-ethereum" # NOTE Make sure to update util/version/Cargo.toml as well -version = "2.4.0" +version = "2.5.0" license = "GPL-3.0" authors = ["Parity Technologies "] diff --git a/util/version/Cargo.toml b/util/version/Cargo.toml index d663ab4834..8700050546 100644 --- a/util/version/Cargo.toml +++ b/util/version/Cargo.toml @@ -3,7 +3,7 @@ [package] name = "parity-version" # NOTE: this value is used for Parity Ethereum version string (via env CARGO_PKG_VERSION) -version = "2.4.0" +version = "2.5.0" authors = ["Parity Technologies "] build = "build.rs" From 4311d434976b3e79e0cde5ef855beb32d4504248 Mon Sep 17 00:00:00 2001 From: TriplEight Date: Thu, 21 Feb 2019 21:06:49 +0100 Subject: [PATCH 090/168] revert some changes, could be buggy (#10399) --- .gitlab-ci.yml | 29 +++++------------------------ 1 file changed, 5 insertions(+), 24 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 52b16d7cb7..8c263744dd 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -33,7 +33,7 @@ variables: when: on_success expire_in: 1 mos paths: - - artifacts/ + - artifacts/ .determine_version: &determine_version - VERSION="$(sed -r -n '1,/^version/s/^version = "([^"]+)".*$/\1/p' Cargo.toml)" @@ -99,7 +99,7 @@ build-windows: publish-docker: stage: publish only: *releaseable_branches - <<: *no_git + # <<: *no_git cache: {} dependencies: - build-linux @@ -129,7 +129,7 @@ publish-snap: publish-onchain: stage: publish only: *releaseable_branches - <<: *no_git + # <<: *no_git cache: {} dependencies: - build-linux @@ -140,23 +140,6 @@ publish-onchain: tags: - linux-docker -# configures aws for fast uploads/syncs -.s3-before-script: &s3-before-script - before_script: - - mkdir -p ${HOME}/.aws - - | - cat > ${HOME}/.aws/config < Date: Fri, 22 Feb 2019 14:00:20 +0100 Subject: [PATCH 091/168] Fix to_pod storage trie value decoding (#10368) --- ethcore/src/state/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ethcore/src/state/mod.rs b/ethcore/src/state/mod.rs index a585d34865..c670ed89e3 100644 --- a/ethcore/src/state/mod.rs +++ b/ethcore/src/state/mod.rs @@ -1020,7 +1020,7 @@ impl State { let trie = self.factories.trie.readonly(accountdb, &root)?; for o_kv in trie.iter()? { if let Ok((key, val)) = o_kv { - pod_storage.insert(key[..].into(), U256::from(&val[..]).into()); + pod_storage.insert(key[..].into(), rlp::decode::(&val[..]).expect("Decoded from trie which was encoded from the same type; qed").into()); } } From fcccbf3b756c89e81422f3d0d8d6d5c24927e72c Mon Sep 17 00:00:00 2001 From: Antoine Date: Fri, 22 Feb 2019 15:31:34 +0100 Subject: [PATCH 092/168] fix #10390 (#10391) --- ethcore/private-tx/src/lib.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/ethcore/private-tx/src/lib.rs b/ethcore/private-tx/src/lib.rs index 711bdc6126..8d2a087da5 100644 --- a/ethcore/private-tx/src/lib.rs +++ b/ethcore/private-tx/src/lib.rs @@ -362,18 +362,20 @@ impl Provider { signatures.push(signed_tx.signature()); let rsv: Vec = signatures.into_iter().map(|sign| sign.into_electrum().into()).collect(); // Create public transaction + let signer_account = self.signer_account.ok_or_else(|| ErrorKind::SignerAccountNotSet)?; + let state = self.client.state_at(BlockId::Latest).ok_or(ErrorKind::StatePruned)?; + let nonce = state.nonce(&signer_account)?; let public_tx = self.public_transaction( desc.state.clone(), &desc.original_transaction, &rsv, - desc.original_transaction.nonce, + nonce, desc.original_transaction.gas_price )?; trace!(target: "privatetx", "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 signature = self.accounts.sign(signer_account, hash)?; let signed = SignedTransaction::new(public_tx.with_signature(signature, chain_id))?; match self.miner.import_own_transaction(&*self.client, signed.into()) { From bceb883d9982780bc2b9cf582067fc0a18149a12 Mon Sep 17 00:00:00 2001 From: 5chdn <5chdn@users.noreply.github.com> Date: Mon, 25 Feb 2019 12:56:38 +0100 Subject: [PATCH 093/168] snap: reenable i386, arm64, armhf architecture publishing (#10386) * snap: reenable i386, arm64, armhf architecture publishing * gitlab: fix indent * gitlab: fix yml syntax * Linker for crosscomile * fix target to linker * new docker image * fix lint, add build to this PR * calc SHA3 using rhash * add new images for i386, armhf * show snap target & artifacts * set CARGO_TARGET for publish snap * move detect Version to publish snap * rm libc6 dep from snap-template up pub-snap script * clean up cargo config before add linker * move linker config to docker images --- .gitlab-ci.yml | 59 ++++++++++++++++++++-------- scripts/gitlab/build-unix.sh | 12 +++--- scripts/gitlab/publish-snap.sh | 21 ++++------ scripts/snap/snapcraft.template.yaml | 2 +- 4 files changed, 57 insertions(+), 37 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 8c263744dd..dd01a067c2 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -4,8 +4,7 @@ stages: - publish - optional -image: parity/rust:gitlab-ci - +image: parity/rust-parity-ethereum-build:xenial variables: GIT_STRATEGY: fetch GIT_SUBMODULE_STRATEGY: recursive @@ -35,14 +34,6 @@ variables: paths: - artifacts/ -.determine_version: &determine_version - - VERSION="$(sed -r -n '1,/^version/s/^version = "([^"]+)".*$/\1/p' Cargo.toml)" - - DATE_STR="$(date +%Y%m%d)" - - ID_SHORT="$(echo ${CI_COMMIT_SHA} | cut -c 1-7)" - - test "${SCHEDULE_TAG:-${CI_COMMIT_REF_NAME}}" = "nightly" && VERSION="${VERSION}-${ID_SHORT}-${DATE_STR}" - - export VERSION - - echo "Version = ${VERSION}" - test-linux: stage: test variables: @@ -62,7 +53,7 @@ test-audit: tags: - linux-docker -build-linux: +build-linux: &build-linux stage: build only: *releaseable_branches script: @@ -72,6 +63,24 @@ build-linux: tags: - linux-docker +build-linux-i386: + <<: *build-linux + image: parity/rust-parity-ethereum-build:i386 + variables: + CARGO_TARGET: i686-unknown-linux-gnu + +build-linux-arm64: + <<: *build-linux + image: parity/rust-parity-ethereum-build:arm64 + variables: + CARGO_TARGET: aarch64-unknown-linux-gnu + +build-linux-armhf: + <<: *build-linux + image: parity/rust-parity-ethereum-build:armhf + variables: + CARGO_TARGET: armv7-unknown-linux-gnueabihf + build-darwin: stage: build only: *releaseable_branches @@ -108,7 +117,7 @@ publish-docker: script: - scripts/gitlab/publish-docker.sh parity -publish-snap: +publish-snap: &publish-snap stage: publish only: *releaseable_branches # <<: *no_git @@ -116,16 +125,35 @@ publish-snap: variables: BUILD_ARCH: amd64 cache: {} - before_script: *determine_version dependencies: - build-linux tags: - - rust-stable + - linux-docker script: - scripts/gitlab/publish-snap.sh - allow_failure: true <<: *collect_artifacts +publish-snap-i386: + <<: *publish-snap + variables: + BUILD_ARCH: i386 + dependencies: + - build-linux-i386 + +publish-snap-arm64: + <<: *publish-snap + variables: + BUILD_ARCH: arm64 + dependencies: + - build-linux-arm64 + +publish-snap-armhf: + <<: *publish-snap + variables: + BUILD_ARCH: armhf + dependencies: + - build-linux-armhf + publish-onchain: stage: publish only: *releaseable_branches @@ -191,4 +219,3 @@ build-android: - linux-docker allow_failure: true <<: *collect_artifacts - diff --git a/scripts/gitlab/build-unix.sh b/scripts/gitlab/build-unix.sh index 592bbd54e5..9b2b123280 100755 --- a/scripts/gitlab/build-unix.sh +++ b/scripts/gitlab/build-unix.sh @@ -11,6 +11,9 @@ echo "CC: " $CC echo "CXX: " $CXX #strip ON export RUSTFLAGS=" -C link-arg=-s" +# Linker for crosscomile +echo "_____ Linker _____" +cat .cargo/config echo "_____ Building target: "$CARGO_TARGET" _____" if [ "${CARGO_TARGET}" = "armv7-linux-androideabi" ] @@ -43,11 +46,6 @@ fi echo "_____ Calculating checksums _____" for binary in $(ls) do - rhash --sha256 $binary -o $binary.sha256 - if [ "${CARGO_TARGET}" = "armv7-linux-androideabi" ] - then - echo "> ${binary} cannot be hashed with cross-compiled binary" - else - ./parity tools hash $binary > $binary.sha3 - fi + rhash --sha256 $binary -o $binary.sha256 #do we still need this hash (SHA2)? + rhash --sha3-256 $binary -o $binary.sha3 done diff --git a/scripts/gitlab/publish-snap.sh b/scripts/gitlab/publish-snap.sh index 36d5c5d169..5e0231af00 100755 --- a/scripts/gitlab/publish-snap.sh +++ b/scripts/gitlab/publish-snap.sh @@ -8,7 +8,10 @@ set -u # treat unset variables as error # gsub(/ /, "", $2) deletes whitespaces TRACK=`awk -F '=' '/^track/ {gsub(/"/, "", $2); gsub(/ /, "", $2); print $2}' ./util/version/Cargo.toml` echo Track is: $TRACK - +# prepare variables +VERSION=v"$(sed -r -n '1,/^version/s/^version = "([^"]+)".*$/\1/p' Cargo.toml)" +SNAP_PACKAGE="parity_"$VERSION"_"$BUILD_ARCH".snap" +CARGO_TARGET="$(ls artifacts)" # Choose snap release channel based on parity ethereum version track case ${TRACK} in nightly) export GRADE="devel" CHANNEL="edge";; @@ -21,24 +24,16 @@ esac case ${CI_COMMIT_REF_NAME} in beta|stable) export GRADE="stable" CHANNEL="candidate";; esac - -VERSION="v"$VERSION -SNAP_PACKAGE="parity_"$VERSION"_"$BUILD_ARCH".snap" - echo "__________Create snap package__________" echo "Release channel :" $GRADE " Branch/tag: " $CI_COMMIT_REF_NAME -echo $VERSION:$GRADE:$BUILD_ARCH -# cat scripts/snap/snapcraft.template.yaml | envsubst '$VERSION:$GRADE:$BUILD_ARCH:$CARGO_TARGET' > snapcraft.yaml -# a bit more necromancy (substitutions): -pwd -cd /builds/$CI_PROJECT_PATH/scripts/snap/ +echo $VERSION:$GRADE:$BUILD_ARCH:$CARGO_TARGET + sed -e 's/$VERSION/'"$VERSION"'/g' \ -e 's/$GRADE/'"$GRADE"'/g' \ -e 's/$BUILD_ARCH/'"$BUILD_ARCH"'/g' \ -e 's/$CARGO_TARGET/'"$CARGO_TARGET"'/g' \ - snapcraft.template.yaml > /builds/$CI_PROJECT_PATH/snapcraft.yaml -cd /builds/$CI_PROJECT_PATH -pwd + scripts/snap/snapcraft.template.yaml > snapcraft.yaml + apt update apt install -y --no-install-recommends rhash cat snapcraft.yaml diff --git a/scripts/snap/snapcraft.template.yaml b/scripts/snap/snapcraft.template.yaml index b5f370bacf..7307c4ff6c 100644 --- a/scripts/snap/snapcraft.template.yaml +++ b/scripts/snap/snapcraft.template.yaml @@ -50,4 +50,4 @@ parts: cp -v ethkey $SNAPCRAFT_PART_INSTALL/usr/bin/ethkey cp -v ethstore $SNAPCRAFT_PART_INSTALL/usr/bin/ethstore cp -v whisper $SNAPCRAFT_PART_INSTALL/usr/bin/whisper - stage-packages: [libc6, libudev1, libstdc++6, cmake, libdb5.3] + stage-packages: [libudev1, libstdc++6, cmake, libdb5.3] From c5c3fb6a7505eba94a75cd0eaa4c9e528a16f768 Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Mon, 25 Feb 2019 14:27:28 +0100 Subject: [PATCH 094/168] fix(rpc-types): replace uint and hash with `ethereum_types v0.4` (#10217) * fix(rpc-types): remove uint and hash wrappers * fix(tests) * fix(cleanup) * grumbles(rpc-api): revert `verify_signature` * revert change of `U64` -> `u64` * fix(cleanup after bad merge) * chore(bump ethereum-types) * fix(bad merge) * feat(tests ethereum-types): add tests * chore(update `ethereum-types` to 0.4.2) * feat(tests for h256) * chore(rpc): remove `ethbloom` import Use re-export from `ethereum-types` instead * fix(bad merge): remove `DefaultAccount` type * doc(add TODO with issue link) --- Cargo.lock | 2 + cli-signer/Cargo.toml | 1 + cli-signer/rpc-client/Cargo.toml | 1 + cli-signer/rpc-client/src/lib.rs | 1 + cli-signer/rpc-client/src/signer_client.rs | 3 +- cli-signer/src/lib.rs | 4 +- rpc/src/v1/helpers/dispatch/mod.rs | 4 +- .../helpers/external_signer/signing_queue.rs | 1 + rpc/src/v1/helpers/secretstore.rs | 3 +- rpc/src/v1/helpers/signature.rs | 7 +- rpc/src/v1/helpers/subscribers.rs | 5 +- rpc/src/v1/helpers/work.rs | 6 +- rpc/src/v1/impls/eth.rs | 83 ++++----- rpc/src/v1/impls/eth_filter.rs | 12 +- rpc/src/v1/impls/light/eth.rs | 69 ++++--- rpc/src/v1/impls/light/parity.rs | 3 +- rpc/src/v1/impls/light/parity_set.rs | 5 +- rpc/src/v1/impls/light/trace.rs | 4 +- rpc/src/v1/impls/parity.rs | 4 +- rpc/src/v1/impls/parity_accounts.rs | 71 +++----- rpc/src/v1/impls/parity_set.rs | 5 +- rpc/src/v1/impls/personal.rs | 36 ++-- rpc/src/v1/impls/private.rs | 4 +- rpc/src/v1/impls/secretstore.rs | 5 +- rpc/src/v1/impls/signer.rs | 3 +- rpc/src/v1/impls/signing.rs | 23 +-- rpc/src/v1/impls/signing_unsafe.rs | 21 +-- rpc/src/v1/impls/traces.rs | 4 +- rpc/src/v1/impls/web3.rs | 3 +- rpc/src/v1/mod.rs | 2 +- rpc/src/v1/tests/eth.rs | 5 +- rpc/src/v1/tests/mocked/personal.rs | 8 +- rpc/src/v1/tests/mocked/secretstore.rs | 3 +- rpc/src/v1/tests/mocked/signer.rs | 6 +- rpc/src/v1/tests/mocked/signing_unsafe.rs | 2 +- rpc/src/v1/traits/eth.rs | 2 +- rpc/src/v1/traits/eth_signing.rs | 3 +- rpc/src/v1/traits/parity.rs | 3 +- rpc/src/v1/traits/parity_accounts.rs | 3 +- rpc/src/v1/traits/parity_set.rs | 3 +- rpc/src/v1/traits/parity_signing.rs | 3 +- rpc/src/v1/traits/personal.rs | 4 +- rpc/src/v1/traits/private.rs | 3 +- rpc/src/v1/traits/secretstore.rs | 5 +- rpc/src/v1/traits/signer.rs | 4 +- rpc/src/v1/traits/traces.rs | 4 +- rpc/src/v1/traits/web3.rs | 3 +- rpc/src/v1/types/account_info.rs | 4 +- rpc/src/v1/types/block.rs | 19 +- rpc/src/v1/types/call_request.rs | 5 +- rpc/src/v1/types/confirmations.rs | 6 +- rpc/src/v1/types/consensus_status.rs | 2 +- rpc/src/v1/types/derivation.rs | 3 +- rpc/src/v1/types/eip191.rs | 4 +- rpc/src/v1/types/eth_types.rs | 84 +++++++++ rpc/src/v1/types/filter.rs | 3 +- rpc/src/v1/types/hash.rs | 165 ----------------- rpc/src/v1/types/histogram.rs | 2 +- rpc/src/v1/types/log.rs | 6 +- rpc/src/v1/types/mod.rs | 7 +- rpc/src/v1/types/private_receipt.rs | 3 +- rpc/src/v1/types/provenance.rs | 2 +- rpc/src/v1/types/pubsub.rs | 3 +- rpc/src/v1/types/receipt.rs | 3 +- rpc/src/v1/types/secretstore.rs | 5 +- rpc/src/v1/types/sync.rs | 3 +- rpc/src/v1/types/trace.rs | 8 +- rpc/src/v1/types/trace_filter.rs | 3 +- rpc/src/v1/types/transaction.rs | 3 +- rpc/src/v1/types/transaction_request.rs | 6 +- rpc/src/v1/types/uint.rs | 172 ------------------ rpc/src/v1/types/work.rs | 2 +- 72 files changed, 359 insertions(+), 623 deletions(-) create mode 100644 rpc/src/v1/types/eth_types.rs delete mode 100644 rpc/src/v1/types/hash.rs delete mode 100644 rpc/src/v1/types/uint.rs diff --git a/Cargo.lock b/Cargo.lock index f67f3b610c..71061696de 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -261,6 +261,7 @@ dependencies = [ name = "cli-signer" version = "1.4.0" dependencies = [ + "ethereum-types 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", "parity-rpc 1.12.0", "parity-rpc-client 1.4.0", @@ -2699,6 +2700,7 @@ dependencies = [ name = "parity-rpc-client" version = "1.4.0" dependencies = [ + "ethereum-types 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-ws-server 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/cli-signer/Cargo.toml b/cli-signer/Cargo.toml index f4fa86d945..11dd06107e 100644 --- a/cli-signer/Cargo.toml +++ b/cli-signer/Cargo.toml @@ -7,6 +7,7 @@ name = "cli-signer" version = "1.4.0" [dependencies] +ethereum-types = "0.4" futures = "0.1" rpassword = "1.0" parity-rpc = { path = "../rpc" } diff --git a/cli-signer/rpc-client/Cargo.toml b/cli-signer/rpc-client/Cargo.toml index e7eb354618..53ec983391 100644 --- a/cli-signer/rpc-client/Cargo.toml +++ b/cli-signer/rpc-client/Cargo.toml @@ -7,6 +7,7 @@ name = "parity-rpc-client" version = "1.4.0" [dependencies] +ethereum-types = "0.4" futures = "0.1" log = "0.4" serde = "1.0" diff --git a/cli-signer/rpc-client/src/lib.rs b/cli-signer/rpc-client/src/lib.rs index df7936eaee..d0e087e59d 100644 --- a/cli-signer/rpc-client/src/lib.rs +++ b/cli-signer/rpc-client/src/lib.rs @@ -17,6 +17,7 @@ pub mod client; pub mod signer_client; +extern crate ethereum_types; extern crate futures; extern crate jsonrpc_core; extern crate jsonrpc_ws_server as ws; diff --git a/cli-signer/rpc-client/src/signer_client.rs b/cli-signer/rpc-client/src/signer_client.rs index 339f43b6e3..997841936d 100644 --- a/cli-signer/rpc-client/src/signer_client.rs +++ b/cli-signer/rpc-client/src/signer_client.rs @@ -15,7 +15,8 @@ // along with Parity Ethereum. If not, see . use client::{Rpc, RpcError}; -use rpc::signer::{ConfirmationRequest, TransactionModification, U256, TransactionCondition}; +use ethereum_types::U256; +use rpc::signer::{ConfirmationRequest, TransactionModification, TransactionCondition}; use serde; use serde_json::{Value as JsonValue, to_value}; use std::path::PathBuf; diff --git a/cli-signer/src/lib.rs b/cli-signer/src/lib.rs index f09d4403aa..3ef6e70549 100644 --- a/cli-signer/src/lib.rs +++ b/cli-signer/src/lib.rs @@ -14,13 +14,15 @@ // You should have received a copy of the GNU General Public License // along with Parity Ethereum. If not, see . +extern crate ethereum_types; extern crate futures; extern crate rpassword; extern crate parity_rpc as rpc; extern crate parity_rpc_client as client; -use rpc::signer::{U256, ConfirmationRequest}; +use ethereum_types::U256; +use rpc::signer::ConfirmationRequest; use client::signer_client::SignerRpc; use std::io::{Write, BufRead, BufReader, stdout, stdin}; use std::path::PathBuf; diff --git a/rpc/src/v1/helpers/dispatch/mod.rs b/rpc/src/v1/helpers/dispatch/mod.rs index d23619f417..8877209723 100644 --- a/rpc/src/v1/helpers/dispatch/mod.rs +++ b/rpc/src/v1/helpers/dispatch/mod.rs @@ -86,7 +86,7 @@ use jsonrpc_core::{BoxFuture, Result, Error}; use jsonrpc_core::futures::{future, Future, IntoFuture}; use v1::helpers::{TransactionRequest, FilledTransactionRequest, ConfirmationPayload}; use v1::types::{ - H520 as RpcH520, Bytes as RpcBytes, + Bytes as RpcBytes, RichRawTransaction as RpcRichRawTransaction, ConfirmationPayload as RpcConfirmationPayload, ConfirmationResponse, @@ -309,7 +309,6 @@ pub fn execute( let res = signer.sign_message(address, pass, SignMessage::Data(data)) .map(|result| result .map(|s| H520(s.into_electrum())) - .map(RpcH520::from) .map(ConfirmationResponse::Signature) ); @@ -319,7 +318,6 @@ pub fn execute( let res = signer.sign_message(address, pass, SignMessage::Hash(data)) .map(|result| result .map(|rsv| H520(rsv.into_electrum())) - .map(RpcH520::from) .map(ConfirmationResponse::Signature) ); diff --git a/rpc/src/v1/helpers/external_signer/signing_queue.rs b/rpc/src/v1/helpers/external_signer/signing_queue.rs index 7640500529..9bbc778ece 100644 --- a/rpc/src/v1/helpers/external_signer/signing_queue.rs +++ b/rpc/src/v1/helpers/external_signer/signing_queue.rs @@ -15,6 +15,7 @@ // along with Parity Ethereum. If not, see . use std::collections::BTreeMap; + use ethereum_types::U256; use parking_lot::{Mutex, RwLock}; use super::oneshot; diff --git a/rpc/src/v1/helpers/secretstore.rs b/rpc/src/v1/helpers/secretstore.rs index d8a60d592c..6e1cbca45d 100644 --- a/rpc/src/v1/helpers/secretstore.rs +++ b/rpc/src/v1/helpers/secretstore.rs @@ -16,12 +16,13 @@ use std::collections::BTreeSet; use rand::{Rng, OsRng}; +use ethereum_types::{H256, H512}; use ethkey::{self, Public, Secret, Random, Generator, math}; use crypto; use bytes::Bytes; use jsonrpc_core::Error; use v1::helpers::errors; -use v1::types::{H256, H512, EncryptedDocumentKey}; +use v1::types::EncryptedDocumentKey; use tiny_keccak::Keccak; /// Initialization vector length. diff --git a/rpc/src/v1/helpers/signature.rs b/rpc/src/v1/helpers/signature.rs index b2bea2588f..32827ea1e1 100644 --- a/rpc/src/v1/helpers/signature.rs +++ b/rpc/src/v1/helpers/signature.rs @@ -15,8 +15,9 @@ // along with Parity Ethereum. If not, see . use ethkey::{recover, public_to_address, Signature}; +use ethereum_types::{H256, U64}; use jsonrpc_core::Result; -use v1::types::{Bytes, RecoveredAccount, H256, U64}; +use v1::types::{Bytes, RecoveredAccount}; use v1::helpers::errors; use v1::helpers::dispatch::eth_data_hash; use hash::keccak; @@ -35,7 +36,7 @@ pub fn verify_signature( } else { keccak(message.0) }; - let v: u64 = v.into(); + let v = v.as_u64(); let is_valid_for_current_chain = match (chain_id, v) { (None, v) if v == 0 || v == 1 => true, (Some(chain_id), v) if v >= 35 => (v - 35) / 2 == chain_id, @@ -54,7 +55,7 @@ pub fn verify_signature( mod tests { use super::*; use ethkey::Generator; - use v1::types::H160; + use ethereum_types::{H160, U64}; pub fn add_chain_replay_protection(v: u64, chain_id: Option) -> u64 { v + if let Some(n) = chain_id { 35 + n * 2 } else { 0 } diff --git a/rpc/src/v1/helpers/subscribers.rs b/rpc/src/v1/helpers/subscribers.rs index 5b48b67a22..9483d8e321 100644 --- a/rpc/src/v1/helpers/subscribers.rs +++ b/rpc/src/v1/helpers/subscribers.rs @@ -19,8 +19,8 @@ use std::{ops, str}; use std::collections::HashMap; use jsonrpc_pubsub::{typed::{Subscriber, Sink}, SubscriptionId}; +use ethereum_types::H64; use rand::{Rng, StdRng}; -use v1::types::H64; #[derive(Debug, Clone, Hash, Eq, PartialEq)] pub struct Id(H64); @@ -36,8 +36,9 @@ impl str::FromStr for Id { } } impl Id { + // TODO: replace `format!` see [#10412](https://github.com/paritytech/parity-ethereum/issues/10412) pub fn as_string(&self) -> String { - format!("0x{:?}", self.0) + format!("{:?}", self.0) } } diff --git a/rpc/src/v1/helpers/work.rs b/rpc/src/v1/helpers/work.rs index 0a90d446ee..661b4cab8b 100644 --- a/rpc/src/v1/helpers/work.rs +++ b/rpc/src/v1/helpers/work.rs @@ -20,17 +20,13 @@ use std::sync::Arc; use rlp; use ethcore::miner::{BlockChainClient, MinerService}; -use ethereum_types::{H64 as EthcoreH64, H256 as EthcoreH256}; +use ethereum_types::{H64, H256}; use jsonrpc_core::Error; -use v1::types::{H64, H256}; use v1::helpers::errors; // Submit a POW work and return the block's hash pub fn submit_work_detail(client: &Arc, miner: &Arc, nonce: H64, pow_hash: H256, mix_hash: H256) -> Result { // TODO [ToDr] Should disallow submissions in case of PoA? - let nonce: EthcoreH64 = nonce.into(); - let pow_hash: EthcoreH256 = pow_hash.into(); - let mix_hash: EthcoreH256 = mix_hash.into(); trace!(target: "miner", "submit_work_detail: Decoded: nonce={}, pow_hash={}, mix_hash={}", nonce, pow_hash, mix_hash); let seal = vec![rlp::encode(&mix_hash), rlp::encode(&nonce)]; let import = miner.submit_seal(pow_hash, seal) diff --git a/rpc/src/v1/impls/eth.rs b/rpc/src/v1/impls/eth.rs index 8d47b9b7b5..31b8be10c2 100644 --- a/rpc/src/v1/impls/eth.rs +++ b/rpc/src/v1/impls/eth.rs @@ -21,7 +21,7 @@ use std::time::{Instant, Duration, SystemTime, UNIX_EPOCH}; use std::sync::Arc; use rlp::Rlp; -use ethereum_types::{U256, H256, H160, Address}; +use ethereum_types::{Address, H64, H160, H256, U64, U256}; use parking_lot::Mutex; use ethash::{self, SeedHashCompute}; @@ -47,8 +47,7 @@ use v1::traits::Eth; use v1::types::{ RichBlock, Block, BlockTransactions, BlockNumber, Bytes, SyncStatus, SyncInfo, Transaction, CallRequest, Index, Filter, Log, Receipt, Work, EthAccount, StorageProof, - H64 as RpcH64, H256 as RpcH256, H160 as RpcH160, U256 as RpcU256, block_number_to_id, - U64 as RpcU64, + block_number_to_id }; use v1::metadata::Metadata; @@ -530,7 +529,7 @@ impl Eth for EthClient< } } - fn author(&self) -> Result { + fn author(&self) -> Result { let miner = self.miner.authoring_params().author; if miner == 0.into() { (self.accounts)() @@ -539,7 +538,7 @@ impl Eth for EthClient< .map(From::from) .ok_or_else(|| errors::account("No accounts were found", "")) } else { - Ok(RpcH160::from(miner)) + Ok(H160::from(miner)) } } @@ -547,32 +546,30 @@ impl Eth for EthClient< Ok(self.miner.is_currently_sealing()) } - fn chain_id(&self) -> Result> { - Ok(self.client.signing_chain_id().map(RpcU64::from)) + fn chain_id(&self) -> Result> { + Ok(self.client.signing_chain_id().map(U64::from)) } - fn hashrate(&self) -> Result { - Ok(RpcU256::from(self.external_miner.hashrate())) + fn hashrate(&self) -> Result { + Ok(U256::from(self.external_miner.hashrate())) } - fn gas_price(&self) -> Result { - Ok(RpcU256::from(default_gas_price(&*self.client, &*self.miner, self.options.gas_price_percentile))) + fn gas_price(&self) -> Result { + Ok(U256::from(default_gas_price(&*self.client, &*self.miner, self.options.gas_price_percentile))) } - fn accounts(&self) -> Result> { + fn accounts(&self) -> Result> { self.deprecation_notice.print("eth_accounts", deprecated::msgs::ACCOUNTS); let accounts = (self.accounts)(); Ok(accounts.into_iter().map(Into::into).collect()) } - fn block_number(&self) -> Result { - Ok(RpcU256::from(self.client.chain_info().best_block_number)) + fn block_number(&self) -> Result { + Ok(U256::from(self.client.chain_info().best_block_number)) } - fn balance(&self, address: RpcH160, num: Option) -> BoxFuture { - let address = address.into(); - + fn balance(&self, address: H160, num: Option) -> BoxFuture { let num = num.unwrap_or_default(); try_bf!(check_known(&*self.client, num.clone())); @@ -584,11 +581,10 @@ impl Eth for EthClient< Box::new(future::done(res)) } - fn proof(&self, address: RpcH160, values: Vec, num: Option) -> BoxFuture { + fn proof(&self, address: H160, values: Vec, num: Option) -> BoxFuture { try_bf!(errors::require_experimental(self.options.allow_experimental_rpcs, "1186")); - let a: H160 = address.clone().into(); - let key1 = keccak(a); + let key1 = keccak(address); let num = num.unwrap_or_default(); let id = match num { @@ -603,7 +599,7 @@ impl Eth for EthClient< try_bf!(check_known(&*self.client, num.clone())); let res = match self.client.prove_account(key1, id) { - Some((proof,account)) => Ok(EthAccount { + Some((proof, account)) => Ok(EthAccount { address: address, balance: account.balance.into(), nonce: account.nonce.into(), @@ -627,10 +623,8 @@ impl Eth for EthClient< Box::new(future::done(res)) } - fn storage_at(&self, address: RpcH160, pos: RpcU256, num: Option) -> BoxFuture { - let address: Address = RpcH160::into(address); - let position: U256 = RpcU256::into(pos); - + fn storage_at(&self, address: H160, position: U256, num: Option) -> BoxFuture { + let address: Address = address.into(); let num = num.unwrap_or_default(); try_bf!(check_known(&*self.client, num.clone())); @@ -642,8 +636,8 @@ impl Eth for EthClient< Box::new(future::done(res)) } - fn transaction_count(&self, address: RpcH160, num: Option) -> BoxFuture { - let address: Address = RpcH160::into(address); + fn transaction_count(&self, address: H160, num: Option) -> BoxFuture { + let address: Address = address.into(); let res = match num.unwrap_or_default() { BlockNumber::Pending if self.options.pending_nonce_from_queue => { @@ -676,7 +670,7 @@ impl Eth for EthClient< Box::new(future::done(res)) } - fn block_transaction_count_by_hash(&self, hash: RpcH256) -> BoxFuture> { + fn block_transaction_count_by_hash(&self, hash: H256) -> BoxFuture> { let trx_count = self.client.block(BlockId::Hash(hash.into())) .map(|block| block.transactions_count().into()); let result = Ok(trx_count) @@ -684,7 +678,7 @@ impl Eth for EthClient< Box::new(future::done(result)) } - fn block_transaction_count_by_number(&self, num: BlockNumber) -> BoxFuture> { + fn block_transaction_count_by_number(&self, num: BlockNumber) -> BoxFuture> { Box::new(future::done(match num { BlockNumber::Pending => Ok(Some(self.miner.pending_transaction_hashes(&*self.client).len().into())), @@ -701,7 +695,7 @@ impl Eth for EthClient< })) } - fn block_uncles_count_by_hash(&self, hash: RpcH256) -> BoxFuture> { + fn block_uncles_count_by_hash(&self, hash: H256) -> BoxFuture> { let uncle_count = self.client.block(BlockId::Hash(hash.into())) .map(|block| block.uncles_count().into()); let result = Ok(uncle_count) @@ -709,7 +703,7 @@ impl Eth for EthClient< Box::new(future::done(result)) } - fn block_uncles_count_by_number(&self, num: BlockNumber) -> BoxFuture> { + fn block_uncles_count_by_number(&self, num: BlockNumber) -> BoxFuture> { Box::new(future::done(match num { BlockNumber::Pending => Ok(Some(0.into())), _ => { @@ -725,8 +719,8 @@ impl Eth for EthClient< })) } - fn code_at(&self, address: RpcH160, num: Option) -> BoxFuture { - let address: Address = RpcH160::into(address); + fn code_at(&self, address: H160, num: Option) -> BoxFuture { + let address: Address = H160::into(address); let num = num.unwrap_or_default(); try_bf!(check_known(&*self.client, num.clone())); @@ -739,7 +733,7 @@ impl Eth for EthClient< Box::new(future::done(res)) } - fn block_by_hash(&self, hash: RpcH256, include_txs: bool) -> BoxFuture> { + fn block_by_hash(&self, hash: H256, include_txs: bool) -> BoxFuture> { let result = self.rich_block(BlockId::Hash(hash.into()).into(), include_txs) .and_then(errors::check_block_gap(&*self.client, self.options.allow_missing_blocks)); Box::new(future::done(result)) @@ -751,8 +745,7 @@ impl Eth for EthClient< Box::new(future::done(result)) } - fn transaction_by_hash(&self, hash: RpcH256) -> BoxFuture> { - let hash: H256 = hash.into(); + fn transaction_by_hash(&self, hash: H256) -> BoxFuture> { let tx = try_bf!(self.transaction(PendingTransactionId::Hash(hash))).or_else(|| { self.miner.transaction(&hash) .map(|t| Transaction::from_pending(t.pending().clone())) @@ -762,7 +755,7 @@ impl Eth for EthClient< Box::new(future::done(result)) } - fn transaction_by_block_hash_and_index(&self, hash: RpcH256, index: Index) -> BoxFuture> { + fn transaction_by_block_hash_and_index(&self, hash: H256, index: Index) -> BoxFuture> { let id = PendingTransactionId::Location(PendingOrBlock::Block(BlockId::Hash(hash.into())), index.value()); let result = self.transaction(id).and_then( errors::check_block_gap(&*self.client, self.options.allow_missing_blocks)); @@ -783,9 +776,7 @@ impl Eth for EthClient< Box::new(future::done(result)) } - fn transaction_receipt(&self, hash: RpcH256) -> BoxFuture> { - let hash: H256 = hash.into(); - + fn transaction_receipt(&self, hash: H256) -> BoxFuture> { if self.options.allow_pending_receipt_query { let best_block = self.client.chain_info().best_block_number; if let Some(receipt) = self.miner.pending_receipt(best_block, &hash) { @@ -799,7 +790,7 @@ impl Eth for EthClient< Box::new(future::done(result)) } - fn uncle_by_block_hash_and_index(&self, hash: RpcH256, index: Index) -> BoxFuture> { + fn uncle_by_block_hash_and_index(&self, hash: H256, index: Index) -> BoxFuture> { let result = self.uncle(PendingUncleId { id: PendingOrBlock::Block(BlockId::Hash(hash.into())), position: index.value() @@ -889,19 +880,19 @@ impl Eth for EthClient< } } - fn submit_work(&self, nonce: RpcH64, pow_hash: RpcH256, mix_hash: RpcH256) -> Result { + fn submit_work(&self, nonce: H64, pow_hash: H256, mix_hash: H256) -> Result { match helpers::submit_work_detail(&self.client, &self.miner, nonce, pow_hash, mix_hash) { Ok(_) => Ok(true), Err(_) => Ok(false), } } - fn submit_hashrate(&self, rate: RpcU256, id: RpcH256) -> Result { + fn submit_hashrate(&self, rate: U256, id: H256) -> Result { self.external_miner.submit_hashrate(rate.into(), id.into()); Ok(true) } - fn send_raw_transaction(&self, raw: Bytes) -> Result { + fn send_raw_transaction(&self, raw: Bytes) -> Result { Rlp::new(&raw.into_vec()).as_val() .map_err(errors::rlp) .and_then(|tx| SignedTransaction::new(tx).map_err(errors::transaction)) @@ -916,7 +907,7 @@ impl Eth for EthClient< .map(Into::into) } - fn submit_transaction(&self, raw: Bytes) -> Result { + fn submit_transaction(&self, raw: Bytes) -> Result { self.send_raw_transaction(raw) } @@ -960,7 +951,7 @@ impl Eth for EthClient< )) } - fn estimate_gas(&self, request: CallRequest, num: Option) -> BoxFuture { + fn estimate_gas(&self, request: CallRequest, num: Option) -> BoxFuture { let request = CallRequest::into(request); let signed = try_bf!(fake_sign::sign_call(request)); let num = num.unwrap_or_default(); diff --git a/rpc/src/v1/impls/eth_filter.rs b/rpc/src/v1/impls/eth_filter.rs index 20a0d27400..f8d4d29022 100644 --- a/rpc/src/v1/impls/eth_filter.rs +++ b/rpc/src/v1/impls/eth_filter.rs @@ -21,7 +21,7 @@ use std::collections::{BTreeSet, VecDeque}; use ethcore::client::{BlockChainClient, BlockId}; use ethcore::miner::{self, MinerService}; -use ethereum_types::H256; +use ethereum_types::{H256, U256}; use parking_lot::Mutex; use types::filter::Filter as EthcoreFilter; @@ -29,7 +29,7 @@ use jsonrpc_core::{BoxFuture, Result}; 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::types::{BlockNumber, Index, Filter, FilterChanges, Log}; use v1::helpers::{errors, SyncPollFilter, PollFilter, PollManager, limit_logs}; use v1::impls::eth::pending_logs; @@ -137,7 +137,7 @@ impl Filterable for EthFilterClient where } impl EthFilter for T { - fn new_filter(&self, filter: Filter) -> Result { + fn new_filter(&self, filter: Filter) -> Result { let mut polls = self.polls().lock(); let block_number = self.best_block_number(); let include_pending = filter.to_block == Some(BlockNumber::Pending); @@ -150,7 +150,7 @@ impl EthFilter for T { Ok(id.into()) } - fn new_block_filter(&self) -> Result { + fn new_block_filter(&self) -> Result { let mut polls = self.polls().lock(); // +1, since we don't want to include the current block let id = polls.create_poll(SyncPollFilter::new(PollFilter::Block { @@ -160,7 +160,7 @@ impl EthFilter for T { Ok(id.into()) } - fn new_pending_transaction_filter(&self) -> Result { + fn new_pending_transaction_filter(&self) -> Result { let mut polls = self.polls().lock(); let pending_transactions = self.pending_transaction_hashes(); let id = polls.create_poll(SyncPollFilter::new(PollFilter::PendingTransaction(pending_transactions))); @@ -191,7 +191,7 @@ impl EthFilter for T { match self.block_hash(block_number) { Some(hash) => { *last_block_number = n; - hashes.push(RpcH256::from(hash)); + hashes.push(H256::from(hash)); // Only keep the most recent history if recent_reported_hashes.len() >= PollFilter::MAX_BLOCK_HISTORY_SIZE { recent_reported_hashes.pop_back(); diff --git a/rpc/src/v1/impls/light/eth.rs b/rpc/src/v1/impls/light/eth.rs index e13f562194..909d4c2443 100644 --- a/rpc/src/v1/impls/light/eth.rs +++ b/rpc/src/v1/impls/light/eth.rs @@ -28,7 +28,7 @@ use light::client::LightChainClient; use light::{cht, TransactionQueue}; use light::on_demand::{request, OnDemand}; -use ethereum_types::{U256, Address}; +use ethereum_types::{Address, H64, H160, H256, U64, U256}; use hash::{KECCAK_NULL_RLP, KECCAK_EMPTY_LIST_RLP}; use parking_lot::{RwLock, Mutex}; use rlp::Rlp; @@ -44,11 +44,8 @@ use v1::helpers::deprecated::{self, DeprecationNotice}; use v1::helpers::light_fetch::{self, LightFetch}; use v1::traits::Eth; use v1::types::{ - RichBlock, Block, BlockTransactions, BlockNumber, LightBlockNumber, Bytes, - SyncStatus as RpcSyncStatus, SyncInfo as RpcSyncInfo, - Transaction, CallRequest, Index, Filter, Log, Receipt, Work, EthAccount, - H64 as RpcH64, H256 as RpcH256, H160 as RpcH160, U256 as RpcU256, - U64 as RpcU64, + RichBlock, Block, BlockTransactions, BlockNumber, LightBlockNumber, Bytes, SyncStatus as RpcSyncStatus, + SyncInfo as RpcSyncInfo, Transaction, CallRequest, Index, Filter, Log, Receipt, Work, EthAccount }; use v1::metadata::Metadata; @@ -251,7 +248,7 @@ where } } - fn author(&self) -> Result { + fn author(&self) -> Result { (self.accounts)() .first() .cloned() @@ -263,22 +260,22 @@ where Ok(false) } - fn chain_id(&self) -> Result> { - Ok(self.client.signing_chain_id().map(RpcU64::from)) + fn chain_id(&self) -> Result> { + Ok(self.client.signing_chain_id().map(U64::from)) } - fn hashrate(&self) -> Result { + fn hashrate(&self) -> Result { Ok(Default::default()) } - fn gas_price(&self) -> Result { + fn gas_price(&self) -> Result { Ok(self.cache.lock().gas_price_corpus() .and_then(|c| c.percentile(self.gas_price_percentile).cloned()) - .map(RpcU256::from) + .map(U256::from) .unwrap_or_else(Default::default)) } - fn accounts(&self) -> Result> { + fn accounts(&self) -> Result> { self.deprecation_notice.print("eth_accounts", deprecated::msgs::ACCOUNTS); Ok((self.accounts)() @@ -287,20 +284,20 @@ where .collect()) } - fn block_number(&self) -> Result { + fn block_number(&self) -> Result { Ok(self.client.chain_info().best_block_number.into()) } - fn balance(&self, address: RpcH160, num: Option) -> BoxFuture { + fn balance(&self, address: H160, num: Option) -> BoxFuture { Box::new(self.fetcher().account(address.into(), num.unwrap_or_default().to_block_id()) .map(|acc| acc.map_or(0.into(), |a| a.balance).into())) } - fn storage_at(&self, _address: RpcH160, _key: RpcU256, _num: Option) -> BoxFuture { + fn storage_at(&self, _address: H160, _key: U256, _num: Option) -> BoxFuture { Box::new(future::err(errors::unimplemented(None))) } - fn block_by_hash(&self, hash: RpcH256, include_txs: bool) -> BoxFuture> { + fn block_by_hash(&self, hash: H256, include_txs: bool) -> BoxFuture> { Box::new(self.rich_block(BlockId::Hash(hash.into()), include_txs).map(Some)) } @@ -308,12 +305,12 @@ where Box::new(self.rich_block(num.to_block_id(), include_txs).map(Some)) } - fn transaction_count(&self, address: RpcH160, num: Option) -> BoxFuture { + fn transaction_count(&self, address: H160, num: Option) -> BoxFuture { Box::new(self.fetcher().account(address.into(), num.unwrap_or_default().to_block_id()) .map(|acc| acc.map_or(0.into(), |a| a.nonce).into())) } - fn block_transaction_count_by_hash(&self, hash: RpcH256) -> BoxFuture> { + fn block_transaction_count_by_hash(&self, hash: H256) -> BoxFuture> { let (sync, on_demand) = (self.sync.clone(), self.on_demand.clone()); Box::new(self.fetcher().header(BlockId::Hash(hash.into())).and_then(move |hdr| { @@ -329,7 +326,7 @@ where })) } - fn block_transaction_count_by_number(&self, num: BlockNumber) -> BoxFuture> { + fn block_transaction_count_by_number(&self, num: BlockNumber) -> BoxFuture> { let (sync, on_demand) = (self.sync.clone(), self.on_demand.clone()); Box::new(self.fetcher().header(num.to_block_id()).and_then(move |hdr| { @@ -345,7 +342,7 @@ where })) } - fn block_uncles_count_by_hash(&self, hash: RpcH256) -> BoxFuture> { + fn block_uncles_count_by_hash(&self, hash: H256) -> BoxFuture> { let (sync, on_demand) = (self.sync.clone(), self.on_demand.clone()); Box::new(self.fetcher().header(BlockId::Hash(hash.into())).and_then(move |hdr| { @@ -361,7 +358,7 @@ where })) } - fn block_uncles_count_by_number(&self, num: BlockNumber) -> BoxFuture> { + fn block_uncles_count_by_number(&self, num: BlockNumber) -> BoxFuture> { let (sync, on_demand) = (self.sync.clone(), self.on_demand.clone()); Box::new(self.fetcher().header(num.to_block_id()).and_then(move |hdr| { @@ -377,11 +374,11 @@ where })) } - fn code_at(&self, address: RpcH160, num: Option) -> BoxFuture { + fn code_at(&self, address: H160, num: Option) -> BoxFuture { Box::new(self.fetcher().code(address.into(), num.unwrap_or_default().to_block_id()).map(Into::into)) } - fn send_raw_transaction(&self, raw: Bytes) -> Result { + fn send_raw_transaction(&self, raw: Bytes) -> Result { let best_header = self.client.best_block_header().decode().map_err(errors::decode)?; Rlp::new(&raw.into_vec()).as_val() @@ -400,7 +397,7 @@ where .map(Into::into) } - fn submit_transaction(&self, raw: Bytes) -> Result { + fn submit_transaction(&self, raw: Bytes) -> Result { self.send_raw_transaction(raw) } @@ -413,7 +410,7 @@ where })) } - fn estimate_gas(&self, req: CallRequest, num: Option) -> BoxFuture { + fn estimate_gas(&self, req: CallRequest, num: Option) -> BoxFuture { // TODO: binary chop for more accurate estimates. Box::new(self.fetcher().proved_read_only_execution(req, num).and_then(|res| { match res { @@ -423,7 +420,7 @@ where })) } - fn transaction_by_hash(&self, hash: RpcH256) -> BoxFuture> { + fn transaction_by_hash(&self, hash: H256) -> BoxFuture> { let hash = hash.into(); { @@ -438,7 +435,7 @@ where Box::new(self.fetcher().transaction_by_hash(hash).map(|x| x.map(|(tx, _)| tx))) } - fn transaction_by_block_hash_and_index(&self, hash: RpcH256, idx: Index) -> BoxFuture> { + fn transaction_by_block_hash_and_index(&self, hash: H256, idx: Index) -> BoxFuture> { Box::new(self.fetcher().block(BlockId::Hash(hash.into())).map(move |block| { light_fetch::extract_transaction_at_index(block, idx.value()) })) @@ -450,9 +447,9 @@ where })) } - fn transaction_receipt(&self, hash: RpcH256) -> BoxFuture> { + fn transaction_receipt(&self, hash: H256) -> BoxFuture> { let fetcher = self.fetcher(); - Box::new(fetcher.transaction_by_hash(hash.clone().into()).and_then(move |tx| { + Box::new(fetcher.transaction_by_hash(hash.into()).and_then(move |tx| { // the block hash included in the transaction object here has // already been checked for canonicality and whether it contains // the transaction. @@ -480,7 +477,7 @@ where })) } - fn uncle_by_block_hash_and_index(&self, hash: RpcH256, idx: Index) -> BoxFuture> { + fn uncle_by_block_hash_and_index(&self, hash: H256, idx: Index) -> BoxFuture> { let client = self.client.clone(); Box::new(self.fetcher().block(BlockId::Hash(hash.into())).map(move |block| { extract_uncle_at_index(block, idx, client) @@ -494,7 +491,7 @@ where })) } - fn proof(&self, _address: RpcH160, _values:Vec, _num: Option) -> BoxFuture { + fn proof(&self, _address: H160, _values:Vec, _num: Option) -> BoxFuture { Box::new(future::err(errors::unimplemented(None))) } @@ -528,11 +525,11 @@ where Err(errors::light_unimplemented(None)) } - fn submit_work(&self, _nonce: RpcH64, _pow_hash: RpcH256, _mix_hash: RpcH256) -> Result { + fn submit_work(&self, _nonce: H64, _pow_hash: H256, _mix_hash: H256) -> Result { Err(errors::light_unimplemented(None)) } - fn submit_hashrate(&self, _rate: RpcU256, _id: RpcH256) -> Result { + fn submit_hashrate(&self, _rate: U256, _id: H256) -> Result { Err(errors::light_unimplemented(None)) } } @@ -545,11 +542,11 @@ where { fn best_block_number(&self) -> u64 { self.client.chain_info().best_block_number } - fn block_hash(&self, id: BlockId) -> Option<::ethereum_types::H256> { + fn block_hash(&self, id: BlockId) -> Option { self.client.block_hash(id) } - fn pending_transaction_hashes(&self) -> BTreeSet<::ethereum_types::H256> { + fn pending_transaction_hashes(&self) -> BTreeSet { BTreeSet::new() } diff --git a/rpc/src/v1/impls/light/parity.rs b/rpc/src/v1/impls/light/parity.rs index f744095cba..da7425e1f4 100644 --- a/rpc/src/v1/impls/light/parity.rs +++ b/rpc/src/v1/impls/light/parity.rs @@ -24,6 +24,7 @@ use crypto::DEFAULT_MAC; use ethkey::{crypto::ecies, Brain, Generator}; use ethstore::random_phrase; use sync::{LightSyncInfo, LightSyncProvider, LightNetworkDispatcher, ManageNetwork}; +use ethereum_types::{H64, H160, H256, H512, U64, U256}; use ethcore_logger::RotatingLogger; use jsonrpc_core::{Result, BoxFuture}; @@ -35,7 +36,7 @@ use v1::helpers::light_fetch::{LightFetch, light_all_transactions}; use v1::metadata::Metadata; use v1::traits::Parity; use v1::types::{ - Bytes, U256, U64, H64, H160, H256, H512, CallRequest, + Bytes, CallRequest, Peers, Transaction, RpcSettings, Histogram, TransactionStats, LocalTransactionStatus, LightBlockNumber, ChainStatus, Receipt, diff --git a/rpc/src/v1/impls/light/parity_set.rs b/rpc/src/v1/impls/light/parity_set.rs index c7bd7da17a..080e9402a1 100644 --- a/rpc/src/v1/impls/light/parity_set.rs +++ b/rpc/src/v1/impls/light/parity_set.rs @@ -20,15 +20,16 @@ use std::io; use std::sync::Arc; -use sync::ManageNetwork; +use ethereum_types::{H160, H256, U256}; use fetch::{self, Fetch}; use hash::keccak_buffer; +use sync::ManageNetwork; use jsonrpc_core::{Result, BoxFuture}; use jsonrpc_core::futures::Future; use v1::helpers::errors; use v1::traits::ParitySet; -use v1::types::{Bytes, H160, H256, U256, ReleaseInfo, Transaction}; +use v1::types::{Bytes, ReleaseInfo, Transaction}; /// Parity-specific rpc interface for operations altering the settings. pub struct ParitySetClient { diff --git a/rpc/src/v1/impls/light/trace.rs b/rpc/src/v1/impls/light/trace.rs index 42f62e0c4f..a560f980e7 100644 --- a/rpc/src/v1/impls/light/trace.rs +++ b/rpc/src/v1/impls/light/trace.rs @@ -16,11 +16,13 @@ //! Traces api implementation. +use ethereum_types::H256; use jsonrpc_core::Result; use v1::Metadata; use v1::traits::Traces; use v1::helpers::errors; -use v1::types::{TraceFilter, LocalizedTrace, BlockNumber, Index, CallRequest, Bytes, TraceResults, TraceResultsWithTransactionHash, TraceOptions, H256}; +use v1::types::{TraceFilter, LocalizedTrace, BlockNumber, Index, CallRequest, Bytes, TraceResults, + TraceResultsWithTransactionHash, TraceOptions}; /// Traces api implementation. // TODO: all calling APIs should be possible w. proved remote TX execution. diff --git a/rpc/src/v1/impls/parity.rs b/rpc/src/v1/impls/parity.rs index 648b410694..d985f33f62 100644 --- a/rpc/src/v1/impls/parity.rs +++ b/rpc/src/v1/impls/parity.rs @@ -20,12 +20,12 @@ use std::str::FromStr; use std::collections::BTreeMap; use crypto::DEFAULT_MAC; +use ethereum_types::{Address, H64, H160, H256, H512, U64, U256}; use ethcore::client::{BlockChainClient, StateClient, Call}; use ethcore::miner::{self, MinerService}; use ethcore::snapshot::{SnapshotService, RestorationStatus}; use ethcore::state::StateInfo; use ethcore_logger::RotatingLogger; -use ethereum_types::Address; use ethkey::{crypto::ecies, Brain, Generator}; use ethstore::random_phrase; use jsonrpc_core::futures::future; @@ -41,7 +41,7 @@ use v1::helpers::external_signer::{SigningQueue, SignerService}; use v1::metadata::Metadata; use v1::traits::Parity; use v1::types::{ - Bytes, U256, H64, U64, H160, H256, H512, CallRequest, + Bytes, CallRequest, Peers, Transaction, RpcSettings, Histogram, TransactionStats, LocalTransactionStatus, BlockNumber, ConsensusCapability, VersionInfo, diff --git a/rpc/src/v1/impls/parity_accounts.rs b/rpc/src/v1/impls/parity_accounts.rs index 55f23dded7..e52f8b7ac0 100644 --- a/rpc/src/v1/impls/parity_accounts.rs +++ b/rpc/src/v1/impls/parity_accounts.rs @@ -20,8 +20,8 @@ use std::collections::{ btree_map::{BTreeMap, Entry}, HashSet, }; -use ethereum_types::Address; +use ethereum_types::{Address, H160, H256, H520}; use ethkey::{Brain, Generator, Secret}; use ethstore::KeyFile; use accounts::AccountProvider; @@ -29,10 +29,7 @@ use jsonrpc_core::Result; use v1::helpers::deprecated::{self, DeprecationNotice}; use v1::helpers::errors; use v1::traits::{ParityAccounts, ParityAccountsInfo}; -use v1::types::{ - H160 as RpcH160, H256 as RpcH256, H520 as RpcH520, Derive, DeriveHierarchical, DeriveHash, - ExtAccountInfo, AccountInfo, HwAccountInfo, -}; +use v1::types::{Derive, DeriveHierarchical, DeriveHash,ExtAccountInfo, AccountInfo, HwAccountInfo}; use ethkey::Password; /// Account management (personal) rpc implementation. @@ -58,7 +55,7 @@ impl ParityAccountsClient { } impl ParityAccountsInfo for ParityAccountsClient { - fn accounts_info(&self) -> Result> { + fn accounts_info(&self) -> Result> { self.deprecation_notice("parity_accountsInfo"); let dapp_accounts = self.accounts.accounts() @@ -72,18 +69,18 @@ impl ParityAccountsInfo for ParityAccountsClient { .into_iter() .chain(other.into_iter()) .filter(|&(ref a, _)| dapp_accounts.contains(a)) - .map(|(a, v)| (RpcH160::from(a), AccountInfo { name: v.name })) + .map(|(a, v)| (H160::from(a), AccountInfo { name: v.name })) .collect() ) } - fn hardware_accounts_info(&self) -> Result> { + fn hardware_accounts_info(&self) -> Result> { self.deprecation_notice("parity_hardwareAccountsInfo"); let info = self.accounts.hardware_accounts_info().map_err(|e| errors::account("Could not fetch account info.", e))?; Ok(info .into_iter() - .map(|(a, v)| (RpcH160::from(a), HwAccountInfo { name: v.name, manufacturer: v.meta })) + .map(|(a, v)| (H160::from(a), HwAccountInfo { name: v.name, manufacturer: v.meta })) .collect() ) } @@ -94,7 +91,7 @@ impl ParityAccountsInfo for ParityAccountsClient { self.accounts.locked_hardware_accounts().map_err(|e| errors::account("Error communicating with hardware wallet.", e)) } - fn default_account(&self) -> Result { + fn default_account(&self) -> Result { self.deprecation_notice("parity_defaultAccount"); Ok(self.accounts.default_account() @@ -105,9 +102,7 @@ impl ParityAccountsInfo for ParityAccountsClient { } impl ParityAccounts for ParityAccountsClient { - fn all_accounts_info(&self) -> Result> { - self.deprecation_notice("parity_allAccountsInfo"); - + fn all_accounts_info(&self) -> Result> { let info = self.accounts.accounts_info().map_err(|e| errors::account("Could not fetch account info.", e))?; let other = self.accounts.addresses_info(); @@ -120,7 +115,7 @@ impl ParityAccounts for ParityAccountsClient { uuid: v.uuid.map(|uuid| uuid.to_string()) })); - let mut accounts: BTreeMap = BTreeMap::new(); + let mut accounts: BTreeMap = BTreeMap::new(); for (address, account) in account_iter { match accounts.entry(address) { @@ -138,27 +133,24 @@ impl ParityAccounts for ParityAccountsClient { Ok(accounts) } - fn new_account_from_phrase(&self, phrase: String, pass: Password) -> Result { + fn new_account_from_phrase(&self, phrase: String, pass: Password) -> Result { self.deprecation_notice("parity_newAccountFromPhrase"); - let brain = Brain::new(phrase).generate().unwrap(); self.accounts.insert_account(brain.secret().clone(), &pass) .map(Into::into) .map_err(|e| errors::account("Could not create account.", e)) } - fn new_account_from_wallet(&self, json: String, pass: Password) -> Result { + fn new_account_from_wallet(&self, json: String, pass: Password) -> Result { self.deprecation_notice("parity_newAccountFromWallet"); - self.accounts.import_presale(json.as_bytes(), &pass) .or_else(|_| self.accounts.import_wallet(json.as_bytes(), &pass, true)) .map(Into::into) .map_err(|e| errors::account("Could not create account.", e)) } - fn new_account_from_secret(&self, secret: RpcH256, pass: Password) -> Result { + fn new_account_from_secret(&self, secret: H256, pass: Password) -> Result { self.deprecation_notice("parity_newAccountFromSecret"); - let secret = Secret::from_unsafe_slice(&secret.0) .map_err(|e| errors::account("Could not create account.", e))?; self.accounts.insert_account(secret, &pass) @@ -166,9 +158,8 @@ impl ParityAccounts for ParityAccountsClient { .map_err(|e| errors::account("Could not create account.", e)) } - fn test_password(&self, account: RpcH160, password: Password) -> Result { + fn test_password(&self, account: H160, password: Password) -> Result { self.deprecation_notice("parity_testPassword"); - let account: Address = account.into(); self.accounts @@ -176,9 +167,8 @@ impl ParityAccounts for ParityAccountsClient { .map_err(|e| errors::account("Could not fetch account info.", e)) } - fn change_password(&self, account: RpcH160, password: Password, new_password: Password) -> Result { + fn change_password(&self, account: H160, password: Password, new_password: Password) -> Result { self.deprecation_notice("parity_changePassword"); - let account: Address = account.into(); self.accounts .change_password(&account, password, new_password) @@ -186,9 +176,8 @@ impl ParityAccounts for ParityAccountsClient { .map_err(|e| errors::account("Could not fetch account info.", e)) } - fn kill_account(&self, account: RpcH160, password: Password) -> Result { + fn kill_account(&self, account: H160, password: Password) -> Result { self.deprecation_notice("parity_killAccount"); - let account: Address = account.into(); self.accounts .kill_account(&account, &password) @@ -196,18 +185,16 @@ impl ParityAccounts for ParityAccountsClient { .map_err(|e| errors::account("Could not delete account.", e)) } - fn remove_address(&self, addr: RpcH160) -> Result { + fn remove_address(&self, addr: H160) -> Result { self.deprecation_notice("parity_removeAddresss"); - let addr: Address = addr.into(); self.accounts.remove_address(addr); Ok(true) } - fn set_account_name(&self, addr: RpcH160, name: String) -> Result { + fn set_account_name(&self, addr: H160, name: String) -> Result { self.deprecation_notice("parity_setAccountName"); - let addr: Address = addr.into(); self.accounts.set_account_name(addr.clone(), name.clone()) @@ -215,9 +202,8 @@ impl ParityAccounts for ParityAccountsClient { Ok(true) } - fn set_account_meta(&self, addr: RpcH160, meta: String) -> Result { + fn set_account_meta(&self, addr: H160, meta: String) -> Result { self.deprecation_notice("parity_setAccountMeta"); - let addr: Address = addr.into(); self.accounts.set_account_meta(addr.clone(), meta.clone()) @@ -225,18 +211,16 @@ impl ParityAccounts for ParityAccountsClient { Ok(true) } - fn import_geth_accounts(&self, addresses: Vec) -> Result> { + fn import_geth_accounts(&self, addresses: Vec) -> Result> { self.deprecation_notice("parity_importGethAccounts"); - self.accounts .import_geth_accounts(into_vec(addresses), false) .map(into_vec) .map_err(|e| errors::account("Couldn't import Geth accounts", e)) } - fn geth_accounts(&self) -> Result> { + fn geth_accounts(&self) -> Result> { self.deprecation_notice("parity_listGethAccounts"); - Ok(into_vec(self.accounts.list_geth_accounts(false))) } @@ -292,9 +276,8 @@ impl ParityAccounts for ParityAccountsClient { .map(|_| true) } - fn change_vault(&self, address: RpcH160, new_vault: String) -> Result { + fn change_vault(&self, address: H160, new_vault: String) -> Result { self.deprecation_notice("parity_changeVault"); - self.accounts .change_vault(address.into(), &new_vault) .map_err(|e| errors::account("Could not change vault.", e)) @@ -318,9 +301,8 @@ impl ParityAccounts for ParityAccountsClient { .map(|_| true) } - fn derive_key_index(&self, addr: RpcH160, password: Password, derivation: DeriveHierarchical, save_as_account: bool) -> Result { + fn derive_key_index(&self, addr: H160, password: Password, derivation: DeriveHierarchical, save_as_account: bool) -> Result { self.deprecation_notice("parity_deriveAddressIndex"); - let addr: Address = addr.into(); self.accounts .derive_account( @@ -333,9 +315,8 @@ impl ParityAccounts for ParityAccountsClient { .map_err(|e| errors::account("Could not derive account.", e)) } - fn derive_key_hash(&self, addr: RpcH160, password: Password, derivation: DeriveHash, save_as_account: bool) -> Result { + fn derive_key_hash(&self, addr: H160, password: Password, derivation: DeriveHash, save_as_account: bool) -> Result { self.deprecation_notice("parity_deriveAddressHash"); - let addr: Address = addr.into(); self.accounts .derive_account( @@ -348,9 +329,8 @@ impl ParityAccounts for ParityAccountsClient { .map_err(|e| errors::account("Could not derive account.", e)) } - fn export_account(&self, addr: RpcH160, password: Password) -> Result { + fn export_account(&self, addr: H160, password: Password) -> Result { self.deprecation_notice("parity_exportAccount"); - let addr = addr.into(); self.accounts .export_account( @@ -361,9 +341,8 @@ impl ParityAccounts for ParityAccountsClient { .map_err(|e| errors::account("Could not export account.", e)) } - fn sign_message(&self, addr: RpcH160, password: Password, message: RpcH256) -> Result { + fn sign_message(&self, addr: H160, password: Password, message: H256) -> Result { self.deprecation_notice("parity_signMessage"); - self.accounts .sign( addr.into(), diff --git a/rpc/src/v1/impls/parity_set.rs b/rpc/src/v1/impls/parity_set.rs index 3e0d269745..a50138eb19 100644 --- a/rpc/src/v1/impls/parity_set.rs +++ b/rpc/src/v1/impls/parity_set.rs @@ -21,7 +21,7 @@ use std::time::Duration; use ethcore::client::{BlockChainClient, Mode}; use ethcore::miner::{self, MinerService}; -use ethereum_types::H256 as EthH256; +use ethereum_types::{H160, H256, U256}; use ethkey; use fetch::{self, Fetch}; use hash::keccak_buffer; @@ -32,7 +32,7 @@ use jsonrpc_core::{BoxFuture, Result}; use jsonrpc_core::futures::Future; use v1::helpers::errors; use v1::traits::ParitySet; -use v1::types::{Bytes, H160, H256, U256, ReleaseInfo, Transaction}; +use v1::types::{Bytes, ReleaseInfo, Transaction}; #[cfg(any(test, feature = "accounts"))] pub mod accounts { @@ -160,7 +160,6 @@ impl ParitySet for ParitySetClient where } fn set_engine_signer_secret(&self, secret: H256) -> Result { - let secret: EthH256 = secret.into(); let keypair = ethkey::KeyPair::from_secret(secret.into()).map_err(|e| errors::account("Invalid secret", e))?; self.miner.set_author(miner::Author::Sealer(ethcore::engines::signer::from_keypair(keypair))); Ok(true) diff --git a/rpc/src/v1/impls/personal.rs b/rpc/src/v1/impls/personal.rs index 92886cbe31..b6af1f81e5 100644 --- a/rpc/src/v1/impls/personal.rs +++ b/rpc/src/v1/impls/personal.rs @@ -21,7 +21,7 @@ use std::time::Duration; use accounts::AccountProvider; use bytes::Bytes; use eip_712::{EIP712, hash_structured_data}; -use ethereum_types::{H520, U128, Address}; +use ethereum_types::{H160, H256, H520, U128, Address}; use ethkey::{public_to_address, recover, Signature}; use types::transaction::{PendingTransaction, SignedTransaction}; @@ -34,7 +34,6 @@ use v1::helpers::{errors, eip191}; use v1::metadata::Metadata; use v1::traits::Personal; use v1::types::{ - H160 as RpcH160, H256 as RpcH256, H520 as RpcH520, U128 as RpcU128, Bytes as RpcBytes, ConfirmationPayload as RpcConfirmationPayload, ConfirmationResponse as RpcConfirmationResponse, @@ -108,24 +107,21 @@ impl PersonalClient { impl Personal for PersonalClient { type Metadata = Metadata; - fn accounts(&self) -> Result> { + fn accounts(&self) -> Result> { self.deprecation_notice.print("personal_accounts", deprecated::msgs::ACCOUNTS); - let accounts = self.accounts.accounts().map_err(|e| errors::account("Could not fetch accounts.", e))?; - Ok(accounts.into_iter().map(Into::into).collect::>()) + Ok(accounts.into_iter().map(Into::into).collect::>()) } - fn new_account(&self, pass: String) -> Result { + fn new_account(&self, pass: String) -> Result { self.deprecation_notice.print("personal_newAccount", deprecated::msgs::ACCOUNTS); - self.accounts.new_account(&pass.into()) .map(Into::into) .map_err(|e| errors::account("Could not create account.", e)) } - fn unlock_account(&self, account: RpcH160, account_pass: String, duration: Option) -> Result { + fn unlock_account(&self, account: H160, account_pass: String, duration: Option) -> Result { self.deprecation_notice.print("personal_unlockAccount", deprecated::msgs::ACCOUNTS); - let account: Address = account.into(); let store = self.accounts.clone(); let duration = match duration { @@ -157,9 +153,8 @@ impl Personal for PersonalClient { } } - fn sign(&self, data: RpcBytes, account: RpcH160, password: String) -> BoxFuture { + fn sign(&self, data: RpcBytes, account: H160, password: String) -> BoxFuture { self.deprecation_notice.print("personal_sign", deprecated::msgs::ACCOUNTS); - let dispatcher = self.dispatcher.clone(); let accounts = Arc::new(dispatch::Signer::new(self.accounts.clone())) as _; @@ -177,9 +172,8 @@ impl Personal for PersonalClient { })) } - fn sign_191(&self, version: EIP191Version, data: Value, account: RpcH160, password: String) -> BoxFuture { + fn sign_191(&self, version: EIP191Version, data: Value, account: H160, password: String) -> BoxFuture { self.deprecation_notice.print("personal_sign191", deprecated::msgs::ACCOUNTS); - try_bf!(errors::require_experimental(self.allow_experimental_rpcs, "191")); let data = try_bf!(eip191::hash_message(version, data)); @@ -201,9 +195,8 @@ impl Personal for PersonalClient { ) } - fn sign_typed_data(&self, typed_data: EIP712, account: RpcH160, password: String) -> BoxFuture { + fn sign_typed_data(&self, typed_data: EIP712, account: H160, password: String) -> BoxFuture { self.deprecation_notice.print("personal_signTypedData", deprecated::msgs::ACCOUNTS); - try_bf!(errors::require_experimental(self.allow_experimental_rpcs, "712")); let data = match hash_structured_data(typed_data) { @@ -228,7 +221,7 @@ impl Personal for PersonalClient { ) } - fn ec_recover(&self, data: RpcBytes, signature: RpcH520) -> BoxFuture { + fn ec_recover(&self, data: RpcBytes, signature: H520) -> BoxFuture { let signature: H520 = signature.into(); let signature = Signature::from_electrum(&signature); let data: Bytes = data.into(); @@ -253,28 +246,25 @@ impl Personal for PersonalClient { .map(move |pending_tx| dispatcher.enrich(pending_tx.transaction))) } - fn send_transaction(&self, meta: Metadata, request: TransactionRequest, password: String) -> BoxFuture { + fn send_transaction(&self, meta: Metadata, request: TransactionRequest, password: String) -> BoxFuture { self.deprecation_notice.print("personal_sendTransaction", deprecated::msgs::ACCOUNTS); - let condition = request.condition.clone().map(Into::into); let dispatcher = self.dispatcher.clone(); Box::new( - self.do_sign_transaction(meta, request, password, move |signed: WithToken| { + self.do_sign_transaction(meta, request, password, move |signed: WithToken| { dispatcher.dispatch_transaction( PendingTransaction::new( signed.into_value(), condition ) ) - }).and_then(|hash| { - Ok(RpcH256::from(hash)) }) ) } - fn sign_and_send_transaction(&self, meta: Metadata, request: TransactionRequest, password: String) -> BoxFuture { + fn sign_and_send_transaction(&self, meta: Metadata, request: TransactionRequest, password: String) -> BoxFuture { self.deprecation_notice.print("personal_signAndSendTransaction", Some("use personal_sendTransaction instead.")); - + warn!("Using deprecated personal_signAndSendTransaction, use personal_sendTransaction instead."); self.send_transaction(meta, request, password) } } diff --git a/rpc/src/v1/impls/private.rs b/rpc/src/v1/impls/private.rs index e9c8c239cd..f1cf991240 100644 --- a/rpc/src/v1/impls/private.rs +++ b/rpc/src/v1/impls/private.rs @@ -21,11 +21,11 @@ use std::sync::Arc; use rlp::Rlp; use ethcore_private_tx::Provider as PrivateTransactionManager; -use ethereum_types::Address; +use ethereum_types::{Address, H160, H256, U256}; use types::transaction::SignedTransaction; use jsonrpc_core::{Error}; -use v1::types::{Bytes, PrivateTransactionReceipt, H160, H256, TransactionRequest, U256, +use v1::types::{Bytes, PrivateTransactionReceipt, TransactionRequest, BlockNumber, PrivateTransactionReceiptAndTransaction, CallRequest, block_number_to_id}; use v1::traits::Private; use v1::metadata::Metadata; diff --git a/rpc/src/v1/impls/secretstore.rs b/rpc/src/v1/impls/secretstore.rs index 8eb1c3d112..b6526b85d5 100644 --- a/rpc/src/v1/impls/secretstore.rs +++ b/rpc/src/v1/impls/secretstore.rs @@ -19,16 +19,17 @@ use std::collections::BTreeSet; use std::sync::Arc; +use accounts::AccountProvider; use crypto::DEFAULT_MAC; +use ethereum_types::{H160, H256, H512}; use ethkey::Secret; -use accounts::AccountProvider; use jsonrpc_core::Result; use v1::helpers::errors; use v1::helpers::secretstore::{generate_document_key, encrypt_document, decrypt_document, decrypt_document_with_shadow, ordered_servers_keccak}; use v1::traits::SecretStore; -use v1::types::{H160, H256, H512, Bytes, EncryptedDocumentKey}; +use v1::types::{Bytes, EncryptedDocumentKey}; use ethkey::Password; /// Parity implementation. diff --git a/rpc/src/v1/impls/signer.rs b/rpc/src/v1/impls/signer.rs index 152a16d4b3..c4f4d35766 100644 --- a/rpc/src/v1/impls/signer.rs +++ b/rpc/src/v1/impls/signer.rs @@ -18,6 +18,7 @@ use std::sync::Arc; +use ethereum_types::U256; use ethkey; use parity_runtime::Executor; use parking_lot::Mutex; @@ -34,7 +35,7 @@ use v1::helpers::{errors, ConfirmationPayload, FilledTransactionRequest, Subscri use v1::helpers::external_signer::{SigningQueue, SignerService}; use v1::metadata::Metadata; use v1::traits::Signer; -use v1::types::{TransactionModification, ConfirmationRequest, ConfirmationResponse, ConfirmationResponseWithToken, U256, Bytes}; +use v1::types::{TransactionModification, ConfirmationRequest, ConfirmationResponse, ConfirmationResponseWithToken, Bytes}; /// Transactions confirmation (personal) rpc implementation. pub struct SignerClient { diff --git a/rpc/src/v1/impls/signing.rs b/rpc/src/v1/impls/signing.rs index 96d4059aa2..12f8909563 100644 --- a/rpc/src/v1/impls/signing.rs +++ b/rpc/src/v1/impls/signing.rs @@ -18,9 +18,10 @@ use std::sync::Arc; use transient_hashmap::TransientHashMap; -use ethereum_types::U256; use parking_lot::Mutex; +use ethereum_types::{H160, H256, H520, U256}; + use jsonrpc_core::{BoxFuture, Result, Error}; use jsonrpc_core::futures::{future, Future, Poll, Async}; use jsonrpc_core::futures::future::Either; @@ -36,7 +37,7 @@ use v1::helpers::external_signer::{ use v1::metadata::Metadata; use v1::traits::{EthSigning, ParitySigning}; use v1::types::{ - H160 as RpcH160, H256 as RpcH256, U256 as RpcU256, Bytes as RpcBytes, H520 as RpcH520, + Bytes as RpcBytes, Either as RpcEither, RichRawTransaction as RpcRichRawTransaction, TransactionRequest as RpcTransactionRequest, @@ -142,9 +143,8 @@ impl ParitySigning for SigningQueueClient { Box::new(self.dispatcher.fill_optional_fields(transaction.into(), default_account, true).map(Into::into)) } - fn post_sign(&self, meta: Metadata, address: RpcH160, data: RpcBytes) -> BoxFuture> { + fn post_sign(&self, meta: Metadata, address: H160, data: RpcBytes) -> BoxFuture> { self.deprecation_notice.print("parity_postSign", deprecated::msgs::ACCOUNTS); - let executor = self.executor.clone(); let confirmations = self.confirmations.clone(); @@ -160,9 +160,8 @@ impl ParitySigning for SigningQueueClient { })) } - fn post_transaction(&self, meta: Metadata, request: RpcTransactionRequest) -> BoxFuture> { + fn post_transaction(&self, meta: Metadata, request: RpcTransactionRequest) -> BoxFuture> { self.deprecation_notice.print("parity_postTransaction", deprecated::msgs::ACCOUNTS); - let executor = self.executor.clone(); let confirmations = self.confirmations.clone(); @@ -176,9 +175,8 @@ impl ParitySigning for SigningQueueClient { })) } - fn check_request(&self, id: RpcU256) -> Result> { + fn check_request(&self, id: U256) -> Result> { self.deprecation_notice.print("parity_checkRequest", deprecated::msgs::ACCOUNTS); - let id: U256 = id.into(); match self.confirmations.lock().get(&id) { None => Err(errors::request_not_found()), // Request info has been dropped, or even never been there @@ -187,9 +185,8 @@ impl ParitySigning for SigningQueueClient { } } - fn decrypt_message(&self, meta: Metadata, address: RpcH160, data: RpcBytes) -> BoxFuture { + fn decrypt_message(&self, meta: Metadata, address: H160, data: RpcBytes) -> BoxFuture { self.deprecation_notice.print("parity_decryptMessage", deprecated::msgs::ACCOUNTS); - let res = self.dispatch( RpcConfirmationPayload::Decrypt((address.clone(), data).into()), meta.origin, @@ -208,9 +205,8 @@ impl ParitySigning for SigningQueueClient { impl EthSigning for SigningQueueClient { type Metadata = Metadata; - fn sign(&self, meta: Metadata, address: RpcH160, data: RpcBytes) -> BoxFuture { + fn sign(&self, meta: Metadata, address: H160, data: RpcBytes) -> BoxFuture { self.deprecation_notice.print("eth_sign", deprecated::msgs::ACCOUNTS); - let res = self.dispatch( RpcConfirmationPayload::EthSignMessage((address.clone(), data).into()), meta.origin, @@ -224,9 +220,8 @@ impl EthSigning for SigningQueueClient { })) } - fn send_transaction(&self, meta: Metadata, request: RpcTransactionRequest) -> BoxFuture { + fn send_transaction(&self, meta: Metadata, request: RpcTransactionRequest) -> BoxFuture { self.deprecation_notice.print("eth_sendTransaction", deprecated::msgs::ACCOUNTS); - let res = self.dispatch( RpcConfirmationPayload::SendTransaction(request), meta.origin, diff --git a/rpc/src/v1/impls/signing_unsafe.rs b/rpc/src/v1/impls/signing_unsafe.rs index 59b8d5e9dc..72a3a6fbf1 100644 --- a/rpc/src/v1/impls/signing_unsafe.rs +++ b/rpc/src/v1/impls/signing_unsafe.rs @@ -18,8 +18,7 @@ use std::sync::Arc; -use ethereum_types::Address; - +use ethereum_types::{Address, H160, H256, H520, U256}; use jsonrpc_core::{BoxFuture, Result}; use jsonrpc_core::futures::{future, Future}; use v1::helpers::{errors}; @@ -28,8 +27,7 @@ use v1::helpers::dispatch::{self, Dispatcher}; use v1::metadata::Metadata; use v1::traits::{EthSigning, ParitySigning}; use v1::types::{ - U256 as RpcU256, - H160 as RpcH160, H256 as RpcH256, H520 as RpcH520, Bytes as RpcBytes, + Bytes as RpcBytes, Either as RpcEither, RichRawTransaction as RpcRichRawTransaction, TransactionRequest as RpcTransactionRequest, @@ -70,9 +68,8 @@ impl EthSigning for SigningUnsafeClient { type Metadata = Metadata; - fn sign(&self, _: Metadata, address: RpcH160, data: RpcBytes) -> BoxFuture { + fn sign(&self, _: Metadata, address: H160, data: RpcBytes) -> BoxFuture { self.deprecation_notice.print("eth_sign", deprecated::msgs::ACCOUNTS); - Box::new(self.handle(RpcConfirmationPayload::EthSignMessage((address.clone(), data).into()), address.into()) .then(|res| match res { Ok(RpcConfirmationResponse::Signature(signature)) => Ok(signature), @@ -81,9 +78,8 @@ impl EthSigning for SigningUnsafeClient })) } - fn send_transaction(&self, _meta: Metadata, request: RpcTransactionRequest) -> BoxFuture { + fn send_transaction(&self, _meta: Metadata, request: RpcTransactionRequest) -> BoxFuture { self.deprecation_notice.print("eth_sendTransaction", deprecated::msgs::ACCOUNTS); - Box::new(self.handle(RpcConfirmationPayload::SendTransaction(request), self.accounts.default_account()) .then(|res| match res { Ok(RpcConfirmationResponse::SendTransaction(hash)) => Ok(hash), @@ -113,9 +109,8 @@ impl ParitySigning for SigningUnsafeClient { Box::new(self.dispatcher.fill_optional_fields(transaction.into(), default_account, true).map(Into::into)) } - fn decrypt_message(&self, _: Metadata, address: RpcH160, data: RpcBytes) -> BoxFuture { + fn decrypt_message(&self, _: Metadata, address: H160, data: RpcBytes) -> BoxFuture { self.deprecation_notice.print("parity_decryptMessage", deprecated::msgs::ACCOUNTS); - Box::new(self.handle(RpcConfirmationPayload::Decrypt((address.clone(), data).into()), address.into()) .then(|res| match res { Ok(RpcConfirmationResponse::Decrypt(data)) => Ok(data), @@ -124,17 +119,17 @@ impl ParitySigning for SigningUnsafeClient { })) } - fn post_sign(&self, _: Metadata, _: RpcH160, _: RpcBytes) -> BoxFuture> { + fn post_sign(&self, _: Metadata, _: H160, _: RpcBytes) -> BoxFuture> { // We don't support this in non-signer mode. Box::new(future::err(errors::signer_disabled())) } - fn post_transaction(&self, _: Metadata, _: RpcTransactionRequest) -> BoxFuture> { + fn post_transaction(&self, _: Metadata, _: RpcTransactionRequest) -> BoxFuture> { // We don't support this in non-signer mode. Box::new(future::err(errors::signer_disabled())) } - fn check_request(&self, _: RpcU256) -> Result> { + fn check_request(&self, _: U256) -> Result> { // We don't support this in non-signer mode. Err(errors::signer_disabled()) } diff --git a/rpc/src/v1/impls/traces.rs b/rpc/src/v1/impls/traces.rs index f2a5c83d4e..d7428aad27 100644 --- a/rpc/src/v1/impls/traces.rs +++ b/rpc/src/v1/impls/traces.rs @@ -19,6 +19,7 @@ use std::sync::Arc; use ethcore::client::{BlockChainClient, CallAnalytics, TransactionId, TraceId, StateClient, StateInfo, Call, BlockId}; +use ethereum_types::H256; use rlp::Rlp; use types::transaction::SignedTransaction; @@ -26,7 +27,8 @@ use jsonrpc_core::Result; use v1::Metadata; use v1::traits::Traces; use v1::helpers::{errors, fake_sign}; -use v1::types::{TraceFilter, LocalizedTrace, BlockNumber, Index, CallRequest, Bytes, TraceResults, TraceResultsWithTransactionHash, TraceOptions, H256, block_number_to_id}; +use v1::types::{TraceFilter, LocalizedTrace, BlockNumber, Index, CallRequest, Bytes, TraceResults, + TraceResultsWithTransactionHash, TraceOptions, block_number_to_id}; fn to_call_analytics(flags: TraceOptions) -> CallAnalytics { CallAnalytics { diff --git a/rpc/src/v1/impls/web3.rs b/rpc/src/v1/impls/web3.rs index 3dfe2a6653..e7bf9dd49f 100644 --- a/rpc/src/v1/impls/web3.rs +++ b/rpc/src/v1/impls/web3.rs @@ -15,11 +15,12 @@ // along with Parity Ethereum. If not, see . //! Web3 rpc implementation. +use ethereum_types::H256; use hash::keccak; use jsonrpc_core::Result; use version::version; use v1::traits::Web3; -use v1::types::{H256, Bytes}; +use v1::types::Bytes; /// Web3 rpc implementation. pub struct Web3Client; diff --git a/rpc/src/v1/mod.rs b/rpc/src/v1/mod.rs index 67b25bffbf..8b8afacdb1 100644 --- a/rpc/src/v1/mod.rs +++ b/rpc/src/v1/mod.rs @@ -53,5 +53,5 @@ pub mod signer { #[cfg(any(test, feature = "accounts"))] pub use super::helpers::engine_signer::EngineSigner; pub use super::helpers::external_signer::{SignerService, ConfirmationsQueue}; - pub use super::types::{ConfirmationRequest, TransactionModification, U256, TransactionCondition}; + pub use super::types::{ConfirmationRequest, TransactionModification, TransactionCondition}; } diff --git a/rpc/src/v1/tests/eth.rs b/rpc/src/v1/tests/eth.rs index 56398add1e..68710ae559 100644 --- a/rpc/src/v1/tests/eth.rs +++ b/rpc/src/v1/tests/eth.rs @@ -26,7 +26,7 @@ use ethcore::spec::{Genesis, Spec}; use ethcore::test_helpers; use ethcore::verification::VerifierType; use ethcore::verification::queue::kind::blocks::Unverified; -use ethereum_types::{H256, Address}; +use ethereum_types::{Address, H256, U256}; use ethjson::blockchain::BlockChain; use ethjson::spec::ForkSpec; use io::IoChannel; @@ -42,7 +42,6 @@ use v1::impls::{EthClient, EthClientOptions, SigningUnsafeClient}; use v1::metadata::Metadata; use v1::tests::helpers::{TestSnapshotService, TestSyncProvider, Config}; use v1::traits::{Eth, EthSigning}; -use v1::types::U256 as NU256; fn account_provider() -> Arc { Arc::new(AccountProvider::transient_provider()) @@ -459,7 +458,7 @@ fn verify_transaction_counts(name: String, chain: BlockChain) { "jsonrpc": "2.0", "method": "eth_getBlockTransactionCountByNumber", "params": [ - "#.to_owned() + &::serde_json::to_string(&NU256::from(num)).unwrap() + r#" + "#.to_owned() + &::serde_json::to_string(&U256::from(num)).unwrap() + r#" ], "id": "# + format!("{}", *id).as_ref() + r#" }"#; diff --git a/rpc/src/v1/tests/mocked/personal.rs b/rpc/src/v1/tests/mocked/personal.rs index 771abe24ef..a2d6b87ce2 100644 --- a/rpc/src/v1/tests/mocked/personal.rs +++ b/rpc/src/v1/tests/mocked/personal.rs @@ -18,8 +18,8 @@ use std::sync::Arc; use std::str::FromStr; use bytes::ToPretty; -use ethereum_types::{U256, Address}; use accounts::AccountProvider; +use ethereum_types::{Address, H520, U256}; use ethcore::client::TestBlockChainClient; use jsonrpc_core::IoHandler; use parking_lot::Mutex; @@ -31,7 +31,7 @@ use v1::{PersonalClient, Personal, Metadata}; use v1::helpers::{nonce, eip191}; use v1::helpers::dispatch::{eth_data_hash, FullDispatcher}; use v1::tests::helpers::TestMinerService; -use v1::types::{EIP191Version, PresignedTransaction, H520}; +use v1::types::{EIP191Version, PresignedTransaction}; use rustc_hex::ToHex; use serde_json::to_value; use ethkey::Secret; @@ -156,7 +156,7 @@ fn sign() { let hash = eth_data_hash(data); let signature = H520(tester.accounts.sign(address, Some("password123".into()), hash).unwrap().into_electrum()); - let signature = format!("0x{:?}", signature); + let signature = format!("{:?}", signature); let response = r#"{"jsonrpc":"2.0","result":""#.to_owned() + &signature + r#"","id":1}"#; @@ -264,7 +264,7 @@ fn ec_recover() { let hash = eth_data_hash(data.clone()); let signature = H520(tester.accounts.sign(address, Some("password123".into()), hash).unwrap().into_electrum()); - let signature = format!("0x{:?}", signature); + let signature = format!("{:?}", signature); let request = r#"{ "jsonrpc": "2.0", diff --git a/rpc/src/v1/tests/mocked/secretstore.rs b/rpc/src/v1/tests/mocked/secretstore.rs index fa3cba58fd..96e20d0028 100644 --- a/rpc/src/v1/tests/mocked/secretstore.rs +++ b/rpc/src/v1/tests/mocked/secretstore.rs @@ -18,6 +18,7 @@ use std::sync::Arc; use crypto::DEFAULT_MAC; use accounts::AccountProvider; +use ethereum_types::H256; use ethkey::{KeyPair, Signature, verify_public}; use serde_json; @@ -26,7 +27,7 @@ use v1::metadata::Metadata; use v1::SecretStoreClient; use v1::traits::secretstore::SecretStore; use v1::helpers::secretstore::ordered_servers_keccak; -use v1::types::{H256, EncryptedDocumentKey}; +use v1::types::EncryptedDocumentKey; struct Dependencies { pub accounts: Arc, diff --git a/rpc/src/v1/tests/mocked/signer.rs b/rpc/src/v1/tests/mocked/signer.rs index dea1f1fb7f..e22c5b8d24 100644 --- a/rpc/src/v1/tests/mocked/signer.rs +++ b/rpc/src/v1/tests/mocked/signer.rs @@ -16,7 +16,7 @@ use std::sync::Arc; use std::str::FromStr; -use ethereum_types::{U256, Address}; +use ethereum_types::{H520, U256, Address}; use bytes::ToPretty; use accounts::AccountProvider; @@ -31,7 +31,7 @@ use jsonrpc_core::IoHandler; use v1::{SignerClient, Signer, Origin}; use v1::metadata::Metadata; use v1::tests::helpers::TestMinerService; -use v1::types::{Bytes as RpcBytes, H520}; +use v1::types::Bytes as RpcBytes; use v1::helpers::{nonce, FilledTransactionRequest, ConfirmationPayload}; use v1::helpers::external_signer::{SigningQueue, SignerService}; use v1::helpers::dispatch::{self, FullDispatcher, eth_data_hash}; @@ -495,7 +495,7 @@ fn should_confirm_data_sign_with_signature() { let data_hash = eth_data_hash(vec![1, 2, 3, 4].into()); let signature = H520(tester.accounts.sign(address, Some("test".into()), data_hash).unwrap().into_electrum()); - let signature = format!("0x{:?}", signature); + let signature = format!("{:?}", signature); // when let request = r#"{ diff --git a/rpc/src/v1/tests/mocked/signing_unsafe.rs b/rpc/src/v1/tests/mocked/signing_unsafe.rs index 7e82038571..a91a85ea1f 100644 --- a/rpc/src/v1/tests/mocked/signing_unsafe.rs +++ b/rpc/src/v1/tests/mocked/signing_unsafe.rs @@ -210,7 +210,7 @@ fn rpc_eth_send_transaction_with_bad_to() { "id": 1 }"#; - let response = r#"{"jsonrpc":"2.0","error":{"code":-32602,"message":"Invalid params: expected a hex-encoded hash with 0x prefix."},"id":1}"#; + let response = r#"{"jsonrpc":"2.0","error":{"code":-32602,"message":"Invalid params: prefix is missing."},"id":1}"#; assert_eq!(tester.io.handle_request_sync(&request), Some(response.into())); } diff --git a/rpc/src/v1/traits/eth.rs b/rpc/src/v1/traits/eth.rs index 0f0dc48a59..14f8fb69e1 100644 --- a/rpc/src/v1/traits/eth.rs +++ b/rpc/src/v1/traits/eth.rs @@ -17,10 +17,10 @@ //! Eth rpc interface. use jsonrpc_core::{Result, BoxFuture}; use jsonrpc_derive::rpc; +use ethereum_types::{H64, H160, H256, U64, U256}; use v1::types::{RichBlock, BlockNumber, Bytes, CallRequest, Filter, FilterChanges, Index, EthAccount}; use v1::types::{Log, Receipt, SyncStatus, Transaction, Work}; -use v1::types::{H64, H160, H256, U256, U64}; /// Eth rpc interface. #[rpc] diff --git a/rpc/src/v1/traits/eth_signing.rs b/rpc/src/v1/traits/eth_signing.rs index c272a42e40..72e13ddabe 100644 --- a/rpc/src/v1/traits/eth_signing.rs +++ b/rpc/src/v1/traits/eth_signing.rs @@ -19,7 +19,8 @@ use jsonrpc_core::BoxFuture; use jsonrpc_derive::rpc; -use v1::types::{Bytes, H160, H256, H520, TransactionRequest, RichRawTransaction}; +use ethereum_types::{H160, H256, H520}; +use v1::types::{Bytes, TransactionRequest, RichRawTransaction}; /// Signing methods implementation relying on unlocked accounts. #[rpc] diff --git a/rpc/src/v1/traits/parity.rs b/rpc/src/v1/traits/parity.rs index 4303af3d6f..e3821355ee 100644 --- a/rpc/src/v1/traits/parity.rs +++ b/rpc/src/v1/traits/parity.rs @@ -18,10 +18,11 @@ use std::collections::BTreeMap; +use ethereum_types::{H64, H160, H256, H512, U64, U256}; use jsonrpc_core::{BoxFuture, Result}; use jsonrpc_derive::rpc; use v1::types::{ - H160, H256, H512, U256, U64, H64, Bytes, CallRequest, + Bytes, CallRequest, Peers, Transaction, RpcSettings, Histogram, RecoveredAccount, TransactionStats, LocalTransactionStatus, BlockNumber, ConsensusCapability, VersionInfo, diff --git a/rpc/src/v1/traits/parity_accounts.rs b/rpc/src/v1/traits/parity_accounts.rs index b17e4b8dfc..eaffac7885 100644 --- a/rpc/src/v1/traits/parity_accounts.rs +++ b/rpc/src/v1/traits/parity_accounts.rs @@ -19,9 +19,10 @@ use std::collections::BTreeMap; use jsonrpc_core::Result; use jsonrpc_derive::rpc; +use ethereum_types::{H160, H256, H520}; use ethkey::Password; use ethstore::KeyFile; -use v1::types::{H160, H256, H520, DeriveHash, DeriveHierarchical, ExtAccountInfo}; +use v1::types::{DeriveHash, DeriveHierarchical, ExtAccountInfo}; use v1::types::{AccountInfo, HwAccountInfo}; /// Parity-specific read-only accounts rpc interface. diff --git a/rpc/src/v1/traits/parity_set.rs b/rpc/src/v1/traits/parity_set.rs index b2628f364c..c7c2338790 100644 --- a/rpc/src/v1/traits/parity_set.rs +++ b/rpc/src/v1/traits/parity_set.rs @@ -16,10 +16,11 @@ //! Parity-specific rpc interface for operations altering the settings. +use ethereum_types::{H160, H256, U256}; use jsonrpc_core::{BoxFuture, Result}; use jsonrpc_derive::rpc; -use v1::types::{Bytes, H160, H256, U256, ReleaseInfo, Transaction}; +use v1::types::{Bytes, ReleaseInfo, Transaction}; /// Parity-specific rpc interface for operations altering the account-related settings. #[rpc] diff --git a/rpc/src/v1/traits/parity_signing.rs b/rpc/src/v1/traits/parity_signing.rs index 26495831a7..acd9e8cd68 100644 --- a/rpc/src/v1/traits/parity_signing.rs +++ b/rpc/src/v1/traits/parity_signing.rs @@ -18,7 +18,8 @@ use jsonrpc_core::{BoxFuture, Result}; use jsonrpc_derive::rpc; -use v1::types::{U256, H160, Bytes, ConfirmationResponse, TransactionRequest, Either}; +use ethereum_types::{H160, U256}; +use v1::types::{Bytes, ConfirmationResponse, TransactionRequest, Either}; /// Signing methods implementation. #[rpc] diff --git a/rpc/src/v1/traits/personal.rs b/rpc/src/v1/traits/personal.rs index 25412f6646..e3632731fa 100644 --- a/rpc/src/v1/traits/personal.rs +++ b/rpc/src/v1/traits/personal.rs @@ -16,10 +16,11 @@ //! Personal rpc interface. use eip_712::EIP712; +use ethereum_types::{H160, H256, H520, U128}; use jsonrpc_core::types::Value; use jsonrpc_core::{BoxFuture, Result}; use jsonrpc_derive::rpc; -use v1::types::{Bytes, U128, H160, H256, H520, TransactionRequest, RichRawTransaction as RpcRichRawTransaction, EIP191Version}; +use v1::types::{Bytes, TransactionRequest, RichRawTransaction as RpcRichRawTransaction, EIP191Version}; /// Personal rpc interface. Safe (read-only) functions. #[rpc] @@ -70,5 +71,4 @@ pub trait Personal { /// @deprecated alias for `personal_sendTransaction`. #[rpc(meta, name = "personal_signAndSendTransaction")] fn sign_and_send_transaction(&self, Self::Metadata, TransactionRequest, String) -> BoxFuture; - } diff --git a/rpc/src/v1/traits/private.rs b/rpc/src/v1/traits/private.rs index b7b871df04..732e3914bd 100644 --- a/rpc/src/v1/traits/private.rs +++ b/rpc/src/v1/traits/private.rs @@ -16,10 +16,11 @@ //! SecretStore-specific rpc interface. +use ethereum_types::{H160, H256, U256}; use jsonrpc_core::Error; use jsonrpc_derive::rpc; -use v1::types::{Bytes, PrivateTransactionReceipt, H160, H256, U256, BlockNumber, +use v1::types::{Bytes, PrivateTransactionReceipt, BlockNumber, PrivateTransactionReceiptAndTransaction, CallRequest}; /// Private transaction management RPC interface. diff --git a/rpc/src/v1/traits/secretstore.rs b/rpc/src/v1/traits/secretstore.rs index 8ff1c0e99e..6883753b4f 100644 --- a/rpc/src/v1/traits/secretstore.rs +++ b/rpc/src/v1/traits/secretstore.rs @@ -17,11 +17,12 @@ //! SecretStore-specific rpc interface. use std::collections::BTreeSet; + use jsonrpc_core::Result; use jsonrpc_derive::rpc; +use ethereum_types::{H160, H256, H512}; use ethkey::Password; - -use v1::types::{H160, H256, H512, Bytes, EncryptedDocumentKey}; +use v1::types::{Bytes, EncryptedDocumentKey}; /// Parity-specific rpc interface. #[rpc] diff --git a/rpc/src/v1/traits/signer.rs b/rpc/src/v1/traits/signer.rs index 675808a980..b5653eba63 100644 --- a/rpc/src/v1/traits/signer.rs +++ b/rpc/src/v1/traits/signer.rs @@ -15,11 +15,13 @@ // along with Parity Ethereum. If not, see . //! Parity Signer-related rpc interface. + +use ethereum_types::U256; use jsonrpc_core::{BoxFuture, Result}; use jsonrpc_pubsub::{typed::Subscriber, SubscriptionId}; use jsonrpc_derive::rpc; -use v1::types::{U256, Bytes, TransactionModification, ConfirmationRequest, ConfirmationResponse, ConfirmationResponseWithToken}; +use v1::types::{Bytes, TransactionModification, ConfirmationRequest, ConfirmationResponse, ConfirmationResponseWithToken}; /// Signer extension for confirmations rpc interface. #[rpc] diff --git a/rpc/src/v1/traits/traces.rs b/rpc/src/v1/traits/traces.rs index 3ac4964bd5..5308ed4c6c 100644 --- a/rpc/src/v1/traits/traces.rs +++ b/rpc/src/v1/traits/traces.rs @@ -16,9 +16,11 @@ //! Traces specific rpc interface. +use ethereum_types::H256; use jsonrpc_core::Result; use jsonrpc_derive::rpc; -use v1::types::{TraceFilter, LocalizedTrace, BlockNumber, Index, CallRequest, Bytes, TraceResults, TraceResultsWithTransactionHash, H256, TraceOptions}; +use v1::types::{TraceFilter, LocalizedTrace, BlockNumber, Index, CallRequest, Bytes, TraceResults, + TraceResultsWithTransactionHash, TraceOptions}; /// Traces specific rpc interface. #[rpc] diff --git a/rpc/src/v1/traits/web3.rs b/rpc/src/v1/traits/web3.rs index 69d74756ea..dd464ee1c2 100644 --- a/rpc/src/v1/traits/web3.rs +++ b/rpc/src/v1/traits/web3.rs @@ -15,10 +15,11 @@ // along with Parity Ethereum. If not, see . //! Web3 rpc interface. +use ethereum_types::H256; use jsonrpc_core::Result; use jsonrpc_derive::rpc; -use v1::types::{H256, Bytes}; +use v1::types::Bytes; /// Web3 rpc interface. #[rpc] diff --git a/rpc/src/v1/types/account_info.rs b/rpc/src/v1/types/account_info.rs index a35537b029..6d7585f87f 100644 --- a/rpc/src/v1/types/account_info.rs +++ b/rpc/src/v1/types/account_info.rs @@ -16,8 +16,8 @@ //! Return types for RPC calls -use ethereum_types::{Public, Address}; -use v1::types::{H160, H256, U256, Bytes}; +use ethereum_types::{Public, Address, H160, H256, U256}; +use v1::types::Bytes; /// Account information. #[derive(Debug, Default, Clone, PartialEq, Serialize)] diff --git a/rpc/src/v1/types/block.rs b/rpc/src/v1/types/block.rs index b3a6018f67..6e23647a0e 100644 --- a/rpc/src/v1/types/block.rs +++ b/rpc/src/v1/types/block.rs @@ -17,11 +17,11 @@ use std::ops::Deref; use std::collections::BTreeMap; +use ethereum_types::{H160, H256, U256, Bloom as H2048}; use serde::ser::Error; use serde::{Serialize, Serializer}; use types::encoded::Header as EthHeader; - -use v1::types::{Bytes, Transaction, H160, H256, H2048, U256}; +use v1::types::{Bytes, Transaction}; /// Block Transactions #[derive(Debug)] @@ -205,8 +205,9 @@ impl Serialize for Rich { #[cfg(test)] mod tests { use std::collections::BTreeMap; + use ethereum_types::{H64, H160, H256, U256, Bloom as H2048}; use serde_json; - use v1::types::{Transaction, H64, H160, H256, H2048, Bytes, U256}; + use v1::types::{Transaction, Bytes}; use super::{Block, RichBlock, BlockTransactions, Header, RichHeader}; #[test] @@ -248,8 +249,8 @@ mod tests { let rich_block = RichBlock { inner: block, extra_info: map![ - "mixHash".into() => format!("0x{:?}", H256::default()), - "nonce".into() => format!("0x{:?}", H64::default()) + "mixHash".into() => format!("{:?}", H256::default()), + "nonce".into() => format!("{:?}", H64::default()) ], }; let serialized_rich_block = serde_json::to_string(&rich_block).unwrap(); @@ -286,8 +287,8 @@ mod tests { let rich_block = RichBlock { inner: block, extra_info: map![ - "mixHash".into() => format!("0x{:?}", H256::default()), - "nonce".into() => format!("0x{:?}", H64::default()) + "mixHash".into() => format!("{:?}", H256::default()), + "nonce".into() => format!("{:?}", H64::default()) ], }; let serialized_rich_block = serde_json::to_string(&rich_block).unwrap(); @@ -321,8 +322,8 @@ mod tests { let rich_header = RichHeader { inner: header, extra_info: map![ - "mixHash".into() => format!("0x{:?}", H256::default()), - "nonce".into() => format!("0x{:?}", H64::default()) + "mixHash".into() => format!("{:?}", H256::default()), + "nonce".into() => format!("{:?}", H64::default()) ], }; let serialized_rich_header = serde_json::to_string(&rich_header).unwrap(); diff --git a/rpc/src/v1/types/call_request.rs b/rpc/src/v1/types/call_request.rs index c265731509..d75e4b1a2d 100644 --- a/rpc/src/v1/types/call_request.rs +++ b/rpc/src/v1/types/call_request.rs @@ -14,8 +14,9 @@ // You should have received a copy of the GNU General Public License // along with Parity Ethereum. If not, see . +use ethereum_types::{H160, U256}; use v1::helpers::CallRequest as Request; -use v1::types::{Bytes, H160, U256}; +use v1::types::Bytes; /// Call request #[derive(Debug, Default, PartialEq, Deserialize)] @@ -57,7 +58,7 @@ mod tests { use std::str::FromStr; use rustc_hex::FromHex; use serde_json; - use v1::types::{U256, H160}; + use ethereum_types::{U256, H160}; use super::CallRequest; #[test] diff --git a/rpc/src/v1/types/confirmations.rs b/rpc/src/v1/types/confirmations.rs index 2a62e2cfae..1534fbcea1 100644 --- a/rpc/src/v1/types/confirmations.rs +++ b/rpc/src/v1/types/confirmations.rs @@ -21,7 +21,8 @@ use serde::{Serialize, Serializer}; use ansi_term::Colour; use bytes::ToPretty; -use v1::types::{U256, TransactionRequest, RichRawTransaction, H160, H256, H520, Bytes, TransactionCondition, Origin}; +use ethereum_types::{H160, H256, H520, U256}; +use v1::types::{TransactionRequest, RichRawTransaction, Bytes, TransactionCondition, Origin}; use v1::helpers; use ethkey::Password; @@ -281,8 +282,9 @@ impl Serialize for Either where #[cfg(test)] mod tests { use std::str::FromStr; + use ethereum_types::{H256, U256}; use serde_json; - use v1::types::{U256, H256, TransactionCondition}; + use v1::types::TransactionCondition; use v1::helpers; use super::*; diff --git a/rpc/src/v1/types/consensus_status.rs b/rpc/src/v1/types/consensus_status.rs index 15047ed051..a5a5c9de8b 100644 --- a/rpc/src/v1/types/consensus_status.rs +++ b/rpc/src/v1/types/consensus_status.rs @@ -14,8 +14,8 @@ // You should have received a copy of the GNU General Public License // along with Parity Ethereum. If not, see . +use ethereum_types::{H160, H256}; use semver; -use v1::types::{H160, H256}; use updater::{self, CapState}; /// Capability info diff --git a/rpc/src/v1/types/derivation.rs b/rpc/src/v1/types/derivation.rs index 4c2f665121..1f2764d9ff 100644 --- a/rpc/src/v1/types/derivation.rs +++ b/rpc/src/v1/types/derivation.rs @@ -18,10 +18,9 @@ use std::fmt; use serde::{Deserialize, Deserializer}; use serde::de::{Error, Visitor}; +use ethereum_types::H256; use ethstore; -use super::hash::H256; - /// Type of derivation pub enum DerivationType { /// Soft - allow proof of parent diff --git a/rpc/src/v1/types/eip191.rs b/rpc/src/v1/types/eip191.rs index 16b8536bf8..fe3aab4c51 100644 --- a/rpc/src/v1/types/eip191.rs +++ b/rpc/src/v1/types/eip191.rs @@ -15,9 +15,11 @@ // along with Parity Ethereum. If not, see . //! EIP-191 specific types + +use ethereum_types::H160; use serde::{Deserialize, Deserializer}; use serde::de; -use v1::types::{H160, Bytes}; +use v1::types::Bytes; /// EIP-191 version specifier #[derive(Debug)] diff --git a/rpc/src/v1/types/eth_types.rs b/rpc/src/v1/types/eth_types.rs new file mode 100644 index 0000000000..606e759248 --- /dev/null +++ b/rpc/src/v1/types/eth_types.rs @@ -0,0 +1,84 @@ +use ethereum_types::{H256, U256}; +use serde_json; + +type Res = Result; + +#[test] +fn should_serialize_u256() { + let serialized1 = serde_json::to_string(&U256::from(0)).unwrap(); + let serialized2 = serde_json::to_string(&U256::from(1)).unwrap(); + let serialized3 = serde_json::to_string(&U256::from(16)).unwrap(); + let serialized4 = serde_json::to_string(&U256::from(256)).unwrap(); + + assert_eq!(serialized1, r#""0x0""#); + assert_eq!(serialized2, r#""0x1""#); + assert_eq!(serialized3, r#""0x10""#); + assert_eq!(serialized4, r#""0x100""#); +} + +#[test] +fn should_serialize_h256() { + let serialized1 = serde_json::to_string(&H256::from(0)).unwrap(); + let serialized2 = serde_json::to_string(&H256::from(1)).unwrap(); + let serialized3 = serde_json::to_string(&H256::from(16)).unwrap(); + let serialized4 = serde_json::to_string(&H256::from(256)).unwrap(); + + assert_eq!(serialized1, r#""0x0000000000000000000000000000000000000000000000000000000000000000""#); + assert_eq!(serialized2, r#""0x0000000000000000000000000000000000000000000000000000000000000001""#); + assert_eq!(serialized3, r#""0x0000000000000000000000000000000000000000000000000000000000000010""#); + assert_eq!(serialized4, r#""0x0000000000000000000000000000000000000000000000000000000000000100""#); +} + +#[test] +fn should_fail_to_deserialize_decimals() { + let deserialized0: Res = serde_json::from_str(r#""∀∂""#); + let deserialized1: Res = serde_json::from_str(r#""""#); + let deserialized2: Res = serde_json::from_str(r#""0""#); + let deserialized3: Res = serde_json::from_str(r#""10""#); + let deserialized4: Res = serde_json::from_str(r#""1000000""#); + let deserialized5: Res = serde_json::from_str(r#""1000000000000000000""#); + let deserialized6: Res = serde_json::from_str(r#""0x""#); + + assert!(deserialized0.is_err()); + assert!(deserialized1.is_err()); + assert!(deserialized2.is_err()); + assert!(deserialized3.is_err()); + assert!(deserialized4.is_err()); + assert!(deserialized5.is_err()); + assert!(deserialized6.is_err(), "Quantities should represent zero as 0x0"); +} + +#[test] +fn should_fail_to_deserialize_bad_hex_strings() { + let deserialized1: Result = serde_json::from_str(r#""0""#); + let deserialized2: Result = serde_json::from_str(r#""0x""#); + let deserialized3: Result = serde_json::from_str(r#""0x∀∂0000000000000000000000000000000000000000000000000000000000""#); + + assert!(deserialized1.is_err(), "hex string should start with 0x"); + assert!(deserialized2.is_err(), "0x-prefixed hex string of length 64"); + assert!(deserialized3.is_err(), "hex string should only contain hex chars"); +} + +#[test] +fn should_deserialize_u256() { + let deserialized1: U256 = serde_json::from_str(r#""0x0""#).unwrap(); + let deserialized2: U256 = serde_json::from_str(r#""0x1""#).unwrap(); + let deserialized3: U256 = serde_json::from_str(r#""0x01""#).unwrap(); + let deserialized4: U256 = serde_json::from_str(r#""0x100""#).unwrap(); + + assert_eq!(deserialized1, 0.into()); + assert_eq!(deserialized2, 1.into()); + assert_eq!(deserialized3, 1.into()); + assert_eq!(deserialized4, 256.into()); +} + +#[test] +fn should_deserialize_h256() { + let deserialized1: H256 = serde_json::from_str(r#""0x0000000000000000000000000000000000000000000000000000000000000000""#).unwrap(); + let deserialized2: H256 = serde_json::from_str(r#""0x0000000000000000000000000000000000000000000000000000000000000001""#).unwrap(); + let deserialized3: H256 = serde_json::from_str(r#""0x0000000000000000000000000000000000000000000000000000000000000100""#).unwrap(); + + assert_eq!(deserialized1, 0.into()); + assert_eq!(deserialized2, 1.into()); + assert_eq!(deserialized3, 256.into()); +} diff --git a/rpc/src/v1/types/filter.rs b/rpc/src/v1/types/filter.rs index dfcf78acf4..c6708da576 100644 --- a/rpc/src/v1/types/filter.rs +++ b/rpc/src/v1/types/filter.rs @@ -14,6 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Parity Ethereum. If not, see . +use ethereum_types::{H160, H256}; use jsonrpc_core::{Error as RpcError}; use serde::de::{Error, DeserializeOwned}; use serde::{Deserialize, Deserializer, Serialize, Serializer}; @@ -21,7 +22,7 @@ use serde_json::{Value, from_value}; use types::filter::Filter as EthFilter; use types::ids::BlockId; -use v1::types::{BlockNumber, H160, H256, Log}; +use v1::types::{BlockNumber, Log}; use v1::helpers::errors::invalid_params; /// Variadic value diff --git a/rpc/src/v1/types/hash.rs b/rpc/src/v1/types/hash.rs deleted file mode 100644 index 6cdaccf43b..0000000000 --- a/rpc/src/v1/types/hash.rs +++ /dev/null @@ -1,165 +0,0 @@ -// Copyright 2015-2019 Parity Technologies (UK) Ltd. -// This file is part of Parity Ethereum. - -// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . - -use std::fmt; -use std::str::FromStr; -use std::cmp::Ordering; -use std::hash::{Hash, Hasher}; -use serde; -use rustc_hex::{ToHex, FromHex}; -use ethereum_types::{H64 as Eth64, H160 as Eth160, H256 as Eth256, H520 as Eth520, H512 as Eth512, Bloom as Eth2048}; - -macro_rules! impl_hash { - ($name: ident, $other: ident, $size: expr) => { - /// Hash serialization - pub struct $name(pub [u8; $size]); - - impl Eq for $name { } - - impl Default for $name { - fn default() -> Self { - $name([0; $size]) - } - } - - impl fmt::Debug for $name { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self.0.to_hex()) - } - } - - impl fmt::Display for $name { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let hex = self.0.to_hex(); - write!(f, "{}..{}", &hex[0..2], &hex[$size-2..$size]) - } - } - - impl From for $name where $other: From { - fn from(o: T) -> Self { - $name($other::from(o).0) - } - } - - impl FromStr for $name { - type Err = <$other as FromStr>::Err; - - fn from_str(s: &str) -> Result { - $other::from_str(s).map(|x| $name(x.0)) - } - } - - impl Into<$other> for $name { - fn into(self) -> $other { - $other(self.0) - } - } - - impl PartialEq for $name { - fn eq(&self, other: &Self) -> bool { - let self_ref: &[u8] = &self.0; - let other_ref: &[u8] = &other.0; - self_ref == other_ref - } - } - - impl PartialOrd for $name { - fn partial_cmp(&self, other: &Self) -> Option { - let self_ref: &[u8] = &self.0; - let other_ref: &[u8] = &other.0; - self_ref.partial_cmp(other_ref) - } - } - - impl Ord for $name { - fn cmp(&self, other: &Self) -> Ordering { - let self_ref: &[u8] = &self.0; - let other_ref: &[u8] = &other.0; - self_ref.cmp(other_ref) - } - } - - impl Hash for $name { - fn hash(&self, state: &mut H) where H: Hasher { - let self_ref: &[u8] = &self.0; - Hash::hash(self_ref, state) - } - } - - impl Clone for $name { - fn clone(&self) -> Self { - let mut r = [0; $size]; - r.copy_from_slice(&self.0); - $name(r) - } - } - - impl serde::Serialize for $name { - fn serialize(&self, serializer: S) -> Result - where S: serde::Serializer { - let mut hex = "0x".to_owned(); - hex.push_str(&self.0.to_hex()); - serializer.serialize_str(&hex) - } - } - - impl<'a> serde::Deserialize<'a> for $name { - fn deserialize(deserializer: D) -> Result<$name, D::Error> where D: serde::Deserializer<'a> { - struct HashVisitor; - - impl<'b> serde::de::Visitor<'b> for HashVisitor { - type Value = $name; - - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - write!(formatter, "a 0x-prefixed, padded, hex-encoded hash with length {}", $size * 2) - } - - fn visit_str(self, value: &str) -> Result where E: serde::de::Error { - - if value.len() < 2 || !value.starts_with("0x") { - return Err(E::custom("expected a hex-encoded hash with 0x prefix")); - } - if value.len() != 2 + $size * 2 { - return Err(E::invalid_length(value.len() - 2, &self)); - } - - match value[2..].from_hex() { - Ok(ref v) => { - let mut result = [0u8; $size]; - result.copy_from_slice(v); - Ok($name(result)) - }, - Err(e) => Err(E::custom(format!("invalid hex value: {:?}", e))), - } - } - - fn visit_string(self, value: String) -> Result where E: serde::de::Error { - self.visit_str(value.as_ref()) - } - } - - deserializer.deserialize_any(HashVisitor) - } - } - } -} - -impl_hash!(H64, Eth64, 8); -impl_hash!(H160, Eth160, 20); -impl_hash!(H256, Eth256, 32); -impl_hash!(H512, Eth512, 64); -impl_hash!(H520, Eth520, 65); -impl_hash!(H2048, Eth2048, 256); diff --git a/rpc/src/v1/types/histogram.rs b/rpc/src/v1/types/histogram.rs index 5b7ab1bb68..d7f14c514e 100644 --- a/rpc/src/v1/types/histogram.rs +++ b/rpc/src/v1/types/histogram.rs @@ -16,7 +16,7 @@ //! Gas prices histogram. -use v1::types::U256; +use ethereum_types::U256; /// Values of RPC settings. #[derive(Serialize, Deserialize)] diff --git a/rpc/src/v1/types/log.rs b/rpc/src/v1/types/log.rs index dd8f3d31cc..3dcc8fb298 100644 --- a/rpc/src/v1/types/log.rs +++ b/rpc/src/v1/types/log.rs @@ -14,8 +14,9 @@ // You should have received a copy of the GNU General Public License // along with Parity Ethereum. If not, see . +use ethereum_types::{H160, H256, U256}; use types::log_entry::{LocalizedLogEntry, LogEntry}; -use v1::types::{Bytes, H160, H256, U256}; +use v1::types::Bytes; /// Log #[derive(Debug, Serialize, PartialEq, Eq, Hash, Clone)] @@ -87,7 +88,8 @@ impl From for Log { mod tests { use serde_json; use std::str::FromStr; - use v1::types::{Log, H160, H256, U256}; + use v1::types::Log; + use ethereum_types::{H160, H256, U256}; #[test] fn log_serialization() { diff --git a/rpc/src/v1/types/mod.rs b/rpc/src/v1/types/mod.rs index 9859bc909d..a41f49fab1 100644 --- a/rpc/src/v1/types/mod.rs +++ b/rpc/src/v1/types/mod.rs @@ -16,6 +16,9 @@ //! RPC types +#[cfg(test)] +mod eth_types; + mod account_info; mod block; mod block_number; @@ -25,7 +28,6 @@ mod confirmations; mod consensus_status; mod derivation; mod filter; -mod hash; mod histogram; mod index; mod log; @@ -40,7 +42,6 @@ mod trace_filter; mod transaction; mod transaction_request; mod transaction_condition; -mod uint; mod work; mod private_receipt; mod eip191; @@ -60,7 +61,6 @@ pub use self::confirmations::{ pub use self::consensus_status::*; pub use self::derivation::{DeriveHash, DeriveHierarchical, Derive}; pub use self::filter::{Filter, FilterChanges}; -pub use self::hash::{H64, H160, H256, H512, H520, H2048}; pub use self::histogram::Histogram; pub use self::index::Index; pub use self::log::Log; @@ -78,7 +78,6 @@ pub use self::trace_filter::TraceFilter; pub use self::transaction::{Transaction, RichRawTransaction, LocalTransactionStatus}; 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}; diff --git a/rpc/src/v1/types/private_receipt.rs b/rpc/src/v1/types/private_receipt.rs index e6170314f7..fd0eae067f 100644 --- a/rpc/src/v1/types/private_receipt.rs +++ b/rpc/src/v1/types/private_receipt.rs @@ -14,8 +14,9 @@ // You should have received a copy of the GNU General Public License // along with Parity Ethereum. If not, see . -use v1::types::{H160, H256, TransactionRequest}; use ethcore_private_tx::{Receipt as EthPrivateReceipt}; +use ethereum_types::{H160, H256}; +use v1::types::TransactionRequest; /// Receipt #[derive(Debug, Serialize)] diff --git a/rpc/src/v1/types/provenance.rs b/rpc/src/v1/types/provenance.rs index 2d9301b49e..dcdd2408fe 100644 --- a/rpc/src/v1/types/provenance.rs +++ b/rpc/src/v1/types/provenance.rs @@ -17,7 +17,7 @@ //! Request Provenance use std::fmt; -use v1::types::H256; +use ethereum_types::H256; /// RPC request origin #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] diff --git a/rpc/src/v1/types/pubsub.rs b/rpc/src/v1/types/pubsub.rs index 179ee0e5c3..c526a2b372 100644 --- a/rpc/src/v1/types/pubsub.rs +++ b/rpc/src/v1/types/pubsub.rs @@ -16,10 +16,11 @@ //! Pub-Sub types. +use ethereum_types::H256; use serde::{Deserialize, Deserializer, Serialize, Serializer}; use serde::de::Error; use serde_json::{Value, from_value}; -use v1::types::{RichHeader, Filter, Log, H256}; +use v1::types::{RichHeader, Filter, Log}; /// Subscription result. #[derive(Debug, Clone, PartialEq, Eq)] diff --git a/rpc/src/v1/types/receipt.rs b/rpc/src/v1/types/receipt.rs index f57c988ffe..f440c8f486 100644 --- a/rpc/src/v1/types/receipt.rs +++ b/rpc/src/v1/types/receipt.rs @@ -14,7 +14,8 @@ // You should have received a copy of the GNU General Public License // along with Parity Ethereum. If not, see . -use v1::types::{Log, H160, H256, H2048, U256, U64}; +use ethereum_types::{H160, H256, U64, U256, Bloom as H2048}; +use v1::types::Log; use types::receipt::{Receipt as EthReceipt, RichReceipt, LocalizedReceipt, TransactionOutcome}; /// Receipt diff --git a/rpc/src/v1/types/secretstore.rs b/rpc/src/v1/types/secretstore.rs index 0de3aaac67..ef76ec5b46 100644 --- a/rpc/src/v1/types/secretstore.rs +++ b/rpc/src/v1/types/secretstore.rs @@ -14,7 +14,8 @@ // You should have received a copy of the GNU General Public License // along with Parity Ethereum. If not, see . -use v1::types::{Bytes, H512}; +use ethereum_types::H512; +use v1::types::Bytes; /// Encrypted document key. #[derive(Default, Debug, Serialize, PartialEq)] @@ -22,7 +23,7 @@ use v1::types::{Bytes, H512}; pub struct EncryptedDocumentKey { /// Common encryption point. Pass this to Secret Store 'Document key storing session' pub common_point: H512, - /// Ecnrypted point. Pass this to Secret Store 'Document key storing session'. + /// Encrypted point. Pass this to Secret Store 'Document key storing session'. pub encrypted_point: H512, /// Document key itself, encrypted with passed account public. Pass this to 'secretstore_encrypt'. pub encrypted_key: Bytes, diff --git a/rpc/src/v1/types/sync.rs b/rpc/src/v1/types/sync.rs index e51c853ad9..10094742c0 100644 --- a/rpc/src/v1/types/sync.rs +++ b/rpc/src/v1/types/sync.rs @@ -16,9 +16,10 @@ use network::client_version::ClientVersion; use std::collections::BTreeMap; + +use ethereum_types::{U256, H512}; use sync::{self, PeerInfo as SyncPeerInfo, TransactionStats as SyncTransactionStats}; use serde::{Serialize, Serializer}; -use v1::types::{U256, H512}; /// Sync info #[derive(Default, Debug, Serialize, PartialEq)] diff --git a/rpc/src/v1/types/trace.rs b/rpc/src/v1/types/trace.rs index 209523d3f8..715ffe62c5 100644 --- a/rpc/src/v1/types/trace.rs +++ b/rpc/src/v1/types/trace.rs @@ -19,14 +19,14 @@ use std::collections::BTreeMap; use ethcore::client::Executed; use ethcore::trace as et; use ethcore::trace::{FlatTrace, LocalizedTrace as EthLocalizedTrace, trace, TraceError}; -use ethereum_types::H256 as EthH256; +use ethereum_types::{H160, H256, U256}; use serde::ser::SerializeStruct; use serde::{Serialize, Serializer}; use types::account_diff; use types::state_diff; use vm; -use v1::types::{Bytes, H160, H256, U256}; +use v1::types::Bytes; #[derive(Debug, Serialize)] /// A diff of some chunk of memory. @@ -639,8 +639,8 @@ pub struct TraceResultsWithTransactionHash { pub transaction_hash: H256, } -impl From<(EthH256, Executed)> for TraceResultsWithTransactionHash { - fn from(t: (EthH256, Executed)) -> Self { +impl From<(H256, Executed)> for TraceResultsWithTransactionHash { + fn from(t: (H256, Executed)) -> Self { TraceResultsWithTransactionHash { output: t.1.output.into(), trace: t.1.trace.into_iter().map(Into::into).collect(), diff --git a/rpc/src/v1/types/trace_filter.rs b/rpc/src/v1/types/trace_filter.rs index d5ef60f47b..a455c3d1cc 100644 --- a/rpc/src/v1/types/trace_filter.rs +++ b/rpc/src/v1/types/trace_filter.rs @@ -18,7 +18,8 @@ use ethcore::client::BlockId; use ethcore::client; -use v1::types::{BlockNumber, H160}; +use ethereum_types::H160; +use v1::types::BlockNumber; /// Trace filter #[derive(Debug, PartialEq, Deserialize)] diff --git a/rpc/src/v1/types/transaction.rs b/rpc/src/v1/types/transaction.rs index dc7d6b5a15..72b591a89f 100644 --- a/rpc/src/v1/types/transaction.rs +++ b/rpc/src/v1/types/transaction.rs @@ -19,9 +19,10 @@ use std::sync::Arc; use serde::{Serialize, Serializer}; use serde::ser::SerializeStruct; use ethcore::{contract_address, CreateContractAddress}; +use ethereum_types::{H160, H256, H512, U64, U256}; use miner; use types::transaction::{LocalizedTransaction, Action, PendingTransaction, SignedTransaction}; -use v1::types::{Bytes, H160, H256, U256, H512, U64, TransactionCondition}; +use v1::types::{Bytes, TransactionCondition}; /// Transaction #[derive(Debug, Default, Clone, PartialEq, Serialize)] diff --git a/rpc/src/v1/types/transaction_request.rs b/rpc/src/v1/types/transaction_request.rs index e7a2126b40..a4698cafa7 100644 --- a/rpc/src/v1/types/transaction_request.rs +++ b/rpc/src/v1/types/transaction_request.rs @@ -16,7 +16,8 @@ //! `TransactionRequest` type -use v1::types::{Bytes, H160, U256, TransactionCondition}; +use ethereum_types::{H160, U256}; +use v1::types::{Bytes, TransactionCondition}; use v1::helpers; use ansi_term::Colour; @@ -137,7 +138,8 @@ mod tests { use std::str::FromStr; use rustc_hex::FromHex; use serde_json; - use v1::types::{U256, H160, TransactionCondition}; + use v1::types::TransactionCondition; + use ethereum_types::{H160, U256}; use super::*; #[test] diff --git a/rpc/src/v1/types/uint.rs b/rpc/src/v1/types/uint.rs deleted file mode 100644 index 3c5801c07c..0000000000 --- a/rpc/src/v1/types/uint.rs +++ /dev/null @@ -1,172 +0,0 @@ -// Copyright 2015-2019 Parity Technologies (UK) Ltd. -// This file is part of Parity Ethereum. - -// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . - -use std::str::FromStr; -use std::fmt; -use serde; -use ethereum_types::{U256 as EthU256, U128 as EthU128}; - -macro_rules! impl_uint { - ($name: ident, $other: ident, $size: expr) => { - /// Uint serialization. - #[derive(Debug, Default, Clone, Copy, PartialEq, Hash)] - pub struct $name($other); - - impl Eq for $name { } - - impl From for $name where $other: From { - fn from(o: T) -> Self { - $name($other::from(o)) - } - } - - impl FromStr for $name { - type Err = <$other as FromStr>::Err; - - fn from_str(s: &str) -> Result { - $other::from_str(s).map($name) - } - } - - impl Into<$other> for $name { - fn into(self) -> $other { - self.0 - } - } - - impl fmt::Display for $name { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self.0) - } - } - - impl fmt::LowerHex for $name { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::LowerHex::fmt(&self.0, f) - } - } - - impl<'a> serde::Deserialize<'a> for $name { - fn deserialize(deserializer: D) -> Result<$name, D::Error> - where D: serde::Deserializer<'a> { - struct UintVisitor; - - impl<'b> serde::de::Visitor<'b> for UintVisitor { - type Value = $name; - - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - write!(formatter, "a 0x-prefixed, hex-encoded number of length {}", $size*16) - } - - fn visit_str(self, value: &str) -> Result where E: serde::de::Error { - if value.len() < 2 || !value.starts_with("0x") { - return Err(E::custom("expected a hex-encoded numbers with 0x prefix")) - } - - // 0x + len - if value.len() > 2 + $size * 16 { - return Err(E::invalid_length(value.len() - 2, &self)); - } - - $other::from_str(&value[2..]).map($name).map_err(|e| E::custom(&format!("invalid hex value: {:?}", e))) - } - - fn visit_string(self, value: String) -> Result where E: serde::de::Error { - self.visit_str(&value) - } - } - - deserializer.deserialize_any(UintVisitor) - } - } - - } -} - -impl_uint!(U128, EthU128, 2); -impl_uint!(U256, EthU256, 4); -impl_uint!(U64, u64, 1); - -impl serde::Serialize for U128 { - fn serialize(&self, serializer: S) -> Result where S: serde::Serializer { - serializer.serialize_str(&format!("{:#x}", self)) - } -} - -impl serde::Serialize for U256 { - fn serialize(&self, serializer: S) -> Result where S: serde::Serializer { - serializer.serialize_str(&format!("{:#x}", self)) - } -} - -impl serde::Serialize for U64 { - fn serialize(&self, serializer: S) -> Result where S: serde::Serializer { - serializer.serialize_str(&format!("{:#x}", self)) - } -} - -#[cfg(test)] -mod tests { - use super::U256; - use serde_json; - - type Res = Result; - - #[test] - fn should_serialize_u256() { - let serialized1 = serde_json::to_string(&U256(0.into())).unwrap(); - let serialized2 = serde_json::to_string(&U256(1.into())).unwrap(); - let serialized3 = serde_json::to_string(&U256(16.into())).unwrap(); - let serialized4 = serde_json::to_string(&U256(256.into())).unwrap(); - - assert_eq!(serialized1, r#""0x0""#); - assert_eq!(serialized2, r#""0x1""#); - assert_eq!(serialized3, r#""0x10""#); - assert_eq!(serialized4, r#""0x100""#); - } - - #[test] - fn should_fail_to_deserialize_decimals() { - let deserialized0: Res = serde_json::from_str(r#""∀∂""#); - let deserialized1: Res = serde_json::from_str(r#""""#); - let deserialized2: Res = serde_json::from_str(r#""0""#); - let deserialized3: Res = serde_json::from_str(r#""10""#); - let deserialized4: Res = serde_json::from_str(r#""1000000""#); - let deserialized5: Res = serde_json::from_str(r#""1000000000000000000""#); - - assert!(deserialized0.is_err()); - assert!(deserialized1.is_err()); - assert!(deserialized2.is_err()); - assert!(deserialized3.is_err()); - assert!(deserialized4.is_err()); - assert!(deserialized5.is_err()); - } - - #[test] - fn should_deserialize_u256() { - let deserialized1: U256 = serde_json::from_str(r#""0x""#).unwrap(); - let deserialized2: U256 = serde_json::from_str(r#""0x0""#).unwrap(); - let deserialized3: U256 = serde_json::from_str(r#""0x1""#).unwrap(); - let deserialized4: U256 = serde_json::from_str(r#""0x01""#).unwrap(); - let deserialized5: U256 = serde_json::from_str(r#""0x100""#).unwrap(); - - assert_eq!(deserialized1, U256(0.into())); - assert_eq!(deserialized2, U256(0.into())); - assert_eq!(deserialized3, U256(1.into())); - assert_eq!(deserialized4, U256(1.into())); - assert_eq!(deserialized5, U256(256.into())); - } -} diff --git a/rpc/src/v1/types/work.rs b/rpc/src/v1/types/work.rs index b7c312162b..ed6c7c8e91 100644 --- a/rpc/src/v1/types/work.rs +++ b/rpc/src/v1/types/work.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Parity Ethereum. If not, see . -use super::{H256, U256}; +use ethereum_types::{H256, U256}; use serde::{Serialize, Serializer}; From afc1b72611ab3352d5901292b0b58495bb54d207 Mon Sep 17 00:00:00 2001 From: joshua-mir <43032097+joshua-mir@users.noreply.github.com> Date: Tue, 26 Feb 2019 13:35:40 +0100 Subject: [PATCH 095/168] 10000 > 5000 (#10422) addresses #10418 --- parity/cli/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/parity/cli/mod.rs b/parity/cli/mod.rs index 873b456ad1..c372e9bff4 100644 --- a/parity/cli/mod.rs +++ b/parity/cli/mod.rs @@ -915,7 +915,7 @@ usage! { ["Snapshot Options"] FLAG flag_no_periodic_snapshot: (bool) = false, or |c: &Config| c.snapshots.as_ref()?.disable_periodic.clone(), "--no-periodic-snapshot", - "Disable automated snapshots which usually occur once every 10000 blocks.", + "Disable automated snapshots which usually occur once every 5000 blocks.", ARG arg_snapshot_threads: (Option) = None, or |c: &Config| c.snapshots.as_ref()?.processing_threads, "--snapshot-threads=[NUM]", From 1871275ecdf02431bf67d09a1b25be8ff8916e3a Mon Sep 17 00:00:00 2001 From: elferdo Date: Tue, 26 Feb 2019 13:49:33 +0100 Subject: [PATCH 096/168] Refactor ethcore::client::TransactResult to use it inside std::result::Result (#10366) * Refactor TransactResult * Adapt evmbin and tests --- ethcore/src/client/evm_test_client.rs | 88 ++++++++++++++------------- ethcore/src/client/mod.rs | 2 +- ethcore/src/json_tests/state.rs | 8 +-- evmbin/src/info.rs | 6 +- 4 files changed, 53 insertions(+), 51 deletions(-) diff --git a/ethcore/src/client/evm_test_client.rs b/ethcore/src/client/evm_test_client.rs index a65e2b313e..d6c03e65a9 100644 --- a/ethcore/src/client/evm_test_client.rs +++ b/ethcore/src/client/evm_test_client.rs @@ -241,16 +241,17 @@ impl<'a> EvmTestClient<'a> { transaction: transaction::SignedTransaction, tracer: T, vm_tracer: V, - ) -> TransactResult { + ) -> std::result::Result, TransactErr> { let initial_gas = transaction.gas; // Verify transaction let is_ok = transaction.verify_basic(true, None, false); if let Err(error) = is_ok { - return TransactResult::Err { - state_root: *self.state.root(), - error: error.into(), - end_state: (self.dump_state)(&self.state), - }; + return Err( + TransactErr{ + state_root: *self.state.root(), + error: error.into(), + end_state: (self.dump_state)(&self.state), + }); } // Apply transaction @@ -283,7 +284,7 @@ impl<'a> EvmTestClient<'a> { match result { Ok(result) => { - TransactResult::Ok { + Ok(TransactSuccess { state_root, gas_left: initial_gas - result.receipt.gas_used, outcome: result.receipt.outcome, @@ -298,47 +299,48 @@ impl<'a> EvmTestClient<'a> { }, end_state, } - }, - Err(error) => TransactResult::Err { + )}, + Err(error) => Err(TransactErr { state_root, error, end_state, - }, + }), } } } -/// A result of applying transaction to the state. -#[derive(Debug)] -pub enum TransactResult { - /// Successful execution - Ok { - /// State root - state_root: H256, - /// Amount of gas left - gas_left: U256, - /// Output - output: Vec, - /// Traces - trace: Vec, - /// VM Traces - vm_trace: Option, - /// Created contract address (if any) - contract_address: Option, - /// Generated logs - logs: Vec, - /// outcome - outcome: receipt::TransactionOutcome, - /// end state if needed - end_state: Option, - }, - /// Transaction failed to run - Err { - /// State root - state_root: H256, - /// Execution error - error: ::error::Error, - /// end state if needed - end_state: Option, - }, +/// To be returned inside a std::result::Result::Ok after a successful +/// transaction completed. +#[allow(dead_code)] +pub struct TransactSuccess { + /// State root + pub state_root: H256, + /// Amount of gas left + pub gas_left: U256, + /// Output + pub output: Vec, + /// Traces + pub trace: Vec, + /// VM Traces + pub vm_trace: Option, + /// Created contract address (if any) + pub contract_address: Option, + /// Generated logs + pub logs: Vec, + /// outcome + pub outcome: receipt::TransactionOutcome, + /// end state if needed + pub end_state: Option, +} + +/// To be returned inside a std::result::Result::Err after a failed +/// transaction. +#[allow(dead_code)] +pub struct TransactErr { + /// State root + pub state_root: H256, + /// Execution error + pub error: ::error::Error, + /// end state if needed + pub end_state: Option, } diff --git a/ethcore/src/client/mod.rs b/ethcore/src/client/mod.rs index d501ba21fe..51b4f53db8 100644 --- a/ethcore/src/client/mod.rs +++ b/ethcore/src/client/mod.rs @@ -30,7 +30,7 @@ mod trace; pub use self::client::*; pub use self::config::{Mode, ClientConfig, DatabaseCompactionProfile, BlockChainConfig, VMType}; #[cfg(any(test, feature = "test-helpers"))] -pub use self::evm_test_client::{EvmTestClient, EvmTestError, TransactResult}; +pub use self::evm_test_client::{EvmTestClient, EvmTestError, TransactErr, TransactSuccess}; pub use self::io_message::ClientIoMessage; #[cfg(any(test, feature = "test-helpers"))] pub use self::test_client::{TestBlockChainClient, EachBlockWith}; diff --git a/ethcore/src/json_tests/state.rs b/ethcore/src/json_tests/state.rs index 33fc6d522d..c51a2c361c 100644 --- a/ethcore/src/json_tests/state.rs +++ b/ethcore/src/json_tests/state.rs @@ -18,7 +18,7 @@ use std::path::Path; use super::test_common::*; use pod_state::PodState; use trace; -use client::{EvmTestClient, EvmTestError, TransactResult}; +use client::{EvmTestClient, EvmTestError, TransactErr, TransactSuccess}; use ethjson; use types::transaction::SignedTransaction; use vm::EnvInfo; @@ -90,18 +90,18 @@ pub fn json_chain_test(json_data: &[u8], start_stop_ho flushln!("{} fail", info); failed.push(name.clone()); }, - Ok(TransactResult::Ok { state_root, .. }) if state_root != post_root => { + Ok(Ok(TransactSuccess { state_root, .. })) if state_root != post_root => { println!("{} !!! State mismatch (got: {}, expect: {}", info, state_root, post_root); flushln!("{} fail", info); failed.push(name.clone()); }, - Ok(TransactResult::Err { state_root, ref error, .. }) if state_root != post_root => { + Ok(Err(TransactErr { state_root, ref error, .. })) if state_root != post_root => { println!("{} !!! State mismatch (got: {}, expect: {}", info, state_root, post_root); println!("{} !!! Execution error: {:?}", info, error); flushln!("{} fail", info); failed.push(name.clone()); }, - Ok(TransactResult::Err { error, .. }) => { + Ok(Err(TransactErr { error, .. })) => { flushln!("{} ok ({:?})", info, error); }, Ok(_) => { diff --git a/evmbin/src/info.rs b/evmbin/src/info.rs index a12cdb16bd..74ea3175a6 100644 --- a/evmbin/src/info.rs +++ b/evmbin/src/info.rs @@ -18,7 +18,7 @@ use std::time::{Instant, Duration}; use ethereum_types::{H256, U256}; -use ethcore::client::{self, EvmTestClient, EvmTestError, TransactResult}; +use ethcore::client::{self, EvmTestClient, EvmTestError, TransactErr, TransactSuccess}; use ethcore::{state, state_db, trace, spec, pod_state, TrieSpec}; use ethjson; use types::transaction; @@ -130,7 +130,7 @@ pub fn run_transaction( let result = run(&spec, trie_spec, transaction.gas, pre_state, |mut client| { let result = client.transact(env_info, transaction, trace::NoopTracer, informant); match result { - TransactResult::Ok { state_root, gas_left, output, vm_trace, end_state, .. } => { + Ok(TransactSuccess { state_root, gas_left, output, vm_trace, end_state, .. }) => { if state_root != post_root { (Err(EvmTestError::PostCondition(format!( "State root mismatch (got: {:#x}, expected: {:#x})", @@ -141,7 +141,7 @@ pub fn run_transaction( (Ok(output), state_root, end_state, Some(gas_left), vm_trace) } }, - TransactResult::Err { state_root, error, end_state } => { + Err(TransactErr { state_root, error, end_state }) => { (Err(EvmTestError::PostCondition(format!( "Unexpected execution error: {:?}", error ))), state_root, end_state, None, None) From e2ab3e4f5bc81c3bbfd8d1a5bdbb78f540729387 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Tue, 26 Feb 2019 18:14:11 +0100 Subject: [PATCH 097/168] fix panic when logging directory does not exist, closes #10420 (#10424) --- parity/main.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/parity/main.rs b/parity/main.rs index 461908b2c8..b8a1e229c3 100644 --- a/parity/main.rs +++ b/parity/main.rs @@ -190,7 +190,10 @@ fn main_direct(force_can_restart: bool) -> i32 { parity_ethereum::Configuration::parse_cli(&args).unwrap_or_else(|e| e.exit()) }; - let logger = setup_log(&conf.logger_config()).expect("Logger is initialized only once; qed"); + let logger = setup_log(&conf.logger_config()).unwrap_or_else(|e| { + eprintln!("{}", e); + process::exit(2) + }); if let Some(spec_override) = take_spec_name_override() { conf.args.flag_testnet = false; From 2fbb952cdd1a7ca75fb56af52f50e2d1b1e30bc4 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Wed, 27 Feb 2019 09:41:03 +0100 Subject: [PATCH 098/168] parity/main.rs uses eprintln instead of raw stderr interface (#10427) --- parity/main.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/parity/main.rs b/parity/main.rs index b8a1e229c3..066061cbaf 100644 --- a/parity/main.rs +++ b/parity/main.rs @@ -34,7 +34,7 @@ extern crate ethcore_logger; use std::ffi::OsString; use std::fs::{remove_file, metadata, File, create_dir_all}; -use std::io::{self as stdio, Read, Write}; +use std::io::{Read, Write}; use std::path::PathBuf; use std::sync::Arc; use std::sync::atomic::{AtomicBool, Ordering}; @@ -213,8 +213,6 @@ fn main_direct(force_can_restart: bool) -> i32 { "{}", Colour::Red.paint(format!("{}", e)) ); - // flush before returning - let _ = std::io::stderr().flush(); return 1; } } @@ -287,7 +285,7 @@ fn main_direct(force_can_restart: bool) -> i32 { let e = exit.clone(); let exiting = exiting.clone(); move |panic_msg| { - let _ = stdio::stderr().write_all(panic_msg.as_bytes()); + eprintln!("{}", panic_msg); if !exiting.swap(true, Ordering::SeqCst) { *e.0.lock() = ExitStatus { panicking: true, @@ -350,7 +348,7 @@ fn main_direct(force_can_restart: bool) -> i32 { if let Some(mut handle) = handle { handle.detach_with_msg(format!("{}", Colour::Red.paint(&err))) } - writeln!(&mut stdio::stderr(), "{}", err).expect("StdErr available; qed"); + eprintln!("{}", err); 1 }, }; From c7ded6a785e4c2f7aff41d8905146224e0cd6551 Mon Sep 17 00:00:00 2001 From: Mohanson Date: Wed, 27 Feb 2019 17:07:12 +0800 Subject: [PATCH 099/168] Remove duplicate test cases (#10385) Case create_account() is same as new_account() --- ethcore/src/state/account.rs | 7 ------- 1 file changed, 7 deletions(-) diff --git a/ethcore/src/state/account.rs b/ethcore/src/state/account.rs index 5f718a944e..fea9444b1c 100644 --- a/ethcore/src/state/account.rs +++ b/ethcore/src/state/account.rs @@ -741,11 +741,4 @@ mod tests { assert_eq!(a.code_hash(), KECCAK_EMPTY); assert_eq!(a.storage_root().unwrap(), KECCAK_NULL_RLP); } - - #[test] - fn create_account() { - let a = Account::new(69u8.into(), 0u8.into(), HashMap::new(), Bytes::new()); - assert_eq!(a.rlp().to_hex(), "f8448045a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"); - } - } From fefec000fb255a37f482afdddbc4b4c5124e0a6c Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Wed, 27 Feb 2019 10:07:41 +0100 Subject: [PATCH 100/168] remove redundant macro println_stderr from parity/cli/usage.rs (#10425) --- parity/cli/usage.rs | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/parity/cli/usage.rs b/parity/cli/usage.rs index f48387b2a7..8b06f4f1f6 100644 --- a/parity/cli/usage.rs +++ b/parity/cli/usage.rs @@ -14,13 +14,6 @@ // You should have received a copy of the GNU General Public License // along with Parity Ethereum. If not, see . -macro_rules! println_stderr( - ($($arg:tt)*) => { { - let r = writeln!(&mut ::std::io::stderr(), $($arg)*); - r.expect("failed printing to stderr"); - } } -); - macro_rules! return_if_parse_error { ($e:expr) => ( match $e { @@ -143,7 +136,7 @@ macro_rules! usage { ) => { use toml; use std::{fs, io, process, cmp}; - use std::io::{Read, Write}; + use std::io::Read; use parity_version::version; use clap::{Arg, App, SubCommand, AppSettings, ArgSettings, Error as ClapError, ErrorKind as ClapErrorKind}; use dir::helpers::replace_home; @@ -172,17 +165,17 @@ macro_rules! usage { match self { ArgsError::Clap(e) => e.exit(), ArgsError::Decode(e) => { - println_stderr!("You might have supplied invalid parameters in config file."); - println_stderr!("{}", e); + eprintln!("You might have supplied invalid parameters in config file."); + eprintln!("{}", e); process::exit(2) }, ArgsError::Config(path, e) => { - println_stderr!("There was an error reading your config file at: {}", path); - println_stderr!("{}", e); + eprintln!("There was an error reading your config file at: {}", path); + eprintln!("{}", e); process::exit(2) }, ArgsError::PeerConfiguration => { - println_stderr!("You have supplied `min_peers` > `max_peers`"); + eprintln!("You have supplied `min_peers` > `max_peers`"); process::exit(2) } } @@ -332,7 +325,7 @@ macro_rules! usage { let args = match (fs::File::open(&config_file), raw_args.arg_config.clone()) { // Load config file (Ok(mut file), _) => { - println_stderr!("Loading config file from {}", &config_file); + eprintln!("Loading config file from {}", &config_file); let mut config = String::new(); file.read_to_string(&mut config).map_err(|e| ArgsError::Config(config_file, e))?; Ok(raw_args.into_args(Self::parse_config(&config)?)) From 94cb3b6e0e8574d33813abd9ec1d8408f91996a6 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Wed, 27 Feb 2019 10:08:04 +0100 Subject: [PATCH 101/168] fix underflow in pip, closes #10419 (#10423) --- ethcore/light/src/net/mod.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ethcore/light/src/net/mod.rs b/ethcore/light/src/net/mod.rs index cffbb0e966..2fd6c340e0 100644 --- a/ethcore/light/src/net/mod.rs +++ b/ethcore/light/src/net/mod.rs @@ -533,6 +533,9 @@ impl LightProtocol { // the timer approach will skip 1 (possibly 2) in rare occasions. if peer_info.sent_head == announcement.head_hash || peer_info.status.head_num >= announcement.head_num || + // fix for underflow reported in + // https://github.com/paritytech/parity-ethereum/issues/10419 + now < peer_info.last_update || now - peer_info.last_update < UPDATE_INTERVAL { continue } From cfc8df156bd566c68cf669bee62e224025cd1f86 Mon Sep 17 00:00:00 2001 From: soc1c <47772477+soc1c@users.noreply.github.com> Date: Wed, 27 Feb 2019 10:47:27 +0100 Subject: [PATCH 102/168] ci: clean up gitlab-ci.yml leftovers from previous merge (#10429) --- .gitlab-ci.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index dd01a067c2..73dbf5ce07 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -108,7 +108,6 @@ build-windows: publish-docker: stage: publish only: *releaseable_branches - # <<: *no_git cache: {} dependencies: - build-linux @@ -120,7 +119,6 @@ publish-docker: publish-snap: &publish-snap stage: publish only: *releaseable_branches - # <<: *no_git image: snapcore/snapcraft variables: BUILD_ARCH: amd64 @@ -157,7 +155,6 @@ publish-snap-armhf: publish-onchain: stage: publish only: *releaseable_branches - # <<: *no_git cache: {} dependencies: - build-linux @@ -197,7 +194,6 @@ publish-awss3-release: publish-docs: stage: publish - # <<: *no_git only: - tags except: From 3d0ce10fa609683a6069a4d1b2dd59b3f5486b20 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Wed, 27 Feb 2019 10:48:40 +0100 Subject: [PATCH 103/168] panic_hook module uses eprintln instead of raw stderr interface (#10426) --- util/panic-hook/src/lib.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/util/panic-hook/src/lib.rs b/util/panic-hook/src/lib.rs index f49fea67b8..03501a47fd 100644 --- a/util/panic-hook/src/lib.rs +++ b/util/panic-hook/src/lib.rs @@ -18,7 +18,6 @@ extern crate backtrace; -use std::io::{self, Write}; use std::panic::{self, PanicInfo}; use std::thread; use std::process; @@ -27,7 +26,7 @@ use backtrace::Backtrace; /// Set the panic hook to write to stderr and abort the process when a panic happens. pub fn set_abort() { set_with(|msg| { - let _ = io::stderr().write_all(msg.as_bytes()); + eprintln!("{}", msg); process::abort() }); } From e71598d87633b8a1fcd74ef418b87918fe75f492 Mon Sep 17 00:00:00 2001 From: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> Date: Wed, 27 Feb 2019 15:50:45 +0100 Subject: [PATCH 104/168] Update hardcoded headers for Foundation, Ropsten, Kovan and Classic (#10417) * update foundation to #7262209 * update kovan to #10434561 * update ropsten to #5027841 * update classic to #7555073 * Update Ropsten headers to #5101569 --- ethcore/res/ethereum/classic.json | 6706 ++++++++++++++------------ ethcore/res/ethereum/foundation.json | 137 +- ethcore/res/ethereum/kovan.json | 258 +- ethcore/res/ethereum/ropsten.json | 181 +- 4 files changed, 4258 insertions(+), 3024 deletions(-) diff --git a/ethcore/res/ethereum/classic.json b/ethcore/res/ethereum/classic.json index 203b9b101e..898268901f 100644 --- a/ethcore/res/ethereum/classic.json +++ b/ethcore/res/ethereum/classic.json @@ -48,3022 +48,3698 @@ "stateRoot": "0xd7f8974fb5ac78d9ac099b9ad5018bedc2ce0a72dad1827a1709da30580f0544" }, "hardcodedSync": { - "header": "f9020ca0bfe78565c7685098b017e32399104274843eeed1fb1cd427c84bbefaf6f1c60ba01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347949eab4b0fc468a7f5d46228bf5a76cb52370d068da0499004e0e047f7c34e1e6b8e873c1829be5047433cc4429935346e43bdbbfc30a06566f1411ae4d7cefdb81be14d36baf1436c2a1bd344507f8d956c94655d27a3a0a916ae91053573cb022d0d78848920ec6429dfe57e4c00c46a442d53b301a8fab9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000869f7836fd69e7835e28018348048d83070cb0845b4823668c6e616e6f706f6f6c2e6f7267a01c3256996334e58c301283bfaf600d82e608ea584f451a65486c01ba4b22e104881716cd90004293eb", - "totalDifficulty": "343601966742385746996", + "header": "f90210a08eb792fdb134b57fffbdf19bd61d4c1cc351fc38a7fcf6609c82b35ea364208fa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794df7d7e053933b5cc24372f878c90e62dadad5d42a0e29a2e741354b453139d244920f7d552f90a579f1dcb99ef6b470bcffc713ebaa04bb64c992b8cf56259177a192d6f0a1eddf192b8daa7dbf1ec8313428cccde20a0ee22efe3b124a0297503fd26e6f7b33c7a88aa75825259297f8e30bee3632a68b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000866a396ffc14908373480183797a1182f618845c7395609165746865726d696e652d6574632d757331a087f3616cc0ba3704e23702bf7461f8f7716f1f1ad3ac4c66391d45adc57d1dea886ecb8e800fe87049", + "totalDifficulty": "575603227549295900024", "CHTs": [ - "0x0eb474b7721727204978e92e27d31cddff56471911e424a4c8271c35f9c982cc", - "0xe10e94515fb5ffb7ffa9bf50db4a959b3f50c2ff75e0b8bd5f5e038749e52a11", - "0x816e7463af7b5d2fcb804ba55f09e8452182b0ba6c995a34e144245d76333d55", - "0x3793af64c1ddc07ab61b2ba120034d91c02183ff788f07d3120fd4e6a48305b5", - "0x14c6106a17e041032210bfa0ca80d11860a1c6d95175d55eff39f97b8d8acded", - "0x396f832bfa3a9c494e9245471f0e65552613d87b6fe62128103590d95de72c2d", - "0xb060979f095c170a776b2b50a1e2ab0ffea80f6e522753fa36ad6f106ee32e9f", - "0x8f452e7cbd8a333ed04d819a143a8d3a75fe8c58418e7fc420bb2a717c0d4d2f", - "0x37fe1b0cf156bfc07571569af210540be753777903a308d5707538fffed75b59", - "0x6f0561d017cfc123b3f0d37b044e4f7231516b8731a1cab89afb569238643c33", - "0x3c1740c410a88c60fe8ccdc44e0ef2cf7f7314818dbf1648c01d0d94fbffc211", - "0xfb98115a7d6df8aaa40115f883014fe97300869bc016648e918fbf2df9608d41", - "0xef1099ab5ca4b79369048678d3ba78122fc081b00b6fd0f6907302a260d58266", - "0x969575f411dd78fdc5b4def0331fc93702029cc3c78851331a0f47dd0faae70b", - "0x9e53053e362be51c0fd25eaafd9e7c5c969d9f2ce8db4b3d4d830cbff347b0c8", - "0xf9de29944954d2b71a93532fc26916ae12fee72d42a79adaf940b0bf75d0ef89", - "0x28b2ce6635e60e06d643750798779023b2a807d9d089ae9ef7f223eebc15a71e", - "0x5295c06cbaff06f42bd8f5d9cbe94a840885caed02f9c9ba6da44a888ef796de", - "0x576eae673a4cbba4c7c7a56b47835ea64ae5989d67d119ebc8e568df40d908a9", - "0x891c0d38bc5e55620615da42ed77ab33806a042512034bcee134279dde1054be", - "0xbab05999d657426a11a902eb4c85ac52e2b72dd1cf38584cf2baeb2c3727bb44", - "0x3bd7e5a966f6dd2dc456948a8efca5584f5a4e0033f3037843a42073dda1f71b", - "0xc4f773ab1e34290f9a3d9ac6ede4749c5dec547353dddea494169d86f71107a3", - "0x993bf037ea9dd58b52027fb6f39332dab867c1e72af34a49d58a5a12f26bcca3", - "0x48b2d8d506eb8fc9dc0402fef26952111449aca0f90d0079f0526435d4e3183b", - "0xfef8f61df240e956f43759d2f481938421e064a9bd6a3be7a53b1213cc9588bb", - "0x5abf01f5066cf1091acdd1f99fbd5fd963633feafc42f9047534a3c1522004a5", - "0xa0f6205842260988161183b51bc36fae458fa184dd61844617d5c5d26fa78346", - "0x77309182fdc26d15dd8d9dd05040d7dc623412785708d8aac39eedee63931944", - "0x661c93311b94b7d4cdcbc0973225c794e71898a2b906922a6c1e8f7e9e289dc3", - "0x9d5d329ee8d9fffaee0111688d31a308dfaac922dcd61f818edd5303d0955be0", - "0x716ca25b184b64ba273b978de098f9946413f6fcc95bfba5cf1169e7e03dd611", - "0xa2e8d5cefa5804894fb42a106340b00de3286fee0992b5887b2cf471539d74a9", - "0xf846e05c9e9e9cb4cd2b7cbae7ae183a43a59ab02251954db632e538adacc357", - "0xbc01b4e23ea082a193e4c1012b1da91f3b4cb762009ca320bc8ed294af874e79", - "0x9218114a32da3ecf660d4d51b101bb51bb17c771561c1946c099be082f0a96b3", - "0x3b4edf03dfd53081cf40c0b90b35c1ccf7c7fe96cf131172eef5eec62f620ea8", - "0xb15758944263c67bdf528d4d7fe05737fbdbf7ffedce5f891a4ddf76177d2609", - "0x1f119374c385240f7b4ba1ec3d502be2c12c159411d5393ff2bd38cf87033625", - "0x8a8d5a93f3475813926b13a4d53f21b28dc79ade2b50830c0b9043e9fcd81576", - "0xcc22f7e2bb9c06c15ca3d82df852ed9097a2ddc687ee389e662de000db0c84fc", - "0xc2047e0dab711db791aadb642f8102abaacf7231b8dbdbe1f60573b0be015a31", - "0x1b4088ceee7783e4563945f162bd5da67020ca377a18d615923e8564d6709f85", - "0xd73450686e33bbda9eef53a95a86e5a0514156b98a5b7dfc6fdc0adb0b83cbcf", - "0xb374076ec961360e38d3486a31c3f72225440984c4c47ca790b4961d94152159", - "0x4f723f4fbd31d63a5421390e68aba0aff97249875688a7d9ab9a339d9aac7bc1", - "0x5fe51ff982edcad6c0052fcdf9a70e8f325c8140ab75848c5d7b0d670bd7edc2", - "0xc3ad483c7cc23bf8d6ae3e3e829bf126d5eeea9c53b566a6da95bef573b9c779", - "0x3c9e50ed9eb57cc055fd9a65a6cdaba2030d8b41f81348f296d7410c1d24ced0", - "0x0c6dfc1f626ff9e85ff072c154152bb3f122a2c1a45bc2d9e7da9b2d5278149a", - "0x92f4452dbdb4fe70e84ecd47af4b1af90975219797cebd451beceb6997ab024d", - "0x9a3d00686736b5b838308da4b8f0aa9edccfaba64621ce2988cea6ea2a267efd", - "0x8d602d0bef069177102726d5ccd93d19805fb5771a350a41e32755ce740b9047", - "0x6681e4097667a22ad3713acc27b6f87abd54583230581933bed9245c2c457ac3", - "0x53077caeabcd926466319a3ee5c51c32e01e1812a65313f113f814d53e9f1dd9", - "0x4dd4c33e99d86ba84f976c639333fc072e262c0b76dfdf2f589300af54048c0a", - "0xbc3b9837a6fa54616dcdb8088080e276e2e99a23c8e7de4109504293703d524e", - "0x24316b344cecd5e601cc0acc91ff94f481ca3fa26d8478644a9d8bcaeb0359b3", - "0xa7bafd3c5f4e3f6b5c078d50eb318d91e867b0e1c966027e3e7458eb104ccd63", - "0xc8da46b7d778980d120357c8de2bba336f5a2ac7a9f4183a0ee1f7597ed47d25", - "0x7469fc5d8c9c648cd10e538710e0f126542e59a82484e7fe56b73f4ec52c36c7", - "0x993bb7c0487ff61c97e4f1533446ae35b6346642e1230f2441da8b354111d597", - "0x90e3944732f86a2254dc4f30650f8438dfd0b777561fb02a8ab1c60438569c24", - "0x4e8472483679b54bdc600010fdd164f54771d7a99fa9272c683b610fff72507b", - "0xf72a861a2ebc232c25529c0f94c59996e64c59c36a1326a183cf171bddf2a75c", - "0x7f222999ba9113e2a64fd026a8f7244e6d2ae8f2a7e7d8d2d6fbde6fdf0b629f", - "0x3304e769f730522c1c5aa745c448075df026b8f82a4dece84fd70d0457050985", - "0x9ee5e3ccaaf94461dff9df8c4805ca831f58a1586af4ece3cab14a45f3b784db", - "0x21e4364859063e20153d2d06eae4d2c9e99354bf97fbff68406d8825d18dbce3", - "0x4805355b72b1b61b07814059f80b4da0351291cc932292f23069197a74127726", - "0x14474f45f38d7ea51418e5f03751c8bfbfb9b3e2957d3051e862aa3c57a63c43", - "0x69372cee3e2807d10ecb72d404a033568a159a5b15d2007537ed9a758164b29f", - "0x147223b51001166a4e65372c9c706f011f1ae94f4bdc9ba6e8960017e8898703", - "0x11a1e48a5c1d7088c0ccb8177d54db9e9f91a99aa7c24f702cd93f4646f181ee", - "0x809c902b2f4b8760c3d2e820c93d6df69a5d184a43a6c654ebe7067e7212137d", - "0x749367027756c27215b2f57168ef15d3b39062c9f79b3777f7fa19e8073de775", - "0x6a9fae37364f97e36e56df97acb1b7d066a608d8366d7e008854756dd28fe748", - "0xdc2f1b7a8aeda15e6bf4f5f424bc54828cc8520e2e7ba27bd8e28ba2b543aae7", - "0xe0fabc892d5c8b4342ff488b76a0400425ea70774f207c546fbf2f9f5b105dcb", - "0x151fb5e02d8eb3c3192cb8c039bcb4c121c4ebeea5e7f98927b85a730a24bbf9", - "0xfeb2f2ea368d0bd4c0b0bd97b444c365bdc0ac9ce2862b0d0162387727edd236", - "0x1eaf828231ebbae54737111bf3c7181fe3d7e9070def1313470d3f81c89f01c7", - "0x8a1b0565013cff488bbe3f35df86fb41c7aedf4d911130802c473f4ddb74d6d6", - "0xce9158b5c903312fa636e074e3efe413184652581a4877d40a0085965dc0bf9a", - "0x1cf602c6306affe2916fa09d3c8c018f23fc44dec8af8e83fa0008c98b4dda72", - "0x189dc4569e96cab937265ecaea76a0880ec97d5b84ac1fbd0cd2d2b36a8c34c3", - "0xd698bd07e485767c1da30bb218265e1304f6eaf426749ccba67478817af84bd4", - "0x47d7e101de73bb0ca97a0bb70094e81b82c63e519a6b2aa5fe10ca7351232870", - "0xb0d441b6c41072889c4a982306c9a40dff77b43425ecc4d771c22f3199eb7708", - "0x7893071deba67f2fc8e1b18bedcac4dbc05a020f37c764c555eadc42dd9d29d3", - "0x3c6d636db3621757d60b2d0e1804e19528ce60c9feed1ead93731820ff19b11c", - "0xde87aaa462b461c4a33e0739ef4cf56d442b7967ac7c5280816a959046b128b6", - "0xb237b17650adcbcf580b64b500ecaa7ca36921a11ad92c1e8992c57cc1a7f618", - "0xec379725db43fefe61f2495f7f7e0531d852e21f896ae806144c4d9b4b986e96", - "0x65ac5548988825831f0887b9ff0f2c13b7f3b49e4a67c39b1694e76414249f6d", - "0x76053b72ec9e6fcf0a28ef273d3e1b0842c3c2c0e905f5b5a3535ffab216c8db", - "0x2ab1e87489eb1daeaf8882c6baa0a8726aeac522e9c4eb4df71e35af2d22cc10", - "0x8c9c6adcabe253b311f6a9b8165ff9c5e26e4cf41f1acd80837e77fc15526a86", - "0xf143155230223a3f126c757b85e193a9129f1bdf97c0ce1f2785f14d40911f30", - "0x8c510d9dca593534f3ed316f240ffb9343d1e3cd6d005df6a75a1b354da0b36e", - "0x3440975cf818a718beff35a85d19bcbbd67e1b16ca9d78af34dcde31a28b3288", - "0xf56ef9c57109f9cb7a925bbb6d453efc19e8a45b331f76153d20a87d86a8b0d8", - "0x19a360772872003f08508a28a362c6e05650b385c24a928ddad4d562bfccf412", - "0x643720694b3773ecf20437d54a6be701810feff233f435dc701dbe88c9a6a13c", - "0xf8c0babe99aa26ecbfc91b304d9cd54ccfb37354c4fdbeb3207bb6d4647fabd6", - "0x481ccc7213d0188e817c071c4cc3a71c96befb9aa98cab964012fd7a8267834a", - "0x02d83ca8d92e0fe6ce7643ae93af60e38ab5659a84c04beba678ceef654aec12", - "0x24e6b4bcd0d97df196f2371532771593fe17be8fcb89f1e1164bcce8616088b9", - "0x3dc91775c50c04812f755f3b48d3d6a0cc599c586ce9d105e2cf4f3e4527b515", - "0xcdc215f05398ea3942d3a38078a3602cbe8ac549d4bf0e4a54191ceb2aff8f76", - "0xee02874e444b784f4265cc60b86a17382d277d03c8bce8a33241460ea8950699", - "0x35c34bc84736fdcbc4d4e2e089f30bcd186a052b2f6dcb639fc45a0aeb6969f8", - "0xbbb3ff849c36659bf2c00feaad9f7b3a342b5cfcf3555b7c2e467a0dc84e90e8", - "0x0584bc60fbe3fae9088c214fb519030646c3240f77180a0bedecd3e9c9f47f89", - "0x9d18a665d89439ad2c97427bdab3e598f5bc0da6a0ede2378f95c5bc31f10d12", - "0xe8a5bdd0ffd33a6fd03cf003c6d2afbe8493e0f0cb69e6366e22b4d1ff985101", - "0x7ca955f4e01eef756b680d09c25626cf50013faa20a12b0a334fd048a04e7b91", - "0x064254551457bd5e7a260a41ed3643746202d503813ceaf42660f9bd1983be34", - "0x1191044e354ea1e3daa25ed2175a6517659e96733d9065d81492ffe4472fb96f", - "0xc823514cf3566b1bb2e19a35e0ef0980bc483fa820d13ae2cfdbf15fd426c272", - "0x413f941f192d0ab77bac68268f45e2c9adbee23a3324d4ae8748d09735355a2d", - "0xa66c94b9603b3058b730baeba1b79d52f548ceeb5bac487903f92481060f6804", - "0xa84d4a8860bdff1fdae6bcefcdcf700fab7857444ef1e76d8259b005872a4636", - "0x9fa64d44edd9c097458d3901612a4b6f655a1421ebb68541cb1a4bdbbe24911e", - "0x402027770edb387510241a68a235723c6c5c95aed54dab058c43d21a6bb48c41", - "0x776281b7e341a66491603b7ae8ed7cc82b99febac43f94cb1c4dda73b17aab63", - "0xfecbaf0fc5a02dcf49095514ce26df927def3cf51f37e04471545aae2364f936", - "0xc477d9293f0ace7243f8b9c89f01210b8f96b4affc9d3332147ea2e2b693c99e", - "0x4a8b9afb9d9097831b2497296b0fd0fae76ab8a596213daed35cf87e6bbefaed", - "0x594c4e9851eddbb4a6c2ac72aaa244ff35d67262efb20935360360d39f7c7ecc", - "0x14b7ef22c46ba8400979b6c06f3b3023607145a5cc6b5b793daae758cb655245", - "0x3a9d233553d1ca4d9862a70ef133a5fb2df75276fb24297b0bd2927a39459450", - "0x22c5e227d5fa7616603bbf36c5e4ee7dbf285fb0cf403a3ae982da70c825cad0", - "0xc2c8d439c7bd884665da56e3b680a5e58ad1e98627fdbec6fa67d7bbfad33a9b", - "0x7d5682cd9f28493ba4b87be141ec99701bbcd1aaadf9840b81de1fc07d4ffb18", - "0x8845f626c5f78d1bea281f892727437f9de8f976e4c4fec6060b2115f1862db5", - "0x769fdf0bcdbaec1ffe98cd3500ce8341b4d7ea2dad5fadb0258212306ccc75f9", - "0x185569d1980147fcdfcd0e0068ab380f0cfa58a690334a558bc1fd0d07897e96", - "0x0ed70ccff752df46f981043c5279ac3f13e7f62c2bdb9a0a9817a1c119ef6402", - "0xbe121e28349e80d601ab997af844aa03ea6492e88d75d3d46517d8f835e3c3fd", - "0xa7aa5f0bb95566292d22891faa75b7ff2020b69fecc8a22d796cc3a60953d98f", - "0xa2611b092b00f78fe639c4fba0274ae474fa448b3f2e4b8aa4d06c654720d478", - "0x8e425115b98f5e41c8b5d03a9e17d56d30050d85dd06cfff12f002c546a256ba", - "0x988b449fbd8c35855154fb4eb22ba6b7b7095be26203d137f484c67facd40dc5", - "0x567c43ac5dabeff01d6997543ec7abf7998088a355a6ba8e70f41a243dd1343a", - "0x6f560cb650142aed532f17de763d61d021cdec2716b0d2cb27b3a64052abb874", - "0x7e4ce5fab8f4f1fd41f9e5f10204032ae7e0e38093b1d07699318975b33910ec", - "0x91a0820eec5390916bf464b1d16c00b5d94386c4c9f4cdf7e0b3cbe40747fbc9", - "0x9c59451a9a242123efa72c5fbd1564b7bcc0067ea9d025336d228ed26b9ba6c0", - "0x1043a5ab3f5a3bced84faaae0e783abb3b81c2b967bbd976042cb5d897d28146", - "0xfc37b3b3c0be392ad2a5e36c120eace1d14e637ac806e79a750b9a6be3c742a7", - "0xce2ccbada44a8db5144073e69914b322dc015273a75b85ea43fd9e21037c760c", - "0x6cf8336b5a410e10604f93351242cb3a6929968212abdf85b4ca9321115b8fdf", - "0xabbe9781950362be1e206d91ea1bdd6f32ea2c6df65b277cb89050ca1deb9296", - "0x922a6b85add6839494c3edff389aa1b054409c330b4a4e2a6c0e4f9bc85b36a9", - "0xc26dcdfa135a09b7eef1e99b445fb66aefb8bceb6ea715b81d78ba87cd56ed8d", - "0x87d647fa7dcde81a0e133aa949d574befefbceab24a42ae4f3809d2bb52a2d9b", - "0x85ee37fa7154568b9dee8a539340f99c7f1bbc7b9be1f2055636ed9dfc074e4d", - "0x8b0114dc9e249f1de4bb3d055790e4bf18aa28a938f39e8a457ab4a43b0dd613", - "0x3be36db134f4c00fc9e1bc376213c7073389c993b0b0744cba619688d6c037d1", - "0xfaf987eb2e066ad8871c489c23102ec5c58add2d13e62d56f2821cc1f4d66d84", - "0x678478da2955e6876ac49c5146e9f7c376dbf2f170f6404054ae4385e72f3f19", - "0x85d8d9dd6c2a8f6b6a1c0fc0cb55ca870d9a7aae1621c143c3176a3a81fcc29c", - "0x76f4dfa4c3387408c823a75aeb872ff39af3820375ff52f7aecb41c96e4faf2a", - "0x6e530647f2e4232063de2fa8f673989d7834d8cdf529791032888f2833880b80", - "0x64422b4dfff6cba0eb6deaeb4593eefc40a357469a7f7c3be078f80c66161333", - "0x5c7ab740510a4183832bd78e6d6105b0f9f928611f7d62ef96aa8dd8da48a72d", - "0x0bbf405e29f015d24e64f063d50ec6c616af64622b1a4132cde86f926e93850f", - "0xd9ba81ea0790f1f8adccd0bd203c7adeec2b490381b822d6b15293cac2f26206", - "0x4f78619baa34f2278022c509671a38d29366936d6860e79ab540ea46b66ba782", - "0x00c1f10211d7604e59a327239f00dc6d036a93416b7871cb214e8eaa52571834", - "0x1b6636708f97485675c0e5b21eb749ee4a5fd0dd886e6690090856bcc5178ec0", - "0x71366e853968c1bbbbf8e3d6e13100dd589521f8db9e561dd20ff8709b5c1a96", - "0x0d2c35a01646cb09e2b56b5792ac03047848bef7415ae26f787cd54ef8f327da", - "0x1c5b71047f99db30453e502c9acdf422d3bf97b0d42b9223ea1b8b9924bb0cb1", - "0x9988eb36e4a669638e3242e5ada3e6596c5e4ef36a83ed2d3348d35fbed4d3d0", - "0x8f00020f98f02af0749df39fb2f534d356e3dbe809bdb3f435c4a575d661d6db", - "0xf70a509c0d1c60afcafc7cc492c5ad575fdcadf6ca8e0e5f184c62dd52021129", - "0x72cdb6544dd469ab42e270e51d136b314c27ed0d6682f914cf3e0398399d2d5d", - "0xd5584896e649b618ab8257859e42ef7798c37cc85103a8019cec10b1524519f3", - "0xd70636cf5cbe78ba86b8de902f83f9c550a8ee31a019da6fcb0b1ab0a02bd31f", - "0x79a506d61c89cb7b1aef845484956389d5f6077fd10f8d1ede1e92474eac15cf", - "0xa66c0575cfea08bc6abbba03b0d10be7bdcfe6c5da9058cb34c22af2c8f3f1d9", - "0xfde316523b6b41fedcf11d776a53bd27fe3058c3912059197cda083a14410689", - "0x6774beba5e02630a7e4379fed7175f0f3d9f8fb5333451f25d5b044521ed38ed", - "0xb513ee7cf03529c88633176792a6b08585ff6163fe174f68e285d6315ffe33aa", - "0x4482f3d82f65f0fdf71fdf669403e0b835b5458e567dbd295b4f51d22f01650c", - "0x1cf0c0859b1839ebfb872a570e0c17886d8d7f26067bcd16af7f9f0415001aa0", - "0x231be14cb1cec949a4e806a7b3aebdb074d58e5a1c48b85c35138d5d3e967e0b", - "0xe8f0a0ef68efb2ea1bfb5d47e3c9446900329ff89a3ab7eccde41e09ec3e79b9", - "0x16348cb5e49e61010da09a5ad3cef83ab369ee3d0f28079584c23749cfa30238", - "0x6d33bc7f502436bfd0d574c3f6b1155c69f8a80e55c42c353e9e68abb46d932e", - "0x0e5d40ed7351b59846ca3dd8cc9c0eb71d4659e0add0dbfb0bb7f518bf45c821", - "0xb1ba4509de4c0f1212b2b07d949740f15ef8df9af8e7e9d765e6b407a0c5d717", - "0xa99615bb15371a15b92c119f8632f1ad7c29d6eb9a69e0ccf33a9dd268cffd54", - "0xfc3601e7f85e4b8e996bddcf1b34cb6c20462e21c715782da12d8e08a01cd21b", - "0x872b0f4f3ef00cc5cc6fdd71091de96c02f5898826fda4f837832f302497b51a", - "0xb34656439e4474e075d8ef523f6f74ef292a22281e6dc0b8fabdfd2339389919", - "0x048d4dc500031aa56d89e799499a86d6dacddea795ddc4571669fa55d694345f", - "0x684b8762b97a9d650f0f0e5edee73b60a29f6e75573bd6244518b11c4a571533", - "0x5d20bbacb93f7b03d92ae0ce8296bfd113a808ab3a8bd7703838d7e8356b6714", - "0x25efac3c3bc3d4f10ed9918fd9581d68eaa18fb72d3ce7ca8e36525d8cdcae73", - "0x48b593a335aa2699a5bb5a60394845c7e4c78046e050aee1c7f8831249f75b26", - "0x6db7243073caa6e5c0442f2f3926885fae0385e0238a69784ea8a00c854ef8c0", - "0x3a104e4932193c644e2135008d78c5153a9331e6d9dde878357c250a3b42b5e7", - "0x74b3b4666fa9811702d4eebf9680053043160be3a6c31a0105c703e07d530710", - "0x179f67ff0710067d3180ec03d664fb3d9936e8777603b051ebad4cbd0aad7763", - "0x38d5fd43ca73f66127a0166ae074324471b1a92e6f4bf99fde235ac408b35562", - "0x1f43748a027e7731c2fe5343ba7b61d7c6c6933ea45466b439a43eee1a3ad398", - "0x6b130b75bc42dbbf76ad97287a3a130ea29122ce7e48c5a8bd1e80a5f3121364", - "0xcd17f77d87174ab6ad6f2dc60d37144aed40b3620a9e6c9ac3e328aeae3097de", - "0x3b7fe9ef499348315c1a2877bd7fa44b622fcabc588687a6de4d2f75aad3f642", - "0x6c73525865791a7ca8410363d634f6babfaba581d7a0252c7f57dc8c8cec583d", - "0xdb16b0220e129be4c929888a8a46d21d422a352ac7b0360711d786eacb56598e", - "0x44fb22efd89e585079bca47bde1073dc052f8ddbad2c27cd8e2839bd4350b18a", - "0x1e6f1395d417a94162117b9371abf3f781a4b05d787f6a38fb0101bc36e548da", - "0x3eddd0764196fe15d7ac7069c04c4bf23070e57931493e9a0127fc521187b698", - "0xec104582dffc06da3cc1af1c8dc7522d26ab2408dc0f62051da2ebae1ec1cbf3", - "0x3616cc0faf8a5f5c19cbeb482be2ea8de01b2a3e81f067366c715607cf29078c", - "0xd37ca9cd5dc7c3c4e2d2f1b3c8db2a016b52444f1c088680c8544b6cea30cfe3", - "0xc3d85c7899da428a305d941e3637e33eb4981f071ee07c1ee1c82aba7c248167", - "0x62975f10a20de37466b1822859f11774efa4f37fb701f6cc0695d206bbb51582", - "0xd940124857e67e220e3d4dc27eb75ff048aadd9b7fb29b680cc3743b3ab6365b", - "0xc89ac3aa4725191e56fbc87d41caac2c692dd5adae638bf741f0ded040ca66e4", - "0x97454878805915bcb60c9915af0fe0558987dabe5d506e03898dede96544dec1", - "0x6ce55ffc54eec31d980ece5204876a3f366f3148a4b8c10cd190153cfc96defd", - "0xa4e923671f4ff6dfde2f11cca452ed4208808e93e1131de4ce0804cbe2e0d3ad", - "0x772d1c2a0e70fe37ac0ea8d7b4a789f92997bd654809f20f0ff7ad76a6d975c3", - "0x8d5de87bc2484465a4876b462ebc1339bc13b8229e6df4f1a9e9b458f5e9adcd", - "0xdb33cbb2dad0eb38613d69392951c6062eb669035691882fdafc526133d15d21", - "0xb22b8c0887f71de2da3d81a5fec2213ccb8a32060211077e2ed1613cf7962e94", - "0xffbc5a82fe0c2b3f3f34343ba6823f35884c8b1dd80fbaa68fd5f33a960034ce", - "0x9640ded5be08a8a7a2e6291a91bdd58bd108205f4cef5209ddd338ad764fa9b9", - "0xaea7f934206d00a592502b8b85159e64b56def4c72db3a790ab46ca81c75d672", - "0xb99ace258fe4e6be541c6e3468913f4f32ef9e9d1375c889e17ceea0c606e729", - "0xc54ae75381803d00b52ea6fa620766662e6f7946d550208743fa64d3aaf22c54", - "0x4e773cd4fb2347b796595cc67eb2b5c7be6409bd8b1944f4cafecb6fc5a60a0b", - "0x263f3826196c238c24d4c792c3c45fc913d4cb94c2d3871827ba43faecbf4d94", - "0x7ae1714256e21b9b45778795cdedfad1160d571004f5ea6debc16406bc2161f6", - "0x0c271dc055d8fb1ba9bf133f3c85628ac3c2b588091768380a881a6183514b51", - "0xa5f41cb430b02fb1027d8e99cd94dd6666516c785d7f618a0894f38f811bdeed", - "0xbf6665cbf1037e0085808897d8b04932a6ced6755fa52555ac00737e8029c7b5", - "0xaaca2ffc61693a6f379e54af473802770b3971f6accef49e5a2e8fc122e0a490", - "0x7a3eb7782e2c02776aa29964689cb1b880201e1b81c8cef39738d7f7235fb022", - "0x7bf417dda75c46efba6a8344775915d2b69f954afd66d8f52576e106d7a7eee2", - "0x3a324507874480d0f4e8466ed6602c99fcaa7907b61e9f2b3f100740f7866fe0", - "0x3589941fb7bfda9bf50ad93cfed18cfdf199a6468074416aa513cf83cc00dd2a", - "0x66b0965611bba105667a3990de5acdbd398d8d6e2cd0276b83814c4647bfe461", - "0x703258ca6154ec4cb1b9162678e3bb546ca6f9e626702f5f62dda98fdc0fcf26", - "0x2a9a8e3537b714cb3e158f7ecc816239786ea3787b1a3bd40482f02eb0b21595", - "0x46104b558f57296b0775d63ee4da42a716c234f3dbd7479204f35b31f4b3d55c", - "0xe7d9d0a86cc8b76526acb8e260de17508874d1db6ad19a4a84210a010212d43b", - "0x04af6e8bd51cf4c4307b2381b2e0c54cd991ca3c7f49b8cdcaff3aead70efe48", - "0xab8fe05db68e486bf2be0c507b834b6e496c1d1fe560cd3210ed7fbf0e9b867a", - "0x0e6b5f226d0bcfbd1f0a2f61189592d8974b16376fef3d0a67f757b796ad6854", - "0xaab68c29b061f8f72d9f3c6f2e318a7125a01010fb0c547835fa31e72d8eeabe", - "0x0446f90437150e4ec6246be5c718e5054d62cbf5878479457d522948c6e87f83", - "0xd1b4669e21c0b175589c0942d4423cd2b438de6665f0bca10818eb6246a07749", - "0xc20d1a68c015d886ef8fc3dede0d116199480164238617667280f833a4dcbb3c", - "0xe67504ba38aee984e9118960827ddce0eaae3d8797bfc87afd4638cb1867e41c", - "0xd3e985af3bf3e3ad0dbcdbed9ff1b04037bd1ff2e71886db3842a29f0ee8c4b6", - "0x8b809d1ae7a835f318f471ce227f7e7ff563a15d1e2463e8fce5852c9a3f9ce4", - "0xc232b56170a5796aa4333d29ad8ba43dab2233e0cf7b48d100aeaa4b2491d6da", - "0x9c338ecb25290e91a83978df4f5b7076b299ba5d87074c36ec96da0b3aa9351d", - "0x616a6134eee1221e531fc6d6b5861f5ced64e9b56505b169da67ca3c47cb54ad", - "0x4afd1e60cbeb40301c2ccc7129042f9a944f4a383a4f34b8acd7aa454fcd0e7e", - "0xd52d1be650ed156ba12b0d6be4b7fda1fe89927bd7626ec0ae45663848144e7d", - "0xa212644d968f7d3d89c6f12c3c3077184943d986dd9cd391d48f8f98eb1bc6a2", - "0x8e3374acfb9d1724fd7f84c22fda25f91737efde3d667f607b364e51beabecee", - "0xd77eb30cd87046093b27be1a09d93cfa5261b780b99116a79d6c16be7db838ec", - "0x05093b9e39e2d9f4fa95ff386cb2af67861359ea6228242be6b323c1eed5c7c3", - "0x8bb25606225d3451a981af24506a549e2bf62a362149e4c77ac72eef6316e691", - "0xd2749fc4a37792b3716634e3dfb8a80ba3e30fd73bc119069d507bfe7efd8a1a", - "0x3b58bef2d77a04b3281e6cf80f984b9067290bfe02a596b2295ccad38e887a33", - "0x2f69797f1800e5da4a4086909058ec857695a220644e61788b24ccfaf7e77137", - "0xd81872c67fbbd1a69d4805cce578b9f36bfd768d3fcbc2fd610182a7696e23b2", - "0x2d3bc9fd303c12ed1ca7efe27d85c7b5ffb8e079e59c86977a113bbbf863549a", - "0xbaef802512a7ea5006cf816c51c35fdae44a86daaeb6e9dd8fd0c37b4f744875", - "0x2e7fb70924e6f0b74541f2f4cb13f49bb3bd577f5bfe1bc29d805b0e7e1a3df1", - "0xe3918602d83478eb416dcf80103b09a051d5cffc71b0cb21461c5031d38befb7", - "0x87dae7dbb38501d6e84f738c11615dd9eda5f7b77e096a765caebea6a8c691c2", - "0xa19f74ad3f4e218fcfb15e4af95713cfff4f5f58169b789167e2b62617023697", - "0x744930fd0046b3f7de0ecf721e3b36e4b36c0f49eb98bb0c9ed33d40e76a2017", - "0x5bc7194687200989382831785b43f7f5efb23105ee2dd7a620a61622a2afec44", - "0x3672af2176d897cb8f64f2decfd924d74581bd85916be85e53f2542a54a24b94", - "0xe2e2dd1875e9265072d96bda4640ec6beefdfa9a91241ae078cec4c2a1c9b8b3", - "0x5866de65d88610e6123b7a57e28e196afac484045261d1a16b83fa232ba267bf", - "0x7224db0ae652be5fe9017454dd40c744c75e513841b5cd11d5fcaff598265c7d", - "0x04438fdfb56d125bb13f6b8bdaced6946299f8a32610205fabf4a8db9c06af60", - "0x9e9af6a569b87a4717b94d8253a0078409bbce7bc08874e091163b621a75b999", - "0xc8a39c68a74f23d615ad49d9d175086bf4e1047a750165bb071e3cdb70e1d639", - "0x10515734fb6d38cbb9a7ef33ec7831646636f845ac40cb24b08c432422763466", - "0x1604dce1fd615791c66246a7cd82edbfe860a5ac48d000cac1984faebc00cafe", - "0x56311f68cc563946e251d8c0ea74adeee6ed8dd7aba8f6ea85367defd5dbdc41", - "0x3fc81adf318fa6db1c4e7ff5424b235943667f2f3dce5119618e0273eb23c93b", - "0x38576704f6ca62083130dca418a9b68e374944d63521fc3f4b7039754d62f63f", - "0x56e2a402baabf470d0f9c3496d75e2c26c26ac159b996c370b118a313a9e9464", - "0x501af705914bfccf4ad29c38eee21641590cd8d334dce9055d90bff57b8fa556", - "0xa734b7f045d2a23ce602b032357a66763714c6e4785768f07d55c22d2f1de372", - "0xc80e2c739a3d142a4018bfe2074da8da33c471b93f5e7b44bb150b9eb63e956b", - "0x7a0b1355d05b1bf4c634651bbb2b6d65cb0a9772c30e4024f5e781e5d404376c", - "0x73827f7c7a15db5c17a986f31dd92de05579b0bb8def065e5f1cee472d00281d", - "0xcd64ee4b2a912d48e6beb06e7d6c9c236b5815434c0ee21cca0a13ff23dfb85f", - "0x768d2fa63c53689ed899f47c6f78844ace885fa18a36da427428f4af46a9e1d9", - "0x643c26723d5a4831d3d07f8692a6dc4456bb6190ce2abf1abf69159942d5d548", - "0x03e20a75c4546d5f54bbd7fd3e54c795c180b880563bf78ec55530a89188a9a6", - "0xa0ea4095dd9fc6f817c656913f8cde4044e2806488be48770de5574c0b5d5f8a", - "0xeead5fac8f3c83c5a10df161d95bcf1d27184c9fb9fbd813ec5f61347c11280e", - "0x5afba4426fcae0f1769e581fa6af97b5ef8fd417771f10405e1c9d09a74357d6", - "0x087f65be7fc2a14f216d7ce418a03fcf1e6169e8620db65c11d1ed6c0afed240", - "0xf9a7e93c40788db39b241e03afe329b6336187fbafa40c97ac405fefc1eccfc1", - "0xb02450b58c5afdd0907ee745263aa6beef662646b96b9ed28b0dbcea4f358667", - "0x5029f1169c92671ecaad7239f40fd93adf3ec07ce2ed0c4cac38b0cc8034def7", - "0xc8465a93a1ba7ec3296d98e0b01ad27bdbf16a347c5517b450905d3c3668d505", - "0xb85cd82c551bcb30a747b2258327dccb04094f918e36c3f120f55fc35abf59d9", - "0x1721b2fb8963696cdf32385fe87e8ec2c2d7fa34e099bb65498e4a030e20a1c3", - "0x6b6dab262c1a32a67353409d2f8b791b1799ee6a8e3c880877af0bc5cc5b812a", - "0xa634110e4766d3451718061efb890238796370da3c4a53a91faa96c8944d2423", - "0x91ec6c6f807285599e0a179d0d246caf10152e733acf3bb967bae35fb36561ec", - "0xc3b2012d5cc8d796d1890d39e2b1730dd53df0b98274bbfef8c93bd969912852", - "0xd036b9b29589cc551bf27ab95b6366d772e7d692d8fba48f473a2fc2d023dbe2", - "0xc51229a0306e56a53bdab1fda497281e23aba6ab17301c2eef3ce3d01f56989a", - "0x2652cb79e0c18dfdf545562b8569cc2775a1b0b1b465cbdc5880b40ffff22676", - "0xf24e0d6c03961043cb41638596c4ca02e2a2522a3e828dc4613a72ce5a535a67", - "0x01725e03a7cbfe2d6c5623829e4d419bbeecd1c7f925dbf1667979bb4da6650a", - "0x3b0c9824b726b2b556c6c46af48b84f856154490a51d775ba06aad48055bcbd7", - "0x2be2f1cb826d7575e53bc5e14f1882d73bfe145ed91b2ff56a885f66e136db46", - "0xd16752cc862f33b14f5976049dadc4f15f147f2fa76c50bafb38a7cb25c8f881", - "0x66b3ba188143bd421009c082031696bfd6d29fe7b9c3345e7e70bf6a470a05ec", - "0x83e017e8701b533c9fd22e30d63c3781b0ac9ec1dff4433fe7fb5c8f6f4e67ba", - "0xe4782b025953c5980653abd26eb95de1bee0524c14a74b970ec5615f98ed6768", - "0xeda29e9b36262e7c79ef9c0b60fddc66bae542b19caeddcdedf439573f773cf9", - "0xbc02ac1f023993253394ca965f4394bb40f9c7822ed6b2cbdd249e4b72f9b637", - "0x8e1bde0f2541d20b7f7e8179014e0f6b98eee5c1e0278ff1de38f4c13fdb4161", - "0x7b762d3d64aded9ff99e3423d7e676dd307b765ca6f1295e079ac53d5a4788b1", - "0x1027bb44ade6a1f82f11e9f298fd3957a9636bfbb97457c319e3d57ce72146b3", - "0x963864b3164578d4a7e58de16593273067a641de752b6df2c9b8bfaf970392f1", - "0x16bdf92929fe3629a57f737d83328d034c36bbdcd006301f28dcf52e1d1cb542", - "0x69952e47225f1aa86d952afb0fa8c668ae710a10cb6a94477d518c8f771f5c30", - "0xe68895f4ae2e4a35fb7e0730a5ef9c3e3030f6351ff6381f77e6311912ced98b", - "0xf28d799eeec538dcb2f371cfc6aa16f4a6808ddef0e6fd0cf72fde291d94f8ad", - "0x5a404922a9bfe57eb85deb66d8d83c869ddf96eae17e7fdfafef19c19efa1eec", - "0x96b735672e85aa95c2f8b4bd5ac80942923cff64a24991b3103e4ee39fb9a8d1", - "0x83d922f50174810fc45daa5a607a9b4fce69d8ab86f428ac57ffdcd9c2ff2908", - "0x3b0ce5a62116eafbf445afff0674112f01e1dca0e2af2b72d0cbbdc452177d65", - "0xe86cc93417c7dbcd4b5f051f4dca1394d272dcc2101a9e94a140b20f5e4c8b59", - "0x99b3e1d593b682e1b6454675593ed6828f8f4c5888b965981e3a7c602d89d031", - "0x81e0eafc2a2adf3d94938c413cd9f588e7525b91f39a689dfc3d0ce6aeb812a0", - "0x699e692ff89a918eee6d19a63caeb07832dabf1eb28d04ec97150c87045d9129", - "0x90ff00b66a14d821b05f692ee6d100dd61abef3234fd29e94bc84574439ed2e0", - "0x2de5779a122ccd84a88c3adc4edf7c1c03dd1d3e89ab45657885aadaa087e833", - "0x775a5587a907aa5ff13bafed032dd96c312b19dcda1b0e74e8a4bd327fe90e50", - "0x4fa48215f975442e6b9ea0629d308667242a7fe89f0cd0eae55ef1d35a3d6ab6", - "0x2e24c24731902f1b9e4042eae9e946b9d884dfa9f733ea5d4f7e778b68daed9b", - "0xf23a4a6061f45b1ff2095adf02ded238b37a0ffa9653fa9c1b0069e37e8552be", - "0x62b94eeb74bca8d9ea91aaeec5c13a05dae022806df28b92ecee99b47de999c7", - "0xbe6c1797cad2d5d9ddac3b3adcbf1622241e2560e3407139e24dde3fd8d3e435", - "0x7df0788058bea0911f2e30133c835515bd777f7aa9cab6bcd27eb3c0a6e360ea", - "0xd87066a4721ce567f44abf179184381d81c1c487158a6c57b5f2455472209a5e", - "0x0aec7d3081c3ee7d61f36e8c7e62ab74e41f00b664b690a341b9ff7feb5adce6", - "0x16345b31779e80499dc01f9ccaa0e9981b2b336500f33cb1f2943b66ccbf74d9", - "0x9ed6c6685dfa2b65903db0b234f4539906121330c5d55e6b2a2fd30549b2dc23", - "0x6539602958d9166335a7a0396ad72be611661bdd40c786cf9b0f382039c6b46a", - "0x72bbb4a201de75b9a4b5cf7381308953234c62f295df08b919c12535febf6fea", - "0x2d37293863f6b90f43979ba5944bec302008957e07b7c7f2292074a0a3934674", - "0x22677859ad20cf8b924d516b9f979652ac91a27459a4eba5455beac7f5f23128", - "0x704c898c04ead58c2fdb2c753359d10934e66b326f104be28ca7a32ef05a2bc1", - "0xca2b1ac29937067b761b57b58ae4069eecc799dbe089342bea274e56fde3d1bf", - "0x4a9773e6a2e75dcf1ff46c8f9931b8170a3609023f47c0ea9c4af000798bbc22", - "0x7e4dcb6c256eca2cbe9d168cc78c2702c373fd6e69c210d0713e2766baba148a", - "0x399ea7dbb66b95bae693402eec304f9cb6f4c6ab729d90ca569fcc2bb24d6442", - "0x49d0e561773458f834c96e8fb9496d4cdf83f2cfab75824cb1eabf8e8962c18d", - "0x80a0a209e41d0c3ff07ffe6a7f1af67997662494a327fa7f3bcb7209340974ed", - "0x2bdd6d6e7ae3f4386fc655817e92563e80f46e1b277be22f81a689de7637ea1f", - "0xb77f32374161e54c50dbc38822760874d966f9e098a2ea7aedf650adf25cc0ad", - "0xb49b1decd65a998a3dae2e4725eaff56276af3f0c50b2a3a35b6e94738d32808", - "0x319f78ae885011458f47ff1a110881cb4ac6a78c7d4d7a2656ddca73a88b58e2", - "0xd9fa2f47bedc0b405df34c98582b553dde76a46d38ac86d9d357ea0aca60ec2b", - "0x4283ac57e82bd08970ada71f4617728bcc467eeebb19c3aa20208a82b18fb508", - "0xf2ea3a5ac3bc77ff64f7c686305044cfe539856fb2833cbefcb283317012062c", - "0x840a9b8c756c3c3de7170c3597bbd085747b97419c01bbe484fc4cc7924736ce", - "0xa88682b957deb995307ed875c4044246d779e3f8c584cad75162fee119613806", - "0x7b9195c23833f65832a44d097290d8573b43e6f3e47dcb8c3826ef9a52fb4ff7", - "0x57bb0076c87f2e7187ea92f9f7643eb5b4b823b8eae9f6e74c8b676dd86b81a2", - "0x68593a8268b245a5c7506a05860755cce1be795994a7d736aba41ead4c025a68", - "0x90e21d5927d39329874688312eeb5296677ecccbbb9c6bdd4400c50c9bda09c4", - "0x773c0cde2d1f44575c89106a01881eb5d9593bc762a40be03ba979496ad7d229", - "0xc1dd843534e9844bcf406cc03b277e71d4e73026635412e25f3555d099f26a55", - "0xdf3f794bbd98096cbfa17e168c0de845383abf52fea618937ed81d31cfdd88db", - "0x1b05b1f316013609fbf813cae674f193a9bd8a75631b55278bbd37513b85641b", - "0x429321ddb251fadec6b6f794acdd8cc9d93512b98af23d20749d93c3c9fdbc36", - "0x6cac90b28ed13c907d094bad45574aabe2355e13e6a9504b6001e5fbb9c25235", - "0x89b43a3f63a2ce4f67071a121f447d7e843948395616116ddeb57a8714becd3e", - "0x6de560c95a0483d51410f66f38884947dfc787e1c61d14421129773010b46e0d", - "0xa0ba45049971dd4b906e73f917fd16312646d53c0cdfdc3eefe53628a58973e8", - "0x3d4a4f7155eac18fb5a126dcae2035155a140a84718f33bb20d2f1461e8cedb7", - "0x1cc19669bd91087d2046770cdc34e8f995cbdf2a0cc62bda70d6074ed58acefb", - "0x7c1c4aa1817de27c62f35d66927d924376798c954d65ba3ba02c0528d11d748d", - "0xf0d67a8f3c5306165cffd44476249c254898bcb26c937f10e8ae244edab1b972", - "0xcc20c5ecb1d3e83bd56e9213761f8320bd40982ab5fb669bed774b4490637932", - "0x7935073eb3e5c37ed1135cb22bfeb0e21727d170d106465fc35de75e8d56cf41", - "0x7d968e74212c501d0bc26ebb816b57a37a8cd2720caddb5bf66f489e13a61bc7", - "0x2c134dcc35d50c63a13bd8868137e0240280f049d7e392b97ff5f76d00aa1296", - "0xfd046f06c1d46d9125a119f786acdd76a85fc596f21cb15f367933b717ba7d83", - "0x9f5f067e4af3c8e92d2d54dd061620f0a13a66006b162a1eab4b1707499597df", - "0x8a6e1fb6205a423ec2920d448a376b95cac7233d5312287bd850471fb49e4f8b", - "0x2a6ea987659383f9885d24c935fe56de39d45caa89e60ba1768189318974ed7e", - "0xc2df6c8a4eae77eeaf11d7e5e2198ec4a33f19f5995caab4db6577fc1ce7b957", - "0x1e2ae8a42eb937749284820e50f11dfbfb606ddac3efb201e0b2664dd0196d63", - "0x4d63bb91f9f8a9965c460326f0604a27ecb0fc56f2126c6b3519b08a895747b7", - "0x9a46c2ec5dcef6f5c5b76d4b08b9d5085709182243cb8308a2863cca8cba13dd", - "0xea57019cc85f7cece4cea7eadda96dc9e464df2689957ebfe8d817b6996b2e43", - "0xb40e930b31dc1508480ffba351b102c8cab53c6603a0dd88bfed1b0da5347153", - "0xf51ceb070d8e7cb998cf4979ac985b4850949b4456980f523d8b9d72604a43da", - "0xddd28627f5c7bd213149bc4886bf4bcb8304f86068694fc743ac81ed749aec3c", - "0x9ef2b3df587caf086f4a9838a829491d1ef45db132ea71c6bc96a4a40d833e92", - "0xc9f7d4e19501c48dda5b0012cd93564898ad080a653e29f3563ecd40d36de84b", - "0x0565db36e6fb7b881eae309fef6fcdcace7c92a7ff148476b627c012aaefe4b9", - "0x08912abab10f16b92ddaa3663375f6e2b656e4ed89f2285aab6e410fc59e650a", - "0xefe9e68ca3bea929722bcccb5150884eb23c32153b14644b1c7f4e033dc3f718", - "0x4b33e0e078056d9efd857f909d1e409516f23da68105463167e23d71c90f6366", - "0x63cd4d1c69c4168798a3d9f15388207ea10ee4dc6be3681b0c7dbce5649d8f90", - "0xc8e7c25854d49022e9a0ae2eda8e7835a6db9ef7d612312e9deae23621ba240f", - "0x22c05e50f27e8bdaf4abb0a045d0639bd7f80057dfea638df6a7184ac49b738b", - "0x4a34356b5a447591ac66c51370fb6539bdf50fda9600082dadd91d33713a74e1", - "0x7147d53533ae40e886f6bc1c3b65c51570d72398f46e3266f2eba7b707b46b3b", - "0x1e49f75a30695e9bef14b036bd1c0f2b322042b2a02ca56604484e913b284c1b", - "0xf2445d48e823bfa77776234356ae0d3c1a850db236b3d2a95e5b00c4d7e687af", - "0x7034246c6342c26f5ae974576358f993d0e5e3c577e6aecdcc182c78082ab181", - "0x965067896ebcb2628ff10127508df1c811087f45ae258a0d8179d576c21e4891", - "0x384ebc34021ebdaf95e1bf0d8d61777b96a1ae65163cd3bd9b4311970a7918b7", - "0x1ca6e203cf1e058f20f5a8b1e33464801bcbbe04c79a7201ad6036bb8aa54101", - "0xf5aaa21a85fa9d502ef278262acf71789a3755d36dd8b3794becab7fb2d338e7", - "0xdeb7dec7ec133b6ac05c3bc0fea3b0002c8ffe58b135f4ae85b71fe0350dc7ce", - "0xd5773586ddb40d4c772541f743f7a4b08e9b419fe5b5b3536afa0b3b888725bc", - "0xeaff5bc016770c7cce7be21952cd8759a8d0eeb1bd849732c15dbbb82c613a74", - "0xb1a6a6acd39b4428accf9120a46d74cca6451ea4a182206425a8a64c6d6be5b2", - "0xfff27e5023fa1fc365db1e79cf3283bee2f51333059bfff47df39f12875e5fc0", - "0xadf1ce203b0acd4cdaf1d9a91cc158a21c823dcfb0740f089ce0830102b1cdef", - "0xcf20c92fcfa22d6fe7a60d1aab2d5a942db39d447d4ba1e9e76888a64694f1e7", - "0x210a684182ea379b50d641aed1baae3bf3752fd84feac4b3dd4e110c5cfc4ce7", - "0x220c5460803cc8db7a2b645dd5a4525b0703182cce173324d20e1c865a157811", - "0xba87b487bfae148239b44f3ad7663fd66cde8e21aac9e1a50bbca7bb7334aeff", - "0x2728161f9f040b4d92ba838d841404604d4d838157fc66f20d6c4c61034fdbda", - "0x3f8a6c7198528e5084b3e8d52d3101c27c5bed8721beb831ff921eaaca4c4282", - "0x2cc2574320b3c7252404db7c67b462fbc8d87bdbeb782ab1bbd257ee634a35c2", - "0x13aae0ecdc6a70d85412178ec12e971b2c4476d5e624938ca0284ccfa611d11f", - "0x6af7161831c3442db94cbe28ee9385fe79339d533b9c0fd3266213c2a5024a14", - "0x06185136927e5bc26ecfbf2299a0fc13cb447df6ca4a60e968be8c2b7ba1c2e3", - "0x70ccc84931d910a2489d50becf82383a836309bb90dddb21026d9e4e4368c85a", - "0x400ae9e4da0f847dcd4bb65e8f9f661a3b0deb78346b4f1f84fc712fd34410f0", - "0x57aacedf503300888fcd8db2138badbfcd663c63c3cf5b3e35979dad635c24d9", - "0x8fea6cc2da76b7cc7062af870cfacf4952b81f09c3c15d31145fbbfe1c0806c1", - "0x5125434cc5d4137ee31b51ed8306b4d665b8dc66504661b46c227e62a9ef1abf", - "0x254bc0b61211e0a57755d73ac618012938472912f855972b7ce62677f5d0e64d", - "0x2d231389c849ea459a7530ac1bdffa4d84908e2c61125a70bfcda932cc8e5efd", - "0x671ae73d4739bcd4841fdff266803117c5684c61031fff16e831a3bffb4bae4e", - "0x64c4db66cae82a96f29296b481619d79a739e2dfce0ac1f659d45f526ae58ee5", - "0x3f2f08ce2f21253f8c9a3fd650a885ca0e77f720a21ad5b4c0867150a0274efe", - "0x98c48268710592ee4c26620375968f2b8730a1bd1777239e6ffb9f116c6e1284", - "0xdc7a5c095c255e1984b4a5fa75c7a1d95d98097fc4eba898e644ff66951d8dcb", - "0xeee7579812ef09ae31068e8087536362a967b2893b709a458822449ea89a48fa", - "0x296e707796c0b9f9a2f55ad06c42d03625dab94af71c2e1c7016a7ef6645bf5a", - "0xd9a3eb363d4a36300dc4d1903a83447c89ec286f8d219f1156335da283992d60", - "0x039adf5a0cfbc394847d8014d64700ac4b6e78b531a1e0328bab256f7c407116", - "0xf9a92c6b1f0b0b3d7ae33cf5ddfddad516bfd7b21842d76098737533efd4f7a8", - "0x5a5d1fa3b8e05a81173e627f14e689c166776b93df401593db8035a65fba58f5", - "0x34f7fda3053b9d06e217223ee06fd194e2962c4a381482429e596df1fe319686", - "0xb4cfd9a71a98ad52c7705d55e96f04cb9064b1c32d3c346be51370b56ebb0f8e", - "0xd46a93765af68d238b776b240afd464a24d8c8bc869280ad618fd0fb6360e878", - "0xf3c622a4ee05d1ce27d59e7b9b3748547f4efdb1d6ff72a58fa93dccb7b76de1", - "0x6cb017c4bd8bb5186590cc4559fd9600399485ca917b10556b98cd7fb61441dd", - "0x7188f59c892b8754845d73f534587f27b7da67f42dcc1c73390fe2970bf0ad28", - "0xb4b17c93af08b9f587963e42703379c5e4f760502870b8096917b09b3950ee35", - "0x03165bf9bc20c87412a41209901d2bf3c8bc03a8586a1706fe1499641cbc4775", - "0x9ef57b2126a38c2dc456c13c272de53366dd1bf1fe768185a93f3562d064fa8d", - "0xbc3660089065220589409f7063dde34aa080179b3f22464fd9df9eed98d88b0f", - "0xbf1cf6eed0e0270d6be602040a97600ca7e1279db4279a9fb7ee643345a264b3", - "0x4cc471987bfae3b32179aac7018ba574c0315b9832915b5d0b804b38e9def6c8", - "0x51351557582b1d821adfdad36536b59b28f9a1f1243115486ce44d4b22d3952e", - "0x66d6b02183b9def37dce37b66ba4e9939241732b49dbc8addd147a89dd9e0517", - "0x47261859ce169e56d4e7dd75c5e2648597c7906f9264710c7e4dff74f353f739", - "0x38edbf1db358c82d0c945a7fc024f7fdc1165331cc19caf6b8943d3ce76b721a", - "0x5231560201678a39175187469f7e36c1c729ae060225012ff4f679f3fabb8237", - "0x763bfbeeab624de07a6e758368f8f61c0fcfc8cda088d2dfcbeb47a5eea9648a", - "0xce910446cce07477d424f791a71a375830ac26a2543b8bd1343e0d775d161e5f", - "0x950ba34133aea3c2947a5e5fc1836375e81c042ee999b60dd4a27e6492fb41fe", - "0xdc24f20fda563bf74ff7540a06f3631af8ab3b3722874a6b383714f463f5fb43", - "0xf2250ef512d3a11144370747f2c86efc73abaa81152bc6083f87aa217d16ee67", - "0x8760d0bc8f28eb2504f3bde3e429a47f0aed1dc2c7abbaf01c68033c07ad368e", - "0x7ef1c11b1f025f7e2aca2624aa9a11781cd860f24ce3fb525e7196e590fc5ff0", - "0x7c4e717fe77c8f9e742e312081d51418614031745b182746c7ceb4ff54deab6e", - "0x56c82f80b8d52128275529fffb3ccf7376f411d7cf9464a15fdecf617b4e7571", - "0x46f7d3ecd09c29d36a62a1a65bd3c59a14c82687b5466c9c130df14c286c2a95", - "0x1d04deaadcfdc7a1e5e612df6eb836f55caafb4f9bf4f1200fdfef4f14229f26", - "0xa0f5e65e99a22e14ebafc71f093dadc96c68883609a7460f904eb15360e3dd6d", - "0x8ea6c444466d4b6916a1b6dadafb87d75e2fa1ddd1836425dbaaad6e99f4d68a", - "0xd53d052bb709813e6dfe218dc4bd99c5ae83b6f5993b182c36a386502713c7b6", - "0x2e0cc1dfae87825d1a1d8946e021dc514dea384241e0a6cb66d5daee570c72fc", - "0xa419612e2bca19a3a8dc7fac4da86c2df4edcc2989e10d3e9050323011676b1d", - "0xe41649d9af504bd273b9da0fde578dc126afb55feb8b3c31a0d4eeaa9c7b83f9", - "0x0121be707b5666d5a78949b2ee263bbfbd013b69caa9566864711bda4c7ed0f5", - "0x788538d654618bcef0a63e31576e19a0872a92733ef7930ef50f8afd6caf110e", - "0x7777a3a4930828cc158f696e6ddcb87696115f473f219ac5582d8a38e0645430", - "0xe15a9f42ce5964358f862fa7a40bff0c8e8d7429a5ca923c9f0d4d0d574378a5", - "0x187bd59945e1cc6a877fb324b1d7ebdf661383ae7e22c56913f2e920de73dd68", - "0x938f100308d20611bd14372b16da0dcbc888868f8bd183d667064dfa8e67a161", - "0x5e61540787c83bfacbb58967280163f55f5ed00e733d6295099588557ef2dcec", - "0xe6625082f4039ef9dccdbeb9488baedf75fcec616ed9d5009deb4eba95cc680f", - "0xd01542aefe234567f106a4f057173b4f6eb5733e0ab9537af2db309edf38763c", - "0xee0174f3f9218a3418b8dd2bcd4132821eb91b31391b7c2c6e5a84d067d21497", - "0xbe26c679aafdea135aa493bab8ee348b255f50bc69592bbe017dd96b0da58b1c", - "0x297e6634c06193ed4725942cec32ccc9b4e77b5d02fce2ec9fbf580e3dfce248", - "0x820d98bcfbc008480ea32b162d15701357f094b1d7c99a1ff92fc0afd9708a06", - "0x82bce2be0a2d468b2fe0d3ba4ec1e5e8eac2d83f8b2e402b3043119a59cafd51", - "0x63ff3569d9a5661b6773a1a5fc10a522ea12a22399cd337ffef75a0d36735ab1", - "0x8431746d8239126bedde7d5c58aaf7f733dd1542c942d415d876ebf8a062f032", - "0x6bfdf119b93ef4da6f48265f4c526f0837a10c8db9c518d0dfe1edf40ae5fcdc", - "0x55aaba1f40c9089c65623f67eef8cdb827282a39cd0778f26e2f73106d3eee3e", - "0x0022a0b29d8188251bf5c6f37c76368dc9c7ed9e00376901162d1fff111273b6", - "0xf4bda8d3cb5b7ad50dfcf2668253e44b98e87d563ce17720dd1eb1a4e1c32628", - "0x994315a889329452a3e08ef029e7d902308022b74aa5a4eb2178929425c90a84", - "0x86a962d1d436f43f6fcad5b61b615f2bd32f10fe8c62428854ce98f4289707b6", - "0x3ce476498f26fd1d0b276ea639d438d7efd3c10451949efee1c91f279ef15ed9", - "0x199b2fef89c1edbe547e8c0b666b7b138d6f94fcfb2f09f26edc429ac163b127", - "0xdf3fd62e7dd0133ffa23a0da13d720373b57e85c28ee97890c355c44323ad592", - "0x92e0cc3bc262330ed8a1f42ad40a2db6c4e75e2d39e24a6ed5eac0855c12dd05", - "0x5b46f058c21b9447f8faaf78b2549f7f1459fa5ddb4211150bc26dd718f8361d", - "0x316b4f0e5b50cea376307236de36f3a1ebad3c59ae28dcf7838339d8711047e6", - "0x2b72ece0cbeaf94140b99cd9312eb891a1264a4d31fd839017e22cd4cdef058a", - "0x0c86b9b2da38f00150d49ac53ccb43a88a44181c90b492e886c54b0d6a93de22", - "0xba5a671174dfd7f877bffd7fb3179b1f3f8444ab14eaa9a0488207141bda26e8", - "0xecf73cee14b1a8fa5c2de5d78c058bd04772666ff455ca4225ac419606041f2c", - "0x1947b6adf9abeeeb55a66cad4afd016f6522faa641c4e14af94cf6e610959ad0", - "0x5467aaeb96dbe111a0d36fa66a71f489fb33ab8d95692695c09f4680086daff2", - "0xa21fd9195eaf856bd048bdb258507351e9a2c168920fd0c550a2340b5176ba26", - "0x9b0cf5690d3c3764f5c102fe1d5139202a1f982bd5afc8967eddaa6bcfb3af42", - "0x32bb410896733f9f6080a5b574b07c0af3e5ecaf69e995751e392c3905c11d20", - "0x5e98b3dbf58bf5adc0ccc9269aa10f9921afd44283837e7cb419ac4fb89f6164", - "0x051cd6e01ef3ebac9f27e1d473b0abc00d870a78cf894cfa8222d00976948b39", - "0x500edc8298fb83a103f5bf779d1df507644e054ef27ae61ccf31d883d85c2a0c", - "0x80c8fd7e50aaa14da3af3ec622adcf89eea9760ddbd5232a49ba55837be5805a", - "0xbb828dd031299bfd428c22110ff5d9f5612447e346e98401ab4a01278834e476", - "0xe2c5f408029af25cb9c130fc8fb5118660d08da399dbec0fa1709d1c0583de57", - "0x1be80d06b4ec5ef612e16bd8d842484039ca5663234174441f0722ca521958ee", - "0x21d755042a542493e44e92b4355af2f06f161c0e2583aaf6862730be7e9976b2", - "0x49b993b77606eb939ae485e82243e530e392af6d68be4ece5ace66a675a7a70e", - "0x954823b80bea8f2007503ebda5a6ae4610f94cc2c9a6ca22088a52468a960524", - "0x2693662c6c0961a92566deaa4a59204a0c436aadc0581b799e6255fe97d26331", - "0x4e80abe082c0b8ae0602c232ab0f766aefa702e744ff142cb9e101a6050acfbd", - "0x9c47c762c73836210a6bd78e5ddf9f2e817951d52b9fea0c823596c3df2a1fc0", - "0xe86094c8da0212cb0cd96f54c9f1b22c11feadc5599f6aa63285971651f11278", - "0x3031451f37f3e0288d61580e5b20e008a2ef5975e5d12345056949dca2c1d421", - "0xbdf90347d794ab3b41da6fb75b5d8d1f426ca2c4923216393e055dcbc89f3cba", - "0x4f7a0c9ebaa4833e7fd0ae0f3ac8dbecf3d97d0036a41ef30230e634142247e0", - "0xd1cdfbbf34bfcabe4a0eb90fb4d8592738203d245d68b753d418c4bfab8ae4e4", - "0xaa56db3fe5b2edc2ed277656deb51e15f86182de49836b4dfe2636de5488a86f", - "0xf67b05c233797d61eaff641e5bd35ee830bc1a8440e06f85e034902bd1023ede", - "0x49bb9be0064ff46c4b7820e7dd08002f3914fbf9250c96873bb3dcc7bddbe3de", - "0x594efbc23c0a371e3e5478c599466ff3a8d985444583b70f275afda13cc05c9b", - "0xd1dc59771492ee0881398f87a7c90db42874d720812c1e105b1512531d9fb1f3", - "0x7462bfbf8457d1df1288cbaf339861dc91c02d772f3c1ff8c215965e555d6905", - "0xee62a752465879dd62d08d7a15a54af1e813a1bbf2035384289bd634e2e99524", - "0xc7c66334011807d017e0df794df5f2f36c4cf496ce0a3589465662f8aa5433c7", - "0x839af48e65e3e1fd3d177d90f1dafcbb0209b107bf882cfe2fd514be625c1396", - "0xfb4eeb8514ede5bc952beee0e7e78c6d7ae544e6c4d935a6c92375b224e40c3d", - "0x38576e990356b7c44eb1dd531fe28420d01d80130e0ef0a42b9a8b01d2687822", - "0x434bb4312789b8cd93c5f930f4305760f86c54ab225b35bec70954aaf2fb4c2d", - "0x19ae08dadbf2f7da90ce777913d59e74592cacf6f385600f7d50cbbf7c4137a9", - "0xfc9a8ba8d7eff3a582725f8fd1539c4f77a87ecf23505de8a321ec6d568cab5f", - "0x20fb269b1a7908ccae92532424cc94604ca9a0908bd7c5e446a687cb3be9e0d1", - "0x9fe0a0e3511056762698573eee8ee2b0b87a8b6daad2141a9ad00c5b159521f4", - "0x3630751af37fd3ae22e78198868341e86735b03432879fb159628937c6bc28da", - "0x427789cffa2250d89b99d50969d8dd9917b5f4c721ed9de79cf81dc59f94d81f", - "0x5ad7e16bd42e35671230458f8f97c18baa5a1f81b675df259c9d2d7cbb09fb77", - "0x3d58c8ee704a934f6de776ef8373c653140e089b85aedd53219dc0b46ff03b58", - "0xa5a0719b16d8771b34e050660ba965b0ebfaa06bad1973033cbe2fd69fac5886", - "0xcd66e1ce23416fb4662d2b29dd72d9f8f981c66098820058451441213f2947aa", - "0xc7eb6f1df45136c9adeacb03eada4557326aa0a22f9ac0d73df25e21beb6bc0e", - "0x890eb4c610c7036e1494514e1f7ff72f414c51143fbf13cf2cd03d8d37a03662", - "0xa54328a1d2ffd9aa3f38a9e6a0539ad2517c4f6129f01768891acc0a2b2a721f", - "0x147644decd98b450b284d05d7332629e3c6444846f7c71dbcc892d3191f2efdb", - "0x1a19c1a8fc7f9d838cbd736243e66b1f637f49b1d8734c2af417227a11623b30", - "0xa8c14722a6f7e7efe695be4e6a21f2d1c8b8d71e2cf69e7645ecc5cdc7b6355a", - "0x8eb33cc1490499aba376f581b68766c4fd40e7d6027f223eb46e27199acc8d67", - "0x1b6a906a5321b057f453624693d4ae6abe79a5b8fcd63a777dffb8b2ea4184ab", - "0x7185ec1f19e7a84c9f914dd223b382ff56464b01a1b88dabda415a01e1d0a1c8", - "0xa172df0cb06617eeb95d362bb36d5e5ac52cbdb2e5f3c2cf3d9b78ef28fad82b", - "0xa11941ce1c866d077fdc995acf3ff2ee0ea0481eddd142f9b343c8403ed606a2", - "0x1958ac9a77c5b9825c401b204001dea8ee2520983fb3e738a467980a7bf9defb", - "0x6b24d043eab24359787ed7e93543967c9f9b7ccf99894c1ee7768f6235cb0cfe", - "0x6ab8c28ddda71b937d1a6feaa67b071f78ff7ead3a192ae63dac34ff24b8d929", - "0xf101e3da7546249b5b6d4dbe960c713cf152627a7482fc3377aa31f430c54530", - "0x22628e903ea9eb3eda9c93ac92d77b1b8a5ee62706dc5ddbcd079c57d5b721eb", - "0x0050467a543fbf0a232c8ce9f66eaec6c38c3c31b8ce3d590d1b07586374c1ed", - "0x4235a1330a45838b2d2aa9873dfbd59cfc0f0cd16e13ca9292f8342eec255fa3", - "0x2049ff9cebd379b51308220449b3568c6d7843f5b49f61b85808287f3d60441c", - "0x50c2ef0e832df29297dc524fcf3af4cd0988fbfea71987f3ac5cba8d4ec34102", - "0xe7260880b2d822d18c9ac2224d09fa18f5c324fb421470aad5af6c2605b40985", - "0xdf51e1b441b9809b26cd7cbdc4df27eb9c7fbb3bf764971684aab6c63e282a75", - "0x597b5c48840a25294feb135e0318ba6d6ca09aac476b1041748738963136a0a4", - "0xc710bd4b45a991f7f1387c25db70a1964ca4fbab32b738424d35a6e06e2483b3", - "0xd67460a50ec79c90a97e25d4cebdeafed6c897593fe8b24afe47a71c818a55b5", - "0x0ac1f2282e4491fdc8d28f1697026b7fa88f46204610cbaf8811d38dc84539f2", - "0xc3352ebc532273e4224dc0e94ec4cbb83afc2b5c364d71534344793032441006", - "0x42f3d39c81e118a7d515d82b6880104909a7915aeaca8ad64fe74d9fe88a7f45", - "0xac6fa42771e9cd6ba31dcff2455d2234c53c282251ca2399c727fd5521eeff0a", - "0x83ae44822213f59d34543a6d4fcf76b4e22cbe5a90674755072613550d348551", - "0x99cdb65200f9d1c602c5c2ded67a8cf2722cd7c1ae3f11d29a2c1b702923df93", - "0x2adda7cfa12bf5ecbc74ed4f4ea419ad7cd3e7cd03a0e2b32e924aa2ab98ec42", - "0x3da7434a58c60b7fc7fee8e30b3073ff4d3c381288fe6ba791f68d74d24ed19a", - "0x9dbe78f9121e6c0d99fa6d441f6aedf54be14fb39a277cbb5f19fd0b846305c3", - "0x2ded5acc49e2e1fcb57a66a81f59405febb50edb6b41d0fa8e445477028f422c", - "0xa46310f11937ce81ebe8d4c60de1a5c8787a1aac35ff3b6e2f0cc793112b7df2", - "0xfa693856fd1867458c335c6e903e5745a950ddf8a43cd9ee76ce8d0b3070bcbd", - "0xb374a194d9edb55d2946d40a16ac4617e4d0674630c6a970f58db17f21d22c12", - "0x651032646288a0b6fb5322626bbbc5b6b87dc5a5d59f5f39073f2f9574646c41", - "0x7f4346336c95c7fcfc1f849cfa63afd46dde8e346ae0801aaaffa9069f989e99", - "0x8bedf8e9f5095b4275635525fea6169c5afedff2ae434e42c5cde973de77ae3f", - "0xf92ac4f6fdd7801f15c8e0ee163241542d1359372d2189d8cd2a33f925933cd5", - "0x806d437ddf966fc6631a8f81a54eb82080fb2ade64a2b715872d8f648d23b57d", - "0x2151451d68f912b58bb510002407943ef6f2cc87a992e6df0765a4c239e63779", - "0x6a02bab7734d8549be10373e6395c368492b8518df793821962a940d5cf93654", - "0x4de627f1d096c86c1c1dcde2a314ba65700b1ac47b9db95e9ae68f8d28f52b16", - "0xeae202c747b699171115bb56652ed534d9ca6de0e8c3d947d63c6d60b5d658de", - "0x7bddba4a7c160445653f62d27c1622323c784461d52aba5a6f19964194a063c5", - "0xddfcf0c5ff899f19c4ed0604e7b4cc645ce5bdb7b7c7d6bcecfe7f2cfa3bdc0b", - "0x7d27d279f52b83afc9a115c71910d06a054fdc2e20625cd05fe35ecb03734f5b", - "0x415f6bcb216ad524eebd7bf177bce80cc3d5fb3e920ed65a8ba6c02f59fa88ba", - "0x570daa81ed1b593529a07396784c2996d5703f4124f941e99e8f9cf6b608b1f5", - "0xb9da28526fe8300989e16c83c4bfe418c74878be1bf3af12ff3b9a098a4c92b0", - "0x691938f83dd63e39be2fb03422682ee8dae8e0a95bf4d09b4727f8162b2da11a", - "0xde168c58358db826c9c953895b7a0419066e65eec0b7fa479c328719cf70df6b", - "0x65a7b2207932e96c427a6c01efd0c3f01a37e02e7dd98b18ea559c2a6c83c8d2", - "0xfe54ee65b1b8e21292fde2eed9ddda163036cd6745254bc7cb9f3dea737832fd", - "0x543d64c2a6b763cabbdc1a9316f37115fd572d96b5c75184c155e68532fdc8a2", - "0x31b41a4f481a786bcf4029b19e84729c699a8d742fef50040221ddf6785d7335", - "0xa383494d908727fc6198035c24afb3f352a16b29b0c1639062e7169618bcb38e", - "0x3da745966ebad677a703f5db94777fdc307f6e3e66a7c3c5ca24f35cff3f43bd", - "0x32fbcb24d42beb2128d95055706b767f7df7ce16c1613e3195342db84dc9955e", - "0x1723ae6147425f5b01b68de9847d79b918ca0f85a800d981029dcb5e3c62eb8d", - "0x997f18b9977469cbeeddaa1bb31472be3806c03ae77973c857e32d6fe2c4d740", - "0x6c27575f33b1d85fdf9643c9ddd27085f4241518cbd5b776e0d2bce19b152ef0", - "0xacb86fb3209fbf57c42eb86d2617eb631e0ba36da7de5b2c7ed63f168a7b112b", - "0xae02559f4868fbe4f114eb320ff0f3a38086f364a2ee537e6051cedfcee76d6a", - "0xc96e439aaa996d4ea4c276d1592fcc06e829d5f3cebf163aeb75f590896a2648", - "0x87debf5b6912717ec3c0846fcfb5b459a15254660cd5064180c0c514b4b15f59", - "0x37587d340df2b40b3f14746b72c5a72c5f51963d208b02c9671d6c623079b584", - "0xdff2805c029c4e3c249de3aa9f5cb3b48daae4f4496deefc91ebe3251c18629d", - "0xa84f66a457869dfc95d625d40496250ff33894be23a43e53ec892481f1eb4fa5", - "0xf8fb34bf78ad6d52be6fbb5472f13322b506f594ad3b585c04f56ed8d0d9afa1", - "0x546937b89a4d3b59817377b9c2ffe9579d4650cce71aa26bf2c76c571ec495b3", - "0x5ac921894e98005d03aa42e8fbde7ad0af0401e350c8ba98c01543a93b37dda9", - "0x3cc76dc057c73f0e0fdff28d484a092747ca42bc10989c599d0f597ead6024d9", - "0x1992cd7e94e9ecfaaebbd08d91519d6b67857db87e2e67c546371738ae0d2d0a", - "0x3604be694574c05c63d69cbfbbddbafe3cb425d75a13e69d61b50fd8d9c947a7", - "0xd1c82e40206d2a89e3a1a40c4a1b63c62ea6fa0847ddc2b25f63cb9bbb4a55b5", - "0x66ba114d5bf45d50e9ab9beaa879ce18d02a8b4f989c29ea7e9ae604593e860a", - "0x94f74c09ce5fd1c8fcb9cbbcc476af20fcfd9cf01c7ea65c14917da7b9560ffb", - "0xa4e154ebf83215c3843ecbff1dc8f646f221505c21d2a76f47d55466d895f1a9", - "0x28c20a0e95e23a023678443d7bf5b2421975b827dbd617239dcf26bf6db9b255", - "0x55d8ddf586d61e137482e3f4bfc1904ce4e04d21c6e7ac4d8c7d29b1483c8c0a", - "0xa9e1aed191a7a1a92bc99604e3b24c02356ea378b16de109362aefa2fa978451", - "0xd543ad635db78b2518681654f98a32d227fa6a1fa9b7043ad12cf58c91e8f729", - "0x102fb87da8b57948fcb763d7b797233f21523545f78388d8d05c6d7f2a4b388d", - "0x4e7273e2a92e897590988f38f8b899879aa1aea754fd5165364e8b98a66e0d62", - "0x5a06544527f88d9fbbc5905742863d873367d99e574d75496c59caa041e2b612", - "0x6a8957954db14594746daa61f907e4694e2a749ff53ea6b1dbe77d7d1f378d22", - "0x0debcd48486aa0d33a783caec0d6fb1256ffcca39071041fed7f047eecde8640", - "0x9d0a9b13dab1888bf0eedda217c501d76f587ee9a8765bb455cebcca0b705599", - "0x30693bf8c9bcb6bb4187606f98e138700e999d8824cada72d3d07f8c104fd263", - "0x494ef870dff64d1d65b4ae4b49ff13c145a6058876eb657751d58c06f62b5032", - "0xee4150e64f9ead8124d50d56fa4b6e6d185fe8ac385bd2a9db7ee991f6e34c02", - "0xb859d7db7abe48cbb9420d008d94e8d47753cc78962e5dabdded9438bed56b1b", - "0xf8b1fb734c345111704d73fe6944d0a274964a347d7dc5c7cb8677104829f5ce", - "0x5dc002623d9b3b872900b0b313ae8520009de730577b6eb2e2de18ae5cd4ac94", - "0x4d63e346ce7e654db6f067e8348c539ccf622d84020812724b936c19ff4f86af", - "0x2ed43f4e5d6889f5379e42d4a06de7c343080da74ff353960e4cf980f750fb90", - "0xfc61d0c90ecb073c022c87098045b6ca3f2b66c94f3723c679d81ac652b16f72", - "0x7e69914b56984b8c7cc9db1732c3d2d32969a58d6662509846e6faeb1305586c", - "0x0ec9b1b68efc96fc7d831ac7316e0ac0d908bac31be330d905f87b136556c241", - "0x32fdf6c25f6c741dfe468289cd7f019ec3a40c5d8fe882ef662b798491c0dc34", - "0x1ffbc6b29826aa58595d1a412fb90050f2bc3cf0ebc5462f308d4c8d85a1eb59", - "0xf0fc93cc2868cb9828ce16463e4cbd59637672d5815dff03aec7f3e1424eb204", - "0xe404321694894ab375f5a65c339f2cd2a53fb5a10f312082ce019681f6ed64e5", - "0x81ab1f93747c4804a85f56b0c6eb61491b958504ef7b898fb1362eda9b394e1e", - "0x1535d439d0043d1436de963e3eba47335bd7afcabeac4d3fc3f342396d3538be", - "0x42da1b95481bfab6cfec59884bb1ac7572636c8f489df2768fe2140cd2702766", - "0xbc3fd861f6e09efac1782d9d383c4ddb9b4268216fbdf3c25689162628e36cec", - "0xcc74c3d8b44a8cd23676babb4efb0e67871582cd5686fde9de6a052c5bf91ad2", - "0xbcd7fe80e95bbbb5ac93b1df5ff0b8e921e7ebc4960877acc1a95c478c65d64c", - "0x045e5918fa69606b9546f5fe83cd9212000828c54f9cab856f85d3a22536a751", - "0xc0f74dbb5a42bf1656698c37aeb904a33e969099f215a7efeeae0024c3a409d4", - "0x36d537998634f2dcab43b387edb63119c0f4cc68b1979a2ceb373089c531ecf9", - "0x87c20426fccdd225bd3b961c7adc1de3f9ac9640f6d26bd183f6e528089922fa", - "0x195ee1daad5c3d0052d6d633eda1c9f7160d488d4bc54f4ac3babdbb678eeec9", - "0xf9a5e6735f9c5577283e8cd717b56f69dc8306b23781755f2e513d15e6738cea", - "0x3e5bc3e78ae33367ce7450c5da7436f1faf3b1a62d238208df207307762688be", - "0x123e7b4f7e6b9338df2827a238a266376a20a1fd065e9f8a4446fcac4c6c92fa", - "0xf4eb14bfd197d49c42daa919322f18228d2d9ae2dac6dd7113c5e7d12d2ef866", - "0x78836678c20a40fbe09849fe190a9e74ee070f2056d7bef85d0f124676a93130", - "0x7986f7321971519933aa5dd507074c7b007328a7dadb8734eb4aecf732703fed", - "0x14485d24b7e90fc39d91ad6051b7f596d320b1f88f54fee132e032753e59a766", - "0xa80a9a5db758bfacf831a54022c85a838e30c8611ab4b17bda0641994302b59f", - "0xedf1814fb78abf675f3c5671c3618e5e51105647997d6dea6a0cfd1f0330bf6d", - "0xa91e9fcdc4f2b5e029abdc6b2523079bb4a2f5346d8a5a674e3d5582b8871d1e", - "0x3dbe468159a8c068285c92360cab488a4c1ec37487dd54cdc0b70e6d7cf074dd", - "0x69877439effb3388639ef6e1cfa132bc605bd8a0da053bcca23d82aa453d0040", - "0x6751d32ee3a1244532e6698ce57cdd0a59f99130e1e7e004c2751bc49d10b355", - "0xd1760a4f6e5a7967985125d2deae8bc783e47b1b85e19fc273e33eb2ef88d271", - "0xfa934c087923cc16f636615657477c48c082623d7cdd35508571655dc14efe57", - "0xb6b1e4387e04c4ddf88ada0aaa162345cd43e54482fddb4297e1eb6f8ba1ce74", - "0x3988089edd46b57c0bc83b1bfeb0050b503cbefdca83e96f1c12e7ea80688a79", - "0xedcb1bd8b522ba5155965cf18c25a090be2f8d7871ce60f0f371cd033d5a31d2", - "0x2f887b56b317e9896698ec9059d36aad63d54d95a01d389aa196ae12e562ca2e", - "0xe6d6b89e1d851fd24cf54f6b60c6c93a8b014ae30906c156374d73605aab3028", - "0x177928968fef8c6da017b177f6be85851616775be043b64f72925e6b8a4eeab2", - "0x71a3de323d9a600e15c25a5a6e05089d849defc3830fd69738f548fa4c57aff2", - "0x8e7d92f316f96b491e4831f52a799846810dd032bd720dc891195739192f3955", - "0x12a3433e8cadc005ac35da334d557c8cdad63576613f07df8c3ec9f528e846d9", - "0x1406da1f5efe9d3de6a829f1219f731f3ac875c7795f72b5a9ad25a57970b9d8", - "0x15a849a0ea56a777e00325b4af4d9996747486cc9893c08b0773210306193521", - "0x6178e69be88e7e93878b731d062b29a34bf2951082b947f35f60fba2c8de62b7", - "0xc4142d4fe01091e82626178b66c13243c9b35de0f07a49e3c5f2ddc15b39feb6", - "0x8abda6239557236af27a2cdfbb4fb91a6b136931c53067739578ed13e1b0a2ff", - "0xf85615d9337092e25080430cfa0b7a24c97effd422a1947a4c07239d5221418c", - "0xf9534d7db3b5fc1bcd7033ade59fd66bbb94a5bae91c4acebbb1540fc8bd3b67", - "0x5ed0f8035d3920d6e94b881cafac324ce5688f8c97668715733e0d00733b0fe7", - "0xeb6c474a0adfd84c79b86090c793697c0bb39d6cb007c725c2ae7afdc98df5a6", - "0xfbfce3e019b0b29ad03fd9146fa368f9965050b40733ce297bce6acefc4668fe", - "0xeda9ed65fbb1c7fcccc91de519f69933ae66c8ed59fb65f64751ca8aa06030c8", - "0x359ea9df33d466b5dc210ef0e99f3b4416ce03a5439f49b4cc4c1b98b22a21b8", - "0x14b2e8729b70abac62120541229182264b78c7ba1a1a379ac8a582aa0bb0d739", - "0xcec0dbdb55f92191974c2c8ed716578c5ba04c4584a0770fc0d7d5cfbdcb2717", - "0x07334b05a08cab079354cc1f7a945caa3c633de89a89c18244de81ed56da850b", - "0xc58e0bb71287fe92564d00b5094ce36b7899c346679011e52b73eae45bace19a", - "0x9dbef45ce9abb762bb9b30b61456a90b74b0b6f5b41af9500699542d933f9535", - "0x3cf848f770e15e7f682075c77f7e980da6750d3d4cb038479983e341eea3c354", - "0x608a4c5958ef3b0a324a7cdeebcc3abae89c1371c949d6b269b2d3936d9fbdb2", - "0x66422fbb9044305317d900702c2f99702317a8a83ccae0911a2832f623356c8f", - "0xe977f86ae4c5b350b350a3d6af7fffdc9baa96d9a7cb24834e5dc4797fe39fa8", - "0x6f56fc66544e099797cc3b0879dd20b21796ace01a0029e0d8464a3764d1e858", - "0xcaef7878c703facf29fde1467dcd08b03761872f598f42f5c56b4cb367b97255", - "0x9055cc0c11cbbe8477c7dd35b37a57e7994248c6bde9ac05e85717cebd2b970d", - "0xd7b08c0ca8abb9f07e3df1c4ebdcb03b0ac2018a905d1c78e6825d2bb5ea1ffc", - "0x0184cb109267e58d5bc0193a04548f0c2b87286ab6b03a1ff7b6d88a725662ef", - "0x3005e0af1ac0c5fd6d58328c06cc7f5d89c8c4ad173106fee1a7e37c9f2dcb95", - "0x8f7f8800d29c66b4fb12334b622fabe1cc4ef06e4ded44e4315efc381987cd56", - "0xdf74e3be6d22159e0e02ce3b8f0b405e6469557ecbd12e4432d52f4ae4637bfe", - "0x2fa9a889f958ddc41bae5916657f946273447add502464674658bcc257f1af15", - "0xbfbdf04ab62a35b2f7b038b02d8c37ee946cfee18e10ef8a4cd5409a5fe81d19", - "0xc4e834510182950161a75a843352b5b46e246a05b7c7e47240b6cdf7e18b4de7", - "0x2534be362fcc238c530f2ce8f64a3366d4003a21e6f32493a082b7efa1d413d3", - "0x628e5f76af96e64ff34c52cc5d07562e72c53e7bd4b7585cbc83b7c9951d0d2f", - "0x41687c81b22f67e4ab6ba0163da6d58c81d94c5db20569b4a42fb58b7321a442", - "0x50f55f58cd9768b611fce3ff13e8da9195b1eef5d0a618fd27f7052f88c8fd84", - "0x1b64cdcbfc12c42e9dbc7a62a1f8eeb0baaab8ccc867f7a7308c88e4968eb9a9", - "0x77e9fd9a5d64b66cb901c5795b9f66424638b24e457024b5e71ffbb79ed8a863", - "0x35644de61c2108bf9d49efef164414cd2594ad4cca6bc421699458c9bace5491", - "0x172ded87912492ee521f79c1ef22e42b1d22f17c3286575a5d419fc00d928199", - "0x3c8fdc337338b107ff5879b3e95cf285b5128ae395c4b89ccfd05a3d942887d3", - "0xf4b22643ebb6d46cf292531792543f9699a99674978045b0c911818211be6017", - "0x783fdc538e4505d4187a0f341b066007caff8030c3bcc4bf49ebd31a8f6b4794", - "0x38e11f176844f680e75b65d5225533639eb522f39495b9ee426135097e5e8fab", - "0xc5e0da94d4dd6e29c8bf3684177a62051e7555ee87007fb07581c885be598edd", - "0x317dc456dd095f9eef53781c214806beb31351cf78cb1854be257b4039324b8c", - "0x5bbf954741e453e3157dada0a69bafb9ebc63c3dbfc0cf6e3fc937a1b14b7356", - "0x56a5354de5acff2b904c5b6b976c473277ac2364571c54583bd682e76bb3f43d", - "0xc37f17385f4e6015cdc8083fc750499ec8c9063544102eb0e3e3b7e0b5046946", - "0xd616c205adf0ecf00c7563fda837e94a4f48be8560ddd15d93988cfd3242b40f", - "0x1ecefd5cb0c61b120c227274dd60b42e6d25229517b20dc3e37a7c3b436f0e92", - "0xcd447982c518db12b8aeba63b68d8caf1eda6bcc44400c9d83c4e4d64b4e949a", - "0x3763ef2d96a89a302260ea66e22e3255001ba2f003770c03905d4f39d8ef6501", - "0x2fcc41e9b574af5402cdce8dc66d79488cbd5cf960209918863ac9526bcb6a70", - "0x17b71848876a6e0a8857f1e5d04762734678ed1a8addb7e378915a7c3f37c981", - "0xcac9e4641f50d52d77e0e77b1a1b5fdd25cae239864367b3d99026d3fb973610", - "0x55eabf50cf101f65e51dd3a54321c1897a67c50512c534ee9398a716a790ffba", - "0x49101d5719e4de5e4e88645de3c22cb3ab794df815555d4f22d54ac6a59f73f5", - "0x509cd8530c28cc098b0aa80d3006a8f71ac7ad56101b880288658917173b8c8d", - "0xdc0e15e6d321519f34d40c6b2cf5f6955c15af815dbe02d84606ed76a01fdbb8", - "0x0b8e107e7abcf80e85b3288786dd79f949449225315c9125730d7d42f0ab9cb6", - "0x07ba997ea28711f221ba26d724a09a52b2737b8aa8532e890490ad811ffa792c", - "0x713775500194ec8691fb540d63e99a70cd443e5539b5f8e2a993266bb58266ef", - "0x3b2ccbf35ac833e845f00329c1f8d130a3f804c55aa83c35421adb83749213bc", - "0xee82c15eb18a075b00de8fd610621683dcad88a19c1c507351b5be0de0c6c4bb", - "0xf874298782be23045971092d8305c469a309a1a33f6cfde7604e6499d2384cdc", - "0x1a9d88cd641f6468fceb32eced3710569d511848f393c2114ae33d7f36c12f3d", - "0x5b2b8c2ba5d3aa8a0503d14e759154d1f2f46d819b363025a77d4cf5e3d83586", - "0x0082bad01acd43bc2c504f66ae28056ce352257b7ba7e2c27dd36d256c079561", - "0x9c6e4e01a831348ce64da4e4bf04cad5f58749573e54f1062b0e2921bacafe74", - "0x600e1b0101161721066952d71401f8fe6e689b66b26e2e74cc924f5e914e8eec", - "0x8720d215255e4d5e2a688096506d5b25c3a79c511d8c0b3dd7ad3ccf542e9abb", - "0x48baaec9724cadc4f7cb8f10549b8daf87b2572151cdf9308b3e96f02b048f23", - "0x2adf0f56fb9bcdbae394025ae949e694e01599887e50c355c90c3ee5ff32eac2", - "0xcf78410476d781bae1567f3d763af732d2ecf56e741cffd1bd3906af83de1f2f", - "0x4e7e223f6881065ee722d6ff9603f1786e4e99292e9caaa75b7b1fe9aef00109", - "0xfdf0b390b0395f007b1b342065096e0a8da957b26ed4cdcaba432a202ec12b65", - "0xcd40d2df140abc1228b2e1f45b5d65a0f3e2ab8b7e740dfb5376b036f63c1c2c", - "0xa491347f128d31f68cd1ae536d8f982fbfa5b58d855a95219f104db741d3d2ad", - "0xaa91fef9cecb842de4df61fd1650267420c8336758fa450f87ee867ff1520905", - "0x75d1574bf7b23319a7c8ff6a0a7cae649313aca8893ccd223f1f77fd71c9b8e1", - "0xc72491916b25756e3f505081b7f63e32f3289b86cbe0181ac9d33d29f666b9e4", - "0xd446465131b34f091673736f70fa0508ee7065c4011359c302a603b6159cb52d", - "0x1380689a50696e1cf0c19869b9773528f01cdf20b8f8a6c6a7165fda31ea49af", - "0x01cac6d9deb56473681c02dc753351feda402a1a1cc2b4cc8beeb23884f40760", - "0x3f622e134dc529c5cfbf58a3ce91d57850578f45b77c4683b2dfe4530ba0826c", - "0x016c95fc875baa0a5d1ae22c8772eaf574a6c918510875f1000d65f3a779dd04", - "0x86e5f579f42ea54a96e622f4a6becdc5ae85e0d0af87997fae87b6707abc8d28", - "0x53d403f0d0f1f30d919ad7212cc5e2e73cb4870c4fb4e6d260d2573e9bc5575e", - "0x961cad0d17fbec30a8f614ff3565d12698af096e61836cbf1f0ea125ae3ed72d", - "0xc9dcfe7844bb4ea845125bc3674f326c0f178c5cba4349b9461e40bd6ec68c3d", - "0x894243ff80e90c4c4676583b4e428f13e077008d225790a234ae215dc53d33a4", - "0xe5fddd80d3cdbafb53e0cf3c095d33904ac8db83bdeef9816111d20384aed444", - "0x5c7ce294d82fe6502045664f7d13d02063ef24f0f4960e4fb62bb6abf08c63eb", - "0xb33a5699ac121a51c0074b4783545a86a428fb239b4307f1e45108c85af88617", - "0x37168f3f0220f50ba3cad0a558cd8b01a7a435b6c3c5cde98b420ba3b54a1cbb", - "0xd50928e60d00c23adfc916e7f9a5363fc8c94c8edb3aef41ac1dc719041f92be", - "0xa08b27f437ade4d527d883194f79927053ac55a3293487a65060aeaf4c4e5147", - "0x326e2d1f45438741b63d346f0da55066dfe0284382f1b4ee54b1d5552c4f7d83", - "0xbd96baee5835d9d6007b0b5957e452d71d1ee31aa6fde99796cce59b17dab703", - "0x1cbe90df49f8929ce1052049bde7d6169efe0b289ad4e05414a8e7bd61788900", - "0xa0b914df37895be6f5341f3f4013ce5c61f108203dbac4ff205d5f1a581712cc", - "0x1582e61974c0bb5f9f2622d70e772f3e9ce145be97eaf5a87ad794268cf352ab", - "0xe946dda774c96c7878a0daa686e4a22e0d9d36a88dd9c93b1776432adbfd68a1", - "0xf88a07db8c0fd2a1354c38617c16b4d2e4f8bb43d9049321ce47a8c03c8430d9", - "0x2adb489b34c480267927daf3ba3ca7567d542edb83fa82e8040ec57e25e3e6d7", - "0xf1c28c6daa3e97466d50d9780bd3335f3dd096c3389b906bcc12426ae4862a99", - "0x4457a8686a3839b7d3b592a1751c25b216bc64e9d0b8a81eec55601ab8d8a98d", - "0x0ea5d5606c5e81f92d31b49b2e54ce6c6314b13ac223c83094280d0196e003b1", - "0x33a91da49deed50914d998615077c5192be56e482ab230bdb3d480d283502e2b", - "0x5385496abf2e351c0cbd7f6fcb5bf5b5345783b4e512bdfa23b9736e77ea43f7", - "0x98f808b18e5778a1bbdefa3f19991a3d008c27e9976db0ce77ddf9e4e21a0feb", - "0x5381dab139fbb0ad6b61afa35c541aba559e2ac25c4ab1cf8a756c2f27c6bba8", - "0xf4bea5f3ab0bc9ba3ad00ad79402d1d62da125d311884f225ad8abe9fc36d56c", - "0x6018a9f7edb5ee7ada70c3e85f22ac88924d06031cff3f61104ef52bf0baa2f1", - "0x01cc4300f1cd2bb4948329d42e17a277c7da52696d46a60442b6f5600d869faf", - "0x330240c95bec1ac1a476cd202aa74e85db562750f860a9fbd76e813f16cbb639", - "0x0809c487d45161c3b85cda014603ba7efd6b67a8c7aaf314cf20c880ec623a7f", - "0x653f53065726f9a7c1b96ce7d836acca515f563a47c9d7d47aa8c5c030a9fe6f", - "0x37b8dd7b2a844e519f9eadab305efa5d112266cbbc76bcd5afc119e0dd337ae5", - "0x385b7031eafc345ed353d9b35dc53010496db172cd906f8e0b7b891b84a65e4b", - "0x38259038fbf1ab3f0ffac98e6b312457f6b2631f68ae477b9302fe740cfb8e50", - "0x5a963aaeadd708291b41bd419cf2ce0585e162e0d46635902b58ee85e317adc3", - "0x881004f4fabe3e7642c8cb5e99dc3909da28451ec442a299f331790c8065e049", - "0x3c721f828959782052312d30d8256c9351a141923a9c2e2ca5b605f3a92cb27a", - "0x3429b149f860e963ed3819ddf19164977d637489eae313331c71165c7eb8f824", - "0x44e291345b79ff4116797899da20baf28fb9d4d2a5d6b1661a0c83b8952e481c", - "0x00078c007b6c0b3b6603b0838b03ee9e8944fe16f99f0a35eda286a288594806", - "0xbcd3506338253f0df5abf0c2866cdd319fe75bad7ac6f18d1f8201164e0b9986", - "0xc047f5f06cc54e4bb54c8e3bf22245d68c18b4787a01d324deb2139d7405814a", - "0x77ec49a04762af36eb63e2bb5c5cbbf15b580020117639ed5546749e34285195", - "0xfce516ae95eaee4067e95a5752494974ebdd182fa47deab70fadc5afb5ea8648", - "0x2ee54548e56d2cecc3e6cff4e60a7664e55d9b1c1c9a61be74bfff7635078cb3", - "0xa79dce8f10567e060638cb2f09ead0b191e59d972c532a7e91b33d27151cc23e", - "0x436b4cf10f5cdbde72be02ca16602190a56c77f1686533e643c885351d4657e1", - "0x9070c78384138f5e17cc9e6148c7cb7591eb9864f042b82ad38ee263383496c6", - "0x12a8d5285c871a0b05e370a337834458ae2159b5d8cb4bc93b6cc83bf7351b68", - "0x3c07d35ea209492f4aa811c51202f081a3bfd6e31705ffec497d70bd59b7a6f2", - "0xc0a99b851e0fc4655cb3cb43547f4ae6c36c350aa71626b61ed3ad3492f04600", - "0x064404380c5969d8e43d759ef990658d7cf5bcb7b4f8512fe58a7e994e199707", - "0x3d3a61c95ffdd3c7f05b3574370bf4cf0eec605ca27cde051b5d77e062315f36", - "0x9259e0113f1e009fad7454eebb238e0c7f4b7aee8118b63b6c05aaa2f0bc39df", - "0x76ff9818e62b25fbd698ea021e200ac9314090b801e000ecddb71bf4829aec8a", - "0xdf0031d6e1c55717102ca1b3a0bd389cc0d227f0f804396d4b84b5dd26abb1ea", - "0xd0220e77632c2353d51b92b1638e909c1f41a7ab0e6801b65e344ab594f48881", - "0xb15fccf30f298101d5ca0034cb8585cf14ddd76d58f3a8ca71a60aff0d0438f8", - "0x5dcb3817ae05b8c8490e197cfdd3f0b701e61d83b8f6423b3f24f27ba0f4c668", - "0xf3bbdc6651a4ba011443f6c6542b3f45b8aa2ba8bc719e7220578d6362cc441d", - "0x1edc95bab3c88a66246393058ad1a9557b371e726adaf261a5faa535cb8fab76", - "0xe02975b5ecb9fb8abecab35298704ecc476d2e6205c2df900312359d5aebdf9d", - "0x2a5c9b033738fe9e7ba6949df526b5a735753464b746e7d1faa29491a8e5f57b", - "0x46ac373df276af8af25aa1407659a8e85ae12b51ea6ae0150ee2b80a76ea6d9a", - "0xe85513a38b54114f4b6cda2bc81a4dcedbec22749cab6676c061d95c7f38258d", - "0xacfba9967af17aa94f0bf73c3b1cfff113e14625742a7398a25a01aa29bf02e3", - "0xd589df920ebfb3c3c1660a16f74213dd6d487ee577bdaf18f6279eefb9252c57", - "0xb2b66c26bd139976ffc2471f8ec71e353108828bad5094a324d1e4762f5547e5", - "0xeac126eb94bb1ba443373fb2556753d95804891d4763a2cdd1d297f1eba0fe6b", - "0xfcb52c727793003a70941fb01bf6c184890a691b70c0aac3b11feb3987de8628", - "0x1c1b6aeaea826ed0cc776a322454663ef555adb0d3c6f50480957ac4ab7f0672", - "0x187affcea64fb6195ee27cdca1096142898be0fb8f216f10913a744f2005f7ab", - "0xb4e42e3a4c94477a6d5d7f3de429edee7d92cff93b647c71d7a20c1e07a35117", - "0xf960751197118967fcea65f10b51d9568c184a8bc968c609d093a0f6c15a71b5", - "0x0bb9ca3521abf8fe971d371749e5c2258b1fd4c681ded047d6dc7820d303fa9b", - "0x52354e8e99ecb5c2dcc1214c08901d715ba62a7463d56c76a6bd1287a74f5c38", - "0x8768dc0cb22a0ea9fde00170783fe3741501d958c186e2c636d03fdf8a995129", - "0xb4204eddcc9c75372de503645bddaffd3f71e8554c3bca09ec700d928a9664aa", - "0x97c94c63bd30754d51abf48aa830bac3724cf77e366965e9f61a100cd0136714", - "0x60dff72f08506ac9ddabe3f957f88a1ef4935f187b6c536643500d65512fd393", - "0xa94f4c353581e474a091655c78c491c38315e93e287f848c17843d807aae3527", - "0x09d90469c97087fd45cf1a2c5471c6e81e0ec1e7850dd76b0d0cfa9fd49aa13b", - "0x298d03c60b8dfca9ecac182b5c0f6818a4c3d84e55314c083f8913a8746fe335", - "0xbfa7ba8daa97bc681bc6ce413494b85ccfbc10e2bc96e148713e0325e21b3b60", - "0xe61dde9cf0c1c6fb0a37993df24dec2f221f97bdd34f607de13fb1f947e7f284", - "0x91e9a9e65d5076819146b246647b9698954bcf55e7f059db32854f93b325d35a", - "0x7bb2fb25b881772f318a10b6ce8896712c93cc85ce9c7c371337020e86817a3f", - "0xbfdda2258ccd28dfc81f83ad7cba81967120257392279c7412f0bb116605a21e", - "0x0a626f29328872380ebf6a10468307abda5a02c3a7b9e04763c0c8c83f903df7", - "0xaa8ee86e9446a125356a96f8ed47c3821da54b003558f68c823c4ac1ab966c81", - "0xe26f3cbd95e0a26683c26adfb71b6d4fc82b034171f29836cb9bf391cf172376", - "0x7cb80eb383da7d8c1120fbe79cf3bff3e5bf19b9f57aebe11f79ee23dd82e611", - "0xc9b85149830b7a2dcc1f613f40ae232bf5cce7770780bfa7c77ecd25ae0bca6e", - "0x859dc28f93d2f3b17e176aa8248d6720be498fc85017491c68d6af5f4798b437", - "0xdcc4dc79cf88601caf6e038bea275a98208d221ac8d3efdd5db3d2181c14c947", - "0xe1bd63a920d45b05efe5d2fb99437a26bb7049ea5b183e99866d6dae947ff724", - "0x4aa94bfe1501f4d37b0c55d77add7bee9bc7f24d444a3ed1c6cf27d67026bb62", - "0x10931498b823a9784c4aa3ece5e88b477050927fe4016e4b10de7e2e0eadbdb9", - "0x7f30cca2119b5a4107cddca59a88f10ad95cfaa879d97bd1e50ae6a347e71b1d", - "0xcd8a0dd7a4fa9b97641d5288375105273c9025a2c9f3d7d9d04179fe3f55143b", - "0x6c8ec850db640544b7e5b22c19253dd1595899a7663d40c4fe13de4258cd60ca", - "0x06ec895b6dd7f299edab3e2e3a65322fb7f8fa8c9a6182b7af4f0fa25acdc45f", - "0x45f6d74f05f7b366770428b49630e836c2fbcc72133ef03a1bcf9953209e693f", - "0x3d868a3921aede543f2bd8ccbe3b51468e7a87f8278e4601c4a8e740e8c339cb", - "0xc808c8fa7b02023e5c64999a141edf6e0ce0239e37656e0fa7c5156443f555c0", - "0x82c273cc2afd955663515932357f19d657eaaed2824551814706ae3843fa1739", - "0x5785f16929a6a73b4621e75d31958e2e9b00dcbf3a6b38bf3ed59672918b68b7", - "0xc8f84b888e55070682103999cfc315ea3d157d0771f0f035cf2ba03f6fe1b1f1", - "0x343a05e1a5e75e09528f194394caf6ca8caf94904d54d89c9d22abd5cae0d83e", - "0xddca7f95c2d9cfdc9efd9158d29045ba92a71d45488c40d28b257425c1c56bfa", - "0x008a2b681c4691d7e0de476180c969aa511467f27755d0d498eb22c9b5333835", - "0xe33fb40ffd6253b5701d24c59a4e217197f9eb7caf7c2223722734f4c74fca4b", - "0x650e8f1c6c4dbc76ace7d6c29b9a659d520af9b291b389bfe3812c1ccbd07c58", - "0xf88c36b8042df77734f99395eb68aa9f4b67a21891c42350e4d5e3e6d8fdf168", - "0x882c68aaa8d1f6acf005ce2ad3a6fef7ec1212ce610dfb8a7bea9417d87431fb", - "0xda73d75513895d5bd5174814da25cddac9a633507960e78ae6884b92e48ee699", - "0xf07d98594c0ecb16cfed18adb9f7b5b1055630b43444c70e6357cd18ebc09392", - "0xd70c5886426c55dda997d615d325b5cb5b652f5673601a045a113d94a17715c1", - "0x3e8dbda1f53c55fa4de65efc7d294a02d78c69a98d59049dcfcdfff6b7eaa521", - "0x67b14249f9c987298fb00e0bf560a976dcaa7fc0d02e816f84c3bf7a4e7c6901", - "0x4f8affa83492afa72e95a36f23356b46e58a0a19ecfff6960d4d6e5b9877b1d9", - "0x09cd2a17655988d2d8cd5fbe44965a6c15c3f123b75e1229621b9ab74d030e53", - "0x30693dcabd19e89bdefff4753cbc64d00c65a4af98f782e6e67b4e84f6b015a9", - "0xf67db822aaef8bdf7967c0dbe25015ff6cf88ce21e8bdd25feb764828ee64951", - "0x9a587510721ee914cf8b9c863859629ca0c8ed22b0aa023e9efb0756d3f9ee5a", - "0x5d00c0a840b96a19679736a7ba555f3e9bc5263b4b8437d6c3779191eda0a7c4", - "0x3e01cf22757510938a5aeb2ec6cf5046b7d3c186bafad7d57b81c7d2a99415db", - "0x0ff2d3ed3c5acfa5db9f9820a1a314865e266a823ab42f40bef6b0276af0a108", - "0xd3207e322207667c614e50be784f6b4d9c3f48362dbb65b17c62f5f33e631ce8", - "0x2c3330fc9f6394c0b8eaea0d156f2b9e2d2da0ddc8837e0a28d373aa779df9d8", - "0x56c8542686730adabbae6717ed8cc8f0b974037842ea5d1c80901f7c85eef3fa", - "0xc51d8a382df91e9f1fb0dd72d416a7d094aa3b8ca4f90561e82fdbb9b78c28c4", - "0x6507fec75b170f930df2e28dc75ef3dd7313834c8a8a2ec837d4ac27fdc906d6", - "0xea23428fd27ff3e5c6681b0640264ff22964c49ab0aa41f592280ae25d380c83", - "0x8e2a629fee2ba03e333bcf7fa0261dadff518dfb0e386b21cac0cdb2c7c514cb", - "0x4b00742b5349bc9892f2d36abe2c723a30c4a20ea5b899a7fee8fd759f066fbf", - "0x5b8d880357c44a79c0d04b5d347dc7c012f2f5cd7679c4d4131e5c481b45f1af", - "0x65d2859128eac961e29c063fd918c7a2b485bf72743cabb0fae8bb288f155dfc", - "0x3db9720d20d90d7d1ea448488d02015f4b1c36f556d704749723ae1c3a35aab5", - "0xd9676bad19db9f6896b2170e6cba496f5714ff9a70252fa1d4c82029435871a7", - "0xa36e49e6be40418bef884caac3b30e63fdaa1b8f622c70ede69e6d7c9c6f4539", - "0xefb40f7d197a63927f761d99596439b7b69cb7a39214258b372450fd471ebd88", - "0x7420e77f7230c7458f728f7ae5f63f0bb9182fd11ccb9a82bfcad17a8d1b4f76", - "0x7ce9551cd4cc5009d28a6048701049a5decbcf7e11904c588107da90f57149ed", - "0xafdbfc0bd5252cec1654dd24c375bf9f4af647cadad403923d6aa525fa44aa85", - "0xef0a4ef158ab6b06863969c24dc7ce5fabbd36181e9eb6d1662ce227b38f8e61", - "0x4e6d1c00feeb4218a0590fe046705fa35929767430f2c33b2176afb45f26a71a", - "0x604a1bef767235afcb7f84a20ef59d39618593def34034c67cdabec8f9436ea1", - "0x5c91553855f3a32f708dfd76c83a7d7f23aa80e5a6d2a7e9d83e82a333c9e267", - "0x48e35d198e8194ef83496392e05e3e14cc9c7ea1f324fb259c08a0f8385b422b", - "0x9df1a27224c2a20b229cc8686d95efb1570e822402c9df4db0b47f190c33dbee", - "0x020eb0cf345413cf0324f7561031eef27f188de5dc41bf38471547aec4e716ed", - "0xe9f7708c2cc8ee4785ed54a0c153730103fd92c42bb71eb4f86a93111ae11018", - "0xe7b3a27e3f5ff6fcf2925db134ee5db522a008db4d54627b729d5502f3968d08", - "0xc9c4b33c131365224675a89e4e6833181ae50661b114da50b14b0669d6ab7155", - "0x8986fba93ce8e336542d3a640d156029ea1cd99c2cc4e946de6d46e040e52bed", - "0x53b6ba779e5b91b5abe44eacd354f6f9b5b2343e66d60bcf5083ddd1a5147d21", - "0x854e090d7d5cacd3e52fed513055b51ae884965bf1146a629825269506f97371", - "0xcaae36c05b0992f80bfcc8f1c5d3a771feb88aa67f2c87b770637fa24000d84e", - "0x6992bffeb071ba81b30b8a6b19e9335f8eaa2da4361844bfd57f08488dab5975", - "0xdb63608d8eefa64871fa9fba1da1776a67d0c0495502c8eb4005eea4a0089563", - "0x57071fc1829365707d66abfb8e388478cf61a14f34af2c864b7299f6bfc2322c", - "0xe077cb6b750e158f666ea79aebd5e19e25b9d3694ac7a44efee1fe58f2bff202", - "0xc8180f9a9292284d2ba09dc40f89595ae6b554e6eb0c96aff578725076881102", - "0x89eb01b1cfe4089ded962a36ddfce84eb0c4337780446cdd88738e7241257c30", - "0xd1bfe1dbb1c9b6a06a1c18472ed66a82ca5c7ea1fdb5dcb9af1347e6ed97697b", - "0x33695a8c53e9e16e1a2255055eb069d9fc59436ce0ed698aa7323cd7e078cd96", - "0xa1c746d3df0eb28100b84c6c91da402c5c0d6a8aaee66bc05095820764cbdefb", - "0x3dd355f33c841eab61323ebfbe4a608b3dc9779a291651b885383ff70b8418dc", - "0x206c8095f502a995777d4756949d8fa7deeac36a106721d6bd1c536994fc8adb", - "0x95a9ffc34a966a157c5e797e3a1d0029bbb86999f1716cbdcca9bdcc5e77a5d5", - "0xb2c4e8a21c25d7cdaeed3a42b8670602580bc99ae5e85d4e36771e5cc2b7e0ff", - "0xc34e130d5fa9ae3df02c54a5eecf210d8420db5342af4041d77b8ade44d2c67d", - "0x5d733448fdde29b3f3749e70addbf4fcde659aeea24f90dab23997a696db5daf", - "0x8d63fe21beb60523466595253d20fe518dda259cb44fab5945943550b4e960ad", - "0x98e584f6dc76ddf7ab116d2e9244d0a0ecd99d180b1916957054f8440623f727", - "0xeb66965a23c4413fc5adbf4925ec5d133d2579c1f7764d6199eb4f7a5548aacc", - "0xc95df33729fa401a40bb0ca23731b61d5225f3ac6d159f243e1585440e16d529", - "0x2052d0e9ec0a62dcc0d0c892e7e704ed0ce03ef8a8e9c898a3691a571abc5c30", - "0x1f8567628ffc96390df8b7b32ce8ca70f6d8bf57b2ea0bd9e724c521ecd4747e", - "0xf2b48a4fef4c6c6127f7194ac76c57167cbbd65b9cff702daae1ae21dbc2896b", - "0x38dcef1bcf7600494424ae0b24956deaf664b92f3dd60b7a941ea144d789dd99", - "0x267d1afa22f77c5fb78434d822ee1c3fd24740d6a30f3ee4fdac95949ba8c044", - "0x0c01005442f62fd12a49115bfee0faf89d2da7572dca5b0e8eee445a0de8ddf7", - "0xa8d05f61408ed491620865b2cef9548d88182f37784e190b46c36bb09dd2d7e3", - "0x655eba047145af7d76cedf34e144040619d2d416367b57c7b7d9362a9375889a", - "0x5233ac6cb0ff6a892fa475b0074f4b6abd8e244f2a665e6649232e528bfa17f7", - "0xea8b2976e790ed22d708bca311a5b26c113e8c0ea4cae30607d94eb232ccb0f9", - "0x159dafbf20b2e624d22018f214cbbfbbd83de406e9bbaaf53ba46041fc3968c9", - "0x4d34b229e010a2ef72dec76c1449cce6f61d9cb17701803560af6b2072850ef9", - "0x32e7064197d2f739695788a00113452e03306a4f73f80ca62fc5e3ec223aa176", - "0xd1604bdf1cf9253b7b0ae8c92d09a2edec43221394c258d29707ba850004615d", - "0x07e0048d3913db33c6a9b45a1b232a2088341441d398b09319b455f57c18628f", - "0xf6492cd50378901ae238c91685319405d9779a1b78f22bf36129fd31fe709cbb", - "0xecaad91132667d0b1a283da22cdac651a4036224bd0efc79bb747d0c5e64b1d7", - "0x20565b022a8a8429a79a56aadbe2e32db24748238fab33eb2b0be5d83d1343bc", - "0x25e6d936a7b526d45ce1430744f5f4b41cf694d2cc50753cc88330e3e2a0bff2", - "0x7130e4b84c6efae0653dad6e16ec677bee7060a8da8ac607bde7a2b01b7511f0", - "0x93a8bf0a86793725e09b480d9098a43fc30a8420c5c2c2bd01ba8afa837c2371", - "0x2690922d4bf86c9a35e982b10f723edae97bb2a842f362036337396c7d9f9d16", - "0xd26efd262c6605d3be1ccdb03b96318613cf2d5b80350eea826758b9fd8bc28c", - "0xd3b2c89961d6cce736a9994f8707f78068a9806044cc2c96004d659f82753690", - "0x0fecacd3eb8c415a8db644b4dfc0ebf04a27f9b5e53bdac80fb927f40da4a8e5", - "0xd5600a3afd0eaedc221893214d629260cea97d7d5335e361d43183b4dc678360", - "0x340558e8951e1af701e95a963221109154f12c5870e9c9b9c4d7f9975d18ff89", - "0xb2ec154d6a59610822ee2318e3f279e249067893f806b129f4f0497b42aecff8", - "0xcf13e6343d50af1b2ff792e5a694531077e67858d76b39262ad19d6194e62df1", - "0x39db02f0b3f062645478457da8145fec8fbbc8a0981be9183365fbdc11a622a9", - "0xade17860c7f456c0b8014490f3cd15cb5f080e7112b789028f1e86ef428c06ca", - "0x1ab544445bb5d499c541c4fa02c5f850b9d18988e94ac6992525e2ad372d4936", - "0x2c3b4b33a865fce54d1ba1909924b0c6cf9a14a8cc4e3a42e1b4eeaaf86fc50d", - "0x857bb3e657f86c864407a7caf0c6b71e42427302adb85c853f330d00433ba077", - "0x79e42bfeb2cd1191783b7b2bea5e0e2693d9d15ce8d230e03dfbeac2c90451f2", - "0x5ec96430d6d1c1e9395a214e1a685e92c3780a78ca94a173d0e38fa6bca96461", - "0x544858c87e845b1f80043fb44f54a2449d31a0018025f1b41309a745415b1e7b", - "0xa26f04bcd6a580b99e9b81ed739ece117ad357facf1ecea246f891ce740029d8", - "0x857eb2767e67873c3f1ee4659c778feebb69b248950068a828d65750002cec36", - "0x7d6ad830b628a38b1753a33e5df98269d351b42d5bd60329e4c205ee5f30584e", - "0x6cbbf7d83f87bba0d4b4997bf336ac52934866cdd77e7dead51de84bfb717fa2", - "0xea77b839435e70cac6a89e891b8d1c495b39d8d6db38c352e10931e70502ec20", - "0x4d6a29a4487600b0e05ebfca7418dd6b43746ce96a41d4f17e25cd6aa1a2b733", - "0x3e8223ea6ca4ff147b59b025237a2a477495e746e7a551045374b27798ece58a", - "0xbf880aea05a3e440f31777f109995f2a1967272eebd9ff0fac241bee8747a8da", - "0x028cbf04056dc0f407496cfa901a4491c659173083ad73f84d457f016e0431f6", - "0x68548e63888fe0f203a333f5a5c950b36aa35e083a0161304a2b80aa626358b9", - "0x385546df2f083f4781a8b9d5b645516f5a77883eb7dc8d5e399f4f563e8956f6", - "0x358a0c7c14057fef517c38de9e2af33ab44f68c5c99157f9429db596e822c842", - "0x5f89b867c11d5258618595e2afd3f783e8db81dad073d8871a33d179f537cfb8", - "0xfd7328d25120390f5982919333df927ba3c63331321678906256c1ac02af9a45", - "0x406a9797947503dc57776a5c2ed6cad71ed975c05e15ef191b310088049c11d4", - "0x6e719945fb48d4db24d57a92e4d6da5cebc1a3db4a64792dad68b06f92c69c87", - "0xe2e7b80879a7ffc1e4e3f901ac99d252c1625b6824000ffd468b2d09d2cffa25", - "0x179979b54792b23d1f1940550d7c961a1373f6dda048817d087ed6d731af73eb", - "0x10b1ca5637aee0b063bf3a2fe5cc1729929b9932cecad392d7da6d567ca82d65", - "0x89edc6ecf4b7f292dc26c29515ffc3367850e5a8dcd95979244f5c57f81003d7", - "0x2cbdbde44b43c5dc078433925dd423ea51886e880b04e90b156957dd6a057d1f", - "0x6953ef4d3aa2abeac14fa44a0be4979bde0e579cc591370b08774f4e65f95d05", - "0x0735cc7c85194d5abf6ca0dec712db94b6b009c9ed74ff6781b7940064cd4626", - "0xc3f9b62bea678c0683ed688b77767b3fe3e4fc86456bbaa8c0172240321242a5", - "0x3640c7a7a1c2b62492098e0b5b9f4c482add16a86c0f88f8a60eafbf28347ccc", - "0x73820554bf239c8e1b92304f3df8290d18aaf765b45c8820f618d05eeb80fd66", - "0x8b948d61bbdf95e634d5c3827c66266e3ee42b49dc0a29100efe0f7028d100d8", - "0x8c422f252ce4e7c981b93c24db0984962019394f50ef5b62cd34e32ba7602026", - "0xd250921e7c17e016360e0b79d61d6c19ca40ca2d84c9a7c8d9da04ae4676c29f", - "0x4e71a2075113014494b5cf8504d48cefcacf14ca6be5d99f945ddafed4b58079", - "0x40d0dd35a9c91dbb1de1df4202a50df1745b2a5e80b256c3542bc0cdd5a2c524", - "0xf77e21f9edcadcf7753c1daa00720e024f56250766ac6c31a89e8afde10c9056", - "0xc70a38751d11c4240f2e94698c0a13a62d0b3cd825527c1dcc5e653186034f07", - "0x0f4f7881dcee934f71ab555428e89e26112ef6e99935761f3d4f314bb5504a20", - "0x82febe35f996dc229d6f6e89ab4c15f5659860505d64d454f625c95284a307b1", - "0xc557d10c1d19c90ccb9a504d31b0d91bedfe9a82388824fe901e8325a9996dd6", - "0xa241dbe076d02feb2b67d606b8592c970d193b84309196191b19087dd74b5eb1", - "0x4f687e1fdd09e68deac949de2738583e0dc2bf245790b5185e2f4e00f5e8da67", - "0x076b44af8dbdd16f859d9604f91e8809f929024eeaa6eb457c30db2657c03430", - "0x1bf2736aed60997b49084afc7a3d2b429d8b8836183c9ba71fd61afbcd1b5f0f", - "0x18ef59174edf670a07ed5eeae04eaaa08345d384d33cba45abf2a08af2415a5b", - "0x30f123870658c6cb69ad9314e6260a5ece2d5eeb4964601d4243aa1b56f4e021", - "0x36ac3e3193b6fa52a7134b9e4c7db6ce746619bd7f4d07201362062a3f98be0d", - "0x6a9250440bff309071b1493b2db2b4134c725ae364fc8a8add7e108f7434de4e", - "0x557876702f5bc2bbe17f13c76d0cdecfa68b0fe281f084b2f343d130405bb80e", - "0x5bb14f5bb4abe8e79909035a11109385ea2fa77c4208946841b61f1dc8a5366d", - "0xe7602f83ef13f3755b1f99c740fc46211f7ade9088a1942b8ecbd5a33482c093", - "0x30b8ee6c04d787ab137e7bd6cad1073e4e77a74db657798cc74c79676de337f3", - "0x01067e41f6b5fe5a26009378b7ea4b0515aac9449eef2730de5efc22554ed10d", - "0x73dc8e186c096c752f8dc2a69805e1b24eb5edc7553be26d36698b25829ebfb6", - "0x23eb0c950ea1467134caced1d86eb89d4addda6f8ebdbcb85d9127a5ce0427eb", - "0xbd0f1080cc7c2adc0874fc6d89207221155bf414e1cfa3f9360fdc98c820627c", - "0x0bdad5419ef94ee6aa76e4971981e54f7d6560f3faa3531f5fede35cb2e211bd", - "0x8a339a58e2ffda5cc2ef1e18a078fa09c3aec4b2a8cf9b6094ff620fb88860dd", - "0xc9a633a65b909af3133befda06a57b3058d625d816ac978f01894fdd7b3295e0", - "0x6dea631bfde98ab2b7db165e29ea75316ea50137d15a30a9a3b444d50d419e10", - "0x0a74031d338957b9564500f28f0e45aa571f48e4c85cdc52d6ac8d472fb66661", - "0x5f9e646f342e665b2fe387bdcabbb381a71e54f766afe9a5ca6c2cf999b50e4c", - "0xa8691691561a9e3236c0a26593f1c49b42f03c94ac3124b16b4aaf07fffb14f5", - "0xe806b7ac21b2e7d80f0e4583dec620b2b3399f4c1adc82a246bc77c847024310", - "0xd588437c72ddaff5ad3a154915700ade8da4023421008956b1b3d1bf164705e4", - "0x2f12257a5c3c0097b274697e648df08c31a3f8cf0833e45e45fe76091c7e22da", - "0x88eb766b8fc471e455e50a183b728e6e7fd3b5a152440bad5d1c7f49e173dafb", - "0xeee35cb04632e48f5b4c94aae1a40c372eacf5ca773c9dfc2fb3378803a6fd2c", - "0xcf9d9bbdb883ac7d171f808738dc5ad4e632d91f45737be4de2f9a2605141f81", - "0x94ace01f0f2f127e2cb47dc05a491df26fff49f68cd4f382c12e7f332032bc09", - "0x8f261b4ff772d1c675fe16f0764ae644d198231daf66a600d56526c1288144bb", - "0x95062df2fc6e23916b7ec403eb5dfdfd8f0aff49ca15e0b743e5a3294552d619", - "0x9626d392247cabfdf89c0254dee12f5d82118b5449059b78b4fdf7ed62ffd688", - "0xc7b341b1a1464207bc1996364debec53e55a3212a2e18211a994d2c8e864e234", - "0xa5d247c7e7511015cf63aee2909dc9ea7bf56b9c2e15f1603b229dc7ed11a6b3", - "0x551f57a199b684836b3b5d6e6cea2c7cd58f830e870d1689936ceb93c652ad8b", - "0x0f0a17a40f9cafa38559a7b8a1b3848514f4b5dad4c4565f8915d04163f1b51a", - "0xd4ffba1b3fbb46554137cb0114feb898c9a1a689c0fcb4dbdea49a313c593aef", - "0xe72848f46d7f041226ed0cb38549fad946e14ca379fbba4cd52a3bc3d6b94c55", - "0xe34036fa757a07055a5ba89f39f90066237152468c6c3fd8e60484000dee38d7", - "0x0984ba7640b44fefc22e2b53463b91b6686b909d038a29039a6e5f84e25e1257", - "0x2fd4072edee29b9b611c38972835d3cc985befaeea149311fad80dd0a8bab088", - "0xc64954228a4067748447b768bdb34d5a434cfdfe01acf86a11d8a278ee7d7433", - "0x7b10e8fb7d81fe90362c7d3af0c153460ed3df92c1c50b6f9a993fc81e0f29a0", - "0x0c33f7aefb88bb9f6cb9061adcb5fc535b2a3841a6ad94b8a4adce1954bc6f25", - "0x21460cc4c2bd2d828027b9c04b047c06b1eaa83f47640639463cbcf603e4b7d9", - "0x9ea560bd5c0c6a0fa9cf2e0e14ddde39cca6c24b11e02b635bfd4ba7ec826e0f", - "0x47c9dc525e0e1f71e159ac75943a32d541596c9b479639e0e8f00a171a29057e", - "0x6f32319d8d958c89295e38c41c2a6106d9f6bd86ea19ee6cd3df34931a2701a6", - "0xf90b80919f035eaa3cd56d1c54f9c69e60ab2445a4995c7969a4826a28220398", - "0xb9ba6d207d1d7866e6205d540abc36bc3198b072aa5d52378a1148f6a61210c5", - "0x2f494b0db620ec08b2961a12d79585de2f6939bbe679a8ae1a580535437bb0e0", - "0x65ecc619942b4fc71b4477dc5929244161cffe2933c84ef8e2d5eb443394e0dd", - "0x12f573e148bbef501d4325a52b737580d413c8f999cc86cd0e497d9201a006e9", - "0x709c2a2f2276d712070a10d20baeb7d1acc602e6cd0d27438950707175f68faf", - "0x472db00ea142b38a076569205123d2ae53f42c1ff86d38100742039440fef89f", - "0x536a68e966effeda6883266a1f6f00b42dbd874d83956a3312ac30e430607bbf", - "0xfda5031fc6bef618ec55de146ed9834dac41afcb0d0521b34e141cbc0617d14f", - "0xae912c6ae86e69a59c61a3fb95c9a60b37c17c3ce2b6e9ae4930dea5fb5454a9", - "0x426c6889a4d6f3896c5209b662d9caa421adfa1f1770f33262807a3c89983364", - "0x6e72f8cb2b6cd35fb0c090f8be71b1ba790cf2163d0cc18dc0bf62fcb0658fdc", - "0x7259d06d38028ec544eeab2e264f2d4ff975f245c3697ea8e141ebd59733a2db", - "0x37729ab26688e0399334fa3cd2748818425b3fc41304fca56881658dee0b90c6", - "0xcbb02add11c0edd8105b440cd44a041b6f55a94712ed12ffeffd1817ae8a8044", - "0x156e069b3b63fb302693018293bcc0ab60b2ee2cc8aab43e1cca3774e0b743b4", - "0xb3a7a06a4f2c1034ef5a2fa5fde7554f239b0193093c74db11ebb5d9b1a18f03", - "0x323b6d191477aac18e4761baf8ff9ce70b1274a995aad02fd582f87285f8a0fe", - "0x7e4d202c5dc858e3a3c45a5f43b0804a4ff5ed53bce625ced7eb65db74e908fb", - "0x75446e5cc0142cf4b0f26f560995f257f87023312697b3574fe0e1f558bcda05", - "0xf53cfce4dcf415ea49360d84188b33a1b6e3c686c6e59f1a7385f68f3e160a7e", - "0x43ee5e27e64e778f31d641050b5c975fdd9788f2d5821bc8e3c188a91a86ba9d", - "0x6a3a73772d1ed7ebeb82eff2419e05583049939493e4ff396fbbce7e2012ef05", - "0xf976ee31f6b27e1e0f359e1f96b5900f34c49c89e81bc753456599d2e5f4a097", - "0x00ec8886d567bd489582441964bda82f3e297801ab0c5d3e58a3df29f9004a4d", - "0x9bd7ecb0d91d576640cdd3022ff0bfa64838f057e55cf35ca945d47f98d8d107", - "0x1868b1c9dcce55407f81879269ef1296c5eeff32ef4f7770bcddca4bf972df14", - "0x24856220dafd06f20fd0914d4468713654f6d9a8a8472a3cba537c6db45c1981", - "0xa05130241c7260630ce231a427081969d4428d33dcaeec08287e7aa80541384f", - "0x4812c23621b2399a68e81d9dd6fe59b0f0953b279104a69047d0df3678c8b628", - "0x4c00bb65a14a1b995a38afe285ff4594c51c8b10c137e73376da3f2660f00044", - "0x3cb2cc9dc9b1c997b8e73ee151de0cc23f5bc0d7dd27d0402b6d79e1b50ef441", - "0x25c0bda0d092dff16a5cb70ac082a0e3c17a42d74191c9c90d46deaf34c85ad5", - "0x8a75c8a0ff4aa70a0f1389f5ddeb0a1b7aca04b94af03e7c2f3986a6a9e8f8b4", - "0x9d9c63e3b449623e45de0542b1ee4d102204137a2ac36a25442f3797668058df", - "0x932b4ab5c339c9654cc1c5e343aef426dbfee3a98b7835efdba1bb583238aaec", - "0x8001e5592beaa70277723223f033b9f830a23d4dbc64fc42efbb80bfbd7e2a22", - "0x1b84fbbecdf3add7f514e0cda2b1c88b21a65d82da4264d06b332ab216179230", - "0x79cb6fe9cd675e096bc92d449093e78e59c6c4c813b550c25a76c2cdf125e582", - "0x4fad1261fa7d06941dc436c1d38188e3660b300dff7f2001a7efa7b8678bdaea", - "0xbf81d3c1b1e781a706c6acdaa23c12f5e900fc3f191d6edcd1636beb3d29a6b7", - "0x36cc017579e8daaefb5592bb0c5b2d2fb7df5afba9fbf02d0c750287c2353b78", - "0x0cf0b82b4a102f35a06f590481b72f93d570e929bc43fc188e829e01fdf0bf9c", - "0xc0b67d7c6100b042bd39d0b4747e854a0672fa2769dff0dfaea01e05621a368b", - "0xb8c49cfa2147f651bbd73f97f02b694a5cc3cf9fd79d47bf34857804206296f9", - "0xd3836371f2d0071e45176aa82ecb05b5185e06e79043f69fff184121380e1093", - "0xaf9e77ff0a9c1bdb16afd7c1d725263ad04394e4b73f013829e63da9600bb35b", - "0x43082e5b9b11362b6b5cef0c5614848ff4c8cc9dbbc7e2b179330b46e7b3652e", - "0x6cb6fd2e7bd5550dbe63b9875814764e64036a921be1e5413ab1355d771cffd1", - "0x1631a928685b0fe688899b105aefa54fe61e564a4c9d8dec99a34f5140e6655f", - "0x095addeb9c0d14bc7e18f547259a68ea3dc982e5256f4a97e3f627c3b2140be2", - "0x520f53d82a67e09c157f3480b4f504dde53d947b9e2238f814f5832f84b8eedf", - "0x433777fbf6cded05adad6e5877ce0ea3e34342af6f65042c6141b4f4201103ba", - "0x077878ad6fd501074b5c713905aa3caeda3237a1b58087e6275328d9482b0577", - "0x6037000d2014c601b14bab5bbf758098b300e68fd3d6f2a0d5e6ced1657cd6d0", - "0x481b8e11fe6ca5cdc881bb6c3d7a0d96e8cd2aca705f950ac542c089d7ca0cc8", - "0x2b070c54b2af6cea0e0ee76d37a92ab3f4e9e04f3b581f41ef2bd5d2631b8b87", - "0x01ead0aee81e4611b5ff7cd64037ec0039a05bf0d02b18b92da6acbf45d4e6b1", - "0xfdcd33327deab31927db501945c15a82f278f34a09112b2d7f74219e9a364555", - "0x0fbf377a65289b1decfc2fef4614b1e5b3404e0a0c9c7d0d147cd86bed55f23d", - "0x8cef4b3d09f838d4acb5e21f777fbd906358a2759d24b055756e9d154b177ab5", - "0xcced9e5d45e86423eddcdcae5fb2080622279ff6f08a0ee47012b33af58f820f", - "0xb1e6b5dceef79d8ebd0b84a8990f724fd645be2434a0a8339e78fe61c2ad3186", - "0x24a11c3547f5fd5e5eabda12369f90b8f5c8ddb82568631b6e704c2ab5c94ec4", - "0xd6cc197005e41f553308ebed885a4df650a2022d0d40d25f37bfc74a94e5b04f", - "0xcac28ad9ef5e3f9b0d2184fb3427dad0838122a44538bb1e0ad15baf08ed7312", - "0x8070860a9337d8e6e016e0ba5953968bf410100bcfe5e567d7562e74b95b5d0d", - "0x8ab5cf8538537e591e95fb1dcb9522067ab5ac783bfd622e6c9bb131d3288ea0", - "0x345a12de03af922ae9e6651cdd4c4249f75bc2aef1f1651692dee6d27a490813", - "0xe9cbfb97fea7afed66cb3551d9b5f6ba697a4476a5dcb3ecf25bf9a41e54bd85", - "0x4028a3855c3b656c1de109e250412d9596cb6fc4aed22b8bfca6d2a60b1454c3", - "0x85591c0037f549f6d807c91b929fb0290c1b53f23e9305bbf4feed86d5483cf7", - "0xe3178cd8d8b7d9c71d9614744a937add2ae6c21f6eddf508fdec243c6408b647", - "0xcf40b5e2f93922022aaba8558b17b193c50f6440359826dc78b58e9b9e34074f", - "0xaa30846598de0f132d8c18084859e6c67189f9489a2b8019936a151e7d0812d5", - "0xb908ee8113c1e60abe60fcd0d7fedfef07ff0efa562673d0ab86f6399812a8cb", - "0x8f9d9102f709fc1b4308b677e515173a1db857b4989b1de2961b801aa8b39db2", - "0xd74e36d71447b437a4a4405dda388a9779347fe41152b7c5515e02edb567b5ae", - "0x5aca44d35187500d73b544e71ea8a12100cf011c219fd8b83e44b4792204edd8", - "0x7196cd91ee48f598c11527924c83431dec39ed7cd67a225b64a9d04ad23211b0", - "0x52584327a0b33be95ebc7040c0dd9b60d2bd0d42d1247b8d2ee06b0d6aae9f58", - "0xe2517f4a4218e9741b501cd6fdbc7e2080cc8827bea231d829d1717d24ce4e3c", - "0xc94771be6c7b5e858823a03e620670cc604cdba8092da13e429c76c2077eb2af", - "0x3f7f556817b418fccb808f7ede824ff17b119e7fb02ec1a4239a71835af5ac5b", - "0xd611cd2fcdea70eafce698fe405f361ca95b67d5631a9930d858f4a7cca46358", - "0x5f2aa6ad1fed0ce4db64bff6de7bfa68e060d357ddf20414fe5f10b4211bcf7c", - "0xe8b5d5fae7903602ab3699ff27f159367e2fbd8fbdb4f45e7b1628b563081940", - "0x31cef735663de763db98bbb0846d5a1127adf45ce41837aa77dd5e4008718711", - "0x58f0b43df5b6c2527dc3e22f2f76cdf7817e23d7c3b9a9732fb91e6da9a537bc", - "0xd13734d21521985e4c6c14bcdc34139efccf1f0a9ab92a72e0b9e639321dce70", - "0x99b982d744b14279defa1771bb358ab55f4f3730a8feed9e14023b39c44f2777", - "0x827078f5ddff2088e6d16039c439492140337ea661cb361fe87e0bb7fc785bc2", - "0xb1f7f5fcb807c343ebc587314a28ac008f849c24753383c3e40c9a12826c9f5c", - "0xd60f786c664eadca5ba1af303f8d8e88d781ec3611b9f781cffd5b17610c19b0", - "0xc514f1487e061262e2be76dd593300b8402df6812700c41a2611ff5aeeddfe45", - "0xac6350441c04277a76c019215cbec0fdab8f6e46087704ef0b75cad0356dfc32", - "0x724a5ff7c13fe6d21249b47f47082797b2470159b298ea281f9616d6b5c5269e", - "0x70dba710ff65ecb7c9fef28b366f5b175e12a63bd1f7530ec18da36027033497", - "0x014f4aad56ae3ececae45610e6d28475e588fd39897127d20675c1ce18479939", - "0xdeffd38ba5e4e685603ea1da27571d48830018be17755ef7c08db7f6dae63647", - "0x1e6e324967609029e28e768443d11cd5d99ca713a88c9ff47144d0b16b9cefc1", - "0xb2a2a5d5583ba070ab2b8adc6f5eca48b621b5244433a5e491784ccdac2e64c8", - "0xdbb937edd70b36b566e397fa369a5a3a0b45e606ed012277c64234eff00f2157", - "0xf043662cdf2a84618401c619fd8aea26a54519add9f72e43a520fc8129c02000", - "0x9b84dae2d1a0d7e23073c558e13e16ddf3a28daab3569c89271e0f780f134be2", - "0x93c7258e9e78238eec47497c842a643b339ef9ce4f236ac2c0541872a427a1be", - "0x8a8fea29216df1683fedc14a7a066226f9299d1be50021d3d2aa4c0585b29f47", - "0x85bde8bc039cd1820bc1b1262545bbefc07b03de47090008becd1417ad3b997c", - "0xa7758356e4555d213a19f5c343de9cbb986509aade6d8237baf1fc6e07084b9c", - "0x546bb118d2a1176ffc967f90bc342edbab4350f28294ad6aa29eec2b0c9159ef", - "0xcb50bf5a5a25b95962b6caf51b5e23fe60f6449f69b4df5d6b6d7fda2463d5bc", - "0x1730541314d8595b13f01281189321299fc3d2e9d0b9aa354099d6d83538570a", - "0x5b57218719bb9816f4341ee1938263fe92cb95e798193cc2b24fdc3836abac02", - "0xe0860d86c780d3bd7375ef6a0d75eaced9fbd90283f8ca8335205ac3d3a3dbfc", - "0xcd65eab452ceadb388b945eab3342dee7542c76bc912dd738e86bfeea1588f96", - "0xc15efc0c25c4c019937ad27026225024ee6992780b9ba02d3c70101a73b354a1", - "0x30e8665a5ac3f3eb1b9c2e67d61dc2dce761e4123ed801c1a6f207aa3828804f", - "0x6c3b5d4f836b7d349a089280c1f4488de60461c7c1a7a5fb3ddcc69c1366195a", - "0xdca4d348f2b9806cef16e320e0b21a539769746679c1a45a6145f2298db496df", - "0xe8fcbceae567fde12d871fe54233ece0d74ba8508fbfbafac0f154806a9462aa", - "0xd79328e9ca262b6a91652efb67dac1fa5e8c3282dbcda58d4b93b8874d226966", - "0xe0fd3af4b67510c68e8968a5e25e741e1ef71c9347e18b8de6139f918a62f6c4", - "0x70731ec895bdb4914a76b97ddda78a8805a39a56987aefe32556b93e2c085d97", - "0xb387f307e22829ce20c5d7906037a5bc202950197bdd75ba59999c2a09778864", - "0xde1ec63948e3c4aaa005630545cf73bf9d20722a1c35b8176cf44d80f4cb7f0f", - "0xf9156bb506ad9a12b3b2357450c443572a3e3399e97f68cc0166ea22155c9277", - "0x3d5c1ac62e043661edf67446ac9f96b1c887d07ebcffc2faeb317b5c3ab596e8", - "0x70e9f96a6d21fa71ec310b99db848e5dde82ac9410ce8c6d24af115421527223", - "0x366fa3d63bfdfd2fc10ce44522f36ca6b8f815629bd36a26c0a5fcd6f95fc5f1", - "0x34b6b13187d684972edbc097949de7ed4f7ad2658f9889e1798e955845f0de36", - "0x1ebf9da97a23393f6dc5cda5c54718f273eda8ac6d1977981a0e1570863d9833", - "0xcf8888cc905df1ee1127f59c8ea7f9243c4688daba7890908949b027f4af92e1", - "0xea4ba26d5fdff1daaa42625fd88aabf7f91cd400829268b9beee5fc09875c630", - "0x639faea36eb1a652b024df696454c856be53c3667e88c7af5299c050c1092bf2", - "0x1e67283656def3ee933332600071fde44127ea3caa9c42f992ed16e33d1122c3", - "0xa4f53ce6159cae14ebc60a69e9c446a2abdb4f4f5cded75b1c5814a84c487528", - "0xf2840725ecbeb6e7396551fe034d21e75a5d34b4cbf8b3b18dc5ffa06a3e2d85", - "0xed7396b51a1b0d93b2288a4bf60ad49d236bc14b0cfeb40dbbdb6e9682d3fcff", - "0x9de490ca8067c84f922547ab496e57b3e1fc4685b744de22f1cac7dff687b930", - "0x3c3f7c57fa9ef833accca168540766407bbdd2c418f13adac42838f205199462", - "0x14257d1a35fa99b3cdab74c8445bed9bbfd25d1604e1b9123fb5c5bf88cb3a29", - "0xac74953d33cdefa9037a415336672144c53310ff50f75d865272ead5e0460799", - "0xa94b857f4dab303c1d4a5213c7bb8b91a441ee8279e69fa92057718f3aa40a4a", - "0xe7c67bb2e440f1062f95e28f0924d0b29bd789103521cc13d13a95673cc49179", - "0xe90ea613252541d3c5237a27d4d23780b579cfda48c057b7304ac14751166031", - "0xd85a4fd06114870b3fe19cba9924405de1e14e026372e84b24b4ab39e7879545", - "0x7d65651c6e789a3b6113f589f696ac6595f279bddba74a17e955ae6ff93a1846", - "0x5e44df731c9b0905ccc33ed49669b78834d065fe3fedcbd0fbb7df95f706c51c", - "0xc90d3dc4bff702b9f17930d27b039bfcb1b7879076bd82a5650177252a526dd0", - "0xb5d0f4ea7136a5f10e47f6a802b46ba0c7dbcd4ee10b4be65ccd55fd4c940bdf", - "0x4f7647e2529b477aded041ed2f4c8e01d5219839950aca43723993c2432105de", - "0xddf89de514a09c21918af718834060348ad0bfd3b86e0953c247834634eb841b", - "0x325b15b05b3c863822647b25ddb970cf9cb52ecd32cf58e6c5e8cecb1beb9c89", - "0x3cae2ef569b1e74770ed80bc31da2addeeadd59d8605eac8edf3dad0fa9b0c37", - "0xd7409a715ae5f091fad14187121bad8263caa2f60ea0d0bd7c524065defb564b", - "0x5cefbb199b507e3b64008e5d639cac8f623e9ace1292fca190bed4b7aa214899", - "0x2c2919f07eecf553b473f98d06171449838bb03c0a468d8a7cfd8062a574df1a", - "0x5c122d8416b78e0e7328881efaa7fcf61be6851a5b7572ec5c341693fcb9c734", - "0xbb81898e64769f0a6f1c20a2472a5128e969f737d1cba5be885372453ec18d1d", - "0xbe203e6f7c0c86ba994fde55d0daae0f066814938debc3b5a44884dda70e3ac3", - "0x73c7842f2480e3d742aed1a1b7682ca1f322d4d2555cb7fa402313024c2a13f9", - "0x5b95cde26a2c2be298a03252ce36514dfd3c9e84f5c5ffb75a050bb5752b6247", - "0x9c7cfa9294869c1c42db3cab3bfb737696b8f81500742bfeeaf29145e2b5c79c", - "0x6cffe595d85a32ad1656c81c87d476e6e7f602609fac052a0a3e3a951d11eafc", - "0xe2ab30bf8127106a4507034cf6b3589ea3dd19bb10c765434fd3f3f7d75c1a4f", - "0x01d7bfcc2d4c6fccf5e0599f9985af838cdc0281c9c8cdd7006b3b0abc775cbe", - "0x004114dfe63995fd66e6932c62cd7b3f40108e5e2f6916d19dc436cf016392d5", - "0x068c036ea74e85ae8d8897589a8dc775c8516e38bd619ed584ffd51021393fbf", - "0x682f4444c85c46d28f5858a91874e0c903e97def4e2a4302ca90ab69b54b4f49", - "0x3fda79ec159c2878e9ce65c575157daaa9561f17a14a0003d95c0c4264985707", - "0xb41874256b5cd3ef80af1536a45a8016cbade06b4a06b1dc0942c27124d934b2", - "0x0eac150f30020a7651a006324da1ae240d4fe623f077c061a954122b0e17b0a9", - "0x0b174907572651a2453a14e0326e7ba836781dbd939c2d75db84d9b481391824", - "0x082beb1974f7201be32469b9df42d9c30a520f4dfa696fcd991ef20367cb6eb3", - "0xf3c3ebe6040e1ce5c5ad1f6e08965ef387adb6633581ce3fdd1858f1da4547c9", - "0x6ba341211e75ea7346853a3f63ad5502f83aeefeac98a479aae546a70141af99", - "0x3962cc5bb73ab7f48d98bf65f3f7f41a8f3c52b4d7d2f12a0a89cd876f875bcf", - "0x5b49809641f72f5c96bba6b27e0331ce7fc7dd3ef18a4463c93d1f685b7a29b9", - "0xd2b2e8eec102c4b68d94d8bacf71755386bc3008d15d6090772a4739eb763300", - "0x704bf1701cee4f631f4de0e330873b1621490faad46203fab288cbd0892da567", - "0x2f7d29943c2b3ed9f59a66ad175d298f1e4761218e3fc52b9a67b4ca7107e93e", - "0x2b370002b007d4df272104b77c1224c24eae67de3e12aa599968b190e8d58c19", - "0x1f25435148cd815f4549de1f21ec227d42f360d207aa2f7de5466c4d28afdd0f", - "0x86d745be32470f409b5d77f92f2412aee084fc523a7ff7e57b53f39b11cba2b6", - "0x86d57512687518e3db56834f819bed57ca4f2e3845ef6affb15f29d1e166c333", - "0x9ec0e54aa6361293f68c14b7ee9dd32abc52d9649522b0d62637ac25d3a978f5", - "0xc2dcddcdd616160a196f1336e9f11c7685c5eaa4d3f5ca7c35d7eb14199d21c4", - "0x03a14db3cd22bffc91ce24e510421d60431db71bd68b8b040c89f85f7664967f", - "0x3cfa17c8017ee8692c5f440e6ff825b2bbfbf18d01466234bf69ec85c3c793e4", - "0xeb12362e925a0b082268e0e006165720dfa72ec2628dcddb6cbee4a4a0ab7bcd", - "0xb8c68067329a16ccc14fa3a5bb373d8281c79a20e1a15f74dab053efb881d13b", - "0x282be7cff399ee51b3b8ba7d9ce73daf0427cb11151b9a81ee0f6efd837c6f6a", - "0x357989e62c038a11c75120f990adee58fcba6e7fd49cde265296b2ee0c7f6db4", - "0x3ca8e01da313e17c3a089b8b99ee118d10140a497aca58d62c25452f1361f0c0", - "0x9778186733b0e642156d6af17ffd8161608a2ad791cef0dc5d6f31e5ed4ccee1", - "0xc309f7651776d4510a9696c89aa82e8720ebb2c41c208e7ba8ccdf1d26dcfea6", - "0xbe30023b89befe4495b15daf4578f415e8cf25087428bb25b1af06b43b04b114", - "0xe7246483ab7e0afa2a6ebe69819744cbdbc588a5294c1c59cf04232782d89c1f", - "0x54e18aa712987567ad36173ccaf070b127277ad6e9db2bfd1831b7868f56c660", - "0xe5c6a4c0f07bcf3dab39def282e3af9f7dce84a7b2bc71c9bc3bcaf35bc6bdea", - "0x5d78d891bdbb232e7d90370b5108ee03ceb0c5abbd5bc1c49c53431a94fa2309", - "0x91f3efceb05e5c6114ce0fa2477d8e2a6d9979ab1d3cef4d964d7d804399ac50", - "0x29830ce8ede37d875e7203bfca97b104b002aa474fa9aa9fccc11b2baf665f83", - "0x93a0646400cf92d5e7490638b12408ee9fd7696f15005287d23238ee5fdba9bd", - "0x47273e8e24cd886a25e278d327bc0b07e4c3a6b27634fc17705f46a019ec042e", - "0x3469aeb8bb2312fba8a530a002d75b75bce0a4b0e7f48d3e92d595dbec818594", - "0xfa8abfdb2535d9f04933e924e967d97c248b62900ee645fc991a47d5ecde87d0", - "0xe9fc29b24fa7b2a6cff23170d96faa84aba582f68792dba4962e7fb53922c568", - "0x506d80c18b5cd845e0277be32d0553130549a976f781c315c674545b1087516e", - "0x676bec126c59b4f69ddb2ac8141d9e90b78a2aa1b5e55e6458cd479fc7f98a10", - "0x4a99d2f7be333ced3b6faa2aaf15f792e00717da5cf15ba2e9b5b7dc02bb1bc9", - "0x776f5be74f05d1200273ea3c9b1919637fc911c76d1a9c3e1e3accbb9ffe6e37", - "0x09b9f219a053c0c3c56581e32ac15fc6bfb4fe69208a5291dd4860cfee263d19", - "0x65c9e06136563c4648b76cb1e7c5d46bb7501773825a10c610f2b63bfd5ddbdc", - "0x2e31a4c4d6670c2155b3ba877cbc6f086c18059b2903ebfcf2cbeb6f73e67bd9", - "0xdeeccdd2dbb206be5fe2bd4e122d6cfa556d00ca0021384138dd914fa3aa2413", - "0x0c24527744343d79639a382412ad22e5ef2e610151e1a19f09f725dfce287ed4", - "0x4fdcebad349c83d27457ec443a5103b375f26b6da958227ff00916cb900643b0", - "0x4b06063a48575a6f89ae7fb8deeb316c30e6ecd080898c47f24d9e7d4f6db960", - "0x463b0fa1bb74f1473673a2760a7e447def169426f9f7cb57ae4c6d417f58d829", - "0x01050ce1aeb140cc812f24c6629f9a171ddf4891b9150b43312fb052ecb29de1", - "0xa9e4bffd5ca3834b5a80dd84bad6ba4dd71138f02cd386668aa8b73f437f3e0d", - "0x379e501e6acdd0f94195bc851c50e7674e103ce8563bc61d7b0e6ccdadc18def", - "0x8d93115aaaa77767f70287e025a445cf6a4c7f455a67615f38c42e827c95912b", - "0xde2d4d8337849ad10a32b1731a0c281eedad191a09b26764568e7cd9769200df", - "0x575de523f7dde0e52b68c15646d22a31e245a037d1218edf86e295fba9b201bc", - "0xa545dd5a5e5dca568a5a28bd387417bf3743e184189106670b03b423b9e5bb08", - "0x044d13ecdf9cd6989d3e5a1d8354d4f5a7d29439a5da0c57505496fee7b6d054", - "0x4d99efa30d95ba2f0002565ccdc0ade2bc3f21d3153c638fe8ad9977f1da8360", - "0xc72982c95de4754f8b0ac62113a71af4c760c3c63f18d230f1fdbbe3c0b379c9", - "0x7a2dc8e509b0901646afbc1a6f9b5b27ff69f2fdaf4377ba027be555acd128ea", - "0xa3656ace4d66ddbf55477ce61954f2e1f165f570b5c7d028d1653e9f879cd080", - "0x47e4e4bbbc704f65e3979494487b0dd51cc56a928f26f97d6e29d76db80ac14c", - "0x5cec964b6d806da75f96c67c1db66d7c539593c476c69a2207be25934443c82f", - "0x685e812268ffe51415ef5e540bd4d2d65c2f34977ffbd54be14c895e4f004abe", - "0x991b2344ae224901f5ef89be9ed8313ad2c217e3727ed8d24f3a35fb71df3982", - "0x1293f5ce59c36d3189ac40e05bd8c0fb4b69008d8d457b224df1ef1e0285b553", - "0x3d41f27e644e2f7de5173dfe7004e32d6dbc8cb56871f578c3b2b943210a4c47", - "0x2decc2a4e91de0ae9a5584cfb03f6a7a4e0a867e397dc74df8f185bf241cbd96", - "0x0aab7f05bcd3b3633184b45c81dffd70b3f1b1b23f28d46747ecaf54fde443b4", - "0x8bbf3aa92fb9ebba36c5a2756dd394adf505cb753f8d3809393e1d967f78e075", - "0x13544a2979e57f73bebdc7cd1b2a1c9cf8911b8f24868aa1e775c8c53d0e2572", - "0xa7497c9f04590c706fe0a3909bd4af5bccc7ac31d7162b2b856d3a36bccfcef8", - "0xb80de8392864c859aa8e9ca078c258a6992bd848de129350ba29548db6aa4afb", - "0xf334d02277f55288c189e6ce79942ced25ffb9ea7bd5aa5ae562a985eca6e57c", - "0x83a563681180ecc7a1fbc6e47e0ba03f5004a87167fdd451d559a573df30533e", - "0xa648f1462985ba8ff73c7aa4d19153843e6a9a454d976533b08f7a14d2fa8902", - "0xede4ba72831451bfc8651419aedc62e221bd8acfd8d4ebe426d5b84d862d3b71", - "0x2ab8f2dc9b620b637aa27f9303068abfba56bb3438905d29c9a6faba4ad014c2", - "0x225e5b7232c6edb127a71ea313501e49dd86f4df0a037b9c97dd5fffa8c08cd7", - "0x85606456efed98380428d075ac4791140c9595b83707a397b274805c8fdac4ba", - "0xe298a5939a283d03311d1a19f83805f63c83efd2d7affa7586be8868284be900", - "0xfedc0db97df763328cd9a8c8bf1de73c420ca33dc3391acd6e4e847eda793d7f", - "0xbefdc3c7e7ad41deb07ec2821d0b84893440f797fb1603863e274368008b8e74", - "0xba3b21ae193db8215fa341504fc5ca46b58df994c473340bbee3f3fe90d72497", - "0xc45fc6625b0f784ae2039747aa93495b05243c00dc5c2bf46dc372c62beccf4d", - "0x32d182e51018fd1e19b576670ec68d59810c4bbfd406e2bd162e1f17a0555f67", - "0xa8886b1a9d7bba27219fe7f563ac0b592b82a1411392ea71a4a5bb288a98d6a8", - "0x396bac50aadd2dfc853c144091324a12ab8661590fbc738d3cab77910aa2d2a2", - "0x50e35af52bf6eac228c5fbf6fe5dec85989b76f44811099f2e8f4950e4ab86e2", - "0x9ba2aebd73945b6dcb9f5171155c0fff29db8cf40baf83b1689a7ad1004912f4", - "0xfb1cb1ff78859e3d5f0db0656821e12b8d247ab3896e6670426dce2055f1ff8b", - "0x230a6f6567f066e76413b72e7650f7cba9315090abc1bc7f93b861d85aaf0c68", - "0x4dbcac91377ca858927a01f5a5e8659b4e718ceca20d4962c43fc1688c4d7574", - "0xb13061dfac0e8f22dba518fd46ea95024cb97ef825c970cd5e452ccb3d7fc6df", - "0xc5af27a85235fd0e1da29b5afe6955d72fc2245c5709a0f29bebcc7c49eb4a0f", - "0x7937707d20bed2c7b68dcae39ebcd93b84bca9f471250e20f86f8ba58bb10fcd", - "0xe1398b71406488244a0c205db9c793be090349bafd87fb147c1aafb9d7d7deaf", - "0xb383706e1aaf7149b1ac3d258f6628e8e6d40be0dc096647b4bb82a08585b707", - "0x2c07639c073fd57cd719e5c67371e5c8db30f34855ffe0d985070b4b36e27cdd", - "0x7b264ea13f78fdba57d1097be39b6b2dbc614ae36cfea1f99d44b9966b3db035", - "0x04d942f60d32a80d93d12fb7c8ef95439e0da5c8358df2c01e7547596461ad79", - "0x71c93b0ec1e403906ce7e5a38d168b72b14cbb7cd0e832c2a7e73f485c7d6567", - "0xf7060c7f697a68824bbc178e02dcd6b12ca204da9bbf2a17b69ca858e2ea9574", - "0xb3b616f183145bbc77d8e3610504189e00c0aac3e15975e4e01f1b2b25c5b5b8", - "0x137f77c2fa4e911b6915c5a84588bfe78bf54ce39d09ab07e495da9283966d19", - "0x5949274e5465952855c28d70a4089644200927b54faa67d5aebbc4eb2b891aa8", - "0x1c695bcec5602b15de8099c550a3b738aba98acc46377cff7a5e58bd7f402ce1", - "0x8d1ffe39767f285d7f164018cf2fa4ec6509194c086c33af7ec8132e3572fc9a", - "0x31331d50f79ace5444f242b279be905e076d675fe4d4e1d32de728e2654a08a3", - "0xce9c3e8fb9a75e284c81925c6ef742c4f34e6f0bef11578a61be5325692a3a60", - "0xa4cac76b0729c42927d1ffb0c870983830ea66636e9abc6138b943301c59b96e", - "0xbcc505e608198cc3546899012cb59a3da60839c9060d2952f8ecc178be4bfd82", - "0x1b5ab87cc34a38f4be26c5e3e05903538e8e3af350f6e2e1258b0cf344ad9f39", - "0x85849c1cadc5d3bb555b88b1e5720110a1d4f7b79f634427a1f8d7e88c2e043c", - "0xee63ee939a6dbc6678415a1af9969526083bbb754a8c55e97cdefbd2f02900dd", - "0x50c63ebc1248164b057854b8ab8bdee0510a97f75e864e1d83feaf59541a64bd", - "0x58daea24885faf1556b3111c06351fa506b40b9f1ed365633a2246165abf3819", - "0x0357ff6bf4ef1b1bab206c3c3efe770c6493cd85d0540fa29492428d0a878c6d", - "0x52963cc6bf51a64c1f8ccc21c520ed95d5ecd0e43a86b85defd7b0113082e9d5", - "0x5cb8353b62e27e59824ee43a4bbdd384a2af41b52f9ea5444a1a180482ae7856", - "0x2815152239935641536e549578cd0d33c74a377ba350a36ef04b038e5fc49142", - "0xe6df1f1b9949e17e0a683b6fb7ec9ede2b49ca3d479202226ab4180445f86d51", - "0x3af2498e3ae79447c4b6b3f025a37c790622e2979462dee5913fda778882e5dd", - "0xd498a21e50c930d1f0fe0afa65c6f977ab8da037175f34f4478e52f4c1631d01", - "0x12478043148cd0413f56918565cc2fb0fb9802dab776f0a055093ee8ac131da3", - "0x9acd35608a37ac8e309e884b88609957ed24ffcb5816477788e08a874e6c5a61", - "0x53ecc517c7158fb6e99863c54795107258b61399279ecf74f443d49533a104b5", - "0xc74f9359d1b15de475fdeb56497a5745a93c741e5f2c370656b2e7c269c06511", - "0x8afdda4ce115a19309597eee883cfd257182db46070c7cb1f24955d9c872c8f7", - "0xc4036bef9a9e692ebe72c946161b3ce5c588f4421b7d6555b5d65f3311a5b0fb", - "0x4b64a608ae22b5a655cba7ef78624eb69f9f8e2b2f7aad8c04cc6ee95386e9ec", - "0x4b5506aa505815e519b5008fa8d23488b642a1f347f6cdbf53975636a677a6df", - "0xc251b21563070f1b3895bb4512bdac4395440217c5ce01fd85e89399dad72b53", - "0x07a7bc11d48537654d24eddee78d35e4510f22b755f1f36c3b81e98087a1ce68", - "0x66a0e9bf542363d8660cf7817ccfa3f4262e4817fba45d2871d0154b6fa7e969", - "0xb2493d6e033e1c29f62a409342beb82f692e565638736fd088d80acf7666b9ca", - "0x4c55f2a4ceb60544682cded4ae8b23bf217ce7d87ae90abeba156d9b1005f397", - "0x32b3cd5438edac8902527ac353356e99effb1dde5209fbe1015673778f7c5685", - "0x4066c6ad2c7170b434bbf3e7ca0fd678803351c3dcf1c56e84bd6c14ac2f7712", - "0xe74fa1fa353cfe643ad94f6a609726fd3c4b06f9dd7503431f84b13bfd87b06a", - "0xc46c3e5bc3c3cbc604513909999f1523d704578cf5f025a33f1a5273ff6cb81b", - "0x261b489751092cbd70d6d3010b5c5dd68c9041063c3f998b742e81060107e17e", - "0x37992c7e208c0b09309ece681e02e957f6310c6f42401702b31f752646fe738b", - "0x2b09e6bae0a34cc6c8c83e97c3369bc847ef6410551494af91a3a39929e7d949", - "0xebc85167d3a2fb3ecdc5b07d78b6ba3a0d8294901f75d687087449ed78b305a1", - "0x8fc0dda2085f4e515491cf0d5a525f10d50c58a0a86a58954b07264425bf1e16", - "0x5acaad0dd003649ef9705e73232b4f9598c3fa14cbfafa1691d0f987639b914d", - "0x41cb16b9f5120095aacbde94f52b635a1ea9f347af8f4092660e84a1b87f8535", - "0xa5f2fb17e7fb322069fe66bf093b99f54ffd9949fa4cc983d2266013d2dac2ec", - "0x014582ecf0cc003d21b02662531b8c0422d499d8b74069533ee24b9774c1b7ff", - "0xda9554b8c2b3fde14390f91282a91a9eded5473cf58dd2f5a6e6168cb4d24d3e", - "0x55fb7a99e9e6e3d9fafd8c9f65dbfe821598f2b5a63435204c063cb4477b1d2e", - "0xe54e3c51b6eea19c23875beccb7e18094e4db26f3c94431df1dec26e6db98773", - "0xa7c04b495735a1a829c64f06b94c486c0880a7c54461defb31a420fe0104e1fd", - "0xc7299bcf0202163a946ddd5d8ceaa209a1d81e28a27e5f8fc660c00505df769c", - "0x2526f9fcfb45966a26370e08b26cbe29fd5aeb568b0f945399a6ace1778ebb57", - "0x59b3d302dbf5e3919550c0c1b75bf111d513f2d0d948ca8cab6c44fc38459b3a", - "0xa73fc3b85209e722b88374b2ef3fa3df240ef81c9f9e0d4e7e422ddd124a5ae5", - "0x0dfe2812db18ec7836f8d2227e35263eb98fd2046f597c203f2b499b538a308b", - "0x1f7c6caf872ae90f4cbd92c7adc49ee2ddce61baaff37186111ba7d5347bb4bf", - "0xd67aa89ad3f03b9d801d3f1cb1ef58a5d9f6b8e4cd9d6fe9b862b697f60951d5", - "0x9d760e7ea703028be2d197a0ce28d4057bd8fd7638781e9846cf5d5886ef6611", - "0xe9bfd8ff1dfb81f4f5e5c3a3f821384f98d7c6b753ad356952fd10527e08ced6", - "0x95b6333df70dee92ff0d880239c2ec7a4016c6192391c08e797fe24e06bfcd0a", - "0x56651120494e23767700b82c6718a9c1abe469da49c38937582d08220330cee2", - "0x70d3bae96dfe1a093bf9233d9f8f4c149fe4079c5f40087dd49c6e524cdd96d5", - "0xd29445a1ef099b0ce227c88efef59677abe47763149e034c3dc96d999b66cad1", - "0x7e2fc31ca7a02f965757f118797ae5093cc95a89fabac7e25a22193f2346ca57", - "0x3b7ceebb659eacad955fe0e95a6f141eb4f59f4fa70e52da5c85d7a9467b9298", - "0xdabfe5efdd2d7a44022fac35b13c8acc8c3c1d69ff360d45d997887feedffa93", - "0xc883f0d5c38f40861f9466fdc84170f7605e9af5ea4d6f9aa5088c6c9e482b7e", - "0xd5b14197d738e2635f7294eb8993b01db1ec02de38a545fae881a3f11f3917a6", - "0x5d2b9e3f7a490660bc2592cdd4e04fc9f5e32de1de4c9a8c223b177627708bf6", - "0x2e94c911c88a1cd80e94acfc9f27bb5675a6ca79dab6f70f38a4df99f84f7bbe", - "0x23fbe80ce230e0cbf881279ff259642d6ddb579f0711c5f66e93db3896ebd835", - "0xf1eab3ddc0e2c231cc78d123e20f4195808a88f79c21b9ec2149e3ffb9b1d5cc", - "0x5156b02d5fb9cc38a14e3b4cef86fd99d01db773f681404889e6f7b76a6b2d51", - "0x4bef16dfae5442b8d2451abc13f610acb565fde8400ab2ce52c44f54f68308ad", - "0xa726272620270e5649309798d90fc52ab80b779fa03fe639fc8ef14256d5b1ee", - "0x7f327dd9c23774439a2c080274d3111e0487e1e9c848a9e11c14b2e5a9b307ed", - "0x711fde0a0f1474e0ababf802d8cc8da401d1bc4f836868f117f8ad3756179296", - "0xedb4b7af3699fa441ab53a6afaf380b5760fb86c6b5a0f2d73075fd9da23c8ae", - "0xd7062907f805b2b54e9573104b7248cda283ff1af3d86b7d77b4f9a94d420200", - "0x540b2ade8a4d3571094a14e7e337cb4ff66a86e3cc9fa5da85e93c21edfb69bc", - "0x3c06c59332db001ac1cc72e9b07adfe31155df74c920d7a897592fba0d265a48", - "0xe24179dbc1457c23d05b307e0b42c1ab276db666e49b48cd3e1b3dc82e285de3", - "0x70675363d1a4a6db8b803e3876b171c4ad70b25a56790ac7e4cf011ded4c9c9d", - "0x80dc30723f933aee8e126815fbc226186c07d724cb13c60bdd55cb470f159c4c", - "0x9be135832d600074ed784053d80ad3fdefde87db55088a545a1f8403429d86f0", - "0xac742c9ddd3e59c3467473ede8a794a8b5d1c8299a471c7510cca0b11259ffec", - "0x3089d8ef215e1cf33020d6f2dd005c96d9e7c8bacd2e272c788b79e3fe016caf", - "0x7b22b3b82634041abaa917ce6ac8738e1ad5ada1038bd1a583c84f2765640e0b", - "0x5812d6270239d7566288bdf58df80a2f692731062d3a0aca56d3df972616b553", - "0x0cbac8f96a15a1f57b3ea657e5888598f7350466f40fd46735f7a8229ae7c528", - "0xac6d9f1c216f28da4b97cf2f78f4a7d6ab38636e57fd9a4db71bff191a8007e4", - "0x8dace71e1c1a12a57dbb4794cc92d3e6641201ee75a8304b28b670719cd9a179", - "0x03d497bdc46d7189b30bdcea32a7d93ae17aba1851da4b5b7baa241f0348649c", - "0x9b2316358a104fd1a93cbc388c1419b1db9043aff711d20510f012bd135a1309", - "0x88d613d910c664cee5d50fe1733340853900df4000225698ce32816f457c30b6", - "0xcd9d22a2cb07552bf921cddcb89d879e49ac840a5cbca91da3324427d7d2b80d", - "0xe7d213479605f340cf3714234eeebbcdb63805c5e9479dc56d4a4b2733997bfa", - "0xd899fb4bf3a918a9cfd46d23152fb1d5e54f97b86bf270ffe28e6e55e924e391", - "0x14a971dc6aed1e7dfd4dc3ba613548b8966495628182ce99c4fde9124ccd04af", - "0x89800cc5cfd0ecfb45bbd253dad288617123b3690098e41b38c0d51cfc10234c", - "0xedfe6f669b7b9dce540683400260000ee191c3481577aac6efc163afd7af6154", - "0x70b50725e51c7a5fd4818be7286bd1cc9b15ec2ed4ab6c1bf7e7203c4fa8f25e", - "0x22d02fe95c6f959f72ef4c96329dfb31be8ddce701e0c3ecfc8398119bedf656", - "0xd7877a10f7f883975c5498cfcb07f044400a09d906cb94c8cd29f7a4b93e4b5d", - "0x2e47d9590efa111e19419df7cec6b157f4e06dbea4e64108b7101017bd0cbec0", - "0xbbaf38881063dfcece265083468830bebdbdbb833a57bd7844044ea0c57d1e44", - "0x9269c959dfb4540e3d6c815aa0135b945acb7f50b38fff49f6e34425477ef553", - "0xab47e57f72ee8c8d8857247f84d3419edf43fdf6470c9ab070d8733cd8ad617a", - "0x2be450e3b77d2d3377218412be18390e984fefa2df07d02edc07ebb2d64a9312", - "0x6cc64bc8709eb51b5321b25453e77f871f364a8b277ffe51afde4b8c7a181338", - "0xda70fdeebaa9502e8d0af2350824ee0807e31cdd55ce4195f32a639f47f399cc", - "0x2dac4b30d219640aa01a2d7c69528c8d31636711c915827a64a9219524f2885d", - "0x50932f0dbacb5af5785065dae19245148270f1d0d3515b8d7e191c5702047b6a", - "0xd919cd9f3f6bf7ff66340bab7c562bf53eb969b3e00fc950d1d3b0d9d815e351", - "0x76a276f09fc452ac94cac15d5226ccf3110080d2bdbcb01e8ad86597a03f21bf", - "0x83bd36f26e7d087ca641848f5bda2313903ca64f8b61cdac127ec56efbfc6ccb", - "0x6a65903a006c6759aba3191ce06fd45b0702f127d822d9c889df12b2d52c7bdd", - "0x8e440f04254f81737b00d3857d1a95bf8709f1475bc0ed15d7347c94e57cc7df", - "0x20929894b05fe04fe12b11d336bbdf33ef983eaf6c501846d48813a97ee4b5f3", - "0xfc727f2888aa9f47d486f93b266c6d09b09b949821b63bf86aaea830c16388f4", - "0xb9035314e27d890b6362db7cbb0953e953b57163be0d80e5ed36759500f3160a", - "0x6d2ba56b3c06326a0fae498467f439b47bce1174862817b5c703019e8d448c4a", - "0x6b92e2415eb7349014bdc3e705a2170a5cc09796930d94e861868f77c45d5802", - "0x83a57de8623aa9742b33b3c8b3737bfb198f738111e437d9bab12baa0660cecb", - "0x979d381266e5105773f922d3172dd020a6010b9e435f3bad16ce6065b537f384", - "0x3fdaa18e7a2ab12c5705b17ae33e96d8df9ab3be631bb9c46d31052ad423a4be", - "0x439e461837340e67edf1c7b7fcf633d5c3d8636174335dd80023dfd61f66c67e", - "0x3ba40c7198d6c75a1ecd79218edb9608b7cecae9f779b37d26873d040d29b308", - "0x66ca7e3c8f892bea4be87afee3db3c9352641139ea4b8d459417180c2df8ac5f", - "0xd55c6d521f3a145379a1daeadfede8f837928315c9c2f1c2642ed0e1a7e87674", - "0xb848560abba9f0e19af44219c2c1a5011ca43eff4ff6471555b3c1c235c40119", - "0x1fa19a85d008e7af8585eb7cbbcc8d61ed6248708429d0f458f1b497ebb190a6", - "0x72a4e2f8b7fe422eeec318f1127b4b4e4fb03e40a028d45f5444c9b287a4a764", - "0xed88ca02a5918d6f621fa1e945bb1533e33ea5c1d41f7915672e3c4e4dce78de", - "0x60ef0df2f7f5c6de3dd7c02fb202c9b3a13f48102f317b54b25b2f0f1f49b6e1", - "0xc49153808e765883dd21e1b58b5725aa1d242f920ff0ffe0c6089a5e00719c82", - "0x0c8581a354376bbb53379f45c92e914e46676b68305e8fcf16eb069c65e87cd1", - "0xb562721b9433cb712b3969d193e132132786434bde1d45916bd7423194c84678", - "0x060cfe84bbb7842e0a49bcf9f8753635d9fcd694de3b8d5827239606269f0cd1", - "0x84306039a875a723780ec685c34474d35ac3431d6ac8d43b2b6d1bba8572eb9b", - "0xfeaec570403a0190c889e5d2ecf96a9a6c720b3944e4b703049c81a35b56d820", - "0xae002e7d8e1279513b037ad09695e93f80868c60d2d8b0ffe6efc8e0ca8a51fe", - "0x20e1f3248ebde32f2fca51a576abfd0db3fcfe359df399f1c3102ed2183b027c", - "0xdf77e0510d24818676727c9d56b58b2495ad63902cedb04e2f3729b58374c942", - "0xc33b4b53e7eac8725f5b3c27a9431dd6e4f966b1289e3b2a1e158474f4a47f4a", - "0x6466f3aecc922abbe6f995a3ede8ae650be7f1c08679c5f6355e32ae95a4412c", - "0x56322467df2291a50bea2baf66169caf34eddd525655cecf6d14fd2295b2a438", - "0xbd81e7bf5e30f4bc1b87c57a4eda09293cf6be979bd2bb02650ce5bcab8da996", - "0x3d611638ca06abfde10ce7f02152069aa30d97949dabe3dafe8980699d49ca0b", - "0x12723caf905e0c044344c83d085f3d89c2eaa695c9d70c0a831d487b050ed453", - "0x473f61c421d202e15d4a62d4513bd48313d253004feb09d9b6e0502c6ba276b1", - "0x9583746c372cd042a46ada64048ac44b30d3b055b6e22ca3cef5404e57a99f0d", - "0x8decffeda7b7de072da8268776c4b9969cbf3e7ae9433334aa7e1e7c93567f55", - "0x543f5b6b686035462d17ef969fa09e0af3e7cd24d13650c2d3597516e62f9909", - "0x5381b2412f6383d057bab3fefd23d08384f345960cc2fb80d7311a63be5080a0", - "0xd96b7933fd9308f7aac9fc42e8feb9f2f4b586400fdee23798cad69611320461", - "0x0982300c344d44c2f63e1c1fb5fffdb44c23749204a0e012733317cde6efaa83", - "0x6048706531d18c5f9a257448b2826fbcf7a72bd08d5d4feb2928acdaeee61768", - "0x2bb89086896edfbe79407ea2bc8535c6be143be6c64ddb1190e626e091c7e802", - "0xd1d6697db021746970393fc0151bef8aca67d202b0e54f4f2702a5f86c2fbe2c", - "0x5c1e1a43ba2578bf4a302e18f37bbc4f1a67441fe6a71ee856662739a5821db3", - "0x1ed663708c0709027c702ad5ce0eca6d3e0f22d6a01d4517adab0a3d25f5eb26", - "0x6ca247d5ec5ae33cbecf8fe88c1aa64745f7a8d299bfd356bacf764141d410be", - "0xfc020b5ae74507a1475ef8e2c0bb516b67bf79aaa2b61bdbc472ba2d75ef5db3", - "0x1ef0990b9051937ff1fa02880131aed9787e6d7d41a598ce7b5094eea1daea80", - "0x9e9e9a83fd6907dc5407c49ea34bd1745919d9ddced756433f374440fa8c704f", - "0xbb3687f8723712f39a8e9f8865543100e048acdcbe2045803ad5a40b61c4a36b", - "0xe60d8a60edc3d7e31ceb356e493a28fbc845f302ae2a8d1e7cb80f53112900b0", - "0x294039b994a3ff53cbba7718280dc827fd582ae789736a026eee1d39284b35e7", - "0xcf87c0d2ee79a0d2506a3d557880f3ee9a20ff51bb44c20caae0849a85055408", - "0x0d6bb688dcf3430e46de1512ebc9e411db3380590bc72dbaaabc52a5320216ad", - "0x9f2cd8a43695c78c7a8fb1352d581c82dd9dd0ff04e3485d5bbdd5e3942f9c4c", - "0xcb32930f407012e479eaa7b4844107167f519deea6c7fc0351cecb93c500d63e", - "0x17e759d815596e0b89a3dc4ba12b9d10ec59988fb0550e1518a8b1cc4f331190", - "0xfb3b36940c6675249451c4c857f6742bb0e1fd3eb126e370eb4deefe238d7d75", - "0x47d619d7d8a9510290dc0b8b2518af2862ff6f761ff09786dced91e39d8afeb7", - "0xe8f40bd7a7bb8f7dffbc63addf31a27e0a987a27c00525c833f6ea8f508537e5", - "0xca372409bc160e5eb7fa70e2bbfe8daac9763b374c7bdea0cadcc933450443e8", - "0x6e234961784273f80136dbdfe0f5618fce6c0d63c2fbbb5d7fd6823632c0ab6c", - "0x2a6cb327e669de9f9783300ef6b2cdba5585236e286ba94dca114de92728ebc7", - "0x0e91e6a11ea59f840d9bc47f251043e10159880276bf69beb075557e38715fbf", - "0xd452ed733b985db558b960ed14310215abce589d4149952a3ebfc7604082079b", - "0x7fc984fb9d191984b5141a9dc7ed1c9657742c63e7958c7652bd896bc6c9f985", - "0x2ce2f74343ae9e37153b5c071c4ba13adcf67676ed7789379c364107d76e32cf", - "0x0bb95a7856e5f61bbe47d56aae9d7f42b994fc4640b50ae80200ed8a678dfd51", - "0x2ab80f2546564ff01e812a39341ae227b69ccc1b38c7f28e61c31925cf622811", - "0x1b24ab582f306305400947e9e7e43a49de6cfd62819517a8ddd904972bd8eee7", - "0x852b65355f93035fdf4358ffc3566d57dd97c9d59a1e545706bc6a13690025a6", - "0x6a44f88a6097b5e3c822abcf1823c98362b26b0bf3753b6fafaafabe9591a07a", - "0x4e7c0a92561e904eed52f2a2b906293411b97795bb194d9c92e335cf9e4ab200", - "0x6ac01d96e58002f8881cea4e177ec7606c69e21d252d863787e5cca65a839792", - "0x4d95bfeb96b7a7978c890842544e8e780f531512c182cf22a73a71b55f1679db", - "0x84de4313a7d87fd748e9872db1164ad3ff9d48993ba429b74dad497dcda5a3b1", - "0xb5ba8e71bc844413cc3eee7325a949af1e0ea81405a3371512fddbef87e4e9f8", - "0x2378cad3d3f0558c0df47cd179791604af7df805f805f7d1ec67b52b2c330d6a", - "0x260d00d98b976fe3aaed233aa9e1b8fddec1092595c91336a5b884fc07e51a30", - "0x7e3e9859270e3a7bb7c5f6d7170e98a8a0a681216e21567c303fbc9e755a4739", - "0xf9aa5450b6036bc61ea2113fb163997ede1bb212f343ae5df0b55561ff32797b", - "0x465cbec75cc303fed26bed3e2701372f9bfefabfcd54096a9189d73994e7aa17", - "0xa86195c2696fa647cd5971d47587212d48957f3faf69721683c158a1372eccfb", - "0xdd104c0ccaebf94bc3c0a6abae1852a71f9b1eee974d5e622f5386ffe0949b7e", - "0x005f5108714efe19e512aa83608e9cac46976b0afcc7a010bfd682965af39d43", - "0x60289c653af2f12a58b10c0f81ed6072b3112eb270b350facd79d0363be2bc8f", - "0x8e22bcefff3aea2767ad9b118be1253d1aedf1e1da502a4855f6ae7eee54c335", - "0x3ec7f166314a0c594eb8138b75a050082884556f7664702333c096bc93b67820", - "0x605398473b453589bc31312579ef3b5ce0b74e3ccb95b680f8beb30d2fba34f6", - "0x51dfca1880e15660901b5f755530c3fa4d652050c134a769b6ab2e1645755cc5", - "0xb24e9463fccdeb2178e520fec46eaa8f2d1da5380d48815a2fe1816f71b79b8d", - "0x97bd624937de7bb8915d7e396c31cdb4afb739bfd4eb6d96f8773ddd0e4f4933", - "0xbe17101284e09bcaa9eb5cd150983b05248b620465244b603b598bbaf9bf312d", - "0xd3c2ce415ee6bc3908cdfada4fcc76b5e0e9fa4f1c6ab43a3710b2ce81f150b8", - "0x8d4918cfe78489e146c071c149a7271ea81dee2ab0615394ecc35827193e737d", - "0x6a7e51675ea6214d36acc7fb193911d2608e41a2df747e328afc6f5a465261c0", - "0xf012c5f418c7e265bce72f9f4e2900084216c9187900927d9aafc899616ea9e6", - "0x934c51d4f2051bb7aa555b3f44bef81ff782b690e29f7cc0a9411ad03ac74a3e", - "0x9ebbecb11efe195d2ef7681c8f1f8af3b501f7c65a0f9ea916f7ffc9a6bafd74", - "0xe28247949b99de84e721641d5e3b638dde927478df0ed0f53b8970b4febbfeaa", - "0x6491ca6bae8781055660837b72622f19daecc7407aa58d24088b45f5725691f2", - "0x3a56f6fdf34d6a4d742451c1f5b6e575685f9a6703541315df1cb8aafe531f7e", - "0xc204b9d22b7cbdcc9132539ea475792f4ea231cb246747c485632be8df4ff5c2", - "0x6188cd2938f72d2dd5e16525574f240b458316d42daafed892faee9189caeba7", - "0xa272f3ccaa93e016333dbc904183db6309e31d06720da1d18addb7560b9bb427", - "0xdce0b5f11909a90c1c6b8fd2bdb3113a035e7784103e05ffc972364530ac36ed", - "0x6bcf3461ce1447e80bd3da2d91dc4530bb649b98333304fe3e0045743c0b96ff", - "0x523496ab97b10356b5bfa8e17b4927b8f0f507368391e24250f218cc00be4bda", - "0x6dfa5889c65ed8413d6633bffc9c3e648621d38eb70e57ada781b3f4dd62374c", - "0xaf1a300f73429dec7f12d0ebe9706cd113e15e1dee6cab37ff11503a836cb3ff", - "0xbb8aa95b40671760e1d131cb269c2d156f29d89911604db04ee7f87511283b56", - "0x93ca5bec69be4ef613260e2dc850668d5a1c839e511322d95ec25203d74673ff", - "0xd7cd3a14db02b6c705bb6cdb03140b50b6b989ab82d733df84f990a9c4d6b292", - "0x9136b9484831f1417ecc2d5ec93fe31b25e79b35513cf5187e50e3b95f862269", - "0x1519b8a6581123491bd0df07cfa3a40b0d098e5cc6ea981368fd073f7c927ff5", - "0x08ad5c68577e9e09e5b00035c65835b404437b792ff327950d07ef227aed6a84", - "0x4e989dc2f09df3e9fef7e50e7b7a9da85c091c11796665602a0f8294dcfcb2d6", - "0xe4a311a951e3743c0d3d05db87cc5d62ab0ebbe6b2e85e035c6452b0803c4be5", - "0x4a64e0fd19dd4b2dd7be3810f870cfca0cb4303d44204ae329f3ef1cd0a78420", - "0xd13981c9f5bfc2efe70eba25bb4f3d3f7bf13d454527df015e951bd79c649c50", - "0x57af6009a040d74b628416de645cb13a58e16fbd63035c6a6d8c8a0bed102ccf", - "0xfbb76c69f42039da5d672776f9e67fe1fd3d7eb0d7f5353852fa64558a91cf88", - "0x07808058eb2b620907baae2b053ef2c5786deb73df750a1b715bb1e0dbc0e14c", - "0x24f1e75fb9fd88b2628285f3e49233ea6f59b474ca05f5823810a8b49ae4cde8", - "0x5cc1e13c706a5c18aa40d8e5db49bcc87c38a07655a814b2179a35b1a8ca79bd", - "0x8ce52067eb546774ae3796de7cbb58f33395438a7976eef1f191cca9c6f59f76", - "0x094311f783939ded904c263a92d5db558e60352a392d3ba77045ff82114978e0", - "0x399ecdbb06d1421fd3651cd625376cea22cce333c6dc200b9e572a001b794a3d", - "0x6a94f126de560108bdb47dcfa8eaa5e9895b3bb9bdf7e7e3078fb725a1ca18a3", - "0xc0c7a71a8e3547cb067a73a984cdf283f6480524578ff611902eb9ef947c4c80", - "0x8593b4417b4d497d0f1d68c21b5f27433be956b6e8f94d0e6efe983492647fa6", - "0x616dacbbf17052280e093ece29a151df4c78027d652ff2ec3887a48daa916d31", - "0xbf17d700c78628de624a49125b764c1240f3d59b85fe376a64cc02f44fd3f46b", - "0x89f0b2b0b4b0eff45499231c9c5fdb53e95f72c589e7ed04c734b4d07df32a69", - "0xd4399b262ddaeec84cb56417cb84d2065664d79a51750ee566217487f420d8d5", - "0x89874f2ef4e0b53e96afe703f4f9e5d5c7da81a621acf00df29f821098142898", - "0x84a9a966381053a4e933c1ebae4fec74d3452ae5feb2b1c90ed59c92fa0f5250", - "0x748adbe8f803c86ef6f20ef7f178123f46d6c45dcfa332827918f4cfa9417663", - "0x0c78bcfbe149b1b2de2253d443011aefb4e5ea0c7a48e2e13156cd5276437557", - "0xa8d86c719b15c328e5117fcc0f4b381df4b8bab346d522df49aae19820ee128a", - "0x3bce6f3055593daacc3ae11b67d5dcc20475e8eaa91eb3153f83bfca6f2e7c8c", - "0x8af84754ff63a68b7b8ba3948e255fc172c53610aa90fc2f5f633bd8ce1ef7c5", - "0xcacfe2b9181c60d0c3d7b48403b18ee184e7c7032f81eebded3f19078c01d7d7", - "0xde4bc2b17855522804fdd6352f36eec477baafd69823908506b949c017aaf4ee", - "0xcbc7689bc06c9f4f04414835a89650a845884a2d102b6900f3abd4d4c8f8dc3b", - "0xb9779ac13bc739d5bc40bdb927c3543310ff114a83bbe35192c250a5f772d441", - "0x1239fa2d0cbb2255d32b82177a976ed5c9f70f0661a5d5267c60f456b9a7f44c", - "0x3e81ff86adae141c75c8b1a91d47db7c6b196ab00cc883fb2fba7655fdd6dca3", - "0x551e92e6d774825a2a48555268c86ee52e1b613e63c8a6e14275ae877dfa80f9", - "0x27a7d2faa486508c7fa20b818d6aa130a914da688d5bc8c60a3547c241937aa0", - "0xd10995979320d9d9d64051e4f721644579b4984a4337de86901b03fc2c042e21", - "0x6f9308ec6c4eb211b8c2323b68c4670db6a8116ac4a370801ddab1da0066df58", - "0x17d3526dec54f66815d8e4358028b0aa91d3a134d843d2945a47dd5aa56ba788", - "0x3a673e5904cc61906f6806b634ae6375de45f4f0d63713555d13a1e274e1bbf8", - "0x39dc807657774ec32abcf299b9c7f03371bfb51a864d11800199ccc7eaafbb4b", - "0xe2bcb8da657b830794b6d9f1e7471663e31996c1bb08456f4d8802448deb8565", - "0x38c7998e73b21038659140e5ae8539cd8cf993686c90148b38d6308a3e3b92cf", - "0x4b6d2986964aac5d5101ded91aaa4ff78a319dc04ab18e550589ef09b638495c", - "0xd8c4da66b5525427cafd152c365f99a255ce2e78af3e3f3dc408de0dd16fee99", - "0x444dbcafda5c0c74092577141df9fc8fb1822ef3375ef0d43eb876fe29c262f3", - "0xc030bec71e90264bacb7c09f9de3a5e282684f9f1d45a2b177c8f19f9c7180d4", - "0xd529e4c2687c7b40d1bda81201770838320b1183da1e18c59c83cc4772296921", - "0xa1ca4f57cfc4ec4522a42cda37df9aa74406d8aa8dc4b56aa62fc78c70d02379", - "0xdd30dc03a60b0fc21dc4b75629124e8190daff2e3504222fd6fb772531bdda85", - "0x2d9d4a9b9b2a27cf863a292a7fd112c81b0deae05457073fa0d5bf7e0dd755d4", - "0x19815e0f25090a9494cf5bea69edb70e7a56e6bf56bd19ddb1856198f54399e0", - "0xa7fa776c8227838d27496a3c659f3da3f5acce22da70701dfd62953edfa2bb09", - "0xe55efa9386b2e0fbd38af545106f197868361f2dc44051cb4a1ad540396283a8", - "0xc6c313738c3c75d434da4083962f8e8355bb8832e17c7104d037b131682b28d3", - "0x756a6309e8c0a374b99b2b2534a851496bc74db36e5bf1c950c0549914f0d0a4", - "0x36f64ed32258a3d2dc849f4abe98db30d8b04df28420c56215e29190e8a447bd", - "0x5273c4accf93338826feb5bd75117a7a0ab5a01225972532ff4ac1d29b289d8c", - "0x6146cf6b830f0222a8bf9353ea26deb973a85c5c4a005136061ab0fb48fe56a8", - "0x97b07c22662079a3a448b373fcb73320fed4a0877125228b4e9a5b74c0bbf703", - "0x68d28adf72884756b688377fac36d371325a01c65f5b70fcd7ac16a2dcd21444", - "0x2c27150b4cd8aea85723c4d264b8799c2e92bd4430719da6bdd3a0290c024a21", - "0x6b553b884acac18804cd52c7139e4a245f2d263b6d014fb6c28e31d7ea08e63b", - "0x64bc2ff8936395f794702b110041a88c1acc9cba50e12c2c5c9730976e667ae9", - "0xc45b2a7e308777811b6c099ffa3287970e003001dfbfe448a2600edf995513b8", - "0xa89c093a0b77cf4ad1ad7ffee799872a66ee38c3989ad39fb90069ab70b1fb4c", - "0xe8d0823460eba540c0c86016014127c7b77b0afdd199fc7bf8145a556a7c523e", - "0xcb2ce7a29b4c67956c439195a84b53f5c54e273c20b6cada43aa68ca7b1b59d1", - "0xcee4cb506d3b0cd84b763f405cd68e2bdf9ec1741778a004eaac9910d17cb67f", - "0x357376e9a49b6c7dab7c5cc95d4a90cc27516f1b7f56c33c4c0125516153819e", - "0x77090e31db86c2f2b031cec1a6dbfa3c3b2f464db7e8444b5def6468c03f5308", - "0xf2b0dee21d7b016c0c9e1a02a970835f934f66c552d653c9d5fcfd20aaf397f6", - "0xfd662e1a27c14d5e8b1e9bf6fca699a3ed7c5bb883cc626d54f53a721c570557", - "0x86194d492a5adc474f114f9cb7b0f6f6795d7680614b29bdbf25e969513a3276", - "0x2bf3ae6993adb5d85fe62bce02a836beb598779ddd37cc2db1f44b1cbea616ab", - "0x4321e3a94d12161ebdbc1b5c0f9223a7f1dc9050792589ce95771c7951b2f176", - "0x79154a76904f2a3c59e7151fff7cd448a3f74c003b866b9faba330481c6895c5", - "0x9c9e7e1d3753804e3644da89248505116009585c6e6d42071cbc532de20749b9", - "0x4dc1441b23210778e4df8417be9f654619527b5b42247bd7a8490a4a5f50dc49", - "0x79fd11e85b307098e827168a157ef45b0af5f4bc073a2920f42c6ff332392a58", - "0x446e8650a156bbb1b96d22e0d09619f90b8baeed34f8b63ba7bf3da3b764e219", - "0xa86cdf11cf5586d8b0449085e7c153a0dd55aaaf930960f3f31f80d099011d70", - "0x4d30e55035eec495badfd3cb8a2174295b2d2cfbee4e669e61bc148d09ff2342", - "0x2f8f3bc3c59975caf160d4a5581cab3499b84a524cb7977e4977de10a74ab875", - "0xe08b4473276f706c7399f584797cf07d33a91c91272ad79e0a5004c00a0d3cbc", - "0x1e27eb957ea54f1806115824c61d78e265cb75807f68d508da5ace6c7dbcd9f2", - "0x8304bbb4592daf4cc754c67dd78a2e2008b1abd8d966521a2291d170c9551e9b", - "0x8298d1605af17c8f47afe0b34b84bba22441a064a3d5311a2ea7e45f76565c8f", - "0xdc8014aead4dcb61449918deef31c64ad8555939347bf04f543d6a1158eb1771", - "0xca91e9581535b11cef0ebcd2e68dc00c3a18844fb4d6f05acf26eb3cd15f1047", - "0x2b26282d94df586bc7d4bc0cfab8ffe1844800c7045621527b9f9f0d5004949c", - "0x9a92f43c5a697a097e39ad12fcd9279b8fb3c3076ea1d910ff871c5ab3342a47", - "0xe33707e3e852b3b6a5cd375d981810399de6a3f96015bff7a4e5065f9c8713db", - "0x132ddae1f0244abf072e6d8115470ad4afb24748169891be0a4b952271599333", - "0x2c1236a98f16a294a9de1c24ea59739fcd6b5932b3f2535c8d131bb2f92c1dd5", - "0x989b0a915bb07ef5e3673a99ee796639722b9e4cf5086433cf8072fa3264f4e0", - "0xbd871c039e619de1514cb6f9223299c44d0555b5eb88570f79fd0d593953c197", - "0x7fcb1ab57bca2410a274f6339927bc12ea6843c106816fe10fc9576b6c7f7cea", - "0x5692b49ef3c3ffab97ab9ab1bcc10017e6d0527e1fab5b257210633dc4d2658c", - "0xe105a92cb6817fe6fdd585068363e0ffd45686fb6dc3658504c70e2057b165c5", - "0x97e65f3bb842f242f51e9ce978320a90720858dc9c535c1d66bd1c269dda0286", - "0xe5ba47b574c389d060e0c5f99f69829d7b6dd8b3bf6e64c315c28521a329c392", - "0xe971dd283f7ed3ca0e28a73d614c490a959c36f44bc30dc7fd79bda064f23aa0", - "0x0c786961cb4df57adc1011891b90813943a13a06032dcb2b7f9ac38dc8b3458a", - "0x3736f1ec97fdfecd7c2e6139fc7ef236586bd9507f65a99913a23bafdd5f069d", - "0x5c6cefd0c6c9c825668f99d1d595f6fa55a45e6a43e23323e901900e02a32f40", - "0x00373765ace6950b4728871a0165aeff55ea61fa8ee07d51d7b8bb8114c20380", - "0x49abb5d78311bf743008c2401f074e4b190d9b29c59cf6328831decd83068172", - "0x0bc28d7480d5a56588b937a530d026a94becf9ced1fe71c6dd1ae0d2922bde50", - "0x45e4ffdd3b6d480ee76f0ee7f6acd7c039ef564d77e5a91546e8269d5468ff99", - "0x09600f167ac2e81cb9164e048908a5b410cef5b48f92eb9a801cf84104430172", - "0x00ddfefc3d36282e9aa8e163d54df86f10737416d9dcf33e786d1713ab54052f", - "0x5b9e3159e4394f03d05ed8b8127ceed638ebe147beda7b7097b6dfbd8342df53", - "0x85d2ae2bfa381b7f5c1b0305f8e252f703d295edbd7c05908e6ae564d05443fb", - "0x5d93339013a78b3344b994bb474fd714bf5495dbcee84346a30219b214f1ed27", - "0x509921ed07765eff19b5c5b7885c4eeb30a8329417d1d819f3428e278364a192", - "0xe004d5f07b3986916f8cca4ba84f9357d4550c26d408f79fb49dee47c5afc100", - "0xcd0f7446313d80026c33427aad00e4689ef0c9966dc5faff93dd1ad258a032be", - "0x0bf64f9c84ef26104cc0d0bc61594bdc0d22f9bf25b436170df1c47351fc8746", - "0xb2e605741fe4b42abeea0ad054727950485ac432754ac2f98db695988c515d1b", - "0x9b6ef4b72c4c5b8159c308fe0395c8f74119bfc495a64e0529209967a1efab7b", - "0xf682c4da2d193bdc8e23cbd2a35d2d2eefff9281bb053f86c84841a3c88e4517", - "0x19cda96cd533527a9a93fe8c38184778cc79ee8ce389c181e67d79971c82fa6e", - "0xddcf6596740ea21e3c5135e32166e5e7944ab1a37ca60c57d9d005f83015865d", - "0x4932d76141f9f33ea5193e58e1767f67b5017ffc277c41fb8b9cb020304b923e", - "0xcab96730ff161fdecb5c0118b34b2a8c6ca2e53cc38ef76b8702284fd64d862f", - "0xe042dd86029d97b89ed789847c9651d49b2790d68b475f194c63c89974704b95", - "0x548200b226d36c3092fb9d721b74b829564bae7f39a63c2be0a78ecac5c69694", - "0x26a162476b85f3f6e366b3b767eb39227ce358a4c78dcbe6c8e3710c6ae05c1d", - "0x6f388c498dcc8b1e986c17332c8df84af7e8af9fca5c5a59600dda14f74e125f", - "0xa342f25dc1194e225f4c8b4d89b8992bf59517cffee52a1f2c2a0cc4727f909e", - "0x5e0d21aaffd603c4f5d73e5eae97e14988b03e45beb15bc44776e2db9ce20fb4", - "0xebbbed03150c85b1a7c7e7e6a6a67fe0483fc7176bdfe4f94bdb094ffce5bb2b", - "0x40e530eaa7fc24685d8cd9cd94a3f4b01aff4cbea49aafd448cd1f7ab4b0c186", - "0xecb1cc861f12d2be9b1f39bf56363937e6bdd5eee6d7e5e90426e7d29bd75e65", - "0xc0bc404c877856648f5793792aba95c9fcf2768eac65028e0a930c57ff9d158d", - "0x3e50fea97445730cf5c3fe8f05c1d03c2298fcd52a7d9be911d1c989f29fe204", - "0xb512ff3c024347545bc2843bc84f6006c0b1a91f49a7549558ac5d8d331c1fce", - "0xc0fd2941f49fe9ec9ca375d0745803539dd3a9750f1bc46380cad3ce29c76264", - "0x7f37105755852886e86d113ada4b4f1f68ebf0aa36dfa36291584dfe28e773eb", - "0xf0942db3af7cd949ae31d1f690f832c6e4f8a3b9744ef9bbf8e7a90b04a0ebff", - "0x6a9cee1f0f3ae40d63dab9547ea6bf342efb99176fd30d0ed2d8de02f1be6c31", - "0x2c2092ec0adfe352c46ade57b3c115783b7d4a92fb63bd1effef32e162d4b34a", - "0x4aae695ff67508f2d03f8674282d58e4f1038cd0d4c2a6a841ce425433e305a5", - "0x543665bfaeb5c10c0dd4d180475c9aa18a9edc313e52405f1c5fdc151538744f", - "0x7473934014d90b821ca0076d132c716728c19927f5680482b69163e8ca5d79a1", - "0xf3f4efa6bc4e493b5e09f32cab59a9cfc28b5a180a59640270a79927058a4f43", - "0xbfea0aeb82cd88ffa0269c56eedfebe83759a4af9345ebcd2156ec234d99633a", - "0x827eef18a3c2e24021dacda3c00187b8cc87e071ed1e2e9246be0066135fc284", - "0xd567403ba1bcccad81978857599647c0a7008cd3ab1a3bbbffec1217da92b060", - "0x74c8805b9b589e9493ee02bc73131431256d18b79de4fc3820ae5220bb5498b3", - "0x32afddf7ebc9d7efe51e045446a61fef4b156a3379212517b0971a91252e1b2c", - "0x4d050a932e5f971f33353a23c5b3382d163319321f55368598bcc3cd8c67f91b", - "0x9c01431659ec8c4db0cffc566ed9da3d04d5db610c6d6fbae260ce3011fb68fd", - "0x0814da2cbf76f83196ccd5342638df799d881eab6a526eab325c06d75b7f8e01", - "0xe669b4a2569397b901dad843884668d52ce85919ac6703671963d55c0923df5f", - "0x44762f71591afce826580a50fb4af763d7ceddc75d6e74d4f40deb3ec4c6ad13", - "0xd3231536bc6b897a24e7925909da660e7bc2c5154e529be0dc590770b5573023", - "0x8934b9858529b0bfa879142e0242f1dbe68143ac2ab347517be826e2cd8ab087", - "0xe833f8513f4e71ec56adc114106d5a8ae19b1aaf95d91a5ce18398f316253102", - "0x0a5d3578d418e0eacc2be66f8eb365a7cff71e6b287459e25a921befc7c55e79", - "0xc11db91e90bca5f39221330704193e670815920a5319eb06676b5d74e1d7d776", - "0x04f1e0808c62821a8f088ca0172820f469d327dd336db66d9595932826fb73dc", - "0x1861241e353c68afcba164f24f650eb3892f219d984e376336f401902b4038fa", - "0x142c7d1eb631e40562c24d2a271f0fa21be1ae76d6c7d98491599dc0d0580d27", - "0x203231cb071fccadc815f222900beca55777075f7d42563529682e6449138a17", - "0x304bcbcc7b6dfee9437b8f6b255accfd789ed115461b41e933140730a46675e7", - "0xc9f2359de838acb06278d7967f2ffdfd3bda5f46300b21939a760914a7e00568", - "0x1b470dceebbda583263a9373a4ddde80e2523b3837ed3c20b111e6fb9aa99a60", - "0x765ebffc2d48b2fe92c3fb14b301cb2338984f7760d514373b01fb34de466b33", - "0xbe814242513e1ef6903600ffd517b8f678cf306e057e01f3971eac7514b72ba1", - "0xf313f2b3c05a1dac53de10ddcbc4cc38b38be85f89640aafa4502631c0e3511e", - "0xdfb72e306c68cf4b22f62e9bca906ef3ac627b2286d2a261489e2c922d700dae", - "0x0783bc2129066d953ef7aca86ecf53ec3ff2bfcf8920f6079ad0a4dd703fe331", - "0x71f1fbfc2a9a232e2674e3e36547ee874806ab37b22728d8c30ecdb7ed2ad539", - "0xbb098368fb1529222eb83277af668535a1173a78825c7e3ef86f4f45429cb838", - "0xc49eea0b1171263bd8df058e6279092d59d1e8a4f108d1b4004333733bc6e7a3", - "0x6f95c83060775d579005c4731e05eda62753bcd0f95295b395b1de22b21f3b0a", - "0x9869e93ab6e4ea9da4cd12c279580e211b4c870a7e7dca098058897795804e76", - "0x816a76e3c912b639ae1e4b5eecadbb8cc173c3aadd796815a9ccdbf9226d58ee", - "0x29f33d9d30c64af6b372e922414c85004655782d024916909834b95643fd6096", - "0x30a9763617e8337203196a11f3e4b81b82d9642f0cf26b2c654c8504d289a17d", - "0x21eb2108b1ad465397ed3aa8016c09a52000c60aaaf42e13d95c271cf394c074", - "0x59d8b8fe9dd951d5ec540bf46808f01c9ec2a5e9dd0247b34b2622c48bfa498d", - "0x71b8061902f451c6fbd95c29ff960353afaea2b0410ee11cb993ce0ccb8af446", - "0xe69938e7da23b9d7ca611326dacaff95009cb5898abf1858593060ccb5aff4f9", - "0x0aacb29673ba3a0dce850ac772455c2b092b1a0fe61ed34965e4cdf723d659d1", - "0x18bf2fb69dc62ea39c195a702b8e9514be4b9d5eba18af13974a63f74febccc6", - "0x560b7fa0d15ec6bc0add83b6125133b97672b39477092cddcd5e2936f49c51d6", - "0xc8b0d3b55acae88939bc9426181dcc7d965bb5f85cc506d26f966c60a66e4ac6", - "0xaa9c3dea2f0184de1774c47923fb7f6ead25bcdea96c70b30127ad61a6bf67ca", - "0xfa90b6e07511736519ec741ca85d23d2912b509ec608a5d319c2369aa358a82e", - "0x0ab8709a1c9ac4e9e516736b4836febf938a0055d5b4cde960ba651e986f2caf", - "0x03e28cb08abb6912d3a25cb45868d699b89bdbc180eba67590b2cf13718c967d", - "0x1617f5fb8c39fac172251ac4bb1a9b8e20f9c36cc6a47e7e0545ee38fa55a6f6", - "0xf8cbfbad5d5e66d95dbd5e83b2968d08b6eb41d28efed0f1d9205b2297168dbb", - "0x4adf7de19d0498164921d4aa39bb070c6183e8511c9f987bc91d89cb54d8affd", - "0x7b5b34085f3267297b40770c0f27095735fa286ade7521e81f500005ab63d253", - "0xc2943d2b12e44ff193ad957440620e43fd9e8da22d74bd7e4b18846eb93fe67e", - "0xa461d24d7d4cc4fdb8016476b3d5e44017bc27609b7fd09136c3a884915c9761", - "0xdcbd32d171d8cd8702ec3093dc2f149c31542a7a35a01fa63043facfbf7ddea4", - "0xe7c4e881bd4df86737497ae6e3fd65fe9d953b8e1c45ef1cbba2d291be860dec", - "0x1fc56bf433f10fe704662c0f9e69a878f243d8832fe723852215f4d2ce51f9d5", - "0x5d22da26a003567829f9e2fcf0c2be4d0f791d44400936ff1132a0dc367c316e", - "0x985c40c0bda98d02e3bbf9e33d13be1ab4b1b917c94e06255a0d60de8a547513", - "0x5aacaa6e4aa6ec649fa272c1ae2cd0376270a0252c39d1bfdd973f03cacecef0", - "0xf2992b858c902441bd44cfe0e2b3057615b7ef6a7d129bf8402e4270b711b126", - "0x690eccebda6832cdab7adc9a56b5d8ad7842aba0d7dfa0aa073347d835e72703", - "0x41f48f7975d1aff8070e4d787b3bc127613fe74cc0207e6355d80c930577348a", - "0x42286416ff16e06c1b8088e484e1687ccb93c134a880e06ebc621cfd1fecfbd4", - "0x241f3e48bbd35c8743856e8020a2def871ffef7ba897c72464286419a8e67e28", - "0x3ba5d479584f036f4b4f99942a5bc2f51cc9c4af24527dc9ced5c66178fbec00", - "0xecef4c63d3679889106352d9e56b56b7aff5e1f1408e3dbe86e35dfe6ea6c97b", - "0x2a55f99801b5437fa85f91046e933d5cb898ee3150c6a068f658e0091a303576", - "0x0103857974871ee986d9d5d430b5c3533c0b1187353300d25dbecc2aef14cfac", - "0xe2721431cf8bcc77d5652b519e879d0cde2524972d74b6ce3e6a78eb0bdc5c80", - "0xb577b9c2b3348feb5bd8e283940c524d940268a3f90c11e35dc9de3438ff038f", - "0x5bf29a628a6ae340206e02f33eab362240f99ce0e3cd8d440d002ed4495252f4", - "0x5b087ac28a0e6555830f6510fd275bf464ee4d50e6848b251dac4b823de6b995", - "0xd6ca4c3a14090c0204fe4b9ac487debafbf0f984c289cded1de950f2e655abd5", - "0x61e776419693248d8a6b8bb2ef9b9663882b57e60650ea7fa22f1251e201befd", - "0x84d0ee42adb4c9b0e127535cf76a00a0d8129396f861d5d41dea599dbbff3d0b", - "0x509683f63b390fdfcbb699a8a30340abfb5425b257e86015170d7b7296b33548", - "0xe18de77507e00ff5a9097ae81007e793ca9abf2c11f65172c1cb54a189032d3c", - "0x38a8a3c1c0c110f674a7e69039258593e15a9194b1e77ebe6176ef5caf09c6f4", - "0x7e55232c46a25bc79bf9390c2b105d0fb342015cb526cf0decdb9db23d1be43a", - "0xb745498c642fb70abdc71c707bb1e4baabd534c5bc503e35545a6395cdb48918", - "0xa4b968ff3f3760b1fa4b352ca6eb8cc883f4c902f8e7baa2644d5a7726694031", - "0xee106b785aa0d24e57532819d4cb34b5795ab0af3080b38c73168ad565103b2c", - "0x1535e68531fad8e1edcfc2621747620ab962ad38a033ba25d1d6f5947381d03d", - "0x98c83d74aa9e52a7eae636a0fb54475173fddddbb56ca42dc314998c5099c649", - "0xdae0dbf33fc395f96a4dc1a8da5af3285b8dbabe5b34639e47c70b0938a9f64d", - "0x91348b33bec70e0e68756023f1432346ca2aebbb6a43df28b7388f6f9f19bc7e", - "0x575859a6c8463bacb07ff4902b06fe1c31ceb9552bd781003d4ea2e15dc81e4c", - "0xef1a187b7033a67ff5dc0cdfe353f81d8286c533669ed4b0c0ed5168f018cb19", - "0xc671086723929e889340d42392545c10126be24c357d509ff1c6c1a5f9a57d4d", - "0xf4f1fdaf74870f153ea8375391b3c446bc3cb9b428a3426164320c720d755daf", - "0x32caf4a46065b4094869812b25138ebed9b9fe17e27bed2f1e1f18485e29a5e4", - "0xb62d0e1a873015ebd2696616378f4f3f39c5e9396ddeb750110b7ef04f189222", - "0x410c675d1f6583e8364939108dc46223cd9835623473ca18dc333a4b86e69390", - "0xffd66aabe2768327036556eee6fde0c9bcfda2b13280decc37d82798075a0b75", - "0x3acda6ba4917e64e977f4135e8c74e9091499c212e6345c58c399b4dd31d6fd3", - "0xacccfad59b3f59f16431348a3078c1dc0b662876754c1f373351d0725dc1df84", - "0x3a74d9e98aff2b6445b9776cdc21c0dafba808326d917f47d57250f150891bc2", - "0xdd4e0bb3b84db7b6e16783870f7c9bc563cb1576834eb9175721eb9cf75f748d", - "0x35e9a92581c9d402a83a7baa67bb72fcd0d9b3f3d7b1b7a143234fdadd2e67d6", - "0x64ead38ff01f1fb408829012a033eb847aa6ce3e9b99dc5e866338aa9c355b4f", - "0x78607406421e95ff55b3b952d2b4846c8b2224b2a6b46d231482ccec5de407e0", - "0x04fb332ad235e8ec13b07cf30b1c1cb6ba8aba4031f932868fc1da5d82c03dfe", - "0x4fcbf75d2beff58cf1645f74c2ea804c29e1abb6ed8d33eb6da0f2f7939b3cc7", - "0xf58b87be3dde47b6a9615315d2eeda6771fa3b31bdc369ea706f7769bd857af8", - "0x7aa5b0a30ab24a79a54080b1b56befc3c88719219ca5cb004cd45d4ca1334dc4", - "0xd2f1129f7a6a0743995aea48e9c3cfdc5efde47398e6a67a634c1c9865b15366", - "0xca65cece85c379cfdd49b9ffc5ed7e9b8a623e06f99bbec608fc3725e4a1429e", - "0x2e6942d93dc94555d948f3358d7ffef3774889455de4da3565ff883a96a590ea", - "0x063dc2dab7f0c558eda8bf9baf3901e1626416f517352760180557bd45014f06", - "0xc633fc9bad22bf62c85d4ce1c064f3ec161014456c4eff5ee9ee197230aea32e", - "0xabab885f2c04a640062289106e7bef857389db6db0a499468b45f5e8147c5f14", - "0x96eb606a5d165dc66e5c293fa139a9e8e28fb1ddc8515279705afe7a57e318e9", - "0xacb239d8e12502e378326dad3b338700d359095129411ace179e5b921c07e731", - "0x8cf7148ce70d71a754bc04049ae797e930a9b16bf4962dd3eea2f13ac6f75776", - "0xf39d2ae39131332c16508e09eb9d507f4c6bdaa284d1f4a9315af8f6122186d0", - "0xcce4df2d5f9484177965c2440bc54d1fbd0429060e82bb76c3b90f444b5246c6", - "0xbe77cc749e5f436a3b76360998ba7e6e263d39fcf792a6dcd7cc4ea18c836990", - "0xcde5a6e02589515ebcc307e20dcbf163ec85e5692ad9542bab23b43de55c487a", - "0xe7977eaf5cd7cb8c7f4e86a2c3813d52943a12baecc76f2b9d1eeda569c29d85", - "0x1011e0ba87c36df65ecf37d2360f98e0d7351f27ed9199fd7df166806332c139", - "0x9e481944f0e07b91eefc66693b69ea71c852552cf8cdafb1bc93336b971d6989", - "0x2b4d369db84d19be84a7af630b0c8a4ce0974418f407463cad8a8223b208a82b", - "0x7cf34185f5e8229b657c57c3c775987128434e909d72d06956515440678e6a25", - "0x5956c7ee723b161a0e7d74c69e57c96ad28261e9d7358bf25bbc16560a8292a5", - "0xd9a932e6f59d547de8699965c4e5964e0f663b9fd5bb9f6dedb4417d356f234c", - "0x59f2fae38f9ae4b74ba9abc5f06d4354fb9eef65983b1c8b1b025720d1b47d51", - "0x1c418c58dd888b1a546a1245021b52e83b1bd3fcbdcd0fe9bd643fe05fde502b", - "0x0db806610e23383046de4a35f8098597f1889e4dde4bf40a244e4995324b29d7", - "0xed51baa16beffad522b677c19935f07d7182b0a4bdb04330146bba3d8e8f80c4", - "0x2ecce838cf6ac5d0589fea00bab4dc9c7b107ed7c70886ea6519807785096f23", - "0x8df70aa241b84fd616047258f87b04249fe23219808a6e14f3d9fd0181c2f352", - "0xddb9d88567f42cea65b5913369c9791522b4dc4a23b0afab2003dcba337a5595", - "0x2e276865fbc34e7035cd50dab4b9b72c980abf8f7dec50988b86995ec57ae497", - "0xe82487c950c00a1e4a9ac6d2c3d0b80584b44dc27d28d6352dcef8786da3a7b4", - "0x724b23460aeb403ae7f9b3512a1e222a63fe721a2ffa4e2f4f3062da8bb5c224", - "0xe27ede30590638e194e91a392993fd9a9a1f168e32e3b9144d71d46e507d716c", - "0xd29403c683d5b1ff60839587e60eea5a6054588903e7c2c0b6f9bf030bd0d659", - "0x4e9464c5a51b3f2c6a829137b67e266ea6381c069e1701f0bce7ae7742e9e49a", - "0x0b107abcfda0ec094a6946c6057564f60eea9e6a55b2c762d4af5a7ab7899c65", - "0x5f908c956864addc2b57f01074c567155bee41412da6d63ba72971ff2eb8114e", - "0x9c00e148df00d9fb2d5847bef0726a48507871baf12be51373a7bed2a0c43f70", - "0x63a2fc58db6de3a2de3bac57255503791c4204941fcf15549a7839ca8ce26efb", - "0xefd321eb79658c3706f6f2a18663361b3adda792fe9064de3785acd101535223", - "0xa73176de8f5b3a5bfe87273711cc35a042c191aa998dc5a67498b0287e54be82", - "0xb8e2f03d134651957c31c47fff8cee2998738a603267a12f665f577a450746f1", - "0x3276e6d7618e898d6a8e1f014ccf9e06000f7cbb279dc9d078dee38f93231d3a", - "0xd23b5d1399be075454bc8f3613377113a7b65b29c1bc1a515f9bbfcc30b88174", - "0xa577feae921d39efcafe8102252452202fca0532681c2967c06eb63d00d83294", - "0xbb2231f4d795b6ea3894d802ad5f303c19edd2a25dde9c3a21ed1b578726b51b", - "0x81700c9bee6a014df24ac76eeaa2a378ce7febde11903e62a3d223ef1eec39fb", - "0xa1e05fe31cd3a58a3c11cbe47fed738e0add5039a8f97275572c7f66431f3d6f", - "0x8b5d0ea77b923d4faca65b07c9621467f2c891a925ef07009353b9e7ed854760", - "0x3566b43040f753d8a18edf7b3c89d44a2a3565aa0280ec673718ee81b82df24e", - "0xdf0672dd1e1bdaba83c0abd1d7c41d420ecdcab0019cb89b3dc310bab32bc8b6", - "0x2ef7e245c518654108cbea643f8b050257b9d3c4927493671a3a094b1dd0674e", - "0x993a3c5fe23e9636f525a4e5ee514949c5113f3b4db21ffc993a8b6bc3a55332", - "0xa023919b4e8c34cd2a1c7dd1768eb8e856ad2a1f5b101c8fed88257fdede3804", - "0x247fa5256cd95b9cc4431fe13466483f0db6707bd2453b6374934e1edd034b18", - "0xe63370f2acf5893c39f3728b66907ddc78d9dc9947db14ed6a7b5a6a876c69d6", - "0x397eb84160515d8b2beb3d37d7dfe167fb907f8a1a6cfd7457b646b95a18e9df", - "0xd236e18de82fddf7cb7f6df91a4d08fc98d9aba622e50cda7499261d01d9bb9a", - "0x76a526408c824b6c9e8afc5a0d5e5492a71f30cee5d70b4306c2298d348f0caa", - "0x00525d5481988d4c4836dadc936aff84036d99aa42722057b35ebd933c61ef3c", - "0x94e54fe2e05dd7d7e4026c0048d5e64e5314f235607e568cea8c26bd31dc3f51", - "0xab1e0c92b35d49b687188518a7af63584cfb13a74c3a9ad800fd8e1a4541faa7", - "0x5e65f148c1a914b300aea241f07de5c43709c38d279ed118bcb40ab9a3a09226", - "0x9fc8a8843a0eef62d8c16d49c70cbf2f3fe84cc155cb741d647f17e2a664e7d1", - "0x8257ba8acf906e46b7cd0de0d7463ee96c62ccb7dcdbe0fff5fbb6bc0da28d74", - "0x2a57b487f4281cc28a5b107a643944796ef2416d7989ce879d06bfd6d4caffa9", - "0x0bdf8efb30c449b26d5c574000646ac316aff27fa49d6e20420a08e441ed5f96", - "0x5d3b67c6a6324936305f405067ae70a35146759278f77793e3f7c4b90ac0c7fc", - "0x156f094425a09a09f394075d02f5b5d5aa6794bb5cf62d824ece1c57d58ea993", - "0xe31782172a116b92ac0ea9de1cadb81c1586e05d5b3993f10f8f695469ff9e81", - "0xd8f85113147a72b1950948000d75d6005ae183997c798fbbf2dadc5c439be9aa", - "0x9bed32bbf1f626012985392906016db1c993fd8ef351f8c72e2ae832a2efdd66", - "0x1c6f7b17c8bd64e03d21ca9b6dc2df278cf0b8c8f6f60c60741659fe5b34af81", - "0xe41e4494cdfc0e92f16fe6ec78e19b9d8cc3db73700a1bb02fc7670c92e4df2e", - "0xca1032438230b4faea930fc0689dd966604487a8d3abbaf21554b3e078547fe2", - "0x2bb999d1acc6cc7449dc0cb965c3bdff42e49b8ddb09cde885174c45730bc2b6", - "0x4601be8295359bb23f6f09d7f053c637ab2ce7942b762ac55b1da6d312a765c9", - "0x13fcff0af19f7f11af35b360a0199bfe610a09864dd1d42b0a6570bac17803d1", - "0x31b567fe7d9e6a9a3c15c449e9aa0ab8f83a453beb2784132f25b0919abfb428", - "0xbd4af1360219156ba336fba9cababad31ee78e1393061e3ff62f7ac785c41f19", - "0x2e15f44010ce7a966dfd3fea57c5124c120cb60d80a635910c0b2feec59fa977", - "0x68ed80af93e72f7fd9198d036d8b995e5baeb0f97c6f2734379116a5814b601f", - "0x6aeaf5d0decd1a5c8eef52435bdad2a60cf1cc5f79e23b90b7afc0110d830a3d", - "0x349b95da9a3c65e1d34533bd08f8c95c934c49b7c20e6c7e38ce4db60239c94b", - "0x2a0053d5a61602e26d932534d5e9a753f75642edf1410b3ffd61076d27d5ec97", - "0xca53c9d106169cd3a7a870efd2c2c7118ff953b8aea5c5b9896dc2ff9b2c5d59", - "0xd227181ff80d67f95f4fa11f86b1bb5dfcf37385262d82d6025bdeecc6bf00bd", - "0xefa99cf897198be702eda71b3fecf4cc12a27e7c90a258c4230aa847b03e16a6", - "0x0788c17ea693a049784eec30b17c49e66e7a71175893a064db7bc6e85a0b536e", - "0xcf2bdf91c2f44cae1148ae027688f70ae27ee65b8c1159cbca3e41ab7755e5c0", - "0x32882f2cf31033d40d5069e68c799f3e3297a9915287fb317bcf657e078fe6d3", - "0x3401436cb69ba8552d4731fb2f734a9a659cb10ac666f374318420d3e299b98a", - "0x988943c9b35e50f6ab03dc275de1dc770aa32574cf9a90dd0c13e7263b46c129", - "0xc282d894a7e4346a492fe495319c5cc9abf0c7f95e28bdf985710f692c770520", - "0xd7f8e14bbf8c6061a0927e107f53123f78448b878b9562cb8113b5d93d2d9142", - "0xe2c995419467eb379ee043399d89bb13a7d316b9a680f9667dc9defc7fcab80b", - "0x567357333aa3c5cf6b1ba20a3514ad0e21eef11f5a5c4ec999048abb78c5ab7f", - "0xb9f31c6c771e610048dcb0f4553629481b6d243980e1ca9ec3d1400a56ef452e", - "0x924533f9da72137f96ba97b39a95c2c369dba0bb09658aea3a387f3141b5a34d", - "0x2f17e624e0f3213c2d953107e72aca40b5f764f4b31278c8ee32a000119aa3ed", - "0x8d301cf22181c65bd6db20ca01df6e3bf13864f88958fc04861c295a31b9a86f", - "0x3bdb760c302d348d16e634c07f437f793b888bc15fcae52c371675b7eec2e241", - "0xaa20ff689413c62b1d9854ed1c59b1629e9fcd9f99512bee40933e722e4d143f", - "0xd9d0f8cb5b86492abc172c0460cbd819d13c05f055cc1306af6285459223373b", - "0xe0ec50a77f89631ac2a1c38448a3e5d8ee739f1cbcb542b23116005ff0726679", - "0x90238eec2af4ab1e1445ab94f422f90c862afbfa8cd6bec154d2f6f40721a615", - "0x5c2350ae9bd5f2e2355c97b0340e96621bccd43e9a7e4e867ba1523f5a5178dc", - "0x896a7844bc430b330fc094554ef21c162e2c5c890b4525720a612c9f16bd80ac", - "0xc2aac353dfdf9d7ce52240f6b84e8fec9e66d4acbd77402fe7218f55fb76e834", - "0x840ca0ec7af88f0e26d3b9e54473fdfd038d5395165b22a935e941187d529136", - "0x5e1274869d1d7f072dcf83d631844ea7e750f90a6183262622f2db72eefbebc9", - "0xc217f1324e0ba4e36cbc896c2dd4418ca5bfa880cc64bfa913d6212cbcfe8a95", - "0xbd7893a4798b0838629ecbf21a8cea963df8920a792f5282604b59c536ca91bc", - "0x85b22d6088f30f1b262369f869a72e1354036363f70c8778b1560658abf75902", - "0x829935ff52d7148a3c5548bcfc72b736b184e4f4661b251e660313895432d66d", - "0x4b0d3238882111cc0065b1e2c9a71eeccb34876b4ddbcba989a47faff0f505f0", - "0xa619fdf363c41d69d2cd4c8063e3abedb18066b8cb6ed4fcddd99686d684f450", - "0x2dad790e3f5f6be580f97dd37b22a1e80a6555f41726bff0639aef54f0bc47e8", - "0xfe2064175fd61af4c646ff0745a79ad689d9be2969bcca0939393603865ccaa5", - "0x8a18e5e22dd996798181fdf8ae77cbc7929e5bffa0145996b00d83c5e7829c6f", - "0xa7adb5fc7ccbb132a8e22a861cb5e3e1940a4ec7c5add1bc767ecc668d1a84fc", - "0x7ea8e25d742691f53294dbfdac087b07d688cc40a4a2de28fb398b2516de4bfd", - "0xc162edab705ae176b26b495f7ef7205552319a72d56c5ded30be9770860d6530", - "0x5406de06f5e2e819ec8a7efda23e19cde88bf8ea9969e3e3393f1235c4be67ee", - "0xe5a6b4f946655b32549531601ba3571fbcc45bf58a7b18ea24b5f4677fd58815", - "0x5bf157c76ea5a10ca8240c44a72450537678bc949f57cb9a748b445907180d8f", - "0x4f2f7c966d440ab36a1ebf61ecb1a9b1ea4ea6227c29e4fc1214a8c63cee7d05", - "0x81dc3a0dcd5ae99dc7bcda8b30cfe89aee00094258891d445425e8e304a71f08", - "0x915c3f6e8b37680ccfa5dfa941ad2147fce2f99842646a7835e2d45e50e4d991", - "0xe616568cf1a281f42a32686b65dd712e2fd003a84dccbaec32b890440dd206ba", - "0x70526aaeb8a25dbdf93b3a7cf9cc638292f2502b7bf78125e88df90335e594a8", - "0x6b3e974c6a004beea5b38dea401870dd2a68c2902ea8b3ad5a8358e10f04eaf9", - "0x99b17fa583f9f80f81edae98fc54bd5552ad44aeeb6123e99670696541cd0442", - "0xcb13a1b63fb6f0b511876a699ac017aade97d8dec84249680e7e36b3729d9744", - "0x2bc84717485fb9eedb00647c8da26e201fcf05a0b5c42e2e03072ca130d1e3c5", - "0x7bd8ffc908159c25a28a3dd97064ee7a76bfa40628ac54066f83e904596562e5", - "0xb9d16b733cdefe95eed9fb024d5737f90723bdc46260f0aebe2adf23712ebb05", - "0x0d6a943a7bbad9fdbd107c4a1df726f7aa61de4bcf1e1c50c8a32d56828e8c72", - "0x7a264f356294d00e55ef0dd56e8ba793550c4366347d60c7cd31176d79dc8486", - "0xf52baa383738251b1085fd6aebdd0da48414bb993fd3bc427b2a07a6ace8d39f", - "0xe2958f9d5bc0f1b23b5a3923d87567a58dfa31cbc0a63715b76c501bcd022f65", - "0xa760fb572f3a44ac43c0cfb75becf5bec1d7dab5e33222050b95a6cb8938b146", - "0x004437e7463a43de8edcd074a4c2f03ce72e4716f88f03567a50b6440b69ef2f", - "0xd7268e9610100bddb2188bdb0f80ffbc479b67bda2ecbc5aaf18f947667f3ecb", - "0x176ac5d88148cdfd9049d3eca742750edf975c32e649be8372b15e43ce162d77", - "0x118df9c7631bfd903fb46cfa867c8ef861d9e828e6f57de585f17ad351819e25", - "0xea084c972d69e9ffb61665a27fa4f2d0006f0e220007c0b2e4760a95d68c6c01", - "0xd6e2a8f3df290a204efcadd3a34bf57eea6a3980fbb68749029660e661282f2b", - "0xc538e4c7b704fa8c1c123f8baca05bca5fda28df7ad7fec099638a4a7dd4fd18", - "0x419823e612d6a0055fe460ec9593b4fc0298ea94e0ce838fb302ff1ae033bf40", - "0x304e214664a6703ad14fa493ed333cd12f6db8f4f6af1223bf00a348fa3223e0", - "0x4de744c5af198cf5a0048c4a3c9ba578ea3478deae31531b87eba2a0e65b6fe6", - "0x523694986a7277170342c7a53bb710b86a432b0a7a3d96e141fbbbc113ac2e88", - "0xb81dcd531f4ea6eca82860d7f45063ca7de742a2fb41d7b6c1d62202fc1af17c", - "0x205a95c1d7e7d2cd684bb666dbaebd2533f4af28837a6fd2f6a7d4aa68816dbc", - "0x7c48dd0273a7207ceb5a8a1e3b33352f6d438e2a7b45d4c082dd85135e21e5e3", - "0x0e3edf65e5a7502793a8f139a69f3946d567a959ec411088af96da979047675c", - "0xa0b8886550aad717f1b5d57519a4bd82bdfa30e3c8ba4ff81a64be341d828aee", - "0x399f2cd7012257b4991343f191aa688915b4375899ca9519630b5ec6c62a8b49", - "0x56068dc17a965fad007ec7f23dec7d396dff33b0a60c4e9b8d0f75fb26178f05", - "0xbb62f47822b394fa87d70cce239c9e57464157fe2012c2c37e8f6b69515d6112", - "0xd6a068fdc6d4cd90203209a07363ee1eba047703e50ce9b06dab471e0dd1a037", - "0xe5a62c74d81ad110ea0ec13847fe64e4c3e8e48b1eb053f1e381abc0caff7bad", - "0x8ca95a015ea27a649b0bee134eb170f01b5c03cc45a8bb2c40557c1598c3892a", - "0xb124e101738d541ac61b5666c0fa19375417d946a2344ca40baf308fe8449a98", - "0x1b9543937289ca48720675ffd354464fecacd8b251a3f267f42906b7188f184d", - "0x0b48dd3eec04741e0f78cf61937b2f263446d4ba269e8c7d4aff9c00a2fafced", - "0xf72ffe4699fea49e7e67f96fb5688247746c9bf25fb58e41f02b0dde4a8003f9", - "0x08328b322ac26a02e89401565b91a3dd9abee62fe991744e2ecb2458c6c26460", - "0xe9dc223fdf695c9b5480de56cc91fa640a4b73a8cfeff30ecf4db4d36727fe21", - "0xa83123655348b15b947d83c14a241d8e303242614b25c45044fd1a1ee28d928e", - "0x14ac46b1f556ab33fd4199e5a46e0584d00bbcb2592ebfd4d4f66efffe31bfa3", - "0x71ad4b7b5605aebe1059ee484b5ec791e9018b50f92ad2f8d4f3c1548a99411b", - "0xcdde5fea3fec154058e16f7ef877c70404b577cd74f98f7dc45600cb7b598b04", - "0x330f9d20ddac508dcf0e08a4c1eddb55cb5d7f645c13f50b3683a41bced9e244", - "0x76de024aee0b03e96765dc6d7c71acbf253e962b4f3892b94196487821381ade", - "0x1c37a50f5e3c774d9ea4438a629d497705c3bae728e8e89608ee68d7cd2b53b5", - "0xe16a37be64f82bfe54595c9c51625ce3b69413b70e0b119a04e79c5b8d593c22", - "0x525afdc902879df4c23b996f34a5387fac6e41300e1a7cc9e24c630a1a140653", - "0x845164906086e678bfdafbf4719cf8f80d988bca007aece4b031c3ca5df08db6", - "0xa4d4bca2c51e8118d16a4b8ed33d41a73c275bef73072a6674005b9ee7bbb793", - "0xd0759f637aab37f4981b927e688f3e51f17cf90660931ab8bdfa40363a6931df", - "0xf54986144fa83bc3953c4a1c91eebd6a4abb185ab7b188cf7492a7ca430b9130", - "0xa31de426ecf5f98c1381c844e2fb7c959ad8adac39484d71e3bd07d3b1094118", - "0xf64fb1f4de6f01317e242b1198802191a6cdd39e1580d356b9e5442adb69c8ab", - "0xb97a74c8e47d37b3ce7c12ba09b53811f23dcaf4a8d260dd370f45e9ccbacc3a", - "0xf118ce791474d987b9a8d3290be077e8316a6fa3bfcda3600e6c2698264db37b", - "0x547fe45b0ca517f898e6a5fd22929cf533911f505e15de083a5685c8eb1ccd0b", - "0xd74d307e3b5a166a64056f07eb85f60fda1d9c17368a96afc6f8141141f85c86", - "0xa315936672e2737800c6d51fc22b56d918126ec329fa7e1ba5e31af36ea4f87f", - "0xe928505d97d673588a68a08ba6e2a4bc25843592598988c1d168d5c938e230cd", - "0xa6bbd3b96bd66597eb68c4059203275421a529c61471a69cdc1d2d9211aee400", - "0xa46efc7ab47e7a0f57a54203a039a4339d992207b31bc707eac98ade8e8f6fab", - "0x46e903455140f009d1f7e9d224ede2e29d1fb3f72cebeb60dfa64ff059b7ff40", - "0x1eeba50e5530be85464456af3ea0ee38855276ba79bebfe305e49fdebd0dc97c", - "0x30e149bba2c3c0db9038c39871325392bcb41169106131469b6ea7994c5d8d03", - "0x9503edfe4cfb20c38ba2efef043ad824f2b17f39e2ace445fd9ce73caec93c75", - "0x608f294da5e0df707b97c4949b775f64ef76c055459c26b651010888cb888037", - "0x8eb5960dc8e49951c41505ce34160bbd588bceb74468a7dc0898c6744d75138a", - "0xb020dd8cccb6beff1e7d996a740b876609a55ce2041ec0e9f09f683bfb22466c", - "0x9e8333dc01746341ff7181ae95ddb75748cf3efbbed24f3b16885efd0aa19da3", - "0x2a97bcddd5f0a7245c520bbabd77e48432c39f3cb17a0241be9c62ab5d185a1a", - "0xa81cdce57af311f79ae16dfad6808b40e8ece16115978131dde0f3edb29aabfa", - "0x8f321249562fcb94c94a80679adf69aa701f0719515753932548a89a28cdc7da", - "0xda37eaec19bd44bb1892d12d842a77ab7dc5ea43ca0a1a92aaa3ffed0ba9d90a", - "0xab8c920add1f9e922890da5d92ff199b384a5f042f5eb4e3fbe565f5ca50ffa8", - "0x9f52ff4d39142c046effbe6e552500886200c9c3154dc68abe0f9e4bdfa9078d", - "0x1eebaf84ba1e6667e825716be63ddc71a963688f47227e0d17d78144c820e17d", - "0xd2c2c19eacb26695c89b51b75fd616de5c769d0c7169794057575e1dff3800f8", - "0xc5ad683c4beaeb409a68cbaf81532e4edce6f64b60853725e493ffdd93e69f7d", - "0x768303ceca362b8a3996a4823c4d64ea4a4ca5892e91ab0433f2917b96486806", - "0x88e25c3ba8ac976c0382344f4a8fa310bcfc7f51e09efab4faaf222cf6dc5d67", - "0xe05f9dc2db75ce9b0fb59cf1ce12581cd10910dc5b91d744791f564bbb87e176", - "0xd75fad017be9f908c431987b10f25526a9c9d346118901d7e0b84e74a44724ff", - "0x83cd50c6634e2edf21044fe789e82850667862be407faeaa90f9bc3b0c60f9ed", - "0xdf6b6b1134dbe14a48678610c630ba5927f3d75d45d01e56534204b87ed575e5", - "0x3e486fed8ba04ace837ba81d61086b3443ec22a803cffaca18e10e0e0f1cf679", - "0x6b7c8f5e560ce6b6eb94ff8e4f811b06f2ba91048ebc2440e25f2c44eff4e637", - "0xa7a92f9396380b5ce01e3666acf035dc80a297448e1b95530b9a8bd9eb19496b", - "0x7df4150c891991e89a5938c12bcb4e4ca1a3bb3ed17e1d14930e78a3b7287cd6", - "0x9cff0374f59c5c0a8b6b8db636387e0d032922e34049356ab00ffa3f2cac8f23", - "0x85a5ca8ea29b19babb6aa45861de2cd9e44e31ff13f7161ead44139e6b2de019", - "0xe418e0eba34f07d10ba270bf4316b78b15c49d2a920f3370b403dc584cf2bccf", - "0x8500b89c737ce038eb99a443d4ed6dd02e00ab06c836b8f03de3e713e485e99e", - "0x0f324429900c3bb11cf6a0c4099148af93d8953b748fa8974c7cc5d942f6f36d", - "0xaffe95fb50dab84128becf268413fbf2c8ccbc2fde2b6f6d8bdad23cc4ed9312", - "0xcb93bb3ee92074161da7d6345022f415accea11b20c412cbac48247c64d099ae", - "0xb5044dbe63680e5fb8479f899caf746b778524a6c6ef3f56614d3b9832cf0006", - "0x1d9eb2e2fd6d8c78a5a4125733cbe69ff25b95cba736f63627bfab166f736c18", - "0x4bcdb35310f9e23c6b952933f3adb4adcf6b43dd88dcbf80dc2d9ed4f8cea505", - "0xf934917c926b2c975bb0cf0ee0eec66727da942e06c65ecb1e168c015f957a65", - "0x7375ee9c763fddfbbf6fe47b1db34faded65f5123dd92ff469d03a41f1fc47d4", - "0x6b4e2a1c3ad70f07688662e228faa861496294b068e21f040edf90cf9d0230bf", - "0xa64458a7d295ff66658de59d0f166a55dec1f9e9e2be6fc2a8ecdcb77b72509f", - "0x4e50f8712edd21e913834cbf4f8d6baf9b371f0d4592a0c6a11f70a8e95ccd26", - "0xa132bb777e81aa07f8d5a6696e3ec6c800a1c0743a946618d04df4b0668f1c8f", - "0xa552543fb7ce61cdaba1d077338aa31a6b69cbc7e6af69cb5443e2d4e1393cf8", - "0x05c451fa47938025e4fb6835d09e9a92f2db33cc99e21b44b98a1f3b0c6071c5", - "0xac9628c769038d220a38801a43aa1449c24b2277df287b04ebbb4082d1763f7b", - "0x6d188b8c97ecb2e45ff51e573fedeb95083b40c8ae15042289753ae65caeb681", - "0x0de60d18d4f052a11a584be1c4595430ea8f5c943dea397da9af2d27518e2646", - "0x02c7e9849aeadc3011c2d36d4f645aa0d3f23a27d19a8b7eec61e2ee723dc675", - "0x2c974900dc848a8a0eea1e248aa0e2469037038bf9c0768e6e46d2781530ac4a", - "0xbb4b7b7d9ae81c7784f6a8e7c309f30a9794f0240562ab889d4113bb1e775697", - "0x463ece715ed0458cdd0f12cec6ab023fb3a3cbf6eda4b55f3b4115921d20df52", - "0xd535c260190be6f755d84d8812697c8ad8801533b939dc95e2072e2f39066564", - "0x7f3a0e061e646047bab6b8dfa88b092ab003c0e84240dd82f6e7d407bd5a3bd8", - "0xaf4803ac72aa8419999b383e5765544cd61b5ca0071f7dce952d7c24d89ff8af", - "0x1c53d5aa090bb88a8302fefb12080eba29c2f9f198b08b073587049159cf4245", - "0xf71ee084795fb52661d5cb7957c7e710e6171683aa691412d5c816a764f61f64", - "0x9eb207ab5d1bc7d1a44afcb2790f32d7c41f1c54a17b277dedcd8ba1e63eaac5", - "0x2ba6c0454e857b17903fbe79d6396a472216ddd825b81d70c696074291e71b1f", - "0x899f295af86c53f6c27e75e6cb98cf428a5da102be6dd8a8e2e59b446a086a18", - "0xcda6ada90684f614c967b6fa4c37e6159522e2dee2fc8663b6a8478be5238165", - "0xa59f5518f36b97d9fd077f736de67de7856d515f5146d5b1ab1b2a36112c6400", - "0xe7265df96658699ef8781fba631750ab18dc9d62c0b24820e0538809d046a2f9", - "0x4d9fe46ea3b33b6e73cddbadbf8bee4aa31aa830c4a1abbba4567f21f78a014f", - "0xf5d3147fbe7420f7c55f6b06e045ee7d2b2e0ac7f2040ebc8183ef24108ad70e", - "0xc8dfe6d026040fedb27da79dcf77aaf83fdb008792c6366256d5988e356eeb94", - "0xeca183cd9a46eddf04e02e0a82fa295b1f56322e5552a7c7f0aad090d209b9d5", - "0x8e26a0ad84d0c8b5e64b8a57eebf3bb86bdd02e24f24ac95c6222959638a3037", - "0x5b1cdf956d672b244ecc6bd5a828cec7b80867a4ea2a547cf7240e39793cb5c1", - "0x48c8d0fa40f9f6a49fc6378152972b85cb984ec221384484148231ef88cc3a97", - "0xccf14e2b03037c17bd6d47ba41460aa54c826e945c0132692d08140f156fd115", - "0x331791c82f8717e22f27aa77b7530acc83beaaf9536cc74ddb90533327c5072e", - "0x6c621acf6c972322182e5431049874a5e78bbaaf1a3f49219fae2c8425d6b5b1", - "0x5bd86b4984df838b2ced1dd0f3e37ae19d52ab1002a8bea859065f8cdaf6bc38", - "0x3143ad07e92a4b2a24b6482b5502ce98d50df46923ace4845ca35e0948090363", - "0x66e2d61040285db2e895e1aac42b69b41f556e6fa82116c1e84b49e67478abbe", - "0xe4f3a6c6761a3e17a5a978c69d0a6688439d4d6de3bbafd2b830b5066d809e0b", - "0x034280d368d7bcbe1f1cc63bd551c3ac2406f612f8f04801d24f98d89e75c444", - "0x2b9ed64e419ea19e5dea807dbfc08b8d21bc13903e8888aaa15741c6c0481440", - "0x72630a380871aa5ec67bd06bd672fb0128b95499582be5d34a4073645d15eb6f", - "0x9ee6618d35b3fffd4abeee984f1e9f3fbd200e5f60c562cb0ae3200b8963f522", - "0xbb40172754ef37505f4ce8077382eed0c45b0f96c882ac26b7d209b951d7cfd1", - "0x76e973e45252e97e2cb31bb8b79424e5391c3e76893cc7be0c1c1101bbafb57b", - "0xa4218614e301d35b94bc536160007b9b88acb5c9987a44a27c514f6456b28be6", - "0x0227fa09131444917185f2cc802ed389687a4f968f99bb221148ab7effd5fd5e", - "0x0a93fa4f9590996785fd599bf2669b290e8eca7f02ca06aee9582357293a8493", - "0xe1a277823bc99e602027fd18db67550f0d5e60045b94bd2655e49531bb152f0c", - "0xfe8ac01e4e478b4019dad76813449f8155de23b4ba2a6e2091f4c8ba82508bba", - "0xb194b4f530b832a2ecdc88c1bf40580474847b91c300751c810bc5cc408095fc", - "0xf1de598992e61dcc7bc9e1f1490d80d10024c6319954aadae6a4df4ac54ea564", - "0x38138e224065ad8ed4af813bcbb35535bea444f99613d686f0ef4ff00c5a3fe8", - "0x13e6a7016f28c856d777e1a7f54bce788a3e21b129cc1b57d8e5ec21e6522d3c", - "0x1c5d57d845f18557e61b1b3761d9452eb26aed8041a4a3073097259546e2045b", - "0x536848934654d65ec83f7cf9a0f69adec6ae974b8e5944127ca819a30a20b012", - "0x1653d5a4610454d67236e8049dcee0b1a531e25d5c7f0bbce913a6a524a60db6", - "0x7bb7bd63c5985b492c4897d59223335537ed0f8928c5c7383b5ca7a6fa3c3cb2", - "0xe4b8e08d3444b8e14e390e219684a6085fa335d11c1c77c530582e2c3c4c8e55", - "0x5fb6b09c1ac68c1ad0fd2041c27f1fad5a83906d4aea5af0f965cf36bc3cca3b", - "0x40034a02507258439d490a5a282956f9ae304b4ea4730ad6386005c767eab5cf", - "0xec6ae08d9c0033901514ef409a7cf68e1a682a202dc97c5c467259c7b6022e2b", - "0x9082855abacd99a2b634ad1f50d8517b0f1b091cf5c649ba377aa3ad2eccb65e", - "0xf76c0b9744305baeee70b1e274f7eaaf3670b2217fff6655bf69968b5acac517", - "0x917198a97cb8f704471f6500aef3e6f014b09e8da719ee03e87f45c95605f2ae", - "0xfe1a48d29d6ddaec284dc0bca96cc874ecefbbb91b74c8ea6030a9bf80470c73", - "0x9ba5c60cee1a7d901f9832e3024ceb9db24460c6636b98df81d008d1678073c7", - "0x7cba18b1ee4fb25f1536708ad3f4c95c43d60930f67dc2cfaaffaee2f91fe1d8", - "0xbd2b278edd0e75c6a39aa2f43b334d8cbb52900c152b2b8e3ccf7f27221c0643", - "0x65c3a4efdb5a189b46db8b8ab60968f6c16c1b56f9f2311b3380c275b7914383", - "0x45de07d3860d9be6f7b90dfa928cdf0da9592c2054b00b774ba7608f3d99324f", - "0x91a4389a9bd65f3dbaf092a5a49f0dc2333bc5ec7b59c3a48cffe97ba52213c0", - "0xff9342e526815c132251c3202d20acaf0012be44ac7c47f7640f27fb6f2d249a", - "0x48854fe3580cd19aee63f0eda576f1af518f3ebfa9f87d24da87a89ba227acad", - "0x8d292c2072d5ef4f3ab12cefaa60e9b54433a0eb7303ee253408c19394345a4f", - "0x48007c06be01f79cda41ea5791e3ef4bb4e946d7af262b52cc74eb3e20e98a1a", - "0x36a39e5a3035ed57c8227571b2d57317ace61cb9c66dddde57a566d34eb7d894", - "0xca4446f6cfc51f82ded4f4c798da29fde3a3bfa1f30de6cd721ab459e570dcb2", - "0x82812417102865e04fcad17c1682c7608cfcb855267b4ecb8c1e0666537e6a9f", - "0x81ef7d9794f8bec6b04ab899cdfbf3ff735eaad06610258ef7f90c77c83d5387", - "0x4810726311224ee42f1969465daac6f12516fcbbfb26e9febf221fd8d1cfb41d", - "0xb39a309cdf26f5f2011a83a0c1840b61cc5bebfda385a479a6a20d872bd082bc", - "0xe5002eba07d8b69ba9470514d286ab800d28b443531349d641d9df57c3cc1399", - "0x662dc062bcbcf4f45759c85e8a0ff833564beea1ff3894d7c5286133b3615a9a", - "0xb2cca2f7a62870673c70313efe23bfdb57ff9e6bfbb9e73948288fa15a8a2f49", - "0xd9e38758784261f67700452e23a59ab25cf22dcead205a50685d5cb03442c81b", - "0x039acba436cc8d99337c16969a076577a50d609cb2986f42702199e3c2dfd8e1", - "0x7141bec6010aa3d5ad1d543f91a8b10ba3bdab7625fec8a7d404238c09893e48", - "0xe0a2f776956dd92600ed94088b7da0aa416ee83cef35d37063d3df2d3442173c", - "0x7e099f882fa8909a3f67cd5950346a00a20bd0678e7ccfaa03395bbe1a7bdb6b", - "0xb52e8fb670f5386581c89d4b01b0bec691b9e828c9fd8916708287b6c1d49f26", - "0x16b599c31ea0a2c2c23e2845cea74c73fc892f16a2b34091ad9ffc5d03e7f609", - "0x4c04bcbce2e30cb9fa64e6c776c8be2a4cea04512c9d70e2a5d8a377aa77ba76", - "0xad1f20b7e161337e3d7aba00d9dc3585569cd8ca932329b3df13fe5f23574f70", - "0x2961a4a19bee2dee47d9eef2f875e03fb75bbfc30473604c902e76c76620507d", - "0x666c0d915622aba83912b23cf5e48ac57219a8e592f09f9e224af94ed35cac7a", - "0xfa6e99ccb3460635ebbb7ba53b332825f9d5185dd10bc1e2eff5fb6de4fba746", - "0xd3bc3b194941ea52e2b31ac5ea1c789233dea804e24c15000332d41f8bb4a8c6", - "0x07281b9f1ab9e962d46f05c76f29b4f4ff3db35baa777c37c5dac6cd33d49a90", - "0x5bf61ee56f75630605881d34c11fc029f7c2eb96dae86c7dde18af8e34aa6c77", - "0x972d651e4903b97eabbe5a58440bd248eb2ab16a536da686a707770b88612d00", - "0xc953d9cf8cd4a68d7a2d9dfdc3bdad8bd0d511f63cbb2144af7227ba49084a71", - "0x9a90ca2c4dad5386cd71110de906f6d96f80934661afba440ce194e44e5a6036", - "0x8dd2c27d9b327b1a6e2216f561c09c276c9db44c3a87e6f8fe381d7a906c9769", - "0x17362077544107f34233c1fad77f12c9140d0f0f0a5206dd887bb9cf627a20dd", - "0x52afd7ffe299cbfe5f418612ecf625ab1c6debcfebc6bad2569c3b83aa1f9f55", - "0x6597cfda3deb8371e447690b5f90df042b72095551d347eb77b2ee55868634bd", - "0x97a7278a76d38714f16a5b3bae0910b18d2851b2519ef5dff0a791f471cff90e", - "0x0f4124bc20c9553612a8e78b90c80c1341a3a290054c75326753be6a103dae22", - "0xa42039e0a42da736e91ffbea82e58beaef7fa7d88263764611b73ed4775e222f", - "0x13f6c5b099ba6a2ed4701a8b3edd76c2645b68d9c2cf9af924da39bbaa2c18c1", - "0x939ddea54fc48f8c8dcc1ca6c04ff2cd70fd8da9e93abd3ed062da56b75a1110", - "0x3e66eecafa70c79675f26d259fa6718c646ce3828e80652134b792f0366f0c68", - "0xcf507596184c9c4a14286412216f771f0495ea5780bc372d12ba6e8445c67d69", - "0xee64dc03e5fa815ea5e9e3e4d2c87126c8e4c0ff56f1152c349e3f9327fbd5f7", - "0x3b6ba90d23473ab15afa76d95b23b2a86309b0d6e2edd3492c374020e544c820", - "0x51ffa382078573a9bb41ad67b775074ae41f9968e2b38341ae9a64a9f1f74815", - "0x6c3a7ec03f93b7d4b73d8b194ab38a23b512a236731b5e54b8b5bcf44aa05608", - "0x0082c925bab49c6ab52f9b996986123039fec2cd6641dcae3e3ea7d60bd7a2e6", - "0x85185f7d346260f24bad3c767a04bfdfb3356f61138b9fbafd7af0f813e1ddc1", - "0xeb5a6ef56f2926a533d3858eee37cbfb5b37e8fb5bd181cf61448e36d8b48dce", - "0x700da1f1e9339d6d55c54c62cc5523c30901162216c2f182f5f2ea66dcaf9620", - "0x84161dc26196b99ceeea8d64f6ef3d127982b934f49678f6a512c07534e8ab54", - "0xca3f434ced785e9b5922b625e1d2457b156372e4917b9d6c8f4f6a995182a176", - "0xaf62ff81c29e9102077eae515015286765592d454c8e15b0a302adefe22e998b", - "0xafa0ed60bf7417e6f74fa7a9c10ab7c7b0b1e94b699569b0e3f70ab01b234ebe", - "0xd2cdc3211869e030c3e291f4fe2f163ef54b24d7ff0bb4489d73a5159ceb461c", - "0xd74c2a92d3c506bcbc11c1bec086cc419fec1d0bca34d50b74b28f89e86cf864", - "0xcc25ec627504ed9f00af661c72990a36a2f9ee4c4507e5fa4def89303456d7eb", - "0x8edd1c1dcd064b7c693c978152209761cd6c92e449e9444e9dee807fd9f9f420", - "0x660e691453e374d0a584b184a5fdb85894290e1ccc68964a8292db53ca096505", - "0x9cc340e9d997cc319fdf2e00c75d80b80953a90049af766b1a499846c5e08bc4", - "0x58e650852eda00e55bc2d9e024a49b3b7a5d6d5092d837407114120ff143b75f", - "0x5426eb6b6b8965e80dab787befc815c6c430e80231e91fee5511062bb21c3e4f", - "0x4bb9b4512664884f7b63bf27ecc75e0a69e32cf2b980a8b9135e410871ce45ae", - "0x22438f10926c874196f8c65e274d018960cedb55ca43787e18adcb54631df7ce", - "0x68aca6a2e6a51c8543939fd10be02784b1149923652da3f07f91999b75be995a", - "0x12a77edd8cc051f6f991cd3912f5f4afa1e797f5daf010ab17b3925220b12e88", - "0x0d3b929dc2733de2865dab86cf42684e8430c2ed47d19606637f932caf8d2d13", - "0x69f8d5c233a251c35851354b8546d89c7c54012736440c8965c256cc9db7dce7", - "0x6757e97aa449d7878cbbddeec490fd0636b2c51d5b00bb61eb4836685d005d2e", - "0xe1029b22f6ded11ab5ce46aa2594ca90006a04e8848f4152fc40c27735217ac3", - "0xadc4af259ba86cfc93384f3c0eea61a4b661f015209064254bc6ecbcfdb74f5e", - "0x02ff4bd0ca8008db90a121deab0c36e45bfc7acdaccaeae04acf3aaf51716607", - "0x9df6ebb38ba3e1d0a3a82f871bacaf81152bce32265c0eaebd9d9e6026665b43", - "0xc25503a6058ef394c48d1153ee2e70a3d8e86e0a46b29ddd0217906d694a71d8", - "0x83698b68d762e75476caa87411797ebc0050f9296ec35664bcfd3aeffd01d8c6", - "0xb185832a5b8fb209b9a6772673cebb3dcdf3d915886282d6adc47376a48fb578", - "0x32ec2d0710f9681d75819f1e2c28e135b3272dbf1da08e4d64ab2e6ae1064cbc", - "0x13c8aa9abf04b6ec2553b171b58356a1c256563406ced1ff3c84a3ffdfb5c1d9", - "0x80aaed5609e1b594b3c54403ce9977dc558ad292ec472ac73c8d7f39243e116b", - "0x8cbee772d46586087fbbc9b4fe2f54ce2405d2483572bda3c2314e79ca0d8deb", - "0xfbfe6a938e7bb9b05d889f8182e8963344df0ac7b9022302b451b036da261f9b", - "0x39131379b64eb550fa0a2574d504bf7de0219d50e6d55cc82998ac8d2684df84", - "0x5fefe2fe1d509eae61cab218f1bd03196b1e631f5c416e5f2c0e9e54a3d44d98", - "0x5839c1c6580a4c04aa09dfde45ce4616b6f30d1ee794dd12fc745b96b2d48c84", - "0xa75d2328c4e63acdda579000e6df9be72d9348c2001e1927264b1a8c303fd292", - "0x7331a0cbfdfdc200cbbd1723bcad1f1ca6e0591c1ee025bf1842d91e4625c8c8", - "0xe9153c020aedc51102bb9b22a2493db4616364fce9b61681287dabeee881130a", - "0x53b7aad781bea92a14b670dfbf5acd8a55d2721a6146f099b904bbc176771b91", - "0x0de55190007ddb76fcb57cebee9b1ec60d52d150ac83beb66b088a86a234f9d9", - "0xc703435d06a2e1c5e52789daa3587b920cc2aeed658907bb7d6442693c65902d", - "0x6d21f9a28fd36d865af468e2c06ef5f41167f3014251a53aa1d2ea55896ca1e5", - "0x6b24cd5b8a48fd9dbe7e8ea6c492b57f3146009daaa108ae5d1199261cfc3914", - "0x40e49643d669f497785df1e601cb1bedc24ca348f86354d4032b1d4a4c6776b1", - "0xc56f0ff0aa22fa1e19d8785aac33805f7a7a01b48e953ebb126a4728cf502518", - "0xdce90cab31ee9f5a345d03464c69cc5dba71ee601bc22ccc8aae1eb442f3b29d", - "0xa551b514490e45b6669024b539f7bb37e6883ec97ff79744cf1f1c2ba1d21ec7", - "0xbadc6d33cd58aaeabb8b62396e102cdcb6b1ce9dbbf7051f937a890a3f69c2c6", - "0xe544b08143014287bb8d917f66e8f22f2a6deaf6ad4a3996426e2186b8bb56e0", - "0x6ed9b64beac26a5fbbd15c09c7eff96652b710670c2ce52a6856cd998521a27c", - "0x48c14f31b1fcbe0deb7816771f962cacbb7c2c219518f3ce52661a89e9928228", - "0x425fc1308118e8ade59df07136948a210786f8b2b6b0e51ea01ab06653822693", - "0xee9b2ef0dc1dd873a3ccdd77046969a4ae938e5ff39695b891c85921883c3277", - "0x25066a1abffdd64dab20529436c3d9a44e6e837d70b19847e355f63b5140c5c1", - "0x7441baf6efba832751b31b93c9b000d8bf552d0328415937d0a3c78595961ee0", - "0xd9219e7f07c0808d2596cb57e26793c1162ea9efe58305e3a26da6fdd57091cf", - "0x1b42d745a54c5e3c48a4911a27c263bbe42c8f038c826975749c1619c2e21cc9", - "0xc5abf3dcbcee854b06836237de3a461d86a8b76e8081926ca3078531e25556f4", - "0x7eafa90a352f95c8eaa914cfba0aa90db5ab1275d966da5fa445d9dd6ac6e0e3", - "0x4230ac1a58e4d9903022416041d5119991f911b41702d43c1caf0723cccb1d05", - "0xd50f2cae10a5cb3084c9f5ed1f9acfce8fdf3d920d89ef41165aa2522b97582a", - "0x6eabcebb9040f7d6791a0a560b987288d8246db9140b5f188c34a6be7fa17552", - "0xbbcb3c36f228d2589cd7097111ecd708e419bbe034ee6d9aa691d483590750d3", - "0x72eded80c21baaefddc61ecb70ab76cfc68ec8509b4f8786fcf25d037d75385f", - "0x2a01f9310e3116bf3527cf90de19bdc78d9cc677ef5c9bba94f3ec321d700a7f", - "0xfa401d300fed7092c91232a2bd8b0173ddb62b12e8e96a5076172abcd44ef858", - "0x984001b77e32ee2ac8d5678f77e6c425e6ab9fb2ea3f4978b6594b4499f893aa", - "0xfce80ebf8039984ced85b45b5ee5c240df0a6aab809d6bc0974a5b1007c77d4f", - "0x0a964a69795de761278c68843100ee547edea07d790d2efe64d975b65d415159", - "0x5ab1dee36283fc991e00fb52079c232f2d9bfa97377addd05c50fb06a09c11ab", - "0x47676449956192bbed4235f3162d06ba3095aecb9f57d9c8a273052278582fc2", - "0x4e43d79f07711fd4d4a8dfc576f08d954b5d6829dbbb59ae4386b34221472966", - "0x8f5cce2a573190694302db226a2b22a89f4487a4f509ec1a759646d0d5face7b", - "0xe10a0419bb270359d2c190014afc1fe52f8df9454f7a8e0fe205309e5a3b33e7", - "0x4626c976a572110230c540dcedce33a5bbb97919867aaf0520128ceec2e9d8f3", - "0x057b497c49e4b2ba614280de64dd91118172ae4b4646c3031a93fce200c8a234", - "0x8350ba4e211602c38812276000b1caec40dc4376176afcac43eaa96d7af30d1f", - "0x9e93fd7b9b9ca98f26945dd5716ee2a6274f8586d14f05854a0f7f25c80541ce", - "0x9f11403407548c359164f3f93265f12ee390ff3b3631ec7b90b98922dfda2343", - "0x714cca7ddeaeaf302fc0ebf50fd072c89f063061ea329e67c809d62ea9f5fed2", - "0x9c088fa9b25f7a5ca635db39b3c95da6859a5941eb1ae3e4f4717013fe740cba", - "0x634542af50119e4adb4d72bec5d0e3b095df21e76865f683346e1bd544922f69", - "0x2a1fdccea29581063da7db3f2aeca7087ec646b11f1d47e6d48d1dea0122fdb6", - "0x156e283ab987a5da12710b459097b5fe3d79db296551fa289632c0d3f9b33ba8", - "0x3eaa070ffd835043d4b2b25d5e7280f030c615b2bbdcaf3ee12a2b2b4c620747", - "0x863d5bddbffaa9f0ef9f696ac5a7f91191b5cb52383e1d0c0e0d5a60332c8728", - "0x4e29095ca17d15099abb1c6c1eb43cdd6dfed160a7d11731f4d1115beaacc7b1", - "0xa46f6ce03354ca96ddfbfa9e1406dc7ab99b0b4ff1ca5e0346f3ce91338bafa7", - "0x9f19f494df488b250ba31e243c9098fbb7db5801a3f76b219d866bec32d009d5", - "0x763dfe2f87eb816d1bad1ba95448619041cdb3cfb1171063c043d1e02d9f6ca6", - "0xf8ed4dc0fc0c03b964eede54ede5e96a940cc85e1ef2191c11465f2f1e3f6f0d", - "0x04f0d8ff18d26b490f137f23144c1ca0e475e74a7f1599fd2f6a4972a3d1c215", - "0x012ead673926ef6b3d2cbc5332a7bbe5dac977ada6065313e90975360dfaff3e", - "0x773ccf0a297a22c43b29f1bad214ac9e3685a5d0bf1df7d49fd4b92065ee7b04", - "0x10b7f56b8cc84f4be7533ec00ae46c7ba852f8d093c889b7edd46d36c819abae", - "0xd70605a437bfc6a4cc3468f0eb6d59b293d4ebbcd7979eda36f02baa48e68d25", - "0x68a93b7685277a1ca51a341517d10ec1f03c3018dc4d99da00624d4eeb3db229", - "0xef8aef04d3b7771e8519952b4e067503abe6b2698411299edbe7dc22a79c39b7", - "0x8e72feb3f31eb9f13645a089efd4eaf6871bec26a9ee91452db0464a7e6bc5e6", - "0x3189fb0be615c0f2e2758400050e2657e3197546a15039e595b091cefc9e0d7b", - "0xfe444b821fdfb12248cbf371192783e4e0ea0a938f5ac7b205e15cac991b6c98", - "0x0329c441b6c6c56d76de552ad43596760d37262011d97bd91e595dd559e53de2", - "0xbecff3658ca19ed610e826a68621e7b5cf2ece293ff13fe3f0c57c3390954af8", - "0x695b87703e7299f3e862740bbf47ebf026e5330171509fa0927c361935ff612b", - "0xf90373fabdb83b403f67cc50d79aa37fc26d73ce8fda798e96c4a4b17440e2cc", - "0x536eee69a1cf54af816f4eb5d08ccaacfbbaaa165451d0a5e8b93b2e872c59ec", - "0x17b56635255ddc2278cbb7e7139cf7a8f6e2e55581c451cf53b5b53aa89f985b", - "0xb4a14da295a0cc51076c48032fc1cdbaefff2380a428eb03f6b068aee99a8fcf", - "0xd3cb3797197a398711299f816f34b7c98aafc8a845298287b4522cb0fd645b01", - "0x55aea7b1fd7bf0864b577e38a89c153ae8653da26c72f53a05d164b9da327a67", - "0xd4eb63ebc06549dd7419012d4bae13890716430efb843175a9270a6c517ea612", - "0x6958093bd81e477479a53443b0c95c11d8791b282d028bd9a6204af0c1f738f4", - "0x505f55a445b93a2ba8d5ac5531370e2bf760db44509f15d2f243175b12a7016c", - "0x4608a060b7bf832310eb73a157d285ad824b07d78bb471ea89ebf421d735d566", - "0x68c88d220d8ac23e19459d650594dde939aedcd75325ca2314b7a9419b938c37", - "0x891a1154ddc1e3239b1100840e1303e0627a53ad501996e56891839b54becc93", - "0x8b943abf7a572dd64da3c4e58c1f34f6f7a905fe7ce652a044ab8983ac45fced", - "0x06b07efee0be55002f485ec0526336fec4a7f825ff7eda3f954e8cc7068207f8", - "0xcafe52ca4b5198fb4e4e24f4c04ad12eb8c9f3ebf9a35ebc0014e25dd7bf5970", - "0xe0ed792746b780ba8e19ebedfd3922ca937fd5b8c28b03e0fb91789cedc0fafa", - "0xfd7ea98fb764223ca3c587820eda0a0d68301979313ea9cf0113508a05fba7d6", - "0xa874e6edabaf6da36996b6387bda14d12c3eafa026b1ca6ad5f1f4cae67855ac", - "0x29d7c85005517eaf1165be4921deea5afdae1f66b670d7de0981c4e502acbf1d", - "0x949318f8059937f207ea564672c86943c2c9bb86ca81a3b0a9523e7bee00a5b5", - "0x200dc199c37d16b25e207165c5576596266ce8b62aa8a9c6cd66d69d52c1a67d", - "0xd29108a106a8a5a87b5282467a0e8d37f74c2ae53e6dc11ad63005f3f3f878c4", - "0x44ebfaad5b4ce81fda3d4194c87b46e9e31fbdbf0ad28fe00cffa73f78d3957b", - "0x6843e2f6d3d56b55251ef7ceeb635226940dfdd698215f5d5a4c3e88ede5c0a4", - "0xb84d57422889adc19626aad033b38b6968aafbf4c6d0881a0ef5fb5932c6ab44", - "0x842626b82b93a54a3a1765ef6257a0c74e1ad2981d8da41fd8305adbac99bc76", - "0xeb347385fa0bb37b8d5d17ab60e6c2ed4bfd19210503d61beb88b71d8bf9adda", - "0x509a54bd689b7011504e835081bb9d3cbddd8592ad80da399689bc9172b48a27", - "0xafc5c51176c7222097b12310a3ee5513a7660491682ff1fcae5d168d2c19c3aa", - "0x406e9fa3f6687fa6519067e213377a5ff7875f6f0a3080880536ed395555ad30", - "0x2624c181d4ee1775bf687b522a36a7b9bb754ff6e40ef12363c7d675b60f3d04", - "0xd5c32eb980158772133a99d0af96e056726ed89be84289cb5fc1d083d48cc407", - "0x7b1c5cfee09aba12ae0742d9bc1cc2630bf8c1e141033b18724a524c2c1b7c2c", - "0x77b4b55b236cb7d27c77063a280eabbeba0d7171759fbf851f40b6ddbf7171df", - "0xa04791b79cad41718cd8a0bf604b0e956aa85230381070f842667d88760c0de7", - "0xb1558e574944d9e8910da9c34ed51d89caabbf6541f077a55ef2ae3c513a1e02", - "0x3ef8620edf05514c4e90c1eeb0a896ef30573f963a7507ee90eb76e4334412b3", - "0xfff99365402379af3e56fc9b999d316cea7a1f388623433cbcfef0ddcb6f9d4a", - "0x99fca466439472d08ea602bafc67d1d097e486b5e41b5a059818021f612e889e", - "0x094436d10026f1c57f04846690a0444646b762eef1fc0420c6e3f5cf5b845e14", - "0xc57923978a9dffe0812618f2f6420f30ee927658f9f1615ef7cad4519b90eda1", - "0x3a20d5e138cac29e3fa031847086bc62e5f90a5e363a70fd52e2602545faf9ec", - "0xf3b0bd1d597eb2b6ad98fbdcec7dec2639b92bc83c33db4fced5d23e6ddb64a2", - "0x0d5bbdf1dc7d52fddbb3e81e2d757b848f9e79b6847ee8d30352d4b01ba927f2", - "0xf8f51ff9cfdf6b2ad5609a68433c012c92cabeb3053335d784b1baac087516b8", - "0x5777236f251506c22a92f371e4ad3c78bedae22c4527ed5e796727512bc2b8e6", - "0x228bea6da7246c2dc862d9de97bbf824df6396cec583a4db71667306c5f6a02b", - "0x67ccfda86cfccbb139d77d8d2acf0d4bd980b507acd9bfdda6b5af6e10493df7", - "0xfd8f9ab200dd111c04803f62145fd82e6a79221776904be20a90c1c6328cfdaf", - "0xcd8ce973cbfa8a91a55ec09ac9acad4cfdd050b598349b996d252ecb3935d277", - "0xfe8067acaad74db589275d3122d84f04f717cfda870d444872824300ea10f969", - "0x4112ee457d4108c37121ef4ff0ceb1a4c7db3a9e3776d647225bf0838153356a", - "0xadb045193cb85002f2868c1ffd672bb93e60ed2841ad368bc8399e92c996229e", - "0x4243b3645b99ab1468bc421309220529d8ab204542c6901ce618ceb32b93becc", - "0x434e3c4da46b052402d465220e27d0e243bb5b116967d4baffc9325e326c9900", - "0xceeadbd91caca5832cace1624baa5f67b0d18f725627702cbd7e19ae3c691712", - "0xac54af2cdd95c862b3d9115c9550231f75ca8d6f6e607038850892daf1dd6643", - "0xc4ff21314ba2cac393c67982362a39b7ec96192fe37c316bdd4cbc692f729ffd", - "0xc84746b891e6dd8aac32b2ed0b373172df4ef375afe7e4ab826532b6b3fa9680", - "0x0b0e01ec97c12e488829d13dc1fd420c08475dc95d1fcd72c066d76220af055f", - "0xf0b54fcb4a3e075f391bfe937dd6b4f7481877182ddd4413e8b70efc63aa7f40", - "0x1a78c5cca33184c9e404a05f61cc56968b924d9d34b7ca6d573563eb250fc691", - "0x37ca206f795c02f45abc34380d67b15aa48122444fc444d4b307ab2f7f30a9e1", - "0xe03c444efd29f8d7c89b480ffbcb996a642ac6205ae43bdbb815ba1968051e36", - "0x2fcaf6ef7c22cebd36ccfdb037e66d9113d0965f3b5b89d597d91b490019471f", - "0x11a06d63b3395d09a048aee4d4291c0a6ab2d5f07a7667362890ce647153c2d2", - "0xc33a74c178ef5460b53a9a81aee02d3b42612acea7adb853ef74cd6b65f36efe", - "0xcce38b309fd919a930d38c7c7a7bc828e5039c22a7f3f858fd99c5d44b8cdb2d", - "0xc470e1078c305a5eaf7311d7ff652e24c9dbed83c3572a1c2ec7f6fce5788b0b", - "0xa29b6d0bf49a64182aebecc190a9a0b06931096d9984e7e6da9800ce17f7cea9", - "0xab0821217488504e1c255343939d109353c79298b04c69ff65152dd0e934022f", - "0x40c7bf4dd5a2d39c0dff9fb3bec5c8247093cc1bd55a8087d83f5fa7c8a35b31", - "0x3387ef8b199a2656c39407d503b9bd1571714e178d1dc7b1a74bc43cf88ca201", - "0xa5b2b8b2d708d97666281684641b611efc792f7c0cb27e053eb06752661b35f3", - "0xb604a4b7c3661098d4644239295cb9f6e456854651a5b289a2f4b65e33964232", - "0x4bf93500c257f054e6a6f993f344917215c9c943589644474f5cf98950b8fa46", - "0xa9ae0b7679a65498eeb2b460fe678c3452043bafc344eeb393ff1d930dd8751c", - "0xf21e50f55d7be256d14dba4f8909879cdaa3926b03da9ffa0c63ec3c9df34c48", - "0x88e1e824c968441ebf88b31f7a24fa5cd4e8985ec82fce5eeb13b3a30845e146", - "0x85d5206b3136bee840dbbf8d3d2302694dca2d5397aadcc34e1c1d6accac0354", - "0x00f68e845a2331a0704037d75361831d5a0079af3c6186ecaf256bf1da923c27", - "0x64c594c02b35bd5f69beb236ccc08140838c30b67a1576d2780123e29e073849", - "0x93f6540af637f1a630a8aaeaa86d046e09348320ca5103ebe2222f747a5acfc6", - "0xf9b4b9461b765b449191c7ee1acaad88d4dd7260e2b826c75d506a908fe71e6b", - "0x86aff1c986fbad8da2ca9de6315222459e9c47c58fd7f1a543e6719c566af5e3", - "0x68629388371ceb2a08bf7e335cde88a1bad7127990b44135058d62dfac258107", - "0x9b81d6745d5ab0a3459d26b97ab8f19fb38bd38c758a0ef106a025d091f6f9ba", - "0x2b42455bb30c387315cdf205a8a178ae4bd2d2e221fbfe4be55f5b364fe9a7bb", - "0x555e4dafa7d5d3f209d70a5c954da144ef231638f4a63715152bbfa4fbf82b4c", - "0x5d779a8f08d68794723fb5e95bafd7004685ec21d2cbae0e5ea728b36418dc36", - "0x7e5163ea9b1c0494aa997997422b02404a13b690257757f87f69bb42f81ba28e", - "0x3814efbbbfd4001641da7d5c93483f96467d55aa8b5b2aa6f980bb12a0dab6cc", - "0x431b7452a8157e3a6cf89a5a85d22127a1282877750519a8cf95e172c654c3cc", - "0x77ad2749e61c96fa868c7764ea626baef8a1bba56d3a3106e981869f9736ca76", - "0x7c069d14a86017ac36cb9007fc9bfe75ca92cd2522dcfd7bbf9d85c5133ed8c4", - "0x21dd48139667872fa67c98430f68e8d38c2948f19fff534ab2a5b8e0b92a4d51", - "0xcbc2dad5151367e6533963061712ee325f08e7df3cc7fa73eb5220cb32a2ec4b", - "0x398fa6f8d2b76d482a0c312bbf48ba8dbe9fb8ae06245da60ac68ce50f42638c", - "0x4ca92096314fe1d2d8e07aae3df39a6237e718c1396e88f3c0b73fb3124c89b6", - "0x3ae030ef952e2da7b29aacb08fc41776a44fa5a6c42e745d8b7991ff82566730", - "0xb4ef4b02dc130cea24a71a6053639238db2db30d4752dd3fcab1d98442fc3f94", - "0xa6256dc24acc6de428f47aab0b65a1f36855c7f0834a3e730d10a3c0c8d2bc49", - "0x9d8c8bfedbcf9552ba9eaa08a61846c52e240ceff531e7b19415ca148781ebcf", - "0xc6737357b53db7d2a14d7e7d4130fe6a516fce1dd0c7716be6137d93e21ceae3", - "0xafa9d3182fe6246f6c8d7b96852bc5dc200e8c3a97ce7d262a18c2fdaf5bf2b7", - "0x8064a1ee1eb4ddbf301fc983a03fa2983bc3743602bbb96d7fa6ef85780ba79b", - "0xc4616fb2fd5381efb37719cd9998c5051966b254abbdbe12228b2210c6f79116", - "0x05c30fff77a3d751853e3ae4c11678755c0afea16480a94bd99d61ac894300e6", - "0x47757d0104771c7e288f383bbbab1eeca2fc752d11989674305898e047a71bae", - "0xcc0f857a7617c16da7d35363cfc0af0ecccd9b1870ffdf1a2b2e2224ef81f876", - "0xab3a1b65f93df60eaff5df9e0bc1d91152d34d3428961c207f36ac3a94f61257", - "0xd0cd178507f1c3bdcfb7b528933f2d6227933bee2614636f3add19a66cc089e0", - "0x6379b65e140eed64020f496a95c36b3c27ea10387f78e0faccc5b4018f8f73fe", - "0x3b6977a571ac8d59bde2e851fec4384fea35a8d3905735fc8b8f2a8cfa6adcbe", - "0x2f193712529ecc908ee0a61172ec7839a9168cb424d8f108e7d7cc356bf20cf6", - "0xfa3e48832d13748aba9128bf6bfc76652cac371e49945fc33c941a9b294f7033", - "0x7086c7711a91271d7e38998715b4a142d7ec107accecf29f4518efe9f3333c4e", - "0x05c126586f4a2c1dc5814d07f158513d42282726918f71bcd1b4e0b67ee944b6", - "0xb7cc1efbf6880a60abe6b20f80bfe2ff3aa59de805ad964f8a7c5ed3bcefdcc9", - "0x64189964cba347ac35018ed9169ae64b78c3d0430145017cce83d78667b648d6", - "0xf6b1d09181b9fd18a0efa47c15631a6aa0eb01613a5fd1068834c4079e1a95e3", - "0xe760b5c16aaf587bee263f348f9adff4e04628b94ef27c828cc7155ebd3ac902", - "0x523a2c0fae8b2408ffe1c3b43e0aa7991b82336ed136e84c3f7d458d31143fe3", - "0xcc6d742b22b4fe3f41cf783a2f6f8dfc97a4b33866cd4bdfb27b05bc2ed39162", - "0x4d4ae86d282ec414a574370458c99e189062a3a48dc59a8e8e2a44790ce9b841", - "0x6fcba6a9469de1db92468f2b58b3b82c5080698aca4403ba8ecd1cfebd12b657", - "0xe7b584b0bcca0a5a119c8b2cddcc7a73c94f6f6a58503ddba7b0335815302f11", - "0xb1edda9625ea65b96a4485e10c798c707f6926e4ac2b51340a6f9d212a71a737", - "0xd8e2a94d4c0937a2033dc3b70b50934cb5b2ab54f57336cd6a8882af9f14b8cd", - "0x93ec08aaf09bd453c2b53cc7d9aff059681e0c23044f99569d0ea649cc7b885c", - "0x8ea82c1ca6be16616b62a8dbd88c75217470092063e0494419a6a926279230c1", - "0x175d030004e718f39b3986daa3beaf2e1a523583e529d6e90d117cbc844c647c", - "0x34cfcabda8b4f51cce74befb08f6a2e9ce884175f33fab59f26c60085ea73a92", - "0xd0570fbc17dc030bf6e7e3619d56ad2e866868939e4e5b23258adb191997b4f1", - "0x83245688ccb6e6f1b541930a3134d3141ef01a5f9b3f55f0321039b9d4a3cc1a", - "0xd782158768560d84ebc21d8e4f270f30055203b2d83c46ccf53ff8890e833fad", - "0xdaf31d5afb20a502b28329ecf1aadfdd16b4fd9118b10f9bebfe6f986a902dc1", - "0x0e24b26cdfc345d98a6d6dc3f4e3aa2629aab6fb2ca3820a78d58b10b09deb72", - "0x895f7a9b16ef1d1933c009b38a35a41632d00735a906b035f7fbdcaff1665295", - "0x70ee8681968778cb7da20dd794b75f08eda6b4b6e4aa653464436ff3685c6186", - "0x569f51cf2b92bde98085c2c167b773fbb9917a35844059696a1a97e378b5b577", - "0x4ee20277fbe5d2e616dc0b170e40d5b62cd8dd9f058c648e8e0d636316be7e00", - "0x1224d7eb3ae847458af472b19d3b0ddb90ce822f3389619487e68f3ce08cf6d7", - "0x57fb6d2ad5a75648449c99a46d92570b1dd74757dc1c0c11fe4923748eeb1711", - "0xa4ebbd26ed7dce135ce61bea0da82b8262d4a5319a7ab9c94527a7c670752b67", - "0x1533f0c29bd8a7b8d90c4c0755fc0b018439291566dc33bc816c8ca21269c63c", - "0x9cb5a5d41061a2168c0a8175d2712cd82d27cc777a015158c2fab0751e192d25", - "0x479f0a41aa04509beacb2eace213d9375393f583d384dd4e69b5b921c681c845", - "0x5791638640c821778349fc3064f6c5215f973f2b4f098ab38fc2138f6a8700b4", - "0xaeb1dc9ba82aa0c9ef266d1beaeeb5c756fb497607ee680c0a161b89cec21d26", - "0xb13f56956bc48a6b0760639488463cf403ed47f6d94c7b6e5a6de1d3d35800c8", - "0xfeccfb58d300594be16cbc9b5502ce851de36e15d62164317ef6e3dd9d72015f", - "0x3b218812b3219e243f99c6d23f24ba2b70e91b6a1e9bd27a5d3c83622c176b2e", - "0xfc8f86579345c5fba8e86d1263b3e9d01dafacd0c7347fff348c9a661925180d", - "0x50c6d100a8c0977d24c78bb58021df17c880a36f1ed118a0806d1aab347e3b42", - "0xd18166f82e90410a556744042badaebf3282c65d3c1fd81cf7e599695436b2d6", - "0x8f47f418fa13eee50b9a97781a02cc6a8b6818389f1b1f9b94aac17897ef1bb4", - "0xa4b3f32d84a547f66ca91ec35deacb2d5cb4da741059c01419b60b8d526d8a15", - "0x3187128246074cff2e8c0928dfc6b29294b0ad3f2ab839e7ba6d0b72f4f078ea", - "0x213988ced1828cfe0021da680b166b7d830b66a795613953589604d09b58bd5e", - "0x343c1581b9d75f1f72a787a29dba31a73384364672f0a06ec6d675bbc5b81beb", - "0x59a9da5a92994baba7e27688505df673c7131f4de43e6d174389124463eaa0b9", - "0x15c6b483253806002ed293f89d86d66314e55fdc32633f3e15dbd73dacdbde1b", - "0x01c22d029f765b941eb772991d3ef50458319d49ecd1e237ae0d61a05b7ff0cc", - "0x62f5ede9e4ac720b4fb34c239953b3289cb77e4e7bfb5268925727f5d21f0c75", - "0xe330297f6aceac790b3f4741efcaa4e58fbe1c61dd52c1d9bf99220803132553", - "0x47073de2812458f45fb789cb1a6d57f9ae772a38deb7dfd4c8c21c383cae3cb4", - "0x9e5dfc6bfe32b5f56c9799aad47fe1a01746fc9edc5d8583dbd1c0a1f7f81246", - "0x1d9a6fd76fc6a6f359fd917582f6a1af617b0b21984fe7038c323802660fe1fd", - "0x6f50b828af00200b81d65e14f07f8c34a5d485056b017146699fb8ac4ebc39ea", - "0xa8b15957d1dea63b64c56d3e40dffcbeacc5c9b8e35d27cd66f61f5c293def93", - "0x0ec32ee93cc52258a0de9eb53f48132b7101abd3de242b9319e791bc4205f57d", - "0x4405dae679f464fda0959884464e47f7d21e21d69288b66c35878560deefd6b6", - "0x1e490b1858da4d82632f376234e04ef4cae529c3307f3dcc5f5b893e38a418b6", - "0x4683e9dde5e2d66da4c288452eb653e2e6ee3a611f36cf2c80e5870c187c28e4", - "0xa657cd63ffa0cc282221e70ee3dc8a7f2e9eed9b8544f25467208b1954bc1f4b", - "0xd8ce555f85b979a26f207bc1e86d1463ab77f8c7e5f5b3c7db6d79785e388662", - "0xf604274a19dbc99c4c079ac4caed9fafd49c123226c3c223a53aff7f7b253b9c", - "0x4edf0d0aa873fedea6dbe3ad1dfa8a2b5e312e2c2b51c464c9af60a5a5c588c3", - "0x5ee990ce5c4e5eda4d80885409624af7b8075bf7349f386a40e03ae64b578707", - "0x3d34e4bb3284428153db9216319a83c3940ee95d0a47d963dd079a46d14ca105", - "0x7503687ea102d05d92bbcd2397eaa1edb42f757a0ceffd3abc871d2d895214db", - "0x7e7201b9fc6176b6ef993dea53732f335efb98abfa3d92462231bb6a5186bf16", - "0x1ab3a0afd0338ee34e047c60cb2c766521b3085658ae2e019c0688c2397bcfc8", - "0x68b5df43d045043400e3583c4ed125ef0df6f1617e30693525f68fede915349b", - "0x201fe9c6fe4cefb948972c644fb9d67634e30529589b4de597f9335bbd6dc8ba", - "0xdc09d73232f082162df780069a77f180bb30d8b736457b0c746c3e0a29d7dbf6", - "0x7c33f90910049812c0a87aa8321c97320ca8953f654f8ff7b6e3982b13e2cc32", - "0x5658b211c7a5a9d8d66be179b8d6039c6fcb5b5c9d232d4655e536e21fade31e", - "0xebfa63617d9055c50466157b9d8d0c16ae58f02df12f4e23f4bc09304701391e", - "0xb29f737d036e5d7164786e62b14d1f9c427792fc4faba265efc59360129aeba9", - "0xa1271a340258127b442c103959fd8d5f6369487c16575d90f9f1267fc3f78456", - "0x1d5e62fc56da958eaced4c2e6a58ad4acd3e978eeeb0f417e4a4078c6014a8de", - "0x4357d167c61da7d4d0b3f1646508a859d8270842cbf1f1f9f082d8f713da3904", - "0xd9556c35934ffc3ad2970a448d8caacc43e452b509f2cce4cf755b19d888b674", - "0x248efe4782d57127bdeb94420062b742031a4bd51c41d36375a9671b279b1e09", - "0x94d06fff869c9923ce5f524c3ccff9d9609b0b36562f47c65c7f8568d3f9207f", - "0xdea7e81ac2b15c4b145dfe132a1dd41300fae3a86eee16f936f46df16f33c686", - "0x733fb7f221502d0f10a13a5ab0473d50746afc5ed442dd69b4f9378abd304e87", - "0xc680bee47e540c3d706cf461399fcc1d7a6749b4b9f6808afa099c52d28cc6b1", - "0xadf685a187510063c7cf4b3ef6ae478705af7b4dd6c3c4080239ddcb6b069b3c", - "0x4ec68b78bfaa971ad03296b71dca45e36852f04f0cf6d0e8ea681c4d32ef6d64", - "0x407017242e04da4a1d4b16d59c59526a172e18d1d7abd4a343ac28ac883298b1", - "0xc92af4b5d045a6b02f2df7cf5a23173d969c447d7c006457a5be7f0251446488", - "0xfb8367fe9396d369332684b2fa3fad1603c7b572dbc00377bfcef0021192a52f", - "0x1d73c88199bc153c932ba313175344b436b28e5e0b39c3353d076c7e26fe843d", - "0x253fc1aca7544fb93d493684be03d3667628b5a0f3f516d7981e3a01e6656440", - "0xb8fb006c1de093ae15658b7be4b6625d5c6d14a5c4dd2623ac9a31e2479d32dc", - "0xb46abb8860cdd8ae411231d897af8269057060cb43880e52e63254f698af82e2", - "0xefb736142ceab502aeccd9df17018719d1004b554154edc5ac62ec45830a0d30", - "0xd9ce776c58f4e1eaf1ca20f61232d3063e98fee3ba0b078e5ba34736a16a7e35", - "0xb63a06ab391813bcf830a53febcf9553f292e097f127ab610745742f12ff7a02", - "0x225004609e0edef06ede2d08f490ef3616b1c5976027dd03f329605bfbf8a916", - "0x748f462a0fceb4743d8b03de6ecad430fbf35d957483b04e04609e9527fa37bf", - "0xf13227684614cb92591a4c0381ebb87b0e52bd21cfa265b501e231d8c3a0e504", - "0xdb56e9aa8ede4b7b042f32190ea90757dd9268457d43231d1a384bc6da5d6396", - "0xb4880cd0f5e5ef6e30e5c015fad427e418ae0efc70d084b7b6d342e1cb71ed2b", - "0x8a59bdfc0413acf03c39f473bd09b34223b109556c4e0fe976a30bdb1b944c52", - "0xfc2f062e32c3fce97a5f3922d3bb5c0842ea02a71775d6852e256ed0143ccb51", - "0xdc3ba03348f62599f9928101c65a8f13e2eabc09a377ed461636e48cc9e0a5a7", - "0xc5b2ac69eb80b3f2ee751ad4aa8e2eb2cc939e81586088986cf9d6e420330de4", - "0xd6d389727a18def7ce0bcaf65417e3d7543b1381b1b49c6f128f3e13f7d3eb74", - "0x02f48b5d43397b1f22bc7617ffd4d93254744b7fb872c051ef8a02698ebddc5e", - "0x90f674e478cf1dd60cccaa750363efe18cb4ed54415db0ea917a09d3d78a1778", - "0x98bc38a5b90450f89255564e3fb825c53d5fcb5eb9dfd9c07485ed6c42aa3f87", - "0x5b70c7cd74a8a92567686c5785657688f3f864b10d2ed8d9f21f004af2d0a3c5", - "0xb153280a3c86e119b7a03dfc4c8cedf79bdd41ee6128b3f5fda20cc83daa39a6", - "0xea4c28d38762dafc3c6716a760883e33666560cd05173d3844e7e280a6d8188a", - "0x8b498049e107092deee810a68bf8914e00d6759a7e62c8d6fda1c5b1531ff72d", - "0xcbcba70e0a5bb3ddb84e1b115432f025a71f2824061cceba494cb917c689f452", - "0x5906b23bc6b56c4e91706c5204d8873d17252c0291585fe4cad030ab6171e710", - "0xce634ca362c4acf53cf9fc68f0e7c8b199b7f3a1f5a2f9cc1c58a31f9650bea8", - "0x840f429289a783b9b4f8e0f575d1bbf0d2f4b00e09ca6dc83abd17d9718ad688", - "0xace326fc69d8ff3746bfede0d167206d3df6093315f3e3cfca8d41a857c20b52", - "0x905d81ceddb8f4301e62a871e29f1f08769336d7c0b94821b12668354af31fa9", - "0x8decc0ea30a4102baac7ccb3e50e15d50102f05f4a3102ee01a0a275d2c51ccd", - "0x56b67da5e38cfc995831754a64f0ce636f060d51c11b746aefac13638bafddb4", - "0x6672660064846341aa343879a40c5b29f10ebd8120c59bc76af66bd86b96cdf1", - "0x3600a734f1b1df6fe6dfd1cf49d8072bab86717bc5f2d276668c1a482e62acce", - "0x28e4ff2dbfe40b374a103ef1bb9e577c0f2cf1186ba3db324286ec490fd02fab", - "0xcc814edcf5ea3fa138fa7d5e387747334c3ad2095ff08465d7e533250430e25a", - "0x1aa1447a8db11875dc7ff7aa49d6927bc31f3b63cd88d2d937f53b1d85e448ac", - "0xa78c6871cc93ff6db876cff3755a59f8fac71e06c89ffc1200de6da08f56dfb5", - "0xf3c259454de9dd21788084bcbcf1cf0953bf7710bd797295fdfecfebd584d4bb", - "0xf86c0f1dbfb94dbce7368211fd3b19875fc831a422989340bce63102a2af3ac6", - "0xbd192dc3426a9b2fa33e2808a258e9bc27e1f14906b9ba9ec973ce604d9ea8ff", - "0xabd37b505d353f7042ef2ea28168f9d6be1a229bcd5ecdd4d69a96663a169446", - "0xf0f05dba6971b57e32e017285fecd48094e6044584889690dd6e0d70c62c3f67", - "0x15a8053e0694262c4954d8110c505ca101898fb5a5814ae8bcd35b8f24d6f90c", - "0x3f8c3d5b5a03f514d0b2f79fcdf7ea58eca2f85651932220362ec9ab50448aac", - "0xdadb41f6e17beff092dbb9a6dd57d3d0951a188fd041f60e455d63755134fc48", - "0x4017f006a6eec8c71840f7051e91dbcb6b18e52fa43529df1121980670f77350", - "0x358dee5f49761fbfe7e6694144a2de8e33614669da6b773fbfa2e330668f4e90", - "0x080216884b389a463ab63c12640f82f442fca56803b2bd7be45ed789db6c7371", - "0x5eb35f253d864713fbe058df986d8af27badce432ebfda59810f096b4e5126d2", - "0xa18c044fdebbe991e181140df95076de9cc5a70c2656ae99ef68e3c1532d7a14", - "0x69af193591c3eb53b00e9fadb149172df458a9e99f403352fcf866bf1456c6b7", - "0xf3a769187ea83cb9d2a96293ec8c9f2074e8231356d3cabe7669aba13f9509f9", - "0x5f26f2aab6b2a0b0f64312d243b7e3dc80621e134fe08f8189b135cfe7d9b2bc", - "0xd3edb5f8556c1a4983450a7d5ecc26a3dbdd332882dd63822e7c8cfb3712b828", - "0x6fd2e87efa3e7d4fb943852a358a515037af5c5eb9da73c3e3dbceb63106d2db", - "0xe574ee1110f966de904fb61d82995be95f3092511eee8195150099cf69fc7129", - "0x6d9c9b7b400d1f5c07aab8f4d23233d26e19feca2279f814729f122c01189c03", - "0xf0756f64317e10b276c71a678b5b62ca94e354c9b8d1ed7019a022be23fa6645", - "0x106402792c6b9f57f4b471736376a153d12ebab21e4bf034b6732324a1fa4561", - "0x33f10f38b702a617e0598cb20bd5df0067ac5ff155cd6b445f1abe46ee3d625f", - "0xffbfbf3aba272f7b978c9815e9e17972786c24fdee8f9167a47e85e9be60a613", - "0x9ed9567c8720d1450b2b0e45195c5a836484a18746e5d5a0bcbffe0b511ad075", - "0xa6ca434a876c017f522aa24937cd4dc1534da3fab47ec57e22ea7d2ad555fb60", - "0x2aec2650b00fa5886b61b1d7c4390dd4e5fd39097e9ed5b1714b741c7b0d4cff", - "0x0cab7259658221598aa39b98d9bd40e18c777ac3b11f6bc7799615c99858efd1", - "0xd76a13ba9212ef2ba4374b265d0405e41ef7016cd14197a2f7a9071e6d4e0a5c", - "0x2802a2d30f42fcb2c953ac6a83212c23711988998eb7f537f9807751b42652bd", - "0xb971ad9aee88adae769dad238a7044c996ee35596cc1b2a7f6e876eaeb4aa80c", - "0x524520c4c947c57827359ffc5a23c4926262c002e6c92d024ea7926a7e0a8fd6", - "0x0de58ec745307c9a36d5f3e97108f666ac58d86b85ce31e73b69579e913d300c", - "0xc0cd603660568434bfa04f6a06342e5fd78c6d916fb8dd77dbfe060cbaf02aef", - "0xde928fdfb8515d944a26630fdafeaf4b3a17dc40b08418097a465fc2009c2938", - "0x11dcbdd72f1b46be2a24dfa6a3cbd8024b6e05f8fe5cacb35618429d9918dec6", - "0xbac41ac48726fc1708a5fff1a06e674a64b8c3a906ec9beb7ff9a444903798c6", - "0x16142a81797daae5fa1914a473f0b89465b0078c5c042f6e1accab6d3ea77376", - "0x6535db5ab7dadf1187ab7c6f0e0a56fdb47a6e6c8f45627ab993b88eb09e7d1d", - "0xa476955c4d2810e17add2ac9604869e9067998fdce26685fd6cf422f861687dd", - "0x4b2ad0b366c96bdba812d3dad76f432dce8f0e8be1943ed92ee4478e9496d8a3", - "0x74bf0384fd4b8afa1bbc0fb0cb6543442a6bb041911a817b55bfa60fb9039733", - "0x5c3da2ac9d4284456d13270fe7d160178cdf61be8bbcbe8a8536da815ee70107", - "0x62da3f7efe7d1de45be7d134d290f9b3dd50e45e751290d870a4b232496ee71d", - "0xd130203c98355022ffd5389a6e84cdd8fa0c570ac887d80ccff892c168a49c4b", - "0xfe129ea286e85269736b508aca4471e643c4d84864809d031dffd660243e2f4d", - "0x69a60dbee253142008ed0cbde35b425e4a2d07545571d2646a5d2a03f36cbf51", - "0x1e2355fe638bd71688579e07145f147384ae18220c8324f95c54ba994b033cde", - "0x391020697dd4cf20f8afb4b76b25f2e08b5f77be696c2406ee45d0d8499adcfd", - "0xbac11283e3e355ef3466ca3dc7d604ca002e26a98b76caf134ea86efb1523eeb", - "0x328b03bf254908db475888105015b638e7b16a4743bb235b85b160e430feee28", - "0xe9450fb3b361bac3eefe1cbe97a096218c40ccf4530a669ff9e10207c69b26ff", - "0xa574c9dc2d563152d012a1931352ec3b9116f949197efad0868a53fe79a2afc9", - "0x629d3aa0c10926f4bf5d250b44fa6959e534444d9f0e8fcf5b206a78ab5974db", - "0xe1e7bfc1e38f36cc8a094038ffa44ad0ff7432c508516e7a8b3520d71714c608", - "0x13ac2b375558ac0582ec61c4edfbdaebb268efb3dd736b6483530db77b266c2a", - "0xa2ec61b999d453a53aa33105a90d310a5afd6f9df76966c53fe524100515da05", - "0xac58616f19436e53d5eed7b50162713711a3f9a76266ede35da4411008de1b4b", - "0xbe8d7a38169e1a92a1ffa712af5173d5cc18948a477a4db917a7f8cd7013d6de", - "0xfc6997785c292450bdc3dfcf9d0609efaa2eb780a6cb33fbc911efc18325c1bc", - "0xb0d71a0c1c3b2f1a746f8cb70fcb99695950ea488216f83854cb267f88c993bc", - "0xa41cb69cbb562b104aefb77c9f0b0b2a7b43b92c7e1bb40c6e781f3667e78c3a", - "0xc3dbaa1d46c2bfadf7b69d5930e00b3d2ee2f0e459310eb9414be6e7d8fdfbf2", - "0xabf64b834999a679f71fa66acc622afa69a45bdf0befe5c8e0224ee12cd3214d", - "0xf788f916838793b4efc5cc80d9f29f717b9a84e877773dd4791fd6a0c1cdfc56", - "0x289de39a57b30662c600ef8056dd354c67722e1fe198ec2bb749c2af77a27643", - "0x580829bdf1584a58d7da444d360dd552818dd1cfd5f7ff4323d21a0c13506b5f", - "0xba51c5ed86b5303e52a3b618f78614bc1640b1b145e87fe625b51ed80d31017a", - "0xeef60ce9f49954e62854e938873e556386b5045a57980bab45e6fbe6a6e9c657", - "0x655bfa2d02761722b8792ee69367dbf3103d16ed0d07f7f8ff6725dcb8f2d955", - "0xc7a54faf2898c69f76123fe1910bef9be9ecd77509ac74714218c9bb8b4204f0", - "0xf59ca122bb48dc6c0c577b04449bb64d7a1ff5661a016bf50e32005f3295b223", - "0xd96401f3f5031c1aceb13d9a3a0525b5bcb7afe47424a5b76e8381732e789a4d", - "0xc74fb4d8533d438c78710932c95500923716fdfa6625154320625465ee32f07d", - "0x63ba1efd6ee8de3b07dd2863eda5d46070f7eb02d35cf670f7b132e16a958bcb", - "0x61eea2352d91b206a674c4c2af59d8a2a0fa70479d77447e3ee9b7db85d353a8", - "0x04b60e8ed3b12a7fab29bb6a74ab7c9a33d403662c47e72227e7eab515f33618", - "0x9c229a533ba459b852dbce6d96bb72c03f9829b9a984119cc4e1c852992bd2f9", - "0x54695b023a34947fae5230256ba2b0905d3e28a28f02c2764f70495d71441a63", - "0x2c47d3759d9df5b9330e6836835939107269d70a7d465be651a3845e4a1903e1", - "0x5fb3708137f2cd39aefe87c67a6c4f9cb60a9945cfb769ea71d0dbb7f3ee8cba", - "0xacba51629f86d56e806aac1561bec11a697a05f6dd182ebdaa906ff77aee7abc", - "0x30ef858593f9a35889c8c036eda78d012e298cde4a3e7e603282b7f8130a4595", - "0x1c11971b18e9c870e513d099e5a49615e409a255725a61083001313a1d929658", - "0x9c6e3731ca9cee43af8c299c02eb49760141e74e1f781d1ba49b6815565f3ce4", - "0xb59c0d2e7c5ca751b9abf8b7740d8d5c8a6fb1799dd1d5a5e9f0ba75769fb2a0", - "0xafbe8a18d07a30f3ecdb907eb4cc05fdd8df2f9e4e91e61f88ab87dbcca25249", - "0x5233d2380755af7c385b5b50d79c5cd9b1255f0145a36245cc6dab7a86c0cbce", - "0x54520d2d08116f06e38d1a316e7e4080f3bd8c4e52b06f3ec20c3a5327f88adc", - "0xd36158eb493e04911fe79cdf4c48dd43a42aa3a23568c7a6b06afafd3ceb51fa", - "0x88a509ee3b2bcebe15ede2063f8fc9a04fe103a84551f279b6ce8d4d36d3b259", - "0xb1b80927c19a8cd540d126e07c52aec2206eaa37a13f2ab4726649d34357879e", - "0x83b1534ad48437dfc54412e49357b13528f0f80dcc32555a2b6f2391cedecbd9", - "0x13d00415b9888e8f64bd3110b04bd47125a96abfe52e0b6ec004c96e142eca1c", - "0x9e3b31cc2715b383eac51b52a3d912e22d3c1f23fa883028ace6a1e80b1c02c1", - "0xcbd325f1c10db1289d1c46feadabc59b24ffbeefbc4f242cecc3dc0dbe5c2e8d", - "0x7627582f663394f8284a6636bf024683547863409f38cb6ec4f67224eaeaa2b4", - "0xa4a44ba1e2badbb513cdd55fafbe2f5741caf2132dd46c602172711c110e41bd", - "0xc7612fd67e5d4bfcd14eb631181977f5b6737855721aa42bf4e9252dec190a53", - "0xbe3030a24be5db7244f04c43dbf419db3c7fde7e7a2f87951cc74df9b88a4071", - "0xab77045cc03cfb77d55f118f15b3416f8f118327e78ae4cc8a074b3c8550f992", - "0x0fccd266f83598b42b88c40c54670e3f2ab3a4c8bbcc0b4effec5ba92e0f26e1", - "0x5285dfd8a25356ebc198835359f53cb86608d1058a90b20980748eaf5efa2ac7", - "0x182bd336222d0cfa5fa9a0d8f4ca769e2d45829af50bc3a454193628e073b44c", - "0xf1a20eabf959a3c1135943378f31a69c049529785e0556a45450174237d8a2ff", - "0x69387452eb76800b6cb66231cf58dc180bae7aed04ab182dcc3845cb1abfee73", - "0x5136ee55850f0aacbc26fe7bcb58a74ea738ae6edc56bdced078297e8ae44087", - "0x37eb930540d64aaf250e003ad0c2274cd047eae6c28bb861bd880cb53aa972e1", - "0x82d64719d65ec1c1dcb0d269222b1acfe77326ee7d901c8bbc542b7696d98de0", - "0xfbbef382c42f25021b7b5787fe6ee0feb1e589310c615cf26642ae507f2e8e07", - "0xa2da021c8e8ac265fd7c181ca94b372375b3c297aab51811494c07a96536d4e1", - "0x7ca0d6023b41793f7a4dad7aa65428e43332f9fe40efb62c1e74253bf64a28f2", - "0xfbe923af0120629c5dc3c118350d1ae310844e0df4cb8ed48decd520fa7b38bc", - "0x3c7efb35e8c27c90cfc06a18160b34b772a5818cb79a1bf62b107ce93cdee33c", - "0xf59c8f80367b98738620c50a44cad556d73ce17a5cc1f403528d72a52fde5375", - "0x7173aafc1f35fc4eaaabb61d26f908a8d0d834252b951f5607a8cda0c97cd79d", - "0x7ccf293b0d2ab799ce9fc487187d61eef099801d8731fa21300bc1b166c11788", - "0x6ed0dde1a0e7bb58435bb525d897d1a9abaf03f235cceee32f3987e1863d94a5", - "0x5a5d21f5ae95355ccf41cbaad953150d3f1231de6df6650cc712cc57f77fb7d5", - "0x7731f59f98388e028b194d16478c9315050555889c30242a836e84e5f27aff60", - "0xfa682bb7f35f7a75c9490c074b1ef4c99afc50f1e32d829c057c765deb899638", - "0x10403d6937901a289c468f7eedfd69d38fea6c6b468f63bd7cb17cd8db4a22d6", - "0xc5ede1b02d3841558bd8ab6f51e14f5a4e6b00daa31f982874f0bad7132465a6", - "0xbf01b8033add1db5cd02633cf114492800816bf01ad4c7e060ae4c9ffe92c13c", - "0x72d22a8029386eb9c26dc3277e08676609385cc2f9addd4095fc1de0ca6bbb17", - "0xbb77dd7851cc4cc50551914a62c71f8b8e2ad7fcb700469a6b893810b7d71a69", - "0x6ffbe73f30d4dc914a859911afea236c9540920e5fc6ea35a5b15baced0c8d7b", - "0x2d06f3ac10ce2d780f52e9f8dcfeed80bed8c4fb628e8169290bf35b59fce156", - "0x1f6c2f6010356f6a37b0217433d7a1f5a2e0cf51c41b6ae6de4afb236fe4b5eb", - "0x011c13ffb7e71e32bbd4517b994856f6d21b7ecf43d117b8642cfaac37b9a8d7", - "0xe2613913bc4cd8dc69550d32163b251cb1e6ab37d65eb71b3aacd05713158157", - "0x54247c638b2b1fe4efaeb4eb101d5177c84c975c759ddb1ac20207341818c6f1", - "0x34fa5ed94aec05a24c812403ad050ccc96d7a052b0d9509cbbdf83503589e3f1", - "0xd4c86048683eecb1e595cf76988e76be819488421c56b96a6dd4641efddf4de3", - "0x541b476f9a0273fba6340f7185c2ce43333de04bdf3c1a7ed022edf4372b2d0d", - "0x65319f2394a1b531beb788f72246a6035539816c618867b0e1d0fa3baf318d38", - "0xcc6b6ebd1eb606210f5d03e191f303c1c4a438b9fd7b81f61c38da76a6bf9fe2", - "0x66c0dd3e062f95edbf9b26189a302e46ceb5cfedbbd50e43139bdbcfe9fa2b54", - "0x728f5ccd05bef6a64b639ff86642f71078719f442915496c430dcd17b437139e", - "0x85a856f40e911384e7a7a42fc5d9197e063bbb890a81382b4ca6ce2e78af2c77", - "0xc80aed20cda1826d775271f2160b6040682095e51d7deaad7405a2f1c801f980", - "0x95576e4497c07a1738d07bd468e65d251f9876c957d7efab7ab7ed0a6eb2c9b4", - "0xc30785c899138565d799884aa7bc486f1a803901b6b8b8b66eb6d97ca597d8bf", - "0x3990fd6682fee93631fa80ce6cfc68fa57e25850860d4d982d0945f72ad37f38", - "0xa136539e69b53ffb451c817c40776af735c95f3392d24d906b22c0e6c6114be5", - "0x8fdb4d50398d776ef876ce77547d4d9e1a4609be5432121ca1dba983ba07a28c", - "0xc7a547ac0db666820263a76b9f9adac876b972b22d6c8bac407ad6fa5c839987", - "0x87aa61ed60484044960beec4d9c45c9112e6e4a70cfec894d5a9f93f94060acb", - "0x50b05f8c5a72944787041204b8a8acb39faf179838116e04ee7bad4d6f21d4c6", - "0x8b90f04539dfb2aec48e0f7a47a1ec601af5414f3284074911eca3a3afc36e3b", - "0x3f9b8f28853028fbd3cb0bebf22a723907600bc2c616ac5251fff33b2df5e9b9", - "0xcd7153ad8c35638d23fb26282ab9361361fd23385ebb9693d8d628a75aec6c07", - "0x370788f25ab289cbd7f9a4b238bd35efb41917b771d8d59493a05aa7bcb3fa4d", - "0x942223044ff0bb9ae56f259006787e5ae6f21f46a3a2bf11c0e977fa60b50b7e", - "0x7dc0e910fa0a6d722dc78f17644842792e619d7e7c044ad47a5fa32583686e9a", - "0x669d80d664251cffc5c7289ae2195a0cbc6fcc732c2af1bf429a4aa98c889520", - "0xd6d24bd4d8a639ac36b14c6d8599ee8ef5d84ab71dd7e6ab829b730d930ce924", - "0xba692b11b9febad8099415d1c0761f2a339328e598d9e04533103afac8c04dbe", - "0x8e9f7d1c6c2674b3139ff88faffe8339e45d72212234b4531654accd66ee3d4e", - "0x2589b94b36fec67b5862871758f86c2773a963197b0d7ba9984427da3b4d6042", - "0xb7d1c1c35718c23dd4498571bb0f4727f3ebb0e1cd02d8094f4713fc0e858894", - "0xe222068e575041014f38e20a85ef1e989e9bb05279281c59569a627769b9d7f8", - "0xb0746c8dbf22e4fcf025fe5383fba7865fd02f79a4403d89753052bb9118e3ed", - "0xbccfcf626a8e36b6eecbadad1870358088b3e584ce79741bf5167380e97f5e9c", - "0x6215dd20373041734291e4dcac34b207235a5d19c3bd24359168d75778b6dd5d", - "0x025f64d258d97752e9b648e956d114c8defccb80c8810113a3522a77ef3f7d35", - "0xc00ffb03dc524d1ea1984eecfb8d26d860791cdde35c8b262faab927891e3fef", - "0x4ec39fa070e38fb24c41af52ae2ac640a859c61c96661d24e53c817228863abb", - "0x7d943dbec346b6bf55c226cae23ee23086185d9377fad511103bfdda3d677ddb", - "0xbfb16c7a87172cc804008bced344dd6c1105a7f0e925f3b7335b6b4d7c8def25", - "0x359acc4a540fb3b54fe22d81f1e3c1b969a99129e130e9e4e24481d024cc81fd", - "0x33091ed3e9f0e50c8c9aa100d9615e8523d594a99095e83863a58cf54332edc6", - "0x5eeb88207a02fe01699c8796b66ad3a0827432559690bf42e76ce1c7f23c0b30", - "0xf5a521239d0f969c8b5c372b84f739af314645de36efd1190f92973c0a2f9098", - "0x1a634f2d829a24589a25a01a22b139b8342c7aad990a14b5e30715d2a83074ce", - "0xc5f62552f5e25ce475af7eea51eba85991c59b73da75eaaccc3e5571b58a6372", - "0x9fb29bce2aff82c7d3eceb134cb1d5c6e6b309b8a9be5d239e6c6dbe231fca32", - "0xac3e3a2edae826437228f39859aea596a84253070a5e442e04adfd5504b9a108", - "0x717d4b6b147ee5eb42baed2a926241dbaed7e6426aae40972488c08430659d20", - "0xe18c4e7cec87f2e53f1e10683835563bb05e182596fd5252017efdf7d29411cd", - "0x6ddc0db9f04fe0b7f8417507afe16b59479303b5473563723b390149a5f09b2c", - "0xfbb88e97efd86e451817b13e55fe3d310edcb302607127808ffb350799631ccf", - "0x5f61ece4f330c3eb3647d2cf9ceb4f3cf238a324bfff628257ac4aa1de7f1663", - "0xa2a3bd77e36c3ede311ef3fe330e4a2b22dd41313ff4ff6347f629777a88377e", - "0xbed3c97e0d2dc6e56006bcbdeb007c8b63e060d80f46b691d38485b03c17c791", - "0xa4e4b8d8922741c5a767d9c4dd71f9d850231d298a5b5ae741397fd065600a52", - "0x0f49e95e5812f573c00dcab19683c391996beacf61442e52a9c240f08f8ab92c", - "0x3701c4ca890dba3cd43fa3b506cb3d9ce540e87c493c6cb9e80bfe05ec5cd255", - "0x785e2c2e4652a9dbc413c4b7bd54dc8c103f6c933eb9ec41ca44e609cf7e0bd5", - "0x7859e4bfa55b11274bb0e91f608c6d840b7de4385ce8158cc08b38449a61213f", - "0x64221410a8e57fa61ee9d1ea1b5ac161face63a493dc7b0da0f398c0d18b6174", - "0xabeeb213fab38140a8e66b41664626f3ffd831b91e83f3cb7d4f2f09a0b73e5a", - "0x8bc1b2eebc3481e54df34a5f0229a54264ac518dd36f994bbd162442fe1190c4", - "0xeb0753b5fe8706efe7224f354cd92381960212ce4d448d3ba554450a66bb5e7c", - "0x30f73d3082f6ce7f9ece8dc9d6c78610babeb05854415279d615eb24d0d10962", - "0x4bdbb7c38040b9f623b67409d8890070fd5d6f89f023556f2bbee1f40f55056c", - "0x18ff647cfbae0ee093bf85bbbe218802afecd7f45bde5dc29c0c76420311f5de", - "0xdf91143a55752eec775c6c02464a781e16c8e93a4270ebe1bf2127658adeb5a4", - "0x64ba37e403fe57a42440bd2fddc1e301297846f69df5990c2d664d3734f902c2", - "0x2f70192df5b8359e851856351ebe2b0888b1c51ce802766f16ea2cf8b723004d", - "0xa5ebf72bbf06ea040306715900f6bd06564887b52e4692333f880e38acc40b0e", - "0x3b86d989319b0c910e74a79b2177efa068d8601b9889b5e3d17d57c59c6a2238", - "0x1e416fb3c47d77206efcabafdfd3fbd0919e7e6d158ccfddf1d0a2a7cff6a37c", - "0x3db2b1eb730ce08d44e27585207b39d5f8dffe7425949fce9e6e1a4f296c6e75", - "0xf703aca3c59fb4e102018a6b156a83af6c93baaa96c54d9a44485a5b90ff6679", - "0xa103f504db51472ce4d6735684bbf46259e04224d42fbbb87548eeb01aabcaec", - "0x282e099b561c70a9a1a3ff6a4518970deac9a096563e15c01151c0c37f78f737", - "0x87bf6fc28f774c2f6bc83f32751e0d509a2e009e2e3dcbce44db2697dab33520", - "0x97d109285466d0d40ed47f6e1c8e11259e69b90b02731a4c25efff829e9c7e71", - "0x18232c1bca21707fe7b74896e3b1568f88094adcc51b4ad9a29a4c76ca33063f", - "0xc230723357dbd10e7e57ab187d1a1f72a27a53c45b650020cffe672fa8e156ca", - "0x6984c028091bbcf3e40bdb8da39d81d2c9f8a73801276ce3644fcf57cfd3e8d0", - "0x8b66e1d6d3d60f03098f29d9f9857a29ae48a5a34d43786a8fe64e6227ee2da6", - "0x353c9a58633a1fc28b5acf9a0f40e69fdd48252c689a9b8db7610c3d003d5441", - "0x1e020c7d1997e15baddb02742e8846228e4eecb6bb1beafc81a759b95783e238", - "0x50e9738978bafa44eff6b9ad9d344efdf40f7ace0dcb146e2c758cb7b3ca05e7", - "0xec6ca85b0c27f1735eb0822dfe5a0d4e642776e2945a9a22e104b9caed098f11", - "0x94f749840d03dfc1d1cc7f31070a1019cceb1eb36a09f520129457057885fb48", - "0xd29d8d19a1dceb08208369498527ccb0fd4aae41077d4c01c715e6989d5f828e", - "0x40b5cc4710284f1175ce67c1a0f134288428d8ea28f64f41fd061a3a4b139242", - "0x7ea68209ad947c37eb3ff8c779ba7f5f3efaad2d61edca2ae5efef666d7c1f5c", - "0x0af74db9e9195f27f1a04acc3150d6d6200a5f50be63a6dc2fa9acb953759517", - "0xd7a6b221519266e935b12a864c84c6d7daf4e4c8c812a93515ea8325e94f2644", - "0x041fd7dff3672a07a2922226bb0526daf0817fcc61cbde7fd3e1f8efa8dd6c76", - "0x79fe74fe4e56514072881413ba7157cc125051476d42fc9361a58021268ff0d0", - "0x01cfb41ca5887931cb98c347c25d6c03eb5e992fd661085307245dc77cfccc42", - "0xa1e93426afb5ef56a564ebfacfc52149e293c25dd36dcc2319d1ee50057eba41", - "0x6a8e8e62cd387ea56c621a5e085daaeb51003e86fc3c252d115ad417e2e79242", - "0x18e5d5dad6f00c36be4ea9c7898645611887a3c3310b97363699178136989527", - "0x6701bc914e70bced06487f22a16792fe3dff4f1fd15ab87ad42dc91de3cc951e", - "0x75161e0ea68a78e4377837bab6162f1b6d53cc5dd76c423acba9bde4f3ff356e", - "0x9d9ea2b7caf0b67dd97b62f0e25d172f78c984baf97ae3851e52e26c5af87770", - "0x4257fe5a910db425844b2edc8badb4977c819a3c40e356d260b93fd2f9170bc3", - "0xf2c878a894811bd844c30441bf38cfe79f3ede5b0574721f32a24755c40aeaaf", - "0xd45e12f2f3a025090fa81bd95e555c8787c26849410f96aa172d3dd153b40a67", - "0x6204243276bb752e5e2d77fc43cf7c5cc92078c283c4d489b7310ea2753ed71e", - "0x806a0a9e0f4e744b02b5091f72f57377a4d7bbbb27829789070967d35fbee325", - "0x13489b922a69fe05869130674253f90b4f883b199f01cd03c85df0a000e1717f", - "0x4fa87d7ead2b1789c72908523c5aa6ef83b7d9559f5c5edb506b4c2f681b617c", - "0x4bad3e31f50fd2dc570c31bd547d278b92e5c93a7d971c38035c09ec5a1dad84", - "0xa0f547806d376b76b33266d94e7d2ef86584a234b540e74f79756e0331405c61", - "0x4bab9342aed359dbce241e580b46043b160a01e44eb62bc29ee5ac413b8a7ad8", - "0xc7ff1b8f8557acccfaf4dd37d13a12e3f9d0e3612398c3d8b1d675467fca56de", - "0xb412685d085b0d52c72ca3d9987cc188f930f759022f060d5f2f368e77a7767e", - "0x0775a447ddac0050f5cb29e08fca1e7d016b42c882ee15bfbae3de5dd99b6705", - "0x1d33342e6115ca2919ad6d31fcea9f4a9fda5dfadfdb4e206e464ac44e59e178", - "0x26dd97156aa189d9f3c799e943f50ad13c2d0cc8018b054af65eb37f5caa76c1", - "0xc4daf50db81c04055bfeba3534a48af718695e2789aead7c3fea58b064bc86d7", - "0x87e2b037cdf4370ece9a2e4a54329d3e1be0b910af6da8c3850ac75d6ba34920", - "0x1b8fd79a76b40690a3bd1bde5cd3b68b36148eb951f45b798958777527a876d4", - "0x63ef67d88acd91fa005706dc9912991ecaa81cc7334ec367340a2c12147cbfad", - "0xe20cf7a6540722b3062b9f49dde601f210aa8cddb5b5ea65eb7bf44f53ce9d5c", - "0x05b5daade0670fddf401298414b70656294b8c5d3203ef7e21536ab2696195c0", - "0x678791e0898a0fd0dff39cdf16d298162200ab1d93beb96ecbf9e9a664362b9c", - "0x77698208c576cf9f2696280872c6f2938595ae522b37c2b8dc5b60b83ce7a9cc", - "0xe9453e5ae3e39110b65b03dca160f930f39e933ecca604f7b1d9db0f3d4e3915", - "0xf3d84caea9ee5dffd395c7da7131456174cba99f905eb734c0df1e070c16d359", - "0x3b56c6cb8308bfe1d9339e14c713eebd5830cd0c538b196d18743bfb729878d2", - "0xd0a1ed8e3bba6cd1ab36ae3e60952e6ae56cf2157039ef2f7136e09999393650", - "0x206a0bc96ac96836c5230d024aab5c7733e4c769b7cfa9fe4c52ec9ccc2c9ecc", - "0x322a0aae92f406bc6c08dfda0b60f625716af5dadfec8d014c6f863eb33c2edc", - "0x701f25bc99f297ac9e8a8e5d8c376f9a363ba277ec87d2eefe30833035657e23", - "0x98ee55ecb672b58e5d02ac83f716013b2e5ad57894383e792cf1bd82cb47b20f", - "0xd7c63ead8a31b5b188fbf0663e4bca087035291834ee1380da270bc26bd19186", - "0xce3824ed345e2101fe30f43287f428c2cdab4a9ee2b4a047d4c6ba1b46a05c98", - "0x853eb9e976bc0fb95caf99b60c978056b0423f2455e5433f3b9d6d28e8ddaec9", - "0x2fefc2d9f5d26e0e9893b98d6546f593dec46105109fbec9c0efb298dd18e534", - "0x255bfda7bb1a2df1a36e7ebc4414338928d59474d9b33f478dab6066275896bc", - "0x678516c205b1f93ddc8d3558e86ccc9ed5dc317387f4a7849ef158e7759234e5", - "0x58d0e9d13bb841286dc4c579c11cfd659b70e84aab4550a75d1d8f01d31c0b64", - "0xb132975005aac90edeba73c75a8533cb9099a5a7f6e9e31755a22b44289bd950", - "0x77ba37c64ec1db20a6dfad1462bc4cb5d49cae6e3c801a99e223e6062dda2598", - "0xe3a4d6edfccad2c55d2a729e6531cc9c20d668dd057c3a8bce78dc7789384d9f", - "0xf419bd76337344144a1e3f1e7a8d3f768fa97f4f1be87757e3f2e50c78c7ab14", - "0xac248be7b1b0f85f35415e09025f379bfbb02776e854d682bfc93caba3a0cbb3", - "0xd853df355a1b6f7b6921870bc5a00a615d5fbdbd9c5214e57e0461a00af92711", - "0x3696d847c84ecdbe2902eb3200013d332d364c0be47f67cc122bd7d4d644f08b", - "0x843a93026d2075704e731fec65fbef6a234eb6d2368f7da29e8e2d3cae45fc3a", - "0x923e0d97b13c9ff4e051cc43daa92960ec646236d1b02faf28902c5067cf83ef", - "0x4a700c31d34448662af972353f9cb471fd155b6c7b5c0afec7acc09e58ee85f6", - "0x2cf612c948d6d8a6ea9886270d5de1e131c2dfd4012f1811849c332716ca650a", - "0xd9acf143ada3cb5e1eb8c3d14b4c188bfce9efc13d317822dc406e08cb5ad9de", - "0x55b3ab14f3d1c8c7b8660a136c98cb4dbd90f8ee329c1fd08edd612a5b866428", - "0xd07432a9b77607da1fe30c98226a224c171cfabf96a1510849255a58f7040595", - "0xe12a4928faffabff9d4835598e103b6079f359061175ccd18159a6dfa7ece183", - "0xa223cb9afb71fbe269c1f721c22fcb13addb8ec06286f9d5b7e337a262c99104", - "0xc133b48eb3f4946ffec9fa143a85d2e009a3b8a99a68ed1d0121c7e9fa616fb9", - "0xcd63f76df5da2994fd87c43f743cd7d35d94cb8dc973cb7a120cb677db9cd5b0", - "0xde86817e4351951cf1b6402036bea2c75901b6aa7a6dff62b9862fe4783e801a", - "0x2872145a9ea250731bbfdbda0b66367300d88f2d9934c6b1d12960067d717bd3", - "0x86e0674ddc6c584cec7931847ec5283675445d337a89d19047817e46e9047d22", - "0x4aac4bdc309bbbcd210b87b0f50d55fe86f5db69b83e201f156bc9ad25347966", - "0x1c0e32260f903386af7e4cf14ef819fb1245d269d2713faa729f05b019445243", - "0x919711d6689630bb81d59ad2c75ace09b462625180ee8fb8fa2d3ac5aa15540b", - "0x231f8566ebd8ac13f2d6cd5a91566aba9074ffd235c762c26280e52feb5ee4c3", - "0xd5df310c108bbf4dcd5f876e0290c5d9c9c2cf20f4f979bc74d962d7da99a777", - "0x45e6ea115a13d30d8dec6f480a9d0b17cb9288f3d2590af02a40bf3dedf3f1ae", - "0xd9930c2a8d4dfd36b70207175e3ec5386fe91371e4b7fb484022e64b5aa8388b", - "0x529278e0e137a319d3a7516b41bcf4be1390e5646fd74fa8c6ece03b9e734deb", - "0x471c07b4e2c5760ad10759fc0889fafda85c2367f2a9147667ad61b687a52fe9", - "0x39332fd9e3c9c89f6b51e4a5fc43d8da10191d07e71c35383e5bafb997c651fe", - "0x72b4753dfe94ecc08b1ca90329dae352e677b64d3e28281b88765cb2e7e3e428", - "0x9a3d06d9134005224fd1f71f14bdda085f18824b9c86b3ec6254b213d8e349fe", - "0x9e8a68163e7e0d096cb822d73c420324ac7416731b27407d74059903c05f2862", - "0x292c607845fdbec84efa2321bdbda9864c3e7e543890fbedf1b85fa4b7ea6b7e", - "0x31be5706424ae91ed9695b2f8f7cb0a81b7623e02da8595f0affd2411170ea11", - "0x9331ce0a7339609a1a4ab7d82e41f432c430685dc6aae81c50ce18aa0592b465", - "0x37dfd9817be661b6f7310ae6c90b3b97fb5f63e0e622618ecedca0d609c39e35", - "0xa350f656a9cf101ba47b0fa109409f1113ae33405ed766d0308740d5497237cf", - "0x272d62080e7b1c27f7134c60ac9f0dd9c903528b1a32338ddc8fc199d9ff2bd6", - "0x8903ab21a203161e433cbfaf719a95b1fae95e029ee19f0c94fa7f1a68f3a1fc", - "0xd3ba92c896627745c0afbbbc9e3d8b5a1511057b24817d7070e08308812f7ce3", - "0x703ec0121dc8e020de0dce30459da694fb8b7ead68bf5b052320c97b0edff1dc", - "0x0491cb350e466467a1078436a1100a70ed6198122f299b4bcbcf8dbac4b1cbe3", - "0x826cc32fd3097689638c8701164358719b6c8645270b70abfc0b07e103d5403d", - "0x351679f35e52895312c8524262a6e420544b443ca3eee81cc11a11c4e40b195d", - "0x0fb18a66d08f29e90c1a71a648d1b36c2dd3fb84bd2e4b8ac24959233cb7a244", - "0xec7fad9848cdb994996bb9fb63cae6e913fe90c9727ba49ab8c9d293b692237b", - "0xd76f7d686c80c1ef3387ff50925bcb540084d3e8d750a862e76e9dce7a443d40", - "0xfa237f1a2b3dd6e4c646d7c77982558af1633cb8662e1d107d5ad5140ec86024", - "0xe7b5e487328a3398b8716043d3e6bcfb39a996405daa98be49493e46e9a46555", - "0x306c41368e9d1a13d4d20256602c4d4182e45b2b69549be7c7133e01dc930057", - "0x9551a36f384e66ad7c5a7d43f510480448f59fc2b3414cb2dafa8d71314ea4fb", - "0x72c3b4a7c21c0ead562b66abb8e6ac42ab96fc5d01c8a5f934df2393b03b738c", - "0x849f7030b271894fd605067a59e373d903a6a52e9fded2357c05340138d3de1b", - "0x5be66687e522cce14e119c9d4b3b3853fef6cadaff6f6c5c2eaef9b6769b1fef", - "0xe063a6dcd767abe2a9e37d3f18b67e2a2efd68ad4d96b4215eb75e4b23295afc", - "0xa8f6fbac9f159d5a5db1e8d614dbd3302bd5737eeae692ae44155d26637ceb4e", - "0xed37085b1ea6b01638a3a145297f390b63b307479e88c55908fcb46afa1e5960", - "0xd963204f34b83d30e97b458148d7e3cd0143495ff67d893b512d7beb7b225035", - "0xdcf4fdc30c4e90b82c2894b12cf27c2c9ca9e4e5ee88d6052d3526a96b93c55c", - "0x48ae98a481df3d2ec8a9c90d0a838125a5237d5716617d4be50d09b2f1f2f592", - "0xf85cea1c73ca422200a9b41a19fec626d13d70e0ae20dbf8c5db66977091e2f8", - "0xbaa3273782c55be478f5e44af8d6d32771bf837002231621eb82fd5b8c07b519", - "0x1dc0a7713568a6fcad865704e07a405a44c2b0096354115f07af09b760eb9a09", - "0xfa70563c38634999282cde0e088e97953e2d8a81180f5c9b2e99ad74493cebf8", - "0x58c7a37a105fe671a833f01f6c189c6f3204d462a0e119b494b6b0c8bd97501d", - "0x9ad437c83bbe3a45191b5c9fca239d1993960a8316e3c52978c266cbfb4d0ed8", - "0x0e8ce8c69bda4ff65d9bd614bb827def7d0f6bce5d550ed72bd5d91c8c1e33ce", - "0x74e04e71ea4c189be803be1116781a66cdfcc50a067387af6d1d468733185b14", - "0x9d1eeeaa2b39e1e0cc9717e921507d34f35faea1450727825d147ecefcf70464", - "0x6758482ad61721f92137d015d4d07bb238b0976bf14a3c548adbbdbba6b73f00", - "0x794c1b2f6ae68389c51761edde1c96b8bd44904769e85a8d7d0035e76be9f13d", - "0xaafd63d0587a40d5b73ba230c976ca80c46a09e3b7f7df136f8eb0b04b60f5de", - "0x67d184707f6e0b9af49aedbfca464946b4f54321c4eaf3263d4ce52de31f8767", - "0xd2af9a84d73ef353c42517a6c5c0667b1f811ce2bb327e3702b49a178fb94179", - "0x2832ef9283d9ffedb03743b454894472eb31740487ce89ef016a00819ff30c2a", - "0x82ea0cb0f3eb68ead50a1d8106278f464e0126c0d7589e6d4c16142d80989194", - "0xfbdc8b5fbb0109cfb3a3b03e01c90c37cb4ee7781563026c338f455ea708058f", - "0xcc34701c30d0ced752f863fbe56d47abfec0c9f8012d1fccacf3814e5bb824af", - "0xb0cdfcf55823aa634004387d1dbc34246921ca0459cf4b9f751377e3a78ee041", - "0x313e6f0cc985a8a0eb2fcb8d3901fcfecbb7d29e98ef8145996e4cea804420c1", - "0xa64f1d4794cd286788c281b14adaa6c0890f9782ec0d80448b8fef906ed7bbc9", - "0x619d70b2e48cc3b295add6bfbb8fc60f38a01e61f4dfb4872b58c1ce7046efb0", - "0xdb35cea33ddc36b0b91b0dcd84155e214a738cc81c8805127c47fb7312257299", - "0xe101f36ff5b89d028618d46138aed3d6b3269605cbf4f83d68c9bbf233f63d81", - "0xe5925c839b60da70be28b38b2081701e3bb0be98cf763539114609b309c5f97f", - "0xb594135c1794da9f7b7af1366d56b4527223c0471ee3780d65cc03cd70fe2391", - "0xd6a8a3b4c6d33bca9b02b8207aa680835266d9c9d4808e2d57f28f92936b7d01", - "0x640a50f666edfa0c4cc55b6c945a09108fdd53af5ca55ae92de4245d56d5e436", - "0x8dc9acbbf2b71953327924fc2cc711574fb1e82a6746a3606a71071369e77601", - "0xd764b84ee9d6a552e34252322f7a939ae546281136a217f5f7f34e41997e677f", - "0x3ec87053d8ec66bf2449a17989721644050b2341adf9036df6843a414a9a1de0", - "0xdca7784726ae438b274f4a3c5892da0bc69ea694791c1ffb5398683952bdea75", - "0x29114fc2dc70ec997d34e3937c2e54136fd1de4ba7fce8353e19af65aef490b1", - "0xf1407df809e1bb932c725821347954eecc9e5e226cd37b6058b45ef9f4fbd377", - "0x873826f03bea4b73698a17d2b0044f1c689daa17925302edb0f815dbf50c7fec", - "0x3e98eaefd07ff2f1f4d6c67aa7ee3cabffd701aa0150f572521a17772bfd8d01", - "0xf44be55471f0b66b065a2465a04f6f47efb35a9ede93a9d8b22aa26d3c6637e0", - "0xb114c762f1f60a913fa570cdb207c279d20abdfd789d7fa62de06e38c44d650e", - "0x6f300baf19fff0f5af714e63ec81314d7de839d4f5900979cc9761e0ac325956", - "0x94d99e9025cec968ce5a80d82965bf72db62250c49131b14c0329b0aaa462b79", - "0xf1ad3dc366363b5a7c2a238e693600ced352984673cc4d0a07ba0ddc2b25c815", - "0xa48dc388a5dcbbd81e38b3e77178a4248232ffeb23acd7869375323f1aba0529", - "0xe995c7008184fe2d5b39eb0b1229caceccc8e86ef5caaa720f15e133e79a2efa", - "0x8bc6d112254905a89fdc319bc231f4d2c52a22d60baea4a499da91119a6872d4", - "0x16cceba4d6c7ccffe424c9331a78bc3748aa7b629f0fefe88c43dad9324a1fc4", - "0x564aceef2d2c0d4b8d6f73c10c234dd82570a9caeb572dfdf023024b61365f4c", - "0x5630bfb3fbd9625f2204846fc81b98774e95191dc8f7995ef33df915f77ce2d5", - "0x23d02e3cb1729ee715fe84775b969989d11c4ccd470910921b75c63c4e9e24b1", - "0x5984c5d4ed0af67154b12c73e38909b45e46e161d85d66e286d33b5ced150a75", - "0xddfc15bdbbd16b80d442f9a0587da4e304d3d7951ada0dc3d041f5a1df85a9ae", - "0x924c83566150cfdd60410c400078830bb4742b7286a6f8badd3e848a5afd0220", - "0x82847029234edd5c2f1538a71ff2eccf1de43e94f651557ba73caab59ef9faf3", - "0x15949ae538f10280406ebf73fd79fe0e77e937f82cd9d0c623e700ff04fa0a7e", - "0xd93edfcb2fb0c16e18b5c42acb751ff197ebee6ef13e01690b08f8e38e777e08", - "0xcb33ce0679bc3b417095cdecd66cbdd4cf5bfd288037d57e93cb6a542613c06b", - "0xa678db01074492af055c36dcee385b37166ad08a4481309945d227640ece520b", - "0x30b123bd31dab5f0dc65766e2b6067e5caee8a53af647b0c7d35d16ab85b2ee3", - "0xfc3faacebfc2c0ed22820eb332bb2f3d9634abc98d26fd42438276541f2beb86", - "0xa0d90324e7577ab7ab5f9667f9d7a0731d223f8edae77dcc9e38225b0206ba29", - "0x75e3bd20d6378133c8a4f9d0ad1121c485130d65340b0596258466fbc733d61b", - "0xbaef6a6c8b335cd317631b907f692cccdd730c82213755988ff7fb78d08fa754", - "0x03c32b933280b801ee17ade93600bed888caf283e0a058bfc0c73f47072f2459", - "0xabc98360fccd9567e9d555924bd815557cd5612836de1b38b63828db742ac297", - "0xdc6770ceead9f41fe0fabf046cfaf0be83f6c27bf28616a97d58c43e3f591ea3", - "0x4f9a91b13c9af1523071f1d4741ead5b6c7a9e72bc2881ede8309040b8ab686c", - "0x175c7e494c7f0347ffed5ce74eafcede61403cd0829d71a9df99e914774ff33d", - "0xe408f526449bec877c0d5ed25e677e8623ea68b797818b93e443179c9ed4d334", - "0x8f3346b57ad4a5de31df1b0b5fb5cac40ef0152fb5360d50ddc84752beae5965", - "0x4b2398450d192781d3ad48ed398fe7cf9e5e8a417b29661894c6dd43e83e2248", - "0xe94177ce0fc04293688209ff52cf53c548ac5b7022e7e60ee739f5c1711099a0", - "0xee6e5c8a30380746df8d9d3f3de53439fe0d864dab6ab5c349012d384284fac5", - "0x9fc9e919898303f537988a6695329143a77e965802be3566396f7a581962c3de", - "0x5277cff2542cb90c1698c7e673b7ceafd16cf4d0750272ebb51e3aa3fb02f3f4", - "0xea07718095d00493c662b21d0dff8bf747783c93897f6f2421571e2c7e3e8955", - "0xa8bfbfcb73a903d2937025226b38aefcfccbb3f9d3fcb0563ede2d9f1cd8ed84", - "0x795af85d146f9e00cfc5d12c97efa5073f19977afeae31c636cb3a6c9771ba14", - "0x60d169884296b60a45cc87beb366a513a6bb7ac34e6acf6066d9abbb1bb3844e", - "0xd256c59553a03c8069aa3dab431c2868c6dee246fcdaa9683b0284d462ad3fb0", - "0x1a399a1ffe8e7f5eb5fa69e70a620e1b15087988934a754a468ff47a7c2f8add", - "0x25cfa588df60eb1127c4057ba949004ef8f7f2681e435fba925f4bf8ce0eb54a", - "0x282d5589c98668c7a9baf871dbd48a3a8c263ea55452086ebdb3b4db440fb9fc", - "0xdd3cfdffe34633d189d9bea7513b890b6d54c2c0d12067d8f45ae72c258c77b4", - "0xc81f96420ae777252b04116d14bb80762c5169b73abad2e1fb23e8bb9334c2bf", - "0x88bf1fb814490289ecdd3d411134d42155a483b7225a496f24ef29d84df164ea", - "0xc6f0b78237824d0b240b8dcf1e31e75e93b4608a495fb7d47ed47ac70caa5aa3", - "0x10f4272adf03ae39311b049b460dce8579b424d3c169101a80aff74efc018846", - "0x52a6ed4acdf0766fc0a63b221d113e3dc7f9e22435d734972e3facdfb3447a8e", - "0xeb75f393b00cbceeace53bff0725e0fa3382e367450fc1c7f0005bb859467d62", - "0xd58b7c94861e7822f924356cf808c0b6ba19c100e49cd8a1fe2ca8a537bb20b5", - "0xd355030bcb4e35157543fafe7f204040ef0e0ecbd60bfbdb897add425112be2f", - "0xbe3ca964fb22fdb9c6c74f07381dabca0e932310cb88676144cd78cb374416c6", - "0x6417c82c4fa9ec681e767a8b3a26640d72c61ea72b1857bd61930187a54f08c5", - "0x0501ac461bf7f2e813ff8b58fb9ba936abe7eb0dc6ef0072f98c52f83458765b", - "0x6ed677008e96476990029e1ac8a86e4d9af83f812dc73d9b876c772c2beb5a77", - "0x9c35dd84c1d73d78dd3277d96ce4c76beac8c6bab498a8a5853970a03026b2c6", - "0xbb0b70d3be3239ac17b3689d67571c12318b51bc6811dea5e8908393d9a567e8", - "0xbfcc8fb9be4c41f8b26214e8462320e79c2fc126abd6e129f701b27b9ac96711", - "0x18bbf70cfc61152ffc64fa6bd21011e446f9d8d1798076e8841cecdbb2e25ccd", - "0x6ec57e3b3b13f8e3fc9298760ea47907c9e08b89bb7599c5cc50c83157a5b12d", - "0x1e681fa5a5d2d63ac23f45cc30720c5b33a3417ef0adccb10b9d9299f5dfdd15", - "0x63397c3ea42e3ea7dabaec5f3aa3cf7e15a4ff94ec745228c0b099928c2a5f1f", - "0xc8d14199fa6b134b84c48a44b9ef1962a9d08b34dbe78713f84ebc0d307c38fe", - "0x4dc0102f265b0e29cb403b258cfee5c73afb843b0805c9218bea86cc12a08503", - "0x4acb64d573cef699cb2d9036488a28bdb3d68a0d294d04c92cd198d42bb48098", - "0x872df3af6d40c5beadf565ea8f6cc502edcde941c43cd3024c812b2cbc33eaf0", - "0xaa24ebf00a407b1ee7e126cb5f396a1b4489577f160a7ec735e0e47fbf077abf", - "0x15e6c3ebacccecb59426bcab8f5845a60a584a18d5f6875431181a816d5dc0e1", - "0x3ae0bd8b42433be46a280335444e8e2d35c1afec926cd2c1d5ea537992c506f1", - "0x1e423a88a245221c826586cc67ea45dfea247c3e9a36c81ae9f0c0b5d5d3e5d8", - "0x5401f93723132c737589b457216dbf231a753c4c4619444af4eae9bc6153ee40", - "0x70d9a2787990c3dd8166357ab21985abc81a55eb0d50af7e19ec20454b314d4d", - "0x4ab7adbe2f74ac269840ae607a17824e8ec74054fae9d9b3998dfb162962e1a0", - "0x91fabfea828408eb161ac781a0896155ccf7d9cbefc3483cde52b35ec67883e9", - "0xaff4547e50acac2e3851620e541e96d7645682f225400793ebc0b959c6a09a01", - "0x0937506d4c9e37d57560bac5851795d6559e51df255ea2c64f2e119b88cc7511", - "0x88d66c613582fcf6df46773a1456304c4c0eddc212612b2dddab065b6051c8cf", - "0x2d6315542c9b30c8984ca951ab488906c78e6c84aec2090397d4a61ef26375b9", - "0x8ca8d613a382711420966787bf7bd541f517733d21ac4f893c282dd930f69b5e" + "0x0eb474b7721727204978e92e27d31cddff56471911e424a4c8271c35f9c982cc", + "0xe10e94515fb5ffb7ffa9bf50db4a959b3f50c2ff75e0b8bd5f5e038749e52a11", + "0x816e7463af7b5d2fcb804ba55f09e8452182b0ba6c995a34e144245d76333d55", + "0x3793af64c1ddc07ab61b2ba120034d91c02183ff788f07d3120fd4e6a48305b5", + "0x14c6106a17e041032210bfa0ca80d11860a1c6d95175d55eff39f97b8d8acded", + "0x396f832bfa3a9c494e9245471f0e65552613d87b6fe62128103590d95de72c2d", + "0xb060979f095c170a776b2b50a1e2ab0ffea80f6e522753fa36ad6f106ee32e9f", + "0x8f452e7cbd8a333ed04d819a143a8d3a75fe8c58418e7fc420bb2a717c0d4d2f", + "0x37fe1b0cf156bfc07571569af210540be753777903a308d5707538fffed75b59", + "0x6f0561d017cfc123b3f0d37b044e4f7231516b8731a1cab89afb569238643c33", + "0x3c1740c410a88c60fe8ccdc44e0ef2cf7f7314818dbf1648c01d0d94fbffc211", + "0xfb98115a7d6df8aaa40115f883014fe97300869bc016648e918fbf2df9608d41", + "0xef1099ab5ca4b79369048678d3ba78122fc081b00b6fd0f6907302a260d58266", + "0x969575f411dd78fdc5b4def0331fc93702029cc3c78851331a0f47dd0faae70b", + "0x9e53053e362be51c0fd25eaafd9e7c5c969d9f2ce8db4b3d4d830cbff347b0c8", + "0xf9de29944954d2b71a93532fc26916ae12fee72d42a79adaf940b0bf75d0ef89", + "0x28b2ce6635e60e06d643750798779023b2a807d9d089ae9ef7f223eebc15a71e", + "0x5295c06cbaff06f42bd8f5d9cbe94a840885caed02f9c9ba6da44a888ef796de", + "0x576eae673a4cbba4c7c7a56b47835ea64ae5989d67d119ebc8e568df40d908a9", + "0x891c0d38bc5e55620615da42ed77ab33806a042512034bcee134279dde1054be", + "0xbab05999d657426a11a902eb4c85ac52e2b72dd1cf38584cf2baeb2c3727bb44", + "0x3bd7e5a966f6dd2dc456948a8efca5584f5a4e0033f3037843a42073dda1f71b", + "0xc4f773ab1e34290f9a3d9ac6ede4749c5dec547353dddea494169d86f71107a3", + "0x993bf037ea9dd58b52027fb6f39332dab867c1e72af34a49d58a5a12f26bcca3", + "0x48b2d8d506eb8fc9dc0402fef26952111449aca0f90d0079f0526435d4e3183b", + "0xfef8f61df240e956f43759d2f481938421e064a9bd6a3be7a53b1213cc9588bb", + "0x5abf01f5066cf1091acdd1f99fbd5fd963633feafc42f9047534a3c1522004a5", + "0xa0f6205842260988161183b51bc36fae458fa184dd61844617d5c5d26fa78346", + "0x77309182fdc26d15dd8d9dd05040d7dc623412785708d8aac39eedee63931944", + "0x661c93311b94b7d4cdcbc0973225c794e71898a2b906922a6c1e8f7e9e289dc3", + "0x9d5d329ee8d9fffaee0111688d31a308dfaac922dcd61f818edd5303d0955be0", + "0x716ca25b184b64ba273b978de098f9946413f6fcc95bfba5cf1169e7e03dd611", + "0xa2e8d5cefa5804894fb42a106340b00de3286fee0992b5887b2cf471539d74a9", + "0xf846e05c9e9e9cb4cd2b7cbae7ae183a43a59ab02251954db632e538adacc357", + "0xbc01b4e23ea082a193e4c1012b1da91f3b4cb762009ca320bc8ed294af874e79", + "0x9218114a32da3ecf660d4d51b101bb51bb17c771561c1946c099be082f0a96b3", + "0x3b4edf03dfd53081cf40c0b90b35c1ccf7c7fe96cf131172eef5eec62f620ea8", + "0xb15758944263c67bdf528d4d7fe05737fbdbf7ffedce5f891a4ddf76177d2609", + "0x1f119374c385240f7b4ba1ec3d502be2c12c159411d5393ff2bd38cf87033625", + "0x8a8d5a93f3475813926b13a4d53f21b28dc79ade2b50830c0b9043e9fcd81576", + "0xcc22f7e2bb9c06c15ca3d82df852ed9097a2ddc687ee389e662de000db0c84fc", + "0xc2047e0dab711db791aadb642f8102abaacf7231b8dbdbe1f60573b0be015a31", + "0x1b4088ceee7783e4563945f162bd5da67020ca377a18d615923e8564d6709f85", + "0xd73450686e33bbda9eef53a95a86e5a0514156b98a5b7dfc6fdc0adb0b83cbcf", + "0xb374076ec961360e38d3486a31c3f72225440984c4c47ca790b4961d94152159", + "0x4f723f4fbd31d63a5421390e68aba0aff97249875688a7d9ab9a339d9aac7bc1", + "0x5fe51ff982edcad6c0052fcdf9a70e8f325c8140ab75848c5d7b0d670bd7edc2", + "0xc3ad483c7cc23bf8d6ae3e3e829bf126d5eeea9c53b566a6da95bef573b9c779", + "0x3c9e50ed9eb57cc055fd9a65a6cdaba2030d8b41f81348f296d7410c1d24ced0", + "0x0c6dfc1f626ff9e85ff072c154152bb3f122a2c1a45bc2d9e7da9b2d5278149a", + "0x92f4452dbdb4fe70e84ecd47af4b1af90975219797cebd451beceb6997ab024d", + "0x9a3d00686736b5b838308da4b8f0aa9edccfaba64621ce2988cea6ea2a267efd", + "0x8d602d0bef069177102726d5ccd93d19805fb5771a350a41e32755ce740b9047", + "0x6681e4097667a22ad3713acc27b6f87abd54583230581933bed9245c2c457ac3", + "0x53077caeabcd926466319a3ee5c51c32e01e1812a65313f113f814d53e9f1dd9", + "0x4dd4c33e99d86ba84f976c639333fc072e262c0b76dfdf2f589300af54048c0a", + "0xbc3b9837a6fa54616dcdb8088080e276e2e99a23c8e7de4109504293703d524e", + "0x24316b344cecd5e601cc0acc91ff94f481ca3fa26d8478644a9d8bcaeb0359b3", + "0xa7bafd3c5f4e3f6b5c078d50eb318d91e867b0e1c966027e3e7458eb104ccd63", + "0xc8da46b7d778980d120357c8de2bba336f5a2ac7a9f4183a0ee1f7597ed47d25", + "0x7469fc5d8c9c648cd10e538710e0f126542e59a82484e7fe56b73f4ec52c36c7", + "0x993bb7c0487ff61c97e4f1533446ae35b6346642e1230f2441da8b354111d597", + "0x90e3944732f86a2254dc4f30650f8438dfd0b777561fb02a8ab1c60438569c24", + "0x4e8472483679b54bdc600010fdd164f54771d7a99fa9272c683b610fff72507b", + "0xf72a861a2ebc232c25529c0f94c59996e64c59c36a1326a183cf171bddf2a75c", + "0x7f222999ba9113e2a64fd026a8f7244e6d2ae8f2a7e7d8d2d6fbde6fdf0b629f", + "0x3304e769f730522c1c5aa745c448075df026b8f82a4dece84fd70d0457050985", + "0x9ee5e3ccaaf94461dff9df8c4805ca831f58a1586af4ece3cab14a45f3b784db", + "0x21e4364859063e20153d2d06eae4d2c9e99354bf97fbff68406d8825d18dbce3", + "0x4805355b72b1b61b07814059f80b4da0351291cc932292f23069197a74127726", + "0x14474f45f38d7ea51418e5f03751c8bfbfb9b3e2957d3051e862aa3c57a63c43", + "0x69372cee3e2807d10ecb72d404a033568a159a5b15d2007537ed9a758164b29f", + "0x147223b51001166a4e65372c9c706f011f1ae94f4bdc9ba6e8960017e8898703", + "0x11a1e48a5c1d7088c0ccb8177d54db9e9f91a99aa7c24f702cd93f4646f181ee", + "0x809c902b2f4b8760c3d2e820c93d6df69a5d184a43a6c654ebe7067e7212137d", + "0x749367027756c27215b2f57168ef15d3b39062c9f79b3777f7fa19e8073de775", + "0x6a9fae37364f97e36e56df97acb1b7d066a608d8366d7e008854756dd28fe748", + "0xdc2f1b7a8aeda15e6bf4f5f424bc54828cc8520e2e7ba27bd8e28ba2b543aae7", + "0xe0fabc892d5c8b4342ff488b76a0400425ea70774f207c546fbf2f9f5b105dcb", + "0x151fb5e02d8eb3c3192cb8c039bcb4c121c4ebeea5e7f98927b85a730a24bbf9", + "0xfeb2f2ea368d0bd4c0b0bd97b444c365bdc0ac9ce2862b0d0162387727edd236", + "0x1eaf828231ebbae54737111bf3c7181fe3d7e9070def1313470d3f81c89f01c7", + "0x8a1b0565013cff488bbe3f35df86fb41c7aedf4d911130802c473f4ddb74d6d6", + "0xce9158b5c903312fa636e074e3efe413184652581a4877d40a0085965dc0bf9a", + "0x1cf602c6306affe2916fa09d3c8c018f23fc44dec8af8e83fa0008c98b4dda72", + "0x189dc4569e96cab937265ecaea76a0880ec97d5b84ac1fbd0cd2d2b36a8c34c3", + "0xd698bd07e485767c1da30bb218265e1304f6eaf426749ccba67478817af84bd4", + "0x47d7e101de73bb0ca97a0bb70094e81b82c63e519a6b2aa5fe10ca7351232870", + "0xb0d441b6c41072889c4a982306c9a40dff77b43425ecc4d771c22f3199eb7708", + "0x7893071deba67f2fc8e1b18bedcac4dbc05a020f37c764c555eadc42dd9d29d3", + "0x3c6d636db3621757d60b2d0e1804e19528ce60c9feed1ead93731820ff19b11c", + "0xde87aaa462b461c4a33e0739ef4cf56d442b7967ac7c5280816a959046b128b6", + "0xb237b17650adcbcf580b64b500ecaa7ca36921a11ad92c1e8992c57cc1a7f618", + "0xec379725db43fefe61f2495f7f7e0531d852e21f896ae806144c4d9b4b986e96", + "0x65ac5548988825831f0887b9ff0f2c13b7f3b49e4a67c39b1694e76414249f6d", + "0x76053b72ec9e6fcf0a28ef273d3e1b0842c3c2c0e905f5b5a3535ffab216c8db", + "0x2ab1e87489eb1daeaf8882c6baa0a8726aeac522e9c4eb4df71e35af2d22cc10", + "0x8c9c6adcabe253b311f6a9b8165ff9c5e26e4cf41f1acd80837e77fc15526a86", + "0xf143155230223a3f126c757b85e193a9129f1bdf97c0ce1f2785f14d40911f30", + "0x8c510d9dca593534f3ed316f240ffb9343d1e3cd6d005df6a75a1b354da0b36e", + "0x3440975cf818a718beff35a85d19bcbbd67e1b16ca9d78af34dcde31a28b3288", + "0xf56ef9c57109f9cb7a925bbb6d453efc19e8a45b331f76153d20a87d86a8b0d8", + "0x19a360772872003f08508a28a362c6e05650b385c24a928ddad4d562bfccf412", + "0x643720694b3773ecf20437d54a6be701810feff233f435dc701dbe88c9a6a13c", + "0xf8c0babe99aa26ecbfc91b304d9cd54ccfb37354c4fdbeb3207bb6d4647fabd6", + "0x481ccc7213d0188e817c071c4cc3a71c96befb9aa98cab964012fd7a8267834a", + "0x02d83ca8d92e0fe6ce7643ae93af60e38ab5659a84c04beba678ceef654aec12", + "0x24e6b4bcd0d97df196f2371532771593fe17be8fcb89f1e1164bcce8616088b9", + "0x3dc91775c50c04812f755f3b48d3d6a0cc599c586ce9d105e2cf4f3e4527b515", + "0xcdc215f05398ea3942d3a38078a3602cbe8ac549d4bf0e4a54191ceb2aff8f76", + "0xee02874e444b784f4265cc60b86a17382d277d03c8bce8a33241460ea8950699", + "0x35c34bc84736fdcbc4d4e2e089f30bcd186a052b2f6dcb639fc45a0aeb6969f8", + "0xbbb3ff849c36659bf2c00feaad9f7b3a342b5cfcf3555b7c2e467a0dc84e90e8", + "0x0584bc60fbe3fae9088c214fb519030646c3240f77180a0bedecd3e9c9f47f89", + "0x9d18a665d89439ad2c97427bdab3e598f5bc0da6a0ede2378f95c5bc31f10d12", + "0xe8a5bdd0ffd33a6fd03cf003c6d2afbe8493e0f0cb69e6366e22b4d1ff985101", + "0x7ca955f4e01eef756b680d09c25626cf50013faa20a12b0a334fd048a04e7b91", + "0x064254551457bd5e7a260a41ed3643746202d503813ceaf42660f9bd1983be34", + "0x1191044e354ea1e3daa25ed2175a6517659e96733d9065d81492ffe4472fb96f", + "0xc823514cf3566b1bb2e19a35e0ef0980bc483fa820d13ae2cfdbf15fd426c272", + "0x413f941f192d0ab77bac68268f45e2c9adbee23a3324d4ae8748d09735355a2d", + "0xa66c94b9603b3058b730baeba1b79d52f548ceeb5bac487903f92481060f6804", + "0xa84d4a8860bdff1fdae6bcefcdcf700fab7857444ef1e76d8259b005872a4636", + "0x9fa64d44edd9c097458d3901612a4b6f655a1421ebb68541cb1a4bdbbe24911e", + "0x402027770edb387510241a68a235723c6c5c95aed54dab058c43d21a6bb48c41", + "0x776281b7e341a66491603b7ae8ed7cc82b99febac43f94cb1c4dda73b17aab63", + "0xfecbaf0fc5a02dcf49095514ce26df927def3cf51f37e04471545aae2364f936", + "0xc477d9293f0ace7243f8b9c89f01210b8f96b4affc9d3332147ea2e2b693c99e", + "0x4a8b9afb9d9097831b2497296b0fd0fae76ab8a596213daed35cf87e6bbefaed", + "0x594c4e9851eddbb4a6c2ac72aaa244ff35d67262efb20935360360d39f7c7ecc", + "0x14b7ef22c46ba8400979b6c06f3b3023607145a5cc6b5b793daae758cb655245", + "0x3a9d233553d1ca4d9862a70ef133a5fb2df75276fb24297b0bd2927a39459450", + "0x22c5e227d5fa7616603bbf36c5e4ee7dbf285fb0cf403a3ae982da70c825cad0", + "0xc2c8d439c7bd884665da56e3b680a5e58ad1e98627fdbec6fa67d7bbfad33a9b", + "0x7d5682cd9f28493ba4b87be141ec99701bbcd1aaadf9840b81de1fc07d4ffb18", + "0x8845f626c5f78d1bea281f892727437f9de8f976e4c4fec6060b2115f1862db5", + "0x769fdf0bcdbaec1ffe98cd3500ce8341b4d7ea2dad5fadb0258212306ccc75f9", + "0x185569d1980147fcdfcd0e0068ab380f0cfa58a690334a558bc1fd0d07897e96", + "0x0ed70ccff752df46f981043c5279ac3f13e7f62c2bdb9a0a9817a1c119ef6402", + "0xbe121e28349e80d601ab997af844aa03ea6492e88d75d3d46517d8f835e3c3fd", + "0xa7aa5f0bb95566292d22891faa75b7ff2020b69fecc8a22d796cc3a60953d98f", + "0xa2611b092b00f78fe639c4fba0274ae474fa448b3f2e4b8aa4d06c654720d478", + "0x8e425115b98f5e41c8b5d03a9e17d56d30050d85dd06cfff12f002c546a256ba", + "0x988b449fbd8c35855154fb4eb22ba6b7b7095be26203d137f484c67facd40dc5", + "0x567c43ac5dabeff01d6997543ec7abf7998088a355a6ba8e70f41a243dd1343a", + "0x6f560cb650142aed532f17de763d61d021cdec2716b0d2cb27b3a64052abb874", + "0x7e4ce5fab8f4f1fd41f9e5f10204032ae7e0e38093b1d07699318975b33910ec", + "0x91a0820eec5390916bf464b1d16c00b5d94386c4c9f4cdf7e0b3cbe40747fbc9", + "0x9c59451a9a242123efa72c5fbd1564b7bcc0067ea9d025336d228ed26b9ba6c0", + "0x1043a5ab3f5a3bced84faaae0e783abb3b81c2b967bbd976042cb5d897d28146", + "0xfc37b3b3c0be392ad2a5e36c120eace1d14e637ac806e79a750b9a6be3c742a7", + "0xce2ccbada44a8db5144073e69914b322dc015273a75b85ea43fd9e21037c760c", + "0x6cf8336b5a410e10604f93351242cb3a6929968212abdf85b4ca9321115b8fdf", + "0xabbe9781950362be1e206d91ea1bdd6f32ea2c6df65b277cb89050ca1deb9296", + "0x922a6b85add6839494c3edff389aa1b054409c330b4a4e2a6c0e4f9bc85b36a9", + "0xc26dcdfa135a09b7eef1e99b445fb66aefb8bceb6ea715b81d78ba87cd56ed8d", + "0x87d647fa7dcde81a0e133aa949d574befefbceab24a42ae4f3809d2bb52a2d9b", + "0x85ee37fa7154568b9dee8a539340f99c7f1bbc7b9be1f2055636ed9dfc074e4d", + "0x8b0114dc9e249f1de4bb3d055790e4bf18aa28a938f39e8a457ab4a43b0dd613", + "0x3be36db134f4c00fc9e1bc376213c7073389c993b0b0744cba619688d6c037d1", + "0xfaf987eb2e066ad8871c489c23102ec5c58add2d13e62d56f2821cc1f4d66d84", + "0x678478da2955e6876ac49c5146e9f7c376dbf2f170f6404054ae4385e72f3f19", + "0x85d8d9dd6c2a8f6b6a1c0fc0cb55ca870d9a7aae1621c143c3176a3a81fcc29c", + "0x76f4dfa4c3387408c823a75aeb872ff39af3820375ff52f7aecb41c96e4faf2a", + "0x6e530647f2e4232063de2fa8f673989d7834d8cdf529791032888f2833880b80", + "0x64422b4dfff6cba0eb6deaeb4593eefc40a357469a7f7c3be078f80c66161333", + "0x5c7ab740510a4183832bd78e6d6105b0f9f928611f7d62ef96aa8dd8da48a72d", + "0x0bbf405e29f015d24e64f063d50ec6c616af64622b1a4132cde86f926e93850f", + "0xd9ba81ea0790f1f8adccd0bd203c7adeec2b490381b822d6b15293cac2f26206", + "0x4f78619baa34f2278022c509671a38d29366936d6860e79ab540ea46b66ba782", + "0x00c1f10211d7604e59a327239f00dc6d036a93416b7871cb214e8eaa52571834", + "0x1b6636708f97485675c0e5b21eb749ee4a5fd0dd886e6690090856bcc5178ec0", + "0x71366e853968c1bbbbf8e3d6e13100dd589521f8db9e561dd20ff8709b5c1a96", + "0x0d2c35a01646cb09e2b56b5792ac03047848bef7415ae26f787cd54ef8f327da", + "0x1c5b71047f99db30453e502c9acdf422d3bf97b0d42b9223ea1b8b9924bb0cb1", + "0x9988eb36e4a669638e3242e5ada3e6596c5e4ef36a83ed2d3348d35fbed4d3d0", + "0x8f00020f98f02af0749df39fb2f534d356e3dbe809bdb3f435c4a575d661d6db", + "0xf70a509c0d1c60afcafc7cc492c5ad575fdcadf6ca8e0e5f184c62dd52021129", + "0x72cdb6544dd469ab42e270e51d136b314c27ed0d6682f914cf3e0398399d2d5d", + "0xd5584896e649b618ab8257859e42ef7798c37cc85103a8019cec10b1524519f3", + "0xd70636cf5cbe78ba86b8de902f83f9c550a8ee31a019da6fcb0b1ab0a02bd31f", + "0x79a506d61c89cb7b1aef845484956389d5f6077fd10f8d1ede1e92474eac15cf", + "0xa66c0575cfea08bc6abbba03b0d10be7bdcfe6c5da9058cb34c22af2c8f3f1d9", + "0xfde316523b6b41fedcf11d776a53bd27fe3058c3912059197cda083a14410689", + "0x6774beba5e02630a7e4379fed7175f0f3d9f8fb5333451f25d5b044521ed38ed", + "0xb513ee7cf03529c88633176792a6b08585ff6163fe174f68e285d6315ffe33aa", + "0x4482f3d82f65f0fdf71fdf669403e0b835b5458e567dbd295b4f51d22f01650c", + "0x1cf0c0859b1839ebfb872a570e0c17886d8d7f26067bcd16af7f9f0415001aa0", + "0x231be14cb1cec949a4e806a7b3aebdb074d58e5a1c48b85c35138d5d3e967e0b", + "0xe8f0a0ef68efb2ea1bfb5d47e3c9446900329ff89a3ab7eccde41e09ec3e79b9", + "0x16348cb5e49e61010da09a5ad3cef83ab369ee3d0f28079584c23749cfa30238", + "0x6d33bc7f502436bfd0d574c3f6b1155c69f8a80e55c42c353e9e68abb46d932e", + "0x0e5d40ed7351b59846ca3dd8cc9c0eb71d4659e0add0dbfb0bb7f518bf45c821", + "0xb1ba4509de4c0f1212b2b07d949740f15ef8df9af8e7e9d765e6b407a0c5d717", + "0xa99615bb15371a15b92c119f8632f1ad7c29d6eb9a69e0ccf33a9dd268cffd54", + "0xfc3601e7f85e4b8e996bddcf1b34cb6c20462e21c715782da12d8e08a01cd21b", + "0x872b0f4f3ef00cc5cc6fdd71091de96c02f5898826fda4f837832f302497b51a", + "0xb34656439e4474e075d8ef523f6f74ef292a22281e6dc0b8fabdfd2339389919", + "0x048d4dc500031aa56d89e799499a86d6dacddea795ddc4571669fa55d694345f", + "0x684b8762b97a9d650f0f0e5edee73b60a29f6e75573bd6244518b11c4a571533", + "0x5d20bbacb93f7b03d92ae0ce8296bfd113a808ab3a8bd7703838d7e8356b6714", + "0x25efac3c3bc3d4f10ed9918fd9581d68eaa18fb72d3ce7ca8e36525d8cdcae73", + "0x48b593a335aa2699a5bb5a60394845c7e4c78046e050aee1c7f8831249f75b26", + "0x6db7243073caa6e5c0442f2f3926885fae0385e0238a69784ea8a00c854ef8c0", + "0x3a104e4932193c644e2135008d78c5153a9331e6d9dde878357c250a3b42b5e7", + "0x74b3b4666fa9811702d4eebf9680053043160be3a6c31a0105c703e07d530710", + "0x179f67ff0710067d3180ec03d664fb3d9936e8777603b051ebad4cbd0aad7763", + "0x38d5fd43ca73f66127a0166ae074324471b1a92e6f4bf99fde235ac408b35562", + "0x1f43748a027e7731c2fe5343ba7b61d7c6c6933ea45466b439a43eee1a3ad398", + "0x6b130b75bc42dbbf76ad97287a3a130ea29122ce7e48c5a8bd1e80a5f3121364", + "0xcd17f77d87174ab6ad6f2dc60d37144aed40b3620a9e6c9ac3e328aeae3097de", + "0x3b7fe9ef499348315c1a2877bd7fa44b622fcabc588687a6de4d2f75aad3f642", + "0x6c73525865791a7ca8410363d634f6babfaba581d7a0252c7f57dc8c8cec583d", + "0xdb16b0220e129be4c929888a8a46d21d422a352ac7b0360711d786eacb56598e", + "0x44fb22efd89e585079bca47bde1073dc052f8ddbad2c27cd8e2839bd4350b18a", + "0x1e6f1395d417a94162117b9371abf3f781a4b05d787f6a38fb0101bc36e548da", + "0x3eddd0764196fe15d7ac7069c04c4bf23070e57931493e9a0127fc521187b698", + "0xec104582dffc06da3cc1af1c8dc7522d26ab2408dc0f62051da2ebae1ec1cbf3", + "0x3616cc0faf8a5f5c19cbeb482be2ea8de01b2a3e81f067366c715607cf29078c", + "0xd37ca9cd5dc7c3c4e2d2f1b3c8db2a016b52444f1c088680c8544b6cea30cfe3", + "0xc3d85c7899da428a305d941e3637e33eb4981f071ee07c1ee1c82aba7c248167", + "0x62975f10a20de37466b1822859f11774efa4f37fb701f6cc0695d206bbb51582", + "0xd940124857e67e220e3d4dc27eb75ff048aadd9b7fb29b680cc3743b3ab6365b", + "0xc89ac3aa4725191e56fbc87d41caac2c692dd5adae638bf741f0ded040ca66e4", + "0x97454878805915bcb60c9915af0fe0558987dabe5d506e03898dede96544dec1", + "0x6ce55ffc54eec31d980ece5204876a3f366f3148a4b8c10cd190153cfc96defd", + "0xa4e923671f4ff6dfde2f11cca452ed4208808e93e1131de4ce0804cbe2e0d3ad", + "0x772d1c2a0e70fe37ac0ea8d7b4a789f92997bd654809f20f0ff7ad76a6d975c3", + "0x8d5de87bc2484465a4876b462ebc1339bc13b8229e6df4f1a9e9b458f5e9adcd", + "0xdb33cbb2dad0eb38613d69392951c6062eb669035691882fdafc526133d15d21", + "0xb22b8c0887f71de2da3d81a5fec2213ccb8a32060211077e2ed1613cf7962e94", + "0xffbc5a82fe0c2b3f3f34343ba6823f35884c8b1dd80fbaa68fd5f33a960034ce", + "0x9640ded5be08a8a7a2e6291a91bdd58bd108205f4cef5209ddd338ad764fa9b9", + "0xaea7f934206d00a592502b8b85159e64b56def4c72db3a790ab46ca81c75d672", + "0xb99ace258fe4e6be541c6e3468913f4f32ef9e9d1375c889e17ceea0c606e729", + "0xc54ae75381803d00b52ea6fa620766662e6f7946d550208743fa64d3aaf22c54", + "0x4e773cd4fb2347b796595cc67eb2b5c7be6409bd8b1944f4cafecb6fc5a60a0b", + "0x263f3826196c238c24d4c792c3c45fc913d4cb94c2d3871827ba43faecbf4d94", + "0x7ae1714256e21b9b45778795cdedfad1160d571004f5ea6debc16406bc2161f6", + "0x0c271dc055d8fb1ba9bf133f3c85628ac3c2b588091768380a881a6183514b51", + "0xa5f41cb430b02fb1027d8e99cd94dd6666516c785d7f618a0894f38f811bdeed", + "0xbf6665cbf1037e0085808897d8b04932a6ced6755fa52555ac00737e8029c7b5", + "0xaaca2ffc61693a6f379e54af473802770b3971f6accef49e5a2e8fc122e0a490", + "0x7a3eb7782e2c02776aa29964689cb1b880201e1b81c8cef39738d7f7235fb022", + "0x7bf417dda75c46efba6a8344775915d2b69f954afd66d8f52576e106d7a7eee2", + "0x3a324507874480d0f4e8466ed6602c99fcaa7907b61e9f2b3f100740f7866fe0", + "0x3589941fb7bfda9bf50ad93cfed18cfdf199a6468074416aa513cf83cc00dd2a", + "0x66b0965611bba105667a3990de5acdbd398d8d6e2cd0276b83814c4647bfe461", + "0x703258ca6154ec4cb1b9162678e3bb546ca6f9e626702f5f62dda98fdc0fcf26", + "0x2a9a8e3537b714cb3e158f7ecc816239786ea3787b1a3bd40482f02eb0b21595", + "0x46104b558f57296b0775d63ee4da42a716c234f3dbd7479204f35b31f4b3d55c", + "0xe7d9d0a86cc8b76526acb8e260de17508874d1db6ad19a4a84210a010212d43b", + "0x04af6e8bd51cf4c4307b2381b2e0c54cd991ca3c7f49b8cdcaff3aead70efe48", + "0xab8fe05db68e486bf2be0c507b834b6e496c1d1fe560cd3210ed7fbf0e9b867a", + "0x0e6b5f226d0bcfbd1f0a2f61189592d8974b16376fef3d0a67f757b796ad6854", + "0xaab68c29b061f8f72d9f3c6f2e318a7125a01010fb0c547835fa31e72d8eeabe", + "0x0446f90437150e4ec6246be5c718e5054d62cbf5878479457d522948c6e87f83", + "0xd1b4669e21c0b175589c0942d4423cd2b438de6665f0bca10818eb6246a07749", + "0xc20d1a68c015d886ef8fc3dede0d116199480164238617667280f833a4dcbb3c", + "0xe67504ba38aee984e9118960827ddce0eaae3d8797bfc87afd4638cb1867e41c", + "0xd3e985af3bf3e3ad0dbcdbed9ff1b04037bd1ff2e71886db3842a29f0ee8c4b6", + "0x8b809d1ae7a835f318f471ce227f7e7ff563a15d1e2463e8fce5852c9a3f9ce4", + "0xc232b56170a5796aa4333d29ad8ba43dab2233e0cf7b48d100aeaa4b2491d6da", + "0x9c338ecb25290e91a83978df4f5b7076b299ba5d87074c36ec96da0b3aa9351d", + "0x616a6134eee1221e531fc6d6b5861f5ced64e9b56505b169da67ca3c47cb54ad", + "0x4afd1e60cbeb40301c2ccc7129042f9a944f4a383a4f34b8acd7aa454fcd0e7e", + "0xd52d1be650ed156ba12b0d6be4b7fda1fe89927bd7626ec0ae45663848144e7d", + "0xa212644d968f7d3d89c6f12c3c3077184943d986dd9cd391d48f8f98eb1bc6a2", + "0x8e3374acfb9d1724fd7f84c22fda25f91737efde3d667f607b364e51beabecee", + "0xd77eb30cd87046093b27be1a09d93cfa5261b780b99116a79d6c16be7db838ec", + "0x05093b9e39e2d9f4fa95ff386cb2af67861359ea6228242be6b323c1eed5c7c3", + "0x8bb25606225d3451a981af24506a549e2bf62a362149e4c77ac72eef6316e691", + "0xd2749fc4a37792b3716634e3dfb8a80ba3e30fd73bc119069d507bfe7efd8a1a", + "0x3b58bef2d77a04b3281e6cf80f984b9067290bfe02a596b2295ccad38e887a33", + "0x2f69797f1800e5da4a4086909058ec857695a220644e61788b24ccfaf7e77137", + "0xd81872c67fbbd1a69d4805cce578b9f36bfd768d3fcbc2fd610182a7696e23b2", + "0x2d3bc9fd303c12ed1ca7efe27d85c7b5ffb8e079e59c86977a113bbbf863549a", + "0xbaef802512a7ea5006cf816c51c35fdae44a86daaeb6e9dd8fd0c37b4f744875", + "0x2e7fb70924e6f0b74541f2f4cb13f49bb3bd577f5bfe1bc29d805b0e7e1a3df1", + "0xe3918602d83478eb416dcf80103b09a051d5cffc71b0cb21461c5031d38befb7", + "0x87dae7dbb38501d6e84f738c11615dd9eda5f7b77e096a765caebea6a8c691c2", + "0xa19f74ad3f4e218fcfb15e4af95713cfff4f5f58169b789167e2b62617023697", + "0x744930fd0046b3f7de0ecf721e3b36e4b36c0f49eb98bb0c9ed33d40e76a2017", + "0x5bc7194687200989382831785b43f7f5efb23105ee2dd7a620a61622a2afec44", + "0x3672af2176d897cb8f64f2decfd924d74581bd85916be85e53f2542a54a24b94", + "0xe2e2dd1875e9265072d96bda4640ec6beefdfa9a91241ae078cec4c2a1c9b8b3", + "0x5866de65d88610e6123b7a57e28e196afac484045261d1a16b83fa232ba267bf", + "0x7224db0ae652be5fe9017454dd40c744c75e513841b5cd11d5fcaff598265c7d", + "0x04438fdfb56d125bb13f6b8bdaced6946299f8a32610205fabf4a8db9c06af60", + "0x9e9af6a569b87a4717b94d8253a0078409bbce7bc08874e091163b621a75b999", + "0xc8a39c68a74f23d615ad49d9d175086bf4e1047a750165bb071e3cdb70e1d639", + "0x10515734fb6d38cbb9a7ef33ec7831646636f845ac40cb24b08c432422763466", + "0x1604dce1fd615791c66246a7cd82edbfe860a5ac48d000cac1984faebc00cafe", + "0x56311f68cc563946e251d8c0ea74adeee6ed8dd7aba8f6ea85367defd5dbdc41", + "0x3fc81adf318fa6db1c4e7ff5424b235943667f2f3dce5119618e0273eb23c93b", + "0x38576704f6ca62083130dca418a9b68e374944d63521fc3f4b7039754d62f63f", + "0x56e2a402baabf470d0f9c3496d75e2c26c26ac159b996c370b118a313a9e9464", + "0x501af705914bfccf4ad29c38eee21641590cd8d334dce9055d90bff57b8fa556", + "0xa734b7f045d2a23ce602b032357a66763714c6e4785768f07d55c22d2f1de372", + "0xc80e2c739a3d142a4018bfe2074da8da33c471b93f5e7b44bb150b9eb63e956b", + "0x7a0b1355d05b1bf4c634651bbb2b6d65cb0a9772c30e4024f5e781e5d404376c", + "0x73827f7c7a15db5c17a986f31dd92de05579b0bb8def065e5f1cee472d00281d", + "0xcd64ee4b2a912d48e6beb06e7d6c9c236b5815434c0ee21cca0a13ff23dfb85f", + "0x768d2fa63c53689ed899f47c6f78844ace885fa18a36da427428f4af46a9e1d9", + "0x643c26723d5a4831d3d07f8692a6dc4456bb6190ce2abf1abf69159942d5d548", + "0x03e20a75c4546d5f54bbd7fd3e54c795c180b880563bf78ec55530a89188a9a6", + "0xa0ea4095dd9fc6f817c656913f8cde4044e2806488be48770de5574c0b5d5f8a", + "0xeead5fac8f3c83c5a10df161d95bcf1d27184c9fb9fbd813ec5f61347c11280e", + "0x5afba4426fcae0f1769e581fa6af97b5ef8fd417771f10405e1c9d09a74357d6", + "0x087f65be7fc2a14f216d7ce418a03fcf1e6169e8620db65c11d1ed6c0afed240", + "0xf9a7e93c40788db39b241e03afe329b6336187fbafa40c97ac405fefc1eccfc1", + "0xb02450b58c5afdd0907ee745263aa6beef662646b96b9ed28b0dbcea4f358667", + "0x5029f1169c92671ecaad7239f40fd93adf3ec07ce2ed0c4cac38b0cc8034def7", + "0xc8465a93a1ba7ec3296d98e0b01ad27bdbf16a347c5517b450905d3c3668d505", + "0xb85cd82c551bcb30a747b2258327dccb04094f918e36c3f120f55fc35abf59d9", + "0x1721b2fb8963696cdf32385fe87e8ec2c2d7fa34e099bb65498e4a030e20a1c3", + "0x6b6dab262c1a32a67353409d2f8b791b1799ee6a8e3c880877af0bc5cc5b812a", + "0xa634110e4766d3451718061efb890238796370da3c4a53a91faa96c8944d2423", + "0x91ec6c6f807285599e0a179d0d246caf10152e733acf3bb967bae35fb36561ec", + "0xc3b2012d5cc8d796d1890d39e2b1730dd53df0b98274bbfef8c93bd969912852", + "0xd036b9b29589cc551bf27ab95b6366d772e7d692d8fba48f473a2fc2d023dbe2", + "0xc51229a0306e56a53bdab1fda497281e23aba6ab17301c2eef3ce3d01f56989a", + "0x2652cb79e0c18dfdf545562b8569cc2775a1b0b1b465cbdc5880b40ffff22676", + "0xf24e0d6c03961043cb41638596c4ca02e2a2522a3e828dc4613a72ce5a535a67", + "0x01725e03a7cbfe2d6c5623829e4d419bbeecd1c7f925dbf1667979bb4da6650a", + "0x3b0c9824b726b2b556c6c46af48b84f856154490a51d775ba06aad48055bcbd7", + "0x2be2f1cb826d7575e53bc5e14f1882d73bfe145ed91b2ff56a885f66e136db46", + "0xd16752cc862f33b14f5976049dadc4f15f147f2fa76c50bafb38a7cb25c8f881", + "0x66b3ba188143bd421009c082031696bfd6d29fe7b9c3345e7e70bf6a470a05ec", + "0x83e017e8701b533c9fd22e30d63c3781b0ac9ec1dff4433fe7fb5c8f6f4e67ba", + "0xe4782b025953c5980653abd26eb95de1bee0524c14a74b970ec5615f98ed6768", + "0xeda29e9b36262e7c79ef9c0b60fddc66bae542b19caeddcdedf439573f773cf9", + "0xbc02ac1f023993253394ca965f4394bb40f9c7822ed6b2cbdd249e4b72f9b637", + "0x8e1bde0f2541d20b7f7e8179014e0f6b98eee5c1e0278ff1de38f4c13fdb4161", + "0x7b762d3d64aded9ff99e3423d7e676dd307b765ca6f1295e079ac53d5a4788b1", + "0x1027bb44ade6a1f82f11e9f298fd3957a9636bfbb97457c319e3d57ce72146b3", + "0x963864b3164578d4a7e58de16593273067a641de752b6df2c9b8bfaf970392f1", + "0x16bdf92929fe3629a57f737d83328d034c36bbdcd006301f28dcf52e1d1cb542", + "0x69952e47225f1aa86d952afb0fa8c668ae710a10cb6a94477d518c8f771f5c30", + "0xe68895f4ae2e4a35fb7e0730a5ef9c3e3030f6351ff6381f77e6311912ced98b", + "0xf28d799eeec538dcb2f371cfc6aa16f4a6808ddef0e6fd0cf72fde291d94f8ad", + "0x5a404922a9bfe57eb85deb66d8d83c869ddf96eae17e7fdfafef19c19efa1eec", + "0x96b735672e85aa95c2f8b4bd5ac80942923cff64a24991b3103e4ee39fb9a8d1", + "0x83d922f50174810fc45daa5a607a9b4fce69d8ab86f428ac57ffdcd9c2ff2908", + "0x3b0ce5a62116eafbf445afff0674112f01e1dca0e2af2b72d0cbbdc452177d65", + "0xe86cc93417c7dbcd4b5f051f4dca1394d272dcc2101a9e94a140b20f5e4c8b59", + "0x99b3e1d593b682e1b6454675593ed6828f8f4c5888b965981e3a7c602d89d031", + "0x81e0eafc2a2adf3d94938c413cd9f588e7525b91f39a689dfc3d0ce6aeb812a0", + "0x699e692ff89a918eee6d19a63caeb07832dabf1eb28d04ec97150c87045d9129", + "0x90ff00b66a14d821b05f692ee6d100dd61abef3234fd29e94bc84574439ed2e0", + "0x2de5779a122ccd84a88c3adc4edf7c1c03dd1d3e89ab45657885aadaa087e833", + "0x775a5587a907aa5ff13bafed032dd96c312b19dcda1b0e74e8a4bd327fe90e50", + "0x4fa48215f975442e6b9ea0629d308667242a7fe89f0cd0eae55ef1d35a3d6ab6", + "0x2e24c24731902f1b9e4042eae9e946b9d884dfa9f733ea5d4f7e778b68daed9b", + "0xf23a4a6061f45b1ff2095adf02ded238b37a0ffa9653fa9c1b0069e37e8552be", + "0x62b94eeb74bca8d9ea91aaeec5c13a05dae022806df28b92ecee99b47de999c7", + "0xbe6c1797cad2d5d9ddac3b3adcbf1622241e2560e3407139e24dde3fd8d3e435", + "0x7df0788058bea0911f2e30133c835515bd777f7aa9cab6bcd27eb3c0a6e360ea", + "0xd87066a4721ce567f44abf179184381d81c1c487158a6c57b5f2455472209a5e", + "0x0aec7d3081c3ee7d61f36e8c7e62ab74e41f00b664b690a341b9ff7feb5adce6", + "0x16345b31779e80499dc01f9ccaa0e9981b2b336500f33cb1f2943b66ccbf74d9", + "0x9ed6c6685dfa2b65903db0b234f4539906121330c5d55e6b2a2fd30549b2dc23", + "0x6539602958d9166335a7a0396ad72be611661bdd40c786cf9b0f382039c6b46a", + "0x72bbb4a201de75b9a4b5cf7381308953234c62f295df08b919c12535febf6fea", + "0x2d37293863f6b90f43979ba5944bec302008957e07b7c7f2292074a0a3934674", + "0x22677859ad20cf8b924d516b9f979652ac91a27459a4eba5455beac7f5f23128", + "0x704c898c04ead58c2fdb2c753359d10934e66b326f104be28ca7a32ef05a2bc1", + "0xca2b1ac29937067b761b57b58ae4069eecc799dbe089342bea274e56fde3d1bf", + "0x4a9773e6a2e75dcf1ff46c8f9931b8170a3609023f47c0ea9c4af000798bbc22", + "0x7e4dcb6c256eca2cbe9d168cc78c2702c373fd6e69c210d0713e2766baba148a", + "0x399ea7dbb66b95bae693402eec304f9cb6f4c6ab729d90ca569fcc2bb24d6442", + "0x49d0e561773458f834c96e8fb9496d4cdf83f2cfab75824cb1eabf8e8962c18d", + "0x80a0a209e41d0c3ff07ffe6a7f1af67997662494a327fa7f3bcb7209340974ed", + "0x2bdd6d6e7ae3f4386fc655817e92563e80f46e1b277be22f81a689de7637ea1f", + "0xb77f32374161e54c50dbc38822760874d966f9e098a2ea7aedf650adf25cc0ad", + "0xb49b1decd65a998a3dae2e4725eaff56276af3f0c50b2a3a35b6e94738d32808", + "0x319f78ae885011458f47ff1a110881cb4ac6a78c7d4d7a2656ddca73a88b58e2", + "0xd9fa2f47bedc0b405df34c98582b553dde76a46d38ac86d9d357ea0aca60ec2b", + "0x4283ac57e82bd08970ada71f4617728bcc467eeebb19c3aa20208a82b18fb508", + "0xf2ea3a5ac3bc77ff64f7c686305044cfe539856fb2833cbefcb283317012062c", + "0x840a9b8c756c3c3de7170c3597bbd085747b97419c01bbe484fc4cc7924736ce", + "0xa88682b957deb995307ed875c4044246d779e3f8c584cad75162fee119613806", + "0x7b9195c23833f65832a44d097290d8573b43e6f3e47dcb8c3826ef9a52fb4ff7", + "0x57bb0076c87f2e7187ea92f9f7643eb5b4b823b8eae9f6e74c8b676dd86b81a2", + "0x68593a8268b245a5c7506a05860755cce1be795994a7d736aba41ead4c025a68", + "0x90e21d5927d39329874688312eeb5296677ecccbbb9c6bdd4400c50c9bda09c4", + "0x773c0cde2d1f44575c89106a01881eb5d9593bc762a40be03ba979496ad7d229", + "0xc1dd843534e9844bcf406cc03b277e71d4e73026635412e25f3555d099f26a55", + "0xdf3f794bbd98096cbfa17e168c0de845383abf52fea618937ed81d31cfdd88db", + "0x1b05b1f316013609fbf813cae674f193a9bd8a75631b55278bbd37513b85641b", + "0x429321ddb251fadec6b6f794acdd8cc9d93512b98af23d20749d93c3c9fdbc36", + "0x6cac90b28ed13c907d094bad45574aabe2355e13e6a9504b6001e5fbb9c25235", + "0x89b43a3f63a2ce4f67071a121f447d7e843948395616116ddeb57a8714becd3e", + "0x6de560c95a0483d51410f66f38884947dfc787e1c61d14421129773010b46e0d", + "0xa0ba45049971dd4b906e73f917fd16312646d53c0cdfdc3eefe53628a58973e8", + "0x3d4a4f7155eac18fb5a126dcae2035155a140a84718f33bb20d2f1461e8cedb7", + "0x1cc19669bd91087d2046770cdc34e8f995cbdf2a0cc62bda70d6074ed58acefb", + "0x7c1c4aa1817de27c62f35d66927d924376798c954d65ba3ba02c0528d11d748d", + "0xf0d67a8f3c5306165cffd44476249c254898bcb26c937f10e8ae244edab1b972", + "0xcc20c5ecb1d3e83bd56e9213761f8320bd40982ab5fb669bed774b4490637932", + "0x7935073eb3e5c37ed1135cb22bfeb0e21727d170d106465fc35de75e8d56cf41", + "0x7d968e74212c501d0bc26ebb816b57a37a8cd2720caddb5bf66f489e13a61bc7", + "0x2c134dcc35d50c63a13bd8868137e0240280f049d7e392b97ff5f76d00aa1296", + "0xfd046f06c1d46d9125a119f786acdd76a85fc596f21cb15f367933b717ba7d83", + "0x9f5f067e4af3c8e92d2d54dd061620f0a13a66006b162a1eab4b1707499597df", + "0x8a6e1fb6205a423ec2920d448a376b95cac7233d5312287bd850471fb49e4f8b", + "0x2a6ea987659383f9885d24c935fe56de39d45caa89e60ba1768189318974ed7e", + "0xc2df6c8a4eae77eeaf11d7e5e2198ec4a33f19f5995caab4db6577fc1ce7b957", + "0x1e2ae8a42eb937749284820e50f11dfbfb606ddac3efb201e0b2664dd0196d63", + "0x4d63bb91f9f8a9965c460326f0604a27ecb0fc56f2126c6b3519b08a895747b7", + "0x9a46c2ec5dcef6f5c5b76d4b08b9d5085709182243cb8308a2863cca8cba13dd", + "0xea57019cc85f7cece4cea7eadda96dc9e464df2689957ebfe8d817b6996b2e43", + "0xb40e930b31dc1508480ffba351b102c8cab53c6603a0dd88bfed1b0da5347153", + "0xf51ceb070d8e7cb998cf4979ac985b4850949b4456980f523d8b9d72604a43da", + "0xddd28627f5c7bd213149bc4886bf4bcb8304f86068694fc743ac81ed749aec3c", + "0x9ef2b3df587caf086f4a9838a829491d1ef45db132ea71c6bc96a4a40d833e92", + "0xc9f7d4e19501c48dda5b0012cd93564898ad080a653e29f3563ecd40d36de84b", + "0x0565db36e6fb7b881eae309fef6fcdcace7c92a7ff148476b627c012aaefe4b9", + "0x08912abab10f16b92ddaa3663375f6e2b656e4ed89f2285aab6e410fc59e650a", + "0xefe9e68ca3bea929722bcccb5150884eb23c32153b14644b1c7f4e033dc3f718", + "0x4b33e0e078056d9efd857f909d1e409516f23da68105463167e23d71c90f6366", + "0x63cd4d1c69c4168798a3d9f15388207ea10ee4dc6be3681b0c7dbce5649d8f90", + "0xc8e7c25854d49022e9a0ae2eda8e7835a6db9ef7d612312e9deae23621ba240f", + "0x22c05e50f27e8bdaf4abb0a045d0639bd7f80057dfea638df6a7184ac49b738b", + "0x4a34356b5a447591ac66c51370fb6539bdf50fda9600082dadd91d33713a74e1", + "0x7147d53533ae40e886f6bc1c3b65c51570d72398f46e3266f2eba7b707b46b3b", + "0x1e49f75a30695e9bef14b036bd1c0f2b322042b2a02ca56604484e913b284c1b", + "0xf2445d48e823bfa77776234356ae0d3c1a850db236b3d2a95e5b00c4d7e687af", + "0x7034246c6342c26f5ae974576358f993d0e5e3c577e6aecdcc182c78082ab181", + "0x965067896ebcb2628ff10127508df1c811087f45ae258a0d8179d576c21e4891", + "0x384ebc34021ebdaf95e1bf0d8d61777b96a1ae65163cd3bd9b4311970a7918b7", + "0x1ca6e203cf1e058f20f5a8b1e33464801bcbbe04c79a7201ad6036bb8aa54101", + "0xf5aaa21a85fa9d502ef278262acf71789a3755d36dd8b3794becab7fb2d338e7", + "0xdeb7dec7ec133b6ac05c3bc0fea3b0002c8ffe58b135f4ae85b71fe0350dc7ce", + "0xd5773586ddb40d4c772541f743f7a4b08e9b419fe5b5b3536afa0b3b888725bc", + "0xeaff5bc016770c7cce7be21952cd8759a8d0eeb1bd849732c15dbbb82c613a74", + "0xb1a6a6acd39b4428accf9120a46d74cca6451ea4a182206425a8a64c6d6be5b2", + "0xfff27e5023fa1fc365db1e79cf3283bee2f51333059bfff47df39f12875e5fc0", + "0xadf1ce203b0acd4cdaf1d9a91cc158a21c823dcfb0740f089ce0830102b1cdef", + "0xcf20c92fcfa22d6fe7a60d1aab2d5a942db39d447d4ba1e9e76888a64694f1e7", + "0x210a684182ea379b50d641aed1baae3bf3752fd84feac4b3dd4e110c5cfc4ce7", + "0x220c5460803cc8db7a2b645dd5a4525b0703182cce173324d20e1c865a157811", + "0xba87b487bfae148239b44f3ad7663fd66cde8e21aac9e1a50bbca7bb7334aeff", + "0x2728161f9f040b4d92ba838d841404604d4d838157fc66f20d6c4c61034fdbda", + "0x3f8a6c7198528e5084b3e8d52d3101c27c5bed8721beb831ff921eaaca4c4282", + "0x2cc2574320b3c7252404db7c67b462fbc8d87bdbeb782ab1bbd257ee634a35c2", + "0x13aae0ecdc6a70d85412178ec12e971b2c4476d5e624938ca0284ccfa611d11f", + "0x6af7161831c3442db94cbe28ee9385fe79339d533b9c0fd3266213c2a5024a14", + "0x06185136927e5bc26ecfbf2299a0fc13cb447df6ca4a60e968be8c2b7ba1c2e3", + "0x70ccc84931d910a2489d50becf82383a836309bb90dddb21026d9e4e4368c85a", + "0x400ae9e4da0f847dcd4bb65e8f9f661a3b0deb78346b4f1f84fc712fd34410f0", + "0x57aacedf503300888fcd8db2138badbfcd663c63c3cf5b3e35979dad635c24d9", + "0x8fea6cc2da76b7cc7062af870cfacf4952b81f09c3c15d31145fbbfe1c0806c1", + "0x5125434cc5d4137ee31b51ed8306b4d665b8dc66504661b46c227e62a9ef1abf", + "0x254bc0b61211e0a57755d73ac618012938472912f855972b7ce62677f5d0e64d", + "0x2d231389c849ea459a7530ac1bdffa4d84908e2c61125a70bfcda932cc8e5efd", + "0x671ae73d4739bcd4841fdff266803117c5684c61031fff16e831a3bffb4bae4e", + "0x64c4db66cae82a96f29296b481619d79a739e2dfce0ac1f659d45f526ae58ee5", + "0x3f2f08ce2f21253f8c9a3fd650a885ca0e77f720a21ad5b4c0867150a0274efe", + "0x98c48268710592ee4c26620375968f2b8730a1bd1777239e6ffb9f116c6e1284", + "0xdc7a5c095c255e1984b4a5fa75c7a1d95d98097fc4eba898e644ff66951d8dcb", + "0xeee7579812ef09ae31068e8087536362a967b2893b709a458822449ea89a48fa", + "0x296e707796c0b9f9a2f55ad06c42d03625dab94af71c2e1c7016a7ef6645bf5a", + "0xd9a3eb363d4a36300dc4d1903a83447c89ec286f8d219f1156335da283992d60", + "0x039adf5a0cfbc394847d8014d64700ac4b6e78b531a1e0328bab256f7c407116", + "0xf9a92c6b1f0b0b3d7ae33cf5ddfddad516bfd7b21842d76098737533efd4f7a8", + "0x5a5d1fa3b8e05a81173e627f14e689c166776b93df401593db8035a65fba58f5", + "0x34f7fda3053b9d06e217223ee06fd194e2962c4a381482429e596df1fe319686", + "0xb4cfd9a71a98ad52c7705d55e96f04cb9064b1c32d3c346be51370b56ebb0f8e", + "0xd46a93765af68d238b776b240afd464a24d8c8bc869280ad618fd0fb6360e878", + "0xf3c622a4ee05d1ce27d59e7b9b3748547f4efdb1d6ff72a58fa93dccb7b76de1", + "0x6cb017c4bd8bb5186590cc4559fd9600399485ca917b10556b98cd7fb61441dd", + "0x7188f59c892b8754845d73f534587f27b7da67f42dcc1c73390fe2970bf0ad28", + "0xb4b17c93af08b9f587963e42703379c5e4f760502870b8096917b09b3950ee35", + "0x03165bf9bc20c87412a41209901d2bf3c8bc03a8586a1706fe1499641cbc4775", + "0x9ef57b2126a38c2dc456c13c272de53366dd1bf1fe768185a93f3562d064fa8d", + "0xbc3660089065220589409f7063dde34aa080179b3f22464fd9df9eed98d88b0f", + "0xbf1cf6eed0e0270d6be602040a97600ca7e1279db4279a9fb7ee643345a264b3", + "0x4cc471987bfae3b32179aac7018ba574c0315b9832915b5d0b804b38e9def6c8", + "0x51351557582b1d821adfdad36536b59b28f9a1f1243115486ce44d4b22d3952e", + "0x66d6b02183b9def37dce37b66ba4e9939241732b49dbc8addd147a89dd9e0517", + "0x47261859ce169e56d4e7dd75c5e2648597c7906f9264710c7e4dff74f353f739", + "0x38edbf1db358c82d0c945a7fc024f7fdc1165331cc19caf6b8943d3ce76b721a", + "0x5231560201678a39175187469f7e36c1c729ae060225012ff4f679f3fabb8237", + "0x763bfbeeab624de07a6e758368f8f61c0fcfc8cda088d2dfcbeb47a5eea9648a", + "0xce910446cce07477d424f791a71a375830ac26a2543b8bd1343e0d775d161e5f", + "0x950ba34133aea3c2947a5e5fc1836375e81c042ee999b60dd4a27e6492fb41fe", + "0xdc24f20fda563bf74ff7540a06f3631af8ab3b3722874a6b383714f463f5fb43", + "0xf2250ef512d3a11144370747f2c86efc73abaa81152bc6083f87aa217d16ee67", + "0x8760d0bc8f28eb2504f3bde3e429a47f0aed1dc2c7abbaf01c68033c07ad368e", + "0x7ef1c11b1f025f7e2aca2624aa9a11781cd860f24ce3fb525e7196e590fc5ff0", + "0x7c4e717fe77c8f9e742e312081d51418614031745b182746c7ceb4ff54deab6e", + "0x56c82f80b8d52128275529fffb3ccf7376f411d7cf9464a15fdecf617b4e7571", + "0x46f7d3ecd09c29d36a62a1a65bd3c59a14c82687b5466c9c130df14c286c2a95", + "0x1d04deaadcfdc7a1e5e612df6eb836f55caafb4f9bf4f1200fdfef4f14229f26", + "0xa0f5e65e99a22e14ebafc71f093dadc96c68883609a7460f904eb15360e3dd6d", + "0x8ea6c444466d4b6916a1b6dadafb87d75e2fa1ddd1836425dbaaad6e99f4d68a", + "0xd53d052bb709813e6dfe218dc4bd99c5ae83b6f5993b182c36a386502713c7b6", + "0x2e0cc1dfae87825d1a1d8946e021dc514dea384241e0a6cb66d5daee570c72fc", + "0xa419612e2bca19a3a8dc7fac4da86c2df4edcc2989e10d3e9050323011676b1d", + "0xe41649d9af504bd273b9da0fde578dc126afb55feb8b3c31a0d4eeaa9c7b83f9", + "0x0121be707b5666d5a78949b2ee263bbfbd013b69caa9566864711bda4c7ed0f5", + "0x788538d654618bcef0a63e31576e19a0872a92733ef7930ef50f8afd6caf110e", + "0x7777a3a4930828cc158f696e6ddcb87696115f473f219ac5582d8a38e0645430", + "0xe15a9f42ce5964358f862fa7a40bff0c8e8d7429a5ca923c9f0d4d0d574378a5", + "0x187bd59945e1cc6a877fb324b1d7ebdf661383ae7e22c56913f2e920de73dd68", + "0x938f100308d20611bd14372b16da0dcbc888868f8bd183d667064dfa8e67a161", + "0x5e61540787c83bfacbb58967280163f55f5ed00e733d6295099588557ef2dcec", + "0xe6625082f4039ef9dccdbeb9488baedf75fcec616ed9d5009deb4eba95cc680f", + "0xd01542aefe234567f106a4f057173b4f6eb5733e0ab9537af2db309edf38763c", + "0xee0174f3f9218a3418b8dd2bcd4132821eb91b31391b7c2c6e5a84d067d21497", + "0xbe26c679aafdea135aa493bab8ee348b255f50bc69592bbe017dd96b0da58b1c", + "0x297e6634c06193ed4725942cec32ccc9b4e77b5d02fce2ec9fbf580e3dfce248", + "0x820d98bcfbc008480ea32b162d15701357f094b1d7c99a1ff92fc0afd9708a06", + "0x82bce2be0a2d468b2fe0d3ba4ec1e5e8eac2d83f8b2e402b3043119a59cafd51", + "0x63ff3569d9a5661b6773a1a5fc10a522ea12a22399cd337ffef75a0d36735ab1", + "0x8431746d8239126bedde7d5c58aaf7f733dd1542c942d415d876ebf8a062f032", + "0x6bfdf119b93ef4da6f48265f4c526f0837a10c8db9c518d0dfe1edf40ae5fcdc", + "0x55aaba1f40c9089c65623f67eef8cdb827282a39cd0778f26e2f73106d3eee3e", + "0x0022a0b29d8188251bf5c6f37c76368dc9c7ed9e00376901162d1fff111273b6", + "0xf4bda8d3cb5b7ad50dfcf2668253e44b98e87d563ce17720dd1eb1a4e1c32628", + "0x994315a889329452a3e08ef029e7d902308022b74aa5a4eb2178929425c90a84", + "0x86a962d1d436f43f6fcad5b61b615f2bd32f10fe8c62428854ce98f4289707b6", + "0x3ce476498f26fd1d0b276ea639d438d7efd3c10451949efee1c91f279ef15ed9", + "0x199b2fef89c1edbe547e8c0b666b7b138d6f94fcfb2f09f26edc429ac163b127", + "0xdf3fd62e7dd0133ffa23a0da13d720373b57e85c28ee97890c355c44323ad592", + "0x92e0cc3bc262330ed8a1f42ad40a2db6c4e75e2d39e24a6ed5eac0855c12dd05", + "0x5b46f058c21b9447f8faaf78b2549f7f1459fa5ddb4211150bc26dd718f8361d", + "0x316b4f0e5b50cea376307236de36f3a1ebad3c59ae28dcf7838339d8711047e6", + "0x2b72ece0cbeaf94140b99cd9312eb891a1264a4d31fd839017e22cd4cdef058a", + "0x0c86b9b2da38f00150d49ac53ccb43a88a44181c90b492e886c54b0d6a93de22", + "0xba5a671174dfd7f877bffd7fb3179b1f3f8444ab14eaa9a0488207141bda26e8", + "0xecf73cee14b1a8fa5c2de5d78c058bd04772666ff455ca4225ac419606041f2c", + "0x1947b6adf9abeeeb55a66cad4afd016f6522faa641c4e14af94cf6e610959ad0", + "0x5467aaeb96dbe111a0d36fa66a71f489fb33ab8d95692695c09f4680086daff2", + "0xa21fd9195eaf856bd048bdb258507351e9a2c168920fd0c550a2340b5176ba26", + "0x9b0cf5690d3c3764f5c102fe1d5139202a1f982bd5afc8967eddaa6bcfb3af42", + "0x32bb410896733f9f6080a5b574b07c0af3e5ecaf69e995751e392c3905c11d20", + "0x5e98b3dbf58bf5adc0ccc9269aa10f9921afd44283837e7cb419ac4fb89f6164", + "0x051cd6e01ef3ebac9f27e1d473b0abc00d870a78cf894cfa8222d00976948b39", + "0x500edc8298fb83a103f5bf779d1df507644e054ef27ae61ccf31d883d85c2a0c", + "0x80c8fd7e50aaa14da3af3ec622adcf89eea9760ddbd5232a49ba55837be5805a", + "0xbb828dd031299bfd428c22110ff5d9f5612447e346e98401ab4a01278834e476", + "0xe2c5f408029af25cb9c130fc8fb5118660d08da399dbec0fa1709d1c0583de57", + "0x1be80d06b4ec5ef612e16bd8d842484039ca5663234174441f0722ca521958ee", + "0x21d755042a542493e44e92b4355af2f06f161c0e2583aaf6862730be7e9976b2", + "0x49b993b77606eb939ae485e82243e530e392af6d68be4ece5ace66a675a7a70e", + "0x954823b80bea8f2007503ebda5a6ae4610f94cc2c9a6ca22088a52468a960524", + "0x2693662c6c0961a92566deaa4a59204a0c436aadc0581b799e6255fe97d26331", + "0x4e80abe082c0b8ae0602c232ab0f766aefa702e744ff142cb9e101a6050acfbd", + "0x9c47c762c73836210a6bd78e5ddf9f2e817951d52b9fea0c823596c3df2a1fc0", + "0xe86094c8da0212cb0cd96f54c9f1b22c11feadc5599f6aa63285971651f11278", + "0x3031451f37f3e0288d61580e5b20e008a2ef5975e5d12345056949dca2c1d421", + "0xbdf90347d794ab3b41da6fb75b5d8d1f426ca2c4923216393e055dcbc89f3cba", + "0x4f7a0c9ebaa4833e7fd0ae0f3ac8dbecf3d97d0036a41ef30230e634142247e0", + "0xd1cdfbbf34bfcabe4a0eb90fb4d8592738203d245d68b753d418c4bfab8ae4e4", + "0xaa56db3fe5b2edc2ed277656deb51e15f86182de49836b4dfe2636de5488a86f", + "0xf67b05c233797d61eaff641e5bd35ee830bc1a8440e06f85e034902bd1023ede", + "0x49bb9be0064ff46c4b7820e7dd08002f3914fbf9250c96873bb3dcc7bddbe3de", + "0x594efbc23c0a371e3e5478c599466ff3a8d985444583b70f275afda13cc05c9b", + "0xd1dc59771492ee0881398f87a7c90db42874d720812c1e105b1512531d9fb1f3", + "0x7462bfbf8457d1df1288cbaf339861dc91c02d772f3c1ff8c215965e555d6905", + "0xee62a752465879dd62d08d7a15a54af1e813a1bbf2035384289bd634e2e99524", + "0xc7c66334011807d017e0df794df5f2f36c4cf496ce0a3589465662f8aa5433c7", + "0x839af48e65e3e1fd3d177d90f1dafcbb0209b107bf882cfe2fd514be625c1396", + "0xfb4eeb8514ede5bc952beee0e7e78c6d7ae544e6c4d935a6c92375b224e40c3d", + "0x38576e990356b7c44eb1dd531fe28420d01d80130e0ef0a42b9a8b01d2687822", + "0x434bb4312789b8cd93c5f930f4305760f86c54ab225b35bec70954aaf2fb4c2d", + "0x19ae08dadbf2f7da90ce777913d59e74592cacf6f385600f7d50cbbf7c4137a9", + "0xfc9a8ba8d7eff3a582725f8fd1539c4f77a87ecf23505de8a321ec6d568cab5f", + "0x20fb269b1a7908ccae92532424cc94604ca9a0908bd7c5e446a687cb3be9e0d1", + "0x9fe0a0e3511056762698573eee8ee2b0b87a8b6daad2141a9ad00c5b159521f4", + "0x3630751af37fd3ae22e78198868341e86735b03432879fb159628937c6bc28da", + "0x427789cffa2250d89b99d50969d8dd9917b5f4c721ed9de79cf81dc59f94d81f", + "0x5ad7e16bd42e35671230458f8f97c18baa5a1f81b675df259c9d2d7cbb09fb77", + "0x3d58c8ee704a934f6de776ef8373c653140e089b85aedd53219dc0b46ff03b58", + "0xa5a0719b16d8771b34e050660ba965b0ebfaa06bad1973033cbe2fd69fac5886", + "0xcd66e1ce23416fb4662d2b29dd72d9f8f981c66098820058451441213f2947aa", + "0xc7eb6f1df45136c9adeacb03eada4557326aa0a22f9ac0d73df25e21beb6bc0e", + "0x890eb4c610c7036e1494514e1f7ff72f414c51143fbf13cf2cd03d8d37a03662", + "0xa54328a1d2ffd9aa3f38a9e6a0539ad2517c4f6129f01768891acc0a2b2a721f", + "0x147644decd98b450b284d05d7332629e3c6444846f7c71dbcc892d3191f2efdb", + "0x1a19c1a8fc7f9d838cbd736243e66b1f637f49b1d8734c2af417227a11623b30", + "0xa8c14722a6f7e7efe695be4e6a21f2d1c8b8d71e2cf69e7645ecc5cdc7b6355a", + "0x8eb33cc1490499aba376f581b68766c4fd40e7d6027f223eb46e27199acc8d67", + "0x1b6a906a5321b057f453624693d4ae6abe79a5b8fcd63a777dffb8b2ea4184ab", + "0x7185ec1f19e7a84c9f914dd223b382ff56464b01a1b88dabda415a01e1d0a1c8", + "0xa172df0cb06617eeb95d362bb36d5e5ac52cbdb2e5f3c2cf3d9b78ef28fad82b", + "0xa11941ce1c866d077fdc995acf3ff2ee0ea0481eddd142f9b343c8403ed606a2", + "0x1958ac9a77c5b9825c401b204001dea8ee2520983fb3e738a467980a7bf9defb", + "0x6b24d043eab24359787ed7e93543967c9f9b7ccf99894c1ee7768f6235cb0cfe", + "0x6ab8c28ddda71b937d1a6feaa67b071f78ff7ead3a192ae63dac34ff24b8d929", + "0xf101e3da7546249b5b6d4dbe960c713cf152627a7482fc3377aa31f430c54530", + "0x22628e903ea9eb3eda9c93ac92d77b1b8a5ee62706dc5ddbcd079c57d5b721eb", + "0x0050467a543fbf0a232c8ce9f66eaec6c38c3c31b8ce3d590d1b07586374c1ed", + "0x4235a1330a45838b2d2aa9873dfbd59cfc0f0cd16e13ca9292f8342eec255fa3", + "0x2049ff9cebd379b51308220449b3568c6d7843f5b49f61b85808287f3d60441c", + "0x50c2ef0e832df29297dc524fcf3af4cd0988fbfea71987f3ac5cba8d4ec34102", + "0xe7260880b2d822d18c9ac2224d09fa18f5c324fb421470aad5af6c2605b40985", + "0xdf51e1b441b9809b26cd7cbdc4df27eb9c7fbb3bf764971684aab6c63e282a75", + "0x597b5c48840a25294feb135e0318ba6d6ca09aac476b1041748738963136a0a4", + "0xc710bd4b45a991f7f1387c25db70a1964ca4fbab32b738424d35a6e06e2483b3", + "0xd67460a50ec79c90a97e25d4cebdeafed6c897593fe8b24afe47a71c818a55b5", + "0x0ac1f2282e4491fdc8d28f1697026b7fa88f46204610cbaf8811d38dc84539f2", + "0xc3352ebc532273e4224dc0e94ec4cbb83afc2b5c364d71534344793032441006", + "0x42f3d39c81e118a7d515d82b6880104909a7915aeaca8ad64fe74d9fe88a7f45", + "0xac6fa42771e9cd6ba31dcff2455d2234c53c282251ca2399c727fd5521eeff0a", + "0x83ae44822213f59d34543a6d4fcf76b4e22cbe5a90674755072613550d348551", + "0x99cdb65200f9d1c602c5c2ded67a8cf2722cd7c1ae3f11d29a2c1b702923df93", + "0x2adda7cfa12bf5ecbc74ed4f4ea419ad7cd3e7cd03a0e2b32e924aa2ab98ec42", + "0x3da7434a58c60b7fc7fee8e30b3073ff4d3c381288fe6ba791f68d74d24ed19a", + "0x9dbe78f9121e6c0d99fa6d441f6aedf54be14fb39a277cbb5f19fd0b846305c3", + "0x2ded5acc49e2e1fcb57a66a81f59405febb50edb6b41d0fa8e445477028f422c", + "0xa46310f11937ce81ebe8d4c60de1a5c8787a1aac35ff3b6e2f0cc793112b7df2", + "0xfa693856fd1867458c335c6e903e5745a950ddf8a43cd9ee76ce8d0b3070bcbd", + "0xb374a194d9edb55d2946d40a16ac4617e4d0674630c6a970f58db17f21d22c12", + "0x651032646288a0b6fb5322626bbbc5b6b87dc5a5d59f5f39073f2f9574646c41", + "0x7f4346336c95c7fcfc1f849cfa63afd46dde8e346ae0801aaaffa9069f989e99", + "0x8bedf8e9f5095b4275635525fea6169c5afedff2ae434e42c5cde973de77ae3f", + "0xf92ac4f6fdd7801f15c8e0ee163241542d1359372d2189d8cd2a33f925933cd5", + "0x806d437ddf966fc6631a8f81a54eb82080fb2ade64a2b715872d8f648d23b57d", + "0x2151451d68f912b58bb510002407943ef6f2cc87a992e6df0765a4c239e63779", + "0x6a02bab7734d8549be10373e6395c368492b8518df793821962a940d5cf93654", + "0x4de627f1d096c86c1c1dcde2a314ba65700b1ac47b9db95e9ae68f8d28f52b16", + "0xeae202c747b699171115bb56652ed534d9ca6de0e8c3d947d63c6d60b5d658de", + "0x7bddba4a7c160445653f62d27c1622323c784461d52aba5a6f19964194a063c5", + "0xddfcf0c5ff899f19c4ed0604e7b4cc645ce5bdb7b7c7d6bcecfe7f2cfa3bdc0b", + "0x7d27d279f52b83afc9a115c71910d06a054fdc2e20625cd05fe35ecb03734f5b", + "0x415f6bcb216ad524eebd7bf177bce80cc3d5fb3e920ed65a8ba6c02f59fa88ba", + "0x570daa81ed1b593529a07396784c2996d5703f4124f941e99e8f9cf6b608b1f5", + "0xb9da28526fe8300989e16c83c4bfe418c74878be1bf3af12ff3b9a098a4c92b0", + "0x691938f83dd63e39be2fb03422682ee8dae8e0a95bf4d09b4727f8162b2da11a", + "0xde168c58358db826c9c953895b7a0419066e65eec0b7fa479c328719cf70df6b", + "0x65a7b2207932e96c427a6c01efd0c3f01a37e02e7dd98b18ea559c2a6c83c8d2", + "0xfe54ee65b1b8e21292fde2eed9ddda163036cd6745254bc7cb9f3dea737832fd", + "0x543d64c2a6b763cabbdc1a9316f37115fd572d96b5c75184c155e68532fdc8a2", + "0x31b41a4f481a786bcf4029b19e84729c699a8d742fef50040221ddf6785d7335", + "0xa383494d908727fc6198035c24afb3f352a16b29b0c1639062e7169618bcb38e", + "0x3da745966ebad677a703f5db94777fdc307f6e3e66a7c3c5ca24f35cff3f43bd", + "0x32fbcb24d42beb2128d95055706b767f7df7ce16c1613e3195342db84dc9955e", + "0x1723ae6147425f5b01b68de9847d79b918ca0f85a800d981029dcb5e3c62eb8d", + "0x997f18b9977469cbeeddaa1bb31472be3806c03ae77973c857e32d6fe2c4d740", + "0x6c27575f33b1d85fdf9643c9ddd27085f4241518cbd5b776e0d2bce19b152ef0", + "0xacb86fb3209fbf57c42eb86d2617eb631e0ba36da7de5b2c7ed63f168a7b112b", + "0xae02559f4868fbe4f114eb320ff0f3a38086f364a2ee537e6051cedfcee76d6a", + "0xc96e439aaa996d4ea4c276d1592fcc06e829d5f3cebf163aeb75f590896a2648", + "0x87debf5b6912717ec3c0846fcfb5b459a15254660cd5064180c0c514b4b15f59", + "0x37587d340df2b40b3f14746b72c5a72c5f51963d208b02c9671d6c623079b584", + "0xdff2805c029c4e3c249de3aa9f5cb3b48daae4f4496deefc91ebe3251c18629d", + "0xa84f66a457869dfc95d625d40496250ff33894be23a43e53ec892481f1eb4fa5", + "0xf8fb34bf78ad6d52be6fbb5472f13322b506f594ad3b585c04f56ed8d0d9afa1", + "0x546937b89a4d3b59817377b9c2ffe9579d4650cce71aa26bf2c76c571ec495b3", + "0x5ac921894e98005d03aa42e8fbde7ad0af0401e350c8ba98c01543a93b37dda9", + "0x3cc76dc057c73f0e0fdff28d484a092747ca42bc10989c599d0f597ead6024d9", + "0x1992cd7e94e9ecfaaebbd08d91519d6b67857db87e2e67c546371738ae0d2d0a", + "0x3604be694574c05c63d69cbfbbddbafe3cb425d75a13e69d61b50fd8d9c947a7", + "0xd1c82e40206d2a89e3a1a40c4a1b63c62ea6fa0847ddc2b25f63cb9bbb4a55b5", + "0x66ba114d5bf45d50e9ab9beaa879ce18d02a8b4f989c29ea7e9ae604593e860a", + "0x94f74c09ce5fd1c8fcb9cbbcc476af20fcfd9cf01c7ea65c14917da7b9560ffb", + "0xa4e154ebf83215c3843ecbff1dc8f646f221505c21d2a76f47d55466d895f1a9", + "0x28c20a0e95e23a023678443d7bf5b2421975b827dbd617239dcf26bf6db9b255", + "0x55d8ddf586d61e137482e3f4bfc1904ce4e04d21c6e7ac4d8c7d29b1483c8c0a", + "0xa9e1aed191a7a1a92bc99604e3b24c02356ea378b16de109362aefa2fa978451", + "0xd543ad635db78b2518681654f98a32d227fa6a1fa9b7043ad12cf58c91e8f729", + "0x102fb87da8b57948fcb763d7b797233f21523545f78388d8d05c6d7f2a4b388d", + "0x4e7273e2a92e897590988f38f8b899879aa1aea754fd5165364e8b98a66e0d62", + "0x5a06544527f88d9fbbc5905742863d873367d99e574d75496c59caa041e2b612", + "0x6a8957954db14594746daa61f907e4694e2a749ff53ea6b1dbe77d7d1f378d22", + "0x0debcd48486aa0d33a783caec0d6fb1256ffcca39071041fed7f047eecde8640", + "0x9d0a9b13dab1888bf0eedda217c501d76f587ee9a8765bb455cebcca0b705599", + "0x30693bf8c9bcb6bb4187606f98e138700e999d8824cada72d3d07f8c104fd263", + "0x494ef870dff64d1d65b4ae4b49ff13c145a6058876eb657751d58c06f62b5032", + "0xee4150e64f9ead8124d50d56fa4b6e6d185fe8ac385bd2a9db7ee991f6e34c02", + "0xb859d7db7abe48cbb9420d008d94e8d47753cc78962e5dabdded9438bed56b1b", + "0xf8b1fb734c345111704d73fe6944d0a274964a347d7dc5c7cb8677104829f5ce", + "0x5dc002623d9b3b872900b0b313ae8520009de730577b6eb2e2de18ae5cd4ac94", + "0x4d63e346ce7e654db6f067e8348c539ccf622d84020812724b936c19ff4f86af", + "0x2ed43f4e5d6889f5379e42d4a06de7c343080da74ff353960e4cf980f750fb90", + "0xfc61d0c90ecb073c022c87098045b6ca3f2b66c94f3723c679d81ac652b16f72", + "0x7e69914b56984b8c7cc9db1732c3d2d32969a58d6662509846e6faeb1305586c", + "0x0ec9b1b68efc96fc7d831ac7316e0ac0d908bac31be330d905f87b136556c241", + "0x32fdf6c25f6c741dfe468289cd7f019ec3a40c5d8fe882ef662b798491c0dc34", + "0x1ffbc6b29826aa58595d1a412fb90050f2bc3cf0ebc5462f308d4c8d85a1eb59", + "0xf0fc93cc2868cb9828ce16463e4cbd59637672d5815dff03aec7f3e1424eb204", + "0xe404321694894ab375f5a65c339f2cd2a53fb5a10f312082ce019681f6ed64e5", + "0x81ab1f93747c4804a85f56b0c6eb61491b958504ef7b898fb1362eda9b394e1e", + "0x1535d439d0043d1436de963e3eba47335bd7afcabeac4d3fc3f342396d3538be", + "0x42da1b95481bfab6cfec59884bb1ac7572636c8f489df2768fe2140cd2702766", + "0xbc3fd861f6e09efac1782d9d383c4ddb9b4268216fbdf3c25689162628e36cec", + "0xcc74c3d8b44a8cd23676babb4efb0e67871582cd5686fde9de6a052c5bf91ad2", + "0xbcd7fe80e95bbbb5ac93b1df5ff0b8e921e7ebc4960877acc1a95c478c65d64c", + "0x045e5918fa69606b9546f5fe83cd9212000828c54f9cab856f85d3a22536a751", + "0xc0f74dbb5a42bf1656698c37aeb904a33e969099f215a7efeeae0024c3a409d4", + "0x36d537998634f2dcab43b387edb63119c0f4cc68b1979a2ceb373089c531ecf9", + "0x87c20426fccdd225bd3b961c7adc1de3f9ac9640f6d26bd183f6e528089922fa", + "0x195ee1daad5c3d0052d6d633eda1c9f7160d488d4bc54f4ac3babdbb678eeec9", + "0xf9a5e6735f9c5577283e8cd717b56f69dc8306b23781755f2e513d15e6738cea", + "0x3e5bc3e78ae33367ce7450c5da7436f1faf3b1a62d238208df207307762688be", + "0x123e7b4f7e6b9338df2827a238a266376a20a1fd065e9f8a4446fcac4c6c92fa", + "0xf4eb14bfd197d49c42daa919322f18228d2d9ae2dac6dd7113c5e7d12d2ef866", + "0x78836678c20a40fbe09849fe190a9e74ee070f2056d7bef85d0f124676a93130", + "0x7986f7321971519933aa5dd507074c7b007328a7dadb8734eb4aecf732703fed", + "0x14485d24b7e90fc39d91ad6051b7f596d320b1f88f54fee132e032753e59a766", + "0xa80a9a5db758bfacf831a54022c85a838e30c8611ab4b17bda0641994302b59f", + "0xedf1814fb78abf675f3c5671c3618e5e51105647997d6dea6a0cfd1f0330bf6d", + "0xa91e9fcdc4f2b5e029abdc6b2523079bb4a2f5346d8a5a674e3d5582b8871d1e", + "0x3dbe468159a8c068285c92360cab488a4c1ec37487dd54cdc0b70e6d7cf074dd", + "0x69877439effb3388639ef6e1cfa132bc605bd8a0da053bcca23d82aa453d0040", + "0x6751d32ee3a1244532e6698ce57cdd0a59f99130e1e7e004c2751bc49d10b355", + "0xd1760a4f6e5a7967985125d2deae8bc783e47b1b85e19fc273e33eb2ef88d271", + "0xfa934c087923cc16f636615657477c48c082623d7cdd35508571655dc14efe57", + "0xb6b1e4387e04c4ddf88ada0aaa162345cd43e54482fddb4297e1eb6f8ba1ce74", + "0x3988089edd46b57c0bc83b1bfeb0050b503cbefdca83e96f1c12e7ea80688a79", + "0xedcb1bd8b522ba5155965cf18c25a090be2f8d7871ce60f0f371cd033d5a31d2", + "0x2f887b56b317e9896698ec9059d36aad63d54d95a01d389aa196ae12e562ca2e", + "0xe6d6b89e1d851fd24cf54f6b60c6c93a8b014ae30906c156374d73605aab3028", + "0x177928968fef8c6da017b177f6be85851616775be043b64f72925e6b8a4eeab2", + "0x71a3de323d9a600e15c25a5a6e05089d849defc3830fd69738f548fa4c57aff2", + "0x8e7d92f316f96b491e4831f52a799846810dd032bd720dc891195739192f3955", + "0x12a3433e8cadc005ac35da334d557c8cdad63576613f07df8c3ec9f528e846d9", + "0x1406da1f5efe9d3de6a829f1219f731f3ac875c7795f72b5a9ad25a57970b9d8", + "0x15a849a0ea56a777e00325b4af4d9996747486cc9893c08b0773210306193521", + "0x6178e69be88e7e93878b731d062b29a34bf2951082b947f35f60fba2c8de62b7", + "0xc4142d4fe01091e82626178b66c13243c9b35de0f07a49e3c5f2ddc15b39feb6", + "0x8abda6239557236af27a2cdfbb4fb91a6b136931c53067739578ed13e1b0a2ff", + "0xf85615d9337092e25080430cfa0b7a24c97effd422a1947a4c07239d5221418c", + "0xf9534d7db3b5fc1bcd7033ade59fd66bbb94a5bae91c4acebbb1540fc8bd3b67", + "0x5ed0f8035d3920d6e94b881cafac324ce5688f8c97668715733e0d00733b0fe7", + "0xeb6c474a0adfd84c79b86090c793697c0bb39d6cb007c725c2ae7afdc98df5a6", + "0xfbfce3e019b0b29ad03fd9146fa368f9965050b40733ce297bce6acefc4668fe", + "0xeda9ed65fbb1c7fcccc91de519f69933ae66c8ed59fb65f64751ca8aa06030c8", + "0x359ea9df33d466b5dc210ef0e99f3b4416ce03a5439f49b4cc4c1b98b22a21b8", + "0x14b2e8729b70abac62120541229182264b78c7ba1a1a379ac8a582aa0bb0d739", + "0xcec0dbdb55f92191974c2c8ed716578c5ba04c4584a0770fc0d7d5cfbdcb2717", + "0x07334b05a08cab079354cc1f7a945caa3c633de89a89c18244de81ed56da850b", + "0xc58e0bb71287fe92564d00b5094ce36b7899c346679011e52b73eae45bace19a", + "0x9dbef45ce9abb762bb9b30b61456a90b74b0b6f5b41af9500699542d933f9535", + "0x3cf848f770e15e7f682075c77f7e980da6750d3d4cb038479983e341eea3c354", + "0x608a4c5958ef3b0a324a7cdeebcc3abae89c1371c949d6b269b2d3936d9fbdb2", + "0x66422fbb9044305317d900702c2f99702317a8a83ccae0911a2832f623356c8f", + "0xe977f86ae4c5b350b350a3d6af7fffdc9baa96d9a7cb24834e5dc4797fe39fa8", + "0x6f56fc66544e099797cc3b0879dd20b21796ace01a0029e0d8464a3764d1e858", + "0xcaef7878c703facf29fde1467dcd08b03761872f598f42f5c56b4cb367b97255", + "0x9055cc0c11cbbe8477c7dd35b37a57e7994248c6bde9ac05e85717cebd2b970d", + "0xd7b08c0ca8abb9f07e3df1c4ebdcb03b0ac2018a905d1c78e6825d2bb5ea1ffc", + "0x0184cb109267e58d5bc0193a04548f0c2b87286ab6b03a1ff7b6d88a725662ef", + "0x3005e0af1ac0c5fd6d58328c06cc7f5d89c8c4ad173106fee1a7e37c9f2dcb95", + "0x8f7f8800d29c66b4fb12334b622fabe1cc4ef06e4ded44e4315efc381987cd56", + "0xdf74e3be6d22159e0e02ce3b8f0b405e6469557ecbd12e4432d52f4ae4637bfe", + "0x2fa9a889f958ddc41bae5916657f946273447add502464674658bcc257f1af15", + "0xbfbdf04ab62a35b2f7b038b02d8c37ee946cfee18e10ef8a4cd5409a5fe81d19", + "0xc4e834510182950161a75a843352b5b46e246a05b7c7e47240b6cdf7e18b4de7", + "0x2534be362fcc238c530f2ce8f64a3366d4003a21e6f32493a082b7efa1d413d3", + "0x628e5f76af96e64ff34c52cc5d07562e72c53e7bd4b7585cbc83b7c9951d0d2f", + "0x41687c81b22f67e4ab6ba0163da6d58c81d94c5db20569b4a42fb58b7321a442", + "0x50f55f58cd9768b611fce3ff13e8da9195b1eef5d0a618fd27f7052f88c8fd84", + "0x1b64cdcbfc12c42e9dbc7a62a1f8eeb0baaab8ccc867f7a7308c88e4968eb9a9", + "0x77e9fd9a5d64b66cb901c5795b9f66424638b24e457024b5e71ffbb79ed8a863", + "0x35644de61c2108bf9d49efef164414cd2594ad4cca6bc421699458c9bace5491", + "0x172ded87912492ee521f79c1ef22e42b1d22f17c3286575a5d419fc00d928199", + "0x3c8fdc337338b107ff5879b3e95cf285b5128ae395c4b89ccfd05a3d942887d3", + "0xf4b22643ebb6d46cf292531792543f9699a99674978045b0c911818211be6017", + "0x783fdc538e4505d4187a0f341b066007caff8030c3bcc4bf49ebd31a8f6b4794", + "0x38e11f176844f680e75b65d5225533639eb522f39495b9ee426135097e5e8fab", + "0xc5e0da94d4dd6e29c8bf3684177a62051e7555ee87007fb07581c885be598edd", + "0x317dc456dd095f9eef53781c214806beb31351cf78cb1854be257b4039324b8c", + "0x5bbf954741e453e3157dada0a69bafb9ebc63c3dbfc0cf6e3fc937a1b14b7356", + "0x56a5354de5acff2b904c5b6b976c473277ac2364571c54583bd682e76bb3f43d", + "0xc37f17385f4e6015cdc8083fc750499ec8c9063544102eb0e3e3b7e0b5046946", + "0xd616c205adf0ecf00c7563fda837e94a4f48be8560ddd15d93988cfd3242b40f", + "0x1ecefd5cb0c61b120c227274dd60b42e6d25229517b20dc3e37a7c3b436f0e92", + "0xcd447982c518db12b8aeba63b68d8caf1eda6bcc44400c9d83c4e4d64b4e949a", + "0x3763ef2d96a89a302260ea66e22e3255001ba2f003770c03905d4f39d8ef6501", + "0x2fcc41e9b574af5402cdce8dc66d79488cbd5cf960209918863ac9526bcb6a70", + "0x17b71848876a6e0a8857f1e5d04762734678ed1a8addb7e378915a7c3f37c981", + "0xcac9e4641f50d52d77e0e77b1a1b5fdd25cae239864367b3d99026d3fb973610", + "0x55eabf50cf101f65e51dd3a54321c1897a67c50512c534ee9398a716a790ffba", + "0x49101d5719e4de5e4e88645de3c22cb3ab794df815555d4f22d54ac6a59f73f5", + "0x509cd8530c28cc098b0aa80d3006a8f71ac7ad56101b880288658917173b8c8d", + "0xdc0e15e6d321519f34d40c6b2cf5f6955c15af815dbe02d84606ed76a01fdbb8", + "0x0b8e107e7abcf80e85b3288786dd79f949449225315c9125730d7d42f0ab9cb6", + "0x07ba997ea28711f221ba26d724a09a52b2737b8aa8532e890490ad811ffa792c", + "0x713775500194ec8691fb540d63e99a70cd443e5539b5f8e2a993266bb58266ef", + "0x3b2ccbf35ac833e845f00329c1f8d130a3f804c55aa83c35421adb83749213bc", + "0xee82c15eb18a075b00de8fd610621683dcad88a19c1c507351b5be0de0c6c4bb", + "0xf874298782be23045971092d8305c469a309a1a33f6cfde7604e6499d2384cdc", + "0x1a9d88cd641f6468fceb32eced3710569d511848f393c2114ae33d7f36c12f3d", + "0x5b2b8c2ba5d3aa8a0503d14e759154d1f2f46d819b363025a77d4cf5e3d83586", + "0x0082bad01acd43bc2c504f66ae28056ce352257b7ba7e2c27dd36d256c079561", + "0x9c6e4e01a831348ce64da4e4bf04cad5f58749573e54f1062b0e2921bacafe74", + "0x600e1b0101161721066952d71401f8fe6e689b66b26e2e74cc924f5e914e8eec", + "0x8720d215255e4d5e2a688096506d5b25c3a79c511d8c0b3dd7ad3ccf542e9abb", + "0x48baaec9724cadc4f7cb8f10549b8daf87b2572151cdf9308b3e96f02b048f23", + "0x2adf0f56fb9bcdbae394025ae949e694e01599887e50c355c90c3ee5ff32eac2", + "0xcf78410476d781bae1567f3d763af732d2ecf56e741cffd1bd3906af83de1f2f", + "0x4e7e223f6881065ee722d6ff9603f1786e4e99292e9caaa75b7b1fe9aef00109", + "0xfdf0b390b0395f007b1b342065096e0a8da957b26ed4cdcaba432a202ec12b65", + "0xcd40d2df140abc1228b2e1f45b5d65a0f3e2ab8b7e740dfb5376b036f63c1c2c", + "0xa491347f128d31f68cd1ae536d8f982fbfa5b58d855a95219f104db741d3d2ad", + "0xaa91fef9cecb842de4df61fd1650267420c8336758fa450f87ee867ff1520905", + "0x75d1574bf7b23319a7c8ff6a0a7cae649313aca8893ccd223f1f77fd71c9b8e1", + "0xc72491916b25756e3f505081b7f63e32f3289b86cbe0181ac9d33d29f666b9e4", + "0xd446465131b34f091673736f70fa0508ee7065c4011359c302a603b6159cb52d", + "0x1380689a50696e1cf0c19869b9773528f01cdf20b8f8a6c6a7165fda31ea49af", + "0x01cac6d9deb56473681c02dc753351feda402a1a1cc2b4cc8beeb23884f40760", + "0x3f622e134dc529c5cfbf58a3ce91d57850578f45b77c4683b2dfe4530ba0826c", + "0x016c95fc875baa0a5d1ae22c8772eaf574a6c918510875f1000d65f3a779dd04", + "0x86e5f579f42ea54a96e622f4a6becdc5ae85e0d0af87997fae87b6707abc8d28", + "0x53d403f0d0f1f30d919ad7212cc5e2e73cb4870c4fb4e6d260d2573e9bc5575e", + "0x961cad0d17fbec30a8f614ff3565d12698af096e61836cbf1f0ea125ae3ed72d", + "0xc9dcfe7844bb4ea845125bc3674f326c0f178c5cba4349b9461e40bd6ec68c3d", + "0x894243ff80e90c4c4676583b4e428f13e077008d225790a234ae215dc53d33a4", + "0xe5fddd80d3cdbafb53e0cf3c095d33904ac8db83bdeef9816111d20384aed444", + "0x5c7ce294d82fe6502045664f7d13d02063ef24f0f4960e4fb62bb6abf08c63eb", + "0xb33a5699ac121a51c0074b4783545a86a428fb239b4307f1e45108c85af88617", + "0x37168f3f0220f50ba3cad0a558cd8b01a7a435b6c3c5cde98b420ba3b54a1cbb", + "0xd50928e60d00c23adfc916e7f9a5363fc8c94c8edb3aef41ac1dc719041f92be", + "0xa08b27f437ade4d527d883194f79927053ac55a3293487a65060aeaf4c4e5147", + "0x326e2d1f45438741b63d346f0da55066dfe0284382f1b4ee54b1d5552c4f7d83", + "0xbd96baee5835d9d6007b0b5957e452d71d1ee31aa6fde99796cce59b17dab703", + "0x1cbe90df49f8929ce1052049bde7d6169efe0b289ad4e05414a8e7bd61788900", + "0xa0b914df37895be6f5341f3f4013ce5c61f108203dbac4ff205d5f1a581712cc", + "0x1582e61974c0bb5f9f2622d70e772f3e9ce145be97eaf5a87ad794268cf352ab", + "0xe946dda774c96c7878a0daa686e4a22e0d9d36a88dd9c93b1776432adbfd68a1", + "0xf88a07db8c0fd2a1354c38617c16b4d2e4f8bb43d9049321ce47a8c03c8430d9", + "0x2adb489b34c480267927daf3ba3ca7567d542edb83fa82e8040ec57e25e3e6d7", + "0xf1c28c6daa3e97466d50d9780bd3335f3dd096c3389b906bcc12426ae4862a99", + "0x4457a8686a3839b7d3b592a1751c25b216bc64e9d0b8a81eec55601ab8d8a98d", + "0x0ea5d5606c5e81f92d31b49b2e54ce6c6314b13ac223c83094280d0196e003b1", + "0x33a91da49deed50914d998615077c5192be56e482ab230bdb3d480d283502e2b", + "0x5385496abf2e351c0cbd7f6fcb5bf5b5345783b4e512bdfa23b9736e77ea43f7", + "0x98f808b18e5778a1bbdefa3f19991a3d008c27e9976db0ce77ddf9e4e21a0feb", + "0x5381dab139fbb0ad6b61afa35c541aba559e2ac25c4ab1cf8a756c2f27c6bba8", + "0xf4bea5f3ab0bc9ba3ad00ad79402d1d62da125d311884f225ad8abe9fc36d56c", + "0x6018a9f7edb5ee7ada70c3e85f22ac88924d06031cff3f61104ef52bf0baa2f1", + "0x01cc4300f1cd2bb4948329d42e17a277c7da52696d46a60442b6f5600d869faf", + "0x330240c95bec1ac1a476cd202aa74e85db562750f860a9fbd76e813f16cbb639", + "0x0809c487d45161c3b85cda014603ba7efd6b67a8c7aaf314cf20c880ec623a7f", + "0x653f53065726f9a7c1b96ce7d836acca515f563a47c9d7d47aa8c5c030a9fe6f", + "0x37b8dd7b2a844e519f9eadab305efa5d112266cbbc76bcd5afc119e0dd337ae5", + "0x385b7031eafc345ed353d9b35dc53010496db172cd906f8e0b7b891b84a65e4b", + "0x38259038fbf1ab3f0ffac98e6b312457f6b2631f68ae477b9302fe740cfb8e50", + "0x5a963aaeadd708291b41bd419cf2ce0585e162e0d46635902b58ee85e317adc3", + "0x881004f4fabe3e7642c8cb5e99dc3909da28451ec442a299f331790c8065e049", + "0x3c721f828959782052312d30d8256c9351a141923a9c2e2ca5b605f3a92cb27a", + "0x3429b149f860e963ed3819ddf19164977d637489eae313331c71165c7eb8f824", + "0x44e291345b79ff4116797899da20baf28fb9d4d2a5d6b1661a0c83b8952e481c", + "0x00078c007b6c0b3b6603b0838b03ee9e8944fe16f99f0a35eda286a288594806", + "0xbcd3506338253f0df5abf0c2866cdd319fe75bad7ac6f18d1f8201164e0b9986", + "0xc047f5f06cc54e4bb54c8e3bf22245d68c18b4787a01d324deb2139d7405814a", + "0x77ec49a04762af36eb63e2bb5c5cbbf15b580020117639ed5546749e34285195", + "0xfce516ae95eaee4067e95a5752494974ebdd182fa47deab70fadc5afb5ea8648", + "0x2ee54548e56d2cecc3e6cff4e60a7664e55d9b1c1c9a61be74bfff7635078cb3", + "0xa79dce8f10567e060638cb2f09ead0b191e59d972c532a7e91b33d27151cc23e", + "0x436b4cf10f5cdbde72be02ca16602190a56c77f1686533e643c885351d4657e1", + "0x9070c78384138f5e17cc9e6148c7cb7591eb9864f042b82ad38ee263383496c6", + "0x12a8d5285c871a0b05e370a337834458ae2159b5d8cb4bc93b6cc83bf7351b68", + "0x3c07d35ea209492f4aa811c51202f081a3bfd6e31705ffec497d70bd59b7a6f2", + "0xc0a99b851e0fc4655cb3cb43547f4ae6c36c350aa71626b61ed3ad3492f04600", + "0x064404380c5969d8e43d759ef990658d7cf5bcb7b4f8512fe58a7e994e199707", + "0x3d3a61c95ffdd3c7f05b3574370bf4cf0eec605ca27cde051b5d77e062315f36", + "0x9259e0113f1e009fad7454eebb238e0c7f4b7aee8118b63b6c05aaa2f0bc39df", + "0x76ff9818e62b25fbd698ea021e200ac9314090b801e000ecddb71bf4829aec8a", + "0xdf0031d6e1c55717102ca1b3a0bd389cc0d227f0f804396d4b84b5dd26abb1ea", + "0xd0220e77632c2353d51b92b1638e909c1f41a7ab0e6801b65e344ab594f48881", + "0xb15fccf30f298101d5ca0034cb8585cf14ddd76d58f3a8ca71a60aff0d0438f8", + "0x5dcb3817ae05b8c8490e197cfdd3f0b701e61d83b8f6423b3f24f27ba0f4c668", + "0xf3bbdc6651a4ba011443f6c6542b3f45b8aa2ba8bc719e7220578d6362cc441d", + "0x1edc95bab3c88a66246393058ad1a9557b371e726adaf261a5faa535cb8fab76", + "0xe02975b5ecb9fb8abecab35298704ecc476d2e6205c2df900312359d5aebdf9d", + "0x2a5c9b033738fe9e7ba6949df526b5a735753464b746e7d1faa29491a8e5f57b", + "0x46ac373df276af8af25aa1407659a8e85ae12b51ea6ae0150ee2b80a76ea6d9a", + "0xe85513a38b54114f4b6cda2bc81a4dcedbec22749cab6676c061d95c7f38258d", + "0xacfba9967af17aa94f0bf73c3b1cfff113e14625742a7398a25a01aa29bf02e3", + "0xd589df920ebfb3c3c1660a16f74213dd6d487ee577bdaf18f6279eefb9252c57", + "0xb2b66c26bd139976ffc2471f8ec71e353108828bad5094a324d1e4762f5547e5", + "0xeac126eb94bb1ba443373fb2556753d95804891d4763a2cdd1d297f1eba0fe6b", + "0xfcb52c727793003a70941fb01bf6c184890a691b70c0aac3b11feb3987de8628", + "0x1c1b6aeaea826ed0cc776a322454663ef555adb0d3c6f50480957ac4ab7f0672", + "0x187affcea64fb6195ee27cdca1096142898be0fb8f216f10913a744f2005f7ab", + "0xb4e42e3a4c94477a6d5d7f3de429edee7d92cff93b647c71d7a20c1e07a35117", + "0xf960751197118967fcea65f10b51d9568c184a8bc968c609d093a0f6c15a71b5", + "0x0bb9ca3521abf8fe971d371749e5c2258b1fd4c681ded047d6dc7820d303fa9b", + "0x52354e8e99ecb5c2dcc1214c08901d715ba62a7463d56c76a6bd1287a74f5c38", + "0x8768dc0cb22a0ea9fde00170783fe3741501d958c186e2c636d03fdf8a995129", + "0xb4204eddcc9c75372de503645bddaffd3f71e8554c3bca09ec700d928a9664aa", + "0x97c94c63bd30754d51abf48aa830bac3724cf77e366965e9f61a100cd0136714", + "0x60dff72f08506ac9ddabe3f957f88a1ef4935f187b6c536643500d65512fd393", + "0xa94f4c353581e474a091655c78c491c38315e93e287f848c17843d807aae3527", + "0x09d90469c97087fd45cf1a2c5471c6e81e0ec1e7850dd76b0d0cfa9fd49aa13b", + "0x298d03c60b8dfca9ecac182b5c0f6818a4c3d84e55314c083f8913a8746fe335", + "0xbfa7ba8daa97bc681bc6ce413494b85ccfbc10e2bc96e148713e0325e21b3b60", + "0xe61dde9cf0c1c6fb0a37993df24dec2f221f97bdd34f607de13fb1f947e7f284", + "0x91e9a9e65d5076819146b246647b9698954bcf55e7f059db32854f93b325d35a", + "0x7bb2fb25b881772f318a10b6ce8896712c93cc85ce9c7c371337020e86817a3f", + "0xbfdda2258ccd28dfc81f83ad7cba81967120257392279c7412f0bb116605a21e", + "0x0a626f29328872380ebf6a10468307abda5a02c3a7b9e04763c0c8c83f903df7", + "0xaa8ee86e9446a125356a96f8ed47c3821da54b003558f68c823c4ac1ab966c81", + "0xe26f3cbd95e0a26683c26adfb71b6d4fc82b034171f29836cb9bf391cf172376", + "0x7cb80eb383da7d8c1120fbe79cf3bff3e5bf19b9f57aebe11f79ee23dd82e611", + "0xc9b85149830b7a2dcc1f613f40ae232bf5cce7770780bfa7c77ecd25ae0bca6e", + "0x859dc28f93d2f3b17e176aa8248d6720be498fc85017491c68d6af5f4798b437", + "0xdcc4dc79cf88601caf6e038bea275a98208d221ac8d3efdd5db3d2181c14c947", + "0xe1bd63a920d45b05efe5d2fb99437a26bb7049ea5b183e99866d6dae947ff724", + "0x4aa94bfe1501f4d37b0c55d77add7bee9bc7f24d444a3ed1c6cf27d67026bb62", + "0x10931498b823a9784c4aa3ece5e88b477050927fe4016e4b10de7e2e0eadbdb9", + "0x7f30cca2119b5a4107cddca59a88f10ad95cfaa879d97bd1e50ae6a347e71b1d", + "0xcd8a0dd7a4fa9b97641d5288375105273c9025a2c9f3d7d9d04179fe3f55143b", + "0x6c8ec850db640544b7e5b22c19253dd1595899a7663d40c4fe13de4258cd60ca", + "0x06ec895b6dd7f299edab3e2e3a65322fb7f8fa8c9a6182b7af4f0fa25acdc45f", + "0x45f6d74f05f7b366770428b49630e836c2fbcc72133ef03a1bcf9953209e693f", + "0x3d868a3921aede543f2bd8ccbe3b51468e7a87f8278e4601c4a8e740e8c339cb", + "0xc808c8fa7b02023e5c64999a141edf6e0ce0239e37656e0fa7c5156443f555c0", + "0x82c273cc2afd955663515932357f19d657eaaed2824551814706ae3843fa1739", + "0x5785f16929a6a73b4621e75d31958e2e9b00dcbf3a6b38bf3ed59672918b68b7", + "0xc8f84b888e55070682103999cfc315ea3d157d0771f0f035cf2ba03f6fe1b1f1", + "0x343a05e1a5e75e09528f194394caf6ca8caf94904d54d89c9d22abd5cae0d83e", + "0xddca7f95c2d9cfdc9efd9158d29045ba92a71d45488c40d28b257425c1c56bfa", + "0x008a2b681c4691d7e0de476180c969aa511467f27755d0d498eb22c9b5333835", + "0xe33fb40ffd6253b5701d24c59a4e217197f9eb7caf7c2223722734f4c74fca4b", + "0x650e8f1c6c4dbc76ace7d6c29b9a659d520af9b291b389bfe3812c1ccbd07c58", + "0xf88c36b8042df77734f99395eb68aa9f4b67a21891c42350e4d5e3e6d8fdf168", + "0x882c68aaa8d1f6acf005ce2ad3a6fef7ec1212ce610dfb8a7bea9417d87431fb", + "0xda73d75513895d5bd5174814da25cddac9a633507960e78ae6884b92e48ee699", + "0xf07d98594c0ecb16cfed18adb9f7b5b1055630b43444c70e6357cd18ebc09392", + "0xd70c5886426c55dda997d615d325b5cb5b652f5673601a045a113d94a17715c1", + "0x3e8dbda1f53c55fa4de65efc7d294a02d78c69a98d59049dcfcdfff6b7eaa521", + "0x67b14249f9c987298fb00e0bf560a976dcaa7fc0d02e816f84c3bf7a4e7c6901", + "0x4f8affa83492afa72e95a36f23356b46e58a0a19ecfff6960d4d6e5b9877b1d9", + "0x09cd2a17655988d2d8cd5fbe44965a6c15c3f123b75e1229621b9ab74d030e53", + "0x30693dcabd19e89bdefff4753cbc64d00c65a4af98f782e6e67b4e84f6b015a9", + "0xf67db822aaef8bdf7967c0dbe25015ff6cf88ce21e8bdd25feb764828ee64951", + "0x9a587510721ee914cf8b9c863859629ca0c8ed22b0aa023e9efb0756d3f9ee5a", + "0x5d00c0a840b96a19679736a7ba555f3e9bc5263b4b8437d6c3779191eda0a7c4", + "0x3e01cf22757510938a5aeb2ec6cf5046b7d3c186bafad7d57b81c7d2a99415db", + "0x0ff2d3ed3c5acfa5db9f9820a1a314865e266a823ab42f40bef6b0276af0a108", + "0xd3207e322207667c614e50be784f6b4d9c3f48362dbb65b17c62f5f33e631ce8", + "0x2c3330fc9f6394c0b8eaea0d156f2b9e2d2da0ddc8837e0a28d373aa779df9d8", + "0x56c8542686730adabbae6717ed8cc8f0b974037842ea5d1c80901f7c85eef3fa", + "0xc51d8a382df91e9f1fb0dd72d416a7d094aa3b8ca4f90561e82fdbb9b78c28c4", + "0x6507fec75b170f930df2e28dc75ef3dd7313834c8a8a2ec837d4ac27fdc906d6", + "0xea23428fd27ff3e5c6681b0640264ff22964c49ab0aa41f592280ae25d380c83", + "0x8e2a629fee2ba03e333bcf7fa0261dadff518dfb0e386b21cac0cdb2c7c514cb", + "0x4b00742b5349bc9892f2d36abe2c723a30c4a20ea5b899a7fee8fd759f066fbf", + "0x5b8d880357c44a79c0d04b5d347dc7c012f2f5cd7679c4d4131e5c481b45f1af", + "0x65d2859128eac961e29c063fd918c7a2b485bf72743cabb0fae8bb288f155dfc", + "0x3db9720d20d90d7d1ea448488d02015f4b1c36f556d704749723ae1c3a35aab5", + "0xd9676bad19db9f6896b2170e6cba496f5714ff9a70252fa1d4c82029435871a7", + "0xa36e49e6be40418bef884caac3b30e63fdaa1b8f622c70ede69e6d7c9c6f4539", + "0xefb40f7d197a63927f761d99596439b7b69cb7a39214258b372450fd471ebd88", + "0x7420e77f7230c7458f728f7ae5f63f0bb9182fd11ccb9a82bfcad17a8d1b4f76", + "0x7ce9551cd4cc5009d28a6048701049a5decbcf7e11904c588107da90f57149ed", + "0xafdbfc0bd5252cec1654dd24c375bf9f4af647cadad403923d6aa525fa44aa85", + "0xef0a4ef158ab6b06863969c24dc7ce5fabbd36181e9eb6d1662ce227b38f8e61", + "0x4e6d1c00feeb4218a0590fe046705fa35929767430f2c33b2176afb45f26a71a", + "0x604a1bef767235afcb7f84a20ef59d39618593def34034c67cdabec8f9436ea1", + "0x5c91553855f3a32f708dfd76c83a7d7f23aa80e5a6d2a7e9d83e82a333c9e267", + "0x48e35d198e8194ef83496392e05e3e14cc9c7ea1f324fb259c08a0f8385b422b", + "0x9df1a27224c2a20b229cc8686d95efb1570e822402c9df4db0b47f190c33dbee", + "0x020eb0cf345413cf0324f7561031eef27f188de5dc41bf38471547aec4e716ed", + "0xe9f7708c2cc8ee4785ed54a0c153730103fd92c42bb71eb4f86a93111ae11018", + "0xe7b3a27e3f5ff6fcf2925db134ee5db522a008db4d54627b729d5502f3968d08", + "0xc9c4b33c131365224675a89e4e6833181ae50661b114da50b14b0669d6ab7155", + "0x8986fba93ce8e336542d3a640d156029ea1cd99c2cc4e946de6d46e040e52bed", + "0x53b6ba779e5b91b5abe44eacd354f6f9b5b2343e66d60bcf5083ddd1a5147d21", + "0x854e090d7d5cacd3e52fed513055b51ae884965bf1146a629825269506f97371", + "0xcaae36c05b0992f80bfcc8f1c5d3a771feb88aa67f2c87b770637fa24000d84e", + "0x6992bffeb071ba81b30b8a6b19e9335f8eaa2da4361844bfd57f08488dab5975", + "0xdb63608d8eefa64871fa9fba1da1776a67d0c0495502c8eb4005eea4a0089563", + "0x57071fc1829365707d66abfb8e388478cf61a14f34af2c864b7299f6bfc2322c", + "0xe077cb6b750e158f666ea79aebd5e19e25b9d3694ac7a44efee1fe58f2bff202", + "0xc8180f9a9292284d2ba09dc40f89595ae6b554e6eb0c96aff578725076881102", + "0x89eb01b1cfe4089ded962a36ddfce84eb0c4337780446cdd88738e7241257c30", + "0xd1bfe1dbb1c9b6a06a1c18472ed66a82ca5c7ea1fdb5dcb9af1347e6ed97697b", + "0x33695a8c53e9e16e1a2255055eb069d9fc59436ce0ed698aa7323cd7e078cd96", + "0xa1c746d3df0eb28100b84c6c91da402c5c0d6a8aaee66bc05095820764cbdefb", + "0x3dd355f33c841eab61323ebfbe4a608b3dc9779a291651b885383ff70b8418dc", + "0x206c8095f502a995777d4756949d8fa7deeac36a106721d6bd1c536994fc8adb", + "0x95a9ffc34a966a157c5e797e3a1d0029bbb86999f1716cbdcca9bdcc5e77a5d5", + "0xb2c4e8a21c25d7cdaeed3a42b8670602580bc99ae5e85d4e36771e5cc2b7e0ff", + "0xc34e130d5fa9ae3df02c54a5eecf210d8420db5342af4041d77b8ade44d2c67d", + "0x5d733448fdde29b3f3749e70addbf4fcde659aeea24f90dab23997a696db5daf", + "0x8d63fe21beb60523466595253d20fe518dda259cb44fab5945943550b4e960ad", + "0x98e584f6dc76ddf7ab116d2e9244d0a0ecd99d180b1916957054f8440623f727", + "0xeb66965a23c4413fc5adbf4925ec5d133d2579c1f7764d6199eb4f7a5548aacc", + "0xc95df33729fa401a40bb0ca23731b61d5225f3ac6d159f243e1585440e16d529", + "0x2052d0e9ec0a62dcc0d0c892e7e704ed0ce03ef8a8e9c898a3691a571abc5c30", + "0x1f8567628ffc96390df8b7b32ce8ca70f6d8bf57b2ea0bd9e724c521ecd4747e", + "0xf2b48a4fef4c6c6127f7194ac76c57167cbbd65b9cff702daae1ae21dbc2896b", + "0x38dcef1bcf7600494424ae0b24956deaf664b92f3dd60b7a941ea144d789dd99", + "0x267d1afa22f77c5fb78434d822ee1c3fd24740d6a30f3ee4fdac95949ba8c044", + "0x0c01005442f62fd12a49115bfee0faf89d2da7572dca5b0e8eee445a0de8ddf7", + "0xa8d05f61408ed491620865b2cef9548d88182f37784e190b46c36bb09dd2d7e3", + "0x655eba047145af7d76cedf34e144040619d2d416367b57c7b7d9362a9375889a", + "0x5233ac6cb0ff6a892fa475b0074f4b6abd8e244f2a665e6649232e528bfa17f7", + "0xea8b2976e790ed22d708bca311a5b26c113e8c0ea4cae30607d94eb232ccb0f9", + "0x159dafbf20b2e624d22018f214cbbfbbd83de406e9bbaaf53ba46041fc3968c9", + "0x4d34b229e010a2ef72dec76c1449cce6f61d9cb17701803560af6b2072850ef9", + "0x32e7064197d2f739695788a00113452e03306a4f73f80ca62fc5e3ec223aa176", + "0xd1604bdf1cf9253b7b0ae8c92d09a2edec43221394c258d29707ba850004615d", + "0x07e0048d3913db33c6a9b45a1b232a2088341441d398b09319b455f57c18628f", + "0xf6492cd50378901ae238c91685319405d9779a1b78f22bf36129fd31fe709cbb", + "0xecaad91132667d0b1a283da22cdac651a4036224bd0efc79bb747d0c5e64b1d7", + "0x20565b022a8a8429a79a56aadbe2e32db24748238fab33eb2b0be5d83d1343bc", + "0x25e6d936a7b526d45ce1430744f5f4b41cf694d2cc50753cc88330e3e2a0bff2", + "0x7130e4b84c6efae0653dad6e16ec677bee7060a8da8ac607bde7a2b01b7511f0", + "0x93a8bf0a86793725e09b480d9098a43fc30a8420c5c2c2bd01ba8afa837c2371", + "0x2690922d4bf86c9a35e982b10f723edae97bb2a842f362036337396c7d9f9d16", + "0xd26efd262c6605d3be1ccdb03b96318613cf2d5b80350eea826758b9fd8bc28c", + "0xd3b2c89961d6cce736a9994f8707f78068a9806044cc2c96004d659f82753690", + "0x0fecacd3eb8c415a8db644b4dfc0ebf04a27f9b5e53bdac80fb927f40da4a8e5", + "0xd5600a3afd0eaedc221893214d629260cea97d7d5335e361d43183b4dc678360", + "0x340558e8951e1af701e95a963221109154f12c5870e9c9b9c4d7f9975d18ff89", + "0xb2ec154d6a59610822ee2318e3f279e249067893f806b129f4f0497b42aecff8", + "0xcf13e6343d50af1b2ff792e5a694531077e67858d76b39262ad19d6194e62df1", + "0x39db02f0b3f062645478457da8145fec8fbbc8a0981be9183365fbdc11a622a9", + "0xade17860c7f456c0b8014490f3cd15cb5f080e7112b789028f1e86ef428c06ca", + "0x1ab544445bb5d499c541c4fa02c5f850b9d18988e94ac6992525e2ad372d4936", + "0x2c3b4b33a865fce54d1ba1909924b0c6cf9a14a8cc4e3a42e1b4eeaaf86fc50d", + "0x857bb3e657f86c864407a7caf0c6b71e42427302adb85c853f330d00433ba077", + "0x79e42bfeb2cd1191783b7b2bea5e0e2693d9d15ce8d230e03dfbeac2c90451f2", + "0x5ec96430d6d1c1e9395a214e1a685e92c3780a78ca94a173d0e38fa6bca96461", + "0x544858c87e845b1f80043fb44f54a2449d31a0018025f1b41309a745415b1e7b", + "0xa26f04bcd6a580b99e9b81ed739ece117ad357facf1ecea246f891ce740029d8", + "0x857eb2767e67873c3f1ee4659c778feebb69b248950068a828d65750002cec36", + "0x7d6ad830b628a38b1753a33e5df98269d351b42d5bd60329e4c205ee5f30584e", + "0x6cbbf7d83f87bba0d4b4997bf336ac52934866cdd77e7dead51de84bfb717fa2", + "0xea77b839435e70cac6a89e891b8d1c495b39d8d6db38c352e10931e70502ec20", + "0x4d6a29a4487600b0e05ebfca7418dd6b43746ce96a41d4f17e25cd6aa1a2b733", + "0x3e8223ea6ca4ff147b59b025237a2a477495e746e7a551045374b27798ece58a", + "0xbf880aea05a3e440f31777f109995f2a1967272eebd9ff0fac241bee8747a8da", + "0x028cbf04056dc0f407496cfa901a4491c659173083ad73f84d457f016e0431f6", + "0x68548e63888fe0f203a333f5a5c950b36aa35e083a0161304a2b80aa626358b9", + "0x385546df2f083f4781a8b9d5b645516f5a77883eb7dc8d5e399f4f563e8956f6", + "0x358a0c7c14057fef517c38de9e2af33ab44f68c5c99157f9429db596e822c842", + "0x5f89b867c11d5258618595e2afd3f783e8db81dad073d8871a33d179f537cfb8", + "0xfd7328d25120390f5982919333df927ba3c63331321678906256c1ac02af9a45", + "0x406a9797947503dc57776a5c2ed6cad71ed975c05e15ef191b310088049c11d4", + "0x6e719945fb48d4db24d57a92e4d6da5cebc1a3db4a64792dad68b06f92c69c87", + "0xe2e7b80879a7ffc1e4e3f901ac99d252c1625b6824000ffd468b2d09d2cffa25", + "0x179979b54792b23d1f1940550d7c961a1373f6dda048817d087ed6d731af73eb", + "0x10b1ca5637aee0b063bf3a2fe5cc1729929b9932cecad392d7da6d567ca82d65", + "0x89edc6ecf4b7f292dc26c29515ffc3367850e5a8dcd95979244f5c57f81003d7", + "0x2cbdbde44b43c5dc078433925dd423ea51886e880b04e90b156957dd6a057d1f", + "0x6953ef4d3aa2abeac14fa44a0be4979bde0e579cc591370b08774f4e65f95d05", + "0x0735cc7c85194d5abf6ca0dec712db94b6b009c9ed74ff6781b7940064cd4626", + "0xc3f9b62bea678c0683ed688b77767b3fe3e4fc86456bbaa8c0172240321242a5", + "0x3640c7a7a1c2b62492098e0b5b9f4c482add16a86c0f88f8a60eafbf28347ccc", + "0x73820554bf239c8e1b92304f3df8290d18aaf765b45c8820f618d05eeb80fd66", + "0x8b948d61bbdf95e634d5c3827c66266e3ee42b49dc0a29100efe0f7028d100d8", + "0x8c422f252ce4e7c981b93c24db0984962019394f50ef5b62cd34e32ba7602026", + "0xd250921e7c17e016360e0b79d61d6c19ca40ca2d84c9a7c8d9da04ae4676c29f", + "0x4e71a2075113014494b5cf8504d48cefcacf14ca6be5d99f945ddafed4b58079", + "0x40d0dd35a9c91dbb1de1df4202a50df1745b2a5e80b256c3542bc0cdd5a2c524", + "0xf77e21f9edcadcf7753c1daa00720e024f56250766ac6c31a89e8afde10c9056", + "0xc70a38751d11c4240f2e94698c0a13a62d0b3cd825527c1dcc5e653186034f07", + "0x0f4f7881dcee934f71ab555428e89e26112ef6e99935761f3d4f314bb5504a20", + "0x82febe35f996dc229d6f6e89ab4c15f5659860505d64d454f625c95284a307b1", + "0xc557d10c1d19c90ccb9a504d31b0d91bedfe9a82388824fe901e8325a9996dd6", + "0xa241dbe076d02feb2b67d606b8592c970d193b84309196191b19087dd74b5eb1", + "0x4f687e1fdd09e68deac949de2738583e0dc2bf245790b5185e2f4e00f5e8da67", + "0x076b44af8dbdd16f859d9604f91e8809f929024eeaa6eb457c30db2657c03430", + "0x1bf2736aed60997b49084afc7a3d2b429d8b8836183c9ba71fd61afbcd1b5f0f", + "0x18ef59174edf670a07ed5eeae04eaaa08345d384d33cba45abf2a08af2415a5b", + "0x30f123870658c6cb69ad9314e6260a5ece2d5eeb4964601d4243aa1b56f4e021", + "0x36ac3e3193b6fa52a7134b9e4c7db6ce746619bd7f4d07201362062a3f98be0d", + "0x6a9250440bff309071b1493b2db2b4134c725ae364fc8a8add7e108f7434de4e", + "0x557876702f5bc2bbe17f13c76d0cdecfa68b0fe281f084b2f343d130405bb80e", + "0x5bb14f5bb4abe8e79909035a11109385ea2fa77c4208946841b61f1dc8a5366d", + "0xe7602f83ef13f3755b1f99c740fc46211f7ade9088a1942b8ecbd5a33482c093", + "0x30b8ee6c04d787ab137e7bd6cad1073e4e77a74db657798cc74c79676de337f3", + "0x01067e41f6b5fe5a26009378b7ea4b0515aac9449eef2730de5efc22554ed10d", + "0x73dc8e186c096c752f8dc2a69805e1b24eb5edc7553be26d36698b25829ebfb6", + "0x23eb0c950ea1467134caced1d86eb89d4addda6f8ebdbcb85d9127a5ce0427eb", + "0xbd0f1080cc7c2adc0874fc6d89207221155bf414e1cfa3f9360fdc98c820627c", + "0x0bdad5419ef94ee6aa76e4971981e54f7d6560f3faa3531f5fede35cb2e211bd", + "0x8a339a58e2ffda5cc2ef1e18a078fa09c3aec4b2a8cf9b6094ff620fb88860dd", + "0xc9a633a65b909af3133befda06a57b3058d625d816ac978f01894fdd7b3295e0", + "0x6dea631bfde98ab2b7db165e29ea75316ea50137d15a30a9a3b444d50d419e10", + "0x0a74031d338957b9564500f28f0e45aa571f48e4c85cdc52d6ac8d472fb66661", + "0x5f9e646f342e665b2fe387bdcabbb381a71e54f766afe9a5ca6c2cf999b50e4c", + "0xa8691691561a9e3236c0a26593f1c49b42f03c94ac3124b16b4aaf07fffb14f5", + "0xe806b7ac21b2e7d80f0e4583dec620b2b3399f4c1adc82a246bc77c847024310", + "0xd588437c72ddaff5ad3a154915700ade8da4023421008956b1b3d1bf164705e4", + "0x2f12257a5c3c0097b274697e648df08c31a3f8cf0833e45e45fe76091c7e22da", + "0x88eb766b8fc471e455e50a183b728e6e7fd3b5a152440bad5d1c7f49e173dafb", + "0xeee35cb04632e48f5b4c94aae1a40c372eacf5ca773c9dfc2fb3378803a6fd2c", + "0xcf9d9bbdb883ac7d171f808738dc5ad4e632d91f45737be4de2f9a2605141f81", + "0x94ace01f0f2f127e2cb47dc05a491df26fff49f68cd4f382c12e7f332032bc09", + "0x8f261b4ff772d1c675fe16f0764ae644d198231daf66a600d56526c1288144bb", + "0x95062df2fc6e23916b7ec403eb5dfdfd8f0aff49ca15e0b743e5a3294552d619", + "0x9626d392247cabfdf89c0254dee12f5d82118b5449059b78b4fdf7ed62ffd688", + "0xc7b341b1a1464207bc1996364debec53e55a3212a2e18211a994d2c8e864e234", + "0xa5d247c7e7511015cf63aee2909dc9ea7bf56b9c2e15f1603b229dc7ed11a6b3", + "0x551f57a199b684836b3b5d6e6cea2c7cd58f830e870d1689936ceb93c652ad8b", + "0x0f0a17a40f9cafa38559a7b8a1b3848514f4b5dad4c4565f8915d04163f1b51a", + "0xd4ffba1b3fbb46554137cb0114feb898c9a1a689c0fcb4dbdea49a313c593aef", + "0xe72848f46d7f041226ed0cb38549fad946e14ca379fbba4cd52a3bc3d6b94c55", + "0xe34036fa757a07055a5ba89f39f90066237152468c6c3fd8e60484000dee38d7", + "0x0984ba7640b44fefc22e2b53463b91b6686b909d038a29039a6e5f84e25e1257", + "0x2fd4072edee29b9b611c38972835d3cc985befaeea149311fad80dd0a8bab088", + "0xc64954228a4067748447b768bdb34d5a434cfdfe01acf86a11d8a278ee7d7433", + "0x7b10e8fb7d81fe90362c7d3af0c153460ed3df92c1c50b6f9a993fc81e0f29a0", + "0x0c33f7aefb88bb9f6cb9061adcb5fc535b2a3841a6ad94b8a4adce1954bc6f25", + "0x21460cc4c2bd2d828027b9c04b047c06b1eaa83f47640639463cbcf603e4b7d9", + "0x9ea560bd5c0c6a0fa9cf2e0e14ddde39cca6c24b11e02b635bfd4ba7ec826e0f", + "0x47c9dc525e0e1f71e159ac75943a32d541596c9b479639e0e8f00a171a29057e", + "0x6f32319d8d958c89295e38c41c2a6106d9f6bd86ea19ee6cd3df34931a2701a6", + "0xf90b80919f035eaa3cd56d1c54f9c69e60ab2445a4995c7969a4826a28220398", + "0xb9ba6d207d1d7866e6205d540abc36bc3198b072aa5d52378a1148f6a61210c5", + "0x2f494b0db620ec08b2961a12d79585de2f6939bbe679a8ae1a580535437bb0e0", + "0x65ecc619942b4fc71b4477dc5929244161cffe2933c84ef8e2d5eb443394e0dd", + "0x12f573e148bbef501d4325a52b737580d413c8f999cc86cd0e497d9201a006e9", + "0x709c2a2f2276d712070a10d20baeb7d1acc602e6cd0d27438950707175f68faf", + "0x472db00ea142b38a076569205123d2ae53f42c1ff86d38100742039440fef89f", + "0x536a68e966effeda6883266a1f6f00b42dbd874d83956a3312ac30e430607bbf", + "0xfda5031fc6bef618ec55de146ed9834dac41afcb0d0521b34e141cbc0617d14f", + "0xae912c6ae86e69a59c61a3fb95c9a60b37c17c3ce2b6e9ae4930dea5fb5454a9", + "0x426c6889a4d6f3896c5209b662d9caa421adfa1f1770f33262807a3c89983364", + "0x6e72f8cb2b6cd35fb0c090f8be71b1ba790cf2163d0cc18dc0bf62fcb0658fdc", + "0x7259d06d38028ec544eeab2e264f2d4ff975f245c3697ea8e141ebd59733a2db", + "0x37729ab26688e0399334fa3cd2748818425b3fc41304fca56881658dee0b90c6", + "0xcbb02add11c0edd8105b440cd44a041b6f55a94712ed12ffeffd1817ae8a8044", + "0x156e069b3b63fb302693018293bcc0ab60b2ee2cc8aab43e1cca3774e0b743b4", + "0xb3a7a06a4f2c1034ef5a2fa5fde7554f239b0193093c74db11ebb5d9b1a18f03", + "0x323b6d191477aac18e4761baf8ff9ce70b1274a995aad02fd582f87285f8a0fe", + "0x7e4d202c5dc858e3a3c45a5f43b0804a4ff5ed53bce625ced7eb65db74e908fb", + "0x75446e5cc0142cf4b0f26f560995f257f87023312697b3574fe0e1f558bcda05", + "0xf53cfce4dcf415ea49360d84188b33a1b6e3c686c6e59f1a7385f68f3e160a7e", + "0x43ee5e27e64e778f31d641050b5c975fdd9788f2d5821bc8e3c188a91a86ba9d", + "0x6a3a73772d1ed7ebeb82eff2419e05583049939493e4ff396fbbce7e2012ef05", + "0xf976ee31f6b27e1e0f359e1f96b5900f34c49c89e81bc753456599d2e5f4a097", + "0x00ec8886d567bd489582441964bda82f3e297801ab0c5d3e58a3df29f9004a4d", + "0x9bd7ecb0d91d576640cdd3022ff0bfa64838f057e55cf35ca945d47f98d8d107", + "0x1868b1c9dcce55407f81879269ef1296c5eeff32ef4f7770bcddca4bf972df14", + "0x24856220dafd06f20fd0914d4468713654f6d9a8a8472a3cba537c6db45c1981", + "0xa05130241c7260630ce231a427081969d4428d33dcaeec08287e7aa80541384f", + "0x4812c23621b2399a68e81d9dd6fe59b0f0953b279104a69047d0df3678c8b628", + "0x4c00bb65a14a1b995a38afe285ff4594c51c8b10c137e73376da3f2660f00044", + "0x3cb2cc9dc9b1c997b8e73ee151de0cc23f5bc0d7dd27d0402b6d79e1b50ef441", + "0x25c0bda0d092dff16a5cb70ac082a0e3c17a42d74191c9c90d46deaf34c85ad5", + "0x8a75c8a0ff4aa70a0f1389f5ddeb0a1b7aca04b94af03e7c2f3986a6a9e8f8b4", + "0x9d9c63e3b449623e45de0542b1ee4d102204137a2ac36a25442f3797668058df", + "0x932b4ab5c339c9654cc1c5e343aef426dbfee3a98b7835efdba1bb583238aaec", + "0x8001e5592beaa70277723223f033b9f830a23d4dbc64fc42efbb80bfbd7e2a22", + "0x1b84fbbecdf3add7f514e0cda2b1c88b21a65d82da4264d06b332ab216179230", + "0x79cb6fe9cd675e096bc92d449093e78e59c6c4c813b550c25a76c2cdf125e582", + "0x4fad1261fa7d06941dc436c1d38188e3660b300dff7f2001a7efa7b8678bdaea", + "0xbf81d3c1b1e781a706c6acdaa23c12f5e900fc3f191d6edcd1636beb3d29a6b7", + "0x36cc017579e8daaefb5592bb0c5b2d2fb7df5afba9fbf02d0c750287c2353b78", + "0x0cf0b82b4a102f35a06f590481b72f93d570e929bc43fc188e829e01fdf0bf9c", + "0xc0b67d7c6100b042bd39d0b4747e854a0672fa2769dff0dfaea01e05621a368b", + "0xb8c49cfa2147f651bbd73f97f02b694a5cc3cf9fd79d47bf34857804206296f9", + "0xd3836371f2d0071e45176aa82ecb05b5185e06e79043f69fff184121380e1093", + "0xaf9e77ff0a9c1bdb16afd7c1d725263ad04394e4b73f013829e63da9600bb35b", + "0x43082e5b9b11362b6b5cef0c5614848ff4c8cc9dbbc7e2b179330b46e7b3652e", + "0x6cb6fd2e7bd5550dbe63b9875814764e64036a921be1e5413ab1355d771cffd1", + "0x1631a928685b0fe688899b105aefa54fe61e564a4c9d8dec99a34f5140e6655f", + "0x095addeb9c0d14bc7e18f547259a68ea3dc982e5256f4a97e3f627c3b2140be2", + "0x520f53d82a67e09c157f3480b4f504dde53d947b9e2238f814f5832f84b8eedf", + "0x433777fbf6cded05adad6e5877ce0ea3e34342af6f65042c6141b4f4201103ba", + "0x077878ad6fd501074b5c713905aa3caeda3237a1b58087e6275328d9482b0577", + "0x6037000d2014c601b14bab5bbf758098b300e68fd3d6f2a0d5e6ced1657cd6d0", + "0x481b8e11fe6ca5cdc881bb6c3d7a0d96e8cd2aca705f950ac542c089d7ca0cc8", + "0x2b070c54b2af6cea0e0ee76d37a92ab3f4e9e04f3b581f41ef2bd5d2631b8b87", + "0x01ead0aee81e4611b5ff7cd64037ec0039a05bf0d02b18b92da6acbf45d4e6b1", + "0xfdcd33327deab31927db501945c15a82f278f34a09112b2d7f74219e9a364555", + "0x0fbf377a65289b1decfc2fef4614b1e5b3404e0a0c9c7d0d147cd86bed55f23d", + "0x8cef4b3d09f838d4acb5e21f777fbd906358a2759d24b055756e9d154b177ab5", + "0xcced9e5d45e86423eddcdcae5fb2080622279ff6f08a0ee47012b33af58f820f", + "0xb1e6b5dceef79d8ebd0b84a8990f724fd645be2434a0a8339e78fe61c2ad3186", + "0x24a11c3547f5fd5e5eabda12369f90b8f5c8ddb82568631b6e704c2ab5c94ec4", + "0xd6cc197005e41f553308ebed885a4df650a2022d0d40d25f37bfc74a94e5b04f", + "0xcac28ad9ef5e3f9b0d2184fb3427dad0838122a44538bb1e0ad15baf08ed7312", + "0x8070860a9337d8e6e016e0ba5953968bf410100bcfe5e567d7562e74b95b5d0d", + "0x8ab5cf8538537e591e95fb1dcb9522067ab5ac783bfd622e6c9bb131d3288ea0", + "0x345a12de03af922ae9e6651cdd4c4249f75bc2aef1f1651692dee6d27a490813", + "0xe9cbfb97fea7afed66cb3551d9b5f6ba697a4476a5dcb3ecf25bf9a41e54bd85", + "0x4028a3855c3b656c1de109e250412d9596cb6fc4aed22b8bfca6d2a60b1454c3", + "0x85591c0037f549f6d807c91b929fb0290c1b53f23e9305bbf4feed86d5483cf7", + "0xe3178cd8d8b7d9c71d9614744a937add2ae6c21f6eddf508fdec243c6408b647", + "0xcf40b5e2f93922022aaba8558b17b193c50f6440359826dc78b58e9b9e34074f", + "0xaa30846598de0f132d8c18084859e6c67189f9489a2b8019936a151e7d0812d5", + "0xb908ee8113c1e60abe60fcd0d7fedfef07ff0efa562673d0ab86f6399812a8cb", + "0x8f9d9102f709fc1b4308b677e515173a1db857b4989b1de2961b801aa8b39db2", + "0xd74e36d71447b437a4a4405dda388a9779347fe41152b7c5515e02edb567b5ae", + "0x5aca44d35187500d73b544e71ea8a12100cf011c219fd8b83e44b4792204edd8", + "0x7196cd91ee48f598c11527924c83431dec39ed7cd67a225b64a9d04ad23211b0", + "0x52584327a0b33be95ebc7040c0dd9b60d2bd0d42d1247b8d2ee06b0d6aae9f58", + "0xe2517f4a4218e9741b501cd6fdbc7e2080cc8827bea231d829d1717d24ce4e3c", + "0xc94771be6c7b5e858823a03e620670cc604cdba8092da13e429c76c2077eb2af", + "0x3f7f556817b418fccb808f7ede824ff17b119e7fb02ec1a4239a71835af5ac5b", + "0xd611cd2fcdea70eafce698fe405f361ca95b67d5631a9930d858f4a7cca46358", + "0x5f2aa6ad1fed0ce4db64bff6de7bfa68e060d357ddf20414fe5f10b4211bcf7c", + "0xe8b5d5fae7903602ab3699ff27f159367e2fbd8fbdb4f45e7b1628b563081940", + "0x31cef735663de763db98bbb0846d5a1127adf45ce41837aa77dd5e4008718711", + "0x58f0b43df5b6c2527dc3e22f2f76cdf7817e23d7c3b9a9732fb91e6da9a537bc", + "0xd13734d21521985e4c6c14bcdc34139efccf1f0a9ab92a72e0b9e639321dce70", + "0x99b982d744b14279defa1771bb358ab55f4f3730a8feed9e14023b39c44f2777", + "0x827078f5ddff2088e6d16039c439492140337ea661cb361fe87e0bb7fc785bc2", + "0xb1f7f5fcb807c343ebc587314a28ac008f849c24753383c3e40c9a12826c9f5c", + "0xd60f786c664eadca5ba1af303f8d8e88d781ec3611b9f781cffd5b17610c19b0", + "0xc514f1487e061262e2be76dd593300b8402df6812700c41a2611ff5aeeddfe45", + "0xac6350441c04277a76c019215cbec0fdab8f6e46087704ef0b75cad0356dfc32", + "0x724a5ff7c13fe6d21249b47f47082797b2470159b298ea281f9616d6b5c5269e", + "0x70dba710ff65ecb7c9fef28b366f5b175e12a63bd1f7530ec18da36027033497", + "0x014f4aad56ae3ececae45610e6d28475e588fd39897127d20675c1ce18479939", + "0xdeffd38ba5e4e685603ea1da27571d48830018be17755ef7c08db7f6dae63647", + "0x1e6e324967609029e28e768443d11cd5d99ca713a88c9ff47144d0b16b9cefc1", + "0xb2a2a5d5583ba070ab2b8adc6f5eca48b621b5244433a5e491784ccdac2e64c8", + "0xdbb937edd70b36b566e397fa369a5a3a0b45e606ed012277c64234eff00f2157", + "0xf043662cdf2a84618401c619fd8aea26a54519add9f72e43a520fc8129c02000", + "0x9b84dae2d1a0d7e23073c558e13e16ddf3a28daab3569c89271e0f780f134be2", + "0x93c7258e9e78238eec47497c842a643b339ef9ce4f236ac2c0541872a427a1be", + "0x8a8fea29216df1683fedc14a7a066226f9299d1be50021d3d2aa4c0585b29f47", + "0x85bde8bc039cd1820bc1b1262545bbefc07b03de47090008becd1417ad3b997c", + "0xa7758356e4555d213a19f5c343de9cbb986509aade6d8237baf1fc6e07084b9c", + "0x546bb118d2a1176ffc967f90bc342edbab4350f28294ad6aa29eec2b0c9159ef", + "0xcb50bf5a5a25b95962b6caf51b5e23fe60f6449f69b4df5d6b6d7fda2463d5bc", + "0x1730541314d8595b13f01281189321299fc3d2e9d0b9aa354099d6d83538570a", + "0x5b57218719bb9816f4341ee1938263fe92cb95e798193cc2b24fdc3836abac02", + "0xe0860d86c780d3bd7375ef6a0d75eaced9fbd90283f8ca8335205ac3d3a3dbfc", + "0xcd65eab452ceadb388b945eab3342dee7542c76bc912dd738e86bfeea1588f96", + "0xc15efc0c25c4c019937ad27026225024ee6992780b9ba02d3c70101a73b354a1", + "0x30e8665a5ac3f3eb1b9c2e67d61dc2dce761e4123ed801c1a6f207aa3828804f", + "0x6c3b5d4f836b7d349a089280c1f4488de60461c7c1a7a5fb3ddcc69c1366195a", + "0xdca4d348f2b9806cef16e320e0b21a539769746679c1a45a6145f2298db496df", + "0xe8fcbceae567fde12d871fe54233ece0d74ba8508fbfbafac0f154806a9462aa", + "0xd79328e9ca262b6a91652efb67dac1fa5e8c3282dbcda58d4b93b8874d226966", + "0xe0fd3af4b67510c68e8968a5e25e741e1ef71c9347e18b8de6139f918a62f6c4", + "0x70731ec895bdb4914a76b97ddda78a8805a39a56987aefe32556b93e2c085d97", + "0xb387f307e22829ce20c5d7906037a5bc202950197bdd75ba59999c2a09778864", + "0xde1ec63948e3c4aaa005630545cf73bf9d20722a1c35b8176cf44d80f4cb7f0f", + "0xf9156bb506ad9a12b3b2357450c443572a3e3399e97f68cc0166ea22155c9277", + "0x3d5c1ac62e043661edf67446ac9f96b1c887d07ebcffc2faeb317b5c3ab596e8", + "0x70e9f96a6d21fa71ec310b99db848e5dde82ac9410ce8c6d24af115421527223", + "0x366fa3d63bfdfd2fc10ce44522f36ca6b8f815629bd36a26c0a5fcd6f95fc5f1", + "0x34b6b13187d684972edbc097949de7ed4f7ad2658f9889e1798e955845f0de36", + "0x1ebf9da97a23393f6dc5cda5c54718f273eda8ac6d1977981a0e1570863d9833", + "0xcf8888cc905df1ee1127f59c8ea7f9243c4688daba7890908949b027f4af92e1", + "0xea4ba26d5fdff1daaa42625fd88aabf7f91cd400829268b9beee5fc09875c630", + "0x639faea36eb1a652b024df696454c856be53c3667e88c7af5299c050c1092bf2", + "0x1e67283656def3ee933332600071fde44127ea3caa9c42f992ed16e33d1122c3", + "0xa4f53ce6159cae14ebc60a69e9c446a2abdb4f4f5cded75b1c5814a84c487528", + "0xf2840725ecbeb6e7396551fe034d21e75a5d34b4cbf8b3b18dc5ffa06a3e2d85", + "0xed7396b51a1b0d93b2288a4bf60ad49d236bc14b0cfeb40dbbdb6e9682d3fcff", + "0x9de490ca8067c84f922547ab496e57b3e1fc4685b744de22f1cac7dff687b930", + "0x3c3f7c57fa9ef833accca168540766407bbdd2c418f13adac42838f205199462", + "0x14257d1a35fa99b3cdab74c8445bed9bbfd25d1604e1b9123fb5c5bf88cb3a29", + "0xac74953d33cdefa9037a415336672144c53310ff50f75d865272ead5e0460799", + "0xa94b857f4dab303c1d4a5213c7bb8b91a441ee8279e69fa92057718f3aa40a4a", + "0xe7c67bb2e440f1062f95e28f0924d0b29bd789103521cc13d13a95673cc49179", + "0xe90ea613252541d3c5237a27d4d23780b579cfda48c057b7304ac14751166031", + "0xd85a4fd06114870b3fe19cba9924405de1e14e026372e84b24b4ab39e7879545", + "0x7d65651c6e789a3b6113f589f696ac6595f279bddba74a17e955ae6ff93a1846", + "0x5e44df731c9b0905ccc33ed49669b78834d065fe3fedcbd0fbb7df95f706c51c", + "0xc90d3dc4bff702b9f17930d27b039bfcb1b7879076bd82a5650177252a526dd0", + "0xb5d0f4ea7136a5f10e47f6a802b46ba0c7dbcd4ee10b4be65ccd55fd4c940bdf", + "0x4f7647e2529b477aded041ed2f4c8e01d5219839950aca43723993c2432105de", + "0xddf89de514a09c21918af718834060348ad0bfd3b86e0953c247834634eb841b", + "0x325b15b05b3c863822647b25ddb970cf9cb52ecd32cf58e6c5e8cecb1beb9c89", + "0x3cae2ef569b1e74770ed80bc31da2addeeadd59d8605eac8edf3dad0fa9b0c37", + "0xd7409a715ae5f091fad14187121bad8263caa2f60ea0d0bd7c524065defb564b", + "0x5cefbb199b507e3b64008e5d639cac8f623e9ace1292fca190bed4b7aa214899", + "0x2c2919f07eecf553b473f98d06171449838bb03c0a468d8a7cfd8062a574df1a", + "0x5c122d8416b78e0e7328881efaa7fcf61be6851a5b7572ec5c341693fcb9c734", + "0xbb81898e64769f0a6f1c20a2472a5128e969f737d1cba5be885372453ec18d1d", + "0xbe203e6f7c0c86ba994fde55d0daae0f066814938debc3b5a44884dda70e3ac3", + "0x73c7842f2480e3d742aed1a1b7682ca1f322d4d2555cb7fa402313024c2a13f9", + "0x5b95cde26a2c2be298a03252ce36514dfd3c9e84f5c5ffb75a050bb5752b6247", + "0x9c7cfa9294869c1c42db3cab3bfb737696b8f81500742bfeeaf29145e2b5c79c", + "0x6cffe595d85a32ad1656c81c87d476e6e7f602609fac052a0a3e3a951d11eafc", + "0xe2ab30bf8127106a4507034cf6b3589ea3dd19bb10c765434fd3f3f7d75c1a4f", + "0x01d7bfcc2d4c6fccf5e0599f9985af838cdc0281c9c8cdd7006b3b0abc775cbe", + "0x004114dfe63995fd66e6932c62cd7b3f40108e5e2f6916d19dc436cf016392d5", + "0x068c036ea74e85ae8d8897589a8dc775c8516e38bd619ed584ffd51021393fbf", + "0x682f4444c85c46d28f5858a91874e0c903e97def4e2a4302ca90ab69b54b4f49", + "0x3fda79ec159c2878e9ce65c575157daaa9561f17a14a0003d95c0c4264985707", + "0xb41874256b5cd3ef80af1536a45a8016cbade06b4a06b1dc0942c27124d934b2", + "0x0eac150f30020a7651a006324da1ae240d4fe623f077c061a954122b0e17b0a9", + "0x0b174907572651a2453a14e0326e7ba836781dbd939c2d75db84d9b481391824", + "0x082beb1974f7201be32469b9df42d9c30a520f4dfa696fcd991ef20367cb6eb3", + "0xf3c3ebe6040e1ce5c5ad1f6e08965ef387adb6633581ce3fdd1858f1da4547c9", + "0x6ba341211e75ea7346853a3f63ad5502f83aeefeac98a479aae546a70141af99", + "0x3962cc5bb73ab7f48d98bf65f3f7f41a8f3c52b4d7d2f12a0a89cd876f875bcf", + "0x5b49809641f72f5c96bba6b27e0331ce7fc7dd3ef18a4463c93d1f685b7a29b9", + "0xd2b2e8eec102c4b68d94d8bacf71755386bc3008d15d6090772a4739eb763300", + "0x704bf1701cee4f631f4de0e330873b1621490faad46203fab288cbd0892da567", + "0x2f7d29943c2b3ed9f59a66ad175d298f1e4761218e3fc52b9a67b4ca7107e93e", + "0x2b370002b007d4df272104b77c1224c24eae67de3e12aa599968b190e8d58c19", + "0x1f25435148cd815f4549de1f21ec227d42f360d207aa2f7de5466c4d28afdd0f", + "0x86d745be32470f409b5d77f92f2412aee084fc523a7ff7e57b53f39b11cba2b6", + "0x86d57512687518e3db56834f819bed57ca4f2e3845ef6affb15f29d1e166c333", + "0x9ec0e54aa6361293f68c14b7ee9dd32abc52d9649522b0d62637ac25d3a978f5", + "0xc2dcddcdd616160a196f1336e9f11c7685c5eaa4d3f5ca7c35d7eb14199d21c4", + "0x03a14db3cd22bffc91ce24e510421d60431db71bd68b8b040c89f85f7664967f", + "0x3cfa17c8017ee8692c5f440e6ff825b2bbfbf18d01466234bf69ec85c3c793e4", + "0xeb12362e925a0b082268e0e006165720dfa72ec2628dcddb6cbee4a4a0ab7bcd", + "0xb8c68067329a16ccc14fa3a5bb373d8281c79a20e1a15f74dab053efb881d13b", + "0x282be7cff399ee51b3b8ba7d9ce73daf0427cb11151b9a81ee0f6efd837c6f6a", + "0x357989e62c038a11c75120f990adee58fcba6e7fd49cde265296b2ee0c7f6db4", + "0x3ca8e01da313e17c3a089b8b99ee118d10140a497aca58d62c25452f1361f0c0", + "0x9778186733b0e642156d6af17ffd8161608a2ad791cef0dc5d6f31e5ed4ccee1", + "0xc309f7651776d4510a9696c89aa82e8720ebb2c41c208e7ba8ccdf1d26dcfea6", + "0xbe30023b89befe4495b15daf4578f415e8cf25087428bb25b1af06b43b04b114", + "0xe7246483ab7e0afa2a6ebe69819744cbdbc588a5294c1c59cf04232782d89c1f", + "0x54e18aa712987567ad36173ccaf070b127277ad6e9db2bfd1831b7868f56c660", + "0xe5c6a4c0f07bcf3dab39def282e3af9f7dce84a7b2bc71c9bc3bcaf35bc6bdea", + "0x5d78d891bdbb232e7d90370b5108ee03ceb0c5abbd5bc1c49c53431a94fa2309", + "0x91f3efceb05e5c6114ce0fa2477d8e2a6d9979ab1d3cef4d964d7d804399ac50", + "0x29830ce8ede37d875e7203bfca97b104b002aa474fa9aa9fccc11b2baf665f83", + "0x93a0646400cf92d5e7490638b12408ee9fd7696f15005287d23238ee5fdba9bd", + "0x47273e8e24cd886a25e278d327bc0b07e4c3a6b27634fc17705f46a019ec042e", + "0x3469aeb8bb2312fba8a530a002d75b75bce0a4b0e7f48d3e92d595dbec818594", + "0xfa8abfdb2535d9f04933e924e967d97c248b62900ee645fc991a47d5ecde87d0", + "0xe9fc29b24fa7b2a6cff23170d96faa84aba582f68792dba4962e7fb53922c568", + "0x506d80c18b5cd845e0277be32d0553130549a976f781c315c674545b1087516e", + "0x676bec126c59b4f69ddb2ac8141d9e90b78a2aa1b5e55e6458cd479fc7f98a10", + "0x4a99d2f7be333ced3b6faa2aaf15f792e00717da5cf15ba2e9b5b7dc02bb1bc9", + "0x776f5be74f05d1200273ea3c9b1919637fc911c76d1a9c3e1e3accbb9ffe6e37", + "0x09b9f219a053c0c3c56581e32ac15fc6bfb4fe69208a5291dd4860cfee263d19", + "0x65c9e06136563c4648b76cb1e7c5d46bb7501773825a10c610f2b63bfd5ddbdc", + "0x2e31a4c4d6670c2155b3ba877cbc6f086c18059b2903ebfcf2cbeb6f73e67bd9", + "0xdeeccdd2dbb206be5fe2bd4e122d6cfa556d00ca0021384138dd914fa3aa2413", + "0x0c24527744343d79639a382412ad22e5ef2e610151e1a19f09f725dfce287ed4", + "0x4fdcebad349c83d27457ec443a5103b375f26b6da958227ff00916cb900643b0", + "0x4b06063a48575a6f89ae7fb8deeb316c30e6ecd080898c47f24d9e7d4f6db960", + "0x463b0fa1bb74f1473673a2760a7e447def169426f9f7cb57ae4c6d417f58d829", + "0x01050ce1aeb140cc812f24c6629f9a171ddf4891b9150b43312fb052ecb29de1", + "0xa9e4bffd5ca3834b5a80dd84bad6ba4dd71138f02cd386668aa8b73f437f3e0d", + "0x379e501e6acdd0f94195bc851c50e7674e103ce8563bc61d7b0e6ccdadc18def", + "0x8d93115aaaa77767f70287e025a445cf6a4c7f455a67615f38c42e827c95912b", + "0xde2d4d8337849ad10a32b1731a0c281eedad191a09b26764568e7cd9769200df", + "0x575de523f7dde0e52b68c15646d22a31e245a037d1218edf86e295fba9b201bc", + "0xa545dd5a5e5dca568a5a28bd387417bf3743e184189106670b03b423b9e5bb08", + "0x044d13ecdf9cd6989d3e5a1d8354d4f5a7d29439a5da0c57505496fee7b6d054", + "0x4d99efa30d95ba2f0002565ccdc0ade2bc3f21d3153c638fe8ad9977f1da8360", + "0xc72982c95de4754f8b0ac62113a71af4c760c3c63f18d230f1fdbbe3c0b379c9", + "0x7a2dc8e509b0901646afbc1a6f9b5b27ff69f2fdaf4377ba027be555acd128ea", + "0xa3656ace4d66ddbf55477ce61954f2e1f165f570b5c7d028d1653e9f879cd080", + "0x47e4e4bbbc704f65e3979494487b0dd51cc56a928f26f97d6e29d76db80ac14c", + "0x5cec964b6d806da75f96c67c1db66d7c539593c476c69a2207be25934443c82f", + "0x685e812268ffe51415ef5e540bd4d2d65c2f34977ffbd54be14c895e4f004abe", + "0x991b2344ae224901f5ef89be9ed8313ad2c217e3727ed8d24f3a35fb71df3982", + "0x1293f5ce59c36d3189ac40e05bd8c0fb4b69008d8d457b224df1ef1e0285b553", + "0x3d41f27e644e2f7de5173dfe7004e32d6dbc8cb56871f578c3b2b943210a4c47", + "0x2decc2a4e91de0ae9a5584cfb03f6a7a4e0a867e397dc74df8f185bf241cbd96", + "0x0aab7f05bcd3b3633184b45c81dffd70b3f1b1b23f28d46747ecaf54fde443b4", + "0x8bbf3aa92fb9ebba36c5a2756dd394adf505cb753f8d3809393e1d967f78e075", + "0x13544a2979e57f73bebdc7cd1b2a1c9cf8911b8f24868aa1e775c8c53d0e2572", + "0xa7497c9f04590c706fe0a3909bd4af5bccc7ac31d7162b2b856d3a36bccfcef8", + "0xb80de8392864c859aa8e9ca078c258a6992bd848de129350ba29548db6aa4afb", + "0xf334d02277f55288c189e6ce79942ced25ffb9ea7bd5aa5ae562a985eca6e57c", + "0x83a563681180ecc7a1fbc6e47e0ba03f5004a87167fdd451d559a573df30533e", + "0xa648f1462985ba8ff73c7aa4d19153843e6a9a454d976533b08f7a14d2fa8902", + "0xede4ba72831451bfc8651419aedc62e221bd8acfd8d4ebe426d5b84d862d3b71", + "0x2ab8f2dc9b620b637aa27f9303068abfba56bb3438905d29c9a6faba4ad014c2", + "0x225e5b7232c6edb127a71ea313501e49dd86f4df0a037b9c97dd5fffa8c08cd7", + "0x85606456efed98380428d075ac4791140c9595b83707a397b274805c8fdac4ba", + "0xe298a5939a283d03311d1a19f83805f63c83efd2d7affa7586be8868284be900", + "0xfedc0db97df763328cd9a8c8bf1de73c420ca33dc3391acd6e4e847eda793d7f", + "0xbefdc3c7e7ad41deb07ec2821d0b84893440f797fb1603863e274368008b8e74", + "0xba3b21ae193db8215fa341504fc5ca46b58df994c473340bbee3f3fe90d72497", + "0xc45fc6625b0f784ae2039747aa93495b05243c00dc5c2bf46dc372c62beccf4d", + "0x32d182e51018fd1e19b576670ec68d59810c4bbfd406e2bd162e1f17a0555f67", + "0xa8886b1a9d7bba27219fe7f563ac0b592b82a1411392ea71a4a5bb288a98d6a8", + "0x396bac50aadd2dfc853c144091324a12ab8661590fbc738d3cab77910aa2d2a2", + "0x50e35af52bf6eac228c5fbf6fe5dec85989b76f44811099f2e8f4950e4ab86e2", + "0x9ba2aebd73945b6dcb9f5171155c0fff29db8cf40baf83b1689a7ad1004912f4", + "0xfb1cb1ff78859e3d5f0db0656821e12b8d247ab3896e6670426dce2055f1ff8b", + "0x230a6f6567f066e76413b72e7650f7cba9315090abc1bc7f93b861d85aaf0c68", + "0x4dbcac91377ca858927a01f5a5e8659b4e718ceca20d4962c43fc1688c4d7574", + "0xb13061dfac0e8f22dba518fd46ea95024cb97ef825c970cd5e452ccb3d7fc6df", + "0xc5af27a85235fd0e1da29b5afe6955d72fc2245c5709a0f29bebcc7c49eb4a0f", + "0x7937707d20bed2c7b68dcae39ebcd93b84bca9f471250e20f86f8ba58bb10fcd", + "0xe1398b71406488244a0c205db9c793be090349bafd87fb147c1aafb9d7d7deaf", + "0xb383706e1aaf7149b1ac3d258f6628e8e6d40be0dc096647b4bb82a08585b707", + "0x2c07639c073fd57cd719e5c67371e5c8db30f34855ffe0d985070b4b36e27cdd", + "0x7b264ea13f78fdba57d1097be39b6b2dbc614ae36cfea1f99d44b9966b3db035", + "0x04d942f60d32a80d93d12fb7c8ef95439e0da5c8358df2c01e7547596461ad79", + "0x71c93b0ec1e403906ce7e5a38d168b72b14cbb7cd0e832c2a7e73f485c7d6567", + "0xf7060c7f697a68824bbc178e02dcd6b12ca204da9bbf2a17b69ca858e2ea9574", + "0xb3b616f183145bbc77d8e3610504189e00c0aac3e15975e4e01f1b2b25c5b5b8", + "0x137f77c2fa4e911b6915c5a84588bfe78bf54ce39d09ab07e495da9283966d19", + "0x5949274e5465952855c28d70a4089644200927b54faa67d5aebbc4eb2b891aa8", + "0x1c695bcec5602b15de8099c550a3b738aba98acc46377cff7a5e58bd7f402ce1", + "0x8d1ffe39767f285d7f164018cf2fa4ec6509194c086c33af7ec8132e3572fc9a", + "0x31331d50f79ace5444f242b279be905e076d675fe4d4e1d32de728e2654a08a3", + "0xce9c3e8fb9a75e284c81925c6ef742c4f34e6f0bef11578a61be5325692a3a60", + "0xa4cac76b0729c42927d1ffb0c870983830ea66636e9abc6138b943301c59b96e", + "0xbcc505e608198cc3546899012cb59a3da60839c9060d2952f8ecc178be4bfd82", + "0x1b5ab87cc34a38f4be26c5e3e05903538e8e3af350f6e2e1258b0cf344ad9f39", + "0x85849c1cadc5d3bb555b88b1e5720110a1d4f7b79f634427a1f8d7e88c2e043c", + "0xee63ee939a6dbc6678415a1af9969526083bbb754a8c55e97cdefbd2f02900dd", + "0x50c63ebc1248164b057854b8ab8bdee0510a97f75e864e1d83feaf59541a64bd", + "0x58daea24885faf1556b3111c06351fa506b40b9f1ed365633a2246165abf3819", + "0x0357ff6bf4ef1b1bab206c3c3efe770c6493cd85d0540fa29492428d0a878c6d", + "0x52963cc6bf51a64c1f8ccc21c520ed95d5ecd0e43a86b85defd7b0113082e9d5", + "0x5cb8353b62e27e59824ee43a4bbdd384a2af41b52f9ea5444a1a180482ae7856", + "0x2815152239935641536e549578cd0d33c74a377ba350a36ef04b038e5fc49142", + "0xe6df1f1b9949e17e0a683b6fb7ec9ede2b49ca3d479202226ab4180445f86d51", + "0x3af2498e3ae79447c4b6b3f025a37c790622e2979462dee5913fda778882e5dd", + "0xd498a21e50c930d1f0fe0afa65c6f977ab8da037175f34f4478e52f4c1631d01", + "0x12478043148cd0413f56918565cc2fb0fb9802dab776f0a055093ee8ac131da3", + "0x9acd35608a37ac8e309e884b88609957ed24ffcb5816477788e08a874e6c5a61", + "0x53ecc517c7158fb6e99863c54795107258b61399279ecf74f443d49533a104b5", + "0xc74f9359d1b15de475fdeb56497a5745a93c741e5f2c370656b2e7c269c06511", + "0x8afdda4ce115a19309597eee883cfd257182db46070c7cb1f24955d9c872c8f7", + "0xc4036bef9a9e692ebe72c946161b3ce5c588f4421b7d6555b5d65f3311a5b0fb", + "0x4b64a608ae22b5a655cba7ef78624eb69f9f8e2b2f7aad8c04cc6ee95386e9ec", + "0x4b5506aa505815e519b5008fa8d23488b642a1f347f6cdbf53975636a677a6df", + "0xc251b21563070f1b3895bb4512bdac4395440217c5ce01fd85e89399dad72b53", + "0x07a7bc11d48537654d24eddee78d35e4510f22b755f1f36c3b81e98087a1ce68", + "0x66a0e9bf542363d8660cf7817ccfa3f4262e4817fba45d2871d0154b6fa7e969", + "0xb2493d6e033e1c29f62a409342beb82f692e565638736fd088d80acf7666b9ca", + "0x4c55f2a4ceb60544682cded4ae8b23bf217ce7d87ae90abeba156d9b1005f397", + "0x32b3cd5438edac8902527ac353356e99effb1dde5209fbe1015673778f7c5685", + "0x4066c6ad2c7170b434bbf3e7ca0fd678803351c3dcf1c56e84bd6c14ac2f7712", + "0xe74fa1fa353cfe643ad94f6a609726fd3c4b06f9dd7503431f84b13bfd87b06a", + "0xc46c3e5bc3c3cbc604513909999f1523d704578cf5f025a33f1a5273ff6cb81b", + "0x261b489751092cbd70d6d3010b5c5dd68c9041063c3f998b742e81060107e17e", + "0x37992c7e208c0b09309ece681e02e957f6310c6f42401702b31f752646fe738b", + "0x2b09e6bae0a34cc6c8c83e97c3369bc847ef6410551494af91a3a39929e7d949", + "0xebc85167d3a2fb3ecdc5b07d78b6ba3a0d8294901f75d687087449ed78b305a1", + "0x8fc0dda2085f4e515491cf0d5a525f10d50c58a0a86a58954b07264425bf1e16", + "0x5acaad0dd003649ef9705e73232b4f9598c3fa14cbfafa1691d0f987639b914d", + "0x41cb16b9f5120095aacbde94f52b635a1ea9f347af8f4092660e84a1b87f8535", + "0xa5f2fb17e7fb322069fe66bf093b99f54ffd9949fa4cc983d2266013d2dac2ec", + "0x014582ecf0cc003d21b02662531b8c0422d499d8b74069533ee24b9774c1b7ff", + "0xda9554b8c2b3fde14390f91282a91a9eded5473cf58dd2f5a6e6168cb4d24d3e", + "0x55fb7a99e9e6e3d9fafd8c9f65dbfe821598f2b5a63435204c063cb4477b1d2e", + "0xe54e3c51b6eea19c23875beccb7e18094e4db26f3c94431df1dec26e6db98773", + "0xa7c04b495735a1a829c64f06b94c486c0880a7c54461defb31a420fe0104e1fd", + "0xc7299bcf0202163a946ddd5d8ceaa209a1d81e28a27e5f8fc660c00505df769c", + "0x2526f9fcfb45966a26370e08b26cbe29fd5aeb568b0f945399a6ace1778ebb57", + "0x59b3d302dbf5e3919550c0c1b75bf111d513f2d0d948ca8cab6c44fc38459b3a", + "0xa73fc3b85209e722b88374b2ef3fa3df240ef81c9f9e0d4e7e422ddd124a5ae5", + "0x0dfe2812db18ec7836f8d2227e35263eb98fd2046f597c203f2b499b538a308b", + "0x1f7c6caf872ae90f4cbd92c7adc49ee2ddce61baaff37186111ba7d5347bb4bf", + "0xd67aa89ad3f03b9d801d3f1cb1ef58a5d9f6b8e4cd9d6fe9b862b697f60951d5", + "0x9d760e7ea703028be2d197a0ce28d4057bd8fd7638781e9846cf5d5886ef6611", + "0xe9bfd8ff1dfb81f4f5e5c3a3f821384f98d7c6b753ad356952fd10527e08ced6", + "0x95b6333df70dee92ff0d880239c2ec7a4016c6192391c08e797fe24e06bfcd0a", + "0x56651120494e23767700b82c6718a9c1abe469da49c38937582d08220330cee2", + "0x70d3bae96dfe1a093bf9233d9f8f4c149fe4079c5f40087dd49c6e524cdd96d5", + "0xd29445a1ef099b0ce227c88efef59677abe47763149e034c3dc96d999b66cad1", + "0x7e2fc31ca7a02f965757f118797ae5093cc95a89fabac7e25a22193f2346ca57", + "0x3b7ceebb659eacad955fe0e95a6f141eb4f59f4fa70e52da5c85d7a9467b9298", + "0xdabfe5efdd2d7a44022fac35b13c8acc8c3c1d69ff360d45d997887feedffa93", + "0xc883f0d5c38f40861f9466fdc84170f7605e9af5ea4d6f9aa5088c6c9e482b7e", + "0xd5b14197d738e2635f7294eb8993b01db1ec02de38a545fae881a3f11f3917a6", + "0x5d2b9e3f7a490660bc2592cdd4e04fc9f5e32de1de4c9a8c223b177627708bf6", + "0x2e94c911c88a1cd80e94acfc9f27bb5675a6ca79dab6f70f38a4df99f84f7bbe", + "0x23fbe80ce230e0cbf881279ff259642d6ddb579f0711c5f66e93db3896ebd835", + "0xf1eab3ddc0e2c231cc78d123e20f4195808a88f79c21b9ec2149e3ffb9b1d5cc", + "0x5156b02d5fb9cc38a14e3b4cef86fd99d01db773f681404889e6f7b76a6b2d51", + "0x4bef16dfae5442b8d2451abc13f610acb565fde8400ab2ce52c44f54f68308ad", + "0xa726272620270e5649309798d90fc52ab80b779fa03fe639fc8ef14256d5b1ee", + "0x7f327dd9c23774439a2c080274d3111e0487e1e9c848a9e11c14b2e5a9b307ed", + "0x711fde0a0f1474e0ababf802d8cc8da401d1bc4f836868f117f8ad3756179296", + "0xedb4b7af3699fa441ab53a6afaf380b5760fb86c6b5a0f2d73075fd9da23c8ae", + "0xd7062907f805b2b54e9573104b7248cda283ff1af3d86b7d77b4f9a94d420200", + "0x540b2ade8a4d3571094a14e7e337cb4ff66a86e3cc9fa5da85e93c21edfb69bc", + "0x3c06c59332db001ac1cc72e9b07adfe31155df74c920d7a897592fba0d265a48", + "0xe24179dbc1457c23d05b307e0b42c1ab276db666e49b48cd3e1b3dc82e285de3", + "0x70675363d1a4a6db8b803e3876b171c4ad70b25a56790ac7e4cf011ded4c9c9d", + "0x80dc30723f933aee8e126815fbc226186c07d724cb13c60bdd55cb470f159c4c", + "0x9be135832d600074ed784053d80ad3fdefde87db55088a545a1f8403429d86f0", + "0xac742c9ddd3e59c3467473ede8a794a8b5d1c8299a471c7510cca0b11259ffec", + "0x3089d8ef215e1cf33020d6f2dd005c96d9e7c8bacd2e272c788b79e3fe016caf", + "0x7b22b3b82634041abaa917ce6ac8738e1ad5ada1038bd1a583c84f2765640e0b", + "0x5812d6270239d7566288bdf58df80a2f692731062d3a0aca56d3df972616b553", + "0x0cbac8f96a15a1f57b3ea657e5888598f7350466f40fd46735f7a8229ae7c528", + "0xac6d9f1c216f28da4b97cf2f78f4a7d6ab38636e57fd9a4db71bff191a8007e4", + "0x8dace71e1c1a12a57dbb4794cc92d3e6641201ee75a8304b28b670719cd9a179", + "0x03d497bdc46d7189b30bdcea32a7d93ae17aba1851da4b5b7baa241f0348649c", + "0x9b2316358a104fd1a93cbc388c1419b1db9043aff711d20510f012bd135a1309", + "0x88d613d910c664cee5d50fe1733340853900df4000225698ce32816f457c30b6", + "0xcd9d22a2cb07552bf921cddcb89d879e49ac840a5cbca91da3324427d7d2b80d", + "0xe7d213479605f340cf3714234eeebbcdb63805c5e9479dc56d4a4b2733997bfa", + "0xd899fb4bf3a918a9cfd46d23152fb1d5e54f97b86bf270ffe28e6e55e924e391", + "0x14a971dc6aed1e7dfd4dc3ba613548b8966495628182ce99c4fde9124ccd04af", + "0x89800cc5cfd0ecfb45bbd253dad288617123b3690098e41b38c0d51cfc10234c", + "0xedfe6f669b7b9dce540683400260000ee191c3481577aac6efc163afd7af6154", + "0x70b50725e51c7a5fd4818be7286bd1cc9b15ec2ed4ab6c1bf7e7203c4fa8f25e", + "0x22d02fe95c6f959f72ef4c96329dfb31be8ddce701e0c3ecfc8398119bedf656", + "0xd7877a10f7f883975c5498cfcb07f044400a09d906cb94c8cd29f7a4b93e4b5d", + "0x2e47d9590efa111e19419df7cec6b157f4e06dbea4e64108b7101017bd0cbec0", + "0xbbaf38881063dfcece265083468830bebdbdbb833a57bd7844044ea0c57d1e44", + "0x9269c959dfb4540e3d6c815aa0135b945acb7f50b38fff49f6e34425477ef553", + "0xab47e57f72ee8c8d8857247f84d3419edf43fdf6470c9ab070d8733cd8ad617a", + "0x2be450e3b77d2d3377218412be18390e984fefa2df07d02edc07ebb2d64a9312", + "0x6cc64bc8709eb51b5321b25453e77f871f364a8b277ffe51afde4b8c7a181338", + "0xda70fdeebaa9502e8d0af2350824ee0807e31cdd55ce4195f32a639f47f399cc", + "0x2dac4b30d219640aa01a2d7c69528c8d31636711c915827a64a9219524f2885d", + "0x50932f0dbacb5af5785065dae19245148270f1d0d3515b8d7e191c5702047b6a", + "0xd919cd9f3f6bf7ff66340bab7c562bf53eb969b3e00fc950d1d3b0d9d815e351", + "0x76a276f09fc452ac94cac15d5226ccf3110080d2bdbcb01e8ad86597a03f21bf", + "0x83bd36f26e7d087ca641848f5bda2313903ca64f8b61cdac127ec56efbfc6ccb", + "0x6a65903a006c6759aba3191ce06fd45b0702f127d822d9c889df12b2d52c7bdd", + "0x8e440f04254f81737b00d3857d1a95bf8709f1475bc0ed15d7347c94e57cc7df", + "0x20929894b05fe04fe12b11d336bbdf33ef983eaf6c501846d48813a97ee4b5f3", + "0xfc727f2888aa9f47d486f93b266c6d09b09b949821b63bf86aaea830c16388f4", + "0xb9035314e27d890b6362db7cbb0953e953b57163be0d80e5ed36759500f3160a", + "0x6d2ba56b3c06326a0fae498467f439b47bce1174862817b5c703019e8d448c4a", + "0x6b92e2415eb7349014bdc3e705a2170a5cc09796930d94e861868f77c45d5802", + "0x83a57de8623aa9742b33b3c8b3737bfb198f738111e437d9bab12baa0660cecb", + "0x979d381266e5105773f922d3172dd020a6010b9e435f3bad16ce6065b537f384", + "0x3fdaa18e7a2ab12c5705b17ae33e96d8df9ab3be631bb9c46d31052ad423a4be", + "0x439e461837340e67edf1c7b7fcf633d5c3d8636174335dd80023dfd61f66c67e", + "0x3ba40c7198d6c75a1ecd79218edb9608b7cecae9f779b37d26873d040d29b308", + "0x66ca7e3c8f892bea4be87afee3db3c9352641139ea4b8d459417180c2df8ac5f", + "0xd55c6d521f3a145379a1daeadfede8f837928315c9c2f1c2642ed0e1a7e87674", + "0xb848560abba9f0e19af44219c2c1a5011ca43eff4ff6471555b3c1c235c40119", + "0x1fa19a85d008e7af8585eb7cbbcc8d61ed6248708429d0f458f1b497ebb190a6", + "0x72a4e2f8b7fe422eeec318f1127b4b4e4fb03e40a028d45f5444c9b287a4a764", + "0xed88ca02a5918d6f621fa1e945bb1533e33ea5c1d41f7915672e3c4e4dce78de", + "0x60ef0df2f7f5c6de3dd7c02fb202c9b3a13f48102f317b54b25b2f0f1f49b6e1", + "0xc49153808e765883dd21e1b58b5725aa1d242f920ff0ffe0c6089a5e00719c82", + "0x0c8581a354376bbb53379f45c92e914e46676b68305e8fcf16eb069c65e87cd1", + "0xb562721b9433cb712b3969d193e132132786434bde1d45916bd7423194c84678", + "0x060cfe84bbb7842e0a49bcf9f8753635d9fcd694de3b8d5827239606269f0cd1", + "0x84306039a875a723780ec685c34474d35ac3431d6ac8d43b2b6d1bba8572eb9b", + "0xfeaec570403a0190c889e5d2ecf96a9a6c720b3944e4b703049c81a35b56d820", + "0xae002e7d8e1279513b037ad09695e93f80868c60d2d8b0ffe6efc8e0ca8a51fe", + "0x20e1f3248ebde32f2fca51a576abfd0db3fcfe359df399f1c3102ed2183b027c", + "0xdf77e0510d24818676727c9d56b58b2495ad63902cedb04e2f3729b58374c942", + "0xc33b4b53e7eac8725f5b3c27a9431dd6e4f966b1289e3b2a1e158474f4a47f4a", + "0x6466f3aecc922abbe6f995a3ede8ae650be7f1c08679c5f6355e32ae95a4412c", + "0x56322467df2291a50bea2baf66169caf34eddd525655cecf6d14fd2295b2a438", + "0xbd81e7bf5e30f4bc1b87c57a4eda09293cf6be979bd2bb02650ce5bcab8da996", + "0x3d611638ca06abfde10ce7f02152069aa30d97949dabe3dafe8980699d49ca0b", + "0x12723caf905e0c044344c83d085f3d89c2eaa695c9d70c0a831d487b050ed453", + "0x473f61c421d202e15d4a62d4513bd48313d253004feb09d9b6e0502c6ba276b1", + "0x9583746c372cd042a46ada64048ac44b30d3b055b6e22ca3cef5404e57a99f0d", + "0x8decffeda7b7de072da8268776c4b9969cbf3e7ae9433334aa7e1e7c93567f55", + "0x543f5b6b686035462d17ef969fa09e0af3e7cd24d13650c2d3597516e62f9909", + "0x5381b2412f6383d057bab3fefd23d08384f345960cc2fb80d7311a63be5080a0", + "0xd96b7933fd9308f7aac9fc42e8feb9f2f4b586400fdee23798cad69611320461", + "0x0982300c344d44c2f63e1c1fb5fffdb44c23749204a0e012733317cde6efaa83", + "0x6048706531d18c5f9a257448b2826fbcf7a72bd08d5d4feb2928acdaeee61768", + "0x2bb89086896edfbe79407ea2bc8535c6be143be6c64ddb1190e626e091c7e802", + "0xd1d6697db021746970393fc0151bef8aca67d202b0e54f4f2702a5f86c2fbe2c", + "0x5c1e1a43ba2578bf4a302e18f37bbc4f1a67441fe6a71ee856662739a5821db3", + "0x1ed663708c0709027c702ad5ce0eca6d3e0f22d6a01d4517adab0a3d25f5eb26", + "0x6ca247d5ec5ae33cbecf8fe88c1aa64745f7a8d299bfd356bacf764141d410be", + "0xfc020b5ae74507a1475ef8e2c0bb516b67bf79aaa2b61bdbc472ba2d75ef5db3", + "0x1ef0990b9051937ff1fa02880131aed9787e6d7d41a598ce7b5094eea1daea80", + "0x9e9e9a83fd6907dc5407c49ea34bd1745919d9ddced756433f374440fa8c704f", + "0xbb3687f8723712f39a8e9f8865543100e048acdcbe2045803ad5a40b61c4a36b", + "0xe60d8a60edc3d7e31ceb356e493a28fbc845f302ae2a8d1e7cb80f53112900b0", + "0x294039b994a3ff53cbba7718280dc827fd582ae789736a026eee1d39284b35e7", + "0xcf87c0d2ee79a0d2506a3d557880f3ee9a20ff51bb44c20caae0849a85055408", + "0x0d6bb688dcf3430e46de1512ebc9e411db3380590bc72dbaaabc52a5320216ad", + "0x9f2cd8a43695c78c7a8fb1352d581c82dd9dd0ff04e3485d5bbdd5e3942f9c4c", + "0xcb32930f407012e479eaa7b4844107167f519deea6c7fc0351cecb93c500d63e", + "0x17e759d815596e0b89a3dc4ba12b9d10ec59988fb0550e1518a8b1cc4f331190", + "0xfb3b36940c6675249451c4c857f6742bb0e1fd3eb126e370eb4deefe238d7d75", + "0x47d619d7d8a9510290dc0b8b2518af2862ff6f761ff09786dced91e39d8afeb7", + "0xe8f40bd7a7bb8f7dffbc63addf31a27e0a987a27c00525c833f6ea8f508537e5", + "0xca372409bc160e5eb7fa70e2bbfe8daac9763b374c7bdea0cadcc933450443e8", + "0x6e234961784273f80136dbdfe0f5618fce6c0d63c2fbbb5d7fd6823632c0ab6c", + "0x2a6cb327e669de9f9783300ef6b2cdba5585236e286ba94dca114de92728ebc7", + "0x0e91e6a11ea59f840d9bc47f251043e10159880276bf69beb075557e38715fbf", + "0xd452ed733b985db558b960ed14310215abce589d4149952a3ebfc7604082079b", + "0x7fc984fb9d191984b5141a9dc7ed1c9657742c63e7958c7652bd896bc6c9f985", + "0x2ce2f74343ae9e37153b5c071c4ba13adcf67676ed7789379c364107d76e32cf", + "0x0bb95a7856e5f61bbe47d56aae9d7f42b994fc4640b50ae80200ed8a678dfd51", + "0x2ab80f2546564ff01e812a39341ae227b69ccc1b38c7f28e61c31925cf622811", + "0x1b24ab582f306305400947e9e7e43a49de6cfd62819517a8ddd904972bd8eee7", + "0x852b65355f93035fdf4358ffc3566d57dd97c9d59a1e545706bc6a13690025a6", + "0x6a44f88a6097b5e3c822abcf1823c98362b26b0bf3753b6fafaafabe9591a07a", + "0x4e7c0a92561e904eed52f2a2b906293411b97795bb194d9c92e335cf9e4ab200", + "0x6ac01d96e58002f8881cea4e177ec7606c69e21d252d863787e5cca65a839792", + "0x4d95bfeb96b7a7978c890842544e8e780f531512c182cf22a73a71b55f1679db", + "0x84de4313a7d87fd748e9872db1164ad3ff9d48993ba429b74dad497dcda5a3b1", + "0xb5ba8e71bc844413cc3eee7325a949af1e0ea81405a3371512fddbef87e4e9f8", + "0x2378cad3d3f0558c0df47cd179791604af7df805f805f7d1ec67b52b2c330d6a", + "0x260d00d98b976fe3aaed233aa9e1b8fddec1092595c91336a5b884fc07e51a30", + "0x7e3e9859270e3a7bb7c5f6d7170e98a8a0a681216e21567c303fbc9e755a4739", + "0xf9aa5450b6036bc61ea2113fb163997ede1bb212f343ae5df0b55561ff32797b", + "0x465cbec75cc303fed26bed3e2701372f9bfefabfcd54096a9189d73994e7aa17", + "0xa86195c2696fa647cd5971d47587212d48957f3faf69721683c158a1372eccfb", + "0xdd104c0ccaebf94bc3c0a6abae1852a71f9b1eee974d5e622f5386ffe0949b7e", + "0x005f5108714efe19e512aa83608e9cac46976b0afcc7a010bfd682965af39d43", + "0x60289c653af2f12a58b10c0f81ed6072b3112eb270b350facd79d0363be2bc8f", + "0x8e22bcefff3aea2767ad9b118be1253d1aedf1e1da502a4855f6ae7eee54c335", + "0x3ec7f166314a0c594eb8138b75a050082884556f7664702333c096bc93b67820", + "0x605398473b453589bc31312579ef3b5ce0b74e3ccb95b680f8beb30d2fba34f6", + "0x51dfca1880e15660901b5f755530c3fa4d652050c134a769b6ab2e1645755cc5", + "0xb24e9463fccdeb2178e520fec46eaa8f2d1da5380d48815a2fe1816f71b79b8d", + "0x97bd624937de7bb8915d7e396c31cdb4afb739bfd4eb6d96f8773ddd0e4f4933", + "0xbe17101284e09bcaa9eb5cd150983b05248b620465244b603b598bbaf9bf312d", + "0xd3c2ce415ee6bc3908cdfada4fcc76b5e0e9fa4f1c6ab43a3710b2ce81f150b8", + "0x8d4918cfe78489e146c071c149a7271ea81dee2ab0615394ecc35827193e737d", + "0x6a7e51675ea6214d36acc7fb193911d2608e41a2df747e328afc6f5a465261c0", + "0xf012c5f418c7e265bce72f9f4e2900084216c9187900927d9aafc899616ea9e6", + "0x934c51d4f2051bb7aa555b3f44bef81ff782b690e29f7cc0a9411ad03ac74a3e", + "0x9ebbecb11efe195d2ef7681c8f1f8af3b501f7c65a0f9ea916f7ffc9a6bafd74", + "0xe28247949b99de84e721641d5e3b638dde927478df0ed0f53b8970b4febbfeaa", + "0x6491ca6bae8781055660837b72622f19daecc7407aa58d24088b45f5725691f2", + "0x3a56f6fdf34d6a4d742451c1f5b6e575685f9a6703541315df1cb8aafe531f7e", + "0xc204b9d22b7cbdcc9132539ea475792f4ea231cb246747c485632be8df4ff5c2", + "0x6188cd2938f72d2dd5e16525574f240b458316d42daafed892faee9189caeba7", + "0xa272f3ccaa93e016333dbc904183db6309e31d06720da1d18addb7560b9bb427", + "0xdce0b5f11909a90c1c6b8fd2bdb3113a035e7784103e05ffc972364530ac36ed", + "0x6bcf3461ce1447e80bd3da2d91dc4530bb649b98333304fe3e0045743c0b96ff", + "0x523496ab97b10356b5bfa8e17b4927b8f0f507368391e24250f218cc00be4bda", + "0x6dfa5889c65ed8413d6633bffc9c3e648621d38eb70e57ada781b3f4dd62374c", + "0xaf1a300f73429dec7f12d0ebe9706cd113e15e1dee6cab37ff11503a836cb3ff", + "0xbb8aa95b40671760e1d131cb269c2d156f29d89911604db04ee7f87511283b56", + "0x93ca5bec69be4ef613260e2dc850668d5a1c839e511322d95ec25203d74673ff", + "0xd7cd3a14db02b6c705bb6cdb03140b50b6b989ab82d733df84f990a9c4d6b292", + "0x9136b9484831f1417ecc2d5ec93fe31b25e79b35513cf5187e50e3b95f862269", + "0x1519b8a6581123491bd0df07cfa3a40b0d098e5cc6ea981368fd073f7c927ff5", + "0x08ad5c68577e9e09e5b00035c65835b404437b792ff327950d07ef227aed6a84", + "0x4e989dc2f09df3e9fef7e50e7b7a9da85c091c11796665602a0f8294dcfcb2d6", + "0xe4a311a951e3743c0d3d05db87cc5d62ab0ebbe6b2e85e035c6452b0803c4be5", + "0x4a64e0fd19dd4b2dd7be3810f870cfca0cb4303d44204ae329f3ef1cd0a78420", + "0xd13981c9f5bfc2efe70eba25bb4f3d3f7bf13d454527df015e951bd79c649c50", + "0x57af6009a040d74b628416de645cb13a58e16fbd63035c6a6d8c8a0bed102ccf", + "0xfbb76c69f42039da5d672776f9e67fe1fd3d7eb0d7f5353852fa64558a91cf88", + "0x07808058eb2b620907baae2b053ef2c5786deb73df750a1b715bb1e0dbc0e14c", + "0x24f1e75fb9fd88b2628285f3e49233ea6f59b474ca05f5823810a8b49ae4cde8", + "0x5cc1e13c706a5c18aa40d8e5db49bcc87c38a07655a814b2179a35b1a8ca79bd", + "0x8ce52067eb546774ae3796de7cbb58f33395438a7976eef1f191cca9c6f59f76", + "0x094311f783939ded904c263a92d5db558e60352a392d3ba77045ff82114978e0", + "0x399ecdbb06d1421fd3651cd625376cea22cce333c6dc200b9e572a001b794a3d", + "0x6a94f126de560108bdb47dcfa8eaa5e9895b3bb9bdf7e7e3078fb725a1ca18a3", + "0xc0c7a71a8e3547cb067a73a984cdf283f6480524578ff611902eb9ef947c4c80", + "0x8593b4417b4d497d0f1d68c21b5f27433be956b6e8f94d0e6efe983492647fa6", + "0x616dacbbf17052280e093ece29a151df4c78027d652ff2ec3887a48daa916d31", + "0xbf17d700c78628de624a49125b764c1240f3d59b85fe376a64cc02f44fd3f46b", + "0x89f0b2b0b4b0eff45499231c9c5fdb53e95f72c589e7ed04c734b4d07df32a69", + "0xd4399b262ddaeec84cb56417cb84d2065664d79a51750ee566217487f420d8d5", + "0x89874f2ef4e0b53e96afe703f4f9e5d5c7da81a621acf00df29f821098142898", + "0x84a9a966381053a4e933c1ebae4fec74d3452ae5feb2b1c90ed59c92fa0f5250", + "0x748adbe8f803c86ef6f20ef7f178123f46d6c45dcfa332827918f4cfa9417663", + "0x0c78bcfbe149b1b2de2253d443011aefb4e5ea0c7a48e2e13156cd5276437557", + "0xa8d86c719b15c328e5117fcc0f4b381df4b8bab346d522df49aae19820ee128a", + "0x3bce6f3055593daacc3ae11b67d5dcc20475e8eaa91eb3153f83bfca6f2e7c8c", + "0x8af84754ff63a68b7b8ba3948e255fc172c53610aa90fc2f5f633bd8ce1ef7c5", + "0xcacfe2b9181c60d0c3d7b48403b18ee184e7c7032f81eebded3f19078c01d7d7", + "0xde4bc2b17855522804fdd6352f36eec477baafd69823908506b949c017aaf4ee", + "0xcbc7689bc06c9f4f04414835a89650a845884a2d102b6900f3abd4d4c8f8dc3b", + "0xb9779ac13bc739d5bc40bdb927c3543310ff114a83bbe35192c250a5f772d441", + "0x1239fa2d0cbb2255d32b82177a976ed5c9f70f0661a5d5267c60f456b9a7f44c", + "0x3e81ff86adae141c75c8b1a91d47db7c6b196ab00cc883fb2fba7655fdd6dca3", + "0x551e92e6d774825a2a48555268c86ee52e1b613e63c8a6e14275ae877dfa80f9", + "0x27a7d2faa486508c7fa20b818d6aa130a914da688d5bc8c60a3547c241937aa0", + "0xd10995979320d9d9d64051e4f721644579b4984a4337de86901b03fc2c042e21", + "0x6f9308ec6c4eb211b8c2323b68c4670db6a8116ac4a370801ddab1da0066df58", + "0x17d3526dec54f66815d8e4358028b0aa91d3a134d843d2945a47dd5aa56ba788", + "0x3a673e5904cc61906f6806b634ae6375de45f4f0d63713555d13a1e274e1bbf8", + "0x39dc807657774ec32abcf299b9c7f03371bfb51a864d11800199ccc7eaafbb4b", + "0xe2bcb8da657b830794b6d9f1e7471663e31996c1bb08456f4d8802448deb8565", + "0x38c7998e73b21038659140e5ae8539cd8cf993686c90148b38d6308a3e3b92cf", + "0x4b6d2986964aac5d5101ded91aaa4ff78a319dc04ab18e550589ef09b638495c", + "0xd8c4da66b5525427cafd152c365f99a255ce2e78af3e3f3dc408de0dd16fee99", + "0x444dbcafda5c0c74092577141df9fc8fb1822ef3375ef0d43eb876fe29c262f3", + "0xc030bec71e90264bacb7c09f9de3a5e282684f9f1d45a2b177c8f19f9c7180d4", + "0xd529e4c2687c7b40d1bda81201770838320b1183da1e18c59c83cc4772296921", + "0xa1ca4f57cfc4ec4522a42cda37df9aa74406d8aa8dc4b56aa62fc78c70d02379", + "0xdd30dc03a60b0fc21dc4b75629124e8190daff2e3504222fd6fb772531bdda85", + "0x2d9d4a9b9b2a27cf863a292a7fd112c81b0deae05457073fa0d5bf7e0dd755d4", + "0x19815e0f25090a9494cf5bea69edb70e7a56e6bf56bd19ddb1856198f54399e0", + "0xa7fa776c8227838d27496a3c659f3da3f5acce22da70701dfd62953edfa2bb09", + "0xe55efa9386b2e0fbd38af545106f197868361f2dc44051cb4a1ad540396283a8", + "0xc6c313738c3c75d434da4083962f8e8355bb8832e17c7104d037b131682b28d3", + "0x756a6309e8c0a374b99b2b2534a851496bc74db36e5bf1c950c0549914f0d0a4", + "0x36f64ed32258a3d2dc849f4abe98db30d8b04df28420c56215e29190e8a447bd", + "0x5273c4accf93338826feb5bd75117a7a0ab5a01225972532ff4ac1d29b289d8c", + "0x6146cf6b830f0222a8bf9353ea26deb973a85c5c4a005136061ab0fb48fe56a8", + "0x97b07c22662079a3a448b373fcb73320fed4a0877125228b4e9a5b74c0bbf703", + "0x68d28adf72884756b688377fac36d371325a01c65f5b70fcd7ac16a2dcd21444", + "0x2c27150b4cd8aea85723c4d264b8799c2e92bd4430719da6bdd3a0290c024a21", + "0x6b553b884acac18804cd52c7139e4a245f2d263b6d014fb6c28e31d7ea08e63b", + "0x64bc2ff8936395f794702b110041a88c1acc9cba50e12c2c5c9730976e667ae9", + "0xc45b2a7e308777811b6c099ffa3287970e003001dfbfe448a2600edf995513b8", + "0xa89c093a0b77cf4ad1ad7ffee799872a66ee38c3989ad39fb90069ab70b1fb4c", + "0xe8d0823460eba540c0c86016014127c7b77b0afdd199fc7bf8145a556a7c523e", + "0xcb2ce7a29b4c67956c439195a84b53f5c54e273c20b6cada43aa68ca7b1b59d1", + "0xcee4cb506d3b0cd84b763f405cd68e2bdf9ec1741778a004eaac9910d17cb67f", + "0x357376e9a49b6c7dab7c5cc95d4a90cc27516f1b7f56c33c4c0125516153819e", + "0x77090e31db86c2f2b031cec1a6dbfa3c3b2f464db7e8444b5def6468c03f5308", + "0xf2b0dee21d7b016c0c9e1a02a970835f934f66c552d653c9d5fcfd20aaf397f6", + "0xfd662e1a27c14d5e8b1e9bf6fca699a3ed7c5bb883cc626d54f53a721c570557", + "0x86194d492a5adc474f114f9cb7b0f6f6795d7680614b29bdbf25e969513a3276", + "0x2bf3ae6993adb5d85fe62bce02a836beb598779ddd37cc2db1f44b1cbea616ab", + "0x4321e3a94d12161ebdbc1b5c0f9223a7f1dc9050792589ce95771c7951b2f176", + "0x79154a76904f2a3c59e7151fff7cd448a3f74c003b866b9faba330481c6895c5", + "0x9c9e7e1d3753804e3644da89248505116009585c6e6d42071cbc532de20749b9", + "0x4dc1441b23210778e4df8417be9f654619527b5b42247bd7a8490a4a5f50dc49", + "0x79fd11e85b307098e827168a157ef45b0af5f4bc073a2920f42c6ff332392a58", + "0x446e8650a156bbb1b96d22e0d09619f90b8baeed34f8b63ba7bf3da3b764e219", + "0xa86cdf11cf5586d8b0449085e7c153a0dd55aaaf930960f3f31f80d099011d70", + "0x4d30e55035eec495badfd3cb8a2174295b2d2cfbee4e669e61bc148d09ff2342", + "0x2f8f3bc3c59975caf160d4a5581cab3499b84a524cb7977e4977de10a74ab875", + "0xe08b4473276f706c7399f584797cf07d33a91c91272ad79e0a5004c00a0d3cbc", + "0x1e27eb957ea54f1806115824c61d78e265cb75807f68d508da5ace6c7dbcd9f2", + "0x8304bbb4592daf4cc754c67dd78a2e2008b1abd8d966521a2291d170c9551e9b", + "0x8298d1605af17c8f47afe0b34b84bba22441a064a3d5311a2ea7e45f76565c8f", + "0xdc8014aead4dcb61449918deef31c64ad8555939347bf04f543d6a1158eb1771", + "0xca91e9581535b11cef0ebcd2e68dc00c3a18844fb4d6f05acf26eb3cd15f1047", + "0x2b26282d94df586bc7d4bc0cfab8ffe1844800c7045621527b9f9f0d5004949c", + "0x9a92f43c5a697a097e39ad12fcd9279b8fb3c3076ea1d910ff871c5ab3342a47", + "0xe33707e3e852b3b6a5cd375d981810399de6a3f96015bff7a4e5065f9c8713db", + "0x132ddae1f0244abf072e6d8115470ad4afb24748169891be0a4b952271599333", + "0x2c1236a98f16a294a9de1c24ea59739fcd6b5932b3f2535c8d131bb2f92c1dd5", + "0x989b0a915bb07ef5e3673a99ee796639722b9e4cf5086433cf8072fa3264f4e0", + "0xbd871c039e619de1514cb6f9223299c44d0555b5eb88570f79fd0d593953c197", + "0x7fcb1ab57bca2410a274f6339927bc12ea6843c106816fe10fc9576b6c7f7cea", + "0x5692b49ef3c3ffab97ab9ab1bcc10017e6d0527e1fab5b257210633dc4d2658c", + "0xe105a92cb6817fe6fdd585068363e0ffd45686fb6dc3658504c70e2057b165c5", + "0x97e65f3bb842f242f51e9ce978320a90720858dc9c535c1d66bd1c269dda0286", + "0xe5ba47b574c389d060e0c5f99f69829d7b6dd8b3bf6e64c315c28521a329c392", + "0xe971dd283f7ed3ca0e28a73d614c490a959c36f44bc30dc7fd79bda064f23aa0", + "0x0c786961cb4df57adc1011891b90813943a13a06032dcb2b7f9ac38dc8b3458a", + "0x3736f1ec97fdfecd7c2e6139fc7ef236586bd9507f65a99913a23bafdd5f069d", + "0x5c6cefd0c6c9c825668f99d1d595f6fa55a45e6a43e23323e901900e02a32f40", + "0x00373765ace6950b4728871a0165aeff55ea61fa8ee07d51d7b8bb8114c20380", + "0x49abb5d78311bf743008c2401f074e4b190d9b29c59cf6328831decd83068172", + "0x0bc28d7480d5a56588b937a530d026a94becf9ced1fe71c6dd1ae0d2922bde50", + "0x45e4ffdd3b6d480ee76f0ee7f6acd7c039ef564d77e5a91546e8269d5468ff99", + "0x09600f167ac2e81cb9164e048908a5b410cef5b48f92eb9a801cf84104430172", + "0x00ddfefc3d36282e9aa8e163d54df86f10737416d9dcf33e786d1713ab54052f", + "0x5b9e3159e4394f03d05ed8b8127ceed638ebe147beda7b7097b6dfbd8342df53", + "0x85d2ae2bfa381b7f5c1b0305f8e252f703d295edbd7c05908e6ae564d05443fb", + "0x5d93339013a78b3344b994bb474fd714bf5495dbcee84346a30219b214f1ed27", + "0x509921ed07765eff19b5c5b7885c4eeb30a8329417d1d819f3428e278364a192", + "0xe004d5f07b3986916f8cca4ba84f9357d4550c26d408f79fb49dee47c5afc100", + "0xcd0f7446313d80026c33427aad00e4689ef0c9966dc5faff93dd1ad258a032be", + "0x0bf64f9c84ef26104cc0d0bc61594bdc0d22f9bf25b436170df1c47351fc8746", + "0xb2e605741fe4b42abeea0ad054727950485ac432754ac2f98db695988c515d1b", + "0x9b6ef4b72c4c5b8159c308fe0395c8f74119bfc495a64e0529209967a1efab7b", + "0xf682c4da2d193bdc8e23cbd2a35d2d2eefff9281bb053f86c84841a3c88e4517", + "0x19cda96cd533527a9a93fe8c38184778cc79ee8ce389c181e67d79971c82fa6e", + "0xddcf6596740ea21e3c5135e32166e5e7944ab1a37ca60c57d9d005f83015865d", + "0x4932d76141f9f33ea5193e58e1767f67b5017ffc277c41fb8b9cb020304b923e", + "0xcab96730ff161fdecb5c0118b34b2a8c6ca2e53cc38ef76b8702284fd64d862f", + "0xe042dd86029d97b89ed789847c9651d49b2790d68b475f194c63c89974704b95", + "0x548200b226d36c3092fb9d721b74b829564bae7f39a63c2be0a78ecac5c69694", + "0x26a162476b85f3f6e366b3b767eb39227ce358a4c78dcbe6c8e3710c6ae05c1d", + "0x6f388c498dcc8b1e986c17332c8df84af7e8af9fca5c5a59600dda14f74e125f", + "0xa342f25dc1194e225f4c8b4d89b8992bf59517cffee52a1f2c2a0cc4727f909e", + "0x5e0d21aaffd603c4f5d73e5eae97e14988b03e45beb15bc44776e2db9ce20fb4", + "0xebbbed03150c85b1a7c7e7e6a6a67fe0483fc7176bdfe4f94bdb094ffce5bb2b", + "0x40e530eaa7fc24685d8cd9cd94a3f4b01aff4cbea49aafd448cd1f7ab4b0c186", + "0xecb1cc861f12d2be9b1f39bf56363937e6bdd5eee6d7e5e90426e7d29bd75e65", + "0xc0bc404c877856648f5793792aba95c9fcf2768eac65028e0a930c57ff9d158d", + "0x3e50fea97445730cf5c3fe8f05c1d03c2298fcd52a7d9be911d1c989f29fe204", + "0xb512ff3c024347545bc2843bc84f6006c0b1a91f49a7549558ac5d8d331c1fce", + "0xc0fd2941f49fe9ec9ca375d0745803539dd3a9750f1bc46380cad3ce29c76264", + "0x7f37105755852886e86d113ada4b4f1f68ebf0aa36dfa36291584dfe28e773eb", + "0xf0942db3af7cd949ae31d1f690f832c6e4f8a3b9744ef9bbf8e7a90b04a0ebff", + "0x6a9cee1f0f3ae40d63dab9547ea6bf342efb99176fd30d0ed2d8de02f1be6c31", + "0x2c2092ec0adfe352c46ade57b3c115783b7d4a92fb63bd1effef32e162d4b34a", + "0x4aae695ff67508f2d03f8674282d58e4f1038cd0d4c2a6a841ce425433e305a5", + "0x543665bfaeb5c10c0dd4d180475c9aa18a9edc313e52405f1c5fdc151538744f", + "0x7473934014d90b821ca0076d132c716728c19927f5680482b69163e8ca5d79a1", + "0xf3f4efa6bc4e493b5e09f32cab59a9cfc28b5a180a59640270a79927058a4f43", + "0xbfea0aeb82cd88ffa0269c56eedfebe83759a4af9345ebcd2156ec234d99633a", + "0x827eef18a3c2e24021dacda3c00187b8cc87e071ed1e2e9246be0066135fc284", + "0xd567403ba1bcccad81978857599647c0a7008cd3ab1a3bbbffec1217da92b060", + "0x74c8805b9b589e9493ee02bc73131431256d18b79de4fc3820ae5220bb5498b3", + "0x32afddf7ebc9d7efe51e045446a61fef4b156a3379212517b0971a91252e1b2c", + "0x4d050a932e5f971f33353a23c5b3382d163319321f55368598bcc3cd8c67f91b", + "0x9c01431659ec8c4db0cffc566ed9da3d04d5db610c6d6fbae260ce3011fb68fd", + "0x0814da2cbf76f83196ccd5342638df799d881eab6a526eab325c06d75b7f8e01", + "0xe669b4a2569397b901dad843884668d52ce85919ac6703671963d55c0923df5f", + "0x44762f71591afce826580a50fb4af763d7ceddc75d6e74d4f40deb3ec4c6ad13", + "0xd3231536bc6b897a24e7925909da660e7bc2c5154e529be0dc590770b5573023", + "0x8934b9858529b0bfa879142e0242f1dbe68143ac2ab347517be826e2cd8ab087", + "0xe833f8513f4e71ec56adc114106d5a8ae19b1aaf95d91a5ce18398f316253102", + "0x0a5d3578d418e0eacc2be66f8eb365a7cff71e6b287459e25a921befc7c55e79", + "0xc11db91e90bca5f39221330704193e670815920a5319eb06676b5d74e1d7d776", + "0x04f1e0808c62821a8f088ca0172820f469d327dd336db66d9595932826fb73dc", + "0x1861241e353c68afcba164f24f650eb3892f219d984e376336f401902b4038fa", + "0x142c7d1eb631e40562c24d2a271f0fa21be1ae76d6c7d98491599dc0d0580d27", + "0x203231cb071fccadc815f222900beca55777075f7d42563529682e6449138a17", + "0x304bcbcc7b6dfee9437b8f6b255accfd789ed115461b41e933140730a46675e7", + "0xc9f2359de838acb06278d7967f2ffdfd3bda5f46300b21939a760914a7e00568", + "0x1b470dceebbda583263a9373a4ddde80e2523b3837ed3c20b111e6fb9aa99a60", + "0x765ebffc2d48b2fe92c3fb14b301cb2338984f7760d514373b01fb34de466b33", + "0xbe814242513e1ef6903600ffd517b8f678cf306e057e01f3971eac7514b72ba1", + "0xf313f2b3c05a1dac53de10ddcbc4cc38b38be85f89640aafa4502631c0e3511e", + "0xdfb72e306c68cf4b22f62e9bca906ef3ac627b2286d2a261489e2c922d700dae", + "0x0783bc2129066d953ef7aca86ecf53ec3ff2bfcf8920f6079ad0a4dd703fe331", + "0x71f1fbfc2a9a232e2674e3e36547ee874806ab37b22728d8c30ecdb7ed2ad539", + "0xbb098368fb1529222eb83277af668535a1173a78825c7e3ef86f4f45429cb838", + "0xc49eea0b1171263bd8df058e6279092d59d1e8a4f108d1b4004333733bc6e7a3", + "0x6f95c83060775d579005c4731e05eda62753bcd0f95295b395b1de22b21f3b0a", + "0x9869e93ab6e4ea9da4cd12c279580e211b4c870a7e7dca098058897795804e76", + "0x816a76e3c912b639ae1e4b5eecadbb8cc173c3aadd796815a9ccdbf9226d58ee", + "0x29f33d9d30c64af6b372e922414c85004655782d024916909834b95643fd6096", + "0x30a9763617e8337203196a11f3e4b81b82d9642f0cf26b2c654c8504d289a17d", + "0x21eb2108b1ad465397ed3aa8016c09a52000c60aaaf42e13d95c271cf394c074", + "0x59d8b8fe9dd951d5ec540bf46808f01c9ec2a5e9dd0247b34b2622c48bfa498d", + "0x71b8061902f451c6fbd95c29ff960353afaea2b0410ee11cb993ce0ccb8af446", + "0xe69938e7da23b9d7ca611326dacaff95009cb5898abf1858593060ccb5aff4f9", + "0x0aacb29673ba3a0dce850ac772455c2b092b1a0fe61ed34965e4cdf723d659d1", + "0x18bf2fb69dc62ea39c195a702b8e9514be4b9d5eba18af13974a63f74febccc6", + "0x560b7fa0d15ec6bc0add83b6125133b97672b39477092cddcd5e2936f49c51d6", + "0xc8b0d3b55acae88939bc9426181dcc7d965bb5f85cc506d26f966c60a66e4ac6", + "0xaa9c3dea2f0184de1774c47923fb7f6ead25bcdea96c70b30127ad61a6bf67ca", + "0xfa90b6e07511736519ec741ca85d23d2912b509ec608a5d319c2369aa358a82e", + "0x0ab8709a1c9ac4e9e516736b4836febf938a0055d5b4cde960ba651e986f2caf", + "0x03e28cb08abb6912d3a25cb45868d699b89bdbc180eba67590b2cf13718c967d", + "0x1617f5fb8c39fac172251ac4bb1a9b8e20f9c36cc6a47e7e0545ee38fa55a6f6", + "0xf8cbfbad5d5e66d95dbd5e83b2968d08b6eb41d28efed0f1d9205b2297168dbb", + "0x4adf7de19d0498164921d4aa39bb070c6183e8511c9f987bc91d89cb54d8affd", + "0x7b5b34085f3267297b40770c0f27095735fa286ade7521e81f500005ab63d253", + "0xc2943d2b12e44ff193ad957440620e43fd9e8da22d74bd7e4b18846eb93fe67e", + "0xa461d24d7d4cc4fdb8016476b3d5e44017bc27609b7fd09136c3a884915c9761", + "0xdcbd32d171d8cd8702ec3093dc2f149c31542a7a35a01fa63043facfbf7ddea4", + "0xe7c4e881bd4df86737497ae6e3fd65fe9d953b8e1c45ef1cbba2d291be860dec", + "0x1fc56bf433f10fe704662c0f9e69a878f243d8832fe723852215f4d2ce51f9d5", + "0x5d22da26a003567829f9e2fcf0c2be4d0f791d44400936ff1132a0dc367c316e", + "0x985c40c0bda98d02e3bbf9e33d13be1ab4b1b917c94e06255a0d60de8a547513", + "0x5aacaa6e4aa6ec649fa272c1ae2cd0376270a0252c39d1bfdd973f03cacecef0", + "0xf2992b858c902441bd44cfe0e2b3057615b7ef6a7d129bf8402e4270b711b126", + "0x690eccebda6832cdab7adc9a56b5d8ad7842aba0d7dfa0aa073347d835e72703", + "0x41f48f7975d1aff8070e4d787b3bc127613fe74cc0207e6355d80c930577348a", + "0x42286416ff16e06c1b8088e484e1687ccb93c134a880e06ebc621cfd1fecfbd4", + "0x241f3e48bbd35c8743856e8020a2def871ffef7ba897c72464286419a8e67e28", + "0x3ba5d479584f036f4b4f99942a5bc2f51cc9c4af24527dc9ced5c66178fbec00", + "0xecef4c63d3679889106352d9e56b56b7aff5e1f1408e3dbe86e35dfe6ea6c97b", + "0x2a55f99801b5437fa85f91046e933d5cb898ee3150c6a068f658e0091a303576", + "0x0103857974871ee986d9d5d430b5c3533c0b1187353300d25dbecc2aef14cfac", + "0xe2721431cf8bcc77d5652b519e879d0cde2524972d74b6ce3e6a78eb0bdc5c80", + "0xb577b9c2b3348feb5bd8e283940c524d940268a3f90c11e35dc9de3438ff038f", + "0x5bf29a628a6ae340206e02f33eab362240f99ce0e3cd8d440d002ed4495252f4", + "0x5b087ac28a0e6555830f6510fd275bf464ee4d50e6848b251dac4b823de6b995", + "0xd6ca4c3a14090c0204fe4b9ac487debafbf0f984c289cded1de950f2e655abd5", + "0x61e776419693248d8a6b8bb2ef9b9663882b57e60650ea7fa22f1251e201befd", + "0x84d0ee42adb4c9b0e127535cf76a00a0d8129396f861d5d41dea599dbbff3d0b", + "0x509683f63b390fdfcbb699a8a30340abfb5425b257e86015170d7b7296b33548", + "0xe18de77507e00ff5a9097ae81007e793ca9abf2c11f65172c1cb54a189032d3c", + "0x38a8a3c1c0c110f674a7e69039258593e15a9194b1e77ebe6176ef5caf09c6f4", + "0x7e55232c46a25bc79bf9390c2b105d0fb342015cb526cf0decdb9db23d1be43a", + "0xb745498c642fb70abdc71c707bb1e4baabd534c5bc503e35545a6395cdb48918", + "0xa4b968ff3f3760b1fa4b352ca6eb8cc883f4c902f8e7baa2644d5a7726694031", + "0xee106b785aa0d24e57532819d4cb34b5795ab0af3080b38c73168ad565103b2c", + "0x1535e68531fad8e1edcfc2621747620ab962ad38a033ba25d1d6f5947381d03d", + "0x98c83d74aa9e52a7eae636a0fb54475173fddddbb56ca42dc314998c5099c649", + "0xdae0dbf33fc395f96a4dc1a8da5af3285b8dbabe5b34639e47c70b0938a9f64d", + "0x91348b33bec70e0e68756023f1432346ca2aebbb6a43df28b7388f6f9f19bc7e", + "0x575859a6c8463bacb07ff4902b06fe1c31ceb9552bd781003d4ea2e15dc81e4c", + "0xef1a187b7033a67ff5dc0cdfe353f81d8286c533669ed4b0c0ed5168f018cb19", + "0xc671086723929e889340d42392545c10126be24c357d509ff1c6c1a5f9a57d4d", + "0xf4f1fdaf74870f153ea8375391b3c446bc3cb9b428a3426164320c720d755daf", + "0x32caf4a46065b4094869812b25138ebed9b9fe17e27bed2f1e1f18485e29a5e4", + "0xb62d0e1a873015ebd2696616378f4f3f39c5e9396ddeb750110b7ef04f189222", + "0x410c675d1f6583e8364939108dc46223cd9835623473ca18dc333a4b86e69390", + "0xffd66aabe2768327036556eee6fde0c9bcfda2b13280decc37d82798075a0b75", + "0x3acda6ba4917e64e977f4135e8c74e9091499c212e6345c58c399b4dd31d6fd3", + "0xacccfad59b3f59f16431348a3078c1dc0b662876754c1f373351d0725dc1df84", + "0x3a74d9e98aff2b6445b9776cdc21c0dafba808326d917f47d57250f150891bc2", + "0xdd4e0bb3b84db7b6e16783870f7c9bc563cb1576834eb9175721eb9cf75f748d", + "0x35e9a92581c9d402a83a7baa67bb72fcd0d9b3f3d7b1b7a143234fdadd2e67d6", + "0x64ead38ff01f1fb408829012a033eb847aa6ce3e9b99dc5e866338aa9c355b4f", + "0x78607406421e95ff55b3b952d2b4846c8b2224b2a6b46d231482ccec5de407e0", + "0x04fb332ad235e8ec13b07cf30b1c1cb6ba8aba4031f932868fc1da5d82c03dfe", + "0x4fcbf75d2beff58cf1645f74c2ea804c29e1abb6ed8d33eb6da0f2f7939b3cc7", + "0xf58b87be3dde47b6a9615315d2eeda6771fa3b31bdc369ea706f7769bd857af8", + "0x7aa5b0a30ab24a79a54080b1b56befc3c88719219ca5cb004cd45d4ca1334dc4", + "0xd2f1129f7a6a0743995aea48e9c3cfdc5efde47398e6a67a634c1c9865b15366", + "0xca65cece85c379cfdd49b9ffc5ed7e9b8a623e06f99bbec608fc3725e4a1429e", + "0x2e6942d93dc94555d948f3358d7ffef3774889455de4da3565ff883a96a590ea", + "0x063dc2dab7f0c558eda8bf9baf3901e1626416f517352760180557bd45014f06", + "0xc633fc9bad22bf62c85d4ce1c064f3ec161014456c4eff5ee9ee197230aea32e", + "0xabab885f2c04a640062289106e7bef857389db6db0a499468b45f5e8147c5f14", + "0x96eb606a5d165dc66e5c293fa139a9e8e28fb1ddc8515279705afe7a57e318e9", + "0xacb239d8e12502e378326dad3b338700d359095129411ace179e5b921c07e731", + "0x8cf7148ce70d71a754bc04049ae797e930a9b16bf4962dd3eea2f13ac6f75776", + "0xf39d2ae39131332c16508e09eb9d507f4c6bdaa284d1f4a9315af8f6122186d0", + "0xcce4df2d5f9484177965c2440bc54d1fbd0429060e82bb76c3b90f444b5246c6", + "0xbe77cc749e5f436a3b76360998ba7e6e263d39fcf792a6dcd7cc4ea18c836990", + "0xcde5a6e02589515ebcc307e20dcbf163ec85e5692ad9542bab23b43de55c487a", + "0xe7977eaf5cd7cb8c7f4e86a2c3813d52943a12baecc76f2b9d1eeda569c29d85", + "0x1011e0ba87c36df65ecf37d2360f98e0d7351f27ed9199fd7df166806332c139", + "0x9e481944f0e07b91eefc66693b69ea71c852552cf8cdafb1bc93336b971d6989", + "0x2b4d369db84d19be84a7af630b0c8a4ce0974418f407463cad8a8223b208a82b", + "0x7cf34185f5e8229b657c57c3c775987128434e909d72d06956515440678e6a25", + "0x5956c7ee723b161a0e7d74c69e57c96ad28261e9d7358bf25bbc16560a8292a5", + "0xd9a932e6f59d547de8699965c4e5964e0f663b9fd5bb9f6dedb4417d356f234c", + "0x59f2fae38f9ae4b74ba9abc5f06d4354fb9eef65983b1c8b1b025720d1b47d51", + "0x1c418c58dd888b1a546a1245021b52e83b1bd3fcbdcd0fe9bd643fe05fde502b", + "0x0db806610e23383046de4a35f8098597f1889e4dde4bf40a244e4995324b29d7", + "0xed51baa16beffad522b677c19935f07d7182b0a4bdb04330146bba3d8e8f80c4", + "0x2ecce838cf6ac5d0589fea00bab4dc9c7b107ed7c70886ea6519807785096f23", + "0x8df70aa241b84fd616047258f87b04249fe23219808a6e14f3d9fd0181c2f352", + "0xddb9d88567f42cea65b5913369c9791522b4dc4a23b0afab2003dcba337a5595", + "0x2e276865fbc34e7035cd50dab4b9b72c980abf8f7dec50988b86995ec57ae497", + "0xe82487c950c00a1e4a9ac6d2c3d0b80584b44dc27d28d6352dcef8786da3a7b4", + "0x724b23460aeb403ae7f9b3512a1e222a63fe721a2ffa4e2f4f3062da8bb5c224", + "0xe27ede30590638e194e91a392993fd9a9a1f168e32e3b9144d71d46e507d716c", + "0xd29403c683d5b1ff60839587e60eea5a6054588903e7c2c0b6f9bf030bd0d659", + "0x4e9464c5a51b3f2c6a829137b67e266ea6381c069e1701f0bce7ae7742e9e49a", + "0x0b107abcfda0ec094a6946c6057564f60eea9e6a55b2c762d4af5a7ab7899c65", + "0x5f908c956864addc2b57f01074c567155bee41412da6d63ba72971ff2eb8114e", + "0x9c00e148df00d9fb2d5847bef0726a48507871baf12be51373a7bed2a0c43f70", + "0x63a2fc58db6de3a2de3bac57255503791c4204941fcf15549a7839ca8ce26efb", + "0xefd321eb79658c3706f6f2a18663361b3adda792fe9064de3785acd101535223", + "0xa73176de8f5b3a5bfe87273711cc35a042c191aa998dc5a67498b0287e54be82", + "0xb8e2f03d134651957c31c47fff8cee2998738a603267a12f665f577a450746f1", + "0x3276e6d7618e898d6a8e1f014ccf9e06000f7cbb279dc9d078dee38f93231d3a", + "0xd23b5d1399be075454bc8f3613377113a7b65b29c1bc1a515f9bbfcc30b88174", + "0xa577feae921d39efcafe8102252452202fca0532681c2967c06eb63d00d83294", + "0xbb2231f4d795b6ea3894d802ad5f303c19edd2a25dde9c3a21ed1b578726b51b", + "0x81700c9bee6a014df24ac76eeaa2a378ce7febde11903e62a3d223ef1eec39fb", + "0xa1e05fe31cd3a58a3c11cbe47fed738e0add5039a8f97275572c7f66431f3d6f", + "0x8b5d0ea77b923d4faca65b07c9621467f2c891a925ef07009353b9e7ed854760", + "0x3566b43040f753d8a18edf7b3c89d44a2a3565aa0280ec673718ee81b82df24e", + "0xdf0672dd1e1bdaba83c0abd1d7c41d420ecdcab0019cb89b3dc310bab32bc8b6", + "0x2ef7e245c518654108cbea643f8b050257b9d3c4927493671a3a094b1dd0674e", + "0x993a3c5fe23e9636f525a4e5ee514949c5113f3b4db21ffc993a8b6bc3a55332", + "0xa023919b4e8c34cd2a1c7dd1768eb8e856ad2a1f5b101c8fed88257fdede3804", + "0x247fa5256cd95b9cc4431fe13466483f0db6707bd2453b6374934e1edd034b18", + "0xe63370f2acf5893c39f3728b66907ddc78d9dc9947db14ed6a7b5a6a876c69d6", + "0x397eb84160515d8b2beb3d37d7dfe167fb907f8a1a6cfd7457b646b95a18e9df", + "0xd236e18de82fddf7cb7f6df91a4d08fc98d9aba622e50cda7499261d01d9bb9a", + "0x76a526408c824b6c9e8afc5a0d5e5492a71f30cee5d70b4306c2298d348f0caa", + "0x00525d5481988d4c4836dadc936aff84036d99aa42722057b35ebd933c61ef3c", + "0x94e54fe2e05dd7d7e4026c0048d5e64e5314f235607e568cea8c26bd31dc3f51", + "0xab1e0c92b35d49b687188518a7af63584cfb13a74c3a9ad800fd8e1a4541faa7", + "0x5e65f148c1a914b300aea241f07de5c43709c38d279ed118bcb40ab9a3a09226", + "0x9fc8a8843a0eef62d8c16d49c70cbf2f3fe84cc155cb741d647f17e2a664e7d1", + "0x8257ba8acf906e46b7cd0de0d7463ee96c62ccb7dcdbe0fff5fbb6bc0da28d74", + "0x2a57b487f4281cc28a5b107a643944796ef2416d7989ce879d06bfd6d4caffa9", + "0x0bdf8efb30c449b26d5c574000646ac316aff27fa49d6e20420a08e441ed5f96", + "0x5d3b67c6a6324936305f405067ae70a35146759278f77793e3f7c4b90ac0c7fc", + "0x156f094425a09a09f394075d02f5b5d5aa6794bb5cf62d824ece1c57d58ea993", + "0xe31782172a116b92ac0ea9de1cadb81c1586e05d5b3993f10f8f695469ff9e81", + "0xd8f85113147a72b1950948000d75d6005ae183997c798fbbf2dadc5c439be9aa", + "0x9bed32bbf1f626012985392906016db1c993fd8ef351f8c72e2ae832a2efdd66", + "0x1c6f7b17c8bd64e03d21ca9b6dc2df278cf0b8c8f6f60c60741659fe5b34af81", + "0xe41e4494cdfc0e92f16fe6ec78e19b9d8cc3db73700a1bb02fc7670c92e4df2e", + "0xca1032438230b4faea930fc0689dd966604487a8d3abbaf21554b3e078547fe2", + "0x2bb999d1acc6cc7449dc0cb965c3bdff42e49b8ddb09cde885174c45730bc2b6", + "0x4601be8295359bb23f6f09d7f053c637ab2ce7942b762ac55b1da6d312a765c9", + "0x13fcff0af19f7f11af35b360a0199bfe610a09864dd1d42b0a6570bac17803d1", + "0x31b567fe7d9e6a9a3c15c449e9aa0ab8f83a453beb2784132f25b0919abfb428", + "0xbd4af1360219156ba336fba9cababad31ee78e1393061e3ff62f7ac785c41f19", + "0x2e15f44010ce7a966dfd3fea57c5124c120cb60d80a635910c0b2feec59fa977", + "0x68ed80af93e72f7fd9198d036d8b995e5baeb0f97c6f2734379116a5814b601f", + "0x6aeaf5d0decd1a5c8eef52435bdad2a60cf1cc5f79e23b90b7afc0110d830a3d", + "0x349b95da9a3c65e1d34533bd08f8c95c934c49b7c20e6c7e38ce4db60239c94b", + "0x2a0053d5a61602e26d932534d5e9a753f75642edf1410b3ffd61076d27d5ec97", + "0xca53c9d106169cd3a7a870efd2c2c7118ff953b8aea5c5b9896dc2ff9b2c5d59", + "0xd227181ff80d67f95f4fa11f86b1bb5dfcf37385262d82d6025bdeecc6bf00bd", + "0xefa99cf897198be702eda71b3fecf4cc12a27e7c90a258c4230aa847b03e16a6", + "0x0788c17ea693a049784eec30b17c49e66e7a71175893a064db7bc6e85a0b536e", + "0xcf2bdf91c2f44cae1148ae027688f70ae27ee65b8c1159cbca3e41ab7755e5c0", + "0x32882f2cf31033d40d5069e68c799f3e3297a9915287fb317bcf657e078fe6d3", + "0x3401436cb69ba8552d4731fb2f734a9a659cb10ac666f374318420d3e299b98a", + "0x988943c9b35e50f6ab03dc275de1dc770aa32574cf9a90dd0c13e7263b46c129", + "0xc282d894a7e4346a492fe495319c5cc9abf0c7f95e28bdf985710f692c770520", + "0xd7f8e14bbf8c6061a0927e107f53123f78448b878b9562cb8113b5d93d2d9142", + "0xe2c995419467eb379ee043399d89bb13a7d316b9a680f9667dc9defc7fcab80b", + "0x567357333aa3c5cf6b1ba20a3514ad0e21eef11f5a5c4ec999048abb78c5ab7f", + "0xb9f31c6c771e610048dcb0f4553629481b6d243980e1ca9ec3d1400a56ef452e", + "0x924533f9da72137f96ba97b39a95c2c369dba0bb09658aea3a387f3141b5a34d", + "0x2f17e624e0f3213c2d953107e72aca40b5f764f4b31278c8ee32a000119aa3ed", + "0x8d301cf22181c65bd6db20ca01df6e3bf13864f88958fc04861c295a31b9a86f", + "0x3bdb760c302d348d16e634c07f437f793b888bc15fcae52c371675b7eec2e241", + "0xaa20ff689413c62b1d9854ed1c59b1629e9fcd9f99512bee40933e722e4d143f", + "0xd9d0f8cb5b86492abc172c0460cbd819d13c05f055cc1306af6285459223373b", + "0xe0ec50a77f89631ac2a1c38448a3e5d8ee739f1cbcb542b23116005ff0726679", + "0x90238eec2af4ab1e1445ab94f422f90c862afbfa8cd6bec154d2f6f40721a615", + "0x5c2350ae9bd5f2e2355c97b0340e96621bccd43e9a7e4e867ba1523f5a5178dc", + "0x896a7844bc430b330fc094554ef21c162e2c5c890b4525720a612c9f16bd80ac", + "0xc2aac353dfdf9d7ce52240f6b84e8fec9e66d4acbd77402fe7218f55fb76e834", + "0x840ca0ec7af88f0e26d3b9e54473fdfd038d5395165b22a935e941187d529136", + "0x5e1274869d1d7f072dcf83d631844ea7e750f90a6183262622f2db72eefbebc9", + "0xc217f1324e0ba4e36cbc896c2dd4418ca5bfa880cc64bfa913d6212cbcfe8a95", + "0xbd7893a4798b0838629ecbf21a8cea963df8920a792f5282604b59c536ca91bc", + "0x85b22d6088f30f1b262369f869a72e1354036363f70c8778b1560658abf75902", + "0x829935ff52d7148a3c5548bcfc72b736b184e4f4661b251e660313895432d66d", + "0x4b0d3238882111cc0065b1e2c9a71eeccb34876b4ddbcba989a47faff0f505f0", + "0xa619fdf363c41d69d2cd4c8063e3abedb18066b8cb6ed4fcddd99686d684f450", + "0x2dad790e3f5f6be580f97dd37b22a1e80a6555f41726bff0639aef54f0bc47e8", + "0xfe2064175fd61af4c646ff0745a79ad689d9be2969bcca0939393603865ccaa5", + "0x8a18e5e22dd996798181fdf8ae77cbc7929e5bffa0145996b00d83c5e7829c6f", + "0xa7adb5fc7ccbb132a8e22a861cb5e3e1940a4ec7c5add1bc767ecc668d1a84fc", + "0x7ea8e25d742691f53294dbfdac087b07d688cc40a4a2de28fb398b2516de4bfd", + "0xc162edab705ae176b26b495f7ef7205552319a72d56c5ded30be9770860d6530", + "0x5406de06f5e2e819ec8a7efda23e19cde88bf8ea9969e3e3393f1235c4be67ee", + "0xe5a6b4f946655b32549531601ba3571fbcc45bf58a7b18ea24b5f4677fd58815", + "0x5bf157c76ea5a10ca8240c44a72450537678bc949f57cb9a748b445907180d8f", + "0x4f2f7c966d440ab36a1ebf61ecb1a9b1ea4ea6227c29e4fc1214a8c63cee7d05", + "0x81dc3a0dcd5ae99dc7bcda8b30cfe89aee00094258891d445425e8e304a71f08", + "0x915c3f6e8b37680ccfa5dfa941ad2147fce2f99842646a7835e2d45e50e4d991", + "0xe616568cf1a281f42a32686b65dd712e2fd003a84dccbaec32b890440dd206ba", + "0x70526aaeb8a25dbdf93b3a7cf9cc638292f2502b7bf78125e88df90335e594a8", + "0x6b3e974c6a004beea5b38dea401870dd2a68c2902ea8b3ad5a8358e10f04eaf9", + "0x99b17fa583f9f80f81edae98fc54bd5552ad44aeeb6123e99670696541cd0442", + "0xcb13a1b63fb6f0b511876a699ac017aade97d8dec84249680e7e36b3729d9744", + "0x2bc84717485fb9eedb00647c8da26e201fcf05a0b5c42e2e03072ca130d1e3c5", + "0x7bd8ffc908159c25a28a3dd97064ee7a76bfa40628ac54066f83e904596562e5", + "0xb9d16b733cdefe95eed9fb024d5737f90723bdc46260f0aebe2adf23712ebb05", + "0x0d6a943a7bbad9fdbd107c4a1df726f7aa61de4bcf1e1c50c8a32d56828e8c72", + "0x7a264f356294d00e55ef0dd56e8ba793550c4366347d60c7cd31176d79dc8486", + "0xf52baa383738251b1085fd6aebdd0da48414bb993fd3bc427b2a07a6ace8d39f", + "0xe2958f9d5bc0f1b23b5a3923d87567a58dfa31cbc0a63715b76c501bcd022f65", + "0xa760fb572f3a44ac43c0cfb75becf5bec1d7dab5e33222050b95a6cb8938b146", + "0x004437e7463a43de8edcd074a4c2f03ce72e4716f88f03567a50b6440b69ef2f", + "0xd7268e9610100bddb2188bdb0f80ffbc479b67bda2ecbc5aaf18f947667f3ecb", + "0x176ac5d88148cdfd9049d3eca742750edf975c32e649be8372b15e43ce162d77", + "0x118df9c7631bfd903fb46cfa867c8ef861d9e828e6f57de585f17ad351819e25", + "0xea084c972d69e9ffb61665a27fa4f2d0006f0e220007c0b2e4760a95d68c6c01", + "0xd6e2a8f3df290a204efcadd3a34bf57eea6a3980fbb68749029660e661282f2b", + "0xc538e4c7b704fa8c1c123f8baca05bca5fda28df7ad7fec099638a4a7dd4fd18", + "0x419823e612d6a0055fe460ec9593b4fc0298ea94e0ce838fb302ff1ae033bf40", + "0x304e214664a6703ad14fa493ed333cd12f6db8f4f6af1223bf00a348fa3223e0", + "0x4de744c5af198cf5a0048c4a3c9ba578ea3478deae31531b87eba2a0e65b6fe6", + "0x523694986a7277170342c7a53bb710b86a432b0a7a3d96e141fbbbc113ac2e88", + "0xb81dcd531f4ea6eca82860d7f45063ca7de742a2fb41d7b6c1d62202fc1af17c", + "0x205a95c1d7e7d2cd684bb666dbaebd2533f4af28837a6fd2f6a7d4aa68816dbc", + "0x7c48dd0273a7207ceb5a8a1e3b33352f6d438e2a7b45d4c082dd85135e21e5e3", + "0x0e3edf65e5a7502793a8f139a69f3946d567a959ec411088af96da979047675c", + "0xa0b8886550aad717f1b5d57519a4bd82bdfa30e3c8ba4ff81a64be341d828aee", + "0x399f2cd7012257b4991343f191aa688915b4375899ca9519630b5ec6c62a8b49", + "0x56068dc17a965fad007ec7f23dec7d396dff33b0a60c4e9b8d0f75fb26178f05", + "0xbb62f47822b394fa87d70cce239c9e57464157fe2012c2c37e8f6b69515d6112", + "0xd6a068fdc6d4cd90203209a07363ee1eba047703e50ce9b06dab471e0dd1a037", + "0xe5a62c74d81ad110ea0ec13847fe64e4c3e8e48b1eb053f1e381abc0caff7bad", + "0x8ca95a015ea27a649b0bee134eb170f01b5c03cc45a8bb2c40557c1598c3892a", + "0xb124e101738d541ac61b5666c0fa19375417d946a2344ca40baf308fe8449a98", + "0x1b9543937289ca48720675ffd354464fecacd8b251a3f267f42906b7188f184d", + "0x0b48dd3eec04741e0f78cf61937b2f263446d4ba269e8c7d4aff9c00a2fafced", + "0xf72ffe4699fea49e7e67f96fb5688247746c9bf25fb58e41f02b0dde4a8003f9", + "0x08328b322ac26a02e89401565b91a3dd9abee62fe991744e2ecb2458c6c26460", + "0xe9dc223fdf695c9b5480de56cc91fa640a4b73a8cfeff30ecf4db4d36727fe21", + "0xa83123655348b15b947d83c14a241d8e303242614b25c45044fd1a1ee28d928e", + "0x14ac46b1f556ab33fd4199e5a46e0584d00bbcb2592ebfd4d4f66efffe31bfa3", + "0x71ad4b7b5605aebe1059ee484b5ec791e9018b50f92ad2f8d4f3c1548a99411b", + "0xcdde5fea3fec154058e16f7ef877c70404b577cd74f98f7dc45600cb7b598b04", + "0x330f9d20ddac508dcf0e08a4c1eddb55cb5d7f645c13f50b3683a41bced9e244", + "0x76de024aee0b03e96765dc6d7c71acbf253e962b4f3892b94196487821381ade", + "0x1c37a50f5e3c774d9ea4438a629d497705c3bae728e8e89608ee68d7cd2b53b5", + "0xe16a37be64f82bfe54595c9c51625ce3b69413b70e0b119a04e79c5b8d593c22", + "0x525afdc902879df4c23b996f34a5387fac6e41300e1a7cc9e24c630a1a140653", + "0x845164906086e678bfdafbf4719cf8f80d988bca007aece4b031c3ca5df08db6", + "0xa4d4bca2c51e8118d16a4b8ed33d41a73c275bef73072a6674005b9ee7bbb793", + "0xd0759f637aab37f4981b927e688f3e51f17cf90660931ab8bdfa40363a6931df", + "0xf54986144fa83bc3953c4a1c91eebd6a4abb185ab7b188cf7492a7ca430b9130", + "0xa31de426ecf5f98c1381c844e2fb7c959ad8adac39484d71e3bd07d3b1094118", + "0xf64fb1f4de6f01317e242b1198802191a6cdd39e1580d356b9e5442adb69c8ab", + "0xb97a74c8e47d37b3ce7c12ba09b53811f23dcaf4a8d260dd370f45e9ccbacc3a", + "0xf118ce791474d987b9a8d3290be077e8316a6fa3bfcda3600e6c2698264db37b", + "0x547fe45b0ca517f898e6a5fd22929cf533911f505e15de083a5685c8eb1ccd0b", + "0xd74d307e3b5a166a64056f07eb85f60fda1d9c17368a96afc6f8141141f85c86", + "0xa315936672e2737800c6d51fc22b56d918126ec329fa7e1ba5e31af36ea4f87f", + "0xe928505d97d673588a68a08ba6e2a4bc25843592598988c1d168d5c938e230cd", + "0xa6bbd3b96bd66597eb68c4059203275421a529c61471a69cdc1d2d9211aee400", + "0xa46efc7ab47e7a0f57a54203a039a4339d992207b31bc707eac98ade8e8f6fab", + "0x46e903455140f009d1f7e9d224ede2e29d1fb3f72cebeb60dfa64ff059b7ff40", + "0x1eeba50e5530be85464456af3ea0ee38855276ba79bebfe305e49fdebd0dc97c", + "0x30e149bba2c3c0db9038c39871325392bcb41169106131469b6ea7994c5d8d03", + "0x9503edfe4cfb20c38ba2efef043ad824f2b17f39e2ace445fd9ce73caec93c75", + "0x608f294da5e0df707b97c4949b775f64ef76c055459c26b651010888cb888037", + "0x8eb5960dc8e49951c41505ce34160bbd588bceb74468a7dc0898c6744d75138a", + "0xb020dd8cccb6beff1e7d996a740b876609a55ce2041ec0e9f09f683bfb22466c", + "0x9e8333dc01746341ff7181ae95ddb75748cf3efbbed24f3b16885efd0aa19da3", + "0x2a97bcddd5f0a7245c520bbabd77e48432c39f3cb17a0241be9c62ab5d185a1a", + "0xa81cdce57af311f79ae16dfad6808b40e8ece16115978131dde0f3edb29aabfa", + "0x8f321249562fcb94c94a80679adf69aa701f0719515753932548a89a28cdc7da", + "0xda37eaec19bd44bb1892d12d842a77ab7dc5ea43ca0a1a92aaa3ffed0ba9d90a", + "0xab8c920add1f9e922890da5d92ff199b384a5f042f5eb4e3fbe565f5ca50ffa8", + "0x9f52ff4d39142c046effbe6e552500886200c9c3154dc68abe0f9e4bdfa9078d", + "0x1eebaf84ba1e6667e825716be63ddc71a963688f47227e0d17d78144c820e17d", + "0xd2c2c19eacb26695c89b51b75fd616de5c769d0c7169794057575e1dff3800f8", + "0xc5ad683c4beaeb409a68cbaf81532e4edce6f64b60853725e493ffdd93e69f7d", + "0x768303ceca362b8a3996a4823c4d64ea4a4ca5892e91ab0433f2917b96486806", + "0x88e25c3ba8ac976c0382344f4a8fa310bcfc7f51e09efab4faaf222cf6dc5d67", + "0xe05f9dc2db75ce9b0fb59cf1ce12581cd10910dc5b91d744791f564bbb87e176", + "0xd75fad017be9f908c431987b10f25526a9c9d346118901d7e0b84e74a44724ff", + "0x83cd50c6634e2edf21044fe789e82850667862be407faeaa90f9bc3b0c60f9ed", + "0xdf6b6b1134dbe14a48678610c630ba5927f3d75d45d01e56534204b87ed575e5", + "0x3e486fed8ba04ace837ba81d61086b3443ec22a803cffaca18e10e0e0f1cf679", + "0x6b7c8f5e560ce6b6eb94ff8e4f811b06f2ba91048ebc2440e25f2c44eff4e637", + "0xa7a92f9396380b5ce01e3666acf035dc80a297448e1b95530b9a8bd9eb19496b", + "0x7df4150c891991e89a5938c12bcb4e4ca1a3bb3ed17e1d14930e78a3b7287cd6", + "0x9cff0374f59c5c0a8b6b8db636387e0d032922e34049356ab00ffa3f2cac8f23", + "0x85a5ca8ea29b19babb6aa45861de2cd9e44e31ff13f7161ead44139e6b2de019", + "0xe418e0eba34f07d10ba270bf4316b78b15c49d2a920f3370b403dc584cf2bccf", + "0x8500b89c737ce038eb99a443d4ed6dd02e00ab06c836b8f03de3e713e485e99e", + "0x0f324429900c3bb11cf6a0c4099148af93d8953b748fa8974c7cc5d942f6f36d", + "0xaffe95fb50dab84128becf268413fbf2c8ccbc2fde2b6f6d8bdad23cc4ed9312", + "0xcb93bb3ee92074161da7d6345022f415accea11b20c412cbac48247c64d099ae", + "0xb5044dbe63680e5fb8479f899caf746b778524a6c6ef3f56614d3b9832cf0006", + "0x1d9eb2e2fd6d8c78a5a4125733cbe69ff25b95cba736f63627bfab166f736c18", + "0x4bcdb35310f9e23c6b952933f3adb4adcf6b43dd88dcbf80dc2d9ed4f8cea505", + "0xf934917c926b2c975bb0cf0ee0eec66727da942e06c65ecb1e168c015f957a65", + "0x7375ee9c763fddfbbf6fe47b1db34faded65f5123dd92ff469d03a41f1fc47d4", + "0x6b4e2a1c3ad70f07688662e228faa861496294b068e21f040edf90cf9d0230bf", + "0xa64458a7d295ff66658de59d0f166a55dec1f9e9e2be6fc2a8ecdcb77b72509f", + "0x4e50f8712edd21e913834cbf4f8d6baf9b371f0d4592a0c6a11f70a8e95ccd26", + "0xa132bb777e81aa07f8d5a6696e3ec6c800a1c0743a946618d04df4b0668f1c8f", + "0xa552543fb7ce61cdaba1d077338aa31a6b69cbc7e6af69cb5443e2d4e1393cf8", + "0x05c451fa47938025e4fb6835d09e9a92f2db33cc99e21b44b98a1f3b0c6071c5", + "0xac9628c769038d220a38801a43aa1449c24b2277df287b04ebbb4082d1763f7b", + "0x6d188b8c97ecb2e45ff51e573fedeb95083b40c8ae15042289753ae65caeb681", + "0x0de60d18d4f052a11a584be1c4595430ea8f5c943dea397da9af2d27518e2646", + "0x02c7e9849aeadc3011c2d36d4f645aa0d3f23a27d19a8b7eec61e2ee723dc675", + "0x2c974900dc848a8a0eea1e248aa0e2469037038bf9c0768e6e46d2781530ac4a", + "0xbb4b7b7d9ae81c7784f6a8e7c309f30a9794f0240562ab889d4113bb1e775697", + "0x463ece715ed0458cdd0f12cec6ab023fb3a3cbf6eda4b55f3b4115921d20df52", + "0xd535c260190be6f755d84d8812697c8ad8801533b939dc95e2072e2f39066564", + "0x7f3a0e061e646047bab6b8dfa88b092ab003c0e84240dd82f6e7d407bd5a3bd8", + "0xaf4803ac72aa8419999b383e5765544cd61b5ca0071f7dce952d7c24d89ff8af", + "0x1c53d5aa090bb88a8302fefb12080eba29c2f9f198b08b073587049159cf4245", + "0xf71ee084795fb52661d5cb7957c7e710e6171683aa691412d5c816a764f61f64", + "0x9eb207ab5d1bc7d1a44afcb2790f32d7c41f1c54a17b277dedcd8ba1e63eaac5", + "0x2ba6c0454e857b17903fbe79d6396a472216ddd825b81d70c696074291e71b1f", + "0x899f295af86c53f6c27e75e6cb98cf428a5da102be6dd8a8e2e59b446a086a18", + "0xcda6ada90684f614c967b6fa4c37e6159522e2dee2fc8663b6a8478be5238165", + "0xa59f5518f36b97d9fd077f736de67de7856d515f5146d5b1ab1b2a36112c6400", + "0xe7265df96658699ef8781fba631750ab18dc9d62c0b24820e0538809d046a2f9", + "0x4d9fe46ea3b33b6e73cddbadbf8bee4aa31aa830c4a1abbba4567f21f78a014f", + "0xf5d3147fbe7420f7c55f6b06e045ee7d2b2e0ac7f2040ebc8183ef24108ad70e", + "0xc8dfe6d026040fedb27da79dcf77aaf83fdb008792c6366256d5988e356eeb94", + "0xeca183cd9a46eddf04e02e0a82fa295b1f56322e5552a7c7f0aad090d209b9d5", + "0x8e26a0ad84d0c8b5e64b8a57eebf3bb86bdd02e24f24ac95c6222959638a3037", + "0x5b1cdf956d672b244ecc6bd5a828cec7b80867a4ea2a547cf7240e39793cb5c1", + "0x48c8d0fa40f9f6a49fc6378152972b85cb984ec221384484148231ef88cc3a97", + "0xccf14e2b03037c17bd6d47ba41460aa54c826e945c0132692d08140f156fd115", + "0x331791c82f8717e22f27aa77b7530acc83beaaf9536cc74ddb90533327c5072e", + "0x6c621acf6c972322182e5431049874a5e78bbaaf1a3f49219fae2c8425d6b5b1", + "0x5bd86b4984df838b2ced1dd0f3e37ae19d52ab1002a8bea859065f8cdaf6bc38", + "0x3143ad07e92a4b2a24b6482b5502ce98d50df46923ace4845ca35e0948090363", + "0x66e2d61040285db2e895e1aac42b69b41f556e6fa82116c1e84b49e67478abbe", + "0xe4f3a6c6761a3e17a5a978c69d0a6688439d4d6de3bbafd2b830b5066d809e0b", + "0x034280d368d7bcbe1f1cc63bd551c3ac2406f612f8f04801d24f98d89e75c444", + "0x2b9ed64e419ea19e5dea807dbfc08b8d21bc13903e8888aaa15741c6c0481440", + "0x72630a380871aa5ec67bd06bd672fb0128b95499582be5d34a4073645d15eb6f", + "0x9ee6618d35b3fffd4abeee984f1e9f3fbd200e5f60c562cb0ae3200b8963f522", + "0xbb40172754ef37505f4ce8077382eed0c45b0f96c882ac26b7d209b951d7cfd1", + "0x76e973e45252e97e2cb31bb8b79424e5391c3e76893cc7be0c1c1101bbafb57b", + "0xa4218614e301d35b94bc536160007b9b88acb5c9987a44a27c514f6456b28be6", + "0x0227fa09131444917185f2cc802ed389687a4f968f99bb221148ab7effd5fd5e", + "0x0a93fa4f9590996785fd599bf2669b290e8eca7f02ca06aee9582357293a8493", + "0xe1a277823bc99e602027fd18db67550f0d5e60045b94bd2655e49531bb152f0c", + "0xfe8ac01e4e478b4019dad76813449f8155de23b4ba2a6e2091f4c8ba82508bba", + "0xb194b4f530b832a2ecdc88c1bf40580474847b91c300751c810bc5cc408095fc", + "0xf1de598992e61dcc7bc9e1f1490d80d10024c6319954aadae6a4df4ac54ea564", + "0x38138e224065ad8ed4af813bcbb35535bea444f99613d686f0ef4ff00c5a3fe8", + "0x13e6a7016f28c856d777e1a7f54bce788a3e21b129cc1b57d8e5ec21e6522d3c", + "0x1c5d57d845f18557e61b1b3761d9452eb26aed8041a4a3073097259546e2045b", + "0x536848934654d65ec83f7cf9a0f69adec6ae974b8e5944127ca819a30a20b012", + "0x1653d5a4610454d67236e8049dcee0b1a531e25d5c7f0bbce913a6a524a60db6", + "0x7bb7bd63c5985b492c4897d59223335537ed0f8928c5c7383b5ca7a6fa3c3cb2", + "0xe4b8e08d3444b8e14e390e219684a6085fa335d11c1c77c530582e2c3c4c8e55", + "0x5fb6b09c1ac68c1ad0fd2041c27f1fad5a83906d4aea5af0f965cf36bc3cca3b", + "0x40034a02507258439d490a5a282956f9ae304b4ea4730ad6386005c767eab5cf", + "0xec6ae08d9c0033901514ef409a7cf68e1a682a202dc97c5c467259c7b6022e2b", + "0x9082855abacd99a2b634ad1f50d8517b0f1b091cf5c649ba377aa3ad2eccb65e", + "0xf76c0b9744305baeee70b1e274f7eaaf3670b2217fff6655bf69968b5acac517", + "0x917198a97cb8f704471f6500aef3e6f014b09e8da719ee03e87f45c95605f2ae", + "0xfe1a48d29d6ddaec284dc0bca96cc874ecefbbb91b74c8ea6030a9bf80470c73", + "0x9ba5c60cee1a7d901f9832e3024ceb9db24460c6636b98df81d008d1678073c7", + "0x7cba18b1ee4fb25f1536708ad3f4c95c43d60930f67dc2cfaaffaee2f91fe1d8", + "0xbd2b278edd0e75c6a39aa2f43b334d8cbb52900c152b2b8e3ccf7f27221c0643", + "0x65c3a4efdb5a189b46db8b8ab60968f6c16c1b56f9f2311b3380c275b7914383", + "0x45de07d3860d9be6f7b90dfa928cdf0da9592c2054b00b774ba7608f3d99324f", + "0x91a4389a9bd65f3dbaf092a5a49f0dc2333bc5ec7b59c3a48cffe97ba52213c0", + "0xff9342e526815c132251c3202d20acaf0012be44ac7c47f7640f27fb6f2d249a", + "0x48854fe3580cd19aee63f0eda576f1af518f3ebfa9f87d24da87a89ba227acad", + "0x8d292c2072d5ef4f3ab12cefaa60e9b54433a0eb7303ee253408c19394345a4f", + "0x48007c06be01f79cda41ea5791e3ef4bb4e946d7af262b52cc74eb3e20e98a1a", + "0x36a39e5a3035ed57c8227571b2d57317ace61cb9c66dddde57a566d34eb7d894", + "0xca4446f6cfc51f82ded4f4c798da29fde3a3bfa1f30de6cd721ab459e570dcb2", + "0x82812417102865e04fcad17c1682c7608cfcb855267b4ecb8c1e0666537e6a9f", + "0x81ef7d9794f8bec6b04ab899cdfbf3ff735eaad06610258ef7f90c77c83d5387", + "0x4810726311224ee42f1969465daac6f12516fcbbfb26e9febf221fd8d1cfb41d", + "0xb39a309cdf26f5f2011a83a0c1840b61cc5bebfda385a479a6a20d872bd082bc", + "0xe5002eba07d8b69ba9470514d286ab800d28b443531349d641d9df57c3cc1399", + "0x662dc062bcbcf4f45759c85e8a0ff833564beea1ff3894d7c5286133b3615a9a", + "0xb2cca2f7a62870673c70313efe23bfdb57ff9e6bfbb9e73948288fa15a8a2f49", + "0xd9e38758784261f67700452e23a59ab25cf22dcead205a50685d5cb03442c81b", + "0x039acba436cc8d99337c16969a076577a50d609cb2986f42702199e3c2dfd8e1", + "0x7141bec6010aa3d5ad1d543f91a8b10ba3bdab7625fec8a7d404238c09893e48", + "0xe0a2f776956dd92600ed94088b7da0aa416ee83cef35d37063d3df2d3442173c", + "0x7e099f882fa8909a3f67cd5950346a00a20bd0678e7ccfaa03395bbe1a7bdb6b", + "0xb52e8fb670f5386581c89d4b01b0bec691b9e828c9fd8916708287b6c1d49f26", + "0x16b599c31ea0a2c2c23e2845cea74c73fc892f16a2b34091ad9ffc5d03e7f609", + "0x4c04bcbce2e30cb9fa64e6c776c8be2a4cea04512c9d70e2a5d8a377aa77ba76", + "0xad1f20b7e161337e3d7aba00d9dc3585569cd8ca932329b3df13fe5f23574f70", + "0x2961a4a19bee2dee47d9eef2f875e03fb75bbfc30473604c902e76c76620507d", + "0x666c0d915622aba83912b23cf5e48ac57219a8e592f09f9e224af94ed35cac7a", + "0xfa6e99ccb3460635ebbb7ba53b332825f9d5185dd10bc1e2eff5fb6de4fba746", + "0xd3bc3b194941ea52e2b31ac5ea1c789233dea804e24c15000332d41f8bb4a8c6", + "0x07281b9f1ab9e962d46f05c76f29b4f4ff3db35baa777c37c5dac6cd33d49a90", + "0x5bf61ee56f75630605881d34c11fc029f7c2eb96dae86c7dde18af8e34aa6c77", + "0x972d651e4903b97eabbe5a58440bd248eb2ab16a536da686a707770b88612d00", + "0xc953d9cf8cd4a68d7a2d9dfdc3bdad8bd0d511f63cbb2144af7227ba49084a71", + "0x9a90ca2c4dad5386cd71110de906f6d96f80934661afba440ce194e44e5a6036", + "0x8dd2c27d9b327b1a6e2216f561c09c276c9db44c3a87e6f8fe381d7a906c9769", + "0x17362077544107f34233c1fad77f12c9140d0f0f0a5206dd887bb9cf627a20dd", + "0x52afd7ffe299cbfe5f418612ecf625ab1c6debcfebc6bad2569c3b83aa1f9f55", + "0x6597cfda3deb8371e447690b5f90df042b72095551d347eb77b2ee55868634bd", + "0x97a7278a76d38714f16a5b3bae0910b18d2851b2519ef5dff0a791f471cff90e", + "0x0f4124bc20c9553612a8e78b90c80c1341a3a290054c75326753be6a103dae22", + "0xa42039e0a42da736e91ffbea82e58beaef7fa7d88263764611b73ed4775e222f", + "0x13f6c5b099ba6a2ed4701a8b3edd76c2645b68d9c2cf9af924da39bbaa2c18c1", + "0x939ddea54fc48f8c8dcc1ca6c04ff2cd70fd8da9e93abd3ed062da56b75a1110", + "0x3e66eecafa70c79675f26d259fa6718c646ce3828e80652134b792f0366f0c68", + "0xcf507596184c9c4a14286412216f771f0495ea5780bc372d12ba6e8445c67d69", + "0xee64dc03e5fa815ea5e9e3e4d2c87126c8e4c0ff56f1152c349e3f9327fbd5f7", + "0x3b6ba90d23473ab15afa76d95b23b2a86309b0d6e2edd3492c374020e544c820", + "0x51ffa382078573a9bb41ad67b775074ae41f9968e2b38341ae9a64a9f1f74815", + "0x6c3a7ec03f93b7d4b73d8b194ab38a23b512a236731b5e54b8b5bcf44aa05608", + "0x0082c925bab49c6ab52f9b996986123039fec2cd6641dcae3e3ea7d60bd7a2e6", + "0x85185f7d346260f24bad3c767a04bfdfb3356f61138b9fbafd7af0f813e1ddc1", + "0xeb5a6ef56f2926a533d3858eee37cbfb5b37e8fb5bd181cf61448e36d8b48dce", + "0x700da1f1e9339d6d55c54c62cc5523c30901162216c2f182f5f2ea66dcaf9620", + "0x84161dc26196b99ceeea8d64f6ef3d127982b934f49678f6a512c07534e8ab54", + "0xca3f434ced785e9b5922b625e1d2457b156372e4917b9d6c8f4f6a995182a176", + "0xaf62ff81c29e9102077eae515015286765592d454c8e15b0a302adefe22e998b", + "0xafa0ed60bf7417e6f74fa7a9c10ab7c7b0b1e94b699569b0e3f70ab01b234ebe", + "0xd2cdc3211869e030c3e291f4fe2f163ef54b24d7ff0bb4489d73a5159ceb461c", + "0xd74c2a92d3c506bcbc11c1bec086cc419fec1d0bca34d50b74b28f89e86cf864", + "0xcc25ec627504ed9f00af661c72990a36a2f9ee4c4507e5fa4def89303456d7eb", + "0x8edd1c1dcd064b7c693c978152209761cd6c92e449e9444e9dee807fd9f9f420", + "0x660e691453e374d0a584b184a5fdb85894290e1ccc68964a8292db53ca096505", + "0x9cc340e9d997cc319fdf2e00c75d80b80953a90049af766b1a499846c5e08bc4", + "0x58e650852eda00e55bc2d9e024a49b3b7a5d6d5092d837407114120ff143b75f", + "0x5426eb6b6b8965e80dab787befc815c6c430e80231e91fee5511062bb21c3e4f", + "0x4bb9b4512664884f7b63bf27ecc75e0a69e32cf2b980a8b9135e410871ce45ae", + "0x22438f10926c874196f8c65e274d018960cedb55ca43787e18adcb54631df7ce", + "0x68aca6a2e6a51c8543939fd10be02784b1149923652da3f07f91999b75be995a", + "0x12a77edd8cc051f6f991cd3912f5f4afa1e797f5daf010ab17b3925220b12e88", + "0x0d3b929dc2733de2865dab86cf42684e8430c2ed47d19606637f932caf8d2d13", + "0x69f8d5c233a251c35851354b8546d89c7c54012736440c8965c256cc9db7dce7", + "0x6757e97aa449d7878cbbddeec490fd0636b2c51d5b00bb61eb4836685d005d2e", + "0xe1029b22f6ded11ab5ce46aa2594ca90006a04e8848f4152fc40c27735217ac3", + "0xadc4af259ba86cfc93384f3c0eea61a4b661f015209064254bc6ecbcfdb74f5e", + "0x02ff4bd0ca8008db90a121deab0c36e45bfc7acdaccaeae04acf3aaf51716607", + "0x9df6ebb38ba3e1d0a3a82f871bacaf81152bce32265c0eaebd9d9e6026665b43", + "0xc25503a6058ef394c48d1153ee2e70a3d8e86e0a46b29ddd0217906d694a71d8", + "0x83698b68d762e75476caa87411797ebc0050f9296ec35664bcfd3aeffd01d8c6", + "0xb185832a5b8fb209b9a6772673cebb3dcdf3d915886282d6adc47376a48fb578", + "0x32ec2d0710f9681d75819f1e2c28e135b3272dbf1da08e4d64ab2e6ae1064cbc", + "0x13c8aa9abf04b6ec2553b171b58356a1c256563406ced1ff3c84a3ffdfb5c1d9", + "0x80aaed5609e1b594b3c54403ce9977dc558ad292ec472ac73c8d7f39243e116b", + "0x8cbee772d46586087fbbc9b4fe2f54ce2405d2483572bda3c2314e79ca0d8deb", + "0xfbfe6a938e7bb9b05d889f8182e8963344df0ac7b9022302b451b036da261f9b", + "0x39131379b64eb550fa0a2574d504bf7de0219d50e6d55cc82998ac8d2684df84", + "0x5fefe2fe1d509eae61cab218f1bd03196b1e631f5c416e5f2c0e9e54a3d44d98", + "0x5839c1c6580a4c04aa09dfde45ce4616b6f30d1ee794dd12fc745b96b2d48c84", + "0xa75d2328c4e63acdda579000e6df9be72d9348c2001e1927264b1a8c303fd292", + "0x7331a0cbfdfdc200cbbd1723bcad1f1ca6e0591c1ee025bf1842d91e4625c8c8", + "0xe9153c020aedc51102bb9b22a2493db4616364fce9b61681287dabeee881130a", + "0x53b7aad781bea92a14b670dfbf5acd8a55d2721a6146f099b904bbc176771b91", + "0x0de55190007ddb76fcb57cebee9b1ec60d52d150ac83beb66b088a86a234f9d9", + "0xc703435d06a2e1c5e52789daa3587b920cc2aeed658907bb7d6442693c65902d", + "0x6d21f9a28fd36d865af468e2c06ef5f41167f3014251a53aa1d2ea55896ca1e5", + "0x6b24cd5b8a48fd9dbe7e8ea6c492b57f3146009daaa108ae5d1199261cfc3914", + "0x40e49643d669f497785df1e601cb1bedc24ca348f86354d4032b1d4a4c6776b1", + "0xc56f0ff0aa22fa1e19d8785aac33805f7a7a01b48e953ebb126a4728cf502518", + "0xdce90cab31ee9f5a345d03464c69cc5dba71ee601bc22ccc8aae1eb442f3b29d", + "0xa551b514490e45b6669024b539f7bb37e6883ec97ff79744cf1f1c2ba1d21ec7", + "0xbadc6d33cd58aaeabb8b62396e102cdcb6b1ce9dbbf7051f937a890a3f69c2c6", + "0xe544b08143014287bb8d917f66e8f22f2a6deaf6ad4a3996426e2186b8bb56e0", + "0x6ed9b64beac26a5fbbd15c09c7eff96652b710670c2ce52a6856cd998521a27c", + "0x48c14f31b1fcbe0deb7816771f962cacbb7c2c219518f3ce52661a89e9928228", + "0x425fc1308118e8ade59df07136948a210786f8b2b6b0e51ea01ab06653822693", + "0xee9b2ef0dc1dd873a3ccdd77046969a4ae938e5ff39695b891c85921883c3277", + "0x25066a1abffdd64dab20529436c3d9a44e6e837d70b19847e355f63b5140c5c1", + "0x7441baf6efba832751b31b93c9b000d8bf552d0328415937d0a3c78595961ee0", + "0xd9219e7f07c0808d2596cb57e26793c1162ea9efe58305e3a26da6fdd57091cf", + "0x1b42d745a54c5e3c48a4911a27c263bbe42c8f038c826975749c1619c2e21cc9", + "0xc5abf3dcbcee854b06836237de3a461d86a8b76e8081926ca3078531e25556f4", + "0x7eafa90a352f95c8eaa914cfba0aa90db5ab1275d966da5fa445d9dd6ac6e0e3", + "0x4230ac1a58e4d9903022416041d5119991f911b41702d43c1caf0723cccb1d05", + "0xd50f2cae10a5cb3084c9f5ed1f9acfce8fdf3d920d89ef41165aa2522b97582a", + "0x6eabcebb9040f7d6791a0a560b987288d8246db9140b5f188c34a6be7fa17552", + "0xbbcb3c36f228d2589cd7097111ecd708e419bbe034ee6d9aa691d483590750d3", + "0x72eded80c21baaefddc61ecb70ab76cfc68ec8509b4f8786fcf25d037d75385f", + "0x2a01f9310e3116bf3527cf90de19bdc78d9cc677ef5c9bba94f3ec321d700a7f", + "0xfa401d300fed7092c91232a2bd8b0173ddb62b12e8e96a5076172abcd44ef858", + "0x984001b77e32ee2ac8d5678f77e6c425e6ab9fb2ea3f4978b6594b4499f893aa", + "0xfce80ebf8039984ced85b45b5ee5c240df0a6aab809d6bc0974a5b1007c77d4f", + "0x0a964a69795de761278c68843100ee547edea07d790d2efe64d975b65d415159", + "0x5ab1dee36283fc991e00fb52079c232f2d9bfa97377addd05c50fb06a09c11ab", + "0x47676449956192bbed4235f3162d06ba3095aecb9f57d9c8a273052278582fc2", + "0x4e43d79f07711fd4d4a8dfc576f08d954b5d6829dbbb59ae4386b34221472966", + "0x8f5cce2a573190694302db226a2b22a89f4487a4f509ec1a759646d0d5face7b", + "0xe10a0419bb270359d2c190014afc1fe52f8df9454f7a8e0fe205309e5a3b33e7", + "0x4626c976a572110230c540dcedce33a5bbb97919867aaf0520128ceec2e9d8f3", + "0x057b497c49e4b2ba614280de64dd91118172ae4b4646c3031a93fce200c8a234", + "0x8350ba4e211602c38812276000b1caec40dc4376176afcac43eaa96d7af30d1f", + "0x9e93fd7b9b9ca98f26945dd5716ee2a6274f8586d14f05854a0f7f25c80541ce", + "0x9f11403407548c359164f3f93265f12ee390ff3b3631ec7b90b98922dfda2343", + "0x714cca7ddeaeaf302fc0ebf50fd072c89f063061ea329e67c809d62ea9f5fed2", + "0x9c088fa9b25f7a5ca635db39b3c95da6859a5941eb1ae3e4f4717013fe740cba", + "0x634542af50119e4adb4d72bec5d0e3b095df21e76865f683346e1bd544922f69", + "0x2a1fdccea29581063da7db3f2aeca7087ec646b11f1d47e6d48d1dea0122fdb6", + "0x156e283ab987a5da12710b459097b5fe3d79db296551fa289632c0d3f9b33ba8", + "0x3eaa070ffd835043d4b2b25d5e7280f030c615b2bbdcaf3ee12a2b2b4c620747", + "0x863d5bddbffaa9f0ef9f696ac5a7f91191b5cb52383e1d0c0e0d5a60332c8728", + "0x4e29095ca17d15099abb1c6c1eb43cdd6dfed160a7d11731f4d1115beaacc7b1", + "0xa46f6ce03354ca96ddfbfa9e1406dc7ab99b0b4ff1ca5e0346f3ce91338bafa7", + "0x9f19f494df488b250ba31e243c9098fbb7db5801a3f76b219d866bec32d009d5", + "0x763dfe2f87eb816d1bad1ba95448619041cdb3cfb1171063c043d1e02d9f6ca6", + "0xf8ed4dc0fc0c03b964eede54ede5e96a940cc85e1ef2191c11465f2f1e3f6f0d", + "0x04f0d8ff18d26b490f137f23144c1ca0e475e74a7f1599fd2f6a4972a3d1c215", + "0x012ead673926ef6b3d2cbc5332a7bbe5dac977ada6065313e90975360dfaff3e", + "0x773ccf0a297a22c43b29f1bad214ac9e3685a5d0bf1df7d49fd4b92065ee7b04", + "0x10b7f56b8cc84f4be7533ec00ae46c7ba852f8d093c889b7edd46d36c819abae", + "0xd70605a437bfc6a4cc3468f0eb6d59b293d4ebbcd7979eda36f02baa48e68d25", + "0x68a93b7685277a1ca51a341517d10ec1f03c3018dc4d99da00624d4eeb3db229", + "0xef8aef04d3b7771e8519952b4e067503abe6b2698411299edbe7dc22a79c39b7", + "0x8e72feb3f31eb9f13645a089efd4eaf6871bec26a9ee91452db0464a7e6bc5e6", + "0x3189fb0be615c0f2e2758400050e2657e3197546a15039e595b091cefc9e0d7b", + "0xfe444b821fdfb12248cbf371192783e4e0ea0a938f5ac7b205e15cac991b6c98", + "0x0329c441b6c6c56d76de552ad43596760d37262011d97bd91e595dd559e53de2", + "0xbecff3658ca19ed610e826a68621e7b5cf2ece293ff13fe3f0c57c3390954af8", + "0x695b87703e7299f3e862740bbf47ebf026e5330171509fa0927c361935ff612b", + "0xf90373fabdb83b403f67cc50d79aa37fc26d73ce8fda798e96c4a4b17440e2cc", + "0x536eee69a1cf54af816f4eb5d08ccaacfbbaaa165451d0a5e8b93b2e872c59ec", + "0x17b56635255ddc2278cbb7e7139cf7a8f6e2e55581c451cf53b5b53aa89f985b", + "0xb4a14da295a0cc51076c48032fc1cdbaefff2380a428eb03f6b068aee99a8fcf", + "0xd3cb3797197a398711299f816f34b7c98aafc8a845298287b4522cb0fd645b01", + "0x55aea7b1fd7bf0864b577e38a89c153ae8653da26c72f53a05d164b9da327a67", + "0xd4eb63ebc06549dd7419012d4bae13890716430efb843175a9270a6c517ea612", + "0x6958093bd81e477479a53443b0c95c11d8791b282d028bd9a6204af0c1f738f4", + "0x505f55a445b93a2ba8d5ac5531370e2bf760db44509f15d2f243175b12a7016c", + "0x4608a060b7bf832310eb73a157d285ad824b07d78bb471ea89ebf421d735d566", + "0x68c88d220d8ac23e19459d650594dde939aedcd75325ca2314b7a9419b938c37", + "0x891a1154ddc1e3239b1100840e1303e0627a53ad501996e56891839b54becc93", + "0x8b943abf7a572dd64da3c4e58c1f34f6f7a905fe7ce652a044ab8983ac45fced", + "0x06b07efee0be55002f485ec0526336fec4a7f825ff7eda3f954e8cc7068207f8", + "0xcafe52ca4b5198fb4e4e24f4c04ad12eb8c9f3ebf9a35ebc0014e25dd7bf5970", + "0xe0ed792746b780ba8e19ebedfd3922ca937fd5b8c28b03e0fb91789cedc0fafa", + "0xfd7ea98fb764223ca3c587820eda0a0d68301979313ea9cf0113508a05fba7d6", + "0xa874e6edabaf6da36996b6387bda14d12c3eafa026b1ca6ad5f1f4cae67855ac", + "0x29d7c85005517eaf1165be4921deea5afdae1f66b670d7de0981c4e502acbf1d", + "0x949318f8059937f207ea564672c86943c2c9bb86ca81a3b0a9523e7bee00a5b5", + "0x200dc199c37d16b25e207165c5576596266ce8b62aa8a9c6cd66d69d52c1a67d", + "0xd29108a106a8a5a87b5282467a0e8d37f74c2ae53e6dc11ad63005f3f3f878c4", + "0x44ebfaad5b4ce81fda3d4194c87b46e9e31fbdbf0ad28fe00cffa73f78d3957b", + "0x6843e2f6d3d56b55251ef7ceeb635226940dfdd698215f5d5a4c3e88ede5c0a4", + "0xb84d57422889adc19626aad033b38b6968aafbf4c6d0881a0ef5fb5932c6ab44", + "0x842626b82b93a54a3a1765ef6257a0c74e1ad2981d8da41fd8305adbac99bc76", + "0xeb347385fa0bb37b8d5d17ab60e6c2ed4bfd19210503d61beb88b71d8bf9adda", + "0x509a54bd689b7011504e835081bb9d3cbddd8592ad80da399689bc9172b48a27", + "0xafc5c51176c7222097b12310a3ee5513a7660491682ff1fcae5d168d2c19c3aa", + "0x406e9fa3f6687fa6519067e213377a5ff7875f6f0a3080880536ed395555ad30", + "0x2624c181d4ee1775bf687b522a36a7b9bb754ff6e40ef12363c7d675b60f3d04", + "0xd5c32eb980158772133a99d0af96e056726ed89be84289cb5fc1d083d48cc407", + "0x7b1c5cfee09aba12ae0742d9bc1cc2630bf8c1e141033b18724a524c2c1b7c2c", + "0x77b4b55b236cb7d27c77063a280eabbeba0d7171759fbf851f40b6ddbf7171df", + "0xa04791b79cad41718cd8a0bf604b0e956aa85230381070f842667d88760c0de7", + "0xb1558e574944d9e8910da9c34ed51d89caabbf6541f077a55ef2ae3c513a1e02", + "0x3ef8620edf05514c4e90c1eeb0a896ef30573f963a7507ee90eb76e4334412b3", + "0xfff99365402379af3e56fc9b999d316cea7a1f388623433cbcfef0ddcb6f9d4a", + "0x99fca466439472d08ea602bafc67d1d097e486b5e41b5a059818021f612e889e", + "0x094436d10026f1c57f04846690a0444646b762eef1fc0420c6e3f5cf5b845e14", + "0xc57923978a9dffe0812618f2f6420f30ee927658f9f1615ef7cad4519b90eda1", + "0x3a20d5e138cac29e3fa031847086bc62e5f90a5e363a70fd52e2602545faf9ec", + "0xf3b0bd1d597eb2b6ad98fbdcec7dec2639b92bc83c33db4fced5d23e6ddb64a2", + "0x0d5bbdf1dc7d52fddbb3e81e2d757b848f9e79b6847ee8d30352d4b01ba927f2", + "0xf8f51ff9cfdf6b2ad5609a68433c012c92cabeb3053335d784b1baac087516b8", + "0x5777236f251506c22a92f371e4ad3c78bedae22c4527ed5e796727512bc2b8e6", + "0x228bea6da7246c2dc862d9de97bbf824df6396cec583a4db71667306c5f6a02b", + "0x67ccfda86cfccbb139d77d8d2acf0d4bd980b507acd9bfdda6b5af6e10493df7", + "0xfd8f9ab200dd111c04803f62145fd82e6a79221776904be20a90c1c6328cfdaf", + "0xcd8ce973cbfa8a91a55ec09ac9acad4cfdd050b598349b996d252ecb3935d277", + "0xfe8067acaad74db589275d3122d84f04f717cfda870d444872824300ea10f969", + "0x4112ee457d4108c37121ef4ff0ceb1a4c7db3a9e3776d647225bf0838153356a", + "0xadb045193cb85002f2868c1ffd672bb93e60ed2841ad368bc8399e92c996229e", + "0x4243b3645b99ab1468bc421309220529d8ab204542c6901ce618ceb32b93becc", + "0x434e3c4da46b052402d465220e27d0e243bb5b116967d4baffc9325e326c9900", + "0xceeadbd91caca5832cace1624baa5f67b0d18f725627702cbd7e19ae3c691712", + "0xac54af2cdd95c862b3d9115c9550231f75ca8d6f6e607038850892daf1dd6643", + "0xc4ff21314ba2cac393c67982362a39b7ec96192fe37c316bdd4cbc692f729ffd", + "0xc84746b891e6dd8aac32b2ed0b373172df4ef375afe7e4ab826532b6b3fa9680", + "0x0b0e01ec97c12e488829d13dc1fd420c08475dc95d1fcd72c066d76220af055f", + "0xf0b54fcb4a3e075f391bfe937dd6b4f7481877182ddd4413e8b70efc63aa7f40", + "0x1a78c5cca33184c9e404a05f61cc56968b924d9d34b7ca6d573563eb250fc691", + "0x37ca206f795c02f45abc34380d67b15aa48122444fc444d4b307ab2f7f30a9e1", + "0xe03c444efd29f8d7c89b480ffbcb996a642ac6205ae43bdbb815ba1968051e36", + "0x2fcaf6ef7c22cebd36ccfdb037e66d9113d0965f3b5b89d597d91b490019471f", + "0x11a06d63b3395d09a048aee4d4291c0a6ab2d5f07a7667362890ce647153c2d2", + "0xc33a74c178ef5460b53a9a81aee02d3b42612acea7adb853ef74cd6b65f36efe", + "0xcce38b309fd919a930d38c7c7a7bc828e5039c22a7f3f858fd99c5d44b8cdb2d", + "0xc470e1078c305a5eaf7311d7ff652e24c9dbed83c3572a1c2ec7f6fce5788b0b", + "0xa29b6d0bf49a64182aebecc190a9a0b06931096d9984e7e6da9800ce17f7cea9", + "0xab0821217488504e1c255343939d109353c79298b04c69ff65152dd0e934022f", + "0x40c7bf4dd5a2d39c0dff9fb3bec5c8247093cc1bd55a8087d83f5fa7c8a35b31", + "0x3387ef8b199a2656c39407d503b9bd1571714e178d1dc7b1a74bc43cf88ca201", + "0xa5b2b8b2d708d97666281684641b611efc792f7c0cb27e053eb06752661b35f3", + "0xb604a4b7c3661098d4644239295cb9f6e456854651a5b289a2f4b65e33964232", + "0x4bf93500c257f054e6a6f993f344917215c9c943589644474f5cf98950b8fa46", + "0xa9ae0b7679a65498eeb2b460fe678c3452043bafc344eeb393ff1d930dd8751c", + "0xf21e50f55d7be256d14dba4f8909879cdaa3926b03da9ffa0c63ec3c9df34c48", + "0x88e1e824c968441ebf88b31f7a24fa5cd4e8985ec82fce5eeb13b3a30845e146", + "0x85d5206b3136bee840dbbf8d3d2302694dca2d5397aadcc34e1c1d6accac0354", + "0x00f68e845a2331a0704037d75361831d5a0079af3c6186ecaf256bf1da923c27", + "0x64c594c02b35bd5f69beb236ccc08140838c30b67a1576d2780123e29e073849", + "0x93f6540af637f1a630a8aaeaa86d046e09348320ca5103ebe2222f747a5acfc6", + "0xf9b4b9461b765b449191c7ee1acaad88d4dd7260e2b826c75d506a908fe71e6b", + "0x86aff1c986fbad8da2ca9de6315222459e9c47c58fd7f1a543e6719c566af5e3", + "0x68629388371ceb2a08bf7e335cde88a1bad7127990b44135058d62dfac258107", + "0x9b81d6745d5ab0a3459d26b97ab8f19fb38bd38c758a0ef106a025d091f6f9ba", + "0x2b42455bb30c387315cdf205a8a178ae4bd2d2e221fbfe4be55f5b364fe9a7bb", + "0x555e4dafa7d5d3f209d70a5c954da144ef231638f4a63715152bbfa4fbf82b4c", + "0x5d779a8f08d68794723fb5e95bafd7004685ec21d2cbae0e5ea728b36418dc36", + "0x7e5163ea9b1c0494aa997997422b02404a13b690257757f87f69bb42f81ba28e", + "0x3814efbbbfd4001641da7d5c93483f96467d55aa8b5b2aa6f980bb12a0dab6cc", + "0x431b7452a8157e3a6cf89a5a85d22127a1282877750519a8cf95e172c654c3cc", + "0x77ad2749e61c96fa868c7764ea626baef8a1bba56d3a3106e981869f9736ca76", + "0x7c069d14a86017ac36cb9007fc9bfe75ca92cd2522dcfd7bbf9d85c5133ed8c4", + "0x21dd48139667872fa67c98430f68e8d38c2948f19fff534ab2a5b8e0b92a4d51", + "0xcbc2dad5151367e6533963061712ee325f08e7df3cc7fa73eb5220cb32a2ec4b", + "0x398fa6f8d2b76d482a0c312bbf48ba8dbe9fb8ae06245da60ac68ce50f42638c", + "0x4ca92096314fe1d2d8e07aae3df39a6237e718c1396e88f3c0b73fb3124c89b6", + "0x3ae030ef952e2da7b29aacb08fc41776a44fa5a6c42e745d8b7991ff82566730", + "0xb4ef4b02dc130cea24a71a6053639238db2db30d4752dd3fcab1d98442fc3f94", + "0xa6256dc24acc6de428f47aab0b65a1f36855c7f0834a3e730d10a3c0c8d2bc49", + "0x9d8c8bfedbcf9552ba9eaa08a61846c52e240ceff531e7b19415ca148781ebcf", + "0xc6737357b53db7d2a14d7e7d4130fe6a516fce1dd0c7716be6137d93e21ceae3", + "0xafa9d3182fe6246f6c8d7b96852bc5dc200e8c3a97ce7d262a18c2fdaf5bf2b7", + "0x8064a1ee1eb4ddbf301fc983a03fa2983bc3743602bbb96d7fa6ef85780ba79b", + "0xc4616fb2fd5381efb37719cd9998c5051966b254abbdbe12228b2210c6f79116", + "0x05c30fff77a3d751853e3ae4c11678755c0afea16480a94bd99d61ac894300e6", + "0x47757d0104771c7e288f383bbbab1eeca2fc752d11989674305898e047a71bae", + "0xcc0f857a7617c16da7d35363cfc0af0ecccd9b1870ffdf1a2b2e2224ef81f876", + "0xab3a1b65f93df60eaff5df9e0bc1d91152d34d3428961c207f36ac3a94f61257", + "0xd0cd178507f1c3bdcfb7b528933f2d6227933bee2614636f3add19a66cc089e0", + "0x6379b65e140eed64020f496a95c36b3c27ea10387f78e0faccc5b4018f8f73fe", + "0x3b6977a571ac8d59bde2e851fec4384fea35a8d3905735fc8b8f2a8cfa6adcbe", + "0x2f193712529ecc908ee0a61172ec7839a9168cb424d8f108e7d7cc356bf20cf6", + "0xfa3e48832d13748aba9128bf6bfc76652cac371e49945fc33c941a9b294f7033", + "0x7086c7711a91271d7e38998715b4a142d7ec107accecf29f4518efe9f3333c4e", + "0x05c126586f4a2c1dc5814d07f158513d42282726918f71bcd1b4e0b67ee944b6", + "0xb7cc1efbf6880a60abe6b20f80bfe2ff3aa59de805ad964f8a7c5ed3bcefdcc9", + "0x64189964cba347ac35018ed9169ae64b78c3d0430145017cce83d78667b648d6", + "0xf6b1d09181b9fd18a0efa47c15631a6aa0eb01613a5fd1068834c4079e1a95e3", + "0xe760b5c16aaf587bee263f348f9adff4e04628b94ef27c828cc7155ebd3ac902", + "0x523a2c0fae8b2408ffe1c3b43e0aa7991b82336ed136e84c3f7d458d31143fe3", + "0xcc6d742b22b4fe3f41cf783a2f6f8dfc97a4b33866cd4bdfb27b05bc2ed39162", + "0x4d4ae86d282ec414a574370458c99e189062a3a48dc59a8e8e2a44790ce9b841", + "0x6fcba6a9469de1db92468f2b58b3b82c5080698aca4403ba8ecd1cfebd12b657", + "0xe7b584b0bcca0a5a119c8b2cddcc7a73c94f6f6a58503ddba7b0335815302f11", + "0xb1edda9625ea65b96a4485e10c798c707f6926e4ac2b51340a6f9d212a71a737", + "0xd8e2a94d4c0937a2033dc3b70b50934cb5b2ab54f57336cd6a8882af9f14b8cd", + "0x93ec08aaf09bd453c2b53cc7d9aff059681e0c23044f99569d0ea649cc7b885c", + "0x8ea82c1ca6be16616b62a8dbd88c75217470092063e0494419a6a926279230c1", + "0x175d030004e718f39b3986daa3beaf2e1a523583e529d6e90d117cbc844c647c", + "0x34cfcabda8b4f51cce74befb08f6a2e9ce884175f33fab59f26c60085ea73a92", + "0xd0570fbc17dc030bf6e7e3619d56ad2e866868939e4e5b23258adb191997b4f1", + "0x83245688ccb6e6f1b541930a3134d3141ef01a5f9b3f55f0321039b9d4a3cc1a", + "0xd782158768560d84ebc21d8e4f270f30055203b2d83c46ccf53ff8890e833fad", + "0xdaf31d5afb20a502b28329ecf1aadfdd16b4fd9118b10f9bebfe6f986a902dc1", + "0x0e24b26cdfc345d98a6d6dc3f4e3aa2629aab6fb2ca3820a78d58b10b09deb72", + "0x895f7a9b16ef1d1933c009b38a35a41632d00735a906b035f7fbdcaff1665295", + "0x70ee8681968778cb7da20dd794b75f08eda6b4b6e4aa653464436ff3685c6186", + "0x569f51cf2b92bde98085c2c167b773fbb9917a35844059696a1a97e378b5b577", + "0x4ee20277fbe5d2e616dc0b170e40d5b62cd8dd9f058c648e8e0d636316be7e00", + "0x1224d7eb3ae847458af472b19d3b0ddb90ce822f3389619487e68f3ce08cf6d7", + "0x57fb6d2ad5a75648449c99a46d92570b1dd74757dc1c0c11fe4923748eeb1711", + "0xa4ebbd26ed7dce135ce61bea0da82b8262d4a5319a7ab9c94527a7c670752b67", + "0x1533f0c29bd8a7b8d90c4c0755fc0b018439291566dc33bc816c8ca21269c63c", + "0x9cb5a5d41061a2168c0a8175d2712cd82d27cc777a015158c2fab0751e192d25", + "0x479f0a41aa04509beacb2eace213d9375393f583d384dd4e69b5b921c681c845", + "0x5791638640c821778349fc3064f6c5215f973f2b4f098ab38fc2138f6a8700b4", + "0xaeb1dc9ba82aa0c9ef266d1beaeeb5c756fb497607ee680c0a161b89cec21d26", + "0xb13f56956bc48a6b0760639488463cf403ed47f6d94c7b6e5a6de1d3d35800c8", + "0xfeccfb58d300594be16cbc9b5502ce851de36e15d62164317ef6e3dd9d72015f", + "0x3b218812b3219e243f99c6d23f24ba2b70e91b6a1e9bd27a5d3c83622c176b2e", + "0xfc8f86579345c5fba8e86d1263b3e9d01dafacd0c7347fff348c9a661925180d", + "0x50c6d100a8c0977d24c78bb58021df17c880a36f1ed118a0806d1aab347e3b42", + "0xd18166f82e90410a556744042badaebf3282c65d3c1fd81cf7e599695436b2d6", + "0x8f47f418fa13eee50b9a97781a02cc6a8b6818389f1b1f9b94aac17897ef1bb4", + "0xa4b3f32d84a547f66ca91ec35deacb2d5cb4da741059c01419b60b8d526d8a15", + "0x3187128246074cff2e8c0928dfc6b29294b0ad3f2ab839e7ba6d0b72f4f078ea", + "0x213988ced1828cfe0021da680b166b7d830b66a795613953589604d09b58bd5e", + "0x343c1581b9d75f1f72a787a29dba31a73384364672f0a06ec6d675bbc5b81beb", + "0x59a9da5a92994baba7e27688505df673c7131f4de43e6d174389124463eaa0b9", + "0x15c6b483253806002ed293f89d86d66314e55fdc32633f3e15dbd73dacdbde1b", + "0x01c22d029f765b941eb772991d3ef50458319d49ecd1e237ae0d61a05b7ff0cc", + "0x62f5ede9e4ac720b4fb34c239953b3289cb77e4e7bfb5268925727f5d21f0c75", + "0xe330297f6aceac790b3f4741efcaa4e58fbe1c61dd52c1d9bf99220803132553", + "0x47073de2812458f45fb789cb1a6d57f9ae772a38deb7dfd4c8c21c383cae3cb4", + "0x9e5dfc6bfe32b5f56c9799aad47fe1a01746fc9edc5d8583dbd1c0a1f7f81246", + "0x1d9a6fd76fc6a6f359fd917582f6a1af617b0b21984fe7038c323802660fe1fd", + "0x6f50b828af00200b81d65e14f07f8c34a5d485056b017146699fb8ac4ebc39ea", + "0xa8b15957d1dea63b64c56d3e40dffcbeacc5c9b8e35d27cd66f61f5c293def93", + "0x0ec32ee93cc52258a0de9eb53f48132b7101abd3de242b9319e791bc4205f57d", + "0x4405dae679f464fda0959884464e47f7d21e21d69288b66c35878560deefd6b6", + "0x1e490b1858da4d82632f376234e04ef4cae529c3307f3dcc5f5b893e38a418b6", + "0x4683e9dde5e2d66da4c288452eb653e2e6ee3a611f36cf2c80e5870c187c28e4", + "0xa657cd63ffa0cc282221e70ee3dc8a7f2e9eed9b8544f25467208b1954bc1f4b", + "0xd8ce555f85b979a26f207bc1e86d1463ab77f8c7e5f5b3c7db6d79785e388662", + "0xf604274a19dbc99c4c079ac4caed9fafd49c123226c3c223a53aff7f7b253b9c", + "0x4edf0d0aa873fedea6dbe3ad1dfa8a2b5e312e2c2b51c464c9af60a5a5c588c3", + "0x5ee990ce5c4e5eda4d80885409624af7b8075bf7349f386a40e03ae64b578707", + "0x3d34e4bb3284428153db9216319a83c3940ee95d0a47d963dd079a46d14ca105", + "0x7503687ea102d05d92bbcd2397eaa1edb42f757a0ceffd3abc871d2d895214db", + "0x7e7201b9fc6176b6ef993dea53732f335efb98abfa3d92462231bb6a5186bf16", + "0x1ab3a0afd0338ee34e047c60cb2c766521b3085658ae2e019c0688c2397bcfc8", + "0x68b5df43d045043400e3583c4ed125ef0df6f1617e30693525f68fede915349b", + "0x201fe9c6fe4cefb948972c644fb9d67634e30529589b4de597f9335bbd6dc8ba", + "0xdc09d73232f082162df780069a77f180bb30d8b736457b0c746c3e0a29d7dbf6", + "0x7c33f90910049812c0a87aa8321c97320ca8953f654f8ff7b6e3982b13e2cc32", + "0x5658b211c7a5a9d8d66be179b8d6039c6fcb5b5c9d232d4655e536e21fade31e", + "0xebfa63617d9055c50466157b9d8d0c16ae58f02df12f4e23f4bc09304701391e", + "0xb29f737d036e5d7164786e62b14d1f9c427792fc4faba265efc59360129aeba9", + "0xa1271a340258127b442c103959fd8d5f6369487c16575d90f9f1267fc3f78456", + "0x1d5e62fc56da958eaced4c2e6a58ad4acd3e978eeeb0f417e4a4078c6014a8de", + "0x4357d167c61da7d4d0b3f1646508a859d8270842cbf1f1f9f082d8f713da3904", + "0xd9556c35934ffc3ad2970a448d8caacc43e452b509f2cce4cf755b19d888b674", + "0x248efe4782d57127bdeb94420062b742031a4bd51c41d36375a9671b279b1e09", + "0x94d06fff869c9923ce5f524c3ccff9d9609b0b36562f47c65c7f8568d3f9207f", + "0xdea7e81ac2b15c4b145dfe132a1dd41300fae3a86eee16f936f46df16f33c686", + "0x733fb7f221502d0f10a13a5ab0473d50746afc5ed442dd69b4f9378abd304e87", + "0xc680bee47e540c3d706cf461399fcc1d7a6749b4b9f6808afa099c52d28cc6b1", + "0xadf685a187510063c7cf4b3ef6ae478705af7b4dd6c3c4080239ddcb6b069b3c", + "0x4ec68b78bfaa971ad03296b71dca45e36852f04f0cf6d0e8ea681c4d32ef6d64", + "0x407017242e04da4a1d4b16d59c59526a172e18d1d7abd4a343ac28ac883298b1", + "0xc92af4b5d045a6b02f2df7cf5a23173d969c447d7c006457a5be7f0251446488", + "0xfb8367fe9396d369332684b2fa3fad1603c7b572dbc00377bfcef0021192a52f", + "0x1d73c88199bc153c932ba313175344b436b28e5e0b39c3353d076c7e26fe843d", + "0x253fc1aca7544fb93d493684be03d3667628b5a0f3f516d7981e3a01e6656440", + "0xb8fb006c1de093ae15658b7be4b6625d5c6d14a5c4dd2623ac9a31e2479d32dc", + "0xb46abb8860cdd8ae411231d897af8269057060cb43880e52e63254f698af82e2", + "0xefb736142ceab502aeccd9df17018719d1004b554154edc5ac62ec45830a0d30", + "0xd9ce776c58f4e1eaf1ca20f61232d3063e98fee3ba0b078e5ba34736a16a7e35", + "0xb63a06ab391813bcf830a53febcf9553f292e097f127ab610745742f12ff7a02", + "0x225004609e0edef06ede2d08f490ef3616b1c5976027dd03f329605bfbf8a916", + "0x748f462a0fceb4743d8b03de6ecad430fbf35d957483b04e04609e9527fa37bf", + "0xf13227684614cb92591a4c0381ebb87b0e52bd21cfa265b501e231d8c3a0e504", + "0xdb56e9aa8ede4b7b042f32190ea90757dd9268457d43231d1a384bc6da5d6396", + "0xb4880cd0f5e5ef6e30e5c015fad427e418ae0efc70d084b7b6d342e1cb71ed2b", + "0x8a59bdfc0413acf03c39f473bd09b34223b109556c4e0fe976a30bdb1b944c52", + "0xfc2f062e32c3fce97a5f3922d3bb5c0842ea02a71775d6852e256ed0143ccb51", + "0xdc3ba03348f62599f9928101c65a8f13e2eabc09a377ed461636e48cc9e0a5a7", + "0xc5b2ac69eb80b3f2ee751ad4aa8e2eb2cc939e81586088986cf9d6e420330de4", + "0xd6d389727a18def7ce0bcaf65417e3d7543b1381b1b49c6f128f3e13f7d3eb74", + "0x02f48b5d43397b1f22bc7617ffd4d93254744b7fb872c051ef8a02698ebddc5e", + "0x90f674e478cf1dd60cccaa750363efe18cb4ed54415db0ea917a09d3d78a1778", + "0x98bc38a5b90450f89255564e3fb825c53d5fcb5eb9dfd9c07485ed6c42aa3f87", + "0x5b70c7cd74a8a92567686c5785657688f3f864b10d2ed8d9f21f004af2d0a3c5", + "0xb153280a3c86e119b7a03dfc4c8cedf79bdd41ee6128b3f5fda20cc83daa39a6", + "0xea4c28d38762dafc3c6716a760883e33666560cd05173d3844e7e280a6d8188a", + "0x8b498049e107092deee810a68bf8914e00d6759a7e62c8d6fda1c5b1531ff72d", + "0xcbcba70e0a5bb3ddb84e1b115432f025a71f2824061cceba494cb917c689f452", + "0x5906b23bc6b56c4e91706c5204d8873d17252c0291585fe4cad030ab6171e710", + "0xce634ca362c4acf53cf9fc68f0e7c8b199b7f3a1f5a2f9cc1c58a31f9650bea8", + "0x840f429289a783b9b4f8e0f575d1bbf0d2f4b00e09ca6dc83abd17d9718ad688", + "0xace326fc69d8ff3746bfede0d167206d3df6093315f3e3cfca8d41a857c20b52", + "0x905d81ceddb8f4301e62a871e29f1f08769336d7c0b94821b12668354af31fa9", + "0x8decc0ea30a4102baac7ccb3e50e15d50102f05f4a3102ee01a0a275d2c51ccd", + "0x56b67da5e38cfc995831754a64f0ce636f060d51c11b746aefac13638bafddb4", + "0x6672660064846341aa343879a40c5b29f10ebd8120c59bc76af66bd86b96cdf1", + "0x3600a734f1b1df6fe6dfd1cf49d8072bab86717bc5f2d276668c1a482e62acce", + "0x28e4ff2dbfe40b374a103ef1bb9e577c0f2cf1186ba3db324286ec490fd02fab", + "0xcc814edcf5ea3fa138fa7d5e387747334c3ad2095ff08465d7e533250430e25a", + "0x1aa1447a8db11875dc7ff7aa49d6927bc31f3b63cd88d2d937f53b1d85e448ac", + "0xa78c6871cc93ff6db876cff3755a59f8fac71e06c89ffc1200de6da08f56dfb5", + "0xf3c259454de9dd21788084bcbcf1cf0953bf7710bd797295fdfecfebd584d4bb", + "0xf86c0f1dbfb94dbce7368211fd3b19875fc831a422989340bce63102a2af3ac6", + "0xbd192dc3426a9b2fa33e2808a258e9bc27e1f14906b9ba9ec973ce604d9ea8ff", + "0xabd37b505d353f7042ef2ea28168f9d6be1a229bcd5ecdd4d69a96663a169446", + "0xf0f05dba6971b57e32e017285fecd48094e6044584889690dd6e0d70c62c3f67", + "0x15a8053e0694262c4954d8110c505ca101898fb5a5814ae8bcd35b8f24d6f90c", + "0x3f8c3d5b5a03f514d0b2f79fcdf7ea58eca2f85651932220362ec9ab50448aac", + "0xdadb41f6e17beff092dbb9a6dd57d3d0951a188fd041f60e455d63755134fc48", + "0x4017f006a6eec8c71840f7051e91dbcb6b18e52fa43529df1121980670f77350", + "0x358dee5f49761fbfe7e6694144a2de8e33614669da6b773fbfa2e330668f4e90", + "0x080216884b389a463ab63c12640f82f442fca56803b2bd7be45ed789db6c7371", + "0x5eb35f253d864713fbe058df986d8af27badce432ebfda59810f096b4e5126d2", + "0xa18c044fdebbe991e181140df95076de9cc5a70c2656ae99ef68e3c1532d7a14", + "0x69af193591c3eb53b00e9fadb149172df458a9e99f403352fcf866bf1456c6b7", + "0xf3a769187ea83cb9d2a96293ec8c9f2074e8231356d3cabe7669aba13f9509f9", + "0x5f26f2aab6b2a0b0f64312d243b7e3dc80621e134fe08f8189b135cfe7d9b2bc", + "0xd3edb5f8556c1a4983450a7d5ecc26a3dbdd332882dd63822e7c8cfb3712b828", + "0x6fd2e87efa3e7d4fb943852a358a515037af5c5eb9da73c3e3dbceb63106d2db", + "0xe574ee1110f966de904fb61d82995be95f3092511eee8195150099cf69fc7129", + "0x6d9c9b7b400d1f5c07aab8f4d23233d26e19feca2279f814729f122c01189c03", + "0xf0756f64317e10b276c71a678b5b62ca94e354c9b8d1ed7019a022be23fa6645", + "0x106402792c6b9f57f4b471736376a153d12ebab21e4bf034b6732324a1fa4561", + "0x33f10f38b702a617e0598cb20bd5df0067ac5ff155cd6b445f1abe46ee3d625f", + "0xffbfbf3aba272f7b978c9815e9e17972786c24fdee8f9167a47e85e9be60a613", + "0x9ed9567c8720d1450b2b0e45195c5a836484a18746e5d5a0bcbffe0b511ad075", + "0xa6ca434a876c017f522aa24937cd4dc1534da3fab47ec57e22ea7d2ad555fb60", + "0x2aec2650b00fa5886b61b1d7c4390dd4e5fd39097e9ed5b1714b741c7b0d4cff", + "0x0cab7259658221598aa39b98d9bd40e18c777ac3b11f6bc7799615c99858efd1", + "0xd76a13ba9212ef2ba4374b265d0405e41ef7016cd14197a2f7a9071e6d4e0a5c", + "0x2802a2d30f42fcb2c953ac6a83212c23711988998eb7f537f9807751b42652bd", + "0xb971ad9aee88adae769dad238a7044c996ee35596cc1b2a7f6e876eaeb4aa80c", + "0x524520c4c947c57827359ffc5a23c4926262c002e6c92d024ea7926a7e0a8fd6", + "0x0de58ec745307c9a36d5f3e97108f666ac58d86b85ce31e73b69579e913d300c", + "0xc0cd603660568434bfa04f6a06342e5fd78c6d916fb8dd77dbfe060cbaf02aef", + "0xde928fdfb8515d944a26630fdafeaf4b3a17dc40b08418097a465fc2009c2938", + "0x11dcbdd72f1b46be2a24dfa6a3cbd8024b6e05f8fe5cacb35618429d9918dec6", + "0xbac41ac48726fc1708a5fff1a06e674a64b8c3a906ec9beb7ff9a444903798c6", + "0x16142a81797daae5fa1914a473f0b89465b0078c5c042f6e1accab6d3ea77376", + "0x6535db5ab7dadf1187ab7c6f0e0a56fdb47a6e6c8f45627ab993b88eb09e7d1d", + "0xa476955c4d2810e17add2ac9604869e9067998fdce26685fd6cf422f861687dd", + "0x4b2ad0b366c96bdba812d3dad76f432dce8f0e8be1943ed92ee4478e9496d8a3", + "0x74bf0384fd4b8afa1bbc0fb0cb6543442a6bb041911a817b55bfa60fb9039733", + "0x5c3da2ac9d4284456d13270fe7d160178cdf61be8bbcbe8a8536da815ee70107", + "0x62da3f7efe7d1de45be7d134d290f9b3dd50e45e751290d870a4b232496ee71d", + "0xd130203c98355022ffd5389a6e84cdd8fa0c570ac887d80ccff892c168a49c4b", + "0xfe129ea286e85269736b508aca4471e643c4d84864809d031dffd660243e2f4d", + "0x69a60dbee253142008ed0cbde35b425e4a2d07545571d2646a5d2a03f36cbf51", + "0x1e2355fe638bd71688579e07145f147384ae18220c8324f95c54ba994b033cde", + "0x391020697dd4cf20f8afb4b76b25f2e08b5f77be696c2406ee45d0d8499adcfd", + "0xbac11283e3e355ef3466ca3dc7d604ca002e26a98b76caf134ea86efb1523eeb", + "0x328b03bf254908db475888105015b638e7b16a4743bb235b85b160e430feee28", + "0xe9450fb3b361bac3eefe1cbe97a096218c40ccf4530a669ff9e10207c69b26ff", + "0xa574c9dc2d563152d012a1931352ec3b9116f949197efad0868a53fe79a2afc9", + "0x629d3aa0c10926f4bf5d250b44fa6959e534444d9f0e8fcf5b206a78ab5974db", + "0xe1e7bfc1e38f36cc8a094038ffa44ad0ff7432c508516e7a8b3520d71714c608", + "0x13ac2b375558ac0582ec61c4edfbdaebb268efb3dd736b6483530db77b266c2a", + "0xa2ec61b999d453a53aa33105a90d310a5afd6f9df76966c53fe524100515da05", + "0xac58616f19436e53d5eed7b50162713711a3f9a76266ede35da4411008de1b4b", + "0xbe8d7a38169e1a92a1ffa712af5173d5cc18948a477a4db917a7f8cd7013d6de", + "0xfc6997785c292450bdc3dfcf9d0609efaa2eb780a6cb33fbc911efc18325c1bc", + "0xb0d71a0c1c3b2f1a746f8cb70fcb99695950ea488216f83854cb267f88c993bc", + "0xa41cb69cbb562b104aefb77c9f0b0b2a7b43b92c7e1bb40c6e781f3667e78c3a", + "0xc3dbaa1d46c2bfadf7b69d5930e00b3d2ee2f0e459310eb9414be6e7d8fdfbf2", + "0xabf64b834999a679f71fa66acc622afa69a45bdf0befe5c8e0224ee12cd3214d", + "0xf788f916838793b4efc5cc80d9f29f717b9a84e877773dd4791fd6a0c1cdfc56", + "0x289de39a57b30662c600ef8056dd354c67722e1fe198ec2bb749c2af77a27643", + "0x580829bdf1584a58d7da444d360dd552818dd1cfd5f7ff4323d21a0c13506b5f", + "0xba51c5ed86b5303e52a3b618f78614bc1640b1b145e87fe625b51ed80d31017a", + "0xeef60ce9f49954e62854e938873e556386b5045a57980bab45e6fbe6a6e9c657", + "0x655bfa2d02761722b8792ee69367dbf3103d16ed0d07f7f8ff6725dcb8f2d955", + "0xc7a54faf2898c69f76123fe1910bef9be9ecd77509ac74714218c9bb8b4204f0", + "0xf59ca122bb48dc6c0c577b04449bb64d7a1ff5661a016bf50e32005f3295b223", + "0xd96401f3f5031c1aceb13d9a3a0525b5bcb7afe47424a5b76e8381732e789a4d", + "0xc74fb4d8533d438c78710932c95500923716fdfa6625154320625465ee32f07d", + "0x63ba1efd6ee8de3b07dd2863eda5d46070f7eb02d35cf670f7b132e16a958bcb", + "0x61eea2352d91b206a674c4c2af59d8a2a0fa70479d77447e3ee9b7db85d353a8", + "0x04b60e8ed3b12a7fab29bb6a74ab7c9a33d403662c47e72227e7eab515f33618", + "0x9c229a533ba459b852dbce6d96bb72c03f9829b9a984119cc4e1c852992bd2f9", + "0x54695b023a34947fae5230256ba2b0905d3e28a28f02c2764f70495d71441a63", + "0x2c47d3759d9df5b9330e6836835939107269d70a7d465be651a3845e4a1903e1", + "0x5fb3708137f2cd39aefe87c67a6c4f9cb60a9945cfb769ea71d0dbb7f3ee8cba", + "0xacba51629f86d56e806aac1561bec11a697a05f6dd182ebdaa906ff77aee7abc", + "0x30ef858593f9a35889c8c036eda78d012e298cde4a3e7e603282b7f8130a4595", + "0x1c11971b18e9c870e513d099e5a49615e409a255725a61083001313a1d929658", + "0x9c6e3731ca9cee43af8c299c02eb49760141e74e1f781d1ba49b6815565f3ce4", + "0xb59c0d2e7c5ca751b9abf8b7740d8d5c8a6fb1799dd1d5a5e9f0ba75769fb2a0", + "0xafbe8a18d07a30f3ecdb907eb4cc05fdd8df2f9e4e91e61f88ab87dbcca25249", + "0x5233d2380755af7c385b5b50d79c5cd9b1255f0145a36245cc6dab7a86c0cbce", + "0x54520d2d08116f06e38d1a316e7e4080f3bd8c4e52b06f3ec20c3a5327f88adc", + "0xd36158eb493e04911fe79cdf4c48dd43a42aa3a23568c7a6b06afafd3ceb51fa", + "0x88a509ee3b2bcebe15ede2063f8fc9a04fe103a84551f279b6ce8d4d36d3b259", + "0xb1b80927c19a8cd540d126e07c52aec2206eaa37a13f2ab4726649d34357879e", + "0x83b1534ad48437dfc54412e49357b13528f0f80dcc32555a2b6f2391cedecbd9", + "0x13d00415b9888e8f64bd3110b04bd47125a96abfe52e0b6ec004c96e142eca1c", + "0x9e3b31cc2715b383eac51b52a3d912e22d3c1f23fa883028ace6a1e80b1c02c1", + "0xcbd325f1c10db1289d1c46feadabc59b24ffbeefbc4f242cecc3dc0dbe5c2e8d", + "0x7627582f663394f8284a6636bf024683547863409f38cb6ec4f67224eaeaa2b4", + "0xa4a44ba1e2badbb513cdd55fafbe2f5741caf2132dd46c602172711c110e41bd", + "0xc7612fd67e5d4bfcd14eb631181977f5b6737855721aa42bf4e9252dec190a53", + "0xbe3030a24be5db7244f04c43dbf419db3c7fde7e7a2f87951cc74df9b88a4071", + "0xab77045cc03cfb77d55f118f15b3416f8f118327e78ae4cc8a074b3c8550f992", + "0x0fccd266f83598b42b88c40c54670e3f2ab3a4c8bbcc0b4effec5ba92e0f26e1", + "0x5285dfd8a25356ebc198835359f53cb86608d1058a90b20980748eaf5efa2ac7", + "0x182bd336222d0cfa5fa9a0d8f4ca769e2d45829af50bc3a454193628e073b44c", + "0xf1a20eabf959a3c1135943378f31a69c049529785e0556a45450174237d8a2ff", + "0x69387452eb76800b6cb66231cf58dc180bae7aed04ab182dcc3845cb1abfee73", + "0x5136ee55850f0aacbc26fe7bcb58a74ea738ae6edc56bdced078297e8ae44087", + "0x37eb930540d64aaf250e003ad0c2274cd047eae6c28bb861bd880cb53aa972e1", + "0x82d64719d65ec1c1dcb0d269222b1acfe77326ee7d901c8bbc542b7696d98de0", + "0xfbbef382c42f25021b7b5787fe6ee0feb1e589310c615cf26642ae507f2e8e07", + "0xa2da021c8e8ac265fd7c181ca94b372375b3c297aab51811494c07a96536d4e1", + "0x7ca0d6023b41793f7a4dad7aa65428e43332f9fe40efb62c1e74253bf64a28f2", + "0xfbe923af0120629c5dc3c118350d1ae310844e0df4cb8ed48decd520fa7b38bc", + "0x3c7efb35e8c27c90cfc06a18160b34b772a5818cb79a1bf62b107ce93cdee33c", + "0xf59c8f80367b98738620c50a44cad556d73ce17a5cc1f403528d72a52fde5375", + "0x7173aafc1f35fc4eaaabb61d26f908a8d0d834252b951f5607a8cda0c97cd79d", + "0x7ccf293b0d2ab799ce9fc487187d61eef099801d8731fa21300bc1b166c11788", + "0x6ed0dde1a0e7bb58435bb525d897d1a9abaf03f235cceee32f3987e1863d94a5", + "0x5a5d21f5ae95355ccf41cbaad953150d3f1231de6df6650cc712cc57f77fb7d5", + "0x7731f59f98388e028b194d16478c9315050555889c30242a836e84e5f27aff60", + "0xfa682bb7f35f7a75c9490c074b1ef4c99afc50f1e32d829c057c765deb899638", + "0x10403d6937901a289c468f7eedfd69d38fea6c6b468f63bd7cb17cd8db4a22d6", + "0xc5ede1b02d3841558bd8ab6f51e14f5a4e6b00daa31f982874f0bad7132465a6", + "0xbf01b8033add1db5cd02633cf114492800816bf01ad4c7e060ae4c9ffe92c13c", + "0x72d22a8029386eb9c26dc3277e08676609385cc2f9addd4095fc1de0ca6bbb17", + "0xbb77dd7851cc4cc50551914a62c71f8b8e2ad7fcb700469a6b893810b7d71a69", + "0x6ffbe73f30d4dc914a859911afea236c9540920e5fc6ea35a5b15baced0c8d7b", + "0x2d06f3ac10ce2d780f52e9f8dcfeed80bed8c4fb628e8169290bf35b59fce156", + "0x1f6c2f6010356f6a37b0217433d7a1f5a2e0cf51c41b6ae6de4afb236fe4b5eb", + "0x011c13ffb7e71e32bbd4517b994856f6d21b7ecf43d117b8642cfaac37b9a8d7", + "0xe2613913bc4cd8dc69550d32163b251cb1e6ab37d65eb71b3aacd05713158157", + "0x54247c638b2b1fe4efaeb4eb101d5177c84c975c759ddb1ac20207341818c6f1", + "0x34fa5ed94aec05a24c812403ad050ccc96d7a052b0d9509cbbdf83503589e3f1", + "0xd4c86048683eecb1e595cf76988e76be819488421c56b96a6dd4641efddf4de3", + "0x541b476f9a0273fba6340f7185c2ce43333de04bdf3c1a7ed022edf4372b2d0d", + "0x65319f2394a1b531beb788f72246a6035539816c618867b0e1d0fa3baf318d38", + "0xcc6b6ebd1eb606210f5d03e191f303c1c4a438b9fd7b81f61c38da76a6bf9fe2", + "0x66c0dd3e062f95edbf9b26189a302e46ceb5cfedbbd50e43139bdbcfe9fa2b54", + "0x728f5ccd05bef6a64b639ff86642f71078719f442915496c430dcd17b437139e", + "0x85a856f40e911384e7a7a42fc5d9197e063bbb890a81382b4ca6ce2e78af2c77", + "0xc80aed20cda1826d775271f2160b6040682095e51d7deaad7405a2f1c801f980", + "0x95576e4497c07a1738d07bd468e65d251f9876c957d7efab7ab7ed0a6eb2c9b4", + "0xc30785c899138565d799884aa7bc486f1a803901b6b8b8b66eb6d97ca597d8bf", + "0x3990fd6682fee93631fa80ce6cfc68fa57e25850860d4d982d0945f72ad37f38", + "0xa136539e69b53ffb451c817c40776af735c95f3392d24d906b22c0e6c6114be5", + "0x8fdb4d50398d776ef876ce77547d4d9e1a4609be5432121ca1dba983ba07a28c", + "0xc7a547ac0db666820263a76b9f9adac876b972b22d6c8bac407ad6fa5c839987", + "0x87aa61ed60484044960beec4d9c45c9112e6e4a70cfec894d5a9f93f94060acb", + "0x50b05f8c5a72944787041204b8a8acb39faf179838116e04ee7bad4d6f21d4c6", + "0x8b90f04539dfb2aec48e0f7a47a1ec601af5414f3284074911eca3a3afc36e3b", + "0x3f9b8f28853028fbd3cb0bebf22a723907600bc2c616ac5251fff33b2df5e9b9", + "0xcd7153ad8c35638d23fb26282ab9361361fd23385ebb9693d8d628a75aec6c07", + "0x370788f25ab289cbd7f9a4b238bd35efb41917b771d8d59493a05aa7bcb3fa4d", + "0x942223044ff0bb9ae56f259006787e5ae6f21f46a3a2bf11c0e977fa60b50b7e", + "0x7dc0e910fa0a6d722dc78f17644842792e619d7e7c044ad47a5fa32583686e9a", + "0x669d80d664251cffc5c7289ae2195a0cbc6fcc732c2af1bf429a4aa98c889520", + "0xd6d24bd4d8a639ac36b14c6d8599ee8ef5d84ab71dd7e6ab829b730d930ce924", + "0xba692b11b9febad8099415d1c0761f2a339328e598d9e04533103afac8c04dbe", + "0x8e9f7d1c6c2674b3139ff88faffe8339e45d72212234b4531654accd66ee3d4e", + "0x2589b94b36fec67b5862871758f86c2773a963197b0d7ba9984427da3b4d6042", + "0xb7d1c1c35718c23dd4498571bb0f4727f3ebb0e1cd02d8094f4713fc0e858894", + "0xe222068e575041014f38e20a85ef1e989e9bb05279281c59569a627769b9d7f8", + "0xb0746c8dbf22e4fcf025fe5383fba7865fd02f79a4403d89753052bb9118e3ed", + "0xbccfcf626a8e36b6eecbadad1870358088b3e584ce79741bf5167380e97f5e9c", + "0x6215dd20373041734291e4dcac34b207235a5d19c3bd24359168d75778b6dd5d", + "0x025f64d258d97752e9b648e956d114c8defccb80c8810113a3522a77ef3f7d35", + "0xc00ffb03dc524d1ea1984eecfb8d26d860791cdde35c8b262faab927891e3fef", + "0x4ec39fa070e38fb24c41af52ae2ac640a859c61c96661d24e53c817228863abb", + "0x7d943dbec346b6bf55c226cae23ee23086185d9377fad511103bfdda3d677ddb", + "0xbfb16c7a87172cc804008bced344dd6c1105a7f0e925f3b7335b6b4d7c8def25", + "0x359acc4a540fb3b54fe22d81f1e3c1b969a99129e130e9e4e24481d024cc81fd", + "0x33091ed3e9f0e50c8c9aa100d9615e8523d594a99095e83863a58cf54332edc6", + "0x5eeb88207a02fe01699c8796b66ad3a0827432559690bf42e76ce1c7f23c0b30", + "0xf5a521239d0f969c8b5c372b84f739af314645de36efd1190f92973c0a2f9098", + "0x1a634f2d829a24589a25a01a22b139b8342c7aad990a14b5e30715d2a83074ce", + "0xc5f62552f5e25ce475af7eea51eba85991c59b73da75eaaccc3e5571b58a6372", + "0x9fb29bce2aff82c7d3eceb134cb1d5c6e6b309b8a9be5d239e6c6dbe231fca32", + "0xac3e3a2edae826437228f39859aea596a84253070a5e442e04adfd5504b9a108", + "0x717d4b6b147ee5eb42baed2a926241dbaed7e6426aae40972488c08430659d20", + "0xe18c4e7cec87f2e53f1e10683835563bb05e182596fd5252017efdf7d29411cd", + "0x6ddc0db9f04fe0b7f8417507afe16b59479303b5473563723b390149a5f09b2c", + "0xfbb88e97efd86e451817b13e55fe3d310edcb302607127808ffb350799631ccf", + "0x5f61ece4f330c3eb3647d2cf9ceb4f3cf238a324bfff628257ac4aa1de7f1663", + "0xa2a3bd77e36c3ede311ef3fe330e4a2b22dd41313ff4ff6347f629777a88377e", + "0xbed3c97e0d2dc6e56006bcbdeb007c8b63e060d80f46b691d38485b03c17c791", + "0xa4e4b8d8922741c5a767d9c4dd71f9d850231d298a5b5ae741397fd065600a52", + "0x0f49e95e5812f573c00dcab19683c391996beacf61442e52a9c240f08f8ab92c", + "0x3701c4ca890dba3cd43fa3b506cb3d9ce540e87c493c6cb9e80bfe05ec5cd255", + "0x785e2c2e4652a9dbc413c4b7bd54dc8c103f6c933eb9ec41ca44e609cf7e0bd5", + "0x7859e4bfa55b11274bb0e91f608c6d840b7de4385ce8158cc08b38449a61213f", + "0x64221410a8e57fa61ee9d1ea1b5ac161face63a493dc7b0da0f398c0d18b6174", + "0xabeeb213fab38140a8e66b41664626f3ffd831b91e83f3cb7d4f2f09a0b73e5a", + "0x8bc1b2eebc3481e54df34a5f0229a54264ac518dd36f994bbd162442fe1190c4", + "0xeb0753b5fe8706efe7224f354cd92381960212ce4d448d3ba554450a66bb5e7c", + "0x30f73d3082f6ce7f9ece8dc9d6c78610babeb05854415279d615eb24d0d10962", + "0x4bdbb7c38040b9f623b67409d8890070fd5d6f89f023556f2bbee1f40f55056c", + "0x18ff647cfbae0ee093bf85bbbe218802afecd7f45bde5dc29c0c76420311f5de", + "0xdf91143a55752eec775c6c02464a781e16c8e93a4270ebe1bf2127658adeb5a4", + "0x64ba37e403fe57a42440bd2fddc1e301297846f69df5990c2d664d3734f902c2", + "0x2f70192df5b8359e851856351ebe2b0888b1c51ce802766f16ea2cf8b723004d", + "0xa5ebf72bbf06ea040306715900f6bd06564887b52e4692333f880e38acc40b0e", + "0x3b86d989319b0c910e74a79b2177efa068d8601b9889b5e3d17d57c59c6a2238", + "0x1e416fb3c47d77206efcabafdfd3fbd0919e7e6d158ccfddf1d0a2a7cff6a37c", + "0x3db2b1eb730ce08d44e27585207b39d5f8dffe7425949fce9e6e1a4f296c6e75", + "0xf703aca3c59fb4e102018a6b156a83af6c93baaa96c54d9a44485a5b90ff6679", + "0xa103f504db51472ce4d6735684bbf46259e04224d42fbbb87548eeb01aabcaec", + "0x282e099b561c70a9a1a3ff6a4518970deac9a096563e15c01151c0c37f78f737", + "0x87bf6fc28f774c2f6bc83f32751e0d509a2e009e2e3dcbce44db2697dab33520", + "0x97d109285466d0d40ed47f6e1c8e11259e69b90b02731a4c25efff829e9c7e71", + "0x18232c1bca21707fe7b74896e3b1568f88094adcc51b4ad9a29a4c76ca33063f", + "0xc230723357dbd10e7e57ab187d1a1f72a27a53c45b650020cffe672fa8e156ca", + "0x6984c028091bbcf3e40bdb8da39d81d2c9f8a73801276ce3644fcf57cfd3e8d0", + "0x8b66e1d6d3d60f03098f29d9f9857a29ae48a5a34d43786a8fe64e6227ee2da6", + "0x353c9a58633a1fc28b5acf9a0f40e69fdd48252c689a9b8db7610c3d003d5441", + "0x1e020c7d1997e15baddb02742e8846228e4eecb6bb1beafc81a759b95783e238", + "0x50e9738978bafa44eff6b9ad9d344efdf40f7ace0dcb146e2c758cb7b3ca05e7", + "0xec6ca85b0c27f1735eb0822dfe5a0d4e642776e2945a9a22e104b9caed098f11", + "0x94f749840d03dfc1d1cc7f31070a1019cceb1eb36a09f520129457057885fb48", + "0xd29d8d19a1dceb08208369498527ccb0fd4aae41077d4c01c715e6989d5f828e", + "0x40b5cc4710284f1175ce67c1a0f134288428d8ea28f64f41fd061a3a4b139242", + "0x7ea68209ad947c37eb3ff8c779ba7f5f3efaad2d61edca2ae5efef666d7c1f5c", + "0x0af74db9e9195f27f1a04acc3150d6d6200a5f50be63a6dc2fa9acb953759517", + "0xd7a6b221519266e935b12a864c84c6d7daf4e4c8c812a93515ea8325e94f2644", + "0x041fd7dff3672a07a2922226bb0526daf0817fcc61cbde7fd3e1f8efa8dd6c76", + "0x79fe74fe4e56514072881413ba7157cc125051476d42fc9361a58021268ff0d0", + "0x01cfb41ca5887931cb98c347c25d6c03eb5e992fd661085307245dc77cfccc42", + "0xa1e93426afb5ef56a564ebfacfc52149e293c25dd36dcc2319d1ee50057eba41", + "0x6a8e8e62cd387ea56c621a5e085daaeb51003e86fc3c252d115ad417e2e79242", + "0x18e5d5dad6f00c36be4ea9c7898645611887a3c3310b97363699178136989527", + "0x6701bc914e70bced06487f22a16792fe3dff4f1fd15ab87ad42dc91de3cc951e", + "0x75161e0ea68a78e4377837bab6162f1b6d53cc5dd76c423acba9bde4f3ff356e", + "0x9d9ea2b7caf0b67dd97b62f0e25d172f78c984baf97ae3851e52e26c5af87770", + "0x4257fe5a910db425844b2edc8badb4977c819a3c40e356d260b93fd2f9170bc3", + "0xf2c878a894811bd844c30441bf38cfe79f3ede5b0574721f32a24755c40aeaaf", + "0xd45e12f2f3a025090fa81bd95e555c8787c26849410f96aa172d3dd153b40a67", + "0x6204243276bb752e5e2d77fc43cf7c5cc92078c283c4d489b7310ea2753ed71e", + "0x806a0a9e0f4e744b02b5091f72f57377a4d7bbbb27829789070967d35fbee325", + "0x13489b922a69fe05869130674253f90b4f883b199f01cd03c85df0a000e1717f", + "0x4fa87d7ead2b1789c72908523c5aa6ef83b7d9559f5c5edb506b4c2f681b617c", + "0x4bad3e31f50fd2dc570c31bd547d278b92e5c93a7d971c38035c09ec5a1dad84", + "0xa0f547806d376b76b33266d94e7d2ef86584a234b540e74f79756e0331405c61", + "0x4bab9342aed359dbce241e580b46043b160a01e44eb62bc29ee5ac413b8a7ad8", + "0xc7ff1b8f8557acccfaf4dd37d13a12e3f9d0e3612398c3d8b1d675467fca56de", + "0xb412685d085b0d52c72ca3d9987cc188f930f759022f060d5f2f368e77a7767e", + "0x0775a447ddac0050f5cb29e08fca1e7d016b42c882ee15bfbae3de5dd99b6705", + "0x1d33342e6115ca2919ad6d31fcea9f4a9fda5dfadfdb4e206e464ac44e59e178", + "0x26dd97156aa189d9f3c799e943f50ad13c2d0cc8018b054af65eb37f5caa76c1", + "0xc4daf50db81c04055bfeba3534a48af718695e2789aead7c3fea58b064bc86d7", + "0x87e2b037cdf4370ece9a2e4a54329d3e1be0b910af6da8c3850ac75d6ba34920", + "0x1b8fd79a76b40690a3bd1bde5cd3b68b36148eb951f45b798958777527a876d4", + "0x63ef67d88acd91fa005706dc9912991ecaa81cc7334ec367340a2c12147cbfad", + "0xe20cf7a6540722b3062b9f49dde601f210aa8cddb5b5ea65eb7bf44f53ce9d5c", + "0x05b5daade0670fddf401298414b70656294b8c5d3203ef7e21536ab2696195c0", + "0x678791e0898a0fd0dff39cdf16d298162200ab1d93beb96ecbf9e9a664362b9c", + "0x77698208c576cf9f2696280872c6f2938595ae522b37c2b8dc5b60b83ce7a9cc", + "0xe9453e5ae3e39110b65b03dca160f930f39e933ecca604f7b1d9db0f3d4e3915", + "0xf3d84caea9ee5dffd395c7da7131456174cba99f905eb734c0df1e070c16d359", + "0x3b56c6cb8308bfe1d9339e14c713eebd5830cd0c538b196d18743bfb729878d2", + "0xd0a1ed8e3bba6cd1ab36ae3e60952e6ae56cf2157039ef2f7136e09999393650", + "0x206a0bc96ac96836c5230d024aab5c7733e4c769b7cfa9fe4c52ec9ccc2c9ecc", + "0x322a0aae92f406bc6c08dfda0b60f625716af5dadfec8d014c6f863eb33c2edc", + "0x701f25bc99f297ac9e8a8e5d8c376f9a363ba277ec87d2eefe30833035657e23", + "0x98ee55ecb672b58e5d02ac83f716013b2e5ad57894383e792cf1bd82cb47b20f", + "0xd7c63ead8a31b5b188fbf0663e4bca087035291834ee1380da270bc26bd19186", + "0xce3824ed345e2101fe30f43287f428c2cdab4a9ee2b4a047d4c6ba1b46a05c98", + "0x853eb9e976bc0fb95caf99b60c978056b0423f2455e5433f3b9d6d28e8ddaec9", + "0x2fefc2d9f5d26e0e9893b98d6546f593dec46105109fbec9c0efb298dd18e534", + "0x255bfda7bb1a2df1a36e7ebc4414338928d59474d9b33f478dab6066275896bc", + "0x678516c205b1f93ddc8d3558e86ccc9ed5dc317387f4a7849ef158e7759234e5", + "0x58d0e9d13bb841286dc4c579c11cfd659b70e84aab4550a75d1d8f01d31c0b64", + "0xb132975005aac90edeba73c75a8533cb9099a5a7f6e9e31755a22b44289bd950", + "0x77ba37c64ec1db20a6dfad1462bc4cb5d49cae6e3c801a99e223e6062dda2598", + "0xe3a4d6edfccad2c55d2a729e6531cc9c20d668dd057c3a8bce78dc7789384d9f", + "0xf419bd76337344144a1e3f1e7a8d3f768fa97f4f1be87757e3f2e50c78c7ab14", + "0xac248be7b1b0f85f35415e09025f379bfbb02776e854d682bfc93caba3a0cbb3", + "0xd853df355a1b6f7b6921870bc5a00a615d5fbdbd9c5214e57e0461a00af92711", + "0x3696d847c84ecdbe2902eb3200013d332d364c0be47f67cc122bd7d4d644f08b", + "0x843a93026d2075704e731fec65fbef6a234eb6d2368f7da29e8e2d3cae45fc3a", + "0x923e0d97b13c9ff4e051cc43daa92960ec646236d1b02faf28902c5067cf83ef", + "0x4a700c31d34448662af972353f9cb471fd155b6c7b5c0afec7acc09e58ee85f6", + "0x2cf612c948d6d8a6ea9886270d5de1e131c2dfd4012f1811849c332716ca650a", + "0xd9acf143ada3cb5e1eb8c3d14b4c188bfce9efc13d317822dc406e08cb5ad9de", + "0x55b3ab14f3d1c8c7b8660a136c98cb4dbd90f8ee329c1fd08edd612a5b866428", + "0xd07432a9b77607da1fe30c98226a224c171cfabf96a1510849255a58f7040595", + "0xe12a4928faffabff9d4835598e103b6079f359061175ccd18159a6dfa7ece183", + "0xa223cb9afb71fbe269c1f721c22fcb13addb8ec06286f9d5b7e337a262c99104", + "0xc133b48eb3f4946ffec9fa143a85d2e009a3b8a99a68ed1d0121c7e9fa616fb9", + "0xcd63f76df5da2994fd87c43f743cd7d35d94cb8dc973cb7a120cb677db9cd5b0", + "0xde86817e4351951cf1b6402036bea2c75901b6aa7a6dff62b9862fe4783e801a", + "0x2872145a9ea250731bbfdbda0b66367300d88f2d9934c6b1d12960067d717bd3", + "0x86e0674ddc6c584cec7931847ec5283675445d337a89d19047817e46e9047d22", + "0x4aac4bdc309bbbcd210b87b0f50d55fe86f5db69b83e201f156bc9ad25347966", + "0x1c0e32260f903386af7e4cf14ef819fb1245d269d2713faa729f05b019445243", + "0x919711d6689630bb81d59ad2c75ace09b462625180ee8fb8fa2d3ac5aa15540b", + "0x231f8566ebd8ac13f2d6cd5a91566aba9074ffd235c762c26280e52feb5ee4c3", + "0xd5df310c108bbf4dcd5f876e0290c5d9c9c2cf20f4f979bc74d962d7da99a777", + "0x45e6ea115a13d30d8dec6f480a9d0b17cb9288f3d2590af02a40bf3dedf3f1ae", + "0xd9930c2a8d4dfd36b70207175e3ec5386fe91371e4b7fb484022e64b5aa8388b", + "0x529278e0e137a319d3a7516b41bcf4be1390e5646fd74fa8c6ece03b9e734deb", + "0x471c07b4e2c5760ad10759fc0889fafda85c2367f2a9147667ad61b687a52fe9", + "0x39332fd9e3c9c89f6b51e4a5fc43d8da10191d07e71c35383e5bafb997c651fe", + "0x72b4753dfe94ecc08b1ca90329dae352e677b64d3e28281b88765cb2e7e3e428", + "0x9a3d06d9134005224fd1f71f14bdda085f18824b9c86b3ec6254b213d8e349fe", + "0x9e8a68163e7e0d096cb822d73c420324ac7416731b27407d74059903c05f2862", + "0x292c607845fdbec84efa2321bdbda9864c3e7e543890fbedf1b85fa4b7ea6b7e", + "0x31be5706424ae91ed9695b2f8f7cb0a81b7623e02da8595f0affd2411170ea11", + "0x9331ce0a7339609a1a4ab7d82e41f432c430685dc6aae81c50ce18aa0592b465", + "0x37dfd9817be661b6f7310ae6c90b3b97fb5f63e0e622618ecedca0d609c39e35", + "0xa350f656a9cf101ba47b0fa109409f1113ae33405ed766d0308740d5497237cf", + "0x272d62080e7b1c27f7134c60ac9f0dd9c903528b1a32338ddc8fc199d9ff2bd6", + "0x8903ab21a203161e433cbfaf719a95b1fae95e029ee19f0c94fa7f1a68f3a1fc", + "0xd3ba92c896627745c0afbbbc9e3d8b5a1511057b24817d7070e08308812f7ce3", + "0x703ec0121dc8e020de0dce30459da694fb8b7ead68bf5b052320c97b0edff1dc", + "0x0491cb350e466467a1078436a1100a70ed6198122f299b4bcbcf8dbac4b1cbe3", + "0x826cc32fd3097689638c8701164358719b6c8645270b70abfc0b07e103d5403d", + "0x351679f35e52895312c8524262a6e420544b443ca3eee81cc11a11c4e40b195d", + "0x0fb18a66d08f29e90c1a71a648d1b36c2dd3fb84bd2e4b8ac24959233cb7a244", + "0xec7fad9848cdb994996bb9fb63cae6e913fe90c9727ba49ab8c9d293b692237b", + "0xd76f7d686c80c1ef3387ff50925bcb540084d3e8d750a862e76e9dce7a443d40", + "0xfa237f1a2b3dd6e4c646d7c77982558af1633cb8662e1d107d5ad5140ec86024", + "0xe7b5e487328a3398b8716043d3e6bcfb39a996405daa98be49493e46e9a46555", + "0x306c41368e9d1a13d4d20256602c4d4182e45b2b69549be7c7133e01dc930057", + "0x9551a36f384e66ad7c5a7d43f510480448f59fc2b3414cb2dafa8d71314ea4fb", + "0x72c3b4a7c21c0ead562b66abb8e6ac42ab96fc5d01c8a5f934df2393b03b738c", + "0x849f7030b271894fd605067a59e373d903a6a52e9fded2357c05340138d3de1b", + "0x5be66687e522cce14e119c9d4b3b3853fef6cadaff6f6c5c2eaef9b6769b1fef", + "0xe063a6dcd767abe2a9e37d3f18b67e2a2efd68ad4d96b4215eb75e4b23295afc", + "0xa8f6fbac9f159d5a5db1e8d614dbd3302bd5737eeae692ae44155d26637ceb4e", + "0xed37085b1ea6b01638a3a145297f390b63b307479e88c55908fcb46afa1e5960", + "0xd963204f34b83d30e97b458148d7e3cd0143495ff67d893b512d7beb7b225035", + "0xdcf4fdc30c4e90b82c2894b12cf27c2c9ca9e4e5ee88d6052d3526a96b93c55c", + "0x48ae98a481df3d2ec8a9c90d0a838125a5237d5716617d4be50d09b2f1f2f592", + "0xf85cea1c73ca422200a9b41a19fec626d13d70e0ae20dbf8c5db66977091e2f8", + "0xbaa3273782c55be478f5e44af8d6d32771bf837002231621eb82fd5b8c07b519", + "0x1dc0a7713568a6fcad865704e07a405a44c2b0096354115f07af09b760eb9a09", + "0xfa70563c38634999282cde0e088e97953e2d8a81180f5c9b2e99ad74493cebf8", + "0x58c7a37a105fe671a833f01f6c189c6f3204d462a0e119b494b6b0c8bd97501d", + "0x9ad437c83bbe3a45191b5c9fca239d1993960a8316e3c52978c266cbfb4d0ed8", + "0x0e8ce8c69bda4ff65d9bd614bb827def7d0f6bce5d550ed72bd5d91c8c1e33ce", + "0x74e04e71ea4c189be803be1116781a66cdfcc50a067387af6d1d468733185b14", + "0x9d1eeeaa2b39e1e0cc9717e921507d34f35faea1450727825d147ecefcf70464", + "0x6758482ad61721f92137d015d4d07bb238b0976bf14a3c548adbbdbba6b73f00", + "0x794c1b2f6ae68389c51761edde1c96b8bd44904769e85a8d7d0035e76be9f13d", + "0xaafd63d0587a40d5b73ba230c976ca80c46a09e3b7f7df136f8eb0b04b60f5de", + "0x67d184707f6e0b9af49aedbfca464946b4f54321c4eaf3263d4ce52de31f8767", + "0xd2af9a84d73ef353c42517a6c5c0667b1f811ce2bb327e3702b49a178fb94179", + "0x2832ef9283d9ffedb03743b454894472eb31740487ce89ef016a00819ff30c2a", + "0x82ea0cb0f3eb68ead50a1d8106278f464e0126c0d7589e6d4c16142d80989194", + "0xfbdc8b5fbb0109cfb3a3b03e01c90c37cb4ee7781563026c338f455ea708058f", + "0xcc34701c30d0ced752f863fbe56d47abfec0c9f8012d1fccacf3814e5bb824af", + "0xb0cdfcf55823aa634004387d1dbc34246921ca0459cf4b9f751377e3a78ee041", + "0x313e6f0cc985a8a0eb2fcb8d3901fcfecbb7d29e98ef8145996e4cea804420c1", + "0xa64f1d4794cd286788c281b14adaa6c0890f9782ec0d80448b8fef906ed7bbc9", + "0x619d70b2e48cc3b295add6bfbb8fc60f38a01e61f4dfb4872b58c1ce7046efb0", + "0xdb35cea33ddc36b0b91b0dcd84155e214a738cc81c8805127c47fb7312257299", + "0xe101f36ff5b89d028618d46138aed3d6b3269605cbf4f83d68c9bbf233f63d81", + "0xe5925c839b60da70be28b38b2081701e3bb0be98cf763539114609b309c5f97f", + "0xb594135c1794da9f7b7af1366d56b4527223c0471ee3780d65cc03cd70fe2391", + "0xd6a8a3b4c6d33bca9b02b8207aa680835266d9c9d4808e2d57f28f92936b7d01", + "0x640a50f666edfa0c4cc55b6c945a09108fdd53af5ca55ae92de4245d56d5e436", + "0x8dc9acbbf2b71953327924fc2cc711574fb1e82a6746a3606a71071369e77601", + "0xd764b84ee9d6a552e34252322f7a939ae546281136a217f5f7f34e41997e677f", + "0x3ec87053d8ec66bf2449a17989721644050b2341adf9036df6843a414a9a1de0", + "0xdca7784726ae438b274f4a3c5892da0bc69ea694791c1ffb5398683952bdea75", + "0x29114fc2dc70ec997d34e3937c2e54136fd1de4ba7fce8353e19af65aef490b1", + "0xf1407df809e1bb932c725821347954eecc9e5e226cd37b6058b45ef9f4fbd377", + "0x873826f03bea4b73698a17d2b0044f1c689daa17925302edb0f815dbf50c7fec", + "0x3e98eaefd07ff2f1f4d6c67aa7ee3cabffd701aa0150f572521a17772bfd8d01", + "0xf44be55471f0b66b065a2465a04f6f47efb35a9ede93a9d8b22aa26d3c6637e0", + "0xb114c762f1f60a913fa570cdb207c279d20abdfd789d7fa62de06e38c44d650e", + "0x6f300baf19fff0f5af714e63ec81314d7de839d4f5900979cc9761e0ac325956", + "0x94d99e9025cec968ce5a80d82965bf72db62250c49131b14c0329b0aaa462b79", + "0xf1ad3dc366363b5a7c2a238e693600ced352984673cc4d0a07ba0ddc2b25c815", + "0xa48dc388a5dcbbd81e38b3e77178a4248232ffeb23acd7869375323f1aba0529", + "0xe995c7008184fe2d5b39eb0b1229caceccc8e86ef5caaa720f15e133e79a2efa", + "0x8bc6d112254905a89fdc319bc231f4d2c52a22d60baea4a499da91119a6872d4", + "0x16cceba4d6c7ccffe424c9331a78bc3748aa7b629f0fefe88c43dad9324a1fc4", + "0x564aceef2d2c0d4b8d6f73c10c234dd82570a9caeb572dfdf023024b61365f4c", + "0x5630bfb3fbd9625f2204846fc81b98774e95191dc8f7995ef33df915f77ce2d5", + "0x23d02e3cb1729ee715fe84775b969989d11c4ccd470910921b75c63c4e9e24b1", + "0x5984c5d4ed0af67154b12c73e38909b45e46e161d85d66e286d33b5ced150a75", + "0xddfc15bdbbd16b80d442f9a0587da4e304d3d7951ada0dc3d041f5a1df85a9ae", + "0x924c83566150cfdd60410c400078830bb4742b7286a6f8badd3e848a5afd0220", + "0x82847029234edd5c2f1538a71ff2eccf1de43e94f651557ba73caab59ef9faf3", + "0x15949ae538f10280406ebf73fd79fe0e77e937f82cd9d0c623e700ff04fa0a7e", + "0xd93edfcb2fb0c16e18b5c42acb751ff197ebee6ef13e01690b08f8e38e777e08", + "0xcb33ce0679bc3b417095cdecd66cbdd4cf5bfd288037d57e93cb6a542613c06b", + "0xa678db01074492af055c36dcee385b37166ad08a4481309945d227640ece520b", + "0x30b123bd31dab5f0dc65766e2b6067e5caee8a53af647b0c7d35d16ab85b2ee3", + "0xfc3faacebfc2c0ed22820eb332bb2f3d9634abc98d26fd42438276541f2beb86", + "0xa0d90324e7577ab7ab5f9667f9d7a0731d223f8edae77dcc9e38225b0206ba29", + "0x75e3bd20d6378133c8a4f9d0ad1121c485130d65340b0596258466fbc733d61b", + "0xbaef6a6c8b335cd317631b907f692cccdd730c82213755988ff7fb78d08fa754", + "0x03c32b933280b801ee17ade93600bed888caf283e0a058bfc0c73f47072f2459", + "0xabc98360fccd9567e9d555924bd815557cd5612836de1b38b63828db742ac297", + "0xdc6770ceead9f41fe0fabf046cfaf0be83f6c27bf28616a97d58c43e3f591ea3", + "0x4f9a91b13c9af1523071f1d4741ead5b6c7a9e72bc2881ede8309040b8ab686c", + "0x175c7e494c7f0347ffed5ce74eafcede61403cd0829d71a9df99e914774ff33d", + "0xe408f526449bec877c0d5ed25e677e8623ea68b797818b93e443179c9ed4d334", + "0x8f3346b57ad4a5de31df1b0b5fb5cac40ef0152fb5360d50ddc84752beae5965", + "0x4b2398450d192781d3ad48ed398fe7cf9e5e8a417b29661894c6dd43e83e2248", + "0xe94177ce0fc04293688209ff52cf53c548ac5b7022e7e60ee739f5c1711099a0", + "0xee6e5c8a30380746df8d9d3f3de53439fe0d864dab6ab5c349012d384284fac5", + "0x9fc9e919898303f537988a6695329143a77e965802be3566396f7a581962c3de", + "0x5277cff2542cb90c1698c7e673b7ceafd16cf4d0750272ebb51e3aa3fb02f3f4", + "0xea07718095d00493c662b21d0dff8bf747783c93897f6f2421571e2c7e3e8955", + "0xa8bfbfcb73a903d2937025226b38aefcfccbb3f9d3fcb0563ede2d9f1cd8ed84", + "0x795af85d146f9e00cfc5d12c97efa5073f19977afeae31c636cb3a6c9771ba14", + "0x60d169884296b60a45cc87beb366a513a6bb7ac34e6acf6066d9abbb1bb3844e", + "0xd256c59553a03c8069aa3dab431c2868c6dee246fcdaa9683b0284d462ad3fb0", + "0x1a399a1ffe8e7f5eb5fa69e70a620e1b15087988934a754a468ff47a7c2f8add", + "0x25cfa588df60eb1127c4057ba949004ef8f7f2681e435fba925f4bf8ce0eb54a", + "0x282d5589c98668c7a9baf871dbd48a3a8c263ea55452086ebdb3b4db440fb9fc", + "0xdd3cfdffe34633d189d9bea7513b890b6d54c2c0d12067d8f45ae72c258c77b4", + "0xc81f96420ae777252b04116d14bb80762c5169b73abad2e1fb23e8bb9334c2bf", + "0x88bf1fb814490289ecdd3d411134d42155a483b7225a496f24ef29d84df164ea", + "0xc6f0b78237824d0b240b8dcf1e31e75e93b4608a495fb7d47ed47ac70caa5aa3", + "0x10f4272adf03ae39311b049b460dce8579b424d3c169101a80aff74efc018846", + "0x52a6ed4acdf0766fc0a63b221d113e3dc7f9e22435d734972e3facdfb3447a8e", + "0xeb75f393b00cbceeace53bff0725e0fa3382e367450fc1c7f0005bb859467d62", + "0xd58b7c94861e7822f924356cf808c0b6ba19c100e49cd8a1fe2ca8a537bb20b5", + "0xd355030bcb4e35157543fafe7f204040ef0e0ecbd60bfbdb897add425112be2f", + "0xbe3ca964fb22fdb9c6c74f07381dabca0e932310cb88676144cd78cb374416c6", + "0x6417c82c4fa9ec681e767a8b3a26640d72c61ea72b1857bd61930187a54f08c5", + "0x0501ac461bf7f2e813ff8b58fb9ba936abe7eb0dc6ef0072f98c52f83458765b", + "0x6ed677008e96476990029e1ac8a86e4d9af83f812dc73d9b876c772c2beb5a77", + "0x9c35dd84c1d73d78dd3277d96ce4c76beac8c6bab498a8a5853970a03026b2c6", + "0xbb0b70d3be3239ac17b3689d67571c12318b51bc6811dea5e8908393d9a567e8", + "0xbfcc8fb9be4c41f8b26214e8462320e79c2fc126abd6e129f701b27b9ac96711", + "0x18bbf70cfc61152ffc64fa6bd21011e446f9d8d1798076e8841cecdbb2e25ccd", + "0x6ec57e3b3b13f8e3fc9298760ea47907c9e08b89bb7599c5cc50c83157a5b12d", + "0x1e681fa5a5d2d63ac23f45cc30720c5b33a3417ef0adccb10b9d9299f5dfdd15", + "0x63397c3ea42e3ea7dabaec5f3aa3cf7e15a4ff94ec745228c0b099928c2a5f1f", + "0xc8d14199fa6b134b84c48a44b9ef1962a9d08b34dbe78713f84ebc0d307c38fe", + "0x4dc0102f265b0e29cb403b258cfee5c73afb843b0805c9218bea86cc12a08503", + "0x4acb64d573cef699cb2d9036488a28bdb3d68a0d294d04c92cd198d42bb48098", + "0x872df3af6d40c5beadf565ea8f6cc502edcde941c43cd3024c812b2cbc33eaf0", + "0xaa24ebf00a407b1ee7e126cb5f396a1b4489577f160a7ec735e0e47fbf077abf", + "0x15e6c3ebacccecb59426bcab8f5845a60a584a18d5f6875431181a816d5dc0e1", + "0x3ae0bd8b42433be46a280335444e8e2d35c1afec926cd2c1d5ea537992c506f1", + "0x1e423a88a245221c826586cc67ea45dfea247c3e9a36c81ae9f0c0b5d5d3e5d8", + "0x5401f93723132c737589b457216dbf231a753c4c4619444af4eae9bc6153ee40", + "0x70d9a2787990c3dd8166357ab21985abc81a55eb0d50af7e19ec20454b314d4d", + "0x4ab7adbe2f74ac269840ae607a17824e8ec74054fae9d9b3998dfb162962e1a0", + "0x91fabfea828408eb161ac781a0896155ccf7d9cbefc3483cde52b35ec67883e9", + "0xaff4547e50acac2e3851620e541e96d7645682f225400793ebc0b959c6a09a01", + "0x0937506d4c9e37d57560bac5851795d6559e51df255ea2c64f2e119b88cc7511", + "0x88d66c613582fcf6df46773a1456304c4c0eddc212612b2dddab065b6051c8cf", + "0x2d6315542c9b30c8984ca951ab488906c78e6c84aec2090397d4a61ef26375b9", + "0x8ca8d613a382711420966787bf7bd541f517733d21ac4f893c282dd930f69b5e", + "0x1751120f6735feecee772482da8121e9e57d930d23e69cdd5bc039f43520b9b7", + "0xe161051a099cf4b605fc773734e68f46253efcd52fc9c7d7a207f956c407c606", + "0x3742dfd43498b7159cef3dfdb520d34583ac955cf8abb3a453835f3132877d76", + "0x1cb6bf586b0d422a986d235cd2cfccab6aae1ff580434bc9d1eed944d0c54d0a", + "0x3028e937857f2ac53e1d988fe8aac0f18616fb221560c69530c4399bc49db96c", + "0xf5ba682318437ed7770cab6098d356ee63c41cbb8d7a114ae094aba333f78416", + "0x9ff54c1d56a1977d406ef680e80850a4eae13e2f5b0012c0961a87426881088c", + "0xed99d4a9efedd66d3902ea4bf332bbc3649eb84e6a32a239c6fa712019f4158f", + "0xf9fb0e5082e82b4e3fde779d9f42870319e30e01b43f88a89f651c6994f1c513", + "0x69467611b658799b1ed8369ce39b66b5479f9601ee796a93bf57e94c4a840db5", + "0x8e1d27af1e1eef4038af7c34a142ebefc75269fe0991575f06f658afd96b293e", + "0x3a03db5ce3be82a8b47d34e271a7f126509d0f0402ee067395b4a6d7963d178a", + "0x641e2f3a93b6867ff70d8acf1dfe8a82e151c84d7561341107528f58e69df814", + "0x8b33c66fdefed9127a548e2ea61a30188d7a2b16b6bbf5c52d5bccdf860a47a2", + "0xd62cef231735d396b265e3241d51d08a90f6ec82267442ed151fe6484fd2f2b6", + "0xf52f27645bee7eb4c8f9c11e61aa11658240bcec7b6bef9c56149a3dae1d9374", + "0xbe6de14b25ace5ce862be24755393abdd07b3f4c50985062815139073e4c39bb", + "0x60e06bca41e0d1b136a7ef2476c0b495dd3443089f19f2e8c306611e40d5caae", + "0xa9c739fd18f5962d8b71215ca05f129153968e12634ddc7a19d54136de335247", + "0xecb51e8baa0e733048627977d8ec736cea38e501cb9256d7b5b4f264c4851055", + "0x634a99ea3bd706001327f1eb6fb79a9c0aa49a6517e78c1135095160152e3273", + "0xb9846ba9630ef1607061ca5cd2c70c48b632f285bd18fa2db6b4ade2720538d8", + "0x8ca68b47412dc13adfc72489a0371f5f2f0cfd5942d5ffae08a57a79b9c70ec9", + "0x13c9d7b77677291c415253af2508e66ae8fc09b547e66bd0372bfc7371b3379e", + "0xcf3d8c54e42a98852364dfc2a22a9029b944bea2361208262c149dca5fe1717e", + "0x752a1d54477a8120a7df54691c70c21dd399e9d84a576717cfcdbe9320a10686", + "0xfaa8c3a9658b4f096aa4c89aed1fd305062608aa73fb9d734c9d9205d2055760", + "0x96839db4f4ebcbff566b96dcec7c57de674b8075c07e6a17a4120b225618f6eb", + "0xd7accc2bae2cccacfb7b7bca6fa9659bac4bcc7f47fd05b459f8eb271725e676", + "0x37cd77dbc69588fc060a696827004b1d1f48e46b317cb82dc8329b65c4f2ea5b", + "0x83682e40a4dc120e5019eddcf84be4e42563904d1f06bae96cc5c513790762f0", + "0x4c519f5d6664f4441baa7cb15053d7a385c7c31ffaa52044fb48195d9edce9e4", + "0x28e1f389b7b0338f7ae494af7b4f239fe703ac53cb8648c24ed201eb3d0fa366", + "0x65d0b0371e3ab2d49d30ec178921d8410de8223ef4fdc4721d0a3aa1d1fd2676", + "0xe7779ddea50b161ecf429a3d382b7eb564306ad7c050da244a6ea2ec4336a85e", + "0x42ed7b3277a97be9aff896f3bcbb1a3ca9a1abcda194185f40aecff40dd05c9f", + "0x16151d4334d8e9555e2df32d6a58ba3caedc4cee88906391fead30cf7b6c1492", + "0x22454deb333cf072d9a19f52c64c232f4e232100e4097dcefc552c66cd037174", + "0xc77ea7b5df0d670d6828243b057169f25c1dd3a55ee23706aa16859254119d74", + "0x297b0d48dd676057449e91ec41a35ff23ca7101062c92c0dfb10f989be59b5f6", + "0x74b963f879f86a4bfe0233082129bc19095888f0d9ff99e09d835d8214de6e31", + "0x09b537b0d42a9c3a1a191c9295611c1ad9fa5f8002a2ffb990131ef3afdf2cc4", + "0x71b3dd8b8b917826609084149140de5e0b34f71e2baae4685d8be00784231499", + "0xa2666cdcd63be625dd08c7298d6bc06dce126e6a294240a4db43aa3aa0b3428c", + "0x3860cc7900f214952e4b797bc5ae198d59385d8fa747076b497a5b4a2c51df66", + "0xa53b70488cc1e45c1e11460c66ee94c46dae564c5a1cb7e3eb6796796943d880", + "0x06c7f6905ed8d559f757a6d823b876850002ea38697373a77bd9447ac9d34f60", + "0xeca8100c89ce9478abf32238bdad1505f3e1299915b6b67d1f5260ee3d494c09", + "0x06187fc14bd288ff503e878d0300b088dd2f9fa7c4da3193f321fceb4702a841", + "0x4b8d46ce312100e848366f8283558873f17fae5719f7f33f9a73df885fa12828", + "0x1d68bc807568d3d971d36d08f06c2e6d70cfd02ba03d322d7cf144dfc53c3044", + "0x0635b0924e22d1b03d1ae8bf9cd51a6b3479cf9e15e9c341ab97c9578ecfbebb", + "0xd181293e935a777d4b4905e7eda21cf0a6d48842b28228a9ab4e480cee7abfe9", + "0xcd1e363a1e2bf26e5f3c98a7a426e7528e4a24155bfa2a1a968a971d129af069", + "0x32ba79240b478b0b82d06adabfff6caa596987c07d73fec3907f4bb21aab169d", + "0xc4c7b178c63ef2f10860a346acd8d43be342ad103c41cafacff07bf748b6c262", + "0xf7c42fe2f081334fd729629f766de6919c41084dc143999abd637dde580895b0", + "0x2b3c788d5492557137bcbde36a3c77bcad3fbf46e93dc83c43801c13debe4a3c", + "0xfb2fd5480e25e6d50f22bf422edb888194e510ee40d112d21210958bc47d919b", + "0xfbc6dbeb8b5687e5360da7e241bdac501a6ed768e6c9694dab686adde5776cb9", + "0xac01b85031a280013440e18402e378d16e8b8cf582923597d4937bd9502a7951", + "0x6de81b17804834c0390ca350d4027b7a0824ddfb38bdb01f2922e240594a26b8", + "0x18ba82983465250c42294ad5c3fb634d372df537b67c1bd735aef7b3d045a9bd", + "0xdaf21a1151c73bedabb678497324ab939a9ab1dc3ac506e395b164a2daede36a", + "0xda42e99c8b304a39bf2ed10d88bcbf9ff527c1e3b9a5932400f331e9bc51a88c", + "0x563e2b38354aa19dd91ec0914f95852810f3f605e828a727ec0a69f54278be61", + "0xc64bc37db96aeaef1d1b9f5da5b50964690022e0c78015811a8034f2e10be4a8", + "0x96958617222852f4f6dad6bc4cbc79657170d2f9c4ea0a5cdbaf3ae723460a0b", + "0x0abac5a8433b40108cfbd385a3bb0298c069ea4660349927c64945eb409da78b", + "0xe5d5f48418141703f119222ec582abae55448128570da3ddacd758f112e67472", + "0x2491021cbfeee20e3a578b9f0508c85eaed8232d3ae1e6f074f43410ee373a57", + "0x353a4b80cc69d701510ba8711543f1b5677916ecad829c76740f21bbf7b1658a", + "0x74397d86b849a792c4ae5e8e65750a932310d1496a0ccd3f5f4170dccd707d3a", + "0xef520df7a1258440507525a8b1be9e60016a95a7da4eab82dc85d8aeeea3a929", + "0x0182f92a90d14a09e6ad6595d86dae389d297766dcb8d1d7a685bdaad733d2d5", + "0xe2b947deda76a4cc65948c3a40dc7ae7bfecc285f8881856bc55d4d8834f5ec8", + "0xb56dd5d67c8d49b5220cb8901a67525e00cde18ca52a5b26d09974c430b1c304", + "0xd5aaccc68b4fe4694c9cf7bde2d3c27a4c8c5df40232df1b875195404a762977", + "0xba7681f4f365a69625ec74bb1d114124bdb156767992c778ae5b49c4390438d4", + "0x838d298d84516b49a77b86ae27e300b1ad52beef517df8dd4b87d43960e51839", + "0x931e8b07cc0df6eb35d54d24d180e2b98e0ad3bec2525793511bbbb218063853", + "0x94db666ca733d8fa4954091dcc53e24fd1fc7e6135479b803ba45fde46753b74", + "0x4e311786ff11cb12e929f2509b5c7e94a87739f4475a213adf546dfe288966da", + "0x5a7be45e660da5079427166c854a81f2d4bbe2e326d0ae1f1d0ad067120c6c73", + "0xdb863b5b5109bd3f6fb7af19bd608c5a8836e2c0d8512cc438aee184ba97708c", + "0x8e21743089dd75ae94a2970874ccf87d8c57f2bd90c701d9c30fa922ab600f67", + "0xde96e7f8eb356b706754151805417b690e9ea613cb0886df7424f07f90b9f35e", + "0xd9af1f5dfa685f1b0e0b4bacdee2e24cb2448b9c990a21cd32ea85628bf00553", + "0xe61ae40a63d3cc113a9df987512cc6f94cb69caf36ddf68baf7b77089fd8842e", + "0xd32d2de4b6de7d3b9a8b75fe004b1829006473daa4507ad3c2bd74bb5473f2f5", + "0x5032a547596c291d8e0f20797dbe1b52896deb1b13a930b9ead43ca93ffab7f7", + "0xdf75524819354c93547474a730c86e285852736e3aa6a93a1397cbeb8574be5b", + "0x2ad84a52217a7b78ef30fe6ce5b36fac975f8eb996d89423e35d4de57dda944f", + "0x24273629f43c888b4ae4ce0e98babbb86aebdc304ecf7565e8f5cee13713e109", + "0xe340a7207222fbcd3a18df2e95aba462efff7806fd0ab5c79f163a9ad277239f", + "0x14b19088ed16354ec0d508d91100fa39f1c50c5b153edde1c7fe12b6325c3269", + "0x8ad8cf08a5d25b9798457a32ad4b559ceefd8086aa662e210abef814d8dc5c84", + "0x002ca4fd98f15c2f1c8eb360e3cd38eb102d6f93082e3f1bd43220309d53bca7", + "0x5c3df07ac15d8f1e16662b5ed8821e43f45b8adeff87282ba92b1a53434bfa83", + "0x75d277049869aeb977bbd1d7c371b6a9d84c3714834d1a16a32af5286acfed23", + "0x0bad0d61579e2555d6fe7f4cc514b674c67b589ebe5e7c5cc451bacbdd5c1318", + "0x92f15acffbdc999e32e763c32ae7a6f373f4864b2807de08e7af49c70f64c659", + "0x9443fe858cda8b2788eae50b66fd1d44280c58f022471d8c6696716f0322d8cd", + "0x9c3bfc75fbe747bf2c0f1015472e67fcb8ec91f40e9b509429ebd91954b32d25", + "0xd112736eda168795236314f0de72558fcfb104e2f692d952b16533446ba75ed8", + "0xf0671d0460f40c687b9d7d7a5a46812897f3e8289aa7913b3eeeddcf902ad907", + "0xbd8dff979715487464394682bece79900bce98196542df4479086aa7a28d00f0", + "0x615d56554914d61bc4da030292a1056d18f71728de4941d0bcfe8dd123253f84", + "0x826a5d357b7f2a007804bbe75fb89ac6f7ef3011f408a07470b031e476d49758", + "0xceebf085d7d36747965b6a2ea80d1a1e47c71a27f28584ac89e35535d2da35ec", + "0xd4fa150d101967f3d7eb60c23b9993bf9a93ef36bda6bb75e17c3f8e992a7620", + "0x8672059e26d3c2605d82c219d2ead47d94446c8dc1351b109149a0514d618f64", + "0x38064f1f84a646320bcbc7778596c25e9aae2e356548b4559aa447b6bb8d79ac", + "0x6f195e60a921fc96202810a55c4ba9a042685f20761fedf15a22b28198fb0497", + "0x8dc83f591d7eaecdf50fe1e92e0480d1f174007f5b7a351f377ea651ecfe76ab", + "0x6bd195f328b200ec4ebc57f94ddb36be5b77aa16e633b9ea8aea5c8a3f1f1b1a", + "0xdc1f7643b1ac9c9703e5caa148001f2e2cb7168775ad3c6c95c675d6adf85e6d", + "0xdb2aab4822e191e5fbab62ccf4d8b8e548f62d50fd2b0e1008e834edb91762d5", + "0x7100363198ee3bfa9317ef4e8455bcac54276b3a55b8c01873a54f1604e7b24f", + "0x9de02048489d873a3b3c22cf74d275696aa699ec103b4aff251a2f22ebe20b80", + "0x2a3cc09ec20941ee8b04bd89e38b7cdd9e9f0dea006111d0b1a61a47f77e45d9", + "0x082317557cce01fb189870585aaf7e9af411e7c8cf38b4ef7f101c96b0549b50", + "0x64f53c41e32b0b9b2fb925222bec9676a21ea39b558e2bec0132fd045aca03b4", + "0xe407abd21dc0cb6a76932ac56f7b018bb3a1e9aedbc38d59aca4c8776260cacf", + "0xa6686c4193a6b61439b55658605f9429082ead789e70629860260706a62151c2", + "0x190dad8ee494cd10a5fc87d5b33cad2b401fa8e9e60ddc3152182cb15dc4bf37", + "0xbd81f8a9a639cf29aae2534b2e7e9de0ca54329360fd6b5263b27d8c9c3320c8", + "0x60923c3f36a0cdd88877ab46cbfc471eb43313059ec3fc814bfc40710efe24b4", + "0x7bed716f7a843c885688ed7af46771588f563b63507f0862e822ebd8077978f1", + "0xdd4a6184be0103d67fcab1ed07b91257b7c337ccf5dfd651967a9bf51de0ad7a", + "0xb675cafb5bedda4ebd58031ea37b88d6a5cdc6c70d2302ef2c8bbca1a941a434", + "0x1e84b7b0320b305d21864238c1d5309029d6f236705e86ba557ac4ab3286306c", + "0x07fb4aee552ed17b6633df226091a7440c6e8fcef8defba0b74dc26e3f63bd70", + "0xaa2af0c4c0e3b5e10c6bd02f9834ea38650d21ee6267f31f59a94b65211ce71c", + "0x0ffd43f9155d4d98d28bc491a351e354a1597aa54180f5a7525800f366205d0a", + "0x47a3c45224065eebf34ac0c544487b07bc81e977380845ca3599af1c9ad1fbde", + "0x582a6e56abeb12b0904f5e72f292ec8eb7087a9ec904f704bbf4fb4b626c761a", + "0x961aa84e2f69cf7cc86af84bc5eebfa47f16f69f31eab4ddbb6e34b4ad78f368", + "0x2fcc76736c384389f7bcf80af928b1b2d5f2a666ca7c7233855a38e2f5fa7a16", + "0xa5f51bfee955689e2cfefec36f6fa11c8c39191a93d55003414649089dafedc0", + "0xc33e8750e8c0c9be14b844b61a6c1c6a05c762935a28811a1fb61b9ce613b8bb", + "0x75db0ee106632fdce0d6dbb847f756344f044ef0783563c41c2212a47e140d1e", + "0xfd48e7fd4bb7e075dec1c506cf23ce165151bdaf95902a4d33e174658c5fa872", + "0xc06795ff7239caed1d216e9c715b56b180c131cd8e7303518c8bdffda6a9a293", + "0x6aa82ce836cf55ca0180fefb94631376ca40e8d0b8929a75a011de0b617ae2f2", + "0xb9b8a68c9c52fee3911f56dcc301138864c45af8157568df0a25f1c4bbdd3985", + "0x6bf761d69df953d56be46933bc155b6d5cef72fb502470a02dd4f376f6642152", + "0x5a1282a8d75bdd8bfe98800b202b31eb8d00e05a7233bd3b94ebb724ccc78902", + "0xf7ba12d853026203a0ffdeea4b2a7f2c765552bc218006802f2fc3fae24718fc", + "0x20cc11d68ba309de6ddcfebf6af9f3dabc109e4f80b37a553652e3860e4e718c", + "0x1a348abe945c24781cc3130841d9bd7cd3f65a4ded62f03ca43e1edf0a3d5d3e", + "0xe49ee1bc38403dbd29dd9f1d9a0c30658766d190a99d88055beb8ebb3bf68255", + "0x8d11133a1e20b7c98a820626c3c7165b99290814807450582a75fb66cbdcc4a8", + "0x82de0eb96093abd04ea54056408859c5df792f9b9fae157912bc1612e946cbc0", + "0x09a05827e3d8ba4ef391d3a59499d3f4f0368725fdfe606b2037c0da1fddd04f", + "0x27afaeb9233d09de28c35d425a826c1f8ed5d9aeaff974e30bc8267119f181da", + "0x8c20e9a837f4ff4791d535285e97e0db6fbbb6f90650ad599ee8cb539fbc6fdc", + "0x145c283aa63d68999c2cf54b3a1db63e7e1c5cdc513f151620b7601af93c43a4", + "0x33a610d432ac33a5afd2d4f45cbc7d2d38c3b2306cf951354e8caaa6c80078d0", + "0x26b9f9916168a3a3824ec188e9fbb4740e38f2f01571cf6f5c5f797515420a6a", + "0x02b0b674e9b1bee1606e1b04d74cb568d257eae593e53291e02e3c63a5a50a62", + "0xad6a8970d964768a29ae2c0a69870ebb86257043282e901a08c83347f2f576d5", + "0xb3432872f6e00304d0c7f697e4d5bc84fbcb0db519b0b2d10bfc59fb7a66d0dd", + "0x801b0b76518a3871d99475a87ffa410966ba140ab06ba70bf1e0f986a75ea99d", + "0xe30da2b86208f67afe68b136fbad8baa2dc2085798178be34793e4fd28276ed7", + "0x56d15e4935bcd3441337544b0dfb1be964594dd15ede8920c8aea890c0f5f3d3", + "0xf2cd6dd6bde075ed422413aa2a4dcf7ea831e9c0b05e72a11284702ff4648695", + "0x8d0d6a0e37eea6274b66eda85cb955a480744eaa0ccbbf6c53a2138c2ee7f6f3", + "0xde0e7560fafd1f6145705ce76500d117e916a549c331466eefb672d5d1bb683c", + "0x378f9c77586f4204fb0eb4dbde4c1cd5212dff3dd00f78ffe4d0a7fa993b4420", + "0x38d96f59c01f5677a8f0ae74c85ab92f403d3e0d458dff74bbe30cf0bba9bb82", + "0xa167bb791f78123df4933c7ce81adead29863c93383fad587e0736eb9f62f96c", + "0x1e2eee0b810ff2e3647d4241f0ae3c10de6ab1a81783b141929ce29f50f1b611", + "0xb3da422014ba7a2b692577d4831ee8a2fa0e93075c6e3022b9fe87e589b03ab3", + "0x36bc055c7f7b0082ed73b69ddcfee537ad59dcb2f79f11f32302c781a44c1138", + "0x7824e636dc9b3c3082dc8d7dbf90b75a6694a149d1451070cee9234d3d1442c3", + "0x3a7cdb84f95330c17cefdc3618f67d67930923ccbc1a9233a303aeb06c900908", + "0xfd200a9779e710a0474fdaa7c2bf426748bc17fe8da08699c0fa863d0dde4252", + "0x0bb5f63f4fa916b3aa8e92537a98a9741dbd0191e8ebfdd1bdedefee6a03ed27", + "0x58d261dd02d2d38c4d9d64834659bd223a694780f8b0cd287694299099f0bb9a", + "0x246c86e5fcb56893162362ac404d498193ffe74b43516848c73e3d2d2f1ec680", + "0xe5094d30072956be53f7be3d77e4bac8ddcd8a73781cefd6731af1ebdcc3b9f2", + "0xfb3c6d47d72af2421fcabc66965595841a373214d33e5ae4decca29928f9b8eb", + "0x8c88883b7846c76de5512b190be454046d88c529ba80800db53fb6bdc9f5c480", + "0xe3d7ba4090d3273ae1d0a79a999b256d888d1893cdaf0f9bd046b01a2d35149f", + "0xd832fbf93a01f4f99da4c824161dac8fb5ba379d7a62bbb11630fa059eba4bc5", + "0x2743d2076ecb58f172ee8f2a7c1dcd3284a86f4b38346898c9a0e30cd1c016fc", + "0x375ba23cdd92078d0c1eb959a84e83f973821b7c5148c78c2b5c911ed89d4a33", + "0x22037d3589911f11598fbee2ceea39758667a6316b6a05dbe016c8f27c0ef556", + "0x077901299ce69ce115289009bbd864d5bc412b227c9d45b0a258b1249d1aec64", + "0x0f3356271576310287a00a52bddc9da2865ee028b30319aa238018d1dacac7cb", + "0x4a3d3a133af48e90299cdc0ce8360a1374c3ba7697def7d71ee7113172244351", + "0x32734db80d04af59061f913484a2fc22f0b13778ef049e02e8f9fb30e1da9d39", + "0xa3a472ea8349299a3378e0ff14369ee28337f73a475ddbf508e74259b998067d", + "0xbf358991d9c5ec46243f526f8c322c70f8eb6e5fd99954cb8dda31406cf492fc", + "0xcdd3269fc0abeebb8e44e74b5990413755665b3f7ea6ec763dc19091eae902d9", + "0xb2347bc4742f37f82069ad24608916ccb17e0b23097b6f50c6ffa672f9d7798f", + "0xc950786f85a20e53d496a7f6f539dc93ed4db152ff3fa07ec9ff545f93b98a2b", + "0x5524afc5be48482b279a86994b227152a9070e998c7a8beb8164024213cbe865", + "0xabc025567a68660848fd0063a75564b9fb1483d038cd5a191fc9bbde69c91374", + "0xec61a7238f379549a2b267fce0884513fcae479bce9aef046298cfd35225301c", + "0x0646761899d9bd075b892cb4b8ba2444fa83a8674013022b784e91808241624d", + "0xbbda1dec49e56ce2d3554dcad78a37693eb6437a5e21cbf05a357c2663f6e144", + "0xe218e9d37ba3f4544dfdc31e3332eff0c8a9b6d3bb10188531d4e2de4eacc3bc", + "0xf708a6e77a00c47a72d9f019165044d827a26d9adf51ea53cccb6693063313e7", + "0x3c9f9d34166dc61e2e7c0e15f0e61b0ca46462f7e136f0705c49524019cee3e4", + "0x0c4616a6f0f847fee88f1b914118c3acd207f7e2d84260db50137d1daa6e891d", + "0x5e34ae26c1072f07b7815190fdd67f5cb2605c849300bf28e9ea6c3eee400f77", + "0x15ae51496b44825cd74fc5d34c964b9e2764115d287e47bac9744eda09f6204a", + "0xcd6a8ea1da8d5eeba387281ae5e3cc2edb14b8c8ebdd87ee604bc09befd0fd6e", + "0xea39450403c2fefde5f54cba19b8fb2845c282d9076bbddcd89c4d030a7d786b", + "0x51a9808cfb305f3d1d2dcb5cd8355ad295ffd193f503313d0c23b631d70c85fd", + "0x94473e8d272904770c25c158fbb2ff05d41de0a1cfd1f0780b99e0c70e6da313", + "0x3b78c5f500f3723cdcd7225a83749aa6a1e1d6678162ea667df496a9a59fe822", + "0x3c02d338e7ab6b10a91e311dd0d7fe83bc62f4fb90559535e15f01a6a94f8908", + "0x254613902cb39d43f8fd4efdbee4ae29ee1f73df829239eca702c4c6b76a8056", + "0xf5a59c3ee350c1b5360a790f713b054bf34370f18e7fb3e68d5d1544dc142b9a", + "0x7d8c61e608461215a5190422cb8cda548f67de7d396c610a7043a12c38797f26", + "0x21f61007950ed1ff63140a6533b5caa66d6afeb768190870a0bfa56bff4ba249", + "0x35221c26f511f1d356dbc6cd33354ab04270417796b29c26cfc208fcc22a1926", + "0x7493f5f0d913201df01cf514d9209fc689be68f3759cf7487a0d9c942a4f0eb9", + "0xa28f9fd0a06f07196bc4cd235f86781811d26ce87ba510e9d089ff0ac48dfa09", + "0x296f7a79477fc94384c240d103d3899a0979bc7680ae6b0c77dba5b40236c5f6", + "0x4f610acedd15c3df59a079a3edf02ba8c3cb1375cb54a86f9b8b7aadd3bacd4a", + "0x78e6df69fbd9a8a51dcc14a9faa99e591f6b65cd7aecdced5e898c3207c88433", + "0xb1c4470ea0cae862dd84e77be0aea69d045149193ee2ede2280aec5fe2bf9290", + "0x2906203e1e907396b983b5ddc8f53c026fd8d278a7d580d770edacd560abf9f4", + "0x172486825d1472fb99a53996de84a6e58e9d1c25ccc9eff81ff660728fd35200", + "0x0d85f1ac03ed46541c171dc9e521d58e50c1059ed14591f3ac01870b0ce6f4fe", + "0xa327265260bf6252279cb97e7dbf25a423cf979d347251e2cd548f902aaa5333", + "0xd2465f53b0d477871e9979b56e1c4de2fb81f5ea6657d26d9142ba450f60f9d8", + "0x11c5da85c8ef6bc2afb51fb8c85d3e15e4dded355a55bcca7ab03fb9addfd9bc", + "0x8ae739acf676fefc410ffacb01d9e588fd94df577eb88c86b29bc9b97fd0b39f", + "0x9b626245152f0c1fe45650dbea9edf10cd7a4f4a9b9f472a4f5f58365b736b7b", + "0x2ad3f303486ec33231a94fe6899f8a6881c6273556afb9d43df10557ecaa2625", + "0x815535b3b87aa7cdb45dfb6e08248f73d50d2e97b3919b7c6d4be0db82ba736c", + "0xc5b2ee3ef00a78ddd19411529d9df0415b598d8bf8b0e9be14e0db3abf75b538", + "0x4a43c2151e9bc477dcd23bb690f59f764d1b4f40b434d0bbd229c2fa33187793", + "0xc98e003d7f67589e42dde11b6e5c4337e56ba5379ed36ba64e328140b66809b3", + "0x548d00d6d57076dad3ba99c12446fd704459ae26efb2f32f31ed8cc002d70472", + "0x220074ab3e4ab2b1478ea4e671da8f4a29cb63820cf444b8b8c80dbf55dc7ef7", + "0xa605579bdd11648f0569166a6b6b9fff1c5f5314e4a4443fb45e779b6ea67f23", + "0xbbd91c03ba7a25c5ed6d2c3efaadb9beac37bc41371d1627061bbd1b07bba2cf", + "0xe5a0b22f3733c62c253ec1d438a162bb523d600078b137ab64a68acbabbfd591", + "0xd62697c4e5a86182930e5f03370ee5ae429897299b0a089942d0affad839c396", + "0x441bd17de05582bccadff86e92e1093066042c74ee6dcd2a3d372fef2464a25f", + "0xa1c7340ef8700794a780d623c61611ec782a28e89744f2b438cccd582111ad84", + "0x8325267cbc3f24ec1ca175420d0a1efe55f32bba8856cd5649a06c1c2dda7d6b", + "0xa10890568036a3d81ead9346e8b5d272ea5e30425351baf87fbc87c85caf12ed", + "0xf99feda98b47b71aa95ee45df084689e805639fa816c19726e8a3a7bd4fa714e", + "0xafde69e66a08f8d67df3328ffa50bbff36e596342becb1b30de9d63c7ddbe779", + "0xe6b92570ceedb890e38cc820fde3a63f08ad816fe36690a8e0e3d590d2fd767d", + "0x8d8127ae7b04e1c40e690b67e6b0ec7f84ca3048579826f66e6c2f931d0e158c", + "0xbcc4f1260c39444a096c6ad54fdf3b83ace0c5b88d1ed08a2fc36539b50ee6e0", + "0x186074682f41df28b76a245dc37378308fe996b6b1c033daf582bdfdf6a99593", + "0x62d93c7126ac1ae0d815460a87ce1b7a2bacabdd7ce02fe34d4d8c1a62960a9a", + "0x5b6a7a8fce8f9f7181806ab5a3c84a5f60a7bc4ead1247735a43b08d225195fe", + "0xc848fb9925e445d3595c338197ac7d31296d9247f43f2a604494bd63e3ce78df", + "0xf40966a6c7666339a4c136186fd753079739732c2bb724cdcb6047a5e5d2ef1b", + "0x6d8c1765efdff94ab61b3b4872c1acae846e8a98c763fc7924cbb27865295deb", + "0xdda74969fd0e49dc1e9bbc04f8e3dd952ce0e9a98041c7599058bf481b57da8a", + "0x72ff550e2a8f2bc45918e8fc1deb14e4309eb8cf03629ec83217f06e457dabb0", + "0xe03fa58b28a8e1b601846bfccfdec6a290accdc467898caf0be38acf0cbe8e30", + "0x75c3bfbfe321a63b96c376fd1cd3dff0d06308c1749c5544ea7bc36b0dd223f5", + "0x75880a9c922a15652b74b9114bba464ac49626fe1df76d3aff3e6def1f8a9ff4", + "0xec8655c4f3280725ef24930f547a23988f57b407ca7962477921c65aa8d582d4", + "0xaf3830d825b5ba849d7a7fd8de3d74683191ca71eee0c5dc13fcd45892ae739c", + "0xacc6f31736270b88b54c0b51afc6c3d4388769a9a76befc1fe2f8c72e4e62c56", + "0xa534247fc228dab8d5d42a2d8aae86d854deb257a81c7ff19131656a3f1aceee", + "0xe2895527939deb6f2e6367642c0b6b13caa8a9888338ede14c60bf12bb5a54da", + "0xe59ac0c8184eb0936d6f5eaab44aefb441e5e2d1fe69e290868245b04935d924", + "0x48d2dd98705594a63855f3c4ebe02695f6f67b89703c3abeabdc11691d6aa10d", + "0x7e58bdf9588e2449e7ea947d05ea19c698450df9cd188882a23f5007aaca9e7d", + "0xa0974b5f82e5c03e874a4edb97557450a5280904c35d863b5f14eb1860caa681", + "0x4ddd9abaa7c78129efcbd0a47611b735c69d876626e7b13a5c6b6cde4ef6b744", + "0x065e3d364e47bd0f98ba30a89411954ea051e38b487d4344beb6fe59f5bb191d", + "0x4732727e9fd520893173d2a334a0fe55ac63dd9b49956eb13b2fd89a6e686f82", + "0xceb1f7c0b101f66014a7bb3483828026af59328c0a192eaf6e7c04eec97c4077", + "0x87d17806635d4f607567d24f1267b4a55156b92d4021d22dcc312af69a9f4e4f", + "0x1a865d70134d23472644fc40d4ba988f5e9ce3d24c43c39eff3fbdf80ad6a2e4", + "0x757160e251b8c79293c218ea60e6d3b453bcfe8176993a35ab69b067c5e9e2f2", + "0x1590a6f60eb7ade8bf7ff3d1f00bde5e06e1333b1c9c7ab3aacfb7b0d2ccb535", + "0x4262d42ffe1b9b0036b63a4c70df1d9bf0dad17cc646cab635757e9bb97804f8", + "0xdd1e6c9526efe954559d889158c5a0acc6ec7b9184b4323bfdd3205a25863424", + "0x3d713007089684f50ac3bbd9bb4b88dc17652ba2ad0e1e4e980e25ecaee6c63e", + "0xe031bc30250931e60bd8a220659fc868c8b966c34c94c65d981ea99867baf8ce", + "0x646d9776e8465e4cbad03ec86c25704d39f2dee031dff68d8fe4675da0f3a3c3", + "0x73130be5f9c034f7cef8e297497e6d3905ad9ca28ddc6ae4606b2900269204bd", + "0x76e319544cf0c7c037d7e7dfc5a22cbe8e0f08390f93b985942953c1c695ad4d", + "0xf5e6b2572536543da031afe3d1a085191cb363405b2290c95ea2b58a2777502e", + "0x07c89313a0f9582709438509df2eff3dd71d063cbd7465e5e704915583b105af", + "0x4bb2017c31178ebf59a614f3fabf7c3c4a0b52fc560be65a9ca018dd10fafd20", + "0x1aa73d4ca741cbee068e178e9457806cee040aeac414f407ec03be19c57d1427", + "0xc6f1b04e3b6d58a01a3f08a5adbbc29d531301e152b9e952268624472c4e53bd", + "0x99fc97c755b1307b937fec8fe4a90f874f62a734a19761976ed178dd1f66a6b7", + "0x1f60601cfebff679cd55ea8d164984a902aee16f9409916e30f12b83d9d8ddb9", + "0x2777d5ed02d18c45209d28adde18152b50565fccffcbf792fa9ad08092ba4f5f", + "0x081ad560b5fe6c1102d728e35b89294da36e6f2abfa7487b069824ce07e31067", + "0x4348d38b71aac331b929c1db4e33a7e3ee650dc7d7c7944b24b9c815709864f0", + "0x6522d302c92d109bb7a481ff1ecc01b9f9415ea1e447e91721959f5cfc64b6d2", + "0xe6e8719ed1687434dc226626d83e6a8cd317418e3b8feb41b677087e9c848658", + "0xe05f788540f52a58df08bb86344e1a0b8bff2c29cb4cca07b277e729ae20be35", + "0xc939ff4b5cae98c9b65bae38a2a9f0ecf7fab9dffd9d89f4c3c43a645b6b0ef9", + "0x3da552ed48e9cdf2325e58320e79083cd45c6c891e1ca95f30bd9a6cd74dca79", + "0x46543e616a4fecf94cd4d92ec83a836e072d6e075272ab3626927f661647bb42", + "0x10fb4585c8ac92719b0dcf6d735fcf3cfdd3fbd5a56acd53be227a3f96df61a0", + "0xeb58e384a7f55adcc5269da55ef4bde232dd9b4179757619f75a8bdba729877b", + "0x1bc53b776541a38ddf5aa1e21137a94fdba7a76f76b511b767474bcc8d6ede98", + "0x8d7b8db0737d9ee9612f232bdcd1c35be0a8536dd2bea3b4cdf79813391903e7", + "0x36a2279bdc7e5d17c8ba0479b563a5d3304f6e2ff472d534ee698315706cd4e5", + "0x49c45d4b2e3d01230ce8072d8b55f25b715b87a0f8b6c82cf420429435e98133", + "0xa62973c2b8c9e0bbfd28137a2622256e5094dd6b69003a84cb13ec22c57cd41c", + "0x0c9552fc3306720151bef2a6b13a24560b932e0d3db36b1b167d1afd8aa7e341", + "0xd40c221db7809051f8204e132793a7998f7c1b285c3a2f52a1de9d0a0262b703", + "0x77bd0c7abfb7ba1178d75537eef04a618a61e0285a1f4913d414dc1191fec41f", + "0x6d865ddc6512a32b54671ff7c9732326e967aa0deea9ecfbe811be8a66247c6b", + "0x64e4787de14840b123064911dcf83727683f4b59a1a60b2dbd2301aa50e150b1", + "0x1726f22f71e69d3e919702809f5be7b4a855f127427164211bbb83712899bb60", + "0x7a0ce836320b43e8fdb8b1789af8a856f97ed401167309c8b0eb7a99f73bf41b", + "0xcff5ec573970e3984409dd50d911dae041fc3a51d2035c481985f2d36a40a018", + "0xe308ccfd734d243298f65be9dedcf0320e5fc6ffe28bc18a4abf7cf30869fbb9", + "0x6465d11dfd96a8c36c86265748197b9ed81056189467520d048e320da8addedb", + "0x6da91a602c5b73550abac25299b46a2f8727c5f156c1a7ef6912cc30ac60247f", + "0xdf85ef603adbe64ad1d06d903bec6d0a136ec88bf4788acb4b1d6ef256c4f342", + "0xfbf21ccc3a80affb14aa36fc08caf0cc6babb271becbf5d7f8778fc2e8e2cac1", + "0xc9f2bcb111dcbc477ae94b7ad5cdb7747aed186c8336dac2f04c41efb8d9bc68", + "0x54eeadf4dc7b7d9aca271a0e1b86b1a2cec0edb59da9a267d2254a635bb888b4", + "0xcab9c1cb0ed4ee12496d612fede759e40ca4937d21a370cddfca557933795f5e", + "0xaa53a4d43024db7d7d55581b7c690d2894661b137dec89a667ee60a0066df278", + "0xe947f3e7cb27ee9acb3e21771fee420b1b8d95e8deead159fae0cf3d3bceaafe", + "0x9111f637e6470bc6b200fa0af8314fbc2a649432f665fe505ed6c35782941cc7", + "0xe07f2cddcc582df384760910f1e3b01d25c4fb76110dfdcc565e89c179317484", + "0xfe9f06aea3dddcdf1baab052506a89a671354e36ad00b0838414927e2cf7fcc3", + "0x84c6fe378564403f23d29c3d15dd1b15e6d376fcb9a95dcf6bbddbb32e18f154", + "0xd31439e688f850e75895edcd6af76c55a2d9288bca689c6955e3f83e621ab750", + "0xdcc931be9f3ceeb04edb4052abe56b79fbddd84eca955392801c527923178d6e", + "0x72c462d90b888f78410307496dd042aa6aada8de17e2b112bb10f245adb89f88", + "0x3bb25b18d8fcba475e66562b6a685a18b1ddfde6c8bd16bce45e0dfbc3a54467", + "0xe4678a3925c238589fbc5dd61fa3b22f8b6893b206291c5982ac9ad395f45724", + "0x1d493abec856ba109aa3e21afb621510c1abd38875ef1decb5d790f303d8322d", + "0xc8b1820789f1aadc67b6cc5f7f9a0b9018bb4aa274708621c036cf670db899a6", + "0x116d77b470c6d37dafbe4d2dc110d2dd92420891f18c2f5b8f43ed9341304502", + "0xa9b47217de308165e87d8a2df2778469b4304c39cd1d743bebdefc7eae435832", + "0xbb1e6776f78c94e0c37119952ab925acfd70cd9c9b5ec8d2286cceaad547d537", + "0xfbcaac553ac391cfc5578cfde41837465a132606fdde27e93706c64e4024b4bf", + "0xb39f16fc4baf58a30a6cc625bba7a6ef7427541fd3f44ec158463bd74494f8cf", + "0xf4a3704d5217afba230999e16a8af8c0df77a236eae8fc250aae3b0ef10c704b", + "0xb1a8cdad34ec1ef934bdf49dbc910b4f23346fd6fec4ab15617c77b539b9dfec", + "0xe773a6a957a4594421c4b682748df2ce0924c8299caf31e821d7f2da89ef1b0d", + "0x80703bf02ae8c47b20cdf35017460945d31d43c9004307a0f68fe15a79ff4422", + "0x000aac49cfcf7479f54da63f6cfb15c358e58cc50dcd4f178c1d48c7cfc70ac6", + "0x37359a207f2d1a5d483485e175a25ef1dbd1597593489e03da0855d5b73978f7", + "0x36649fa2d11c71a4e009fb10e118d00e6bcfb4947c7da998042766aa65509e2e", + "0xdd367d7be52578d809f2117f011bbfab36e9f10025248764f65b49c3e4c6f2e2", + "0x1100529aba908d0134d124c320ecc5ae5f68e55e2c83d81e153b9b84730e0348", + "0x12b9176f9dfacc4c0e07b233a0eeac51661c9ca7bd8534bb324c72dae99b8869", + "0x141374e0e24f1d70dfb9fcd8f49f42de1208cb7268d18bf11dbdf60047a4373d", + "0x5bc84c71853b2f6ec0e7733d7b12cdf644af07746881174157d25046a3cb0c15", + "0xc0b190e2f49eb4a8496985ac98feeecb61f8f103110cbf4b0f404f086eb90dc3", + "0x1baed721a6b29aaf434b0de72486e92c5dac340f846d0db2533aa74ab58c2fe6", + "0x7bf7d41ee40b8a20bf80ab71b9674ff474a9c0b2b0b3b768f4d177b118f55021", + "0x461bbf7146e4e95ea95add280d7b7199a5dabe4bf369dd0bbb6d74eb363eb399", + "0x38728b104efd235331b7e0e2cd519adcb8333682fd48e404dab19b5a0fdc1eba", + "0x841b6488a00830c28b4b1517134f01a071015124a6202abd48d7440b5f6464ce", + "0x00b07f0c3e6fe366d115950cace606137c284c418e6353adca18df07b4224183", + "0x09bf2e8d2d2ba69603ee2aadc58f87dee12a0a07e091c7cb98e18c00242bfe98", + "0xa94a6b1b9cfc8c6efd37e74635630eb2a5f4dbe1a6cea2d2f0b9ada691f49534", + "0x995162698367b47f8eafb9f2de2e8261ef17ebd9ff4565d6578dd32021b4b49c", + "0x51728725af93c6fab7f955cae9158aa0cae132b7977efb080320bd5540d4a246", + "0x7a901c710bb225aeb851f1f5b92fcf3dd1526018f34bf94cfbf0081b9e2bc252", + "0xff8057f4427717a343ac8a056043fc6f80ace0a9166d263a8d12c52c7d985148", + "0x3f2a6a04434fa68093777e69a0648da8ba8ae27b6264ae26f91a0322ae6b4273", + "0x875175a87bddd42be4f2115630976f143b7804da25737dde75f373a9da7db767", + "0x0ef0d47ca0cb90186b0db9b7f69438dd7d416414833b993d1facea8c190a2cfe", + "0xe70920e1e8f41cc04d34b2381747674d64dd87c892dca35cce6be3c21c5ff74c", + "0xf6bf1b5438ad9b45d88310b11340fd5f961e0c3f97d25cdab298466485ff70af", + "0xa86b8867cca790d03b4508e46425705b5755071f6b196a484edb26eb77d669a2", + "0xb2462de4b1149fe1c462cd4a944c5800209426be3196d28432d22d928a6e3b56", + "0xdde87562cd130db3a4cbdeb300e7eef5ecd884751b9692b3530253da3b426d3a", + "0xef6f3bcf6cd610dce1327131251c1febcfb2c8be013a2cdeeeea1d7ed2145279", + "0x49c449580aebe61fdbbe7b659956cdff5d34a3d7078f2d531e1dbf9e78fc707f", + "0xa7d87aa0df5d0f8c84f0a11ee2c5d00acf63cdbf98be9244ab37ee5c705c1991", + "0xa8ebb8e6ad2015dace964ede93c8014d4fa3439aab2cdca09100c337be0c87f7", + "0xa5e855d01efd43ce43dbf196eb94199ca4206ae95fa293d2d43dc58ab69eb5dc", + "0xde56b2630dd3988a67d4c1a8bbfcbbcd90c99f0162ce697df8ba5a2fafb38681", + "0xd1d6195544c51fb80f41bc2ee4ee73e44536d8b2d2f478d719d72f0b7880c09e", + "0x2691de4f1ef0d2451f07454d5419abeb80502f4460bf365984d46a7343d47239", + "0x3eed848da0595777b65d377857ef1097d7c0e9d812bc0b1c334e94a3cddcadf2", + "0x82b5df95601fcd73e1aca3706974e9aa9f704d02715ebd750fd0603522850e72", + "0xd4597a1d9e91391da18fa148006db4f439ed269360a8415b35ef74eb3e767f5a", + "0x3fa8dfbe6d64ba346d07559d4698263e63d8bd456f114eae1416bb993d99e64f", + "0x4336ba517815c335dec9a08e7d1857fd3e668a12dc8abb0085193cc6dfb60463", + "0x10939a82565c112b767fa5d4c5628a670c5623f1c417a175d09becb077aba66a", + "0xf3211211715089b537ae8c270d7bc0952bc26994d070ae4692f1aa4c850f1747", + "0x719010b1fea904cb96f56b5a16c730839f030fe8f967595a2647b57b67a7ffb5", + "0xf6c883fc56e57a70259f1c1b56e94581efbc18115a13e7a83560e32458a78c6d", + "0xaea535f44b812fae7f3a7e216d695c4b709cfce4869ee4b0470c6df99a6abb06", + "0x9e659a2d3d72b13a65fea0396623edd3c2491d309ab195ddfde6e83832bf6764", + "0x35047f5b4aa180f07d47273ab0d9ea3dac5bcaf5ff3a80ae713427a3aaba2f1e", + "0xbb35cec8f1b8fc9707994df6b93dba18342156add6290dc6f906c8c06988b080", + "0xce5aae3a026f15cddd8bcb904ae984b27364c85a1db01669eb437a1d2ec116db", + "0x5b80480132259b9f159917b9af112113ff6ab2c9cd3587080c4b45118c9f5912", + "0x20ee0b82e04f86a6936971893aae1dd6c9f4a03b78d0ca6e5af1d195d8779b7c", + "0xa4a90b7855d6fe80b403c5cdc32405ef1156ab83015d8a1634560b4046aae931", + "0x32e97984751c36a6ab0f651b4675d70c8b4ee461afa7daae6bbc65760ec7029d", + "0xc1c17b3f900bbbaf392ba82c480c90b706079ae1c559f5edbe9e8cd56b0f41f2", + "0x4314478c7404a573d1e17600f07209b331917459c6756de910a81071f4e468b6", + "0x6256928f29827180db86269ec33ca31e510b8c2bc287aec00281bb4599cffda1", + "0x91ce6107d89e783bfd9887e9f2cf180e029c86886287357cc36cfc29fdfad94c", + "0xd5937778af97763ed36c35a9955b1f840c5bab2032b3418c11537f896596af75", + "0xbc3580fb9dccc7f6a214e4bd3c0c09e2e9a8b8a8e2de20c841082465e9fd64a5", + "0x3a1936cb41e17890be0e162ea95ab908f0612c20fec62c22c2bd7ff1947d0482", + "0xfc4c9e86ee1f824fb446a966073bff965fd116b1618904e9a8397cd586bc7107", + "0x6c66246c94ad6c8e2b8b7bc90690775338c238cdf431e53f4382244256a5bb8e", + "0x3e56991487b66b41f209ee749d817dfcdc1aea634ffb0b2125d4a086053f9a5d", + "0x6bcfbd7381295875e2d7a2f1d35a96320b0d222ce8187987b9ce693d1ce0a5e2", + "0x4580fecc6d2f4f9e68053b3067b931b252e5140598120fc3d593ae2add79da85", + "0x69afbc59d9d5f2aea003558cfc32bc0f59fbb28bcbf048e83e67dacb2f051a9e", + "0x6f20a07738f02c250baf47779acab06b31ed2713891621cbdbc3a33cb1a0f1bb", + "0xec3ae039172c3f35b12d185048c7ae3e9ebaa9afe3b01fbe9af9eaa8d132ab41", + "0xf8953caf4a7078796d54a797424db24f42e22a1257110f429de39365f87eb167", + "0xf83d0408a57377c2ef00481c15f0fa35ff5bbc53913456f2ffdd074614b728d2", + "0x120474940e643c946c9b1d0411ebe85441681cf7674dafc7f437085b78a26fae", + "0x7639039a138a51df89c0c06c08353ff3baa86bb5f4846860b62727ac9e98b75a", + "0x0c334c25b7bc1d64748cf6b1a21b64ca859762c239b2bb63aa66f0192bbe9e82", + "0x91bc6284b38b103e31cf20d99b8f94a5f2a8714e05ac021b8139e51ed97034f7", + "0xa119da5d5daf11ec238315f7eb7153c980b7df420896759b05d6e0cb9c15b099", + "0x478774c200ade9d6bcd6ee55006191dcd262829396f5d1a33c5104838fe6a998", + "0x72fdd84d4358dfb09c172e0e91f57ef0706337e9e9e6de1faf28a5ad1993cbaa", + "0x40d5695aa29352d0b03f4e367f03d50996a7091f5210774bea024421b4ea2efc", + "0x5ad627cc00bc5fca0ad8ddf5a09d4e310948c41c54d8650da28817efa05fd8d3", + "0x090a72d69f2255810ac423e447d0118afe8fd4d656d198f9af6fcf16725c2cb6", + "0x16ab98a77e42ca0084d5b6f0962c8d9729569a3ee5468f404b31046d710be31f", + "0x40f3eed9711a132dc483b6a1f911d386228e67b12d23d9b30c4f476bc7869290", + "0xa92722e58027878eec3a115f41467b420af8c4ec901f8fd8b2cda0208e526deb", + "0x1f341f622cba201761ace6fc164b5ffa90c32cca3379a9bcdb0b215d347b2c1e", + "0xff49ac00c27cbbf5da17956b19371e5ae8a288fd6ff7562b7f8f55d6bb356bdb", + "0x6a856bf3855f801748f3c259465a30574eb720db4e4547feaf9a6a3c8fba9b66", + "0x4367b7f1597bfac50a191888271edb84e9ccbe98340a3e896abc1410f6c2fd49", + "0x3a5dffd2b7db4b4437983e21126581c6f0e5b2b2fd7a62e3b51caaf415a7488b", + "0xb96ba50acd12ffd0e253514b8a9d9f8a2387a35f6eda3a63666e7a0bb5a74536", + "0xedc56a3af991603540ab6d8ac47c383e5429213abe2bcfa6e48ff9b7ac4df978", + "0xd9248991faddf6a9e2939921f8129a2b88ed785c0f0e41a11c16ff2ecc76945e", + "0x788ffda4f94d6cd932b41956dc6d48c04b17e75a019ddc66a452ee0be582d324", + "0xf755360190f6621f8d319a0a3169b62d0ad47561474b705cda88ba44b4ff7f22", + "0x412e8de38edabd1156e6c9f948c9f9aa0c896499f77aa5332b000cc70053d868", + "0x8ed82eae843f37e7b41dad6a309b6e2deb3e7ba09ecda1083e3896e593bf38ac", + "0x450ee983d78f5da457d1d44e83c2994194bf0f88d16365385da07a6475dc278a", + "0x068f39349ae7b94ba18f55e5c56a4d0f4fee5f3d6506c91dfa486956b886cef3", + "0x1e0ba420bf0a554523d73b0d7dde4ce1fe813feb445dad74913fc0d60a2fcdde", + "0x51dc8f1fe4e01e1ab6577a8e82506dad9f0269dcb4fd3f355edcea3565c2759c", + "0xb1dab28ba4711c54adf76b9606b6d7dcf2b9c6e2b5957e9e97350e5ba703a3b4", + "0x51234eb88a707e5d6844d09c1549a2381335d49cdd03dfa92506713724c25591", + "0xfdae48e9ed96dcb8eb3ccc35c84a342e9e5314a8bb04e5e9dde16e9281cb918a", + "0xf9bc67cfc4401b08c467a61590909fff1442eca8f0be2780f28a5a9116a08655", + "0x53212f1b630a1e52f27d7698ba7bc9af6b94178a7e57ff8861a8c9d0ca9924aa", + "0xad4b53eac401436504a3768f2784fb72ad48ec2ae1fd6f80e842a3fe26836be3", + "0x11eca84857ac81b5085dd50a4a10c8f032150c215ab8229ef4335fa8c6340465", + "0x41c288fdc4d9a9406e987d90b11a3728ed3c9a77e20bb7e5ce34d62ca5166b7f", + "0xa73bd71d818dafe4633209ef735c6d58b086b8c805442bb57fc46ceba9a7517d", + "0x80cf0b2ca45900bd5705c14c025c53e1cd4f180130060e8fa8f7112074300c1f", + "0x5795c53dbb9fe7e3a9b3998fc213a4961d6716d58e2c9727d3aa2d5ff7758cc6", + "0x18d7ea60dfd5e763aeddd204fd2654b52cce96a4737e665e67a952d7f9d40a32", + "0x88955311540d5b5333c728f976f4bfce14a07839fd3c4d9d8488a12cf99c38d0", + "0xf818504defde32f54d398b607eceaa073e33f161eb48f606cdcc203c38490577", + "0x845a911cadbadd8800dad80b820fe953953df4d0e2d5cae24bcc2027a6ddc08a", + "0x35a1001cda605ea277494b223a6835667b8ecfe4b5f733444bfafc760efc2d12", + "0xbdfed38c959847df8ac6f43a301355fc1ee46ce0906da434a4db7d05ecf1688b", + "0x5f1d4b9dd2efbb6bd0649c23f214b055a14f02643bb75b14754cc2af4901825a", + "0x6a8d121588d21dfe2e94a38bf6aae3de47e513917a61f5b2d75fb5ffd391610a", + "0x0dc0cfebad3445a400760669f16d711dad869a4e87bf579d0745e6307b1203c4", + "0xee23bf9111193c3cfa4173a224752c6e8c52e2b87327d6aa6164cea231d29b6e", + "0x37a2e1540239c7ccfa424d72f2092601873e8d0ade78e4c5b422a7a3e5ad3bb9", + "0xcd9b85e253cf016c1e1d8a6479387c1d6e460bed771e6283462064c377aade65", + "0xa1e924b638bd740dc0a8710c188d3b266e3e40fd1b1711dc3f30234051d1c552", + "0x6cf65402fc320eb643b795fcf3878732799389d54f59ca521c9d265f93b5ca9d", + "0x88c6a984e2d74c2d6ed90de3e7341764e2c03e640226c36d895254458f18799c", + "0xb8947441ed6817ddb0206da8ce4eedfaa41adcc461f13dd260559f92cac0507f", + "0x92f4e68423c159cee14f2feaeff830ffd973c386bb9e09a8620024a36814d858", + "0x673d7a32c6c60c83431915bb032bb0e41f26bb0175ecae230041070c62a09042", + "0x7229d4e3eae51188ccd8cd1c65dcef8cfcfd42ecf39edbaafdc6ec49b43a8afe", + "0xc1087cfd4fcf9f1447f22ccaff5acf35148162f06957002f0a49e85cb703c1bb", + "0x08c0e8cefeec470ed1c4de8117a55c9ba975e3ea485a284b4944adde16a69c5f", + "0x3c3311722c540c28ff86b1ba17c830c537b5eb8fb60f3957404c3da7746768d4", + "0x2db506655cdd06836d09a478ca79cee997f3dbc58bffd49d89b91f449b7b04a1", + "0x9b648bebb498ff6c37d4101cd78f1b3982c54dbcf9fe2c29ebfd2f9b7e04f099", + "0x82c680a2a3eac1238adddb76f6f18bd28bb4818fb30cde24863dc197dc8ec13e", + "0xcc8ed40abb13449df851c4694088283228a9eebc5d3e30bfb251abc02076bc9b", + "0x6b7b737c5a012fcebc781999145113a89e44f1275938201ebbaaed865b78fbac", + "0x795483f3990d7056e6557356e0ebcd0c1a305534b9ad22c40977a471ff765008", + "0xd50325af06de4c2dd53c51a1b68a57b23a1dc9ba1a1ab01299bf3da48e0263c7", + "0x481ddc79fd4eafaa1405c85748602a4012a3ce668021399a309ad7530f17d1df", + "0x776e02940d65eda493f5925362bbecb2e19b088fd51a044c5b5091bc0908edd5", + "0x89dcec4b0df855daa6ee38c26228d1f0f83e3efbcdb8c9f743ee544559f880ed", + "0xd888802df592a2c8779432354f50abbfd89e826795bc3ad204a8329031e0f612", + "0xf148daf80df025a45bd6767db4f260685ea2c8efca1f4f2e1f07a1b46eaaebb2", + "0x42f87796c2eae0d78af26581f92960e76582636705fa747d52f94b5ff9dd672c", + "0x5a7c25f42a4821d4c2a8621c8fddbb0818df1507fceb2f9bce29b737864e69e5", + "0x7f339843b3a45076d4bbac3edce392ce978318ce4fe363a1a5e8a851229fea4c", + "0x66d1bfef48f6b3c695bcce0e1c406bfb413cec8358c62e718880e9531a2e1188", + "0x1672dc0afd5f480fafa3d5d76632e9fd24bcf2f791c03d4b79ce26f2a6b43c40", + "0xc00de487ae1557f6dec118421611a654c3b6e9315f807e18e9285ab698d62de4", + "0x3fd80e20d89463b793ee947515aaf2478bfaf3b76c476b57c80f594b3601a4c3", + "0xeb5dc70e6d66098fe7f431ec8438c3c0ef664fc449d228fb3717cd643b0662ea", + "0xc95e9fc217820b220a1dfc8d80555f3abde3f7811f7719084d5d1439a65b8cb1", + "0xe80d667231fec8e334dd88133150bc6e5aef23d4dee2b15ff9815c191ce30b5c", + "0xb35c99fbd6e410abd0496238bf7e66d68b2c452848d852a46ebbfece862c6f46", + "0xd434d46f3e94dad8a411881bcae2db9cb99506ac8a0354c50586cc81c1867f66", + "0x360bb1940475abbe7168c9de22e43e1e711883e9fb614419dfc23ee3b301c1d1", + "0x8cbea95b1ddf914937d23916db6083e6044b8c52617a71ed140cbf884dca696a", + "0x3cfc521239386fdb6c7c02dbf20960672c5118b5273bf51890df9ad31a388c99", + "0x6e73b52562133ec4a8cd389a352af64705c2a1318ae99b2dfc78dcff1d72319d", + "0x86e6f9bd9edcca335b9169738198aef3a541a6b41bf58274429a29cd0b3924a8", + "0x9668e3aa0d09467be183c811485203df5e10f4e332b2f033f4cda7369d90aa3f", + "0x4b5e3df053f882204387151c1e7120c0f7086a9edba0d3c2c3a505c0d61802c5", + "0x634c9245fe89685be14edb30de2543a878c97fd7506a9b186df5e064b286165c", + "0x10719cf7fb4a7eb4b70192a8494dc071ffec3fd37a17b7ceb10bbacc4cd3c132", + "0x36766864b6d50c50ac2b75e2b335a2b143a1954d61f57e7827cc205c33dacb8b", + "0x4160390fedc6faa039c11711fc2b9fddb40968b534b370ceed6e37e37a0fa437", + "0xe1a28cfb5ae74d7adc0e0e0dacf0f0e197af1ab27626de8b5a56f4dae938a8e6", + "0xc2251525dcd1a93c21f4911f525f8ccfc36a6e4f90b4e275c8bb788522607618", + "0xad403b7913b7d705db6628354f8621dacdd4c91b6bb60b747e6ba6080e37e7e8", + "0x2f67cb9ecf5c4678d1d27779730833825f0bba23ddb3b3c2090e22ad7deef26d", + "0x07df980ce9fb75bf368e179a5cb7b4af1c695aebb0342f25d00e421016281687", + "0x8a56b31e9b9d3c6b2b153a32c99ef4ef65ac34911da645a4556d5813d6505283", + "0xc49d0910f95d400041dcbc98d8e2d95261c2cc9054c8c36a94cd18042794268b", + "0x2030bbd6de4e34c41df9a5471601df5980773ffd594fb8a80c2619aa20a7d427", + "0xfb1ef5d538b7db8c1b712fbd6002357fe95aa9009ddde8df604eccbd66b57a0d", + "0x7a623749e4bc69d3c1ab3670dfc992e263278714c8876515a99a06ffd91f63a0", + "0xceb9b81c22f6808affbfd3a9e049d7e3890f2b54da827d91a1de11e790272c3b", + "0xd68fc65ea61dcf560631c3ef0f5c078086fd6c7b6b4c0d0ebb231e2a07a4a230", + "0x36dc7267df912c83c92ed9f53ead40bc2ef241bdfc62f0d7a4c24e9aa8568c2a", + "0x3abd8e1e1950b65ca1198bef4bd671546ba59600f017a63ecc656070f77624e9", + "0xcf65057e90df4030c8d37724fe2a81f00728774c9965302aa90f8cea36cfabc6", + "0x7c96f5fee074c4cccb1db5b3b396623a28e41a430ed4c5aa51175f274e65d1ce", + "0xde71773646c63b3a68ed6d6ff26f1760b68e497d1579d0de51e372ce74d6db98", + "0xf0fc0c493d23d02a7822ca306c739608929b4be780125f8be038b3314f57de3e", + "0x6230ecdc6b41bb4e2cdceb84f474c0845a1762aa5a3bbaa6ee11813be6f1c9f0", + "0xb201eb0d085a065c6371973c2c9b13bb783bff3fa888f7f06e7760f8ea31e4c2", + "0x1b2055c094924aa007c23f8970029dd6a4e4042efbd1cb5876092de0abae3af8", + "0xf4adf2731dd675c33673e0a2a0e964f14fc9c26081e7a3d9dc9567b61f194a9a", + "0xa1b61107f1a84d5c629a6126eda275fbc2eb34ed171129d432654345cc5a368a", + "0xbaaab04bce4baa421f76a029729617d0ad72de8926632aeb5e8050deb16c3cb7", + "0xf2555f067f8855d2381b298fd78a308262fe8bfc0fe6807a5cb923dab9a0f519", + "0x86dd603d29b186cbdef1cf6958e9d37ad8f8092aeef7f19f5539853fa26b58d3", + "0xa23cb2599d49f0e93608835c375386936678ac58ae14d87c112b86f0694b5596", + "0xd358582a0445ad0cf49dcf89e5945fba4f62aa42311b2a31eaac068817f555ce", + "0x860ecd3efc5d8dbc40e5cc6786859ca07c85fe40ca959523739b62b0e4e0fee1", + "0xc772b9adacbaaefecdf5ae2ecddcb9a6c2cdc141a211875465d3bd29b00e14fb", + "0xafb210d709cb8b0ba068a9f8fccc5d138e1f84d03d26a6b3d854addab236ec95", + "0xbdc3cb79641e51c9f707d159c9d88c2026258b6f73e65471c0c25527969035bc", + "0x5c13fae2b3043759ccaf48d9f12545ea32c27bf7bb66e6f619eae2f417bf821b", + "0x68a007f921b6e70f29a1d6d16f9656f07476f371fbf9a1c1a7acb5c2b609bb30", + "0x183850e4f92d307db4ae75ba4695f24bef26eba825b4a51575f51fab0e1a6f27", + "0xfff3b9a3742d7ef534f50a079cbcc55833faef098818277d6ca6371ca3d753a9", + "0x78ef8ce32497df07a7bec9add4b07eb81b42590f02597249538075e41ab6dd2c", + "0xe58fa1651c0f44e0926bed37c52a60665d732128a34db9703830cf95df0e7e67", + "0x6b7b688c0b98a58621392de01a9bff28e86115cb9a4f884326d29a2d21667bd1", + "0xb5df489fba833ac4828f5b3283289eb327feb115de64e7b71b9d3128762be589", + "0xd12a2a88f3b740960fc2155dcd81bea7e8ed81a4d02a78ba18e98aec67161783", + "0x0b22142f3c76af00919230cbc5b00d7d263c5e85647d2de8a3e6352ba02cad64", + "0x6b4e299b6771ffa71a09f9b43bb7d573b3b76df27abbb167f3e5ac711ffa751e", + "0x19a3415b944a837037f7efa5fbba4b005b9d4b91b9d8b6365da23e54cb8140a8", + "0x0255c4c289bb1520a8f771e95d3863d9e3542eb626d8448391cd8e9aa2823855", + "0xe304bf675403603fc39c4160e20b47624cfccbea2a371d7613e36e47c8251038", + "0xc2c138a736de8ef11dcc3317ddd89dfeefddbb20f8cbe9b26e6d58f0fa0fbb3b", + "0x00c0f43ab18e8ae57cd4cb88ca1074ba08dfc3e7a493caff5d02321f17d3f96c", + "0x3840eb9a35e137d7104c7bc4e62a2d1445021aa136363e0fb463d0a8ccc24cbb", + "0x6bdcec67ee09dd0cba8a0fb3eee93bbb18f947607b8a0b9c8553ebcd6d63eb16", + "0xf63940a931f3171b375c2f55d0ddfeb17f34e4b37e671591748326e72a5d39b2", + "0x45e659968306110b827b48998208ba102a8c28ccf08da317e34c8951eeb18f8a", + "0x2f6ca4bee975b058f62fc48bc7b17eb8631c4ce36b3f7f1f6f7958811b7a34c0", + "0xc1daa62e5add1fe79f3883cd53f3cfd53ee29d8934a0d49f8c339347cd276739", + "0x90b542089fed6c8240d9367e60357bf7c685775744c57b079867e0a724644184", + "0x62e290067d8abb0e1fe21a488cf54471d6421cda07c80b01ab750d3d352186c8", + "0x3d42eb2d8d2639fd63038f69895b00ab04d92b1ab0a0b7772775615fe2a8424f", + "0x4caec53a8c0977a0f38813cd37458c783709da6d386dbe0a0358be87482aad15", + "0xbd8f3c60b0b998d72cdfdbad6fefd2ab3762583f4efc8606f62657d9c05cabe1", + "0xb6ec64aa2f81f1d5cefef4e819dbf54e8ed9f018faeb99e16c2560ceb3d82533", + "0x0acab9585bf5d17fffb1c0e479646c8a138670f181a1bc9b5fee71a396b24564", + "0xd9ea8713827ed39e9d0a8c308f20c567cda99c591b9777ed40a5b878e2454451", + "0xe7991c113e4fe09610a4061dff84bda3205bdcb49ec137340f596e03c4a961d1", + "0x4e19826671fdd3c0028c4820776eeae96ef435ed23f07c54b2393a517caa968d", + "0x4ff24d17dd4b18d0ca4167c6769d20aac8285779da23cf8f56a12cdd9806933f", + "0x6a2431fc40b88341209023b8898c7e8e8f28b6c0d83225d597bd445382b6fd55", + "0xd8be9caf486a1b8f3ed5b637882d2449a9e89dffd582a5fd55bffc4fb4f85418", + "0x54d6060edbbb771b06997b4dfc6fadac4b76fab74908a169b06201a13a0a22ca", + "0x8b461cd45b90b3c062c801349d4f723274cce36ec256c44e2d749897da891627", + "0x46fa69a77abdce3a0298effcc823f9e69dd22869ba26b4c1d01541bf2de7937b", + "0x13279e1b1ff0c1527e09aa8cd610c1aa54328f88c4dffcebfe41281c53a10aa9", + "0xd1ad1dece0824c9bb0b7e09269f813a1a75e4efa1eb6cb93ab1dd42119223f06", + "0x46243b104f4399a3404db73fecc1767b3308f4d51df8e10c306c648901a064b3", + "0xfce2eb01ca4594199347b46eab5c889371e7d3add681da4d36595976c5f7fc58", + "0x8af66d1c12db728f09018d3839a320f82c7b27b97000f9212989699c78e6c26c", + "0x545d857048fedaa6de9e10d59aea4f3369ae1ea2cfd4d990292c15bd7f37e182", + "0x63c4467f63fdf41ba4bdce830189c6421d6c67f3db531ce357e317123412245d", + "0x6f4305c01be3eae45809e6caf06360fd9690cc39c305ba5a64dd47811882a16a", + "0x751d6be0d942d718f44cd70f10d1611db0c4c89124b76b732b7decc1218959a4", + "0x7db5bfdec57bdc3b74e47bdcb41cfcaa642927e5eb436c0c76e36a43a02b62b2", + "0xa75bbf12e95613fdf3cdaa4badf1d340af7c6251fa2f649737fb19399720e7ab", + "0xb6cdaa8b0737001af40740abe099a51857a35aef0f209e859db01480a2f23816", + "0x1b8f7551cee4eb0e92ce6a9f0b1a4e4d943acef65e2ac65f2466e4fc2272aca6", + "0x164c76393945a764479fede040f13455768aa3ac44071acfff7f96b59f8332d1", + "0x561400d0ca3d1f322296b635e7b58d7266d65739e0d4fdfae898a9c49ce364b3", + "0x56892960f0c37d7513b88b7f99540aa49bc92e8bc7256bc1c2fc990a6c84344c", + "0x493500d343bbc38b73f289a74204d9186b34f477705f9ab32dd92892209f011b", + "0xbb713e726c6c4b3a8206a5a05e3c4b8b2f27aad052fbfaf385f16ae562573309", + "0x5eb20169a44963f8c1011a5940cefaff81139426fa200e6427bc028d8cbbbcdd", + "0xcead0359164f39fd00200de825cecc63bccc8cb76bca930262f5ee625efd234b", + "0x4aea59dbe3908afc1ec06f6d891236e906f135efcd28347c766a2315ee662640", + "0x0fd5dcb637ea55c9ed20147153e7ff1bb578832452c3b56e661c7594f141f712", + "0x3904bbb37b1f292628ca91fcb546e947f7cc52e827487819116449b739aee8df", + "0xbfe3767fca8cabd6d18d4d3c4aff79174a373082d6b6d4a63f2d03d0a64126d3", + "0x3793ae1a9b7887b8cb1f2ca995098b73bed8865c47f02d5ddd4e5b968a404ae8", + "0xfbcccfc208701b5ef22e6390f91b37e1f3d8f7a8ffe47951e5ae9cfcb4f28e5f", + "0xc5bdca16693d60334353a58233521bb12bf80e4312e63618f08400bd51be7876", + "0xd6896c40cb689153480778c4a46edffa531739573f08e3f3d0c9013e9f4532fb", + "0xe4c31595f204a44aeafe75779dca0ca894185b3e2627cc4e932e432054e58057", + "0x1ab27949919c75168ec496faca66141917449e1cc292702b52f165f3c224f5b2", + "0xdcd8131d8a1e98342029c3ae4fd1045d0a3b3a038e7dbd8e13fe3ecab30d13f1", + "0x373636000f911dd05c0c412ef69fd5c71888aced86d721ca6f6d3a097fb6243a", + "0xfbfa33ec677bcf4ad9b9f9404cf6945a2f2d0cb4544436d97b0615dee48e9ad0", + "0x4cee41306c387e673b6ae31295a331ec122ac2dcbc1664fbf4634c55c8f3df19", + "0x0df90b24ac4280df5a90a40bf1e1f6b895d790d7ad36ab863e80ee1923d71c81", + "0xce57e7edcdcfaa1d4d020f955e3c7c84746ba8a77a2dca69914331ae6a588c93", + "0x2857b09b2507973040e63fe5147f8c0722bb31b494f122187bd9ec3a119868b2", + "0x5edd2c25d12dbcb1b0083ee471f3c8d3562f8e812c7368afd39bccc5a8a475a8", + "0x0eb3fc45bed06182648ebc82fce9c599973616c2dff37791c014d81b72bf7ebc", + "0xf0daf44cc73cc1875444b8f97cbf96923ecb1d2406e6afdf30be1ebd67170a8b", + "0xe6cf543cebd12913b99e51f454690b2e6fb54d885e06269c7dd1dc940fae79f9", + "0x9b46655d15c4c8e06d28f97f8655a1211c97b32cbe932a1167040168ed757017", + "0xb48a7111ee89b664c7b3fc3552fa3ce288598880e3c63c86ba2b40d0f1de47be", + "0x733d13d1ecf3101ff428d49e3cd50ec300ada80429f46ec9621d308920e313f8", + "0x02bc80564388ece34922f531ace4b429925990d68c42226303ec2393ac4c8d72", + "0xabb2831b72888718eddc4575d79c31d5075f7687c9e6f7df9c5b1e3f672735bb", + "0x017650f52c51f3cf2e7d82ed8b757206873eb71508161210b4f7320089875b16", + "0x97d26f102797f52ab80bcc786c683b3768f54dad05b0cf5d2f7c69f7c5e4b477", + "0x8e01eb81eadd76e276e853bfd3f052d9a9d05de552985a74f4c51ca7c702cd32", + "0xaa9dc013b931a332f294dc074707216440270a27774c7928882cec0124a84f45", + "0x4d49d26f98115d18353e7c15cfbeda5cbb0dc3757a152fc486079565ec05f744", + "0x6dd93f797d1983445c06e551ab46dde6096110dc602aabf520959cbddaa98e0d", + "0x5af113b1aed1076edb16781bc9116dc2d347a178ed6c1ccab4d89d66a2801dbd", + "0x193c02baefae0ffd3e3a7afea1e7e1ddebd7799eb511fc7c62628fc31866c6bc", + "0xf4b7f803d7e61cbe2a08a4ec9b814fc3d70fa9da89a8eb58e93868ba95fd4f71", + "0x99a2cde1e1b08a6559bd4679df647911294be7a73cec0f8c6bdeb0adbd914073", + "0x3ef3b1292bba31f20b5759d0ae2aedd24facd710f837d5373460ce1be08249f9", + "0xe158ef6d40a5b798a181d561f8494c83157478b09eab7c08b438c55498297d76", + "0x466b6c92326aa974a81f77b3b365d590f5ff3387cf6946d9b26a97e8c6c07599", + "0x71144f5a9b95b05102d1ac52c332de9f3ee054937a0fb6cacec61c230818abe2", + "0x43857db3249a1efb81a8aaa934631ffaf6087d7d95e99b8b7e3a307088babdf2", + "0xd76ab08fcae444fef658d002d0ba8f0fb10ca37e2190aa848fa765db9bf938c6", + "0xbc372c482f74e1c5d04a565ee4ffbb470c376da174ea317d7abd6de7f24cf9c5", + "0x9033c56c26ccb9a08332d0a89eb22560607964e29aff9161f6736f12f7473d3d", + "0x082d2acfa4df63deb929cb4514cde04faa0d4a06d53fdb1a58de3ec3fdf4fe15", + "0x2ea6011771c74d920c395caf9c70650afb4deeacf9d496007d03baff837a689e", + "0xdac8c9829f362a81e7a88306123986375d2c83b4cba0dcf1998e44e4692c256f", + "0x1d3fc9c51b3ccf0ec3620736d22ba7123441a2dc334bf925c75ac395cce6d74c", + "0x4881784250b53fa771634929fc34fa26bff9666701bfea61dcfc1a8b6ad012c8", + "0x8a33423f7fc2f11af8ee8beedc8b7e21cc2cd515a6c5ac1a55918dd5e2b16e99", + "0x3fc7e4707e24b5af35c4659da17186f4ce36d526fa91a121f4b9c2f3084263b9", + "0xe104a42b2766455416e0ee8736c1b3191822bed35fe36c01b5e3436f83157ee5", + "0xb9f270344e24eada673b5edff6f07e6fdcab6dfa89ff5f9197115cfca40428f9", + "0xe10df92ac34ed8b77c25d1f5c3f7e4dfb9785464e80b5752d641d986d86ec718", + "0x5baf89908afca6661198fa8bd6af1a08ad0c055abbc724801deb2f5772532c70", + "0x234c4085cfd920d8a76610df100a57e2c798d7c28481e4ee0dea38429691b061", + "0xfbcd104ca8ab7ffaade1ac59a4d9f62969035ea2fb40b54a0207292eae753e89", + "0xfa617eee82fc7887f71bbe0d38ec6535f58c14194441680de7ed91e6156e338a", + "0xd1e2a7c1b81a765293272287e9cdffc50d36b01bf884b1912f4ef37cc08fd7fe", + "0xd9ff3c03d42cecc78087cde6c9b3c4f699c3f1691adf0d3bef421361cb47c794", + "0xc8dd84e4ddac7535547b103be4023f54f74ec0c24e6140314232e1a65d2b4b67", + "0x80e188b2d5f02e63498e455bcd45b00a97915971c7901f666428e8d17c5071aa", + "0xa3378ec252a08d59233803847d8bd8ad275b78bb64224998b4ae308559ca3937", + "0x362ca494021482f0d9dea4abd844ca11b71fbeb0a98e7db7bfb3bb6f864eb58c", + "0x09ec27c856f50888e4634ffaca66f8185fd13e0bb2bbf522ce6209886502c7a5", + "0x24996d2f96618887c1c5e61d5d7ce6948853ca35811d48f72155a4778308e255", + "0x4f199a8efc8615c623902b5c279dd995ac1df4654a07aab0423e070d14bd24d0" ] }, "nodes": [ diff --git a/ethcore/res/ethereum/foundation.json b/ethcore/res/ethereum/foundation.json index 061c435705..8f96a842a7 100644 --- a/ethcore/res/ethereum/foundation.json +++ b/ethcore/res/ethereum/foundation.json @@ -181,8 +181,8 @@ "stateRoot": "0xd7f8974fb5ac78d9ac099b9ad5018bedc2ce0a72dad1827a1709da30580f0544" }, "hardcodedSync": { - "header": "f9020aa016c0aa39e09bf4ec53d630cdea0be984445c6c76f769b1541ce6b11c281c2fbda01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d493479452bc44d5378309ee2abf1539bf71de1b7d7be3b5a0de05c24d96b1b9012d7a875feecf86924d7a8d98b00fd0b9b7768785088edb01a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000870892f443c80323836ab801837a121d80845c2bdd638c6e616e6f706f6f6c2e6f7267a08f47201b260e0e422100cebf3d61a6acdcc49f4a24e0b1e680e26f13bea9dc4e88bef16aef8812be32", - "totalDifficulty": "8531065961847479229671", + "header": "f90215a0ea51746efaaede944c3397e41ae72b7908c8ce25967c1edcd02618b068486feba01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794829bd824b016326a401d083b33d092293333a830a0aee38c1032f191c3d42cc581f53d31adb1f0d91f463e6a8c12fc35fd1db58d5aa0568149713d45e959d5d07624917617d0d7865124c25c28eb9b798013096ddeafa0847bb20a0b62d1d8e2b467c33b28ded6796c556cd2b2a169b640b40e58fd2340b9010048c03883204a1ef0204300012248c8841814900c04362858000450c8927a22a88d5b471c4869c00001d8641080695910c20801022c2910408829a8002620115dc8200ec2851300611284301c3243e091030706068c8160505403250d03f44437410080072a69048082b43070805d08424a021328221500101418463040904ca094a189c801e50000c41402603426c4701a6302e1023040080d8380e21d600a2083003a2604082001b183068d1470840a49008a514148800a08030a8002c821b24010f20ea31c55060582801c14483ec29d4081c7152d2244840016c123da6f42249b6002c8401618a0000a8c8df892954d8080800c160244453086480d8264b6870ae8321581e6cb836ed001837a30a08379e5a2845c72b9c0947070796520e4b883e5bda9e7a59ee4bb99e9b1bca06883c088b374f7c667ed0fda0f1ec7c18890c892b88f14b41f03e7d927bcca82880db92c004f0313a8", + "totalDifficulty": "9242028122621986440675", "CHTs": [ "0x0eb474b7721727204978e92e27d31cddff56471911e424a4c8271c35f9c982cc", "0xe10e94515fb5ffb7ffa9bf50db4a959b3f50c2ff75e0b8bd5f5e038749e52a11", @@ -3598,7 +3598,138 @@ "0x43b9d76f1c2bbab800dadc6ccb88b966ccda198e30068364cb9c0b9a346f5f03", "0x1c9ae4b3977a1d4969ef3d950d2c74548c8b44bcee652a65f7df128511b84e48", "0xa06a1a6ba91e429f805640faf789214f42be0d8d574065b7daea7daa37b05865", - "0xf53ed26aeec7ba846e10a84814e7264197a0b2bf485c74d98e8315f0ddfd4b3d" + "0xf53ed26aeec7ba846e10a84814e7264197a0b2bf485c74d98e8315f0ddfd4b3d", + "0x57fa0c3eee29055cf5232125619ff171a60d2e8f0246af1ea8120969e03dc3f7", + "0xeca0088d30058eac4ecb7ce8dfa454e46e642154b7851db0faa430a01bf33744", + "0x3f43e499ddd06a059b192a9cb9881d15078157508c1ac30d687951454a22441f", + "0xd99f60df5d3b55202089a3a69147e43a021c5760485e0899116f56060ba56a92", + "0xe662a0a21e688b7452d0d5b6372bc8aeb00c589849f63da9c3fb4c280e6236b8", + "0xcc83d5becb2f1580e7771c576b97709778a8502096948677f1274e9b0ff444de", + "0x17cfc1a415766b30cfd1ecdb2bc8bca535928e1048803b9820e81d7058aa3b68", + "0x8e1410621e8b0edbfd9c98cd1dac02e6b5dc8336da445cdb00c16c457ca27750", + "0x3d8bc5d8acf9ff44f9099594290a91d47040eba0f766609f1dc034d6bb127f4d", + "0xbc32d05ddd709d4f7ba929353a618d70b8eecbe1d3b06010cdc7dbf053569e25", + "0x818d10c0a40a9675a1d87673d9dc55895b8ee337a0cdd99dda88d6c1d506a301", + "0x633d32a1adbc08ab373324175e0205412bd17ed1be4ee5882d20944c3439f77d", + "0x8107273c0ecc4179096f1492d21de076f84d0c4529ff6d563acaf85a8f5db5c9", + "0x5d8c25ebc9468667d043926dc4a6d28caaa6be696ba3e4d248ab7150b20fd771", + "0x5a8cdc39a49bff71df23eb7fb01811ce114edf6829f946a6155113b39480d023", + "0x72f7ce230da5fe9ad521901d2e1f7c88a20c98ea82fc09c240501ba327ff3518", + "0xc9c91729c335752f0e04f091dc181ce8659dfc13a77034b319c47554a5ff0bee", + "0x3773c7671613b65b8c6fbedc97c96ba6e3b8a6cf64acf6d1947f2881dfec93b1", + "0xb378b0953123036f313210f7e020441f41c81344b0437e5c947aa3d2e76cc357", + "0xcf3b0163249f3b6d1c9b756eddcabc9fb9d11e121dd96499c750350dd56cfa3d", + "0x8baa2ead915e991532ce72a856a001f7cc493a58016d3a0255cd416108357396", + "0xf748b8ba84812b2f5ac3b91b51402194fe08c1d15382d10895fcc8d4622b58f7", + "0x7ec5d0b6b989137882c20bebe11d2facc3e68e9a93a9b2c793d804d9e973304a", + "0x4512ed8b4f3586a79c971cba695d727684c6485ccadfff6a3db45ff93fb1e1dd", + "0xe6edc389d0ade0c7e558ffd357a7557af9f2d38b0b20c84a67936914acf088de", + "0xf2947281385a9b2077e6e8657a6bdfb9c93f82311bd739d8e9b96bf97454ade3", + "0xc768e9216d0dfa3da3fd3727ac4a673897567570653a8517219c079edd191496", + "0x9bcb33bab81663ac501a5a4d2f3d739668b42a6bd2cf7645c3571d58b37c60a6", + "0x540fda7f30ecbf8a61855b9619a139e502d8b9e1a3e72179f2399efb3aafab0e", + "0xde605b760659834d38aa120d97d5b0721eddcdfeaa69a716e44b35ef721c85c7", + "0x8979afdd57a677913bfd414f3c7cf88c3c7144f5168476e7c08518396cf8134c", + "0x6826b8b3aae4d8f97707e9751a4313738ad42861bac31090afb77a34f7214b7e", + "0xade12591565e41be9e81ac8a673324a680b0a9e6d980ede210c966b1b9252938", + "0xb2f3710b4e6c805bd20ad93fa0f254bd645b5c9b5fa299f1f8f9bb57d299e21d", + "0xdb80cf61e5a9d6b6237855eb518851f474d12db1fde3c534762e1f7d9367763f", + "0xc40c3599108f6057fb67f09e7aee418490af2a887d59f428af222519a7c03a12", + "0x0916f11f929196f5834bad46ea7eaf55716ec2d269aef9f486cac38fa7734831", + "0xd5362e4d43e3da51e12debe7966c2a06ae0fdd327cff666aeb7185b5d6cc71e2", + "0xaed4937eb0e5c9a5e6803cff864691f7ac63fa9f82d3c2e1ec9a2777d4d3f263", + "0x49f63292bb091a6d6e6515e5f822903da4a9e652847a7de5b0fba5ca69336ae2", + "0x7347591d5dc652262db2e95f65a570ae894f28a631dace959f6264027ae5f3c3", + "0x300ebb8f363f2921f5baa4ad46332bd7d10eb113679afa0851ede28a33ce62b7", + "0xff1b93baa7285220352ab656d513ee19c12da79c0c87d2035c148744164cf32f", + "0xd1793b3309372878fea3c14f2e4dae39588ddaa2396fe246b3c4cdb534a167dd", + "0xe2c7d728bb7899ab8b0ae0d07d585cd380a38f63fb9079532419fb5cbeacbe01", + "0xc972d3a0a76889c41d1130c52bf175526a5560d2fab7b28bba7c914a9b9621cc", + "0xebd731a2040b488d736e846efdb41ac5a6020e7c2b287249c105c71bf59b9504", + "0x8745a726f0e971fbe22c9b28234c3d93333c0f8d5c126ff9ee5000e26da7031b", + "0x3033928e0f79cc47d31814e409312127ef73a15a6aa915786e4410677942dc6b", + "0xeb77e57fc7de01107d1adfbf479a4c3a6ab5ddd008dab67069c5fb488551634e", + "0x6eae31a9b04e7d30e7781e33323f52e9f411fc7143b8feeefeb71cf6b4e86081", + "0x39ac81712892e1ca0cec0b63cb7d526edb0a276e6ff41369288f788d4eeff7a3", + "0x9de1c4046104a2bfe58e94215f59e1ce5898e3efcaa2ac6a7916817648e3b304", + "0x3d6fa25cdb3aa2cda4bf65a85927fa5b5c79d3ca427b6b128d34dd24aa08b5aa", + "0x8f5d95fb92d3eedb02da88535e4d0c9ed713fb2a6ded42ad8d2036306abd3b31", + "0x36abaa49a58fd335ecfe8b0ec61a68da28af30833018788fb710c3847dc3e258", + "0xe0224a4df20ed2e5cd78db19cd906d29bcf3aeb6f79135aeb62be16f766572ab", + "0x7584341a036595e957e7f7c09a5932c1e75e5a5a73ccd31fc2806b134a899082", + "0x1dd6909a77af37732b2e59d4341047ad85b610f470684433f2929673399c2fb0", + "0x5d9bf04171804ff9f2927a14176988349c0d0a86654d8a5897ada06ca4a18d02", + "0xa1714a70cbbaffc82a9018ec48acd7aaa70a5b6ed00800249fdd76326c5eb32a", + "0xb8fe04ca47841ffa34b5f17ce8922c86a9b98bb6d7d13c4b0fd27df931200422", + "0x308d034f42f0beba3aedda196573bff7b9c9852888d6f9e3362b4259d2c1cbe0", + "0x05be7b2c1b9f84273af920a4af58b183619b016aa20199fd6845eeacc479c744", + "0x613880fff823c896127092c2c4e0319e6cca955b650829ffa053c4b228429d61", + "0xca039f943e38b017fafd119e870ee80bcd19e7994b15449a03b7bf35c1a69add", + "0xfe29c86d46c9db3f2332f2109a81199c5f48730826755b56715a98eae6e6bef9", + "0x6e95261130af62956647ad47ebf45dba97a9dd684940d5b241a6b0cc36fc0b45", + "0x113eff6173e9551800e70882942c37723aa83d573f2349ac614e6d245411af19", + "0x07e9fbe087e6b8f4a2cf41373b1977823875a9d3be56b937b977503a20996437", + "0xae0792daa47529f8690d30dddb9e0ccbdcd3e4a3b3f0386f098b147c4cb3dd58", + "0x6ad953988a96ea288c407afc70581289c4dd6b8ffceda65f6d4a51e8cb7228a8", + "0x949d0b15d25fb79f31900f0e48ac3fef50b3d1b69f24f505fad87ca56ad883ca", + "0xf0e01643fc4c21dc3adb6dc1a0bc9f601af1bd4b5ed50ba156a280996d521db9", + "0xcf396c2e2018e5dc71ce2e8d8d2716565fd9ef6ae097b871b4349a487e0a6727", + "0x5f22e44bdf7a346985839c4a395f66e2fbed238f0463ab2b02d7dd23c4e25748", + "0x8808ab6e652afa85738443a808d140c103757cd1a356bbe2b409e95cced6fa7c", + "0x9ab3eb50f50a357020c69c9501cb2864febf0be1c04edd20cb1fce3fc075b7db", + "0xc360f24716b701218d2c486938e17d7b56a85b818b4e808f7c12c85778914f68", + "0x0e8388813ad36963923d68e9a223087e2e29282dec830d13e04ca444a6e1ed6f", + "0xf77bc7d25e80792e69d8900f5e77a9eb276bc13d391720c8b8a1c608deaca05e", + "0x0979a99fa0f1a046c1da8204f2912b3c09c6dc7d37e0b6dba11935e5af8b1fb5", + "0xf9327d2fb74c22853685a3d41d6f63984a354115af69c7873650c9f8bc2d31ba", + "0x9fa02b5ef88c4496cd054f6dd26f292e389976b38a22760cbb505f068754a60f", + "0x1dff7dbca8c5d169d2ad52a4434a01ef647f29707e59d4543053a8bc7afc664c", + "0x051dc8f86a07ed084afe4d14f0b39268fc5858c908056401586acd0c9bd628d4", + "0xe6776e7bffe6398d66564b7e5993ef70c7347287842319e585c7f844002d9555", + "0xc5bc5e2c1e26900fe2492019e11bc4ec5595e1c8eb68bc1ddde65aed94ab83b1", + "0x6f868ac5f8f7071b3742573d8f4a3aea1bff632f6c5c15988572ea1983e9e535", + "0x086a27e853ff55ef97cf876e0d703898eaa0769ee4efadffacbb8c03de35657e", + "0x00aa9b9ffb2837aec2fd6444802437a5dcd4654ddc2df584e1ca351832a9e163", + "0xd395a77dd37f2e397456a5385e1fe4e781458db37d3a6d8da3b1d5fb7c5558fe", + "0x7567bd55454dc888c6aca9481ac1fd6641a93b3d2f5d1bc81bab97dd78f490ad", + "0xb7e980a03060221442dc0f9487a6f0614f5b83ea23350d2de3ff0ae4e93d02a6", + "0x1b43c09f68af74141ab23bcc3402932257deece48af74503e6ca452ecd59d9a3", + "0xfde1e03da25883b8eb78e3ac92914feab4e7294eb78a94e801876d59aa559f8b", + "0x807aca1ff5c2132a7c2b5d67de9c536968755dcfc32e8873fdd296f807148d56", + "0x8f3160048010ee14d59c26c0c2767b78350023327534ca27b086feea4cde5910", + "0xb26f5f50bdef8212578eb07f7afb52785944811975e1671a405013a0fcfb88cf", + "0x4e14680b46a09bdf8b9046f62ec5a28b8edd5704c3cc91fefb83646a5dd3eee9", + "0x792f84baa0644328b9cf5af899a154faae97fbbae7a1e7874e6219085b271265", + "0xc4d26ab903ed6478fd9a0fa80382f7b4eecd25125b623c6dcbc4ebaf0d8b3fc1", + "0x906b46aba1de6a6e3692bea009597d0a8dc40b76a1c5a4476a9daeeed65c2b25", + "0x167fb1cbf8026a1af6c16ff3b18285dd9d934158a9b9ae75b90ba7895ca2b7c9", + "0xaa659098a8ed4e33e511872bc82cf758eb6c2b47e318899b4e4385bd32fae051", + "0x757c86586e3307882c6d966c2a88745e4bc1a9002337a5d137d83ef3d4496768", + "0xf342de6ecb6bb5579cfca4e7dd4dedd2c1a685287dcbd891fb918226eb82cacd", + "0xb025cb5c7c1d64a8138ddd439aa95cd9a4c1162d628dae1f09bbf8a225a49f22", + "0x6ab070192b7919718111a5b1d74862c48a5705d4e9c6b47a3a81564180c3526f", + "0xf9a23794eddea371183902ae36ae4b54387b4b8b170bf848dc24a5ea39649545", + "0xfb9dfb946dd83814681f93091ceb299d417d8ec8d28e2ddb7843d913b699a6a3", + "0x44ea56c8eabaaef19c9fde38ad0f92c074039d93960b51238c1b11ed2315163a", + "0x66f8ce000b102ea085a18cfb17e99f242e0458d0b0d9d39b6a8653008fdaa98b", + "0xd573e736c4609d90ade296503843c9a12ad8f3795eefb32635dce70f2fb17381", + "0xa783abcf83917308a63bee26ef64b010e15b62014ed560881adc3ce78f80c3b3", + "0xf8406110d71475627fa02fe434b3270c353eca0ea700bd196a9c42dd2e6c472d", + "0x5e3350f159e6370a741af5879bdcc8b08c44538dabd162fef2b745e9ff2828c6", + "0x915c517a16a1dc3095bfb9550f24afc3a60f442c9205a7ebddc7eed37fb267e7", + "0x9ec7f72f0e8d5509e3ec337b0c879f730c16c55e4259526c0816d6891feb1dc6", + "0xc294284cac5de499512f9b12707b5f66dbb3b635c1cc6d4419b17f40e272e339", + "0xfbda44ddfe4b7c31b915fa94a27aa01fcfb22a9fcf0b557f9788bbf48b3f7f32", + "0x4418fe011a16af7da4645f300143a6cb005650ea96ce23c6adb4a82f60f72beb", + "0xfd3a00e52f4cc05610976b0def190199543ff3e423f09f8bbe5cef8315f36d7a", + "0x5c9fee100da6ec53ab1cf96ca9f369401853753eeaea30bef75f6989faddc504", + "0x713e2e28396b62bc63ab0a3dcfeabe977bceece4057a687d157320358f2dd08b", + "0x62ba90cbd06efea1d7bb7128e37e33d94a21b246b7eb7159d2708b5552247a75", + "0xe13d2697cfeea63e973c7493b4c54917a639fcf13eb1b327e02acee353bf84bb", + "0x8ed199e2fd654bfc9dfd5e7ea7dc82bea9f4535eb480c95984a5a6bc1533bf8e", + "0x4e5475dae57c548460d4ddd15583223bf2a4a2046c2ee56ca670892794a37d90", + "0x80409971b3e59ec71deb1a158a92ab6fe8318cb9adebcf583586e23e42d370c4", + "0xeb35d7c78965874110f67b77307deae4bb29dc98c01fbac3737409ede61df7c6" ] }, "nodes": [ diff --git a/ethcore/res/ethereum/kovan.json b/ethcore/res/ethereum/kovan.json index fc12ba608d..ac86ebe7aa 100644 --- a/ethcore/res/ethereum/kovan.json +++ b/ethcore/res/ethereum/kovan.json @@ -64,8 +64,8 @@ "gasLimit": "0x5B8D80" }, "hardcodedSync": { - "header": "f90247a0017c9292a6abf6bb9aa48c30f8854dc0e9649bceaf19079b1aac50ebea4fa316a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794007733a1fe69cf3f2cf989f81c7b4cac1693387aa06b81f6633226562f466201f0d097877c903a650f7427aefa7433fb971f601287a0098141509099d91ed2c2e503d43db5b5412d51880994e8e03a86e1d7a9ca8e8ca0495f318f8bfdd4beb517d115ad5d5330aebafe70eb2b1cfb0ab029221a0f48c1b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000090fffffffffffffffffffffffffffffffe83975801837a120083035108845c2c49e49fde830202058f5061726974792d457468657265756d86312e33312e30826c6984170b1279b8413ee0655a59d1f7f8db39c22055c614346450e99965fef62efa43b21b20f0966e3e41eb65fcaf6f9ce3a34359dc064827e06f3a29d2c717f287234785d369e56f00", - "totalDifficulty": "3324635628632492920129912637269655024947201711", + "header": "f90247a03dc1f4ed47c057717131ce81535d06194d990be6969334e9b8034e0c875f9dffa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940010f94b296a852aaac52ea6c5ac72e03afd032da0fd1833e970c207ca16e1e74d937c9d8e01a1f719643fb25963028427295fc2cca00d9d5e376ebe3558b412402702d34a93256bb03a61df9f17ae234f0a70f95b20a0129c38f28acd251820f96305d217511a725a1fae1a434d77034bd7efef1f9f5ab901000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000080000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000090fffffffffffffffffffffffffffffffa839f3801837a1200834bb5f3845c7361249fde8302020a8f5061726974792d457468657265756d86312e33322e30826c6984171cd849b841d077cf579661ac8634ee865b5cc67918223aed686d6ba189624a6f6c0dfc5249418b25423e30e072a79d5377e01845d5234ff5e0b9b0207b1bf2515f805b47e300", + "totalDifficulty": "3500253997070921577369506418666760871805116639", "CHTs": [ "0xdb9557458495268ddd69409fc1f66631ed5ff9bf6c479be6eabe5d83a460acac", "0xd413800c22172be6e0b7a36348c90098955991f119ddad32c5b928e8db4deb02", @@ -4909,7 +4909,259 @@ "0xe3d68466d0747ab6245e5d8620eaae080a0f3c2aa34a56defe8adaef56d5474a", "0x8d0f53bb5f7610133f04a763263815e092e43b0016369866e959d22eca466d85", "0x8c8f0fff76977593112a64826f15ec0e909d9a1f1589e121a37f73d881e6b696", - "0x9ab1411e7ef5b295ab1a9dfe4ee1cd1a740af5b7e4b0a0e9c4a5f37e803c7c94" + "0x9ab1411e7ef5b295ab1a9dfe4ee1cd1a740af5b7e4b0a0e9c4a5f37e803c7c94", + "0x7a842e2c606aba52515ed7f114116bc782810bdade34b582077c57844e6af18d", + "0x40b14c755b9cecf8264622d80dcb5864241c0f41e9665908ef3683e83d33e9f1", + "0xd0faf39bcb44f583ded1cffebc93a8acb49a10b3bb2b0c9ed794b8aa4bd9e30c", + "0xe1eb93e1abdc400b49eda22b5818fcf61c56309f10d5e3cf3794bcd7760c4c0c", + "0xededdd50db9028797406a8559fd824a3e024b2362bb24f708c4f8423c657b31a", + "0x20f6ed1b586555773ded5606e711a4b9bc47b84f45bdb97653de8eb4c9aa40b7", + "0x77ade166b067475ddc450b0d6991b5a8de93c3b60d76d2b6a3f15ace449ea6d7", + "0x766c057ee18d96d84ac85caff6e0ff4954d3add40ed9488987ec5f4865f06ea3", + "0xe5dc0692cb0da1b9778ac99fb26b01ee7da45da56996dc7e5191f28e60a83bba", + "0xb86ddaab167daf9b8d4827e12f19201cb7ba2fdc7767aa7054f478650360b5a0", + "0x570f60bd9224065c7ac611e89e9737354b3186440dd328efa7ee0078850fc296", + "0x0438822dca67b58f7c5ede70758f24ad164e1c0e3f6628274535101c13121201", + "0x709382d302a6e5b21823af6ed14f22dfa79d7632b8649c67cff749fd9cad1d54", + "0xd42c07bf201d8025e9202ce752e25207cae1804877149a756536348853478dfb", + "0x82944c59acd3d43c731cc820a38f4b9ea4fafb3c5a5cc474ca0612c2e50f88a1", + "0xe9c2665ac57f450a47b8f5407dbfa7575ef4fd3bc4c90a1e64e7e0f597c6c4f2", + "0x862decca6c5c15a52cfc88a629237dc1740d533dea40a0850d8d0cff47672c43", + "0xeb453cbb85db88ed6ab19e57fc0b90c045c3c0dd6aca67f3be579c6e75e6a1ab", + "0x8f32d04dacbfaf1bdcde08205fe539f24a5e453c686257d5e39217ecf17e2a01", + "0x81f1d7ed305f8981fd6ef9adc7374a3bab51b9f5d042c35e7cb16c7eadaf37ed", + "0x8301660b9f830042d66b7197ca95eda84e9220d74f48ccef41aabcd8bec18c57", + "0x07c00b7b9e698074ac994f5a96cfbfbc6f3e8ba34bdd727deb60aa3ab9f0f1ff", + "0x44c59c12a76078144f62fc9646f8a37ac38a0db2db3cb002712834c0bf2a1bbe", + "0xb3abeacf4280e9fa9357fcdd9b4e866938c37513e0f8a31b9f8c5733c48498f5", + "0x72dd15a76cc64e9091fca937497027b77517334012d71b47502ec28f4cf31433", + "0x0f86404545ab226dda8789da56d1d67edaf201062dc4f3268e0a4c3314ca6628", + "0xf2c60e7441c1cd8b448b9d93fcc7e5f5a107d3b502454fb2f6b8607c49e12a01", + "0xc272b28ebdd6cb2cc76cc255f68602e731579bc79ee8c9f6a3471474f14febcf", + "0xed87c1f9b73e4f757d822e5161c6299aee52be1465ca389f0ce008eab6f51c17", + "0xcec988f7b79b0b5b9f4b1e43466b56dcae86823e45997fe208e7f2cbe4604947", + "0x0583ed42e92bf0cc3a54a4b80edde80606aa9a16d6254fe89b809faa0c7c5f46", + "0xc61e76957a49acc14fe008c525de69838370fdb7c3063bc04dd98b031b12eb92", + "0x5495eb0d9ac61871a364a5bd697628f4e480b8eea4c454cb583b0b11e59373ce", + "0x3ee00540b8bc71257573acbf77c97969e0af184589df1decccc5490858b1399b", + "0x6c10a21b5e7a430ed342bf38a88522919f217fb7a087576d7040f71b7d6a8e0f", + "0xc0410a1981bbae319921e5af78c1e80e4539e1ba9140adb9139ff40816255910", + "0x300f10eb6ba9d4ebd662710a91bfccde83a561b0dad7e14256a7b62e8b720662", + "0x9f5de17b88d3bbc6efbab33a7b2d8f2c120643b3844f8e37d19e10f1526195f8", + "0x2918baee5948882cfbbb57f6ba18a0434d2a0c3928eaea3d1b12de0054c00b5f", + "0xf5cb3b2a6d29bf9a0988877cbe22a01726883159a787a324bf1e685b92ab8018", + "0x08a9570f38daac2ca30d32e582f9f8f3a80e82020668b5020b29bf0456779b9a", + "0xf807d91faee554d99a4a728b219d285834f231129a6225a5a4340bd74693b133", + "0x7798ef990ab47b908f703dccfcc0d5507dcb7afaa9e5b98841825f7d2ac6b655", + "0xe5d3b714c47a7f5b8bc95dacec03facff800774c72f4379051a1c574b919bfee", + "0x5c5f6fdd4dc6d353865ee1edd5893b634f7239b327840b4973509027c8622f74", + "0xf713adae992084b0593ac33894fea127fd73a6439533cc94d07b89c50b071fc0", + "0x548d8bfbc57c4773fa2918dd13efd1f55a68d4a86b526f4560abcf48665ed637", + "0xf47bdfe91932a9b4e968e64ad23690b7c3421137b44030000ffdd78ac798b3bf", + "0x4ec25256a43c957c1cef4be253a69fc771889ad563ae677fe3e5ea6936cd760e", + "0x9b8a28041d701c32f976fada9ce9a73fcf5dad79587c9e02b5abd7a299d74292", + "0xc7c6285cea2145104924ab507bbd5aef09403f61e90ad04e0fa8a67e2abb140e", + "0x2e839dc3048ebe96490dacdf688b017f388288954704c9a99cdf25f9203fddce", + "0x37e37dbf1f4cb8b825cd5b68ea18a80a0bcbed46cbdb54c5ebb136ba4e88ff95", + "0xcdebce72ebb15b5fe081d0f3290cd8412c56e93269541af2461598fa2a05cd1e", + "0x37716cf58953f21168a83613bfb13db775fc96175384aee35f76e82095d19716", + "0x7f7ed8d8526f0586f08dcfba6a279689d0f7aebfb0b11e627c7cd0a31ea99256", + "0x1066be85b9d156b32227a7b74cd23b330f3c80e62f8b671b1dd03d2fbaf038b5", + "0x53b3ba2bf9f02a52c7caf9ef6b46df80d9fa1ab12437774b2f2d073e886dfd5b", + "0xad963410b3f77f2399b7ab925c7ef5cff512534c2e12e7e3e9573152f197f28d", + "0xa3b75316cb456a516d1e26ad8df52a0a2894f26ff3a2938f9e09cbd9354981d7", + "0x522ee88e34308bbdff564080e665cde9b3b4ae4a61afe558e5609996c1b2f855", + "0xd7d377a1ea94fdab72ce796d3e62cffa96b2b2226bbc9fcea51817414fc367a0", + "0x2ad4691181f4947c25d521a9d593e25c5e67c0b6150b3d9e27515c7808223633", + "0xf76442cc901ec7207c33840e6a029e3655d279394261b8e2fc350547f2fd4cd0", + "0x39688b8d86b6cacfea5d71e7311b01e2009a939c6531eb8af8e88b1d1b7a04a9", + "0xcc35ca75b97530d9c19199827d373210bc9624fa0ef572f7c3aaf2672918da58", + "0x85a6af5bf38ef40d2be7a529f3f370f56f380406fb8c5165f5bdff75a182b2ec", + "0x54296a0ca61a8a80d4ce9333c985983f953975f6bd7eb6beec593c149a3359cf", + "0xaa1f116c6fad9512afa8329eb499f197c5716a53ee283f06c417f45d9ce2fcf8", + "0xb9799045a8f20c5885649ec1a632eacd44a72b794dc7492469f8c1abff3edb24", + "0xd86348fcec2db2efc3deafcc18ca121de0176b1e89698a3c5244f377792784e7", + "0x7267a4a5e59e848f1c3c9e4c6f43e7aa128b73261adb296a89a7abccdfd16cd9", + "0x817a39c73cf85997721cb067b4e00812ab7fcde3e4506e37e6514c8c4e87846f", + "0xb8e7a1c1aa51637ee68590a2d5be7a8124fae067cb3b0ab3898f5c45fb275010", + "0x43f77794f4bb485488cf082b416885292a7b254057e7a75e331f4641c1ea2839", + "0x9bf3050d09ec32ddf7c40fb96ae136085587c3a4ef6cd413f73dd42615327218", + "0x069923933c215e6c60c8285f0afb83de8d4d9911a2c6417178f5f149388af874", + "0x01e1fb2dcd7bdf5e30e5569a677f39e9356d70ad5e7c30cbc8c73eec66bba5dc", + "0x39fcb505c1365111a0837993dfdf527a716a441628f248aeda785b32e04eeac4", + "0x7837393e026631af009ee2f61e1a39037f97f77f98690ce92fcdd934b80d3ddc", + "0x7695c9c3257358c759fd8c9018b2834ff56c42abecebaae806a281c03b887aa6", + "0x0446616edf3b74a68fbe0c22029b61d16b67c300022211e013572b90815b6050", + "0x274d5faf73eac9078b9d9c870bf07103aa749b0273871fa8e166932e3c0c1556", + "0x34fa06554a8bf6a2305d7ad293d1617f5295c046cd6de60689af2af9d44decc5", + "0xb641c3b6baa2370b85fb8bbb8c054fd9e7d44425a095778e859915f5b3931006", + "0xd4db8f0bebfa97e5ba93fe7aa444eb74782a98f03735720482b5080a4d3d980d", + "0x4261a0741221a7bcfa4d8bd1d6e8a62fe47ded969cc2b1446a7a76da9a23e844", + "0x6664826f16716dd01d707896f892a24b29aa9b78b2a162bfd01aade882314815", + "0xd9cacec24e60731fffc19e6fe8bf0241499ca78c51f38f841f6c1d91cb4f686d", + "0x57755fffef02b43c1be01eed12caee89bf5cb4ffa8b823aaed947083cde2d0ee", + "0x5d9bfb52ffa30989655e77512a3f40db66c790311c9cfb10d161b62b7542e334", + "0x302296acbdbd6737cdb060223f289ddd71516c8c42cc5128bdd545de6df02bb6", + "0xee1c6c48a63232e8dba59646f8d50dd6eded16ab310f39548300249efeaf7b45", + "0x60d151e272c9e6874c9c9bd90e8b241c0ec1e978b5b1db2d6632542f9b02488c", + "0x71c8d8c3da03c317eb14b12b5d403581432b3f0cea447da99dde8b60c9dc9cb7", + "0x9fd4de13da3b68bc5682debfae937d4ba4fb67f87cbc30677941ca53f5029945", + "0x2fb70f11714902235b3ca78b281c8ec80aab89f77e3fc59136bfbba44a2c46e2", + "0x30109aa2d8e89ef3669e4abb89870c77c5acf5a34bf273fd56b925d1a4fca03c", + "0x8d5c57cfcf34f5cd277a7d51c5a2fd1405b26231646db44043e735b8aae78478", + "0xaf961653148c2e6007d011e20d008c25a2c842f5dea15e2fefa76b3f324424ba", + "0xb4cc2c774796dd0c44923ecb3904e8f0c64839d32b7afd0c7f87eb0ba5e52949", + "0xf4c16b1aeaf622d35b4f897c5b9c96358af2fde5ede56d377132a6e57549565e", + "0x15c2a9f6eddc424c3ff3f91ebe6ac55d98442923267c80f59023d18b9d29cd9c", + "0x65abebec89e4a4d6e674a29f3e5ee304050da861a3a3c91ebe79a3a8aa159db5", + "0x46030219478d3c508cdbfe4cf76ce3924942cfbeb9ec6ac9e83dd5414cc8714a", + "0x4712aadd9407b29cdd5d3f0747374fea712eb3202fd2c13795268d498dd0843e", + "0xdc5ed31d4a9c4fce3f91f75102feef6da9a190638bf1f090df64175b531b1cc1", + "0x077992451f048591ea0bb7b46818c602b6fb1d535ddfab2dfbdaa6731745fb66", + "0x889307e6b877b390b86024c2f48afa3df0c9b375512e38ef778dde91dc950f55", + "0xc6127728eccce59452504b58e10c29ab854712f248d6c90b43360c2786f38647", + "0x76516eefb0f149ab9fbf2dace9fbdd4d435e583b3bb19820f45801abbb8309c8", + "0xa3771e4be252fc17bac8dd8cb9cce1168e531061b59be4fc9115838af2d3217e", + "0x1a0218061cd1c34a080b3a70cbb0c9f66420816a21a2f18f67e5fca6ce62b3f7", + "0x42751bae5dfa6d27b92cb15bf0c490d8184b97fb647563bbb4a7612f31369473", + "0x03bf5030aed483c4d07ba6a5be51ff968ce869decc37fe264b98661bccc55668", + "0xaf604a8c41a8a2fb37e317b2a565afa4e25c289a17b3e7030106849094d517ed", + "0xdbf8ed6fc0f94eddd863c883c17c974dd91f679194d4cc74316092327eb6bb42", + "0x27624ca6ec82b25f6bcaae3b0159c79803228ef5a5e4443498e39e7ca8280195", + "0x19338a8eb7d6884c8e6614b408ff2e5d44ed84e208673910f10fed7f1bf95c37", + "0xb612ba1448b74093a5be0f2ba8d330ca56647eaa2c84c3a1e3d2ef765f430126", + "0x523a7f824cb76717e0985ea2cabb23de5751c67ea03d6b569c30552d8bc9caf2", + "0xdc4f2e1b704ed39f818c36b26df95184c39927246f52a74772be1eebbddc78a7", + "0x4b5e3bc7c2e4f098b829f59ed096527216ea84bf9041d2a3c53c00cb7b5e7a56", + "0x3cec3a6e9f95bb0e2a63194ac6353ac6fe9a12fad00e8f603703454638e8d819", + "0x29b860f98a7239c9fe3994b68019ae8fd4d4009c07a088d23cd70ae6033fc727", + "0xa8d1900bc2c3156c6bc8a41378c0d2c646f0328d4f8b8963f52ac0dd506731ed", + "0xd9f8c709f2a6cbcda62ceae4c5244554af106e7f7fa0837d8887e23887d32e31", + "0xea7c17fa8dbc43b3680741957d5a020cf0df2d491aebd6955bf6027a63f75dd9", + "0xf764705990e0a12e1a97ea2cfe3d5fc0c28a601d1bb6c1bca0d24e61175d7403", + "0xbd5d6454bb6824df5a458fbd1a29476e76c645564c42064eb6cad79237e17a99", + "0x39e99ee5f716670380fcba0312b8b9d902dc3fe4e49e19bceaa4b2f3c2041366", + "0xbdb6860183ab7aa4362223c519791e7a0b63379b87ef4c30739e57515aae764e", + "0xbf6e060baab8b162bdf78e1996e30cdf4d6dd60b5daef909a5e7fada00090928", + "0x1ddc651ab0d26eda2c160911e4be92c8ef843ef510ee28f1d0b8356760c595f3", + "0xdfc38ad4e3225dcdd2dcadf32b024f754236601cb60c7aaec61a692a9f367acf", + "0x326cd0b07c68ed36049ef9ce9af1db0593a26193d9988d21d8ab05f7ffd91adf", + "0xfd76ef987cf758c89c04a221c10e50794132d3866bbf4e739e288a9b3014a9e8", + "0x590f03df3ea2123eac0957d2a84a4a0e0184be0eb75851643c0b876f364942cc", + "0x0fc92d4be9d7f7d5c49f3552d89203090fb7f4a4d34ac1a9925036c84d5d0d97", + "0xd90702e78e72b71a3f7db3510c25d0b26d098da80003cfa4abe3c525e3212d2b", + "0xec682fda87e3e66fc89855bd1ec01a80b515d6dda5f4b2d207cc5b2ac840532d", + "0xa75c0c5ae9cc31a14badd2f0cd66b9c081aa541e4f862ef0ee5aa8a692baa89c", + "0x9c237fd14d83ea449bc37922861be5fe81531264bb802d6a07c149b6883c826f", + "0xab2240195acb14c2cb5f3e6bdd352c4c36765ba6d2d3042bf15b3942b50471d7", + "0xe56052f2729f3d7d08b7958c0630b9c3ca2c6fcd9fd5655314bd1d5ca94e7852", + "0xd774822e8bd746a6b253e9c71f80fa6d6f9ad95bdffad3310eecb98785c549d6", + "0x4e478c8d5034a0e51e1e760fe258afc0c1f56cfa145f89bf34156426ea837b0e", + "0xf84cba0083c61307c45e7caa3844053ca78e2a1ce181edf17041130f314f4d00", + "0x24db4dc31929f9c0521a63d1b6ffd14939130c7d25df7a0827513a6ff0b28159", + "0x969f5efaeff2db44bcebbe23b9ff916a15087a313e814dd9f8140388fa62a48d", + "0xbdf6deadf158fbbe80670ae75744a419b999b747cc0804ec2a81b9082b5a4ccb", + "0xd25da9760de21e6483493f5f781cf526527aa0bc17ee9c9abefebda4e8bc5b71", + "0x83d5382a1a2132d7fa2bd48e06e59243f6ec71ee50626b65a84a7e5d3543f8f7", + "0xa5720e9755e2d04563583af4a2581a8a1761e82eb769dc7695b1f9654e36f753", + "0x97ceee5cb98a9e917223523650405aaa2e71cb12e568319baae1ee75df592fd8", + "0x1e1e8d3d81ae5be21cb8445833d9b8928b6c9a6b9217532b15ce0ba6cefa64e4", + "0x1c3ca12af63f1121e93b5fb602ab8c8ab1773d07bab5a60e78cb8e70e190bd4d", + "0xb343c9f8dbe3e65462838749865a748d4a5eeebe5b6622b56325e2e6680626ef", + "0x04eda02f974da35a3f4308d6b6be16b602d9317256209bf674f3282b2bda878a", + "0x0f85c864e5ac359d9a0ff54a4e0b44a31109c57d7c2171185138dee5638c627f", + "0x476f9f649f2365455d4756f541e8b8f8e34b32f8c67196a06fff2f71abddf5e5", + "0x185b523fa66564ed0e4cafadabe1c04a399b51114f5fb743136fcb2a0a53e477", + "0xc87106d70447c962f367b567b37281e4d840fc16d7b97dd349ecd073d0419cc6", + "0xc0e624f73d54230b99169c8919c965319ab2a93a31923bd22b50350bf0d25798", + "0xd78f2ea276fce38b53569cc64a6ce7ccec2fdf4f1a295106a1f2c54330a0db40", + "0x4a1c2807ccd57ecd989a2b0d4ed2d3ec609449e15c5652cff515ba5506cfb745", + "0x453e4ded943f491b41f0522188e88b28667172202b8a015f113171c29de193b2", + "0x9ea9a96b93c19a00f2238e15bb3c74409eca441e6d0ecb47b574fa8fe7390c67", + "0x9833f04cfbab3190d2d831116f1f0e1871018d862cc2389511bc266756963540", + "0x48ccbadc3d160d322bfc61d44962628b088da09d045c43d028b1b9fb979462bf", + "0x33d90a0c09d27087c15b01228250cac34fd4307d45593e7239096bb77822f6cc", + "0x545e2a8e511ef59a5fd7f183b0bed449d59788e4e377350b56bdb387e82ad4f8", + "0xe7e31fa668cee51a20ad4f2bbd459016639bcd47421836cc1bb3e0e2a4705998", + "0xaf6e1ffeaea0bcb61d5d90fb6d6146bf4f6102f49c3e5f653e1bcd6b043ab3ab", + "0x98bee111ed4d2cbd72725011d5a565b1873c86b8f3e17f16389ee009dfe3c6e3", + "0x2107b120a64b8fe21702af4bd26e8d981fec6d0051c83046bfa5dd05354ad05a", + "0xc982a8ce403f43557d0a812b8be06827d88e2410f6e7920971972fb205bc8a4c", + "0x5d58c764a39ccd3edc5e1b37f3ec73ddcfafde249e066c6185712c0d566b2e33", + "0x9afff9b16248767858ce0520877d7f414764eae8ad77d9810d615540c119e476", + "0x6154b7412dc1fabb80fd7ee43a3b91651e07b62d15afba8c004611d8ce2a88a9", + "0xfa859b6679bd6a2b283ad4ba43b8b3d96b19292d017e933cb307100e0e2a9c36", + "0xf32a85527d705fa439494f314800609a6c5f6657b205b0127b64cd595aa2c31c", + "0x02d1fe3725fad05e13189d6d9e078af8c825bccb5775dd1a6c90be3b57081d02", + "0xb003929860e22e0a4bebf5be75be8ac86a511e3f9e9b421aa9a99fe0fa4d9144", + "0x583341c3a9526d29c43bf22619df050676fc5e56974a8588a91bfef7409818f4", + "0xb94ebbab275786dbeff9189ca740bf324f916c76b800da87e6e507d546128ca9", + "0x5f26114f75c4f839fd6776b3a67b1a74fe6afe5fee1d3053fc5b09b38a2f31f5", + "0x053d6e94968bde9f906aa52065c0626810d138908f1645f2e563d3aca9660276", + "0x458fdb60ca1d0b7ffd846744ee6fc7219ce6700b4e5cd97603c4885563a0d14b", + "0xdc09316757c1ed63b9d984647db8fb69fc9e8e6153424a6e99016f868dea613c", + "0x409e2e26caddccbabf10754bf500262fca5aeaf6ebc937062e1d59b087873a70", + "0x288ee1a1e4b4437ac97c7130d4260bb0298ed2038b57c801fcf2389762a8dbe9", + "0xb82f496c7c8c8d2847ea7434e15c61883f4510e3151f56636394d88e902e19de", + "0x5fe701b2ac79e258c7201cadcf7892cd37e76bf9f7f9b9b46d39ba0fd359076c", + "0x32a841cf4e27eb60b5a6825665cc257fd1db222d501b42b5c6a814cdcddc1038", + "0x5b76c42acd108597e0f0ea8c92acb039a047dccc7f294205d1e404981bcffe0c", + "0x7084da3532f91d33a42701d9c580905f4cbc4137f33db33a579aec2ce5db1c53", + "0x11e58ad87c481e2d1b1583bed5b6e71ffbc1114bed29b7ac14a75d852a4741b2", + "0xdbbe146f3e58fa32d465a175205d757f18929cea4870bccbaa2698c58cd32f6c", + "0xf1dacbb951e0663d5db612046e090c04f18bbe31271d3d786f20deffd44b4205", + "0xa11dd2266cbe0af5b7f1f7955c28fc43a88abb8d82ac18e835723c85e8fd2d22", + "0x716ed679abca531ed520deed7b6d955e1c07c5ea483cb57a2322ed8c7a5a31e1", + "0xca4e5b466b978777d7a60a8bd841271da8643bdf0085379677131bf4b3604f33", + "0xe3ab5b13f5cb1bd8dc38c5182a7f16c02abdcae7a310d6c0233b96070d9d30f7", + "0x5f29236e49036d429f283d25a2e4cd6ee8f01b314201a34713b50871ac1ab628", + "0xf1e41d548090c62f207208b575e0bb7b4eb08c30abe40525effbcbb8b5511482", + "0x088fcad31ede2ffe1cb9e67becae368ba3be97a02d4837be59bef650f4b90e4c", + "0x4f4cadc003d445a2014dd5f819a2b67e67620a21af8302469f9ec264cee75e2a", + "0x23b331796e1c5c95a701a1f791ca392da953a7a9d5d2a834d0cc941ef6567250", + "0xb147414487aa60ae8ef7aef8577ce50b4a750b0ab77175aaa39fe78ca5d2e12c", + "0xa2250e2b126ef24cb732c79cf87afc5186b88402b70e0c9b7d3139205c7dfd09", + "0x5c40cffeb999c74452e77145e22c3c1d1080deadf4f49e40cd5184c683f628d8", + "0xe2f8ad15a61579535dc9afc59d9ad16308b80e409fed46af55b7938856485c33", + "0xec81eb466fd503be4a807bad9b2d0b6ccc24d1dce3f82f69adc99dc81d69a3b5", + "0xb87d20dbc44c1a473048e96a2957a4b9fb2ea606cf7b3de9d44937d18695f0d9", + "0xbf0dd81b0e07b07b22deb6b97d5cbd1d03a2726a1e7bf9f795c8104d1ff1c458", + "0x6aeed28f1590a1c96f1085a1867a4957673cbb8e4251e5876a43182e7b40e4ec", + "0x24df74cf385560d990f59f8c59d3545662f71b42736bbd1c1361b5a1c45d2b47", + "0x881647b453a1e3ff0b6e64a3667db62add41599f003f9032418576323a5ce1f2", + "0x9fb9c9bdcfcf35e02f0029f74b86d131be7cb49f409055cc075008e9ae33bff5", + "0x5f17c4c7b4d1b0cfd3929eadb46bf1060b8394f6bd5c0095623f73de5f8acf03", + "0x63c4b4aa80474a3cf70243f3a2d891266760f6f54693f4f189c0aa9b3d6302ec", + "0x97921aed12f6d78f6052050f7401caca6bd07cd643fd7a30f681a72a45b64a0c", + "0x82e6c73da95617192ccbc9374bbdec4c4323f8f63a27197cdb52a0d73b88e16d", + "0x3e24fcbe6a8d8ba769994150cc7a17dbb38d2248af14bc8328f729f4e01fe173", + "0x8390ef908e1dd84308347bdecd7f7e1f176551e291c6b8851c1f90d0ee4d87a3", + "0x016143668addb39c55a8c5397cf097567faeec1787643a89f8feaf817ea10d5b", + "0xde78935eace5f67e88d141d650c35b2b0c5144b12833a3c4bb64441aca1afc23", + "0x129345fd67f04b97d9e76fc9758c80b0616a68710f51decc61f85fed9250396a", + "0xcf6625191fe20056831cfa3839cd3f8fe60d17e6e4248dc46ecd35401986770a", + "0xda56c24559455221d6e465dc3385bb8fe8b547f96952e07647e46e10127873fb", + "0x85045ce82b529f7055bb8496f4084283edc86b6b79f0f1fa060ed9050419c542", + "0x4b94dbf2a96a4749a04d47fe563644b7f396f4c81753d8ec3a70e5065df0a3b9", + "0x4b025b46575b54136db392c9075b5973a421fb521ab37d8760a04f90b4f8526b", + "0xcfdf125601a1939cca129c4d38dc89a6157cf0a51400bfd8cbc1ea9a3ac5e859", + "0xbb9b417a9d9c975a1707778fa83950a2a6f6c7c20620e623e913509cc256c26c", + "0xc2dc9b5d9413508462391fbac33d1d4ac2fc4b3167d152d0888c5ef9b18a9bf8", + "0x918d35dede6db7175e5a11d9c26ed38fe8198da231d3955b1eee020ad32fa3d3", + "0x12515f32629d7e71e2f1ef0de1a08ab2ed2cf9cb2ffea11aeab06e7dab64eec8", + "0x3484f89e98c0436f603319b8c5d5e324f3e2cb6995be3334641e14a21e998b21", + "0xb045c079ca13a4a6760bae38dccad8b35503437c4643b1180f99b2bef15b9eff", + "0xf81cb06b474d642ef15ae0382f3d792071862d4a00a967ed352fcf5fc55529b0", + "0x2edc394894bdc21c9827c789cd1f1226459e5489f7a87dd941efdcee56d0be78", + "0x7a1993168a29b0869fbb337144031dd0bc47520ab9498c9065b71fc90a100294", + "0x1963f11d488f5db4ea7f6e99b0bfe5006702e911930a7a95fab8a45ea1c4c955", + "0x7e12d33b54970a2fba8539d57c02b8318fab2f22ceb8b0ef69b6cc9ccfbd0658", + "0x32655b99bb59604c91af6270b15834688de512ca3088544785c0f0304d1faa20", + "0xec8984da3bc415604c9facb5cec0238f162b3da22fc4d20bcfed387c647728fe", + "0x7ba1756f8fa6637d8cb6cc588a679f6366827bc2044865744837c63e8a5aadcc", + "0xfc1a94a88f1e52bb78a0862eea4b996444f0264a3b301c1a31e59744d0216de8", + "0x79472bc4de84a0c430f15bcf8569486cddd2de985409ceb8e48abec8aa3e3fe7", + "0x02bc578dcc715304c651a43d8dcb4a761d2073a93cca2c39da3ee513f0c6d415" ] }, "accounts": { diff --git a/ethcore/res/ethereum/ropsten.json b/ethcore/res/ethereum/ropsten.json index c3b2b96b4f..953e7fdb42 100644 --- a/ethcore/res/ethereum/ropsten.json +++ b/ethcore/res/ethereum/ropsten.json @@ -62,8 +62,8 @@ "gasLimit": "0x1000000" }, "hardcodedSync": { - "header": "f90218a00379bed5cf7fb318965ec9b496aadc573fb78d1570ad2c43703c72e6c6ed997aa0b86c16b5c12556b0ea79b4d52ec77e3a3362ef43eeea51b594afc53c4b0ac115942450ec589db090d88e8de36c1790ca309841181da06183029c4e9e730abd17f5ea5427b626ed83796cab9bb4f28444cb7ab159f8f2a00ef00ef22f20f7d802cbede6ed8ff42d62671a7c07af9496e14710d7e63bbb9ea0a0e273f9d56a2ad827fb338fc0a109c28c0eee076d01454b76d42c99f8c54168b90100000c0002000000000000000000000400000000000000000000002000080000000008800010000000000000000000000002100000000000000000000020000000000000000000420000000008002000000000000000000000800001100000200004000000000000000000000008000000000000000000000000020010000000000000010000000010000040000000000000000020000000000000000028000018000000000000000000002000008000000800000000004000000000000000000000000002000009000000000810000000000040000000000000200100000000040000000000000000000200200000000000000000000000000000000000200000844af3d7d883486001837a120083146f76845c2c29239ad983010814846765746888676f312e31312e348664617277696ea071764589dfd7ecd322aee118da27aa747da4f5d14c1a5951f9b3a297d47a031888ba12cdb8daaeae57", - "totalDifficulty": "17277173430188370", + "header": "f90217a058893ba2a7f3d1625239b0ffab5b58219412b5fb51a608fc6ae7ff012496db9ba01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942b126e450158f14add6770739a2e6b4037526817a0a46d5b8474c625b4efd3d1d2864d7790770737587aa926fb223945d55a1d0da8a04ff0c821428157d6a4ace26e17d775eac4f42cc7d777898ded413780207fda11a0777f1c1c378807634128348e4f0eeca6a0e7f516ea411690ca04266323f671a4b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000844737e14e834dd801837a1200830186a0845c76311499d883010816846765746888676f312e31312e35856c696e7578a0676e77abeb493056c28a2d8fcd1238da73a29c9d915441fd8b5e36f6e910fa5d8803afeb22c339444f", + "totalDifficulty": "18334236703652990", "CHTs": [ "0x614648fc0a459451850bdfe353a932b5ff824e1b568478394f78b3ed5427e37a", "0x1eae561c582dbb7f4e041998e084e165d0332c915d3a6da367638a8d24f3fafc", @@ -2380,7 +2380,182 @@ "0x12cf00d3b11cbfaf2038ca1e9de63e4dff65a3352da5824043978ba8fe7e08cf", "0xd64011bda551b01b0b33e1065b0069fd1fe103e2e68c50fc5bdf1f99b4ab5e0f", "0x3e3bef8f3d76d1f410327cfd8f4453e0fb9ed392da173e26ffaaed662411f7af", - "0x435816db536c536e0470a3fbfa32fcd6adab877831ffa66417e19bfaa2c9c62b" + "0x435816db536c536e0470a3fbfa32fcd6adab877831ffa66417e19bfaa2c9c62b", + "0x19d27119d0c702eb7735d70b30c26567d6ae4c5d204870a036f2273f027a80a9", + "0xd48c41e8365e9872d953b89e2b3dd0fa762b3360958ec9928124f54c79df5f19", + "0x7da805659d8b9e3f6b14aab3a5bd8d25e9d2d960076b4baf6c394a02fc763d12", + "0x5491cc6940517e3a790bf6e32437537e0241c9fcb3302a3bf94133ceb65b8862", + "0x0568a4d9b4e91fd1046fda2cb8a718ba57ba1526610013f465be7777e94356c1", + "0x0831b1ce49717503b49502ffe6b854ab2eb2c4db30f5ea5033c011f5e5e3d309", + "0xabd50d7ea56144421474763563ecdb591ec1df8645ccba4e28990d8b9b8ed16e", + "0xfe4ceb9425449bde581ef04b46c1fc7bdbd8f422c43d64b2d1bbbe3ff4dd7a26", + "0x489137c52ef8c71e620220d8e9e842c2a5befa812b70b0a709ab4603a729047d", + "0x8fa480e08230c6b9d964bca0bc5d5a246e4eac6c8d45c75a4cfac8c4601f455d", + "0xe5cde020c71c0ad3e7f9a789247e5518bc1b824b4c6297e12d09a42e265e4bef", + "0xd4c0b9e39b70ef4f229884817c317f20f53386969f8c1e2ddc69cfa57b1014f9", + "0x75b91e206eb0a2fa7752da4d6421fc294a4cd7d6d06dbdeb7b7df50e157ae99e", + "0xa650044c8fb1c0d98b1e671d576f389b0b7be37e946b7623ff6203ca72c574aa", + "0xe6dd07898de5688be966dbc612764a9956ef1105a7a02695ea269b6e40ccb077", + "0xd1c7d40ae3558d4b42cbf6bce332e718ed8f9b7026b81195beea713ea9fe81da", + "0xdfd6c816adcdd1a588db0bbb4c09050527a107bcc47d76be91c7e309a54dec92", + "0xa67e60d39fad4b6389908ced2c0b6fc4d0b1ae78379de0452963589cde410618", + "0x88a629bbfd9f5ec014580d47210562cc0ba162fc2e7f609dcc34babef9d2f89a", + "0x685dcd734516a666b7e9018a420cc1ed6f1cd13d13f54dc782d3d2529bafd375", + "0x00adf1bec319f440e54009e1ffc45d58f38a120644a111239aef09d1f91c20ed", + "0x0ec349f19c0374334a6f9463b349e97c6a6696984c7779cf29bf048a6317224e", + "0x0f190a67c3804e6aa618106b554578687d0f3983c8350709362fb7e4728adace", + "0x7af75c91424ed2a01f0b796ea4772780395cf77d4051c91552fcb962a384a04c", + "0xa43e2914fa364effea580b8d8ae6d7c5480acf7b9330b226438c12fb5e478ea2", + "0x38deda38720cb7918d43b4b7296fa0168d77ffefee1217bbe198b382fefade22", + "0x40e97169e2871117267eedd1095f76d97719f6e9dec56b3423a9258bb09815d7", + "0x3368d112a868cabf7d21ea1c5c851fe0a37551c03d72cfd6b235e3a904eb5889", + "0xaa25f4d9f97ca1cdbda79c61f1ab84883a037eed60d9ec2301cdd5c404c9805b", + "0x21132089753a085a0a982388817137c591a9a34d2cd9e6651c57c76a8b80b716", + "0xdf0c2df6ca5680424ac369b411ce78031614632c5fe44e2d8af1ddac30cd729a", + "0x4f55598eecadc5136e90d15fcb9f87e1eec65ce18121127b49cd159c69c94098", + "0x8a6b7276e3def38187b0cf9156aec251bab76637505f97583dc4d426ec86be50", + "0xe8a516509c5bcb7e81372ce88f7d51982e092ea93f895e5dc666ddaea58edd54", + "0x3edb18c971bd2f867ab6dbb3d63228aa94ed0d0eb9f603af71ebfb201095b836", + "0x0e7de89c28113289c1f84ed91c289328b9cac13495b289ce11cd1c5942be1188", + "0x2610da85e8fb400db625442fecb8cbe20435e8736fedf3bbf715501697ae6be0", + "0x5668c3a61683c91b17467e48b2f27c7e377010eaee64c69d53ecb1ab89dee1e1", + "0x58bb1cf79609e7223f1883dcc6d80538e278e514b1e11c6c2871db55dcdd9914", + "0xfd8faec518007958057845c7b9f204c8dd473db5dc19ad5f2460802b1fae2693", + "0x304b287a3513bf02a35fa61a8cb6aeb214d453d9d53213f458c207d2e15a537e", + "0x7b8f9c4775a775637d9e3274068df7c5330096a52750d604e6f3818c4a7f0b15", + "0xaac892295bff6dc1d99e51a4114857a5fffbc3c8b2b24bd057156c91a5e3bf7a", + "0x34266cdb180c5227ebae64b8ddbecec44a6144214b9412d723924a92fb4a93c4", + "0x1ed56966b89b57904056fcec5d2a23ca5a5d809a7f5c889c5123e3994d660398", + "0xb44dde8ad3b29068b5d3b3551bef7082d8f09366ac622e57f6b494bd594c7a03", + "0xabebaf98aa2e70020b83e45d5ab56164dcc58a4493264cdd6dfff3e921b395aa", + "0xdf26e98e5499f58665912d987eaebe8234eec92c9cb4e788b274b9e9cc8b527d", + "0xdb1f809c70c5633bac0f1642ad929984ff56154b16e0d81b8fa6b10706336c3e", + "0xecc6cfaadef8dab02149f15d1f39932e53b3fcf25fdb1d0379ef9b933222c018", + "0x17351e250078e53f17a144aad0933172ddc648a8f2fc530f0d4468623328b43a", + "0xb832ca94746ea0be489afd60548e74d654278b8a08bffdda83f87e58459769c8", + "0xbe1d486c25ec6042a110acb68d2fb9daeafb830f1d739506213b5a0de51887b5", + "0x560e8231a58aa914a6b82977734a8ce364d970af688f014e8957933ca3026d66", + "0x76b6b1959f5e0579fef78f6549b171028811c2fd64265bafd701e0a2de9d64b4", + "0xba8ee49b308ea0c0475cd30b90252f4909063b86119e4d1cd53dcf6b4671b0bb", + "0x168bfb6c2fd68fd7194561d6b0f6f76e733dfa092d550de243a2a7c0e6b14fa0", + "0x8d5dbd6b82c31c1237d84256a837ff86e005033d83622531bb00de243da0e5f4", + "0xd12f68a021b6f806c9d75468486f2c4fbad295ec51c0f507c445fc535a0caa81", + "0xdbe40f0f8ee88a80512e2f9162776abf02218c6dfb61a36042ba973ab55aad3a", + "0x6cf853351f1371aacafc02da272b304b246176c2867377185b349c5f5880257f", + "0x3f37a65caa18187a3552e300aab18b27d4a2b2a25c049f29e5d8d7a2c57af78f", + "0xad59d1d4be0ce243a38e94ffee6b21fe073b28b0bee9b0249f560219e9bf604d", + "0xe28ca7ade73017341acecc09a647c6c0e638f6ebdf1566b534dd27d5e9ad67ce", + "0xe3577a39c6d3670d2fcee9f36bfb4e79bcbea5695013ae037a7a7b4c5302979a", + "0x56a8566c6bb04d61331e9950a97248e152742d6f0408a77258c102efde79a0bd", + "0xf199dbb8b24df16441c45f5db31af6597172dcff5bcb84306a3f8ee9e7ebdea1", + "0x85a9e253bae3c1c5064f320911e7f964c7315602e83374f5df7ba532cd2acefc", + "0x80ce75ad1b2de3054cc12adc1774ef8e37f3123387d06daeb545953b7a2bb044", + "0xb26d9c8ece65562068826bc872a6fd93e76634b8b7b598769d3df142ed5d17d2", + "0xa43a1662961c4bd1bfa93fdf911067aca94460c733f5a9e296f9e47740b6f8a2", + "0xf84716d76638301b784430585722e4c112375a69329ac03fb8e98882fbbd2fb3", + "0xbdb1551fc7d0e24f2096586ea482b83b8603db1642ba6aa12d8369214af5e4c4", + "0x8f8f8de670e0dc95346e2b14b82bf8a63d9a2a4eca385b1fafc19964cf98f710", + "0x6d3f91249ce7f7f852a4ffab23b7e949117df088f2e2aa3db0fb386755a16c92", + "0xeb9c005485707baed2b7ab034e68597bb8be65bd6f8283b690cd338bf7d1826b", + "0xcaa884959fbea1f5110d7cc4360c24b2ede43d32f8cba522d28946ffd2d900fa", + "0xa561dbe805f8ba3cb6d3d1524c4b3bcbc95ac330e6d71d33642412f8f0a1a2a3", + "0xf158b9329dbbb90083c88982656840cb134713ba122e7e39b287bca4b0605dd4", + "0xee3ce79371c0f0a1ac399a3a722a1c7515f6b02d2e03118e3fb6d521e245ab6e", + "0x1083d6dba68c10cb19935b627e5576b5bc4e7904c8ff59657ced1c8397468017", + "0xa893338e4a49166bd36f4361799c7cccaaee211b512e0c8821136cdb823e8ac8", + "0x1327e2948ee57993f1b721e9fedc8f7d2e91f041b3e01340375bcbbdead83bfc", + "0x6bc88c663e475911e9fbdfb9a33931c34bcfff5e533e82059d33cd69ee414d94", + "0x81d95020affda45f536e01b1a4b840eb72afe2e82633d81de11acdeada45d93b", + "0x91e59cb7e3729c776c4dd441c3377659b37fd881760b9e70c73d5288e99bfa0a", + "0xbf69325ef2072cd5e3d2e93b8e6e2abbaa03434212e1ba4d36459a0f064a64ba", + "0x11f4a2d21c3145af81ba0edb80a9c27cf1e2d53b1a43a42b58b49d4340ce4fa2", + "0x8c366dac642346ca05e2fc047999f9adcab3b8166482854b06c77c2439e0655d", + "0xdcae4952619f997d791aa6a973f1c8c1d3a0c21859b0c37bec64533a6f7c0630", + "0x5300c16e42bf43e34c9e59fc5748c3e05d38437943956eb80ae91cebb4e33d87", + "0x40ec29594f14d9d9a76b13342face2565914b050cc5e5eb96299c51ec92a529d", + "0xa7da6ccf5a72ad5b8cfb6d00aed5f9f7e2bd70670c57873735ce976249fdd5d9", + "0x177a1ca473ae2fb06ed39e180567da24fd14faffa062edbdcb0cffe4520045b9", + "0xea7c63d98ea30c23e0f4df53566214eda57c96f9449aab5a02c165ddb8e61bd7", + "0x6bf4bac02febf1f9459a433d08b373143f44c0beabd3f7bce4218259e8d91311", + "0x6883559d2ed97c78d0aea12c0d14f0dbc911db36a3bd9e3f8a7142e1083e118f", + "0x999416083ffc7371c9b95b6d1bea32da9c2b00827e1f0e1f615354dfe76dd5aa", + "0x82873c88efa3041aae1d36c2a787e592a7af56c3d86f321b1dc619b974c88ff6", + "0x6bfb4371b0a7b9eb9e3fb1f6987854d6e4210286b98bf8dfe6f71f12014ffe59", + "0x5502ec7d23c5559afca6ac2d6178c1f2c778e4dca22a6bc8b16619082cafdc00", + "0x97307b650b949382bc80b6ea446b629c0fbd37bb65a36ac1b33b1e4ac310c056", + "0xe33b1569d06b2b5d05065c11a0dc4f22d214a7a4e4003c1888f7469094330a8d", + "0x691870ffdeabba194cbc10492332d51702d75c40681662fcbd5489753bd5fcaf", + "0xd9676a94b8e3eeac02389ca8c0a6d730e2718c0cfc3a5bab3110aa170d64bbf5", + "0xf558d9d27beca0657bd8ca7e82d1788b1777dbe06b474b7598acdfd46e8030cf", + "0x381d766d66669a50d13a141535c441887cad897984d7b2bd52e9bf33c385669c", + "0xacbc99a6cf54ca6fcc9ad8f844f8bbd7639791b663956cda2ac59fed34027024", + "0x04e5b5dfedaa9369bed72fe0ce827e3c16e7a07a274661d76ec92347baa8deda", + "0x2a905b1aa12a30fb04f56b2d9a26a38ce10cc2e9dc910f213ec3c6b368b15bf0", + "0x0f40416a8bc6d699c404972d27c9b69093b387a78f22295cb0a6001cd437a4fa", + "0x05a52a1501ff0d2c044f0c1932e5eb217aa734cabd527d865796fdd120fd8856", + "0x36c70cc55f4b571882ecab711522e4bffd3ae8f6873d940a0e4626ade7797612", + "0x4a7af1b12b32d3bb38ec4aa0cda6535cd96043466a56f0641253c7b21abe9205", + "0xf637f992df45cd4b58d2db4d5c8360a65cf05a11f14dba70638e50b5bf70bff4", + "0x5b271fd0d5a0adaa16218fab9f75e0599d85c093233761a76c03ba060d5b7948", + "0x8e3554617c506afbd2eed41a4c8e2ecc1bf619b163843a983411c884e5b07320", + "0x96c35e763be9f9a95f76c81fbe1659d22715f5cdc0cb36c168c67a1062818914", + "0x1d1235e2789d0d283a3d4c06e391a1e38869c788255facbaca7e23c4e76e5ba4", + "0x25246df476679b7364020ebe600ff596b6eb17b23c68ab05885a02616bd2e5f5", + "0x0a516b13c9e864bcaabf531c43ed3ca725d4521c9d34ee08280fd13500cdcfb5", + "0x15b0defb12ba7d05f4c5b387efbcf5eb41e325ece9a0b83619a5b7e19283b677", + "0x5000d5c4cad2ef87de73eb2f10d6733a840d069200cb30d4221031381e8c8f36", + "0x15e98f25d14ef227fbca0b760e2d436e291d3668498f486611a6a3118f5a8556", + "0xdc0d786b90d673f30f84706d29643bf0c392464f30ea66052b153ec28ee4b7cb", + "0xe4da2a6b7a254b85df06dbe8f2bf24b4ca3ef6d5c3b0fc8c17e0ebd32d5d69ac", + "0xe2e6fe80f327eded1c263684cbc525e27839bc816b237588b902c66623c38eb7", + "0x1b8c963829103769fab68bdf45dfe4d6130abc9560590871665f23b190e959e6", + "0x5d2e7cb7a42acaadbc832fb8974756f9473b18263ea50aa281fbcfe217a15762", + "0xcf46e1381d84a33aa488d4674b3ac43a1b6afb102c7a425fcc1447769ef5e6f9", + "0x00532839fe3e0691e406d230c8d384b6bc562923048ea0d89f1be054252eee58", + "0xa68d5545328145a3dabe1b143a57a13057d14866c6b9c9da8b4781f4efed4945", + "0x5223699aa191c964875eb16507aacefde636e88c0f0093d92bc38be221fb3792", + "0xa9b807ba38a8434b3befcc91f6b93427dc81f365354f62d5ee69730e319ce5d9", + "0xfd0dd9977372d780c38981010a339dd6552e8f81fc7654362590e7c6b9fd1f6f", + "0xca3900d2a87a6e0b04d679bb87dc81bd1ac11e79e4f0355e314c7e41d76de4e3", + "0x78ee224a33ce3b2629f7640392846f17c228288b89d6c2d9db42726cf64225cb", + "0x48a4acdd0758838c9ce2b322bc77459c1cc0fdca3d588d60697c8a5aa3035273", + "0x6eb8aeeda5a4b26e73ac2bd7f838c974b5bc45de138d14ba58b51bfb6d51cf93", + "0xd6895877c885791db924b0ab1a1d666c06a10e6d210e02cf9c2f29726d3c565b", + "0xcffa80c70e6246e7b17173c071384a7b46dfdd5ab4b4b524c88871ca02c7e658", + "0xbf64411370653f8e08373438b03ccff7fc6ae1d70385cd26a7e73b57da07dd75", + "0xd9a39f3b774d208608c7d1d9d1fcdacf0c0ff6e8cb7915bca57e8056a8b914c9", + "0xd6a1f8fae6440d4ba8b2e392dbd07f6dd6290651a221b3749cd2dd6b0f39ba0c", + "0xa1ad925960651423f598ab111a0f2bcc5d3fc7f62fc72eb2753815277183a4ac", + "0xf3f6feaa55dcb3eb9c572404a0da1cf7dbb53983a98873b3f0398aad91773b69", + "0xdb902ac0d33bba7b0bcfbbe3b5533b970d07381fb00a973b4dd92c8f7af7bcb8", + "0x5f97ac6dd3f55bbf179eafc50c64042f2daccfcb3bae9c4305045b709cf19ae2", + "0x7061adfb4514170759ff4ddf3922b10f2c85c1a65c361936e504ec77df84b703", + "0x07ae6b39e66142978d35c4c2a517c55c23ec47ae341557e8cbe8a0d001df0f6f", + "0x0e6b9fc3fec4e75d812128fbbae0946dc48b511b198a5301833992e763423da3", + "0x7e1da14382f9908299fe46dedaf1878a6d01e9070554f1436514d320e0a4ebc8", + "0xdb6cdc7239c51386bb9eb371765cccb84e4e4de38acc5ad7e5503bd0f60a31a4", + "0xcd0069c9fb9ba8d136a2020580827799eac95f613f7b75bce8322fe67ecdc2e0", + "0x06932b0dc851ffb7ce68ed9083cecb5ba074716f188c5bb4df94de8e7e057046", + "0x3a2e83e02240263c4e416898f9d54bd0b579ddb0076537b58c47c3a17df15208", + "0x61b166d6dee81bdf6d101f23bf8ca40b74c2eb3f47561b4ef024d30f410f88a7", + "0x7a9e85a9000cb7308a5c57c7b1421b22f63e64f48630a79e449e7a207cf586a1", + "0xd573fcbaafb3882fdb1985c1b939961d35dd7bcbd5865be82276d0cea1afc7a8", + "0x697152abd7502169e0d801346a41c815d8bd8e75e55845d4a4b251def64a9583", + "0x77e5cfae8dc5913c4bbd4f4d84a797bf8919a0c21a4eab4f5dfb42fe8c5019d3", + "0x6e7af8bd163f679b81489d3ec3cc4948cc57ccb3e0c8cbc80e387783bb87641d", + "0x4bd5ece25cfda291179b8977a84369ab1590c9d4d5b45a24865ca010e5ffa676", + "0x6331f61c715be1fe8e0c90740cb89c0a7cee24524be2258ad49542959f845477", + "0x0af729bb18715399a1b07ffe2e0d562f71c27ee2bc01921c25327d421165bef7", + "0x98ee97e5bbeaa0715143a39f38ac56736f54fe5b971584b4061c58721c051a3f", + "0xd06e19176339b1fb5cf469b1f0ee4350a416d20aaa9c1be50bdd26687b2424bc", + "0x2385cde28be71e40f64ba5db5bd1a8e5f4b767a9a17c21a96fd2642ead428394", + "0x3d2ef2f0e4bae5c2ca6fb9fcfa1a9ffc435471a7a533b3b7df2b28402d335f58", + "0x2ecc6ed70661e692248c80735650c253dfe6b3c2213bfc259ebc70c898ee8e6e", + "0x8a68b3eb663796ca2189e49b9fe5902e36615d03d28ac34c01f63a135b930f0b", + "0x563d7efb4175fc12dab431175b5097186c2379a5aca1901e39d641d02865d426", + "0x1a55cf9842f9008e0730ae9fc6af9f288edba323803d0ae787fc0fdda99be8c9", + "0xccdf47cee7142cad27bbf224f0afd1a6e5178345cab510f2f8ee27115ab27ff7", + "0xc5b3582937ad993c5c234d059e6cd3b98f2fa4e3fe4ad591ecb6ae710b51fee9" ] }, "nodes": [ From ed18c7b54cb30ccb1029e2ac33029ed4d6a172af Mon Sep 17 00:00:00 2001 From: Hernando Castano Date: Fri, 1 Mar 2019 17:23:40 +0100 Subject: [PATCH 105/168] Use correct name for documentation field in Cargo.toml (#10440) --- util/memzero/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/memzero/Cargo.toml b/util/memzero/Cargo.toml index be2e627ffb..67d17d26d0 100644 --- a/util/memzero/Cargo.toml +++ b/util/memzero/Cargo.toml @@ -5,6 +5,6 @@ description = "A wrapper for zero-ing out memory when dropped" license = "GPL-3.0" homepage = "https://parity.io" repository = "https://github.com/paritytech/parity-ethereum" -docs = "https://docs.rs/crate/memzero" +documentation = "https://docs.rs/crate/memzero" authors = ["Parity Technologies "] edition = "2018" From 97cb010df8845a1d371e01ece028b3ed223276c9 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Sat, 2 Mar 2019 12:18:18 +0000 Subject: [PATCH 106/168] Silence Error::cause deprecations (#10438) --- ethcore/light/src/on_demand/mod.rs | 4 ++++ ethcore/private-tx/src/error.rs | 4 ++++ ethcore/service/src/error.rs | 4 ++++ ethcore/src/error.rs | 4 ++++ util/network/src/error.rs | 4 ++++ 5 files changed, 20 insertions(+) diff --git a/ethcore/light/src/on_demand/mod.rs b/ethcore/light/src/on_demand/mod.rs index ff1c980e28..609868ecb4 100644 --- a/ethcore/light/src/on_demand/mod.rs +++ b/ethcore/light/src/on_demand/mod.rs @@ -70,6 +70,10 @@ pub const DEFAULT_NUM_CONSECUTIVE_FAILED_REQUESTS: usize = 1; /// OnDemand related errors pub mod error { + // Silence: `use of deprecated item 'std::error::Error::cause': replaced by Error::source, which can support downcasting` + // https://github.com/paritytech/parity-ethereum/issues/10302 + #![allow(deprecated)] + use futures::sync::oneshot::Canceled; error_chain! { diff --git a/ethcore/private-tx/src/error.rs b/ethcore/private-tx/src/error.rs index b3465883f4..60eb17987a 100644 --- a/ethcore/private-tx/src/error.rs +++ b/ethcore/private-tx/src/error.rs @@ -14,6 +14,10 @@ // You should have received a copy of the GNU General Public License // along with Parity Ethereum. If not, see . +// Silence: `use of deprecated item 'std::error::Error::cause': replaced by Error::source, which can support downcasting` +// https://github.com/paritytech/parity-ethereum/issues/10302 +#![allow(deprecated)] + use ethereum_types::Address; use rlp::DecoderError; use ethtrie::TrieError; diff --git a/ethcore/service/src/error.rs b/ethcore/service/src/error.rs index 483409535a..d46abe1d95 100644 --- a/ethcore/service/src/error.rs +++ b/ethcore/service/src/error.rs @@ -14,6 +14,10 @@ // You should have received a copy of the GNU General Public License // along with Parity Ethereum. If not, see . +// Silence: `use of deprecated item 'std::error::Error::cause': replaced by Error::source, which can support downcasting` +// https://github.com/paritytech/parity-ethereum/issues/10302 +#![allow(deprecated)] + use ethcore; use io; use ethcore_private_tx; diff --git a/ethcore/src/error.rs b/ethcore/src/error.rs index 32cfe057a0..c3ffc90438 100644 --- a/ethcore/src/error.rs +++ b/ethcore/src/error.rs @@ -16,6 +16,10 @@ //! General error types for use in ethcore. +// Silence: `use of deprecated item 'std::error::Error::cause': replaced by Error::source, which can support downcasting` +// https://github.com/paritytech/parity-ethereum/issues/10302 +#![allow(deprecated)] + use std::{fmt, error}; use std::time::SystemTime; diff --git a/util/network/src/error.rs b/util/network/src/error.rs index bce6be8919..bd48830c1b 100644 --- a/util/network/src/error.rs +++ b/util/network/src/error.rs @@ -14,6 +14,10 @@ // You should have received a copy of the GNU General Public License // along with Parity Ethereum. If not, see . +// Silence: `use of deprecated item 'std::error::Error::cause': replaced by Error::source, which can support downcasting` +// https://github.com/paritytech/parity-ethereum/issues/10302 +#![allow(deprecated)] + use std::{io, net, fmt}; use libc::{ENFILE, EMFILE}; use io::IoError; From 1bd45642167b567f2890ba8854b93d5d3486c93a Mon Sep 17 00:00:00 2001 From: "Denis S. Soldatov aka General-Beck" Date: Mon, 4 Mar 2019 21:59:20 +0300 Subject: [PATCH 107/168] CI publish to aws (#10446) * move publish aws from gitlab.yml to gitlab scripts * gitlab.yml cleaning move publish AWS to gitlab scripts remove dependencies from android build --- .gitlab-ci.yml | 15 ++------------- scripts/gitlab/publish-aws.sh | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+), 13 deletions(-) create mode 100755 scripts/gitlab/publish-aws.sh diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 73dbf5ce07..71019c387f 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -176,19 +176,7 @@ publish-awss3-release: - build-darwin - build-windows script: - - echo "__________Push binaries to AWS S3____________" - - case "${SCHEDULE_TAG:-${CI_COMMIT_REF_NAME}}" in - (beta|stable|nightly) - export BUCKET=releases.parity.io/ethereum; - ;; - (*) - export BUCKET=builds-parity; - ;; - esac - - aws s3 sync ./artifacts s3://${BUCKET}/${SCHEDULE_TAG:-${CI_COMMIT_REF_NAME}}/ - after_script: - - aws s3 ls s3://${BUCKET}/${SCHEDULE_TAG:-${CI_COMMIT_REF_NAME}}/ - --recursive --human-readable --summarize + - scripts/gitlab/publish-aws.sh tags: - linux-docker @@ -209,6 +197,7 @@ build-android: image: parity/rust-android:gitlab-ci variables: CARGO_TARGET: armv7-linux-androideabi + dependencies: script: - scripts/gitlab/build-unix.sh tags: diff --git a/scripts/gitlab/publish-aws.sh b/scripts/gitlab/publish-aws.sh new file mode 100755 index 0000000000..395a3bd777 --- /dev/null +++ b/scripts/gitlab/publish-aws.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +set -e # fail on any error +set -u # treat unset variables as error + +echo "__________Push binaries to AWS S3____________" +case "${SCHEDULE_TAG:-${CI_COMMIT_REF_NAME}}" in + (beta|stable|nightly) + export BUCKET=releases.parity.io/ethereum; + ;; + (*) + export BUCKET=builds-parity; + ;; + esac +aws s3 sync ./artifacts s3://${BUCKET}/${SCHEDULE_TAG:-${CI_COMMIT_REF_NAME}}/ +echo "__________Read from S3____________" +aws s3 ls s3://${BUCKET}/${SCHEDULE_TAG:-${CI_COMMIT_REF_NAME}}/ + --recursive --human-readable --summarize From 701464281554adf9ceb14709b221e17d0301f60a Mon Sep 17 00:00:00 2001 From: Axel Chalon Date: Mon, 4 Mar 2019 20:24:53 +0100 Subject: [PATCH 108/168] Implement parity_versionInfo & parity_setChain on LC; fix parity_setChain (#10312) * Light client: implement parity_versionInfo RPC * Light client: implement set_exit_handler & parity_setChain RPC * parity_setChain RPC: return an error if failed (instead of `true`) * Implement eth_subscribe('syncing') RPC for full node & light node * Fix indentation * Revert commit: Implement eth_subscribe('syncing') * Revert change to Cr callback function --- ethcore/light/src/client/mod.rs | 25 +++++++++++++++++++++++++ ethcore/src/client/client.rs | 6 ++++-- ethcore/src/client/test_client.rs | 2 +- ethcore/src/client/traits.rs | 2 +- parity/rpc_apis.rs | 2 +- parity/run.rs | 8 ++++++-- rpc/src/v1/helpers/errors.rs | 9 +++++++++ rpc/src/v1/impls/light/parity.rs | 5 +++-- rpc/src/v1/impls/light/parity_set.rs | 9 ++++++--- rpc/src/v1/impls/parity_set.rs | 5 ++--- 10 files changed, 58 insertions(+), 15 deletions(-) diff --git a/ethcore/light/src/client/mod.rs b/ethcore/light/src/client/mod.rs index 90ebba39aa..8205ae2ab3 100644 --- a/ethcore/light/src/client/mod.rs +++ b/ethcore/light/src/client/mod.rs @@ -116,6 +116,9 @@ pub trait LightChainClient: Send + Sync { /// Query whether a block is known. fn is_known(&self, hash: &H256) -> bool; + /// Set the chain via a spec name. + fn set_spec_name(&self, new_spec_name: String) -> Result<(), ()>; + /// Clear the queue. fn clear_queue(&self); @@ -164,6 +167,8 @@ pub struct Client { listeners: RwLock>>, fetcher: T, verify_full: bool, + /// A closure to call when we want to restart the client + exit_handler: Mutex>>, } impl Client { @@ -190,6 +195,7 @@ impl Client { listeners: RwLock::new(vec![]), fetcher, verify_full: config.verify_full, + exit_handler: Mutex::new(None), }) } @@ -360,6 +366,14 @@ impl Client { self.chain.heap_size_of_children() } + /// Set a closure to call when the client wants to be restarted. + /// + /// The parameter passed to the callback is the name of the new chain spec to use after + /// the restart. + pub fn set_exit_handler(&self, f: F) where F: Fn(String) + 'static + Send { + *self.exit_handler.lock() = Some(Box::new(f)); + } + /// Get a handle to the verification engine. pub fn engine(&self) -> &Arc { &self.engine @@ -563,6 +577,17 @@ impl LightChainClient for Client { Client::engine(self) } + fn set_spec_name(&self, new_spec_name: String) -> Result<(), ()> { + trace!(target: "mode", "Client::set_spec_name({:?})", new_spec_name); + if let Some(ref h) = *self.exit_handler.lock() { + (*h)(new_spec_name); + Ok(()) + } else { + warn!("Not hypervised; cannot change chain."); + Err(()) + } + } + fn is_known(&self, hash: &H256) -> bool { self.status(hash) == BlockStatus::InChain } diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index d40fc30330..0be48a636e 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -1706,15 +1706,17 @@ impl BlockChainClient for Client { self.config.spec_name.clone() } - fn set_spec_name(&self, new_spec_name: String) { + fn set_spec_name(&self, new_spec_name: String) -> Result<(), ()> { trace!(target: "mode", "Client::set_spec_name({:?})", new_spec_name); if !self.enabled.load(AtomicOrdering::Relaxed) { - return; + return Err(()); } if let Some(ref h) = *self.exit_handler.lock() { (*h)(new_spec_name); + Ok(()) } else { warn!("Not hypervised; cannot change chain."); + Err(()) } } diff --git a/ethcore/src/client/test_client.rs b/ethcore/src/client/test_client.rs index 5236f7cd40..fbad806fdf 100644 --- a/ethcore/src/client/test_client.rs +++ b/ethcore/src/client/test_client.rs @@ -863,7 +863,7 @@ impl BlockChainClient for TestBlockChainClient { fn spec_name(&self) -> String { "foundation".into() } - fn set_spec_name(&self, _: String) { unimplemented!(); } + fn set_spec_name(&self, _: String) -> Result<(), ()> { unimplemented!(); } fn disable(&self) { self.disabled.store(true, AtomicOrder::Relaxed); } diff --git a/ethcore/src/client/traits.rs b/ethcore/src/client/traits.rs index 2bc7026220..8e4abc01cd 100644 --- a/ethcore/src/client/traits.rs +++ b/ethcore/src/client/traits.rs @@ -360,7 +360,7 @@ pub trait BlockChainClient : Sync + Send + AccountData + BlockChain + CallContra fn spec_name(&self) -> String; /// Set the chain via a spec name. - fn set_spec_name(&self, spec_name: String); + fn set_spec_name(&self, spec_name: String) -> Result<(), ()>; /// Disable the client from importing blocks. This cannot be undone in this session and indicates /// that a subsystem has reason to believe this executable incapable of syncing the chain. diff --git a/parity/rpc_apis.rs b/parity/rpc_apis.rs index 4413e6a779..9287f62720 100644 --- a/parity/rpc_apis.rs +++ b/parity/rpc_apis.rs @@ -634,7 +634,7 @@ impl LightDependencies { handler.extend_with(ParityAccounts::to_delegate(ParityAccountsClient::new(&self.accounts))); } Api::ParitySet => handler.extend_with( - light::ParitySetClient::new(self.sync.clone(), self.fetch.clone()) + light::ParitySetClient::new(self.client.clone(), self.sync.clone(), self.fetch.clone()) .to_delegate(), ), Api::Traces => handler.extend_with(light::TracesClient.to_delegate()), diff --git a/parity/run.rs b/parity/run.rs index 13e93c1e21..c4a3c75120 100644 --- a/parity/run.rs +++ b/parity/run.rs @@ -165,7 +165,9 @@ impl ::local_store::NodeInfo for FullNodeInfo { type LightClient = ::light::client::Client<::light_helpers::EpochFetch>; // helper for light execution. -fn execute_light_impl(cmd: RunCmd, logger: Arc) -> Result { +fn execute_light_impl(cmd: RunCmd, logger: Arc, on_client_rq: Cr) -> Result + where Cr: Fn(String) + 'static + Send +{ use light::client as light_client; use sync::{LightSyncParams, LightSync, ManageNetwork}; use parking_lot::{Mutex, RwLock}; @@ -367,6 +369,8 @@ fn execute_light_impl(cmd: RunCmd, logger: Arc) -> Result(cmd: RunCmd, logger: Arc, Rr: Fn() + 'static + Send { if cmd.light { - execute_light_impl(cmd, logger) + execute_light_impl(cmd, logger, on_client_rq) } else { execute_impl(cmd, logger, on_client_rq, on_updater_rq) } diff --git a/rpc/src/v1/helpers/errors.rs b/rpc/src/v1/helpers/errors.rs index eebd76dbe3..1ff40f979b 100644 --- a/rpc/src/v1/helpers/errors.rs +++ b/rpc/src/v1/helpers/errors.rs @@ -59,6 +59,7 @@ mod codes { pub const NO_PEERS: i64 = -32066; pub const DEPRECATED: i64 = -32070; pub const EXPERIMENTAL_RPC: i64 = -32071; + pub const CANNOT_RESTART: i64 = -32080; } pub fn unimplemented(details: Option) -> Error { @@ -125,6 +126,14 @@ pub fn account(error: &str, details: T) -> Error { } } +pub fn cannot_restart() -> Error { + Error { + code: ErrorCode::ServerError(codes::CANNOT_RESTART), + message: "Parity could not be restarted. This feature is disabled in development mode and if the binary name isn't parity.".into(), + data: None, + } +} + /// Internal error signifying a logic error in code. /// Should not be used when function can just fail /// because of invalid parameters or incomplete node state. diff --git a/rpc/src/v1/impls/light/parity.rs b/rpc/src/v1/impls/light/parity.rs index da7425e1f4..24dba420e4 100644 --- a/rpc/src/v1/impls/light/parity.rs +++ b/rpc/src/v1/impls/light/parity.rs @@ -24,6 +24,7 @@ use crypto::DEFAULT_MAC; use ethkey::{crypto::ecies, Brain, Generator}; use ethstore::random_phrase; use sync::{LightSyncInfo, LightSyncProvider, LightNetworkDispatcher, ManageNetwork}; +use updater::VersionInfo as UpdaterVersionInfo; use ethereum_types::{H64, H160, H256, H512, U64, U256}; use ethcore_logger::RotatingLogger; @@ -299,7 +300,7 @@ where } fn version_info(&self) -> Result { - Err(errors::light_unimplemented(None)) + Ok(UpdaterVersionInfo::this().into()) } fn releases_info(&self) -> Result> { @@ -389,7 +390,7 @@ where } fn logs_no_tx_hash(&self, filter: Filter) -> BoxFuture> { - let filter = match filter.try_into() { + let filter = match filter.try_into() { Ok(value) => value, Err(err) => return Box::new(future::err(err)), }; diff --git a/rpc/src/v1/impls/light/parity_set.rs b/rpc/src/v1/impls/light/parity_set.rs index 080e9402a1..f129f86b3c 100644 --- a/rpc/src/v1/impls/light/parity_set.rs +++ b/rpc/src/v1/impls/light/parity_set.rs @@ -23,6 +23,7 @@ use std::sync::Arc; use ethereum_types::{H160, H256, U256}; use fetch::{self, Fetch}; use hash::keccak_buffer; +use light::client::LightChainClient; use sync::ManageNetwork; use jsonrpc_core::{Result, BoxFuture}; @@ -33,14 +34,16 @@ use v1::types::{Bytes, ReleaseInfo, Transaction}; /// Parity-specific rpc interface for operations altering the settings. pub struct ParitySetClient { + client: Arc, net: Arc, fetch: F, } impl ParitySetClient { /// Creates new `ParitySetClient` with given `Fetch`. - pub fn new(net: Arc, fetch: F) -> Self { + pub fn new(client: Arc, net: Arc, fetch: F) -> Self { ParitySetClient { + client: client, net: net, fetch: fetch, } @@ -118,8 +121,8 @@ impl ParitySet for ParitySetClient { Err(errors::light_unimplemented(None)) } - fn set_spec_name(&self, _spec_name: String) -> Result { - Err(errors::light_unimplemented(None)) + fn set_spec_name(&self, spec_name: String) -> Result { + self.client.set_spec_name(spec_name).map(|_| true).map_err(|()| errors::cannot_restart()) } fn hash_content(&self, url: String) -> BoxFuture { diff --git a/rpc/src/v1/impls/parity_set.rs b/rpc/src/v1/impls/parity_set.rs index a50138eb19..16ef8d5432 100644 --- a/rpc/src/v1/impls/parity_set.rs +++ b/rpc/src/v1/impls/parity_set.rs @@ -211,8 +211,7 @@ impl ParitySet for ParitySetClient where } fn set_spec_name(&self, spec_name: String) -> Result { - self.client.set_spec_name(spec_name); - Ok(true) + self.client.set_spec_name(spec_name).map(|_| true).map_err(|()| errors::cannot_restart()) } fn hash_content(&self, url: String) -> BoxFuture { @@ -240,7 +239,7 @@ impl ParitySet for ParitySetClient where let hash = hash.into(); Ok(self.miner.remove_transaction(&hash) - .map(|t| Transaction::from_pending(t.pending().clone())) + .map(|t| Transaction::from_pending(t.pending().clone())) ) } } From 3e1d73126c41779e36a05383a4278822ccc6023a Mon Sep 17 00:00:00 2001 From: "Denis S. Soldatov aka General-Beck" Date: Tue, 5 Mar 2019 20:33:10 +0300 Subject: [PATCH 109/168] CI aws git checkout (#10451) * Updating the CI system with the publication of releases and binary files on github Signed-off-by: Denis S. Soldatov aka General-Beck * move publish aws from gitlab.yml to gitlab scripts Signed-off-by: Denis S. Soldatov aka General-Beck * gitlab.yml cleaning move publish AWS to gitlab scripts remove dependencies from android build Signed-off-by: Denis S. Soldatov aka General-Beck * Revert "Updating the CI system with the publication of releases and binary files on github" This reverts commit da87e06f2e4751dbca08a898b52926aef5ad0aba. * remove no-git for aws * microfix * no need in no_git then --- .gitlab-ci.yml | 10 ++-------- scripts/gitlab/publish-aws.sh | 4 ++-- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 71019c387f..579d046372 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -12,11 +12,6 @@ variables: CARGO_HOME: "${CI_PROJECT_DIR}/.cargo" CARGO_TARGET: x86_64-unknown-linux-gnu -.no_git: &no_git - variables: - GIT_STRATEGY: none - GIT_SUBMODULE_STRATEGY: none - .releaseable_branches: # list of git refs for building GitLab artifacts (think "pre-release binaries") only: &releaseable_branches @@ -102,7 +97,7 @@ build-windows: script: - sh scripts/gitlab/build-windows.sh tags: - - rust-windows + - rust-windows <<: *collect_artifacts publish-docker: @@ -169,7 +164,6 @@ publish-awss3-release: image: parity/awscli:latest stage: publish only: *releaseable_branches - <<: *no_git cache: {} dependencies: - build-linux @@ -197,7 +191,7 @@ build-android: image: parity/rust-android:gitlab-ci variables: CARGO_TARGET: armv7-linux-androideabi - dependencies: + dependencies: [] script: - scripts/gitlab/build-unix.sh tags: diff --git a/scripts/gitlab/publish-aws.sh b/scripts/gitlab/publish-aws.sh index 395a3bd777..56572657bd 100755 --- a/scripts/gitlab/publish-aws.sh +++ b/scripts/gitlab/publish-aws.sh @@ -6,10 +6,10 @@ set -u # treat unset variables as error echo "__________Push binaries to AWS S3____________" case "${SCHEDULE_TAG:-${CI_COMMIT_REF_NAME}}" in (beta|stable|nightly) - export BUCKET=releases.parity.io/ethereum; + BUCKET=releases.parity.io/ethereum; ;; (*) - export BUCKET=builds-parity; + BUCKET=builds-parity; ;; esac aws s3 sync ./artifacts s3://${BUCKET}/${SCHEDULE_TAG:-${CI_COMMIT_REF_NAME}}/ From 91933d857da2d30692276ad3a3b043067c3ff568 Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Wed, 6 Mar 2019 15:30:35 +0100 Subject: [PATCH 110/168] perf(ethcore): `micro-opt` (#10405) Mostly fixes that changes `eagerly eval` to `lazy eval` --- ethcore/light/src/on_demand/mod.rs | 6 +----- ethcore/src/client/client.rs | 2 +- ethcore/src/engines/authority_round/mod.rs | 24 ++++++++++++++------- ethcore/src/engines/validator_set/multi.rs | 4 ++-- ethcore/src/error.rs | 4 ++-- ethcore/src/executed.rs | 2 +- ethcore/src/externalities.rs | 2 +- ethcore/src/machine.rs | 2 +- ethcore/src/snapshot/consensus/authority.rs | 6 +++--- ethcore/src/snapshot/consensus/work.rs | 4 ++-- ethcore/src/snapshot/mod.rs | 4 ++-- ethcore/src/spec/spec.rs | 2 +- ethcore/src/state/mod.rs | 8 +++---- ethcore/src/verification/verification.rs | 2 +- ethcore/types/src/ids.rs | 2 +- 15 files changed, 39 insertions(+), 35 deletions(-) diff --git a/ethcore/light/src/on_demand/mod.rs b/ethcore/light/src/on_demand/mod.rs index 609868ecb4..c04c687947 100644 --- a/ethcore/light/src/on_demand/mod.rs +++ b/ethcore/light/src/on_demand/mod.rs @@ -24,7 +24,6 @@ use std::marker::PhantomData; use std::sync::Arc; use std::time::Duration; -use ethcore::executed::{Executed, ExecutionError}; use futures::{Poll, Future, Async}; use futures::sync::oneshot::{self, Receiver}; use network::PeerId; @@ -41,10 +40,10 @@ use cache::Cache; use request::{self as basic_request, Request as NetworkRequest}; use self::request::CheckedRequest; +pub use ethcore::executed::ExecutionResult; pub use self::request::{Request, Response, HeaderRef, Error as ValidityError}; pub use self::request_guard::{RequestGuard, Error as RequestError}; pub use self::response_guard::{ResponseGuard, Error as ResponseGuardError, Inner as ResponseGuardInner}; - pub use types::request::ResponseError; #[cfg(test)] @@ -54,9 +53,6 @@ pub mod request; mod request_guard; mod response_guard; -/// The result of execution -pub type ExecutionResult = Result; - /// The initial backoff interval for OnDemand queries pub const DEFAULT_REQUEST_MIN_BACKOFF_DURATION: Duration = Duration::from_secs(10); /// The maximum request interval for OnDemand queries diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index 0be48a636e..9eab30f342 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -1149,7 +1149,7 @@ impl Client { pub fn take_snapshot(&self, writer: W, at: BlockId, p: &snapshot::Progress) -> Result<(), EthcoreError> { let db = self.state_db.read().journal_db().boxed_clone(); let best_block_number = self.chain_info().best_block_number; - let block_number = self.block_number(at).ok_or(snapshot::Error::InvalidStartingBlock(at))?; + let block_number = self.block_number(at).ok_or_else(|| snapshot::Error::InvalidStartingBlock(at))?; if db.is_pruned() && self.pruning_info().earliest_state > block_number { return Err(snapshot::Error::OldBlockPrunedDB.into()); diff --git a/ethcore/src/engines/authority_round/mod.rs b/ethcore/src/engines/authority_round/mod.rs index 2a42acfe23..ef439b5d4b 100644 --- a/ethcore/src/engines/authority_round/mod.rs +++ b/ethcore/src/engines/authority_round/mod.rs @@ -512,15 +512,19 @@ fn header_expected_seal_fields(header: &Header, empty_steps_transition: u64) -> } fn header_step(header: &Header, empty_steps_transition: u64) -> Result { - let expected_seal_fields = header_expected_seal_fields(header, empty_steps_transition); - Rlp::new(&header.seal().get(0).expect( - &format!("was either checked with verify_block_basic or is genesis; has {} fields; qed (Make sure the spec file has a correct genesis seal)", expected_seal_fields))).as_val() + Rlp::new(&header.seal().get(0).unwrap_or_else(|| + panic!("was either checked with verify_block_basic or is genesis; has {} fields; qed (Make sure the spec + file has a correct genesis seal)", header_expected_seal_fields(header, empty_steps_transition)) + )) + .as_val() } fn header_signature(header: &Header, empty_steps_transition: u64) -> Result { - let expected_seal_fields = header_expected_seal_fields(header, empty_steps_transition); - Rlp::new(&header.seal().get(1).expect( - &format!("was checked with verify_block_basic; has {} fields; qed", expected_seal_fields))).as_val::().map(Into::into) + Rlp::new(&header.seal().get(1).unwrap_or_else(|| + panic!("was checked with verify_block_basic; has {} fields; qed", + header_expected_seal_fields(header, empty_steps_transition)) + )) + .as_val::().map(Into::into) } // extracts the raw empty steps vec from the header seal. should only be called when there are 3 fields in the seal @@ -934,8 +938,12 @@ impl Engine for AuthorityRound { return BTreeMap::default(); } - let step = header_step(header, self.empty_steps_transition).as_ref().map(ToString::to_string).unwrap_or("".into()); - let signature = header_signature(header, self.empty_steps_transition).as_ref().map(ToString::to_string).unwrap_or("".into()); + let step = header_step(header, self.empty_steps_transition).as_ref() + .map(ToString::to_string) + .unwrap_or_default(); + let signature = header_signature(header, self.empty_steps_transition).as_ref() + .map(ToString::to_string) + .unwrap_or_default(); let mut info = map![ "step".into() => step, diff --git a/ethcore/src/engines/validator_set/multi.rs b/ethcore/src/engines/validator_set/multi.rs index 8aa7aa3dee..b9ef677478 100644 --- a/ethcore/src/engines/validator_set/multi.rs +++ b/ethcore/src/engines/validator_set/multi.rs @@ -74,7 +74,7 @@ impl Multi { impl ValidatorSet for Multi { fn default_caller(&self, block_id: BlockId) -> Box { self.correct_set(block_id).map(|set| set.default_caller(block_id)) - .unwrap_or(Box::new(|_, _| Err("No validator set for given ID.".into()))) + .unwrap_or_else(|| Box::new(|_, _| Err("No validator set for given ID.".into()))) } fn on_epoch_begin(&self, _first: bool, header: &Header, call: &mut SystemCall) -> Result<(), ::error::Error> { @@ -141,7 +141,7 @@ impl ValidatorSet for Multi { *self.block_number.write() = Box::new(move |id| client .upgrade() .ok_or_else(|| "No client!".into()) - .and_then(|c| c.block_number(id).ok_or("Unknown block".into()))); + .and_then(|c| c.block_number(id).ok_or_else(|| "Unknown block".into()))); } } diff --git a/ethcore/src/error.rs b/ethcore/src/error.rs index c3ffc90438..d5aa45ba0e 100644 --- a/ethcore/src/error.rs +++ b/ethcore/src/error.rs @@ -37,7 +37,7 @@ use engines::EngineError; pub use executed::{ExecutionError, CallError}; -#[derive(Debug, PartialEq, Clone, Copy, Eq)] +#[derive(Debug, PartialEq, Clone, Eq)] /// Errors concerning block processing. pub enum BlockError { /// Block has too many uncles. @@ -88,7 +88,7 @@ pub enum BlockError { /// Timestamp header field is too far in future. TemporarilyInvalid(OutOfBounds), /// Log bloom header field is invalid. - InvalidLogBloom(Mismatch), + InvalidLogBloom(Box>), /// Number field of header is invalid. InvalidNumber(Mismatch), /// Block number isn't sensible. diff --git a/ethcore/src/executed.rs b/ethcore/src/executed.rs index f9be002ff8..0f46ee1dec 100644 --- a/ethcore/src/executed.rs +++ b/ethcore/src/executed.rs @@ -197,4 +197,4 @@ impl fmt::Display for CallError { } /// Transaction execution result. -pub type ExecutionResult = Result; +pub type ExecutionResult = Result, ExecutionError>; diff --git a/ethcore/src/externalities.rs b/ethcore/src/externalities.rs index a2f35b6ded..23a4a83c3d 100644 --- a/ethcore/src/externalities.rs +++ b/ethcore/src/externalities.rs @@ -117,7 +117,7 @@ impl<'a, T: 'a, V: 'a, B: 'a> Ext for Externalities<'a, T, V, B> { fn initial_storage_at(&self, key: &H256) -> vm::Result { if self.state.is_base_storage_root_unchanged(&self.origin_info.address)? { - self.state.checkpoint_storage_at(0, &self.origin_info.address, key).map(|v| v.unwrap_or(H256::zero())).map_err(Into::into) + self.state.checkpoint_storage_at(0, &self.origin_info.address, key).map(|v| v.unwrap_or_default()).map_err(Into::into) } else { warn!(target: "externalities", "Detected existing account {:#x} where a forced contract creation happened.", self.origin_info.address); Ok(H256::zero()) diff --git a/ethcore/src/machine.rs b/ethcore/src/machine.rs index a14cb3bd29..c0eae63d1e 100644 --- a/ethcore/src/machine.rs +++ b/ethcore/src/machine.rs @@ -173,7 +173,7 @@ impl EthereumMachine { origin: SYSTEM_ADDRESS, gas, gas_price: 0.into(), - value: value.unwrap_or(ActionValue::Transfer(0.into())), + value: value.unwrap_or_else(|| ActionValue::Transfer(0.into())), code, code_hash, data, diff --git a/ethcore/src/snapshot/consensus/authority.rs b/ethcore/src/snapshot/consensus/authority.rs index 909e00281c..4423e07401 100644 --- a/ethcore/src/snapshot/consensus/authority.rs +++ b/ethcore/src/snapshot/consensus/authority.rs @@ -76,7 +76,7 @@ impl SnapshotComponents for PoaSnapshot { } let header = chain.block_header_data(&transition.block_hash) - .ok_or(Error::BlockNotFound(transition.block_hash))?; + .ok_or_else(|| Error::BlockNotFound(transition.block_hash))?; let entry = { let mut entry_stream = RlpStream::new_list(2); @@ -101,12 +101,12 @@ impl SnapshotComponents for PoaSnapshot { let (block, receipts) = chain.block(&block_at) .and_then(|b| chain.block_receipts(&block_at).map(|r| (b, r))) - .ok_or(Error::BlockNotFound(block_at))?; + .ok_or_else(|| Error::BlockNotFound(block_at))?; let block = block.decode()?; let parent_td = chain.block_details(block.header.parent_hash()) .map(|d| d.total_difficulty) - .ok_or(Error::BlockNotFound(block_at))?; + .ok_or_else(|| Error::BlockNotFound(block_at))?; rlps.push({ let mut stream = RlpStream::new_list(5); diff --git a/ethcore/src/snapshot/consensus/work.rs b/ethcore/src/snapshot/consensus/work.rs index 0293d1a2fd..106fe4474c 100644 --- a/ethcore/src/snapshot/consensus/work.rs +++ b/ethcore/src/snapshot/consensus/work.rs @@ -116,7 +116,7 @@ impl<'a> PowWorker<'a> { let (block, receipts) = self.chain.block(&self.current_hash) .and_then(|b| self.chain.block_receipts(&self.current_hash).map(|r| (b, r))) - .ok_or(Error::BlockNotFound(self.current_hash))?; + .ok_or_else(|| Error::BlockNotFound(self.current_hash))?; let abridged_rlp = AbridgedBlock::from_block_view(&block.view()).into_inner(); @@ -160,7 +160,7 @@ impl<'a> PowWorker<'a> { let (last_header, last_details) = self.chain.block_header_data(&last) .and_then(|n| self.chain.block_details(&last).map(|d| (n, d))) - .ok_or(Error::BlockNotFound(last))?; + .ok_or_else(|| Error::BlockNotFound(last))?; let parent_number = last_header.number() - 1; let parent_hash = last_header.parent_hash(); diff --git a/ethcore/src/snapshot/mod.rs b/ethcore/src/snapshot/mod.rs index c05d0de6a3..19a5f8ce6e 100644 --- a/ethcore/src/snapshot/mod.rs +++ b/ethcore/src/snapshot/mod.rs @@ -157,7 +157,7 @@ pub fn take_snapshot( processing_threads: usize, ) -> Result<(), Error> { let start_header = chain.block_header_data(&block_at) - .ok_or(Error::InvalidStartingBlock(BlockId::Hash(block_at)))?; + .ok_or_else(|| Error::InvalidStartingBlock(BlockId::Hash(block_at)))?; let state_root = start_header.state_root(); let number = start_header.number(); @@ -512,7 +512,7 @@ fn rebuild_accounts( // fill out the storage trie and code while decoding. let (acc, maybe_code) = { let mut acct_db = AccountDBMut::from_hash(db, hash); - let storage_root = known_storage_roots.get(&hash).cloned().unwrap_or(H256::zero()); + let storage_root = known_storage_roots.get(&hash).cloned().unwrap_or_default(); account::from_fat_rlp(&mut acct_db, fat_rlp, storage_root)? }; diff --git a/ethcore/src/spec/spec.rs b/ethcore/src/spec/spec.rs index 4bd46b2bb6..2726ed4fd5 100644 --- a/ethcore/src/spec/spec.rs +++ b/ethcore/src/spec/spec.rs @@ -515,7 +515,7 @@ fn load_from(spec_params: SpecParams, s: ethjson::spec::Spec) -> Result), } #[derive(Eq, PartialEq, Clone, Copy, Debug)] @@ -218,7 +218,7 @@ pub fn check_proof( let options = TransactOptions::with_no_tracing().save_output_from_contract(); match state.execute(env_info, machine, transaction, options, true) { - Ok(executed) => ProvedExecution::Complete(executed), + Ok(executed) => ProvedExecution::Complete(Box::new(executed)), Err(ExecutionError::Internal(_)) => ProvedExecution::BadProof, Err(e) => ProvedExecution::Failed(e), } @@ -1254,7 +1254,7 @@ impl State { let trie = TrieDB::new(db, &self.root)?; let maybe_account: Option = { let panicky_decoder = |bytes: &[u8]| { - ::rlp::decode(bytes).expect(&format!("prove_account, could not query trie for account key={}", &account_key)) + ::rlp::decode(bytes).unwrap_or_else(|_| panic!("prove_account, could not query trie for account key={}", &account_key)) }; let query = (&mut recorder, panicky_decoder); trie.get_with(&account_key, query)? diff --git a/ethcore/src/verification/verification.rs b/ethcore/src/verification/verification.rs index 3f5008a2b8..2ce9f9de30 100644 --- a/ethcore/src/verification/verification.rs +++ b/ethcore/src/verification/verification.rs @@ -274,7 +274,7 @@ pub fn verify_block_final(expected: &Header, got: &Header) -> Result<(), Error> return Err(From::from(BlockError::InvalidGasUsed(Mismatch { expected: *expected.gas_used(), found: *got.gas_used() }))) } if expected.log_bloom() != got.log_bloom() { - return Err(From::from(BlockError::InvalidLogBloom(Mismatch { expected: *expected.log_bloom(), found: *got.log_bloom() }))) + return Err(From::from(BlockError::InvalidLogBloom(Box::new(Mismatch { expected: *expected.log_bloom(), found: *got.log_bloom() })))) } if expected.receipts_root() != got.receipts_root() { return Err(From::from(BlockError::InvalidReceiptsRoot(Mismatch { expected: *expected.receipts_root(), found: *got.receipts_root() }))) diff --git a/ethcore/types/src/ids.rs b/ethcore/types/src/ids.rs index dccb240d94..1f099be57d 100644 --- a/ethcore/types/src/ids.rs +++ b/ethcore/types/src/ids.rs @@ -17,7 +17,7 @@ //! Unique identifiers. use ethereum_types::H256; -use {BlockNumber}; +use BlockNumber; /// Uniquely identifies block. #[derive(Debug, PartialEq, Copy, Clone, Hash, Eq)] From 742a6007fec36b053c802debf89dd114c5be6840 Mon Sep 17 00:00:00 2001 From: "Denis S. Soldatov aka General-Beck" Date: Thu, 7 Mar 2019 14:45:35 +0300 Subject: [PATCH 111/168] Revert "CI aws git checkout (#10451)" (#10456) * Revert "CI aws git checkout (#10451)" This reverts commit 3e1d73126c41779e36a05383a4278822ccc6023a. * Update .gitlab-ci.yml revert aws script with small fixes * Delete publish-aws.sh --- .gitlab-ci.yml | 20 ++++++++++++++++++-- scripts/gitlab/publish-aws.sh | 18 ------------------ 2 files changed, 18 insertions(+), 20 deletions(-) delete mode 100755 scripts/gitlab/publish-aws.sh diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 579d046372..1988564233 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -12,6 +12,10 @@ variables: CARGO_HOME: "${CI_PROJECT_DIR}/.cargo" CARGO_TARGET: x86_64-unknown-linux-gnu +.no_git: &no_git #disable git strategy + variables: + GIT_STRATEGY: none + GIT_SUBMODULE_STRATEGY: none .releaseable_branches: # list of git refs for building GitLab artifacts (think "pre-release binaries") only: &releaseable_branches @@ -21,7 +25,7 @@ variables: - schedules -.collect_artifacts: &collect_artifacts +.collect_artifacts: &collect_artifacts artifacts: name: "${CI_JOB_NAME}_${SCHEDULE_TAG:-${CI_COMMIT_REF_NAME}}" when: on_success @@ -164,13 +168,25 @@ publish-awss3-release: image: parity/awscli:latest stage: publish only: *releaseable_branches + <<: *no_git cache: {} dependencies: - build-linux - build-darwin - build-windows script: - - scripts/gitlab/publish-aws.sh + - echo "__________Push binaries to AWS S3____________" + - case "${SCHEDULE_TAG:-${CI_COMMIT_REF_NAME}}" in + (beta|stable|nightly) + export BUCKET=releases.parity.io/ethereum; + ;; + (*) + export BUCKET=builds-parity; + ;; + esac + - aws s3 sync ./artifacts s3://${BUCKET}/${SCHEDULE_TAG:-${CI_COMMIT_REF_NAME}}/ + - echo "__________Read from S3____________" + - aws s3 ls s3://${BUCKET}/${SCHEDULE_TAG:-${CI_COMMIT_REF_NAME}} --recursive --human-readable --summarize tags: - linux-docker diff --git a/scripts/gitlab/publish-aws.sh b/scripts/gitlab/publish-aws.sh deleted file mode 100755 index 56572657bd..0000000000 --- a/scripts/gitlab/publish-aws.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash - -set -e # fail on any error -set -u # treat unset variables as error - -echo "__________Push binaries to AWS S3____________" -case "${SCHEDULE_TAG:-${CI_COMMIT_REF_NAME}}" in - (beta|stable|nightly) - BUCKET=releases.parity.io/ethereum; - ;; - (*) - BUCKET=builds-parity; - ;; - esac -aws s3 sync ./artifacts s3://${BUCKET}/${SCHEDULE_TAG:-${CI_COMMIT_REF_NAME}}/ -echo "__________Read from S3____________" -aws s3 ls s3://${BUCKET}/${SCHEDULE_TAG:-${CI_COMMIT_REF_NAME}}/ - --recursive --human-readable --summarize From ab27848dc473023d84af819df6812e11e7da9576 Mon Sep 17 00:00:00 2001 From: 5chdn <5chdn@users.noreply.github.com> Date: Thu, 7 Mar 2019 21:11:58 +0100 Subject: [PATCH 112/168] docs: update changelogs for 2.2.{8,9,10,11}, 2.3.{1,2,3,4,5}, and 2.4.0 (#10389) * docs: move changelog 2-3 to docs/ * docs: fix changelog 2-3 path * docs: add changelogs for 2.2.{8,9,10,11} * docs: add changelogs for 2.3.{1,2,3,4} * Update CHANGELOG.md * Update CHANGELOG-2.3.md * Update CHANGELOG.md * Update CHANGELOG.md --- CHANGELOG.md | 260 ++++++++++++++++++------------------------ docs/CHANGELOG-2.2.md | 75 ++++++++++++ docs/CHANGELOG-2.3.md | 255 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 438 insertions(+), 152 deletions(-) create mode 100644 docs/CHANGELOG-2.3.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 62119ce7ab..1ef1c68399 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,162 +1,118 @@ -## Parity-Ethereum [v2.3.0](https://github.com/paritytech/parity-ethereum/releases/tag/v2.3.0) (2019-01-16) +## Parity-Ethereum [v2.4.0](https://github.com/paritytech/parity-ethereum/releases/tag/v2.4.0) (2019-02-25) -Parity-Ethereum 2.3.0-beta is a consensus-relevant security release that reverts Constantinople on the Ethereum network. Upgrading is mandatory for Ethereum, and strongly recommended for other networks. +Parity-Ethereum 2.4.0-beta is our trifortnightly minor version release coming with a lot of new features as well as bugfixes and performance improvements. -- **Consensus** - Ethereum Network: Pull Constantinople protocol upgrade on Ethereum (#10189) - - Read more: [Security Alert: Ethereum Constantinople Postponement](https://blog.ethereum.org/2019/01/15/security-alert-ethereum-constantinople-postponement/) -- **Networking** - All networks: Ping nodes from discovery (#10167) -- **Wasm** - Kovan Network: Update pwasm-utils to 0.6.1 (#10134) - -Other notable changes: - -- Existing blocks in the database are now kept when restoring a Snapshot. (#8643) -- Block and transaction propagation is improved significantly. (#9954) -- The ERC-191 Signed Data Standard is now supported by `personal_sign191`. (#9701) -- Add support for ERC-191/712 `eth_signTypedData` as a standard for machine-verifiable and human-readable typed data signing with Ethereum keys. (#9631) -- Add support for ERC-1186 `eth_getProof` (#9001) -- Add experimental RPCs flag to enable ERC-191, ERC-712, and ERC-1186 APIs via `--jsonrpc-experimental` (#9928) -- Make `CALLCODE` to trace value to be the code address. (#9881) - -Configuration changes: - -- The EIP-98 transition is now disabled by default. If you previously had no `eip98transition` specified in your chain specification, you would enable this now manually on block `0x0`. (#9955) -- Also, unknown fields in chain specs are now rejected. (#9972) -- The Tendermint engine was removed from Parity Ethereum and is no longer available and maintained. (#9980) -- Ropsten testnet data and keys moved from `test/` to `ropsten/` subdir. To reuse your old keys and data either copy or symlink them to the new location. (#10123) -- Strict empty steps validation (#10041) - - If you have a chain with`empty_steps` already running, some blocks most likely contain non-strict entries (unordered or duplicated empty steps). In this release `strict_empty_steps_transition` is enabled by default at block `0x0` for any chain with `empty_steps`. - - If your network uses `empty_steps` you **must** (A) plan a hard fork and change `strict_empty_steps_transition` to the desired fork block and (B) update the clients of the whole network to 2.2.7-stable / 2.3.0-beta. If for some reason you don't want to do this please set`strict_empty_steps_transition` to `0xfffffffff` to disable it. - -_Note:_ This release marks Parity 2.3 as _beta_. All versions of Parity 2.2 are now considered _stable_. +Notable changes: +- Account management is now deprecated ([#10213](https://github.com/paritytech/parity-ethereum/pull/10213)) +- Local accounts can now be specified via CLI ([#9960](https://github.com/paritytech/parity-ethereum/pull/9960)) +- Chains can now be reset to a particular block via CLI ([#9782](https://github.com/paritytech/parity-ethereum/pull/9782)) +- Ethash now additionally implements ProgPoW ([#9762](https://github.com/paritytech/parity-ethereum/pull/9762)) +- The `eip1283DisableTransition` flag was added to revert EIP-1283 ([#10214](https://github.com/paritytech/parity-ethereum/pull/10214)) The full list of included changes: - -- Backports for 2.3.0 beta ([#10164](https://github.com/paritytech/parity-ethereum/pull/10164)) -- Snap: fix path in script ([#10157](https://github.com/paritytech/parity-ethereum/pull/10157)) -- Make sure parent block is not in importing queue when importing ancient blocks ([#10138](https://github.com/paritytech/parity-ethereum/pull/10138)) -- Ci: re-enable snap publishing ([#10142](https://github.com/paritytech/parity-ethereum/pull/10142)) -- Hf in POA Core (2019-01-18) - Constantinople ([#10155](https://github.com/paritytech/parity-ethereum/pull/10155)) -- Update EWF's tobalaba chainspec ([#10152](https://github.com/paritytech/parity-ethereum/pull/10152)) -- Replace ethcore-logger with env-logger. ([#10102](https://github.com/paritytech/parity-ethereum/pull/10102)) -- Finality: dont require chain head to be in the chain ([#10054](https://github.com/paritytech/parity-ethereum/pull/10054)) -- Remove caching for node connections ([#10143](https://github.com/paritytech/parity-ethereum/pull/10143)) -- Blooms file iterator empty on out of range position. ([#10145](https://github.com/paritytech/parity-ethereum/pull/10145)) -- Autogen docs for the "Configuring Parity Ethereum" wiki page. ([#10067](https://github.com/paritytech/parity-ethereum/pull/10067)) -- Misc: bump license header to 2019 ([#10135](https://github.com/paritytech/parity-ethereum/pull/10135)) -- Hide most of the logs from cpp example. ([#10139](https://github.com/paritytech/parity-ethereum/pull/10139)) -- Don't try to send oversized packets ([#10042](https://github.com/paritytech/parity-ethereum/pull/10042)) -- Private tx enabled flag added into STATUS packet ([#9999](https://github.com/paritytech/parity-ethereum/pull/9999)) -- Update pwasm-utils to 0.6.1 ([#10134](https://github.com/paritytech/parity-ethereum/pull/10134)) -- Extract blockchain from ethcore ([#10114](https://github.com/paritytech/parity-ethereum/pull/10114)) -- Ethcore: update hardcoded headers ([#10123](https://github.com/paritytech/parity-ethereum/pull/10123)) -- Identity fix ([#10128](https://github.com/paritytech/parity-ethereum/pull/10128)) -- Use LenCachingMutex to optimize verification. ([#10117](https://github.com/paritytech/parity-ethereum/pull/10117)) -- Pyethereum keystore support ([#9710](https://github.com/paritytech/parity-ethereum/pull/9710)) -- Bump rocksdb-sys to 0.5.5 ([#10124](https://github.com/paritytech/parity-ethereum/pull/10124)) -- Parity-clib: `async C bindings to RPC requests` + `subscribe/unsubscribe to websocket events` ([#9920](https://github.com/paritytech/parity-ethereum/pull/9920)) -- Refactor (hardware wallet) : reduce the number of threads ([#9644](https://github.com/paritytech/parity-ethereum/pull/9644)) -- Hf in POA Sokol (2019-01-04) ([#10077](https://github.com/paritytech/parity-ethereum/pull/10077)) -- Fix broken links ([#10119](https://github.com/paritytech/parity-ethereum/pull/10119)) -- Follow-up to [#10105](https://github.com/paritytech/parity-ethereum/issues/10105) ([#10107](https://github.com/paritytech/parity-ethereum/pull/10107)) -- Move EIP-712 crate back to parity-ethereum ([#10106](https://github.com/paritytech/parity-ethereum/pull/10106)) -- Move a bunch of stuff around ([#10101](https://github.com/paritytech/parity-ethereum/pull/10101)) -- Revert "Add --frozen when running cargo ([#10081](https://github.com/paritytech/parity-ethereum/pull/10081))" ([#10105](https://github.com/paritytech/parity-ethereum/pull/10105)) -- Fix left over small grumbles on whitespaces ([#10084](https://github.com/paritytech/parity-ethereum/pull/10084)) -- Add --frozen when running cargo ([#10081](https://github.com/paritytech/parity-ethereum/pull/10081)) -- Fix pubsub new_blocks notifications to include all blocks ([#9987](https://github.com/paritytech/parity-ethereum/pull/9987)) -- Update some dependencies for compilation with pc-windows-gnu ([#10082](https://github.com/paritytech/parity-ethereum/pull/10082)) -- Fill transaction hash on ethGetLog of light client. ([#9938](https://github.com/paritytech/parity-ethereum/pull/9938)) -- Update changelog update for 2.2.5-beta and 2.1.10-stable ([#10064](https://github.com/paritytech/parity-ethereum/pull/10064)) -- Implement len caching for parking_lot RwLock ([#10032](https://github.com/paritytech/parity-ethereum/pull/10032)) -- Update parking_lot to 0.7 ([#10050](https://github.com/paritytech/parity-ethereum/pull/10050)) -- Bump crossbeam. ([#10048](https://github.com/paritytech/parity-ethereum/pull/10048)) -- Ethcore: enable constantinople on ethereum ([#10031](https://github.com/paritytech/parity-ethereum/pull/10031)) -- Strict empty steps validation ([#10041](https://github.com/paritytech/parity-ethereum/pull/10041)) -- Center the Subtitle, use some CAPS ([#10034](https://github.com/paritytech/parity-ethereum/pull/10034)) -- Change test miner max memory to malloc reports. ([#10024](https://github.com/paritytech/parity-ethereum/pull/10024)) -- Sort the storage for private state ([#10018](https://github.com/paritytech/parity-ethereum/pull/10018)) -- Fix: test corpus_inaccessible panic ([#10019](https://github.com/paritytech/parity-ethereum/pull/10019)) -- Ci: move future releases to ethereum subdir on s3 ([#10017](https://github.com/paritytech/parity-ethereum/pull/10017)) -- Light(on_demand): decrease default time window to 10 secs ([#10016](https://github.com/paritytech/parity-ethereum/pull/10016)) -- Light client : failsafe crate (circuit breaker) ([#9790](https://github.com/paritytech/parity-ethereum/pull/9790)) -- Lencachingmutex ([#9988](https://github.com/paritytech/parity-ethereum/pull/9988)) -- Version and notification for private contract wrapper added ([#9761](https://github.com/paritytech/parity-ethereum/pull/9761)) -- Handle failing case for update account cache in require ([#9989](https://github.com/paritytech/parity-ethereum/pull/9989)) -- Add tokio runtime to ethcore io worker ([#9979](https://github.com/paritytech/parity-ethereum/pull/9979)) -- Move daemonize before creating account provider ([#10003](https://github.com/paritytech/parity-ethereum/pull/10003)) -- Docs: update changelogs ([#9990](https://github.com/paritytech/parity-ethereum/pull/9990)) -- Fix daemonize ([#10000](https://github.com/paritytech/parity-ethereum/pull/10000)) -- Fix Bloom migration ([#9992](https://github.com/paritytech/parity-ethereum/pull/9992)) -- Remove tendermint engine support ([#9980](https://github.com/paritytech/parity-ethereum/pull/9980)) -- Calculate gas for deployment transaction ([#9840](https://github.com/paritytech/parity-ethereum/pull/9840)) -- Fix unstable peers and slowness in sync ([#9967](https://github.com/paritytech/parity-ethereum/pull/9967)) -- Adds parity_verifySignature RPC method ([#9507](https://github.com/paritytech/parity-ethereum/pull/9507)) -- Improve block and transaction propagation ([#9954](https://github.com/paritytech/parity-ethereum/pull/9954)) -- Deny unknown fields for chainspec ([#9972](https://github.com/paritytech/parity-ethereum/pull/9972)) -- Fix docker build ([#9971](https://github.com/paritytech/parity-ethereum/pull/9971)) -- Ci: rearrange pipeline by logic ([#9970](https://github.com/paritytech/parity-ethereum/pull/9970)) -- Add changelogs for 2.0.9, 2.1.4, 2.1.6, and 2.2.1 ([#9963](https://github.com/paritytech/parity-ethereum/pull/9963)) -- Add Error message when sync is still in progress. ([#9475](https://github.com/paritytech/parity-ethereum/pull/9475)) -- Make CALLCODE to trace value to be the code address ([#9881](https://github.com/paritytech/parity-ethereum/pull/9881)) -- Fix light client informant while syncing ([#9932](https://github.com/paritytech/parity-ethereum/pull/9932)) -- Add a optional json dump state to evm-bin ([#9706](https://github.com/paritytech/parity-ethereum/pull/9706)) -- Disable EIP-98 transition by default ([#9955](https://github.com/paritytech/parity-ethereum/pull/9955)) -- Remove secret_store runtimes. ([#9888](https://github.com/paritytech/parity-ethereum/pull/9888)) -- Fix a deadlock ([#9952](https://github.com/paritytech/parity-ethereum/pull/9952)) -- Chore(eip712): remove unused `failure-derive` ([#9958](https://github.com/paritytech/parity-ethereum/pull/9958)) -- Do not use the home directory as the working dir in docker ([#9834](https://github.com/paritytech/parity-ethereum/pull/9834)) -- Prevent silent errors in daemon mode, closes [#9367](https://github.com/paritytech/parity-ethereum/issues/9367) ([#9946](https://github.com/paritytech/parity-ethereum/pull/9946)) -- Fix empty steps ([#9939](https://github.com/paritytech/parity-ethereum/pull/9939)) -- Adjust requests costs for light client ([#9925](https://github.com/paritytech/parity-ethereum/pull/9925)) -- Eip-1186: add `eth_getProof` RPC-Method ([#9001](https://github.com/paritytech/parity-ethereum/pull/9001)) -- Missing blocks in filter_changes RPC ([#9947](https://github.com/paritytech/parity-ethereum/pull/9947)) -- Allow rust-nightly builds fail in nightly builds ([#9944](https://github.com/paritytech/parity-ethereum/pull/9944)) -- Update eth-secp256k1 to include fix for BSDs ([#9935](https://github.com/paritytech/parity-ethereum/pull/9935)) -- Unbreak build on rust -stable ([#9934](https://github.com/paritytech/parity-ethereum/pull/9934)) -- Keep existing blocks when restoring a Snapshot ([#8643](https://github.com/paritytech/parity-ethereum/pull/8643)) -- Add experimental RPCs flag ([#9928](https://github.com/paritytech/parity-ethereum/pull/9928)) -- Clarify poll lifetime ([#9922](https://github.com/paritytech/parity-ethereum/pull/9922)) -- Docs(require rust 1.30) ([#9923](https://github.com/paritytech/parity-ethereum/pull/9923)) -- Use block header for building finality ([#9914](https://github.com/paritytech/parity-ethereum/pull/9914)) -- Simplify cargo audit ([#9918](https://github.com/paritytech/parity-ethereum/pull/9918)) -- Light-fetch: Differentiate between out-of-gas/manual throw and use required gas from response on failure ([#9824](https://github.com/paritytech/parity-ethereum/pull/9824)) -- Eip 191 ([#9701](https://github.com/paritytech/parity-ethereum/pull/9701)) -- Fix(logger): `reqwest` no longer a dependency ([#9908](https://github.com/paritytech/parity-ethereum/pull/9908)) -- Remove rust-toolchain file ([#9906](https://github.com/paritytech/parity-ethereum/pull/9906)) -- Foundation: 6692865, ropsten: 4417537, kovan: 9363457 ([#9907](https://github.com/paritytech/parity-ethereum/pull/9907)) -- Ethcore: use Machine::verify_transaction on parent block ([#9900](https://github.com/paritytech/parity-ethereum/pull/9900)) -- Chore(rpc-tests): remove unused rand ([#9896](https://github.com/paritytech/parity-ethereum/pull/9896)) -- Fix: Intermittent failing CI due to addr in use ([#9885](https://github.com/paritytech/parity-ethereum/pull/9885)) -- Chore(bump docopt): 0.8 -> 1.0 ([#9889](https://github.com/paritytech/parity-ethereum/pull/9889)) -- Use expect ([#9883](https://github.com/paritytech/parity-ethereum/pull/9883)) -- Use Weak reference in PubSubClient ([#9886](https://github.com/paritytech/parity-ethereum/pull/9886)) -- Ci: nuke the gitlab caches ([#9855](https://github.com/paritytech/parity-ethereum/pull/9855)) -- Remove unused code ([#9884](https://github.com/paritytech/parity-ethereum/pull/9884)) -- Fix json tracer overflow ([#9873](https://github.com/paritytech/parity-ethereum/pull/9873)) -- Allow to seal work on latest block ([#9876](https://github.com/paritytech/parity-ethereum/pull/9876)) -- Fix docker script ([#9854](https://github.com/paritytech/parity-ethereum/pull/9854)) -- Health endpoint ([#9847](https://github.com/paritytech/parity-ethereum/pull/9847)) -- Gitlab-ci: make android release build succeed ([#9743](https://github.com/paritytech/parity-ethereum/pull/9743)) -- Clean up existing benchmarks ([#9839](https://github.com/paritytech/parity-ethereum/pull/9839)) -- Update Callisto block reward code to support HF1 ([#9811](https://github.com/paritytech/parity-ethereum/pull/9811)) -- Option to disable keep alive for JSON-RPC http transport ([#9848](https://github.com/paritytech/parity-ethereum/pull/9848)) -- Classic.json Bootnode Update ([#9828](https://github.com/paritytech/parity-ethereum/pull/9828)) -- Support MIX. ([#9767](https://github.com/paritytech/parity-ethereum/pull/9767)) -- Ci: remove failing tests for android, windows, and macos ([#9788](https://github.com/paritytech/parity-ethereum/pull/9788)) -- Implement NoProof for json tests and update tests reference (replaces [#9744](https://github.com/paritytech/parity-ethereum/issues/9744)) ([#9814](https://github.com/paritytech/parity-ethereum/pull/9814)) -- Chore(bump regex) ([#9842](https://github.com/paritytech/parity-ethereum/pull/9842)) -- Ignore global cache for patched accounts ([#9752](https://github.com/paritytech/parity-ethereum/pull/9752)) -- Move state root verification before gas used ([#9841](https://github.com/paritytech/parity-ethereum/pull/9841)) -- Fix(docker-aarch64) : cross-compile config ([#9798](https://github.com/paritytech/parity-ethereum/pull/9798)) -- Version: bump nightly to 2.3.0 ([#9819](https://github.com/paritytech/parity-ethereum/pull/9819)) -- Tests modification for windows CI ([#9671](https://github.com/paritytech/parity-ethereum/pull/9671)) -- Eip-712 implementation ([#9631](https://github.com/paritytech/parity-ethereum/pull/9631)) -- Fix typo ([#9826](https://github.com/paritytech/parity-ethereum/pull/9826)) -- Clean up serde rename and use rename_all = camelCase when possible ([#9823](https://github.com/paritytech/parity-ethereum/pull/9823)) +- More Backports for Beta 2.4.0 ([#10431](https://github.com/paritytech/parity-ethereum/pull/10431)) + - Revert some changes, could be buggy ([#10399](https://github.com/paritytech/parity-ethereum/pull/10399)) + - Ci: clean up gitlab-ci.yml leftovers from previous merge ([#10429](https://github.com/paritytech/parity-ethereum/pull/10429)) + - 10000 > 5000 ([#10422](https://github.com/paritytech/parity-ethereum/pull/10422)) + - Fix underflow in pip, closes [#10419](https://github.com/paritytech/parity-ethereum/pull/10419) ([#10423](https://github.com/paritytech/parity-ethereum/pull/10423)) + - Fix panic when logging directory does not exist, closes [#10420](https://github.com/paritytech/parity-ethereum/pull/10420) ([#10424](https://github.com/paritytech/parity-ethereum/pull/10424)) + - Update hardcoded headers for Foundation, Ropsten, Kovan and Classic ([#10417](https://github.com/paritytech/parity-ethereum/pull/10417)) +- Backports for Beta 2.4.0 ([#10416](https://github.com/paritytech/parity-ethereum/pull/10416)) + - No-git for publish jobs, empty artifacts dir ([#10393](https://github.com/paritytech/parity-ethereum/pull/10393)) + - Snap: reenable i386, arm64, armhf architecture publishing ([#10386](https://github.com/paritytech/parity-ethereum/pull/10386)) + - Tx pool: always accept local transactions ([#10375](https://github.com/paritytech/parity-ethereum/pull/10375)) + - Fix to_pod storage trie value decoding ([#10368](https://github.com/paritytech/parity-ethereum/pull/10368)) +- Version: mark 2.4.0 beta +- Update to latest mem-db, hash-db and trie-db. ([#10314](https://github.com/paritytech/parity-ethereum/pull/10314)) +- Tx pool: always accept local transactions ([#10375](https://github.com/paritytech/parity-ethereum/pull/10375)) +- Fix(trace_main! macro): don't re-export ([#10384](https://github.com/paritytech/parity-ethereum/pull/10384)) +- Exchanged old(azure) bootnodes with new(ovh) ones ([#10309](https://github.com/paritytech/parity-ethereum/pull/10309)) +- Ethash: implement Progpow ([#9762](https://github.com/paritytech/parity-ethereum/pull/9762)) +- Snap: add the removable-media plug ([#10377](https://github.com/paritytech/parity-ethereum/pull/10377)) +- Add message to IO errors ([#10324](https://github.com/paritytech/parity-ethereum/pull/10324)) +- Chore(bump parity-daemonize): require rust >= 1.31 ([#10359](https://github.com/paritytech/parity-ethereum/pull/10359)) +- Secretstore: use in-memory transport in cluster tests ([#9850](https://github.com/paritytech/parity-ethereum/pull/9850)) +- Add fields to `memzero`'s Cargo.toml ([#10362](https://github.com/paritytech/parity-ethereum/pull/10362)) +- Snap: release untagged versions from branches to the candidate snap channel ([#10357](https://github.com/paritytech/parity-ethereum/pull/10357)) +- Fix(compilation warns): `no-default-features` ([#10346](https://github.com/paritytech/parity-ethereum/pull/10346)) +- No volumes are needed, just run -v volume:/path/in/the/container ([#10345](https://github.com/paritytech/parity-ethereum/pull/10345)) +- Fixed misstype ([#10351](https://github.com/paritytech/parity-ethereum/pull/10351)) +- Snap: prefix version and populate candidate channel ([#10343](https://github.com/paritytech/parity-ethereum/pull/10343)) +- Bundle protocol and packet_id together in chain sync ([#10315](https://github.com/paritytech/parity-ethereum/pull/10315)) +- Role back docker build image and docker deploy image to ubuntu:xenial… ([#10338](https://github.com/paritytech/parity-ethereum/pull/10338)) +- Change docker image based on debian instead of ubuntu due to the chan… ([#10336](https://github.com/paritytech/parity-ethereum/pull/10336)) +- Don't add discovery initiators to the node table ([#10305](https://github.com/paritytech/parity-ethereum/pull/10305)) +- Fix(docker): fix not receives SIGINT ([#10059](https://github.com/paritytech/parity-ethereum/pull/10059)) +- Snap: official image / test ([#10168](https://github.com/paritytech/parity-ethereum/pull/10168)) +- Fix(add helper for timestamp overflows) ([#10330](https://github.com/paritytech/parity-ethereum/pull/10330)) +- Additional error for invalid gas ([#10327](https://github.com/paritytech/parity-ethereum/pull/10327)) +- Revive parity_setMinGasPrice RPC call ([#10294](https://github.com/paritytech/parity-ethereum/pull/10294)) +- Add Statetest support for Constantinople Fix ([#10323](https://github.com/paritytech/parity-ethereum/pull/10323)) +- Fix(parity-clib): grumbles that were not addressed in [#9920](https://github.com/paritytech/parity-ethereum/pull/9920) ([#10154](https://github.com/paritytech/parity-ethereum/pull/10154)) +- Fix(light-rpc): Make `light_sync` generic ([#10238](https://github.com/paritytech/parity-ethereum/pull/10238)) +- Fix publish job ([#10317](https://github.com/paritytech/parity-ethereum/pull/10317)) +- Secure WS-RPC: grant access to all apis ([#10246](https://github.com/paritytech/parity-ethereum/pull/10246)) +- Make specification of protocol in SyncRequester::send_request explicit ([#10295](https://github.com/paritytech/parity-ethereum/pull/10295)) +- Fix: parity-clib/examples/cpp/CMakeLists.txt ([#10313](https://github.com/paritytech/parity-ethereum/pull/10313)) +- Ci optimizations ([#10297](https://github.com/paritytech/parity-ethereum/pull/10297)) +- Increase number of requested block bodies in chain sync ([#10247](https://github.com/paritytech/parity-ethereum/pull/10247)) +- Deprecate account management ([#10213](https://github.com/paritytech/parity-ethereum/pull/10213)) +- Properly handle check_epoch_end_signal errors ([#10015](https://github.com/paritytech/parity-ethereum/pull/10015)) +- Fix(osx and windows builds): bump parity-daemonize ([#10291](https://github.com/paritytech/parity-ethereum/pull/10291)) +- Add missing step for Using `systemd` service file ([#10175](https://github.com/paritytech/parity-ethereum/pull/10175)) +- Call private contract methods from another private contract (read-onl… ([#10086](https://github.com/paritytech/parity-ethereum/pull/10086)) +- Update ring to 0.14 ([#10262](https://github.com/paritytech/parity-ethereum/pull/10262)) +- Fix(secret-store): deprecation warning ([#10301](https://github.com/paritytech/parity-ethereum/pull/10301)) +- Update to jsonrpc-derive 10.0.2, fixes aliases bug ([#10300](https://github.com/paritytech/parity-ethereum/pull/10300)) +- Convert to jsonrpc-derive, use jsonrpc-* from crates.io ([#10298](https://github.com/paritytech/parity-ethereum/pull/10298)) +- Fix Windows build ([#10284](https://github.com/paritytech/parity-ethereum/pull/10284)) +- Don't run the CPP example on CI ([#10285](https://github.com/paritytech/parity-ethereum/pull/10285)) +- Additional tests for uint deserialization. ([#10279](https://github.com/paritytech/parity-ethereum/pull/10279)) +- Prevent silent errors in daemon mode ([#10007](https://github.com/paritytech/parity-ethereum/pull/10007)) +- Fix join-set test to be deterministic. ([#10263](https://github.com/paritytech/parity-ethereum/pull/10263)) +- Update CHANGELOG-2.2.md ([#10254](https://github.com/paritytech/parity-ethereum/pull/10254)) +- Macos heapsize force jemalloc ([#10234](https://github.com/paritytech/parity-ethereum/pull/10234)) +- Allow specifying local accounts via CLI ([#9960](https://github.com/paritytech/parity-ethereum/pull/9960)) +- Take in account zero gas price certification when doing transact_cont… ([#10232](https://github.com/paritytech/parity-ethereum/pull/10232)) +- Update CHANGELOG.md ([#10249](https://github.com/paritytech/parity-ethereum/pull/10249)) +- Fix typo: CHANGELOG-2.1 -> CHANGELOG-2.2 ([#10233](https://github.com/paritytech/parity-ethereum/pull/10233)) +- Update copyright year to 2019. ([#10181](https://github.com/paritytech/parity-ethereum/pull/10181)) +- Fixed: types::transaction::SignedTransaction; ([#10229](https://github.com/paritytech/parity-ethereum/pull/10229)) +- Fix(ManageNetwork): replace Range with RangeInclusive ([#10209](https://github.com/paritytech/parity-ethereum/pull/10209)) +- Import rpc transactions sequentially ([#10051](https://github.com/paritytech/parity-ethereum/pull/10051)) +- Enable St-Peters-Fork ("Constantinople Fix") ([#10223](https://github.com/paritytech/parity-ethereum/pull/10223)) +- Add EIP-1283 disable transition ([#10214](https://github.com/paritytech/parity-ethereum/pull/10214)) +- Echo CORS request headers by default ([#10221](https://github.com/paritytech/parity-ethereum/pull/10221)) +- Happy New Year! ([#10211](https://github.com/paritytech/parity-ethereum/pull/10211)) +- Perform stripping during build ([#10208](https://github.com/paritytech/parity-ethereum/pull/10208)) +- Remove CallContract and RegistryInfo re-exports from `ethcore/client` ([#10205](https://github.com/paritytech/parity-ethereum/pull/10205)) +- Extract CallContract and RegistryInfo traits into their own crate ([#10178](https://github.com/paritytech/parity-ethereum/pull/10178)) +- Update the changelogs for 2.1.11, 2.2.6, 2.2.7, and 2.3.0 ([#10197](https://github.com/paritytech/parity-ethereum/pull/10197)) +- Cancel Constantinople HF on POA Core ([#10198](https://github.com/paritytech/parity-ethereum/pull/10198)) +- Adds cli interface to allow reseting chain to a particular block ([#9782](https://github.com/paritytech/parity-ethereum/pull/9782)) +- Run all `igd` methods in its own thread ([#10195](https://github.com/paritytech/parity-ethereum/pull/10195)) +- Pull constantinople on ethereum network ([#10189](https://github.com/paritytech/parity-ethereum/pull/10189)) +- Update for Android cross-compilation. ([#10180](https://github.com/paritytech/parity-ethereum/pull/10180)) +- Version: bump fork blocks for kovan and foundation ([#10186](https://github.com/paritytech/parity-ethereum/pull/10186)) +- Handle the case for contract creation on an empty but exist account w… ([#10065](https://github.com/paritytech/parity-ethereum/pull/10065)) +- Align personal_unlockAccount behaviour when permanent unlock is disab… ([#10060](https://github.com/paritytech/parity-ethereum/pull/10060)) +- Drop `runtime` after others (especially `ws_server`) ([#10179](https://github.com/paritytech/parity-ethereum/pull/10179)) +- Version: bump nightly to 2.4 ([#10165](https://github.com/paritytech/parity-ethereum/pull/10165)) +- Skip locking in statedb for non-canon blocks ([#10141](https://github.com/paritytech/parity-ethereum/pull/10141)) +- Remove reference to ui-interface command-line option ([#10170](https://github.com/paritytech/parity-ethereum/pull/10170)) +- Fix [#9822](https://github.com/paritytech/parity-ethereum/pull/9822): trace_filter does not return failed contract creation ([#10140](https://github.com/paritytech/parity-ethereum/pull/10140)) +- Fix _cannot recursively call into `Core`_ issue ([#10144](https://github.com/paritytech/parity-ethereum/pull/10144)) +- Fix(whisper): correct PoW calculation ([#10166](https://github.com/paritytech/parity-ethereum/pull/10166)) +- Bump JSON-RPC ([#10151](https://github.com/paritytech/parity-ethereum/pull/10151)) +- Ping nodes from discovery ([#10167](https://github.com/paritytech/parity-ethereum/pull/10167)) +- Fix(android): remove dependency to libusb ([#10161](https://github.com/paritytech/parity-ethereum/pull/10161)) +- Refactor(trim_right_matches -> trim_end_matches) ([#10159](https://github.com/paritytech/parity-ethereum/pull/10159)) +- Merge Machine and WithRewards ([#10071](https://github.com/paritytech/parity-ethereum/pull/10071)) ## Previous releases -- [CHANGELOG-2.2](docs/CHANGELOG-2.2.md) (_stable_) +- [CHANGELOG-2.3](docs/CHANGELOG-2.3.md) (_stable_) +- [CHANGELOG-2.2](docs/CHANGELOG-2.2.md) (EOL: 2019-02-25) - [CHANGELOG-2.1](docs/CHANGELOG-2.1.md) (EOL: 2019-01-16) - [CHANGELOG-2.0](docs/CHANGELOG-2.0.md) (EOL: 2018-11-15) - [CHANGELOG-1.11](docs/CHANGELOG-1.11.md) (EOL: 2018-09-19) diff --git a/docs/CHANGELOG-2.2.md b/docs/CHANGELOG-2.2.md index b9fce50007..69d6a0dcb7 100644 --- a/docs/CHANGELOG-2.2.md +++ b/docs/CHANGELOG-2.2.md @@ -1,3 +1,78 @@ +Note: Parity Ethereum 2.2 reached End-of-Life on 2019-02-25 (EOL). + +## Parity-Ethereum [v2.2.11](https://github.com/paritytech/parity-ethereum/releases/tag/v2.2.11) (2019-02-21) + +Parity-Ethereum 2.2.11-stable is a maintenance release that fixes snap and docker installations. + +The full list of included changes: + +- Stable: snap: release untagged versions from branches to the candidate ([#10357](https://github.com/paritytech/parity-ethereum/pull/10357)) ([#10372](https://github.com/paritytech/parity-ethereum/pull/10372)) + - Snap: release untagged versions from branches to the candidate snap channel ([#10357](https://github.com/paritytech/parity-ethereum/pull/10357)) + - Snap: add the removable-media plug ([#10377](https://github.com/paritytech/parity-ethereum/pull/10377)) + - Exchanged old(azure) bootnodes with new(ovh) ones ([#10309](https://github.com/paritytech/parity-ethereum/pull/10309)) +- Stable Backports ([#10353](https://github.com/paritytech/parity-ethereum/pull/10353)) + - Version: bump stable to 2.2.11 + - Snap: prefix version and populate candidate channel ([#10343](https://github.com/paritytech/parity-ethereum/pull/10343)) + - Snap: populate candidate releases with beta snaps to avoid stale channel + - Snap: prefix version with v* + - No volumes are needed, just run -v volume:/path/in/the/container ([#10345](https://github.com/paritytech/parity-ethereum/pull/10345)) + +## Parity-Ethereum [v2.2.10](https://github.com/paritytech/parity-ethereum/releases/tag/v2.2.10) (2019-02-13) + +Parity-Ethereum 2.2.10-stable is a security-relevant release. A bug in the JSONRPC-deserialization module can cause crashes of all versions of Parity Ethereum nodes if an attacker is able to submit a specially-crafted RPC to certain publicly available endpoints. + +- https://www.parity.io/new-parity-ethereum-update-fixes-several-rpc-vulnerabilities/ + +The full list of included changes: + +- Additional error for invalid gas ([#10327](https://github.com/paritytech/parity-ethereum/pull/10327)) ([#10329](https://github.com/paritytech/parity-ethereum/pull/10329)) +- Backports for Stable 2.2.10 ([#10332](https://github.com/paritytech/parity-ethereum/pull/10332)) + - fix(docker-aarch64) : cross-compile config ([#9798](https://github.com/paritytech/parity-ethereum/pull/9798)) + - import rpc transactions sequentially ([#10051](https://github.com/paritytech/parity-ethereum/pull/10051)) + - fix(docker): fix not receives SIGINT ([#10059](https://github.com/paritytech/parity-ethereum/pull/10059)) + - snap: official image / test ([#10168](https://github.com/paritytech/parity-ethereum/pull/10168)) + - perform stripping during build ([#10208](https://github.com/paritytech/parity-ethereum/pull/10208)) + - Additional tests for uint/hash/bytes deserialization. ([#10279](https://github.com/paritytech/parity-ethereum/pull/10279)) + - Don't run the CPP example on CI ([#10285](https://github.com/paritytech/parity-ethereum/pull/10285)) + - CI optimizations ([#10297](https://github.com/paritytech/parity-ethereum/pull/10297)) + - fix publish job ([#10317](https://github.com/paritytech/parity-ethereum/pull/10317)) + - Add Statetest support for Constantinople Fix ([#10323](https://github.com/paritytech/parity-ethereum/pull/10323)) + - Add helper for Timestamp overflows ([#10330](https://github.com/paritytech/parity-ethereum/pull/10330)) + - Don't add discovery initiators to the node table ([#10305](https://github.com/paritytech/parity-ethereum/pull/10305)) + - change docker image based on debian instead of ubuntu due to the chan ([#10336](https://github.com/paritytech/parity-ethereum/pull/10336)) + - role back docker build image and docker deploy image to ubuntu:xenial based ([#10338](https://github.com/paritytech/parity-ethereum/pull/10338)) + +## Parity-Ethereum [v2.2.9](https://github.com/paritytech/parity-ethereum/releases/tag/v2.2.9) (2019-02-03) + +Parity-Ethereum 2.2.9-stable is a security-relevant release. A bug in the JSONRPC-deserialization module can cause crashes of all versions of Parity Ethereum nodes if an attacker is able to submit a specially-crafted RPC to certain publicly available endpoints. + +- https://www.parity.io/security-alert-parity-ethereum-03-02/ + +The full list of included changes: + +- Additional tests for uint deserialization. ([#10279](https://github.com/paritytech/parity-ethereum/pull/10279)) ([#10281](https://github.com/paritytech/parity-ethereum/pull/10281)) +- Version: bump stable to 2.2.9 ([#10282](https://github.com/paritytech/parity-ethereum/pull/10282)) + +## Parity-Ethereum [v2.2.8](https://github.com/paritytech/parity-ethereum/releases/tag/v2.2.8) (2019-02-01) + +Parity-Ethereum 2.2.8-stable is a consensus-relevant release that enables _St. Petersfork_ on: + +- Ethereum Block `7280000` (along with Constantinople) +- Kovan Block `10255201` +- Ropsten Block `4939394` +- POA Sokol Block `7026400` + +In addition to this, Constantinople is cancelled for the POA Core network. Upgrading is mandatory for clients on any of these chains. + +The full list of included changes: + +- Backports for stable 2.2.8 ([#10224](https://github.com/paritytech/parity-ethereum/pull/10224)) + - Update for Android cross-compilation. ([#10180](https://github.com/paritytech/parity-ethereum/pull/10180)) + - Cancel Constantinople HF on POA Core ([#10198](https://github.com/paritytech/parity-ethereum/pull/10198)) + - Add EIP-1283 disable transition ([#10214](https://github.com/paritytech/parity-ethereum/pull/10214)) + - Enable St-Peters-Fork ("Constantinople Fix") ([#10223](https://github.com/paritytech/parity-ethereum/pull/10223)) +- Stable: Macos heapsize force jemalloc ([#10234](https://github.com/paritytech/parity-ethereum/pull/10234)) ([#10258](https://github.com/paritytech/parity-ethereum/pull/10258)) + ## Parity-Ethereum [v2.2.7](https://github.com/paritytech/parity-ethereum/releases/tag/v2.2.7) (2019-01-15) Parity-Ethereum 2.2.7-stable is a consensus-relevant security release that reverts Constantinople on the Ethereum network. Upgrading is mandatory for Ethereum, and strongly recommended for other networks. diff --git a/docs/CHANGELOG-2.3.md b/docs/CHANGELOG-2.3.md new file mode 100644 index 0000000000..f7e75d4427 --- /dev/null +++ b/docs/CHANGELOG-2.3.md @@ -0,0 +1,255 @@ +## Parity-Ethereum [v2.3.5](https://github.com/paritytech/parity-ethereum/releases/tag/v2.3.5) (2019-02-25) + +Parity-Ethereum 2.3.5-stable is a bugfix release that improves performance and stability. + +Note, all 2.2 releases and older are now unsupported and upgrading is recommended. + +The full list of included changes: + +- More Backports for Stable 2.3.5 ([#10430](https://github.com/paritytech/parity-ethereum/pull/10430)) + - Revert some changes, could be buggy ([#10399](https://github.com/paritytech/parity-ethereum/pull/10399)) + - Ci: clean up gitlab-ci.yml leftovers from previous merge ([#10429](https://github.com/paritytech/parity-ethereum/pull/10429)) + - 10000 > 5000 ([#10422](https://github.com/paritytech/parity-ethereum/pull/10422)) + - Fix underflow in pip, closes [#10419](https://github.com/paritytech/parity-ethereum/pull/10419) ([#10423](https://github.com/paritytech/parity-ethereum/pull/10423)) + - Fix panic when logging directory does not exist, closes [#10420](https://github.com/paritytech/parity-ethereum/pull/10420) ([#10424](https://github.com/paritytech/parity-ethereum/pull/10424)) + - Update hardcoded headers for Foundation, Ropsten, Kovan and Classic ([#10417](https://github.com/paritytech/parity-ethereum/pull/10417)) +- Backports for Stable 2.3.5 ([#10414](https://github.com/paritytech/parity-ethereum/pull/10414)) + - No-git for publish jobs, empty artifacts dir ([#10393](https://github.com/paritytech/parity-ethereum/pull/10393)) + - Snap: reenable i386, arm64, armhf architecture publishing ([#10386](https://github.com/paritytech/parity-ethereum/pull/10386)) + - Tx pool: always accept local transactions ([#10375](https://github.com/paritytech/parity-ethereum/pull/10375)) + - Fix to_pod storage trie value decoding ([#10368)](https://github.com/paritytech/parity-ethereum/pull/10368)) +- Version: mark 2.3.5 as stable + +## Parity-Ethereum [v2.3.4](https://github.com/paritytech/parity-ethereum/releases/tag/v2.3.4) (2019-02-21) + +Parity-Ethereum 2.3.4-beta is a maintenance release that fixes snap and docker installations. + +The full list of included changes: +- Beta: snap: release untagged versions from branches to the candidate ([#10357](https://github.com/paritytech/parity-ethereum/pull/10357)) ([#10373](https://github.com/paritytech/parity-ethereum/pull/10373)) + - Snap: release untagged versions from branches to the candidate snap channel ([#10357](https://github.com/paritytech/parity-ethereum/pull/10357)) + - Snap: add the removable-media plug ([#10377](https://github.com/paritytech/parity-ethereum/pull/10377)) + - Exchanged old(azure) bootnodes with new(ovh) ones ([#10309](https://github.com/paritytech/parity-ethereum/pull/10309)) +- Beta Backports ([#10354](https://github.com/paritytech/parity-ethereum/pull/10354)) + - Version: bump beta to 2.3.4 + - Snap: prefix version and populate candidate channel ([#10343](https://github.com/paritytech/parity-ethereum/pull/10343)) + - Snap: populate candidate releases with beta snaps to avoid stale channel + - Snap: prefix version with v* + - No volumes are needed, just run -v volume:/path/in/the/container ([#10345](https://github.com/paritytech/parity-ethereum/pull/10345)) + +## Parity-Ethereum [v2.3.3](https://github.com/paritytech/parity-ethereum/releases/tag/v2.3.3) (2019-02-13) + +Parity-Ethereum 2.3.3-beta is a security-relevant release. A bug in the JSONRPC-deserialization module can cause crashes of all versions of Parity Ethereum nodes if an attacker is able to submit a specially-crafted RPC to certain publicly available endpoints. + +- https://www.parity.io/new-parity-ethereum-update-fixes-several-rpc-vulnerabilities/ + +The full list of included changes: + +- Additional error for invalid gas ([#10327](https://github.com/paritytech/parity-ethereum/pull/10327)) ([#10328](https://github.com/paritytech/parity-ethereum/pull/10328)) +- Backports for Beta 2.3.3 ([#10333](https://github.com/paritytech/parity-ethereum/pull/10333)) + - Properly handle check_epoch_end_signal errors ([#10015](https://github.com/paritytech/parity-ethereum/pull/10015)) + - import rpc transactions sequentially ([#10051](https://github.com/paritytech/parity-ethereum/pull/10051)) + - fix(docker): fix not receives SIGINT ([#10059](https://github.com/paritytech/parity-ethereum/pull/10059)) + - snap: official image / test ([#10168](https://github.com/paritytech/parity-ethereum/pull/10168)) + - Extract CallContract and RegistryInfo traits into their own crate ([#10178](https://github.com/paritytech/parity-ethereum/pull/10178)) + - perform stripping during build ([#10208](https://github.com/paritytech/parity-ethereum/pull/10208)) + - Remove CallContract and RegistryInfo re-exports from `ethcore/client` ([#10205](https://github.com/paritytech/parity-ethereum/pull/10205)) + - fixed: types::transaction::SignedTransaction; ([#10229](https://github.com/paritytech/parity-ethereum/pull/10229)) + - Additional tests for uint/hash/bytes deserialization. ([#10279](https://github.com/paritytech/parity-ethereum/pull/10279)) + - Fix Windows build ([#10284](https://github.com/paritytech/parity-ethereum/pull/10284)) + - Don't run the CPP example on CI ([#10285](https://github.com/paritytech/parity-ethereum/pull/10285)) + - CI optimizations ([#10297](https://github.com/paritytech/parity-ethereum/pull/10297)) + - fix publish job ([#10317](https://github.com/paritytech/parity-ethereum/pull/10317)) + - Add Statetest support for Constantinople Fix ([#10323](https://github.com/paritytech/parity-ethereum/pull/10323)) + - Add helper for Timestamp overflows ([#10330](https://github.com/paritytech/parity-ethereum/pull/10330)) + - Don't add discovery initiators to the node table ([#10305](https://github.com/paritytech/parity-ethereum/pull/10305)) + - change docker image based on debian instead of ubuntu due to the chan ([#10336](https://github.com/paritytech/parity-ethereum/pull/10336)) + - role back docker build image and docker deploy image to ubuntu:xenial based ([#10338](https://github.com/paritytech/parity-ethereum/pull/10338)) + +## Parity-Ethereum [v2.3.2](https://github.com/paritytech/parity-ethereum/releases/tag/v2.3.2) (2019-02-03) + +Parity-Ethereum 2.3.2-stable is a security-relevant release. A bug in the JSONRPC-deserialization module can cause crashes of all versions of Parity Ethereum nodes if an attacker is able to submit a specially-crafted RPC to certain publicly available endpoints. + +- https://www.parity.io/security-alert-parity-ethereum-03-02/ + +The full list of included changes: +- Version: bump beta to 2.3.2 ([#10283](https://github.com/paritytech/parity-ethereum/pull/10283)) +- Additional tests for uint deserialization. ([#10279](https://github.com/paritytech/parity-ethereum/pull/10279)) ([#10280](https://github.com/paritytech/parity-ethereum/pull/10280)) +- Backport [#10285](https://github.com/paritytech/parity-ethereum/pull/10285) to beta ([#10286](https://github.com/paritytech/parity-ethereum/pull/10286)) + +## Parity-Ethereum [v2.3.1](https://github.com/paritytech/parity-ethereum/releases/tag/v2.3.1) (2019-02-01) + +Parity-Ethereum 2.3.1-beta is a consensus-relevant release that enables _St. Petersfork_ on: + +- Ethereum Block `7280000` (along with Constantinople) +- Kovan Block `10255201` +- Ropsten Block `4939394` +- POA Sokol Block `7026400` + +In addition to this, Constantinople is cancelled for the POA Core network. Upgrading is mandatory for clients on any of these chains. + +The full list of included changes: + +- Backports for beta 2.3.1 ([#10225](https://github.com/paritytech/parity-ethereum/pull/10225)) + - Fix _cannot recursively call into `Core`_ issue ([#10144](https://github.com/paritytech/parity-ethereum/pull/10144)) + - Update for Android cross-compilation. ([#10180](https://github.com/paritytech/parity-ethereum/pull/10180)) + - Fix _cannot recursively call into `Core`_ - Part 2 ([#10195](https://github.com/paritytech/parity-ethereum/pull/10195)) + - Cancel Constantinople HF on POA Core ([#10198](https://github.com/paritytech/parity-ethereum/pull/10198)) + - Add EIP-1283 disable transition ([#10214](https://github.com/paritytech/parity-ethereum/pull/10214)) + - Enable St-Peters-Fork ("Constantinople Fix") ([#10223](https://github.com/paritytech/parity-ethereum/pull/10223)) +- Beta: Macos heapsize force jemalloc ([#10234](https://github.com/paritytech/parity-ethereum/pull/10234)) ([#10259](https://github.com/paritytech/parity-ethereum/pull/10259)) + +## Parity-Ethereum [v2.3.0](https://github.com/paritytech/parity-ethereum/releases/tag/v2.3.0) (2019-01-16) + +Parity-Ethereum 2.3.0-beta is a consensus-relevant security release that reverts Constantinople on the Ethereum network. Upgrading is mandatory for Ethereum, and strongly recommended for other networks. + +- **Consensus** - Ethereum Network: Pull Constantinople protocol upgrade on Ethereum ([#10189](https://github.com/paritytech/parity-ethereum/pull/10189)) + - Read more: [Security Alert: Ethereum Constantinople Postponement](https://blog.ethereum.org/2019/01/15/security-alert-ethereum-constantinople-postponement/) +- **Networking** - All networks: Ping nodes from discovery ([#10167](https://github.com/paritytech/parity-ethereum/pull/10167)) +- **Wasm** - Kovan Network: Update pwasm-utils to 0.6.1 ([#10134](https://github.com/paritytech/parity-ethereum/pull/10134)) + +Other notable changes: + +- Existing blocks in the database are now kept when restoring a Snapshot. ([#8643](https://github.com/paritytech/parity-ethereum/pull/8643)) +- Block and transaction propagation is improved significantly. ([#9954](https://github.com/paritytech/parity-ethereum/pull/9954)) +- The ERC-191 Signed Data Standard is now supported by `personal_sign191`. ([#9701](https://github.com/paritytech/parity-ethereum/pull/9701)) +- Add support for ERC-191/712 `eth_signTypedData` as a standard for machine-verifiable and human-readable typed data signing with Ethereum keys. ([#9631](https://github.com/paritytech/parity-ethereum/pull/9631)) +- Add support for ERC-1186 `eth_getProof` ([#9001](https://github.com/paritytech/parity-ethereum/pull/9001)) +- Add experimental RPCs flag to enable ERC-191, ERC-712, and ERC-1186 APIs via `--jsonrpc-experimental` ([#9928](https://github.com/paritytech/parity-ethereum/pull/9928)) +- Make `CALLCODE` to trace value to be the code address. ([#9881](https://github.com/paritytech/parity-ethereum/pull/9881)) + +Configuration changes: + +- The EIP-98 transition is now disabled by default. If you previously had no `eip98transition` specified in your chain specification, you would enable this now manually on block `0x0`. ([#9955](https://github.com/paritytech/parity-ethereum/pull/9955)) +- Also, unknown fields in chain specs are now rejected. ([#9972](https://github.com/paritytech/parity-ethereum/pull/9972)) +- The Tendermint engine was removed from Parity Ethereum and is no longer available and maintained. ([#9980](https://github.com/paritytech/parity-ethereum/pull/9980)) +- Ropsten testnet data and keys moved from `test/` to `ropsten/` subdir. To reuse your old keys and data either copy or symlink them to the new location. ([#10123](https://github.com/paritytech/parity-ethereum/pull/10123)) +- Strict empty steps validation ([#10041](https://github.com/paritytech/parity-ethereum/pull/10041)) + - If you have a chain with`empty_steps` already running, some blocks most likely contain non-strict entries (unordered or duplicated empty steps). In this release `strict_empty_steps_transition` is enabled by default at block `0x0` for any chain with `empty_steps`. + - If your network uses `empty_steps` you **must** (A) plan a hard fork and change `strict_empty_steps_transition` to the desired fork block and (B) update the clients of the whole network to 2.2.7-stable / 2.3.0-beta. If for some reason you don't want to do this please set`strict_empty_steps_transition` to `0xfffffffff` to disable it. + +_Note:_ This release marks Parity 2.3 as _beta_. All versions of Parity 2.2 are now considered _stable_. + +The full list of included changes: + +- Backports for 2.3.0 beta ([#10164](https://github.com/paritytech/parity-ethereum/pull/10164)) +- Snap: fix path in script ([#10157](https://github.com/paritytech/parity-ethereum/pull/10157)) +- Make sure parent block is not in importing queue when importing ancient blocks ([#10138](https://github.com/paritytech/parity-ethereum/pull/10138)) +- Ci: re-enable snap publishing ([#10142](https://github.com/paritytech/parity-ethereum/pull/10142)) +- Hf in POA Core (2019-01-18) - Constantinople ([#10155](https://github.com/paritytech/parity-ethereum/pull/10155)) +- Update EWF's tobalaba chainspec ([#10152](https://github.com/paritytech/parity-ethereum/pull/10152)) +- Replace ethcore-logger with env-logger. ([#10102](https://github.com/paritytech/parity-ethereum/pull/10102)) +- Finality: dont require chain head to be in the chain ([#10054](https://github.com/paritytech/parity-ethereum/pull/10054)) +- Remove caching for node connections ([#10143](https://github.com/paritytech/parity-ethereum/pull/10143)) +- Blooms file iterator empty on out of range position. ([#10145](https://github.com/paritytech/parity-ethereum/pull/10145)) +- Autogen docs for the "Configuring Parity Ethereum" wiki page. ([#10067](https://github.com/paritytech/parity-ethereum/pull/10067)) +- Misc: bump license header to 2019 ([#10135](https://github.com/paritytech/parity-ethereum/pull/10135)) +- Hide most of the logs from cpp example. ([#10139](https://github.com/paritytech/parity-ethereum/pull/10139)) +- Don't try to send oversized packets ([#10042](https://github.com/paritytech/parity-ethereum/pull/10042)) +- Private tx enabled flag added into STATUS packet ([#9999](https://github.com/paritytech/parity-ethereum/pull/9999)) +- Update pwasm-utils to 0.6.1 ([#10134](https://github.com/paritytech/parity-ethereum/pull/10134)) +- Extract blockchain from ethcore ([#10114](https://github.com/paritytech/parity-ethereum/pull/10114)) +- Ethcore: update hardcoded headers ([#10123](https://github.com/paritytech/parity-ethereum/pull/10123)) +- Identity fix ([#10128](https://github.com/paritytech/parity-ethereum/pull/10128)) +- Use LenCachingMutex to optimize verification. ([#10117](https://github.com/paritytech/parity-ethereum/pull/10117)) +- Pyethereum keystore support ([#9710](https://github.com/paritytech/parity-ethereum/pull/9710)) +- Bump rocksdb-sys to 0.5.5 ([#10124](https://github.com/paritytech/parity-ethereum/pull/10124)) +- Parity-clib: `async C bindings to RPC requests` + `subscribe/unsubscribe to websocket events` ([#9920](https://github.com/paritytech/parity-ethereum/pull/9920)) +- Refactor (hardware wallet) : reduce the number of threads ([#9644](https://github.com/paritytech/parity-ethereum/pull/9644)) +- Hf in POA Sokol (2019-01-04) ([#10077](https://github.com/paritytech/parity-ethereum/pull/10077)) +- Fix broken links ([#10119](https://github.com/paritytech/parity-ethereum/pull/10119)) +- Follow-up to [#10105](https://github.com/paritytech/parity-ethereum/issues/10105) ([#10107](https://github.com/paritytech/parity-ethereum/pull/10107)) +- Move EIP-712 crate back to parity-ethereum ([#10106](https://github.com/paritytech/parity-ethereum/pull/10106)) +- Move a bunch of stuff around ([#10101](https://github.com/paritytech/parity-ethereum/pull/10101)) +- Revert "Add --frozen when running cargo ([#10081](https://github.com/paritytech/parity-ethereum/pull/10081))" ([#10105](https://github.com/paritytech/parity-ethereum/pull/10105)) +- Fix left over small grumbles on whitespaces ([#10084](https://github.com/paritytech/parity-ethereum/pull/10084)) +- Add --frozen when running cargo ([#10081](https://github.com/paritytech/parity-ethereum/pull/10081)) +- Fix pubsub new_blocks notifications to include all blocks ([#9987](https://github.com/paritytech/parity-ethereum/pull/9987)) +- Update some dependencies for compilation with pc-windows-gnu ([#10082](https://github.com/paritytech/parity-ethereum/pull/10082)) +- Fill transaction hash on ethGetLog of light client. ([#9938](https://github.com/paritytech/parity-ethereum/pull/9938)) +- Update changelog update for 2.2.5-beta and 2.1.10-stable ([#10064](https://github.com/paritytech/parity-ethereum/pull/10064)) +- Implement len caching for parking_lot RwLock ([#10032](https://github.com/paritytech/parity-ethereum/pull/10032)) +- Update parking_lot to 0.7 ([#10050](https://github.com/paritytech/parity-ethereum/pull/10050)) +- Bump crossbeam. ([#10048](https://github.com/paritytech/parity-ethereum/pull/10048)) +- Ethcore: enable constantinople on ethereum ([#10031](https://github.com/paritytech/parity-ethereum/pull/10031)) +- Strict empty steps validation ([#10041](https://github.com/paritytech/parity-ethereum/pull/10041)) +- Center the Subtitle, use some CAPS ([#10034](https://github.com/paritytech/parity-ethereum/pull/10034)) +- Change test miner max memory to malloc reports. ([#10024](https://github.com/paritytech/parity-ethereum/pull/10024)) +- Sort the storage for private state ([#10018](https://github.com/paritytech/parity-ethereum/pull/10018)) +- Fix: test corpus_inaccessible panic ([#10019](https://github.com/paritytech/parity-ethereum/pull/10019)) +- Ci: move future releases to ethereum subdir on s3 ([#10017](https://github.com/paritytech/parity-ethereum/pull/10017)) +- Light(on_demand): decrease default time window to 10 secs ([#10016](https://github.com/paritytech/parity-ethereum/pull/10016)) +- Light client : failsafe crate (circuit breaker) ([#9790](https://github.com/paritytech/parity-ethereum/pull/9790)) +- Lencachingmutex ([#9988](https://github.com/paritytech/parity-ethereum/pull/9988)) +- Version and notification for private contract wrapper added ([#9761](https://github.com/paritytech/parity-ethereum/pull/9761)) +- Handle failing case for update account cache in require ([#9989](https://github.com/paritytech/parity-ethereum/pull/9989)) +- Add tokio runtime to ethcore io worker ([#9979](https://github.com/paritytech/parity-ethereum/pull/9979)) +- Move daemonize before creating account provider ([#10003](https://github.com/paritytech/parity-ethereum/pull/10003)) +- Docs: update changelogs ([#9990](https://github.com/paritytech/parity-ethereum/pull/9990)) +- Fix daemonize ([#10000](https://github.com/paritytech/parity-ethereum/pull/10000)) +- Fix Bloom migration ([#9992](https://github.com/paritytech/parity-ethereum/pull/9992)) +- Remove tendermint engine support ([#9980](https://github.com/paritytech/parity-ethereum/pull/9980)) +- Calculate gas for deployment transaction ([#9840](https://github.com/paritytech/parity-ethereum/pull/9840)) +- Fix unstable peers and slowness in sync ([#9967](https://github.com/paritytech/parity-ethereum/pull/9967)) +- Adds parity_verifySignature RPC method ([#9507](https://github.com/paritytech/parity-ethereum/pull/9507)) +- Improve block and transaction propagation ([#9954](https://github.com/paritytech/parity-ethereum/pull/9954)) +- Deny unknown fields for chainspec ([#9972](https://github.com/paritytech/parity-ethereum/pull/9972)) +- Fix docker build ([#9971](https://github.com/paritytech/parity-ethereum/pull/9971)) +- Ci: rearrange pipeline by logic ([#9970](https://github.com/paritytech/parity-ethereum/pull/9970)) +- Add changelogs for 2.0.9, 2.1.4, 2.1.6, and 2.2.1 ([#9963](https://github.com/paritytech/parity-ethereum/pull/9963)) +- Add Error message when sync is still in progress. ([#9475](https://github.com/paritytech/parity-ethereum/pull/9475)) +- Make CALLCODE to trace value to be the code address ([#9881](https://github.com/paritytech/parity-ethereum/pull/9881)) +- Fix light client informant while syncing ([#9932](https://github.com/paritytech/parity-ethereum/pull/9932)) +- Add a optional json dump state to evm-bin ([#9706](https://github.com/paritytech/parity-ethereum/pull/9706)) +- Disable EIP-98 transition by default ([#9955](https://github.com/paritytech/parity-ethereum/pull/9955)) +- Remove secret_store runtimes. ([#9888](https://github.com/paritytech/parity-ethereum/pull/9888)) +- Fix a deadlock ([#9952](https://github.com/paritytech/parity-ethereum/pull/9952)) +- Chore(eip712): remove unused `failure-derive` ([#9958](https://github.com/paritytech/parity-ethereum/pull/9958)) +- Do not use the home directory as the working dir in docker ([#9834](https://github.com/paritytech/parity-ethereum/pull/9834)) +- Prevent silent errors in daemon mode, closes [#9367](https://github.com/paritytech/parity-ethereum/issues/9367) ([#9946](https://github.com/paritytech/parity-ethereum/pull/9946)) +- Fix empty steps ([#9939](https://github.com/paritytech/parity-ethereum/pull/9939)) +- Adjust requests costs for light client ([#9925](https://github.com/paritytech/parity-ethereum/pull/9925)) +- Eip-1186: add `eth_getProof` RPC-Method ([#9001](https://github.com/paritytech/parity-ethereum/pull/9001)) +- Missing blocks in filter_changes RPC ([#9947](https://github.com/paritytech/parity-ethereum/pull/9947)) +- Allow rust-nightly builds fail in nightly builds ([#9944](https://github.com/paritytech/parity-ethereum/pull/9944)) +- Update eth-secp256k1 to include fix for BSDs ([#9935](https://github.com/paritytech/parity-ethereum/pull/9935)) +- Unbreak build on rust -stable ([#9934](https://github.com/paritytech/parity-ethereum/pull/9934)) +- Keep existing blocks when restoring a Snapshot ([#8643](https://github.com/paritytech/parity-ethereum/pull/8643)) +- Add experimental RPCs flag ([#9928](https://github.com/paritytech/parity-ethereum/pull/9928)) +- Clarify poll lifetime ([#9922](https://github.com/paritytech/parity-ethereum/pull/9922)) +- Docs(require rust 1.30) ([#9923](https://github.com/paritytech/parity-ethereum/pull/9923)) +- Use block header for building finality ([#9914](https://github.com/paritytech/parity-ethereum/pull/9914)) +- Simplify cargo audit ([#9918](https://github.com/paritytech/parity-ethereum/pull/9918)) +- Light-fetch: Differentiate between out-of-gas/manual throw and use required gas from response on failure ([#9824](https://github.com/paritytech/parity-ethereum/pull/9824)) +- Eip 191 ([#9701](https://github.com/paritytech/parity-ethereum/pull/9701)) +- Fix(logger): `reqwest` no longer a dependency ([#9908](https://github.com/paritytech/parity-ethereum/pull/9908)) +- Remove rust-toolchain file ([#9906](https://github.com/paritytech/parity-ethereum/pull/9906)) +- Foundation: 6692865, ropsten: 4417537, kovan: 9363457 ([#9907](https://github.com/paritytech/parity-ethereum/pull/9907)) +- Ethcore: use Machine::verify_transaction on parent block ([#9900](https://github.com/paritytech/parity-ethereum/pull/9900)) +- Chore(rpc-tests): remove unused rand ([#9896](https://github.com/paritytech/parity-ethereum/pull/9896)) +- Fix: Intermittent failing CI due to addr in use ([#9885](https://github.com/paritytech/parity-ethereum/pull/9885)) +- Chore(bump docopt): 0.8 -> 1.0 ([#9889](https://github.com/paritytech/parity-ethereum/pull/9889)) +- Use expect ([#9883](https://github.com/paritytech/parity-ethereum/pull/9883)) +- Use Weak reference in PubSubClient ([#9886](https://github.com/paritytech/parity-ethereum/pull/9886)) +- Ci: nuke the gitlab caches ([#9855](https://github.com/paritytech/parity-ethereum/pull/9855)) +- Remove unused code ([#9884](https://github.com/paritytech/parity-ethereum/pull/9884)) +- Fix json tracer overflow ([#9873](https://github.com/paritytech/parity-ethereum/pull/9873)) +- Allow to seal work on latest block ([#9876](https://github.com/paritytech/parity-ethereum/pull/9876)) +- Fix docker script ([#9854](https://github.com/paritytech/parity-ethereum/pull/9854)) +- Health endpoint ([#9847](https://github.com/paritytech/parity-ethereum/pull/9847)) +- Gitlab-ci: make android release build succeed ([#9743](https://github.com/paritytech/parity-ethereum/pull/9743)) +- Clean up existing benchmarks ([#9839](https://github.com/paritytech/parity-ethereum/pull/9839)) +- Update Callisto block reward code to support HF1 ([#9811](https://github.com/paritytech/parity-ethereum/pull/9811)) +- Option to disable keep alive for JSON-RPC http transport ([#9848](https://github.com/paritytech/parity-ethereum/pull/9848)) +- Classic.json Bootnode Update ([#9828](https://github.com/paritytech/parity-ethereum/pull/9828)) +- Support MIX. ([#9767](https://github.com/paritytech/parity-ethereum/pull/9767)) +- Ci: remove failing tests for android, windows, and macos ([#9788](https://github.com/paritytech/parity-ethereum/pull/9788)) +- Implement NoProof for json tests and update tests reference (replaces [#9744](https://github.com/paritytech/parity-ethereum/issues/9744)) ([#9814](https://github.com/paritytech/parity-ethereum/pull/9814)) +- Chore(bump regex) ([#9842](https://github.com/paritytech/parity-ethereum/pull/9842)) +- Ignore global cache for patched accounts ([#9752](https://github.com/paritytech/parity-ethereum/pull/9752)) +- Move state root verification before gas used ([#9841](https://github.com/paritytech/parity-ethereum/pull/9841)) +- Fix(docker-aarch64) : cross-compile config ([#9798](https://github.com/paritytech/parity-ethereum/pull/9798)) +- Version: bump nightly to 2.3.0 ([#9819](https://github.com/paritytech/parity-ethereum/pull/9819)) +- Tests modification for windows CI ([#9671](https://github.com/paritytech/parity-ethereum/pull/9671)) +- Eip-712 implementation ([#9631](https://github.com/paritytech/parity-ethereum/pull/9631)) +- Fix typo ([#9826](https://github.com/paritytech/parity-ethereum/pull/9826)) +- Clean up serde rename and use rename_all = camelCase when possible ([#9823](https://github.com/paritytech/parity-ethereum/pull/9823)) From 23d977eccefe471adbcd9dfdd50cd6415420c154 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Mon, 11 Mar 2019 11:37:48 +0100 Subject: [PATCH 113/168] simplify ethcore machine by removing redundant traits (#10454) --- ethcore/src/engines/instant_seal.rs | 11 ++++------ ethcore/src/engines/mod.rs | 12 +++++------ ethcore/src/engines/null_engine.rs | 10 ++++----- ethcore/src/machine.rs | 3 +-- ethcore/types/src/header.rs | 27 +++++------------------ machine/src/lib.rs | 33 ----------------------------- 6 files changed, 20 insertions(+), 76 deletions(-) diff --git a/ethcore/src/engines/instant_seal.rs b/ethcore/src/engines/instant_seal.rs index 595805c199..189015f081 100644 --- a/ethcore/src/engines/instant_seal.rs +++ b/ethcore/src/engines/instant_seal.rs @@ -15,7 +15,8 @@ // along with Parity Ethereum. If not, see . use engines::{Engine, Seal}; -use parity_machine::{Machine, Transactions, TotalScoredHeader}; +use parity_machine::{Machine, Transactions}; +use types::header::ExtendedHeader; /// `InstantSeal` params. #[derive(Default, Debug, PartialEq)] @@ -48,11 +49,7 @@ impl InstantSeal { } } -impl Engine for InstantSeal - where M::LiveBlock: Transactions, - M::ExtendedHeader: TotalScoredHeader, - ::Value: Ord -{ +impl Engine for InstantSeal where M::LiveBlock: Transactions { fn name(&self) -> &str { "InstantSeal" } @@ -84,7 +81,7 @@ impl Engine for InstantSeal header_timestamp >= parent_timestamp } - fn fork_choice(&self, new: &M::ExtendedHeader, current: &M::ExtendedHeader) -> super::ForkChoice { + fn fork_choice(&self, new: &ExtendedHeader, current: &ExtendedHeader) -> super::ForkChoice { super::total_difficulty_fork_choice(new, current) } } diff --git a/ethcore/src/engines/mod.rs b/ethcore/src/engines/mod.rs index 9cced0a0da..a63c69039c 100644 --- a/ethcore/src/engines/mod.rs +++ b/ethcore/src/engines/mod.rs @@ -44,13 +44,13 @@ use builtin::Builtin; use vm::{EnvInfo, Schedule, CreateContractAddress, CallType, ActionValue}; use error::Error; use types::BlockNumber; -use types::header::Header; +use types::header::{Header, ExtendedHeader}; use snapshot::SnapshotComponents; use spec::CommonParams; use types::transaction::{self, UnverifiedTransaction, SignedTransaction}; use ethkey::{Signature}; -use parity_machine::{Machine, LocalizedMachine as Localized, TotalScoredHeader}; +use parity_machine::{Machine, LocalizedMachine as Localized}; use ethereum_types::{H256, U256, Address}; use unexpected::{Mismatch, OutOfBounds}; use bytes::Bytes; @@ -255,7 +255,7 @@ pub trait Engine: Sync + Send { &self, _block: &mut M::LiveBlock, _epoch_begin: bool, - _ancestry: &mut Iterator, + _ancestry: &mut Iterator, ) -> Result<(), M::Error> { Ok(()) } @@ -421,16 +421,16 @@ pub trait Engine: Sync + Send { /// Gather all ancestry actions. Called at the last stage when a block is committed. The Engine must guarantee that /// the ancestry exists. - fn ancestry_actions(&self, _header: &M::Header, _ancestry: &mut Iterator) -> Vec { + fn ancestry_actions(&self, _header: &M::Header, _ancestry: &mut Iterator) -> Vec { Vec::new() } /// Check whether the given new block is the best block, after finalization check. - fn fork_choice(&self, new: &M::ExtendedHeader, best: &M::ExtendedHeader) -> ForkChoice; + fn fork_choice(&self, new: &ExtendedHeader, best: &ExtendedHeader) -> ForkChoice; } /// Check whether a given block is the best block based on the default total difficulty rule. -pub fn total_difficulty_fork_choice(new: &T, best: &T) -> ForkChoice where ::Value: Ord { +pub fn total_difficulty_fork_choice(new: &ExtendedHeader, best: &ExtendedHeader) -> ForkChoice { if new.total_score() > best.total_score() { ForkChoice::New } else { diff --git a/ethcore/src/engines/null_engine.rs b/ethcore/src/engines/null_engine.rs index 4a2610259c..74eb2dae80 100644 --- a/ethcore/src/engines/null_engine.rs +++ b/ethcore/src/engines/null_engine.rs @@ -18,8 +18,9 @@ use engines::Engine; use engines::block_reward::{self, RewardKind}; use ethereum_types::U256; use machine::WithRewards; -use parity_machine::{Machine, Header, LiveBlock, TotalScoredHeader}; +use parity_machine::{Machine, Header, LiveBlock}; use types::BlockNumber; +use types::header::ExtendedHeader; /// Params for a null engine. #[derive(Clone, Default)] @@ -58,10 +59,7 @@ impl Default for NullEngine { } } -impl Engine for NullEngine - where M::ExtendedHeader: TotalScoredHeader, - ::Value: Ord -{ +impl Engine for NullEngine { fn name(&self) -> &str { "NullEngine" } @@ -105,7 +103,7 @@ impl Engine for NullEngine Some(Box::new(::snapshot::PowSnapshot::new(10000, 10000))) } - fn fork_choice(&self, new: &M::ExtendedHeader, current: &M::ExtendedHeader) -> super::ForkChoice { + fn fork_choice(&self, new: &ExtendedHeader, current: &ExtendedHeader) -> super::ForkChoice { super::total_difficulty_fork_choice(new, current) } } diff --git a/ethcore/src/machine.rs b/ethcore/src/machine.rs index c0eae63d1e..c273fc84cf 100644 --- a/ethcore/src/machine.rs +++ b/ethcore/src/machine.rs @@ -24,7 +24,7 @@ use ethereum_types::{U256, H256, Address}; use rlp::Rlp; use types::transaction::{self, SYSTEM_ADDRESS, UNSIGNED_SENDER, UnverifiedTransaction, SignedTransaction}; use types::BlockNumber; -use types::header::{Header, ExtendedHeader}; +use types::header::Header; use vm::{CallType, ActionParams, ActionValue, ParamsType}; use vm::{EnvInfo, Schedule, CreateContractAddress}; @@ -430,7 +430,6 @@ pub enum AuxiliaryRequest { impl ::parity_machine::Machine for EthereumMachine { type Header = Header; - type ExtendedHeader = ExtendedHeader; type LiveBlock = ExecutedBlock; type EngineClient = ::client::EngineClient; diff --git a/ethcore/types/src/header.rs b/ethcore/types/src/header.rs index 829776f013..e2b90e754a 100644 --- a/ethcore/types/src/header.rs +++ b/ethcore/types/src/header.rs @@ -376,13 +376,6 @@ impl ::parity_machine::Header for Header { fn number(&self) -> BlockNumber { Header::number(self) } } -impl ::parity_machine::ScoredHeader for Header { - type Value = U256; - - fn score(&self) -> &U256 { self.difficulty() } - fn set_score(&mut self, score: U256) { self.set_difficulty(score) } -} - impl ::parity_machine::Header for ExtendedHeader { fn bare_hash(&self) -> H256 { self.header.bare_hash() } fn hash(&self) -> H256 { self.header.hash() } @@ -391,21 +384,11 @@ impl ::parity_machine::Header for ExtendedHeader { fn number(&self) -> BlockNumber { self.header.number() } } -impl ::parity_machine::ScoredHeader for ExtendedHeader { - type Value = U256; - - fn score(&self) -> &U256 { self.header.difficulty() } - fn set_score(&mut self, score: U256) { self.header.set_difficulty(score) } -} - -impl ::parity_machine::TotalScoredHeader for ExtendedHeader { - type Value = U256; - - fn total_score(&self) -> U256 { self.parent_total_difficulty + *self.header.difficulty() } -} - -impl ::parity_machine::FinalizableHeader for ExtendedHeader { - fn is_finalized(&self) -> bool { self.is_finalized } +impl ExtendedHeader { + /// Returns combined difficulty of all ancestors together with the difficulty of this header. + pub fn total_score(&self) -> U256 { + self.parent_total_difficulty + *self.header.difficulty() + } } #[cfg(test)] diff --git a/machine/src/lib.rs b/machine/src/lib.rs index b7054ca038..bf2b35e8b6 100644 --- a/machine/src/lib.rs +++ b/machine/src/lib.rs @@ -40,37 +40,6 @@ pub trait Header { fn number(&self) -> u64; } -/// A header with an associated score (difficulty in PoW terms) -pub trait ScoredHeader: Header { - type Value; - - /// Get the score of this header. - fn score(&self) -> &Self::Value; - - /// Set the score of this header. - fn set_score(&mut self, score: Self::Value); -} - -/// A header with associated total score. -pub trait TotalScoredHeader: Header { - type Value; - - /// Get the total score of this header. - fn total_score(&self) -> Self::Value; -} - -/// A header with finalized information. -pub trait FinalizableHeader: Header { - /// Get whether this header is considered finalized, so that it will never be replaced in reorganization. - fn is_finalized(&self) -> bool; -} - -/// A header with metadata information. -pub trait WithMetadataHeader: Header { - /// Get the current header metadata. - fn metadata(&self) -> Option<&[u8]>; -} - /// A "live" block is one which is in the process of the transition. /// The state of this block can be mutated by arbitrary rules of the /// state transition function. @@ -101,8 +70,6 @@ pub trait Machine: for<'a> LocalizedMachine<'a> { type Header: Header; /// The live block type. type LiveBlock: LiveBlock; - /// Block header with metadata information. - type ExtendedHeader: Header; /// A handle to a blockchain client for this machine. type EngineClient: ?Sized; /// A description of needed auxiliary data. From 4320c9bc4f8e94c4199c2fc10099896d2f5485ff Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Mon, 11 Mar 2019 11:48:01 +0100 Subject: [PATCH 114/168] docs(spec): remove link to obsolete issue (#10464) --- ethcore/src/spec/spec.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/ethcore/src/spec/spec.rs b/ethcore/src/spec/spec.rs index 2726ed4fd5..82dd5da5c4 100644 --- a/ethcore/src/spec/spec.rs +++ b/ethcore/src/spec/spec.rs @@ -999,7 +999,6 @@ mod tests { use types::view; use types::views::BlockView; - // https://github.com/paritytech/parity-ethereum/issues/1840 #[test] fn test_load_empty() { let tempdir = TempDir::new("").unwrap(); From 82a148a99b2e73de7365a8e095b5e7d498e70b5b Mon Sep 17 00:00:00 2001 From: TriplEight Date: Mon, 11 Mar 2019 15:26:35 +0100 Subject: [PATCH 115/168] Tests parallelized (#10452) * tests splitted, phase 1 * typo * fix wrong launch commands * typos * rearrangements * use `nproc` function for threads * use nproc for threads * let theads be auto, build-andriod no more in regular run * split val chain and cargo check * renamed some files * wrong phase * check rust files before test jobs * lint error * rust files modivied var * test except changes * add rust_changes except * lint error * fixes * .gitlab-ci.yml can't be excluded * pipeline shouldn't start * pipeline must go * pipeline must go 2 * pipeline must go 3 * pipeline must go 4 * pipeline must go 5 * pipeline must go 6 * pipeline must go 7 * pipeline must not go 1 * pipeline must go 8 * avoid skippng tests yet, reintroducing them after the caching * test theory * parallelized cargo check with combusting helicopters * less uploads * alias for cargo checks * nice template --- .gitlab-ci.yml | 69 +++++++++++----- .../gitlab/{build-unix.sh => build-linux.sh} | 0 .../gitlab/{test-all.sh => rust-changes.sh} | 4 +- scripts/gitlab/test-cpp.sh | 17 ++++ scripts/gitlab/test-linux.sh | 12 +++ .../validate-chainspecs.sh} | 9 ++- test.sh | 79 ------------------- 7 files changed, 87 insertions(+), 103 deletions(-) rename scripts/gitlab/{build-unix.sh => build-linux.sh} (100%) rename scripts/gitlab/{test-all.sh => rust-changes.sh} (87%) create mode 100755 scripts/gitlab/test-cpp.sh create mode 100755 scripts/gitlab/test-linux.sh rename scripts/{validate_chainspecs.sh => gitlab/validate-chainspecs.sh} (51%) delete mode 100755 test.sh diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 1988564233..079b8ed8f8 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -24,8 +24,7 @@ variables: - tags - schedules - -.collect_artifacts: &collect_artifacts +.collect_artifacts: &collect_artifacts artifacts: name: "${CI_JOB_NAME}_${SCHEDULE_TAG:-${CI_COMMIT_REF_NAME}}" when: on_success @@ -33,34 +32,66 @@ variables: paths: - artifacts/ -test-linux: - stage: test - variables: - RUN_TESTS: all - script: - - scripts/gitlab/test-all.sh +.docker-cache-status: &docker-cache-status + dependencies: [] + before_script: + - sccache -s + after_script: - sccache -s tags: - linux-docker -test-audit: + +cargo-check 0 3: + stage: test + <<: *docker-cache-status + script: + - time cargo check --target $CARGO_TARGET --locked --no-default-features + +cargo-check 1 3: + stage: test + <<: *docker-cache-status + script: + - time cargo check --target $CARGO_TARGET --locked --manifest-path util/io/Cargo.toml --no-default-features + +cargo-check 2 3: + stage: test + <<: *docker-cache-status + script: + - time cargo check --target $CARGO_TARGET --locked --manifest-path util/io/Cargo.toml --features "mio" + +cargo-audit: stage: test script: - - set -e - - set -u - cargo audit tags: - linux-docker +validate-chainspecs: + stage: test + <<: *docker-cache-status + script: + - ./scripts/gitlab/validate-chainspecs.sh + +test-cpp: + stage: build + <<: *docker-cache-status + script: + - ./scripts/gitlab/test-cpp.sh + +test-linux: + stage: build + <<: *docker-cache-status + script: + - ./scripts/gitlab/test-linux.sh + build-linux: &build-linux stage: build only: *releaseable_branches + <<: *docker-cache-status script: - - scripts/gitlab/build-unix.sh - - sccache -s + - scripts/gitlab/build-linux.sh <<: *collect_artifacts - tags: - - linux-docker build-linux-i386: <<: *build-linux @@ -88,7 +119,7 @@ build-darwin: CC: gcc CXX: g++ script: - - scripts/gitlab/build-unix.sh + - scripts/gitlab/build-linux.sh tags: - rust-osx <<: *collect_artifacts @@ -203,14 +234,12 @@ publish-docs: - linux-docker build-android: - stage: optional + stage: build image: parity/rust-android:gitlab-ci variables: CARGO_TARGET: armv7-linux-androideabi - dependencies: [] script: - - scripts/gitlab/build-unix.sh + - scripts/gitlab/build-linux.sh tags: - linux-docker - allow_failure: true <<: *collect_artifacts diff --git a/scripts/gitlab/build-unix.sh b/scripts/gitlab/build-linux.sh similarity index 100% rename from scripts/gitlab/build-unix.sh rename to scripts/gitlab/build-linux.sh diff --git a/scripts/gitlab/test-all.sh b/scripts/gitlab/rust-changes.sh similarity index 87% rename from scripts/gitlab/test-all.sh rename to scripts/gitlab/rust-changes.sh index 925124b7ac..236a20d59e 100755 --- a/scripts/gitlab/test-all.sh +++ b/scripts/gitlab/rust-changes.sh @@ -1,7 +1,9 @@ #!/bin/bash +echo "________Running rust_changes.sh________" set -e # fail on any error set -u # treat unset variables as error +echo "__________Checking if Rust files were changed__________" git log --graph --oneline --decorate=short -n 10 case ${SCHEDULE_TAG:-${CI_COMMIT_REF_NAME}} in @@ -26,5 +28,3 @@ then fi rustup show - -exec ./test.sh diff --git a/scripts/gitlab/test-cpp.sh b/scripts/gitlab/test-cpp.sh new file mode 100755 index 0000000000..9f825ec8c7 --- /dev/null +++ b/scripts/gitlab/test-cpp.sh @@ -0,0 +1,17 @@ +#!/bin/bash +echo "________Running test-cpp.sh________" +set -e # fail on any error +set -u # treat unset variables as error +#use nproc `linux only +THREADS=$(nproc) + +echo "________Running the C++ example________" +DIR=parity-clib/examples/cpp/build +mkdir -p $DIR +cd $DIR +cmake .. +make -j $THREADS +# Note: we don't try to run the example because it tries to sync Kovan, and we don't want +# that to happen on CI +cd - +rm -rf $DIR diff --git a/scripts/gitlab/test-linux.sh b/scripts/gitlab/test-linux.sh new file mode 100755 index 0000000000..6a98d2f7bd --- /dev/null +++ b/scripts/gitlab/test-linux.sh @@ -0,0 +1,12 @@ +#!/bin/bash +echo "________Running test-linux.sh________" +set -e # fail on any error +set -u # treat unset variables as error + +FEATURES="json-tests,ci-skip-tests" +OPTIONS="--release" +#use nproc `linux only +THREADS=$(nproc) + +echo "________Running Parity Full Test Suite________" +time cargo test $OPTIONS --features "$FEATURES" --locked --all --target $CARGO_TARGET -- --test-threads $THREADS diff --git a/scripts/validate_chainspecs.sh b/scripts/gitlab/validate-chainspecs.sh similarity index 51% rename from scripts/validate_chainspecs.sh rename to scripts/gitlab/validate-chainspecs.sh index c350445dd9..9b7ef39e72 100755 --- a/scripts/validate_chainspecs.sh +++ b/scripts/gitlab/validate-chainspecs.sh @@ -1,7 +1,12 @@ -#!/usr/bin/env sh +#!/bin/bash +set -e # fail on any error +set -u # treat unset variables as error +echo "________Running validate_chainspecs.sh________" ERR=0 -cargo build --release -p chainspec + +echo "________Validate chainspecs________" +time cargo build --release -p chainspec for spec in ethcore/res/*.json; do if ! ./target/release/chainspec "$spec"; then ERR=1; fi diff --git a/test.sh b/test.sh deleted file mode 100755 index e7d8e2a789..0000000000 --- a/test.sh +++ /dev/null @@ -1,79 +0,0 @@ -#!/bin/sh -# Running Parity Full Test Suite -echo "________Running test.sh________" - -FEATURES="json-tests,ci-skip-tests" -OPTIONS="--release" -VALIDATE=1 -THREADS=8 - -set -e - - -validate () { - if [ "$VALIDATE" -eq "1" ] - then - echo "________Validate build________" - time cargo check $@ --locked --no-default-features - time cargo check $@ --locked --manifest-path util/io/Cargo.toml --no-default-features - time cargo check $@ --locked --manifest-path util/io/Cargo.toml --features "mio" - - # Validate chainspecs - echo "________Validate chainspecs________" - time ./scripts/validate_chainspecs.sh - else - echo "# not validating due to \$VALIDATE!=1" - fi -} - -cpp_test () { - case $CARGO_TARGET in - (x86_64-unknown-linux-gnu) - # Running the C++ example - echo "________Running the C++ example________" - DIR=parity-clib/examples/cpp/build - mkdir -p $DIR - cd $DIR - cmake .. - make -j $THREADS - # Note: we don't try to run the example because it tries to sync Kovan, and we don't want - # that to happen on CI - cd - - rm -rf $DIR - ;; - (*) - echo "________Skipping the C++ example________" - ;; - esac -} - -cargo_test () { - echo "________Running Parity Full Test Suite________" - git submodule update --init --recursive - time cargo test $OPTIONS --features "$FEATURES" --locked --all $@ -- --test-threads $THREADS -} - - -if [ "$CARGO_TARGET" ] -then - validate --target $CARGO_TARGET -else - validate -fi - -test "${RUN_TESTS}" = "all" && cpp_test - -if [ "$CARGO_TARGET" ] -then - - case "${RUN_TESTS}" in - (cargo|all) - cargo_test --target $CARGO_TARGET $@ - ;; - ('') - cargo_test --no-run --target $CARGO_TARGET $@ - ;; - esac -else - cargo_test $@ -fi From 595dac6c3f8f2d3799f96339a1092435e82bc2b8 Mon Sep 17 00:00:00 2001 From: Hernando Castano Date: Tue, 12 Mar 2019 19:16:29 +0100 Subject: [PATCH 116/168] Ensure static validator set changes are recognized (#10467) --- ethcore/src/engines/authority_round/mod.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ethcore/src/engines/authority_round/mod.rs b/ethcore/src/engines/authority_round/mod.rs index ef439b5d4b..31062d80f3 100644 --- a/ethcore/src/engines/authority_round/mod.rs +++ b/ethcore/src/engines/authority_round/mod.rs @@ -1413,8 +1413,10 @@ impl Engine for AuthorityRound { let first = chain_head.number() == 0; - // apply immediate transitions. + // Apply transitions that don't require finality and should be enacted immediately (e.g from chain spec) if let Some(change) = self.validators.is_epoch_end(first, chain_head) { + info!(target: "engine", "Immediately applying validator set change signalled at block {}", chain_head.number()); + self.epoch_manager.lock().note_new_epoch(); let change = combine_proofs(chain_head.number(), &change, &[]); return Some(change) } From a16bad4175abc200269ceb6c2c11492fafdb9f4c Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Wed, 13 Mar 2019 11:36:13 +0100 Subject: [PATCH 117/168] simplify parity machine (#10469) * simplify ethcore machine by removing redundant traits * further ethereum machine simplifications * removed obsolete todo --- Cargo.lock | 9 --- ethcore/Cargo.toml | 1 - ethcore/src/block.rs | 20 ----- ethcore/src/engines/block_reward.rs | 22 ++++-- ethcore/src/engines/instant_seal.rs | 17 +++-- ethcore/src/engines/mod.rs | 75 +++++++++++++------ ethcore/src/engines/null_engine.rs | 20 ++--- ethcore/src/ethereum/ethash.rs | 12 +-- ethcore/src/lib.rs | 1 - ethcore/src/{machine.rs => machine/impls.rs} | 40 +--------- ethcore/src/machine/mod.rs | 7 ++ .../lib.rs => ethcore/src/machine/traits.rs | 56 +------------- ethcore/src/trace/types/trace.rs | 2 +- ethcore/types/Cargo.toml | 1 - ethcore/types/src/engines/epoch.rs | 25 ------- ethcore/types/src/header.rs | 16 ---- ethcore/types/src/lib.rs | 1 - machine/Cargo.toml | 8 -- 18 files changed, 109 insertions(+), 224 deletions(-) rename ethcore/src/{machine.rs => machine/impls.rs} (94%) create mode 100644 ethcore/src/machine/mod.rs rename machine/src/lib.rs => ethcore/src/machine/traits.rs (54%) delete mode 100644 machine/Cargo.toml diff --git a/Cargo.lock b/Cargo.lock index 71061696de..b6c0b3ef61 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -306,7 +306,6 @@ dependencies = [ "heapsize 0.4.2 (git+https://github.com/cheme/heapsize.git?branch=ec-macfix)", "keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-machine 0.1.0", "rlp 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "rlp_derive 0.1.0", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -739,7 +738,6 @@ dependencies = [ "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-crypto 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-machine 0.1.0", "parity-runtime 0.1.0", "parity-snappy 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2600,13 +2598,6 @@ dependencies = [ "serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "parity-machine" -version = "0.1.0" -dependencies = [ - "ethereum-types 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "parity-path" version = "0.1.1" diff --git a/ethcore/Cargo.toml b/ethcore/Cargo.toml index 0e3cea0fc6..2d26ba0381 100644 --- a/ethcore/Cargo.toml +++ b/ethcore/Cargo.toml @@ -50,7 +50,6 @@ num = { version = "0.1", default-features = false, features = ["bigint"] } num_cpus = "1.2" parity-bytes = "0.1" parity-crypto = "0.3.0" -parity-machine = { path = "../machine" } parity-snappy = "0.1" parking_lot = "0.7" trie-db = "0.11.0" diff --git a/ethcore/src/block.rs b/ethcore/src/block.rs index e5fcb45161..9d3528bb0d 100644 --- a/ethcore/src/block.rs +++ b/ethcore/src/block.rs @@ -195,26 +195,6 @@ impl IsBlock for ExecutedBlock { fn block(&self) -> &ExecutedBlock { self } } -impl ::parity_machine::LiveBlock for ExecutedBlock { - type Header = Header; - - fn header(&self) -> &Header { - &self.header - } - - fn uncles(&self) -> &[Header] { - &self.uncles - } -} - -impl ::parity_machine::Transactions for ExecutedBlock { - type Transaction = SignedTransaction; - - fn transactions(&self) -> &[SignedTransaction] { - &self.transactions - } -} - impl<'x> OpenBlock<'x> { /// Create a new `OpenBlock` ready for transaction pushing. pub fn new<'a>( diff --git a/ethcore/src/engines/block_reward.rs b/ethcore/src/engines/block_reward.rs index a95e3820ef..58b55408eb 100644 --- a/ethcore/src/engines/block_reward.rs +++ b/ethcore/src/engines/block_reward.rs @@ -24,11 +24,12 @@ use ethereum_types::{H160, Address, U256}; use std::sync::Arc; use hash::keccak; use error::Error; -use machine::WithRewards; -use parity_machine::Machine; +use machine::Machine; use trace; use types::BlockNumber; use super::{SystemOrCodeCall, SystemOrCodeCallKind}; +use trace::{Tracer, ExecutiveTracer, Tracing}; +use block::ExecutedBlock; use_contract!(block_reward_contract, "res/contracts/block_reward.json"); @@ -152,17 +153,26 @@ impl BlockRewardContract { /// Applies the given block rewards, i.e. adds the given balance to each beneficiary' address. /// If tracing is enabled the operations are recorded. -pub fn apply_block_rewards( +pub fn apply_block_rewards( rewards: &[(Address, RewardKind, U256)], - block: &mut M::LiveBlock, + block: &mut ExecutedBlock, machine: &M, ) -> Result<(), M::Error> { for &(ref author, _, ref block_reward) in rewards { machine.add_balance(block, author, block_reward)?; } - let rewards: Vec<_> = rewards.into_iter().map(|&(a, k, r)| (a, k.into(), r)).collect(); - machine.note_rewards(block, &rewards) + if let Tracing::Enabled(ref mut traces) = *block.traces_mut() { + let mut tracer = ExecutiveTracer::default(); + + for &(address, reward_kind, amount) in rewards { + tracer.trace_reward(address, amount, reward_kind.into()); + } + + traces.push(tracer.drain().into()); + } + + Ok(()) } #[cfg(test)] diff --git a/ethcore/src/engines/instant_seal.rs b/ethcore/src/engines/instant_seal.rs index 189015f081..93e20196a4 100644 --- a/ethcore/src/engines/instant_seal.rs +++ b/ethcore/src/engines/instant_seal.rs @@ -15,8 +15,9 @@ // along with Parity Ethereum. If not, see . use engines::{Engine, Seal}; -use parity_machine::{Machine, Transactions}; -use types::header::ExtendedHeader; +use machine::Machine; +use types::header::{Header, ExtendedHeader}; +use block::ExecutedBlock; /// `InstantSeal` params. #[derive(Default, Debug, PartialEq)] @@ -49,7 +50,7 @@ impl InstantSeal { } } -impl Engine for InstantSeal where M::LiveBlock: Transactions { +impl Engine for InstantSeal { fn name(&self) -> &str { "InstantSeal" } @@ -58,11 +59,15 @@ impl Engine for InstantSeal where M::LiveBlock: Transactions { fn seals_internally(&self) -> Option { Some(true) } - fn generate_seal(&self, block: &M::LiveBlock, _parent: &M::Header) -> Seal { - if block.transactions().is_empty() { Seal::None } else { Seal::Regular(Vec::new()) } + fn generate_seal(&self, block: &ExecutedBlock, _parent: &Header) -> Seal { + if block.transactions.is_empty() { + Seal::None + } else { + Seal::Regular(Vec::new()) + } } - fn verify_local_seal(&self, _header: &M::Header) -> Result<(), M::Error> { + fn verify_local_seal(&self, _header: &Header) -> Result<(), M::Error> { Ok(()) } diff --git a/ethcore/src/engines/mod.rs b/ethcore/src/engines/mod.rs index a63c69039c..e7be7bebba 100644 --- a/ethcore/src/engines/mod.rs +++ b/ethcore/src/engines/mod.rs @@ -27,14 +27,13 @@ pub mod signer; pub use self::authority_round::AuthorityRound; pub use self::basic_authority::BasicAuthority; -pub use self::epoch::{EpochVerifier, Transition as EpochTransition}; pub use self::instant_seal::{InstantSeal, InstantSealParams}; pub use self::null_engine::NullEngine; pub use self::signer::EngineSigner; // TODO [ToDr] Remove re-export (#10130) pub use types::engines::ForkChoice; -pub use types::engines::epoch; +pub use types::engines::epoch::{self, Transition as EpochTransition}; use std::sync::{Weak, Arc}; use std::collections::{BTreeMap, HashMap}; @@ -50,11 +49,13 @@ use spec::CommonParams; use types::transaction::{self, UnverifiedTransaction, SignedTransaction}; use ethkey::{Signature}; -use parity_machine::{Machine, LocalizedMachine as Localized}; +use machine::{Machine, LocalizedMachine as Localized}; use ethereum_types::{H256, U256, Address}; use unexpected::{Mismatch, OutOfBounds}; use bytes::Bytes; use types::ancestry_action::AncestryAction; +use block::ExecutedBlock; +use machine; /// Default EIP-210 contract code. /// As defined in https://github.com/ethereum/EIPs/pull/210 @@ -235,10 +236,10 @@ pub trait Engine: Sync + Send { fn machine(&self) -> &M; /// The number of additional header fields required for this engine. - fn seal_fields(&self, _header: &M::Header) -> usize { 0 } + fn seal_fields(&self, _header: &Header) -> usize { 0 } /// Additional engine-specific information for the user/developer concerning `header`. - fn extra_info(&self, _header: &M::Header) -> BTreeMap { BTreeMap::new() } + fn extra_info(&self, _header: &Header) -> BTreeMap { BTreeMap::new() } /// Maximum number of uncles a block is allowed to declare. fn maximum_uncle_count(&self, _block: BlockNumber) -> usize { 0 } @@ -253,7 +254,7 @@ pub trait Engine: Sync + Send { /// `epoch_begin` set to true if this block kicks off an epoch. fn on_new_block( &self, - _block: &mut M::LiveBlock, + _block: &mut ExecutedBlock, _epoch_begin: bool, _ancestry: &mut Iterator, ) -> Result<(), M::Error> { @@ -261,7 +262,7 @@ pub trait Engine: Sync + Send { } /// Block transformation functions, after the transactions. - fn on_close_block(&self, _block: &mut M::LiveBlock) -> Result<(), M::Error> { + fn on_close_block(&self, _block: &mut ExecutedBlock) -> Result<(), M::Error> { Ok(()) } @@ -279,7 +280,7 @@ pub trait Engine: Sync + Send { /// /// It is fine to require access to state or a full client for this function, since /// light clients do not generate seals. - fn generate_seal(&self, _block: &M::LiveBlock, _parent: &M::Header) -> Seal { Seal::None } + fn generate_seal(&self, _block: &ExecutedBlock, _parent: &Header) -> Seal { Seal::None } /// Verify a locally-generated seal of a header. /// @@ -291,25 +292,25 @@ pub trait Engine: Sync + Send { /// /// It is fine to require access to state or a full client for this function, since /// light clients do not generate seals. - fn verify_local_seal(&self, header: &M::Header) -> Result<(), M::Error>; + fn verify_local_seal(&self, header: &Header) -> Result<(), M::Error>; /// Phase 1 quick block verification. Only does checks that are cheap. Returns either a null `Ok` or a general error detailing the problem with import. /// The verification module can optionally avoid checking the seal (`check_seal`), if seal verification is disabled this method won't be called. - fn verify_block_basic(&self, _header: &M::Header) -> Result<(), M::Error> { Ok(()) } + fn verify_block_basic(&self, _header: &Header) -> Result<(), M::Error> { Ok(()) } /// Phase 2 verification. Perform costly checks such as transaction signatures. Returns either a null `Ok` or a general error detailing the problem with import. /// The verification module can optionally avoid checking the seal (`check_seal`), if seal verification is disabled this method won't be called. - fn verify_block_unordered(&self, _header: &M::Header) -> Result<(), M::Error> { Ok(()) } + fn verify_block_unordered(&self, _header: &Header) -> Result<(), M::Error> { Ok(()) } /// Phase 3 verification. Check block information against parent. Returns either a null `Ok` or a general error detailing the problem with import. - fn verify_block_family(&self, _header: &M::Header, _parent: &M::Header) -> Result<(), M::Error> { Ok(()) } + fn verify_block_family(&self, _header: &Header, _parent: &Header) -> Result<(), M::Error> { Ok(()) } /// Phase 4 verification. Verify block header against potentially external data. /// Should only be called when `register_client` has been called previously. - fn verify_block_external(&self, _header: &M::Header) -> Result<(), M::Error> { Ok(()) } + fn verify_block_external(&self, _header: &Header) -> Result<(), M::Error> { Ok(()) } /// Genesis epoch data. - fn genesis_epoch_data<'a>(&self, _header: &M::Header, _state: &>::StateContext) -> Result, String> { Ok(Vec::new()) } + fn genesis_epoch_data<'a>(&self, _header: &Header, _state: &>::StateContext) -> Result, String> { Ok(Vec::new()) } /// Whether an epoch change is signalled at the given header but will require finality. /// If a change can be enacted immediately then return `No` from this function but @@ -320,7 +321,7 @@ pub trait Engine: Sync + Send { /// Return `Yes` or `No` when the answer is definitively known. /// /// Should not interact with state. - fn signals_epoch_end<'a>(&self, _header: &M::Header, _aux: >::AuxiliaryData) + fn signals_epoch_end<'a>(&self, _header: &Header, _aux: >::AuxiliaryData) -> EpochChange { EpochChange::No @@ -336,9 +337,9 @@ pub trait Engine: Sync + Send { /// Return optional transition proof. fn is_epoch_end( &self, - _chain_head: &M::Header, + _chain_head: &Header, _finalized: &[H256], - _chain: &Headers, + _chain: &Headers

, _transition_store: &PendingTransitionStore, ) -> Option> { None @@ -355,8 +356,8 @@ pub trait Engine: Sync + Send { /// Return optional transition proof. fn is_epoch_end_light( &self, - _chain_head: &M::Header, - _chain: &Headers, + _chain_head: &Header, + _chain: &Headers
, _transition_store: &PendingTransitionStore, ) -> Option> { None @@ -364,13 +365,13 @@ pub trait Engine: Sync + Send { /// Create an epoch verifier from validation proof and a flag indicating /// whether finality is required. - fn epoch_verifier<'a>(&self, _header: &M::Header, _proof: &'a [u8]) -> ConstructedVerifier<'a, M> { - ConstructedVerifier::Trusted(Box::new(self::epoch::NoOp)) + fn epoch_verifier<'a>(&self, _header: &Header, _proof: &'a [u8]) -> ConstructedVerifier<'a, M> { + ConstructedVerifier::Trusted(Box::new(NoOp)) } /// Populate a header's fields based on its parent's header. /// Usually implements the chain scoring rule based on weight. - fn populate_from_parent(&self, _header: &mut M::Header, _parent: &M::Header) { } + fn populate_from_parent(&self, _header: &mut Header, _parent: &Header) { } /// Handle any potential consensus messages; /// updating consensus state and potentially issuing a new one. @@ -378,7 +379,7 @@ pub trait Engine: Sync + Send { /// Find out if the block is a proposal block and should not be inserted into the DB. /// Takes a header of a fully verified block. - fn is_proposal(&self, _verified_header: &M::Header) -> bool { false } + fn is_proposal(&self, _verified_header: &Header) -> bool { false } /// Register a component which signs consensus messages. fn set_signer(&self, _signer: Box) {} @@ -421,7 +422,7 @@ pub trait Engine: Sync + Send { /// Gather all ancestry actions. Called at the last stage when a block is committed. The Engine must guarantee that /// the ancestry exists. - fn ancestry_actions(&self, _header: &M::Header, _ancestry: &mut Iterator) -> Vec { + fn ancestry_actions(&self, _header: &Header, _ancestry: &mut Iterator) -> Vec { Vec::new() } @@ -523,3 +524,29 @@ pub trait EthEngine: Engine<::machine::EthereumMachine> { // convenience wrappers for existing functions. impl EthEngine for T where T: Engine<::machine::EthereumMachine> { } + +/// Verifier for all blocks within an epoch with self-contained state. +pub trait EpochVerifier: Send + Sync { + /// Lightly verify the next block header. + /// This may not be a header belonging to a different epoch. + fn verify_light(&self, header: &Header) -> Result<(), M::Error>; + + /// Perform potentially heavier checks on the next block header. + fn verify_heavy(&self, header: &Header) -> Result<(), M::Error> { + self.verify_light(header) + } + + /// Check a finality proof against this epoch verifier. + /// Returns `Some(hashes)` if the proof proves finality of these hashes. + /// Returns `None` if the proof doesn't prove anything. + fn check_finality_proof(&self, _proof: &[u8]) -> Option> { + None + } +} + +/// Special "no-op" verifier for stateless, epoch-less engines. +pub struct NoOp; + +impl EpochVerifier for NoOp { + fn verify_light(&self, _header: &Header) -> Result<(), M::Error> { Ok(()) } +} diff --git a/ethcore/src/engines/null_engine.rs b/ethcore/src/engines/null_engine.rs index 74eb2dae80..27138985ad 100644 --- a/ethcore/src/engines/null_engine.rs +++ b/ethcore/src/engines/null_engine.rs @@ -17,10 +17,10 @@ use engines::Engine; use engines::block_reward::{self, RewardKind}; use ethereum_types::U256; -use machine::WithRewards; -use parity_machine::{Machine, Header, LiveBlock}; +use machine::Machine; use types::BlockNumber; -use types::header::ExtendedHeader; +use types::header::{Header, ExtendedHeader}; +use block::ExecutedBlock; /// Params for a null engine. #[derive(Clone, Default)] @@ -59,23 +59,23 @@ impl Default for NullEngine { } } -impl Engine for NullEngine { +impl Engine for NullEngine { fn name(&self) -> &str { "NullEngine" } fn machine(&self) -> &M { &self.machine } - fn on_close_block(&self, block: &mut M::LiveBlock) -> Result<(), M::Error> { + fn on_close_block(&self, block: &mut ExecutedBlock) -> Result<(), M::Error> { use std::ops::Shr; - let author = *LiveBlock::header(&*block).author(); - let number = LiveBlock::header(&*block).number(); + let author = *block.header.author(); + let number = block.header.number(); let reward = self.params.block_reward; if reward == U256::zero() { return Ok(()) } - let n_uncles = LiveBlock::uncles(&*block).len(); + let n_uncles = block.uncles.len(); let mut rewards = Vec::new(); @@ -84,7 +84,7 @@ impl Engine for NullEngine { rewards.push((author, RewardKind::Author, result_block_reward)); // bestow uncle rewards. - for u in LiveBlock::uncles(&*block) { + for u in &block.uncles { let uncle_author = u.author(); let result_uncle_reward = (reward * U256::from(8 + u.number() - number)).shr(3); rewards.push((*uncle_author, RewardKind::uncle(number, u.number()), result_uncle_reward)); @@ -95,7 +95,7 @@ impl Engine for NullEngine { fn maximum_uncle_count(&self, _block: BlockNumber) -> usize { 2 } - fn verify_local_seal(&self, _header: &M::Header) -> Result<(), M::Error> { + fn verify_local_seal(&self, _header: &Header) -> Result<(), M::Error> { Ok(()) } diff --git a/ethcore/src/ethereum/ethash.rs b/ethcore/src/ethereum/ethash.rs index 293009fdec..561b3493be 100644 --- a/ethcore/src/ethereum/ethash.rs +++ b/ethcore/src/ethereum/ethash.rs @@ -241,17 +241,16 @@ impl Engine for Arc { /// This assumes that all uncles are valid uncles (i.e. of at least one generation before the current). fn on_close_block(&self, block: &mut ExecutedBlock) -> Result<(), Error> { use std::ops::Shr; - use parity_machine::LiveBlock; - let author = *LiveBlock::header(&*block).author(); - let number = LiveBlock::header(&*block).number(); + let author = *block.header.author(); + let number = block.header.number(); let rewards = match self.ethash_params.block_reward_contract { Some(ref c) if number >= self.ethash_params.block_reward_contract_transition => { let mut beneficiaries = Vec::new(); beneficiaries.push((author, RewardKind::Author)); - for u in LiveBlock::uncles(&*block) { + for u in &block.uncles { let uncle_author = u.author(); beneficiaries.push((*uncle_author, RewardKind::uncle(number, u.number()))); } @@ -274,7 +273,8 @@ impl Engine for Arc { let eras_rounds = self.ethash_params.ecip1017_era_rounds; let (eras, reward) = ecip1017_eras_block_reward(eras_rounds, reward, number); - let n_uncles = LiveBlock::uncles(&*block).len(); + //let n_uncles = LiveBlock::uncles(&*block).len(); + let n_uncles = block.uncles.len(); // Bestow block rewards. let mut result_block_reward = reward + reward.shr(5) * U256::from(n_uncles); @@ -282,7 +282,7 @@ impl Engine for Arc { rewards.push((author, RewardKind::Author, result_block_reward)); // Bestow uncle rewards. - for u in LiveBlock::uncles(&*block) { + for u in &block.uncles { let uncle_author = u.author(); let result_uncle_reward = if eras == 0 { (reward * U256::from(8 + u.number() - number)).shr(3) diff --git a/ethcore/src/lib.rs b/ethcore/src/lib.rs index 5ba6a26d01..17b33025a1 100644 --- a/ethcore/src/lib.rs +++ b/ethcore/src/lib.rs @@ -89,7 +89,6 @@ extern crate num; extern crate num_cpus; extern crate parity_bytes as bytes; extern crate parity_crypto; -extern crate parity_machine; extern crate parity_snappy as snappy; extern crate parking_lot; extern crate trie_db as trie; diff --git a/ethcore/src/machine.rs b/ethcore/src/machine/impls.rs similarity index 94% rename from ethcore/src/machine.rs rename to ethcore/src/machine/impls.rs index c273fc84cf..4cb052b9fe 100644 --- a/ethcore/src/machine.rs +++ b/ethcore/src/machine/impls.rs @@ -36,7 +36,7 @@ use error::Error; use executive::Executive; use spec::CommonParams; use state::{CleanupMode, Substate}; -use trace::{NoopTracer, NoopVMTracer, Tracer, ExecutiveTracer, RewardType, Tracing}; +use trace::{NoopTracer, NoopVMTracer}; use tx_filter::TransactionFilter; /// Parity tries to round block.gas_limit to multiple of this constant @@ -428,10 +428,7 @@ pub enum AuxiliaryRequest { Both, } -impl ::parity_machine::Machine for EthereumMachine { - type Header = Header; - - type LiveBlock = ExecutedBlock; +impl super::Machine for EthereumMachine { type EngineClient = ::client::EngineClient; type AuxiliaryRequest = AuxiliaryRequest; type AncestryAction = ::types::ancestry_action::AncestryAction; @@ -447,42 +444,11 @@ impl ::parity_machine::Machine for EthereumMachine { } } -impl<'a> ::parity_machine::LocalizedMachine<'a> for EthereumMachine { +impl<'a> super::LocalizedMachine<'a> for EthereumMachine { type StateContext = Call<'a>; type AuxiliaryData = AuxiliaryData<'a>; } -/// A state machine that uses block rewards. -pub trait WithRewards: ::parity_machine::Machine { - /// Note block rewards, traces each reward storing information about benefactor, amount and type - /// of reward. - fn note_rewards( - &self, - live: &mut Self::LiveBlock, - rewards: &[(Address, RewardType, U256)], - ) -> Result<(), Self::Error>; -} - -impl WithRewards for EthereumMachine { - fn note_rewards( - &self, - live: &mut Self::LiveBlock, - rewards: &[(Address, RewardType, U256)], - ) -> Result<(), Self::Error> { - if let Tracing::Enabled(ref mut traces) = *live.traces_mut() { - let mut tracer = ExecutiveTracer::default(); - - for &(address, ref reward_type, amount) in rewards { - tracer.trace_reward(address, amount, reward_type.clone()); - } - - traces.push(tracer.drain().into()); - } - - Ok(()) - } -} - // Try to round gas_limit a bit so that: // 1) it will still be in desired range // 2) it will be a nearest (with tendency to increase) multiple of PARITY_GAS_LIMIT_DETERMINANT diff --git a/ethcore/src/machine/mod.rs b/ethcore/src/machine/mod.rs new file mode 100644 index 0000000000..882dc011a2 --- /dev/null +++ b/ethcore/src/machine/mod.rs @@ -0,0 +1,7 @@ +//! Generalization of a state machine for a consensus engine. + +mod impls; +mod traits; + +pub use self::impls::*; +pub use self::traits::*; diff --git a/machine/src/lib.rs b/ethcore/src/machine/traits.rs similarity index 54% rename from machine/src/lib.rs rename to ethcore/src/machine/traits.rs index bf2b35e8b6..4d4004bffe 100644 --- a/machine/src/lib.rs +++ b/ethcore/src/machine/traits.rs @@ -17,59 +17,11 @@ //! Generalization of a state machine for a consensus engine. //! This will define traits for the header, block, and state of a blockchain. -extern crate ethereum_types; - -use ethereum_types::{H256, U256, Address}; - -/// A header. This contains important metadata about the block, as well as a -/// "seal" that indicates validity to a consensus engine. -pub trait Header { - /// Cryptographic hash of the header, excluding the seal. - fn bare_hash(&self) -> H256; - - /// Cryptographic hash of the header, including the seal. - fn hash(&self) -> H256; - - /// Get a reference to the seal fields. - fn seal(&self) -> &[Vec]; - - /// The author of the header. - fn author(&self) -> &Address; - - /// The number of the header. - fn number(&self) -> u64; -} - -/// A "live" block is one which is in the process of the transition. -/// The state of this block can be mutated by arbitrary rules of the -/// state transition function. -pub trait LiveBlock: 'static { - /// The block header type; - type Header: Header; - - /// Get a reference to the header. - fn header(&self) -> &Self::Header; - - /// Get a reference to the uncle headers. If the block type doesn't - /// support uncles, return the empty slice. - fn uncles(&self) -> &[Self::Header]; -} - -/// Trait for blocks which have a transaction type. -pub trait Transactions: LiveBlock { - /// The transaction type. - type Transaction; - - /// Get a reference to the transactions in this block. - fn transactions(&self) -> &[Self::Transaction]; -} +use ethereum_types::{U256, Address}; +use block::ExecutedBlock; /// Generalization of types surrounding blockchain-suitable state machines. pub trait Machine: for<'a> LocalizedMachine<'a> { - /// The block header type. - type Header: Header; - /// The live block type. - type LiveBlock: LiveBlock; /// A handle to a blockchain client for this machine. type EngineClient: ?Sized; /// A description of needed auxiliary data. @@ -82,10 +34,10 @@ pub trait Machine: for<'a> LocalizedMachine<'a> { /// Get the balance, in base units, associated with an account. /// Extracts data from the live block. - fn balance(&self, live: &Self::LiveBlock, address: &Address) -> Result; + fn balance(&self, live: &ExecutedBlock, address: &Address) -> Result; /// Increment the balance of an account in the state of the live block. - fn add_balance(&self, live: &mut Self::LiveBlock, address: &Address, amount: &U256) -> Result<(), Self::Error>; + fn add_balance(&self, live: &mut ExecutedBlock, address: &Address, amount: &U256) -> Result<(), Self::Error>; } /// Machine-related types localized to a specific lifetime. diff --git a/ethcore/src/trace/types/trace.rs b/ethcore/src/trace/types/trace.rs index 18ec24a84f..16084e94cb 100644 --- a/ethcore/src/trace/types/trace.rs +++ b/ethcore/src/trace/types/trace.rs @@ -135,7 +135,7 @@ impl Create { } /// Reward type. -#[derive(Debug, PartialEq, Clone)] +#[derive(Debug, PartialEq, Clone, Copy)] pub enum RewardType { /// Block Block, diff --git a/ethcore/types/Cargo.toml b/ethcore/types/Cargo.toml index 855fd71728..e3f9bd1db6 100644 --- a/ethcore/types/Cargo.toml +++ b/ethcore/types/Cargo.toml @@ -11,7 +11,6 @@ ethkey = { path = "../../accounts/ethkey" } heapsize = "0.4" keccak-hash = "0.1" parity-bytes = "0.1" -parity-machine = { path = "../../machine" } rlp = { version = "0.3.0", features = ["ethereum"] } rlp_derive = { path = "../../util/rlp-derive" } unexpected = { path = "../../util/unexpected" } diff --git a/ethcore/types/src/engines/epoch.rs b/ethcore/types/src/engines/epoch.rs index 34054a193f..2a43b47755 100644 --- a/ethcore/types/src/engines/epoch.rs +++ b/ethcore/types/src/engines/epoch.rs @@ -71,28 +71,3 @@ impl Decodable for PendingTransition { } } -/// Verifier for all blocks within an epoch with self-contained state. -pub trait EpochVerifier: Send + Sync { - /// Lightly verify the next block header. - /// This may not be a header belonging to a different epoch. - fn verify_light(&self, header: &M::Header) -> Result<(), M::Error>; - - /// Perform potentially heavier checks on the next block header. - fn verify_heavy(&self, header: &M::Header) -> Result<(), M::Error> { - self.verify_light(header) - } - - /// Check a finality proof against this epoch verifier. - /// Returns `Some(hashes)` if the proof proves finality of these hashes. - /// Returns `None` if the proof doesn't prove anything. - fn check_finality_proof(&self, _proof: &[u8]) -> Option> { - None - } -} - -/// Special "no-op" verifier for stateless, epoch-less engines. -pub struct NoOp; - -impl EpochVerifier for NoOp { - fn verify_light(&self, _header: &M::Header) -> Result<(), M::Error> { Ok(()) } -} diff --git a/ethcore/types/src/header.rs b/ethcore/types/src/header.rs index e2b90e754a..3dfe6ab83b 100644 --- a/ethcore/types/src/header.rs +++ b/ethcore/types/src/header.rs @@ -368,22 +368,6 @@ impl HeapSizeOf for Header { } } -impl ::parity_machine::Header for Header { - fn bare_hash(&self) -> H256 { Header::bare_hash(self) } - fn hash(&self) -> H256 { Header::hash(self) } - fn seal(&self) -> &[Vec] { Header::seal(self) } - fn author(&self) -> &Address { Header::author(self) } - fn number(&self) -> BlockNumber { Header::number(self) } -} - -impl ::parity_machine::Header for ExtendedHeader { - fn bare_hash(&self) -> H256 { self.header.bare_hash() } - fn hash(&self) -> H256 { self.header.hash() } - fn seal(&self) -> &[Vec] { self.header.seal() } - fn author(&self) -> &Address { self.header.author() } - fn number(&self) -> BlockNumber { self.header.number() } -} - impl ExtendedHeader { /// Returns combined difficulty of all ancestors together with the difficulty of this header. pub fn total_score(&self) -> U256 { diff --git a/ethcore/types/src/lib.rs b/ethcore/types/src/lib.rs index 4ca5c80dcf..3223db7220 100644 --- a/ethcore/types/src/lib.rs +++ b/ethcore/types/src/lib.rs @@ -39,7 +39,6 @@ extern crate ethkey; extern crate heapsize; extern crate keccak_hash as hash; extern crate parity_bytes as bytes; -extern crate parity_machine; extern crate rlp; extern crate unexpected; diff --git a/machine/Cargo.toml b/machine/Cargo.toml deleted file mode 100644 index 2ebb5c4099..0000000000 --- a/machine/Cargo.toml +++ /dev/null @@ -1,8 +0,0 @@ -[package] -name = "parity-machine" -version = "0.1.0" -description = "Generalization of a state machine for consensus engines" -authors = ["Parity Technologies "] - -[dependencies] -ethereum-types = "0.4" From c9db8ea21da87ca5432d75ffa974105a4c7142ef Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Thu, 14 Mar 2019 11:28:15 +0100 Subject: [PATCH 118/168] further simplify machine (#10472) * removed AuxiliaryRequest from Machin trait * removed AncestryAction from Machine trait * removed AuxiliaryData from Machine trait * removed LocalizedMachine trait --- ethcore/src/engines/mod.rs | 12 +++++------- ethcore/src/machine/impls.rs | 7 ------- ethcore/src/machine/traits.rs | 16 +--------------- 3 files changed, 6 insertions(+), 29 deletions(-) diff --git a/ethcore/src/engines/mod.rs b/ethcore/src/engines/mod.rs index e7be7bebba..5e451b5e4f 100644 --- a/ethcore/src/engines/mod.rs +++ b/ethcore/src/engines/mod.rs @@ -49,13 +49,12 @@ use spec::CommonParams; use types::transaction::{self, UnverifiedTransaction, SignedTransaction}; use ethkey::{Signature}; -use machine::{Machine, LocalizedMachine as Localized}; +use machine::{self, Machine, AuxiliaryRequest, AuxiliaryData}; use ethereum_types::{H256, U256, Address}; use unexpected::{Mismatch, OutOfBounds}; use bytes::Bytes; use types::ancestry_action::AncestryAction; use block::ExecutedBlock; -use machine; /// Default EIP-210 contract code. /// As defined in https://github.com/ethereum/EIPs/pull/210 @@ -177,8 +176,7 @@ pub type PendingTransitionStore<'a> = Fn(H256) -> Option: Send + Sync { /// Generate a proof, given the state. - // TODO: make this into an &M::StateContext - fn generate_proof<'a>(&self, state: &>::StateContext) -> Result, String>; + fn generate_proof<'a>(&self, state: &machine::Call) -> Result, String>; /// Check a proof generated elsewhere (potentially by a peer). // `engine` needed to check state proofs, while really this should // just be state machine params. @@ -218,7 +216,7 @@ impl<'a, M: Machine> ConstructedVerifier<'a, M> { /// Results of a query of whether an epoch change occurred at the given block. pub enum EpochChange { /// Cannot determine until more data is passed. - Unsure(M::AuxiliaryRequest), + Unsure(AuxiliaryRequest), /// No epoch change. No, /// The epoch will change, with proof. @@ -310,7 +308,7 @@ pub trait Engine: Sync + Send { fn verify_block_external(&self, _header: &Header) -> Result<(), M::Error> { Ok(()) } /// Genesis epoch data. - fn genesis_epoch_data<'a>(&self, _header: &Header, _state: &>::StateContext) -> Result, String> { Ok(Vec::new()) } + fn genesis_epoch_data<'a>(&self, _header: &Header, _state: &machine::Call) -> Result, String> { Ok(Vec::new()) } /// Whether an epoch change is signalled at the given header but will require finality. /// If a change can be enacted immediately then return `No` from this function but @@ -321,7 +319,7 @@ pub trait Engine: Sync + Send { /// Return `Yes` or `No` when the answer is definitively known. /// /// Should not interact with state. - fn signals_epoch_end<'a>(&self, _header: &Header, _aux: >::AuxiliaryData) + fn signals_epoch_end<'a>(&self, _header: &Header, _aux: AuxiliaryData<'a>) -> EpochChange { EpochChange::No diff --git a/ethcore/src/machine/impls.rs b/ethcore/src/machine/impls.rs index 4cb052b9fe..90d410c70d 100644 --- a/ethcore/src/machine/impls.rs +++ b/ethcore/src/machine/impls.rs @@ -430,8 +430,6 @@ pub enum AuxiliaryRequest { impl super::Machine for EthereumMachine { type EngineClient = ::client::EngineClient; - type AuxiliaryRequest = AuxiliaryRequest; - type AncestryAction = ::types::ancestry_action::AncestryAction; type Error = Error; @@ -444,11 +442,6 @@ impl super::Machine for EthereumMachine { } } -impl<'a> super::LocalizedMachine<'a> for EthereumMachine { - type StateContext = Call<'a>; - type AuxiliaryData = AuxiliaryData<'a>; -} - // Try to round gas_limit a bit so that: // 1) it will still be in desired range // 2) it will be a nearest (with tendency to increase) multiple of PARITY_GAS_LIMIT_DETERMINANT diff --git a/ethcore/src/machine/traits.rs b/ethcore/src/machine/traits.rs index 4d4004bffe..1523885e0e 100644 --- a/ethcore/src/machine/traits.rs +++ b/ethcore/src/machine/traits.rs @@ -21,13 +21,9 @@ use ethereum_types::{U256, Address}; use block::ExecutedBlock; /// Generalization of types surrounding blockchain-suitable state machines. -pub trait Machine: for<'a> LocalizedMachine<'a> { +pub trait Machine: Send + Sync { /// A handle to a blockchain client for this machine. type EngineClient: ?Sized; - /// A description of needed auxiliary data. - type AuxiliaryRequest; - /// Actions taken on ancestry blocks when commiting a new block. - type AncestryAction; /// Errors which can occur when querying or interacting with the machine. type Error; @@ -39,13 +35,3 @@ pub trait Machine: for<'a> LocalizedMachine<'a> { /// Increment the balance of an account in the state of the live block. fn add_balance(&self, live: &mut ExecutedBlock, address: &Address, amount: &U256) -> Result<(), Self::Error>; } - -/// Machine-related types localized to a specific lifetime. -// TODO: this is a workaround for a lack of associated type constructors in the language. -pub trait LocalizedMachine<'a>: Sync + Send { - /// Definition of auxiliary data associated to a specific block. - type AuxiliaryData: 'a; - /// A context providing access to the state in a controlled capacity. - /// Generally also provides verifiable proofs. - type StateContext: ?Sized + 'a; -} From f875175325c227f06d74641a5908558e6578aaab Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Thu, 14 Mar 2019 13:40:59 +0100 Subject: [PATCH 119/168] remove unused Engine::is_proposal (#10475) --- ethcore/src/client/client.rs | 18 +++++------------- ethcore/src/engines/mod.rs | 4 ---- 2 files changed, 5 insertions(+), 17 deletions(-) diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index 9eab30f342..92c996982f 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -298,19 +298,11 @@ impl Importer { match self.check_and_lock_block(&bytes, block, client) { Ok((closed_block, pending)) => { - if self.engine.is_proposal(&header) { - self.block_queue.mark_as_good(&[hash]); - proposed_blocks.push(bytes); - } else { - imported_blocks.push(hash); - - let transactions_len = closed_block.transactions().len(); - - let route = self.commit_block(closed_block, &header, encoded::Block::new(bytes), pending, client); - import_results.push(route); - - client.report.write().accrue_block(&header, transactions_len); - } + imported_blocks.push(hash); + let transactions_len = closed_block.transactions().len(); + let route = self.commit_block(closed_block, &header, encoded::Block::new(bytes), pending, client); + import_results.push(route); + client.report.write().accrue_block(&header, transactions_len); }, Err(err) => { self.bad_blocks.report(bytes, format!("{:?}", err)); diff --git a/ethcore/src/engines/mod.rs b/ethcore/src/engines/mod.rs index 5e451b5e4f..5d83bf0a3b 100644 --- a/ethcore/src/engines/mod.rs +++ b/ethcore/src/engines/mod.rs @@ -375,10 +375,6 @@ pub trait Engine: Sync + Send { /// updating consensus state and potentially issuing a new one. fn handle_message(&self, _message: &[u8]) -> Result<(), EngineError> { Err(EngineError::UnexpectedMessage) } - /// Find out if the block is a proposal block and should not be inserted into the DB. - /// Takes a header of a fully verified block. - fn is_proposal(&self, _verified_header: &Header) -> bool { false } - /// Register a component which signs consensus messages. fn set_signer(&self, _signer: Box) {} From d83143d0ba7b3bc0c47519afd65b01fb4379cef6 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Thu, 14 Mar 2019 21:34:26 +0100 Subject: [PATCH 120/168] remove unused Engine::maximum_uncle_age (#10476) --- ethcore/src/client/client.rs | 8 ++++---- ethcore/src/engines/mod.rs | 5 ++--- ethcore/src/verification/verification.rs | 6 +++--- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index 92c996982f..f0fdacfe86 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -61,7 +61,7 @@ use client::{ IoClient, BadBlocks, }; use client::bad_blocks; -use engines::{EthEngine, EpochTransition, ForkChoice, EngineError}; +use engines::{MAX_UNCLE_AGE, EthEngine, EpochTransition, ForkChoice, EngineError}; use engines::epoch::PendingTransition; use error::{ ImportErrorKind, ExecutionError, CallError, BlockError, @@ -1918,7 +1918,7 @@ impl BlockChainClient for Client { } fn find_uncles(&self, hash: &H256) -> Option> { - self.chain.read().find_uncle_hashes(hash, self.engine.maximum_uncle_age()) + self.chain.read().find_uncle_hashes(hash, MAX_UNCLE_AGE) } fn state_data(&self, hash: &H256) -> Option { @@ -2282,7 +2282,7 @@ impl ReopenBlock for Client { let h = chain.best_block_hash(); // Add new uncles let uncles = chain - .find_uncle_hashes(&h, engine.maximum_uncle_age()) + .find_uncle_hashes(&h, MAX_UNCLE_AGE) .unwrap_or_else(Vec::new); for h in uncles { @@ -2326,7 +2326,7 @@ impl PrepareOpenBlock for Client { // Add uncles chain - .find_uncle_headers(&h, engine.maximum_uncle_age()) + .find_uncle_headers(&h, MAX_UNCLE_AGE) .unwrap_or_else(Vec::new) .into_iter() .take(engine.maximum_uncle_count(open_block.header().number())) diff --git a/ethcore/src/engines/mod.rs b/ethcore/src/engines/mod.rs index 5d83bf0a3b..06e6b522be 100644 --- a/ethcore/src/engines/mod.rs +++ b/ethcore/src/engines/mod.rs @@ -59,6 +59,8 @@ use block::ExecutedBlock; /// Default EIP-210 contract code. /// As defined in https://github.com/ethereum/EIPs/pull/210 pub const DEFAULT_BLOCKHASH_CONTRACT: &'static str = "73fffffffffffffffffffffffffffffffffffffffe33141561006a5760014303600035610100820755610100810715156100455760003561010061010083050761010001555b6201000081071515610064576000356101006201000083050761020001555b5061013e565b4360003512151561008457600060405260206040f361013d565b61010060003543031315156100a857610100600035075460605260206060f361013c565b6101006000350715156100c55762010000600035430313156100c8565b60005b156100ea576101006101006000350507610100015460805260206080f361013b565b620100006000350715156101095763010000006000354303131561010c565b60005b1561012f57610100620100006000350507610200015460a052602060a0f361013a565b600060c052602060c0f35b5b5b5b5b"; +/// The number of generations back that uncles can be. +pub const MAX_UNCLE_AGE: usize = 6; /// Voting errors. #[derive(Debug)] @@ -242,9 +244,6 @@ pub trait Engine: Sync + Send { /// Maximum number of uncles a block is allowed to declare. fn maximum_uncle_count(&self, _block: BlockNumber) -> usize { 0 } - /// The number of generations back that uncles can be. - fn maximum_uncle_age(&self) -> usize { 6 } - /// Optional maximum gas limit. fn maximum_gas_limit(&self) -> Option { None } diff --git a/ethcore/src/verification/verification.rs b/ethcore/src/verification/verification.rs index 2ce9f9de30..8a11f0ef45 100644 --- a/ethcore/src/verification/verification.rs +++ b/ethcore/src/verification/verification.rs @@ -34,7 +34,7 @@ use unexpected::{Mismatch, OutOfBounds}; use blockchain::*; use call_contract::CallContract; use client::BlockInfo; -use engines::EthEngine; +use engines::{EthEngine, MAX_UNCLE_AGE}; use error::{BlockError, Error}; use types::{BlockNumber, header::Header}; use types::transaction::SignedTransaction; @@ -192,7 +192,7 @@ fn verify_uncles(block: &PreverifiedBlock, bc: &BlockProvider, engine: &EthEngin excluded.insert(header.hash()); let mut hash = header.parent_hash().clone(); excluded.insert(hash.clone()); - for _ in 0..engine.maximum_uncle_age() { + for _ in 0..MAX_UNCLE_AGE { match bc.block_details(&hash) { Some(details) => { excluded.insert(details.parent); @@ -225,7 +225,7 @@ fn verify_uncles(block: &PreverifiedBlock, bc: &BlockProvider, engine: &EthEngin // (8 Invalid) let depth = if header.number() > uncle.number() { header.number() - uncle.number() } else { 0 }; - if depth > engine.maximum_uncle_age() as u64 { + if depth > MAX_UNCLE_AGE as u64 { return Err(From::from(BlockError::UncleTooOld(OutOfBounds { min: Some(header.number() - depth), max: Some(header.number() - 1), found: uncle.number() }))); } else if depth < 1 { From a574df3132ceac41a36e5a246b0ad3be12178bab Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Fri, 15 Mar 2019 13:22:47 +0100 Subject: [PATCH 121/168] simplify block module and usage (#10479) * removed trait IsBlock and simplify block usage * removed redundant ClosedBlock::hash function --- ethcore/src/block.rs | 92 +++++++--------------- ethcore/src/client/client.rs | 28 +++---- ethcore/src/engines/authority_round/mod.rs | 56 ++++++------- ethcore/src/engines/basic_authority.rs | 4 +- ethcore/src/engines/instant_seal.rs | 2 +- ethcore/src/ethereum/ethash.rs | 12 +-- ethcore/src/machine/impls.rs | 14 ++-- ethcore/src/miner/miner.rs | 62 ++++++++------- ethcore/src/tests/client.rs | 3 +- rpc/src/v1/tests/helpers/miner_service.rs | 4 +- 10 files changed, 125 insertions(+), 152 deletions(-) diff --git a/ethcore/src/block.rs b/ethcore/src/block.rs index 9d3528bb0d..bbcfa473eb 100644 --- a/ethcore/src/block.rs +++ b/ethcore/src/block.rs @@ -31,7 +31,7 @@ //! `ExecutedBlock` is an underlaying data structure used by all structs above to store block //! related info. -use std::cmp; +use std::{cmp, ops}; use std::collections::HashSet; use std::sync::Arc; @@ -52,7 +52,6 @@ use vm::{EnvInfo, LastHashes}; use hash::keccak; use rlp::{RlpStream, Encodable, encode_list}; use types::transaction::{SignedTransaction, Error as TransactionError}; -use types::block::Block; use types::header::{Header, ExtendedHeader}; use types::receipt::{Receipt, TransactionOutcome}; @@ -155,46 +154,12 @@ impl ExecutedBlock { } } -/// Trait for a object that is a `ExecutedBlock`. -pub trait IsBlock { - /// Get the `ExecutedBlock` associated with this object. - fn block(&self) -> &ExecutedBlock; - - /// Get the base `Block` object associated with this. - fn to_base(&self) -> Block { - Block { - header: self.header().clone(), - transactions: self.transactions().iter().cloned().map(Into::into).collect(), - uncles: self.uncles().to_vec(), - } - } - - /// Get the header associated with this object's block. - fn header(&self) -> &Header { &self.block().header } - - /// Get the final state associated with this object's block. - fn state(&self) -> &State { &self.block().state } - - /// Get all information on transactions in this block. - fn transactions(&self) -> &[SignedTransaction] { &self.block().transactions } - - /// Get all information on receipts in this block. - fn receipts(&self) -> &[Receipt] { &self.block().receipts } - - /// Get all uncles in this block. - fn uncles(&self) -> &[Header] { &self.block().uncles } -} - /// Trait for an object that owns an `ExecutedBlock` pub trait Drain { /// Returns `ExecutedBlock` fn drain(self) -> ExecutedBlock; } -impl IsBlock for ExecutedBlock { - fn block(&self) -> &ExecutedBlock { self } -} - impl<'x> OpenBlock<'x> { /// Create a new `OpenBlock` ready for transaction pushing. pub fn new<'a>( @@ -250,7 +215,7 @@ impl<'x> OpenBlock<'x> { /// NOTE Will check chain constraints and the uncle number but will NOT check /// that the header itself is actually valid. pub fn push_uncle(&mut self, valid_uncle_header: Header) -> Result<(), BlockError> { - let max_uncles = self.engine.maximum_uncle_count(self.block.header().number()); + let max_uncles = self.engine.maximum_uncle_count(self.block.header.number()); if self.block.uncles.len() + 1 > max_uncles { return Err(BlockError::TooManyUncles(OutOfBounds{ min: None, @@ -264,11 +229,6 @@ impl<'x> OpenBlock<'x> { Ok(()) } - /// Get the environment info concerning this block. - pub fn env_info(&self) -> EnvInfo { - self.block.env_info() - } - /// Push a transaction into the block. /// /// If valid, it will be executed, and archived together with the receipt. @@ -277,7 +237,7 @@ impl<'x> OpenBlock<'x> { return Err(TransactionError::AlreadyImported.into()); } - let env_info = self.env_info(); + let env_info = self.block.env_info(); let outcome = self.block.state.apply(&env_info, self.engine.machine(), &t, self.block.traces.is_enabled())?; self.block.transactions_set.insert(h.unwrap_or_else(||t.hash())); @@ -374,22 +334,39 @@ impl<'x> OpenBlock<'x> { pub fn block_mut(&mut self) -> &mut ExecutedBlock { &mut self.block } } -impl<'x> IsBlock for OpenBlock<'x> { - fn block(&self) -> &ExecutedBlock { &self.block } +impl<'a> ops::Deref for OpenBlock<'a> { + type Target = ExecutedBlock; + + fn deref(&self) -> &Self::Target { + &self.block + } } -impl IsBlock for ClosedBlock { - fn block(&self) -> &ExecutedBlock { &self.block } +impl ops::Deref for ClosedBlock { + type Target = ExecutedBlock; + + fn deref(&self) -> &Self::Target { + &self.block + } } -impl IsBlock for LockedBlock { - fn block(&self) -> &ExecutedBlock { &self.block } +impl ops::Deref for LockedBlock { + type Target = ExecutedBlock; + + fn deref(&self) -> &Self::Target { + &self.block + } } -impl ClosedBlock { - /// Get the hash of the header without seal arguments. - pub fn hash(&self) -> H256 { self.header().bare_hash() } +impl ops::Deref for SealedBlock { + type Target = ExecutedBlock; + fn deref(&self) -> &Self::Target { + &self.block + } +} + +impl ClosedBlock { /// Turn this into a `LockedBlock`, unable to be reopened again. pub fn lock(self) -> LockedBlock { LockedBlock { @@ -423,18 +400,13 @@ impl LockedBlock { self.block.header.set_receipts_root( ordered_trie_root(self.block.receipts.iter().map(|r| r.rlp_bytes())) ); - // compute hash and cache it. - self.block.header.compute_hash(); } - /// Get the hash of the header without seal arguments. - pub fn hash(&self) -> H256 { self.header().bare_hash() } - /// Provide a valid seal in order to turn this into a `SealedBlock`. /// /// NOTE: This does not check the validity of `seal` with the engine. pub fn seal(self, engine: &EthEngine, seal: Vec) -> Result { - let expected_seal_fields = engine.seal_fields(self.header()); + let expected_seal_fields = engine.seal_fields(&self.block.header); let mut s = self; if seal.len() != expected_seal_fields { return Err(BlockError::InvalidSealArity( @@ -490,10 +462,6 @@ impl Drain for SealedBlock { } } -impl IsBlock for SealedBlock { - fn block(&self) -> &ExecutedBlock { &self.block } -} - /// Enact the block given by block header, transactions and uncles fn enact( header: Header, diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index f0fdacfe86..29d642477a 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -45,7 +45,7 @@ use types::receipt::{Receipt, LocalizedReceipt}; use types::{BlockNumber, header::{Header, ExtendedHeader}}; use vm::{EnvInfo, LastHashes}; -use block::{IsBlock, LockedBlock, Drain, ClosedBlock, OpenBlock, enact_verified, SealedBlock}; +use block::{LockedBlock, Drain, ClosedBlock, OpenBlock, enact_verified, SealedBlock}; use client::ancient_import::AncientVerifier; use client::{ Nonce, Balance, ChainInfo, BlockInfo, TransactionInfo, @@ -299,7 +299,7 @@ impl Importer { match self.check_and_lock_block(&bytes, block, client) { Ok((closed_block, pending)) => { imported_blocks.push(hash); - let transactions_len = closed_block.transactions().len(); + let transactions_len = closed_block.transactions.len(); let route = self.commit_block(closed_block, &header, encoded::Block::new(bytes), pending, client); import_results.push(route); client.report.write().accrue_block(&header, transactions_len); @@ -423,13 +423,13 @@ impl Importer { // if the expected receipts root header does not match. // (i.e. allow inconsistency in receipts outcome before the transition block) if header.number() < engine.params().validate_receipts_transition - && header.receipts_root() != locked_block.block().header().receipts_root() + && header.receipts_root() != locked_block.header.receipts_root() { locked_block.strip_receipts_outcomes(); } // Final Verification - if let Err(e) = self.verifier.verify_block_final(&header, locked_block.block().header()) { + if let Err(e) = self.verifier.verify_block_final(&header, &locked_block.header) { warn!(target: "client", "Stage 5 block verification failed for #{} ({})\nError: {:?}", header.number(), header.hash(), e); bail!(e); } @@ -437,8 +437,8 @@ impl Importer { let pending = self.check_epoch_end_signal( &header, bytes, - locked_block.receipts(), - locked_block.state().db(), + &locked_block.receipts, + locked_block.state.db(), client )?; @@ -2276,8 +2276,8 @@ impl ReopenBlock for Client { fn reopen_block(&self, block: ClosedBlock) -> OpenBlock { let engine = &*self.engine; let mut block = block.reopen(engine); - let max_uncles = engine.maximum_uncle_count(block.header().number()); - if block.uncles().len() < max_uncles { + let max_uncles = engine.maximum_uncle_count(block.header.number()); + if block.uncles.len() < max_uncles { let chain = self.chain.read(); let h = chain.best_block_hash(); // Add new uncles @@ -2286,14 +2286,14 @@ impl ReopenBlock for Client { .unwrap_or_else(Vec::new); for h in uncles { - if !block.uncles().iter().any(|header| header.hash() == h) { + if !block.uncles.iter().any(|header| header.hash() == h) { let uncle = chain.block_header_data(&h).expect("find_uncle_hashes only returns hashes for existing headers; qed"); let uncle = uncle.decode().expect("decoding failure"); block.push_uncle(uncle).expect("pushing up to maximum_uncle_count; push_uncle is not ok only if more than maximum_uncle_count is pushed; so all push_uncle are Ok; qed"); - if block.uncles().len() >= max_uncles { break } + if block.uncles.len() >= max_uncles { break } } } @@ -2329,7 +2329,7 @@ impl PrepareOpenBlock for Client { .find_uncle_headers(&h, MAX_UNCLE_AGE) .unwrap_or_else(Vec::new) .into_iter() - .take(engine.maximum_uncle_count(open_block.header().number())) + .take(engine.maximum_uncle_count(open_block.header.number())) .foreach(|h| { open_block.push_uncle(h.decode().expect("decoding failure")).expect("pushing maximum_uncle_count; open_block was just created; @@ -2354,7 +2354,7 @@ impl ImportSealedBlock for Client { fn import_sealed_block(&self, block: SealedBlock) -> EthcoreResult { let start = Instant::now(); let raw = block.rlp_bytes(); - let header = block.header().clone(); + let header = block.header.clone(); let hash = header.hash(); self.notify(|n| n.block_pre_import(&raw, &hash, header.difficulty())); @@ -2377,8 +2377,8 @@ impl ImportSealedBlock for Client { let pending = self.importer.check_epoch_end_signal( &header, &block_data, - block.receipts(), - block.state().db(), + &block.receipts, + block.state.db(), self )?; let route = self.importer.commit_block( diff --git a/ethcore/src/engines/authority_round/mod.rs b/ethcore/src/engines/authority_round/mod.rs index 31062d80f3..db25380aa8 100644 --- a/ethcore/src/engines/authority_round/mod.rs +++ b/ethcore/src/engines/authority_round/mod.rs @@ -1030,7 +1030,7 @@ impl Engine for AuthorityRound { return Seal::None; } - let header = block.header(); + let header = &block.header; let parent_step = header_step(parent, self.empty_steps_transition) .expect("Header has been verified; qed"); @@ -1076,7 +1076,7 @@ impl Engine for AuthorityRound { // `EmptyStep(step, parent_hash)` message. If we exceed the maximum amount of `empty_step` rounds we proceed // with the seal. if header.number() >= self.empty_steps_transition && - block.transactions().is_empty() && + block.transactions.is_empty() && empty_steps.len() < self.maximum_empty_steps { if self.step.can_propose.compare_and_swap(true, false, AtomicOrdering::SeqCst) { @@ -1146,7 +1146,7 @@ impl Engine for AuthorityRound { if self.immediate_transitions || !epoch_begin { return Ok(()) } // genesis is never a new block, but might as well check. - let header = block.header().clone(); + let header = block.header.clone(); let first = header.number() == 0; let mut call = |to, data| { @@ -1166,8 +1166,8 @@ impl Engine for AuthorityRound { /// Apply the block reward on finalisation of the block. fn on_close_block(&self, block: &mut ExecutedBlock) -> Result<(), Error> { let mut beneficiaries = Vec::new(); - if block.header().number() >= self.empty_steps_transition { - let empty_steps = if block.header().seal().is_empty() { + if block.header.number() >= self.empty_steps_transition { + let empty_steps = if block.header.seal().is_empty() { // this is a new block, calculate rewards based on the empty steps messages we have accumulated let client = match self.client.read().as_ref().and_then(|weak| weak.upgrade()) { Some(client) => client, @@ -1177,7 +1177,7 @@ impl Engine for AuthorityRound { }, }; - let parent = client.block_header(::client::BlockId::Hash(*block.header().parent_hash())) + let parent = client.block_header(::client::BlockId::Hash(*block.header.parent_hash())) .expect("hash is from parent; parent header must exist; qed") .decode()?; @@ -1186,7 +1186,7 @@ impl Engine for AuthorityRound { self.empty_steps(parent_step.into(), current_step.into(), parent.hash()) } else { // we're verifying a block, extract empty steps from the seal - header_empty_steps(block.header())? + header_empty_steps(&block.header)? }; for empty_step in empty_steps { @@ -1195,11 +1195,11 @@ impl Engine for AuthorityRound { } } - let author = *block.header().author(); + let author = *block.header.author(); beneficiaries.push((author, RewardKind::Author)); let rewards: Vec<_> = match self.block_reward_contract { - Some(ref c) if block.header().number() >= self.block_reward_contract_transition => { + Some(ref c) if block.header.number() >= self.block_reward_contract_transition => { let mut call = super::default_system_or_code_call(&self.machine, block); let rewards = c.reward(&beneficiaries, &mut call)?; @@ -1634,17 +1634,17 @@ mod tests { let b2 = b2.close_and_lock().unwrap(); engine.set_signer(Box::new((tap.clone(), addr1, "1".into()))); - if let Seal::Regular(seal) = engine.generate_seal(b1.block(), &genesis_header) { + if let Seal::Regular(seal) = engine.generate_seal(&b1, &genesis_header) { assert!(b1.clone().try_seal(engine, seal).is_ok()); // Second proposal is forbidden. - assert!(engine.generate_seal(b1.block(), &genesis_header) == Seal::None); + assert!(engine.generate_seal(&b1, &genesis_header) == Seal::None); } engine.set_signer(Box::new((tap, addr2, "2".into()))); - if let Seal::Regular(seal) = engine.generate_seal(b2.block(), &genesis_header) { + if let Seal::Regular(seal) = engine.generate_seal(&b2, &genesis_header) { assert!(b2.clone().try_seal(engine, seal).is_ok()); // Second proposal is forbidden. - assert!(engine.generate_seal(b2.block(), &genesis_header) == Seal::None); + assert!(engine.generate_seal(&b2, &genesis_header) == Seal::None); } } @@ -1668,13 +1668,13 @@ mod tests { let b2 = b2.close_and_lock().unwrap(); engine.set_signer(Box::new((tap.clone(), addr1, "1".into()))); - match engine.generate_seal(b1.block(), &genesis_header) { + match engine.generate_seal(&b1, &genesis_header) { Seal::None | Seal::Proposal(_) => panic!("wrong seal"), Seal::Regular(_) => { engine.step(); engine.set_signer(Box::new((tap.clone(), addr2, "0".into()))); - match engine.generate_seal(b2.block(), &genesis_header) { + match engine.generate_seal(&b2, &genesis_header) { Seal::Regular(_) | Seal::Proposal(_) => panic!("sealed despite wrong difficulty"), Seal::None => {} } @@ -1902,7 +1902,7 @@ mod tests { let b1 = b1.close_and_lock().unwrap(); // the block is empty so we don't seal and instead broadcast an empty step message - assert_eq!(engine.generate_seal(b1.block(), &genesis_header), Seal::None); + assert_eq!(engine.generate_seal(&b1, &genesis_header), Seal::None); // spec starts with step 2 let empty_step_rlp = encode(&empty_step(engine, 2, &genesis_header.hash())); @@ -1912,7 +1912,7 @@ mod tests { let len = notify.messages.read().len(); // make sure that we don't generate empty step for the second time - assert_eq!(engine.generate_seal(b1.block(), &genesis_header), Seal::None); + assert_eq!(engine.generate_seal(&b1, &genesis_header), Seal::None); assert_eq!(len, notify.messages.read().len()); } @@ -1941,7 +1941,7 @@ mod tests { // since the block is empty it isn't sealed and we generate empty steps engine.set_signer(Box::new((tap.clone(), addr1, "1".into()))); - assert_eq!(engine.generate_seal(b1.block(), &genesis_header), Seal::None); + assert_eq!(engine.generate_seal(&b1, &genesis_header), Seal::None); engine.step(); // step 3 @@ -1958,7 +1958,7 @@ mod tests { // we will now seal a block with 1tx and include the accumulated empty step message engine.set_signer(Box::new((tap.clone(), addr2, "0".into()))); - if let Seal::Regular(seal) = engine.generate_seal(b2.block(), &genesis_header) { + if let Seal::Regular(seal) = engine.generate_seal(&b2, &genesis_header) { engine.set_signer(Box::new((tap.clone(), addr1, "1".into()))); let empty_step2 = sealed_empty_step(engine, 2, &genesis_header.hash()); let empty_steps = ::rlp::encode_list(&vec![empty_step2]); @@ -1994,14 +1994,14 @@ mod tests { // since the block is empty it isn't sealed and we generate empty steps engine.set_signer(Box::new((tap.clone(), addr1, "1".into()))); - assert_eq!(engine.generate_seal(b1.block(), &genesis_header), Seal::None); + assert_eq!(engine.generate_seal(&b1, &genesis_header), Seal::None); engine.step(); // step 3 let b2 = OpenBlock::new(engine, Default::default(), false, db2, &genesis_header, last_hashes.clone(), addr2, (3141562.into(), 31415620.into()), vec![], false, &mut Vec::new().into_iter()).unwrap(); let b2 = b2.close_and_lock().unwrap(); engine.set_signer(Box::new((tap.clone(), addr2, "0".into()))); - assert_eq!(engine.generate_seal(b2.block(), &genesis_header), Seal::None); + assert_eq!(engine.generate_seal(&b2, &genesis_header), Seal::None); engine.step(); // step 4 @@ -2010,7 +2010,7 @@ mod tests { let b3 = b3.close_and_lock().unwrap(); engine.set_signer(Box::new((tap.clone(), addr1, "1".into()))); - if let Seal::Regular(seal) = engine.generate_seal(b3.block(), &genesis_header) { + if let Seal::Regular(seal) = engine.generate_seal(&b3, &genesis_header) { let empty_step2 = sealed_empty_step(engine, 2, &genesis_header.hash()); engine.set_signer(Box::new((tap.clone(), addr2, "0".into()))); let empty_step3 = sealed_empty_step(engine, 3, &genesis_header.hash()); @@ -2044,19 +2044,19 @@ mod tests { // since the block is empty it isn't sealed and we generate empty steps engine.set_signer(Box::new((tap.clone(), addr1, "1".into()))); - assert_eq!(engine.generate_seal(b1.block(), &genesis_header), Seal::None); + assert_eq!(engine.generate_seal(&b1, &genesis_header), Seal::None); engine.step(); // step 3 // the signer of the accumulated empty step message should be rewarded let b2 = OpenBlock::new(engine, Default::default(), false, db2, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![], false, &mut Vec::new().into_iter()).unwrap(); - let addr1_balance = b2.block().state().balance(&addr1).unwrap(); + let addr1_balance = b2.state.balance(&addr1).unwrap(); // after closing the block `addr1` should be reward twice, one for the included empty step message and another for block creation let b2 = b2.close_and_lock().unwrap(); // the spec sets the block reward to 10 - assert_eq!(b2.block().state().balance(&addr1).unwrap(), addr1_balance + (10 * 2)) + assert_eq!(b2.state.balance(&addr1).unwrap(), addr1_balance + (10 * 2)) } #[test] @@ -2155,7 +2155,7 @@ mod tests { // since the block is empty it isn't sealed and we generate empty steps engine.set_signer(Box::new((tap.clone(), addr1, "1".into()))); - assert_eq!(engine.generate_seal(b1.block(), &genesis_header), Seal::None); + assert_eq!(engine.generate_seal(&b1, &genesis_header), Seal::None); engine.step(); // step 3 @@ -2173,7 +2173,7 @@ mod tests { false, &mut Vec::new().into_iter(), ).unwrap(); - let addr1_balance = b2.block().state().balance(&addr1).unwrap(); + let addr1_balance = b2.state.balance(&addr1).unwrap(); // after closing the block `addr1` should be reward twice, one for the included empty step // message and another for block creation @@ -2181,7 +2181,7 @@ mod tests { // the contract rewards (1000 + kind) for each benefactor/reward kind assert_eq!( - b2.block().state().balance(&addr1).unwrap(), + b2.state.balance(&addr1).unwrap(), addr1_balance + (1000 + 0) + (1000 + 2), ) } diff --git a/ethcore/src/engines/basic_authority.rs b/ethcore/src/engines/basic_authority.rs index 1a4bdb55a9..e907e7834f 100644 --- a/ethcore/src/engines/basic_authority.rs +++ b/ethcore/src/engines/basic_authority.rs @@ -104,7 +104,7 @@ impl Engine for BasicAuthority { /// Attempt to seal the block internally. fn generate_seal(&self, block: &ExecutedBlock, _parent: &Header) -> Seal { - let header = block.header(); + let header = &block.header; let author = header.author(); if self.validators.contains(header.parent_hash(), author) { // account should be pernamently unlocked, otherwise sealing will fail @@ -266,7 +266,7 @@ mod tests { let last_hashes = Arc::new(vec![genesis_header.hash()]); let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, addr, (3141562.into(), 31415620.into()), vec![], false, &mut Vec::new().into_iter()).unwrap(); let b = b.close_and_lock().unwrap(); - if let Seal::Regular(seal) = engine.generate_seal(b.block(), &genesis_header) { + if let Seal::Regular(seal) = engine.generate_seal(&b, &genesis_header) { assert!(b.try_seal(engine, seal).is_ok()); } } diff --git a/ethcore/src/engines/instant_seal.rs b/ethcore/src/engines/instant_seal.rs index 93e20196a4..e792c5860e 100644 --- a/ethcore/src/engines/instant_seal.rs +++ b/ethcore/src/engines/instant_seal.rs @@ -110,7 +110,7 @@ mod tests { let last_hashes = Arc::new(vec![genesis_header.hash()]); let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, Address::default(), (3141562.into(), 31415620.into()), vec![], false, &mut Vec::new().into_iter()).unwrap(); let b = b.close_and_lock().unwrap(); - if let Seal::Regular(seal) = engine.generate_seal(b.block(), &genesis_header) { + if let Seal::Regular(seal) = engine.generate_seal(&b, &genesis_header) { assert!(b.try_seal(engine, seal).is_ok()); } } diff --git a/ethcore/src/ethereum/ethash.rs b/ethcore/src/ethereum/ethash.rs index 561b3493be..226747acbb 100644 --- a/ethcore/src/ethereum/ethash.rs +++ b/ethcore/src/ethereum/ethash.rs @@ -542,7 +542,7 @@ mod tests { let last_hashes = Arc::new(vec![genesis_header.hash()]); let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, Address::zero(), (3141562.into(), 31415620.into()), vec![], false, &mut Vec::new().into_iter()).unwrap(); let b = b.close().unwrap(); - assert_eq!(b.state().balance(&Address::zero()).unwrap(), U256::from_str("4563918244f40000").unwrap()); + assert_eq!(b.state.balance(&Address::zero()).unwrap(), U256::from_str("4563918244f40000").unwrap()); } #[test] @@ -596,8 +596,8 @@ mod tests { b.push_uncle(uncle).unwrap(); let b = b.close().unwrap(); - assert_eq!(b.state().balance(&Address::zero()).unwrap(), "478eae0e571ba000".into()); - assert_eq!(b.state().balance(&uncle_author).unwrap(), "3cb71f51fc558000".into()); + assert_eq!(b.state.balance(&Address::zero()).unwrap(), "478eae0e571ba000".into()); + assert_eq!(b.state.balance(&uncle_author).unwrap(), "3cb71f51fc558000".into()); } #[test] @@ -612,9 +612,9 @@ mod tests { let ubi_contract: Address = "00efdd5883ec628983e9063c7d969fe268bbf310".into(); let dev_contract: Address = "00756cf8159095948496617f5fb17ed95059f536".into(); - assert_eq!(b.state().balance(&Address::zero()).unwrap(), U256::from_str("d8d726b7177a80000").unwrap()); - assert_eq!(b.state().balance(&ubi_contract).unwrap(), U256::from_str("2b5e3af16b1880000").unwrap()); - assert_eq!(b.state().balance(&dev_contract).unwrap(), U256::from_str("c249fdd327780000").unwrap()); + assert_eq!(b.state.balance(&Address::zero()).unwrap(), U256::from_str("d8d726b7177a80000").unwrap()); + assert_eq!(b.state.balance(&ubi_contract).unwrap(), U256::from_str("2b5e3af16b1880000").unwrap()); + assert_eq!(b.state.balance(&dev_contract).unwrap(), U256::from_str("c249fdd327780000").unwrap()); } #[test] diff --git a/ethcore/src/machine/impls.rs b/ethcore/src/machine/impls.rs index 90d410c70d..72f20ecdf7 100644 --- a/ethcore/src/machine/impls.rs +++ b/ethcore/src/machine/impls.rs @@ -28,7 +28,7 @@ use types::header::Header; use vm::{CallType, ActionParams, ActionValue, ParamsType}; use vm::{EnvInfo, Schedule, CreateContractAddress}; -use block::{ExecutedBlock, IsBlock}; +use block::ExecutedBlock; use builtin::Builtin; use call_contract::CallContract; use client::BlockInfo; @@ -126,7 +126,7 @@ impl EthereumMachine { data: Option>, ) -> Result, Error> { let (code, code_hash) = { - let state = block.state(); + let state = &block.state; (state.code(&contract_address)?, state.code_hash(&contract_address)?) @@ -193,12 +193,12 @@ impl EthereumMachine { /// Push last known block hash to the state. fn push_last_hash(&self, block: &mut ExecutedBlock) -> Result<(), Error> { let params = self.params(); - if block.header().number() == params.eip210_transition { + if block.header.number() == params.eip210_transition { let state = block.state_mut(); state.init_code(¶ms.eip210_contract_address, params.eip210_contract_code.clone())?; } - if block.header().number() >= params.eip210_transition { - let parent_hash = block.header().parent_hash().clone(); + if block.header.number() >= params.eip210_transition { + let parent_hash = *block.header.parent_hash(); let _ = self.execute_as_system( block, params.eip210_contract_address, @@ -215,7 +215,7 @@ impl EthereumMachine { self.push_last_hash(block)?; if let Some(ref ethash_params) = self.ethash_extensions { - if block.header().number() == ethash_params.dao_hardfork_transition { + if block.header.number() == ethash_params.dao_hardfork_transition { let state = block.state_mut(); for child in ðash_params.dao_hardfork_accounts { let beneficiary = ðash_params.dao_hardfork_beneficiary; @@ -434,7 +434,7 @@ impl super::Machine for EthereumMachine { type Error = Error; fn balance(&self, live: &ExecutedBlock, address: &Address) -> Result { - live.state().balance(address).map_err(Into::into) + live.state.balance(address).map_err(Into::into) } fn add_balance(&self, live: &mut ExecutedBlock, address: &Address, amount: &U256) -> Result<(), Error> { diff --git a/ethcore/src/miner/miner.rs b/ethcore/src/miner/miner.rs index 7d6bcbe496..ce1c9ef6ee 100644 --- a/ethcore/src/miner/miner.rs +++ b/ethcore/src/miner/miner.rs @@ -46,7 +46,7 @@ use types::header::Header; use types::receipt::RichReceipt; use using_queue::{UsingQueue, GetAction}; -use block::{ClosedBlock, IsBlock, SealedBlock}; +use block::{ClosedBlock, SealedBlock}; use client::{ BlockChain, ChainInfo, BlockProducer, SealedBlockImporter, Nonce, TransactionInfo, TransactionId }; @@ -362,7 +362,7 @@ impl Miner { .and_then(|b| { // to prevent a data race between block import and updating pending block // we allow the number to be equal. - if b.block().header().number() >= latest_block_number { + if b.header.number() >= latest_block_number { Some(f(b)) } else { None @@ -392,7 +392,7 @@ impl Miner { // Open block let (mut open_block, original_work_hash) = { let mut sealing = self.sealing.lock(); - let last_work_hash = sealing.queue.peek_last_ref().map(|pb| pb.block().header().hash()); + let last_work_hash = sealing.queue.peek_last_ref().map(|pb| pb.header.hash()); let best_hash = chain_info.best_block_hash; // check to see if last ClosedBlock in would_seals is actually same parent block. @@ -401,7 +401,7 @@ impl Miner { // if at least one was pushed successfully, close and enqueue new ClosedBlock; // otherwise, leave everything alone. // otherwise, author a fresh block. - let mut open_block = match sealing.queue.get_pending_if(|b| b.block().header().parent_hash() == &best_hash) { + let mut open_block = match sealing.queue.get_pending_if(|b| b.header.parent_hash() == &best_hash) { Some(old_block) => { trace!(target: "miner", "prepare_block: Already have previous work; updating and returning"); // add transactions to old_block @@ -436,7 +436,7 @@ impl Miner { let mut invalid_transactions = HashSet::new(); let mut not_allowed_transactions = HashSet::new(); let mut senders_to_penalize = HashSet::new(); - let block_number = open_block.block().header().number(); + let block_number = open_block.header.number(); let mut tx_count = 0usize; let mut skipped_transactions = 0usize; @@ -453,7 +453,7 @@ impl Miner { let max_transactions = if min_tx_gas.is_zero() { usize::max_value() } else { - MAX_SKIPPED_TRANSACTIONS.saturating_add(cmp::min(*open_block.block().header().gas_limit() / min_tx_gas, u64::max_value().into()).as_u64() as usize) + MAX_SKIPPED_TRANSACTIONS.saturating_add(cmp::min(*open_block.header.gas_limit() / min_tx_gas, u64::max_value().into()).as_u64() as usize) }; let pending: Vec> = self.transaction_queue.pending( @@ -636,7 +636,7 @@ impl Miner { { { let sealing = self.sealing.lock(); - if block.transactions().is_empty() + if block.transactions.is_empty() && !self.forced_sealing() && Instant::now() <= sealing.next_mandatory_reseal { @@ -646,7 +646,7 @@ impl Miner { trace!(target: "miner", "seal_block_internally: attempting internal seal."); - let parent_header = match chain.block_header(BlockId::Hash(*block.header().parent_hash())) { + let parent_header = match chain.block_header(BlockId::Hash(*block.header.parent_hash())) { Some(h) => { match h.decode() { Ok(decoded_hdr) => decoded_hdr, @@ -656,7 +656,7 @@ impl Miner { None => return false, }; - match self.engine.generate_seal(block.block(), &parent_header) { + match self.engine.generate_seal(&block, &parent_header) { // Save proposal for later seal submission and broadcast it. Seal::Proposal(seal) => { trace!(target: "miner", "Received a Proposal seal."); @@ -705,11 +705,11 @@ impl Miner { /// Prepares work which has to be done to seal. fn prepare_work(&self, block: ClosedBlock, original_work_hash: Option) { let (work, is_new) = { - let block_header = block.block().header().clone(); + let block_header = block.header.clone(); let block_hash = block_header.hash(); let mut sealing = self.sealing.lock(); - let last_work_hash = sealing.queue.peek_last_ref().map(|pb| pb.block().header().hash()); + let last_work_hash = sealing.queue.peek_last_ref().map(|pb| pb.header.hash()); trace!( target: "miner", @@ -742,7 +742,7 @@ impl Miner { trace!( target: "miner", "prepare_work: leaving (last={:?})", - sealing.queue.peek_last_ref().map(|b| b.block().header().hash()) + sealing.queue.peek_last_ref().map(|b| b.header.hash()) ); (work, is_new) }; @@ -994,7 +994,7 @@ impl miner::MinerService for Miner { let from_pending = || { self.map_existing_pending_block(|sealing| { - sealing.transactions() + sealing.transactions .iter() .map(|signed| signed.hash()) .collect() @@ -1041,7 +1041,7 @@ impl miner::MinerService for Miner { let from_pending = || { self.map_existing_pending_block(|sealing| { - sealing.transactions() + sealing.transactions .iter() .map(|signed| pool::VerifiedTransaction::from_pending_block_transaction(signed.clone())) .map(Arc::new) @@ -1086,9 +1086,9 @@ impl miner::MinerService for Miner { fn pending_receipts(&self, best_block: BlockNumber) -> Option> { self.map_existing_pending_block(|pending| { - let receipts = pending.receipts(); - pending.transactions() - .into_iter() + let receipts = &pending.receipts; + pending.transactions + .iter() .enumerate() .map(|(index, tx)| { let prev_gas = if index == 0 { Default::default() } else { receipts[index - 1].gas_used }; @@ -1102,7 +1102,7 @@ impl miner::MinerService for Miner { Action::Call(_) => None, Action::Create => { let sender = tx.sender(); - Some(contract_address(self.engine.create_address_scheme(pending.header().number()), &sender, &tx.nonce, &tx.data).0) + Some(contract_address(self.engine.create_address_scheme(pending.header.number()), &sender, &tx.nonce, &tx.data).0) } }, logs: receipt.logs.clone(), @@ -1139,7 +1139,7 @@ impl miner::MinerService for Miner { // refuse to seal the first block of the chain if it contains hard forks // which should be on by default. - if block.block().header().number() == 1 { + if block.header.number() == 1 { if let Some(name) = self.engine.params().nonzero_bugfix_hard_fork() { warn!("Your chain specification contains one or more hard forks which are required to be \ on by default. Please remove these forks and start your chain again: {}.", name); @@ -1180,7 +1180,7 @@ impl miner::MinerService for Miner { self.prepare_pending_block(chain); self.sealing.lock().queue.use_last_ref().map(|b| { - let header = b.header(); + let header = &b.header; (header.hash(), header.number(), header.timestamp(), *header.difficulty()) }) } @@ -1194,9 +1194,9 @@ impl miner::MinerService for Miner { } else { GetAction::Take }, - |b| &b.hash() == &block_hash + |b| &b.header.bare_hash() == &block_hash ) { - trace!(target: "miner", "Submitted block {}={}={} with seal {:?}", block_hash, b.hash(), b.header().bare_hash(), seal); + trace!(target: "miner", "Submitted block {}={} with seal {:?}", block_hash, b.header.bare_hash(), seal); b.lock().try_seal(&*self.engine, seal).or_else(|e| { warn!(target: "miner", "Mined solution rejected: {}", e); Err(ErrorKind::PowInvalid.into()) @@ -1207,8 +1207,8 @@ impl miner::MinerService for Miner { }; result.and_then(|sealed| { - let n = sealed.header().number(); - let h = sealed.header().hash(); + let n = sealed.header.number(); + let h = sealed.header.hash(); info!(target: "miner", "Submitted block imported OK. #{}: {}", Colour::White.bold().paint(format!("{}", n)), Colour::White.bold().paint(format!("{:x}", h))); Ok(sealed) }) @@ -1304,19 +1304,25 @@ impl miner::MinerService for Miner { } fn pending_state(&self, latest_block_number: BlockNumber) -> Option { - self.map_existing_pending_block(|b| b.state().clone(), latest_block_number) + self.map_existing_pending_block(|b| b.state.clone(), latest_block_number) } fn pending_block_header(&self, latest_block_number: BlockNumber) -> Option
{ - self.map_existing_pending_block(|b| b.header().clone(), latest_block_number) + self.map_existing_pending_block(|b| b.header.clone(), latest_block_number) } fn pending_block(&self, latest_block_number: BlockNumber) -> Option { - self.map_existing_pending_block(|b| b.to_base(), latest_block_number) + self.map_existing_pending_block(|b| { + Block { + header: b.header.clone(), + transactions: b.transactions.iter().cloned().map(Into::into).collect(), + uncles: b.uncles.to_vec(), + } + }, latest_block_number) } fn pending_transactions(&self, latest_block_number: BlockNumber) -> Option> { - self.map_existing_pending_block(|b| b.transactions().into_iter().cloned().collect(), latest_block_number) + self.map_existing_pending_block(|b| b.transactions.iter().cloned().collect(), latest_block_number) } } diff --git a/ethcore/src/tests/client.rs b/ethcore/src/tests/client.rs index 60ea5e1f0e..4d12bb1385 100644 --- a/ethcore/src/tests/client.rs +++ b/ethcore/src/tests/client.rs @@ -27,7 +27,6 @@ use types::filter::Filter; use types::view; use types::views::BlockView; -use block::IsBlock; use client::{BlockChainClient, Client, ClientConfig, BlockId, ChainInfo, BlockInfo, PrepareOpenBlock, ImportSealedBlock, ImportBlock}; use ethereum; use executive::{Executive, TransactOptions}; @@ -254,7 +253,7 @@ fn can_mine() { let b = client.prepare_open_block(Address::default(), (3141562.into(), 31415620.into()), vec![]).unwrap().close().unwrap(); - assert_eq!(*b.block().header().parent_hash(), view!(BlockView, &dummy_blocks[0]).header_view().hash()); + assert_eq!(*b.header.parent_hash(), view!(BlockView, &dummy_blocks[0]).header_view().hash()); } #[test] diff --git a/rpc/src/v1/tests/helpers/miner_service.rs b/rpc/src/v1/tests/helpers/miner_service.rs index 77618c8532..b16651bd9c 100644 --- a/rpc/src/v1/tests/helpers/miner_service.rs +++ b/rpc/src/v1/tests/helpers/miner_service.rs @@ -20,7 +20,7 @@ use std::sync::Arc; use std::collections::{BTreeMap, BTreeSet, HashMap}; use bytes::Bytes; -use ethcore::block::{SealedBlock, IsBlock}; +use ethcore::block::SealedBlock; use ethcore::client::{Nonce, PrepareOpenBlock, StateClient, EngineInfo}; use ethcore::engines::{EthEngine, signer::EngineSigner}; use ethcore::error::Error; @@ -193,7 +193,7 @@ impl MinerService for TestMinerService { let params = self.authoring_params(); let open_block = chain.prepare_open_block(params.author, params.gas_range_target, params.extra_data).unwrap(); let closed = open_block.close().unwrap(); - let header = closed.header(); + let header = &closed.header; Some((header.hash(), header.number(), header.timestamp(), *header.difficulty())) } From fb461659c7a66005fd41028aa03aeef1914e804e Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Fri, 15 Mar 2019 15:43:54 +0100 Subject: [PATCH 122/168] OpenBlock::new take IntoIterator instead of mutable ref to Iterator (#10480) --- ethcore/src/block.rs | 14 +++++------ ethcore/src/client/client.rs | 2 +- ethcore/src/client/test_client.rs | 2 +- ethcore/src/engines/authority_round/mod.rs | 28 +++++++++++----------- ethcore/src/engines/basic_authority.rs | 2 +- ethcore/src/engines/instant_seal.rs | 2 +- ethcore/src/ethereum/ethash.rs | 6 ++--- ethcore/src/test_helpers.rs | 2 +- ethcore/src/tests/trace.rs | 6 ++--- 9 files changed, 32 insertions(+), 32 deletions(-) diff --git a/ethcore/src/block.rs b/ethcore/src/block.rs index bbcfa473eb..c5311cbe01 100644 --- a/ethcore/src/block.rs +++ b/ethcore/src/block.rs @@ -162,7 +162,7 @@ pub trait Drain { impl<'x> OpenBlock<'x> { /// Create a new `OpenBlock` ready for transaction pushing. - pub fn new<'a>( + pub fn new<'a, I: IntoIterator>( engine: &'x EthEngine, factories: Factories, tracing: bool, @@ -173,7 +173,7 @@ impl<'x> OpenBlock<'x> { gas_range_target: (U256, U256), extra_data: Bytes, is_epoch_begin: bool, - ancestry: &mut Iterator, + ancestry: I, ) -> Result { let number = parent.number() + 1; let state = State::from_existing(db, parent.state_root().clone(), engine.account_start_nonce(number), factories)?; @@ -195,7 +195,7 @@ impl<'x> OpenBlock<'x> { engine.populate_from_parent(&mut r.block.header, parent); engine.machine().on_new_block(&mut r.block)?; - engine.on_new_block(&mut r.block, is_epoch_begin, ancestry)?; + engine.on_new_block(&mut r.block, is_epoch_begin, &mut ancestry.into_iter())?; Ok(r) } @@ -592,7 +592,7 @@ mod tests { (3141562.into(), 31415620.into()), vec![], false, - &mut Vec::new().into_iter(), + None, )?; b.populate_from(&header); @@ -627,7 +627,7 @@ mod tests { let genesis_header = spec.genesis_header(); let db = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap(); let last_hashes = Arc::new(vec![genesis_header.hash()]); - let b = OpenBlock::new(&*spec.engine, Default::default(), false, db, &genesis_header, last_hashes, Address::zero(), (3141562.into(), 31415620.into()), vec![], false, &mut Vec::new().into_iter()).unwrap(); + let b = OpenBlock::new(&*spec.engine, Default::default(), false, db, &genesis_header, last_hashes, Address::zero(), (3141562.into(), 31415620.into()), vec![], false, None).unwrap(); let b = b.close_and_lock().unwrap(); let _ = b.seal(&*spec.engine, vec![]); } @@ -641,7 +641,7 @@ mod tests { let db = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap(); let last_hashes = Arc::new(vec![genesis_header.hash()]); - let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes.clone(), Address::zero(), (3141562.into(), 31415620.into()), vec![], false, &mut Vec::new().into_iter()).unwrap() + let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes.clone(), Address::zero(), (3141562.into(), 31415620.into()), vec![], false, None).unwrap() .close_and_lock().unwrap().seal(engine, vec![]).unwrap(); let orig_bytes = b.rlp_bytes(); let orig_db = b.drain().state.drop().1; @@ -665,7 +665,7 @@ mod tests { let db = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap(); let last_hashes = Arc::new(vec![genesis_header.hash()]); - let mut open_block = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes.clone(), Address::zero(), (3141562.into(), 31415620.into()), vec![], false, &mut Vec::new().into_iter()).unwrap(); + let mut open_block = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes.clone(), Address::zero(), (3141562.into(), 31415620.into()), vec![], false, None).unwrap(); let mut uncle1_header = Header::new(); uncle1_header.set_extra_data(b"uncle1".to_vec()); let mut uncle2_header = Header::new(); diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index 29d642477a..9680c19dfc 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -2321,7 +2321,7 @@ impl PrepareOpenBlock for Client { gas_range_target, extra_data, is_epoch_begin, - &mut chain.ancestry_with_metadata_iter(best_header.hash()), + chain.ancestry_with_metadata_iter(best_header.hash()), )?; // Add uncles diff --git a/ethcore/src/client/test_client.rs b/ethcore/src/client/test_client.rs index fbad806fdf..502a9ee72b 100644 --- a/ethcore/src/client/test_client.rs +++ b/ethcore/src/client/test_client.rs @@ -416,7 +416,7 @@ impl PrepareOpenBlock for TestBlockChainClient { gas_range_target, extra_data, false, - &mut Vec::new().into_iter(), + None, )?; // TODO [todr] Override timestamp for predictability open_block.set_timestamp(*self.latest_block_timestamp.read()); diff --git a/ethcore/src/engines/authority_round/mod.rs b/ethcore/src/engines/authority_round/mod.rs index db25380aa8..65ea2f7798 100644 --- a/ethcore/src/engines/authority_round/mod.rs +++ b/ethcore/src/engines/authority_round/mod.rs @@ -1628,9 +1628,9 @@ mod tests { let db1 = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap(); let db2 = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap(); let last_hashes = Arc::new(vec![genesis_header.hash()]); - let b1 = OpenBlock::new(engine, Default::default(), false, db1, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![], false, &mut Vec::new().into_iter()).unwrap(); + let b1 = OpenBlock::new(engine, Default::default(), false, db1, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![], false, None).unwrap(); let b1 = b1.close_and_lock().unwrap(); - let b2 = OpenBlock::new(engine, Default::default(), false, db2, &genesis_header, last_hashes, addr2, (3141562.into(), 31415620.into()), vec![], false, &mut Vec::new().into_iter()).unwrap(); + let b2 = OpenBlock::new(engine, Default::default(), false, db2, &genesis_header, last_hashes, addr2, (3141562.into(), 31415620.into()), vec![], false, None).unwrap(); let b2 = b2.close_and_lock().unwrap(); engine.set_signer(Box::new((tap.clone(), addr1, "1".into()))); @@ -1662,9 +1662,9 @@ mod tests { let db2 = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap(); let last_hashes = Arc::new(vec![genesis_header.hash()]); - let b1 = OpenBlock::new(engine, Default::default(), false, db1, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![], false, &mut Vec::new().into_iter()).unwrap(); + let b1 = OpenBlock::new(engine, Default::default(), false, db1, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![], false, None).unwrap(); let b1 = b1.close_and_lock().unwrap(); - let b2 = OpenBlock::new(engine, Default::default(), false, db2, &genesis_header, last_hashes, addr2, (3141562.into(), 31415620.into()), vec![], false, &mut Vec::new().into_iter()).unwrap(); + let b2 = OpenBlock::new(engine, Default::default(), false, db2, &genesis_header, last_hashes, addr2, (3141562.into(), 31415620.into()), vec![], false, None).unwrap(); let b2 = b2.close_and_lock().unwrap(); engine.set_signer(Box::new((tap.clone(), addr1, "1".into()))); @@ -1898,7 +1898,7 @@ mod tests { engine.set_signer(Box::new((tap.clone(), addr1, "1".into()))); - let b1 = OpenBlock::new(engine, Default::default(), false, db1, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![], false, &mut Vec::new().into_iter()).unwrap(); + let b1 = OpenBlock::new(engine, Default::default(), false, db1, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![], false, None).unwrap(); let b1 = b1.close_and_lock().unwrap(); // the block is empty so we don't seal and instead broadcast an empty step message @@ -1936,7 +1936,7 @@ mod tests { engine.register_client(Arc::downgrade(&client) as _); // step 2 - let b1 = OpenBlock::new(engine, Default::default(), false, db1, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![], false, &mut Vec::new().into_iter()).unwrap(); + let b1 = OpenBlock::new(engine, Default::default(), false, db1, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![], false, None).unwrap(); let b1 = b1.close_and_lock().unwrap(); // since the block is empty it isn't sealed and we generate empty steps @@ -1945,7 +1945,7 @@ mod tests { engine.step(); // step 3 - let mut b2 = OpenBlock::new(engine, Default::default(), false, db2, &genesis_header, last_hashes.clone(), addr2, (3141562.into(), 31415620.into()), vec![], false, &mut Vec::new().into_iter()).unwrap(); + let mut b2 = OpenBlock::new(engine, Default::default(), false, db2, &genesis_header, last_hashes.clone(), addr2, (3141562.into(), 31415620.into()), vec![], false, None).unwrap(); b2.push_transaction(Transaction { action: Action::Create, nonce: U256::from(0), @@ -1989,7 +1989,7 @@ mod tests { engine.register_client(Arc::downgrade(&client) as _); // step 2 - let b1 = OpenBlock::new(engine, Default::default(), false, db1, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![], false, &mut Vec::new().into_iter()).unwrap(); + let b1 = OpenBlock::new(engine, Default::default(), false, db1, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![], false, None).unwrap(); let b1 = b1.close_and_lock().unwrap(); // since the block is empty it isn't sealed and we generate empty steps @@ -1998,7 +1998,7 @@ mod tests { engine.step(); // step 3 - let b2 = OpenBlock::new(engine, Default::default(), false, db2, &genesis_header, last_hashes.clone(), addr2, (3141562.into(), 31415620.into()), vec![], false, &mut Vec::new().into_iter()).unwrap(); + let b2 = OpenBlock::new(engine, Default::default(), false, db2, &genesis_header, last_hashes.clone(), addr2, (3141562.into(), 31415620.into()), vec![], false, None).unwrap(); let b2 = b2.close_and_lock().unwrap(); engine.set_signer(Box::new((tap.clone(), addr2, "0".into()))); assert_eq!(engine.generate_seal(&b2, &genesis_header), Seal::None); @@ -2006,7 +2006,7 @@ mod tests { // step 4 // the spec sets the maximum_empty_steps to 2 so we will now seal an empty block and include the empty step messages - let b3 = OpenBlock::new(engine, Default::default(), false, db3, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![], false, &mut Vec::new().into_iter()).unwrap(); + let b3 = OpenBlock::new(engine, Default::default(), false, db3, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![], false, None).unwrap(); let b3 = b3.close_and_lock().unwrap(); engine.set_signer(Box::new((tap.clone(), addr1, "1".into()))); @@ -2039,7 +2039,7 @@ mod tests { engine.register_client(Arc::downgrade(&client) as _); // step 2 - let b1 = OpenBlock::new(engine, Default::default(), false, db1, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![], false, &mut Vec::new().into_iter()).unwrap(); + let b1 = OpenBlock::new(engine, Default::default(), false, db1, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![], false, None).unwrap(); let b1 = b1.close_and_lock().unwrap(); // since the block is empty it isn't sealed and we generate empty steps @@ -2049,7 +2049,7 @@ mod tests { // step 3 // the signer of the accumulated empty step message should be rewarded - let b2 = OpenBlock::new(engine, Default::default(), false, db2, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![], false, &mut Vec::new().into_iter()).unwrap(); + let b2 = OpenBlock::new(engine, Default::default(), false, db2, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![], false, None).unwrap(); let addr1_balance = b2.state.balance(&addr1).unwrap(); // after closing the block `addr1` should be reward twice, one for the included empty step message and another for block creation @@ -2149,7 +2149,7 @@ mod tests { (3141562.into(), 31415620.into()), vec![], false, - &mut Vec::new().into_iter(), + None, ).unwrap(); let b1 = b1.close_and_lock().unwrap(); @@ -2171,7 +2171,7 @@ mod tests { (3141562.into(), 31415620.into()), vec![], false, - &mut Vec::new().into_iter(), + None, ).unwrap(); let addr1_balance = b2.state.balance(&addr1).unwrap(); diff --git a/ethcore/src/engines/basic_authority.rs b/ethcore/src/engines/basic_authority.rs index e907e7834f..69b8d07c52 100644 --- a/ethcore/src/engines/basic_authority.rs +++ b/ethcore/src/engines/basic_authority.rs @@ -264,7 +264,7 @@ mod tests { let genesis_header = spec.genesis_header(); let db = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap(); let last_hashes = Arc::new(vec![genesis_header.hash()]); - let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, addr, (3141562.into(), 31415620.into()), vec![], false, &mut Vec::new().into_iter()).unwrap(); + let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, addr, (3141562.into(), 31415620.into()), vec![], false, None).unwrap(); let b = b.close_and_lock().unwrap(); if let Seal::Regular(seal) = engine.generate_seal(&b, &genesis_header) { assert!(b.try_seal(engine, seal).is_ok()); diff --git a/ethcore/src/engines/instant_seal.rs b/ethcore/src/engines/instant_seal.rs index e792c5860e..a578c990b3 100644 --- a/ethcore/src/engines/instant_seal.rs +++ b/ethcore/src/engines/instant_seal.rs @@ -108,7 +108,7 @@ mod tests { let db = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap(); let genesis_header = spec.genesis_header(); let last_hashes = Arc::new(vec![genesis_header.hash()]); - let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, Address::default(), (3141562.into(), 31415620.into()), vec![], false, &mut Vec::new().into_iter()).unwrap(); + let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, Address::default(), (3141562.into(), 31415620.into()), vec![], false, None).unwrap(); let b = b.close_and_lock().unwrap(); if let Seal::Regular(seal) = engine.generate_seal(&b, &genesis_header) { assert!(b.try_seal(engine, seal).is_ok()); diff --git a/ethcore/src/ethereum/ethash.rs b/ethcore/src/ethereum/ethash.rs index 226747acbb..698e23cf7e 100644 --- a/ethcore/src/ethereum/ethash.rs +++ b/ethcore/src/ethereum/ethash.rs @@ -540,7 +540,7 @@ mod tests { let genesis_header = spec.genesis_header(); let db = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap(); let last_hashes = Arc::new(vec![genesis_header.hash()]); - let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, Address::zero(), (3141562.into(), 31415620.into()), vec![], false, &mut Vec::new().into_iter()).unwrap(); + let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, Address::zero(), (3141562.into(), 31415620.into()), vec![], false, None).unwrap(); let b = b.close().unwrap(); assert_eq!(b.state.balance(&Address::zero()).unwrap(), U256::from_str("4563918244f40000").unwrap()); } @@ -589,7 +589,7 @@ mod tests { let genesis_header = spec.genesis_header(); let db = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap(); let last_hashes = Arc::new(vec![genesis_header.hash()]); - let mut b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, Address::zero(), (3141562.into(), 31415620.into()), vec![], false, &mut Vec::new().into_iter()).unwrap(); + let mut b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, Address::zero(), (3141562.into(), 31415620.into()), vec![], false, None).unwrap(); let mut uncle = Header::new(); let uncle_author: Address = "ef2d6d194084c2de36e0dabfce45d046b37d1106".into(); uncle.set_author(uncle_author); @@ -607,7 +607,7 @@ mod tests { let genesis_header = spec.genesis_header(); let db = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap(); let last_hashes = Arc::new(vec![genesis_header.hash()]); - let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, Address::zero(), (3141562.into(), 31415620.into()), vec![], false, &mut Vec::new().into_iter()).unwrap(); + let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, Address::zero(), (3141562.into(), 31415620.into()), vec![], false, None).unwrap(); let b = b.close().unwrap(); let ubi_contract: Address = "00efdd5883ec628983e9063c7d969fe268bbf310".into(); diff --git a/ethcore/src/test_helpers.rs b/ethcore/src/test_helpers.rs index ae4968080b..b5575f36cd 100644 --- a/ethcore/src/test_helpers.rs +++ b/ethcore/src/test_helpers.rs @@ -155,7 +155,7 @@ pub fn generate_dummy_client_with_spec_and_data(test_spec: F, block_number: u (3141562.into(), 31415620.into()), vec![], false, - &mut Vec::new().into_iter(), + None, ).unwrap(); rolling_timestamp += 10; b.set_timestamp(rolling_timestamp); diff --git a/ethcore/src/tests/trace.rs b/ethcore/src/tests/trace.rs index f687aac127..c14f13cf59 100644 --- a/ethcore/src/tests/trace.rs +++ b/ethcore/src/tests/trace.rs @@ -86,7 +86,7 @@ fn can_trace_block_and_uncle_reward() { (3141562.into(), 31415620.into()), vec![], false, - &mut Vec::new().into_iter(), + None, ).unwrap(); rolling_timestamp += 10; root_block.set_timestamp(rolling_timestamp); @@ -115,7 +115,7 @@ fn can_trace_block_and_uncle_reward() { (3141562.into(), 31415620.into()), vec![], false, - &mut Vec::new().into_iter(), + None, ).unwrap(); rolling_timestamp += 10; parent_block.set_timestamp(rolling_timestamp); @@ -143,7 +143,7 @@ fn can_trace_block_and_uncle_reward() { (3141562.into(), 31415620.into()), vec![], false, - &mut Vec::new().into_iter(), + None, ).unwrap(); rolling_timestamp += 10; block.set_timestamp(rolling_timestamp); From a8ee3c97e6f5cd9acab1604f2358c9daef4e1c27 Mon Sep 17 00:00:00 2001 From: TriplEight Date: Tue, 19 Mar 2019 01:14:59 +0100 Subject: [PATCH 123/168] =?UTF-8?q?=D0=A1aching=20through=20docker=20volum?= =?UTF-8?q?e=20(#10477)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * _old codebase_ before docker update * before docker update, testing runnr * docker update, testing the caching * distributed job cargo homes * distributed job cargo homes 2 * distributed job cargo homes 3 * dockerfile with gitlab checkout, audit uses template * dockerfile gets repo in volume * change builds_dir * trying docker cache for repo * repo cached automatically * after script is not concatenated * check sccache non-cacheable reasons nature * watch cache * log sccache * log sccache 2 * debug log sccache * fix debug log sccache * fix debug log sccache 2 * debug log cache 3 * debug log cache 3 * trace log all sccache * test wo cargo cache * test w removed cargo cache * report non-cacheable reasons, cargo cache is back and empty * report non-cacheable reasons, cargo cache is back and empty 2 * report non-cacheable reasons, cargo cache is back and empty 3 * wrap into after_script * restore CI tags `qa` -> `linux-docker` * return to main runners, this will fail until config on runners And Dockerfile won't be updated * typo fix CI lint * return to docker tag --- .gitlab-ci.yml | 52 +++++++++++++++++++++++++++++++------------------- 1 file changed, 32 insertions(+), 20 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 079b8ed8f8..cab10b56a9 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -9,10 +9,9 @@ variables: GIT_STRATEGY: fetch GIT_SUBMODULE_STRATEGY: recursive CI_SERVER_NAME: "GitLab CI" - CARGO_HOME: "${CI_PROJECT_DIR}/.cargo" CARGO_TARGET: x86_64-unknown-linux-gnu -.no_git: &no_git #disable git strategy +.no_git: &no_git # disable git strategy variables: GIT_STRATEGY: none GIT_SUBMODULE_STRATEGY: none @@ -32,12 +31,17 @@ variables: paths: - artifacts/ -.docker-cache-status: &docker-cache-status - dependencies: [] +.docker-cache-status: &docker-cache-status + variables: + CARGO_HOME: "/cargo/${CI_JOB_NAME}" before_script: + - SCCACHE_ERROR_LOG=/builds/parity/parity-ethereum/sccache_error.log RUST_LOG=sccache::server=debug sccache --start-server - sccache -s after_script: - - sccache -s + - echo "All crate-types:" + - grep 'parse_arguments.*--crate-type' sccache_error.log | sed -re 's/.*"--crate-type", "([^"]+)".*/\1/' | sort | uniq -c + - echo "Non-cacheable reasons:" + - grep CannotCache sccache_error.log | sed -re 's/.*CannotCache\((.+)\).*/\1/' | sort | uniq -c tags: - linux-docker @@ -47,43 +51,60 @@ cargo-check 0 3: <<: *docker-cache-status script: - time cargo check --target $CARGO_TARGET --locked --no-default-features + - sccache -s cargo-check 1 3: stage: test <<: *docker-cache-status script: - time cargo check --target $CARGO_TARGET --locked --manifest-path util/io/Cargo.toml --no-default-features + - sccache -s cargo-check 2 3: stage: test <<: *docker-cache-status script: - time cargo check --target $CARGO_TARGET --locked --manifest-path util/io/Cargo.toml --features "mio" + - sccache -s cargo-audit: stage: test + <<: *docker-cache-status script: - cargo audit - tags: - - linux-docker + - sccache -s validate-chainspecs: stage: test <<: *docker-cache-status script: - ./scripts/gitlab/validate-chainspecs.sh + - sccache -s test-cpp: stage: build <<: *docker-cache-status script: - ./scripts/gitlab/test-cpp.sh + - sccache -s test-linux: stage: build <<: *docker-cache-status script: - ./scripts/gitlab/test-linux.sh + - sccache -s + +build-android: + stage: build + image: parity/rust-android:gitlab-ci + variables: + CARGO_TARGET: armv7-linux-androideabi + script: + - scripts/gitlab/build-linux.sh + tags: + - linux-docker + <<: *collect_artifacts build-linux: &build-linux stage: build @@ -91,6 +112,7 @@ build-linux: &build-linux <<: *docker-cache-status script: - scripts/gitlab/build-linux.sh + - sccache -s <<: *collect_artifacts build-linux-i386: @@ -138,7 +160,7 @@ build-windows: publish-docker: stage: publish only: *releaseable_branches - cache: {} + cache: {} dependencies: - build-linux tags: @@ -152,7 +174,7 @@ publish-snap: &publish-snap image: snapcore/snapcraft variables: BUILD_ARCH: amd64 - cache: {} + cache: {} dependencies: - build-linux tags: @@ -227,19 +249,9 @@ publish-docs: - tags except: - nightly - cache: {} + cache: {} script: - scripts/gitlab/publish-docs.sh tags: - linux-docker -build-android: - stage: build - image: parity/rust-android:gitlab-ci - variables: - CARGO_TARGET: armv7-linux-androideabi - script: - - scripts/gitlab/build-linux.sh - tags: - - linux-docker - <<: *collect_artifacts From effead9ba5c544ea982223802812d6871e9c4bec Mon Sep 17 00:00:00 2001 From: "Denis S. Soldatov aka General-Beck" Date: Tue, 19 Mar 2019 13:39:44 +0300 Subject: [PATCH 124/168] fix win&mac build (#10486) add CARGO_HOME: "${CI_PROJECT_DIR}/.cargo" --- .gitlab-ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index cab10b56a9..217c49126f 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -138,6 +138,7 @@ build-darwin: only: *releaseable_branches variables: CARGO_TARGET: x86_64-apple-darwin + CARGO_HOME: "${CI_PROJECT_DIR}/.cargo" CC: gcc CXX: g++ script: @@ -151,6 +152,7 @@ build-windows: only: *releaseable_branches variables: CARGO_TARGET: x86_64-pc-windows-msvc + CARGO_HOME: "${CI_PROJECT_DIR}/.cargo" script: - sh scripts/gitlab/build-windows.sh tags: From 78a534633d754c95225312646184eff83e4cb78b Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Tue, 19 Mar 2019 16:37:24 +0100 Subject: [PATCH 125/168] fix(rpc): lint `unused_extern_crates` + fix warns (#10489) --- Cargo.lock | 2 -- rpc/Cargo.toml | 4 +--- rpc/src/lib.rs | 15 +++++++-------- 3 files changed, 8 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b6c0b3ef61..36c723bbd8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2658,7 +2658,6 @@ dependencies = [ "jsonrpc-pubsub 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-ws-server 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "kvdb-memorydb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "macros 0.1.0", "multihash 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2683,7 +2682,6 @@ dependencies = [ "tokio-timer 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "transaction-pool 1.13.3 (registry+https://github.com/rust-lang/crates.io-index)", "transient-hashmap 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "trie-db 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "vm 0.1.0", ] diff --git a/rpc/Cargo.toml b/rpc/Cargo.toml index c6c59dc15a..aea96f663a 100644 --- a/rpc/Cargo.toml +++ b/rpc/Cargo.toml @@ -38,7 +38,6 @@ common-types = { path = "../ethcore/types" } ethash = { path = "../ethash" } ethcore = { path = "../ethcore", features = ["test-helpers"] } ethcore-accounts = { path = "../accounts", optional = true } -ethcore-io = { path = "../util/io" } ethcore-light = { path = "../ethcore/light" } ethcore-logger = { path = "../parity/logger" } ethcore-miner = { path = "../miner" } @@ -59,7 +58,6 @@ keccak-hash = "0.1.2" parity-runtime = { path = "../util/runtime" } parity-updater = { path = "../updater" } parity-version = { path = "../util/version" } -trie-db = "0.11.0" rlp = { version = "0.3.0", features = ["ethereum"] } stats = { path = "../util/stats" } vm = { path = "../ethcore/vm" } @@ -67,9 +65,9 @@ vm = { path = "../ethcore/vm" } [dev-dependencies] ethcore = { path = "../ethcore", features = ["test-helpers"] } ethcore-accounts = { path = "../accounts" } +ethcore-io = { path = "../util/io" } ethcore-network = { path = "../util/network" } fake-fetch = { path = "../util/fake-fetch" } -kvdb-memorydb = "0.1" macros = { path = "../util/macros" } pretty_assertions = "0.1" transaction-pool = "1.13" diff --git a/rpc/src/lib.rs b/rpc/src/lib.rs index 4a90fbe693..cafd7a8e44 100644 --- a/rpc/src/lib.rs +++ b/rpc/src/lib.rs @@ -16,7 +16,7 @@ //! Parity RPC. -#![warn(missing_docs)] +#![warn(missing_docs, unused_extern_crates)] #[macro_use] extern crate futures; @@ -32,7 +32,6 @@ extern crate rustc_hex; extern crate semver; extern crate serde; extern crate serde_json; -extern crate tiny_keccak; extern crate tokio_timer; extern crate transient_hashmap; @@ -48,7 +47,6 @@ extern crate ethcore; extern crate fastmap; extern crate parity_bytes as bytes; extern crate parity_crypto as crypto; -extern crate ethcore_io as io; extern crate ethcore_light as light; extern crate ethcore_logger; extern crate ethcore_miner as miner; @@ -63,15 +61,18 @@ extern crate keccak_hash as hash; extern crate parity_runtime; extern crate parity_updater as updater; extern crate parity_version as version; -extern crate trie_db as trie; extern crate eip_712; extern crate rlp; extern crate stats; +extern crate tempdir; extern crate vm; #[cfg(any(test, feature = "ethcore-accounts"))] extern crate ethcore_accounts as accounts; +#[cfg(any(test, feature = "ethcore-accounts"))] +extern crate tiny_keccak; + #[macro_use] extern crate log; #[macro_use] @@ -90,13 +91,11 @@ extern crate pretty_assertions; #[macro_use] extern crate macros; -#[cfg(test)] -extern crate kvdb_memorydb; - #[cfg(test)] extern crate fake_fetch; -extern crate tempdir; +#[cfg(test)] +extern crate ethcore_io as io; pub extern crate jsonrpc_ws_server as ws; From 037fd1b309d7769e8eb9f5d8dc54978c158c4fdb Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Tue, 19 Mar 2019 23:17:05 +0100 Subject: [PATCH 126/168] fix(extract `timestamp_checked_add` as lib) (#10383) * fix(extract `timestamp_checked_add` as lib) * fix(whisper types): remove unused `EmptyTopics` * fix(time-lib): feature-flag to use time-lib or std This commit adds conditional compilation checks that falls back to `our time-lib` when `time_checked_add` is not available in the standard library Note, `time_checked_add` covers both `checked_add` and `checked_sub` * fix(grumble): use cfg_attr to define rustc feature --- Cargo.lock | 6 +++ Cargo.toml | 3 +- ethcore/Cargo.toml | 1 + ethcore/src/engines/authority_round/mod.rs | 17 ++++++-- ethcore/src/lib.rs | 4 ++ ethcore/src/verification/verification.rs | 38 +++++----------- util/time-utils/Cargo.toml | 9 ++++ util/time-utils/src/lib.rs | 50 ++++++++++++++++++++++ whisper/Cargo.toml | 1 + whisper/src/lib.rs | 5 +++ whisper/src/message.rs | 25 ++++++----- whisper/src/net/mod.rs | 9 ++-- 12 files changed, 123 insertions(+), 45 deletions(-) create mode 100644 util/time-utils/Cargo.toml create mode 100644 util/time-utils/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 36c723bbd8..5902aa786c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -752,6 +752,7 @@ dependencies = [ "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", "stats 0.1.0", "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "time-utils 0.1.0", "trace-time 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "trie-db 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "trie-standardmap 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2817,6 +2818,7 @@ dependencies = [ "serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "time-utils 0.1.0", "tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3772,6 +3774,10 @@ dependencies = [ "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "time-utils" +version = "0.1.0" + [[package]] name = "timer" version = "0.2.0" diff --git a/Cargo.toml b/Cargo.toml index ee4440dd01..a783175607 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -138,7 +138,8 @@ members = [ "util/triehash-ethereum", "util/keccak-hasher", "util/patricia-trie-ethereum", - "util/fastmap" + "util/fastmap", + "util/time-utils" ] [patch.crates-io] diff --git a/ethcore/Cargo.toml b/ethcore/Cargo.toml index 2d26ba0381..3b8d60af8e 100644 --- a/ethcore/Cargo.toml +++ b/ethcore/Cargo.toml @@ -63,6 +63,7 @@ serde = "1.0" serde_derive = "1.0" stats = { path = "../util/stats" } tempdir = {version="0.3", optional = true} +time-utils = { path = "../util/time-utils" } trace-time = "0.1" triehash-ethereum = { version = "0.2", path = "../util/triehash-ethereum" } unexpected = { path = "../util/unexpected" } diff --git a/ethcore/src/engines/authority_round/mod.rs b/ethcore/src/engines/authority_round/mod.rs index 65ea2f7798..36f25144f7 100644 --- a/ethcore/src/engines/authority_round/mod.rs +++ b/ethcore/src/engines/authority_round/mod.rs @@ -47,6 +47,9 @@ use types::header::{Header, ExtendedHeader}; use types::ancestry_action::AncestryAction; use unexpected::{Mismatch, OutOfBounds}; +#[cfg(not(time_checked_add))] +use time_utils::CheckedSystemTime; + mod finality; /// `AuthorityRound` params. @@ -574,8 +577,15 @@ fn verify_timestamp(step: &Step, header_step: u64) -> Result<(), BlockError> { // NOTE This error might be returned only in early stage of verification (Stage 1). // Returning it further won't recover the sync process. trace!(target: "engine", "verify_timestamp: block too early"); - let oob = oob.map(|n| SystemTime::now() + Duration::from_secs(n)); - Err(BlockError::TemporarilyInvalid(oob).into()) + + let now = SystemTime::now(); + let found = now.checked_add(Duration::from_secs(oob.found)).ok_or(BlockError::TimestampOverflow)?; + let max = oob.max.and_then(|m| now.checked_add(Duration::from_secs(m))); + let min = oob.min.and_then(|m| now.checked_add(Duration::from_secs(m))); + + let new_oob = OutOfBounds { min, max, found }; + + Err(BlockError::TemporarilyInvalid(new_oob).into()) }, Ok(_) => Ok(()), } @@ -611,6 +621,7 @@ fn combine_proofs(signal_number: BlockNumber, set_proof: &[u8], finality_proof: stream.out() } + fn destructure_proofs(combined: &[u8]) -> Result<(BlockNumber, &[u8], &[u8]), Error> { let rlp = Rlp::new(combined); Ok(( @@ -626,7 +637,7 @@ trait AsMillis { impl AsMillis for Duration { fn as_millis(&self) -> u64 { - self.as_secs()*1_000 + (self.subsec_nanos()/1_000_000) as u64 + self.as_secs() * 1_000 + (self.subsec_nanos() / 1_000_000) as u64 } } diff --git a/ethcore/src/lib.rs b/ethcore/src/lib.rs index 17b33025a1..eee076b32e 100644 --- a/ethcore/src/lib.rs +++ b/ethcore/src/lib.rs @@ -15,6 +15,7 @@ // along with Parity Ethereum. If not, see . #![warn(missing_docs, unused_extern_crates)] +#![cfg_attr(feature = "time_checked_add", feature(time_checked_add))] //! Ethcore library //! @@ -148,6 +149,9 @@ extern crate fetch; #[cfg(all(test, feature = "price-info"))] extern crate parity_runtime; +#[cfg(not(time_checked_add))] +extern crate time_utils; + pub mod block; pub mod builtin; pub mod client; diff --git a/ethcore/src/verification/verification.rs b/ethcore/src/verification/verification.rs index 8a11f0ef45..36a847f64a 100644 --- a/ethcore/src/verification/verification.rs +++ b/ethcore/src/verification/verification.rs @@ -40,24 +40,8 @@ use types::{BlockNumber, header::Header}; use types::transaction::SignedTransaction; use verification::queue::kind::blocks::Unverified; - -/// Returns `Ok` when the result less or equal to `i32::max_value` to prevent `SystemTime` to panic because -/// it is platform specific, may be i32 or i64. -/// -/// `Err Result { - let d1 = sys.duration_since(UNIX_EPOCH).map_err(|_| BlockError::TimestampOverflow)?; - let total_time = d1.checked_add(d2).ok_or(BlockError::TimestampOverflow)?; - - if total_time.as_secs() <= i32::max_value() as u64 { - Ok(sys + d2) - } else { - Err(BlockError::TimestampOverflow) - } -} +#[cfg(not(time_checked_add))] +use time_utils::CheckedSystemTime; /// Preprocessed block data gathered in `verify_block_unordered` call pub struct PreverifiedBlock { @@ -323,9 +307,11 @@ pub fn verify_header_params(header: &Header, engine: &EthEngine, is_full: bool, if is_full { const ACCEPTABLE_DRIFT: Duration = Duration::from_secs(15); + // this will resist overflow until `year 2037` let max_time = SystemTime::now() + ACCEPTABLE_DRIFT; let invalid_threshold = max_time + ACCEPTABLE_DRIFT * 9; - let timestamp = timestamp_checked_add(UNIX_EPOCH, Duration::from_secs(header.timestamp()))?; + let timestamp = UNIX_EPOCH.checked_add(Duration::from_secs(header.timestamp())) + .ok_or(BlockError::TimestampOverflow)?; if timestamp > invalid_threshold { return Err(From::from(BlockError::InvalidTimestamp(OutOfBounds { max: Some(max_time), min: None, found: timestamp }))) @@ -347,8 +333,11 @@ fn verify_parent(header: &Header, parent: &Header, engine: &EthEngine) -> Result let gas_limit_divisor = engine.params().gas_limit_bound_divisor; if !engine.is_timestamp_valid(header.timestamp(), parent.timestamp()) { - let min = timestamp_checked_add(SystemTime::now(), Duration::from_secs(parent.timestamp().saturating_add(1)))?; - let found = timestamp_checked_add(SystemTime::now(), Duration::from_secs(header.timestamp()))?; + let now = SystemTime::now(); + let min = now.checked_add(Duration::from_secs(parent.timestamp().saturating_add(1))) + .ok_or(BlockError::TimestampOverflow)?; + let found = now.checked_add(Duration::from_secs(header.timestamp())) + .ok_or(BlockError::TimestampOverflow)?; return Err(From::from(BlockError::InvalidTimestamp(OutOfBounds { max: None, min: Some(min), found }))) } if header.number() != parent.number() + 1 { @@ -835,11 +824,4 @@ mod tests { check_fail(unordered_test(&create_test_block_with_data(&header, &bad_transactions, &[]), &engine), TooManyTransactions(keypair.address())); unordered_test(&create_test_block_with_data(&header, &good_transactions, &[]), &engine).unwrap(); } - - #[test] - fn checked_add_systime_dur() { - assert!(timestamp_checked_add(UNIX_EPOCH, Duration::new(i32::max_value() as u64 + 1, 0)).is_err()); - assert!(timestamp_checked_add(UNIX_EPOCH, Duration::new(i32::max_value() as u64, 0)).is_ok()); - assert!(timestamp_checked_add(UNIX_EPOCH, Duration::new(i32::max_value() as u64 - 1, 1_000_000_000)).is_ok()); - } } diff --git a/util/time-utils/Cargo.toml b/util/time-utils/Cargo.toml new file mode 100644 index 0000000000..38e7dd02c6 --- /dev/null +++ b/util/time-utils/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "time-utils" +version = "0.1.0" +authors = ["Parity Technologies "] +description = "Time utilities for checked arithmetic" +license = "GPL3" +edition = "2018" + +[dependencies] diff --git a/util/time-utils/src/lib.rs b/util/time-utils/src/lib.rs new file mode 100644 index 0000000000..ff9f159cfa --- /dev/null +++ b/util/time-utils/src/lib.rs @@ -0,0 +1,50 @@ +use std::time::{Duration, SystemTime, UNIX_EPOCH}; + +/// Temporary trait for `checked operations` on SystemTime until these are available in standard library +pub trait CheckedSystemTime { + /// Returns `Some` when the result less or equal to `i32::max_value` to prevent `SystemTime` to panic because + /// it is platform specific, possible representations are i32, i64, u64 and Duration. `None` otherwise + fn checked_add(self, _d: Duration) -> Option; + /// Returns `Some` when the result is successful and `None` when it is not + fn checked_sub(self, _d: Duration) -> Option; +} + +impl CheckedSystemTime for SystemTime { + fn checked_add(self, dur: Duration) -> Option { + let this_dur = self.duration_since(UNIX_EPOCH).ok()?; + let total_time = this_dur.checked_add(dur)?; + + if total_time.as_secs() <= i32::max_value() as u64 { + Some(self + dur) + } else { + None + } + } + + fn checked_sub(self, dur: Duration) -> Option { + let this_dur = self.duration_since(UNIX_EPOCH).ok()?; + let total_time = this_dur.checked_sub(dur)?; + + if total_time.as_secs() <= i32::max_value() as u64 { + Some(self - dur) + } else { + None + } + } +} + +#[cfg(test)] +mod tests { + #[test] + fn it_works() { + use super::CheckedSystemTime; + use std::time::{Duration, SystemTime, UNIX_EPOCH}; + + assert!(CheckedSystemTime::checked_add(UNIX_EPOCH, Duration::new(i32::max_value() as u64 + 1, 0)).is_none()); + assert!(CheckedSystemTime::checked_add(UNIX_EPOCH, Duration::new(i32::max_value() as u64, 0)).is_some()); + assert!(CheckedSystemTime::checked_add(UNIX_EPOCH, Duration::new(i32::max_value() as u64 - 1, 1_000_000_000)).is_some()); + + assert!(CheckedSystemTime::checked_sub(UNIX_EPOCH, Duration::from_secs(120)).is_none()); + assert!(CheckedSystemTime::checked_sub(SystemTime::now(), Duration::from_secs(1000)).is_some()); + } +} diff --git a/whisper/Cargo.toml b/whisper/Cargo.toml index 5c3548a50c..97aa8f23ac 100644 --- a/whisper/Cargo.toml +++ b/whisper/Cargo.toml @@ -24,6 +24,7 @@ serde_json = "1.0" slab = "0.3" smallvec = "0.6" tiny-keccak = "1.4" +time-utils = { path = "../util/time-utils" } jsonrpc-core = "10.0.1" jsonrpc-derive = "10.0.2" diff --git a/whisper/src/lib.rs b/whisper/src/lib.rs index 0e79946d9a..cdc88780d4 100644 --- a/whisper/src/lib.rs +++ b/whisper/src/lib.rs @@ -17,6 +17,8 @@ //! Whisper P2P messaging system as a DevP2P subprotocol, with RPC and Rust //! interface. +#![cfg_attr(feature = "time_checked_add", feature(time_checked_add))] + extern crate byteorder; extern crate parity_crypto as crypto; extern crate ethcore_network as network; @@ -46,6 +48,9 @@ extern crate log; #[macro_use] extern crate serde_derive; +#[cfg(not(time_checked_add))] +extern crate time_utils; + #[cfg(test)] extern crate serde_json; diff --git a/whisper/src/message.rs b/whisper/src/message.rs index f8e8565a8e..0fc686e52a 100644 --- a/whisper/src/message.rs +++ b/whisper/src/message.rs @@ -24,6 +24,9 @@ use rlp::{self, DecoderError, RlpStream, Rlp}; use smallvec::SmallVec; use tiny_keccak::{keccak256, Keccak}; +#[cfg(not(time_checked_add))] +use time_utils::CheckedSystemTime; + /// Work-factor proved. Takes 3 parameters: size of message, time to live, /// and hash. /// @@ -117,6 +120,7 @@ pub enum Error { EmptyTopics, LivesTooLong, IssuedInFuture, + TimestampOverflow, ZeroTTL, } @@ -133,6 +137,7 @@ impl fmt::Display for Error { Error::LivesTooLong => write!(f, "Message claims to be issued before the unix epoch."), Error::IssuedInFuture => write!(f, "Message issued in future."), Error::ZeroTTL => write!(f, "Message live for zero time."), + Error::TimestampOverflow => write!(f, "Timestamp overflow"), Error::EmptyTopics => write!(f, "Message has no topics."), } } @@ -226,10 +231,6 @@ impl rlp::Decodable for Envelope { } } -/// Error indicating no topics. -#[derive(Debug, Copy, Clone)] -pub struct EmptyTopics; - /// Message creation parameters. /// Pass this to `Message::create` to make a message. pub struct CreateParams { @@ -255,11 +256,11 @@ pub struct Message { impl Message { /// Create a message from creation parameters. /// Panics if TTL is 0. - pub fn create(params: CreateParams) -> Result { + pub fn create(params: CreateParams) -> Result { use byteorder::{BigEndian, ByteOrder}; use rand::{Rng, SeedableRng, XorShiftRng}; - if params.topics.is_empty() { return Err(EmptyTopics) } + if params.topics.is_empty() { return Err(Error::EmptyTopics) } let mut rng = { let mut thread_rng = ::rand::thread_rng(); @@ -270,7 +271,8 @@ impl Message { assert!(params.ttl > 0); let expiry = { - let after_mining = SystemTime::now() + Duration::from_millis(params.work); + let after_mining = SystemTime::now().checked_sub(Duration::from_millis(params.work)) + .ok_or(Error::TimestampOverflow)?; let since_epoch = after_mining.duration_since(time::UNIX_EPOCH) .expect("time after now is after unix epoch; qed"); @@ -357,7 +359,10 @@ impl Message { (envelope.expiry - envelope.ttl).saturating_sub(LEEWAY_SECONDS) ); - if time::UNIX_EPOCH + issue_time_adjusted > now { + let issue_time_adjusted = time::UNIX_EPOCH.checked_add(issue_time_adjusted) + .ok_or(Error::TimestampOverflow)?; + + if issue_time_adjusted > now { return Err(Error::IssuedInFuture); } @@ -400,8 +405,8 @@ impl Message { } /// Get the expiry time. - pub fn expiry(&self) -> SystemTime { - time::UNIX_EPOCH + Duration::from_secs(self.envelope.expiry) + pub fn expiry(&self) -> Option { + time::UNIX_EPOCH.checked_add(Duration::from_secs(self.envelope.expiry)) } /// Get the topics. diff --git a/whisper/src/net/mod.rs b/whisper/src/net/mod.rs index 64431d1426..d263f6cfbd 100644 --- a/whisper/src/net/mod.rs +++ b/whisper/src/net/mod.rs @@ -223,7 +223,10 @@ impl Messages { } } - let expiry = message.expiry(); + let expiry = match message.expiry() { + Some(time) => time, + _ => return false, + }; self.cumulative_size += message.encoded_size(); @@ -232,8 +235,8 @@ impl Messages { let sorted_entry = SortedEntry { slab_id: id, - work_proved: work_proved, - expiry: expiry, + work_proved, + expiry, }; match self.sorted.binary_search(&sorted_entry) { From 9519493e32ba98ac655381c786dffdf9ea0e33d7 Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Wed, 20 Mar 2019 16:01:38 +0100 Subject: [PATCH 127/168] fix(time-utils): add missing license (#10497) --- util/time-utils/src/lib.rs | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/util/time-utils/src/lib.rs b/util/time-utils/src/lib.rs index ff9f159cfa..0bfc3bb982 100644 --- a/util/time-utils/src/lib.rs +++ b/util/time-utils/src/lib.rs @@ -1,9 +1,25 @@ +// Copyright 2015-2019 Parity Technologies (UK) Ltd. +// This file is part of Parity Ethereum. + +// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . + use std::time::{Duration, SystemTime, UNIX_EPOCH}; -/// Temporary trait for `checked operations` on SystemTime until these are available in standard library +/// Temporary trait for `checked operations` on SystemTime until these are available in the standard library pub trait CheckedSystemTime { /// Returns `Some` when the result less or equal to `i32::max_value` to prevent `SystemTime` to panic because - /// it is platform specific, possible representations are i32, i64, u64 and Duration. `None` otherwise + /// it is platform specific, possible representations are i32, i64, u64 or Duration. `None` otherwise fn checked_add(self, _d: Duration) -> Option; /// Returns `Some` when the result is successful and `None` when it is not fn checked_sub(self, _d: Duration) -> Option; From b700ff3501facd214324b1adf70994df868d0506 Mon Sep 17 00:00:00 2001 From: Guillaume Ballet Date: Thu, 21 Mar 2019 15:45:02 +0100 Subject: [PATCH 128/168] whisper/cli: add p2p port and ip parameters (#10057) * whisper/cli: add p2p port and ip parameters This is so that those params don't change randomly and are in sync with the URL that is displayed. * feedback: Result instead of panic Co-Authored-By: gballet * feedback: Map error in port conversion Co-Authored-By: gballet * whisper/cli: User can specify enode private key So that the enode doesn't change at every run. * whipser/cli: finish integrating review feedback. * Accomodate error API change * Update rustc-hex version in whisper/cli/Cargo.toml Co-Authored-By: gballet * Update README with new whisper cli options * Fix typo in error message Co-Authored-By: gballet * Fix Cargo.lock and build issue after lib version upgrade * Fix another typo Co-Authored-By: gballet --- Cargo.lock | 2 ++ whisper/README.md | 7 +++-- whisper/cli/Cargo.toml | 2 ++ whisper/cli/src/main.rs | 59 +++++++++++++++++++++++++++++++++++++---- 4 files changed, 63 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5902aa786c..811bb6cbc7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4369,12 +4369,14 @@ dependencies = [ "env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore-network 1.12.0", "ethcore-network-devp2p 1.12.0", + "ethkey 0.3.0", "jsonrpc-core 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-http-server 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-pubsub 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "panic_hook 0.1.0", "parity-whisper 0.1.0", + "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/whisper/README.md b/whisper/README.md index dc449568aa..b64c0244f9 100644 --- a/whisper/README.md +++ b/whisper/README.md @@ -14,8 +14,11 @@ Usage: 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]. + -p, --port PORT Specify which P2P port to use [default: random]. + -a, --address ADDRESS Specify which P2P address to use [default: 127.0.0.1]. + -s, --secret KEYFILE Specify which file contains the key to generate the enode. + -P, --rpc-port PORT Specify which RPC port to use [default: 8545]. + -A, --rpc-address ADDRESS Specify which RPC 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. ``` diff --git a/whisper/cli/Cargo.toml b/whisper/cli/Cargo.toml index 4d123c09ab..5ed38e47d7 100644 --- a/whisper/cli/Cargo.toml +++ b/whisper/cli/Cargo.toml @@ -18,6 +18,8 @@ panic_hook = { path = "../../util/panic-hook" } parity-whisper = { path = "../" } serde = "1.0" serde_derive = "1.0" +ethkey = { path = "../../accounts/ethkey" } +rustc-hex = "2.0" [[bin]] name = "whisper" diff --git a/whisper/cli/src/main.rs b/whisper/cli/src/main.rs index 9ef2304b47..41d9e80e42 100644 --- a/whisper/cli/src/main.rs +++ b/whisper/cli/src/main.rs @@ -33,6 +33,8 @@ extern crate serde; extern crate jsonrpc_core; extern crate jsonrpc_pubsub; extern crate jsonrpc_http_server; +extern crate ethkey; +extern crate rustc_hex; #[macro_use] extern crate log as rlog; @@ -45,6 +47,10 @@ use std::{fmt, io, process, env, sync::Arc}; use jsonrpc_core::{Metadata, MetaIoHandler}; use jsonrpc_pubsub::{PubSubMetadata, Session}; use jsonrpc_http_server::{AccessControlAllowOrigin, DomainsValidation}; +use std::net::{SocketAddr, SocketAddrV4, Ipv4Addr}; +use std::str::FromStr; +use ethkey::Secret; +use rustc_hex::FromHex; const POOL_UNIT: usize = 1024 * 1024; const USAGE: &'static str = r#" @@ -57,8 +63,11 @@ Usage: 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]. + -p, --port PORT Specify which P2P port to use [default: random]. + -a, --address ADDRESS Specify which P2P address to use [default: 127.0.0.1]. + -s, --secret KEYFILE Specify which file contains the key to generate the enode. + -P, --rpc-port PORT Specify which RPC port to use [default: 8545]. + -A, --rpc-address ADDRESS Specify which RPC 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. "#; @@ -79,7 +88,10 @@ struct Args { flag_whisper_pool_size: usize, flag_port: String, flag_address: String, + flag_rpc_port: String, + flag_rpc_address: String, flag_log: String, + flag_secret: String, } struct WhisperPoolHandle { @@ -131,6 +143,8 @@ enum Error { JsonRpc(jsonrpc_core::Error), Network(net::Error), SockAddr(std::net::AddrParseError), + FromHex(rustc_hex::FromHexError), + ParseInt(std::num::ParseIntError), } impl From for Error { @@ -163,6 +177,18 @@ impl From for Error { } } +impl From for Error { + fn from(err: rustc_hex::FromHexError) -> Self { + Error::FromHex(err) + } +} + +impl From for Error { + fn from(err: std::num::ParseIntError) -> Self { + Error::ParseInt(err) + } +} + impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { match *self { @@ -171,6 +197,8 @@ impl fmt::Display for Error { Error::Io(ref e) => write!(f, "{}", e), Error::JsonRpc(ref e) => write!(f, "{:?}", e), Error::Network(ref e) => write!(f, "{}", e), + Error::ParseInt(ref e) => write!(f, "Invalid port: {}", e), + Error::FromHex(ref e) => write!(f, "Error deciphering key: {}", e), } } } @@ -196,7 +224,7 @@ fn execute(command: I) -> Result<(), Error> where I: IntoIterator, // 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); + let rpc_url = format!("{}:{}", args.flag_rpc_address, args.flag_rpc_port); initialize_logger(args.flag_log); info!(target: "whisper-cli", "start"); @@ -207,8 +235,29 @@ fn execute(command: I) -> Result<(), Error> where I: IntoIterator, // Whisper protocol network handler let whisper_network_handler = Arc::new(whisper::net::Network::new(pool_size, manager.clone())); + let network_config = { + let mut cfg = net::NetworkConfiguration::new(); + let port = match args.flag_port.as_str() { + "random" => 0 as u16, + port => port.parse::()?, + + }; + let addr = Ipv4Addr::from_str(&args.flag_address[..])?; + cfg.listen_address = Some(SocketAddr::V4(SocketAddrV4::new(addr, port))); + cfg.use_secret = match args.flag_secret.as_str() { + "" => None, + fname => { + let key_text = std::fs::read_to_string(fname)?; + let key : Vec = FromHex::from_hex(key_text.as_str())?; + Secret::from_slice(key.as_slice()) + } + }; + cfg.nat_enabled = false; + cfg + }; + // Create network service - let network = devp2p::NetworkService::new(net::NetworkConfiguration::new_local(), None)?; + let network = devp2p::NetworkService::new(network_config, None)?; // Start network service network.start().map_err(|(err, _)| err)?; @@ -233,7 +282,7 @@ fn execute(command: I) -> Result<(), Error> where I: IntoIterator, let server = jsonrpc_http_server::ServerBuilder::new(io) .cors(DomainsValidation::AllowOnly(vec![AccessControlAllowOrigin::Null])) - .start_http(&url.parse()?)?; + .start_http(&rpc_url.parse()?)?; server.wait(); From 375a8daeb4693baa9f853255d94640ff4297f572 Mon Sep 17 00:00:00 2001 From: Hernando Castano Date: Thu, 21 Mar 2019 17:37:13 +0100 Subject: [PATCH 129/168] Add additional request tests (#10503) --- ethcore/light/src/types/request/batch.rs | 74 ++++++++++++++++++++++++ ethcore/light/src/types/request/mod.rs | 4 +- 2 files changed, 76 insertions(+), 2 deletions(-) diff --git a/ethcore/light/src/types/request/batch.rs b/ethcore/light/src/types/request/batch.rs index 6dc75c2497..f99b49d2b2 100644 --- a/ethcore/light/src/types/request/batch.rs +++ b/ethcore/light/src/types/request/batch.rs @@ -255,4 +255,78 @@ mod tests { hash: Field::BackReference(0, 0), })).unwrap(); } + + #[test] + fn batch_tx_index_backreference() { + let mut builder = Builder::default(); + builder.push(Request::HeaderProof(IncompleteHeaderProofRequest { + num: 100.into(), // header proof puts hash at output 0. + })).unwrap(); + builder.push(Request::TransactionIndex(IncompleteTransactionIndexRequest { + hash: Field::BackReference(0, 0), + })).unwrap(); + + let mut batch = builder.build(); + batch.requests[1].fill(|_req_idx, _out_idx| Ok(Output::Hash(42.into()))); + + assert!(batch.next_complete().is_some()); + batch.answered += 1; + assert!(batch.next_complete().is_some()); + } + + #[test] + #[should_panic] + fn batch_tx_index_backreference_wrong_output() { + let mut builder = Builder::default(); + builder.push(Request::HeaderProof(IncompleteHeaderProofRequest { + num: 100.into(), // header proof puts hash at output 0. + })).unwrap(); + builder.push(Request::TransactionIndex(IncompleteTransactionIndexRequest { + hash: Field::BackReference(0, 0), + })).unwrap(); + + let mut batch = builder.build(); + batch.requests[1].fill(|_req_idx, _out_idx| Ok(Output::Number(42))); + + batch.next_complete(); + batch.answered += 1; + batch.next_complete(); + } + + #[test] + fn batch_receipts_backreference() { + let mut builder = Builder::default(); + builder.push(Request::HeaderProof(IncompleteHeaderProofRequest { + num: 100.into(), // header proof puts hash at output 0. + })).unwrap(); + builder.push(Request::Receipts(IncompleteReceiptsRequest { + hash: Field::BackReference(0, 0), + })).unwrap(); + + let mut batch = builder.build(); + batch.requests[1].fill(|_req_idx, _out_idx| Ok(Output::Hash(42.into()))); + + assert!(batch.next_complete().is_some()); + batch.answered += 1; + assert!(batch.next_complete().is_some()); + } + + #[test] + #[should_panic] + fn batch_receipts_backreference_wrong_output() { + let mut builder = Builder::default(); + builder.push(Request::HeaderProof(IncompleteHeaderProofRequest { + num: 100.into(), // header proof puts hash at output 0. + })).unwrap(); + builder.push(Request::Receipts(IncompleteReceiptsRequest { + hash: Field::BackReference(0, 0), + })).unwrap(); + + let mut batch = builder.build(); + batch.requests[1].fill(|_req_idx, _out_idx| Ok(Output::Number(42))); + + batch.next_complete(); + batch.answered += 1; + batch.next_complete(); + } } diff --git a/ethcore/light/src/types/request/mod.rs b/ethcore/light/src/types/request/mod.rs index d43aa72636..cacfbcbe50 100644 --- a/ethcore/light/src/types/request/mod.rs +++ b/ethcore/light/src/types/request/mod.rs @@ -907,7 +907,7 @@ pub mod transaction_index { fn fill(&mut self, oracle: F) where F: Fn(usize, usize) -> Result { if let Field::BackReference(req, idx) = self.hash { self.hash = match oracle(req, idx) { - Ok(Output::Number(hash)) => Field::Scalar(hash.into()), + Ok(Output::Hash(hash)) => Field::Scalar(hash.into()), _ => Field::BackReference(req, idx), } } @@ -982,7 +982,7 @@ pub mod block_receipts { fn fill(&mut self, oracle: F) where F: Fn(usize, usize) -> Result { if let Field::BackReference(req, idx) = self.hash { self.hash = match oracle(req, idx) { - Ok(Output::Number(hash)) => Field::Scalar(hash.into()), + Ok(Output::Hash(hash)) => Field::Scalar(hash.into()), _ => Field::BackReference(req, idx), } } From f2c34f7ca2e5893044bb5891c50b5f730dbe9a86 Mon Sep 17 00:00:00 2001 From: "Denis S. Soldatov aka General-Beck" Date: Fri, 22 Mar 2019 13:46:57 +0300 Subject: [PATCH 130/168] fix Sha3/keccak256 hash calculation for binaries (#10509) https://github.com/paritytech/parity-ethereum/issues/10495 --- scripts/gitlab/build-linux.sh | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/scripts/gitlab/build-linux.sh b/scripts/gitlab/build-linux.sh index 9b2b123280..f0697080cb 100755 --- a/scripts/gitlab/build-linux.sh +++ b/scripts/gitlab/build-linux.sh @@ -47,5 +47,10 @@ echo "_____ Calculating checksums _____" for binary in $(ls) do rhash --sha256 $binary -o $binary.sha256 #do we still need this hash (SHA2)? - rhash --sha3-256 $binary -o $binary.sha3 + if [[ $CARGO_TARGET == *"x86_64"* ]]; + then + ./parity tools hash $binary > $binary.sha3 + else + echo "> ${binary} cannot be hashed with cross-compiled binary (keccak256)" + fi done From 17042e9c32005ded509dd821868acbd8d16cc475 Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Fri, 22 Mar 2019 12:01:11 +0100 Subject: [PATCH 131/168] fix(rpc): fix a bunch of clippy lints (#10493) * fix(rpc): fix a bunch of clippy lints * fix(rpc clippy): remove unused ignored lints * fix(clippy): fix all redundant_field_names This commit fixes all uses of `redundant_field_names` and removes the ignored lint `redundant_field_names` * fix(brain unwrap): replace with expect --- parity/rpc_apis.rs | 4 +- rpc/src/authcodes.rs | 12 +- rpc/src/http_common.rs | 2 +- rpc/src/lib.rs | 27 ++- rpc/src/tests/helpers.rs | 6 +- rpc/src/tests/http_client.rs | 22 +-- rpc/src/tests/ws.rs | 2 +- rpc/src/v1/extractors.rs | 14 +- rpc/src/v1/helpers/deprecated.rs | 2 +- rpc/src/v1/helpers/dispatch/light.rs | 8 +- rpc/src/v1/helpers/dispatch/mod.rs | 8 +- rpc/src/v1/helpers/external_signer/mod.rs | 2 +- rpc/src/v1/helpers/external_signer/oneshot.rs | 2 +- .../helpers/external_signer/signing_queue.rs | 4 +- rpc/src/v1/helpers/fake_sign.rs | 10 +- rpc/src/v1/helpers/ipfs.rs | 2 +- rpc/src/v1/helpers/light_fetch.rs | 56 +++---- rpc/src/v1/helpers/signature.rs | 2 +- rpc/src/v1/helpers/subscription_manager.rs | 2 +- rpc/src/v1/helpers/work.rs | 17 +- rpc/src/v1/impls/debug.rs | 11 +- rpc/src/v1/impls/eth.rs | 158 +++++++++--------- rpc/src/v1/impls/eth_filter.rs | 23 ++- rpc/src/v1/impls/eth_pubsub.rs | 22 +-- rpc/src/v1/impls/light/eth.rs | 108 ++++++------ rpc/src/v1/impls/light/net.rs | 2 +- rpc/src/v1/impls/light/parity.rs | 54 +++--- rpc/src/v1/impls/light/parity_set.rs | 6 +- rpc/src/v1/impls/parity.rs | 37 ++-- rpc/src/v1/impls/parity_set.rs | 14 +- rpc/src/v1/impls/private.rs | 27 +-- rpc/src/v1/impls/pubsub.rs | 2 +- rpc/src/v1/impls/rpc.rs | 4 +- rpc/src/v1/impls/signer.rs | 17 +- rpc/src/v1/impls/signing.rs | 15 +- rpc/src/v1/impls/signing_unsafe.rs | 6 +- rpc/src/v1/impls/traces.rs | 20 +-- rpc/src/v1/impls/web3.rs | 8 +- rpc/src/v1/informant.rs | 12 +- rpc/src/v1/tests/mocked/web3.rs | 6 +- rpc/src/v1/types/block.rs | 24 +-- rpc/src/v1/types/block_number.rs | 2 +- rpc/src/v1/types/confirmations.rs | 10 +- rpc/src/v1/types/consensus_status.rs | 2 +- rpc/src/v1/types/filter.rs | 13 +- rpc/src/v1/types/log.rs | 8 +- rpc/src/v1/types/private_receipt.rs | 6 +- rpc/src/v1/types/pubsub.rs | 8 +- rpc/src/v1/types/receipt.rs | 26 +-- rpc/src/v1/types/sync.rs | 4 +- rpc/src/v1/types/trace.rs | 48 +++--- rpc/src/v1/types/transaction.rs | 40 ++--- rpc/src/v1/types/transaction_request.rs | 16 +- 53 files changed, 472 insertions(+), 491 deletions(-) diff --git a/parity/rpc_apis.rs b/parity/rpc_apis.rs index 9287f62720..288f85ab42 100644 --- a/parity/rpc_apis.rs +++ b/parity/rpc_apis.rs @@ -283,7 +283,7 @@ impl FullDependencies { handler.extend_with(DebugClient::new(self.client.clone()).to_delegate()); } Api::Web3 => { - handler.extend_with(Web3Client::new().to_delegate()); + handler.extend_with(Web3Client::default().to_delegate()); } Api::Net => { handler.extend_with(NetClient::new(&self.sync).to_delegate()); @@ -529,7 +529,7 @@ impl LightDependencies { warn!(target: "rpc", "Debug API is not available in light client mode.") } Api::Web3 => { - handler.extend_with(Web3Client::new().to_delegate()); + handler.extend_with(Web3Client::default().to_delegate()); } Api::Net => { handler.extend_with(light::NetClient::new(self.sync.clone()).to_delegate()); diff --git a/rpc/src/authcodes.rs b/rpc/src/authcodes.rs index 976ce1a3fb..b348dfd729 100644 --- a/rpc/src/authcodes.rs +++ b/rpc/src/authcodes.rs @@ -51,7 +51,7 @@ const TIME_THRESHOLD: u64 = 7; /// minimal length of hash const TOKEN_LENGTH: usize = 16; /// Separator between fields in serialized tokens file. -const SEPARATOR: &'static str = ";"; +const SEPARATOR: &str = ";"; /// Number of seconds to keep unused tokens. const UNUSED_TOKEN_TIMEOUT: u64 = 3600 * 24; // a day @@ -115,7 +115,7 @@ impl AuthCodes { }) .collect(); Ok(AuthCodes { - codes: codes, + codes, now: time_provider, }) } @@ -128,7 +128,7 @@ impl AuthCodes { pub fn to_file(&self, file: &Path) -> io::Result<()> { let mut file = fs::File::create(file)?; let content = self.codes.iter().map(|code| { - let mut data = vec![code.code.clone(), encode_time(code.created_at.clone())]; + let mut data = vec![code.code.clone(), encode_time(code.created_at)]; if let Some(used_at) = code.last_used_at { data.push(encode_time(used_at)); } @@ -141,11 +141,11 @@ impl AuthCodes { pub fn new(codes: Vec, now: T) -> Self { AuthCodes { codes: codes.into_iter().map(|code| Code { - code: code, + code, created_at: time::Duration::from_secs(now.now()), last_used_at: None, }).collect(), - now: now, + now, } } @@ -183,7 +183,7 @@ impl AuthCodes { .join("-"); trace!(target: "signer", "New authentication token generated."); self.codes.push(Code { - code: code, + code, created_at: time::Duration::from_secs(self.now.now()), last_used_at: None, }); diff --git a/rpc/src/http_common.rs b/rpc/src/http_common.rs index 517bbbf760..99bd392f35 100644 --- a/rpc/src/http_common.rs +++ b/rpc/src/http_common.rs @@ -44,7 +44,7 @@ impl http::MetaExtractor for MetaExtractor where { fn read_metadata(&self, req: &hyper::Request) -> M { let as_string = |header: Option<&hyper::header::HeaderValue>| { - header.and_then(|val| val.to_str().ok().map(|s| s.to_owned())) + header.and_then(|val| val.to_str().ok().map(ToOwned::to_owned)) }; let origin = as_string(req.headers().get("origin")); diff --git a/rpc/src/lib.rs b/rpc/src/lib.rs index cafd7a8e44..a537cb2942 100644 --- a/rpc/src/lib.rs +++ b/rpc/src/lib.rs @@ -17,6 +17,25 @@ //! Parity RPC. #![warn(missing_docs, unused_extern_crates)] +#![cfg_attr(feature = "cargo-clippy", warn(clippy::all, clippy::pedantic))] +#![cfg_attr( + feature = "cargo-clippy", + allow( + // things are often more readable this way + clippy::cast_lossless, + clippy::module_name_repetitions, + clippy::single_match_else, + clippy::type_complexity, + clippy::use_self, + // not practical + clippy::match_bool, + clippy::needless_pass_by_value, + clippy::similar_names, + // don't require markdown syntax for docs + clippy::doc_markdown, + ), + warn(clippy::indexing_slicing) +)] #[macro_use] extern crate futures; @@ -145,8 +164,8 @@ pub fn start_http( Ok(http::ServerBuilder::with_meta_extractor(handler, extractor) .keep_alive(keep_alive) .threads(threads) - .cors(cors_domains.into()) - .allowed_hosts(allowed_hosts.into()) + .cors(cors_domains) + .allowed_hosts(allowed_hosts) .health_api(("/api/health", "parity_nodeStatus")) .cors_allow_headers(AccessControlAllowHeaders::Any) .max_request_body_size(max_payload * 1024 * 1024) @@ -176,8 +195,8 @@ pub fn start_http_with_middleware( Ok(http::ServerBuilder::with_meta_extractor(handler, extractor) .keep_alive(keep_alive) .threads(threads) - .cors(cors_domains.into()) - .allowed_hosts(allowed_hosts.into()) + .cors(cors_domains) + .allowed_hosts(allowed_hosts) .cors_allow_headers(AccessControlAllowHeaders::Any) .max_request_body_size(max_payload * 1024 * 1024) .request_middleware(middleware) diff --git a/rpc/src/tests/helpers.rs b/rpc/src/tests/helpers.rs index fe04906d4a..301d77e91c 100644 --- a/rpc/src/tests/helpers.rs +++ b/rpc/src/tests/helpers.rs @@ -39,7 +39,7 @@ impl Server { Server { server: f(remote), - event_loop: event_loop, + event_loop, } } } @@ -60,8 +60,8 @@ pub struct GuardedAuthCodes { pub path: PathBuf, } -impl GuardedAuthCodes { - pub fn new() -> Self { +impl Default for GuardedAuthCodes { + fn default() -> Self { let tempdir = TempDir::new("").unwrap(); let path = tempdir.path().join("file"); diff --git a/rpc/src/tests/http_client.rs b/rpc/src/tests/http_client.rs index 7720f4254b..0588c791e7 100644 --- a/rpc/src/tests/http_client.rs +++ b/rpc/src/tests/http_client.rs @@ -30,7 +30,7 @@ pub struct Response { impl Response { pub fn assert_header(&self, header: &str, value: &str) { let header = format!("{}: {}", header, value); - assert!(self.headers.iter().find(|h| *h == &header).is_some(), "Couldn't find header {} in {:?}", header, &self.headers) + assert!(self.headers.iter().any(|h| h == &header), "Couldn't find header {} in {:?}", header, &self.headers) } pub fn assert_status(&self, status: &str) { @@ -98,35 +98,35 @@ pub fn request(address: &SocketAddr, request: &str) -> Response { let mut lines = response.lines(); let status = lines.next().expect("Expected a response").to_owned(); let headers_raw = read_block(&mut lines, false); - let headers = headers_raw.split('\n').map(|v| v.to_owned()).collect(); + let headers = headers_raw.split('\n').map(ToOwned::to_owned).collect(); let body = read_block(&mut lines, true); Response { - status: status, - headers: headers, - headers_raw: headers_raw, - body: body, + status, + headers, + headers_raw, + body, } } /// Check if all required security headers are present pub fn assert_security_headers_present(headers: &[String], port: Option) { - if let None = port { + if port.is_none() { assert!( - headers.iter().find(|header| header.as_str() == "X-Frame-Options: SAMEORIGIN").is_some(), + headers.iter().any(|header| header.as_str() == "X-Frame-Options: SAMEORIGIN") "X-Frame-Options: SAMEORIGIN missing: {:?}", headers ); } assert!( - headers.iter().find(|header| header.as_str() == "X-XSS-Protection: 1; mode=block").is_some(), + headers.iter().any(|header| header.as_str() == "X-XSS-Protection: 1; mode=block") "X-XSS-Protection missing: {:?}", headers ); assert!( - headers.iter().find(|header| header.as_str() == "X-Content-Type-Options: nosniff").is_some(), + headers.iter().any(|header| header.as_str() == "X-Content-Type-Options: nosniff") "X-Content-Type-Options missing: {:?}", headers ); assert!( - headers.iter().find(|header| header.starts_with("Content-Security-Policy: ")).is_some(), + headers.iter().any(|header| header.starts_with("Content-Security-Policy: ")) "Content-Security-Policy missing: {:?}", headers ) } diff --git a/rpc/src/tests/ws.rs b/rpc/src/tests/ws.rs index 7bb0b00894..3b60788820 100644 --- a/rpc/src/tests/ws.rs +++ b/rpc/src/tests/ws.rs @@ -29,7 +29,7 @@ use tests::http_client; pub fn serve() -> (Server, usize, GuardedAuthCodes) { let address = "127.0.0.1:0".parse().unwrap(); let io = MetaIoHandler::default(); - let authcodes = GuardedAuthCodes::new(); + let authcodes = GuardedAuthCodes::default(); let stats = Arc::new(informant::RpcStats::default()); let res = Server::new(|_| ::start_ws( diff --git a/rpc/src/v1/extractors.rs b/rpc/src/v1/extractors.rs index 2620125e0d..d3384c2c1d 100644 --- a/rpc/src/v1/extractors.rs +++ b/rpc/src/v1/extractors.rs @@ -41,8 +41,8 @@ impl HttpMetaExtractor for RpcExtractor { Metadata { origin: Origin::Rpc( format!("{} / {}", - origin.unwrap_or("unknown origin".to_string()), - user_agent.unwrap_or("unknown agent".to_string())) + origin.unwrap_or_else(|| "unknown origin".to_string()), + user_agent.unwrap_or_else(|| "unknown agent".to_string())) ), session: None, } @@ -67,7 +67,7 @@ impl WsExtractor { /// Creates new `WsExtractor` with given authcodes path. pub fn new(path: Option<&Path>) -> Self { WsExtractor { - authcodes_path: path.map(|p| p.to_owned()), + authcodes_path: path.map(ToOwned::to_owned), } } } @@ -80,7 +80,7 @@ impl ws::MetaExtractor for WsExtractor { Some(ref path) => { let authorization = req.protocols.get(0).and_then(|p| auth_token_hash(&path, p, true)); match authorization { - Some(id) => Origin::Signer { session: id.into() }, + Some(id) => Origin::Signer { session: id }, None => Origin::Ws { session: id.into() }, } }, @@ -186,7 +186,7 @@ impl WsStats { /// Creates new WS usage tracker. pub fn new(stats: Arc) -> Self { WsStats { - stats: stats, + stats, } } } @@ -210,7 +210,7 @@ impl> WsDispatcher { /// Create new `WsDispatcher` with given full handler. pub fn new(full_handler: core::MetaIoHandler) -> Self { WsDispatcher { - full_handler: full_handler, + full_handler, } } } @@ -229,7 +229,7 @@ impl> core::Middleware for WsDispatcher< X: core::futures::Future, Error=()> + Send + 'static, { let use_full = match &meta.origin { - &Origin::Signer { .. } => true, + Origin::Signer { .. } => true, _ => false, }; diff --git a/rpc/src/v1/helpers/deprecated.rs b/rpc/src/v1/helpers/deprecated.rs index eb754c01ac..49e9d8b074 100644 --- a/rpc/src/v1/helpers/deprecated.rs +++ b/rpc/src/v1/helpers/deprecated.rs @@ -66,7 +66,7 @@ impl Instant> DeprecationNotice { pub fn print<'a, T: Into>>(&self, method: MethodName, details: T) { let now = (self.now)(); match self.next_warning_at.read().get(method) { - Some(next) if next > &now => return, + Some(next) if *next > now => return, _ => {}, } diff --git a/rpc/src/v1/helpers/dispatch/light.rs b/rpc/src/v1/helpers/dispatch/light.rs index 2913e52c85..59c3af5232 100644 --- a/rpc/src/v1/helpers/dispatch/light.rs +++ b/rpc/src/v1/helpers/dispatch/light.rs @@ -147,19 +147,19 @@ where const DEFAULT_GAS_PRICE: U256 = U256([0, 0, 0, 21_000_000]); let gas_limit = self.client.best_block_header().gas_limit(); - let request_gas_price = request.gas_price.clone(); + let request_gas_price = request.gas_price; let from = request.from.unwrap_or(default_sender); let with_gas_price = move |gas_price| { let request = request; FilledTransactionRequest { - from: from.clone(), + from, used_default_from: request.from.is_none(), to: request.to, nonce: request.nonce, - gas_price: gas_price, + gas_price, gas: request.gas.unwrap_or_else(|| gas_limit / 3), - value: request.value.unwrap_or_else(|| 0.into()), + value: request.value.unwrap_or_default(), data: request.data.unwrap_or_else(Vec::new), condition: request.condition, } diff --git a/rpc/src/v1/helpers/dispatch/mod.rs b/rpc/src/v1/helpers/dispatch/mod.rs index 8877209723..3f247f0c6c 100644 --- a/rpc/src/v1/helpers/dispatch/mod.rs +++ b/rpc/src/v1/helpers/dispatch/mod.rs @@ -294,7 +294,7 @@ pub fn execute( Box::new( dispatcher.sign(request, &signer, pass, post_sign).map(|(hash, token)| { - WithToken::from((ConfirmationResponse::SendTransaction(hash.into()), token)) + WithToken::from((ConfirmationResponse::SendTransaction(hash), token)) }) ) }, @@ -368,13 +368,13 @@ pub fn from_rpc(payload: RpcConfirmationPayload, default_account: Address, di .map(ConfirmationPayload::SignTransaction)) }, RpcConfirmationPayload::Decrypt(RpcDecryptRequest { address, msg }) => { - Box::new(future::ok(ConfirmationPayload::Decrypt(address.into(), msg.into()))) + Box::new(future::ok(ConfirmationPayload::Decrypt(address, msg.into()))) }, RpcConfirmationPayload::EthSignMessage(RpcEthSignRequest { address, data }) => { - Box::new(future::ok(ConfirmationPayload::EthSignMessage(address.into(), data.into()))) + Box::new(future::ok(ConfirmationPayload::EthSignMessage(address, data.into()))) }, RpcConfirmationPayload::EIP191SignMessage(RpcSignRequest { address, data }) => { - Box::new(future::ok(ConfirmationPayload::SignMessage(address.into(), data.into()))) + Box::new(future::ok(ConfirmationPayload::SignMessage(address, data))) }, } } diff --git a/rpc/src/v1/helpers/external_signer/mod.rs b/rpc/src/v1/helpers/external_signer/mod.rs index 49bbaafe59..0797929cbd 100644 --- a/rpc/src/v1/helpers/external_signer/mod.rs +++ b/rpc/src/v1/helpers/external_signer/mod.rs @@ -40,7 +40,7 @@ impl SignerService { SignerService { queue: Arc::new(ConfirmationsQueue::default()), generate_new_token: Box::new(new_token), - is_enabled: is_enabled, + is_enabled, } } diff --git a/rpc/src/v1/helpers/external_signer/oneshot.rs b/rpc/src/v1/helpers/external_signer/oneshot.rs index 623691d399..eac3dca7f8 100644 --- a/rpc/src/v1/helpers/external_signer/oneshot.rs +++ b/rpc/src/v1/helpers/external_signer/oneshot.rs @@ -28,7 +28,7 @@ pub struct Sender { impl Sender { pub fn send(self, data: Res) { let res = self.sender.send(data); - if let Err(_) = res { + if res.is_err() { debug!(target: "rpc", "Responding to a no longer active request."); } } diff --git a/rpc/src/v1/helpers/external_signer/signing_queue.rs b/rpc/src/v1/helpers/external_signer/signing_queue.rs index 9bbc778ece..00a459a869 100644 --- a/rpc/src/v1/helpers/external_signer/signing_queue.rs +++ b/rpc/src/v1/helpers/external_signer/signing_queue.rs @@ -121,7 +121,7 @@ impl ConfirmationsQueue { )); // notify confirmation receiver about resolution - let result = result.ok_or(errors::request_rejected()); + let result = result.ok_or_else(errors::request_rejected); sender.sender.send(result); Some(sender.request) @@ -150,7 +150,7 @@ impl SigningQueue for ConfirmationsQueue { // Increment id let id = { let mut last_id = self.id.lock(); - *last_id = *last_id + U256::from(1); + *last_id += U256::from(1); *last_id }; // Add request to queue diff --git a/rpc/src/v1/helpers/fake_sign.rs b/rpc/src/v1/helpers/fake_sign.rs index 76d37aab2f..9f9b7c8ed6 100644 --- a/rpc/src/v1/helpers/fake_sign.rs +++ b/rpc/src/v1/helpers/fake_sign.rs @@ -24,16 +24,16 @@ pub fn sign_call(request: CallRequest) -> Result { let max_gas = U256::from(50_000_000); let gas = match request.gas { Some(gas) => gas, - None => max_gas * 10u32, + None => max_gas * 10_u32, }; - let from = request.from.unwrap_or(0.into()); + let from = request.from.unwrap_or_default(); Ok(Transaction { - nonce: request.nonce.unwrap_or_else(|| 0.into()), + nonce: request.nonce.unwrap_or_default(), action: request.to.map_or(Action::Create, Action::Call), gas, - gas_price: request.gas_price.unwrap_or_else(|| 0.into()), - value: request.value.unwrap_or(0.into()), + gas_price: request.gas_price.unwrap_or_default(), + value: request.value.unwrap_or_default(), data: request.data.unwrap_or_default(), }.fake_sign(from)) } diff --git a/rpc/src/v1/helpers/ipfs.rs b/rpc/src/v1/helpers/ipfs.rs index 928362cf89..93110dbf34 100644 --- a/rpc/src/v1/helpers/ipfs.rs +++ b/rpc/src/v1/helpers/ipfs.rs @@ -28,5 +28,5 @@ pub fn cid(content: Bytes) -> Result { let hash = digest::sha256(&content.0); let mh = multihash::encode(multihash::Hash::SHA2256, &*hash).map_err(errors::encoding)?; let cid = Cid::new(Codec::DagProtobuf, Version::V0, &mh); - Ok(cid.to_string().into()) + Ok(cid.to_string()) } diff --git a/rpc/src/v1/helpers/light_fetch.rs b/rpc/src/v1/helpers/light_fetch.rs index 3ac17c2fd8..3d19e3fa86 100644 --- a/rpc/src/v1/helpers/light_fetch.rs +++ b/rpc/src/v1/helpers/light_fetch.rs @@ -121,7 +121,7 @@ pub fn extract_transaction_at_index(block: encoded::Block, index: usize) -> Opti cached_sender, } }) - .map(|tx| Transaction::from_localized(tx)) + .map(Transaction::from_localized) } // extract the header indicated by the given `HeaderRef` from the given responses. @@ -159,7 +159,7 @@ where let idx = reqs.len(); let hash_ref = Field::back_ref(idx, 0); reqs.push(req.into()); - reqs.push(request::HeaderByHash(hash_ref.clone()).into()); + reqs.push(request::HeaderByHash(hash_ref).into()); Ok(HeaderRef::Unresolved(idx + 1, hash_ref)) } @@ -197,7 +197,7 @@ where Err(e) => return Either::A(future::err(e)), }; - reqs.push(request::Account { header: header_ref.clone(), address: address }.into()); + reqs.push(request::Account { header: header_ref.clone(), address }.into()); let account_idx = reqs.len() - 1; reqs.push(request::Code { header: header_ref, code_hash: Field::back_ref(account_idx, 0) }.into()); @@ -216,7 +216,7 @@ where Err(e) => return Either::A(future::err(e)), }; - reqs.push(request::Account { header: header_ref, address: address }.into()); + reqs.push(request::Account { header: header_ref, address }.into()); Either::B(self.send_requests(reqs, |mut res|match res.pop() { Some(OnDemandResponse::Account(acc)) => acc, @@ -246,7 +246,7 @@ where } }; - let from = req.from.unwrap_or_else(|| Address::zero()); + let from = req.from.unwrap_or_default(); let nonce_fut = match req.nonce { Some(nonce) => Either::A(future::ok(Some(nonce))), None => Either::B(self.account(from, id).map(|acc| acc.map(|a| a.nonce))), @@ -370,10 +370,10 @@ where for (transaction_log_index, log) in receipt.logs.into_iter().enumerate() { if filter.matches(&log) { matches.insert((num, block_index), Log { - address: log.address.into(), + address: log.address, topics: log.topics.into_iter().map(Into::into).collect(), data: log.data.into(), - block_hash: Some(hash.into()), + block_hash: Some(hash), block_number: Some(num.into()), // No way to easily retrieve transaction hash, so let's just skip it. transaction_hash: None, @@ -410,8 +410,8 @@ where let mut blocks = BTreeMap::new(); for log in result.iter() { let block_hash = log.block_hash.as_ref().expect("Previously initialized with value; qed"); - blocks.entry(block_hash.clone()).or_insert_with(|| { - fetcher_block.block(BlockId::Hash(block_hash.clone().into())) + blocks.entry(*block_hash).or_insert_with(|| { + fetcher_block.block(BlockId::Hash(*block_hash)) }); } // future get blocks (unordered it) @@ -419,12 +419,12 @@ where let transactions_per_block: BTreeMap<_, _> = blocks.iter() .map(|block| (block.hash(), block.transactions())).collect(); for log in result.iter_mut() { - let log_index: U256 = log.transaction_index.expect("Previously initialized with value; qed").into(); - let block_hash = log.block_hash.clone().expect("Previously initialized with value; qed").into(); + let log_index = log.transaction_index.expect("Previously initialized with value; qed"); + let block_hash = log.block_hash.expect("Previously initialized with value; qed"); let tx_hash = transactions_per_block.get(&block_hash) // transaction index is from an enumerate call in log common so not need to check value .and_then(|txs| txs.get(log_index.as_usize())) - .map(|tr| tr.hash().into()); + .map(types::transaction::UnverifiedTransaction::hash); log.transaction_hash = tx_hash; } result @@ -442,7 +442,7 @@ where Box::new(future::loop_fn(params, move |(sync, on_demand)| { let maybe_future = sync.with_context(|ctx| { - let req = request::TransactionIndex(tx_hash.clone().into()); + let req = request::TransactionIndex(tx_hash.into()); on_demand.request(ctx, req) }); @@ -468,7 +468,7 @@ where let index = index.index as usize; let transaction = extract_transaction_at_index(blk, index); - if transaction.as_ref().map_or(true, |tx| tx.hash != tx_hash.into()) { + if transaction.as_ref().map_or(true, |tx| tx.hash != tx_hash) { // index is actively wrong: indicated block has // fewer transactions than necessary or the transaction // at that index had a different hash. @@ -522,7 +522,7 @@ where ) -> impl Future, Error = Error> { let fetch_hashes = [from_block, to_block].iter() .filter_map(|block_id| match block_id { - BlockId::Hash(hash) => Some(hash.clone()), + BlockId::Hash(hash) => Some(*hash), _ => None, }) .collect::>(); @@ -533,14 +533,14 @@ where self.headers_by_hash(&fetch_hashes[..]).and_then(move |mut header_map| { let (from_block_num, to_block_num) = { let block_number = |id| match id { - &BlockId::Earliest => 0, - &BlockId::Latest => best_number, - &BlockId::Hash(ref h) => - header_map.get(h).map(|hdr| hdr.number()) + BlockId::Earliest => 0, + BlockId::Latest => best_number, + BlockId::Hash(ref h) => + header_map.get(h).map(types::encoded::Header::number) .expect("from_block and to_block headers are fetched by hash; this closure is only called on from_block and to_block; qed"), - &BlockId::Number(x) => x, + BlockId::Number(x) => x, }; - (block_number(&from_block), block_number(&to_block)) + (block_number(from_block), block_number(to_block)) }; if to_block_num < from_block_num { @@ -557,7 +557,7 @@ where let headers_fut = fetcher.headers_range(from_block_num, to_block_num, to_header_hint); Either::B(headers_fut.map(move |headers| { // Validate from_block if it's a hash - let last_hash = headers.last().map(|hdr| hdr.hash()); + let last_hash = headers.last().map(types::encoded::Header::hash); match (last_hash, from_block) { (Some(h1), BlockId::Hash(h2)) if h1 != h2 => Vec::new(), _ => headers, @@ -578,15 +578,13 @@ where } self.send_requests(reqs, move |res| { - let headers = refs.drain() - .map(|(hash, header_ref)| { + refs.into_iter().map(|(hash, header_ref)| { let hdr = extract_header(&res, header_ref) .expect("these responses correspond to requests that header_ref belongs to; \ qed"); (hash, hdr) - }) - .collect(); - headers + }) + .collect() }) } @@ -678,7 +676,7 @@ where { fn clone(&self) -> Self { Self { - from: self.from.clone(), + from: self.from, tx: self.tx.clone(), hdr: self.hdr.clone(), env_info: self.env_info.clone(), @@ -719,7 +717,7 @@ where required, got); if required <= params.hdr.gas_limit() { params.tx.gas = required; - return Ok(future::Loop::Continue(params)) + Ok(future::Loop::Continue(params)) } else { warn!(target: "light_fetch", "Required gas is bigger than block header's gas dropping the request"); diff --git a/rpc/src/v1/helpers/signature.rs b/rpc/src/v1/helpers/signature.rs index 32827ea1e1..b191a3737e 100644 --- a/rpc/src/v1/helpers/signature.rs +++ b/rpc/src/v1/helpers/signature.rs @@ -45,7 +45,7 @@ pub fn verify_signature( let v = if v >= 35 { (v - 1) % 2 } else { v }; - let signature = Signature::from_rsv(&r.into(), &s.into(), v as u8); + let signature = Signature::from_rsv(&r, &s, v as u8); let public_key = recover(&signature, &hash).map_err(errors::encryption)?; let address = public_to_address(&public_key); Ok(RecoveredAccount { address, public_key, is_valid_for_current_chain }) diff --git a/rpc/src/v1/helpers/subscription_manager.rs b/rpc/src/v1/helpers/subscription_manager.rs index 4f50cad423..d83beb397f 100644 --- a/rpc/src/v1/helpers/subscription_manager.rs +++ b/rpc/src/v1/helpers/subscription_manager.rs @@ -52,7 +52,7 @@ impl> GenericPollManager { pub fn new(rpc: MetaIoHandler) -> Self { GenericPollManager { subscribers: Default::default(), - rpc: rpc, + rpc, } } diff --git a/rpc/src/v1/helpers/work.rs b/rpc/src/v1/helpers/work.rs index 661b4cab8b..b52cb70c5f 100644 --- a/rpc/src/v1/helpers/work.rs +++ b/rpc/src/v1/helpers/work.rs @@ -29,15 +29,10 @@ pub fn submit_work_detail(client: &Arc, // TODO [ToDr] Should disallow submissions in case of PoA? trace!(target: "miner", "submit_work_detail: Decoded: nonce={}, pow_hash={}, mix_hash={}", nonce, pow_hash, mix_hash); let seal = vec![rlp::encode(&mix_hash), rlp::encode(&nonce)]; - let import = miner.submit_seal(pow_hash, seal) - .and_then(|block| client.import_sealed_block(block)); - match import { - Ok(hash) => { - Ok(hash.into()) - }, - Err(err) => { - warn!(target: "miner", "Cannot submit work - {:?}.", err); - Err(errors::cannot_submit_work(err)) - }, - } + miner.submit_seal(pow_hash, seal) + .and_then(|block| client.import_sealed_block(block)) + .map_err(|e| { + warn!(target: "miner", "Cannot submit work - {:?}.", e); + errors::cannot_submit_work(e) + }) } diff --git a/rpc/src/v1/impls/debug.rs b/rpc/src/v1/impls/debug.rs index abec9b1f87..e46dd628d1 100644 --- a/rpc/src/v1/impls/debug.rs +++ b/rpc/src/v1/impls/debug.rs @@ -19,6 +19,7 @@ use std::sync::Arc; use ethcore::client::BlockChainClient; +use types::header::Header; use types::transaction::LocalizedTransaction; use jsonrpc_core::Result; @@ -50,7 +51,7 @@ impl Debug for DebugClient { let hash = block.header.hash(); RichBlock { inner: Block { - hash: Some(hash.into()), + hash: Some(hash), size: Some(block.bytes.len().into()), parent_hash: cast(block.header.parent_hash()), uncles_hash: cast(block.header.uncles_hash()), @@ -65,14 +66,14 @@ impl Debug for DebugClient { timestamp: block.header.timestamp().into(), difficulty: cast(block.header.difficulty()), total_difficulty: None, - seal_fields: block.header.seal().into_iter().cloned().map(Into::into).collect(), - uncles: block.uncles.into_iter().map(|u| u.hash().into()).collect(), + seal_fields: block.header.seal().iter().cloned().map(Into::into).collect(), + uncles: block.uncles.iter().map(Header::hash).collect(), transactions: BlockTransactions::Full(block.transactions .into_iter() .enumerate() .map(|(transaction_index, signed)| Transaction::from_localized(LocalizedTransaction { - block_number: number.into(), - block_hash: hash.into(), + block_number: number, + block_hash: hash, transaction_index, signed, cached_sender: None, diff --git a/rpc/src/v1/impls/eth.rs b/rpc/src/v1/impls/eth.rs index 31b8be10c2..1b5fdf447f 100644 --- a/rpc/src/v1/impls/eth.rs +++ b/rpc/src/v1/impls/eth.rs @@ -197,7 +197,7 @@ impl EthClient EthClient None, - false => Some(view.hash().into()), + false => Some(view.hash()), }, size: Some(block.rlp().as_raw().len().into()), - parent_hash: view.parent_hash().into(), - uncles_hash: view.uncles_hash().into(), - author: view.author().into(), - miner: view.author().into(), - state_root: view.state_root().into(), - transactions_root: view.transactions_root().into(), - receipts_root: view.receipts_root().into(), + parent_hash: view.parent_hash(), + uncles_hash: view.uncles_hash(), + author: view.author(), + miner: view.author(), + state_root: view.state_root(), + transactions_root: view.transactions_root(), + receipts_root: view.receipts_root(), number: match is_pending { true => None, false => Some(view.number().into()), }, - gas_used: view.gas_used().into(), - gas_limit: view.gas_limit().into(), + gas_used: view.gas_used(), + gas_limit: view.gas_limit(), logs_bloom: match is_pending { true => None, - false => Some(view.log_bloom().into()), + false => Some(view.log_bloom()), }, timestamp: view.timestamp().into(), - difficulty: view.difficulty().into(), - total_difficulty: Some(total_difficulty.into()), + difficulty: view.difficulty(), + total_difficulty: Some(total_difficulty), seal_fields: view.seal().into_iter().map(Into::into).collect(), - uncles: block.uncle_hashes().into_iter().map(Into::into).collect(), + uncles: block.uncle_hashes(), transactions: match include_txs { - true => BlockTransactions::Full(block.view().localized_transactions().into_iter().map(|t| Transaction::from_localized(t)).collect()), - false => BlockTransactions::Hashes(block.transaction_hashes().into_iter().map(Into::into).collect()), + true => BlockTransactions::Full(block.view().localized_transactions().into_iter().map(Transaction::from_localized).collect()), + false => BlockTransactions::Hashes(block.transaction_hashes()), }, extra_data: Bytes::new(view.extra_data()), }, @@ -334,7 +334,7 @@ impl EthClient EthClient { return Ok(None); } }; - let parent_difficulty = match client.block_total_difficulty(BlockId::Hash(uncle.parent_hash().clone())) { + let parent_difficulty = match client.block_total_difficulty(BlockId::Hash(*uncle.parent_hash())) { Some(difficulty) => difficulty, None => { return Ok(None); } }; @@ -398,29 +398,28 @@ impl EthClient(miner: &M, best_block: EthBlockNumber, filter: &EthcoreFi .filter(|pair| filter.matches(&pair.1)) .map(|pair| { let mut log = Log::from(pair.1); - log.transaction_hash = Some(pair.0.into()); + log.transaction_hash = Some(pair.0); log }) .collect() @@ -518,8 +517,8 @@ impl Eth for EthClient< let info = SyncInfo { starting_block: status.start_block_number.into(), - current_block: current_block.into(), - highest_block: highest_block.into(), + current_block, + highest_block, warp_chunks_amount: warp_chunks_amount.map(|x| U256::from(x as u64)).map(Into::into), warp_chunks_processed: warp_chunks_processed.map(|x| U256::from(x as u64)).map(Into::into), }; @@ -535,10 +534,9 @@ impl Eth for EthClient< (self.accounts)() .first() .cloned() - .map(From::from) .ok_or_else(|| errors::account("No accounts were found", "")) } else { - Ok(H160::from(miner)) + Ok(miner) } } @@ -551,18 +549,18 @@ impl Eth for EthClient< } fn hashrate(&self) -> Result { - Ok(U256::from(self.external_miner.hashrate())) + Ok(self.external_miner.hashrate()) } fn gas_price(&self) -> Result { - Ok(U256::from(default_gas_price(&*self.client, &*self.miner, self.options.gas_price_percentile))) + Ok(default_gas_price(&*self.client, &*self.miner, self.options.gas_price_percentile)) } fn accounts(&self) -> Result> { self.deprecation_notice.print("eth_accounts", deprecated::msgs::ACCOUNTS); let accounts = (self.accounts)(); - Ok(accounts.into_iter().map(Into::into).collect()) + Ok(accounts) } fn block_number(&self) -> Result { @@ -574,7 +572,7 @@ impl Eth for EthClient< try_bf!(check_known(&*self.client, num.clone())); let res = match self.client.balance(&address, self.get_state(num)) { - Some(balance) => Ok(balance.into()), + Some(balance) => Ok(balance), None => Err(errors::state_pruned()), }; @@ -600,16 +598,16 @@ impl Eth for EthClient< try_bf!(check_known(&*self.client, num.clone())); let res = match self.client.prove_account(key1, id) { Some((proof, account)) => Ok(EthAccount { - address: address, - balance: account.balance.into(), - nonce: account.nonce.into(), - code_hash: account.code_hash.into(), - storage_hash: account.storage_root.into(), + address, + balance: account.balance, + nonce: account.nonce, + code_hash: account.code_hash, + storage_hash: account.storage_root, account_proof: proof.into_iter().map(Bytes::new).collect(), storage_proof: values.into_iter().filter_map(|storage_index| { - let key2: H256 = storage_index.into(); + let key2: H256 = storage_index; self.client.prove_storage(key1, keccak(key2), id) - .map(|(storage_proof,storage_value)| StorageProof { + .map(|(storage_proof, storage_value)| StorageProof { key: key2.into(), value: storage_value.into(), proof: storage_proof.into_iter().map(Bytes::new).collect() @@ -624,12 +622,11 @@ impl Eth for EthClient< } fn storage_at(&self, address: H160, position: U256, num: Option) -> BoxFuture { - let address: Address = address.into(); let num = num.unwrap_or_default(); try_bf!(check_known(&*self.client, num.clone())); let res = match self.client.storage_at(&address, &H256::from(position), self.get_state(num)) { - Some(s) => Ok(s.into()), + Some(s) => Ok(s), None => Err(errors::state_pruned()), }; @@ -637,11 +634,9 @@ impl Eth for EthClient< } fn transaction_count(&self, address: H160, num: Option) -> BoxFuture { - let address: Address = address.into(); - let res = match num.unwrap_or_default() { BlockNumber::Pending if self.options.pending_nonce_from_queue => { - Ok(self.miner.next_nonce(&*self.client, &address).into()) + Ok(self.miner.next_nonce(&*self.client, &address)) } BlockNumber::Pending => { let info = self.client.chain_info(); @@ -654,14 +649,14 @@ impl Eth for EthClient< }); match nonce { - Some(nonce) => Ok(nonce.into()), + Some(nonce) => Ok(nonce), None => Err(errors::database("latest nonce missing")) } }, number => { try_bf!(check_known(&*self.client, number.clone())); match self.client.nonce(&address, block_number_to_id(number)) { - Some(nonce) => Ok(nonce.into()), + Some(nonce) => Ok(nonce), None => Err(errors::state_pruned()), } } @@ -671,7 +666,7 @@ impl Eth for EthClient< } fn block_transaction_count_by_hash(&self, hash: H256) -> BoxFuture> { - let trx_count = self.client.block(BlockId::Hash(hash.into())) + let trx_count = self.client.block(BlockId::Hash(hash)) .map(|block| block.transactions_count().into()); let result = Ok(trx_count) .and_then(errors::check_block_gap(&*self.client, self.options.allow_missing_blocks)); @@ -696,7 +691,7 @@ impl Eth for EthClient< } fn block_uncles_count_by_hash(&self, hash: H256) -> BoxFuture> { - let uncle_count = self.client.block(BlockId::Hash(hash.into())) + let uncle_count = self.client.block(BlockId::Hash(hash)) .map(|block| block.uncles_count().into()); let result = Ok(uncle_count) .and_then(errors::check_block_gap(&*self.client, self.options.allow_missing_blocks)); @@ -734,7 +729,7 @@ impl Eth for EthClient< } fn block_by_hash(&self, hash: H256, include_txs: bool) -> BoxFuture> { - let result = self.rich_block(BlockId::Hash(hash.into()).into(), include_txs) + let result = self.rich_block(BlockId::Hash(hash).into(), include_txs) .and_then(errors::check_block_gap(&*self.client, self.options.allow_missing_blocks)); Box::new(future::done(result)) } @@ -756,7 +751,7 @@ impl Eth for EthClient< } fn transaction_by_block_hash_and_index(&self, hash: H256, index: Index) -> BoxFuture> { - let id = PendingTransactionId::Location(PendingOrBlock::Block(BlockId::Hash(hash.into())), index.value()); + let id = PendingTransactionId::Location(PendingOrBlock::Block(BlockId::Hash(hash)), index.value()); let result = self.transaction(id).and_then( errors::check_block_gap(&*self.client, self.options.allow_missing_blocks)); Box::new(future::done(result)) @@ -792,7 +787,7 @@ impl Eth for EthClient< fn uncle_by_block_hash_and_index(&self, hash: H256, index: Index) -> BoxFuture> { let result = self.uncle(PendingUncleId { - id: PendingOrBlock::Block(BlockId::Hash(hash.into())), + id: PendingOrBlock::Block(BlockId::Hash(hash)), position: index.value() }).and_then(errors::check_block_gap(&*self.client, self.options.allow_missing_blocks)); Box::new(future::done(result)) @@ -822,7 +817,7 @@ impl Eth for EthClient< } fn logs(&self, filter: Filter) -> BoxFuture> { - base_logs(&*self.client, &*self.miner, filter.into()) + base_logs(&*self.client, &*self.miner, filter) } fn work(&self, no_new_work_timeout: Option) -> Result { @@ -865,16 +860,16 @@ impl Eth for EthClient< Err(errors::no_new_work()) } else if self.options.send_block_number_in_get_work { Ok(Work { - pow_hash: pow_hash.into(), + pow_hash, seed_hash: seed_hash.into(), - target: target.into(), + target, number: Some(number), }) } else { Ok(Work { - pow_hash: pow_hash.into(), + pow_hash, seed_hash: seed_hash.into(), - target: target.into(), + target, number: None }) } @@ -888,7 +883,7 @@ impl Eth for EthClient< } fn submit_hashrate(&self, rate: U256, id: H256) -> Result { - self.external_miner.submit_hashrate(rate.into(), id.into()); + self.external_miner.submit_hashrate(rate, id); Ok(true) } @@ -919,8 +914,8 @@ impl Eth for EthClient< let (mut state, header) = if num == BlockNumber::Pending { let info = self.client.chain_info(); - let state = try_bf!(self.miner.pending_state(info.best_block_number).ok_or(errors::state_pruned())); - let header = try_bf!(self.miner.pending_block_header(info.best_block_number).ok_or(errors::state_pruned())); + let state = try_bf!(self.miner.pending_state(info.best_block_number).ok_or_else(errors::state_pruned)); + let header = try_bf!(self.miner.pending_block_header(info.best_block_number).ok_or_else(errors::state_pruned)); (state, header) } else { @@ -931,8 +926,8 @@ impl Eth for EthClient< BlockNumber::Pending => unreachable!(), // Already covered }; - let state = try_bf!(self.client.state_at(id).ok_or(errors::state_pruned())); - let header = try_bf!(self.client.block_header(id).ok_or(errors::state_pruned()).and_then(|h| h.decode().map_err(errors::decode))); + let state = try_bf!(self.client.state_at(id).ok_or_else(errors::state_pruned)); + let header = try_bf!(self.client.block_header(id).ok_or_else(errors::state_pruned).and_then(|h| h.decode().map_err(errors::decode))); (state, header) }; @@ -958,8 +953,10 @@ impl Eth for EthClient< let (state, header) = if num == BlockNumber::Pending { let info = self.client.chain_info(); - let state = try_bf!(self.miner.pending_state(info.best_block_number).ok_or(errors::state_pruned())); - let header = try_bf!(self.miner.pending_block_header(info.best_block_number).ok_or(errors::state_pruned())); + let state = try_bf!(self.miner.pending_state(info.best_block_number) + .ok_or_else(errors::state_pruned)); + let header = try_bf!(self.miner.pending_block_header(info.best_block_number) + .ok_or_else(errors::state_pruned)); (state, header) } else { @@ -970,14 +967,15 @@ impl Eth for EthClient< BlockNumber::Pending => unreachable!(), // Already covered }; - let state = try_bf!(self.client.state_at(id).ok_or(errors::state_pruned())); - let header = try_bf!(self.client.block_header(id).ok_or(errors::state_pruned()).and_then(|h| h.decode().map_err(errors::decode))); - + let state = try_bf!(self.client.state_at(id) + .ok_or_else(errors::state_pruned)); + let header = try_bf!(self.client.block_header(id) + .ok_or_else(errors::state_pruned) + .and_then(|h| h.decode().map_err(errors::decode))); (state, header) }; Box::new(future::done(self.client.estimate_gas(&signed, &state, &header) - .map(Into::into) .map_err(errors::call) )) } diff --git a/rpc/src/v1/impls/eth_filter.rs b/rpc/src/v1/impls/eth_filter.rs index f8d4d29022..c51c85fb62 100644 --- a/rpc/src/v1/impls/eth_filter.rs +++ b/rpc/src/v1/impls/eth_filter.rs @@ -68,8 +68,8 @@ impl EthFilterClient { /// Creates new Eth filter client. pub fn new(client: Arc, miner: Arc, poll_lifetime: u32) -> Self { EthFilterClient { - client: client, - miner: miner, + client, + miner, polls: Mutex::new(PollManager::new(poll_lifetime)), } } @@ -188,17 +188,14 @@ impl EthFilter for T { let mut hashes = Vec::new(); for n in (*last_block_number + 1)..=current_number { let block_number = BlockId::Number(n); - match self.block_hash(block_number) { - Some(hash) => { - *last_block_number = n; - hashes.push(H256::from(hash)); - // Only keep the most recent history - if recent_reported_hashes.len() >= PollFilter::MAX_BLOCK_HISTORY_SIZE { - recent_reported_hashes.pop_back(); - } - recent_reported_hashes.push_front((n, hash)); - }, - None => (), + if let Some(hash) = self.block_hash(block_number) { + *last_block_number = n; + hashes.push(hash); + // Only keep the most recent history + if recent_reported_hashes.len() >= PollFilter::MAX_BLOCK_HISTORY_SIZE { + recent_reported_hashes.pop_back(); + } + recent_reported_hashes.push_front((n, hash)); } } diff --git a/rpc/src/v1/impls/eth_pubsub.rs b/rpc/src/v1/impls/eth_pubsub.rs index b4baf5aa4d..91f32827b1 100644 --- a/rpc/src/v1/impls/eth_pubsub.rs +++ b/rpc/src/v1/impls/eth_pubsub.rs @@ -134,10 +134,10 @@ impl ChainNotificationHandler { fn notify_heads(&self, headers: &[(encoded::Header, BTreeMap)]) { for subscriber in self.heads_subscribers.read().values() { for &(ref header, ref extra_info) in headers { - Self::notify(&self.executor, subscriber, pubsub::Result::Header(RichHeader { + Self::notify(&self.executor, subscriber, pubsub::Result::Header(Box::new(RichHeader { inner: header.into(), extra_info: extra_info.clone(), - })); + }))); } } } @@ -154,7 +154,7 @@ impl ChainNotificationHandler { .map(|&(hash, ref ex)| { let mut filter = filter.clone(); filter.from_block = BlockId::Hash(hash); - filter.to_block = filter.from_block.clone(); + filter.to_block = filter.from_block; logs(filter, ex).into_future() }) .collect::>() @@ -167,7 +167,7 @@ impl ChainNotificationHandler { let logs = logs.into_iter().flat_map(|log| log).collect(); for log in limit_logs(logs, limit) { - Self::notify(&executor, &subscriber, pubsub::Result::Log(log)) + Self::notify(&executor, &subscriber, pubsub::Result::Log(Box::new(log))) } }) .map_err(|e| warn!("Unable to fetch latest logs: {:?}", e)) @@ -179,7 +179,7 @@ impl ChainNotificationHandler { pub fn notify_new_transactions(&self, hashes: &[H256]) { for subscriber in self.transactions_subscribers.read().values() { for hash in hashes { - Self::notify(&self.executor, subscriber, pubsub::Result::TransactionHash((*hash).into())); + Self::notify(&self.executor, subscriber, pubsub::Result::TransactionHash(*hash)); } } } @@ -223,13 +223,13 @@ impl LightChainNotify for ChainNotificationHandler { impl ChainNotify for ChainNotificationHandler { fn new_blocks(&self, new_blocks: NewBlocks) { if self.heads_subscribers.read().is_empty() && self.logs_subscribers.read().is_empty() { return } - const EXTRA_INFO_PROOF: &'static str = "Object exists in in blockchain (fetched earlier), extra_info is always available if object exists; qed"; + const EXTRA_INFO_PROOF: &str = "Object exists in in blockchain (fetched earlier), extra_info is always available if object exists; qed"; let headers = new_blocks.route.route() .iter() .filter_map(|&(hash, ref typ)| { match typ { - &ChainRouteType::Retracted => None, - &ChainRouteType::Enacted => self.client.block_header(BlockId::Hash(hash)) + ChainRouteType::Retracted => None, + ChainRouteType::Enacted => self.client.block_header(BlockId::Hash(hash)) } }) .map(|header| { @@ -244,9 +244,9 @@ impl ChainNotify for ChainNotificationHandler { // We notify logs enacting and retracting as the order in route. self.notify_logs(new_blocks.route.route(), |filter, ex| { match ex { - &ChainRouteType::Enacted => + ChainRouteType::Enacted => Ok(self.client.logs(filter).unwrap_or_default().into_iter().map(Into::into).collect()), - &ChainRouteType::Retracted => + ChainRouteType::Retracted => Ok(self.client.logs(filter).unwrap_or_default().into_iter().map(Into::into).map(|mut log: Log| { log.log_type = "removed".into(); log.removed = true; @@ -267,7 +267,7 @@ impl EthPubSub for EthPubSubClient { kind: pubsub::Kind, params: Option, ) { - let error = match (kind, params.into()) { + let error = match (kind, params) { (pubsub::Kind::NewHeads, None) => { self.heads_subscribers.write().push(subscriber); return; diff --git a/rpc/src/v1/impls/light/eth.rs b/rpc/src/v1/impls/light/eth.rs index 909d4c2443..fa972c5d60 100644 --- a/rpc/src/v1/impls/light/eth.rs +++ b/rpc/src/v1/impls/light/eth.rs @@ -142,23 +142,23 @@ where let extra_info = engine.extra_info(&header); RichBlock { inner: Block { - hash: Some(header.hash().into()), + hash: Some(header.hash()), size: Some(block.rlp().as_raw().len().into()), - parent_hash: header.parent_hash().clone().into(), - uncles_hash: header.uncles_hash().clone().into(), - author: header.author().clone().into(), - miner: header.author().clone().into(), - state_root: header.state_root().clone().into(), - transactions_root: header.transactions_root().clone().into(), - receipts_root: header.receipts_root().clone().into(), + parent_hash: *header.parent_hash(), + uncles_hash: *header.uncles_hash(), + author: *header.author(), + miner: *header.author(), + state_root: *header.state_root(), + transactions_root: *header.transactions_root(), + receipts_root: *header.receipts_root(), number: Some(header.number().into()), - gas_used: header.gas_used().clone().into(), - gas_limit: header.gas_limit().clone().into(), - logs_bloom: Some(header.log_bloom().clone().into()), + gas_used: *header.gas_used(), + gas_limit: *header.gas_limit(), + logs_bloom: Some(*header.log_bloom()), timestamp: header.timestamp().into(), - difficulty: header.difficulty().clone().into(), + difficulty: *header.difficulty(), total_difficulty: score.map(Into::into), - seal_fields: header.seal().into_iter().cloned().map(Into::into).collect(), + seal_fields: header.seal().iter().cloned().map(Into::into).collect(), uncles: block.uncle_hashes().into_iter().map(Into::into).collect(), transactions: match include_txs { true => BlockTransactions::Full(block.view().localized_transactions().into_iter().map(Transaction::from_localized).collect()), @@ -166,7 +166,7 @@ where }, extra_data: Bytes::new(header.extra_data().clone()), }, - extra_info: extra_info + extra_info, } }; @@ -237,9 +237,9 @@ where .unwrap_or_else(|| current_block); Ok(RpcSyncStatus::Info(RpcSyncInfo { - starting_block: U256::from(self.sync.start_block()).into(), - current_block: current_block.into(), - highest_block: highest_block.into(), + starting_block: U256::from(self.sync.start_block()), + current_block, + highest_block, warp_chunks_amount: None, warp_chunks_processed: None, })) @@ -289,8 +289,8 @@ where } fn balance(&self, address: H160, num: Option) -> BoxFuture { - Box::new(self.fetcher().account(address.into(), num.unwrap_or_default().to_block_id()) - .map(|acc| acc.map_or(0.into(), |a| a.balance).into())) + Box::new(self.fetcher().account(address, num.unwrap_or_default().to_block_id()) + .map(|acc| acc.map_or(0.into(), |a| a.balance))) } fn storage_at(&self, _address: H160, _key: U256, _num: Option) -> BoxFuture { @@ -298,7 +298,7 @@ where } fn block_by_hash(&self, hash: H256, include_txs: bool) -> BoxFuture> { - Box::new(self.rich_block(BlockId::Hash(hash.into()), include_txs).map(Some)) + Box::new(self.rich_block(BlockId::Hash(hash), include_txs).map(Some)) } fn block_by_number(&self, num: BlockNumber, include_txs: bool) -> BoxFuture> { @@ -306,20 +306,20 @@ where } fn transaction_count(&self, address: H160, num: Option) -> BoxFuture { - Box::new(self.fetcher().account(address.into(), num.unwrap_or_default().to_block_id()) - .map(|acc| acc.map_or(0.into(), |a| a.nonce).into())) + Box::new(self.fetcher().account(address, num.unwrap_or_default().to_block_id()) + .map(|acc| acc.map_or(0.into(), |a| a.nonce))) } fn block_transaction_count_by_hash(&self, hash: H256) -> BoxFuture> { let (sync, on_demand) = (self.sync.clone(), self.on_demand.clone()); - Box::new(self.fetcher().header(BlockId::Hash(hash.into())).and_then(move |hdr| { + Box::new(self.fetcher().header(BlockId::Hash(hash)).and_then(move |hdr| { if hdr.transactions_root() == KECCAK_NULL_RLP { - Either::A(future::ok(Some(U256::from(0).into()))) + Either::A(future::ok(Some(U256::from(0)))) } else { sync.with_context(|ctx| on_demand.request(ctx, request::Body(hdr.into()))) .map(|x| x.expect(NO_INVALID_BACK_REFS)) - .map(|x| x.map(|b| Some(U256::from(b.transactions_count()).into()))) + .map(|x| x.map(|b| Some(U256::from(b.transactions_count())))) .map(|x| Either::B(x.map_err(errors::on_demand_error))) .unwrap_or_else(|| Either::A(future::err(errors::network_disabled()))) } @@ -331,11 +331,11 @@ where Box::new(self.fetcher().header(num.to_block_id()).and_then(move |hdr| { if hdr.transactions_root() == KECCAK_NULL_RLP { - Either::A(future::ok(Some(U256::from(0).into()))) + Either::A(future::ok(Some(U256::from(0)))) } else { sync.with_context(|ctx| on_demand.request(ctx, request::Body(hdr.into()))) .map(|x| x.expect(NO_INVALID_BACK_REFS)) - .map(|x| x.map(|b| Some(U256::from(b.transactions_count()).into()))) + .map(|x| x.map(|b| Some(U256::from(b.transactions_count())))) .map(|x| Either::B(x.map_err(errors::on_demand_error))) .unwrap_or_else(|| Either::A(future::err(errors::network_disabled()))) } @@ -345,13 +345,13 @@ where fn block_uncles_count_by_hash(&self, hash: H256) -> BoxFuture> { let (sync, on_demand) = (self.sync.clone(), self.on_demand.clone()); - Box::new(self.fetcher().header(BlockId::Hash(hash.into())).and_then(move |hdr| { + Box::new(self.fetcher().header(BlockId::Hash(hash)).and_then(move |hdr| { if hdr.uncles_hash() == KECCAK_EMPTY_LIST_RLP { - Either::A(future::ok(Some(U256::from(0).into()))) + Either::A(future::ok(Some(U256::from(0)))) } else { sync.with_context(|ctx| on_demand.request(ctx, request::Body(hdr.into()))) .map(|x| x.expect(NO_INVALID_BACK_REFS)) - .map(|x| x.map(|b| Some(U256::from(b.uncles_count()).into()))) + .map(|x| x.map(|b| Some(U256::from(b.uncles_count())))) .map(|x| Either::B(x.map_err(errors::on_demand_error))) .unwrap_or_else(|| Either::A(future::err(errors::network_disabled()))) } @@ -363,11 +363,11 @@ where Box::new(self.fetcher().header(num.to_block_id()).and_then(move |hdr| { if hdr.uncles_hash() == KECCAK_EMPTY_LIST_RLP { - Either::B(future::ok(Some(U256::from(0).into()))) + Either::B(future::ok(Some(U256::from(0)))) } else { sync.with_context(|ctx| on_demand.request(ctx, request::Body(hdr.into()))) .map(|x| x.expect(NO_INVALID_BACK_REFS)) - .map(|x| x.map(|b| Some(U256::from(b.uncles_count()).into()))) + .map(|x| x.map(|b| Some(U256::from(b.uncles_count())))) .map(|x| Either::A(x.map_err(errors::on_demand_error))) .unwrap_or_else(|| Either::B(future::err(errors::network_disabled()))) } @@ -375,7 +375,7 @@ where } fn code_at(&self, address: H160, num: Option) -> BoxFuture { - Box::new(self.fetcher().code(address.into(), num.unwrap_or_default().to_block_id()).map(Into::into)) + Box::new(self.fetcher().code(address, num.unwrap_or_default().to_block_id()).map(Into::into)) } fn send_raw_transaction(&self, raw: Bytes) -> Result { @@ -414,15 +414,13 @@ where // TODO: binary chop for more accurate estimates. Box::new(self.fetcher().proved_read_only_execution(req, num).and_then(|res| { match res { - Ok(exec) => Ok((exec.refunded + exec.gas_used).into()), + Ok(exec) => Ok(exec.refunded + exec.gas_used), Err(e) => Err(errors::execution(e)), } })) } fn transaction_by_hash(&self, hash: H256) -> BoxFuture> { - let hash = hash.into(); - { let tx_queue = self.transaction_queue.read(); if let Some(tx) = tx_queue.get(&hash) { @@ -436,7 +434,7 @@ where } fn transaction_by_block_hash_and_index(&self, hash: H256, idx: Index) -> BoxFuture> { - Box::new(self.fetcher().block(BlockId::Hash(hash.into())).map(move |block| { + Box::new(self.fetcher().block(BlockId::Hash(hash)).map(move |block| { light_fetch::extract_transaction_at_index(block, idx.value()) })) } @@ -449,14 +447,14 @@ where fn transaction_receipt(&self, hash: H256) -> BoxFuture> { let fetcher = self.fetcher(); - Box::new(fetcher.transaction_by_hash(hash.into()).and_then(move |tx| { + Box::new(fetcher.transaction_by_hash(hash).and_then(move |tx| { // the block hash included in the transaction object here has // already been checked for canonicality and whether it contains // the transaction. match tx { - Some((tx, index)) => match tx.block_hash.clone() { + Some((tx, index)) => match tx.block_hash { Some(block_hash) => { - let extract_receipt = fetcher.receipts(BlockId::Hash(block_hash.clone().into())) + let extract_receipt = fetcher.receipts(BlockId::Hash(block_hash)) .and_then(move |mut receipts| future::ok(receipts.swap_remove(index))) .map(Receipt::from) .map(move |mut receipt| { @@ -479,7 +477,7 @@ where fn uncle_by_block_hash_and_index(&self, hash: H256, idx: Index) -> BoxFuture> { let client = self.client.clone(); - Box::new(self.fetcher().block(BlockId::Hash(hash.into())).map(move |block| { + Box::new(self.fetcher().block(BlockId::Hash(hash)).map(move |block| { extract_uncle_at_index(block, idx, client) })) } @@ -576,27 +574,27 @@ fn extract_uncle_at_index(block: encoded::Block, index: Ind let extra_info = client.engine().extra_info(&uncle); Some(RichBlock { inner: Block { - hash: Some(uncle.hash().into()), + hash: Some(uncle.hash()), size: None, - parent_hash: uncle.parent_hash().clone().into(), - uncles_hash: uncle.uncles_hash().clone().into(), - author: uncle.author().clone().into(), - miner: uncle.author().clone().into(), - state_root: uncle.state_root().clone().into(), - transactions_root: uncle.transactions_root().clone().into(), + parent_hash: *uncle.parent_hash(), + uncles_hash: *uncle.uncles_hash(), + author: *uncle.author(), + miner: *uncle.author(), + state_root: *uncle.state_root(), + transactions_root: *uncle.transactions_root(), number: Some(uncle.number().into()), - gas_used: uncle.gas_used().clone().into(), - gas_limit: uncle.gas_limit().clone().into(), - logs_bloom: Some(uncle.log_bloom().clone().into()), + gas_used: *uncle.gas_used(), + gas_limit: *uncle.gas_limit(), + logs_bloom: Some(*uncle.log_bloom()), timestamp: uncle.timestamp().into(), - difficulty: uncle.difficulty().clone().into(), + difficulty: *uncle.difficulty(), total_difficulty: None, - receipts_root: uncle.receipts_root().clone().into(), + receipts_root: *uncle.receipts_root(), extra_data: uncle.extra_data().clone().into(), - seal_fields: uncle.seal().into_iter().cloned().map(Into::into).collect(), + seal_fields: uncle.seal().iter().cloned().map(Into::into).collect(), uncles: vec![], transactions: BlockTransactions::Hashes(vec![]), }, - extra_info: extra_info, + extra_info, }) } diff --git a/rpc/src/v1/impls/light/net.rs b/rpc/src/v1/impls/light/net.rs index 3f73e010b9..a9ab012e5a 100644 --- a/rpc/src/v1/impls/light/net.rs +++ b/rpc/src/v1/impls/light/net.rs @@ -29,7 +29,7 @@ impl NetClient where S: LightSyncProvider { /// Creates new NetClient. pub fn new(sync: Arc) -> Self { NetClient { - sync: sync, + sync, } } } diff --git a/rpc/src/v1/impls/light/parity.rs b/rpc/src/v1/impls/light/parity.rs index 24dba420e4..b6e378f680 100644 --- a/rpc/src/v1/impls/light/parity.rs +++ b/rpc/src/v1/impls/light/parity.rs @@ -140,7 +140,7 @@ where active: peer_numbers.active, connected: peer_numbers.connected, max: peer_numbers.max as u32, - peers: peers, + peers, }) } @@ -157,7 +157,7 @@ where if reg == Default::default() { Ok(None) } else { - Ok(Some(reg.into())) + Ok(Some(reg)) } } @@ -191,7 +191,7 @@ where } fn phrase_to_address(&self, phrase: String) -> Result { - Ok(Brain::new(phrase).generate().unwrap().address().into()) + Ok(Brain::new(phrase).generate().expect("Brain::generate always returns Ok; qed").address()) } fn list_accounts(&self, _: u64, _: Option, _: Option) -> Result>> { @@ -203,7 +203,7 @@ where } fn encrypt_message(&self, key: H512, phrase: Bytes) -> Result { - ecies::encrypt(&key.into(), &DEFAULT_MAC, &phrase.0) + ecies::encrypt(&key, &DEFAULT_MAC, &phrase.0) .map_err(errors::encryption) .map(Into::into) } @@ -215,7 +215,7 @@ where txq.ready_transactions(chain_info.best_block_number, chain_info.best_block_timestamp) .into_iter() .take(limit.unwrap_or_else(usize::max_value)) - .map(|tx| Transaction::from_pending(tx)) + .map(Transaction::from_pending) .collect::>() ) } @@ -223,7 +223,7 @@ where fn all_transactions(&self) -> Result> { Ok( light_all_transactions(&self.light_dispatch) - .map(|tx| Transaction::from_pending(tx)) + .map(Transaction::from_pending) .collect() ) } @@ -231,7 +231,7 @@ where fn all_transaction_hashes(&self) -> Result> { Ok( light_all_transactions(&self.light_dispatch) - .map(|tx| tx.transaction.hash().into()) + .map(|tx| tx.transaction.hash()) .collect() ) } @@ -242,7 +242,7 @@ where Ok( txq.future_transactions(chain_info.best_block_number, chain_info.best_block_timestamp) .into_iter() - .map(|tx| Transaction::from_pending(tx)) + .map(Transaction::from_pending) .collect::>() ) } @@ -250,7 +250,7 @@ where fn pending_transactions_stats(&self) -> Result> { let stats = self.light_dispatch.sync.transactions_stats(); Ok(stats.into_iter() - .map(|(hash, stats)| (hash.into(), stats.into())) + .map(|(hash, stats)| (hash, stats.into())) .collect() ) } @@ -262,11 +262,11 @@ where let txq = self.light_dispatch.transaction_queue.read(); for pending in txq.ready_transactions(best_num, best_tm) { - map.insert(pending.hash().into(), LocalTransactionStatus::Pending); + map.insert(pending.hash(), LocalTransactionStatus::Pending); } for future in txq.future_transactions(best_num, best_tm) { - map.insert(future.hash().into(), LocalTransactionStatus::Future); + map.insert(future.hash(), LocalTransactionStatus::Future); } // TODO: other types? @@ -276,11 +276,11 @@ where fn ws_url(&self) -> Result { helpers::to_url(&self.ws_address) - .ok_or_else(|| errors::ws_disabled()) + .ok_or_else(errors::ws_disabled) } fn next_nonce(&self, address: H160) -> BoxFuture { - Box::new(self.light_dispatch.next_nonce(address.into()).map(Into::into)) + Box::new(self.light_dispatch.next_nonce(address)) } fn mode(&self) -> Result { @@ -314,7 +314,7 @@ where .and_then(|first| chain_info.first_block_number.map(|last| (first, U256::from(last)))); Ok(ChainStatus { - block_gap: gap.map(|(x, y)| (x.into(), y.into())), + block_gap: gap, }) } @@ -336,25 +336,25 @@ where let extra_info = engine.extra_info(&header); Ok(RichHeader { inner: Header { - hash: Some(header.hash().into()), + hash: Some(header.hash()), size: Some(encoded.rlp().as_raw().len().into()), - parent_hash: header.parent_hash().clone().into(), - uncles_hash: header.uncles_hash().clone().into(), - author: header.author().clone().into(), - miner: header.author().clone().into(), - state_root: header.state_root().clone().into(), - transactions_root: header.transactions_root().clone().into(), - receipts_root: header.receipts_root().clone().into(), + parent_hash: *header.parent_hash(), + uncles_hash: *header.uncles_hash(), + author: *header.author(), + miner: *header.author(), + state_root: *header.state_root(), + transactions_root: *header.transactions_root(), + receipts_root: *header.receipts_root(), number: Some(header.number().into()), - gas_used: header.gas_used().clone().into(), - gas_limit: header.gas_limit().clone().into(), - logs_bloom: header.log_bloom().clone().into(), + gas_used: *header.gas_used(), + gas_limit: *header.gas_limit(), + logs_bloom: *header.log_bloom(), timestamp: header.timestamp().into(), - difficulty: header.difficulty().clone().into(), + difficulty: *header.difficulty(), seal_fields: header.seal().iter().cloned().map(Into::into).collect(), extra_data: Bytes::new(header.extra_data().clone()), }, - extra_info: extra_info, + extra_info, }) }; let id = number.unwrap_or_default().to_block_id(); diff --git a/rpc/src/v1/impls/light/parity_set.rs b/rpc/src/v1/impls/light/parity_set.rs index f129f86b3c..68fc212b2f 100644 --- a/rpc/src/v1/impls/light/parity_set.rs +++ b/rpc/src/v1/impls/light/parity_set.rs @@ -43,9 +43,9 @@ impl ParitySetClient { /// Creates new `ParitySetClient` with given `Fetch`. pub fn new(client: Arc, net: Arc, fetch: F) -> Self { ParitySetClient { - client: client, - net: net, - fetch: fetch, + client, + net, + fetch, } } } diff --git a/rpc/src/v1/impls/parity.rs b/rpc/src/v1/impls/parity.rs index d985f33f62..27a7037958 100644 --- a/rpc/src/v1/impls/parity.rs +++ b/rpc/src/v1/impls/parity.rs @@ -109,7 +109,7 @@ impl Parity for ParityClient where } fn min_gas_price(&self) -> Result { - Ok(self.miner.queue_status().options.minimal_gas_price.into()) + Ok(self.miner.queue_status().options.minimal_gas_price) } fn extra_data(&self) -> Result { @@ -117,11 +117,11 @@ impl Parity for ParityClient where } fn gas_floor_target(&self) -> Result { - Ok(U256::from(self.miner.authoring_params().gas_range_target.0)) + Ok(self.miner.authoring_params().gas_range_target.0) } fn gas_ceil_target(&self) -> Result { - Ok(U256::from(self.miner.authoring_params().gas_range_target.1)) + Ok(self.miner.authoring_params().gas_range_target.1) } fn dev_logs(&self) -> Result> { @@ -152,7 +152,7 @@ impl Parity for ParityClient where active: sync_status.num_active_peers, connected: sync_status.num_peers, max: sync_status.current_max_peers(*num_peers_range.start(), *num_peers_range.end()), - peers: peers + peers, }) } @@ -170,7 +170,6 @@ impl Parity for ParityClient where .additional_params() .get("registrar") .and_then(|s| Address::from_str(s).ok()) - .map(|s| H160::from(s)) ) } @@ -207,7 +206,7 @@ impl Parity for ParityClient where } fn phrase_to_address(&self, phrase: String) -> Result { - Ok(Brain::new(phrase).generate().unwrap().address().into()) + Ok(Brain::new(phrase).generate().expect("Brain::generate always returns Ok; qed").address()) } fn list_accounts(&self, count: u64, after: Option, block_number: Option) -> Result>> { @@ -236,12 +235,12 @@ impl Parity for ParityClient where }; Ok(self.client - .list_storage(number, &address.into(), after.map(Into::into).as_ref(), count) + .list_storage(number, &address, after.map(Into::into).as_ref(), count) .map(|a| a.into_iter().map(Into::into).collect())) } fn encrypt_message(&self, key: H512, phrase: Bytes) -> Result { - ecies::encrypt(&key.into(), &DEFAULT_MAC, &phrase.0) + ecies::encrypt(&key, &DEFAULT_MAC, &phrase.0) .map_err(errors::encryption) .map(Into::into) } @@ -271,13 +270,7 @@ impl Parity for ParityClient where } fn all_transaction_hashes(&self) -> Result> { - let all_transaction_hashes = self.miner.queued_transaction_hashes(); - - Ok(all_transaction_hashes - .into_iter() - .map(|hash| hash.into()) - .collect() - ) + Ok(self.miner.queued_transaction_hashes()) } fn future_transactions(&self) -> Result> { @@ -287,7 +280,7 @@ impl Parity for ParityClient where fn pending_transactions_stats(&self) -> Result> { let stats = self.sync.transactions_stats(); Ok(stats.into_iter() - .map(|(hash, stats)| (hash.into(), stats.into())) + .map(|(hash, stats)| (hash, stats.into())) .collect() ) } @@ -296,7 +289,7 @@ impl Parity for ParityClient where let transactions = self.miner.local_transactions(); Ok(transactions .into_iter() - .map(|(hash, status)| (hash.into(), LocalTransactionStatus::from(status))) + .map(|(hash, status)| (hash, LocalTransactionStatus::from(status))) .collect() ) } @@ -307,9 +300,7 @@ impl Parity for ParityClient where } fn next_nonce(&self, address: H160) -> BoxFuture { - let address: Address = address.into(); - - Box::new(future::ok(self.miner.next_nonce(&*self.client, &address).into())) + Box::new(future::ok(self.miner.next_nonce(&*self.client, &address))) } fn mode(&self) -> Result { @@ -339,7 +330,7 @@ impl Parity for ParityClient where .and_then(|first| chain_info.first_block_number.map(|last| (first, U256::from(last)))); Ok(ChainStatus { - block_gap: gap.map(|(x, y)| (x.into(), y.into())), + block_gap: gap, }) } @@ -370,7 +361,7 @@ impl Parity for ParityClient where BlockNumber::Pending => unreachable!(), // Already covered }; - let header = try_bf!(self.client.block_header(id.clone()).ok_or_else(errors::unknown_block)); + let header = try_bf!(self.client.block_header(id).ok_or_else(errors::unknown_block)); let info = self.client.block_extra_info(id).expect(EXTRA_INFO_PROOF); (header, Some(info)) @@ -467,7 +458,7 @@ impl Parity for ParityClient where fn logs_no_tx_hash(&self, filter: Filter) -> BoxFuture> { use v1::impls::eth::base_logs; // only specific impl for lightclient - base_logs(&*self.client, &*self.miner, filter.into()) + base_logs(&*self.client, &*self.miner, filter) } fn verify_signature(&self, is_prefixed: bool, message: Bytes, r: H256, s: H256, v: U64) -> Result { diff --git a/rpc/src/v1/impls/parity_set.rs b/rpc/src/v1/impls/parity_set.rs index 16ef8d5432..b7cef6c6b8 100644 --- a/rpc/src/v1/impls/parity_set.rs +++ b/rpc/src/v1/impls/parity_set.rs @@ -119,7 +119,7 @@ impl ParitySet for ParitySetClient where { fn set_min_gas_price(&self, gas_price: U256) -> Result { - match self.miner.set_minimal_gas_price(gas_price.into()) { + match self.miner.set_minimal_gas_price(gas_price) { Ok(success) => Ok(success), Err(e) => Err(errors::unsupported(e, None)), } @@ -136,15 +136,15 @@ impl ParitySet for ParitySetClient where } fn set_gas_floor_target(&self, target: U256) -> Result { - let mut range = self.miner.authoring_params().gas_range_target.clone(); - range.0 = target.into(); + let mut range = self.miner.authoring_params().gas_range_target; + range.0 = target; self.miner.set_gas_range_target(range); Ok(true) } fn set_gas_ceil_target(&self, target: U256) -> Result { - let mut range = self.miner.authoring_params().gas_range_target.clone(); - range.1 = target.into(); + let mut range = self.miner.authoring_params().gas_range_target; + range.1 = target; self.miner.set_gas_range_target(range); Ok(true) } @@ -155,7 +155,7 @@ impl ParitySet for ParitySetClient where } fn set_author(&self, address: H160) -> Result { - self.miner.set_author(miner::Author::External(address.into())); + self.miner.set_author(miner::Author::External(address)); Ok(true) } @@ -236,8 +236,6 @@ impl ParitySet for ParitySetClient where } fn remove_transaction(&self, hash: H256) -> Result> { - let hash = hash.into(); - Ok(self.miner.remove_transaction(&hash) .map(|t| Transaction::from_pending(t.pending().clone())) ) diff --git a/rpc/src/v1/impls/private.rs b/rpc/src/v1/impls/private.rs index f1cf991240..c3be3f9150 100644 --- a/rpc/src/v1/impls/private.rs +++ b/rpc/src/v1/impls/private.rs @@ -60,7 +60,7 @@ impl Private for PrivateClient { .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))?; + let receipt = client.create_private_transaction(signed_transaction).map_err(errors::private_message)?; Ok(receipt.into()) } @@ -76,16 +76,17 @@ impl Private for PrivateClient { 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 (transaction, contract_address) = client + .public_creation_transaction(id, &signed_transaction, addresses.as_slice(), gas_price) + .map_err(errors::private_message)?; let tx_hash = transaction.hash(None); let request = TransactionRequest { - from: Some(signed_transaction.sender().into()), + from: Some(signed_transaction.sender()), to: None, - nonce: Some(transaction.nonce.into()), - gas_price: Some(transaction.gas_price.into()), - gas: Some(transaction.gas.into()), - value: Some(transaction.value.into()), + nonce: Some(transaction.nonce), + gas_price: Some(transaction.gas_price), + gas: Some(transaction.gas), + value: Some(transaction.value), data: Some(transaction.data.into()), condition: None, }; @@ -93,8 +94,8 @@ impl Private for PrivateClient { Ok(PrivateTransactionReceiptAndTransaction { transaction: request, receipt: PrivateTransactionReceipt { - transaction_hash: tx_hash.into(), - contract_address: contract_address.into(), + transaction_hash: tx_hash, + contract_address, status_code: 0, } }) @@ -109,13 +110,13 @@ impl Private for PrivateClient { let request = CallRequest::into(request); let signed = fake_sign::sign_call(request)?; let client = self.unwrap_manager()?; - let executed_result = client.private_call(id, &signed).map_err(|e| errors::private_message(e))?; + let executed_result = client.private_call(id, &signed).map_err(errors::private_message)?; 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()) + let key = client.contract_key_id(&contract_address).map_err(errors::private_message)?; + Ok(key) } } diff --git a/rpc/src/v1/impls/pubsub.rs b/rpc/src/v1/impls/pubsub.rs index 9650fd2d07..1575aacdd6 100644 --- a/rpc/src/v1/impls/pubsub.rs +++ b/rpc/src/v1/impls/pubsub.rs @@ -81,7 +81,7 @@ impl> PubSub for PubSubClient { type Metadata = Metadata; fn parity_subscribe(&self, mut meta: Metadata, subscriber: Subscriber, method: String, params: Option) { - let params = params.unwrap_or(core::Params::Array(vec![])); + let params = params.unwrap_or_else(|| core::Params::Array(vec![])); // Make sure to get rid of PubSub session otherwise it will never be dropped. meta.session = None; diff --git a/rpc/src/v1/impls/rpc.rs b/rpc/src/v1/impls/rpc.rs index f218c5ade6..0c2afd57ca 100644 --- a/rpc/src/v1/impls/rpc.rs +++ b/rpc/src/v1/impls/rpc.rs @@ -32,8 +32,8 @@ impl RpcClient { let valid_apis = vec!["web3", "eth", "net", "personal", "rpc"]; RpcClient { - modules: modules, - valid_apis: valid_apis.into_iter().map(|x| x.to_owned()).collect(), + modules, + valid_apis: valid_apis.into_iter().map(ToOwned::to_owned).collect(), } } } diff --git a/rpc/src/v1/impls/signer.rs b/rpc/src/v1/impls/signer.rs index c4f4d35766..4edac1144a 100644 --- a/rpc/src/v1/impls/signer.rs +++ b/rpc/src/v1/impls/signer.rs @@ -85,7 +85,6 @@ impl SignerClient { T: IntoFuture, Error=Error>, T::Future: Send + 'static { - let id = id.into(); let dispatcher = self.dispatcher.clone(); let signer = self.signer.clone(); @@ -94,15 +93,15 @@ impl SignerClient { // Modify payload if let ConfirmationPayload::SendTransaction(ref mut request) = payload { if let Some(sender) = modification.sender { - request.from = sender.into(); + request.from = sender; // Altering sender should always reset the nonce. request.nonce = None; } if let Some(gas_price) = modification.gas_price { - request.gas_price = gas_price.into(); + request.gas_price = gas_price; } if let Some(gas) = modification.gas { - request.gas = gas.into(); + request.gas = gas; } if let Some(ref condition) = modification.condition { request.condition = condition.clone().map(Into::into); @@ -177,7 +176,7 @@ impl Signer for SignerClient { Box::new(self.confirm_internal(id, modification, move |dis, accounts, payload| { dispatch::execute(dis, accounts, payload, dispatch::SignWith::Password(pass.into())) - }).map(|v| v.into_value())) + }).map(dispatch::WithToken::into_value)) } fn confirm_request_with_token(&self, id: U256, modification: TransactionModification, token: String) @@ -191,7 +190,7 @@ impl Signer for SignerClient { WithToken::No(_) => Err(errors::internal("Unexpected response without token.", "")), WithToken::Yes(response, token) => Ok(ConfirmationResponseWithToken { result: response, - token: token, + token, }), })) } @@ -199,8 +198,6 @@ impl Signer for SignerClient { fn confirm_request_raw(&self, id: U256, bytes: Bytes) -> Result { self.deprecation_notice.print("signer_confirmRequestRaw", deprecated::msgs::ACCOUNTS); - let id = id.into(); - self.signer.take(&id).map(|sender| { let payload = sender.request.payload.clone(); let result = match payload { @@ -251,7 +248,7 @@ impl Signer for SignerClient { fn reject_request(&self, id: U256) -> Result { self.deprecation_notice.print("signer_rejectRequest", deprecated::msgs::ACCOUNTS); - let res = self.signer.take(&id.into()).map(|sender| self.signer.request_rejected(sender)); + let res = self.signer.take(&id).map(|sender| self.signer.request_rejected(sender)); Ok(res.is_some()) } @@ -259,7 +256,7 @@ impl Signer for SignerClient { self.deprecation_notice.print("signer_generateAuthorizationToken", deprecated::msgs::ACCOUNTS); self.signer.generate_token() - .map_err(|e| errors::token(e)) + .map_err(errors::token) } fn subscribe_pending(&self, _meta: Self::Metadata, sub: Subscriber>) { diff --git a/rpc/src/v1/impls/signing.rs b/rpc/src/v1/impls/signing.rs index 12f8909563..38ca6d59c9 100644 --- a/rpc/src/v1/impls/signing.rs +++ b/rpc/src/v1/impls/signing.rs @@ -75,7 +75,7 @@ fn schedule(executor: Executor, future: RpcConfirmationReceiver) { { let mut confirmations = confirmations.lock(); - confirmations.insert(id.clone(), None); + confirmations.insert(id, None); } let future = future.then(move |result| { @@ -122,7 +122,7 @@ impl SigningQueueClient { let sender = payload.sender(); if accounts.is_unlocked(&sender) { Either::A(dispatch::execute(dispatcher, &accounts, payload, dispatch::SignWith::Nothing) - .map(|v| v.into_value()) + .map(dispatch::WithToken::into_value) .map(DispatchResult::Value)) } else { Either::B(future::done( @@ -149,13 +149,13 @@ impl ParitySigning for SigningQueueClient { let confirmations = self.confirmations.clone(); Box::new(self.dispatch( - RpcConfirmationPayload::EthSignMessage((address.clone(), data).into()), + RpcConfirmationPayload::EthSignMessage((address, data).into()), meta.origin ).map(move |result| match result { DispatchResult::Value(v) => RpcEither::Or(v), DispatchResult::Future(id, future) => { schedule(executor, confirmations, id, future); - RpcEither::Either(id.into()) + RpcEither::Either(id) }, })) } @@ -170,14 +170,13 @@ impl ParitySigning for SigningQueueClient { DispatchResult::Value(v) => RpcEither::Or(v), DispatchResult::Future(id, future) => { schedule(executor, confirmations, id, future); - RpcEither::Either(id.into()) + RpcEither::Either(id) }, })) } fn check_request(&self, id: U256) -> Result> { self.deprecation_notice.print("parity_checkRequest", deprecated::msgs::ACCOUNTS); - let id: U256 = id.into(); match self.confirmations.lock().get(&id) { None => Err(errors::request_not_found()), // Request info has been dropped, or even never been there Some(&None) => Ok(None), // No confirmation yet, request is known, confirmation is pending @@ -188,7 +187,7 @@ impl ParitySigning for SigningQueueClient { fn decrypt_message(&self, meta: Metadata, address: H160, data: RpcBytes) -> BoxFuture { self.deprecation_notice.print("parity_decryptMessage", deprecated::msgs::ACCOUNTS); let res = self.dispatch( - RpcConfirmationPayload::Decrypt((address.clone(), data).into()), + RpcConfirmationPayload::Decrypt((address, data).into()), meta.origin, ); @@ -208,7 +207,7 @@ impl EthSigning for SigningQueueClient { fn sign(&self, meta: Metadata, address: H160, data: RpcBytes) -> BoxFuture { self.deprecation_notice.print("eth_sign", deprecated::msgs::ACCOUNTS); let res = self.dispatch( - RpcConfirmationPayload::EthSignMessage((address.clone(), data).into()), + RpcConfirmationPayload::EthSignMessage((address, data).into()), meta.origin, ); diff --git a/rpc/src/v1/impls/signing_unsafe.rs b/rpc/src/v1/impls/signing_unsafe.rs index 72a3a6fbf1..f08a9ffbe6 100644 --- a/rpc/src/v1/impls/signing_unsafe.rs +++ b/rpc/src/v1/impls/signing_unsafe.rs @@ -60,7 +60,7 @@ impl SigningUnsafeClient { .and_then(move |payload| { dispatch::execute(dis, &accounts, payload, dispatch::SignWith::Nothing) }) - .map(|v| v.into_value())) + .map(dispatch::WithToken::into_value)) } } @@ -70,7 +70,7 @@ impl EthSigning for SigningUnsafeClient fn sign(&self, _: Metadata, address: H160, data: RpcBytes) -> BoxFuture { self.deprecation_notice.print("eth_sign", deprecated::msgs::ACCOUNTS); - Box::new(self.handle(RpcConfirmationPayload::EthSignMessage((address.clone(), data).into()), address.into()) + Box::new(self.handle(RpcConfirmationPayload::EthSignMessage((address, data).into()), address) .then(|res| match res { Ok(RpcConfirmationResponse::Signature(signature)) => Ok(signature), Err(e) => Err(e), @@ -111,7 +111,7 @@ impl ParitySigning for SigningUnsafeClient { fn decrypt_message(&self, _: Metadata, address: H160, data: RpcBytes) -> BoxFuture { self.deprecation_notice.print("parity_decryptMessage", deprecated::msgs::ACCOUNTS); - Box::new(self.handle(RpcConfirmationPayload::Decrypt((address.clone(), data).into()), address.into()) + Box::new(self.handle(RpcConfirmationPayload::Decrypt((address, data).into()), address) .then(|res| match res { Ok(RpcConfirmationResponse::Decrypt(data)) => Ok(data), Err(e) => Err(e), diff --git a/rpc/src/v1/impls/traces.rs b/rpc/src/v1/impls/traces.rs index d7428aad27..a6301eda53 100644 --- a/rpc/src/v1/impls/traces.rs +++ b/rpc/src/v1/impls/traces.rs @@ -74,13 +74,13 @@ impl Traces for TracesClient where } fn transaction_traces(&self, transaction_hash: H256) -> Result>> { - Ok(self.client.transaction_traces(TransactionId::Hash(transaction_hash.into())) + Ok(self.client.transaction_traces(TransactionId::Hash(transaction_hash)) .map(|traces| traces.into_iter().map(LocalizedTrace::from).collect())) } fn trace(&self, transaction_hash: H256, address: Vec) -> Result> { let id = TraceId { - transaction: TransactionId::Hash(transaction_hash.into()), + transaction: TransactionId::Hash(transaction_hash), address: address.into_iter().map(|i| i.value()).collect() }; @@ -102,8 +102,8 @@ impl Traces for TracesClient where BlockNumber::Pending => return Err(errors::invalid_params("`BlockNumber::Pending` is not supported", ())), }; - let mut state = self.client.state_at(id).ok_or(errors::state_pruned())?; - let header = self.client.block_header(id).ok_or(errors::state_pruned())?; + let mut state = self.client.state_at(id).ok_or_else(errors::state_pruned)?; + let header = self.client.block_header(id).ok_or_else(errors::state_pruned)?; self.client.call(&signed, to_call_analytics(flags), &mut state, &header.decode().map_err(errors::decode)?) .map(TraceResults::from) @@ -129,8 +129,8 @@ impl Traces for TracesClient where BlockNumber::Pending => return Err(errors::invalid_params("`BlockNumber::Pending` is not supported", ())), }; - let mut state = self.client.state_at(id).ok_or(errors::state_pruned())?; - let header = self.client.block_header(id).ok_or(errors::state_pruned())?; + let mut state = self.client.state_at(id).ok_or_else(errors::state_pruned)?; + let header = self.client.block_header(id).ok_or_else(errors::state_pruned)?; self.client.call_many(&requests, &mut state, &header.decode().map_err(errors::decode)?) .map(|results| results.into_iter().map(TraceResults::from).collect()) @@ -151,8 +151,8 @@ impl Traces for TracesClient where BlockNumber::Pending => return Err(errors::invalid_params("`BlockNumber::Pending` is not supported", ())), }; - let mut state = self.client.state_at(id).ok_or(errors::state_pruned())?; - let header = self.client.block_header(id).ok_or(errors::state_pruned())?; + let mut state = self.client.state_at(id).ok_or_else(errors::state_pruned)?; + let header = self.client.block_header(id).ok_or_else(errors::state_pruned)?; self.client.call(&signed, to_call_analytics(flags), &mut state, &header.decode().map_err(errors::decode)?) .map(TraceResults::from) @@ -160,7 +160,7 @@ impl Traces for TracesClient where } fn replay_transaction(&self, transaction_hash: H256, flags: TraceOptions) -> Result { - self.client.replay(TransactionId::Hash(transaction_hash.into()), to_call_analytics(flags)) + self.client.replay(TransactionId::Hash(transaction_hash), to_call_analytics(flags)) .map(TraceResults::from) .map_err(errors::call) } @@ -175,7 +175,7 @@ impl Traces for TracesClient where }; self.client.replay_block_transactions(id, to_call_analytics(flags)) - .map(|results| results.into_iter().map(TraceResultsWithTransactionHash::from).collect()) + .map(|results| results.map(TraceResultsWithTransactionHash::from).collect()) .map_err(errors::call) } } diff --git a/rpc/src/v1/impls/web3.rs b/rpc/src/v1/impls/web3.rs index e7bf9dd49f..5ffda51b66 100644 --- a/rpc/src/v1/impls/web3.rs +++ b/rpc/src/v1/impls/web3.rs @@ -23,19 +23,15 @@ use v1::traits::Web3; use v1::types::Bytes; /// Web3 rpc implementation. +#[derive(Default)] pub struct Web3Client; -impl Web3Client { - /// Creates new Web3Client. - pub fn new() -> Self { Web3Client } -} - impl Web3 for Web3Client { fn client_version(&self) -> Result { Ok(version().to_owned().replacen("/", "//", 1)) } fn sha3(&self, data: Bytes) -> Result { - Ok(keccak(&data.0).into()) + Ok(keccak(&data.0)) } } diff --git a/rpc/src/v1/informant.rs b/rpc/src/v1/informant.rs index 9455fa9ebb..945378390b 100644 --- a/rpc/src/v1/informant.rs +++ b/rpc/src/v1/informant.rs @@ -135,7 +135,7 @@ impl StatsCalculator { #[derive(Default, Debug)] pub struct RpcStats { requests: RwLock, - roundtrips: RwLock>, + roundtrips: RwLock>, active_sessions: AtomicUsize, } @@ -157,7 +157,7 @@ impl RpcStats { } /// Add roundtrip time (microseconds) - pub fn add_roundtrip(&self, microseconds: u32) { + pub fn add_roundtrip(&self, microseconds: u128) { self.roundtrips.write().add(microseconds) } @@ -172,7 +172,7 @@ impl RpcStats { } /// Returns approximated roundtrip in microseconds - pub fn approximated_roundtrip(&self) -> u32 { + pub fn approximated_roundtrip(&self) -> u128 { self.roundtrips.read().approximated_median() } } @@ -197,10 +197,6 @@ impl Middleware { notifier, } } - - fn as_micro(dur: time::Duration) -> u32 { - (dur.as_secs() * 1_000_000) as u32 + dur.subsec_nanos() / 1_000 - } } impl core::Middleware for Middleware { @@ -223,7 +219,7 @@ impl core::Middleware for Middleware< let stats = self.stats.clone(); let future = process(request, meta).map(move |res| { - let time = Self::as_micro(start.elapsed()); + let time = start.elapsed().as_micros(); if time > 10_000 { debug!(target: "rpc", "[{:?}] Took {}ms", id, time / 1_000); } diff --git a/rpc/src/v1/tests/mocked/web3.rs b/rpc/src/v1/tests/mocked/web3.rs index 79bcfe01db..5590d5d283 100644 --- a/rpc/src/v1/tests/mocked/web3.rs +++ b/rpc/src/v1/tests/mocked/web3.rs @@ -20,7 +20,7 @@ use v1::{Web3, Web3Client}; #[test] fn rpc_web3_version() { - let web3 = Web3Client::new().to_delegate(); + let web3 = Web3Client::default().to_delegate(); let mut io = IoHandler::new(); io.extend_with(web3); @@ -34,7 +34,7 @@ fn rpc_web3_version() { #[test] fn rpc_web3_sha3() { - let web3 = Web3Client::new().to_delegate(); + let web3 = Web3Client::default().to_delegate(); let mut io = IoHandler::new(); io.extend_with(web3); @@ -46,7 +46,7 @@ fn rpc_web3_sha3() { #[test] fn rpc_web3_sha3_wiki() { - let web3 = Web3Client::new().to_delegate(); + let web3 = Web3Client::default().to_delegate(); let mut io = IoHandler::new(); io.extend_with(web3); diff --git a/rpc/src/v1/types/block.rs b/rpc/src/v1/types/block.rs index 6e23647a0e..61f4402af0 100644 --- a/rpc/src/v1/types/block.rs +++ b/rpc/src/v1/types/block.rs @@ -139,21 +139,21 @@ impl From for Header { impl<'a> From<&'a EthHeader> for Header { fn from(h: &'a EthHeader) -> Self { Header { - hash: Some(h.hash().into()), + hash: Some(h.hash()), size: Some(h.rlp().as_raw().len().into()), - parent_hash: h.parent_hash().into(), - uncles_hash: h.uncles_hash().into(), - author: h.author().into(), - miner: h.author().into(), - state_root: h.state_root().into(), - transactions_root: h.transactions_root().into(), - receipts_root: h.receipts_root().into(), + parent_hash: h.parent_hash(), + uncles_hash: h.uncles_hash(), + author: h.author(), + miner: h.author(), + state_root: h.state_root(), + transactions_root: h.transactions_root(), + receipts_root: h.receipts_root(), number: Some(h.number().into()), - gas_used: h.gas_used().into(), - gas_limit: h.gas_limit().into(), - logs_bloom: h.log_bloom().into(), + gas_used: h.gas_used(), + gas_limit: h.gas_limit(), + logs_bloom: h.log_bloom(), timestamp: h.timestamp().into(), - difficulty: h.difficulty().into(), + difficulty: h.difficulty(), extra_data: h.extra_data().into(), seal_fields: h.view().decode_seal() .expect("Client/Miner returns only valid headers. We only serialize headers from Client/Miner; qed") diff --git a/rpc/src/v1/types/block_number.rs b/rpc/src/v1/types/block_number.rs index 64b100d5aa..7e19f2d3d9 100644 --- a/rpc/src/v1/types/block_number.rs +++ b/rpc/src/v1/types/block_number.rs @@ -107,7 +107,7 @@ impl<'a> Visitor<'a> for BlockNumberVisitor { _ if value.starts_with("0x") => u64::from_str_radix(&value[2..], 16).map(BlockNumber::Num).map_err(|e| { Error::custom(format!("Invalid block number: {}", e)) }), - _ => Err(Error::custom(format!("Invalid block number: missing 0x prefix"))), + _ => Err(Error::custom("Invalid block number: missing 0x prefix".to_string())), } } diff --git a/rpc/src/v1/types/confirmations.rs b/rpc/src/v1/types/confirmations.rs index 1534fbcea1..dedd0ba253 100644 --- a/rpc/src/v1/types/confirmations.rs +++ b/rpc/src/v1/types/confirmations.rs @@ -41,7 +41,7 @@ pub struct ConfirmationRequest { impl From for ConfirmationRequest { fn from(c: helpers::ConfirmationRequest) -> Self { ConfirmationRequest { - id: c.id.into(), + id: c.id, payload: c.payload.into(), origin: c.origin, } @@ -214,15 +214,15 @@ impl From for ConfirmationPayload { helpers::ConfirmationPayload::SendTransaction(t) => ConfirmationPayload::SendTransaction(t.into()), helpers::ConfirmationPayload::SignTransaction(t) => ConfirmationPayload::SignTransaction(t.into()), helpers::ConfirmationPayload::EthSignMessage(address, data) => ConfirmationPayload::EthSignMessage(EthSignRequest { - address: address.into(), + address, data: data.into(), }), helpers::ConfirmationPayload::SignMessage(address, data) => ConfirmationPayload::EIP191SignMessage(EIP191SignRequest { - address: address.into(), - data: data.into(), + address, + data, }), helpers::ConfirmationPayload::Decrypt(address, msg) => ConfirmationPayload::Decrypt(DecryptRequest { - address: address.into(), + address, msg: msg.into(), }), } diff --git a/rpc/src/v1/types/consensus_status.rs b/rpc/src/v1/types/consensus_status.rs index a5a5c9de8b..da2aa26a1d 100644 --- a/rpc/src/v1/types/consensus_status.rs +++ b/rpc/src/v1/types/consensus_status.rs @@ -109,7 +109,7 @@ impl Into for updater::VersionInfo { VersionInfo { track: self.track.into(), version: self.version.into(), - hash: self.hash.into(), + hash: self.hash, } } } diff --git a/rpc/src/v1/types/filter.rs b/rpc/src/v1/types/filter.rs index c6708da576..ec9f541797 100644 --- a/rpc/src/v1/types/filter.rs +++ b/rpc/src/v1/types/filter.rs @@ -88,10 +88,7 @@ impl Filter { }; let (from_block, to_block) = match self.block_hash { - Some(hash) => { - let hash = hash.into(); - (BlockId::Hash(hash), BlockId::Hash(hash)) - }, + Some(hash) => (BlockId::Hash(hash), BlockId::Hash(hash)), None => (self.from_block.map_or_else(|| BlockId::Latest, &num_to_id), self.to_block.map_or_else(|| BlockId::Latest, &num_to_id)), @@ -101,14 +98,14 @@ impl Filter { from_block, to_block, address: self.address.and_then(|address| match address { VariadicValue::Null => None, - VariadicValue::Single(a) => Some(vec![a.into()]), - VariadicValue::Multiple(a) => Some(a.into_iter().map(Into::into).collect()) + VariadicValue::Single(a) => Some(vec![a]), + VariadicValue::Multiple(a) => Some(a) }), topics: { let mut iter = self.topics.map_or_else(Vec::new, |topics| topics.into_iter().take(4).map(|topic| match topic { VariadicValue::Null => None, - VariadicValue::Single(t) => Some(vec![t.into()]), - VariadicValue::Multiple(t) => Some(t.into_iter().map(Into::into).collect()) + VariadicValue::Single(t) => Some(vec![t]), + VariadicValue::Multiple(t) => Some(t) }).collect()).into_iter(); vec![ diff --git a/rpc/src/v1/types/log.rs b/rpc/src/v1/types/log.rs index 3dcc8fb298..57b2cdd5dc 100644 --- a/rpc/src/v1/types/log.rs +++ b/rpc/src/v1/types/log.rs @@ -51,12 +51,12 @@ pub struct Log { impl From for Log { fn from(e: LocalizedLogEntry) -> Log { Log { - address: e.entry.address.into(), + address: e.entry.address, topics: e.entry.topics.into_iter().map(Into::into).collect(), data: e.entry.data.into(), - block_hash: Some(e.block_hash.into()), + block_hash: Some(e.block_hash), block_number: Some(e.block_number.into()), - transaction_hash: Some(e.transaction_hash.into()), + transaction_hash: Some(e.transaction_hash), transaction_index: Some(e.transaction_index.into()), log_index: Some(e.log_index.into()), transaction_log_index: Some(e.transaction_log_index.into()), @@ -69,7 +69,7 @@ impl From for Log { impl From for Log { fn from(e: LogEntry) -> Log { Log { - address: e.address.into(), + address: e.address, topics: e.topics.into_iter().map(Into::into).collect(), data: e.data.into(), block_hash: None, diff --git a/rpc/src/v1/types/private_receipt.rs b/rpc/src/v1/types/private_receipt.rs index fd0eae067f..68e9e716f9 100644 --- a/rpc/src/v1/types/private_receipt.rs +++ b/rpc/src/v1/types/private_receipt.rs @@ -34,9 +34,9 @@ pub struct PrivateTransactionReceipt { impl From for PrivateTransactionReceipt { fn from(r: EthPrivateReceipt) -> Self { PrivateTransactionReceipt { - transaction_hash: r.hash.into(), - contract_address: r.contract_address.into(), - status_code: r.status_code.into(), + transaction_hash: r.hash, + contract_address: r.contract_address, + status_code: r.status_code, } } } diff --git a/rpc/src/v1/types/pubsub.rs b/rpc/src/v1/types/pubsub.rs index c526a2b372..1586b115c3 100644 --- a/rpc/src/v1/types/pubsub.rs +++ b/rpc/src/v1/types/pubsub.rs @@ -26,9 +26,9 @@ use v1::types::{RichHeader, Filter, Log}; #[derive(Debug, Clone, PartialEq, Eq)] pub enum Result { /// New block header. - Header(RichHeader), + Header(Box), /// Log - Log(Log), + Log(Box), /// Transaction hash TransactionHash(H256), } @@ -144,7 +144,7 @@ mod tests { #[test] fn should_serialize_header() { - let header = Result::Header(RichHeader { + let header = Result::Header(Box::new(RichHeader { extra_info: Default::default(), inner: Header { hash: Some(Default::default()), @@ -165,7 +165,7 @@ mod tests { seal_fields: vec![Default::default(), Default::default()], size: Some(69.into()), }, - }); + })); let expected = r#"{"author":"0x0000000000000000000000000000000000000000","difficulty":"0x0","extraData":"0x","gasLimit":"0x0","gasUsed":"0x0","hash":"0x0000000000000000000000000000000000000000000000000000000000000000","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","miner":"0x0000000000000000000000000000000000000000","number":"0x0","parentHash":"0x0000000000000000000000000000000000000000000000000000000000000000","receiptsRoot":"0x0000000000000000000000000000000000000000000000000000000000000000","sealFields":["0x","0x"],"sha3Uncles":"0x0000000000000000000000000000000000000000000000000000000000000000","size":"0x45","stateRoot":"0x0000000000000000000000000000000000000000000000000000000000000000","timestamp":"0x0","transactionsRoot":"0x0000000000000000000000000000000000000000000000000000000000000000"}"#; assert_eq!(serde_json::to_string(&header).unwrap(), expected); } diff --git a/rpc/src/v1/types/receipt.rs b/rpc/src/v1/types/receipt.rs index f440c8f486..f492ca98c5 100644 --- a/rpc/src/v1/types/receipt.rs +++ b/rpc/src/v1/types/receipt.rs @@ -56,7 +56,7 @@ impl Receipt { fn outcome_to_state_root(outcome: TransactionOutcome) -> Option { match outcome { TransactionOutcome::Unknown | TransactionOutcome::StatusCode(_) => None, - TransactionOutcome::StateRoot(root) => Some(root.into()), + TransactionOutcome::StateRoot(root) => Some(root), } } @@ -72,18 +72,18 @@ impl From for Receipt { fn from(r: LocalizedReceipt) -> Self { Receipt { to: r.to.map(Into::into), - from: Some(r.from.into()), - transaction_hash: Some(r.transaction_hash.into()), + from: Some(r.from), + transaction_hash: Some(r.transaction_hash), transaction_index: Some(r.transaction_index.into()), - block_hash: Some(r.block_hash.into()), + block_hash: Some(r.block_hash), block_number: Some(r.block_number.into()), - cumulative_gas_used: r.cumulative_gas_used.into(), - gas_used: Some(r.gas_used.into()), + cumulative_gas_used: r.cumulative_gas_used, + gas_used: Some(r.gas_used), contract_address: r.contract_address.map(Into::into), logs: r.logs.into_iter().map(Into::into).collect(), status_code: Self::outcome_to_status_code(&r.outcome), state_root: Self::outcome_to_state_root(r.outcome), - logs_bloom: r.log_bloom.into(), + logs_bloom: r.log_bloom, } } } @@ -93,17 +93,17 @@ impl From for Receipt { Receipt { from: None, to: None, - transaction_hash: Some(r.transaction_hash.into()), + transaction_hash: Some(r.transaction_hash), transaction_index: Some(r.transaction_index.into()), block_hash: None, block_number: None, - cumulative_gas_used: r.cumulative_gas_used.into(), - gas_used: Some(r.gas_used.into()), + cumulative_gas_used: r.cumulative_gas_used, + gas_used: Some(r.gas_used), contract_address: r.contract_address.map(Into::into), logs: r.logs.into_iter().map(Into::into).collect(), status_code: Self::outcome_to_status_code(&r.outcome), state_root: Self::outcome_to_state_root(r.outcome), - logs_bloom: r.log_bloom.into(), + logs_bloom: r.log_bloom, } } } @@ -117,13 +117,13 @@ impl From for Receipt { transaction_index: None, block_hash: None, block_number: None, - cumulative_gas_used: r.gas_used.into(), + cumulative_gas_used: r.gas_used, gas_used: None, contract_address: None, logs: r.logs.into_iter().map(Into::into).collect(), status_code: Self::outcome_to_status_code(&r.outcome), state_root: Self::outcome_to_state_root(r.outcome), - logs_bloom: r.log_bloom.into(), + logs_bloom: r.log_bloom, } } } diff --git a/rpc/src/v1/types/sync.rs b/rpc/src/v1/types/sync.rs index 10094742c0..901611fea2 100644 --- a/rpc/src/v1/types/sync.rs +++ b/rpc/src/v1/types/sync.rs @@ -120,7 +120,7 @@ impl From for PipProtocolInfo { fn from(info: sync::PipProtocolInfo) -> Self { PipProtocolInfo { version: info.version, - difficulty: info.difficulty.into(), + difficulty: info.difficulty, head: format!("{:x}", info.head), } } @@ -179,7 +179,7 @@ impl From for TransactionStats { first_seen: s.first_seen, propagated_to: s.propagated_to .into_iter() - .map(|(id, count)| (id.into(), count)) + .map(|(id, count)| (id, count)) .collect(), } } diff --git a/rpc/src/v1/types/trace.rs b/rpc/src/v1/types/trace.rs index 715ffe62c5..58a5ee5962 100644 --- a/rpc/src/v1/types/trace.rs +++ b/rpc/src/v1/types/trace.rs @@ -58,8 +58,8 @@ pub struct StorageDiff { impl From for StorageDiff { fn from(c: et::StorageDiff) -> Self { StorageDiff { - key: c.location.into(), - val: c.value.into(), + key: c.location, + val: c.value, } } } @@ -190,7 +190,7 @@ impl From for AccountDiff { balance: c.balance.into(), nonce: c.nonce.into(), code: c.code.into(), - storage: c.storage.into_iter().map(|(k, v)| (k.into(), v.into())).collect(), + storage: c.storage.into_iter().map(|(k, v)| (k, v.into())).collect(), } } } @@ -208,7 +208,7 @@ impl Serialize for StateDiff { impl From for StateDiff { fn from(c: state_diff::StateDiff) -> Self { - StateDiff(c.raw.into_iter().map(|(k, v)| (k.into(), v.into())).collect()) + StateDiff(c.raw.into_iter().map(|(k, v)| (k, v.into())).collect()) } } @@ -228,9 +228,9 @@ pub struct Create { impl From for Create { fn from(c: trace::Create) -> Self { Create { - from: c.from.into(), - value: c.value.into(), - gas: c.gas.into(), + from: c.from, + value: c.value, + gas: c.gas, init: Bytes::new(c.init), } } @@ -285,10 +285,10 @@ pub struct Call { impl From for Call { fn from(c: trace::Call) -> Self { Call { - from: c.from.into(), - to: c.to.into(), - value: c.value.into(), - gas: c.gas.into(), + from: c.from, + to: c.to, + value: c.value, + gas: c.gas, input: c.input.into(), call_type: c.call_type.into(), } @@ -335,8 +335,8 @@ pub struct Reward { impl From for Reward { fn from(r: trace::Reward) -> Self { Reward { - author: r.author.into(), - value: r.value.into(), + author: r.author, + value: r.value, reward_type: r.reward_type.into(), } } @@ -357,9 +357,9 @@ pub struct Suicide { impl From for Suicide { fn from(s: trace::Suicide) -> Self { Suicide { - address: s.address.into(), - refund_address: s.refund_address.into(), - balance: s.balance.into(), + address: s.address, + refund_address: s.refund_address, + balance: s.balance, } } } @@ -401,7 +401,7 @@ pub struct CallResult { impl From for CallResult { fn from(c: trace::CallResult) -> Self { CallResult { - gas_used: c.gas_used.into(), + gas_used: c.gas_used, output: c.output.into(), } } @@ -422,9 +422,9 @@ pub struct CreateResult { impl From for CreateResult { fn from(c: trace::CreateResult) -> Self { CreateResult { - gas_used: c.gas_used.into(), + gas_used: c.gas_used, code: c.code.into(), - address: c.address.into(), + address: c.address, } } } @@ -526,11 +526,11 @@ impl From for LocalizedTrace { action: t.action.into(), result: t.result.into(), trace_address: t.trace_address.into_iter().map(Into::into).collect(), - subtraces: t.subtraces.into(), + subtraces: t.subtraces, transaction_position: t.transaction_number.map(Into::into), transaction_hash: t.transaction_hash.map(Into::into), - block_number: t.block_number.into(), - block_hash: t.block_hash.into(), + block_number: t.block_number, + block_hash: t.block_hash, } } } @@ -591,7 +591,7 @@ impl From for Trace { fn from(t: FlatTrace) -> Self { Trace { trace_address: t.trace_address.into_iter().map(Into::into).collect(), - subtraces: t.subtraces.into(), + subtraces: t.subtraces, action: t.action.into(), result: t.result.into(), } @@ -646,7 +646,7 @@ impl From<(H256, Executed)> for TraceResultsWithTransactionHash { trace: t.1.trace.into_iter().map(Into::into).collect(), vm_trace: t.1.vm_trace.map(Into::into), state_diff: t.1.state_diff.map(Into::into), - transaction_hash: t.0.into(), + transaction_hash: t.0, } } } diff --git a/rpc/src/v1/types/transaction.rs b/rpc/src/v1/types/transaction.rs index 72b591a89f..931e038669 100644 --- a/rpc/src/v1/types/transaction.rs +++ b/rpc/src/v1/types/transaction.rs @@ -177,22 +177,22 @@ impl Transaction { let signature = t.signature(); let scheme = CreateContractAddress::FromSenderAndNonce; Transaction { - hash: t.hash().into(), - nonce: t.nonce.into(), - block_hash: Some(t.block_hash.clone().into()), + hash: t.hash(), + nonce: t.nonce, + block_hash: Some(t.block_hash), block_number: Some(t.block_number.into()), transaction_index: Some(t.transaction_index.into()), - from: t.sender().into(), + from: t.sender(), to: match t.action { Action::Create => None, - Action::Call(ref address) => Some(address.clone().into()) + Action::Call(ref address) => Some(*address) }, - value: t.value.into(), - gas_price: t.gas_price.into(), - gas: t.gas.into(), + value: t.value, + gas_price: t.gas_price, + gas: t.gas, input: Bytes::new(t.data.clone()), creates: match t.action { - Action::Create => Some(contract_address(scheme, &t.sender(), &t.nonce, &t.data).0.into()), + Action::Create => Some(contract_address(scheme, &t.sender(), &t.nonce, &t.data).0), Action::Call(_) => None, }, raw: ::rlp::encode(&t.signed).into(), @@ -211,22 +211,22 @@ impl Transaction { let signature = t.signature(); let scheme = CreateContractAddress::FromSenderAndNonce; Transaction { - hash: t.hash().into(), - nonce: t.nonce.into(), + hash: t.hash(), + nonce: t.nonce, block_hash: None, block_number: None, transaction_index: None, - from: t.sender().into(), + from: t.sender(), to: match t.action { Action::Create => None, - Action::Call(ref address) => Some(address.clone().into()) + Action::Call(ref address) => Some(*address) }, - value: t.value.into(), - gas_price: t.gas_price.into(), - gas: t.gas.into(), + value: t.value, + gas_price: t.gas_price, + gas: t.gas, input: Bytes::new(t.data.clone()), creates: match t.action { - Action::Create => Some(contract_address(scheme, &t.sender(), &t.nonce, &t.data).0.into()), + Action::Create => Some(contract_address(scheme, &t.sender(), &t.nonce, &t.data).0), Action::Call(_) => None, }, raw: ::rlp::encode(&t).into(), @@ -243,7 +243,7 @@ impl Transaction { /// Convert `PendingTransaction` into RPC Transaction. pub fn from_pending(t: PendingTransaction) -> Transaction { let mut r = Transaction::from_signed(t.transaction); - r.condition = t.condition.map(|b| b.into()); + r.condition = r.condition.map(Into::into); r } } @@ -265,8 +265,8 @@ impl LocalTransactionStatus { Canceled(tx) => LocalTransactionStatus::Canceled(convert(tx)), Replaced { old, new } => LocalTransactionStatus::Replaced( convert(old), - new.signed().gas_price.into(), - new.signed().hash().into(), + new.signed().gas_price, + new.signed().hash(), ), } } diff --git a/rpc/src/v1/types/transaction_request.rs b/rpc/src/v1/types/transaction_request.rs index a4698cafa7..944ee11148 100644 --- a/rpc/src/v1/types/transaction_request.rs +++ b/rpc/src/v1/types/transaction_request.rs @@ -63,7 +63,7 @@ pub fn format_ether(i: U256) -> String { impl fmt::Display for TransactionRequest { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let eth = self.value.unwrap_or(U256::from(0)); + let eth = self.value.unwrap_or_default(); match self.to { Some(ref to) => write!( f, @@ -106,14 +106,14 @@ impl From for TransactionRequest { impl From for TransactionRequest { fn from(r: helpers::FilledTransactionRequest) -> Self { TransactionRequest { - from: Some(r.from.into()), - to: r.to.map(Into::into), - gas_price: Some(r.gas_price.into()), - gas: Some(r.gas.into()), - value: Some(r.value.into()), + from: Some(r.from), + to: r.to, + gas_price: Some(r.gas_price), + gas: Some(r.gas), + value: Some(r.value), data: Some(r.data.into()), - nonce: r.nonce.map(Into::into), - condition: r.condition.map(Into::into), + nonce: r.nonce, + condition: r.condition, } } } From 023e511f83ed30726a72c99807c2ef225afdab0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?So=C4=8Dik?= <47772477+soc1c@users.noreply.github.com> Date: Fri, 22 Mar 2019 15:59:20 +0100 Subject: [PATCH 132/168] docs: add changelogs for 2.3.{6,7,8} and 2.4.{1,2,3} (#10494) * docs: add changelogs for 2.3.{6,7} and 2.4.{1,2} * docs: add changelogs for 2.4.3 beta and 2.3.8 stable * Update docs/CHANGELOG-2.3.md Co-Authored-By: soc1c <47772477+soc1c@users.noreply.github.com> * Update docs/CHANGELOG-2.3.md Co-Authored-By: soc1c <47772477+soc1c@users.noreply.github.com> * docs: remove empty lines --- CHANGELOG.md | 36 +++++++++++++++++++++++++++++++++++- docs/CHANGELOG-2.3.md | 35 ++++++++++++++++++++++++++++++++++- 2 files changed, 69 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ef1c68399..b986da688c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,37 @@ +## Parity-Ethereum [v2.4.3](https://github.com/paritytech/parity-ethereum/releases/tag/v2.4.3) (2019-03-22) + +Parity-Ethereum 2.4.3-beta is a bugfix release that improves performance and stability. This patch release contains a critical bug fix where serving light clients previously led to client crashes. Upgrading is highly recommended. + +The full list of included changes: +- 2.4.3 beta backports ([#10508](https://github.com/paritytech/parity-ethereum/pull/10508)) + - Version: bump beta + - Add additional request tests ([#10503](https://github.com/paritytech/parity-ethereum/pull/10503)) + +## Parity-Ethereum [v2.4.2](https://github.com/paritytech/parity-ethereum/releases/tag/v2.4.2) (2019-03-20) + +Parity-Ethereum 2.4.2-beta is a bugfix release that improves performance and stability. + +The full list of included changes: +- 2.4.2 beta backports ([#10488](https://github.com/paritytech/parity-ethereum/pull/10488)) + - Version: bump beta + - Сaching through docker volume ([#10477](https://github.com/paritytech/parity-ethereum/pull/10477)) + - fix win&mac build ([#10486](https://github.com/paritytech/parity-ethereum/pull/10486)) + - fix(extract `timestamp_checked_add` as lib) ([#10383](https://github.com/paritytech/parity-ethereum/pull/10383)) + +## Parity-Ethereum [v2.4.1](https://github.com/paritytech/parity-ethereum/releases/tag/v2.4.1) (2019-03-19) + +Parity-Ethereum 2.4.1-beta is a bugfix release that improves performance and stability. + +The full list of included changes: +- 2.4.1 beta backports ([#10471](https://github.com/paritytech/parity-ethereum/pull/10471)) + - Version: bump beta + - Implement parity_versionInfo & parity_setChain on LC; fix parity_setChain ([#10312](https://github.com/paritytech/parity-ethereum/pull/10312)) + - CI publish to aws ([#10446](https://github.com/paritytech/parity-ethereum/pull/10446)) + - CI aws git checkout ([#10451](https://github.com/paritytech/parity-ethereum/pull/10451)) + - Revert "CI aws git checkout ([#10451](https://github.com/paritytech/parity-ethereum/pull/10451))" ([#10456](https://github.com/paritytech/parity-ethereum/pull/10456)) + - Tests parallelized ([#10452](https://github.com/paritytech/parity-ethereum/pull/10452)) + - Ensure static validator set changes are recognized ([#10467](https://github.com/paritytech/parity-ethereum/pull/10467)) + ## Parity-Ethereum [v2.4.0](https://github.com/paritytech/parity-ethereum/releases/tag/v2.4.0) (2019-02-25) Parity-Ethereum 2.4.0-beta is our trifortnightly minor version release coming with a lot of new features as well as bugfixes and performance improvements. @@ -6,7 +40,7 @@ Notable changes: - Account management is now deprecated ([#10213](https://github.com/paritytech/parity-ethereum/pull/10213)) - Local accounts can now be specified via CLI ([#9960](https://github.com/paritytech/parity-ethereum/pull/9960)) - Chains can now be reset to a particular block via CLI ([#9782](https://github.com/paritytech/parity-ethereum/pull/9782)) -- Ethash now additionally implements ProgPoW ([#9762](https://github.com/paritytech/parity-ethereum/pull/9762)) +- Ethash now additionally implements ProgPoW ([#9762](https://github.com/paritytech/parity-ethereum/pull/9762)) - The `eip1283DisableTransition` flag was added to revert EIP-1283 ([#10214](https://github.com/paritytech/parity-ethereum/pull/10214)) The full list of included changes: diff --git a/docs/CHANGELOG-2.3.md b/docs/CHANGELOG-2.3.md index f7e75d4427..34286baf1b 100644 --- a/docs/CHANGELOG-2.3.md +++ b/docs/CHANGELOG-2.3.md @@ -1,3 +1,36 @@ +## Parity-Ethereum [v2.3.8](https://github.com/paritytech/parity-ethereum/releases/tag/v2.3.8) (2019-03-22) + +Parity-Ethereum 2.3.8-stable is a bugfix release that improves performance and stability. This patch release contains a critical bug fix where serving light clients previously led to client crashes. Upgrading is highly recommended. + +The full list of included changes: +- 2.3.8 stable backports ([#10507](https://github.com/paritytech/parity-ethereum/pull/10507)) + - Version: bump stable + - Add additional request tests ([#10503](https://github.com/paritytech/parity-ethereum/pull/10503)) + +## Parity-Ethereum [v2.3.7](https://github.com/paritytech/parity-ethereum/releases/tag/v2.3.7) (2019-03-20) + +Parity-Ethereum 2.3.7-stable is a bugfix release that improves performance and stability. + +The full list of included changes: +- 2.3.7 stable backports ([#10487](https://github.com/paritytech/parity-ethereum/pull/10487)) + - Version: bump stable + - Сaching through docker volume ([#10477](https://github.com/paritytech/parity-ethereum/pull/10477)) + - fix win&mac build ([#10486](https://github.com/paritytech/parity-ethereum/pull/10486)) + - fix(extract `timestamp_checked_add` as lib) ([#10383](https://github.com/paritytech/parity-ethereum/pull/10383)) + +## Parity-Ethereum [v2.3.6](https://github.com/paritytech/parity-ethereum/releases/tag/v2.3.6) (2019-03-19) + +Parity-Ethereum 2.3.6-stable is a bugfix release that improves performance and stability. + +The full list of included changes: +- 2.3.6 stable backports ([#10470](https://github.com/paritytech/parity-ethereum/pull/10470)) + - Version: bump stable + - CI publish to aws ([#10446](https://github.com/paritytech/parity-ethereum/pull/10446)) + - Ensure static validator set changes are recognized ([#10467](https://github.com/paritytech/parity-ethereum/pull/10467)) + - CI aws git checkout ([#10451](https://github.com/paritytech/parity-ethereum/pull/10451)) + - Revert "CI aws git checkout ([#10451](https://github.com/paritytech/parity-ethereum/pull/10451))" ([#10456](https://github.com/paritytech/parity-ethereum/pull/10456)) + - Tests parallelized ([#10452](https://github.com/paritytech/parity-ethereum/pull/10452)) + ## Parity-Ethereum [v2.3.5](https://github.com/paritytech/parity-ethereum/releases/tag/v2.3.5) (2019-02-25) Parity-Ethereum 2.3.5-stable is a bugfix release that improves performance and stability. @@ -18,7 +51,7 @@ The full list of included changes: - Snap: reenable i386, arm64, armhf architecture publishing ([#10386](https://github.com/paritytech/parity-ethereum/pull/10386)) - Tx pool: always accept local transactions ([#10375](https://github.com/paritytech/parity-ethereum/pull/10375)) - Fix to_pod storage trie value decoding ([#10368)](https://github.com/paritytech/parity-ethereum/pull/10368)) -- Version: mark 2.3.5 as stable +- Version: mark 2.3.5 as stable ## Parity-Ethereum [v2.3.4](https://github.com/paritytech/parity-ethereum/releases/tag/v2.3.4) (2019-02-21) From 6cf3ba7efd8a366b440c7675df1c0576c8cd4762 Mon Sep 17 00:00:00 2001 From: Hernando Castano Date: Mon, 25 Mar 2019 10:42:33 +0100 Subject: [PATCH 133/168] Add a more realistic Batch test (#10511) * Remove unrealistic tests * Add test that more closely resembles real usage --- ethcore/light/src/types/request/batch.rs | 35 +++++++----------------- 1 file changed, 10 insertions(+), 25 deletions(-) diff --git a/ethcore/light/src/types/request/batch.rs b/ethcore/light/src/types/request/batch.rs index f99b49d2b2..63641b5daa 100644 --- a/ethcore/light/src/types/request/batch.rs +++ b/ethcore/light/src/types/request/batch.rs @@ -275,8 +275,7 @@ mod tests { } #[test] - #[should_panic] - fn batch_tx_index_backreference_wrong_output() { + fn batch_tx_index_backreference_public_api() { let mut builder = Builder::default(); builder.push(Request::HeaderProof(IncompleteHeaderProofRequest { num: 100.into(), // header proof puts hash at output 0. @@ -286,11 +285,16 @@ mod tests { })).unwrap(); let mut batch = builder.build(); - batch.requests[1].fill(|_req_idx, _out_idx| Ok(Output::Number(42))); - batch.next_complete(); - batch.answered += 1; - batch.next_complete(); + assert!(batch.next_complete().is_some()); + let hdr_proof_res = header_proof::Response { + proof: vec![], + hash: 12.into(), + td: 21.into(), + }; + batch.supply_response_unchecked(&hdr_proof_res); + + assert!(batch.next_complete().is_some()); } #[test] @@ -310,23 +314,4 @@ mod tests { batch.answered += 1; assert!(batch.next_complete().is_some()); } - - #[test] - #[should_panic] - fn batch_receipts_backreference_wrong_output() { - let mut builder = Builder::default(); - builder.push(Request::HeaderProof(IncompleteHeaderProofRequest { - num: 100.into(), // header proof puts hash at output 0. - })).unwrap(); - builder.push(Request::Receipts(IncompleteReceiptsRequest { - hash: Field::BackReference(0, 0), - })).unwrap(); - - let mut batch = builder.build(); - batch.requests[1].fill(|_req_idx, _out_idx| Ok(Output::Number(42))); - - batch.next_complete(); - batch.answered += 1; - batch.next_complete(); - } } From 9cb86061032a323710a1dd549e1e1f0a4e33eedd Mon Sep 17 00:00:00 2001 From: TriplEight Date: Tue, 26 Mar 2019 12:37:45 +0100 Subject: [PATCH 134/168] verbose flag for cpp tests (#10524) --- scripts/gitlab/test-cpp.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/gitlab/test-cpp.sh b/scripts/gitlab/test-cpp.sh index 9f825ec8c7..1cbd58a30c 100755 --- a/scripts/gitlab/test-cpp.sh +++ b/scripts/gitlab/test-cpp.sh @@ -10,7 +10,7 @@ DIR=parity-clib/examples/cpp/build mkdir -p $DIR cd $DIR cmake .. -make -j $THREADS +make VERBOSE=1 -j $THREADS # Note: we don't try to run the example because it tries to sync Kovan, and we don't want # that to happen on CI cd - From aa8487c1d0ce8481c0c8bb571488a8eebf78b854 Mon Sep 17 00:00:00 2001 From: 5chdn <5chdn@users.noreply.github.com> Date: Tue, 26 Mar 2019 23:31:52 +0100 Subject: [PATCH 135/168] ethcore: add clique engine (#9981) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix broken sync * correct seal fields * ethcore: fix comment * parity: remove duplicate params * clique: fix whitespaces * ethcore: fix goerli chain spec * refactor signer_snapshot into pending/finalized state * move close_block_extra_data after seal is applied * refactor most of the logic into the signer_snapshot * clique: refactor locking logic out of the consensus engine interface * Fix jsonspec and add an unittest * Replace space with tabs * Unbroke sync * Fix broken sync * 1/2 state tracking without votes * 2/2 implement vote tracking * ci: use travis for goerli * ci: setup a clique network * ci: sync a görli node * add clique deploy script * ci: fix paths in clique deploy script * ci: use docker compose * ci: fix travis job names * ci: fix build deps * ci: massively reduce tests * Revert "ci: massively reduce tests" This reverts commit 6369f0b069ed2607a7e9f2e1d85489bacdc43384. * ci: run cargo test directly * ci: separate build and test stages * ci: cache rust installation * ci: simplify ci stages * ci: make clique deploy script executable * ci: shutdown goerli sync after 20min * ci: remove slow sync stage * ci: use timeout to finish jobs * ci: fix build path * ci: use absolute paths to end this confusion * ci: add geth and parity to path * ci: be more verbose * ci: allow for more relaxed caching timeout * ci: update repositories for custom ppa * ci: fix typo in file name * ci: fix docker compose file * ci: add ethkey to docker * ci: make sure deploy script is up to date with upstream * ci: stop docker container after certain time * ci: force superuser to update permissions on docker files * ci: reduce run time of script to ~30 min * ci: remove duplicate caching in travis * remove trace statements * clique: add more validation involving the recent signer list * ethcore: enable constantinople for rinkeby * ethcore: fix whitespaces in rinkeby spec * ethcore: reformat goerli.json * Revert "ci: remove duplicate caching in travis" This reverts commit a562838d3d194d37f9871dcbe00b783637978f89. * tmp commit * another tmp commit * it builds! * add sealing capabilities * add seal_header hook to allow separation of block seal/importing code paths * clique: remove populate_from_parent. * add panic * make turn delay random * initialize OpenBlock properly in 'enact' * misc: remove duplicate lines * misc: fix license headers * misc: convert spaces to tabs * misc: fix tabs * Update Cargo.toml * Update Cargo.toml * Update Cargo.toml * clique: ensure validator restores state before trying to seal * clique: make 'state' return an Error. Make some error messages more clear * Fix compile error after rebase & toolchain upgrade * fix a bunch of import warnings * Refactor code * Fix permissions * Refactoring syncing * Implement full validator checks * Refactor util functions to seperate file * mining 1 * ethcore: add chainspec for kotti * ethcore: rename pre-goerli configs * ethcore: load kotti chain spec * cli: add kotti to params * Implement working local sealing * making sealing & syncing work together * Relax timestamp checking * ethcore: prepare for the real goerli to launch * Implement NOTURN wiggle properly & cleanupnup warnings * Implement vote casting * Update docs & skip signing if no signer * Optimize step-service interval * Record state on local sealed block * Fix script filemode * Cleaning up codebase * restore enact trace logging * Delete clique.sh and move sync.sh * remove travis.yml * Remove dead code * Cleanup compile warning * address review comments * adding more comments and removing unwrap() * ci: remove sync script * Address review comments * fix compile error * adding better debugging for timing * Implement an dedicated thread for sealing timing * fix(add helper for timestamp overflows) (#10330) * fix(add helper timestamp overflows) * fix(simplify code) * fix(make helper private) * snap: official image / test (#10168) * official image / test * fix / test * bit more necromancy * fix paths * add source bin/df /test * add source bin/df /test2 * something w paths /test * something w paths /test * add source-type /test * show paths /test * copy plugin /test * plugin -> nil * install rhash * no questions while installing rhash * publish snap only for release * fix(docker): fix not receives SIGINT (#10059) * fix(docker): fix not receives SIGINT * fix: update with reviews * update with review * update * update * Don't add discovery initiators to the node table (#10305) * Don't add discovery initiators to the node table * Use enums for tracking state of the nodes in discovery * Dont try to ping ourselves * Fix minor nits * Update timeouts when observing an outdated node * Extracted update_bucket_record from update_node * Fixed typo * Fix two final nits from @todr * change docker image based on debian instead of ubuntu due to the chan… (#10336) * change docker image based on debian instead of ubuntu due to the changes of the build container * role back docker build image and docker deploy image to ubuntu:xenial based (#10338) * Bundle protocol and packet_id together in chain sync (#10315) Define a new `enum` where devp2p subprotocol packet ids (currently eth and par) are defined. Additionally provide functionality to query id value and protocol of a given id object. * snap: prefix version and populate candidate channel (#10343) * snap: populate candidate releases with beta snaps to avoid stale channel * snap: prefix version with v* * addressing review comments * engine: fix copyright header * scripts: restore permissions on sign command * ethcore: enforce tabs * ethcore: enforce tabs * ethcore: enforce tabs * addressing comments * addressing comments * addressing more comments * addressing more comments * addressing more comments * addressing more comments * addressing more comments * json-spec: fix clique epoch to non-zero u64 * ci: enable travis for parity goerli * ci: don't separate build and test step * ci: don't run c++ tests on travis * ci: simplify cargo test to squeeze into travis timeout * ci: don't run tests on travis at all * style(fixes) * fix(add tests) * fix(recent_signer bug) * fix(complete all tests) * fix(nits) * fix(simplify asserts) * fix(cliqueState): simplify code * fix(nits) * docs(comments what's need to fixed) * fix(revert unintended changes) * fix(tests) * fix(logs): voting logs * fix(readability + more logs) * fix(sync) * docs(add missing licens header) * fix(log): info! -> trace! * docs(fix nits) + fix(remove assert) * perf(use counter instead of vec) * fix(remove needless block in match) * fix(faulty comment) * grumbles(docs for tests) * fix(nits) * fix(revert_vote): only remove vote when votes == 0 * fix(vote counter): checked arithmetics * fix(simplify tests) * fix(nits) * fix(clique): err types * fix(clique utils): make use of errors * fix(cleanup nits) * fix(clique sealing): don't read state no signer * fix(replace Vec with BTreeSet) * fix(tests): BTreeSet and more generic helpers * fix(nits) * fix(ethcore_block_seal): remove needless `Box` * fix(faulty log): info -> trace * fix(checked SystemTime): prevent SystemTime panics * style(chain cfg): space after `:` * style(fn enact): fix whitespace * docs(clique): StepService * docs(nit): fix faulty comment * docs(fix typo) * style(fix bad indentation) * fix(bad regex match) * grumble(on_seal_block): make `&mut` to avoid clone * docs(on_seal_block): fix faulty documentation * Delete .travis.yml * docs: remove eth hf references in spec * Update client.rs * fix(nits) * fix(clique step): `RwLock` -> `AtomicBool` * fix(clique): use `Duration::as_millis` * Clean up some Clique documentation Co-authored-by: soc1c Co-authored-by: HCastano Co-authored-by: niklasad1 Co-authored-by: jwasinger Co-authored-by: ChainSafe Co-authored-by: thefallentree Co-authored-by: 5chdn <5chdn@users.noreply.github.com> --- ethcore/Cargo.toml | 2 +- ethcore/res/ethereum/goerli.json | 911 +++++++++++++++++++++ ethcore/res/ethereum/kotti.json | 855 +++++++++++++++++++ ethcore/res/ethereum/rinkeby.json | 902 ++++++++++++++++++++ ethcore/src/block.rs | 45 +- ethcore/src/client/client.rs | 7 +- ethcore/src/engines/clique/block_state.rs | 369 +++++++++ ethcore/src/engines/clique/mod.rs | 768 +++++++++++++++++ ethcore/src/engines/clique/params.rs | 41 + ethcore/src/engines/clique/step_service.rs | 77 ++ ethcore/src/engines/clique/tests.rs | 804 ++++++++++++++++++ ethcore/src/engines/clique/util.rs | 115 +++ ethcore/src/engines/mod.rs | 50 +- ethcore/src/ethereum/mod.rs | 25 +- ethcore/src/miner/miner.rs | 8 +- ethcore/src/spec/spec.rs | 12 +- json/src/spec/clique.rs | 57 ++ json/src/spec/engine.rs | 18 +- json/src/spec/mod.rs | 2 + parity/cli/mod.rs | 4 +- parity/params.rs | 19 + util/version/Cargo.toml | 1 + 22 files changed, 5055 insertions(+), 37 deletions(-) create mode 100644 ethcore/res/ethereum/goerli.json create mode 100644 ethcore/res/ethereum/kotti.json create mode 100644 ethcore/res/ethereum/rinkeby.json create mode 100644 ethcore/src/engines/clique/block_state.rs create mode 100644 ethcore/src/engines/clique/mod.rs create mode 100644 ethcore/src/engines/clique/params.rs create mode 100644 ethcore/src/engines/clique/step_service.rs create mode 100644 ethcore/src/engines/clique/tests.rs create mode 100644 ethcore/src/engines/clique/util.rs create mode 100644 json/src/spec/clique.rs diff --git a/ethcore/Cargo.toml b/ethcore/Cargo.toml index 3b8d60af8e..336d6a0fcc 100644 --- a/ethcore/Cargo.toml +++ b/ethcore/Cargo.toml @@ -39,7 +39,7 @@ keccak-hasher = { path = "../util/keccak-hasher" } kvdb = "0.1" kvdb-memorydb = "0.1" kvdb-rocksdb = { version = "0.1.3", optional = true } -lazy_static = "1.0" +lazy_static = "1.2.0" len-caching-lock = { path = "../util/len-caching-lock" } log = "0.4" lru-cache = "0.1" diff --git a/ethcore/res/ethereum/goerli.json b/ethcore/res/ethereum/goerli.json new file mode 100644 index 0000000000..e3ba75927b --- /dev/null +++ b/ethcore/res/ethereum/goerli.json @@ -0,0 +1,911 @@ +{ + "name": "Görli Testnet", + "dataDir": "goerli", + "engine": { + "clique": { + "params": { + "period": 15, + "epoch": 30000 + } + } + }, + "params": { + "accountStartNonce": "0x0", + "chainID": "0x5", + "eip140Transition": "0x0", + "eip145Transition": "0x0", + "eip150Transition": "0x0", + "eip155Transition": "0x0", + "eip160Transition": "0x0", + "eip161abcTransition": "0x0", + "eip161dTransition": "0x0", + "eip211Transition": "0x0", + "eip214Transition": "0x0", + "eip658Transition": "0x0", + "eip1014Transition": "0x0", + "eip1052Transition": "0x0", + "eip1283Transition": "0x0", + "eip1283DisableTransition": "0x0", + "gasLimitBoundDivisor": "0x400", + "maxCodeSize": "0x6000", + "maxCodeSizeTransition": "0x0", + "maximumExtraDataSize": "0xffff", + "minGasLimit": "0x1388", + "networkID": "0x5" + }, + "genesis": { + "author": "0x0000000000000000000000000000000000000000", + "difficulty": "0x1", + "extraData": "0x22466c6578692069732061207468696e6722202d204166726900000000000000e0a2bd4258d2768837baa26a28fe71dc079f84c70000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "gasLimit": "0xa00000", + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "seal": { + "ethereum": { + "nonce": "0x0000000000000000", + "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + }, + "timestamp": "0x5c51a607" + }, + "nodes": [ + "enode://011f758e6552d105183b1761c5e2dea0111bc20fd5f6422bc7f91e0fabbec9a6595caf6239b37feb773dddd3f87240d99d859431891e4a642cf2a0a9e6cbb98a@51.141.78.53:30303", + "enode://176b9417f511d05b6b2cf3e34b756cf0a7096b3094572a8f6ef4cdcb9d1f9d00683bf0f83347eebdf3b81c3521c2332086d9592802230bf528eaf606a1d9677b@13.93.54.137:30303" + ], + "accounts": { + "0x0000000000000000000000000000000000000000": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000001": { + "balance": "0x1", + "builtin": { + "name": "ecrecover", + "pricing": { + "linear": { + "base": 3000, + "word": 0 + } + } + } + }, + "0x0000000000000000000000000000000000000002": { + "balance": "0x1", + "builtin": { + "name": "sha256", + "pricing": { + "linear": { + "base": 60, + "word": 12 + } + } + } + }, + "0x0000000000000000000000000000000000000003": { + "balance": "0x1", + "builtin": { + "name": "ripemd160", + "pricing": { + "linear": { + "base": 600, + "word": 120 + } + } + } + }, + "0x0000000000000000000000000000000000000004": { + "balance": "0x1", + "builtin": { + "name": "identity", + "pricing": { + "linear": { + "base": 15, + "word": 3 + } + } + } + }, + "0x0000000000000000000000000000000000000005": { + "balance": "0x1", + "builtin": { + "name": "modexp", + "activate_at": "0x0", + "pricing": { + "modexp": { + "divisor": 20 + } + } + } + }, + "0x0000000000000000000000000000000000000006": { + "balance": "0x1", + "builtin": { + "name": "alt_bn128_add", + "activate_at": "0x0", + "pricing": { + "linear": { + "base": 500, + "word": 0 + } + } + } + }, + "0x0000000000000000000000000000000000000007": { + "balance": "0x1", + "builtin": { + "name": "alt_bn128_mul", + "activate_at": "0x0", + "pricing": { + "linear": { + "base": 40000, + "word": 0 + } + } + } + }, + "0x0000000000000000000000000000000000000008": { + "balance": "0x1", + "builtin": { + "name": "alt_bn128_pairing", + "activate_at": "0x0", + "pricing": { + "alt_bn128_pairing": { + "base": 100000, + "pair": 80000 + } + } + } + }, + "0x0000000000000000000000000000000000000009": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000000a": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000000b": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000000c": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000000d": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000000e": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000000f": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000010": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000011": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000012": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000013": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000014": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000015": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000016": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000017": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000018": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000019": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000001a": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000001b": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000001c": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000001d": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000001e": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000001f": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000020": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000021": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000022": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000023": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000024": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000025": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000026": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000027": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000028": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000029": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000002a": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000002b": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000002c": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000002d": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000002e": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000002f": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000030": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000031": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000032": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000033": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000034": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000035": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000036": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000037": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000038": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000039": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000003a": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000003b": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000003c": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000003d": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000003e": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000003f": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000040": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000041": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000042": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000043": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000044": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000045": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000046": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000047": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000048": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000049": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000004a": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000004b": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000004c": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000004d": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000004e": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000004f": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000050": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000051": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000052": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000053": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000054": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000055": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000056": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000057": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000058": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000059": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000005a": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000005b": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000005c": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000005d": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000005e": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000005f": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000060": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000061": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000062": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000063": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000064": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000065": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000066": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000067": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000068": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000069": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000006a": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000006b": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000006c": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000006d": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000006e": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000006f": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000070": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000071": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000072": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000073": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000074": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000075": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000076": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000077": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000078": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000079": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000007a": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000007b": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000007c": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000007d": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000007e": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000007f": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000080": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000081": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000082": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000083": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000084": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000085": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000086": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000087": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000088": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000089": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000008a": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000008b": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000008c": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000008d": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000008e": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000008f": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000090": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000091": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000092": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000093": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000094": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000095": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000096": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000097": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000098": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000099": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000009a": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000009b": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000009c": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000009d": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000009e": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000009f": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000a0": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000a1": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000a2": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000a3": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000a4": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000a5": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000a6": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000a7": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000a8": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000a9": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000aa": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000ab": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000ac": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000ad": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000ae": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000af": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000b0": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000b1": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000b2": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000b3": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000b4": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000b5": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000b6": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000b7": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000b8": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000b9": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000ba": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000bb": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000bc": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000bd": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000be": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000bf": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000c0": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000c1": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000c2": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000c3": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000c4": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000c5": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000c6": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000c7": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000c8": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000c9": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000ca": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000cb": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000cc": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000cd": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000ce": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000cf": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000d0": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000d1": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000d2": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000d3": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000d4": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000d5": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000d6": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000d7": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000d8": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000d9": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000da": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000db": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000dc": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000dd": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000de": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000df": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000e0": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000e1": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000e2": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000e3": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000e4": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000e5": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000e6": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000e7": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000e8": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000e9": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000ea": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000eb": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000ec": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000ed": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000ee": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000ef": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000f0": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000f1": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000f2": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000f3": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000f4": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000f5": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000f6": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000f7": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000f8": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000f9": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000fa": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000fb": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000fc": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000fd": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000fe": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000ff": { + "balance": "0x1" + }, + "0x4c2ae482593505f0163cdefc073e81c63cda4107": { + "balance": "0x152d02c7e14af6800000" + }, + "0xa8e8f14732658e4b51e8711931053a8a69baf2b1": { + "balance": "0x152d02c7e14af6800000" + }, + "0xd9a5179f091d85051d3c982785efd1455cec8699": { + "balance": "0x84595161401484a000000" + }, + "0xe0a2bd4258d2768837baa26a28fe71dc079f84c7": { + "balance": "0x4a47e3c12448f4ad000000" + } + } +} diff --git a/ethcore/res/ethereum/kotti.json b/ethcore/res/ethereum/kotti.json new file mode 100644 index 0000000000..06d1d31ea3 --- /dev/null +++ b/ethcore/res/ethereum/kotti.json @@ -0,0 +1,855 @@ +{ + "name": "Kotti Testnet", + "dataDir": "kotti", + "engine": { + "clique": { + "params": { + "period": 15, + "epoch": 30000 + } + } + }, + "params": { + "accountStartNonce": "0x0", + "chainID": "0x6", + "eip150Transition": "0x0", + "eip155Transition": "0x0", + "eip160Transition": "0x0", + "eip161abcTransition": "0x7fffffffffffffff", + "eip161dTransition": "0x7fffffffffffffff", + "gasLimitBoundDivisor": "0x400", + "maximumExtraDataSize": "0xffff", + "minGasLimit": "0x1388", + "networkID": "0x6" + }, + "genesis": { + "author": "0x0000000000000000000000000000000000000000", + "difficulty": "0x1", + "extraData": "0x000000000000000000000000000000000000000000000000000000000000000025b7955e43adf9c2a01a9475908702cce67f302a6aaf8cba3c9255a2b863415d4db7bae4f4bbca020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "gasLimit": "0xa00000", + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "seal": { + "ethereum": { + "nonce": "0x0000000000000000", + "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + }, + "timestamp": "0x5c2d2287" + }, + "nodes": [ + "enode://06333009fc9ef3c9e174768e495722a7f98fe7afd4660542e983005f85e556028410fd03278944f44cfe5437b1750b5e6bd1738f700fe7da3626d52010d2954c@51.141.15.254:30303", + "enode://ae8658da8d255d1992c3ec6e62e11d6e1c5899aa1566504bc1ff96a0c9c8bd44838372be643342553817f5cc7d78f1c83a8093dee13d77b3b0a583c050c81940@18.232.185.151:30303" + ], + "accounts": { + "0x0000000000000000000000000000000000000000": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000001": { + "balance": "0x1", + "builtin": { + "name": "ecrecover", + "pricing": { + "linear": { + "base": 3000, + "word": 0 + } + } + } + }, + "0x0000000000000000000000000000000000000002": { + "balance": "0x1", + "builtin": { + "name": "sha256", + "pricing": { + "linear": { + "base": 60, + "word": 12 + } + } + } + }, + "0x0000000000000000000000000000000000000003": { + "balance": "0x1", + "builtin": { + "name": "ripemd160", + "pricing": { + "linear": { + "base": 600, + "word": 120 + } + } + } + }, + "0x0000000000000000000000000000000000000004": { + "balance": "0x1", + "builtin": { + "name": "identity", + "pricing": { + "linear": { + "base": 15, + "word": 3 + } + } + } + }, + "0x0000000000000000000000000000000000000005": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000006": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000007": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000008": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000009": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000000a": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000000b": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000000c": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000000d": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000000e": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000000f": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000010": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000011": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000012": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000013": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000014": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000015": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000016": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000017": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000018": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000019": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000001a": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000001b": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000001c": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000001d": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000001e": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000001f": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000020": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000021": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000022": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000023": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000024": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000025": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000026": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000027": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000028": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000029": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000002a": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000002b": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000002c": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000002d": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000002e": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000002f": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000030": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000031": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000032": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000033": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000034": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000035": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000036": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000037": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000038": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000039": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000003a": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000003b": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000003c": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000003d": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000003e": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000003f": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000040": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000041": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000042": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000043": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000044": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000045": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000046": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000047": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000048": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000049": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000004a": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000004b": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000004c": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000004d": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000004e": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000004f": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000050": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000051": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000052": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000053": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000054": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000055": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000056": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000057": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000058": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000059": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000005a": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000005b": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000005c": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000005d": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000005e": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000005f": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000060": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000061": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000062": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000063": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000064": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000065": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000066": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000067": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000068": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000069": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000006a": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000006b": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000006c": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000006d": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000006e": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000006f": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000070": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000071": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000072": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000073": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000074": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000075": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000076": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000077": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000078": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000079": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000007a": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000007b": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000007c": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000007d": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000007e": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000007f": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000080": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000081": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000082": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000083": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000084": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000085": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000086": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000087": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000088": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000089": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000008a": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000008b": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000008c": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000008d": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000008e": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000008f": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000090": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000091": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000092": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000093": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000094": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000095": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000096": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000097": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000098": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000099": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000009a": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000009b": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000009c": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000009d": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000009e": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000009f": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000a0": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000a1": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000a2": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000a3": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000a4": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000a5": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000a6": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000a7": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000a8": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000a9": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000aa": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000ab": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000ac": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000ad": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000ae": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000af": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000b0": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000b1": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000b2": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000b3": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000b4": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000b5": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000b6": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000b7": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000b8": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000b9": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000ba": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000bb": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000bc": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000bd": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000be": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000bf": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000c0": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000c1": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000c2": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000c3": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000c4": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000c5": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000c6": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000c7": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000c8": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000c9": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000ca": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000cb": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000cc": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000cd": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000ce": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000cf": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000d0": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000d1": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000d2": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000d3": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000d4": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000d5": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000d6": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000d7": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000d8": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000d9": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000da": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000db": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000dc": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000dd": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000de": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000df": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000e0": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000e1": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000e2": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000e3": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000e4": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000e5": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000e6": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000e7": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000e8": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000e9": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000ea": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000eb": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000ec": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000ed": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000ee": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000ef": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000f0": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000f1": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000f2": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000f3": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000f4": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000f5": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000f6": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000f7": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000f8": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000f9": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000fa": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000fb": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000fc": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000fd": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000fe": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000ff": { + "balance": "0x1" + }, + "0x25b7955e43adf9c2a01a9475908702cce67f302a": { + "balance": "0x84595161401484a000000" + }, + "0x6aaf8cba3c9255a2b863415d4db7bae4f4bbca02": { + "balance": "0x4a723dc6b40b8a9a000000" + } + } +} diff --git a/ethcore/res/ethereum/rinkeby.json b/ethcore/res/ethereum/rinkeby.json new file mode 100644 index 0000000000..7d9cc80237 --- /dev/null +++ b/ethcore/res/ethereum/rinkeby.json @@ -0,0 +1,902 @@ +{ + "name": "Rinkeby", + "dataDir": "rinkeby", + "engine": { + "clique": { + "params": { + "period": 15, + "epoch": 30000 + } + } + }, + "params": { + "accountStartNonce": "0x0", + "chainID": "0x4", + "eip140Transition": "0xfcc25", + "eip145Transition": "0x37db77", + "eip150Transition": "0x2", + "eip155Transition": "0x3", + "eip160Transition": "0x0", + "eip161abcTransition": "0x0", + "eip161dTransition": "0x0", + "eip211Transition": "0xfcc25", + "eip214Transition": "0xfcc25", + "eip658Transition": "0xfcc25", + "eip1014Transition": "0x37db77", + "eip1052Transition": "0x37db77", + "eip1283Transition": "0x37db77", + "gasLimitBoundDivisor": "0x400", + "maxCodeSize": "0x6000", + "maxCodeSizeTransition": "0x0", + "maximumExtraDataSize": "0xffff", + "minGasLimit": "0x1388", + "networkID": "0x4" + }, + "genesis": { + "author": "0x0000000000000000000000000000000000000000", + "difficulty": "0x1", + "extraData": "0x52657370656374206d7920617574686f7269746168207e452e436172746d616e42eb768f2244c8811c63729a21a3569731535f067ffc57839b00206d1ad20c69a1981b489f772031b279182d99e65703f0076e4812653aab85fca0f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "gasLimit": "0x47b760", + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "seal": { + "ethereum": { + "nonce": "0x0000000000000000", + "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + }, + "timestamp": "0x58ee40ba" + }, + "nodes": [ + "enode://a24ac7c5484ef4ed0c5eb2d36620ba4e4aa13b8c84684e1b4aab0cebea2ae45cb4d375b77eab56516d34bfbd3c1a833fc51296ff084b770b94fb9028c4d25ccf@52.169.42.101:30303", + "enode://343149e4feefa15d882d9fe4ac7d88f885bd05ebb735e547f12e12080a9fa07c8014ca6fd7f373123488102fe5e34111f8509cf0b7de3f5b44339c9f25e87cb8@52.3.158.184:30303", + "enode://b6b28890b006743680c52e64e0d16db57f28124885595fa03a562be1d2bf0f3a1da297d56b13da25fb992888fd556d4c1a27b1f39d531bde7de1921c90061cc6@159.89.28.211:30303" + ], + "accounts": { + "0x0000000000000000000000000000000000000000": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000001": { + "balance": "0x1", + "builtin": { + "name": "ecrecover", + "pricing": { + "linear": { + "base": 3000, + "word": 0 + } + } + } + }, + "0x0000000000000000000000000000000000000002": { + "balance": "0x1", + "builtin": { + "name": "sha256", + "pricing": { + "linear": { + "base": 60, + "word": 12 + } + } + } + }, + "0x0000000000000000000000000000000000000003": { + "balance": "0x1", + "builtin": { + "name": "ripemd160", + "pricing": { + "linear": { + "base": 600, + "word": 120 + } + } + } + }, + "0x0000000000000000000000000000000000000004": { + "balance": "0x1", + "builtin": { + "name": "identity", + "pricing": { + "linear": { + "base": 15, + "word": 3 + } + } + } + }, + "0x0000000000000000000000000000000000000005": { + "balance": "0x1", + "builtin": { + "name": "modexp", + "activate_at": "0xfcc25", + "pricing": { + "modexp": { + "divisor": 20 + } + } + } + }, + "0x0000000000000000000000000000000000000006": { + "balance": "0x1", + "builtin": { + "name": "alt_bn128_add", + "activate_at": "0xfcc25", + "pricing": { + "linear": { + "base": 500, + "word": 0 + } + } + } + }, + "0x0000000000000000000000000000000000000007": { + "balance": "0x1", + "builtin": { + "name": "alt_bn128_mul", + "activate_at": "0xfcc25", + "pricing": { + "linear": { + "base": 40000, + "word": 0 + } + } + } + }, + "0x0000000000000000000000000000000000000008": { + "balance": "0x1", + "builtin": { + "name": "alt_bn128_pairing", + "activate_at": "0xfcc25", + "pricing": { + "alt_bn128_pairing": { + "base": 100000, + "pair": 80000 + } + } + } + }, + "0x0000000000000000000000000000000000000009": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000000a": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000000b": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000000c": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000000d": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000000e": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000000f": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000010": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000011": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000012": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000013": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000014": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000015": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000016": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000017": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000018": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000019": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000001a": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000001b": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000001c": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000001d": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000001e": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000001f": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000020": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000021": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000022": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000023": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000024": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000025": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000026": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000027": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000028": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000029": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000002a": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000002b": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000002c": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000002d": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000002e": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000002f": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000030": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000031": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000032": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000033": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000034": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000035": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000036": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000037": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000038": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000039": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000003a": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000003b": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000003c": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000003d": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000003e": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000003f": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000040": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000041": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000042": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000043": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000044": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000045": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000046": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000047": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000048": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000049": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000004a": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000004b": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000004c": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000004d": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000004e": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000004f": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000050": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000051": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000052": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000053": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000054": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000055": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000056": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000057": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000058": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000059": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000005a": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000005b": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000005c": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000005d": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000005e": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000005f": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000060": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000061": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000062": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000063": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000064": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000065": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000066": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000067": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000068": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000069": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000006a": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000006b": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000006c": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000006d": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000006e": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000006f": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000070": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000071": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000072": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000073": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000074": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000075": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000076": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000077": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000078": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000079": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000007a": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000007b": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000007c": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000007d": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000007e": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000007f": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000080": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000081": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000082": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000083": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000084": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000085": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000086": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000087": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000088": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000089": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000008a": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000008b": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000008c": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000008d": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000008e": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000008f": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000090": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000091": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000092": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000093": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000094": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000095": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000096": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000097": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000098": { + "balance": "0x1" + }, + "0x0000000000000000000000000000000000000099": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000009a": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000009b": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000009c": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000009d": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000009e": { + "balance": "0x1" + }, + "0x000000000000000000000000000000000000009f": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000a0": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000a1": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000a2": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000a3": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000a4": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000a5": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000a6": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000a7": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000a8": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000a9": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000aa": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000ab": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000ac": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000ad": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000ae": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000af": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000b0": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000b1": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000b2": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000b3": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000b4": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000b5": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000b6": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000b7": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000b8": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000b9": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000ba": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000bb": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000bc": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000bd": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000be": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000bf": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000c0": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000c1": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000c2": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000c3": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000c4": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000c5": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000c6": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000c7": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000c8": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000c9": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000ca": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000cb": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000cc": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000cd": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000ce": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000cf": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000d0": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000d1": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000d2": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000d3": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000d4": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000d5": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000d6": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000d7": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000d8": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000d9": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000da": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000db": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000dc": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000dd": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000de": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000df": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000e0": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000e1": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000e2": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000e3": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000e4": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000e5": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000e6": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000e7": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000e8": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000e9": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000ea": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000eb": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000ec": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000ed": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000ee": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000ef": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000f0": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000f1": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000f2": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000f3": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000f4": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000f5": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000f6": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000f7": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000f8": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000f9": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000fa": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000fb": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000fc": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000fd": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000fe": { + "balance": "0x1" + }, + "0x00000000000000000000000000000000000000ff": { + "balance": "0x1" + }, + "0x31b98d14007bdee637298086988a0bbd31184523": { + "balance": "0x200000000000000000000000000000000000000000000000000000000000000" + } + } +} diff --git a/ethcore/src/block.rs b/ethcore/src/block.rs index c5311cbe01..56cfc1c4c1 100644 --- a/ethcore/src/block.rs +++ b/ethcore/src/block.rs @@ -284,7 +284,6 @@ impl<'x> OpenBlock<'x> { self.block.header.set_difficulty(*header.difficulty()); self.block.header.set_gas_limit(*header.gas_limit()); self.block.header.set_timestamp(header.timestamp()); - self.block.header.set_author(*header.author()); self.block.header.set_uncles_hash(*header.uncles_hash()); self.block.header.set_transactions_root(*header.transactions_root()); // TODO: that's horrible. set only for backwards compatibility @@ -405,15 +404,20 @@ impl LockedBlock { /// Provide a valid seal in order to turn this into a `SealedBlock`. /// /// NOTE: This does not check the validity of `seal` with the engine. - pub fn seal(self, engine: &EthEngine, seal: Vec) -> Result { - let expected_seal_fields = engine.seal_fields(&self.block.header); + pub fn seal(self, engine: &EthEngine, seal: Vec) -> Result { + let expected_seal_fields = engine.seal_fields(&self.header); let mut s = self; if seal.len() != expected_seal_fields { - return Err(BlockError::InvalidSealArity( - Mismatch { expected: expected_seal_fields, found: seal.len() })); + Err(BlockError::InvalidSealArity(Mismatch { + expected: expected_seal_fields, + found: seal.len() + }))?; } + s.block.header.set_seal(seal); + engine.on_seal_block(&mut s.block)?; s.block.header.compute_hash(); + Ok(SealedBlock { block: s.block }) @@ -422,6 +426,7 @@ impl LockedBlock { /// Provide a valid seal in order to turn this into a `SealedBlock`. /// This does check the validity of `seal` with the engine. /// Returns the `ClosedBlock` back again if the seal is no good. + /// TODO(https://github.com/paritytech/parity-ethereum/issues/10407): This is currently only used in POW chain call paths, we should really merge it with seal() above. pub fn try_seal( self, engine: &EthEngine, @@ -463,7 +468,7 @@ impl Drain for SealedBlock { } /// Enact the block given by block header, transactions and uncles -fn enact( +pub(crate) fn enact( header: Header, transactions: Vec, uncles: Vec
, @@ -476,13 +481,12 @@ fn enact( is_epoch_begin: bool, ancestry: &mut Iterator, ) -> Result { - { - if ::log::max_level() >= ::log::Level::Trace { - let s = State::from_existing(db.boxed_clone(), parent.state_root().clone(), engine.account_start_nonce(parent.number() + 1), factories.clone())?; - trace!(target: "enact", "num={}, root={}, author={}, author_balance={}\n", - header.number(), s.root(), header.author(), s.balance(&header.author())?); - } - } + // For trace log + let trace_state = if log_enabled!(target: "enact", ::log::Level::Trace) { + Some(State::from_existing(db.boxed_clone(), parent.state_root().clone(), engine.account_start_nonce(parent.number() + 1), factories.clone())?) + } else { + None + }; let mut b = OpenBlock::new( engine, @@ -491,13 +495,23 @@ fn enact( db, parent, last_hashes, - Address::new(), + // Engine such as Clique will calculate author from extra_data. + // this is only important for executing contracts as the 'executive_author'. + engine.executive_author(&header)?, (3141562.into(), 31415620.into()), vec![], is_epoch_begin, ancestry, )?; + if let Some(ref s) = trace_state { + let env = b.env_info(); + let root = s.root(); + let author_balance = s.balance(&env.author)?; + trace!(target: "enact", "num={}, root={}, author={}, author_balance={}\n", + b.block.header.number(), root, env.author, author_balance); + } + b.populate_from(&header); b.push_transactions(transactions)?; @@ -563,6 +577,7 @@ mod tests { last_hashes: Arc, factories: Factories, ) -> Result { + let block = Unverified::from_rlp(block_bytes)?; let header = block.header; let transactions: Result, Error> = block @@ -617,7 +632,7 @@ mod tests { ) -> Result { let header = Unverified::from_rlp(block_bytes.clone())?.header; Ok(enact_bytes(block_bytes, engine, tracing, db, parent, last_hashes, factories)? - .seal(engine, header.seal().to_vec())?) + .seal(engine, header.seal().to_vec())?) } #[test] diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index 9680c19dfc..193f48b20e 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -399,6 +399,7 @@ impl Importer { let db = client.state_db.read().boxed_clone_canon(header.parent_hash()); let is_epoch_begin = chain.epoch_transition(parent.number(), *header.parent_hash()).is_some(); + let enact_result = enact_verified( block, engine, @@ -2515,7 +2516,11 @@ impl SnapshotClient for Client {} impl Drop for Client { fn drop(&mut self) { - self.engine.stop(); + if let Some(c) = Arc::get_mut(&mut self.engine) { + c.stop() + } else { + warn!(target: "shutdown", "unable to get mut ref for engine for shutdown."); + } } } diff --git a/ethcore/src/engines/clique/block_state.rs b/ethcore/src/engines/clique/block_state.rs new file mode 100644 index 0000000000..4257076c06 --- /dev/null +++ b/ethcore/src/engines/clique/block_state.rs @@ -0,0 +1,369 @@ +// Copyright 2015-2019 Parity Technologies (UK) Ltd. +// This file is part of Parity Ethereum. + +// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . + +use std::collections::{HashMap, BTreeSet, VecDeque}; +use std::fmt; +use std::time::{Duration, SystemTime, UNIX_EPOCH}; + +use engines::EngineError; +use engines::clique::util::{extract_signers, recover_creator}; +use engines::clique::{VoteType, DIFF_INTURN, DIFF_NOTURN, NULL_AUTHOR, SIGNING_DELAY_NOTURN_MS}; +use error::{Error, BlockError}; +use ethereum_types::{Address, H64}; +use rand::Rng; +use types::BlockNumber; +use types::header::Header; +use unexpected::Mismatch; + +#[cfg(not(feature = "time_checked_add"))] +use time_utils::CheckedSystemTime; + +/// Type that keeps track of the state for a given vote +// Votes that go against the proposal aren't counted since it's equivalent to not voting +#[derive(Copy, Clone, Debug, PartialEq, PartialOrd)] +pub struct VoteState { + kind: VoteType, + votes: u64, +} + +/// Type that represent a vote +#[derive(Copy, Clone, Debug, PartialEq, PartialOrd)] +pub struct Vote { + block_number: BlockNumber, + beneficiary: Address, + kind: VoteType, + signer: Address, + reverted: bool, +} + +/// Type that represent a pending vote +#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq, PartialOrd)] +pub struct PendingVote { + signer: Address, + beneficiary: Address, +} + +/// Clique state for each block. +#[cfg(not(test))] +#[derive(Clone, Debug, Default)] +pub struct CliqueBlockState { + /// Current votes for a beneficiary + votes: HashMap, + /// A list of all votes for the given epoch + votes_history: Vec, + /// a list of all valid signer, sorted by ascending order. + signers: BTreeSet
, + /// a deque of recent signer, new entry should be pushed front, apply() modifies this. + recent_signers: VecDeque
, + /// inturn signing should wait until this time + pub next_timestamp_inturn: Option, + /// noturn signing should wait until this time + pub next_timestamp_noturn: Option, +} + +#[cfg(test)] +#[derive(Clone, Debug, Default)] +pub struct CliqueBlockState { + /// All recorded votes for a given signer, `Vec` is a stack of votes + pub votes: HashMap, + /// A list of all votes for the given epoch + pub votes_history: Vec, + /// a list of all valid signer, sorted by ascending order. + pub signers: BTreeSet
, + /// a deque of recent signer, new entry should be pushed front, apply() modifies this. + pub recent_signers: VecDeque
, + /// inturn signing should wait until this time + pub next_timestamp_inturn: Option, + /// noturn signing should wait until this time + pub next_timestamp_noturn: Option, +} + +impl fmt::Display for CliqueBlockState { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let signers: Vec = self.signers.iter() + .map(|s| + format!("{} {:?}", + s, + self.votes.iter().map(|(v, s)| format!("[beneficiary {}, votes: {}]", v.beneficiary, s.votes)) + .collect::>() + ) + ) + .collect(); + + let recent_signers: Vec = self.recent_signers.iter().map(|s| format!("{}", s)).collect(); + let num_votes = self.votes_history.len(); + let add_votes = self.votes_history.iter().filter(|v| v.kind == VoteType::Add).count(); + let rm_votes = self.votes_history.iter().filter(|v| v.kind == VoteType::Remove).count(); + let reverted_votes = self.votes_history.iter().filter(|v| v.reverted).count(); + + write!(f, + "Votes {{ \n signers: {:?} \n recent_signers: {:?} \n number of votes: {} \n number of add votes {} + \r number of remove votes {} \n number of reverted votes: {}}}", + signers, recent_signers, num_votes, add_votes, rm_votes, reverted_votes) + } +} + +impl CliqueBlockState { + /// Create new state with given information, this is used creating new state from Checkpoint block. + pub fn new(signers: BTreeSet
) -> Self { + CliqueBlockState { + signers, + ..Default::default() + } + } + + // see https://github.com/ethereum/go-ethereum/blob/master/consensus/clique/clique.go#L474 + fn verify(&self, header: &Header) -> Result { + let creator = recover_creator(header)?.clone(); + + // The signer is not authorized + if !self.signers.contains(&creator) { + trace!(target: "engine", "current state: {}", self); + Err(EngineError::NotAuthorized(creator))? + } + + // The signer has signed a block too recently + if self.recent_signers.contains(&creator) { + trace!(target: "engine", "current state: {}", self); + Err(EngineError::CliqueTooRecentlySigned(creator))? + } + + // Wrong difficulty + let inturn = self.is_inturn(header.number(), &creator); + + if inturn && *header.difficulty() != DIFF_INTURN { + Err(BlockError::InvalidDifficulty(Mismatch { + expected: DIFF_INTURN, + found: *header.difficulty(), + }))? + } + + if !inturn && *header.difficulty() != DIFF_NOTURN { + Err(BlockError::InvalidDifficulty(Mismatch { + expected: DIFF_NOTURN, + found: *header.difficulty(), + }))? + } + + Ok(creator) + } + + /// Verify and apply a new header to current state + pub fn apply(&mut self, header: &Header, is_checkpoint: bool) -> Result { + let creator = self.verify(header)?; + self.recent_signers.push_front(creator); + self.rotate_recent_signers(); + + if is_checkpoint { + // checkpoint block should not affect previous tallying, so we check that. + let signers = extract_signers(header)?; + if self.signers != signers { + let invalid_signers: Vec = signers.into_iter() + .filter(|s| !self.signers.contains(s)) + .map(|s| format!("{}", s)) + .collect(); + Err(EngineError::CliqueFaultyRecoveredSigners(invalid_signers))? + }; + + // TODO(niklasad1): I'm not sure if we should shrink here because it is likely that next epoch + // will need some memory and might be better for allocation algorithm to decide whether to shrink or not + // (typically doubles or halves the allocted memory when necessary) + self.votes.clear(); + self.votes_history.clear(); + self.votes.shrink_to_fit(); + self.votes_history.shrink_to_fit(); + } + + // Contains vote + if *header.author() != NULL_AUTHOR { + let decoded_seal = header.decode_seal::>()?; + if decoded_seal.len() != 2 { + Err(BlockError::InvalidSealArity(Mismatch { expected: 2, found: decoded_seal.len() }))? + } + + let nonce: H64 = decoded_seal[1].into(); + self.update_signers_on_vote(VoteType::from_nonce(nonce)?, creator, *header.author(), header.number())?; + } + + Ok(creator) + } + + fn update_signers_on_vote( + &mut self, + kind: VoteType, + signer: Address, + beneficiary: Address, + block_number: u64 + ) -> Result<(), Error> { + + trace!(target: "engine", "Attempt vote {:?} {:?}", kind, beneficiary); + + let pending_vote = PendingVote { signer, beneficiary }; + + let reverted = if self.is_valid_vote(&beneficiary, kind) { + self.add_vote(pending_vote, kind) + } else { + // This case only happens if a `signer` wants to revert their previous vote + // (does nothing if no previous vote was found) + self.revert_vote(pending_vote) + }; + + // Add all votes to the history + self.votes_history.push( + Vote { + block_number, + beneficiary, + kind, + signer, + reverted, + }); + + // If no vote was found for the beneficiary return `early` but don't propogate an error + let (votes, vote_kind) = match self.get_current_votes_and_kind(beneficiary) { + Some((v, k)) => (v, k), + None => return Ok(()), + }; + let threshold = self.signers.len() / 2; + + debug!(target: "engine", "{}/{} votes to have consensus", votes, threshold + 1); + trace!(target: "engine", "votes: {:?}", votes); + + if votes > threshold { + match vote_kind { + VoteType::Add => { + if self.signers.insert(beneficiary) { + debug!(target: "engine", "added new signer: {}", beneficiary); + } + } + VoteType::Remove => { + if self.signers.remove(&beneficiary) { + debug!(target: "engine", "removed signer: {}", beneficiary); + } + } + } + + self.rotate_recent_signers(); + self.remove_all_votes_from(beneficiary); + } + + Ok(()) + } + + /// Calculate the next timestamp for `inturn` and `noturn` fails if any of them can't be represented as + /// `SystemTime` + // TODO(niklasad1): refactor this method to be in constructor of `CliqueBlockState` instead. + // This is a quite bad API because we must mutate both variables even when already `inturn` fails + // That's why we can't return early and must have the `if-else` in the end + pub fn calc_next_timestamp(&mut self, timestamp: u64, period: u64) -> Result<(), Error> { + let inturn = UNIX_EPOCH.checked_add(Duration::from_secs(timestamp.saturating_add(period))); + + self.next_timestamp_inturn = inturn; + + let delay = Duration::from_millis( + rand::thread_rng().gen_range(0u64, (self.signers.len() as u64 / 2 + 1) * SIGNING_DELAY_NOTURN_MS)); + self.next_timestamp_noturn = inturn.map(|inturn| { + inturn + delay + }); + + if self.next_timestamp_inturn.is_some() && self.next_timestamp_noturn.is_some() { + Ok(()) + } else { + Err(BlockError::TimestampOverflow)? + } + } + + /// Returns true if the block difficulty should be `inturn` + pub fn is_inturn(&self, current_block_number: u64, author: &Address) -> bool { + if let Some(pos) = self.signers.iter().position(|x| *author == *x) { + return current_block_number % self.signers.len() as u64 == pos as u64; + } + false + } + + /// Returns whether the signer is authorized to sign a block + pub fn is_authorized(&self, author: &Address) -> bool { + self.signers.contains(author) && !self.recent_signers.contains(author) + } + + /// Returns whether it makes sense to cast the specified vote in the + /// current state (e.g. don't try to add an already authorized signer). + pub fn is_valid_vote(&self, address: &Address, vote_type: VoteType) -> bool { + let in_signer = self.signers.contains(address); + match vote_type { + VoteType::Add => !in_signer, + VoteType::Remove => in_signer, + } + } + + /// Returns the list of current signers + pub fn signers(&self) -> &BTreeSet
{ + &self.signers + } + + // Note this method will always return `true` but it is intended for a uniform `API` + fn add_vote(&mut self, pending_vote: PendingVote, kind: VoteType) -> bool { + + self.votes.entry(pending_vote) + .and_modify(|state| { + state.votes = state.votes.saturating_add(1); + }) + .or_insert_with(|| VoteState { kind, votes: 1 }); + true + } + + fn revert_vote(&mut self, pending_vote: PendingVote) -> bool { + let mut revert = false; + let mut remove = false; + + self.votes.entry(pending_vote).and_modify(|state| { + if state.votes.saturating_sub(1) == 0 { + remove = true; + } + revert = true; + }); + + if remove { + self.votes.remove(&pending_vote); + } + + revert + } + + fn get_current_votes_and_kind(&self, beneficiary: Address) -> Option<(usize, VoteType)> { + let kind = self.votes.iter() + .find(|(v, _t)| v.beneficiary == beneficiary) + .map(|(_v, t)| t.kind)?; + + let votes = self.votes.keys() + .filter(|vote| vote.beneficiary == beneficiary) + .count(); + + Some((votes, kind)) + } + + fn rotate_recent_signers(&mut self) { + if self.recent_signers.len() >= ( self.signers.len() / 2 ) + 1 { + self.recent_signers.pop_back(); + } + } + + fn remove_all_votes_from(&mut self, beneficiary: Address) { + self.votes = std::mem::replace(&mut self.votes, HashMap::new()) + .into_iter() + .filter(|(v, _t)| v.signer != beneficiary && v.beneficiary != beneficiary) + .collect(); + } +} diff --git a/ethcore/src/engines/clique/mod.rs b/ethcore/src/engines/clique/mod.rs new file mode 100644 index 0000000000..f5e83440dd --- /dev/null +++ b/ethcore/src/engines/clique/mod.rs @@ -0,0 +1,768 @@ +// Copyright 2015-2019 Parity Technologies (UK) Ltd. +// This file is part of Parity Ethereum. + +// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . + +//! Implementation of the Clique PoA Engine. +//! +//! File structure: +//! - mod.rs -> Provides the engine API implementation, with additional block state tracking +//! - block_state.rs -> Records the Clique state for given block. +//! - params.rs -> Contains the parameters for the Clique engine. +//! - step_service.rs -> An event loop to trigger sealing. +//! - util.rs -> Various standalone utility functions. +//! - tests.rs -> Consensus tests as defined in EIP-225. + +/// How syncing works: +/// +/// 1. Client will call: +/// - `Clique::verify_block_basic()` +/// - `Clique::verify_block_unordered()` +/// - `Clique::verify_block_family()` +/// 2. Using `Clique::state()` we try and retrieve the parent state. If this isn't found +/// we need to back-fill it from the last known checkpoint. +/// 3. Once we have a good state, we can record it using `CliqueBlockState::apply()`. + +/// How sealing works: +/// +/// 1. Set a signer using `Engine::set_signer()`. If a miner account was set up through +/// a config file or CLI flag `MinerService::set_author()` will eventually set the signer +/// 2. We check that the engine seals internally through `Clique::seals_internally()` +/// Note: This is always true for Clique +/// 3. Calling `Clique::new()` will spawn a `StepService` thread. This thread will call `Engine::step()` +/// periodically. Internally, the Clique `step()` function calls `Client::update_sealing()`, which is +/// what makes and seals a block. +/// 4. `Clique::generate_seal()` will then be called by `miner`. This will return a `Seal` which +/// is either a `Seal::None` or `Seal:Regular`. The following shows how a `Seal` variant is chosen: +/// a. We return `Seal::None` if no signer is available or the signer is not authorized. +/// b. If period == 0 and block has transactions, we return `Seal::Regular`, otherwise return `Seal::None`. +/// c. If we're `INTURN`, wait for at least `period` since last block before trying to seal. +/// d. If we're not `INTURN`, we wait for a random amount of time using the algorithm specified +/// in EIP-225 before trying to seal again. +/// 5. Miner will create new block, in process it will call several engine methods to do following: +/// a. `Clique::open_block_header_timestamp()` must set timestamp correctly. +/// b. `Clique::populate_from_parent()` must set difficulty to correct value. +/// Note: `Clique::populate_from_parent()` is used in both the syncing and sealing code paths. +/// 6. We call `Clique::on_seal_block()` which will allow us to modify the block header during seal generation. +/// 7. Finally, `Clique::verify_local_seal()` is called. After this, the syncing code path will be followed +/// in order to import the new block. + +use std::cmp; +use std::collections::HashMap; +use std::collections::VecDeque; +use std::sync::{Arc, Weak}; +use std::thread; +use std::time; +use std::time::{Duration, SystemTime, UNIX_EPOCH}; + +use block::ExecutedBlock; +use client::{BlockId, EngineClient}; +use engines::clique::util::{extract_signers, recover_creator}; +use engines::{Engine, EngineError, Seal}; +use error::{BlockError, Error}; +use ethereum_types::{Address, H64, H160, H256, U256}; +use ethkey::Signature; +use hash::KECCAK_EMPTY_LIST_RLP; +use itertools::Itertools; +use lru_cache::LruCache; +use machine::{Call, EthereumMachine}; +use parking_lot::RwLock; +use rand::Rng; +use super::signer::EngineSigner; +use unexpected::{Mismatch, OutOfBounds}; +use types::BlockNumber; +use types::header::{ExtendedHeader, Header}; + +#[cfg(not(feature = "time_checked_add"))] +use time_utils::CheckedSystemTime; + +use self::block_state::CliqueBlockState; +use self::params::CliqueParams; +use self::step_service::StepService; + +mod params; +mod block_state; +mod step_service; +mod util; + +// TODO(niklasad1): extract tester types into a separate mod to be shared in the code base +#[cfg(test)] +mod tests; + +// Protocol constants +/// Fixed number of extra-data prefix bytes reserved for signer vanity +pub const VANITY_LENGTH: usize = 32; +/// Fixed number of extra-data suffix bytes reserved for signer signature +pub const SIGNATURE_LENGTH: usize = 65; +/// Address length of signer +pub const ADDRESS_LENGTH: usize = 20; +/// Nonce value for DROP vote +pub const NONCE_DROP_VOTE: H64 = H64([0; 8]); +/// Nonce value for AUTH vote +pub const NONCE_AUTH_VOTE: H64 = H64([0xff; 8]); +/// Difficulty for INTURN block +pub const DIFF_INTURN: U256 = U256([2, 0, 0, 0]); +/// Difficulty for NOTURN block +pub const DIFF_NOTURN: U256 = U256([1, 0, 0, 0]); +/// Default empty author field value +pub const NULL_AUTHOR: Address = H160([0x00; 20]); +/// Default empty nonce value +pub const NULL_NONCE: H64 = NONCE_DROP_VOTE; +/// Default value for mixhash +pub const NULL_MIXHASH: H256 = H256([0; 32]); +/// Default value for uncles hash +pub const NULL_UNCLES_HASH: H256 = KECCAK_EMPTY_LIST_RLP; +/// Default noturn block wiggle factor defined in spec. +pub const SIGNING_DELAY_NOTURN_MS: u64 = 500; + +/// How many CliqueBlockState to cache in the memory. +pub const STATE_CACHE_NUM: usize = 128; + +/// Vote to add or remove the beneficiary +#[derive(Copy, Clone, Debug, PartialEq, PartialOrd)] +pub enum VoteType { + Add, + Remove, +} + +impl VoteType { + /// Try to construct a `Vote` from a nonce + pub fn from_nonce(nonce: H64) -> Result { + if nonce == NONCE_AUTH_VOTE { + Ok(VoteType::Add) + } else if nonce == NONCE_DROP_VOTE { + Ok(VoteType::Remove) + } else { + Err(EngineError::CliqueInvalidNonce(nonce))? + } + } + + /// Get the rlp encoding of the vote + pub fn as_rlp(&self) -> Vec> { + match self { + VoteType::Add => vec![rlp::encode(&NULL_MIXHASH), rlp::encode(&NONCE_AUTH_VOTE)], + VoteType::Remove => vec![rlp::encode(&NULL_MIXHASH), rlp::encode(&NONCE_DROP_VOTE)], + } + } +} + +/// Clique Engine implementation +// block_state_by_hash -> block state indexed by header hash. +#[cfg(not(test))] +pub struct Clique { + epoch_length: u64, + period: u64, + machine: EthereumMachine, + client: RwLock>>, + block_state_by_hash: RwLock>, + proposals: RwLock>, + signer: RwLock>>, + step_service: Option>, +} + +#[cfg(test)] +/// Test version of `CliqueEngine` to make all fields public +pub struct Clique { + pub epoch_length: u64, + pub period: u64, + pub machine: EthereumMachine, + pub client: RwLock>>, + pub block_state_by_hash: RwLock>, + pub proposals: RwLock>, + pub signer: RwLock>>, + pub step_service: Option>, +} + +impl Clique { + /// Initialize Clique engine from empty state. + pub fn new(our_params: CliqueParams, machine: EthereumMachine) -> Result, Error> { + let mut engine = Clique { + epoch_length: our_params.epoch, + period: our_params.period, + client: Default::default(), + block_state_by_hash: RwLock::new(LruCache::new(STATE_CACHE_NUM)), + proposals: Default::default(), + signer: Default::default(), + machine, + step_service: None, + }; + + let res = Arc::new(engine); + + if our_params.period > 0 { + engine.step_service = Some(StepService::start(Arc::downgrade(&res) as Weak>)); + } + + Ok(res) + } + + #[cfg(test)] + /// Initialize test variant of `CliqueEngine`, + /// Note we need to `mock` the miner and it is introduced to test block verification to trigger new blocks + /// to mainly test consensus edge cases + pub fn with_test(epoch_length: u64, period: u64) -> Self { + use spec::Spec; + + Self { + epoch_length, + period, + client: Default::default(), + block_state_by_hash: RwLock::new(LruCache::new(STATE_CACHE_NUM)), + proposals: Default::default(), + signer: Default::default(), + machine: Spec::new_test_machine(), + step_service: None, + } + } + + fn sign_header(&self, header: &Header) -> Result<(Signature, H256), Error> { + + match self.signer.read().as_ref() { + None => { + Err(EngineError::RequiresSigner)? + } + Some(signer) => { + let digest = header.hash(); + match signer.sign(digest) { + Ok(sig) => Ok((sig, digest)), + Err(e) => Err(EngineError::Custom(e.into()))?, + } + } + } + } + + /// Construct an new state from given checkpoint header. + fn new_checkpoint_state(&self, header: &Header) -> Result { + debug_assert_eq!(header.number() % self.epoch_length, 0); + + let mut state = CliqueBlockState::new( + extract_signers(header)?); + + // TODO(niklasad1): refactor to perform this check in the `CliqueBlockState` constructor instead + state.calc_next_timestamp(header.timestamp(), self.period)?; + + Ok(state) + } + + fn state_no_backfill(&self, hash: &H256) -> Option { + self.block_state_by_hash.write().get_mut(hash).cloned() + } + + /// Get `CliqueBlockState` for given header, backfill from last checkpoint if needed. + fn state(&self, header: &Header) -> Result { + let mut block_state_by_hash = self.block_state_by_hash.write(); + if let Some(state) = block_state_by_hash.get_mut(&header.hash()) { + return Ok(state.clone()); + } + // If we are looking for an checkpoint block state, we can directly reconstruct it. + if header.number() % self.epoch_length == 0 { + let state = self.new_checkpoint_state(header)?; + block_state_by_hash.insert(header.hash(), state.clone()); + return Ok(state); + } + // BlockState is not found in memory, which means we need to reconstruct state from last checkpoint. + match self.client.read().as_ref().and_then(|w| w.upgrade()) { + None => { + return Err(EngineError::RequiresClient)?; + } + Some(c) => { + let last_checkpoint_number = header.number() - header.number() % self.epoch_length as u64; + debug_assert_ne!(last_checkpoint_number, header.number()); + + let mut chain: &mut VecDeque
= &mut VecDeque::with_capacity( + (header.number() - last_checkpoint_number + 1) as usize); + + // Put ourselves in. + chain.push_front(header.clone()); + + // populate chain to last checkpoint + loop { + let (last_parent_hash, last_num) = { + let l = chain.front().expect("chain has at least one element; qed"); + (*l.parent_hash(), l.number()) + }; + + if last_num == last_checkpoint_number + 1 { + break; + } + match c.block_header(BlockId::Hash(last_parent_hash)) { + None => { + return Err(BlockError::UnknownParent(last_parent_hash))?; + } + Some(next) => { + chain.push_front(next.decode()?); + } + } + } + + // Catching up state, note that we don't really store block state for intermediary blocks, + // for speed. + let backfill_start = time::Instant::now(); + trace!(target: "engine", + "Back-filling block state. last_checkpoint_number: {}, target: {}({}).", + last_checkpoint_number, header.number(), header.hash()); + + // Get the state for last checkpoint. + let last_checkpoint_hash = *chain.front() + .expect("chain has at least one element; qed") + .parent_hash(); + + let last_checkpoint_header = match c.block_header(BlockId::Hash(last_checkpoint_hash)) { + None => return Err(EngineError::CliqueMissingCheckpoint(last_checkpoint_hash))?, + Some(header) => header.decode()?, + }; + + let last_checkpoint_state = match block_state_by_hash.get_mut(&last_checkpoint_hash) { + Some(state) => state.clone(), + None => self.new_checkpoint_state(&last_checkpoint_header)?, + }; + + block_state_by_hash.insert(last_checkpoint_header.hash(), last_checkpoint_state.clone()); + + // Backfill! + let mut new_state = last_checkpoint_state.clone(); + for item in chain { + new_state.apply(item, false)?; + } + new_state.calc_next_timestamp(header.timestamp(), self.period)?; + block_state_by_hash.insert(header.hash(), new_state.clone()); + + let elapsed = backfill_start.elapsed(); + trace!(target: "engine", "Back-filling succeed, took {} ms.", elapsed.as_millis()); + Ok(new_state) + } + } + } +} + +impl Engine for Clique { + fn name(&self) -> &str { "Clique" } + + fn machine(&self) -> &EthereumMachine { &self.machine } + + // Clique use same fields, nonce + mixHash + fn seal_fields(&self, _header: &Header) -> usize { 2 } + + fn maximum_uncle_count(&self, _block: BlockNumber) -> usize { 0 } + + fn on_new_block( + &self, + _block: &mut ExecutedBlock, + _epoch_begin: bool, + _ancestry: &mut Iterator, + ) -> Result<(), Error> { + Ok(()) + } + + // Clique has no block reward. + fn on_close_block(&self, _block: &mut ExecutedBlock) -> Result<(), Error> { + Ok(()) + } + + fn on_seal_block(&self, block: &mut ExecutedBlock) -> Result<(), Error> { + trace!(target: "engine", "on_seal_block"); + + let header = &mut block.header; + + let state = self.state_no_backfill(header.parent_hash()) + .ok_or_else(|| BlockError::UnknownParent(*header.parent_hash()))?; + + let is_checkpoint = header.number() % self.epoch_length == 0; + + header.set_author(NULL_AUTHOR); + + // Cast a random Vote if not checkpoint + if !is_checkpoint { + // TODO(niklasad1): this will always be false because `proposals` is never written to + let votes = self.proposals.read().iter() + .filter(|(address, vote_type)| state.is_valid_vote(*address, **vote_type)) + .map(|(address, vote_type)| (*address, *vote_type)) + .collect_vec(); + + if !votes.is_empty() { + // Pick a random vote. + let random_vote = rand::thread_rng().gen_range(0 as usize, votes.len()); + let (beneficiary, vote_type) = votes[random_vote]; + + trace!(target: "engine", "Casting vote: beneficiary {}, type {:?} ", beneficiary, vote_type); + + header.set_author(beneficiary); + header.set_seal(vote_type.as_rlp()); + } + } + + // Work on clique seal. + + let mut seal: Vec = Vec::with_capacity(VANITY_LENGTH + SIGNATURE_LENGTH); + + // At this point, extra_data should only contain miner vanity. + if header.extra_data().len() != VANITY_LENGTH { + Err(BlockError::ExtraDataOutOfBounds(OutOfBounds { + min: Some(VANITY_LENGTH), + max: Some(VANITY_LENGTH), + found: header.extra_data().len() + }))?; + } + // vanity + { + seal.extend_from_slice(&header.extra_data()[0..VANITY_LENGTH]); + } + + // If we are building an checkpoint block, add all signers now. + if is_checkpoint { + seal.reserve(state.signers().len() * 20); + state.signers().iter().foreach(|addr| { + seal.extend_from_slice(&addr[..]); + }); + } + + header.set_extra_data(seal.clone()); + + // append signature onto extra_data + let (sig, _msg) = self.sign_header(&header)?; + seal.extend_from_slice(&sig[..]); + header.set_extra_data(seal.clone()); + + header.compute_hash(); + + // locally sealed block don't go through valid_block_family(), so we have to record state here. + let mut new_state = state.clone(); + new_state.apply(&header, is_checkpoint)?; + new_state.calc_next_timestamp(header.timestamp(), self.period)?; + self.block_state_by_hash.write().insert(header.hash(), new_state); + + trace!(target: "engine", "on_seal_block: finished, final header: {:?}", header); + + Ok(()) + } + + /// Clique doesn't require external work to seal, so we always return true here. + fn seals_internally(&self) -> Option { + Some(true) + } + + /// Returns if we are ready to seal, the real sealing (signing extra_data) is actually done in `on_seal_block()`. + fn generate_seal(&self, block: &ExecutedBlock, parent: &Header) -> Seal { + trace!(target: "engine", "tried to generate_seal"); + let null_seal = util::null_seal(); + + if block.header.number() == 0 { + trace!(target: "engine", "attempted to seal genesis block"); + return Seal::None; + } + + // if sealing period is 0, and not an checkpoint block, refuse to seal + if self.period == 0 { + if block.transactions.is_empty() && block.header.number() % self.epoch_length != 0 { + return Seal::None; + } + return Seal::Regular(null_seal); + } + + // Check we actually have authority to seal. + if let Some(author) = self.signer.read().as_ref().map(|x| x.address()) { + + // ensure the voting state exists + match self.state(&parent) { + Err(e) => { + warn!(target: "engine", "generate_seal: can't get parent state(number: {}, hash: {}): {} ", + parent.number(), parent.hash(), e); + return Seal::None; + } + Ok(state) => { + // Are we authorized to seal? + if !state.is_authorized(&author) { + trace!(target: "engine", "generate_seal: Not authorized to sign right now."); + // wait for one third of period to try again. + thread::sleep(Duration::from_secs(self.period / 3 + 1)); + return Seal::None; + } + + let inturn = state.is_inturn(block.header.number(), &author); + + let now = SystemTime::now(); + + let limit = match inturn { + true => state.next_timestamp_inturn.unwrap_or(now), + false => state.next_timestamp_noturn.unwrap_or(now), + }; + + // Wait for the right moment. + if now < limit { + trace!(target: "engine", + "generate_seal: sleeping to sign: inturn: {}, now: {:?}, to: {:?}.", + inturn, now, limit); + match limit.duration_since(SystemTime::now()) { + Ok(duration) => { + thread::sleep(duration); + }, + Err(e) => { + warn!(target:"engine", "generate_seal: unable to sleep, err: {}", e); + return Seal::None; + } + } + } + + trace!(target: "engine", "generate_seal: seal ready for block {}, txs: {}.", + block.header.number(), block.transactions.len()); + return Seal::Regular(null_seal); + } + } + } + Seal::None + } + + fn verify_local_seal(&self, _header: &Header) -> Result<(), Error> { Ok(()) } + + fn verify_block_basic(&self, header: &Header) -> Result<(), Error> { + // Largely same as https://github.com/ethereum/go-ethereum/blob/master/consensus/clique/clique.go#L275 + + // Ignore genesis block. + if header.number() == 0 { + return Ok(()); + } + + // Don't waste time checking blocks from the future + { + let limit = SystemTime::now().checked_add(Duration::from_secs(self.period)) + .ok_or(BlockError::TimestampOverflow)?; + + // This should succeed under the contraints that the system clock works + let limit_as_dur = limit.duration_since(UNIX_EPOCH).map_err(|e| { + Box::new(format!("Converting SystemTime to Duration failed: {}", e)) + })?; + + let hdr = Duration::from_secs(header.timestamp()); + if hdr > limit_as_dur { + let found = UNIX_EPOCH.checked_add(hdr).ok_or(BlockError::TimestampOverflow)?; + + Err(BlockError::TemporarilyInvalid(OutOfBounds { + min: None, + max: Some(limit), + found, + }))? + } + } + + let is_checkpoint = header.number() % self.epoch_length == 0; + + if is_checkpoint && *header.author() != NULL_AUTHOR { + return Err(EngineError::CliqueWrongAuthorCheckpoint(Mismatch { + expected: 0.into(), + found: *header.author(), + }))?; + } + + let seal_fields = header.decode_seal::>()?; + if seal_fields.len() != 2 { + Err(BlockError::InvalidSealArity(Mismatch { + expected: 2, + found: seal_fields.len(), + }))? + } + + let mixhash: H256 = seal_fields[0].into(); + let nonce: H64 = seal_fields[1].into(); + + // Nonce must be 0x00..0 or 0xff..f + if nonce != NONCE_DROP_VOTE && nonce != NONCE_AUTH_VOTE { + Err(EngineError::CliqueInvalidNonce(nonce))?; + } + + if is_checkpoint && nonce != NULL_NONCE { + Err(EngineError::CliqueInvalidNonce(nonce))?; + } + + // Ensure that the mix digest is zero as Clique don't have fork protection currently + if mixhash != NULL_MIXHASH { + Err(BlockError::MismatchedH256SealElement(Mismatch { + expected: NULL_MIXHASH, + found: mixhash, + }))? + } + + let extra_data_len = header.extra_data().len(); + + if extra_data_len < VANITY_LENGTH { + Err(EngineError::CliqueMissingVanity)? + } + + if extra_data_len < VANITY_LENGTH + SIGNATURE_LENGTH { + Err(EngineError::CliqueMissingSignature)? + } + + let signers = extra_data_len - (VANITY_LENGTH + SIGNATURE_LENGTH); + + // Checkpoint blocks must at least contain one signer + if is_checkpoint && signers == 0 { + Err(EngineError::CliqueCheckpointNoSigner)? + } + + // Addresses must be be divisable by 20 + if is_checkpoint && signers % ADDRESS_LENGTH != 0 { + Err(EngineError::CliqueCheckpointInvalidSigners(signers))? + } + + // Ensure that the block doesn't contain any uncles which are meaningless in PoA + if *header.uncles_hash() != NULL_UNCLES_HASH { + Err(BlockError::InvalidUnclesHash(Mismatch { + expected: NULL_UNCLES_HASH, + found: *header.uncles_hash(), + }))? + } + + // Ensure that the block's difficulty is meaningful (may not be correct at this point) + if *header.difficulty() != DIFF_INTURN && *header.difficulty() != DIFF_NOTURN { + Err(BlockError::DifficultyOutOfBounds(OutOfBounds { + min: Some(DIFF_NOTURN), + max: Some(DIFF_INTURN), + found: *header.difficulty(), + }))? + } + + // All basic checks passed, continue to next phase + Ok(()) + } + + fn verify_block_unordered(&self, _header: &Header) -> Result<(), Error> { + // Nothing to check here. + Ok(()) + } + + /// Verify block family by looking up parent state (backfill if needed), then try to apply current header. + /// see https://github.com/ethereum/go-ethereum/blob/master/consensus/clique/clique.go#L338 + fn verify_block_family(&self, header: &Header, parent: &Header) -> Result<(), Error> { + // Ignore genesis block. + if header.number() == 0 { + return Ok(()); + } + + // parent sanity check + if parent.hash() != *header.parent_hash() || header.number() != parent.number() + 1 { + Err(BlockError::UnknownParent(parent.hash()))? + } + + // Ensure that the block's timestamp isn't too close to it's parent + let limit = parent.timestamp().saturating_add(self.period); + if limit > header.timestamp() { + let max = UNIX_EPOCH.checked_add(Duration::from_secs(header.timestamp())); + let found = UNIX_EPOCH.checked_add(Duration::from_secs(limit)) + .ok_or(BlockError::TimestampOverflow)?; + + Err(BlockError::InvalidTimestamp(OutOfBounds { + min: None, + max, + found, + }))? + } + + // Retrieve the parent state + let parent_state = self.state(&parent)?; + // Try to apply current state, apply() will further check signer and recent signer. + let mut new_state = parent_state.clone(); + new_state.apply(header, header.number() % self.epoch_length == 0)?; + new_state.calc_next_timestamp(header.timestamp(), self.period)?; + self.block_state_by_hash.write().insert(header.hash(), new_state); + + Ok(()) + } + + fn genesis_epoch_data(&self, header: &Header, _call: &Call) -> Result, String> { + let mut state = self.new_checkpoint_state(header).expect("Unable to parse genesis data."); + state.calc_next_timestamp(header.timestamp(), self.period).map_err(|e| format!("{}", e))?; + self.block_state_by_hash.write().insert(header.hash(), state); + + // no proof. + Ok(Vec::new()) + } + + // Our task here is to set difficulty + fn populate_from_parent(&self, header: &mut Header, parent: &Header) { + // TODO(https://github.com/paritytech/parity-ethereum/issues/10410): this is a horrible hack, + // it is due to the fact that enact and miner both use OpenBlock::new() which will both call + // this function. more refactoring is definitely needed. + if header.extra_data().len() < VANITY_LENGTH + SIGNATURE_LENGTH { + trace!(target: "engine", "populate_from_parent in sealing"); + + // It's unclear how to prevent creating new blocks unless we are authorized, the best way (and geth does this too) + // it's just to ignore setting an correct difficulty here, we will check authorization in next step in generate_seal anyway. + if let Some(signer) = self.signer.read().as_ref() { + let state = match self.state(&parent) { + Err(e) => { + trace!(target: "engine", "populate_from_parent: Unable to find parent state: {}, ignored.", e); + return; + } + Ok(state) => state, + }; + + if state.is_authorized(&signer.address()) { + if state.is_inturn(header.number(), &signer.address()) { + header.set_difficulty(DIFF_INTURN); + } else { + header.set_difficulty(DIFF_NOTURN); + } + } + } else { + trace!(target: "engine", "populate_from_parent: no signer registered"); + } + } + } + + fn set_signer(&self, signer: Box) { + trace!(target: "engine", "set_signer: {}", signer.address()); + *self.signer.write() = Some(signer); + } + + fn register_client(&self, client: Weak) { + *self.client.write() = Some(client.clone()); + } + + fn step(&self) { + if self.signer.read().is_some() { + if let Some(ref weak) = *self.client.read() { + if let Some(c) = weak.upgrade() { + c.update_sealing(); + } + } + } + } + + fn stop(&mut self) { + if let Some(mut s) = self.step_service.as_mut() { + Arc::get_mut(&mut s).map(|x| x.stop()); + } else { + warn!(target: "engine", "Stopping `CliqueStepService` failed requires mutable access"); + } + } + + /// Clique timestamp is set to parent + period , or current time which ever is higher. + fn open_block_header_timestamp(&self, parent_timestamp: u64) -> u64 { + let now = time::SystemTime::now().duration_since(time::UNIX_EPOCH).unwrap_or_default(); + cmp::max(now.as_secs() as u64, parent_timestamp.saturating_add(self.period)) + } + + fn is_timestamp_valid(&self, header_timestamp: u64, parent_timestamp: u64) -> bool { + header_timestamp >= parent_timestamp.saturating_add(self.period) + } + + fn fork_choice(&self, new: &ExtendedHeader, current: &ExtendedHeader) -> super::ForkChoice { + super::total_difficulty_fork_choice(new, current) + } + + // Clique uses the author field for voting, the real author is hidden in the `extra_data` field. + // So when executing tx's (like in `enact()`) we want to use the executive author + fn executive_author(&self, header: &Header) -> Result { + recover_creator(header) + } +} diff --git a/ethcore/src/engines/clique/params.rs b/ethcore/src/engines/clique/params.rs new file mode 100644 index 0000000000..e24edfcbac --- /dev/null +++ b/ethcore/src/engines/clique/params.rs @@ -0,0 +1,41 @@ +// Copyright 2015-2019 Parity Technologies (UK) Ltd. +// This file is part of Parity Ethereum. + +// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . + +//! Clique specific parameters. + +use ethjson; + +/// `Clique` params. +pub struct CliqueParams { + /// Period as defined in EIP + pub period: u64, + /// Epoch length as defined in EIP + pub epoch: u64, +} + +impl From for CliqueParams { + fn from(p: ethjson::spec::CliqueParams) -> Self { + let period = p.period.map_or_else(|| 30000 as u64, Into::into); + let epoch = p.epoch.map_or_else(|| 15 as u64, Into::into); + + assert!(epoch > 0); + + CliqueParams { + period, + epoch, + } + } +} diff --git a/ethcore/src/engines/clique/step_service.rs b/ethcore/src/engines/clique/step_service.rs new file mode 100644 index 0000000000..7a4b5269d2 --- /dev/null +++ b/ethcore/src/engines/clique/step_service.rs @@ -0,0 +1,77 @@ +// Copyright 2015-2019 Parity Technologies (UK) Ltd. +// This file is part of Parity Ethereum. + +// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . + + +use std::sync::Weak; +use std::sync::atomic::{AtomicBool, Ordering}; +use std::time::Duration; +use std::thread; +use std::sync::Arc; + +use engines::Engine; +use machine::Machine; + +/// Service that is managing the engine +pub struct StepService { + shutdown: Arc, + thread: Option>, +} + +impl StepService { + /// Start the `StepService` + pub fn start(engine: Weak>) -> Arc { + let shutdown = Arc::new(AtomicBool::new(false)); + let s = shutdown.clone(); + + let thread = thread::Builder::new() + .name("CliqueStepService".into()) + .spawn(move || { + // startup delay. + thread::sleep(Duration::from_secs(5)); + + loop { + // see if we are in shutdown. + if shutdown.load(Ordering::Acquire) { + trace!(target: "miner", "CliqueStepService: received shutdown signal!"); + break; + } + + trace!(target: "miner", "CliqueStepService: triggering sealing"); + + // Try sealing + engine.upgrade().map(|x| x.step()); + + // Yield + thread::sleep(Duration::from_millis(2000)); + } + trace!(target: "miner", "CliqueStepService: shutdown."); + }).expect("CliqueStepService thread failed"); + + Arc::new(StepService { + shutdown: s, + thread: Some(thread), + }) + } + + /// Stop the `StepService` + pub fn stop(&mut self) { + trace!(target: "miner", "CliqueStepService: shutting down."); + self.shutdown.store(true, Ordering::Release); + if let Some(t) = self.thread.take() { + t.join().expect("CliqueStepService thread panicked!"); + } + } +} diff --git a/ethcore/src/engines/clique/tests.rs b/ethcore/src/engines/clique/tests.rs new file mode 100644 index 0000000000..c7916192dd --- /dev/null +++ b/ethcore/src/engines/clique/tests.rs @@ -0,0 +1,804 @@ +// Copyright 2015-2019 Parity Technologies (UK) Ltd. +// This file is part of Parity Ethereum. + +// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . + +//! Consensus tests for `PoA Clique Engine`, see http://eips.ethereum.org/EIPS/eip-225 for more information + +use block::*; +use engines::Engine; +use error::{Error, ErrorKind}; +use ethereum_types::{Address, H256}; +use ethkey::{Secret, KeyPair}; +use state_db::StateDB; +use super::*; +use test_helpers::get_temp_state_db; + +use std::sync::Arc; +use std::collections::HashMap; + +/// Possible signers +pub const SIGNER_TAGS: [char; 6] = ['A', 'B', 'C', 'D', 'E', 'F']; + +/// Clique block types +pub enum CliqueBlockType { + /// Epoch transition block must contain list of signers + Checkpoint, + /// Block with no votes + Empty, + /// Vote + Vote(VoteType), +} + +/// Clique tester +pub struct CliqueTester { + /// Mocked Clique + pub clique: Clique, + /// Mocked genesis state + pub genesis: Header, + /// StateDB + pub db: StateDB, + /// List of signers + pub signers: HashMap, +} + +impl CliqueTester { + /// Create a `Clique` tester with settings + pub fn with(epoch: u64, period: u64, initial_signers: Vec) -> Self { + assert_eq!(initial_signers.iter().all(|s| SIGNER_TAGS.contains(s)), true, + "Not all the initial signers is in SIGNER_TAGS, possible keys are 'A' ..= 'F'"); + + let clique = Clique::with_test(epoch, period); + let mut genesis = Header::default(); + let mut signers = HashMap::new(); + + let call = |_a, _b| { + unimplemented!("Clique doesn't use Engine::Call"); + }; + + let mut extra_data = vec![0; VANITY_LENGTH]; + + for &signer in SIGNER_TAGS.iter() { + let secret = Secret::from(H256::from(signer as u64)); + let keypair = KeyPair::from_secret(secret).unwrap(); + if initial_signers.contains(&signer) { + extra_data.extend(&*keypair.address()); + } + signers.insert(signer, keypair); + } + + // append dummy signature + extra_data.extend(std::iter::repeat(0).take(SIGNATURE_LENGTH)); + + genesis.set_extra_data(extra_data); + genesis.set_gas_limit(U256::from(0xa00000)); + genesis.set_difficulty(U256::from(1)); + genesis.set_seal(util::null_seal()); + + clique.genesis_epoch_data(&genesis, &call).expect("Create genesis failed"); + Self {clique, genesis, db: get_temp_state_db(), signers} + } + + /// Get difficulty for a given block + pub fn get_difficulty(&self, block_num: BlockNumber, header: &Header, signer: &Address) -> U256 { + let state = self.clique.state(header).unwrap(); + if state.is_inturn(block_num, signer) { + DIFF_INTURN + } else { + DIFF_NOTURN + } + } + + /// Get the state of a given block + // Note, this will read the cache and `will` not work with more than 128 blocks + pub fn get_state_at_block(&self, hash: &H256) -> CliqueBlockState { + self.clique.block_state_by_hash.write() + .get_mut(hash) + .expect("CliqueBlockState not found tested failed") + .clone() + } + + /// Get signers after a certain state + // This is generally used to fetch the state after a test has been executed and checked against + // the intial list of signers provided in the test + pub fn clique_signers(&self, hash: &H256) -> impl Iterator { + self.get_state_at_block(hash).signers().clone().into_iter() + } + + /// Fetches all addresses at current `block` and converts them back to `tags (char)` and sorts them + /// Addresses are supposed sorted based on address but these tests are using `tags` just for simplicity + /// and the order is not important! + pub fn into_tags>(&self, addr: T) -> Vec { + let mut tags: Vec = addr.filter_map(|addr| { + for (t, kp) in self.signers.iter() { + if addr == kp.address() { + return Some(*t) + } + } + None + }) + .collect(); + + tags.sort(); + tags + } + + /// Create a new `Clique` block and import + pub fn new_block_and_import( + &self, + block_type: CliqueBlockType, + last_header: &Header, + beneficary: Option
, + signer: char, + ) -> Result { + + let mut extra_data = vec![0; VANITY_LENGTH]; + let mut seal = util::null_seal(); + let last_hash = last_header.hash(); + + match block_type { + CliqueBlockType::Checkpoint => { + let signers = self.clique.state(&last_header).unwrap().signers().clone(); + for signer in signers { + extra_data.extend(&*signer); + } + } + CliqueBlockType::Vote(v) => seal = v.as_rlp(), + CliqueBlockType::Empty => (), + }; + + let db = self.db.boxed_clone(); + + let mut block = OpenBlock::new( + &self.clique, + Default::default(), + false, + db, + &last_header.clone(), + Arc::new(vec![last_hash]), + beneficary.unwrap_or_default(), + (3141562.into(), 31415620.into()), + extra_data, + false, + None, + ).unwrap(); + + { + let difficulty = self.get_difficulty(block.header.number(), last_header, &self.signers[&signer].address()); + let b = block.block_mut(); + b.header.set_timestamp(last_header.timestamp() + self.clique.period); + b.header.set_difficulty(difficulty); + b.header.set_seal(seal); + + let sign = ethkey::sign(self.signers[&signer].secret(), &b.header.hash()).unwrap(); + let mut extra_data = b.header.extra_data().clone(); + extra_data.extend_from_slice(&*sign); + b.header.set_extra_data(extra_data); + } + + let current_header = &block.header; + self.clique.verify_block_basic(current_header)?; + self.clique.verify_block_family(current_header, &last_header)?; + + Ok(current_header.clone()) + } +} + +#[test] +fn one_signer_with_no_votes() { + let tester = CliqueTester::with(10, 1, vec!['A']); + + let empty_block = tester.new_block_and_import(CliqueBlockType::Empty, &tester.genesis, None, 'A').unwrap(); + + let tags = tester.into_tags(tester.clique_signers(&empty_block.hash())); + assert_eq!(&tags, &['A']); +} + +#[test] +fn one_signer_two_votes() { + let tester = CliqueTester::with(10, 1, vec!['A']); + + // Add a vote for `B` signed by `A` + let vote = tester.new_block_and_import(CliqueBlockType::Vote(VoteType::Add), &tester.genesis, + Some(tester.signers[&'B'].address()), 'A').unwrap(); + let tags = tester.into_tags(tester.clique_signers(&vote.hash())); + assert_eq!(&tags, &['A', 'B']); + + // Add a empty block signed by `B` + let empty = tester.new_block_and_import(CliqueBlockType::Empty, &vote, None, 'B').unwrap(); + + // Add vote for `C` signed by A but should not be accepted + let vote = tester.new_block_and_import(CliqueBlockType::Vote(VoteType::Add), &empty, + Some(tester.signers[&'C'].address()), 'A').unwrap(); + + let tags = tester.into_tags(tester.clique_signers(&vote.hash())); + assert_eq!(&tags, &['A', 'B']); +} + +#[test] +fn two_signers_six_votes_deny_last() { + let tester = CliqueTester::with(10, 1, vec!['A', 'B']); + + let mut prev_header = tester.genesis.clone(); + + // Add two votes for `C` signed by `A` and `B` + for &signer in SIGNER_TAGS.iter().take(2) { + let vote = tester.new_block_and_import(CliqueBlockType::Vote(VoteType::Add), &prev_header, + Some(tester.signers[&'C'].address()), signer).unwrap(); + prev_header = vote.clone(); + } + + // Add two votes for `D` signed by `A` and `B` + for &signer in SIGNER_TAGS.iter().take(2) { + let vote = tester.new_block_and_import(CliqueBlockType::Vote(VoteType::Add), &prev_header, + Some(tester.signers[&'D'].address()), signer).unwrap(); + prev_header = vote.clone(); + } + + // Add a empty block signed by `C` + let empty = tester.new_block_and_import(CliqueBlockType::Empty, &prev_header, None, 'C').unwrap(); + prev_header = empty.clone(); + + // Add two votes for `E` signed by `A` and `B` + for &signer in SIGNER_TAGS.iter().take(2) { + let vote = tester.new_block_and_import(CliqueBlockType::Vote(VoteType::Add), &prev_header, + Some(tester.signers[&'E'].address()), signer).unwrap(); + prev_header = vote.clone(); + } + + let tags = tester.into_tags(tester.clique_signers(&prev_header.hash())); + assert_eq!(&tags, &['A', 'B', 'C', 'D']); +} + +#[test] +fn one_signer_dropping_itself() { + let tester = CliqueTester::with(10, 1, vec!['A']); + let vote = tester.new_block_and_import(CliqueBlockType::Vote(VoteType::Remove), &tester.genesis, + Some(tester.signers[&'A'].address()), 'A').unwrap(); + let signers = tester.clique_signers(&vote.hash()); + assert!(signers.count() == 0); +} + +#[test] +fn two_signers_one_remove_vote_no_consensus() { + let tester = CliqueTester::with(10, 1, vec!['A', 'B']); + let vote = tester.new_block_and_import(CliqueBlockType::Vote(VoteType::Remove), &tester.genesis, + Some(tester.signers[&'B'].address()), 'A').unwrap(); + + let tags = tester.into_tags(tester.clique_signers(&vote.hash())); + assert_eq!(&tags, &['A', 'B']); +} + +#[test] +fn two_signers_consensus_remove_b() { + let tester = CliqueTester::with(10, 1, vec!['A', 'B']); + let first_vote = tester.new_block_and_import(CliqueBlockType::Vote(VoteType::Remove), &tester.genesis, + Some(tester.signers[&'B'].address()), 'A').unwrap(); + let second_vote = tester.new_block_and_import(CliqueBlockType::Vote(VoteType::Remove), &first_vote, + Some(tester.signers[&'B'].address()), 'B').unwrap(); + + let tags = tester.into_tags(tester.clique_signers(&second_vote.hash())); + assert_eq!(&tags, &['A']); +} + +#[test] +fn three_signers_consensus_remove_c() { + let tester = CliqueTester::with(10, 1, vec!['A', 'B', 'C']); + let first_vote = tester.new_block_and_import(CliqueBlockType::Vote(VoteType::Remove), &tester.genesis, + Some(tester.signers[&'C'].address()), 'A').unwrap(); + let second_vote = tester.new_block_and_import(CliqueBlockType::Vote(VoteType::Remove), &first_vote, + Some(tester.signers[&'C'].address()), 'B').unwrap(); + + let tags = tester.into_tags(tester.clique_signers(&second_vote.hash())); + assert_eq!(&tags, &['A', 'B']); +} + +#[test] +fn four_signers_half_no_consensus() { + let tester = CliqueTester::with(10, 1, vec!['A', 'B', 'C', 'D']); + let first_vote = tester.new_block_and_import(CliqueBlockType::Vote(VoteType::Remove), &tester.genesis, + Some(tester.signers[&'C'].address()), 'A').unwrap(); + + let second_vote = tester.new_block_and_import(CliqueBlockType::Vote(VoteType::Remove), &first_vote, + Some(tester.signers[&'C'].address()), 'B').unwrap(); + + let tags = tester.into_tags(tester.clique_signers(&second_vote.hash())); + assert_eq!(&tags, &['A', 'B', 'C', 'D']); +} + +#[test] +fn four_signers_three_consensus_rm() { + let tester = CliqueTester::with(10, 1, vec!['A', 'B', 'C', 'D']); + + let mut prev_header = tester.genesis.clone(); + + // Three votes to remove `D` signed by ['A', 'B', 'C'] + for signer in SIGNER_TAGS.iter().take(3) { + let vote = tester.new_block_and_import(CliqueBlockType::Vote(VoteType::Remove), &prev_header, + Some(tester.signers[&'D'].address()), *signer).unwrap(); + prev_header = vote.clone(); + } + + let tags = tester.into_tags(tester.clique_signers(&prev_header.hash())); + assert_eq!(&tags, &['A', 'B', 'C']); +} + +#[test] +fn vote_add_only_counted_once_per_signer() { + let tester = CliqueTester::with(10, 1, vec!['A', 'B']); + + // Add a vote for `C` signed by `A` + let vote = tester.new_block_and_import(CliqueBlockType::Vote(VoteType::Add), &tester.genesis, + Some(tester.signers[&'C'].address()), 'A').unwrap(); + // Empty block signed by B` + let empty = tester.new_block_and_import(CliqueBlockType::Empty, &vote, None, 'B').unwrap(); + + // Add a vote for `C` signed by `A` + let vote = tester.new_block_and_import(CliqueBlockType::Vote(VoteType::Add), &empty, + Some(tester.signers[&'C'].address()), 'A').unwrap(); + // Empty block signed by `B` + let empty = tester.new_block_and_import(CliqueBlockType::Empty, &vote, None, 'B').unwrap(); + + // Add a vote for `C` signed by `A` + let vote = tester.new_block_and_import(CliqueBlockType::Vote(VoteType::Add), &empty, + Some(tester.signers[&'C'].address()), 'A').unwrap(); + + let tags = tester.into_tags(tester.clique_signers(&vote.hash())); + assert_eq!(&tags, &['A', 'B']); +} + +#[test] +fn vote_add_concurrently_is_permitted() { + let tester = CliqueTester::with(10, 1, vec!['A', 'B']); + + // Add a vote for `C` signed by `A` + let b = tester.new_block_and_import(CliqueBlockType::Vote(VoteType::Add), &tester.genesis, + Some(tester.signers[&'C'].address()), 'A').unwrap(); + + // Empty block signed by `B` + let b = tester.new_block_and_import(CliqueBlockType::Empty, &b, None, 'B').unwrap(); + + // Add a vote for `D` signed by `A` + let b = tester.new_block_and_import(CliqueBlockType::Vote(VoteType::Add), &b, + Some(tester.signers[&'D'].address()), 'A').unwrap(); + + // Empty block signed by `B` + let b = tester.new_block_and_import(CliqueBlockType::Empty, &b, None, 'B').unwrap(); + + // Empty block signed by `A` + let b = tester.new_block_and_import(CliqueBlockType::Empty, &b, None, 'A').unwrap(); + + // Add a vote for `D` signed by `B` + let b = tester.new_block_and_import(CliqueBlockType::Vote(VoteType::Add), &b, + Some(tester.signers[&'D'].address()), 'B').unwrap(); + + // Empty block signed by `A` + let b = tester.new_block_and_import(CliqueBlockType::Empty, &b, None, 'A').unwrap(); + + // Add a vote for `C` signed by `B` + let b = tester.new_block_and_import(CliqueBlockType::Vote(VoteType::Add), &b, + Some(tester.signers[&'C'].address()), 'B').unwrap(); + + let tags = tester.into_tags(tester.clique_signers(&b.hash())); + assert_eq!(&tags, &['A', 'B', 'C', 'D']); +} + +#[test] +fn vote_rm_only_counted_once_per_signer() { + let tester = CliqueTester::with(10, 1, vec!['A', 'B']); + + let mut prev_header = tester.genesis.clone(); + + for _ in 0..2 { + // Vote to remove `B` signed by `A` + let b = tester.new_block_and_import(CliqueBlockType::Vote(VoteType::Remove), &prev_header, + Some(tester.signers[&'B'].address()), 'A').unwrap(); + // Empty block signed by `B` + let b = tester.new_block_and_import(CliqueBlockType::Empty, &b, None, 'B').unwrap(); + + prev_header = b.clone(); + } + + // Add a vote for `B` signed by `A` + let b = tester.new_block_and_import(CliqueBlockType::Vote(VoteType::Remove), &prev_header, + Some(tester.signers[&'B'].address()), 'A').unwrap(); + + let tags = tester.into_tags(tester.clique_signers(&b.hash())); + assert_eq!(&tags, &['A', 'B']); +} + +#[test] +fn vote_rm_concurrently_is_permitted() { + let tester = CliqueTester::with(100, 1, vec!['A', 'B', 'C', 'D']); + + // Add a vote for `C` signed by `A` + let block = tester.new_block_and_import(CliqueBlockType::Vote(VoteType::Remove), &tester.genesis, + Some(tester.signers[&'C'].address()), 'A').unwrap(); + + // Empty block signed by `B` + let block = tester.new_block_and_import(CliqueBlockType::Empty, &block, None, 'B').unwrap(); + // Empty block signed by `C` + let block = tester.new_block_and_import(CliqueBlockType::Empty, &block, None, 'C').unwrap(); + + // Add a vote for `D` signed by `A` + let block = tester.new_block_and_import(CliqueBlockType::Vote(VoteType::Remove), &block, + Some(tester.signers[&'D'].address()), 'A').unwrap(); + + // Empty block signed by `B` + let block = tester.new_block_and_import(CliqueBlockType::Empty, &block, None, 'B').unwrap(); + // Empty block signed by `C` + let block = tester.new_block_and_import(CliqueBlockType::Empty, &block, None, 'C').unwrap(); + // Empty block signed by `A` + let block = tester.new_block_and_import(CliqueBlockType::Empty, &block, None, 'A').unwrap(); + + // Add a vote for `D` signed by `B` + let block = tester.new_block_and_import(CliqueBlockType::Vote(VoteType::Remove), &block, + Some(tester.signers[&'D'].address()), 'B').unwrap(); + // Add a vote for `D` signed by `C` + let block = tester.new_block_and_import(CliqueBlockType::Vote(VoteType::Remove), &block, + Some(tester.signers[&'D'].address()), 'C').unwrap(); + + // Empty block signed by `A` + let block = tester.new_block_and_import(CliqueBlockType::Empty, &block, None, 'A').unwrap(); + // Add a vote for `C` signed by `B` + let block = tester.new_block_and_import(CliqueBlockType::Vote(VoteType::Remove), &block, + Some(tester.signers[&'C'].address()), 'B').unwrap(); + + let tags = tester.into_tags(tester.clique_signers(&block.hash())); + assert_eq!(&tags, &['A', 'B']); +} + +#[test] +fn vote_to_rm_are_immediate_and_ensure_votes_are_rm() { + let tester = CliqueTester::with(100, 1, vec!['A', 'B', 'C']); + + // Vote to remove `B` signed by `C` + let block = tester.new_block_and_import(CliqueBlockType::Vote(VoteType::Remove), &tester.genesis, + Some(tester.signers[&'B'].address()), 'C').unwrap(); + // Vote to remove `C` signed by `A` + let block = tester.new_block_and_import(CliqueBlockType::Vote(VoteType::Remove), &block, + Some(tester.signers[&'C'].address()), 'A').unwrap(); + // Vote to remove `C` signed by `B` + let block = tester.new_block_and_import(CliqueBlockType::Vote(VoteType::Remove), &block, + Some(tester.signers[&'C'].address()), 'B').unwrap(); + // Vote to remove `B` signed by `A` + let block = tester.new_block_and_import(CliqueBlockType::Vote(VoteType::Remove), &block, + Some(tester.signers[&'B'].address()), 'A').unwrap(); + + let tags = tester.into_tags(tester.clique_signers(&block.hash())); + assert_eq!(&tags, &['A', 'B']); +} + +#[test] +fn vote_to_rm_are_immediate_and_votes_should_be_dropped_from_kicked_signer() { + let tester = CliqueTester::with(100, 1, vec!['A', 'B', 'C']); + + // Vote to add `D` signed by `C` + let block = tester.new_block_and_import(CliqueBlockType::Vote(VoteType::Add), &tester.genesis, + Some(tester.signers[&'D'].address()), 'C').unwrap(); + // Vote to remove `C` signed by `A` + let block = tester.new_block_and_import(CliqueBlockType::Vote(VoteType::Remove), &block, + Some(tester.signers[&'C'].address()), 'A').unwrap(); + + // Vote to remove `C` signed by `B` + let block = tester.new_block_and_import(CliqueBlockType::Vote(VoteType::Remove), &block, + Some(tester.signers[&'C'].address()), 'B').unwrap(); + + // Vote to add `D` signed by `A` + let block = tester.new_block_and_import(CliqueBlockType::Vote(VoteType::Add), &block, + Some(tester.signers[&'D'].address()), 'A').unwrap(); + + let tags = tester.into_tags(tester.clique_signers(&block.hash())); + assert_eq!(&tags, &['A', 'B']); +} + +#[test] +fn cascading_not_allowed() { + let tester = CliqueTester::with(100, 1, vec!['A', 'B', 'C', 'D']); + + // Vote against `C` signed by `A` + let block = tester.new_block_and_import(CliqueBlockType::Vote(VoteType::Remove), &tester.genesis, + Some(tester.signers[&'C'].address()), 'A').unwrap(); + + // Empty block signed by `B` + let block = tester.new_block_and_import(CliqueBlockType::Empty, &block, None, 'B').unwrap(); + + // Empty block signed by `C` + let block = tester.new_block_and_import(CliqueBlockType::Empty, &block, None, 'C').unwrap(); + + // Vote against `D` signed by `A` + let block = tester.new_block_and_import(CliqueBlockType::Vote(VoteType::Remove), &block, + Some(tester.signers[&'D'].address()), 'A').unwrap(); + + // Vote against `C` signed by `B` + let block = tester.new_block_and_import(CliqueBlockType::Vote(VoteType::Remove), &block, + Some(tester.signers[&'C'].address()), 'B').unwrap(); + + // Empty block signed by `C` + let block = tester.new_block_and_import(CliqueBlockType::Empty, &block, None, 'C').unwrap(); + + // Empty block signed by `A` + let block = tester.new_block_and_import(CliqueBlockType::Empty, &block, None, 'A').unwrap(); + + // Vote against `D` signed by `B` + let block = tester.new_block_and_import(CliqueBlockType::Vote(VoteType::Remove), &block, + Some(tester.signers[&'D'].address()), 'B').unwrap(); + + // Vote against `D` signed by `C` + let block = tester.new_block_and_import(CliqueBlockType::Vote(VoteType::Remove), &block, + Some(tester.signers[&'D'].address()), 'C').unwrap(); + + let tags = tester.into_tags(tester.clique_signers(&block.hash())); + assert_eq!(&tags, &['A', 'B', 'C']); +} + +#[test] +fn consensus_out_of_bounds_consensus_execute_on_touch() { + let tester = CliqueTester::with(100, 1, vec!['A', 'B', 'C', 'D']); + + // Vote against `C` signed by `A` + let block = tester.new_block_and_import(CliqueBlockType::Vote(VoteType::Remove), &tester.genesis, + Some(tester.signers[&'C'].address()), 'A').unwrap(); + + // Empty block signed by `B` + let block = tester.new_block_and_import(CliqueBlockType::Empty, &block, None, 'B').unwrap(); + + // Empty block signed by `C` + let block = tester.new_block_and_import(CliqueBlockType::Empty, &block, None, 'C').unwrap(); + + // Vote against `D` signed by `A` + let block = tester.new_block_and_import(CliqueBlockType::Vote(VoteType::Remove), &block, + Some(tester.signers[&'D'].address()), 'A').unwrap(); + + // Vote against `C` signed by `B` + let block = tester.new_block_and_import(CliqueBlockType::Vote(VoteType::Remove), &block, + Some(tester.signers[&'C'].address()), 'B').unwrap(); + + // Empty block signed by `C` + let block = tester.new_block_and_import(CliqueBlockType::Empty, &block, None, 'C').unwrap(); + + // Empty block signed by `A` + let block = tester.new_block_and_import(CliqueBlockType::Empty, &block, None, 'A').unwrap(); + + // Vote against `D` signed by `B` + let block = tester.new_block_and_import(CliqueBlockType::Vote(VoteType::Remove), &block, + Some(tester.signers[&'D'].address()), 'B').unwrap(); + + // Vote against `D` signed by `C` + let block = tester.new_block_and_import(CliqueBlockType::Vote(VoteType::Remove), &block, + Some(tester.signers[&'D'].address()), 'C').unwrap(); + + let tags = tester.into_tags(tester.clique_signers(&block.hash())); + assert_eq!(&tags, &['A', 'B', 'C'], "D should have been removed after 3/4 remove votes"); + + // Empty block signed by `A` + let block = tester.new_block_and_import(CliqueBlockType::Empty, &block, None, 'A').unwrap(); + + // Vote for `C` signed by `C` + let block = tester.new_block_and_import(CliqueBlockType::Vote(VoteType::Add), &block, + Some(tester.signers[&'C'].address()), 'C').unwrap(); + + let tags = tester.into_tags(tester.clique_signers(&block.hash())); + assert_eq!(&tags, &['A', 'B']); +} + +#[test] +fn consensus_out_of_bounds_first_touch() { + let tester = CliqueTester::with(100, 1, vec!['A', 'B', 'C', 'D']); + + // Vote against `C` signed by `A` + let block = tester.new_block_and_import(CliqueBlockType::Vote(VoteType::Remove), &tester.genesis, + Some(tester.signers[&'C'].address()), 'A').unwrap(); + + // Empty block signed by `B` + let block = tester.new_block_and_import(CliqueBlockType::Empty, &block, None, 'B').unwrap(); + + // Empty block signed by `C` + let block = tester.new_block_and_import(CliqueBlockType::Empty, &block, None, 'C').unwrap(); + + // Vote against `D` signed by `A` + let block = tester.new_block_and_import(CliqueBlockType::Vote(VoteType::Remove), &block, + Some(tester.signers[&'D'].address()), 'A').unwrap(); + + // Vote against `C` signed by `B` + let block = tester.new_block_and_import(CliqueBlockType::Vote(VoteType::Remove), &block, + Some(tester.signers[&'C'].address()), 'B').unwrap(); + + // Empty block signed by `C` + let block = tester.new_block_and_import(CliqueBlockType::Empty, &block, None, 'C').unwrap(); + + // Empty block signed by `A` + let block = tester.new_block_and_import(CliqueBlockType::Empty, &block, None, 'A').unwrap(); + + // Vote against `D` signed by `B` + let block = tester.new_block_and_import(CliqueBlockType::Vote(VoteType::Remove), &block, + Some(tester.signers[&'D'].address()), 'B').unwrap(); + + // Vote against `D` signed by `C` + let block = tester.new_block_and_import(CliqueBlockType::Vote(VoteType::Remove), &block, + Some(tester.signers[&'D'].address()), 'C').unwrap(); + + let tags = tester.into_tags(tester.clique_signers(&block.hash())); + assert_eq!(&tags, &['A', 'B', 'C']); + + // Empty block signed by `A` + let block = tester.new_block_and_import(CliqueBlockType::Empty, &block, None, 'A').unwrap(); + + // Vote for `C` signed by `B` + let block = tester.new_block_and_import(CliqueBlockType::Vote(VoteType::Add), &block, + Some(tester.signers[&'C'].address()), 'B').unwrap(); + + let tags = tester.into_tags(tester.clique_signers(&block.hash())); + assert_eq!(&tags, &['A', 'B', 'C']); +} + +#[test] +fn pending_votes_doesnt_survive_authorization_changes() { + let tester = CliqueTester::with(100, 1, vec!['A', 'B', 'C', 'D', 'E']); + + let mut prev_header = tester.genesis.clone(); + + // Vote for `F` from [`A`, `B`, `C`] + for sign in SIGNER_TAGS.iter().take(3) { + let block = tester.new_block_and_import(CliqueBlockType::Vote(VoteType::Add), &prev_header, + Some(tester.signers[&'F'].address()), *sign).unwrap(); + prev_header = block.clone(); + } + + let tags = tester.into_tags(tester.clique_signers(&prev_header.hash())); + assert_eq!(&tags, &['A', 'B', 'C', 'D', 'E', 'F'], "F should have been added"); + + // Vote against `F` from [`D`, `E`, `B`, `C`] + for sign in SIGNER_TAGS.iter().skip(3).chain(SIGNER_TAGS.iter().skip(1).take(2)) { + let block = tester.new_block_and_import(CliqueBlockType::Vote(VoteType::Remove), &prev_header, + Some(tester.signers[&'F'].address()), *sign).unwrap(); + prev_header = block.clone(); + } + + let tags = tester.into_tags(tester.clique_signers(&prev_header.hash())); + assert_eq!(&tags, &['A', 'B', 'C', 'D', 'E'], "F should have been removed"); + + // Vote for `F` from [`D`, `E`] + for sign in SIGNER_TAGS.iter().skip(3).take(2) { + let block = tester.new_block_and_import(CliqueBlockType::Vote(VoteType::Add), &prev_header, + Some(tester.signers[&'F'].address()), *sign).unwrap(); + prev_header = block.clone(); + } + + // Vote against `A` from [`B`, `C`, `D`] + for sign in SIGNER_TAGS.iter().skip(1).take(3) { + let block = tester.new_block_and_import(CliqueBlockType::Vote(VoteType::Remove), &prev_header, + Some(tester.signers[&'A'].address()), *sign).unwrap(); + prev_header = block.clone(); + } + + let tags = tester.into_tags(tester.clique_signers(&prev_header.hash())); + assert_eq!(&tags, &['B', 'C', 'D', 'E'], "A should have been removed"); + + let block = tester.new_block_and_import(CliqueBlockType::Vote(VoteType::Add), &prev_header, + Some(tester.signers[&'F'].address()), 'B').unwrap(); + + let tags = tester.into_tags(tester.clique_signers(&block.hash())); + assert_eq!(&tags, &['B', 'C', 'D', 'E', 'F'], "F should have been added again"); +} + +#[test] +fn epoch_transition_reset_all_votes() { + let tester = CliqueTester::with(3, 1, vec!['A', 'B']); + + let block = tester.new_block_and_import(CliqueBlockType::Vote(VoteType::Add), &tester.genesis, + Some(tester.signers[&'C'].address()), 'A').unwrap(); + + let block = tester.new_block_and_import(CliqueBlockType::Empty, &block, None, 'B').unwrap(); + let block = tester.new_block_and_import(CliqueBlockType::Checkpoint, &block, None, 'A').unwrap(); + + let block = tester.new_block_and_import(CliqueBlockType::Vote(VoteType::Add), &block, + Some(tester.signers[&'C'].address()), 'B').unwrap(); + + let tags = tester.into_tags(tester.clique_signers(&block.hash())); + assert_eq!(&tags, &['A', 'B'], "Votes should have been reset after checkpoint"); +} + +#[test] +fn unauthorized_signer_should_not_be_able_to_sign_block() { + let tester = CliqueTester::with(3, 1, vec!['A']); + let err = tester.new_block_and_import(CliqueBlockType::Empty, &tester.genesis, None, 'B').unwrap_err(); + + match err.kind() { + ErrorKind::Engine(EngineError::NotAuthorized(_)) => (), + _ => assert!(true == false, "Wrong error kind"), + } +} + +#[test] +fn signer_should_not_be_able_to_sign_two_consequtive_blocks() { + let tester = CliqueTester::with(3, 1, vec!['A', 'B']); + let b = tester.new_block_and_import(CliqueBlockType::Empty, &tester.genesis, None, 'A').unwrap(); + let err = tester.new_block_and_import(CliqueBlockType::Empty, &b, None, 'A').unwrap_err(); + + match err.kind() { + ErrorKind::Engine(EngineError::CliqueTooRecentlySigned(_)) => (), + _ => assert!(true == false, "Wrong error kind"), + } +} + + +#[test] +fn recent_signers_should_not_reset_on_checkpoint() { + let tester = CliqueTester::with(3, 1, vec!['A', 'B', 'C']); + + let block = tester.new_block_and_import(CliqueBlockType::Empty, &tester.genesis, None, 'A').unwrap(); + let block = tester.new_block_and_import(CliqueBlockType::Empty, &block, None, 'B').unwrap(); + let block = tester.new_block_and_import(CliqueBlockType::Checkpoint, &block, None, 'A').unwrap(); + + let err = tester.new_block_and_import(CliqueBlockType::Empty, &block, None, 'A').unwrap_err(); + + match err.kind() { + ErrorKind::Engine(EngineError::CliqueTooRecentlySigned(_)) => (), + _ => assert!(true == false, "Wrong error kind"), + } +} + +// Not part of http://eips.ethereum.org/EIPS/eip-225 +#[test] +fn bonus_consensus_should_keep_track_of_votes_before_latest_per_signer() { + let tester = CliqueTester::with(100, 1, vec!['A', 'B', 'C', 'D']); + + // Add a vote for `E` signed by `A` + let vote = tester.new_block_and_import(CliqueBlockType::Vote(VoteType::Add), &tester.genesis, + Some(tester.signers[&'E'].address()), 'A').unwrap(); + // Empty block signed by `B` + let vote = tester.new_block_and_import(CliqueBlockType::Empty, &vote, None, 'B').unwrap(); + + // Empty block signed by `C` + let vote = tester.new_block_and_import(CliqueBlockType::Empty, &vote, None, 'C').unwrap(); + + // Empty block signed by `D` + let vote = tester.new_block_and_import(CliqueBlockType::Empty, &vote, None, 'D').unwrap(); + + // Add a vote for `F` signed by `A` + let vote = tester.new_block_and_import(CliqueBlockType::Vote(VoteType::Add), &vote, + Some(tester.signers[&'F'].address()), 'A').unwrap(); + // Empty block signed by `C` + let vote = tester.new_block_and_import(CliqueBlockType::Empty, &vote, None, 'C').unwrap(); + + // Empty block signed by `D` + let vote = tester.new_block_and_import(CliqueBlockType::Empty, &vote, None, 'D').unwrap(); + + // Add a vote for `E` signed by `B` + let vote = tester.new_block_and_import(CliqueBlockType::Vote(VoteType::Add), &vote, + Some(tester.signers[&'E'].address()), 'B').unwrap(); + // Empty block signed by `A` + let vote = tester.new_block_and_import(CliqueBlockType::Empty, &vote, None, 'A').unwrap(); + + // Empty block signed by `C` + let vote = tester.new_block_and_import(CliqueBlockType::Empty, &vote, None, 'C').unwrap(); + + // Empty block signed by `D` + let vote = tester.new_block_and_import(CliqueBlockType::Empty, &vote, None, 'D').unwrap(); + + // Add a vote for `F` signed by `B` + let vote = tester.new_block_and_import(CliqueBlockType::Vote(VoteType::Add), &vote, + Some(tester.signers[&'F'].address()), 'B').unwrap(); + + // Empty block signed by A` + let vote = tester.new_block_and_import(CliqueBlockType::Empty, &vote, None, 'A').unwrap(); + + // Add a vote for `E` signed by `C` + let vote = tester.new_block_and_import(CliqueBlockType::Vote(VoteType::Add), &vote, + Some(tester.signers[&'E'].address()), 'C').unwrap(); + + let tags = tester.into_tags(tester.clique_signers(&vote.hash())); + assert_eq!(&tags, &['A', 'B', 'C', 'D', 'E']); +} diff --git a/ethcore/src/engines/clique/util.rs b/ethcore/src/engines/clique/util.rs new file mode 100644 index 0000000000..3f75289e91 --- /dev/null +++ b/ethcore/src/engines/clique/util.rs @@ -0,0 +1,115 @@ +// Copyright 2015-2019 Parity Technologies (UK) Ltd. +// This file is part of Parity Ethereum. + +// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . + +use std::collections::BTreeSet; + +use engines::EngineError; +use engines::clique::{ADDRESS_LENGTH, SIGNATURE_LENGTH, VANITY_LENGTH, NULL_NONCE, NULL_MIXHASH}; +use error::Error; +use ethereum_types::{Address, H256}; +use ethkey::{public_to_address, recover as ec_recover, Signature}; +use lru_cache::LruCache; +use parking_lot::RwLock; +use rlp::encode; +use types::header::Header; + +/// How many recovered signature to cache in the memory. +pub const CREATOR_CACHE_NUM: usize = 4096; +lazy_static! { + /// key: header hash + /// value: creator address + static ref CREATOR_BY_HASH: RwLock> = RwLock::new(LruCache::new(CREATOR_CACHE_NUM)); +} + +/// Recover block creator from signature +pub fn recover_creator(header: &Header) -> Result { + // Initialization + let mut cache = CREATOR_BY_HASH.write(); + + if let Some(creator) = cache.get_mut(&header.hash()) { + return Ok(*creator); + } + + let data = header.extra_data(); + if data.len() < VANITY_LENGTH { + Err(EngineError::CliqueMissingVanity)? + } + + if data.len() < VANITY_LENGTH + SIGNATURE_LENGTH { + Err(EngineError::CliqueMissingSignature)? + } + + // Split `signed_extra data` and `signature` + let (signed_data_slice, signature_slice) = data.split_at(data.len() - SIGNATURE_LENGTH); + + // convert `&[u8]` to `[u8; 65]` + let signature = { + let mut s = [0; SIGNATURE_LENGTH]; + s.copy_from_slice(signature_slice); + s + }; + + // modify header and hash it + let unsigned_header = &mut header.clone(); + unsigned_header.set_extra_data(signed_data_slice.to_vec()); + let msg = unsigned_header.hash(); + + let pubkey = ec_recover(&Signature::from(signature), &msg)?; + let creator = public_to_address(&pubkey); + + cache.insert(header.hash(), creator.clone()); + Ok(creator) +} + +/// Extract signer list from extra_data. +/// +/// Layout of extra_data: +/// ---- +/// VANITY: 32 bytes +/// Signers: N * 32 bytes as hex encoded (20 characters) +/// Signature: 65 bytes +/// -- +pub fn extract_signers(header: &Header) -> Result, Error> { + let data = header.extra_data(); + + if data.len() <= VANITY_LENGTH + SIGNATURE_LENGTH { + Err(EngineError::CliqueCheckpointNoSigner)? + } + + // extract only the portion of extra_data which includes the signer list + let signers_raw = &data[(VANITY_LENGTH)..data.len() - (SIGNATURE_LENGTH)]; + + if signers_raw.len() % ADDRESS_LENGTH != 0 { + Err(EngineError::CliqueCheckpointInvalidSigners(signers_raw.len()))? + } + + let num_signers = signers_raw.len() / 20; + + let signers: BTreeSet
= (0..num_signers) + .map(|i| { + let start = i * ADDRESS_LENGTH; + let end = start + ADDRESS_LENGTH; + signers_raw[start..end].into() + }) + .collect(); + + Ok(signers) +} + +/// Retrieve `null_seal` +pub fn null_seal() -> Vec> { + vec![encode(&NULL_MIXHASH.to_vec()), encode(&NULL_NONCE.to_vec())] +} diff --git a/ethcore/src/engines/mod.rs b/ethcore/src/engines/mod.rs index 06e6b522be..5124f079db 100644 --- a/ethcore/src/engines/mod.rs +++ b/ethcore/src/engines/mod.rs @@ -18,6 +18,7 @@ mod authority_round; mod basic_authority; +mod clique; mod instant_seal; mod null_engine; mod validator_set; @@ -30,6 +31,7 @@ pub use self::basic_authority::BasicAuthority; pub use self::instant_seal::{InstantSeal, InstantSealParams}; pub use self::null_engine::NullEngine; pub use self::signer::EngineSigner; +pub use self::clique::Clique; // TODO [ToDr] Remove re-export (#10130) pub use types::engines::ForkChoice; @@ -50,7 +52,7 @@ use types::transaction::{self, UnverifiedTransaction, SignedTransaction}; use ethkey::{Signature}; use machine::{self, Machine, AuxiliaryRequest, AuxiliaryData}; -use ethereum_types::{H256, U256, Address}; +use ethereum_types::{H64, H256, U256, Address}; use unexpected::{Mismatch, OutOfBounds}; use bytes::Bytes; use types::ancestry_action::AncestryAction; @@ -85,12 +87,45 @@ pub enum EngineError { RequiresClient, /// Invalid engine specification or implementation. InvalidEngine, + /// Requires signer ref, but none registered. + RequiresSigner, + /// Checkpoint is missing + CliqueMissingCheckpoint(H256), + /// Missing vanity data + CliqueMissingVanity, + /// Missing signature + CliqueMissingSignature, + /// Missing signers + CliqueCheckpointNoSigner, + /// List of signers is invalid + CliqueCheckpointInvalidSigners(usize), + /// Wrong author on a checkpoint + CliqueWrongAuthorCheckpoint(Mismatch
), + /// Wrong checkpoint authors recovered + CliqueFaultyRecoveredSigners(Vec), + /// Invalid nonce (should contain vote) + CliqueInvalidNonce(H64), + /// The signer signed a block to recently + CliqueTooRecentlySigned(Address), + /// Custom + Custom(String), } impl fmt::Display for EngineError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { use self::EngineError::*; let msg = match *self { + CliqueMissingCheckpoint(ref hash) => format!("Missing checkpoint block: {}", hash), + CliqueMissingVanity => format!("Extra data is missing vanity data"), + CliqueMissingSignature => format!("Extra data is missing signature"), + CliqueCheckpointInvalidSigners(len) => format!("Checkpoint block list was of length: {} of checkpoint but + it needs to be bigger than zero and a divisible by 20", len), + CliqueCheckpointNoSigner => format!("Checkpoint block list of signers was empty"), + CliqueInvalidNonce(ref mis) => format!("Unexpected nonce {} expected {} or {}", mis, 0_u64, u64::max_value()), + CliqueWrongAuthorCheckpoint(ref oob) => format!("Unexpected checkpoint author: {}", oob), + CliqueFaultyRecoveredSigners(ref mis) => format!("Faulty recovered signers {:?}", mis), + CliqueTooRecentlySigned(ref address) => format!("The signer: {} has signed a block too recently", address), + Custom(ref s) => s.clone(), DoubleVote(ref address) => format!("Author {} issued too many blocks.", address), NotProposer(ref mis) => format!("Author is not a current proposer: {}", mis), NotAuthorized(ref address) => format!("Signer {} is not authorized.", address), @@ -100,6 +135,7 @@ impl fmt::Display for EngineError { FailedSystemCall(ref msg) => format!("Failed to make system call: {}", msg), MalformedMessage(ref msg) => format!("Received malformed consensus message: {}", msg), RequiresClient => format!("Call requires client but none registered"), + RequiresSigner => format!("Call requires signer but none registered"), InvalidEngine => format!("Invalid engine specification or implementation"), }; @@ -120,7 +156,7 @@ pub enum Seal { Proposal(Vec), /// Regular block seal; should be part of the blockchain. Regular(Vec), - /// Engine does generate seal for this block right now. + /// Engine does not generate seal for this block right now. None, } @@ -263,6 +299,9 @@ pub trait Engine: Sync + Send { Ok(()) } + /// Allow mutating the header during seal generation. Currently only used by Clique. + fn on_seal_block(&self, _block: &mut ExecutedBlock) -> Result<(), Error> { Ok(()) } + /// None means that it requires external input (e.g. PoW) to seal a block. /// Some(true) means the engine is currently prime for seal generation (i.e. node is the current validator). /// Some(false) means that the node might seal internally but is not qualified now. @@ -387,7 +426,7 @@ pub trait Engine: Sync + Send { fn step(&self) {} /// Stops any services that the may hold the Engine and makes it safe to drop. - fn stop(&self) {} + fn stop(&mut self) {} /// Create a factory for building snapshot chunks and restoring from them. /// Returning `None` indicates that this engine doesn't support snapshot creation. @@ -421,6 +460,11 @@ pub trait Engine: Sync + Send { /// Check whether the given new block is the best block, after finalization check. fn fork_choice(&self, new: &ExtendedHeader, best: &ExtendedHeader) -> ForkChoice; + + /// Returns author should used when executing tx's for this block. + fn executive_author(&self, header: &Header) -> Result { + Ok(*header.author()) + } } /// Check whether a given block is the best block based on the default total difficulty rule. diff --git a/ethcore/src/ethereum/mod.rs b/ethcore/src/ethereum/mod.rs index b7c60789a3..d37ca9b4f7 100644 --- a/ethcore/src/ethereum/mod.rs +++ b/ethcore/src/ethereum/mod.rs @@ -94,6 +94,11 @@ pub fn new_mix<'a, T: Into>>(params: T) -> Spec { load(params.into(), include_bytes!("../../res/ethereum/mix.json")) } +/// Create a new Callisto chain spec +pub fn new_callisto<'a, T: Into>>(params: T) -> Spec { + load(params.into(), include_bytes!("../../res/ethereum/callisto.json")) +} + /// Create a new Morden testnet chain spec. pub fn new_morden<'a, T: Into>>(params: T) -> Spec { load(params.into(), include_bytes!("../../res/ethereum/morden.json")) @@ -109,16 +114,26 @@ pub fn new_kovan<'a, T: Into>>(params: T) -> Spec { load(params.into(), include_bytes!("../../res/ethereum/kovan.json")) } +/// Create a new Rinkeby testnet chain spec. +pub fn new_rinkeby<'a, T: Into>>(params: T) -> Spec { + load(params.into(), include_bytes!("../../res/ethereum/rinkeby.json")) +} + +/// Create a new Görli testnet chain spec. +pub fn new_goerli<'a, T: Into>>(params: T) -> Spec { + load(params.into(), include_bytes!("../../res/ethereum/goerli.json")) +} + +/// Create a new Kotti testnet chain spec. +pub fn new_kotti<'a, T: Into>>(params: T) -> Spec { + load(params.into(), include_bytes!("../../res/ethereum/kotti.json")) +} + /// Create a new POA Sokol testnet chain spec. pub fn new_sokol<'a, T: Into>>(params: T) -> Spec { load(params.into(), include_bytes!("../../res/ethereum/poasokol.json")) } -/// Create a new Callisto chaun spec -pub fn new_callisto<'a, T: Into>>(params: T) -> Spec { - load(params.into(), include_bytes!("../../res/ethereum/callisto.json")) -} - // For tests /// Create a new Foundation Frontier-era chain spec as though it never changes to Homestead. diff --git a/ethcore/src/miner/miner.rs b/ethcore/src/miner/miner.rs index ce1c9ef6ee..adaeff0874 100644 --- a/ethcore/src/miner/miner.rs +++ b/ethcore/src/miner/miner.rs @@ -214,7 +214,6 @@ impl Author { } } - struct SealingWork { queue: UsingQueue, enabled: bool, @@ -630,7 +629,10 @@ impl Miner { } } - /// Attempts to perform internal sealing (one that does not require work) and handles the result depending on the type of Seal. + // TODO: (https://github.com/paritytech/parity-ethereum/issues/10407) + // This is only used in authority_round path, and should be refactored to merge with the other seal() path. + // Attempts to perform internal sealing (one that does not require work) and handles the result depending on the + // type of Seal. fn seal_and_import_block_internally(&self, chain: &C, block: ClosedBlock) -> bool where C: BlockChain + SealedBlockImporter, { @@ -1142,7 +1144,7 @@ impl miner::MinerService for Miner { if block.header.number() == 1 { if let Some(name) = self.engine.params().nonzero_bugfix_hard_fork() { warn!("Your chain specification contains one or more hard forks which are required to be \ - on by default. Please remove these forks and start your chain again: {}.", name); + on by default. Please remove these forks and start your chain again: {}.", name); return; } } diff --git a/ethcore/src/spec/spec.rs b/ethcore/src/spec/spec.rs index 82dd5da5c4..fe32c0d87e 100644 --- a/ethcore/src/spec/spec.rs +++ b/ethcore/src/spec/spec.rs @@ -35,7 +35,7 @@ use vm::{EnvInfo, CallType, ActionValue, ActionParams, ParamsType}; use builtin::Builtin; use engines::{ - EthEngine, NullEngine, InstantSeal, InstantSealParams, BasicAuthority, + EthEngine, NullEngine, InstantSeal, InstantSealParams, BasicAuthority, Clique, AuthorityRound, DEFAULT_BLOCKHASH_CONTRACT }; use error::Error; @@ -99,9 +99,9 @@ pub struct CommonParams { pub validate_receipts_transition: BlockNumber, /// Validate transaction chain id. pub validate_chain_id_transition: BlockNumber, - /// Number of first block where EIP-140 (Metropolis: REVERT opcode) rules begin. + /// Number of first block where EIP-140 rules begin. pub eip140_transition: BlockNumber, - /// Number of first block where EIP-210 (Metropolis: BLOCKHASH changes) rules begin. + /// Number of first block where EIP-210 rules begin. pub eip210_transition: BlockNumber, /// EIP-210 Blockhash contract address. pub eip210_contract_address: Address, @@ -109,8 +109,7 @@ pub struct CommonParams { pub eip210_contract_code: Bytes, /// Gas allocated for EIP-210 blockhash update. pub eip210_contract_gas: U256, - /// Number of first block where EIP-211 (Metropolis: RETURNDATASIZE/RETURNDATACOPY) rules - /// begin. + /// Number of first block where EIP-211 rules begin. pub eip211_transition: BlockNumber, /// Number of first block where EIP-214 rules begin. pub eip214_transition: BlockNumber, @@ -611,6 +610,8 @@ impl Spec { ethjson::spec::Engine::InstantSeal(Some(instant_seal)) => Arc::new(InstantSeal::new(instant_seal.params.into(), machine)), ethjson::spec::Engine::InstantSeal(None) => Arc::new(InstantSeal::new(InstantSealParams::default(), machine)), ethjson::spec::Engine::BasicAuthority(basic_authority) => Arc::new(BasicAuthority::new(basic_authority.params.into(), machine)), + ethjson::spec::Engine::Clique(clique) => Clique::new(clique.params.into(), machine) + .expect("Failed to start Clique consensus engine."), ethjson::spec::Engine::AuthorityRound(authority_round) => AuthorityRound::new(authority_round.params.into(), machine) .expect("Failed to start AuthorityRound consensus engine."), } @@ -827,7 +828,6 @@ impl Spec { ethjson::spec::Spec::load(reader) .map_err(fmt_err) .map(load_machine_from) - } /// Loads spec from json file. Provide factories for executing contracts and ensuring diff --git a/json/src/spec/clique.rs b/json/src/spec/clique.rs new file mode 100644 index 0000000000..64be9c569a --- /dev/null +++ b/json/src/spec/clique.rs @@ -0,0 +1,57 @@ +// Copyright 2015-2019 Parity Technologies (UK) Ltd. +// This file is part of Parity Ethereum. + +// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . + +//! Clique params deserialization. + +use std::num::NonZeroU64; + +/// Clique params deserialization. +#[derive(Debug, PartialEq, Deserialize)] +pub struct CliqueParams { + /// period as defined in EIP + pub period: Option, + /// epoch length as defined in EIP + pub epoch: Option +} + +/// Clique engine deserialization. +#[derive(Debug, PartialEq, Deserialize)] +pub struct Clique { + /// CliqueEngine params + pub params: CliqueParams, +} + +#[cfg(test)] +mod tests { + use serde_json; + use uint::Uint; + use ethereum_types::U256; + use super::*; + + #[test] + fn clique_deserialization() { + let s = r#"{ + "params": { + "period": 5, + "epoch": 30000 + } + }"#; + + let deserialized: Clique = serde_json::from_str(s).unwrap(); + assert_eq!(deserialized.params.period, Some(5u64)); + assert_eq!(deserialized.params.epoch, NonZeroU64::new(30000)); + } +} diff --git a/json/src/spec/engine.rs b/json/src/spec/engine.rs index 8941f89e14..cfa1d8cafd 100644 --- a/json/src/spec/engine.rs +++ b/json/src/spec/engine.rs @@ -16,7 +16,7 @@ //! Engine deserialization. -use super::{Ethash, BasicAuthority, AuthorityRound, NullEngine, InstantSeal}; +use super::{Ethash, BasicAuthority, AuthorityRound, NullEngine, InstantSeal, Clique}; /// Engine deserialization. #[derive(Debug, PartialEq, Deserialize)] @@ -34,6 +34,8 @@ pub enum Engine { BasicAuthority(BasicAuthority), /// AuthorityRound engine. AuthorityRound(AuthorityRound), + /// Clique engine. + Clique(Clique) } #[cfg(test)] @@ -130,5 +132,19 @@ mod tests { Engine::AuthorityRound(_) => {}, // AuthorityRound is unit tested in its own file. _ => panic!(), }; + + let s = r#"{ + "clique": { + "params": { + "period": 15, + "epoch": 30000 + } + } + }"#; + let deserialized: Engine = serde_json::from_str(s).unwrap(); + match deserialized { + Engine::Clique(_) => {}, // Clique is unit tested in its own file. + _ => panic!(), + }; } } diff --git a/json/src/spec/mod.rs b/json/src/spec/mod.rs index 1d6815d37c..f1145be2e9 100644 --- a/json/src/spec/mod.rs +++ b/json/src/spec/mod.rs @@ -31,6 +31,7 @@ pub mod authority_round; pub mod null_engine; pub mod instant_seal; pub mod hardcoded_sync; +pub mod clique; pub use self::account::Account; pub use self::builtin::{Builtin, Pricing, Linear}; @@ -44,6 +45,7 @@ pub use self::ethash::{Ethash, EthashParams, BlockReward}; pub use self::validator_set::ValidatorSet; pub use self::basic_authority::{BasicAuthority, BasicAuthorityParams}; pub use self::authority_round::{AuthorityRound, AuthorityRoundParams}; +pub use self::clique::{Clique, CliqueParams}; pub use self::null_engine::{NullEngine, NullEngineParams}; pub use self::instant_seal::{InstantSeal, InstantSealParams}; pub use self::hardcoded_sync::HardcodedSync; diff --git a/parity/cli/mod.rs b/parity/cli/mod.rs index c372e9bff4..01f4469bb5 100644 --- a/parity/cli/mod.rs +++ b/parity/cli/mod.rs @@ -300,7 +300,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 ethereum, classic, poacore, tobalaba, expanse, musicoin, ellaism, easthub, social, mix, callisto, morden, ropsten, kovan, poasokol, testnet, or dev.", + "Specify the blockchain type. CHAIN may be either a JSON chain specification file or ethereum, classic, poacore, tobalaba, expanse, musicoin, ellaism, easthub, social, mix, callisto, morden, ropsten, kovan, rinkeby, goerli, kotti, poasokol, testnet, or dev.", ARG arg_keys_path: (String) = "$BASE/keys", or |c: &Config| c.parity.as_ref()?.keys_path.clone(), "--keys-path=[PATH]", @@ -926,7 +926,7 @@ usage! { "--whisper", "Enable the Whisper network.", - ARG arg_whisper_pool_size: (usize) = 10usize, or |c: &Config| c.whisper.as_ref()?.pool_size.clone(), + ARG arg_whisper_pool_size: (usize) = 10usize, or |c: &Config| c.whisper.as_ref()?.pool_size.clone(), "--whisper-pool-size=[MB]", "Target size of the whisper message pool in megabytes.", diff --git a/parity/params.rs b/parity/params.rs index a916d05a78..389b708ce6 100644 --- a/parity/params.rs +++ b/parity/params.rs @@ -47,6 +47,9 @@ pub enum SpecType { Morden, Ropsten, Kovan, + Rinkeby, + Goerli, + Kotti, Sokol, Dev, Custom(String), @@ -77,6 +80,9 @@ impl str::FromStr for SpecType { "morden" | "classic-testnet" => SpecType::Morden, "ropsten" => SpecType::Ropsten, "kovan" | "testnet" => SpecType::Kovan, + "rinkeby" => SpecType::Rinkeby, + "goerli" | "görli" => SpecType::Goerli, + "kotti" => SpecType::Kotti, "sokol" | "poasokol" => SpecType::Sokol, "dev" => SpecType::Dev, other => SpecType::Custom(other.into()), @@ -102,6 +108,9 @@ impl fmt::Display for SpecType { SpecType::Morden => "morden", SpecType::Ropsten => "ropsten", SpecType::Kovan => "kovan", + SpecType::Rinkeby => "rinkeby", + SpecType::Goerli => "goerli", + SpecType::Kotti => "kotti", SpecType::Sokol => "sokol", SpecType::Dev => "dev", SpecType::Custom(ref custom) => custom, @@ -127,6 +136,9 @@ impl SpecType { SpecType::Morden => Ok(ethereum::new_morden(params)), SpecType::Ropsten => Ok(ethereum::new_ropsten(params)), SpecType::Kovan => Ok(ethereum::new_kovan(params)), + SpecType::Rinkeby => Ok(ethereum::new_rinkeby(params)), + SpecType::Goerli => Ok(ethereum::new_goerli(params)), + SpecType::Kotti => Ok(ethereum::new_kotti(params)), SpecType::Sokol => Ok(ethereum::new_sokol(params)), SpecType::Dev => Ok(Spec::new_instant()), SpecType::Custom(ref filename) => { @@ -385,6 +397,10 @@ mod tests { assert_eq!(SpecType::Ropsten, "ropsten".parse().unwrap()); assert_eq!(SpecType::Kovan, "kovan".parse().unwrap()); assert_eq!(SpecType::Kovan, "testnet".parse().unwrap()); + assert_eq!(SpecType::Rinkeby, "rinkeby".parse().unwrap()); + assert_eq!(SpecType::Goerli, "goerli".parse().unwrap()); + assert_eq!(SpecType::Goerli, "görli".parse().unwrap()); + assert_eq!(SpecType::Kotti, "kotti".parse().unwrap()); assert_eq!(SpecType::Sokol, "sokol".parse().unwrap()); assert_eq!(SpecType::Sokol, "poasokol".parse().unwrap()); } @@ -410,6 +426,9 @@ mod tests { assert_eq!(format!("{}", SpecType::Morden), "morden"); assert_eq!(format!("{}", SpecType::Ropsten), "ropsten"); assert_eq!(format!("{}", SpecType::Kovan), "kovan"); + assert_eq!(format!("{}", SpecType::Rinkeby), "rinkeby"); + assert_eq!(format!("{}", SpecType::Goerli), "goerli"); + assert_eq!(format!("{}", SpecType::Kotti), "kotti"); assert_eq!(format!("{}", SpecType::Sokol), "sokol"); assert_eq!(format!("{}", SpecType::Dev), "dev"); assert_eq!(format!("{}", SpecType::Custom("foo/bar".into())), "foo/bar"); diff --git a/util/version/Cargo.toml b/util/version/Cargo.toml index 8700050546..890b4e0a80 100644 --- a/util/version/Cargo.toml +++ b/util/version/Cargo.toml @@ -19,6 +19,7 @@ track = "nightly" foundation = { forkBlock = 7280000, critical = false } ropsten = { forkBlock = 4939394, critical = false } kovan = { forkBlock = 10255201, critical = false } +goerli = { forkBlock = 0, critical = false } [dependencies] parity-bytes = "0.1" From 3b2381793608549a4d8387de1256a42352318ffb Mon Sep 17 00:00:00 2001 From: Kirill Fomichev Date: Wed, 27 Mar 2019 10:01:05 +0300 Subject: [PATCH 136/168] Add trace information to eth_estimateGas (#10519) * Add trace information to eth_estimateGas * replace unwrap better version * change vm::Error formatter to more user-friendly * remove extra error format * use map_or instead sequence of map/unwrap_or --- ethcore/src/client/client.rs | 19 ++++++++++++------- ethcore/src/executed.rs | 4 ++-- rpc/src/v1/helpers/errors.rs | 6 +++--- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index 193f48b20e..1662256f49 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -1571,22 +1571,27 @@ impl Call for Client { let schedule = machine.schedule(env_info.number); Executive::new(&mut clone, &env_info, &machine, &schedule) .transact_virtual(&tx, options()) - .ok() - .map(|r| r.exception.is_none()) }; - let cond = |gas| exec(gas).unwrap_or(false); + let cond = |gas| { + exec(gas) + .ok() + .map_or(false, |r| r.exception.is_none()) + }; if !cond(upper) { upper = max_upper; match exec(upper) { - Some(false) => return Err(CallError::Exceptional), - None => { + Ok(v) => { + if let Some(exception) = v.exception { + return Err(CallError::Exceptional(exception)) + } + }, + Err(_e) => { trace!(target: "estimate_gas", "estimate_gas failed with {}", upper); let err = ExecutionError::Internal(format!("Requires higher than upper limit of {}", upper)); return Err(err.into()) - }, - _ => {}, + } } } let lower = t.gas_required(&self.engine.schedule(env_info.number)).into(); diff --git a/ethcore/src/executed.rs b/ethcore/src/executed.rs index 0f46ee1dec..10e06fd05e 100644 --- a/ethcore/src/executed.rs +++ b/ethcore/src/executed.rs @@ -167,7 +167,7 @@ pub enum CallError { /// Couldn't find requested block's state in the chain. StatePruned, /// Couldn't find an amount of gas that didn't result in an exception. - Exceptional, + Exceptional(vm::Error), /// Corrupt state. StateCorrupt, /// Error executing. @@ -187,7 +187,7 @@ impl fmt::Display for CallError { let msg = match *self { TransactionNotFound => "Transaction couldn't be found in the chain".into(), StatePruned => "Couldn't find the transaction block's state in the chain".into(), - Exceptional => "An exception happened in the execution".into(), + Exceptional(ref e) => format!("An exception ({}) happened in the execution", e), StateCorrupt => "Stored state found to be corrupted.".into(), Execution(ref e) => format!("{}", e), }; diff --git a/rpc/src/v1/helpers/errors.rs b/rpc/src/v1/helpers/errors.rs index 1ff40f979b..c04374d656 100644 --- a/rpc/src/v1/helpers/errors.rs +++ b/rpc/src/v1/helpers/errors.rs @@ -173,11 +173,11 @@ pub fn state_corrupt() -> Error { internal("State corrupt", "") } -pub fn exceptional() -> Error { +pub fn exceptional(data: T) -> Error { Error { code: ErrorCode::ServerError(codes::EXCEPTION_ERROR), message: "The execution failed due to an exception.".into(), - data: None, + data: Some(Value::String(data.to_string())), } } @@ -467,7 +467,7 @@ pub fn call(error: CallError) -> Error { match error { CallError::StatePruned => state_pruned(), CallError::StateCorrupt => state_corrupt(), - CallError::Exceptional => exceptional(), + CallError::Exceptional(e) => exceptional(e), CallError::Execution(e) => execution(e), CallError::TransactionNotFound => internal("{}, this should not be the case with eth_call, most likely a bug.", CallError::TransactionNotFound), } From 7d26a82232ff4a02ccffa759f400e001faa3d753 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Wed, 27 Mar 2019 13:46:05 +0000 Subject: [PATCH 137/168] private-tx: replace error_chain (#10510) * Update to vanilla tx pool error * private-tx: remove error-chain, implement Error, derive Display * private-tx: replace ErrorKind and bail! * private-tx: add missing From impls and other compiler errors * private-tx: use original tx-pool error * Don't be silly cargo --- Cargo.lock | 14 +- ethcore/private-tx/Cargo.toml | 2 +- ethcore/private-tx/src/encryptor.rs | 26 +- ethcore/private-tx/src/error.rs | 289 +++++++++--------- ethcore/private-tx/src/lib.rs | 53 ++-- .../private-tx/src/private_transactions.rs | 6 +- ethcore/service/src/error.rs | 5 +- 7 files changed, 199 insertions(+), 196 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 811bb6cbc7..fd1b238d97 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -513,6 +513,17 @@ dependencies = [ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "derive_more" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "difference" version = "1.0.0" @@ -1006,8 +1017,8 @@ name = "ethcore-private-tx" version = "1.0.0" dependencies = [ "common-types 0.1.0", + "derive_more 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)", - "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethabi 6.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethabi-contract 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethabi-derive 6.0.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4513,6 +4524,7 @@ dependencies = [ "checksum csv-core 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4dd8e6d86f7ba48b4276ef1317edc8cc36167546d8972feb4a2b5fec0b374105" "checksum ct-logs 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1b4660f8b07a560a88c02d76286edb9f0d5d64e495d2b0f233186155aa51be1f" "checksum ctrlc 1.1.1 (git+https://github.com/paritytech/rust-ctrlc.git)" = "" +"checksum derive_more 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fbe9f11be34f800b3ecaaed0ec9ec2e015d1d0ba0c8644c1310f73d6e8994615" "checksum difference 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b3304d19798a8e067e48d8e69b2c37f0b5e9b4e462504ad9e27e9f3fce02bba8" "checksum digest 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "03b072242a8cbaf9c145665af9d250c59af3b958f83ed6824e13533cf76d5b90" "checksum docopt 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "db2906c2579b5b7207fc1e328796a9a8835dc44e22dbe8e460b1d636f9a7b225" diff --git a/ethcore/private-tx/Cargo.toml b/ethcore/private-tx/Cargo.toml index fdf6e52baa..a50d704ab4 100644 --- a/ethcore/private-tx/Cargo.toml +++ b/ethcore/private-tx/Cargo.toml @@ -7,7 +7,7 @@ authors = ["Parity Technologies "] [dependencies] common-types = { path = "../types" } -error-chain = { version = "0.12", default-features = false } +derive_more = "0.14.0" ethabi = "6.0" ethabi-contract = "6.0" ethabi-derive = "6.0" diff --git a/ethcore/private-tx/src/encryptor.rs b/ethcore/private-tx/src/encryptor.rs index 2d284dd38a..597cc88796 100644 --- a/ethcore/private-tx/src/encryptor.rs +++ b/ethcore/private-tx/src/encryptor.rs @@ -31,7 +31,7 @@ use crypto; use futures::Future; use fetch::{Fetch, Client as FetchClient, Method, BodyReader, Request}; use bytes::{Bytes, ToPretty}; -use error::{Error, ErrorKind}; +use error::Error; use url::Url; use super::Signer; use super::key_server_keys::address_to_key; @@ -111,11 +111,11 @@ impl SecretStoreEncryptor { return Ok(key); } let contract_address_signature = self.sign_contract_address(contract_address)?; - let requester = self.config.key_server_account.ok_or_else(|| ErrorKind::KeyServerAccountNotSet)?; + let requester = self.config.key_server_account.ok_or_else(|| Error::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)?; + let base_url = self.config.base_url.clone().ok_or_else(|| Error::KeyServerNotSet)?; // prepare request url let url = format!("{}/{}/{}{}", @@ -132,16 +132,16 @@ impl SecretStoreEncryptor { Method::GET }; - let url = Url::from_str(&url).map_err(|e| ErrorKind::Encrypt(e.to_string()))?; + let url = Url::from_str(&url).map_err(|e| Error::Encrypt(e.to_string()))?; let response = self.client.fetch(Request::new(url, method), Default::default()).wait() - .map_err(|e| ErrorKind::Encrypt(e.to_string()))?; + .map_err(|e| Error::Encrypt(e.to_string()))?; if response.is_not_found() { - bail!(ErrorKind::EncryptionKeyNotFound(*contract_address)); + return Err(Error::EncryptionKeyNotFound(*contract_address)); } if !response.is_success() { - bail!(ErrorKind::Encrypt(response.status().canonical_reason().unwrap_or("unknown").into())); + return Err(Error::Encrypt(response.status().canonical_reason().unwrap_or("unknown").into())); } // read HTTP response @@ -149,7 +149,7 @@ impl SecretStoreEncryptor { 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 encrypted_bytes: ethjson::bytes::Bytes = result.trim_matches('\"').parse().map_err(|e| Error::Encrypt(e))?; // decrypt Public let decrypted_bytes = self.signer.decrypt(requester, &crypto::DEFAULT_MAC, &encrypted_bytes)?; @@ -189,7 +189,7 @@ impl SecretStoreEncryptor { } fn sign_contract_address(&self, contract_address: &Address) -> Result { - let key_server_account = self.config.key_server_account.ok_or_else(|| ErrorKind::KeyServerAccountNotSet)?; + let key_server_account = self.config.key_server_account.ok_or_else(|| Error::KeyServerAccountNotSet)?; Ok(self.signer.sign(key_server_account, address_to_key(contract_address))?) } } @@ -204,7 +204,7 @@ impl Encryptor for SecretStoreEncryptor { // retrieve the key, try to generate it if it doesn't exist yet let key = match self.retrieve_key("", false, contract_address) { Ok(key) => Ok(key), - Err(Error(ErrorKind::EncryptionKeyNotFound(_), _)) => { + Err(Error::EncryptionKeyNotFound(_)) => { trace!(target: "privatetx", "Key for account wasnt found in sstore. Creating. Address: {:?}", contract_address); self.retrieve_key(&format!("/{}", self.config.threshold), true, contract_address) } @@ -215,7 +215,7 @@ impl Encryptor for SecretStoreEncryptor { let mut cypher = Vec::with_capacity(plain_data.len() + initialisation_vector.len()); cypher.extend(repeat(0).take(plain_data.len())); crypto::aes::encrypt_128_ctr(&key, initialisation_vector, plain_data, &mut cypher) - .map_err(|e| ErrorKind::Encrypt(e.to_string()))?; + .map_err(|e| Error::Encrypt(e.to_string()))?; cypher.extend_from_slice(&initialisation_vector); Ok(cypher) @@ -230,7 +230,7 @@ impl Encryptor for SecretStoreEncryptor { // initialization vector takes INIT_VEC_LEN bytes let cypher_len = cypher.len(); if cypher_len < INIT_VEC_LEN { - bail!(ErrorKind::Decrypt("Invalid cypher".into())); + return Err(Error::Decrypt("Invalid cypher".into())); } // retrieve existing key @@ -241,7 +241,7 @@ impl Encryptor for SecretStoreEncryptor { let mut plain_data = Vec::with_capacity(cypher_len - INIT_VEC_LEN); plain_data.extend(repeat(0).take(cypher_len - INIT_VEC_LEN)); crypto::aes::decrypt_128_ctr(&key, &iv, cypher, &mut plain_data) - .map_err(|e| ErrorKind::Decrypt(e.to_string()))?; + .map_err(|e| Error::Decrypt(e.to_string()))?; Ok(plain_data) } } diff --git a/ethcore/private-tx/src/error.rs b/ethcore/private-tx/src/error.rs index 60eb17987a..8c86bf0cad 100644 --- a/ethcore/private-tx/src/error.rs +++ b/ethcore/private-tx/src/error.rs @@ -14,10 +14,8 @@ // You should have received a copy of the GNU General Public License // along with Parity Ethereum. If not, see . -// Silence: `use of deprecated item 'std::error::Error::cause': replaced by Error::source, which can support downcasting` -// https://github.com/paritytech/parity-ethereum/issues/10302 -#![allow(deprecated)] - +use std::error; +use derive_more::Display; use ethereum_types::Address; use rlp::DecoderError; use ethtrie::TrieError; @@ -25,173 +23,170 @@ use ethcore::error::{Error as EthcoreError, ExecutionError}; use types::transaction::Error as TransactionError; use ethkey::Error as KeyError; use ethkey::crypto::Error as CryptoError; -use txpool::Error as TxPoolError; - -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."]; - Txpool(TxPoolError) #[doc = "Tx pool error."]; - Crypto(CryptoError) #[doc = "Crypto error."]; - } - - 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."] - BadTransactionType { - 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), - } +use txpool::{Error as TxPoolError}; + +#[derive(Debug, Display)] +pub enum Error { + /// Error concerning the Rust standard library's IO subsystem. + #[display(fmt = "Io Error: {}", _0)] + Io(::std::io::Error), + /// RLP decoding error. + #[display(fmt = "Decoder Error: {}", _0)] + Decoder(DecoderError), + /// Error concerning TrieDBs. + #[display(fmt = "Trie Error: {}", _0)] + Trie(TrieError), + /// Transaction pool error. + #[display(fmt = "Transaction Pool Error: {}", _0)] + TxPool(TxPoolError), + /// Crypto error. + #[display(fmt = "Crypto Error {}", _0)] + Crypto(CryptoError), + /// Encryption error. + #[display(fmt = "Encryption error. ({})", _0)] + Encrypt(String), + /// Decryption error. + #[display(fmt = "Decryption error. ({})", _0)] + Decrypt(String), + /// Address not authorized. + #[display(fmt = "Private transaction execution is not authorised for {}", _0)] + NotAuthorised(Address), + /// Transaction creates more than one contract. + #[display(fmt = "Private transaction created too many contracts")] + TooManyContracts, + /// Contract call error. + #[display(fmt = "Contract call error. ({})", _0)] + Call(String), + /// State is not available. + #[display(fmt = "State is not available")] + StatePruned, + /// State is incorrect. + #[display(fmt = "State is incorrect")] + StateIncorrect, + /// Wrong private transaction type. + #[display(fmt = "Wrong private transaction type")] + BadTransactionType, + /// Contract does not exist or was not created. + #[display(fmt = "Contract does not exist or was not created")] + ContractDoesNotExist, + /// Reference to the client is corrupted. + #[display(fmt = "Reference to the client is corrupted")] + ClientIsMalformed, + /// Queue of private transactions for verification is full. + #[display(fmt = "Queue of private transactions for verification is full")] + QueueIsFull, + /// The transaction already exists in queue of private transactions. + #[display(fmt = "The transaction already exists in queue of private transactions.")] + PrivateTransactionAlreadyImported, + /// The information about private transaction is not found in the store. + #[display(fmt = "The information about private transaction is not found in the store.")] + PrivateTransactionNotFound, + /// Account for signing public transactions not set. + #[display(fmt = "Account for signing public transactions not set.")] + SignerAccountNotSet, + /// Account for validating private transactions not set. + #[display(fmt = "Account for validating private transactions not set.")] + ValidatorAccountNotSet, + /// Account for signing requests to key server not set. + #[display(fmt = "Account for signing requests to key server not set.")] + KeyServerAccountNotSet, + /// Encryption key is not found on key server. + #[display(fmt = "Encryption key is not found on key server for {}", _0)] + EncryptionKeyNotFound(Address), + /// Key server URL is not set. + #[display(fmt = "Key server URL is not set.")] + KeyServerNotSet, + /// VM execution error. + #[display(fmt = "VM execution error {}", _0)] + Execution(ExecutionError), + /// General signing error. + #[display(fmt = "General signing error {}", _0)] + Key(KeyError), + /// Error of transactions processing. + #[display(fmt = "Error of transactions processing {}", _0)] + Transaction(TransactionError), + /// General ethcore error. + #[display(fmt = "General ethcore error {}", _0)] + Ethcore(EthcoreError), + /// A convenient variant for String. + #[display(fmt = "{}", _0)] + Msg(String), +} - #[doc = "General signing error."] - Key(err: KeyError) { - description("General signing error."), - display("General signing error {}", err), +impl error::Error for Error { + fn source(&self) -> Option<&(error::Error + 'static)> { + match self { + Error::Io(e) => Some(e), + Error::Decoder(e) => Some(e), + Error::Trie(e) => Some(e), + Error::TxPool(e) => Some(e), + Error::Crypto(e) => Some(e), + Error::Execution(e) => Some(e), + Error::Key(e) => Some(e), + Error::Transaction(e) => Some(e), + Error::Ethcore(e) => Some(e), + _ => None, } + } +} - #[doc = "Error of transactions processing."] - Transaction(err: TransactionError) { - description("Error of transactions processing."), - display("Error of transactions processing {}", err), - } +impl From for Error { + fn from(s: String) -> Self { + Error::Msg(s) + } +} - #[doc = "General ethcore error."] - Ethcore(err: EthcoreError) { - description("General ethcore error."), - display("General ethcore error {}", err), - } +impl From for Error { + fn from(err: std::io::Error) -> Self { + Error::Io(err).into() } } impl From for Error { fn from(err: KeyError) -> Self { - ErrorKind::Key(err).into() + Error::Key(err).into() + } +} + +impl From for Error { + fn from(err: CryptoError) -> Self { + Error::Crypto(err).into() + } +} + +impl From for Error { + fn from(err: DecoderError) -> Self { + Error::Decoder(err).into() } } impl From for Error { fn from(err: ExecutionError) -> Self { - ErrorKind::Execution(err).into() + Error::Execution(err).into() } } impl From for Error { fn from(err: TransactionError) -> Self { - ErrorKind::Transaction(err).into() + Error::Transaction(err).into() + } +} + +impl From for Error { + fn from(err: TrieError) -> Self { + Error::Trie(err).into() + } +} + +impl From for Error { + fn from(err: TxPoolError) -> Self { + Error::TxPool(err).into() } } impl From for Error { fn from(err: EthcoreError) -> Self { - ErrorKind::Ethcore(err).into() + Error::Ethcore(err).into() } } diff --git a/ethcore/private-tx/src/lib.rs b/ethcore/private-tx/src/lib.rs index 8d2a087da5..64381b497b 100644 --- a/ethcore/private-tx/src/lib.rs +++ b/ethcore/private-tx/src/lib.rs @@ -54,8 +54,7 @@ extern crate log; extern crate ethabi_derive; #[macro_use] extern crate ethabi_contract; -#[macro_use] -extern crate error_chain; +extern crate derive_more; #[macro_use] extern crate rlp_derive; @@ -68,7 +67,7 @@ pub use encryptor::{Encryptor, SecretStoreEncryptor, EncryptorConfig, NoopEncryp pub use key_server_keys::{KeyProvider, SecretStoreKeys, StoringKeyProvider}; pub use private_transactions::{VerifiedPrivateTransaction, VerificationStore, PrivateTransactionSigningDesc, SigningStore}; pub use messages::{PrivateTransaction, SignedPrivateTransaction}; -pub use error::{Error, ErrorKind}; +pub use error::Error; use std::sync::{Arc, Weak}; use std::collections::{HashMap, HashSet, BTreeMap}; @@ -238,10 +237,10 @@ impl Provider { trace!(target: "privatetx", "Creating private transaction from regular transaction: {:?}", signed_transaction); if self.signer_account.is_none() { warn!(target: "privatetx", "Signing account not set"); - bail!(ErrorKind::SignerAccountNotSet); + return Err(Error::SignerAccountNotSet); } let tx_hash = signed_transaction.hash(); - let contract = Self::contract_address_from_transaction(&signed_transaction).map_err(|_| ErrorKind::BadTransactionType)?; + let contract = Self::contract_address_from_transaction(&signed_transaction).map_err(|_| Error::BadTransactionType)?; let data = signed_transaction.rlp_bytes(); let encrypted_transaction = self.encrypt(&contract, &Self::iv_from_transaction(&signed_transaction), &data)?; let private = PrivateTransaction::new(encrypted_transaction, contract); @@ -309,19 +308,19 @@ impl Provider { // TODO #9825 [ToDr] Usage of BlockId::Latest let contract_nonce = self.get_contract_nonce(&contract, BlockId::Latest); if let Err(e) = contract_nonce { - bail!("Cannot retrieve contract nonce: {:?}", e); + return Err(format!("Cannot retrieve contract nonce: {:?}", e).into()); } let contract_nonce = contract_nonce.expect("Error was checked before"); let private_state = self.execute_private_transaction(BlockId::Latest, &transaction.transaction); if let Err(e) = private_state { - bail!("Cannot retrieve private state: {:?}", e); + return Err(format!("Cannot retrieve private state: {:?}", e).into()); } let private_state = private_state.expect("Error was checked before"); let private_state_hash = self.calculate_state_hash(&private_state, contract_nonce); trace!(target: "privatetx", "Hashed effective private state for validator: {:?}", private_state_hash); let signed_state = self.accounts.sign(validator_account, private_state_hash); if let Err(e) = signed_state { - bail!("Cannot sign the state: {:?}", e); + return Err(format!("Cannot sign the state: {:?}", e).into()); } let signed_state = signed_state.expect("Error was checked before"); let signed_private_transaction = SignedPrivateTransaction::new(private_hash, signed_state, None); @@ -362,8 +361,8 @@ impl Provider { signatures.push(signed_tx.signature()); let rsv: Vec = signatures.into_iter().map(|sign| sign.into_electrum().into()).collect(); // Create public transaction - let signer_account = self.signer_account.ok_or_else(|| ErrorKind::SignerAccountNotSet)?; - let state = self.client.state_at(BlockId::Latest).ok_or(ErrorKind::StatePruned)?; + let signer_account = self.signer_account.ok_or_else(|| Error::SignerAccountNotSet)?; + let state = self.client.state_at(BlockId::Latest).ok_or(Error::StatePruned)?; let nonce = state.nonce(&signer_account)?; let public_tx = self.public_transaction( desc.state.clone(), @@ -382,7 +381,7 @@ impl Provider { Ok(_) => trace!(target: "privatetx", "Public transaction added to queue"), Err(err) => { warn!(target: "privatetx", "Failed to add transaction to queue, error: {:?}", err); - bail!(err); + return Err(err.into()); } } // Notify about state changes @@ -397,7 +396,7 @@ impl Provider { // Remove from store for signing if let Err(err) = self.transactions_for_signing.write().remove(&private_hash) { warn!(target: "privatetx", "Failed to remove transaction from signing store, error: {:?}", err); - bail!(err); + return Err(err); } } else { // Add signature to the store @@ -405,7 +404,7 @@ impl Provider { Ok(_) => trace!(target: "privatetx", "Signature stored for private transaction"), Err(err) => { warn!(target: "privatetx", "Failed to add signature to signing store, error: {:?}", err); - bail!(err); + return Err(err); } } } @@ -417,7 +416,7 @@ impl Provider { Action::Call(contract) => Ok(contract), _ => { warn!(target: "privatetx", "Incorrect type of action for the transaction"); - bail!(ErrorKind::BadTransactionType); + return Err(Error::BadTransactionType); } } } @@ -436,13 +435,13 @@ impl Provider { } false => { warn!(target: "privatetx", "Sender's state doesn't correspond to validator's"); - bail!(ErrorKind::StateIncorrect); + return Err(Error::StateIncorrect); } } } Err(err) => { warn!(target: "privatetx", "Sender's state doesn't correspond to validator's, error {:?}", err); - bail!(err); + return Err(err.into()); } } } @@ -482,21 +481,21 @@ impl Provider { fn get_decrypted_state(&self, address: &Address, block: BlockId) -> Result { let (data, decoder) = private_contract::functions::state::call(); let value = self.client.call_contract(block, *address, data)?; - let state = decoder.decode(&value).map_err(|e| ErrorKind::Call(format!("Contract call failed {:?}", e)))?; + let state = decoder.decode(&value).map_err(|e| Error::Call(format!("Contract call failed {:?}", e)))?; self.decrypt(address, &state) } fn get_decrypted_code(&self, address: &Address, block: BlockId) -> Result { let (data, decoder) = private_contract::functions::code::call(); let value = self.client.call_contract(block, *address, data)?; - let state = decoder.decode(&value).map_err(|e| ErrorKind::Call(format!("Contract call failed {:?}", e)))?; + let state = decoder.decode(&value).map_err(|e| Error::Call(format!("Contract call failed {:?}", e)))?; self.decrypt(address, &state) } pub fn get_contract_nonce(&self, address: &Address, block: BlockId) -> Result { let (data, decoder) = private_contract::functions::nonce::call(); let value = self.client.call_contract(block, *address, data)?; - decoder.decode(&value).map_err(|e| ErrorKind::Call(format!("Contract call failed {:?}", e)).into()) + decoder.decode(&value).map_err(|e| Error::Call(format!("Contract call failed {:?}", e)).into()) } fn snapshot_to_storage(raw: Bytes) -> HashMap { @@ -533,10 +532,10 @@ impl Provider { T: Tracer, V: VMTracer, { - let mut env_info = self.client.env_info(block).ok_or(ErrorKind::StatePruned)?; + let mut env_info = self.client.env_info(block).ok_or(Error::StatePruned)?; env_info.gas_limit = transaction.gas; - let mut state = self.client.state_at(block).ok_or(ErrorKind::StatePruned)?; + let mut state = self.client.state_at(block).ok_or(Error::StatePruned)?; // TODO #9825 in case of BlockId::Latest these need to operate on the same state let contract_address = match transaction.action { Action::Call(ref contract_address) => { @@ -612,15 +611,15 @@ impl Provider { /// Create encrypted public contract deployment transaction. pub fn public_creation_transaction(&self, block: BlockId, source: &SignedTransaction, validators: &[Address], gas_price: U256) -> Result<(Transaction, Address), Error> { if let Action::Call(_) = source.action { - bail!(ErrorKind::BadTransactionType); + return Err(Error::BadTransactionType); } let sender = source.sender(); - let state = self.client.state_at(block).ok_or(ErrorKind::StatePruned)?; + let state = self.client.state_at(block).ok_or(Error::StatePruned)?; let nonce = state.nonce(&sender)?; let executed = self.execute_private(source, TransactOptions::with_no_tracing(), block)?; let header = self.client.block_header(block) - .ok_or(ErrorKind::StatePruned) - .and_then(|h| h.decode().map_err(|_| ErrorKind::StateIncorrect).into())?; + .ok_or(Error::StatePruned) + .and_then(|h| h.decode().map_err(|_| Error::StateIncorrect).into())?; let (executed_code, executed_state) = (executed.code.unwrap_or_default(), executed.state); let tx_data = Self::generate_constructor(validators, executed_code.clone(), executed_state.clone()); let mut tx = Transaction { @@ -651,7 +650,7 @@ impl Provider { /// 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::BadTransactionType); + return Err(Error::BadTransactionType); } let result = self.execute_private(source, TransactOptions::with_no_tracing(), block)?; Ok(result.state) @@ -680,7 +679,7 @@ impl Provider { pub fn get_validators(&self, block: BlockId, address: &Address) -> Result, Error> { let (data, decoder) = private_contract::functions::get_validators::call(); let value = self.client.call_contract(block, *address, data)?; - decoder.decode(&value).map_err(|e| ErrorKind::Call(format!("Contract call failed {:?}", e)).into()) + decoder.decode(&value).map_err(|e| Error::Call(format!("Contract call failed {:?}", e)).into()) } fn get_contract_version(&self, block: BlockId, address: &Address) -> usize { diff --git a/ethcore/private-tx/src/private_transactions.rs b/ethcore/private-tx/src/private_transactions.rs index 21989025b1..0182c82dd9 100644 --- a/ethcore/private-tx/src/private_transactions.rs +++ b/ethcore/private-tx/src/private_transactions.rs @@ -28,7 +28,7 @@ use parking_lot::RwLock; use types::transaction::{UnverifiedTransaction, SignedTransaction}; use txpool; use txpool::{VerifiedTransaction, Verifier}; -use error::{Error, ErrorKind}; +use error::Error; type Pool = txpool::Pool; @@ -228,7 +228,7 @@ impl SigningStore { contract_nonce: U256, ) -> Result<(), Error> { if self.transactions.len() > MAX_QUEUE_LEN { - bail!(ErrorKind::QueueIsFull); + return Err(Error::QueueIsFull); } self.transactions.insert(private_hash, PrivateTransactionSigningDesc { @@ -254,7 +254,7 @@ impl SigningStore { /// 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)?; + let desc = self.transactions.get_mut(private_hash).ok_or_else(|| Error::PrivateTransactionNotFound)?; if !desc.received_signatures.contains(&signature) { desc.received_signatures.push(signature); } diff --git a/ethcore/service/src/error.rs b/ethcore/service/src/error.rs index d46abe1d95..c73cb0dfc1 100644 --- a/ethcore/service/src/error.rs +++ b/ethcore/service/src/error.rs @@ -23,12 +23,9 @@ 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); + PrivateTransactions(ethcore_private_tx::Error); } } From 407de5e8c43b4733844580fb3f22023e4497a718 Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Wed, 27 Mar 2019 14:46:20 +0100 Subject: [PATCH 138/168] fix(light): make `OnDemand` generic instead of using the concrete type (#10514) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * ethcore: add clique engine (#9981) * fix broken sync * correct seal fields * ethcore: fix comment * parity: remove duplicate params * clique: fix whitespaces * ethcore: fix goerli chain spec * refactor signer_snapshot into pending/finalized state * move close_block_extra_data after seal is applied * refactor most of the logic into the signer_snapshot * clique: refactor locking logic out of the consensus engine interface * Fix jsonspec and add an unittest * Replace space with tabs * Unbroke sync * Fix broken sync * 1/2 state tracking without votes * 2/2 implement vote tracking * ci: use travis for goerli * ci: setup a clique network * ci: sync a görli node * add clique deploy script * ci: fix paths in clique deploy script * ci: use docker compose * ci: fix travis job names * ci: fix build deps * ci: massively reduce tests * Revert "ci: massively reduce tests" This reverts commit 6369f0b069ed2607a7e9f2e1d85489bacdc43384. * ci: run cargo test directly * ci: separate build and test stages * ci: cache rust installation * ci: simplify ci stages * ci: make clique deploy script executable * ci: shutdown goerli sync after 20min * ci: remove slow sync stage * ci: use timeout to finish jobs * ci: fix build path * ci: use absolute paths to end this confusion * ci: add geth and parity to path * ci: be more verbose * ci: allow for more relaxed caching timeout * ci: update repositories for custom ppa * ci: fix typo in file name * ci: fix docker compose file * ci: add ethkey to docker * ci: make sure deploy script is up to date with upstream * ci: stop docker container after certain time * ci: force superuser to update permissions on docker files * ci: reduce run time of script to ~30 min * ci: remove duplicate caching in travis * remove trace statements * clique: add more validation involving the recent signer list * ethcore: enable constantinople for rinkeby * ethcore: fix whitespaces in rinkeby spec * ethcore: reformat goerli.json * Revert "ci: remove duplicate caching in travis" This reverts commit a562838d3d194d37f9871dcbe00b783637978f89. * tmp commit * another tmp commit * it builds! * add sealing capabilities * add seal_header hook to allow separation of block seal/importing code paths * clique: remove populate_from_parent. * add panic * make turn delay random * initialize OpenBlock properly in 'enact' * misc: remove duplicate lines * misc: fix license headers * misc: convert spaces to tabs * misc: fix tabs * Update Cargo.toml * Update Cargo.toml * Update Cargo.toml * clique: ensure validator restores state before trying to seal * clique: make 'state' return an Error. Make some error messages more clear * Fix compile error after rebase & toolchain upgrade * fix a bunch of import warnings * Refactor code * Fix permissions * Refactoring syncing * Implement full validator checks * Refactor util functions to seperate file * mining 1 * ethcore: add chainspec for kotti * ethcore: rename pre-goerli configs * ethcore: load kotti chain spec * cli: add kotti to params * Implement working local sealing * making sealing & syncing work together * Relax timestamp checking * ethcore: prepare for the real goerli to launch * Implement NOTURN wiggle properly & cleanupnup warnings * Implement vote casting * Update docs & skip signing if no signer * Optimize step-service interval * Record state on local sealed block * Fix script filemode * Cleaning up codebase * restore enact trace logging * Delete clique.sh and move sync.sh * remove travis.yml * Remove dead code * Cleanup compile warning * address review comments * adding more comments and removing unwrap() * ci: remove sync script * Address review comments * fix compile error * adding better debugging for timing * Implement an dedicated thread for sealing timing * fix(add helper for timestamp overflows) (#10330) * fix(add helper timestamp overflows) * fix(simplify code) * fix(make helper private) * snap: official image / test (#10168) * official image / test * fix / test * bit more necromancy * fix paths * add source bin/df /test * add source bin/df /test2 * something w paths /test * something w paths /test * add source-type /test * show paths /test * copy plugin /test * plugin -> nil * install rhash * no questions while installing rhash * publish snap only for release * fix(docker): fix not receives SIGINT (#10059) * fix(docker): fix not receives SIGINT * fix: update with reviews * update with review * update * update * Don't add discovery initiators to the node table (#10305) * Don't add discovery initiators to the node table * Use enums for tracking state of the nodes in discovery * Dont try to ping ourselves * Fix minor nits * Update timeouts when observing an outdated node * Extracted update_bucket_record from update_node * Fixed typo * Fix two final nits from @todr * change docker image based on debian instead of ubuntu due to the chan… (#10336) * change docker image based on debian instead of ubuntu due to the changes of the build container * role back docker build image and docker deploy image to ubuntu:xenial based (#10338) * Bundle protocol and packet_id together in chain sync (#10315) Define a new `enum` where devp2p subprotocol packet ids (currently eth and par) are defined. Additionally provide functionality to query id value and protocol of a given id object. * snap: prefix version and populate candidate channel (#10343) * snap: populate candidate releases with beta snaps to avoid stale channel * snap: prefix version with v* * addressing review comments * engine: fix copyright header * scripts: restore permissions on sign command * ethcore: enforce tabs * ethcore: enforce tabs * ethcore: enforce tabs * addressing comments * addressing comments * addressing more comments * addressing more comments * addressing more comments * addressing more comments * addressing more comments * json-spec: fix clique epoch to non-zero u64 * ci: enable travis for parity goerli * ci: don't separate build and test step * ci: don't run c++ tests on travis * ci: simplify cargo test to squeeze into travis timeout * ci: don't run tests on travis at all * style(fixes) * fix(add tests) * fix(recent_signer bug) * fix(complete all tests) * fix(nits) * fix(simplify asserts) * fix(cliqueState): simplify code * fix(nits) * docs(comments what's need to fixed) * fix(revert unintended changes) * fix(tests) * fix(logs): voting logs * fix(readability + more logs) * fix(sync) * docs(add missing licens header) * fix(log): info! -> trace! * docs(fix nits) + fix(remove assert) * perf(use counter instead of vec) * fix(remove needless block in match) * fix(faulty comment) * grumbles(docs for tests) * fix(nits) * fix(revert_vote): only remove vote when votes == 0 * fix(vote counter): checked arithmetics * fix(simplify tests) * fix(nits) * fix(clique): err types * fix(clique utils): make use of errors * fix(cleanup nits) * fix(clique sealing): don't read state no signer * fix(replace Vec with BTreeSet) * fix(tests): BTreeSet and more generic helpers * fix(nits) * fix(ethcore_block_seal): remove needless `Box` * fix(faulty log): info -> trace * fix(checked SystemTime): prevent SystemTime panics * style(chain cfg): space after `:` * style(fn enact): fix whitespace * docs(clique): StepService * docs(nit): fix faulty comment * docs(fix typo) * style(fix bad indentation) * fix(bad regex match) * grumble(on_seal_block): make `&mut` to avoid clone * docs(on_seal_block): fix faulty documentation * Delete .travis.yml * docs: remove eth hf references in spec * Update client.rs * fix(nits) * fix(clique step): `RwLock` -> `AtomicBool` * fix(clique): use `Duration::as_millis` * Clean up some Clique documentation * Add trace information to eth_estimateGas (#10519) * Add trace information to eth_estimateGas * replace unwrap better version * change vm::Error formatter to more user-friendly * remove extra error format * use map_or instead sequence of map/unwrap_or * fix(light/on_demand): extract as a trait * fix(grumble): OnDemand remove needless trait bound --- ethcore/light/src/on_demand/mod.rs | 153 +++++++++++++++------------ ethcore/light/src/on_demand/tests.rs | 2 +- parity/light_helpers/epoch_fetch.rs | 2 +- parity/light_helpers/queue_cull.rs | 2 +- rpc/src/v1/helpers/dispatch/light.rs | 37 ++++--- rpc/src/v1/helpers/light_fetch.rs | 48 +++++---- rpc/src/v1/impls/eth_pubsub.rs | 14 +-- rpc/src/v1/impls/light/eth.rs | 30 +++--- rpc/src/v1/impls/light/parity.rs | 23 ++-- 9 files changed, 179 insertions(+), 132 deletions(-) diff --git a/ethcore/light/src/on_demand/mod.rs b/ethcore/light/src/on_demand/mod.rs index c04c687947..7d1f4fabf8 100644 --- a/ethcore/light/src/on_demand/mod.rs +++ b/ethcore/light/src/on_demand/mod.rs @@ -94,6 +94,24 @@ pub mod error { } } +/// Public interface for performing network requests `OnDemand` +pub trait OnDemandRequester: Send + Sync { + /// Submit a strongly-typed batch of requests. + /// + /// Fails if back-reference are not coherent. + fn request(&self, ctx: &BasicContext, requests: T) -> Result, basic_request::NoSuchOutput> + where + T: request::RequestAdapter; + + /// Submit a vector of requests to be processed together. + /// + /// Fails if back-references are not coherent. + /// The returned vector of responses will correspond to the requests exactly. + fn request_raw(&self, ctx: &BasicContext, requests: Vec) + -> Result, basic_request::NoSuchOutput>; +} + + // relevant peer info. #[derive(Debug, Clone, PartialEq, Eq)] struct Peer { @@ -355,71 +373,8 @@ pub struct OnDemand { request_number_of_consecutive_errors: usize } -impl OnDemand { - - /// Create a new `OnDemand` service with the given cache. - pub fn new( - cache: Arc>, - response_time_window: Duration, - request_backoff_start: Duration, - request_backoff_max: Duration, - request_backoff_rounds_max: usize, - request_number_of_consecutive_errors: usize, - ) -> Self { - - Self { - pending: RwLock::new(Vec::new()), - peers: RwLock::new(HashMap::new()), - in_transit: RwLock::new(HashMap::new()), - cache, - no_immediate_dispatch: false, - response_time_window: Self::sanitize_circuit_breaker_input(response_time_window, "Response time window"), - request_backoff_start: Self::sanitize_circuit_breaker_input(request_backoff_start, "Request initial backoff time window"), - request_backoff_max: Self::sanitize_circuit_breaker_input(request_backoff_max, "Request maximum backoff time window"), - request_backoff_rounds_max, - request_number_of_consecutive_errors, - } - } - - fn sanitize_circuit_breaker_input(dur: Duration, name: &'static str) -> Duration { - if dur.as_secs() < 1 { - warn!(target: "on_demand", - "{} is too short must be at least 1 second, configuring it to 1 second", name); - Duration::from_secs(1) - } else { - dur - } - } - - // make a test version: this doesn't dispatch pending requests - // until you trigger it manually. - #[cfg(test)] - fn new_test( - cache: Arc>, - request_ttl: Duration, - request_backoff_start: Duration, - request_backoff_max: Duration, - request_backoff_rounds_max: usize, - request_number_of_consecutive_errors: usize, - ) -> Self { - let mut me = OnDemand::new( - cache, - request_ttl, - request_backoff_start, - request_backoff_max, - request_backoff_rounds_max, - request_number_of_consecutive_errors, - ); - me.no_immediate_dispatch = true; - - me - } - - /// Submit a vector of requests to be processed together. - /// - /// Fails if back-references are not coherent. - /// The returned vector of responses will correspond to the requests exactly. - pub fn request_raw(&self, ctx: &BasicContext, requests: Vec) +impl OnDemandRequester for OnDemand { + fn request_raw(&self, ctx: &BasicContext, requests: Vec) -> Result, basic_request::NoSuchOutput> { let (sender, receiver) = oneshot::channel(); @@ -475,10 +430,7 @@ impl OnDemand { Ok(receiver) } - /// Submit a strongly-typed batch of requests. - /// - /// Fails if back-reference are not coherent. - pub fn request(&self, ctx: &BasicContext, requests: T) -> Result, basic_request::NoSuchOutput> + fn request(&self, ctx: &BasicContext, requests: T) -> Result, basic_request::NoSuchOutput> where T: request::RequestAdapter { self.request_raw(ctx, requests.make_requests()).map(|recv| OnResponses { @@ -487,6 +439,69 @@ impl OnDemand { }) } +} + +impl OnDemand { + + /// Create a new `OnDemand` service with the given cache. + pub fn new( + cache: Arc>, + response_time_window: Duration, + request_backoff_start: Duration, + request_backoff_max: Duration, + request_backoff_rounds_max: usize, + request_number_of_consecutive_errors: usize, + ) -> Self { + + Self { + pending: RwLock::new(Vec::new()), + peers: RwLock::new(HashMap::new()), + in_transit: RwLock::new(HashMap::new()), + cache, + no_immediate_dispatch: false, + response_time_window: Self::sanitize_circuit_breaker_input(response_time_window, "Response time window"), + request_backoff_start: Self::sanitize_circuit_breaker_input(request_backoff_start, "Request initial backoff time window"), + request_backoff_max: Self::sanitize_circuit_breaker_input(request_backoff_max, "Request maximum backoff time window"), + request_backoff_rounds_max, + request_number_of_consecutive_errors, + } + } + + fn sanitize_circuit_breaker_input(dur: Duration, name: &'static str) -> Duration { + if dur.as_secs() < 1 { + warn!(target: "on_demand", + "{} is too short must be at least 1 second, configuring it to 1 second", name); + Duration::from_secs(1) + } else { + dur + } + } + + // make a test version: this doesn't dispatch pending requests + // until you trigger it manually. + #[cfg(test)] + fn new_test( + cache: Arc>, + request_ttl: Duration, + request_backoff_start: Duration, + request_backoff_max: Duration, + request_backoff_rounds_max: usize, + request_number_of_consecutive_errors: usize, + ) -> Self { + let mut me = OnDemand::new( + cache, + request_ttl, + request_backoff_start, + request_backoff_max, + request_backoff_rounds_max, + request_number_of_consecutive_errors, + ); + me.no_immediate_dispatch = true; + + me + } + + // maybe dispatch pending requests. // sometimes fn attempt_dispatch(&self, ctx: &BasicContext) { diff --git a/ethcore/light/src/on_demand/tests.rs b/ethcore/light/src/on_demand/tests.rs index fd0e8b0f97..49ec35f10d 100644 --- a/ethcore/light/src/on_demand/tests.rs +++ b/ethcore/light/src/on_demand/tests.rs @@ -29,7 +29,7 @@ use std::sync::Arc; use std::time::{Duration, Instant}; use std::thread; -use super::{request, OnDemand, Peer, HeaderRef}; +use super::{request, OnDemand, OnDemandRequester, Peer, HeaderRef}; // useful contexts to give the service. enum Context { diff --git a/parity/light_helpers/epoch_fetch.rs b/parity/light_helpers/epoch_fetch.rs index 01e74059ea..9c7fd6a8ee 100644 --- a/parity/light_helpers/epoch_fetch.rs +++ b/parity/light_helpers/epoch_fetch.rs @@ -27,7 +27,7 @@ use futures::{future, Future}; use futures::future::Either; use light::client::fetch::ChainDataFetcher; -use light::on_demand::{request, OnDemand}; +use light::on_demand::{request, OnDemand, OnDemandRequester}; use parking_lot::RwLock; use ethereum_types::H256; diff --git a/parity/light_helpers/queue_cull.rs b/parity/light_helpers/queue_cull.rs index ec1ca612b8..693d8f93cf 100644 --- a/parity/light_helpers/queue_cull.rs +++ b/parity/light_helpers/queue_cull.rs @@ -24,7 +24,7 @@ use sync::{LightSync, LightNetworkDispatcher}; use io::{IoContext, IoHandler, TimerToken}; use light::client::LightChainClient; -use light::on_demand::{request, OnDemand}; +use light::on_demand::{request, OnDemand, OnDemandRequester}; use light::TransactionQueue; use futures::{future, Future}; diff --git a/rpc/src/v1/helpers/dispatch/light.rs b/rpc/src/v1/helpers/dispatch/light.rs index 59c3af5232..88f9fafcf1 100644 --- a/rpc/src/v1/helpers/dispatch/light.rs +++ b/rpc/src/v1/helpers/dispatch/light.rs @@ -20,7 +20,7 @@ use ethereum_types::{H256, Address, U256}; use light::TransactionQueue as LightTransactionQueue; use light::cache::Cache as LightDataCache; use light::client::LightChainClient; -use light::on_demand::{request, OnDemand}; +use light::on_demand::{request, OnDemandRequester}; use parking_lot::{Mutex, RwLock}; use stats::Corpus; use sync::{LightSyncProvider, LightNetworkDispatcher, ManageNetwork}; @@ -37,13 +37,17 @@ use v1::types::{RichRawTransaction as RpcRichRawTransaction,}; use super::{Dispatcher, Accounts, SignWith, PostSign}; /// Dispatcher for light clients -- fetches default gas price, next nonce, etc. from network. -pub struct LightDispatcher { +pub struct LightDispatcher +where + S: LightSyncProvider + LightNetworkDispatcher + ManageNetwork + 'static, + OD: OnDemandRequester + 'static +{ /// Sync service. pub sync: Arc, /// Header chain client. pub client: Arc, /// On-demand request service. - pub on_demand: Arc, + pub on_demand: Arc, /// Data cache. pub cache: Arc>, /// Transaction queue. @@ -54,9 +58,10 @@ pub struct LightDispatcher LightDispatcher +impl LightDispatcher where - S: LightSyncProvider + LightNetworkDispatcher + ManageNetwork + 'static + S: LightSyncProvider + LightNetworkDispatcher + ManageNetwork + 'static, + OD: OnDemandRequester + 'static { /// Create a new `LightDispatcher` from its requisite parts. /// @@ -64,7 +69,7 @@ where pub fn new( sync: Arc, client: Arc, - on_demand: Arc, + on_demand: Arc, cache: Arc>, transaction_queue: Arc>, nonces: Arc>, @@ -117,9 +122,10 @@ where } } -impl Clone for LightDispatcher +impl Clone for LightDispatcher where - S: LightSyncProvider + LightNetworkDispatcher + ManageNetwork + 'static + S: LightSyncProvider + LightNetworkDispatcher + ManageNetwork + 'static, + OD: OnDemandRequester + 'static { fn clone(&self) -> Self { Self { @@ -134,9 +140,10 @@ where } } -impl Dispatcher for LightDispatcher +impl Dispatcher for LightDispatcher where - S: LightSyncProvider + LightNetworkDispatcher + ManageNetwork + 'static + S: LightSyncProvider + LightNetworkDispatcher + ManageNetwork + 'static, + OD: OnDemandRequester + 'static { // Ignore the `force_nonce` flag in order to always query the network when fetching the nonce and // the account state. If the nonce is specified in the transaction use that nonce instead but do the @@ -239,12 +246,16 @@ where /// Get a recent gas price corpus. // TODO: this could be `impl Trait`. -pub fn fetch_gas_price_corpus( +pub fn fetch_gas_price_corpus( sync: Arc, client: Arc, - on_demand: Arc, + on_demand: Arc, cache: Arc>, -) -> BoxFuture> { +) -> BoxFuture> +where + S: LightSyncProvider + LightNetworkDispatcher + ManageNetwork + 'static, + OD: OnDemandRequester + 'static +{ const GAS_PRICE_SAMPLE_SIZE: usize = 100; if let Some(cached) = { cache.lock().gas_price_corpus() } { diff --git a/rpc/src/v1/helpers/light_fetch.rs b/rpc/src/v1/helpers/light_fetch.rs index 3d19e3fa86..f507964734 100644 --- a/rpc/src/v1/helpers/light_fetch.rs +++ b/rpc/src/v1/helpers/light_fetch.rs @@ -35,16 +35,15 @@ use light::cache::Cache; use light::client::LightChainClient; use light::{cht, MAX_HEADERS_PER_REQUEST}; use light::on_demand::{ - request, OnDemand, HeaderRef, Request as OnDemandRequest, + request, OnDemandRequester, HeaderRef, Request as OnDemandRequest, Response as OnDemandResponse, ExecutionResult, }; use light::on_demand::error::Error as OnDemandError; use light::request::Field; - use sync::{LightNetworkDispatcher, ManageNetwork, LightSyncProvider}; -use ethereum_types::{U256, Address}; +use ethereum_types::Address; use hash::H256; use parking_lot::Mutex; use fastmap::H256FastMap; @@ -57,9 +56,10 @@ use v1::types::{BlockNumber, CallRequest, Log, Transaction}; const NO_INVALID_BACK_REFS_PROOF: &str = "Fails only on invalid back-references; back-references here known to be valid; qed"; const WRONG_RESPONSE_AMOUNT_TYPE_PROOF: &str = "responses correspond directly with requests in amount and type; qed"; -pub fn light_all_transactions(dispatch: &Arc>) -> impl Iterator +pub fn light_all_transactions(dispatch: &Arc>) -> impl Iterator where - S: LightSyncProvider + LightNetworkDispatcher + ManageNetwork + 'static + S: LightSyncProvider + LightNetworkDispatcher + ManageNetwork + 'static, + OD: OnDemandRequester + 'static { let txq = dispatch.transaction_queue.read(); let chain_info = dispatch.client.chain_info(); @@ -71,12 +71,15 @@ where /// Helper for fetching blockchain data either from the light client or the network /// as necessary. -pub struct LightFetch +pub struct LightFetch +where + S: LightSyncProvider + LightNetworkDispatcher + ManageNetwork + 'static, + OD: OnDemandRequester + 'static { /// The light client. pub client: Arc, /// The on-demand request service. - pub on_demand: Arc, + pub on_demand: Arc, /// Handle to the network. pub sync: Arc, /// The light data cache. @@ -85,9 +88,10 @@ pub struct LightFetch Clone for LightFetch +impl Clone for LightFetch where - S: LightSyncProvider + LightNetworkDispatcher + ManageNetwork + 'static + S: LightSyncProvider + LightNetworkDispatcher + ManageNetwork + 'static, + OD: OnDemandRequester + 'static { fn clone(&self) -> Self { Self { @@ -136,9 +140,10 @@ fn extract_header(res: &[OnDemandResponse], header: HeaderRef) -> Option LightFetch +impl LightFetch where - S: LightSyncProvider + LightNetworkDispatcher + ManageNetwork + 'static + S: LightSyncProvider + LightNetworkDispatcher + ManageNetwork + 'static, + OD: OnDemandRequester + 'static { // push the necessary requests onto the request chain to get the header by the given ID. // yield a header reference which other requests can use. @@ -277,7 +282,7 @@ where action: req.to.map_or(Action::Create, Action::Call), gas: req.gas.unwrap_or_else(|| START_GAS.into()), gas_price, - value: req.value.unwrap_or_else(U256::zero), + value: req.value.unwrap_or_default(), data: req.data.unwrap_or_default(), })) ) @@ -387,7 +392,7 @@ where block_index += 1; } } - future::ok::<_,OnDemandError>(matches) + future::ok::<_, OnDemandError>(matches) }) .map_err(errors::on_demand_error) .map(|matches| matches.into_iter().map(|(_, v)| v).collect()) @@ -657,22 +662,24 @@ where } } -struct ExecuteParams +struct ExecuteParams where - S: LightSyncProvider + LightNetworkDispatcher + ManageNetwork + 'static + S: LightSyncProvider + LightNetworkDispatcher + ManageNetwork + 'static, + OD: OnDemandRequester + 'static { from: Address, tx: EthTransaction, hdr: encoded::Header, env_info: ::vm::EnvInfo, engine: Arc<::ethcore::engines::EthEngine>, - on_demand: Arc, + on_demand: Arc, sync: Arc, } -impl Clone for ExecuteParams +impl Clone for ExecuteParams where - S: LightSyncProvider + LightNetworkDispatcher + ManageNetwork + 'static + S: LightSyncProvider + LightNetworkDispatcher + ManageNetwork + 'static, + OD: OnDemandRequester + 'static { fn clone(&self) -> Self { Self { @@ -689,9 +696,10 @@ where // Has a peer execute the transaction with given params. If `gas_known` is false, this will set the `gas value` to the // `required gas value` unless it exceeds the block gas limit -fn execute_read_only_tx(gas_known: bool, params: ExecuteParams) -> impl Future + Send +fn execute_read_only_tx(gas_known: bool, params: ExecuteParams) -> impl Future + Send where - S: LightSyncProvider + LightNetworkDispatcher + ManageNetwork + 'static + S: LightSyncProvider + LightNetworkDispatcher + ManageNetwork + 'static, + OD: OnDemandRequester + 'static { if !gas_known { Box::new(future::loop_fn(params, |mut params| { diff --git a/rpc/src/v1/impls/eth_pubsub.rs b/rpc/src/v1/impls/eth_pubsub.rs index 91f32827b1..4507281578 100644 --- a/rpc/src/v1/impls/eth_pubsub.rs +++ b/rpc/src/v1/impls/eth_pubsub.rs @@ -33,7 +33,7 @@ use ethcore::client::{BlockChainClient, ChainNotify, NewBlocks, ChainRouteType, use ethereum_types::H256; use light::cache::Cache; use light::client::{LightChainClient, LightChainNotify}; -use light::on_demand::OnDemand; +use light::on_demand::OnDemandRequester; use parity_runtime::Executor; use parking_lot::{RwLock, Mutex}; @@ -89,14 +89,15 @@ impl EthPubSubClient { } } -impl EthPubSubClient> +impl EthPubSubClient> where - S: LightSyncProvider + LightNetworkDispatcher + ManageNetwork + 'static + S: LightSyncProvider + LightNetworkDispatcher + ManageNetwork + 'static, + OD: OnDemandRequester + 'static { /// Creates a new `EthPubSubClient` for `LightClient`. pub fn light( client: Arc, - on_demand: Arc, + on_demand: Arc, sync: Arc, cache: Arc>, executor: Executor, @@ -194,9 +195,10 @@ pub trait LightClient: Send + Sync { fn logs(&self, filter: EthFilter) -> BoxFuture>; } -impl LightClient for LightFetch +impl LightClient for LightFetch where - S: LightSyncProvider + LightNetworkDispatcher + ManageNetwork + 'static + S: LightSyncProvider + LightNetworkDispatcher + ManageNetwork + 'static, + OD: OnDemandRequester + 'static { fn block_header(&self, id: BlockId) -> Option { self.client.block_header(id) diff --git a/rpc/src/v1/impls/light/eth.rs b/rpc/src/v1/impls/light/eth.rs index fa972c5d60..b3e183c1c9 100644 --- a/rpc/src/v1/impls/light/eth.rs +++ b/rpc/src/v1/impls/light/eth.rs @@ -26,7 +26,7 @@ use jsonrpc_core::futures::future::Either; use light::cache::Cache as LightDataCache; use light::client::LightChainClient; use light::{cht, TransactionQueue}; -use light::on_demand::{request, OnDemand}; +use light::on_demand::{request, OnDemandRequester}; use ethereum_types::{Address, H64, H160, H256, U64, U256}; use hash::{KECCAK_NULL_RLP, KECCAK_EMPTY_LIST_RLP}; @@ -54,10 +54,10 @@ use sync::{LightSyncInfo, LightSyncProvider, LightNetworkDispatcher, ManageNetwo const NO_INVALID_BACK_REFS: &str = "Fails only on invalid back-references; back-references here known to be valid; qed"; /// Light client `ETH` (and filter) RPC. -pub struct EthClient { +pub struct EthClient { sync: Arc, client: Arc, - on_demand: Arc, + on_demand: Arc, transaction_queue: Arc>, accounts: Arc Vec
+ Send + Sync>, cache: Arc>, @@ -67,9 +67,10 @@ pub struct EthClient deprecation_notice: DeprecationNotice, } -impl Clone for EthClient +impl Clone for EthClient where - S: LightSyncProvider + LightNetworkDispatcher + 'static + S: LightSyncProvider + LightNetworkDispatcher + 'static, + OD: OnDemandRequester + 'static { fn clone(&self) -> Self { // each instance should have its own poll manager. @@ -88,17 +89,18 @@ where } } -impl EthClient +impl EthClient where C: LightChainClient + 'static, - S: LightSyncProvider + LightNetworkDispatcher + ManageNetwork + 'static + S: LightSyncProvider + LightNetworkDispatcher + ManageNetwork + 'static, + OD: OnDemandRequester + 'static { /// Create a new `EthClient` with a handle to the light sync instance, client, /// and on-demand request service, which is assumed to be attached as a handler. pub fn new( sync: Arc, client: Arc, - on_demand: Arc, + on_demand: Arc, transaction_queue: Arc>, accounts: Arc Vec
+ Send + Sync>, cache: Arc>, @@ -120,7 +122,7 @@ where } /// Create a light data fetcher instance. - fn fetcher(&self) -> LightFetch + fn fetcher(&self) -> LightFetch { LightFetch { client: self.client.clone(), @@ -218,10 +220,11 @@ where } } -impl Eth for EthClient +impl Eth for EthClient where C: LightChainClient + 'static, - S: LightSyncInfo + LightSyncProvider + LightNetworkDispatcher + ManageNetwork + 'static + S: LightSyncInfo + LightSyncProvider + LightNetworkDispatcher + ManageNetwork + 'static, + OD: OnDemandRequester + 'static { type Metadata = Metadata; @@ -533,10 +536,11 @@ where } // This trait implementation triggers a blanked impl of `EthFilter`. -impl Filterable for EthClient +impl Filterable for EthClient where C: LightChainClient + 'static, - S: LightSyncProvider + LightNetworkDispatcher + ManageNetwork + 'static + S: LightSyncProvider + LightNetworkDispatcher + ManageNetwork + 'static, + OD: OnDemandRequester + 'static { fn best_block_number(&self) -> u64 { self.client.chain_info().best_block_number } diff --git a/rpc/src/v1/impls/light/parity.rs b/rpc/src/v1/impls/light/parity.rs index b6e378f680..0486366de6 100644 --- a/rpc/src/v1/impls/light/parity.rs +++ b/rpc/src/v1/impls/light/parity.rs @@ -30,6 +30,7 @@ use ethcore_logger::RotatingLogger; use jsonrpc_core::{Result, BoxFuture}; use jsonrpc_core::futures::{future, Future}; +use light::on_demand::OnDemandRequester; use v1::helpers::{self, errors, ipfs, NetworkSettings, verify_signature}; use v1::helpers::external_signer::{SignerService, SigningQueue}; use v1::helpers::dispatch::LightDispatcher; @@ -48,8 +49,12 @@ use v1::types::{ use Host; /// Parity implementation for light client. -pub struct ParityClient { - light_dispatch: Arc>, +pub struct ParityClient +where + S: LightSyncProvider + LightNetworkDispatcher + ManageNetwork + 'static, + OD: OnDemandRequester + 'static +{ + light_dispatch: Arc>, logger: Arc, settings: Arc, signer: Option>, @@ -57,13 +62,14 @@ pub struct ParityClient ParityClient +impl ParityClient where - S: LightSyncProvider + LightNetworkDispatcher + ManageNetwork + 'static + S: LightSyncProvider + LightNetworkDispatcher + ManageNetwork + 'static, + OD: OnDemandRequester + 'static { /// Creates new `ParityClient`. pub fn new( - light_dispatch: Arc>, + light_dispatch: Arc>, logger: Arc, settings: Arc, signer: Option>, @@ -81,7 +87,7 @@ where } /// Create a light blockchain data fetcher. - fn fetcher(&self) -> LightFetch + fn fetcher(&self) -> LightFetch { LightFetch { client: self.light_dispatch.client.clone(), @@ -93,9 +99,10 @@ where } } -impl Parity for ParityClient +impl Parity for ParityClient where - S: LightSyncInfo + LightSyncProvider + LightNetworkDispatcher + ManageNetwork + 'static + S: LightSyncInfo + LightSyncProvider + LightNetworkDispatcher + ManageNetwork + 'static, + OD: OnDemandRequester + 'static { type Metadata = Metadata; From e4c2fe9e72df4323362e784b2c3d1960f2b9500e Mon Sep 17 00:00:00 2001 From: "Denis S. Soldatov aka General-Beck" Date: Wed, 27 Mar 2019 16:47:08 +0300 Subject: [PATCH 139/168] Initial support sccache for windows build (#10520) * Initial support sccache for win build * show sccache stats * cache paths for shared runners * sccache status is in the script. * removed windows test for now --- .gitlab-ci.yml | 16 +++++++++------- scripts/gitlab/build-windows.sh | 5 +++++ 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 217c49126f..33d6587942 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -33,7 +33,7 @@ variables: .docker-cache-status: &docker-cache-status variables: - CARGO_HOME: "/cargo/${CI_JOB_NAME}" + CARGO_HOME: "/ci-cache/parity-ethereum/cargo/${CI_JOB_NAME}" before_script: - SCCACHE_ERROR_LOG=/builds/parity/parity-ethereum/sccache_error.log RUST_LOG=sccache::server=debug sccache --start-server - sccache -s @@ -102,18 +102,18 @@ build-android: CARGO_TARGET: armv7-linux-androideabi script: - scripts/gitlab/build-linux.sh + <<: *collect_artifacts tags: - linux-docker - <<: *collect_artifacts build-linux: &build-linux stage: build only: *releaseable_branches <<: *docker-cache-status + <<: *collect_artifacts script: - scripts/gitlab/build-linux.sh - sccache -s - <<: *collect_artifacts build-linux-i386: <<: *build-linux @@ -136,6 +136,7 @@ build-linux-armhf: build-darwin: stage: build only: *releaseable_branches + <<: *collect_artifacts variables: CARGO_TARGET: x86_64-apple-darwin CARGO_HOME: "${CI_PROJECT_DIR}/.cargo" @@ -145,19 +146,20 @@ build-darwin: - scripts/gitlab/build-linux.sh tags: - rust-osx - <<: *collect_artifacts build-windows: stage: build + <<: *collect_artifacts only: *releaseable_branches variables: CARGO_TARGET: x86_64-pc-windows-msvc - CARGO_HOME: "${CI_PROJECT_DIR}/.cargo" + CARGO_HOME: "C:/ci-cache/parity-ethereum/cargo/%CI_JOB_NAME%" + RUSTC_WRAPPER: sccache + SCCACHE_DIR: "C:/ci-cache/parity-ethereum/sccache" script: - sh scripts/gitlab/build-windows.sh tags: - rust-windows - <<: *collect_artifacts publish-docker: stage: publish @@ -173,6 +175,7 @@ publish-docker: publish-snap: &publish-snap stage: publish only: *releaseable_branches + <<: *collect_artifacts image: snapcore/snapcraft variables: BUILD_ARCH: amd64 @@ -183,7 +186,6 @@ publish-snap: &publish-snap - linux-docker script: - scripts/gitlab/publish-snap.sh - <<: *collect_artifacts publish-snap-i386: <<: *publish-snap diff --git a/scripts/gitlab/build-windows.sh b/scripts/gitlab/build-windows.sh index d4176c7580..7ddf4453e5 100755 --- a/scripts/gitlab/build-windows.sh +++ b/scripts/gitlab/build-windows.sh @@ -4,11 +4,14 @@ set -u # treat unset variables as error set INCLUDE="C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Include;C:\vs2015\VC\include;C:\Program Files (x86)\Windows Kits\10\Include\10.0.10240.0\ucrt" set LIB="C:\vs2015\VC\lib;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\ucrt\x64" +sccache -s echo "__________Show ENVIROMENT__________" echo "CI_SERVER_NAME: " $CI_SERVER_NAME echo "CARGO_HOME: " $CARGO_HOME echo "CARGO_TARGET: " $CARGO_TARGET +echo "RUSTC_WRAPPER: " $RUSTC_WRAPPER +echo "SCCACHE_DIR: " $SCCACHE_DIR echo "_____ Building target: "$CARGO_TARGET" _____" time cargo build --target $CARGO_TARGET --release --features final @@ -44,3 +47,5 @@ do done cp parity.exe.sha256 parity.sha256 cp parity.exe.sha3 parity.sha3 + +sccache -s From 0199acbece836c49e07410796c40c185e9051451 Mon Sep 17 00:00:00 2001 From: soc1c <47772477+soc1c@users.noreply.github.com> Date: Wed, 27 Mar 2019 15:07:38 +0100 Subject: [PATCH 140/168] ethcore: remove eth social and easthub chain configs (#10531) --- ethcore/res/ethereum/easthub.json | 87 - ethcore/res/ethereum/social.json | 8854 ----------------------------- ethcore/src/ethereum/mod.rs | 10 - parity/cli/mod.rs | 2 +- parity/params.rs | 12 - 5 files changed, 1 insertion(+), 8964 deletions(-) delete mode 100644 ethcore/res/ethereum/easthub.json delete mode 100644 ethcore/res/ethereum/social.json diff --git a/ethcore/res/ethereum/easthub.json b/ethcore/res/ethereum/easthub.json deleted file mode 100644 index 51de695cd1..0000000000 --- a/ethcore/res/ethereum/easthub.json +++ /dev/null @@ -1,87 +0,0 @@ -{ - "name": "Easthub", - "dataDir": "easthub", - "engine": { - "Ethash": { - "params": { - "minimumDifficulty": "0x020000", - "difficultyBoundDivisor": "0x0800", - "durationLimit": "0x0d", - "blockReward": "0x2B5E3AF16B1880000", - "homesteadTransition": "0x0", - "bombDefuseTransition": "0x0", - "ecip1017EraRounds": 5000000 - } - } - }, - "params": { - "gasLimitBoundDivisor": "0x0400", - "registrar": "0x0000000000000000000000000000000000000000", - "accountStartNonce": "0x00", - "maximumExtraDataSize": "0x20", - "minGasLimit": "0x1388", - "networkID": "0x7", - "chainID": "0x7", - "eip150Transition": "0x0", - "eip160Transition": "0x0", - "eip155Transition": "0x0", - "eip161abcTransition": "0x7fffffffffffffff", - "eip161dTransition": "0x7fffffffffffffff" - }, - "genesis": { - "seal": { - "ethereum": { - "nonce": "0x0000000000000042", - "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - }, - "difficulty": "0x0400000000", - "author": "0x0000000000000000000000000000000000000000", - "timestamp": "0x00", - "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "extraData": "0x323031382045617374636f696e2050726f6a656374", - "gasLimit": "0x1388" - }, - "nodes": [ - "enode://ca57e40edb95a08a81b85a91e91099a0aaab777ad329ea7f3f772bc0fd511a276a5d84944725d181ff80f8c7dc1034814bff25b9723b03363d48617fed4b15f0@13.125.109.174:30303", - "enode://57254e23a7e5fe1e081ee5d1b236e37735a120660daeb4bf1fec6943a82c915c5b6fad23eeb1a43a27c23f236e084e8051aaa28f7d4139149f844747facb62bb@18.217.39.51:30303", - "enode://ef248f327c73c0318f4d51a62270b0612f3c4a4fd04b77d04854dc355980e137708d1e48811bc91387b0d7eb85cf447d8bbc095404f39bb7064e76751bda9cd4@52.221.160.236:30303", - "enode://bf6f0e37dd733cf04f2b079c753d2dea7cc7c59d8637eff9a8e63e17d08e2bfc91229fbb2dff08fe6ee12e51c1b6f8ed969d7042b89d77029e7ea02b05e17be3@18.197.47.177:30303" - ], - "accounts": { - "0000000000000000000000000000000000000001": { "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } }, - "0000000000000000000000000000000000000002": { "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } }, - "0000000000000000000000000000000000000003": { "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } }, - "0000000000000000000000000000000000000004": { "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } }, - "20c1252a8cb33a7a9a257b2a4cfeed8daf87c847": { - "balance": "100000000000000000000000000" - }, - "9dcd37c8e5aea3a0d37c5d0a2db683362d81febd": { - "balance": "100000000000000000000000000" - }, - "9eff080302333f44a60bfd8c33bd63015c6d921b": { - "balance": "100000000000000000000000000" - }, - "c1df2e5de98d5c41fec0642dc302971f5d3500bd": { - "balance": "100000000000000000000000000" - }, - "2e0fb67cd1d029cbaea4b74c361efcc06b3105fd": { - "balance": "100000000000000000000000000" - }, - "2b6425cc3cd90654f077889ef7262ac2f5846460": { - "balance": "100000000000000000000000000" - }, - "28562041230c6d575e233e4ed1b35c514884d964": { - "balance": "100000000000000000000000000" - }, - "16eb6896a5a83d39ac762d79d21f825f5f980d12": { - "balance": "100000000000000000000000000" - }, - "f09e3f1de27dd03a1ac0a021b2d9e45bde1b360c": { - "balance": "100000000000000000000000000" - }, - "2d87547819c6433f208ee3096161cdb2835a2333": { - "balance": "100000000000000000000000000" - } - } -} diff --git a/ethcore/res/ethereum/social.json b/ethcore/res/ethereum/social.json deleted file mode 100644 index 0768c239f7..0000000000 --- a/ethcore/res/ethereum/social.json +++ /dev/null @@ -1,8854 +0,0 @@ -{ - "name": "Ethereum Social", - "dataDir": "social", - "engine": { - "Ethash": { - "params": { - "minimumDifficulty": "0x020000", - "difficultyBoundDivisor": "0x0800", - "durationLimit": "0x0d", - "blockReward": "0x2B5E3AF16B1880000", - "homesteadTransition": "0x0", - "bombDefuseTransition": "0x0", - "ecip1017EraRounds": 5000000 - } - } - }, - "params": { - "gasLimitBoundDivisor": "0x0400", - "registrar": "0x0000000000000000000000000000000000000000", - "accountStartNonce": "0x00", - "maximumExtraDataSize": "0x20", - "minGasLimit": "0x1388", - "networkID": "0x1C", - "chainID": "0x1C", - "eip150Transition": "0x0", - "eip160Transition": "0x0", - "eip161abcTransition": "0x7fffffffffffffff", - "eip161dTransition": "0x7fffffffffffffff", - "eip155Transition": "0x0" - }, - "genesis": { - "seal": { - "ethereum": { - "nonce": "0x0000000000000042", - "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - }, - "difficulty": "0x0400000000", - "author": "0x0000000000000000000000000000000000000000", - "timestamp": "0x00", - "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "extraData": "0x3230313820457468657265756d20536f6369616c2050726f6a656374", - "gasLimit": "0x1388" - }, - "nodes": [ - "enode://38a3bdd683008f2b404fbd8e59a4ae7377fb1b796be8aca02861a6864304df7f443ae9669d0072d567eb30ab2183556a3cd832b8f2c99246e9a3d9f64ecdc1af@52.78.243.91:30303", - "enode://ee31120190438ca3842afccca9d732d8bfca4bbf9b846fd2bb11178194aa49a74d77ff4801d50a7bd9eb3629f8903661d0fb973e7f43b395263530b390002033@13.209.99.197:30303", - "enode://d538165bf6026602ba9ac296b2b56994e03bb917c73b79cbb11df75a45576fa74df494097bdbcda9bf2c0954a47a65b65674780fa1fbde5bcc89a34870d44983@13.125.206.82:30303", - "enode://67b5de9a4562ba0a01877e3876249c8e551844424773bdbf9713d126b3f144ac7a49d8eb06fc9830871f03b50a7d9b5d98d9d1be5544aef8afcaa10eea2fb9eb@13.125.68.29:30303", - "enode://2d31dd1f8acd956cf36a1c3f27e374f5b94c55df4206749b03a6d0a50366c8090280c91f71aad00886cbde6ebbfcabeaaa91bd910b16e4fb398b337e9ecfdbd9@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 d37ca9b4f7..d85fbf9b7b 100644 --- a/ethcore/src/ethereum/mod.rs +++ b/ethcore/src/ethereum/mod.rs @@ -79,16 +79,6 @@ pub fn new_ellaism<'a, T: Into>>(params: T) -> Spec { load(params.into(), include_bytes!("../../res/ethereum/ellaism.json")) } -/// Create a new Easthub mainnet chain spec. -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 MIX mainnet chain spec. pub fn new_mix<'a, T: Into>>(params: T) -> Spec { load(params.into(), include_bytes!("../../res/ethereum/mix.json")) diff --git a/parity/cli/mod.rs b/parity/cli/mod.rs index 01f4469bb5..561f547712 100644 --- a/parity/cli/mod.rs +++ b/parity/cli/mod.rs @@ -300,7 +300,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 ethereum, classic, poacore, tobalaba, expanse, musicoin, ellaism, easthub, social, mix, callisto, morden, ropsten, kovan, rinkeby, goerli, kotti, poasokol, testnet, or dev.", + "Specify the blockchain type. CHAIN may be either a JSON chain specification file or ethereum, classic, poacore, tobalaba, expanse, musicoin, ellaism, mix, callisto, morden, ropsten, kovan, rinkeby, goerli, kotti, poasokol, testnet, 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 389b708ce6..d01f784616 100644 --- a/parity/params.rs +++ b/parity/params.rs @@ -40,8 +40,6 @@ pub enum SpecType { Expanse, Musicoin, Ellaism, - Easthub, - Social, Mix, Callisto, Morden, @@ -73,8 +71,6 @@ impl str::FromStr for SpecType { "expanse" => SpecType::Expanse, "musicoin" => SpecType::Musicoin, "ellaism" => SpecType::Ellaism, - "easthub" => SpecType::Easthub, - "social" => SpecType::Social, "mix" => SpecType::Mix, "callisto" => SpecType::Callisto, "morden" | "classic-testnet" => SpecType::Morden, @@ -101,8 +97,6 @@ impl fmt::Display for SpecType { SpecType::Expanse => "expanse", SpecType::Musicoin => "musicoin", SpecType::Ellaism => "ellaism", - SpecType::Easthub => "easthub", - SpecType::Social => "social", SpecType::Mix => "mix", SpecType::Callisto => "callisto", SpecType::Morden => "morden", @@ -129,8 +123,6 @@ impl SpecType { SpecType::Expanse => Ok(ethereum::new_expanse(params)), 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::Mix => Ok(ethereum::new_mix(params)), SpecType::Callisto => Ok(ethereum::new_callisto(params)), SpecType::Morden => Ok(ethereum::new_morden(params)), @@ -388,8 +380,6 @@ mod tests { assert_eq!(SpecType::Expanse, "expanse".parse().unwrap()); assert_eq!(SpecType::Musicoin, "musicoin".parse().unwrap()); assert_eq!(SpecType::Ellaism, "ellaism".parse().unwrap()); - assert_eq!(SpecType::Easthub, "easthub".parse().unwrap()); - assert_eq!(SpecType::Social, "social".parse().unwrap()); assert_eq!(SpecType::Mix, "mix".parse().unwrap()); assert_eq!(SpecType::Callisto, "callisto".parse().unwrap()); assert_eq!(SpecType::Morden, "morden".parse().unwrap()); @@ -419,8 +409,6 @@ mod tests { assert_eq!(format!("{}", SpecType::Expanse), "expanse"); assert_eq!(format!("{}", SpecType::Musicoin), "musicoin"); assert_eq!(format!("{}", SpecType::Ellaism), "ellaism"); - assert_eq!(format!("{}", SpecType::Easthub), "easthub"); - assert_eq!(format!("{}", SpecType::Social), "social"); assert_eq!(format!("{}", SpecType::Mix), "mix"); assert_eq!(format!("{}", SpecType::Callisto), "callisto"); assert_eq!(format!("{}", SpecType::Morden), "morden"); From 04c686766060d1954ba1069d7634e7458053ec43 Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Wed, 27 Mar 2019 20:53:06 +0100 Subject: [PATCH 141/168] Fix max_gas (#10537) Fix max_gas --- rpc/src/v1/helpers/fake_sign.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/rpc/src/v1/helpers/fake_sign.rs b/rpc/src/v1/helpers/fake_sign.rs index 9f9b7c8ed6..d93408b89a 100644 --- a/rpc/src/v1/helpers/fake_sign.rs +++ b/rpc/src/v1/helpers/fake_sign.rs @@ -15,17 +15,15 @@ // along with Parity Ethereum. If not, see . use types::transaction::{Transaction, SignedTransaction, Action}; +use std::cmp::min; use ethereum_types::U256; use jsonrpc_core::Error; use v1::helpers::CallRequest; pub fn sign_call(request: CallRequest) -> Result { - let max_gas = U256::from(50_000_000); - let gas = match request.gas { - Some(gas) => gas, - None => max_gas * 10_u32, - }; + let max_gas = U256::from(500_000_000); + let gas = min(request.gas.unwrap_or(max_gas), max_gas); let from = request.from.unwrap_or_default(); Ok(Transaction { From ebf51c0be0f1850407eced8077a4a999ac1a9829 Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Thu, 28 Mar 2019 16:31:06 +0100 Subject: [PATCH 142/168] fix(bump dependencies) (#10540) * cargo update -p log:0.4.5 * cargo update -p regex:1.0.5 * cargo update -p parking_lot * cargo update -p serde_derive * cargo update -p serde_json * cargo update -p serde * cargo update -p lazy_static * cargo update -p num_cpus * cargo update -p toml --- Cargo.lock | 504 ++++++++++++++++++++++++++--------------------------- 1 file changed, 252 insertions(+), 252 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fd1b238d97..6bb4e41793 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -115,7 +115,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -161,7 +161,7 @@ version = "0.1.0" dependencies = [ "byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "ethbloom 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -220,7 +220,7 @@ name = "chainspec" version = "0.1.0" dependencies = [ "ethjson 0.1.0", - "serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -327,10 +327,10 @@ dependencies = [ "handlebars 0.32.4 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)", "itertools-num 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", "simplelog 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "walkdir 2.2.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -352,7 +352,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cast 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "thread-scoped 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -415,7 +415,7 @@ dependencies = [ "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -429,7 +429,7 @@ dependencies = [ "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -442,7 +442,7 @@ dependencies = [ "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-utils 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -484,7 +484,7 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "csv-core 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -552,10 +552,10 @@ name = "docopt" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", "strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -574,13 +574,13 @@ dependencies = [ "indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "lunarity-lexer 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", "toolshed 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "validator 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "validator_derive 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -614,8 +614,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "humantime 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -646,9 +646,9 @@ dependencies = [ "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethereum-types 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", "tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -678,12 +678,12 @@ dependencies = [ "either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethereum-types 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "primal 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -695,7 +695,7 @@ dependencies = [ "crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "ethereum-types-serialize 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "fixed-hash 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", "tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -738,20 +738,20 @@ dependencies = [ "kvdb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb-memorydb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb-rocksdb 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "len-caching-lock 0.1.1", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "lru-cache 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "macros 0.1.0", "memory-cache 0.1.0", "memory-db 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "num 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-crypto 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-runtime 0.1.0", "parity-snappy 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "patricia-trie-ethereum 0.1.0", "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "rayon 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -759,8 +759,8 @@ dependencies = [ "rlp_compress 0.1.0", "rlp_derive 0.1.0", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", "stats 0.1.0", "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "time-utils 0.1.0", @@ -784,11 +784,11 @@ dependencies = [ "ethstore 0.2.1", "fake-hardware-wallet 0.0.1", "hardware-wallet 1.12.0", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -808,9 +808,9 @@ dependencies = [ "keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb-memorydb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "rayon 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "rlp 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "rlp_compress 0.1.0", @@ -843,7 +843,7 @@ dependencies = [ "ethereum-types 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.4.2 (git+https://github.com/cheme/heapsize.git?branch=ec-macfix)", "kvdb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "rlp 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "rlp_derive 0.1.0", ] @@ -855,10 +855,10 @@ dependencies = [ "crossbeam-deque 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", "timer 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -889,17 +889,17 @@ dependencies = [ "keccak-hasher 0.1.1", "kvdb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb-memorydb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "memory-cache 0.1.0", "memory-db 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "patricia-trie-ethereum 0.1.0", "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "rlp 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "rlp_derive 0.1.0", - "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "stats 0.1.0", "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", @@ -916,10 +916,10 @@ dependencies = [ "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -944,9 +944,9 @@ dependencies = [ "hyper 0.12.19 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "linked-hash-map 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "parity-runtime 0.1.0", - "parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "price-info 1.12.0", "rlp 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -965,14 +965,14 @@ dependencies = [ "ethereum-types 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "ethkey 0.3.0", "ipnetwork 0.12.8 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", "parity-crypto 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-snappy 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "rlp 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -992,21 +992,21 @@ dependencies = [ "ipnetwork 0.12.8 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "lru-cache 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-crypto 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-path 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "parity-snappy 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "rlp 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1033,18 +1033,18 @@ dependencies = [ "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.4.2 (git+https://github.com/cheme/heapsize.git?branch=ec-macfix)", "keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-crypto 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "patricia-trie-ethereum 0.1.0", "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", "rlp 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "rlp_derive 0.1.0", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", "tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "transaction-pool 1.13.3 (registry+https://github.com/rust-lang/crates.io-index)", "trie-db 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1072,16 +1072,16 @@ dependencies = [ "keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb-rocksdb 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-crypto 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-runtime 0.1.0", - "parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.7.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.80 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1105,7 +1105,7 @@ dependencies = [ "ethereum-types 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb-rocksdb 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "trace-time 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1119,8 +1119,8 @@ dependencies = [ "jsonrpc-core 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-tcp-server 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1148,10 +1148,10 @@ dependencies = [ "keccak-hasher 0.1.1", "kvdb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb-memorydb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "macros 0.1.0", "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "rlp 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1168,7 +1168,7 @@ dependencies = [ "ethbloom 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethereum-types-serialize 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "fixed-hash 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", "uint 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1177,7 +1177,7 @@ name = "ethereum-types-serialize" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1186,9 +1186,9 @@ version = "0.1.0" dependencies = [ "ethereum-types 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1199,16 +1199,16 @@ dependencies = [ "edit-distance 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "eth-secp256k1 0.5.7 (git+https://github.com/paritytech/rust-secp256k1)", "ethereum-types 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "memzero 0.1.0", "parity-crypto 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-wordlist 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.3 (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.80 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", "tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1222,8 +1222,8 @@ dependencies = [ "panic_hook 0.1.0", "parity-wordlist 1.2.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.80 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", "threadpool 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1235,18 +1235,18 @@ dependencies = [ "ethereum-types 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "ethkey 0.3.0", "itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-crypto 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-wordlist 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.3 (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.80 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1261,12 +1261,12 @@ dependencies = [ "docopt 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)", "ethstore 0.2.1", - "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "panic_hook 0.1.0", - "parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.7.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.80 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1279,11 +1279,11 @@ dependencies = [ "ethereum-types 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.4.2 (git+https://github.com/cheme/heapsize.git?branch=ec-macfix)", "keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "memory-cache 0.1.0", "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "vm 0.1.0", ] @@ -1303,9 +1303,9 @@ dependencies = [ "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "vm 0.1.0", ] @@ -1387,7 +1387,7 @@ dependencies = [ "http 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.12.19 (registry+https://github.com/rust-lang/crates.io-index)", "hyper-rustls 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1418,7 +1418,7 @@ name = "fs-swap" version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", "libloading 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1454,7 +1454,7 @@ version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1493,9 +1493,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "aho-corasick 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1509,7 +1509,7 @@ dependencies = [ "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", "http 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", "indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "string 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1525,14 +1525,14 @@ name = "handlebars" version = "0.32.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "pest 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "pest_derive 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1543,8 +1543,8 @@ dependencies = [ "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)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "protobuf 1.7.4 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1631,7 +1631,7 @@ dependencies = [ "httparse 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.2 (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.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "mime 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1657,7 +1657,7 @@ dependencies = [ "httparse 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1805,7 +1805,7 @@ dependencies = [ "combine 3.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "jni-sys 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "walkdir 2.2.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1827,10 +1827,10 @@ dependencies = [ "keccak-hasher 0.1.1", "kvdb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb-memorydb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "memory-db 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "rlp 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1840,10 +1840,10 @@ version = "10.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1864,7 +1864,7 @@ dependencies = [ "hyper 0.12.19 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-server-utils 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "unicase 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1876,9 +1876,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "jsonrpc-core 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-server-utils 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "parity-tokio-ipc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1888,9 +1888,9 @@ version = "10.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "jsonrpc-core 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1901,9 +1901,9 @@ dependencies = [ "bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "globset 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "unicase 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1916,8 +1916,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "jsonrpc-core 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-server-utils 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1929,9 +1929,9 @@ dependencies = [ "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-server-utils 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "parity-ws 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1991,7 +1991,7 @@ dependencies = [ "interleaved-ordered 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-rocksdb 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", "regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2004,7 +2004,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "lazy_static" -version = "1.2.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -2016,7 +2016,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "len-caching-lock" version = "0.1.1" dependencies = [ - "parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2086,12 +2086,12 @@ name = "log" version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "log" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2178,7 +2178,7 @@ version = "0.1.0" dependencies = [ "kvdb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb-rocksdb 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "macros 0.1.0", "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2213,7 +2213,7 @@ dependencies = [ "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazycell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2226,7 +2226,7 @@ version = "2.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "lazycell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2236,7 +2236,7 @@ name = "mio-named-pipes" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", "miow 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2318,9 +2318,9 @@ dependencies = [ "ethcore-network-devp2p 1.12.0", "ethereum-types 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb-memorydb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "lru-cache 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2383,7 +2383,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "num_cpus" -version = "1.8.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2476,7 +2476,7 @@ dependencies = [ "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2519,11 +2519,11 @@ dependencies = [ "keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb-rocksdb 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "migration-rocksdb 0.1.0", "node-filter 1.12.0", - "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "number_prefix 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "panic_hook 0.1.0", "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2537,22 +2537,22 @@ dependencies = [ "parity-updater 1.12.0", "parity-version 2.5.0", "parity-whisper 0.1.0", - "parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "registrar 0.0.1", "rlp 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "rpassword 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "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.8 (registry+https://github.com/rust-lang/crates.io-index)", + "toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2568,12 +2568,12 @@ dependencies = [ "fetch 0.1.0", "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "mime 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)", "mime_guess 2.0.0-alpha.6 (registry+https://github.com/rust-lang/crates.io-index)", "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-runtime 0.1.0", - "parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "registrar 0.0.1", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2603,11 +2603,11 @@ dependencies = [ "ethkey 0.3.0", "kvdb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb-memorydb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "rlp 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2670,7 +2670,7 @@ dependencies = [ "jsonrpc-pubsub 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-ws-server 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "macros 0.1.0", "multihash 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "order-stat 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2679,15 +2679,15 @@ dependencies = [ "parity-runtime 0.1.0", "parity-updater 1.12.0", "parity-version 2.5.0", - "parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "rlp 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", "stats 0.1.0", "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2706,12 +2706,12 @@ dependencies = [ "jsonrpc-core 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-ws-server 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-rpc 1.12.0", - "parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2748,7 +2748,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "mio-named-pipes 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "miow 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2770,14 +2770,14 @@ dependencies = [ "ethcore-sync 1.12.0", "ethereum-types 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-hash-fetch 1.12.0", "parity-path 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "parity-version 2.5.0", - "parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "target_info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2792,7 +2792,7 @@ dependencies = [ "rlp 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "target_info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "toml 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "vergen 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2817,16 +2817,16 @@ dependencies = [ "jsonrpc-core 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-derive 10.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-pubsub 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "memzero 0.1.0", "ordered-float 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "parity-crypto 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "rlp 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "time-utils 0.1.0", @@ -2839,7 +2839,7 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2851,7 +2851,7 @@ dependencies = [ "byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "httparse 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", "mio-extras 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2871,7 +2871,7 @@ dependencies = [ [[package]] name = "parking_lot" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "lock_api 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3008,10 +3008,10 @@ dependencies = [ "fake-fetch 0.0.1", "fetch 0.1.0", "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "parity-runtime 0.1.0", - "parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3086,9 +3086,9 @@ dependencies = [ "ethereum-types 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "ethjson 0.1.0", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", "vm 0.1.0", "wasm 0.1.0", ] @@ -3099,7 +3099,7 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "parity-wasm 0.31.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3242,9 +3242,9 @@ version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3274,7 +3274,7 @@ dependencies = [ [[package]] name = "regex" -version = "1.0.5" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "aho-corasick 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3333,7 +3333,7 @@ version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", "untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3364,7 +3364,7 @@ name = "rlp_compress" version = "0.1.0" dependencies = [ "elastic-array 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "rlp 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3440,7 +3440,7 @@ version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "ring 0.14.3 (registry+https://github.com/rust-lang/crates.io-index)", "sct 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3490,7 +3490,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3500,12 +3500,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde" -version = "1.0.80" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde_derive" -version = "1.0.80" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3515,12 +3515,12 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.32" +version = "1.0.39" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "ryu 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3559,7 +3559,7 @@ version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "term 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3625,7 +3625,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "stats" version = "0.1.0" dependencies = [ - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3764,7 +3764,7 @@ name = "thread_local" version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3772,7 +3772,7 @@ name = "threadpool" version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3844,7 +3844,7 @@ dependencies = [ "bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", "scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3888,7 +3888,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3910,10 +3910,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-executor 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3971,8 +3971,8 @@ dependencies = [ "crossbeam-deque 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-executor 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -4004,7 +4004,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4020,7 +4020,7 @@ dependencies = [ "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", "mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4029,10 +4029,10 @@ dependencies = [ [[package]] name = "toml" -version = "0.4.8" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4048,7 +4048,7 @@ name = "trace-time" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4057,7 +4057,7 @@ version = "1.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "trace-time 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -4082,7 +4082,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "elastic-array 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "hash-db 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -4237,11 +4237,11 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -4251,10 +4251,10 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "if_chain 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)", "validator 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -4286,7 +4286,7 @@ dependencies = [ "ethereum-types 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "ethjson 0.1.0", "keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "patricia-trie-ethereum 0.1.0", "rlp 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4314,7 +4314,7 @@ version = "0.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "try-lock 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -4324,7 +4324,7 @@ version = "0.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -4336,7 +4336,7 @@ dependencies = [ "env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)", "ethereum-types 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "parity-wasm 0.31.3 (registry+https://github.com/rust-lang/crates.io-index)", "pwasm-utils 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "vm 0.1.0", @@ -4384,12 +4384,12 @@ dependencies = [ "jsonrpc-core 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-http-server 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-pubsub 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "panic_hook 0.1.0", "parity-whisper 0.1.0", "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4605,7 +4605,7 @@ dependencies = [ "checksum kvdb-memorydb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "45bcdf5eb083602cff61a6f8438dce2a7900d714e893fc48781c39fb119d37aa" "checksum kvdb-rocksdb 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "06cf755dc587839ba34d3cbe3f12b6ad55850fbcdfe67336157a021a1a5c43ae" "checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" -"checksum lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a374c89b9db55895453a74c1e38861d9deec0b01b405a82516e9d5de4820dea1" +"checksum lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc5729f27f159ddd61f4df6228e827e86643d4d3e7c32183cb30a1c08f604a14" "checksum lazycell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ddba4c30a78328befecec92fc94970e53b3ae385827d28620f0f5bb2493081e0" "checksum libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)" = "e962c7641008ac010fa60a7dfdc1712449f29c44ef2d4702394aea943ee75047" "checksum libloading 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9c3ad660d7cb8c5822cd83d10897b0f1f1526792737a179e73896152f85b88c2" @@ -4616,7 +4616,7 @@ dependencies = [ "checksum local-encoding 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e1ceb20f39ff7ae42f3ff9795f3986b1daad821caaa1e1732a0944103a5a1a66" "checksum lock_api 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "775751a3e69bde4df9b38dd00a1b5d6ac13791e4223d4a0506577f0dd27cfb7a" "checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" -"checksum log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fcce5fa49cc693c312001daf1d13411c4a5283796bac1084299ea3e567113f" +"checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6" "checksum lru-cache 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4d06ff7ff06f729ce5f4e227876cb88d10bc59cd4ae1e09fbb2bde15c850dc21" "checksum lunarity-lexer 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8a1670671f305792567116d4660e6e5bd785d6fa973e817c3445c0a7a54cecb6" "checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" @@ -4644,7 +4644,7 @@ dependencies = [ "checksum num-iter 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "af3fdbbc3291a5464dc57b03860ec37ca6bf915ed6ee385e7c6c052c422b2124" "checksum num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31" "checksum num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1" -"checksum num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c51a3322e4bca9d212ad9a158a02abc6934d005490c054a2778df73a70aa0a30" +"checksum num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1a23f0ed30a54abaa0c7e83b1d2d87ada7c3c23078d1d87815af3e3b6385fbba" "checksum number_prefix 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "dbf9993e59c894e3c08aa1c2712914e9e6bf1fcbfc6bef283e2183df345a4fee" "checksum ole32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5d2c49021782e5233cd243168edfa8037574afed4eba4bbaf538b3d8d1789d8c" "checksum order-stat 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "efa535d5117d3661134dbf1719b6f0ffe06f2375843b13935db186cd094105eb" @@ -4664,7 +4664,7 @@ dependencies = [ "checksum parity-wordlist 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf13102febd98f4ad416a526b42deb82daf482626ba6ab10d0ebf8f45327514c" "checksum parity-ws 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2fec5048fba72a2e01baeb0d08089db79aead4b57e2443df172fb1840075a233" "checksum parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f0802bff09003b291ba756dc7e79313e51cc31667e94afbe847def490424cde5" -"checksum parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9723236a9525c757d9725b993511e3fc941e33f27751942232f0058298297edf" +"checksum parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ab41b4aed082705d1056416ae4468b6ea99d52599ecf3169b00088d43113e337" "checksum parking_lot_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad7f7e6ebdc79edff6fdcb87a55b620174f7a989e3eb31b65231f4af57f00b8c" "checksum parking_lot_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94c8c7923936b28d546dfd14d4472eaf34c99b14e1c973a32b3e6d4eb04298c9" "checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" @@ -4705,7 +4705,7 @@ dependencies = [ "checksum redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "c214e91d3ecf43e9a4e41e578973adeb14b474f2bee858742d127af75a0112b1" "checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" "checksum regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9329abc99e39129fcceabd24cf5d85b4671ef7c29c50e972bc5afe32438ec384" -"checksum regex 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "2069749032ea3ec200ca51e4a31df41759190a88edca0d2d86ee8bedf7073341" +"checksum regex 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "53ee8cfdddb2e0291adfb9f13d31d3bbe0a03c9a402c01b1e24188d86c35b24f" "checksum regex-syntax 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7d707a4fa2637f2dca2ef9fd02225ec7661fe01a53623c1e6515b6916511f7a7" "checksum regex-syntax 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "747ba3b235651f6e2f67dfa8bcdcd073ddb7c243cb21c442fc12395dfcac212d" "checksum relay 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1576e382688d7e9deecea24417e350d3062d97e32e45d70b1cde65994ff1489a" @@ -4730,9 +4730,9 @@ dependencies = [ "checksum sct 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2f5adf8fbd58e1b1b52699dc8bed2630faecb6d8c7bee77d009d6bbe4af569b9" "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" -"checksum serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)" = "15c141fc7027dd265a47c090bf864cf62b42c4d228bbcf4e51a0c9e2b0d3f7ef" -"checksum serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)" = "225de307c6302bec3898c51ca302fc94a7a1697ef0845fcee6448f33c032249c" -"checksum serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)" = "43344e7ce05d0d8280c5940cabb4964bea626aa58b1ec0e8c73fa2a8512a38ce" +"checksum serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)" = "92514fb95f900c9b5126e32d020f5c6d40564c27a5ea6d1d7d9f157a96623560" +"checksum serde_derive 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)" = "bb6eabf4b5914e88e24eea240bb7c9f9a2cbc1bbbe8d961d381975ec3c6b806c" +"checksum serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)" = "5a23aa71d4a4d43fdbfaac00eff68ba8a06a51759a89ac3304323e800c4dd40d" "checksum sha1 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "171698ce4ec7cbb93babeb3190021b4d72e96ccb98e33d277ae4ea959d6f2d9e" "checksum sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" "checksum sha2 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9eb6be24e4c23a84d7184280d2722f7f2731fcdd4a9d886efbfe4413e4847ea0" @@ -4786,7 +4786,7 @@ dependencies = [ "checksum tokio-timer 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "3a52f00c97fedb6d535d27f65cccb7181c8dd4c6edc3eda9ea93f6d45d05168e" "checksum tokio-udp 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "da941144b816d0dcda4db3a1ba87596e4df5e860a72b70783fe435891f80601c" "checksum tokio-uds 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "22e3aa6d1fcc19e635418dc0a30ab5bd65d347973d6f43f1a37bf8d9d1335fc9" -"checksum toml 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "4a2ecc31b0351ea18b3fe11274b8db6e4d82bce861bbb22e6dbed40417902c65" +"checksum toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "758664fc71a3a69038656bee8b6be6477d2a6c315a6b81f7081f591bffa4111f" "checksum toolshed 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "450441e131c7663af72e63a33c02a6a1fbaaa8601dc652ed6757813bb55aeec7" "checksum trace-time 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe82f2f0bf1991e163e757baf044282823155dd326e70f44ce2186c3c320cc9" "checksum transaction-pool 1.13.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e5866e5126b14358f1d7af4bf51a0be677a363799b90e655edcec8254edef1d2" From 4e2e88a620e0b9d995ff1cc8c47ea56b85cfa18c Mon Sep 17 00:00:00 2001 From: TriplEight Date: Thu, 28 Mar 2019 17:19:00 +0100 Subject: [PATCH 143/168] separate docker image to build docs (#10543) --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 33d6587942..775d1ecee1 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -249,6 +249,7 @@ publish-awss3-release: publish-docs: stage: publish + image: parity/rust-parity-ethereum-docs:xenial only: - tags except: @@ -258,4 +259,3 @@ publish-docs: - scripts/gitlab/publish-docs.sh tags: - linux-docker - From 89d627769ead4b05948ec680290bd415b2606e58 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Fri, 29 Mar 2019 13:25:15 +0100 Subject: [PATCH 144/168] updated lru-cache to 0.1.2 (#10542) --- Cargo.lock | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6bb4e41793..1d43c68c53 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -741,7 +741,7 @@ dependencies = [ "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "len-caching-lock 0.1.1", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "lru-cache 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "lru-cache 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "macros 0.1.0", "memory-cache 0.1.0", "memory-db 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -993,7 +993,7 @@ dependencies = [ "keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "lru-cache 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "lru-cache 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-crypto 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2052,11 +2052,6 @@ dependencies = [ "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "linked-hash-map" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "linked-hash-map" version = "0.5.1" @@ -2099,10 +2094,10 @@ dependencies = [ [[package]] name = "lru-cache" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "linked-hash-map 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "linked-hash-map 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2151,7 +2146,7 @@ name = "memory-cache" version = "0.1.0" dependencies = [ "heapsize 0.4.2 (git+https://github.com/cheme/heapsize.git?branch=ec-macfix)", - "lru-cache 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "lru-cache 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2319,7 +2314,7 @@ dependencies = [ "ethereum-types 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb-memorydb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "lru-cache 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "lru-cache 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -4611,13 +4606,12 @@ dependencies = [ "checksum libloading 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9c3ad660d7cb8c5822cd83d10897b0f1f1526792737a179e73896152f85b88c2" "checksum libusb 0.3.0 (git+https://github.com/paritytech/libusb-rs)" = "" "checksum libusb-sys 0.2.4 (git+https://github.com/paritytech/libusb-sys)" = "" -"checksum linked-hash-map 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7860ec297f7008ff7a1e3382d7f7e1dcd69efc94751a2284bafc3d013c2aa939" "checksum linked-hash-map 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "70fb39025bc7cdd76305867c4eccf2f2dcf6e9a57f5b21a93e1c2d86cd03ec9e" "checksum local-encoding 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e1ceb20f39ff7ae42f3ff9795f3986b1daad821caaa1e1732a0944103a5a1a66" "checksum lock_api 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "775751a3e69bde4df9b38dd00a1b5d6ac13791e4223d4a0506577f0dd27cfb7a" "checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" "checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6" -"checksum lru-cache 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4d06ff7ff06f729ce5f4e227876cb88d10bc59cd4ae1e09fbb2bde15c850dc21" +"checksum lru-cache 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c" "checksum lunarity-lexer 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8a1670671f305792567116d4660e6e5bd785d6fa973e817c3445c0a7a54cecb6" "checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" "checksum memchr 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4b3629fe9fdbff6daa6c33b90f7c08355c1aca05a3d01fa8063b822fcf185f3b" From 8840a293dd000dfd40353b2c4a10f51380d4b5d6 Mon Sep 17 00:00:00 2001 From: jwasinger Date: Sat, 30 Mar 2019 12:28:32 -0700 Subject: [PATCH 145/168] clique: make state backfill time measurement more accurate (#10551) --- ethcore/src/engines/clique/mod.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/ethcore/src/engines/clique/mod.rs b/ethcore/src/engines/clique/mod.rs index f5e83440dd..c0fad8e78f 100644 --- a/ethcore/src/engines/clique/mod.rs +++ b/ethcore/src/engines/clique/mod.rs @@ -280,6 +280,13 @@ impl Clique { let last_checkpoint_number = header.number() - header.number() % self.epoch_length as u64; debug_assert_ne!(last_checkpoint_number, header.number()); + // Catching up state, note that we don't really store block state for intermediary blocks, + // for speed. + let backfill_start = time::Instant::now(); + trace!(target: "engine", + "Back-filling block state. last_checkpoint_number: {}, target: {}({}).", + last_checkpoint_number, header.number(), header.hash()); + let mut chain: &mut VecDeque
= &mut VecDeque::with_capacity( (header.number() - last_checkpoint_number + 1) as usize); @@ -306,13 +313,6 @@ impl Clique { } } - // Catching up state, note that we don't really store block state for intermediary blocks, - // for speed. - let backfill_start = time::Instant::now(); - trace!(target: "engine", - "Back-filling block state. last_checkpoint_number: {}, target: {}({}).", - last_checkpoint_number, header.number(), header.hash()); - // Get the state for last checkpoint. let last_checkpoint_hash = *chain.front() .expect("chain has at least one element; qed") From 440e52f4106110ba86b72c6a520ebe63f30efe19 Mon Sep 17 00:00:00 2001 From: TriplEight Date: Sat, 30 Mar 2019 20:29:08 +0100 Subject: [PATCH 146/168] build android with cache, win fixes (#10546) * build android with cache! * windows fixes * windows fixes 2 * windows fixes 3 * windows fixes 4 * windows should have sccache variables in env variables --- .gitlab-ci.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 775d1ecee1..436b8a156f 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -97,12 +97,13 @@ test-linux: build-android: stage: build - image: parity/rust-android:gitlab-ci + image: parity/rust-parity-ethereum-android-build:stretch variables: CARGO_TARGET: armv7-linux-androideabi + <<: *docker-cache-status + <<: *collect_artifacts script: - scripts/gitlab/build-linux.sh - <<: *collect_artifacts tags: - linux-docker @@ -153,9 +154,8 @@ build-windows: only: *releaseable_branches variables: CARGO_TARGET: x86_64-pc-windows-msvc - CARGO_HOME: "C:/ci-cache/parity-ethereum/cargo/%CI_JOB_NAME%" - RUSTC_WRAPPER: sccache - SCCACHE_DIR: "C:/ci-cache/parity-ethereum/sccache" + CARGO_HOME: "C:/ci-cache/parity-ethereum/cargo/$CI_JOB_NAME" + GIT_SUBMODULE_STRATEGY: none script: - sh scripts/gitlab/build-windows.sh tags: From 7b2afdfc8c0b5469d4201c5d749b64ede8420942 Mon Sep 17 00:00:00 2001 From: Vladyslav Lupashevskyi Date: Sun, 31 Mar 2019 11:39:38 +0300 Subject: [PATCH 147/168] Implement caching for service transactions checker (#10088) * Tx permission contract improvement * Take in account zero gas price certification when doing transact_contract * DRY in ServiceTransactionChecker * Fix typos and regroup mod * Introduce CertifiedAddressesCache * Introduce refresh_cache for CertifiedAddressesCache * Add CertifiedAddressesCache read and write on checking * Refresh CertifiedAddressesCache on new imported block * Separate ChainInfo trait and fix errors after merge * Do not fire an error when service txes contract does not exist * WIP: Shared certified addresses cache between miner and client + use HashMap instead of BTreeMap * Refactor refresh_cache for ServiceTransactionChecker * Refresh cache fixes * Add cache read in check_address + log when cache is used + improve code * Remove ChainInfo from ServiceTransaction dependencies * DRY ServiceTransactionChecker * Fix Client and Miner in tests * Fix node_filter test * Fix Client::new in add_peer_with_private_config * WIP: Separated ChainNotify from ethcore trait and implemented ChainNotify for ServiceTransactionChecker * Fix watcher test * Revert "Merge branch 'master' into master" This reverts commit 4e7371dc109d022efe3087defc33d827998ce648, reversing changes made to bffd73e5fd58a516bbf404281b51cf26422e181e. * Revert "Fix watcher test" This reverts commit bffd73e5fd58a516bbf404281b51cf26422e181e. * Revert "WIP: Separated ChainNotify from ethcore trait and implemented ChainNotify for ServiceTransactionChecker" This reverts commit 6e73d1e61fa15dc10ffd4fab63df29eabe9c3b3a. * Revert "Fix Client::new in add_peer_with_private_config" This reverts commit ec610a30bee95588d58b79edcc9e43c2ff90f1ad. * Revert "Fix node_filter test" This reverts commit 06a4b2de86317c902f579e912b40de0b0fbf6d78. * Revert "Fix Client and Miner in tests" This reverts commit 51bbad330ea6e7bdfc1516208cc8705d5d11516d. * Implement ServiceTransactionChecker in miner and delegate it to client + revert unnecessary changes * Merge master * Code improvements * Merge branch 'master' of https://github.com/paritytech/parity-ethereum # Conflicts: # Cargo.lock # ethcore/private-tx/src/lib.rs # ethcore/src/miner/miner.rs # ethcore/src/miner/pool_client.rs --- ethcore/private-tx/src/lib.rs | 3 +- ethcore/src/client/client.rs | 13 ++++--- ethcore/src/miner/miner.rs | 30 ++++++++++++++-- ethcore/src/miner/pool_client.rs | 10 ++---- miner/src/service_transaction_checker.rs | 46 ++++++++++++++++++++++-- 5 files changed, 82 insertions(+), 20 deletions(-) diff --git a/ethcore/private-tx/src/lib.rs b/ethcore/private-tx/src/lib.rs index 64381b497b..d487b4d835 100644 --- a/ethcore/private-tx/src/lib.rs +++ b/ethcore/private-tx/src/lib.rs @@ -277,13 +277,12 @@ impl Provider { fn pool_client<'a>(&'a self, nonce_cache: &'a NonceCache, local_accounts: &'a HashSet
) -> miner::pool_client::PoolClient<'a, Client> { let engine = self.client.engine(); - let refuse_service_transactions = true; miner::pool_client::PoolClient::new( &*self.client, nonce_cache, engine, local_accounts, - refuse_service_transactions, + None, // refuse_service_transactions = true ) } diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index 1662256f49..0b07d71030 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -25,7 +25,6 @@ use blockchain::{BlockReceipts, BlockChain, BlockChainDB, BlockProvider, TreeRou use bytes::Bytes; use call_contract::{CallContract, RegistryInfo}; use ethcore_miner::pool::VerifiedTransaction; -use ethcore_miner::service_transaction_checker::ServiceTransactionChecker; use ethereum_types::{H256, Address, U256}; use evm::Schedule; use hash::keccak; @@ -2157,10 +2156,14 @@ impl BlockChainClient for Client { fn transact_contract(&self, address: Address, data: Bytes) -> Result<(), transaction::Error> { let authoring_params = self.importer.miner.authoring_params(); - let service_transaction_checker = ServiceTransactionChecker::default(); - let gas_price = match service_transaction_checker.check_address(self, authoring_params.author) { - Ok(true) => U256::zero(), - _ => self.importer.miner.sensible_gas_price(), + let service_transaction_checker = self.importer.miner.service_transaction_checker(); + let gas_price = if let Some(checker) = service_transaction_checker { + match checker.check_address(self, authoring_params.author) { + Ok(true) => U256::zero(), + _ => self.importer.miner.sensible_gas_price(), + } + } else { + self.importer.miner.sensible_gas_price() }; let transaction = transaction::Transaction { nonce: self.latest_nonce(&authoring_params.author), diff --git a/ethcore/src/miner/miner.rs b/ethcore/src/miner/miner.rs index adaeff0874..d9d4570a72 100644 --- a/ethcore/src/miner/miner.rs +++ b/ethcore/src/miner/miner.rs @@ -25,6 +25,7 @@ use call_contract::CallContract; use ethcore_miner::gas_pricer::GasPricer; use ethcore_miner::local_accounts::LocalAccounts; use ethcore_miner::pool::{self, TransactionQueue, VerifiedTransaction, QueueStatus, PrioritizationStrategy}; +use ethcore_miner::service_transaction_checker::ServiceTransactionChecker; #[cfg(feature = "work-notify")] use ethcore_miner::work_notify::NotifyWork; use ethereum_types::{H256, U256, Address}; @@ -246,6 +247,7 @@ pub struct Miner { engine: Arc, accounts: Arc, io_channel: RwLock>>, + service_transaction_checker: Option, } impl Miner { @@ -272,6 +274,7 @@ impl Miner { let verifier_options = options.pool_verification_options.clone(); let tx_queue_strategy = options.tx_queue_strategy; let nonce_cache_size = cmp::max(4096, limits.max_count / 4); + let refuse_service_transactions = options.refuse_service_transactions; Miner { sealing: Mutex::new(SealingWork { @@ -292,6 +295,11 @@ impl Miner { accounts: Arc::new(accounts), engine: spec.engine.clone(), io_channel: RwLock::new(None), + service_transaction_checker: if refuse_service_transactions { + None + } else { + Some(ServiceTransactionChecker::default()) + }, } } @@ -350,6 +358,11 @@ impl Miner { }); } + /// Returns ServiceTransactionChecker + pub fn service_transaction_checker(&self) -> Option { + self.service_transaction_checker.clone() + } + /// Retrieves an existing pending block iff it's not older than given block number. /// /// NOTE: This will not prepare a new pending block if it's not existing. @@ -377,7 +390,7 @@ impl Miner { &self.nonce_cache, &*self.engine, &*self.accounts, - self.options.refuse_service_transactions, + self.service_transaction_checker.as_ref(), ) } @@ -1283,7 +1296,7 @@ impl miner::MinerService for Miner { let nonce_cache = self.nonce_cache.clone(); let engine = self.engine.clone(); let accounts = self.accounts.clone(); - let refuse_service_transactions = self.options.refuse_service_transactions; + let service_transaction_checker = self.service_transaction_checker.clone(); let cull = move |chain: &::client::Client| { let client = PoolClient::new( @@ -1291,7 +1304,7 @@ impl miner::MinerService for Miner { &nonce_cache, &*engine, &*accounts, - refuse_service_transactions, + service_transaction_checker.as_ref(), ); queue.cull(client); }; @@ -1303,6 +1316,17 @@ impl miner::MinerService for Miner { self.transaction_queue.cull(client); } } + if let Some(ref service_transaction_checker) = self.service_transaction_checker { + match service_transaction_checker.refresh_cache(chain) { + Ok(true) => { + trace!(target: "client", "Service transaction cache was refreshed successfully"); + }, + Ok(false) => { + trace!(target: "client", "Registrar or/and service transactions contract does not exist"); + }, + Err(e) => error!(target: "client", "Error occurred while refreshing service transaction cache: {}", e) + }; + }; } fn pending_state(&self, latest_block_number: BlockNumber) -> Option { diff --git a/ethcore/src/miner/pool_client.rs b/ethcore/src/miner/pool_client.rs index df364d4464..60e93dee8a 100644 --- a/ethcore/src/miner/pool_client.rs +++ b/ethcore/src/miner/pool_client.rs @@ -75,7 +75,7 @@ pub struct PoolClient<'a, C: 'a> { engine: &'a EthEngine, accounts: &'a LocalAccounts, best_block_header: Header, - service_transaction_checker: Option, + service_transaction_checker: Option<&'a ServiceTransactionChecker>, } impl<'a, C: 'a> Clone for PoolClient<'a, C> { @@ -100,7 +100,7 @@ impl<'a, C: 'a> PoolClient<'a, C> where cache: &'a NonceCache, engine: &'a EthEngine, accounts: &'a LocalAccounts, - refuse_service_transactions: bool, + service_transaction_checker: Option<&'a ServiceTransactionChecker>, ) -> Self { let best_block_header = chain.best_block_header(); PoolClient { @@ -109,11 +109,7 @@ impl<'a, C: 'a> PoolClient<'a, C> where engine, accounts, best_block_header, - service_transaction_checker: if refuse_service_transactions { - None - } else { - Some(Default::default()) - }, + service_transaction_checker, } } diff --git a/miner/src/service_transaction_checker.rs b/miner/src/service_transaction_checker.rs index c9b3b4b238..56e65c8b8f 100644 --- a/miner/src/service_transaction_checker.rs +++ b/miner/src/service_transaction_checker.rs @@ -16,11 +16,15 @@ //! A service transactions contract checker. -use call_contract::{CallContract, RegistryInfo}; +use std::collections::HashMap; +use std::mem; +use std::sync::Arc; +use call_contract::{RegistryInfo, CallContract}; use types::ids::BlockId; use types::transaction::SignedTransaction; use ethabi::FunctionOutputDecoder; use ethereum_types::Address; +use parking_lot::RwLock; use_contract!(service_transaction, "res/contracts/service_transaction.json"); @@ -28,9 +32,12 @@ const SERVICE_TRANSACTION_CONTRACT_REGISTRY_NAME: &'static str = "service_transa /// Service transactions checker. #[derive(Default, Clone)] -pub struct ServiceTransactionChecker; +pub struct ServiceTransactionChecker { + certified_addresses_cache: Arc>> +} impl ServiceTransactionChecker { + /// Checks if given address in tx is whitelisted to send service transactions. pub fn check(&self, client: &C, tx: &SignedTransaction) -> Result { let sender = tx.sender(); @@ -44,9 +51,42 @@ impl ServiceTransactionChecker { /// Checks if given address is whitelisted to send service transactions. pub fn check_address(&self, client: &C, sender: Address) -> Result { + trace!(target: "txqueue", "Checking service transaction checker contract from {}", sender); + if let Some(allowed) = self.certified_addresses_cache.try_read().as_ref().and_then(|c| c.get(&sender)) { + return Ok(*allowed); + } let contract_address = client.registry_address(SERVICE_TRANSACTION_CONTRACT_REGISTRY_NAME.to_owned(), BlockId::Latest) .ok_or_else(|| "contract is not configured")?; - trace!(target: "txqueue", "Checking service transaction checker contract from {}", sender); + self.call_contract(client, contract_address, sender).and_then(|allowed| { + if let Some(mut cache) = self.certified_addresses_cache.try_write() { + cache.insert(sender, allowed); + }; + Ok(allowed) + }) + } + + /// Refresh certified addresses cache + pub fn refresh_cache(&self, client: &C) -> Result { + trace!(target: "txqueue", "Refreshing certified addresses cache"); + // replace the cache with an empty list, + // since it's not recent it won't be used anyway. + let cache = mem::replace(&mut *self.certified_addresses_cache.write(), HashMap::default()); + + if let Some(contract_address) = client.registry_address(SERVICE_TRANSACTION_CONTRACT_REGISTRY_NAME.to_owned(), BlockId::Latest) { + let addresses: Vec<_> = cache.keys().collect(); + let mut cache: HashMap = HashMap::default(); + for address in addresses { + let allowed = self.call_contract(client, contract_address, *address)?; + cache.insert(*address, allowed); + } + mem::replace(&mut *self.certified_addresses_cache.write(), cache); + Ok(true) + } else { + Ok(false) + } + } + + fn call_contract(&self, client: &C, contract_address: Address, sender: Address) -> Result { let (data, decoder) = service_transaction::functions::certified::call(sender); let value = client.call_contract(BlockId::Latest, contract_address, data)?; decoder.decode(&value).map_err(|e| e.to_string()) From 95236d25b2d56cb66b23a6a200f5e55fc3b66f57 Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Sun, 31 Mar 2019 10:40:33 +0200 Subject: [PATCH 148/168] fix(light eth_gasPrice): ask network if not in cache (#10535) * fix(light eth_gasPrice): ask N/W if not in cache * fix(bad rebase) --- rpc/src/v1/helpers/light_fetch.rs | 32 +++++++++++++++++++------------ rpc/src/v1/impls/eth.rs | 4 ++-- rpc/src/v1/impls/light/eth.rs | 10 +++------- rpc/src/v1/traits/eth.rs | 2 +- 4 files changed, 26 insertions(+), 22 deletions(-) diff --git a/rpc/src/v1/helpers/light_fetch.rs b/rpc/src/v1/helpers/light_fetch.rs index f507964734..7167a73163 100644 --- a/rpc/src/v1/helpers/light_fetch.rs +++ b/rpc/src/v1/helpers/light_fetch.rs @@ -43,7 +43,7 @@ use light::request::Field; use sync::{LightNetworkDispatcher, ManageNetwork, LightSyncProvider}; -use ethereum_types::Address; +use ethereum_types::{Address, U256}; use hash::H256; use parking_lot::Mutex; use fastmap::H256FastMap; @@ -55,6 +55,7 @@ use v1::types::{BlockNumber, CallRequest, Log, Transaction}; const NO_INVALID_BACK_REFS_PROOF: &str = "Fails only on invalid back-references; back-references here known to be valid; qed"; const WRONG_RESPONSE_AMOUNT_TYPE_PROOF: &str = "responses correspond directly with requests in amount and type; qed"; +const DEFAULT_GAS_PRICE: u64 = 21_000; pub fn light_all_transactions(dispatch: &Arc>) -> impl Iterator where @@ -231,7 +232,6 @@ where /// Helper for getting proved execution. pub fn proved_read_only_execution(&self, req: CallRequest, num: Option) -> impl Future + Send { - const DEFAULT_GAS_PRICE: u64 = 21_000; // (21000 G_transaction + 32000 G_create + some marginal to allow a few operations) const START_GAS: u64 = 60_000; @@ -257,18 +257,9 @@ where None => Either::B(self.account(from, id).map(|acc| acc.map(|a| a.nonce))), }; - let gas_price_percentile = self.gas_price_percentile; let gas_price_fut = match req.gas_price { Some(price) => Either::A(future::ok(price)), - None => Either::B(dispatch::light::fetch_gas_price_corpus( - self.sync.clone(), - self.client.clone(), - self.on_demand.clone(), - self.cache.clone(), - ).map(move |corp| match corp.percentile(gas_price_percentile) { - Some(percentile) => *percentile, - None => DEFAULT_GAS_PRICE.into(), - })) + None => Either::B(self.gas_price()), }; // if nonce resolves, this should too since it'll be in the LRU-cache. @@ -307,6 +298,23 @@ where })) } + /// Helper to fetch the corpus gas price from 1) the cache 2) the network then it tries to estimate the percentile + /// using `gas_price_percentile` if the estimated percentile is zero the `DEFAULT_GAS_PRICE` is returned + pub fn gas_price(&self) -> impl Future + Send { + let gas_price_percentile = self.gas_price_percentile; + + dispatch::light::fetch_gas_price_corpus( + self.sync.clone(), + self.client.clone(), + self.on_demand.clone(), + self.cache.clone(), + ) + .map(move |corp| { + corp.percentile(gas_price_percentile) + .map_or_else(|| DEFAULT_GAS_PRICE.into(), |percentile| *percentile) + }) + } + /// Get a block itself. Fails on unknown block ID. pub fn block(&self, id: BlockId) -> impl Future + Send { let mut reqs = Vec::new(); diff --git a/rpc/src/v1/impls/eth.rs b/rpc/src/v1/impls/eth.rs index 1b5fdf447f..32f9c1c57f 100644 --- a/rpc/src/v1/impls/eth.rs +++ b/rpc/src/v1/impls/eth.rs @@ -552,8 +552,8 @@ impl Eth for EthClient< Ok(self.external_miner.hashrate()) } - fn gas_price(&self) -> Result { - Ok(default_gas_price(&*self.client, &*self.miner, self.options.gas_price_percentile)) + fn gas_price(&self) -> BoxFuture { + Box::new(future::ok(default_gas_price(&*self.client, &*self.miner, self.options.gas_price_percentile))) } fn accounts(&self) -> Result> { diff --git a/rpc/src/v1/impls/light/eth.rs b/rpc/src/v1/impls/light/eth.rs index b3e183c1c9..cd17b06739 100644 --- a/rpc/src/v1/impls/light/eth.rs +++ b/rpc/src/v1/impls/light/eth.rs @@ -38,8 +38,7 @@ use types::filter::Filter as EthcoreFilter; use types::ids::BlockId; use v1::impls::eth_filter::Filterable; -use v1::helpers::{errors, limit_logs}; -use v1::helpers::{SyncPollFilter, PollManager}; +use v1::helpers::{errors, limit_logs, SyncPollFilter, PollManager}; use v1::helpers::deprecated::{self, DeprecationNotice}; use v1::helpers::light_fetch::{self, LightFetch}; use v1::traits::Eth; @@ -271,11 +270,8 @@ where Ok(Default::default()) } - fn gas_price(&self) -> Result { - Ok(self.cache.lock().gas_price_corpus() - .and_then(|c| c.percentile(self.gas_price_percentile).cloned()) - .map(U256::from) - .unwrap_or_else(Default::default)) + fn gas_price(&self) -> BoxFuture { + Box::new(self.fetcher().gas_price()) } fn accounts(&self) -> Result> { diff --git a/rpc/src/v1/traits/eth.rs b/rpc/src/v1/traits/eth.rs index 14f8fb69e1..69a37ae526 100644 --- a/rpc/src/v1/traits/eth.rs +++ b/rpc/src/v1/traits/eth.rs @@ -56,7 +56,7 @@ pub trait Eth { /// Returns current gas_price. #[rpc(name = "eth_gasPrice")] - fn gas_price(&self) -> Result; + fn gas_price(&self) -> BoxFuture; /// Returns accounts list. #[rpc(name = "eth_accounts")] From ec56b1f09d83d06b749e49d3973f5260cb9fc524 Mon Sep 17 00:00:00 2001 From: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> Date: Sun, 31 Mar 2019 11:46:36 +0200 Subject: [PATCH 149/168] Update light client harcoded headers (#10547) * kovan #10643457 * ropsten #5296129 * foundation #7460865 * classic #7747585 * indentation * morden #3973121 --- ethcore/res/ethereum/classic.json | 100 +- ethcore/res/ethereum/foundation.json | 103 +- ethcore/res/ethereum/kovan.json | 108 +- ethcore/res/ethereum/morden.json | 1946 ++++++++++++++++++++++++++ ethcore/res/ethereum/ropsten.json | 101 +- 5 files changed, 2346 insertions(+), 12 deletions(-) diff --git a/ethcore/res/ethereum/classic.json b/ethcore/res/ethereum/classic.json index 898268901f..393129c12f 100644 --- a/ethcore/res/ethereum/classic.json +++ b/ethcore/res/ethereum/classic.json @@ -48,8 +48,8 @@ "stateRoot": "0xd7f8974fb5ac78d9ac099b9ad5018bedc2ce0a72dad1827a1709da30580f0544" }, "hardcodedSync": { - "header": "f90210a08eb792fdb134b57fffbdf19bd61d4c1cc351fc38a7fcf6609c82b35ea364208fa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794df7d7e053933b5cc24372f878c90e62dadad5d42a0e29a2e741354b453139d244920f7d552f90a579f1dcb99ef6b470bcffc713ebaa04bb64c992b8cf56259177a192d6f0a1eddf192b8daa7dbf1ec8313428cccde20a0ee22efe3b124a0297503fd26e6f7b33c7a88aa75825259297f8e30bee3632a68b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000866a396ffc14908373480183797a1182f618845c7395609165746865726d696e652d6574632d757331a087f3616cc0ba3704e23702bf7461f8f7716f1f1ad3ac4c66391d45adc57d1dea886ecb8e800fe87049", - "totalDifficulty": "575603227549295900024", + "header": "f9021ba0a281d23475d3d5ff03df8636c9f528cdd91498af274a3b2f8989bbd51bfeb809a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794004730417cd2b1d19f6be2679906ded4fa8a64e2a0d5fdd62e7e29dc3da1cd3fe5ad549e000260bfdb55f523fde008f26390220d23a0370ff78457d6c7469ff333a13165f4bb8057d00cfa68365cb4d1a8c8a1da46d5a0dea37365a20f5bb5ad3766a24a9fe7b04b946e35aaba74f862467a7c5cdb7d67b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000004000000000040000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000100000000000000000000000080000000000000000020000000000000000000000000000000000000000000000000000000000000000000000020000000000001000000000000000000000000000000080010000000000000008000000000000000866fc181925a9783763801837a121d830c317c845c9d1efe9b457468657265756d436c6173736963534f4c4f2f326d696e657273a0bb6e626c7ee3d827da18e1b303d9552ba17e92cefcedfc58bdfc5bac6a8ebabe882d8c26402344c24b", + "totalDifficulty": "598584828374329723203", "CHTs": [ "0x0eb474b7721727204978e92e27d31cddff56471911e424a4c8271c35f9c982cc", "0xe10e94515fb5ffb7ffa9bf50db4a959b3f50c2ff75e0b8bd5f5e038749e52a11", @@ -3739,7 +3739,101 @@ "0x362ca494021482f0d9dea4abd844ca11b71fbeb0a98e7db7bfb3bb6f864eb58c", "0x09ec27c856f50888e4634ffaca66f8185fd13e0bb2bbf522ce6209886502c7a5", "0x24996d2f96618887c1c5e61d5d7ce6948853ca35811d48f72155a4778308e255", - "0x4f199a8efc8615c623902b5c279dd995ac1df4654a07aab0423e070d14bd24d0" + "0x4f199a8efc8615c623902b5c279dd995ac1df4654a07aab0423e070d14bd24d0", + "0xe6875990cef0d2ce1f9d100654cdf522bbe345a462ebca769b1e288128c13201", + "0x36c141d47991e557f7226d8b1fe791c334f046f867d7865d663f99e2a337d915", + "0x337e59da56cde8e3f9e90fafff54d4fa240ba01aec855fd55626e4b3a45a9767", + "0x67672d3a29c49e3545d25422b6015a1eebe86596f55d4c9b8772e89c99ac9f8b", + "0x6d6e167641bcd2e5241ac2710951f7f0c47fb311e32e998831e6fe38f5bebb25", + "0x6dc4fa5ae3f281a90619216491284d951151f37be648694d1952314f43ffe05d", + "0x3c865ccee7900b39d671c43ae15df71fad294781d74815537de94d02b48dd8a0", + "0x10ba37d2ff46db181ff8a15f38bfeecfd9c21e28bf63cb5ab975a2d7c74c0aef", + "0xba265a598f3af5bf4c2b87bd8d28a55f963cfbd09108aaccd5b00294f662e8b9", + "0xaab422eb98f7b0ab9a01558069a3666efa2be2510097b0054bd5c8fceb1023df", + "0xdbff3ce1e6fb0388029f95bd091c95b88c6539fabfe6f1de8e44c47dab064ff8", + "0xb1aa0c7254f3aaa61b58c9d973f3d89f5f4dc6bfee011ad4c4a3e3ae76aaf7df", + "0x055e36325029db9e089808ca01b0ee3eae53703f3e91ee51e587e7b7dcaa8a3d", + "0x00ec5a25517cf0c0a1bf892e5209fd0185ff1ffc6b2523642bf86f6a3d0c10f3", + "0x7bc6a8d5017760f12ace9ebfcdf5a91abcfd6e4f4131df5c4dbe84d2d6a6add9", + "0xeb5da64c8d0cc93a44da96ee9c3c0a22054a2a2e87a7491a5618ade1f59a1b96", + "0xc0a937729678bb6aca27ae16c662ccd2dd0b53346c610d6e5d5b1655762fa4b3", + "0x55c732917d3894ffeb9844fcb1c690d0956c4e2a8eccb6552cdde4ea90c99db2", + "0xf1dfd2205daf748da9e8e98bc4ee94cd6b2db5560e4cead28910e14c576337aa", + "0x60a271fb20c017f90d99c57783ebb8b1a3233398c49f89d73db14b09adf2893b", + "0x8fbd97d55dc64f2124c79054765515f49d79a05f2962b17875f12b353c33f564", + "0x5afd5951c5e834fbf22071047f72619496e9a9dbc6073b661c44741b67fabf03", + "0x2d05a19223820f92e385d2c942b70cca32804546f3aa7058381ca3f6c1ecde11", + "0x267dab323804f2e7bdcc80dde83ccbff56d1aa0fffd0edc7c02ffd4a24bbe027", + "0xf4e9e580bbcc5a9be1f942c12d4b34eb1a4c07feffd0b95abe27ddff57a6cc8f", + "0x3f146ceffcd100ca9fc1af743fad74acd03a289f4038413acfcfd0eb87d14a56", + "0xef98171ed6b269c0ebd6bdbb1d98694316b639bae6a3ad01f4964c3d2eb3d2cf", + "0x510013a35d5c71863b3385176c794ad90e17af1fd271b933f9f7ab980311b27c", + "0x5eb181d22f30ed203c4d3fad610d31c2338dae6a88eee250af19ae0f58319ad1", + "0x50a28d65b51ff086dcf2110feca7d990db95f078394c56bfb850a3b8cfd7f1a2", + "0x4148b8f2136b84773b7ff71d73aa8ffb98f0f3952939849f324c28b9173efd70", + "0xa980bc7fa736bf6d6d794ffa5e035664c45117c21e40da7ba76de7c2ff8164d0", + "0x794a8ef17e48986df700d6e68799a50695086702d6224ae9a71663fd03f8a55e", + "0xf354c82e1c75d7d758099dcd4d0592363eef81e85cba773aa6d6b30e1900582a", + "0xbb4c8b990add1c4e43ddebf742eb605028ae2daa8b61db7d237386d81e4c3413", + "0x61470a53ef9757fa7c452bdbe26d448dd8bf6590fc11420ebeddf441fe56f381", + "0x603558b2f72405e9625ac561d62c2bbcdda84d8ef4b5510d06bdac0553025bf2", + "0xf52d9ba6ba149d0e4266a8d05b73e4a445e9583560024e0185d4b8b12bd55640", + "0x26ef211f77b4a67ddb0a24c4e63f7d247d6ce8635dd9862894bdc067633ff395", + "0xed4ce5eb08b63534c5de241513a996322d168f6b8bf5c75167e79dd7ca1cc817", + "0x9d5f39f494a36d17db609b7a7a62734ca7222426c3556132bf1e2241d6c45cd2", + "0xe664772da4521e1140cc2c5db744010f57c15374dfb78a97701904787846a8f6", + "0x93faea0d197923b1578ac190fe608203f637fe4991ad4954c15ea94e17ee948b", + "0x2b028c1aaae5217cabb97c46c20541c93e55a868f78e82740f9fb9a0a033d662", + "0x529103419484990ad11c05e0c4c696826f67fbcd491e19aaac461cc340747ec4", + "0xc1e773415513b7bf47340d7b0a29e5d49d1a88bb3d0ee2a79726169d32012378", + "0xf97c43bb4ae25524b180e59cb6cac75858d4a8a0772fcf4f3bd24dfad42169da", + "0x19fa7ad12455fd022cfd15897d553e031ca1adf80c963c770250d36f1810a5f0", + "0xe67ce6e2444b8318a01150952a537ee47b701555c79f60eb90d3c3cdf93fb6b1", + "0x1b49d232180b0922704ebd4e9fabca5dd8ae9cfc2a39ea07226ba903a15037e3", + "0x56540b02ffe1743468342b5664b6e51cb3ef6c48dd74d6cd74e0c0c513c13129", + "0xd4d9d67f352c7f54d68ce994b3765b032108a5bd0b5b62d14b893949b96008d4", + "0x44d1b765df81594fd37e7700019f19b1ebd6d9b50631455931b83ce35238cb6b", + "0x2b67aef7cecfec055853cd63e8519bf506d7a1ae69a768e4db9415bdff532c47", + "0xc30ac2a4acc33cec2cdc83e114fb8237c4900a2fc89dddb6af3a4dd5e4868e51", + "0xe0e7127e086e2011f30fcd0469b35769cae163acb8ee6db8a8e2c032c2b351c5", + "0xb46c428070d15ec926fdf1d7465a9168c56dbb959d5391e26480500a98e36047", + "0x8dab41ce167633da3c0b5332833dfad5d2c28ef30c94973e5f4647e312781676", + "0xc632d30657b39208c254cf4f899d00d7c3196cbdc31248798a760972bf399fec", + "0xb4eb2c6c656406a9bc6cc6176dbdfc0e878046530d830a51e04a4e22c4572370", + "0xadb48a02c9c87b246360edb45528ba23cceed736a2ee0cfd03177428e6243024", + "0x443ac2e63e6d629398e607d6689725dd68fd5254916c1b76c876885456a13338", + "0xb66c4d950a9304025654de37c7d0e9759b755d86226a816d1e3b4c7d654a1bc3", + "0xded624610c3493bc7806844342c37909c1c1d179025c215108a12a0428ae9e36", + "0x28c85177961714ce796f152dcd31c8b19db1c39deebfe383d6fdf2334d4261b6", + "0x6d342534c3a4a875c5455ed3ef546e876cedb5aee7b2ecf194c6e47c6a09d3a4", + "0x65a84879e014085b7a0de5bf604050bc6bffd8ab7748253203fff49573763558", + "0xcb0e4339dfbfc8b420c915149a0d352fda69c31668b32452c432f067462b4325", + "0x3466440e4c88895f2642f2986dea4be482c028592530224d73e67254b2bac69f", + "0xb7c325fec25c7b278724ebb91c64fc2ac37e91e44b136dd6c29bf48b80990888", + "0x7a9a2bd3ab5972c1a4ec5972f959a1e30eb678090ed76947e38d76fc3ed758a5", + "0x74deabf896026cb20e2f5f8a88828b265d6696883dab972fe1bc9a4ca98d68b5", + "0x195d2e25b1ec8deea095bcbaac5277f4586237e68bd9c9ad24e65a8e53d6d27a", + "0xcc343c21f7f18c1d507cc3cf12381d7bbe55d7355363361d05d972343fb4b7fe", + "0xd2637aaef2034203e549453225eb1d75633d2c66e8cad0419395250c1e369536", + "0x0f8052a87aa435deee2826e6dbc944128835264d5770dbb064373de05333f8c2", + "0x2091278a3d6a7ed1ab0458cc307903a51d75c6a1c549ebed1f0aed29ce6533b8", + "0x3f7d25feee0dcf39372ccbad55989442d9b7ce16ac93e4b1dca63bd92d5204e4", + "0xd0f866c38597038e360af960e3e84c79a0027576bf3fdf4358a9442f0c671b61", + "0xc527b3694dc6b46f0562cb36e2f766e5b75793ad2794258d8be5119bff4ea8b0", + "0x47f1d7d32904cb0945e97140c2412d12b1e0980c2f72c7878250170aae4124dd", + "0x57aa1ef2a7ec01ee7acd0c4baed5407f30d6c34f2bc6bce7fda6366517343199", + "0xd392127f856736dd74d16a24309a247682e2736f78fc92713c484a6f13edcdbf", + "0x595aa7e3eddba867389d63b2eaa6b16e4e5163076f03d2c8013e40c3b0fc98c0", + "0x50bb320d8bea03db548be3a3b619159e1993ba8eea83af6f022b9cd29ae4d0ff", + "0x53deeb64ee923912f76a233532f474d76d8f6b8cc42eedcce81bda8ad608294c", + "0x1af301b0eaf36d16a74b2d1f76e9e26659f047cd3466a765049260047c25bbee", + "0x05c1d40227ece15c55f06dc922f5a9be01cc147a96e070e7a81b696f0f40b6ee", + "0xa63ee877c70d8e51e795d153a34ce3bcc212f8fb8e77df52ff83084b9133a280", + "0x07ab3e2107db7ff479f5be0d7a57e3b76627cf6230cdeb61d78ebaa2c391d360", + "0xc893aee6d249c152f5db3d7763f34a3311345dff721ae9c71ab5fb3d2b3e2559", + "0x250caa98ea3e682be9c866990f19647f443d57690052229ac0ccfa0ab30a5a71", + "0xc32fd5318214071a41cd8e98499b2b65942c5837c686a06b536146fd0bf294bf", + "0xac390c012eecd83fa8f4cc77a59992914b5c95af36b28747e07adea13228acbc" ] }, "nodes": [ diff --git a/ethcore/res/ethereum/foundation.json b/ethcore/res/ethereum/foundation.json index 8f96a842a7..5a7fd3be31 100644 --- a/ethcore/res/ethereum/foundation.json +++ b/ethcore/res/ethereum/foundation.json @@ -181,8 +181,8 @@ "stateRoot": "0xd7f8974fb5ac78d9ac099b9ad5018bedc2ce0a72dad1827a1709da30580f0544" }, "hardcodedSync": { - "header": "f90215a0ea51746efaaede944c3397e41ae72b7908c8ce25967c1edcd02618b068486feba01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794829bd824b016326a401d083b33d092293333a830a0aee38c1032f191c3d42cc581f53d31adb1f0d91f463e6a8c12fc35fd1db58d5aa0568149713d45e959d5d07624917617d0d7865124c25c28eb9b798013096ddeafa0847bb20a0b62d1d8e2b467c33b28ded6796c556cd2b2a169b640b40e58fd2340b9010048c03883204a1ef0204300012248c8841814900c04362858000450c8927a22a88d5b471c4869c00001d8641080695910c20801022c2910408829a8002620115dc8200ec2851300611284301c3243e091030706068c8160505403250d03f44437410080072a69048082b43070805d08424a021328221500101418463040904ca094a189c801e50000c41402603426c4701a6302e1023040080d8380e21d600a2083003a2604082001b183068d1470840a49008a514148800a08030a8002c821b24010f20ea31c55060582801c14483ec29d4081c7152d2244840016c123da6f42249b6002c8401618a0000a8c8df892954d8080800c160244453086480d8264b6870ae8321581e6cb836ed001837a30a08379e5a2845c72b9c0947070796520e4b883e5bda9e7a59ee4bb99e9b1bca06883c088b374f7c667ed0fda0f1ec7c18890c892b88f14b41f03e7d927bcca82880db92c004f0313a8", - "totalDifficulty": "9242028122621986440675", + "header": "f90212a0113ba3b1153987fc483b01ccfe9ecadbdc36a7b264be75d6486cb6b694cc38a1a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d493479452bc44d5378309ee2abf1539bf71de1b7d7be3b5a0d91db5900e312a1ba8d39505406a95dc0ea20393b723c4bf488ade4e3c4ee4c3a05e63ab076852043b1c2fe010e2f14ab13dcc8e1c546ac497a24ce88c4abf3056a0b72e4a776f895459b6bf0937040990d868b1f45889aeaa26684e07472263fc31b90100b00200000063664554889124822ce2001022840543085d5810042382888542ca3816801780384384cd6851081cdc4d4b2b205a814b049198110a6869d60f4009a79c3854c9000581044889080000611c09142200106552000044027024004038092102814ed6c48040a8715851088a20108e80165f8c0c514019037a0000121304b2343416800b029000024404248238a06818414cb8690244879491855405026bc8250220520992c2380099d10024411c6048424083d1307822442d8444700405147883c4c041300aaa2408bb61084012983825a22830040a180106b5e27182088060b111515832902903a8f1d432a48004d0250437106a503491000048a91587067a897789f4d78371d801837a309c8379ffd7845c9d879e9150505945206e616e6f706f6f6c2e6f7267a0db22736cb3f06f9c86804902731fa6841eaaa1cd6326ea2a30e9c304d48bdd04880323b06837344cb8", + "totalDifficulty": "9633968582330911261986", "CHTs": [ "0x0eb474b7721727204978e92e27d31cddff56471911e424a4c8271c35f9c982cc", "0xe10e94515fb5ffb7ffa9bf50db4a959b3f50c2ff75e0b8bd5f5e038749e52a11", @@ -3729,7 +3729,104 @@ "0x8ed199e2fd654bfc9dfd5e7ea7dc82bea9f4535eb480c95984a5a6bc1533bf8e", "0x4e5475dae57c548460d4ddd15583223bf2a4a2046c2ee56ca670892794a37d90", "0x80409971b3e59ec71deb1a158a92ab6fe8318cb9adebcf583586e23e42d370c4", - "0xeb35d7c78965874110f67b77307deae4bb29dc98c01fbac3737409ede61df7c6" + "0xeb35d7c78965874110f67b77307deae4bb29dc98c01fbac3737409ede61df7c6", + "0xd358b672db99b007ac54ef3ea7c77c0eb0b4e9cc1437ca4eb70d71aaaf84b6f2", + "0x0ca4c79c1709b947794ae73dd3b73b357273c4e5cfc83ec85c4c2b649e10740f", + "0x704635b2335b5ad2be0e586e60770dc1e0548794ee2c1670cbfbc2ed0c1f64ae", + "0x6a6f2425c865216b49e7e73026fd2e9cc02f131c0050ce849f274c37828909f0", + "0xce31e62ac098db0fef0823941009b826d4e5b8e11f2e01208ee6abccb160c0cc", + "0x5669c0e6ccaa8abff08e944fe8bdcf0001dce9c10ef8b90d7f821819e028dcb6", + "0x37b59281d4eec501ed45d68c2bfac450d336ee5a18ecb7d2d812763d2cfd4321", + "0xfb52f084a5ffd63001f47acdb2ea62e91714af63f896c151100350d83bd2c7e4", + "0x67bfc4a94fde6e81b54ebe52914c0d73a053bbac22d6d64862e987e53c78ed61", + "0x49c141a8ac1124f40d06c569f49363a8af092d0028b02d8f4c895af2f86d0f28", + "0x5c81c85021692d5dd1bdbd3a4543ec86d49e674380a0e5f59d4400902d7e753b", + "0x9b46d19b0cee63461453a487bbf855fb4a7d70933ce2b7445d1dce8dbbc11cf9", + "0x50fe5cb0ddf34ed2ee8341848bc00df89fda05fbf0ebb1b34d12afe9e5ae4d1a", + "0xd56b4c4880798175c2db50c5c5d6845b5c1e7b6b33172ba107f5de075ed09def", + "0xe0928a4092e5ab5b9a34a8748c3ddf86a6a9ab50e85777c4e1e8088ac7b44ae7", + "0xfcde6d53ff8286afecafa27d608e94c07a4d78813edeccb73a1076772d1f7e83", + "0x1bff0dc76b0d8877a9ea133a023a5dc0f88559f16f0adffbf7b4d58b6be487a1", + "0x5252a71f6c9784b538ecd810bded0520f349f5aa748657a9b4422474eee08388", + "0xc4cccd5ae51babfe8e9f76af2c64227b0fd63bc2f4336b7820a32846516d9835", + "0xd07bc360f06a492a13047247448ba37fc9a167bd81ee63607976be269d245e14", + "0x9499022a6b509dd05eae2a7c799c332382b810843065e82ec72891b771cc3a8a", + "0x0ba258fb2666908035e53ec37a96ee13719779de43f14a57223b704961ef667a", + "0x4dec79cac5e3b414aa835c69bb2c580ccc03eaed675b61070f37b606ff4715bd", + "0xac640ffa67870bd91b1ff36450256fb1e5f59e65f4ef844875185c38f7f986b5", + "0x0af93eccdfbb75dc353ff31949329b3c96ffa93f63e9ae4a515f6e177e201d35", + "0x5a2d5ba9defce6db1bff0bbbe4eee170fe3b9c0ecb4a1ec6e16f904b55c07beb", + "0xd92f1c26de95255b1e0926341c35b5bfd106820dbdcb381400516d247062f3fd", + "0x447ec0cf1a32e8201cb92d0ad13adc6e664a07612bf38ce9c598c799cd947fb1", + "0x28460192df35aec41fe3992efc94da904d69e4b65e518fd2c530b38c1ec88819", + "0x6b0557132b0efe568a96f77fad4f1e18cf05670c007488052f347cf3461ee98c", + "0xb82f3f400a0edc100ddd6e82c2ea587eb5d56ea0f8faa379f8fa259f31ea0838", + "0x370b650e0bd14d9e5d749f628fca91ff47184473b6cba948e9ad3492a68bed5e", + "0x794e423feca451babc044923a79ceab62ff3a9a7e8947dcadd0d91f78a11cff6", + "0x7fe410432bfc7048e6685eb6bf0b4ae9808864a2e09ed1d373dc211f40c59da7", + "0x9f53d260f145de7b48c04829abd97989bc11d748af7d119ebf56948ca438913a", + "0xad5ad5cd5ff452e16c07bba12f0b34bb1c3c8c33d54db45b515cf6761d6a1cc8", + "0xcc6e322ea2c52af09d720524c85629019eac5ca01dcec5da887ad4b32157b9e4", + "0x5d3ddb9fa275898453e8430b26270e2812709717898683f0a3291291b29d688a", + "0xeff621bef47694a862a320a661b691b491e4a5c44e1d2026c9756f84903a6375", + "0x110e7059d20e4531323dcf981ad6cb9d67d56815c54394ab1b0b7af4235aa218", + "0xe44d27931b9429204cd2e9cba838f0ed707d5668ab55ecf2c906b2748fa1f16d", + "0x9d7166683764cde8445c58697df637cd48e35b3ad00f6e6d4bbf12844ba217c5", + "0xf5f6625754100a91cd7283d47e72cca73c39e5fa2e0405d427430bccd49cc2bb", + "0xd6b27ee81a557ff5d8947225c19f3ba023af18415a413acdf438548b24902427", + "0xccc665895dbabf0d8775c5fddf167b41579b0e6bff8fe99c8da00622334c8861", + "0x1986e5fd526af0a0e74ab83cb82c18dbd5a73fe72b94c8ca10318f8f6bd2d98a", + "0xd3f245d6f37b0c47506fc4a2b12d85ff87eb35c2f45f82c3e5bebdc7362d8cd6", + "0x53b97494c77ef9a843ce61b2a58231bc145b492b710fc3dcf79c297187993bbf", + "0x00d4cd1f9460a8625ed0a539257e58a9ab8051ff239172f0a9437cb9f0d1a11f", + "0x1c3d92f1e67b04c24db2eb04184ca7ccd5533540aca4dcbe084a70648c347ee5", + "0x200e39cb704bcda42f547c0cae54c0dd4c0b1aaf17469d69deaa67d3ef0d95c5", + "0x5aa208366dc50c2e9f0075b0e8aad396851f54a42c9ec1114c2994da0c2fcace", + "0xbea70811c324fb1553c4fc492521ce062756da0a469d8f98cd6c0f7a3a7b5e3a", + "0x79aa191ef9975049a5f2b8b7e2921a3f78d045b99b7a569a93680c5ee2600a18", + "0x233fd477509141aed423948a0c5c5b8f0ab8cc3c4836c0f44c8cd6c0811b419c", + "0x1737e144530678804416cd7c3c8200f54f395bf7712c9ade8340988e1e123af5", + "0xbdad2ae32cbfc13446adfe9e4101f32fb52b1e336c165a1125c917d6c1a1fceb", + "0xc20dedeedd63be4c10d92d9d0e7b47e20d503f331cb31d47ec9e99b915305ba0", + "0x262281f50e2892d8cfca3b8f8a6645b5931fb4601755f02fb863d719cd690381", + "0xb0a717f11ff1e3f1a4bd775792c7e5a75af6e56967ab1615be6b4941ca9315e3", + "0xe8f45b1aee0fb0e87148b316ee0ce662ae3bb2abd05e9666429fcf30893641b1", + "0xe7a439e2577c4f892921f798efa19353d236146b849c20253b07f03194b36286", + "0xf4eda704d4864d8fccefecc246fb683dbdeee5468a53dd11d71d71477d170422", + "0x308d977f739b7a8cb4810242fb447a8f6cad45389a127f5822ca2df48fa9df86", + "0x3115d6d0f174e00bf3e5704f57e44b62f7e279894ce62f39568ffe4367fc5a44", + "0x6b6e6354b8d1e1ab0430fe2a5068b2b2263ff453676dbfdce5da60a6d625f20f", + "0x9b8a7b122572f459d946e67a1c78973040bcf67a64327f689d4016c53afcc4cf", + "0xa367c0bc2e6029afec518db94fa79288801f5ebf2cba50980fc9754a40784d19", + "0xc1a017142eac944b5fda4cd66a9b6b6dc64551c3ce958e8811797433b96ec5d8", + "0xc9e3999a3f162d42ae52644ce4f765b5ccc7fe2a4c91cc59048eeb8c8086718e", + "0x67c135523c9703aa1f1b653d9279804af4cd81cd3de99e10a853b42d78143914", + "0x9af2390bb01b245c65f76454f1c80102871131417cc8fbff4b1ada056d04dd47", + "0xf4cec7d4f4a76c769021ab0dab848d668fd36e910259e45094d88defabd13448", + "0xe2a224fd4510ac5f8a6782d2eed14ee164e6bb92d3f0a7e5e71497046fe9f30c", + "0x9884ca2b5533c36e03fecf28470fd3c45292dc623fb220c5eb0a580781fbe724", + "0x078b1365c5dc77fdea6bb010fab6c4dede06e27386d4d5f205bf7e7857b03865", + "0x8f930fa645409fc1d7fb28637360489a5e5eaa6554857441c3fd8990243d9972", + "0x2e21ac485ed90007e8b69cf247c28b25361729bcc7501a3296f9c06dd0742888", + "0x46c3ea9e86ad55d87b6f5d50fd9c145bcb6ca90a4d570c1f86b5532b0762d8c0", + "0x87edc87f5ac353d64b0f157ce3e3180ce73fdd1f0ae9db1406e49581f1780de7", + "0xc940108991c82f871c3eea33ec93951c9bc33cd0aba1c77262cb6fc6ea16f4eb", + "0xba2f1d37cebd9bcde635bee4c0f260af8fddb43a84508f244b562dd1f7bdbe92", + "0x738e8d02870cf37ba27db2eb621d5f7b32a225010de41e3983ed389ebaa0e364", + "0x84af8e6e7ceb53e068bdf16091bfe966458bb5d3e4a925360411a213aaf46a5c", + "0x548302ac8a0af1ef5bb91d469f66f8669cdb2a07c432e7504a806e00487adb63", + "0x35bc3a284170d090e6fe053d3bd2a8fc3aa299d113b69b90340ca4c7e019016d", + "0xfe7b61c4388f2615642f9ffb44279f31a98c0f0d2f3f37b5f77ba09a67c12737", + "0x864581a4e526055847c252f6169bc54b5a1615de8e1cb7e80c649315b04a9aab", + "0xb8b4c67301cf9d3e91ae59a0394c8085737358bde297c58688b48a9d33c04205", + "0xa1ee0d1c7d50d37f96505ed06b166722f47fdd784b71bb3d47539ae40be96262", + "0x63b2658609397ec6a9e9d9d0a5b318b79b1e39348606ca53e0f84f6466d3aad4", + "0x2211abc4f8bbd6784aa191805465b10520a6c505d6257063aa9b911d5781fb89", + "0xefed35d1327328deece22922f08d3c3931c80c1ea9a8bc719b8226f38823bb6d", + "0x64b862e2d5a6c24d569f3352b8524ebfecfd5a3205a3200ec78df72d79a66838", + "0x6da8edf169a9c78307258a723c1ac1d96db20a7131018efad16f0606683c0f07", + "0xbae1427beab8c3e71cea57e5f9cdd55bc278c6d6073ae2628f0d3efbf9894a42", + "0x389bbd1b3fa390e8d3339cf5b018ec64d9cfc02bbcb801acad0857fe377ed83b" ] }, "nodes": [ diff --git a/ethcore/res/ethereum/kovan.json b/ethcore/res/ethereum/kovan.json index ac86ebe7aa..22a1974d32 100644 --- a/ethcore/res/ethereum/kovan.json +++ b/ethcore/res/ethereum/kovan.json @@ -64,8 +64,8 @@ "gasLimit": "0x5B8D80" }, "hardcodedSync": { - "header": "f90247a03dc1f4ed47c057717131ce81535d06194d990be6969334e9b8034e0c875f9dffa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940010f94b296a852aaac52ea6c5ac72e03afd032da0fd1833e970c207ca16e1e74d937c9d8e01a1f719643fb25963028427295fc2cca00d9d5e376ebe3558b412402702d34a93256bb03a61df9f17ae234f0a70f95b20a0129c38f28acd251820f96305d217511a725a1fae1a434d77034bd7efef1f9f5ab901000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000080000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000090fffffffffffffffffffffffffffffffa839f3801837a1200834bb5f3845c7361249fde8302020a8f5061726974792d457468657265756d86312e33322e30826c6984171cd849b841d077cf579661ac8634ee865b5cc67918223aed686d6ba189624a6f6c0dfc5249418b25423e30e072a79d5377e01845d5234ff5e0b9b0207b1bf2515f805b47e300", - "totalDifficulty": "3500253997070921577369506418666760871805116639", + "header": "f90247a0d0c0f490e8e5045fa96fd77ce45ed983900feaab964b2b0ba3a2d3a6b5e0f842a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d493479400d6cc1ba9cf89bd2e58009741f4f7325badc0eda0c91e59c81193c4fead4f64ecaa349e97056409dfbb787772ea3c1e55e7582b2ea08be1332f5e7eac286c7e5e5ccf3760e47f4a919548c15e748ad4351bb8405f9aa054e0533aa3433f4d07afa226230c867fc1e2844b5f49b25aba8df17630d9f8c8b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000090fffffffffffffffffffffffffffffffe83a26801837a12008306f78d845c9da0b09fde830203088f5061726974792d457468657265756d86312e33332e30827769841727682cb841d6db93a25c84287603ee26e48db0dd301753840cc7283d411d3febd0485e02b2520086bebfb3aec1ab69403f45f0d59249bf0d458f33aa268dc4badefc73c8d300", + "totalDifficulty": "3571337622391237938633151520660827524104528124", "CHTs": [ "0xdb9557458495268ddd69409fc1f66631ed5ff9bf6c479be6eabe5d83a460acac", "0xd413800c22172be6e0b7a36348c90098955991f119ddad32c5b928e8db4deb02", @@ -5161,7 +5161,109 @@ "0x7ba1756f8fa6637d8cb6cc588a679f6366827bc2044865744837c63e8a5aadcc", "0xfc1a94a88f1e52bb78a0862eea4b996444f0264a3b301c1a31e59744d0216de8", "0x79472bc4de84a0c430f15bcf8569486cddd2de985409ceb8e48abec8aa3e3fe7", - "0x02bc578dcc715304c651a43d8dcb4a761d2073a93cca2c39da3ee513f0c6d415" + "0x02bc578dcc715304c651a43d8dcb4a761d2073a93cca2c39da3ee513f0c6d415", + "0xcf6175cfa60c20178241c18111d64f8837ec008751c5c333bee96c616d3cb6d1", + "0xd8281202c7b6da2a2541cd7f8d4270066f6546bec601e83647896ebdf0f2eb66", + "0xc4975ca8b2b71f61d2ba2825833df91096bd733301d54a3c7b6eca016ac14153", + "0xd01d6f14e93c8ba17a602378bce1c9bdb51373675109d6233c497b6c638a03a0", + "0x805057e19b7dd857ec014b4e6333bb60f48c02d29b128fe37a69f952df8ef16b", + "0x69c55bdbaf74bfa3d53ed32b79dd35ac2c24dd723a1c0bfd70871cefa4dbb8a8", + "0x523efe8059e6e8e2abd85d77d22123f97cbbd9864b4a3ac1fe0c0e4b8a7131eb", + "0xe5a4f129016bcfbd71913d1eff01cec924f9d130b8762c921d43fe5bbbbdbbd0", + "0x07f68773d16907348ac6e7c5be293ee1163ef41b91a2a8abb17a004c4796fb42", + "0x90742f88c71f9e689b6d2ca0236c48bba0e8ddeace5fa4d53a5af082055cfd73", + "0xaf7af6e9f695c4ca9e9a3c0229d94cbf02fcafbc4ed978a6b662862182308a72", + "0x0208eac99df5025cab13d9767a2ba3e42ba1eccb72cfa01d87e834d15eea3751", + "0xee9ff9384cef76b51a9d5b8eb12fd7e00ee7f8142f81bd68393e7fcf0eaef90a", + "0x4770986e657683d901d73df444836f11f169f94ac55ec81e4e19f2212052788c", + "0x9f9c16d009da6e8ee20d9d5f3bd7f1a77b853dfd19beef68d980fca6bce2b707", + "0x468efd7c8dad29cfff0e278fd950f89e2d5a57d6824c6c1a7a7659bd7e7c0ffe", + "0xd0391bd0a2c1fb2260d89bd5e519d4ef26b4945a7ad0c1b695687fe1b24698dd", + "0xdef9ee668e09f8769b2c706a8de426e06f0bd9c264e67bf0c0bb177b851cef23", + "0x10c5b79048e611c6e65f92dd54754753e595cd8f8f0f1005d7a647fa59deeb78", + "0x4ce6d5812d2565237a9b018ed6ec386cf3e9fe1f2f429605288f2ef744c5a940", + "0xbbacf6662d816d5eb14fc1271c1a3404de94e12c175545bc8273c231c280b789", + "0xb216fd154d3726f16907ae571728d92ae2199872f180e4cd6be3b53a8dd43ae0", + "0x2b76e6685604c69f29399451c66ce053ae033ab011eb52c97c112df968e37232", + "0xf93b8076ce0dc6742196d2c9af501fad39f570cd927e8fe3b8dac4127a20a6a4", + "0x35027cc654f998af75b8379fac0a9d51703f058b518880e25e658151619f1611", + "0x3e7f59319228d40e5e07c06b696ad6478237ed0c8a71cff418ac259c6b5579e4", + "0x7295e21fccabab1545c1e64a57f0401e62689057ab4fef26f70c8d02b63867ab", + "0xb06bcf07fe1345c41ba16df213d699e2e185ef2fd3b5e19b194459d0b7baffc1", + "0x1b13d005a29e35fff33373e2d8abc81805a85e7970b48dca8fd605069c8a0d85", + "0x90a5a61ce554bb73253d7f62c78b1764f03fb0fd8f65b6aae4f9e529acb1d991", + "0x1b1eccf7565339748947358caf473ba0cea743da2ed4790763d3ac8c402f261c", + "0xef9b05ae7ce93febce342336e40922e0884891da43aac06f3e9bbfc0aec688f9", + "0x11e1075b50de92e960d0d65e9b37b3cec81095f5afc2afccc6a9a8a325264049", + "0x128e6dba4205701f673dda9e980dc0c02f3c0c8cbc570f9a240257a261f81b39", + "0x6fd9d3eaffaeebd52ce93ac8fcd0f69b146e2c0b05218850de1c9218db8ecd8f", + "0xc47e3487ad63b7db773f413cd5302818061f168409c27ff2daba4579c0a4263f", + "0x0a55695d4a132063735f7319d3a90a2e0b83fd6ec6b6f9994068f928f68afe12", + "0x39403d84aa319edbb18e0313a61ae075ba9c5dae40b9850eccbfc3e09e6b27a7", + "0x79ba98eede4cd0b7031472baacab20df85c704a26e4cfaa6e01e3d4a9d26ca39", + "0x219240759d36a317f269e4301256164cb3709628e0ba07e90a6bedd664cea059", + "0xec793562f8498937f270c6ae5490ab8f2ad21a20510699dc4d7d4d0139efeb3b", + "0x0a3e9c209903b906013c8876cb4292e6ccc8b76dbf4af2ca25d8260f9f8e7c22", + "0x0eb347bb16d897b4909dcaf31a0009e198cd197f722075c112fe29bc9f017f20", + "0xac1e6a97c51f5051dc8f3a1fa33c1071e29aff3d7040972dbb5481ba215010b3", + "0x7e1be83ac51c7e68110c6984da43885af18bc9fe988a57ada7b2379d0a122563", + "0xdb01b1cb4084a43c9a57bf8a65a58245edee5bbbdcf0573a3626e9290b4a2e6a", + "0x6c97523c89da4c9325fe17d2e879bbd6b4693f3e6d807564de83ccf801e66737", + "0x7511c0b30bd4dfa6f9a4f38793ee11e2a616de5d9d2212024c0875052ef2559e", + "0x6faa338fd78b41f2ecb623d578520b373e0c74caafce95938161dbd95edb0e24", + "0x0622bf3e00fae0e244d138f73d16035cd05aa9e0c4c16d20b36adad77951c2d4", + "0x72e1ed876e0bcdbdd200dbd55a9d7e8248a4c7ca75588681b61f6f76eb980060", + "0x981a052ee33c36c52fc33598c2563ff3698e1efd130090658cb457bb814ecff8", + "0x2b732d67211042b340c1bc49682518bb00dfcaebd0cfe861b5d38df9c127ed64", + "0xfcba6702d24950030403f872be646d058039d735cf297fcedb5daa255d47ce72", + "0xba3bdc1bd47ab43c2d39ee67a512f306e987b577166d7037705a1fda772bbeec", + "0xa39705f9efc0c0b9051742b705dab9fed7a08b3a00ff15583e15de95a9933356", + "0x551658242a3237fda7b61eae6dc40f368ffbbe3e7f292bf1b3d291d1f21a631d", + "0x631783a116fb5af727d2617276bf310e9f018e1f072d9f3d5432773ec29a193a", + "0x7d2bee7cbf5aa7a5247f047b1147f55380e035a5ff1ce958037d96a539fada37", + "0xfbe38f5210d9fc7c3474be4ff932d1ca393a565426f5d1443537e962beabbbca", + "0xfc9b71f941a0a9dafd6356c4a42c369f22144b43f32f5d50fe3d4c1cf3ee3cda", + "0xa4eb11bb0a0e210af085dc446766f4bb0d19dfec04e9d5d0d2c0ee390597906d", + "0x42e8e9e3d4d6de275146369fa7c010a10979793276a4406bbfd77a543809e762", + "0xb2fef38ac3b58b498cdad7d195bdb3604ca0cfc0ca3c7282163636d3022def43", + "0x923269e9a526ddaa446a2e7acaea5189726ff77e664c20a341f6ad2f6b810d5f", + "0x02e876ba6df7c9ddd7a9ad9bbc15f5918b096e299260fc85a8c7ebaa71d7dde5", + "0x660442f393884c6c4b879168ab3c80c57318c6c62a67ba8df3788edf9ad7303f", + "0x37f7ab248fded056ae5ecde87bf51c1f4baea786fc7c9f5b6760ad13c90659ac", + "0x36fda244e2896e45d3a8a9ed67d7c09a2974c75944a7233f571928a497b55f8c", + "0x4914478536196c3c813fe151cdf37097c6dc9e8d5c0cf9b370fe7567905fc4be", + "0xcedb88613a1d6fbc24909963911efbc5ff56ba09377350b5e824123b50d1a910", + "0x236fe31e63e426111507b2f972547255bd12c6f5df9079953a8b8346179bba57", + "0x2f08e1b0ad4024814428237b4f0e7ca5a83257d25a1cb97f42db14307113916f", + "0x41e45a3a2239551e8cb9598fb855f3d8922386c2e004426e294d111a94856b92", + "0xd5d385b54446abfa8c78950aacae52edede3a7a65d9c7515043431a4498e4f85", + "0xf2d2eb5169760d81d16067b9453979783a2feea91dfa253baa3183f2419478b0", + "0xa5aac8d064c4f4cdfdd2c7f7326c1e0260aeb44be48b391616eb01fc6d30c95e", + "0xb2a298085b0a082fc1781aad1abd263e9cc2c5eeeaa70acd88e8bdfbc0be7d15", + "0xe2d19c438ddb9b96e77a9bc70566f49021bb6444569eea3cd039ecab4d61f73a", + "0xa8549fc117d3faba2ca53efb94bbb37e9cb82bed8273e408da5ed47f5df7aab4", + "0x161c898240dd6e0a0a1f1f5948c652a796bb6586995783a35e7ed6c3c02fb82b", + "0x57214b17853934f1a548a7e9942849a04b9220f5b783a9d2be7395108bdc12e7", + "0x7902ef6c69f5d0a3de1e45d8b46aebcf35aa87cc5f4644186f1c34614a429175", + "0xc290a119f495ff04f406c28461e2de50abf92743b7fdd680048e491044fc59b7", + "0x09bf0fa4aa8b65dcc8f937e46287eb2585c85c587b425f8a0af69d02948f35d9", + "0xff20130699483dee0caacca392c2ad58738f61ea2443869616a3bf006e0cd1ad", + "0x937c629f7307f7411a4b1cc5b92f6a1f1f42f716463f15c449c681d16525996f", + "0x7cd028f48f117d8da3d537f0bb0fb0c832d3111d16fc116bd06454ddd513a095", + "0x4bf15bb783cf917375b5494e00ce003d8da01c65fcbac40d44e62a6172f2cca8", + "0xaff5ceacf024e9146631c772e4e87f223a241e789c88ae083da716c9aa47b860", + "0x68c1db9a727678d2018ec98d0bbc369faec2fb1283b479abd5d6f2b1b04036aa", + "0xe70962a032b4cb81910cea9911eef50ede2eeaa6f487f1e9f8fbf88f133249b1", + "0x1bc2bd4440a1412fbf582d167e0d08629ad2bfe0bc0dfaeb5eb7730a4baf007c", + "0x2d4cbafea30b01e466b41f6911deae979f4f5c82dcbdd76f711f7bf9300c23f4", + "0x252e39a51862ebaf28d9b38f9fb842c70b5bf0669ca008b4c83c542e5236a1af", + "0xba04c89c7ec2867d778f8632e7f51e11f06e56004520444ca922eabdab623473", + "0x74b8dc3bf589a6d9051fbed9af3021e8fb775eab0f457cfd5d38b2ec8f88a24c", + "0x8c0a98cd1665f50b702b44e10dfbfaa70f08b65ede72e39306b1d31b75c07afb", + "0xa38c3526f5f6bce7e64a195cf8659160bc7318b8862ba206535626c338485c64", + "0x4ad34e3c6be8cac9be3fba22eb7e99d951baf5827df5ef921f2b01d63862e116", + "0x596670c729beb030c8756bf2ec6c884f9b4edc433a94f5dc5d4d337dbb712d76", + "0x39611d27f11938df810165987ee7edbe87cfb7e4068216cbb45848b4029f8419" ] }, "accounts": { diff --git a/ethcore/res/ethereum/morden.json b/ethcore/res/ethereum/morden.json index f388baa179..e626152adc 100644 --- a/ethcore/res/ethereum/morden.json +++ b/ethcore/res/ethereum/morden.json @@ -69,5 +69,1951 @@ "0000000000000000000000000000000000000003": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } }, "0000000000000000000000000000000000000004": { "balance": "1", "nonce": "1048576", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } }, "102e61f5d8f9bc71d0ad4a084df4e65e05ce0e1c": { "balance": "1606938044258990275541962092341162602522202993782792835301376", "nonce": "1048576" } + }, + "hardcodedSync": { + "header": "f901faa0542ffdc248bf2c071b74d84e73ae9a2b8bd11bd6d202430d0f204cd88cb3aa76a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d493479497b4ec458abf3a8f88a206ca43c8d9a6934f6f11a06d11abe2a71059fa61264bbbe9a34b1f5be8fb4ada52a705637f8f110236f1dfa056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000833b7d7e833ca0018347e7c480845c9d6a1480a0845d9ab9164c875ceece68e674bd2369b9f9eb7916ea1e23f439f2b3a6904939880dc60854f15ab6a3", + "totalDifficulty": "557317515715884", + "CHTs": [ + "0xc807dd41b69a19ac6c380c2a0b4823c3878ed073b43cd978e2a77a64df7f3ae2", + "0xe5f9137adaf6d6d8566cf206c012248bf24591578436d990789adebbbf57cbad", + "0x23a3c9bcf4eedd6c0c515aec8c30cf1cf769c829a30ea31d267b07b5e199a7f2", + "0x6ba3c43460794f494efd505fea3a2e519513f199ea9148c9e2d106ce42041128", + "0xa9266cf07f4bc9cc436829752e4ff0581d7a6f811d136d0a43a213eadafd6213", + "0x9f9668d12083d72e1309f0ea9643f721ad8363464ea8b82c97a10f46f455c281", + "0xe65d639f27dc2a1c3942e6685618699f1d6bc880fe027887f62028a6baf4aae9", + "0x102089b9a2c7a1d7954cb550403ec61da257fdc244d43c10d3ae0071dd9a8b8d", + "0x05b953b7920f1ab12d8da8dc4b885ea506bf6de0a1da696415c7e181c9b4b4ee", + "0x811a33e154c19dc735c6a88f59860b33f0022d453d8073ab50437368eaf95654", + "0x33123d65bf01fae8cd8ee499737deb366bf22805e3ebf0bd085bf2e8a6839676", + "0xb5f7aed6d5a438494df68b4e408fdc11beb8aeaa116241d08ec59a0675f547f7", + "0xa342b40b1d75f398d9973a5233e5073a8d0ed46c3ce56390d37abf3856716c58", + "0xf596fe04fa052d40c3f163e895a271b84d33f5433ae3756d0eb3c4e3f736afec", + "0xbf740fe291640e5efa787aaf5f6e5c1e785549f64e82fc63a5f286c71fa2416c", + "0x40800be2869e05982f1bcb20e7e69e671b9983201993c731d9719446384dc8a9", + "0xa2e55c78e611d6f8b66090b7b5d503624a3283c3ec8d2c44f0f303fa60565371", + "0x259a40837fa15a1ff862c673efe47e8cc6d3357d629a3ed541877ca53a23df4c", + "0x8720da23454e67059c90d4d17e5f593c81c7f39fd03fab1450a6f37d7422f3f8", + "0x0ce848313e625f8dc5c47cfb6a724d2c1a31d93c73a50e249fc05cb8e9ed037b", + "0xfcfe0c8034e349e97371f7212868b2accb215c5af01588951404cf72eb22baf7", + "0xe755886383ea0cc4d91adf37a307bf4e1cda6dac9beae697016799df4c555c25", + "0x163968f7d35ac07bab096aeee286446b69a4f73d5adb3f86e0159f0b1ea96697", + "0x4a470e0bbf6eb96388d6e737ae12acfca3e43189a83dba465e58ebe9149eeaaf", + "0x1888c221c04b7aa45a9861f1de385830f6a571e1582c10ce77974fad24e81212", + "0x854e426e6cbaa0ff1607fd5fbc0a66359886e2dbaea606440e1d914f460f5e99", + "0xafe3c2e3d8dd08fbcacc2e4111dcd5673a7fede0e4dceac6b0e31947cf425932", + "0xef40d19cc969283d769845f483c76cdacfb70d9d546281d2febef109fe4a844b", + "0x8729785f16e26626dea3a212059bfceb66f0d5e6a188888013817bfb246cc152", + "0xa66ec51b44a6b7f8fc6b2347e1f4ef93a7edf1cec752693e237e3c6ed853a4bc", + "0xfb2720906e0da3d302881963289954200c6dd2578800c712ef2db702fb2b1810", + "0x030ddc8f72c3070b7c7303c71138bf4fb1b638b1ff54aea16a304682bbbf5267", + "0x7892407bc680352974e4c64722e3be4d3a88dd73275d3176ab00e8b7bc427753", + "0x991e25dadfb80022c044cfcddc5bb814ccc6b7ba46efbee757236e467f8dfe57", + "0x37d1d97d1a440b6534d8e7f8997b3993e804a384b18db0fd1142fd2ddec9ff8a", + "0xccce382a99c1fa1062468b9a1f444854bddb36391536ad87a433c148bf908cee", + "0xfbc43e9f5a631c12c7fc73813be957dbdd2e91a33d8f6c928f026464e8a710ec", + "0x152c55912b4a751800117c2d628cda1ef651470d9236388c7974a6ef7653129d", + "0xacb187f272f5eeb3ee36d3f7d0f4b6f9fdc3f4cb701984ffd4023f9fcb2dc9ac", + "0x79b52e935e6838d3ab159aa7454c15431a63b09d554c6650c058c7c014ac6001", + "0xdf2a1ae101b560ba5e34118a748a28cc5241c9a51b5c8343c0e8912904b82774", + "0x2c1ace44b890710096696cf715851b77392229644ac8dd6a3497b46ec383dbbf", + "0xdd2da6958538e572ac83dfdeee1714650a5065ea1fafc0f431539ff38616491a", + "0x599c359830f0cdf99989cdca29e96263b9b760ff3c33be905f4257c2e5301bd1", + "0xf96202d560e1b2161bcaa5f315e5b1e2eca93dd3d8072b3ccabbc8135dd12e9b", + "0x7d93ec83e59fd401c711df9026bd72a87bf343d799e1282afde6aa1b1a43cefa", + "0xb5a859b110f68ea54b38e93ab8ac2f0345b7fd067b08aa51d67c154c80312ad3", + "0x7cefd82fbbbe8dacf4c55871368b8b5eec505f60883a85640242f4ac4c5deecb", + "0xedfdaf2bdd69df02c1e8dbadb65712e0504eee5e5ff3fc0f539469710dd5a5a1", + "0x8ff0e0e4855c0890d71ba87386aa3d5f6478212e19613cf05b6bd067f5a0adc4", + "0x7830f4ee53e26ca607905bb9c127d6915cd7534854270acf1decdd45bfc82c90", + "0x6eac559c95bca27833457ca73be5d93fae6f30b75bfcc53610fde590eb251805", + "0x624112cd83afb5f5078de2d1523f69beb9bd21f8646472d8c87e9b282bfb9463", + "0x0fcf00311346ece9b518b3946c71ab18b4e0068b58daacb60ae44f7b7f9c6159", + "0x580dfc57fe900b2621048d7d689ecae98a567645601449d7d7c703bfc3f93e47", + "0xa1558a82f05714aa7afc11e8d0b964d6087a4454dcc218f85a4d4c34f1adc2a2", + "0x2a95556e84c7524fd21e8e7807100f52ea278e25f43f16530d4c4a3d98434bff", + "0xc9cfbdce22901b6a2a2890883daa122501dab5d6fce92f527d699a1c6bb21e73", + "0xd1b86b1c3af0fa51d068ab86c59bfa33e564454b31afa8e4e38d71af50744b49", + "0x731468089781f91a8851f7765ed37939bf6a128e1ec1519182bad053d28e6335", + "0xbe15dc806e540e017226c5c70293005b4897efe5fa2fc250458c69158977053e", + "0x47b02ef97cfae1cebb39c9d586243583566f7a8c1a94a7e0cee03b9f69852397", + "0x630012d012d1401ccc0d0fb2e00b3cf5ecde470bffce52f93c55db24fc8aad50", + "0x462eb1e05f12c8509051c0a49a62eded4aaea9ac3e6971a1e938eb205db4e235", + "0x771bf93a1c5b137c4ac01300cbea8bd784eca03c19669eb107c2e6d52884bee4", + "0x118f4942e1a52a92e034c63fd99ff027e3669fc31967e8faaf6ea293e0b8709c", + "0x20db323c06beca205a373f294b05f299fb60861b7e86b61e20e298acba3fca65", + "0xce32378b733330dafce88de5b97c64ecefa43bdb0aa81b29b29bab6fe275650c", + "0xbbac315984167276c7116f7704589fed29fc34d63d188563ff7c8110bd6e97e1", + "0x5d40637104a9bb5524e2b3ef41d37e2634a2cf894732353a6fe04432c09bd762", + "0xb9a69a32753eb0ecd5e259e64c3953533efb8b8fe164b973a16c77a9e6146114", + "0x4aa4df7a0849f424c5975c28fa0b5b449eca26022a7d6fe65620c1d93bec9820", + "0xf099fcf9f8108254dd60531362341e641c4c150a3848373c82932bc1d51925b2", + "0xc603041029c1d86644ad750208997d2c72c061fac7fa4af0bce0701275295a0e", + "0x15d16b41757f81830c23faf58c499cd09497a474f46c5ae511aeb45aa48bdc3f", + "0x964a3f4efeab9fcf290566afa41e210276c1db10a0b1155f4615974e575c09de", + "0xe5fc4556103e0aac0047784ad3eb75c4c4c5561834b3e60692828c1f98d4253b", + "0x46927e7b6a30ccf6abc8f1ac967743dad7af1b6002cb408ec04f92d1666dd5e8", + "0xac4ef88238077f309c4d487f8b7347b768074b54bdc32b9d86dc4d884fdc3bac", + "0x41116a0be7226adf1968baaa3b5b58267eb228019cad151397ab0bf98954109d", + "0x7e7e9d375928de3025a59d90da01d7e0225a9cfd9296f219ac25218596725acf", + "0xb7a35780b22190c0c17e43e8287440e4975d380421160e75fea99cceae2330c5", + "0xe38c7f40a3a760425d6f27183c4ce827313503a126d0a6385c5e41e83b3dba2c", + "0xe431d175d47cd897c227a1657cdc89811984f95b94993bb61ec54d9c7b23f8d5", + "0x4f47b0e4c5443c11a7862ce98367cadd11b042a4991c9f1bbda88d29f3ac8569", + "0x19e6f17eb87ca400b3aa7a5f3b28d8dd0062b858fdcd9ffaaed1bcad9e378e51", + "0xd1144f5c397c11ce4bada4394881046a5be59d2160d1e6c4ad231b7582fce79c", + "0x01b05affa98baf640abf73b370a2730758f492eb2e639134523ebb4b0d4d9c27", + "0x009ee372593740561b641c5d8a84b0e65d88677c85623b4d331b87cdc9b95394", + "0xe0869946fe60ec13ad38d8d20b8e3a4cae09eeb023aeec2ccea4635a92359cdb", + "0x1f5a36ce048ca23f44ccc485ef9497e5c990c3e9db0ce4dd5a7b8ae334629504", + "0xbee0980f08ce37a634a4423cda8d50c4cd1fbacc093565c14e3a24a35632ed2e", + "0xac61b0e93d7fc80f1fd21b13d27825e44373c413eea519b57ecf203c0f028bc5", + "0x53a90ce7fa7dbedbc8e840fe2d405415539aff25fca430314736e50c6f9ee984", + "0x81064e012d19da85422f9fc09cf9bf1e716dfccc51286974d25b2f8ab6d31fd3", + "0x66fb9aebbb257df30adfdf66aa63c7e3c1daea27d4ef563d97743da88863a86e", + "0x5a7b6908f93ef5c779a4ece2232f84a4803359b40c851f53cc949b8ccca22c8c", + "0x5ca0093f965d120ede845e1c53e9eea3e0aba705fe3351245250bdabec550aca", + "0xfccb96ec021b946ab6d957df39288e58bd7d0f965f731ed9ddc634134d831aea", + "0x1ac0a3e2bde62f28e81edcb8586677ecad77108ac3186dc9ac695a1ece429e2f", + "0x2baec4e11e355f77599f6b5e51d43cd21ada652cc38147073d246a54b8c74be5", + "0x349f045d2d0647b7728c48de3ec8c137b01e5ec2180c97633fce75665847032f", + "0x5f072dbdff5e4fa6525fd7cba56fb3f614bb67b5f0d3307de35d19ff9d22ee94", + "0x1117e7dd45312ad180d28c76c40385397a27d6572c34dbbd6a4f04918e6370e1", + "0x3ed396cc8c99b9784f21688ee6d960330b72dcc4014f920bcea28417b9e2b231", + "0x4c654a1dcbc0763b6e4ea6024e81fd7393bf4b921661fee3f2ec9080d7960b0a", + "0x6750fec450fee7f6b710db501098f7da59fe76e644940700f511648ba6580594", + "0xa539a7d3f460dda620fd08fe11b15bd1d7f93d5987fd05166eea95bb133608a1", + "0x9cce533ac9adf70b3c5de99f6d4c25b7493fc62ed4e086bc0cac5e78ae6b434e", + "0x196e7a933f28e4f70229e702198ee364ac095877bc255be915e468af637b2cd8", + "0x64adc83833fd478f41ec97f20691e6e0dfe66994e9341710a7ea6deb66739268", + "0x48c8fadb1a46fdf9f10a5ca6d8c1156879007d39dd4621eef2a3af50a971cabb", + "0x19c0b693193def13b28111fcf1fb06fc1a1268b40b49124fb606e69b497952de", + "0x6ffccde7aa6d1987680db26332077859cc42713d7b479b390601e9d382ed4970", + "0x4685c98bf99101061453e23a4994157ebf86780d73c65325f1f053471f4658ba", + "0xa8c0250d3c708b22c01bd468052afe784628d8fa39c12836a872d144f03d500e", + "0x60c76dd584982a3f05b715a6c90f9c1e9ef46d2827e97940e1b67feb011bd5cc", + "0x0f5a92f5573ce6f4be3ae58ee5e9131cc45f4794480a4974ee80ea50ea2a2dae", + "0x2495bf976e3877303dc3647cdd2ae47cba05b82a6069b7721a6e6a731054315a", + "0x16a120253b7c4f074bbfc659ad65af3534aa86217e133f2678fa503485b61fe2", + "0x85181fbf375026def264b1ff000dcdfbd487be6d18aae3272f181d92c9f0337c", + "0x3c7181cf51f5e05aa1f4642e3b51811a94f1cf4a48f2ca661c15bf21937a0f91", + "0xf65a4c993a941a28ee135e56aff76a9c1a65cd90b2e3bea8c52b97e322b2c6a3", + "0x2650635481a5ec0b92d46fccbc2b959759eb1506642244570d34d279720cf950", + "0xcf0415f4a01e2dc759b8c4df61c20d9b61e001326b9964cc08a24d1bcaba79a9", + "0x497626c7a99d2383832c282bb9276f9458989bb51dd2cb8beab19069f145325a", + "0x258105ceab92adcf7e1071085f4881963cc0cf98c28b5da174813e80b564acac", + "0xfc8e8f4d831f9176b13e214af17977495105128e55bd58886cb6b699ab0b82e8", + "0xf1fe70de2aa4bf8832839027edc5273b4e1c9b68557bc64b9dd41639b76f6da9", + "0x67b2609150cab4fdc60735dfd251f58e0ab4c37f4c5e06b742088b0299bbaef1", + "0x991be3047b87a9c7df5d14c8b994e225c18967ffd8f165fa0f11701ec9893bb5", + "0xa55540cd2b397abcd88733896795d3f36bbfdd1024d18ea7d08f5c29713de23b", + "0xc72955a6debdbb088a6588a5613bd2e329612e366ffbefb246244563c78e3a13", + "0xf2e8bf5f11b5d144fcb2e9c26dd1c4b7acbfaf7ea9221a4db35361275bc02d78", + "0xb61d47b97a001e07a63212bb473fa8486d1da002ee774d30fa03a704f575984b", + "0x373146b0da2d2269aefc099d0e1ad48acb1dfa018af540433abe1785fb84ad7a", + "0x55b5675e4a7418ef176fc57e339bbd438a73e9d07496ee3044aeb9c55001b176", + "0x758af96b4ba6fb256a7f30378dc0d46ca067e3e7cdab7ea3e974551d5b9aa2df", + "0xb37b1858153b6d2d2f914625067dee98501b768641e30f12e4596fb0a6603093", + "0xedffe2510bc146b7d1fbbb226b9fd3370f6b711b1cffc1f6951485be80ec2246", + "0x19985ecc6a8750b3326248776c85a4270e6d125718eab5d8d988a2b7c75606cc", + "0x48b5d00c0063db48b907c2a03ee9f33015c7c07ccc845caa7a158899b358b85d", + "0x99d95d31ec4d06281f0b08173851fe4ab50b5c787f2e6f9ce20466cb7121b31b", + "0xcc104b8bab53ee3753bace59a4ef59775e3665af65c728b301ca3fa5befcc1b5", + "0xa852c92b55f55c16a99f0d110d4ea7451a172a3be46745ab7d8fbc5eee9b9283", + "0x9b2b3660afa61c4e56a25b8cfca058102c2f2b16e97f9e26e80fe61d5af7fb8e", + "0xee87d114b2af91345deea4ee759c989e854b5456fc5b1c11ff4cfea40192f0de", + "0xdf865eb8ff849b25b12ad4aa19964baefdce7945ec032da2e3c1705a53f020d0", + "0xc367c8e3f196b16d93ac86459deda6ee469846072f2ea72e53c84f152d576ccc", + "0x60ce704c4addb76ddce1e3d81476e98e11bf2d2ef46087eda113d7e6edbd8f55", + "0x18c87d7573c19dc3f66dc3c9756c40573e66e59d15afa69b007fc51bdf0d357e", + "0x0b5b583d706437fb2cc549c39c802852cec9c50acaaff8c9151a20a6ca8d2ef0", + "0x0014b94a1acf7461b89b0506f30c26ebda6d319e5a6ee63751d320b3f4affcf5", + "0xb6ac380ff03a0a66a152437ed43434fa786d6d3c22335852f806f3943c3fe132", + "0xea8da8fed31e69e2698dc928b67b5353d35525f25dce1f6ae45865b9ce90169b", + "0xfe9e5bbdd55aff1c660ac89c54fcc0547abbd671b210ccf4af31b70404820884", + "0x7347c74c6be6312e284904e5b60115d5ff48a032777e91423d5356aa9d415a9c", + "0xadc1b5c371a79c723166c3ddae708b9eb788bfa6d04794bfab5553b43153c38a", + "0x32f150c20cc07e1ef70f305a3270f351bae9dc13b6e0d67c661de5412cf0db0e", + "0xd914de07ff853dbdaee5231be517ab681ed340e552458d640815c0e44da377aa", + "0x5a01f086ca42b793754187d98dfb333996a649852e51b48ba0eab1716fa6f224", + "0xe5ad5f6ddac1eb411bfb05d2ccd41d3d1743ad1c9cbb96738a9979399ee1dbd2", + "0x574517aadfc912986e188b0ff0818312fe9f016007f4a30759a92fdfa069a6ab", + "0xc46db2db2552e53f2fa6a169ce803bb18172cf20d5a36b872a5c4d9963c7d42b", + "0x8ad27ac3db4da1eac8d6415b5aebe303cfcd681950269f0d1ce57215788cfe23", + "0x2aa7a60b25904d1e968f0dbeab510c06355b052b80872ab07cc58d809b58ad15", + "0x3031132b43c9ff4b2c96dcf7c04b31d18b6e8bc2e0cba24e8fd786b02aa00fc5", + "0xe1fde8dc15e887c6423dc4b6ce04d6e18a65831b073836a921dfc04ee016b299", + "0x5dbad0a396f6cd16ada2369dc2d08ab6af60b7da48fb0f6c320a566927745f3b", + "0x4d5d4913791fb3d819ad4c45e9f0ecbe062d0198e25bc6b20bc695e931d35d86", + "0x8825cb707e721a61c4bfe7f80a83b2a734d8406146b11ffed638259da5f91dce", + "0x6c686743164839f169f94ae4c7f80298df5b9eefa955cd6615def97b5fe2375d", + "0x5afee77d12298cd027840f0c1a26ed057f6af4192c19eefc6df965cf502788c6", + "0xda9312700594f18fd5dfbc2782fb440d3b79073b31b58f85275aa907b25e0b98", + "0x94eb93407bea97e074f639256839e2b1e955fc36b1fad232b19b278dc89006c5", + "0x81f48cf3fd6183fdf5e109c5818392c8b23ec98cf22a8b330cec22802950bafb", + "0x7ba2755d9dd57bfa22feb05fb10ebd1a887d016d660083eeab1c447f5d2aaea4", + "0x770be40b4c51529a27ed6e34e4d7caa52e1cc4e645eef2a5597b566972eef290", + "0x4dd8f1711f834aa709485ea0be3f948cf4a32ac4157cd217262266ee282083eb", + "0x76d2d40a7ddf60cbcd63154570fef14ef41f60b6400347cd9e66f2be51fadcaf", + "0x2bb51be5bd7fe41a05fa9a719aeb4b26f0e624b5ca5e874723c88f8af34a8448", + "0xa62d0bdefa2428c6347e1575029824b1e6c985a5a8496d2b862850bfb038b55c", + "0x4afd8ffc47fa73d5f34752278974358d1979c62dd4d0ccffc65aa16a3a748764", + "0xdc2cd7b80144147d26f66e44a03b3fd81f88d8c92c967b056b12ed54a09c1bc4", + "0x2e08104188c24e988c719984149d16dc4aa90bac4339cb4c3390f6a7040bd122", + "0x5957803ea74ae2f332137a7283c87c9412e66ea0ac9f6d3512ece8761933d4ed", + "0x66ea33306be78fc4cac257e19ba5856ea60e171f359d2611916bb6c1a1e8f01d", + "0x6f1b23cb0739caac8cf2e9bb61a2c1d390f6032b8fd2cfd229def9319856703f", + "0xfac23cca5ffe9719b9e60549a88da5a2accbaf1a8848184882b2ce94f66ffde1", + "0xe8f6f317143515b3fee7802be18866e8b33e8939f0c4899ac69c84dd484168cc", + "0x450bda8ac1c25a5e864e7a4dd3c0bf7ef9b4672b7bd886b4449dd6a9c2520d5d", + "0xe54ee7a1a9f089c66895c681a6876187dc3995e2299e17112a6d60295e1c8812", + "0x23d7c3d49ebb33312168eefb03ffe680a6eb969b719c573bcbca5ace4fadd182", + "0x961abd32c2fb7fde7054ee5232cbd485de5f83c427b36802f27b2efad7817d7b", + "0x98d83a56dfbf64cfffbdf1d631d0df7a4d2036a629d36794f9bbfeb106d94b09", + "0x7e06ea4d5059d55dfe9df764004261f907d08ce4043e6af73f09561974d57169", + "0xdb208e24e9f6193ca94486801ab570f7cbf8844803609ba03f7c4524aa92a38c", + "0x663f20eacbe6847073b04e7b2d98e820bd85cf29370d71c8c3573d0764360861", + "0x7bb39b75c462f7812f1a458dd06db76362bfd10d27425eec78a88228a48f1805", + "0xcf07ca736e96ab42264abc426229019165a3ee4ce8eeb2558ff8a086aec30918", + "0xafdc6af1dc2f93556a4aad36d0695dc2e1ec84d5dfe928c66d55df7270d5be4b", + "0x4f9172ef6b6fb4fc08c8b4878bda85bc58ed557b18aa3a3aaae449c773c1bf04", + "0x81ffe0561836f05fabf77b79e2aed4941d90d0910451c3863caa5ff3451b941a", + "0x112490bb941dcdc267ef27e3dcac89fe2690947575df1e53657577af72e6fead", + "0xde4a0bc4ded2a7d6a181ecdd9cf064858293bc313a84c2b33f51d42d7fa9d96c", + "0x25364f970061fce0d3b481cb97fd386a6c6e7b978e40015cc8357cb4b3e6f89c", + "0x524eca86148baee8391217d99caa2a644e5aaee2591fb90962ce2a34e7bbab36", + "0x56e971166db8d020b247c33a5ad59f713e1241808a2441c47ebd6bf5189f01a7", + "0x13e761f3f512358b4963547418ccec496b1205347cd3ebe2a510ab18f7cf2115", + "0x45bc998da3b99baebae0fcf5703f1ef5884fa0d049bafd51d1a491a762c80193", + "0x6727277814838b616dc4e78831cfefa4b9ff0026d2e7f52a33a8e7c99b5e0846", + "0x216e20d230f00e5b2c788f6073bb68c4a0afe5291d833350dc555259a8f37e0f", + "0xdf1cc61ea687ed6bf1bd576899003f08a13cc7b5e5ccfe08649887f866888973", + "0x9301d182de849055c299983a7c99a59166460e37637fc227ee038380dca42680", + "0xdb0fd7bc019418c8426879d453f6e72c38305091cb7306a8f503c6461b72aeeb", + "0x4a8183ad7c2a0301b5ea7c6554476e9d7747dd8931330b8b7841394b8178018e", + "0xe1014a500104e29335b7d5a423cf2504b6d2e4fb313021ef8d4051d07f612cff", + "0x823de414bae4688460c5697d22d3b95a882b74c29a14f0565c54ec61e1449b69", + "0x80f8e29216dffab2e4350de36925b60895cdb6968e497db432e12026d6cd56e9", + "0x900673ec8035f93ad51b3ae2e3ebb26d09c50a6a7f5436fc95e5ebfa6ad16d37", + "0x7073bb4f9dfa46161d314a87a6d77c661ff1bbb507fbf4030a461625fba06d32", + "0x397feec1f80c15e2364c776d69d78fcbca750bd19fb4c30cfcdc1b361caa659c", + "0xa881765daf0b5dbf10c34832cdbad13f5cacb9812514241b443d26dfba8bc448", + "0x9e0b130bed0a59e804c4c380665757ffcd0ee6e300a1b17639afd55f6cde9e16", + "0xa3e0f7e5e174fff98c24d3f31ecff842443178ca09234029bd5d0549694bb4f1", + "0x887201dd3dda8405c4a29fc49a3ba22a3ee26f227b4a8079e7c839dcb014cadb", + "0x20604a57bf1bcaa1ba7885135efde3fb4e8b118c85c6448a2f9fbddab44bdfae", + "0x4f9a6712963d57774c919b82b8ba48026dc61c01b94b77668829b5ccde82f2ec", + "0xd9e91f925e3eb83f8361c37e03aa0aa60641e5a5f9b01f92fcfab199b6493ddb", + "0x339bfe6603d8e2f0bf2c8fa925ed97a41f589653268aab0f494b79fb5092562d", + "0x2e927b1510753f5a83d707cf89d3b62e1e5ef7433d4e0b194863ff27125861e7", + "0xb177f311494d3d52e4161f072d24ede73d0c18256ac43a8ee5db30c525245fad", + "0xf873b085f8a42bdf1508b478aea9106cdb4f27f347ec997c4cdd5664c35e0e78", + "0xd80fd167784537b68ff33e2e6423b6b9647d82af112a5299c21da4d5b8e6d20d", + "0x34ca5d08b8d391778cac1d821fa1d6e94989ada35c2c52b691eeb0e8183d8552", + "0xbf80f2a0081854b4d2d0b91dcdd199741b92167dc0f5581cba76a7fe52b96150", + "0xdabf29b0fff0d327a111e17eec9160b178f6898650e45829c0c3afba6dcdbf02", + "0x025dfabea1e942dbafd9b0ad5f0b6982fb52315acfcf1270141f924575124609", + "0xff960681061cb1590f38af8a44b6597394687f780d3ce0afc9cf4203926cca6c", + "0x72ef02bcdbd5c43463104f0b2f22750556b0c73e862c89d1750baceae6e47d5f", + "0x1e4cad2aed7ee0951c21015d12919a51142ce902ec15b08f457ca5f962099b10", + "0x8aa5bb7bd5cf82a5696f523e16aeb4f9b48aa22d252b8338b403bd0b19b3de37", + "0x5762ad980b237f1a70fab5f6ce570f68eb1ba25caa87ef66e0f653b02e6bf808", + "0xb4121faa65ed4fc53f6f377e4da1a3c0f65848f0fc3363a6d66da7bcad514a30", + "0x67959aedb680f267d61dd647b88a6e177d5d84213f94ab4a071870a51df2d476", + "0x715647d7da67f6114f16ff0f6c9277a186cb4adcdbbe9e990a901118a84254ce", + "0x0cbdf473c4f3646c32f8c0002d7f993f7876f8c9086222d5a82c678eef60ce9c", + "0x551adbb1ce65205710014bf69a5a6bf5a98cc67f98e6df1efd22bcc1fa6d5d08", + "0x3bb1e51f43a2d13049d15492b8b78cea716f3d3f884d35ec65c72d24a6112c9d", + "0xbc91486359e3e62f22c39791afe7b2b4e09843d8a3ca301897684cb8d05988b8", + "0xb575d4642418c78e9f29f121e82886b23d7a061edd7bc6d762155a1bf34f552b", + "0x3c4b2299588786594bce7d50e060d26725182e92f8de40a86dc18a4434ac292b", + "0xafa9cd14e23ec071c5a22e2d0ff21656c8cabb710578d31acb6cc8e1e3315ded", + "0x9f6a198a59246aa15d3b0573cc080d0ed31f5f41e1c4efe16ada8656fcc94c46", + "0x4667eb3aea65369ebdbfea2683e172295d6b28436e4a5c7fbefebd8e15a01fe3", + "0x89ec767b3b1e41da68ad53f11c5755e61a18a0d07fdf6d7d53cca6849087f135", + "0x2046d27b46d093c35eef24698d1fffc5e7532007a2279f646c7bde034402af71", + "0x8629705c85e0d6060906ced37a5be8fb7b5ac351eca5a1934f9a084a47fe7420", + "0x42f465868c164eebdc6efd395ef39936aaa9e65e753850e6d2c2cde9837e1647", + "0x766d160e4d26eba8675552a90dff4f63ab598e1955bbe0ba1a5963f2a524b090", + "0xd05c5c90fa9bc35c43f2a6ab9f5cffa6f9bc2557f9019cc2e9c8aae269041fa5", + "0xc1a11fd05c80a1c9512ce10c89ede225405ac58321f63a9d1335261454dc0036", + "0x05092398d5beed07cf2744b91561083dab7040b09d3b3bf64d2b68ea0d4a817b", + "0x7fa4113fc5be42a29c84e7665fd3d18c06ecd482d645a7556e2f5bfce25754a4", + "0x06e59dcfd141ed7be88b602f2ebe9efa4091c80de4353500b21d597e26f22caa", + "0x03da4109fcc40e21edc20001b619da6184d64eddb1b3fc91d2a2ab6ecf74bab3", + "0x64ca02e31ca8df66861511a9a20f4297bda741972ffc636f6187fdf7f09fcf17", + "0x7c561edead7f97f117f9d7b556fb5dea0c4d8ec5bc79897328c4acfe069b73a3", + "0x64b7d9a23879a3fd86d561ccc911791c2f0d5616ef0c0cffd33ccde84c5b7da6", + "0x083fec3acb799318048eed14ed35a85cf45010c70e482fd99749ae25c1d0b782", + "0xe9529f45f938dd2576195d7d2798cca2eb5df1f31e0f72a4645393b641e77a1b", + "0x47f289d3467b967a0f8034098efb542172420e00cc29e1552cba377597916969", + "0xf4416df2dd30effcbeb3b80bd035a4236a0a5cb85eeebd861ff1d58d699eda50", + "0xa3fec237960e77871219fc08473c948ce4c0f9ac61ad80ea2bed7996f9507d69", + "0x6f3d597bbdc64c01d432bea19b720e72a705f843a5f1eb8330d7115b55e60f71", + "0xf67e1f41826290d68f6b0e900be97212ab334280112dd5e9f848db18ac3b9271", + "0xf0230633f08dca03a3647c4f6ed4f093df94d7fbe59b51609460a6b466837bf1", + "0x0484bc99cd286afe2d3e33f30f0e6887bdd3c314a5e81e844f21940ecfb1ff9b", + "0x8ce05e8d880ab3498a7de438eae5f6080b048b3e9b9f5a23c111c1db7ed9ed83", + "0x5a0109a7920d888d4cbb0431eb0b34ed1fa1e2681ede169ebc845252c4aebe14", + "0x7f28a7a93453c7aad30ef6b3b85f38ed40bfd4f7469a0a2f66055c60a3276281", + "0xf48b88a653ec5bc25bd78a14d038a517545f83b274a8b3cbf81102647e5482ba", + "0x55f6cdc8ac367916e81eaeb3e7255eba26a9c5495b6b1442ba30f1856f4ba85a", + "0x97120be21f046e4ebd57ceefd9f5e4583c33103017fadda5c05bc6e6f847eb14", + "0x8ce01af1b8f413b97c1aca65b18602bc48a84135b84c425ffade62535f6d177c", + "0x2ba45b460e684678f4e7605c4c912f2480ee9c2b17b7f75f018423951c2ce03f", + "0x932155dd74599a7896ee933838b632593175e350f8db1ee001c8c8b55d156630", + "0x9592f1f50289aa899f796c73c62583e758617ba66ce3ad2f5a1e3e4009ea0e44", + "0x68f2510fa98cb203caef5b5434d8ec4b5a63f7af17aee2eb83cedac637e162df", + "0x28dcca4c376df916bbed16d0e1d73c0568af5b08b4db3a86f108333638d61f76", + "0x980002c98d465e0011c438939c6a97b8b8182733da14ae198ea077a257f01eb2", + "0x7f280b8d3da47619e505063394c7e84beef045eca57c22a9ac71d2c0e4f9ff1a", + "0x6798250b993f3b9b83d30139a2d497f93fd825c1dc94fd57c10ef5c8818852c5", + "0xf5b978c4ff28deaf652b1ea3d7b7367cadc440baf440735a62b25adad4cb776e", + "0x74d37be2d2addd3839d9541111d72c98f09900305e891d94ea74879ac975851c", + "0xc77c2caf24dddd1204a856631c8dd2358e2c35bbd5732b53c1469fe91f975b82", + "0xcd6ab2ed9cb320e22fc345c58e23121efb68654810cee0dcadb265e06c3ff7bf", + "0x204b4e66ce38c8396f924799548aafc99d268694262207bb5fd5d45ebafdba17", + "0x3c67f0ee0d1125ee7ef93f0ac38bb14c490b4d85be9bedced7e4761cef9eb40d", + "0xdeef5f3116639ab746da2d6481b1d6ce75a80fcf9d495bcc863e4fadbb4d9de6", + "0x30570d79646a5cc3a81c10976b310892030d339b679b56f453d78bee39a70b7a", + "0x4c5faab35c94e41bc9e1d19984d184e396483d98ca546fd700abb5b332df9412", + "0x1f3e674220a9274313dd76dfe3a84777e04051a9dfb8d87799da979739561d18", + "0xf74999202a6e5120d01c97e857bd8aff0f36f1946b57f6b63e9766fda3b87724", + "0xae65d50f5ff120b96489289d97952d46a3697a00424b309bc3840dee2c9aecf6", + "0xfbda361f2512dc8e64dc15a3253c5242a2ff8cea29e435da91bcd3b2c6d979c8", + "0x7e9bd0797f03dc6d6e0c5d0493968883488efb507844ce749de8101de40c0b21", + "0xc60a8ba7bda89df7e936559df5067e6d1c7924962e6abfab40c708b0174d2264", + "0x8d5700d40e1f396af84d673852afe843090f573fe874b602cf5815fd011ee501", + "0xa05a1aa13f640a250df26e37d48ee70e5216f9224fbb541e6d4b2f4858c76f71", + "0x2ad9058a64d93621095801ce8272d2208e90e71a1a0b38dc24f71123fda8d8f6", + "0x40c96a4cc194d009b6609b154fbe63a833cc702dc2fff5b837e5eb6c88c7e005", + "0xa2c233b6964e1625a43ab70f1837543e5b3868dbc0fdb4732ecf8a4155d29d79", + "0xcd627d5278f9400834eb48b54f331a74734846497d86acc348e02a41d513b201", + "0xb34b79d45abf13ca51f88f7d7f144a260a44308390573eb2b8dd292b70b02e77", + "0xb8986ff28901817523ad8d796dadf9e5284257fb34709a98d5a3e5738dfe4379", + "0xb096d14fff72a2c833b112281f5f52ac5dbb4d48f2245570a81b85b140f40948", + "0x3818f5b06bc70eef065d7d481f80c97c6806c4207e600c63c663c1da210d8be9", + "0x7e3090a67933b2f83e6152fb75178f79e26f82ad07c4358ae463414a0b02780e", + "0x21aa5f90daa5ad68746f55e7f2510459ef32760867fece3f0224d65b3258afac", + "0x377b4d870eaf1d610e9eda269e4eb85382f527ac683e5ab53d04b3b0caef05fa", + "0xe6b2742b454708e3db3dbff642643e5159931a211a999ce57cc633e6c4d8da93", + "0x39ef67462038d2e25a9146727ead5ba921e9080e2c999a67ebce9d724893fae1", + "0xfc86a21f2f521f6d20e57bd3af58f42cab41add721580831a3b3bbf3680c0ccc", + "0xa2f54cdf34b1c869f5b248b3ef849859971a23eccbfb94ae8acf4370cec11924", + "0x8900fc71a6af6e496b5ac6ddd94fcf9a0656a342362019e971c44038e867d3e4", + "0xd1c988a3136c1521f70a547eb40c9ef40eac2750b940a951afed3dff7789590f", + "0x39e49739745830f5d91649e8032d30e22e45265ff92676f7d50c9a2335e21d84", + "0xcc964177439b593bcdfee8bab03bbedb9036de7b856e6b7d43c95e055f2a8f45", + "0x76e4575fdeee92408341b576d00ba3de2bdb964de3630ba0d494d79093d74536", + "0x3915002188b2d3e81ecebf0e1406148f0b20aba94e78a5b68969cf62b10ee7f9", + "0xf18f968a8f3f6f926b88be7b62230c9ecf6d44420971331886b7cc3c6bc9074b", + "0xe605ec94dd9a2e7e2c214a49f8eac960b12862a6aa435ddb8b4c74288b343c95", + "0xe6500a2b86b56f1acdd1012440835cba227ac7841550f30415f83b0cad5e6b16", + "0x0c20a4fbf0c1c766560016cb42ddb2f30aa6f841d8962e98dc98b723c8729be4", + "0xdef58db01c902fb676f8c515b708dc4762c3151fb9d80724eb1f3a02573071d0", + "0x44f0d489aa086c5b6cf6d3198cee057f60dfd6baac0529fa9b9b49e15d6209e2", + "0x91d2cf4797ca2c817d38db0ade3de064f66760d4f0604f90e209f5cf1b541977", + "0x873666cca9e593788f770f7cfa928755dc706647466b4cebd0362079a13b41e5", + "0x992ed0a28457f993bf57ada40110f6ee947fa127348ff6d211bba26a0fb3696c", + "0xfbcb1fd57adc08ee435b077e17be9b087df6d0e71bf39060a0f620955c1dd07f", + "0x544771081accc2219221cf353e97ccada6aef8aa94048981a7d060a37899a932", + "0x768ad3e04bec129183a33fc136476e1130d9b167177c6de4849613ec220083f0", + "0x44b0a9afa8de7b437c6c199f0fcbf0aaf377c1b847c9e8c64be7f14cb3792b56", + "0x10b9c4a0da33edf3db0b0aa33f2ed1d1bdc08ef6d7bfb8e910fe0a74ce809efe", + "0x6831f98b09864abbeb1177d50bdddf12acccc7abbbe1af173982814ac04275db", + "0x3e0466a93aefe563285ea1b7b6fff1c64b274161cdb5a37542e888a0219677e7", + "0x01315c879852a7492c6eaba9819f843f60456a8e2fde0a9ee2cc5192b3a00b66", + "0x0ac3011320ca4cde5af849ef12dc87f318315681ecc0f303c62f29fc556a2490", + "0x91fc1434251b487ff854c41c65dfc5ab63d309c0d88dea41af268e0d7cbf5df3", + "0x59d8dc5031c170ae9042d44f1d7a0b95669a15edbfadeebeed0f290c2afaceee", + "0xf636e4550a81c8f1b7e318f15c85cb57149fb4bfe3b879fd45f809fd57ee7db7", + "0x68f9a9de0600d560c7693bc0728741751bbae831bf358ffc195d7c304d9b280f", + "0x6c1358206b4fffb9716a634a5804bb4fb9331bd2c356d0064054a9263804a400", + "0xe9bbe71942123394e1615bc1935f0ea7a7079c708234581a708c38d304a1f783", + "0x41511870cd7271c3e3b1bfcb3fa043a4db8ed6510543e35dd8d4ab588017f4a4", + "0xe90ae56748f84a0885a7362993155b47b4d0c5532d7862c6fa422e28f09b32a1", + "0x37e43842eea4ac64b65d94b5fa1ad7a2d6d16f5941c43586913f574d5998ed7a", + "0x1117f28caf34809d49a0b1ef2f890680116b44c76c9aa27efa0357885dc1f2dc", + "0x699f428493f3cc759565072dc237c01636e283b808f95842e2be46e45a58f3dd", + "0xc91f3d366051b95a6a5b3290b501e7e435ea967cf39df1ac94e8769a87744f34", + "0xe28d8d82d81fb59b445e16df7493a74d1540b43ce61692605bf0d5287af9418f", + "0x667313aa96fd2950367a671e5ac01e685fcca1fb45f325510d38fb2c622ab67f", + "0x48860cdb6aaaa321d2accbb8f1e9769e70dd6d4c29c8baf490f4f0e23c40dd05", + "0x3dd9f9705c4d72c2d69c90cf2fd68c0aa5d0cedefd7dc012e9b7f2231f3a0786", + "0xc7aa31f7bccc6ce532d673132cd980d51b00cbb2768c9846bb60dd6ecfb584b6", + "0x403229d6b2a73c367262bb93d02de563ead582921fc763b8fdf495fada77bd55", + "0xffcd7f454695bd9f3b89a460b1c98de5ba3a989888e2331c885896e49c19f64e", + "0x5f9091b21020642ba4c1027902906f7e6246c42392ef333f00990d62ed8cd008", + "0x2d7c6d6bcb42dcbb9a7868cf3c3df439ec18f28ea232a7aee34feed6cba38027", + "0xed6ad62ff36c517deab2f8a266eeccfb74548baa3b61ce4e6b6577628a9a0732", + "0x4f301038bb42b93f85eef264ffc59e8695265cddb4084c38ad08d9260ed99681", + "0xbd54f734c93e0c71128409dde4a423543b080b3e16c49bf61fd967b56b22d53f", + "0xa32f3f4e4763b4567b2613bf15c6999789213849588e756bc6165bbc9e58d072", + "0xa9398a4b294a26fc9cdbbcac4c32dc3a57a88a5f269b41bd49a0e696728f57a9", + "0x757e6d5b5b128b028599ca3ce3cf637aca013140864a382704fbd73f91ef1059", + "0x9d35eeb49fbb88ab329141001d211dc074223f992f7faa25453b31ad1686fe23", + "0x32fc286389aafda1f3911062dbb61841ba8b8943d221d553a97276aec4b18221", + "0x45f5f7330f02814ec0a491feef7accf09dfe0d4acf6295799894f793efc5082a", + "0x1063c89a6cf98b0ff44456df9925bc3877e96c3fd1811940d94fc0ee554d108a", + "0x2dd74888cffb6d854fa2acfc2f9780ba82a3fd849b3031d0a48bda091ae787d7", + "0xfc589908c8b621b7aa96b4c5675ebdf61ba09a2758dcfa8a8ed741edc1c0b946", + "0xdf8bf0a37b01ee0e2ff7b9e6a1186ba41b6a3cc1f2dbc776664b86df5159e8bc", + "0xd880db83f1091fb064ebc0143110e0de9b2471be1bf09d033e73f586203c789c", + "0x5dac7c9f4a5925292ed8fe41fec20063bf7a08046fcf31c7fc782119ffe422cf", + "0xbf3bf656c9170df01e9ffc1192ffbd0976a68c325767a6006245e7b885523a72", + "0xf56e3fc84c71743bb8955503ab1b5ff18b673b90982127524d98ad734323840d", + "0x393141d2b434845ca225588e2d94e5b082b425b9e627ab4417f11dedc1a3e3f1", + "0x4685ebaf81be0f1d89eff701f49d8436fe2f451e557d5635d199aeebbdb0e2ff", + "0xe1cfe4c9836cba7d13abc522cac6ae5513c396d8b46c7f61f8aa17da54205060", + "0x39b272decd976241df1fe242a2cb2a98f73d9a40ee3fd445b6830752174c4718", + "0xb656eb1cd8bd2c42b6ebe6231bd6d78556ad2424603eaba3f4740e7497483078", + "0x14ffcbc3d98ccae3ba2414c17f12a9a70365856729a6317a9c80e46575f89563", + "0x36ac3e640f31e48b5fffabdba7fd751fd803a1707b6ba7c587a7508b3b1b4231", + "0x1fa3f177431e20f569a2c10c79dce754eb8b7791baf5f2aa1a389c64c9f4c547", + "0xf7e53b29648da476b4df26086445adea1cbba0ebf2271461417bcf64bde0713b", + "0xd8a0a1781144535cba0e4b7e9ef72d439af344d6d13e9f31d35791e82aea57fd", + "0x730110ffac5fdcad1c3b82c00ba16e43eef88f3f4fd90eb5403922fe5bedff42", + "0x24cc38d4eb2b82fbfeaf2bf91bf7fa470a5ef49e344e75973418915fe218b42b", + "0x18f05c3a8f656c831d4e4f61100bb6619216770eb66775cb9ff9141849f9cb0a", + "0x0eabb089aa92365dd492fb0f81fdb2ff6f4575976154b1ead5d8b06ba5b4fafe", + "0xfa557813e8cba6fadbd410aaaa5d7e01a94c2eae756c7d064b8c19a26d5f8964", + "0xb424772a132e6a59b63715ea1e2689fcbc00b1d98368f530af840bef4ef72b7f", + "0xdc5738d415e77cd5a0ef5dd3d4a52f911b1e9dd4e386924e28b9b0b6dd7e6884", + "0xbb8596337aff09d46c4a5d6ee9bdfe369e41b2384a57f45b5a5151d4bf2be89e", + "0x882a79f76f1e876bfa8802c7e2305537f72aa1a7ca4ab34e09bdf28dac815776", + "0x6d3cc146b6db4257fd768280a58146bab3d6bbb6651c5bdfc12645d132afd904", + "0xecf827c44a85e1250ba58b311f1160007b29675570223ed5c642ce7f9b9a5cbb", + "0x64c58db8a9534ce75f56bba7f2fe704a4333d56641fc2eac3cb39217b3c10e76", + "0x2d3b0e05f4d190813b4dbec787f4a9bfb3b029c44bffdb193a1abb9577c8a9f8", + "0x514ecd87c88b6ee3b984d389b66ed5c96ee48f334fa5ddcd03c145f4e4d3dcce", + "0xe856f1c77b345793bbf9ebd77b812ce2f393d2993e8b735f1b1482a2b2425d13", + "0x05fcc98827976ee1d39a0d31e34e7d9239dbdf287159a07d0353c077e19e4350", + "0x7166e2b9120fae430512ba36205080875b12a5c0bd92ec1de24fff377d380cf5", + "0x67cd75d24ce797449761038f174c7b1aebad5e83a0e39179a011e0ba389f67c1", + "0x16769224b8cb92072bab6506514c78142f7bc02f8f87b00b65845d21b6bc5b19", + "0x0f915099c11b5d1a9fe07ad11f684a84c60bb78a4b1324d287a3440d1b043beb", + "0x07eb4a64b36b479ab579cd25a68da5091e63cc19b03b49e55da80f5cfd85df10", + "0xd7c98fd3e2f8290d670c96ff39df33df4a803f9f5f43e01d2f09a2bc13cab132", + "0x339a8c9604ea03a4ba70ba357c49af83bf845731d3f9c2ac52f8cf5fdad401bf", + "0x9dcfa65fe12ef7232d3d1c052ff4e5afaf115b7d4fa3eb09d07c684fb2cfabd7", + "0xe27eaab5c986d687f3f943d0b6b983e620494cba1e7e2148e7934bb5c4dd0869", + "0x5f6ed69c6633e088e922cfa705aed670a32f100afeab35130b38c323037697e5", + "0x2e3314c00a75e9f17471b393619b3d08ce276bf5de32a6231f7aa270030748ac", + "0xbc86dd6a1f7e07fc84340ecc774e3489571dc61e6c4423e64f148eca272ddf61", + "0x3761f5b746aa79e23ab83692589717ff225b03b02e668f5d51cd715570777f85", + "0xede23d7929b19affed9906d02bc39d519b228a19802b16a4ae9151426688ca05", + "0x6219acadecec83334f3c3ffec13c8a1715430f06f0e7a0039f5271aa334cfb49", + "0x28e09034b7e939e9f0cc236e66b2fac2070ce28837a8267e375cc76761fcfee8", + "0x0c4a9991804e019de882955447687a27117f8480eac60667989f641b6824f836", + "0x67160c6ecbe0913a51ddd163af202d3dfb9d4e826f2e7abcaebe57f9cef2d808", + "0xc9b590712145ac72c81a6e24ea96f1c5398fa8650955d25c9c102bb7ccd0ae1d", + "0x461c328503f928a03640021ea12980077317209ed4fc3d0c21b550316e8992d8", + "0x694f2afb90b35c87cfab511f9518160861a9ce1388f6b2d8900dcc887a943003", + "0x2399aa9e302c40a25d8154b8a7a884455a0a81f08b3b8228ffe6cf56919c2a3d", + "0x2faf9b05da0dcd0e712c95d7c8cde660b6a8dbf145106220a0a2f38919f2fd93", + "0x36fd9ff349ae7bff8945b90d5b4b3576a6b87624feea2153867b1bba89e0c1fc", + "0x024e47593d7509fc49e8c4d0717de52f7b63c702ee191c5ebc15a772a0325711", + "0x78954a4bcb0317e4147a8efff4abd7192bb941cd7278e397e1ed3c282fc54d9e", + "0x2735e04d281edbb1f0907e7565a36255028f8c4b084f0524ba9ff0cd5192a481", + "0x953b4e2340d04b1dd78771a65cd051b983ed8d8e870af85196135b2e10bee666", + "0x281655ac912af297ac13e4193163563c6c4181ebd3132a309aa8e9bc02758ad1", + "0xeeba9581563ada6481807a06b91beea20e05f191def9a31607e49296c6f994f6", + "0x2d4b2fd56623c139066a9d2ae72b728d5ce732eac2af2bfb834c03ce3b1cc752", + "0x0a6d56ba67da39811db01841dbdedf9d34e07bb954792151208670fc12c4c1a8", + "0xa4536f1f2ea3e046503373e88d9f8bcfb06f9f15a245ec73e6daddf1a9a2a025", + "0x28061410720a6908463d604e3375aee44f65a5882fd3f9bb05dda4291824f7a7", + "0x74c50d4fbedb21f96c21a9b1fcacdcdc4300155198a88f66333d843e8fd97cfb", + "0xef12f70d5f61d0cf33ae969ef303690b317a5622efb9ae2206f574ae53b4510a", + "0x00992e5fbc8a9963123e1c3a4cf8be6d1dc696480a3d130f1d6fb5c6612115b8", + "0xa104ba3752a76261008fe458d3214851903d3d6ee7b2eed5672815b8805b8511", + "0xe4da5ca2fdc5e2c8e0d6a93dfcde2e4273e1c837dc17dad1329fd57d0467e131", + "0xa1ccc561a0f5c87e5c36f3e98940f682bc1d5bc97615803ffc100189bbf3e906", + "0x95096f7f0b65d39e2f12a47281e046a31ab4bc01f402279c17aafd5f91a933b4", + "0x8f3cfeae59dde8f3b80f925fbdf104b99b43c661bb8b425d85953a6b63971a27", + "0x3b6544fbea14b28004b9a03a79688b86266e5e7714ea5ba27c8184dd0eff6916", + "0x8dddb96c7499b8e79410ca6b22f03d579c00446bbefa861e7121fb46b1644a7a", + "0x3cfe8d71fd57f392328d45a4fa4d6af05495fc45bd3efc943c35a59dd0feab97", + "0x9dff138167f92a5cb5e19d92545be2f6967e64faec4ce3d912261d13b0f77381", + "0x700a13c03623de6a15525b4b80ca7388305d4b526f0c52795935e02e6c899953", + "0x41d6d84b0af2d06e3c24798a4f430760a70adec3236accd6495e62c51b935602", + "0xa0d4b65158ca6876e04ead358ac8f262ec190cb20383f922fc56bd924f08a2f3", + "0x6fcd99bf39e3e02b159ea0f8f88af3e3d9106cab7ef3e0ca85aae1b7d65df2ab", + "0xbb3433e9eb7540ece7178ba2980221741563600e5203775c253625de9188bc18", + "0x52162680f1accd300e3cf145353a92259a67165072634c170285abe8aa146d14", + "0x4dbbbb9328a0ef70c7b94e7dc68a176078a744e4e37e1bf989aff3ad983f5751", + "0x0925afed938ddd0f2776cad39599d47f162859e5de58f1fc8144a01e14de394b", + "0x0b3ec75ffa53ee08e9ed403921c2ef6190777bed173a1645fdbd51ec3e17ca38", + "0x34e0993e94f3277e54d3497319ce1abddd09ba29a661eb3713bc1ecc07ffbc0b", + "0xb65467d4115d3b13075b298cd8e668c52ee976b776c99809e87fbd31ee945c18", + "0x642f85a0005debc3cac8549728ac17071e6fbfece30cf83e21a36bc36430acd0", + "0xd5991eb67e45b265ca67269dba2a17b56259406c309018e8494781e9a6384ac7", + "0x853d5cffc988d4a2a351f139a6ac36be440fb3a2ca81df18cc24ea842d004490", + "0x97900dca52f34da453abc39cbbe40edd6631381f0cae85f01afe9b66b649b260", + "0xb626879fd793990d2a7debbb0fd9cd4008ce353fd933395bc94555bad3563b7f", + "0xe287bff3e7de4a2ed9480a35d6ef5690abeb159663c2a166d338c4b757703cb4", + "0x2335cd471f8e16049e760f0233590a43f56940e45d6b38d21baf8db8658aab68", + "0xbee5e01c215dedc9a4531b73d6c2d8d71bccc390bcf34113dbda1d02cf3e790d", + "0xb2a661f1d7ddc11dc4b2dac43f1d88be575999ad25a4d7d7b181b11751eba19e", + "0xf18b71981cb3781230b8518216c324f706b13b1a871af74aed365c90f86cffad", + "0xce84447a3903e632751ba244999b7a61a403e92da74f07357523f1f067d48c26", + "0xbddb34858e366611a3e025cf6a357e891526972d408e1e080f3085decf603e67", + "0x7574828f83c1a7265aca08da6fc5d113cdd491fde3962a6c7dce44fb3352cafd", + "0x542527be1b6c42ceec8a75923d97b99416adc53c92a832f8e8e842d1027c9568", + "0xee384399858b14a3aae705182148a5aa513532d91a234d7c930330fde596d98f", + "0x618fd6df8a93242a489c5b630a4ce7e30a8af759536903f450329fda19596441", + "0x2c7129b3ebca24f916e6e252d71fb7d96666b1b55a9693e1bb30a8cc3327307e", + "0x1693e500ccc7a5005a8b52185014037b470bdf5fe112d90aa0e51db9eac80b28", + "0xf2cf8f47b5d3150e36815794f11a2ce96dc4fa4996d801e56e12cf7eab0aea48", + "0x088c123295156fd640dd0badcb95fc471044f0bc26d04aca7ba6fd7272b954c7", + "0x4403d7e8a25d39ea9c4bebb7775997065c90a3d4dbe0f5f2a4c7a53df79b164b", + "0xd0d82b3ae96c163b3a4617f69bdc9d4a9a65b90240675b85e35f91ca23d3b92a", + "0x0d284d21e9bfff443922dce492c3ae89fe99d9b27f9ceb4f894abde85d82a25d", + "0x5772ece7a44d81afff29b6bbba44bb30d4ff31b5fb5b7ad310b459eb48eb7473", + "0x15a33c4e5be3f9ff56b827de07e7614150d735409eff0bd9621aa04fe1d2d48c", + "0x84a218e73e539262c04d38f7b3bedb35e8cf08130dd46d91b7bf22a1c7f086bf", + "0xf7edd133a8830a2730a78659737973a324f455bf0cc1f9df4f7ae0d6eb67fcb0", + "0x6abb178f84769cec981c17606c3f2acdcbac76b8c7c21a1cb1ea5ed84a4e7bc5", + "0x538a4287396f9c38fe3c94ec45b38243f31211bc657cb753f6854297fa43911b", + "0x375bb5fde1e5169cd125a4c177dcab5ba60e41f2cda1c9b79c6e63f02ba235ef", + "0x4b72b6eed046c0f6295e55138f6733c322228d0874cf62030ad110dae30b0407", + "0x44794c2ebb781ac49e8693930da2aa2636fa683dc4c30927170b061b4385fe3d", + "0x0f9166e9ae260c9d6f950533649bc47a91ed78e57e358d2818b3cf8b66b413a0", + "0x2a25690b31702e586a4d1a21462d45a5a973d86ca6d545a41c35ac2efce48074", + "0xe9be0dd81c29721f6b8a35e4bb0fb8a1a8dd437a1932562407ffe727f3750834", + "0xab92028712829c8db7422fa7d93e8e6162ad820fb067e2a7ac1ee224f1cb54fd", + "0x2406f251b937c7236abdf78d7bc58c8f8f00beb689c9999669edd01558e9afc2", + "0x347201dd79965382f2ba90a230bbfc979cc35c37fbb5f21a4b8f384082434a43", + "0x94eed3164903b05cec96cc2d70f5ecceed69a7b1cbf2c2ff77a97042744b3c6a", + "0xfb8d2ddfaf7d81424ca748056c3997ad923e269bd2153169b297ecd02c74b113", + "0x8713d9cc0e3d9705bbfab9ee1f19a9f0df18c8157f6597dd53064ec05e873734", + "0xf4292118ad14c9a3644019696a3bd601589182215076426f6d12f9ce29f45424", + "0xb9fc592f9322030fe018ffbb80cf7ea0996970fa598be9abd6c97a2aed49fb37", + "0x5d9ac03a1a45cd56e7ec438b24ab98c52c7350cd5001af24c444dd451c4c77e8", + "0x6355e320e8310469b8e64784c2c1c13c939d61f55f53088b23634f9bff3a1d57", + "0x77ab799d4eb740269549f99235653da650d2457f95dd3b1cf95bf3855e517d5a", + "0xedc16c860af601fa7c6461f672ed82f8cc22749e53f084f98b08b0737f3b55b5", + "0xa217aaa12d7f566f29048848a586f5f43d787ea663a0e32eddcffa79769a39f7", + "0x1cda6f3902b67eb9681764ed2929c2d4ecb5e8d8b73e7d434557c56f2f2c4660", + "0xb654fbe4f8908c69911f2fa7fda440a015fdecc22c1eaf891d7125a5ae9cf0db", + "0x75dc3b61e81e8d7bd8665cb9ff254ac8efcbba3bbc0d406adbca9b68980cd52f", + "0x3752c044a4fd0d9721046f7bb68afdc920095cf7d107ebe8519b3b205b807b0c", + "0x680359cce41e959f611b5141ec02a42ba1b56041ed549fe3f7fb7c248b75322b", + "0x5342c1d8815e03ec965dcb702cad4a6b496e8000e07aaa737f2d6f02d4d979c8", + "0x52beae62a4d9cf632aea02c0bf7c3c9362fc0b1548cfdc2949edad071db77631", + "0x51555863ee848a88fa5c55af7fcafd5bed4c329207cf7983a6ba8d3e5b93de78", + "0xaac2cd4b648da07cabe53e355e50964604f65f0dcfed74df8ac5da4fbaab93ee", + "0x5124816feacb7422233640b7f2916e24c48cd5ce922046404af6cd517664b630", + "0x69837d6add2cffe312fe18c8a6bcd0244b3d1646fb5fc81cf25a15555e89d278", + "0xb18671100e02cf1d0280f04153e34d85c1bc79e9b18d464f4c840852cd2b7e96", + "0x464d0f22a9b071a24860815710deb7c724f63788ce1e69dfc5958426b7b43887", + "0x165e2391d76a02b3c15c2ba5d418598f9b6b43b9b62006583a1031e0dc1acb64", + "0x19e8655c389628902e2c1b0a143572da7287d0e7b1e30f61062f3d886a170144", + "0xb01f342e0fb810cdede0a82697c139671e88f9b542dc5e2df2e2715e11b9ab09", + "0x5b7c4bd8311a53ff3f56dc9f5a7b1e001b7c4a02188bc58e2d9d92203c211707", + "0xef874c2625b4abe006207e36af5ecd98a92098bcab4238b3e3275a92fb476b54", + "0xedc237012b0e6b3552e05f9360a49fadb1a174a74d7046218daf98da19d4f633", + "0xe5a7ca7180a946e7a8fb73e6f172914c82bd9571649f7ce17efd2cd96d89d875", + "0x4de22e8a3ee27deefb58f39c3d420cd6ef2c7d94b10394d0bb6ef7c7b347b6ba", + "0xc34745225c53661da2e6c6cc8a462be2741916917dc387d7eb6dac8a55063c37", + "0x562928f070776132a3b035c3860b1dcab90843f077336bd13ec7ca0e330b3ffb", + "0xa2673c9aa322bb6d2ab24d65934c7730585cb1613e4ab4e117f25849c88f0119", + "0x8c7b3edb36156e6d4e36a514b42d3cd074295a13f3f095a116ae5198acb64f69", + "0xafc6957c2f88c2bdfb63e89e83fde2167548f913e62297936e0cdbbe4200fd1e", + "0x075a81ff82b52704a862108bb2a4a1839b462e52c8562c1161cd56b00fb7f1f0", + "0xc9ce0f30ab9d986b6f1cad16a747224ac9566ac044dea341f29e0b0fc7a94504", + "0x7afbb952c21475725af2856f114277e2b76b8a0480f8272cb3be41cb514ba442", + "0x2c4f4fcc44f7e2a5892bc232f703ac03f8d4214c02c997ecb57cea861cc6b0f5", + "0xb909cfd7699a69da5342d1918d179fdd3747795392f2caf4619b3294217516ab", + "0x21a802b502b2d4265b9f4a736e5cfa5a7c9346c17b42b7161d45534cd39eb38d", + "0x72429dcbfd5a80324bfe744bca71edd4d71001ba7f7e37c717d84c05277fdece", + "0xf9d1266cbf5d78fbf7d36bf81fe0f4d6fdc39f6e3463c7e3bd334e703fc24b1d", + "0x910367ea4a43e9d466f93c73025dd99cb535bcb1ec551c9a2f5ba97bced399ed", + "0x74f5f129ddf7d2c306e55c2388eeeefb6f8b7e5f610a0006f649588d46f748f3", + "0x8f6d359b43e9d9a265a7c20bab54c6df0fa9c4f3d38cdb84537cc4b5b15acf30", + "0x97bd0d30c019aa3828ec283910fc420a58251837195245dd36352db4027bfe63", + "0xce920942f6bea6d1eb1817c480c6414d1409a63df38f141a3675968b8ad20769", + "0xa5d06dea02d06548aa83e8fb16a8741071a4353a60b9ba1ca530a51a7d945de2", + "0x60af9aca626191064847d505646c185266658e1f22b3eba2f407ea21eea69ab4", + "0x9207b93c6b728cc55dfa0dae22cb777e05da19e20199d40abedc926f0e510d79", + "0xe425b207ab396a9b546da766671bc8d304986c728a01d164e7661c5cd46713b0", + "0x2e207fe33286a8a9a47f40ee828162e74b60262733bf8e59b7f3b0ac1c35dc41", + "0xe72aba9e82b668caff99c2c8abcff3c7cf95f441eadc8f54b712d53cc256e41c", + "0xcc4987f0ed4e51f2f0be181808720ccbd89521b7797770393001d37df2d2d5fc", + "0xb6be663793329373d1007bd4b87d72f003e3bc6c405d729ce667d7d5a4730d33", + "0x90b961b68b506c048a3bb22fd906329e23b0e397f321c3ff55beb63726859778", + "0x86e0f5e1b9a03358bd5c9af44957f12054599d7c3ff54b1328e3658fdb9769f9", + "0xd4578ff34c20c7587703366d08db79df13eeb4222d6e4b59c8d19cfa2b30ea1b", + "0xf9f6f3e0290bdf5d3e61467ea4fb2ee5e7d398d69c3ad18f05ee983a694cbe4a", + "0xc3f71a9c233ecccb30db6d8dced87b1243ed9fb87095c528bda85c855bb8a315", + "0x0d31f22335d9f802c73c57477812974e3ba83bf66547bb2227e28c4b4db92ae3", + "0xe2ecb8549d9887fb377cbb921f44a4aea87d8951b21ec4f678b870edccebe6fd", + "0xce62c9fbce8b074c8c8da53b5aea8d47bdaf0318346bb5027ec4a37e02b43fc3", + "0xd3f0cc456ccd881bc4c9a8b777eb88c1eb0235f362f647eb413ba90433878ce2", + "0x26ed42fbdb81cf01c78345475504bb24933bcf227ec7135d95306218cf47865d", + "0x37aa161b3dfa8716f22f62bd132ee6d149312e079e43c60efa638a1a24ca6770", + "0xae8cc778b277a22245c3b3346b96995733219899228190ce912aec079b576077", + "0x246ad94e203f268d4f0a0f18b23c6fae5d1f43612b22bf8e981526c7bdfedbd7", + "0x466bd42fc5d96c92818771501b188660cb97e48f9d9f12cde6258a85a88890b0", + "0xeca775ea1a5e03baaf47c5bcd3b70c029c309812151e7298bd16080248365dd6", + "0x3d47dc150027f55c6c1810d7b86ec79390a7611771b959cc51fb02f5115742ae", + "0x3aa1f15ce5e5df5ce604fb6904b370bcf5ce9aba7187d73ca90d0a0995425aa1", + "0x4cb879eb362837a7423f051b426a8df627143dfb22c32ee73c969fd47fb9bb2c", + "0xed8ad7f8356fdc4943ad2da2e34bb45b4b874e2fec94b7c62b1c80b0d558010f", + "0x177d8d82d8be1c35db8608c61c478e72828901e405a5dd679b1fea6ed9f30eeb", + "0x3b895fb2e93e4a34df9688ad144bada044c76249842855f991912c1a281601b9", + "0xfa0b99e265454de96a05424e4f33e252297f99238d8db0a7ef82cbc9bca6272e", + "0x81f15f0ddab76af9dabe0d7baf8d14af2afc88332d76833453118ca9798041ae", + "0xe0fd68f5d09a2de8b00eca9295367f73f53e4cf8b890cf61b9178148bdef13ad", + "0xb5cfffd68192f9bf8e9dad4c26f8520883a1f8ece8da9c77326aeb8bee69daec", + "0x4b676f13ee697d50569b222d0bf9b17dcf37efc299ca7cfbffa1e67fe5237434", + "0x00f61c387fb1f436bda1d0ea9f29e107056593e6290582f3640c673de97dbfe5", + "0x2e982786a7951f28a99f8bac00ed2e778dfc2893e68f89000a60763b8a456278", + "0x13483c74333ee06b47d832d832e5f37eca6c4f736ef7b7aa199ea730bb9c670c", + "0x6b12d14476194ce0d9d279bd8c5f83d58be571144b7987b4a481dc8fa10e8e9f", + "0x4b732e2ba405ab706988a602378da042a0a7a6c81965974a1eae029f6e659064", + "0xb4383796f2772c11fc056e60b9a9ba4d23a05c7bda1b23082e7b7fe281f97ca3", + "0x1ad86ac7e2a91ecf27b202746fc8dd57f66e721d14c3cef8cabfaa66ea845a40", + "0xde67d8828e9f223bf8bce95e293c68d8c1678eb23cf7ad81a333914b5b9864b4", + "0xca00948f426ed34a756f36691f3b3b17368d5568296326c06894bdd358271f6b", + "0x1588b3dae135ebc9479b9236c08654175568425930fc3c08c0a3cec3d5390780", + "0xfa5581ab4a047ddf2e4e11897e8361e8ce24603e53228136c9eab918580afe97", + "0x0d3769ed93c991e5b78d4a6c76782f3356b1d24204815f649e6a8e853dc04472", + "0x8f1ecf593080524d701f4cda40f8f1f2704e3994948b32ddd222003609958af5", + "0xe0bd90aed7b8c294794adb61a94ca02fb9fab693771c2de1b0aef8790c75b185", + "0xb00d53d20179d5702f140623c913c5e42e09cbc36e571fb15b820f91539ec5d0", + "0x0bffe46166ec23ba7f066df0cf14179fb47c126beb8a83a0f1b5e06495ae9cc8", + "0x07e3dc084c4f702ac32dbe9db6ac078b19b9fbdfb2305d51d4da9e2d33c87d4d", + "0x5bea17dfd96f81ae273151545eeaac0402ee6007621fab42c74b92833d190e34", + "0x3f078eaf9025ab2f7759848b5c33b0ebb9aab95f028e0ae0f5085c73a3fdef26", + "0x2a6e8f2715be40302b7530e63d9de7ae64b81bd2b77b3d378c496c9d42d3511f", + "0x9b000c787f530038dffc5d69e15dcef0c39dee75289c32c9ae2f11139056fa45", + "0xb96dbaac29d6322da225208d61c756f63df4a7a9a2d41591a27f7ea1a7af4e78", + "0x4b20f795b7e7044361f319a0ba06389a9825a138a30c9e2cd5b25481f2b1331f", + "0xb90f6c8dd72b689af1d1f92de10de4ba48c10acc8d9921b50a872b4ca2fdc86b", + "0x09d51ca40d7ae1775bc1ebae767b7981f7a66c39f303d024793dd73f48a8c512", + "0x71fada2f87226f9cdb9554620d07b42f8279c40db9ab220737769b440e1ba50a", + "0xb52e3c9c0ced2ab02d5d4d7c4735ff444bc8f016ff9a8ce8bd9fbc0a27f783d7", + "0xeb49ef79318d9f7d7cac1ef41a82021b1f84f5bec0d1223d34bd0b067797bb25", + "0x78fb3c876e62793664cde7117b9268f443fbf1e23fae935f6e6e710e111098b5", + "0x3aaeb697dbdc34598493556cf9eb57e35b61e718fbc050cccab4bca362e89549", + "0xd75400305a5327eb5a0036c70e015a2d286f8814be35abce2d5cebd3402f587d", + "0xa362f91fba2627ba450aa041f02f4644ae2fc1c5a19cc02c63b01491fd650bfd", + "0x1fd2dbeb82034a11d5c14d0e376dddede1f8cc2aa660c6a2f57ede57e2c0d2fc", + "0x444e4ad03ac7305087566e07dad8b81046f293db32064afa64e31bd9b2268a21", + "0x7f7e7ce8b73c2a6f8e6a9d9bcf166c7cf67e2c04d9a2a5dbed89d271ebfb529a", + "0x4ef8be82e0bcce97ef82daa382af63539c3258fad8ab4e7c7f815d753a3efacf", + "0x1b0d1400ddf579ecda24a8b0c9adf346b51613febce9ed41f5dbe28e3dc3f544", + "0xf900a2c448235dcb11f46e05aa04f9214732a5770da9f6cf230462a644698a4b", + "0x8cf03541b11d9a0763160367c1fff20b72a377526bded7d3f1deb6c165a10cb7", + "0xd3f1c1b6ab0f0284e788182e1d6a8c7fa92525ed8621b84a2b45938d8d3fdcd5", + "0xf00edeec9fc8082272ba3996e6a2e3ae8835d6930e9625f20a599e579bc13eb8", + "0x971f80bb7cd7d81c0d719e69a908140438a0a3f04b44fd573afe70212e6d204b", + "0xd09d192e746b64f924dad1349488c563103b6a51f4e90438a69ee1d0ddf5a145", + "0x4a1446a3d4ef051a1ea3dc1e461179a2a3374b78c312209e32f62575ba2d3902", + "0x17f4a89d23160692755fc601893f501abd0528dc9adf0d62fd02e77f0c7c91b5", + "0xc122bc9dc4fea4352c119974d7de78b1f6e6a9372f7d0886798445432889c635", + "0x0027a25ffdb229b2681216719ccbcf770efe806655c906a7e7c025c9a855904c", + "0x4dbcfeff4e831313e911ace5367d855ac4b661a3af6c81a4039dbaae5883e8fc", + "0xde01cc015a926be23495402e93019c8647dee8a58dbe6a872107e41bc5c807d6", + "0xf53866c20b7e0fb124e50f21fca74072f33581b1330e106596339f775626eb75", + "0x474ef22e2b54d652719ed75c01d84546eab8ecd94df1c081539e0f7f04efc281", + "0xb655eea027d9c6ac99917dd0b0edbc38551aeff00e18df5189d3784b848ba9ca", + "0x4142871ec25245d2b8172d7e8965a21761f3c9841831b7aa0e039d6540046f77", + "0x4c31f0670a4ab4485d377baa440742393f648461b741696c9eca4d1b0f7f3e55", + "0xf47c0076e4ca3702f22856f7524c563a8efece0ce3062e0112b75d018a01552b", + "0xfa7c6eedd06a74bbba072b43ab37a86b836e6e60ab89b68ecd14ce9153f9d98d", + "0x2dbe33126365c2d5787fc4c095402b2353b84d818a867305aa323ba2fc06fcb2", + "0x31c5c6a750102bb70a45e88b5a42f34734c7b6945d5505e53cda29819d9d4b34", + "0xc94162d9b47606325c024de23f77df8abce2f5b797c9b11296af55df5720ac98", + "0x24a99f9791b2952dd6923033c68b2af947be8017a6a43ddb66e7974566533a55", + "0x0c7cae3072bac27cf58898d9cf027d3f3f662a144635b25e068135006925a244", + "0x2706bd0afceaae0cecaff80d91f5fcc023039d338e028d72142df40f5484c16d", + "0xeeca13bdc1c0f8fb83c839277efbf01e13bb27eb88b64fc137e876bc750c5e8a", + "0x1c16006c6abfb954121c52d04797ccf15a1ffa6df81d70088fcc7cdce14730bc", + "0xa8f70bb282ae54297c053fb0781f4de76d888d3f9b5144b4c6dbf40e40652c2c", + "0x5fae325f5e511c10bc6f084897665c0fbfd3ed319f2e2c2230a4563f5e22caf6", + "0x6c8c138b8aacaf293882b71eb3d15b5de6610ee192816be02b7a048bf57b0a37", + "0xc05764cdc3bdc40b0ab31f55863cbd8b7bb2206e49de9adcc05f52fa6fa98c24", + "0x38ec63286c922eed91e1049fb5bfbfdeca387fe8dba9f15cf6ebb3ffcb3c2a97", + "0x7214dc68ee2c70357ffc20a5074d1a952a4eadac92f87f0a0025d98a896afed8", + "0x8a723d4ddd08df26a6c0cd5755e03d2641448f0440e2dbfcaac5cff7a602e202", + "0x9567fb04ded1384f2ad1cde98ee4fc47e6c85adeec299952ffe48e8c788411e0", + "0x2db99612e0813b685b023f596c66f5a8835b76c54fd0fd8a4a4036266bc9fde7", + "0x6f1895f5f59a5065ba07f7ada8ad706d861b6414d2a0fb80f4ea1a437ce79af9", + "0x338f901d0024719b2fd7b74793770471e049f55cd421c021d8326a38700d4b06", + "0x56c0494b5617c4f8146014381cce5a7bf281774ff31e6d62b66aaac9488799bc", + "0x0c5365039c79856fccfdf5f7103ff2d9dfe63224d323009f364e61b716e8726b", + "0xf047dbeb0fe9062ac0339c104b8c05698a373cfacda540e760105da80d46c36d", + "0xe905e3beccd5ba7666f7a825927400e51fcb9271ef7a7df95f564181cfa98ac3", + "0x15fa4d3d0b5dfe1231edcdb9e2fce7b3af4f6616f6b36fa989864a3f9d928287", + "0x8f1f7b2ddeec2c7beb8b1991cbae9e160ab8b9955ad38727b4c54a841430ddc2", + "0x3cd200ea95174cb21d1b2f36f20e9a53528636925365dced2579fca38d5356c3", + "0x255fdc3224022b132381a13a678edc07300b8069fcd9f21c47d20fa53180ad4a", + "0x155fd13b7e4d8864d27ab0194a89dd23b63d17eb8b72aae64f6f7519f3c4101d", + "0x40f3a4e9436b85432633bc85ee8d84f40ae928d8f9ee8837478bd9f6e050d46f", + "0xe5abc38fbb49e4b3674dd42acae031dbb4bcf6874bf26ca0c7319fe2a519d81b", + "0x7cc31f9b707830adc72477ff2ab79ea168311d0916bf2754e13daf01d4813e30", + "0x19d333afa0cb54a5ee3745cf1156e2daacb6e8f65b03f464320d4d33077c5c06", + "0x38791f1a32f4028172dcdef9050ddf5e83f03604dc86dd8833b65d833e347ec4", + "0x53caec8dfaf64faf8ee9fb49b9d439a1839cfd2a114e3ea59e80e5c924b0973b", + "0x401faa9732506edebd8b33e35f5054a1ce443bcd3f2b2e2fc4d131851cee8433", + "0x24280a731445dba6180ff7c0e99982c967541e21b5e46dbcc52e75e10b198d52", + "0xa61fdad71e4fceba924a9879b2ceb789a5161e9fa75df55303156bcfdb66b79a", + "0x765cf16a2d32f2b63f0b418ee2a46a3b304466a57f6e190aafce53053b925246", + "0xf2bb839a01d78d92b65f9f10ae712ba4ae9fdc187e5f41cc165d3e1bf21d7a37", + "0xfcf2a12414334e043d436e0bb8a2b0e9a0c5e8d390bd0947f737a261d8e27e3c", + "0xb85aa727377d00d02551ebeee6ea4180c8ec32518b208750890aa5c3a7927d8f", + "0x2da1a4d44bb0ed50267a8f7988b5dc7d9a01b621e863990b5b5f2006a1980f9c", + "0x0f9ce379a089978484ba7f865dbd8224bba2cec1e3274e477faa3d098e861daf", + "0xe4dbc55e6939aff20fb0b052ff19a2098b7fa4b69379b8d72462a22a8ff00546", + "0xbebddeb98b2ff22f6677176b065eaef5846fb6b78d77c0ca14929a6a8db5df62", + "0x2028557352218dcbb7a6e019be318d57acde6df729af6c4db59af74a4606f253", + "0xda6f0ac6e72cf93bf863af1e9e80f1da1c48ffcef6d7caf0fbc59d16780f5cd3", + "0xc3bbb6df580ce3a65e4fe1c675dc252fa693f70361f7039eb889ee7566abee27", + "0x371c7ee758803a6858ffed0313e1f778cc1c05b421583984ead810bb4685bbd6", + "0x7fa797720e3f3fc8b0e29a3058b07fd30bce95705bdbf0a976362c1e0b3edf6c", + "0x7dc0a39d699c351a188e485e5dd1ff85c53bc8a91866b34078c15c304b989b35", + "0x999e2886bd5f6c7c32ddbc08470ccd1f4590cdc460a845a0ce6ef49354c9d207", + "0xb25308afe1d597488fe80a19a5d0ce2204a0d03f79eb301f69f778fb13dd0c34", + "0x767809b36c8dbac06bbf20bbbb7f289f55a053d67e6f36fa94218d3d97212623", + "0xfa7a7c8bc8bd8af5cc6c8aa0259a64187a7b78cd93de0ce14ec13df9b2141ce9", + "0xc11f585e553400d55c7a4c3e50f368e615ed5adc3c0e17b51e36a10ff780c395", + "0x8b12c9644197b3cd18543bf57473d48e76a9877dcd0430d1401e47be8cee2ead", + "0xed66cd26d319267898cbcabaa969a20a5f72012e9f9891f30f51b3deca75fda8", + "0xb5bb169c156368c3ef7af609fc0fc57fcc34cf33bdd55abc2805cffe5a6298f5", + "0x134fa3abd5a48083a735a1fdc3c261a56e9cc1a3c51fc889298463d040dfcbc0", + "0xb7009411f50f3c68b77424ffa4e1fbde8da1ea29ee7bbe60c35ee0bf281cf3af", + "0xe9c1cc94016e1c4fee612a5a84e1cfb267ad3613ee087549c2be29ede59883c1", + "0x9aee62d9e40adb47b5390467e2de8e26a412f2d23e7ce07be29e120e73107c86", + "0x560f92c67de947b45e68badb021a1a6db67aa40ab15a9c3d3af6caf077741c19", + "0xdb78ceb6ba758cb9519c04b48ee5f13aad1bf74e219c6793c62a2e66eb2ae486", + "0xf23ed67dbe442d5d0df10cdbc0d4f7081cc9deac7720a7245ab487df5c436b08", + "0x4963e648bb6d493050b48e5063c30c8eecda734b298ee1911b2d494fe200e853", + "0xf77b9ec5dcbebcb725001af466af4b51e6df0f56dd888955d8bf11ceb613acbc", + "0xfe1844dc936a73c836f70bd3ace2f71a1887679f86bcce0d8ec051f8395d58e2", + "0xce072d500d2a3abbd538dbdd8809b7a8de9b16ceb46759c2e5c62d8335b9ac3e", + "0x628480dec741850e8fc78b39b0012e21d2210ba21ff506303b3a30ae7120242b", + "0x5c003242439be0c9231d029329366a8ebe26242e3f7d79216cc360f77194b996", + "0xcc9b55e2949e9f1fd5787b09fabb7f48140743ddb4bfac049d53c07c6901c936", + "0x8c809a16fe0c1c49d5243d7c808a00b80d090e76af66f139cf6ecd713b664a2d", + "0x297f44efa90f5a5c9b82e83d9fd972e0db020e128ec55b769268c1a90ee1ff98", + "0x14b10e0a6f2c4b928235a5f904ed196e8f2f0b7caa6cb22702ff301b0df9fdbb", + "0xaddc83c036d1c4a53ef9779196982402dacd2d18fdf65c59281a2707045d3403", + "0x8b1301861c953e3014841c61bf82c5a29e2c2f275c272c45145e1bf75e11bbe3", + "0x9ad184b5e60c0bd82d1e1cc97c0bf9342da816fdc6929f64c2f47f20cdb8e9a0", + "0xc0a59c2f537d5c7bf8c5df55f02fed2ff08041b261aaa41acf62c951a1c826b7", + "0x9284511705680c802e137409d590c84ae7b29c793d06c596190cf1bcfb868808", + "0x10e7c8f871f620e2a85a36874e58d8ce093a47a2472b5a91a5f18893808491a2", + "0x6617aa1817809081a7fd620506fa60b5b21ddb2b58444108de37ff279ae24ac8", + "0x2eee26c860c64ac6efd4c9490d2ad09079ba71e4326df3f44af24b4e8edb1e7a", + "0xb902f640d25c45aeca0cf43e382976fd6e69fc85e440d589e95d959ccbd1fdb1", + "0x6446d62f00c80734166de70f3567619b72900344c89b2ffe1eea9c30941fb74e", + "0xe1fd088edf1f823f441863a1ac3befc256a20c0aa1735f9a3143a948984ae301", + "0x2095465f0c5b89694f404f88734c02a989e28a41e8b8c2034043da962ac97588", + "0x97f70cd16dd81987bfa047b8944771331a5c31b328064dc8b56fd8b2b38d8a89", + "0xa18f31897f4bd29e1b77525f4458990e8bb7608a12221163037a55f39e7641fd", + "0xebfa2dc85ce0486ab35e5a7236f5747a3bb972162cce1a08a88e8775217581e9", + "0xc2a10452948ec591e4109be62c0d5a8bfefef2134246082a61c1d996f11ac4e6", + "0x4c24ad9e32fcbd76d0d78262e816b427ecf946ebbcbf7969461baf3435a022d7", + "0xc533d00b4a0526cef84e147aa77a9ad4f6787eb4f838aaf0d539c33ecb769494", + "0xdf6926a0b2c8a72abf58a5e309fb236412d541b33fa8324bb2ce92fb0d0ceda0", + "0xdb89855b6b608d1c71689b46f0af66bd918bd98d9653073c9a875a6dc1f7a273", + "0x72b64c8154a8365e8905ef0372608755b70608af7ffa588da0978a59f985d0bf", + "0xc1a4486e65e4d5430c4e63ea471b52057fc1a2fb4343459605fba4e764143fc2", + "0x557443144308f0bba5bc64fdb1deff50eddb5728d64da8b0254ec63845095d47", + "0xc42ea586d77568d096e8bd45289fbb4f42e89176a59b143b5cfe2893fab27db8", + "0x7e880ce359b0589c85a219a545d994c38d1ce05bb365906f41c55c06038e635b", + "0x3daa1c97b81387cc076b1251bef684defca282480002265fe122e99769a0e84c", + "0x2e04dad2a0e7d29fb5b4a357af29d0cc6de6831940622bb59227bd6cb200f0dc", + "0x542ef39a7f12a13bb20cce43191f018360554e56d624b23fe73e452d40601bc5", + "0xe77d21c5b989e6848b7145ceeaf96bb3ce53aec82783124efb8b64ba106c7adf", + "0x6d1591ca6b8988e6bba0fd54532c2c2791960e8f3e82a70d336cc3a78ec8eaab", + "0x0a8390be2eaace41828986333caff47e69935549d6012054d8c5ad8383f041c7", + "0xd90e8723f2d6eddb7f7bd77b01be62a9dcc86fd701f21fc456173e233ba5cc6a", + "0xa21bba87e6683a9e16ece09590fb96239c34c64c5f94e421f16a21e07d4d07b9", + "0x80b11c2f9f3dfb333dae65e77b155f789900096be59d18aea7098a8431f57903", + "0x52d749a1e59a55474f013323cba83e31d37069383a2e8d6e65cbd741d2e8eb3c", + "0xffc5f4ebb7d58d1efac8831238950ec1c7067dfe61f91ffc9285679c21ab17ff", + "0x6ee683f4215196416fd9703ca94ad672f13ae00464d1818478e02cde6bb70982", + "0xa1d9b5d02bb39166ddf32c9cd08f405104f2205d1ab0c7e54aa181f29d827402", + "0x5a782d8541372e665cdbb2b42f178681f40b2d232f73d52bd54765a23cbd5418", + "0x76b8a5648028a7cf9fc4c3eb60697a1a08b6c2f3b81811bd393c7608f7140ff1", + "0x20248198f84d13e945335ff385ccb3668a64225ecd1712412b1f6f224f8c8480", + "0xa922a3c4d2707224fea1639492948c91ec14ddc1b3ee46e03627544cec57dcc7", + "0xa4a95f2d10a2d809f8fcb8f16cc6f8179b62fcb26b789705d0686bba1845489c", + "0xe8df8182eef6fdb724d192e0254573c829127a4064122c9507a1735c009ff6b9", + "0x0dd37e064f7ae08c0207e1dd7699436aca14f9e5d39436e31539bde492a2b1b0", + "0x8453b3edb890a8c6b6a519683a149565ae64920f168a40b35c383a8734e9945d", + "0x59d569c95da5ef5841344f6de16e262afb86039ed3419fbc92c5d2ee13c1beb8", + "0xf154537d82d894a8e7b4226339fcdc953a4a9a11d1213c440166b6a58fefbf89", + "0x7a422d65f4befd89e1a7c2da40d482a6219169e5cfa309a364d1ed0663515146", + "0xecc79e782017eea87f640bc9d9ac7546aaf34d21adf1a3badfef6c48aa76211f", + "0xec44728bc6c94a2763b466d212017f2645c7156518ce4e3ecd485499be3ba6d4", + "0xc9a98ee4d90084697a5aab3665104dd11ef36adad2c21ef003e40e485ea444c9", + "0xf8a4273e27177619d8fde9db3c0659cd5ba9c084f717b697eba3e9ee7dfb1bbe", + "0x89fe4ef0342c6ec695cd14c518fd4e9504dff3f084a802cb0905fb5f6d03d6ca", + "0xf659cc0c0edabecac9a0d95fccb0eea911fecf4e53b9bb3b28e6eb9f9e83c682", + "0x548e708e7a2a136ae6ca621502fe690d6b1e31781cd64123fcbae8a373c11b2d", + "0x1eb65d47369949fca2f497a11f19df8d33fd8f5ca58b804cf504831d08f2fbd0", + "0x494b951ddde767f53900fa2f5c7d1f0dd8638d7fca55203283fc30049ff06196", + "0xcbd0b45603ebb72c7283fded1302eb15a46016ec46f2a64f4a9d7ef59ab6429a", + "0x99adb9987a54647d7b02aa589268bffd35ece71e82d99419b93ad2d67e071c83", + "0x73f4eca410495d4c91d9b979ec8dcd8a575ca89ea089ae3f09199b1a8c3ac9a3", + "0xdb421ebd89476a4cba795edc92e7138433eececa609c17b0f808e9f3573cd992", + "0xbd858de7472f57e2ffa0f326efc6f6834775741317057a4d016d5a95d35a63d2", + "0x54203ed14df2da3d572b61797d9287bf245f9939aa25a2bf29da5db6f7738738", + "0x2ce99eb34c785227f2fe479ad4cfefcf1c6df52201478fed66868f070789fb68", + "0x3ef8a4b6565c6a5840b235d759f7afd7837f5ffbf99640e1587a0ca468376add", + "0x42d89367b255a60f260b889fe98d2add3c77955d5c0aeca0d6f587b0d7709ba2", + "0xe04ce561b160f5fe3beb5de71a97f9f69817928d6138ce956701843d07a78903", + "0xa1c1d23fabb55d905627b1dc61cdbd2d657b981b3ff205f64b8ba04b96b766f9", + "0xf64bd7b3dc213d170be5f21ffb557affe15fdb8384e598c7a262eadea8812b35", + "0x0f50953c45cf831988de2e75f5089cec774b44cbf37391f83f4550e026f758de", + "0x5855905648b09a786527b259051cd04ca511d373849e794dbaffd751b6d47fd5", + "0x209170773e78428bfe4d424ba4b20e174949c1c475f1dbc0e3a77739cad4014e", + "0xd4d057271afb9983e24516e13f690d3a5946ab0bed28e294a5919782298f95d1", + "0x02c16a3265a5e3bf8847e29e57fcc5f7138b3ab479067c6d6d682d2904442069", + "0xb1d1a67f9eeec0a9e8971b860031ec9f71c0b83d2696a2041d0e8e7976683f2c", + "0x813cc8abc863d66a7e60c7e91debe714dbd50dd8f51d6769fa083c561b6f1292", + "0x18f0b5bfbb64a57634088b9af13f06030723974c5176325db9dbf71443ece8ff", + "0xbc2511f70e93a9fc24763c14f37b75582df78cc627b934681fdad73e5f94aaf8", + "0xe04f4a7390a9af34d31314e7610a051574dae583fb31112b468e85b230b08a27", + "0x68afd2ab749095cbf8cdbfdea79d99cb69560c00cd1cfb18992e7bfa278ab60b", + "0xeda982aeeabab6b0f305564901941794984ba5a752ae48f01a9755fbbc3a43c4", + "0x394778dfc7329fc401ecf8a15109b23b8b8ecbbf4e7c800b47cf9468eee95986", + "0x9c0b1978ed25aa551972fd6d90180463d5a9539c06ce3adbe3b83bee26a038d2", + "0x46220a848c83a60e656085cfb7f3c977d8bcfb6368e53fb0877e8a013ec1c3f7", + "0x71354663325aba30a19ab2f2125f9ee901c7d142654af898e6f36e62b9d47d21", + "0x701674d55517850c17882abb2d702a42c52a26e4f341ea33b7204a9245bc7fa9", + "0x13723d73f227a389518f9dcfd81ebbc49a8edaaae8ba63c9765ec62bee0c4d85", + "0x61f9b96a2f3980056aad14d9906835a5a13f0894c530752c6ab0a6a1b316653d", + "0x31fe952a648a9a2f7b8d89a3a57758be3cb74028076237c70318915677885b0f", + "0xd566d66d853468077573024a844328a58aa8ba989424d66bc135db308bcfcdd0", + "0x5aac4e8b1bc902c7210ab0b56f8b58eac98893d2c6d70dd33bcaf63b97cca60a", + "0xc570c28ddf514637c8e07427b895f23d52be931a492220d6bd3dc3d200d105be", + "0xf7f7bffad28ce00b8254d4df4b5079cebd236de2acd9a253c09636c9036b99a0", + "0x59ccd0578c26e64a359d45367b64a97b97f43a85189a109ff8bf7d9acb871dca", + "0xa9315a3b2e7decc5a653c7510f5ec7737737a325767c469b5aac929b4581de5e", + "0x576ef478c948410ac57c074cd25d5d7da97e90fdf9bb7db70a866931ffcf1ffd", + "0xa9ca2b5a515934c38c66d2588408941f1f19f0b898c6ebdd777b8b4110387311", + "0xe8481a5871b10cc7c278c090d0115811824941f119f9e66a391b43bbfa2a6ded", + "0x5dd99890bc491b58398406dc9b16226cc47c207882f94c2a58330579c16fc256", + "0xa965ccf30e1cbb5fa76359622da6e8d979f3ec487e7f788399da9c3b8af4853f", + "0x09113412961999f8d3e80628b8d058a3a6f8416f4be682402b91047a73e69b46", + "0x725b185229d9ae3b5a1c2c15c2e5a9154518df50afafb8c100020e875233a7e6", + "0xcd871a14e5672abbbb45c142a44f937b868c4e265dfa68b10bae64076c68d7ff", + "0x0a257cf0c92e10a16c8fea72fbaf2e6f56c840f2a031589b70a5492f0a9944c6", + "0x64848061f987980ca330eb74b640663ca391cd9735fd2e8bb863dd42961ada7d", + "0x51c27314780be532857fcf9d678d4ab05481f6c43da4527aece3c39a4ba6975e", + "0x78de86801da812219bd71e972e621b437bcdd23ae6a2db4139d9b62e5c40a463", + "0x5c98c32dc0ed6d507965236eb7a718ace9678f6f12bd5f81b68ae44144a15d51", + "0x3725833155294cf2ca6e1b5d272f0dc57130ba6e3a2df55111900f7caea47818", + "0xda487e7cd0f45f93431237f604218ac3d9d439607037b153ce985ce92d16be03", + "0x3dae2a9c0418a46d752c7cb5a1447f8b4c3788788bd4c6b85583c3c149eaf1f9", + "0x53dac7e119929c41a352b46eb54ba52ce59ed5b7283d0883ed48d0f562bef921", + "0x7e302413f400b0ab38f202140ff892e93700c4484e8cc132d7cc115606684cdc", + "0xd21bb71e163b1b4aa2ffd0ce2232cab26b8002a999b901a03484bfd6253f3fc5", + "0xb0284e9fe043f920de245b35e0770c75782b9bfc81ef2ede04ad382a51c6daa4", + "0x9d2efeccfadc80b413720f27779590b366edfb599d81efdbc366846daed1b77e", + "0xf39a139bbaaa2880481a3aab168fb350db74e3b6d6ac34159b1ca4af4d47a850", + "0x51bb2f5edef77de7906c0816826288657eeed00a1111d79df311bb904cd784c3", + "0x071529d3fcd41761d977a0b344932013fb1289eac00d2ba19a3ac5e91e9281c5", + "0x0fe0a5f987e8de4355bae9f7eff1a664d2d2175af90bbab4eef82f3c2dd035bb", + "0xd1094c0c293d5678e7a05b7e537ae0040ba4202183c682075da12c6e02d3f4d9", + "0x6319ffec1f60e3b4659329566b596ec0c875ee654a8fa2ce2cc7b96aece2038c", + "0xe8fc2d78e8023adb761ea580001393a9e0306fa84f9abcc9d6f5d8875db9cdf4", + "0x7e75553809968c9e97b2ca64cb05809e45345d91daac452989a55dfabfa22bec", + "0x985fde0528b9843d4e76f2c23f76731ad14d8fa61f4b8e35d2a32cf7cc31a568", + "0xb0b679f35bbac65ec2f7e134dedc76d2b9f23a14c70faadb2bef1d914da6d791", + "0x1586492da00013d3c6ccaf65690ab7111ae6a83d3f9034d6c26d9d8072eb464b", + "0x46c861b96700ed966bb9b6ea6c5e87e188372eb2e08a1ebaa01d0a46e91b3cb2", + "0xd0457c63e7fe1e0992d1a617cd04a51eff1524d1a18afd66e71c04a321a7c999", + "0xd4863d6fb4d8cc7b62568f3960da84ceda8fec5e84fcdf031af7099942e93148", + "0x4b47db507a812eb9db6b6b2eae64e2b1ed9c51e6877e44beea9132309c9af199", + "0x7ed56768a2fa6c29f5cc1eeac629f32e017076664d5739fa62fa55e3138b18c0", + "0xcc7b6315c0006ae1e93701b345b83e01ede46164f8ac0a0410f5d1a1b0ae63b2", + "0x242f2b4ab0febb86bd74b9da83b1efed9949a05d3b19297f928a3501aabe644a", + "0x8e1b7b621ca8b594ed4b10b52beffa8079eef58c3153943b71dfafa2bc6a7a22", + "0xce4c217d7ba4180883f09301d1a77e9a0c44cbbccc099658dfda1c3eb715ee95", + "0xccf2da237cda4519c41dea0a3067bfc3870f3a6ba073d44999ea3b10bc32c5be", + "0x0d83386aa9ec920477eb85492389f45659b57be79678df596a0781a1405bb6cd", + "0xc74c70ccd1d4487e4f6a8e77ca09cc394b6870e343b4285ade688d1b6df60e03", + "0xa8f22312c6ef7a0ff629dd0c64739f055dd09ac4245c913976e4e6c168f8266b", + "0x9c116ad329b4a3023c5c7bf711c3dc4dc0f9581d68847354b9ceb57687a76643", + "0x292024c45930a03895ab4b1e7478d7d784eeca1f5d61fb1fdc03eb8c345963fb", + "0x0b21a6dac04948393361c6be1abe46f5be0b28ba158893702fc80b0aeefce2ab", + "0x1f5799dfe87f6ad4931696e36b3c5813dd740ac1d025f0db490cdf3335af28c5", + "0xbcf97b72036215bfc439b55440103e37a7931531795d93acfd00d078e6e88cca", + "0xace36522a0c56067bd29df38c2d1e620b9abd880a37425dbb6f5ab857f9c5743", + "0x90c3dcc279a85988c6e9de3ea871bc89d54202e03355bae21c63a4d866a4cf89", + "0x8aa5e6a53075c91ddcc28fc72170c4af931ae9cd63d512b596e9863fed4d198a", + "0xa80aed681718e923660067910680e3eb057e3de6acaf0ca99f005a796503d0ea", + "0x96e8541615584f709fe77778589ca0a17f07770da17089f976e8b7fc302ec77c", + "0x8e2f41b07ad87192b79e3d96c18fcf07a170cdc9b23bf4624b8eb80053a2dc37", + "0x16543b7ba202f359d888640cace56e300346a475999a8122667c48894083dbd1", + "0x7107ab2fca188dceb5e4b0a44eb53252c54da2dba0aefcbe00625e689c2b5bf7", + "0x25f871a59182a4b0f043159c7a716562c7d063025257b89dbda19f5aef68e9c4", + "0xe70b7a990644ee1278e92f3ba1cc6a9a40b3761d8973ee4df91d3e3bd3ad1a4c", + "0xd9948dc162a681b4102d82d01faca492bbf057d2a0ab1ad1aa2d7ad2f5d8d591", + "0x6b911fe9fa1b430a1b7eaf963670cade7032466eccf1fddb6afa9954316c7378", + "0xe3453267f7c86550138eae575f5874fabb4df7cff52a9b7498281788d5be2df9", + "0xd1de756ee8b3e650137e2f1f81be3cef8389fa685a8c2606edce0f470c5b94e6", + "0xcd78d6840591a94a41b6c43486738e3f9537ca7fc529b73c77403e282eda5b05", + "0xb6107d17b47d368d236930768d2329917a155355a17c244e9b6a70df8b899d2a", + "0xeade2b36e555380abb2926f45a8809ae4bb9ca9fc4bc5c2848b08a6fc157ebb0", + "0x6e907d42d9292279e00b5e3791646cdad8bfc5802f02efe7a2bad8beadad3832", + "0xddc9d4963a1708e7114011f41b7003cbc351fd3cc6907638138f968aacfc2b3e", + "0xb9702fee4e5e00b451600c2f6479ff852f41cd760ddfedcaa9d42912d199da8d", + "0x6e0b2e6230e55b58b0caca85b86459fd94a17dd2427ed23ef4d7468e200b436f", + "0xf0965c9e876cc2cee03a67098bcc0bb8ff91c29d110101d05bdcb06e21a94eac", + "0x79902f46ccb4f63b07dd38c88a495b2837a0a984ccf4f2643bd817f353e947b0", + "0xcee76907124f92bda1e5e492de67fcb0e1900302f69682f5aab251e55ea7df0b", + "0x9df0c40c5e452168dd9debad103645074686e09110a50d205c8941d27d14f74e", + "0x4128d10935b67e5dc21e8e40e5c343fc4c4a716455abc0dad24578d4aabe402f", + "0x1b49733ff37e03ac5cfdb1f84a5d93beb0013dad0adf8ff4435b44b20dc0dfcd", + "0x31d0defb61c386a751690bdb4f32e6377ae2a761e52511e524ad9e69961fcd0a", + "0x438cdb21294f0547ffdf5269eb9099cf52c66e45aa235eade26636a13694c90f", + "0xff42d94f2f917a3c4ab43d4375a9bc63a396f3fd120f0295a4b6597e53815b44", + "0x6564791af7389ec58bf575435a3ff1e0d3ce0955c7dcc3b75cb4c85c1a1c8b46", + "0xcf988277bbaf273ae926cdcc57e88b9a2bd916a6d0edb1d7cd0a92cf85d98ad8", + "0x45b8aa768c9ed9d99a3b12cea4ebf803c458b908a65f014a779a79c3d31020c4", + "0x2d96dff93a3df327747c6a2c6e7c08612a9d40923207d8d6d52dccf33caf8661", + "0x9dad452c7da8aa798c9489ba142710769c03e5ca3701673649baf731edb41e4d", + "0x6418305ef9d02d3382450684eb222c9761e94b66a933d9ef8d833c08ad4c6b9d", + "0x1f58fc05ac706d32ff31ae9dbd533c1df2481b1976be571efe22f8810e7487dc", + "0xa9af008f96370a80f1034840d00e072a391d523065ababe94eac561005c02408", + "0xa0384a9854110164b17189b10c9b6ecb22718d515256d12189b4799c1b7460e8", + "0x17f88aa7eb0072037f2b6305a2859c8100a3e2c8dcb6e13d8b58e01abba31292", + "0xc834fc15604decfb4bbc68987f20efca8db47e1d3fbeab2a1f04bf2151b4366f", + "0xfb92c461809fbb8ac4abcab126229d5d25f5476d6f732d27ffc3e31e2db18e4a", + "0xfcb1cd8040e7bb860eeb20cad1575747c9ca129192c8aa69a9cd373e24b1825f", + "0xd8efbd48289db20663d5b087c678025a232fb83c4be1731468ad2f10f69afb8f", + "0xeb5c8eeb8c1e6bbc15df061c358ff7cb5e89e6e3ed51eb63805bb98f0121c683", + "0xaf9d7a05d1d1c3c9d03b008907b30762a435df18c754ed1fa27c9c84a8905953", + "0x06743818d15eccbc13397607121a89575a6da7f9d23e36b07911fcc516e4a9e1", + "0x32a05f9a1c08b68500074915f04daefd0a6835adc985558b62c3b2867109ff18", + "0x40e0b74757199b6863f97f14fbb394b2bf518ac06d8d499615dc087b2d105b89", + "0x09736a30759c20cfe24bc34a40aa85eb511a0f49021934d856588181969dad44", + "0x3dc24b923a7c9593ec6b77220c873a06420bd8f5ce2c2768364074457bc31cdb", + "0xa7e78dfbf9fff15ebd110198711b24f35dc7dc6cbed06b5008036570f4072abe", + "0xfc51a0ea5862e57dec45581827c35aacdc58c6dc410919b1b47e3ad3c707f630", + "0x1c5b2600a9cc29f7d3587a5aabf29b27e9f85acb99acff6a5316312a713d1f77", + "0x080a076a84bdc34236149a6ce92885c0b28d5484c80bc40b7207c45a1c2487fb", + "0x7fd2a3a08ecfdceeaa56952968836be5e8adabcc7a2a00e2629604db5efbc14a", + "0xd214eab26d637a7820a0babe4bca0ef9dadb0482b3847a71fae571f44cc93e33", + "0xbdc71731bd7440bee58f131d47db5c2d4ebe39bfbd9e2fcbb4970a7fedd631f6", + "0x617e379b135d0265b15679e464dc7fcbe696fb8afb64b6b74cde6fcaee043ac2", + "0x96ba4dd6b5bcba95f7d97f6bb3dbf6812825f5de86e12f14dbeac7041854d8db", + "0xef77cf072d0edbd8d5243ca73384a7c2e58cdc3cbcbc5f8895c65c62da30206c", + "0xe75c1cf441c9dd52a7185e3c1f1e6850fb03bc39d06d422da1ebc81afba7b910", + "0x5bad1ba4e6e0a7fa060cf8766bf8b3500adfcbcb922368da9225a36e61e7a469", + "0x1ded514f946945a7f04d26757ff39d9731d8bb28ae304d803bab9a484cf4cb8b", + "0x40a6f34a19594944e96bd5df119c1a06a2615c04924b7b8763c4d9d5c0b8363b", + "0xe0dcb9dc1ad2f5653c369d9f25d4f9058fb8c512e5efd208b814e9fd45540550", + "0x1a07a9808e43a3c473d1e9d2875ab32ec2eaf9ddec432f711554503f927582fb", + "0xc196ec42bc1603eaf0a2348dec8d850d96dd4c275bbd3de356e5a23519002018", + "0xc793895f8aa0e9ed1c22f0aca3b1cf07ad1bd69445d9eb5d51c453bdfdf0dc72", + "0x1f0312147d7bf69ab363ca3a3b9b5a0e43316d7e2c36be97fe0553d2d3225fe8", + "0x09d8080e41bce3b07fdabe7ab36d0f45880c0cdf5d2119930d61233d1d079751", + "0x5863676dae69ac932a7a463e93d312365f563a59acd4086d7c60b61d56438b28", + "0x5c9d57ed61a4994fdca105841fd91eebad100ea8704c9a12afe488103daa6177", + "0xec9c5ef3fe34be04465270a7a215848a00a31324562e97c3d94b7b799b6474e1", + "0x4ee12a6911ab23524291f800c361490221460ae9d72085ed69055126b3fac836", + "0xfc6be696f5c7687c511ba1fc8f4581c792e17876eb968bf5d1e7c6555259b98c", + "0x82ac807f85d8c430464c8fa8f6eadf6cedd5707e8b4aa653ac66f85dd39bd1b8", + "0x08ddb03882de2be4d7ae9165a41746fc76edadbaedaa6d8587c0560c5c989ac2", + "0x7f1e6e84f0ce5f9bdf199f579f4c57a8d35ca5b4bfde55d20e2d7c092e6249d8", + "0x7caa4b3f32f0608e86a112afb9425831ddb735bb5b914599a11355102de0ef65", + "0xc52c467d635c36695e1fe850976745926250b0bcbf12835ec344231e326e7bb9", + "0xd31f10dd9effe25dd19d3eda5863f452bd3dab36cad1cda545137aefe1971eab", + "0xe3c9f6858652e0eb2314c8019fb633a14716a3c130b767577b2a28ee7af0a581", + "0x39a476f8a5268f38e24775566403135d6cc26e46a7480eec576cf9036e96a9a3", + "0x78c798b3ef7f7054b427c22e2d6ec9ef54ad3edb12edcb43ed46fe63c624646c", + "0x2d9eb24d4922203e2d55292c4b5c983b86f56c23685a3a6d57af191c65a06db1", + "0x434d433a6316106fe94059d2fc0116b7181f13846df95892d78261322fa724a6", + "0x5bf38bcbc125fc6feead6a7cffbe6db1674a1d52f4a3f91a29833a730b711218", + "0x852f05410a45326c6118bd9ba185dae319464ff3c0a603a2ea02290646bc53b6", + "0x80db0d9f5a7f2e02f3c19c3553bd0e3151fab7f36f7d899f29770e9d440a8073", + "0xdaec85979550d9dbe8d86e665ecebfb2b055836f1691aac6d64d1379d0c39e7b", + "0x1d1b18c8b2bb47b70c276a0c32fa04a4d7f5b8646c28094422faf0e177bd1b8f", + "0xe248542589724264685768bb7108622542c2d6b2e4659e2fb97d17ef7256f1af", + "0xf095b4169b0e1d33b1c24f6ccb835f8d0d6af4581f4f34feaf96d6713d70ef65", + "0xc24267de7db63ee856dda7184d50cd71890ba7017602191c3bc44e2bb1a1d4d1", + "0x624dc6dc69c1484d7531688ddda389e0ca00dc09210429d6c97b17a0d4f4e9e4", + "0xef3610a3412574d14a7549c5e992ce9fd54772f820b9485c5689e135832692f4", + "0xca58354e960aee45575f4d5abd2ae9d7aff32a7b1bd0df6e3d0d22792030dadd", + "0xbf7b2f80533f34efbe4f6c6395fe8eff19e08c9d964e619e35bd161c4e08a70c", + "0x85482474a66dbff699ccc3756dee5fe88e447448d44fdf2627bd488cc8abe984", + "0xcc598f943c693fa06111c77f475bb528a08e859b2bc6f2871f4ae50eae40de4e", + "0xed41aa8bcb0330da03b360350601f68752dc060873c6f0fe53cdc4f3c8da662a", + "0x047b5d2a97a701b76115ce5b8d71bca40594d9e163752db3e38ed8c6b0448ecb", + "0xb2ff504219c1b24b1483a7e671809202713f9b2dc888d1b46df2878ef830a8bc", + "0x01038d50899f0167b59681287f6fac87cb53dbcf7b4992631809933afee11870", + "0x306c6b040960341a198c88b01bb0eb3e2eac36b483c343de16fb8cd6f318720f", + "0xfde3d4cf83046bcbf18e6a7df3857c9e1bb75f441a4265135837085262814b02", + "0xdaebb2b71d2443003e6efecdbcaff086d0d725c88684787110135bbd15291833", + "0xc0a0198a6e57544f119523402f97c084a1afbb06f0b4d2a41bea0434761b6054", + "0xdcce26167709e6cb4fd29584c83faffcf76c982c5e17726fe4dbd1105bab7439", + "0xad717a26abd29eeb240e986e635fc0add4a6f7c8c9ae116af49b2e81b4eb62a1", + "0x47d513873b8c72791867009b293b401b7ec05cf87dc9f9537581805768369d00", + "0x497839c4688753a5db5eb98e7968e9ef363ce85cb275d40c3dd46b6e5113c3a4", + "0x3aad7265aa7bb39710356bfc3e6c555725c357b323fc281b2763a0f0267c8b8d", + "0x36e21dcfab3aed1c7134789149da4d61b2fee5307f033013380b892065e14991", + "0xbbdedc8436db019fba5aff87ed3c97a78ec2af8b2aa390f1b0f925064604061c", + "0x8dbd104b838055f34d628ff1fbf097152483fe53e6d930ae4a02d37648b758d1", + "0x365e37d424fb7ef1048d0f032f75e7dca20465f0709a3994c6ee903b1818a726", + "0xfb32c65070bc2f46ad8d8378384adb8bc3dae96dd96a8914204c607ce601c3de", + "0x30fe50586990daf14e84ef2d337f0819faf98f0bff730c77c547d34c20ff14bc", + "0x8b2977d229646c3552e4e6a7657fc3372f0a9e744b4fa11edee9f5ffbab99e60", + "0xca3830b76e052f65833a3c8c31c98bcdf8d81f74952f5c4ba32ac8f4c3791d38", + "0x4a8a34bd2ebcbdd69e0492a9e784263b73db418f20f80ad6f1b3ea25702c3bc9", + "0xe9730415f60bcb2f412e676d768ec3e25af7d6439517497e7b8f86950e83b5c8", + "0x42fb83f3376821f23f3316d9d01ad319bbe6b6cefe1dea1c2cfe89639961e668", + "0xfcc901dd86c62e3b1da4af67bb1729b28ece9efbaabd086810151e908218920f", + "0x1a40ff9ada25ab7fc14832c33a3c75cd0595cb904eac7d7a521c67ce75db0dfd", + "0x690eebd8fdd05117d5a4c7335af0c487e4ba70c9352a8c03ae7c8c53963a82ca", + "0x47582399dbb91cacadaf022957b48abe25c7f301a1232587ac3f0298bf4f03b8", + "0x900fc815fba237e026a0f27de6af96dd1055351b7a78df050e8063e67a03c4ed", + "0x807880d09bd8ce9e27b2a7df7e22c46a3f28b81db767a08269006e27a776e0f7", + "0xda996478eb696f963ea50b28c899293f1682de5bc56297b7f14bdf64e35003d8", + "0x630a1fe703d16ec4eb67043ff86c2980a956bbc45961ab343059b449a58016c6", + "0xdddd65b35951ec094cf2c01e505b4545845bd4a1727dad0eed5592e3f91323d4", + "0x6d6b2560db0d26b56f0ec336215ab3ea430307aea23e94d11ebc7f8ae0476ebc", + "0x942d35f09119613dc505286bd8e5b692c5b6ab6b456bfde3bb5e60e6875d41ee", + "0x2336d4efeffd6e88b0bc6e7b2c1759b35a7147e8a441568d374deae1c2f9a964", + "0xde9da773da3969677a8171d1c20ab7cd5fbac9ac5eeb05e161dc3f62c5ca841a", + "0xd4f4fae337a4237f02e8620fbbf077c8d39864d543244f6ea7d08a68220838c8", + "0xcb59a0f2c5ab1feb68118a8c59aa873813a0adf65730f2e937814bec1e149151", + "0x256f444bbb37350ca565dd620b71b28ea15e53994f2eecb394a0881ffa42d575", + "0x5349078ec5fa82d5cedb4709ef0a2354208a7f85b37ef7054bb687ec8bac265c", + "0xe577d5e1dbd5819a83089c701a31df8ccfce478ef9655fb7aa21399745b5c59c", + "0x2fd29cfb8c1352cc78d930de9bbab8ef007d0541d8fd1a8db7cc5cced076dc04", + "0x6ff610d29ac82ac1a5b92ed47297c6213c90146df4d668985d9d157891e81a54", + "0x376e36ba81ac50e32e314bc8860af7624d31307d6af0b1951c7bb03ec2e4b0d0", + "0xc2af74f9c437ef0f7b89b0663d900a13e98c5da81aa5020404a665c211feabd3", + "0x4de6b756c071a6e93acc37ff7fe513c585667be3b64c186c6e45ba2b3d7ae131", + "0xa31a0bfe97be03ebffd4a7f0565ff4372d34b44aa9b9db8b3943cfe2049a25f3", + "0x2a4135dd0986c731ed35cb770389b8494adfd6fb9e323f8b3c62e612ce9ae7ca", + "0xc5a683d3880f1d34d515c753f0bdb68750984df456345a7649fbd3f723539ce7", + "0xc89381d12ff71c930dcb24deb043c3837e6f8c221d986babc9a37585a724adbe", + "0xabbea8d56c9095aec399d7188aa12c8542fdaacb2c25b440d112778c3c8b914d", + "0x9257be6dec259bf4650857f8b8ffccb42d6ef93e55127bc23596ec4ca543d63d", + "0x0acdfb858aa8dc8e693018c2fd5f1d9d0192138fe5fc461284b0f737edb857f4", + "0x8d9507c1f8c22256288db6bed77a16b09bf2e83748503e5d04bcb971c2f49bde", + "0xb5cba97b5e52ddba979b4e74b1a02cf0a423fe9232327ae80fd935d9b2923305", + "0x5634d57b4b9c7a5ed15aa70d59b102b628a0aa47a785f84466ba549b60e49706", + "0xc41bdbc86fcff5dc2a77cc6997b99e75927096c3d56baa56f385ca8df583f6a4", + "0x1b81a4e0f85fbe1520c00931736061fca9a08a8b7f7dd94a65b863817326a296", + "0x12d983159015d26986b0b673451fb362496530a550ae6137f92251f99db2b290", + "0xb6f0dec7ff4e61da0006c02164bea709ac4fe11c20257f154c6a2400acbeae6a", + "0x7b98792ba33a549d893727b0df38352c0262de5dd3f34716e59843bc2588eb4a", + "0x8d33bd97dfa8b29def7899dacd161ba8b52825c281611e5fe3abecad7e57c112", + "0xfb15e7a292a8df0e9c5bf0be2f97e30f81dedcf47c3035c49f0a124b0bc82a25", + "0x6e003471f1c803451676cb993c9d05fbf50d390b8774e4dc891c7a76bd6810f0", + "0x6a5291b1e97e6423545db5831efe391e030337da2a6f207f71484e59835ff627", + "0xa6ebdbc3a608f5cd3e8e6238626a52ee541ede98cc9a8133e7c3ae18c0dcb6d9", + "0xb1b60d7fa6f641156dac04c81d1b5fa640d6790239235345d19fec323abf5d70", + "0xcb21b419047253c8472675a31f71aa694fd2753cd53125f3eb33fc7cb2bc0d1d", + "0xca6444ed3205fb31e0ca9fd84809b725e99476428a7949bc1bbc27bda16e9eb3", + "0x86ee41c48989906e9f5444a4b0862b9e55cae62512f75d1cb6126ea79088a386", + "0xc3d9d6c407c7254854407004426a0edb3b6ea2a9e37f4b3646b0573070f5387e", + "0x52979e891b3479834488cf0da863d6fa051c3f5fefaee825ae8f605db7a4bc56", + "0xc3921490107cacd64b454ce5cf113e868d32b786c00a5582930e5dc93a24ebe9", + "0x4b393efe4ee6de87a9ea89b81d7e5851f2c2d660cde41d22fa1a6e8c8d0fdb31", + "0x2c5b85643df44155127113d73c6c7a30d32e81dfb974ad18b676b82e911cb6fe", + "0x55b84b4c5cf71bbd5fcd9c9bc5130f7b0b70828ec142e9980a1f8e6aee36d0eb", + "0xdbb9f30584c3548de0bba916766ebfea6eaeac0efdbb81e9cdf7403138890115", + "0x85aeaaf7baee871ca9949025ad5b28fd704f0b1d4b4bc702fbf2f197463cacf7", + "0x976056b44f1af84778b80657a52779e4ebae64606253fc2e5502b1b8fc3da207", + "0x3647ad36808ee65e944f785f96eeb53182c0c6300893656901cbd59c30c6aaf6", + "0x159e33c4c437853e340c93bfd494dd4bfad9336e6ce4b55c4b488438672efb22", + "0xcb07707c4f0ce2ad6e62be5e3d9f7ee256ca7e767078a70860f7a11d86d1f969", + "0xd89a699a681bfb1d98e349747faf9b77b2733652ff252800d11a1c5e42c45805", + "0x66487f37ad00673178dfb2785ae9daf32bc6cbc5025e18c6791fe562e4ffb880", + "0x5314e684aa9d1c10297945dbd2258ad847c67c9855d3f3c1ed5a1121650c647d", + "0x5be3a4672b03615e7e2e980d0c68851cbae4753bfaec77f69d62fbc3f69f6a80", + "0x9d59c9afd57f37f565675c8730494238a7ad62a26026adc8c644274e615c8973", + "0x76c06d84cfd419b2465339e377186f316f0231c91999d2069f965350923a2ba9", + "0x677364bbe63180f825bd178974047c40d98e28e48ac2e43ef23f9f863aa4ae09", + "0x90a7f396716df1e03cfddd6c91a3acdadbdf761d7868403d1ebe2affc68a41d4", + "0x44af61cb5be5bf4cee207c7e2c3fdd4951c98385c530a2af8a41e96b18e60ca7", + "0x010d2f7fbdc7d82c47b33d66a5f3b8d2d86255df3a27c37ab44b1ad192ed344b", + "0x4b66f935d07a0cd83f0dce67e9cb7338cac9c343763af39fd4d5317b0e223d31", + "0x95788a4c1ad664283ce7c5e986aa45ffcc3f3ff78342765c0a0537359795cede", + "0x1d0cc84b5bcddada93d89a0c8165e0f62975e2e3f42be87cac48e286e8a58593", + "0x383c470137b4b3c0d5442bd5ffcebff656a0f6f93d8316f97ffa2530446c9a17", + "0x8f85d0673e9ee21c9d74cc3a5e286fd9fcbfbad8a67312bd9fdef4a84604ecbb", + "0x856f549c4bfe8c101e61f5f6907294b186c467b53bf1e5a365ae4c1058688b53", + "0xa02863faa09cc7e8b7d467a1e49aee2740fc72eded6b372566f7f24d39d98c61", + "0x6cc6b1d8eec2d925730f5b0d7a53a7ec5501e75bbe532d01ccf9ee4fbf04f2d9", + "0xa101c9828116728e738096a5bf3693e4c6034567280cf79f301e9331e8c0da20", + "0x08a8d10878ea9f75e586eed72d9972d961e0bae3fb18cdb59b97f13d4573e937", + "0xbe05d30470150602f7d2e7f880bcca34260abd3004f00176454275f1f5ba12b6", + "0x2293224a8b616daf818331ba7ca2984eba091d7fd2c5c021ce1ab8891d1d02d5", + "0xffd50a8a3afdfe098a5f7d8a4df1d98989c6f2154910801b44df299f3a9ca970", + "0xb2bc8f78673c10a805d2a02eca6ecff625108acabbdc1f0c083ae738a6bf80e3", + "0xd3d7800d9ad71590207b86ce8be28af5d3b844451d26335843345235adb33482", + "0x19a2050c8fafc25c023fc874645146c9d69e58cfa62c55d6fa6e414acc7230ef", + "0x1607618728cf21588549167c963f4decc154c39b9ca7535e4ae2898424a5b9d0", + "0x77ad7d04df11bf2568b6b4a43a859fd0c41019e3fc3622011af8bfdc9f2fab39", + "0x8a2f2bdb426c94200183bed7500ef3a5645a936b2b69de6607d5e0809735f3f7", + "0xd31e090eff9d737da218d052287c7bc575eba68e4c04c61afc1bf71fa1294d46", + "0x929e93fc4bba1d6824585e9c63c00b142aa010954d2659557aa2abf020aaa754", + "0xfdc40de28666194855d21df5466739de17b8569a6416cf8e06e6a5f923cbbc9d", + "0xcf47393b9ef0fb5f68c4203c01cb52acb6d3a7633dada6ef171fdc5f70ae3e4c", + "0xd8c41ec1d0a78a2310a1e9a10d69017f91fd73c95ba26743d118f989d29d6f6d", + "0x31c3e809f24ce309488c611bbc62fde0394852c627502be078bba6e4a345d5e9", + "0x4f3ef90c7a078e74d707cfe628d9cc23d2e592b25727f25ef875cc7926f7b58f", + "0x53dd78267af64a3c11157bc09f4c16603bef5423b46a736b3baa082029d409d9", + "0x2c8e9f60300fcddb98d044686dfdc94fb34df87b0088873eae57540d07446f64", + "0x7100344f97940317ff6df6a5bc8e22bafcce7aaf46c8621c2dd0f6bcc3b6898d", + "0x8958726b7851035b1ea0f5889ff74280ad428912b5273752b9e13c627411f4a7", + "0x6ef0d28e7a2e2faa51cc8e06bf00a4ff182977a14a3f45ab71a02869d21cc9db", + "0xbb703737301efe6a34ea929b205de1536fb1aa5819def94ff5cc56e872b3e825", + "0x69614a352941e7e09adfabb909bb9619232cef1ce8866abf0a4c43eb0a255a48", + "0xfad7b1630f6ac59bb9819cb0e33c93838d44cbf9182f598ce4bfabb416153aeb", + "0x2a4c80b6f28493e4fc78ba4b604c927a80d8152aa13e6bbe3cd5487354ca5451", + "0x88c56bbeadf8e475f8476663c308678c5bd7f5673fbf20a154b478ba0a83993e", + "0xe7265c624cdf5bb984c24466035e418a8ed08e5db12e76dbde40287d11dde5e3", + "0xddc2c7e6d23361d39cf3bd6af4b8125ac1f2d32e68f725d77144ed14d19a4ac6", + "0x8adc4525b31039f9d6b7fe2ce7948ebb389ad0fe1b2d0d9ba0675101377483da", + "0x92104f08380fada7c0cac602e66c4d754e703829f9272e126241262fdf7423b9", + "0xe7ad92563a04b8ddc6aa93079a456339c5e631b5e00274b4512d16b28fcaa0ea", + "0x05e51bbff3db812ec3e64f34bc4ca899345b69d7511d25d2b8c05a6f73ba91f0", + "0xbddf31021ebe16aac248f3167d34fb9fa00b885c0e859a1aed26f866379b4762", + "0x87d4a8d3a89be7d5eb725a472c7105451d796ac2e8d41c7089c4604b0908dd3f", + "0x2f01e7b47dd42062a2ec8e4961fbcc8db7ff6575cc82751afa362b6ad21e6907", + "0x8aa4b672c4a537b8c8cadc5900b15c87def5cbbf585760fd080c6369894bedfc", + "0x795a0298b19a0e660a41cbc7c772872f95739e56e95f3b48c6520a5c5e55eee0", + "0x10d0342907960372382e5c3a7ec2dac0e6f5c2bf5f6b57ad548a31f9fe11c249", + "0x073b3efb41e2e904a4e83e01a1b1b34e7b6bb082f41e4f76aa38b55de5d84a2c", + "0x12a10cb67c7337e71aaa7f79829fc0abebcfdd3077ded20de0460e100a1b6604", + "0xd76ad354d8ca67f0b7b33e9a87d5b8c3e9aeb190b160c01562976edfd341691a", + "0x0b0129b4a178efb5cd71bc65ae4e8288ac76449c39b2827284a8a59a53a8b04b", + "0xc9702a1ceaaa255e2c7db468857d47f08538280f704e595270b3d1801905c33d", + "0x67b6eeff27327be016b742cad1297b0a02459e4e5c1b1e16e15932a18698691a", + "0xfa25b1e7d3233021414f61158758dd1721838d41113866cbc763051f16417966", + "0x51af765c6a8b3aa1537da71d29a9bce4ec6a3beb83eb2451bac170d307635ea6", + "0xa93dedcdc389d03b011add42daa6b1aa4c77065b776e8ed2de3bad78afbc1c8f", + "0x278a468d7e1da09d9b5d017f180bf14e48825f9ad09f4238114f4746a5c29168", + "0x8969a4c15171d04fc703d8377b03ec827ee8c29803eae6692ae52d31eb18e055", + "0x69fd35b051fa7a280c6c0abbf340c572f6022c614bdd3acddc89cb0495c5c75d", + "0x2f148c2bf404ffb3041043444c5e589656571f42ff6b101f2f03b4afbc3c1051", + "0x24913a97dc2244e58f154efee2b772f4dfc8bfc41899c66b2cfcb49b5bf9970c", + "0xf8aa8972332906671779ed9639ff4092629758028d02f77529d56a9c89140915", + "0x78c99dc9c7f1d356ffcd80cdde5559c8742e3186b293ebad19f5f5c2ab172949", + "0xab301f68fc9ea59de054f4a14102e5d1ba312416870141319bd846ad804bf9ee", + "0xe0d75a30786e55aa94fdfade60676c098664d4bbda32f01467535b25f8eb2a7c", + "0x6a55d687db9a48b19fe238bd249fa58d7d963ebd156c32bc366f8d65a71526b9", + "0xb640570971229244b145c01474ee04a685a40bb51758a4d68310b4ce63ccabfc", + "0x1fcc3851ea21fb8ab94445b36830318b896edccd64c2d54a3001e198f639ab0a", + "0x70504f1c582a0f3e7d6d8ca8fe82cfbdd69b606cc000d34ddcbe0cd841cd9eaf", + "0x6fcd5480b8e6ae07f38c891d4202402fce91c3144f380abb041dc4cb61485380", + "0xcd817e8ea14464d8a65643d32a4ca07badf0330e96c9e3b4835e982ef2e32667", + "0xe6f62abe81088e3ba52c653b7d748352ac6248a8d1a0dc61a63a13b39f3adb3e", + "0x61a0b71216d09ce57e739a0690c7c833ab74a41cdc7c0a136a5a261da5d5606e", + "0xa5cb275a9a6ab6a127a2ebf6afee6d6d3ed802ab4728ab3ff7ac12f4050a69dc", + "0x97b3c2da2b3a9110705929bfb299b69f9e6d3c05cfc391dc43b339f6994c49e3", + "0x273ca1ea98412abc4d162eec30d669072ca8e59c24ebc17d7b74dd42721b1e06", + "0x392f8b4e7d706a08828684d868acccd647e781219f97477cad4e4755d5feda93", + "0xf3b821c71d040e10e515418a21f73a3ef0ef855cdafa99240e60dba2816e5cea", + "0xe527f8c605a625031c7dc74793ee6d1b1554cf9d5d344347a4a2bf5b6824f059", + "0xbc5e66d951bef421db1595db40e3638a2b8f253a8387bd4d43ded54c4c0846f6", + "0x7fcdc1fe31f1891fcd82c2eea392274adfb26ebcd7ee915b484d0c272838d2a4", + "0x58b7888f6776e36d6c065b3f8de88ec8de76f224ac0f15dedaddc36351ced36c", + "0xbf5037084ff4124e311de573330f6e482621e06df744c1086977e6c7465521f6", + "0xb76efd283b00b528fee1857ff599fbeda6a7ea648c62b37590dc9a1f8f872e5b", + "0xd2a86a75f25cae510761c30a843069e889d5caad4fb45cdc1f0caa80c32481e2", + "0x5fa32d5dbb1887ecf3b93aa544496b8d7af7aaa2242ea50ec96cc5c07da31c00", + "0x8c6894e707d014dc7a2639f07101fb1164ceff5687b3ea1af014e63318113c52", + "0x018a3d80bb4ea6edd284f6146918c905cc3c1c754e9694cb04c6e939e2c3e8f3", + "0x763a1742e8f9e998fcb5f0e5ccf9bf1c0c58a299075ceed7b273e5155ebd7a66", + "0xeec702dcfdef81a97fbc330f028427a5ec979081c3ea6499ef1f0c36fca59c8e", + "0x18ec0a483c6bc0ef114a9ce6f4dc609ca66167d6715b32720938a180889a6ffd", + "0x5a948e7fdc5150ef90985ec51c833ba144efa1cba509124273492a4597ab5923", + "0xe88fee3b7ce1ad4a6dc608a3a5a8412945290c97371959c740eb3ca74c65d254", + "0x2dbc9f004a225f235b5710f22f0f2c77c75455869c50c311a5617e4b795a353d", + "0x3d402479e699d0317ef4b93cab54df4a62d183e628c5b105455fe66c90c73e9e", + "0xc9f150ed85090f0df6b7939a9ad1496208e920fd927728d739fbe5357511b56f", + "0x8c34fe488619a0d70ec30c41eb3f9008ffe47f9c188e63461a6a1448660cfcb0", + "0x1f2db08ab9b278038c3dd9c36b2d279d71000758748cf089283dff7d04e937c7", + "0x98cb2dd0ca201bf90725b6efb8dccbb6d05776b6833ac780aa14fc44e901df3e", + "0x0d0b8e72e7834f89638a466420fbe3e2ab5e2893b7d9c8c84394caef0c45a468", + "0xc054cfc39bfedb31b8c7949b2ac1bd6a07b36c62020188ad336c6039efe1032a", + "0x8f25593a99b7667087b329a8f69535db5c695abd92fc16eea39322e28a5a7577", + "0xd38c37dd354a85a0a2279a87a6f2742e0f5c7aa61085ce608b9bd8eadd7201d5", + "0xe38245a68b4746d911097fc0bdbd0094673f8ec345d789b77850330063dbb9b7", + "0x35a08b8b3d7e4852812693b611e69972fb8c66853bc3b06d6efbcce14117ebaa", + "0xed25487bff2f3aa0db580f6f6579e0fb30f2bfa72de70e3c480d3d77ce393093", + "0xe88653f85db98d947ffa42a789eb9fad86abb4048df4df70dd4b1f94b8726ddb", + "0x500343b55dc6a2a74bea48858dc8dde4a091b9120782d57a9807f1db21ef9a19", + "0x356340a610fff9b3999ba7c20e2fe65500f5defdc8852b4320223649d7591627", + "0xf59edb887df597825e2c68d7f8e8e58320acfd46a31c904c58f38c4084488a95", + "0x8f94067314834a0dbeba084049c6f4508038238795bf45bf623bbdb8eb2cfecc", + "0xd255abad0c2f585bc88bc9db4211cb34353764af1121e0f75709670be507e946", + "0x3914fc87ce6cc781590078758aa3330449de03c6479bd5996ffe1ca533b7ea1d", + "0xdafbeafb230e2e8b44f963026475acc1e7260e7de6e817b7ba9f0340f6c27f50", + "0x7fb53cd64dd1045eb4efc6fb24d4b609db52bb342529783de0b4e44b5b3d3b81", + "0xca94b25fad418cf1eb161a6a3d269b8e3e2224ca95d7d79e903c1c77ee14a020", + "0x7980f221287a1574111ebbe83bf8c5aa443a93e3ff95f5d51da3026cf6606a9c", + "0x3e103b573e171ac4bc2d19ec450d8ab74c696f1b2cb444975a612a8b3f4f5ee9", + "0x45a7beb63386b87bc180332345f0f08eff981871555a5bea3265c312641fda00", + "0x3a779223233d6ed94bc336dffa268cdae36367c7f08a8b0204ce2d79521b707c", + "0xa9763a8dec8ae703b006f71f6b83a034794a91649878b6bf752d55aad4acfbaf", + "0x654869da214419be4d42aaa1f8964a867f24f5db590ac4823ef13c278e7dcfa9", + "0x3698360e59cd6586b0242b8a30e28f9ac0b20996f24607a0e3826ffb743011da", + "0x85a6b0319f93315c1a90d5b44ba88985e1d628c6bde9c370f7bc5e4ff21c05fd", + "0x3f6c395956cf1646cd0d29daaa38c04348808f1d4b4ab9b10fc982fe7f7859d5", + "0x382629e494c41827cd2aa72222335ac3a30eeebe4b4aa96c46c7b7d030cbcc90", + "0x1bcd92ac47810169deecf5ba89398ccfce61bce2575758a0ab4a2c8f85058422", + "0xd0b960c59bf7ee3f06f26d6ad1bf16d0800338f495573a18a264146e5d1a68e5", + "0xfeada9fbcec6d22a9a7e3b0e643257a1c6c827d53553997571afd49eb80c4bc1", + "0x647bdf6ab4a88731217f8610b57c98daacd424d89325c6bd0f2b1a090a7bf527", + "0xb67c9cda2ceae27f1a59b38215067f902bfbb8adedd10a3379dde408eeed0a5c", + "0xeab82329a4d0f75125ece37caa4cb4e3c2a65f9fb39722d28f9567fd09a94dfa", + "0xdd94ff13aeb4191c18446ebdcd1d2449824386b081ebcc056f8f2d8972b0b105", + "0xc9319c95ccac9755526ec36a88d6384f288087f994d66e3e00759b9981652d0d", + "0x0b4cf4f195c7227ebc79cc647cbcf90d852cfa4cc1cc6a305fde8ae870b637c3", + "0x25a7434a908f27b204eff7221d4c3deca22c20331c5aa650a1455c863fa6b422", + "0x2bddd823ea545f3aca6b2fa00a3a2c83dd358eb4cc4cc40b1cc7ae4167bf0f78", + "0x18adf129bd6f7bccf32f1b5ff4cf8d855f17093a4eec217aacc4e0c96e6e06ff", + "0xe0a2c9da78d9fcde12fb306b339eff25b9f29699cf292e59ac50c5553a744b46", + "0xcbaf7f6c3d2af021e9780fa1fe40eb2126e7aec616537fa5d2746404a5753ab7", + "0x8826d7342fa3469ee3ade0d9b169542d5cefcb0edfef48e14c320bc97adcf24a", + "0x6274f27b101ee6f88299b222ad630e3bca648d86ca9f1a6e96fb811656dbebf5", + "0x1811856349dc02b06179e224fa22fee284d367674339407f1af8afc2d4940491", + "0xd8dbaca1f92be6c60dd3637d812f27f82b5a29adada0cc07f36257add080c3b8", + "0xa861c65b35da72c78d5948f433def655288ce2d3fa2c314de9ddab022b0c2833", + "0x19621786ddee5d87bca26828ab9ce5dafd613d2443f2469d87a2764875c64d53", + "0x62c927df988349a637fab53cee5ae65c81bbcfa6bc9bdb4723e7bbfb81760489", + "0xbd07c71513a8d04aa90a2ad6c2bbcb320cb0cc03ca104c2aabd7dc5d49cf7873", + "0x7bc71b4726da12ca677435e46dae08b7bfb2c2a8f3a3c5b98aedbf35bcf06e4c", + "0x858a08cb660417f9c32218d9e1cd0698d60b40b25e185f62373f7747eadc1a79", + "0x8962c42bd8fba724ddad94d51776bbac5a77fb98a68d7993a0c01fb83da6bd9c", + "0xa52f685230c3ae71cdaefc5758a66273ede8c4be2dc3525f911d42a5fda2de45", + "0x62153ab8a4a28289e73bde016a4fe58811cd02e5d659cd9f577c3611493eec63", + "0xa30e5e6005b1a0d9d4b7e86f7203a8139c26c729509469b3f8050b03bc39ca10", + "0x5ce8d37d13cb9a4d32db0b907f035b29ed39b59522e8485d1e4495bb3dfc1572", + "0x67719bbd7f98e2869713bd54329da3e3733f411b29a1193db3fc4398c8505ef3", + "0x00f2dbf1944283fe0f820c499c52a4ead45c5393f30455a28a2e7fa06dddfdf6", + "0x6b6526b0c31b074ff0712dcc57167dd50483dbd7250c64a2d93e126c7dbd10bb", + "0x36eea96f8dec2bc06f364dcb217264187b4541ee750fb8d8fecc1b2126a52a64", + "0xed6890d6723ed588fe2710cb30561aa92c788e3931c6baf1ded01bf9793422e1", + "0x5ba666ce9f3a0cfbb7b1bb7a309066164d4acee27fc19fd565ff55b0611bd04c", + "0x6e2a394127418f2825a8fde981198256797ab14608373bddf13a71062ce3e4f2", + "0x72f4b4f67f06f76b5fab3295a7e56e0f7b7e4185fb383807005a74ec01ddc50c", + "0x0dd58d0c0eddcde1173a19b9a4f6ffa8ca7f400e2300d0af3722f41f0c9b3f52", + "0xfa7118a28e8ef78bc0156a6a2fcba9e81544c91fba55c325ec4794fe012e20b2", + "0xc49f629ec1453253928a8eb4bb5cf74f0f0442d86d0d84a7dd0cdb99d03b3a71", + "0xfebc1806fb5560b28bc14b704febef947911904bcb665fee2cdeed790855466e", + "0x6dc18cb8f447987b1a80c1f4795de09e144e12407edca405dbcc288ac719e94c", + "0xa35b1a31d28f990ea63ed366caae0f75871076d22357cc66a87a999a6e09e127", + "0xe186aba91e09aeaa77f470cc71bf8bc6b18560d69b399df8ead5fb63989a3b82", + "0xb352ec9a9cd2d2ae801dd10bf737588e4620a4d6c636455d33124aa1e5361400", + "0xb12c148effd6855c73c44a78dd9f939c7e687fd44f522277ae4a1f93f53d26dd", + "0xb86482d56ee61d400cc8d9a38224b8ff94a6c9beab33a6edca746e5f0b8f6dcf", + "0xa6dff0601988221497746ede4a09c19d5a7a62737b0f40349a6c24e8ceb1a469", + "0x837e26990d18a624aa08b87e97d608e7f4b75a99fc57a77d130f1c44d417b1aa", + "0xee1bd06e75e4930f67c75358f64e43de6d854e7add62b8d802574ad808690903", + "0xc0f1b5145d241a642bf06baf7dfc49949df0c10afbd8e8560a6d06be3b760b19", + "0xef4cabe0abdb9273e38dbb9e09a63c0d1193bca951d82332d45d01f260fe8717", + "0x4cf2bfeb5beced066e4b7f79615091a2f81e50bac5c8c2d9ed2ef2ac888d86a6", + "0x9ce4c946df64447b7ad033bc7b5f8a62ad50df16853784b8cca241ad5191bcff", + "0xdb5fa1651fdde9cf52b418c2b070ddbee097136327f6b818b8bd41840fa8f920", + "0x45f69323d4e6c4294b382019053ad089572cffc3839f3fc8ac1f9924a0edea32", + "0xb686d73075b45237319c2ff2f743fc2a6f60dc0dddbbe6f414daf712ed6796ca", + "0x34750b64a414231766d84ea92a374932d885d95a18be77d5d16d1b94efb048ee", + "0x6beaa04579373acb926103909f7c03ced095df81ca87452e6d69535dee549eb1", + "0x50830466f05d582254340f6ee211d4432cd4020d4be1cb7830141bec8cad8481", + "0x5c9c21a5a614cf3cff7afe70e35fdabee67c8e90782ef0cdb774d909de3d1509", + "0xf0f07c550a8e6b939fb24ea1de8ce1571e8d6c329421e8a3c897d94ef3198b45", + "0x70c0a4c9b70e9653fdf91c7020a5118b727322702aadd318809ce083ac646aba", + "0x0cde06c1b9d6f5c0b895fbccbd8edc839d9bc21af4bd206f3f4c1a28f7e849c7", + "0xd3ea6feba310996dfa1a6e4e10eb1c4c4edc0fe0d3825553deb601979da10fd2", + "0x7ae5715186b00b86b0aecef3b0d487c96f4cdb4a94711f2237ecc185a29013eb", + "0x1b2828b6d94ea3e2ecd3ae0b417339148710af02a5054f256c217b67f8f55fcc", + "0xcdeac54edecef790a8c212d86c45ee9e097927a04ebdb13891e5b94370e200fc", + "0x9869b5fcf70766bbf76223cae9ca3b8e3ed7e01c065f475f29fd5eca977816a3", + "0xb80fdcce699c4c07b0265f35467da77977c33a558b215b0b9211105b6cb2eb97", + "0xd5d9a3f5d8d9faead565d5de6fd5be3d5a85621c09f49bd3ed7217d59e63ef42", + "0x226531c505bddf99730a2bbad5a84856f3ebf64833368ef14626b331ae882046", + "0xfe6a0ff6492f8e2d0f27785a71aae65868c7b7278f45ac9c13031c6933e5ff58", + "0xf0d19b703b6e7aa0873ce3a64d77fd4dab6553ab6ef5c8db4ccb360d381e4ec3", + "0x1a6379ca31f6704f9643c2944c38c4894150029be5953205e09a5c49d5a83666", + "0x5dd3e7414ac5b924e9d9431d4f69e87901bd066045d6bd0583e92104265a99cb", + "0x7417614538f404ab719354131664f75a5565934fdb35fe2b329a034d052aefab", + "0xbdde0aa58fe227c3a8e01f0d3ed21bfb13145c551cb3b75cee85f0e62c52825b", + "0x25b1b36e72306d5de03b22c4f4a99c94c67b1d7275fa7346ebc990feafa95819", + "0xddbad1f32840a3155a3a17e4710d770b0d0c8d4b9c959b434da223b66882f8c1", + "0x4ecc783780b225cfceeeefa44dfcb4863e4377946511cbebf730b77857ae1379", + "0xfd15b7b9b6240bea86a898d11cfe6d3fa8623e416857910bd9b4213331c4276b", + "0xf710711f4f26da985803eaeb05c5b07e4147e5ddcf61f400a3cbd141299ace37", + "0xc9b5c5012c4f380ff6b25bfd1b46dc97fbf71d0cd25a7eaf799ac5f7dd3f2b18", + "0xe6a1cc39b7dbd7c2a5ba211960422d65b87fda2f38d2dc309f06250f7b8a686a", + "0x19556445cac490ab941f7a43e65ed8856d59bcefd50f15862ecb2e14840c9d04", + "0x8a7fc62d190322fa9fd9a2a70937ad05fe89160b9cca33ad287fb6c24fd0eb32", + "0x9aa81f8a637bca3e0c43cb0d961dd5fe175a3c1d8417a61fe059447dc27dde9c", + "0xe45922992cb23f9b60bd5f3e3687d7c68f39ade4976aa17791d880a2f0068198", + "0x6b4d46adddc2335abe24e9f969b094a0495264607906191b38e0a176e9e280d2", + "0xf5bad7f048acd435c6d0017165ecd85b376fe9e264523b186c3439787fc7126f", + "0xe6029636af0630d9d84718419c0d540cd6738237cc3c5138b189af530bc65e7c", + "0x5f93c70bec8a8cd6f5de0d7d929d70a978d1dce3fc693fc6a8954fd0c2c0e739", + "0xa7aa14a7b0b6773c552eb1b8aa66451e4b368e51d6711902f932e80a7d54fb76", + "0xb48effcbb7bf47c28a17318971a9ee671ed249ac1932c86b1748715d78fb5419", + "0x38fcb78dfa98a0d2bcbd6e883a19d8d8a8db86e9f021b9fd25f5a309b3e91375", + "0xa16e055ffcedb90aaaea09441c16c94aa90beeecdce9f90888e45e7915e49115", + "0x4d536f2bd58b252a36b77738fb4b6ec932d914d27c343a77c3a87e2b37cac722", + "0x7f8e944dffdd1d797cfb1c9484f757f9860f61bdf5bc369d4ec26b740109ec0e", + "0xb86ec6ea0e69c1928fbe009e5fe1da9c938c36581b97130474a1fda44a1bd294", + "0x268d430425915224ec7453fc7113eeddabf368a6e60c00af6af4d46147a5d434", + "0xf2f2a68002878abe219f5a1f1a13bb2b2e84dd2d39c685e2868068c4b613ce11", + "0x691a1eb375b6b4e66c3dee0f03c15a847716a4a76f561f4742f7a7774925f6a3", + "0x1e13e49ce69ca70e4bbd74b020daa2851d96ded8279deaedc846339739eb790c", + "0x058ece03bb6385a48ea9eca0e35e5853ab040c6ca5ba372b2045b0597b426f55", + "0x2f2b782b6bce115d03df9c13c6a7adb7413531ee9568dbd9655bbe5ab6b06141", + "0xae45abdd224d09b9a05a4503cfda3d2e24db0cb597d370e9b5d5da2e37111525", + "0x3c51f84f818ee4ec36e79e3c42abaf50973bfdeed693f6d0f42a2b8c097723a1", + "0x642d6459728b8d6036beed800d20d59280b8d5ea2e210677ed04a5e7973fc1a2", + "0xfd9ec30b1a0d27c8217e3bceb75aa545e659609ebc144b6e4a23fca1d5e90d35", + "0x75e0526f30a2c6c6ca9add64d1c3ca20ff988f22db1e6fbdbeb4dc982bc8f0e8", + "0x1f13605cb2f94d3c8743c8ad3eda5bf7b2a6d3c1c117945744aee8b8ca3289cf", + "0xa62c5d59536a4dd61c0403f85be6f247421549ea7b251e44c21b010a3ae4a76a", + "0xce13aa4fe702750ae5561cbc6f2bcbe8b0d979f7d1751c80d48fafe85b9125ff", + "0x4c34c6c651fb179649b65ee60f93ed64a2ca11f6699e06f9e8e8087e60f81a3d", + "0x53a18b307f80340116beca13bbb10b05c7fb6d65cc4bae466aeb0d40d9da74db", + "0x62897236794db02fdb58a255f08c7abd253f2885134e64ecbbcd1a2e20154705", + "0x996a4c7e9143b80e5767fa637d5370b94591ee336e0f23def3d83f7bad0950d9", + "0xf7e28bd31a3f39a93ccd647030680f970a358bcb84e7a555dc16c6cedfedfe22", + "0x54793ae31a612c9d3d4480b110fe2d2603484db28336459606f672bb0e01390f", + "0x9635672405c8519bba38c1a046f309958d3ee84ca9cce5722146725bf2ef933e", + "0xbd69316d6df7de8a3191030317505d4c4cb6ca8ff5bfd2fa517b76329b912fe4", + "0x3cbe0d66905ae6da05163c24ea90012b8c3acae38fa277f2d8c0e7547a9d7410", + "0x7de8ffaca8d51bb4e59ac89e4b45668c1065996374537204a57870494304bb38", + "0xec1e60f536cd00ee2eb039c48f2100f86743e20e9e8911fae2afbc27d03212d6", + "0x643275d0c81982562e1168553ddf03756d6a813ad92981140879f886133d7203", + "0xfa9a2ec8e05caac288b5fad60462e47fdc64d7b15a0a7f09032431195fbf6e92", + "0x69413e7a6027e5d92d2288b5f028b9aeaf028c3926c779432ed15fac245d19a7", + "0xef20cfc76f417979ce7077c979576bb534f5d5bc5d052af9311cd3cd4d2175e5", + "0x6e560ad9ca9d868231be72819523df157459ee5cce76fbe643e9498369b3e585", + "0xe7739c40398901cd392e091c3a89eefcde07f9bf8e9ee7fda288e3ab24e199ce", + "0x3ff97067449cc13213dab1a46bb66a69997ff1d18efc13d22673145eea8420d8", + "0x1c8b79f893de6e0b46c6f624b1976b47de4ad1568dcd90486dc8283f570bea04", + "0x9fd5f70a4b995d6507e6a42b48ab18f94ac1623e81a147b40c2455ac7ec5ad85", + "0x69373e6e19f7128556c1f21660ea17556e02a530c10bbcfb2de5627fd8e07b9e", + "0xacdbf097f72170bc86f923b172cc4315a8e81cde71b034e2f8fcb9d6752938f1", + "0xbbe3ef5451e45de728039133ee6447b9c2c605aed3a8f808d547ce0412a84a51", + "0xce506260a6f1a254d233e3b32246ba6b0d5ed91d384f55d1253a28bba8534c09", + "0x0a9d69289d09eb6b010640e7e79256d585d73e3dd6a09701c5a8aeb80148e3c3", + "0xaea8a91738082e2038f741b2b66e763ee4490db3e219e7a13e573adc54574d59", + "0x954fc41b9313524ef8584d96fc74b8f81dbb5ca23d7997498716250cfce8d4be", + "0xcc551b51b81be31d97868efa1335801e393b595cd9e4b303d3746bee55869f16", + "0x77797967766e311fcf5d4a3e89a08a7def1b3561346e3f7815b20ed609d505d0", + "0xd2ca2e8da6be2144ce29093e936a59079d9063f887335e7344a2515a8f0827d6", + "0xba3c00208b678c67d753904474b980e77ee05935633697933cae0feadd4ffcb3", + "0xa9f0edc2d5e83dd6b3f6a8fa6cb24f5a11e290e9cb0f671e8dfbfb66e338ac5b", + "0x7f4944b4fb1fed2b17011748925d7d3d88c6a4bfe3331d03da00cd2303afe9c1", + "0xf8961b65f1d6d7be13006a64bc4094d57a6b44ca314b6cc136172e434ebebb50", + "0x4f51ef2c609c7d26d4323cd169dfeb667a841d646a8174830a34370d869c8c71", + "0xa45c68290713fb2c841916ea5b2b9bd32f3fd1c004328b99ce07fde9ada41710", + "0x3623a5202ffa0877e3f5050afd668810e725415c6ebe3003b866ae80c54590d1", + "0x688b978803343067b7004c81f391f8e32bbe6a729289ee2d34bb2cfb86611342", + "0xca75d366a63824765081bdec6292e4605607b1a7580451eadf72efde7135906e", + "0x19ee65d9a8ee8246ae0f0f3c769ecc7b2ad30763872c10a48d502514b30c46ce", + "0xbb08f5f21189afd3bb2049b05d0e6486ba7c2f06ffd968ff7c81cb0071ad672d", + "0x9abdd1d768e82aa8ea6e33178ba898f8295679c6a27c13063b15688720354919", + "0xe6092e5410ad28586c919c8b28cc213ad00d98f356863cf18182532386e4b615", + "0x22ecfe7c8a242323151b1232d30264cdaebbc3540f9ebd91b7ed5b79305293c9", + "0xb88a824d760f95bb0849c1039ec0d55b0a5685f414e53006b918742f4ae29266", + "0x02766f872ed3b29b795d6276beed7bc06f900de45d2333b07776f05d4aa958bc", + "0xa7c8fcfe9b14231731b904f255b56038b711ca83928c86e7224d8930f3aff9c3", + "0x7f992f4b04e56a4d7e63339e5647dba19a7686253f23b17300e238fb7dbaf020", + "0x66df9c89dd28454097f8d3c1c74db2f770b1dc2ac30b77fa6935efb12e16b1d7", + "0xa61ee0699ef1f5e541f1dc14117dbc210d9f36987ac5094394f5987f6bfcc1e6", + "0x2c45e5dc2953619d479810eedb7ca9ee5154ac9f78d639efc05c61e6c60ceb8a", + "0x762c10a410896623963ee11e20cc0ff22aa3a190d7c6ae92ff8071ed2d772624", + "0xab87f1244ba144a65d19dc78fc21d9a096e81bfeca1a4ca81c245d72d91137cf", + "0xa25d89d0591fcc9599acd434a65c3c56beab1602cec01160b1ea4a83bd7a980b", + "0x47ebd358245683f93f0ca6aba8a68dded9926ea691b08fa74757065af6d5d74a", + "0xa0ced4565fd4da621b5fa8793a527dfb87f2ac0577a7e4d7c1130ba2824b56d8", + "0x53a4c9bb0de061ff05bb41356f89d7776164ef279609c0579e0bb60d46f7a1da", + "0xdb16dd0810092b27e08ea9d58ffa0dc2ab9e0244f038ebb789aeb1910ccb1d50", + "0xc0f2f502541a18fc1237bd03b704cc40e0795005b18ef174ad05580588c83767", + "0x94252514f5049544c1a1f9424940d9ad00628fe879222195e7e943418719126a", + "0xd8b3bbd5dffa897a5f0899246cee2159befa2717c38a42a0019bbe3079d44312", + "0xc9218c6b8a4e717d044a4a25e0faeaae12a822bebf8047a22964dbe9ea7fa58b", + "0xe5e9a54f1f97724ccbec0ab1b660de4373134fdef6566723d25f80100e11cd39", + "0x68a65e4b75b51fc1db5549b95dc302498e76fd7ab360624d39ed847dc0ff870f", + "0x9224d78122627202226721b229cfaee68e61ba965ebbe244b5f31af820cdea06", + "0x24f4ab3878d24b7a290bf841b4e7172b7c8ffc05ca7d610b36424275640fa75b", + "0xafafd828658c92c1bf7f0fe6852d278e35661723a0fb8371afa6d7c79f886e8d", + "0xad3cca1c6bcb850b2c44064817f31575d48c56ac214f55a1134f907c495e2a32", + "0x98cc755ad41cd8c7984b103a920fefa77a208b5739d3a14c58d4829f925d975a", + "0xc99b328941a669e0095023db31ed38a45757a0a3eb4f7ef32cec80f0cd354c95", + "0x7c616e1f233cc33555d6f5f43884e385c3af408a586e32ebd52253f1f376ce38", + "0xded9c6184a8f2e426555d10ba5157612056ee4caad0d78b9575d5f3cc5d2a04a", + "0xcb1a955d0dff31d0b2164932d7f3e41e0bc033d353fb80bac5b931ac2b22a5b3", + "0xacb110c37539a77c5bedf5f116274839182d44f5ba45b52a08a0d87575d3a228", + "0xfa9151e46b2fae374129f5592e2350f40ebe194dbe14403cc0dfe1153cefd964", + "0x43982605d335a36b1a46e6dc072240ab39050219e4f241666d4c88a96f480a7d", + "0x2364261ec4ff16a55ddc406d50c1343e439ef9d4ac29d52c0582c95b796013e9", + "0x173bfe3a62c88d2df9793dc247b09d379027224c4287fbe6bc2c7c8d624fd86b", + "0x9573d72cf4be5158a7039ddf51074bbdf912cf044130cebc6369e20c0fdb9594", + "0x1c74b9c52d285c62684fd3c7e58c402be0ba4b6b0a7e50a67401b3020f5bc57e", + "0x21b4c16200f7312b91c3afdf72c99f57a1a28754c0b3fa9420ccd79230eb0175", + "0x28987ce9d2d35bf51a5b1e9fdfe5ac9676a3b7ea0175c89ec84edfa66fcf1ad4", + "0x8e0c39870ca2944a19a399648f16776066726c54a86391579f6ab72b7ec0d47e", + "0xb9de199f2be5ea32384a74c56b06393c51685aec5e52eb8360e8e2b5a32c892d", + "0x9b8156716b03f820ef52f12a68229e716f2c2c1017e08c3b7e77be97c6d0d4dc", + "0x68c5259cee376134bf35ce33ce5729e059fc1052e7c134d1bfeb19c9b9acd0c7", + "0x7a3876b9ac278cfbcdd4830880ef438a430cc830d78f6cc005eb4781380522a7", + "0xa487271258604ee7dec9a306177d5216536f9d62ba20dfd057d60f046b8e4f74", + "0x7f5bd998d4ea80cc0830bbbc0f1b015a198e1d48e58fb03427e45d7e1d805e6f", + "0x680280c7ea2419d4c9e909aba9c469e8ed7829e69a8101b1205df69edf6493ca", + "0x403ecfd702230060d50d1473a243d91738e7df75c4f76c9fc8359a1eb1e866e2", + "0x59fed28f3f4783b297b66a7254eb2a089f082534ca12e8e39243b527cec98c6b", + "0xe05f2b55e5a9180fda374df06b3ad23063950b5e91a3e8745802ce0dc3ffe1e6", + "0x9b266d0df4cb0bd394ca42108e6167d4bc2bd56717ffaa467126cbedc2edf17b", + "0x49ad1b4b721dc959b911767980557a70ba8c616ea5cef04c2aa82dd4b7b4fab6", + "0x584440e213b2551c6ad58ab9e36e707f892888fcc14b15ff789d1084ed0f9a29", + "0x679fcc5e202da23085560424a550b0027f3954a98c47ad80ad2baba5f0e8f3f4", + "0xbcee5d17f10c56fc1bb2cf1b011f76232b6b90d09517213868822e573c8f90c1", + "0x783e66e42aad8192058086573b8babc38951813ab42e97c52738e8ca6fbe8798", + "0x56108248a8d19a507bcfb1d34dcbe52dea56bcfe39bca5fa100501beb6539fee", + "0xd487860b420b5cd5f6e30783cb122dafd8f95f8cb490fb41d7413ba242b50927", + "0x6cb932740f9ca018fa81068501b073572b59094e08c2ba40dd1fac3b9736a0f2", + "0x9213b4cd1d643ad6e6dd78ecc50901c3504f3228bc38480d4e2d80a835d7da84", + "0xb9827c89e2c4ded0193f841d1d93ba9a50c125b165b6cc578ebbb59e1c1e3c2f", + "0x4a60fbbd3d4cdd3a5afaacabb91d9907b54f24cc2c0b472a102ebbc04c6e1d5e", + "0xc34e850a8ba61ccdddc521b6c78889e8f44cf842ad051312842b727478b0dd48", + "0x428440624d658328e7f71e2b244f6ec1d76f00bcfd38ee1a6505041909dd9a3c", + "0x86187fe09c6da9685ddf29a8c707a8b8c07dee71af385570a9f7688dade56860", + "0xeaf224bd9a1646e0936a58ec76bea3f3c15b0905ddc1e42a65d916790696f804", + "0xa0323441bb548307f09abf7c633c0939af2ba068d330177702017865126fe665", + "0xbaae7f994479b34cc6c3a187ce69f769314e4b16cc75d8db676cd471539cb8b9", + "0xd6a97586d7d492d4eb7d4207438d3b260927913040e665b04dc16fac1790b7aa", + "0x93958dcf84bae3ac5abbcf8d663b512bd4698e52729622ecb110387004b3278f", + "0x726ebcb9f4402bcc67749b9bf0e898d6884a34bb88dc42bcaba0928b99de1ce4", + "0x7023076f7ec758a3e7cd7084938e54aa4dad0733c6f7ce5bd3f9316671afb41d", + "0x7cb1c651811bb0af1a5a20072295422f10108dff1792df72fa7300b228d24a30", + "0xc67142637f2d4e57e87562d3eb21d1c9f00743393b8741e2a48cb9c1e7c92501", + "0x3d1ece56ece2a5a8f9ad8bc6489fb9e7d4cda7aca8e9cf787a55e44d40c0eb08", + "0x222a3adca2d078165e2a23f7f5b9ae308ef2d1ec5df16e54c1d523b6f12c9c49", + "0x8e3eddb190424b16d955ef2a352fa69d0c3c91406903e20fc93baa163c448494", + "0x08d24146ee54b8685ac2bfbb67b2fc2d7da0c8cc1b31343cf83e36a076d588ea", + "0x029b75327ea0a6607c83b834ae5afb64fe7870d0e65f0411f4c0011d1bd304bf", + "0x51df1dace22285f5e23451d54f792df6b7dc901b15140e0227b883fde1bae7bc", + "0xc3cab27d73a2321c525e584a726f1c2ad950dcbab18be2c1f7a4e299c8c3a2cf", + "0x432581bd4637fec04aac93de42524f33f2cba4621f78a8405a2b41a4dd18a2f3", + "0xd0557870826a74c353e934ab21e08e35081ff7879f8b323e2c9ebeb23e3e3bf4", + "0x31fbf4768d13bd4ba011c0adfa7ec2182485444299797cf7d51bac3c2445c6a7", + "0x2c17643506d7fd5eff17b207aaf55e51b9cc67c2784db80b9f135a52625c3323", + "0x1f581185e5f13fb76ba2f381f37c1498400ec61578e5d562519a1fb7247b66c7", + "0xaa843b8dc6968a5fb88de5979d4883dd05bf23ddbf076d148547941ac5cd4e26", + "0x650486edb00e65b08acfc08e7d4ad89a9d1237463512af6aff53c7daf16a1725", + "0x234ac9fce1857f817601764d452ac136ae3f89d9f3fd5ef4253120faea881de4", + "0xf568041a9ee5d4ffcc8187e9d6149f282a4d329f1516d408ab6106aaadae74bd", + "0x3ff2bdb830235072ea6545663a12174a17a2f5efa070568d63a734cd70c3361d", + "0xd3678c705a33a9932e625164726fa3dbcb3fad8835fde4675223acaca58b6c58", + "0xe865e21f5e13042da52a933d94e447b90cd93c7b2acb0d9abe223ea5aa268214", + "0x14fff852295e2a1c907aa54b3472c88293df8b51ab2192292709bc92585d5b06", + "0x8a48c21de13833a70b1f91128ddc9819ddcab4cbacef213b0ee63a72d0c87f47", + "0xcb0925187bb428b7742600ccb0692612b49ac9c6ac289055cc668be17d0aad07", + "0xcd9555b8791abcaa3b670328e82ce9c9cc265241d49cd1c77c167b4abe48f3ee", + "0xd2c33c47d9890500febad6a4e2b78a9740917d47a228b3d10948483274cd4b5b", + "0x7861de7794ab5d325fe5b78ed99413dc5976d541555a0304f39be7d1302d99b1", + "0x3a3e2432c3bd72c53d8ed99ab60b5e1a53218fc08ea62f315d05da7766da5b15", + "0x6905579f8ac0193e528b0f86cbd679ff4155e32b8a6fb4a1a0cdbda543dfb81d", + "0x5f0e4686fd7c5ac11413571e716b03dde138c444606d44244ce4d3bab2916107", + "0xb1627edd75717823e0824e3e3689dec2dae9692c91a611d5afdc08779d65cdd0", + "0xed51b24152f2595ae3200f4aeabe1a72c2c996f7574db1e072fed52ec531775a", + "0x4202fe9aa1fbcd3cacf8c1ca8c616a531a1c13b63578925c3fadf66cd02fb62a", + "0x3875a92a2a1fdcdc0fea135aeb6bcce59cce6a493037dbd9ca3c19f6d96cbb6e", + "0xc865ea4be94423d94a6b84cc9f31cd5eca878e461d433ae3275512e442c910bf", + "0xf28c5b3dcc1f343561953f64ec545c89ced8b509c396d1812ca19e2041a17055", + "0x7cbbdd412cfb0b140a1e121cec554a418818bc17f80c1df69a2b43228c37f82c", + "0x1ad7f4a3431f8d2e5670ca885797b7eedc9d5ec04577e79a81406c2e503d0431", + "0x76f07c15d91f17028356f09f4407c020b5b9548f3c8e5cd2de0b37989091f298", + "0x75382bb178f190aae8dc02d266e9fc07b2e4faba551e619c0434682439e0269d", + "0x2b564f0a6e8eb4f829cd70ad7d97f379bec1d2326508e155b8d8252b9c2a305b", + "0x8418bf6714467d26e8341aaea2ca1442cf34d86fbbcd7c3e63da0e895d8b29a7", + "0x5a17e1b9ad15058155679d701e90f92989b75f12f02c7568dc31cfd8659d25a1", + "0xb21f76fb217213c6457654149dab85b87305fe3bf83b1805791c8dc2376e1268", + "0xf3ea43ffcdd0302c11fcae3551982e90af2f748b9ccec50b04e8435327cfbe99", + "0x4fef91b730cbedaed0049e0dc36bf14360256dd2449e3e925178cc46d3156697", + "0xec7074e2607bd5e0f228af7b73c7e39aad72d17019c2afffc3ab647d78939f61", + "0x53f34be1711c68f9a765da967c60fa39b72df4778e8ca7967404492f7a353910", + "0x6f0492df8bae724540b7a1462371edd74c4863c2c8cb6915a86545a36f06f77a", + "0x35898b077c19c49dbdd9415a6c3365636e9a8e98e0760d8b537ca12d5329c9b3", + "0x1a1c020207e42587d674c1275673584f0e239e8c1f2b4f6d8c98c97338bc182a", + "0xc46a3a7d6be035fa17a55b963030326d25c01542f4ec5cec431c012e5ac6d52d", + "0x0b29f6f0e29310a49fcbf18c8783d1dcee2997a62cc19e9c20ab524e6bcccd89", + "0x4b6a5d044ea31f51124c3b8f4c4a58eb9e7c922444d7ceafc76e9767ec2927a6", + "0x003e2e364412086eeee06b7eab2489e258aee32adf9c8700b3e33cbe8c594d7c", + "0xb1713dbc4a35cb1b3f4484eadc891d745dd5584f97012ccd5164f5662bf12c57", + "0xaed111e5b0ba48c69b8b765c11d74e5554fb0655d29ee73f8d38a52071bdac1c", + "0xe7d15702135fc0b830c65f60f74ef407291a634610b39d1dd6538b18f238654b", + "0x30d7bd4e83df5535c96391a6e4bd46d4081437db2911f8cba7ec40d3d626da37", + "0xb659fe1e992a428c553596567583c5aa42a297eaa3fc5a73b2705b03eee588e2", + "0x7174740915226124623dda7ccbe6a559246b8162cf5cc942ed4d1adf7ba86c06", + "0xf2847d813669654e775dff15b5484fb78f940a61f170021f0e74e5b0c4ddabb2", + "0x1acf93e0e1d6af4c48ee251766ef1bb2492fc25f94471265b940fba3ad55819b", + "0x3a8946be87b92d13f5668a3d48b8258c6c8d585c008d5a42ff460ef14a3ac6d9", + "0x104838e64202e4a90e8e8659f0508012e6aac3d75ad48be54fce69c1b536cc65", + "0xd80fa0b84016cfc95a15f4b01d50ecf4b06c7affff144ba226b24674b4a7b96b", + "0xe67240364fceb1d0b730e15e03aa92e1d88aac5c064da3a9225533ec3f7a3cee", + "0x74924dd757f836abaf12789a0f241dba89a42f310282f3e126fd88c96184f299", + "0x2998899e920039c7d933217e35af122b0e22d8fb8de987d5a607d31cd29d2f03", + "0x7e103626c39bf10a4b8eef446d6266994c5f841748307031f70aa23a27565a45", + "0x16446aff8ffb1ddb6894a7f62fa813d7c92c8ad77a797f388c9102055bd34524", + "0x8bae81870b92e523bdce4153102a4c46a660fa36e40ff0228043efc956adeeaa", + "0x0d5e765b9a18172b9a374782f22c3f7b1d5c8191c5b85f99539fe4728a8221eb", + "0xe256bd6c4c35dd174b2119941bcf44af1919616987b3fd3f2d2c67a56c0cb727", + "0x515b83d93a92b76b4d341b75c5b087509045451cd4c97c4d8f753f606df4048c", + "0xed27094e0e5a132112ea97fb3e870080b8a79c0b24e874c7f93dcad5b5a5928f", + "0x549b8ad126d1256023759a2e2258b35faec200d467baca8c37fb616c845977f3", + "0xea971d1ebe07c22175addaa244ecc91b2412bada3e72b5c437300f34c3ba07bf", + "0x3a892e84b04f593005861047dc80db8291fa6bcd064079b377034c9f68ddde20", + "0x7bbd6284646d4668a09ed02df281cc9e0d8f668ed1170df627e5469fb1892037", + "0xce47a83c1c1239e1457b46356719f525efb37a5a60a2e5acc135afb784acf00e", + "0x7d023404e05a3bbdd246b45d6af0af6cecf6366798ba49f220d5335d3baaedf3", + "0x5e4f0a84c2ea318e7711dbaed10bb0941799d4f7f5cc1042af3635c4c43369bb", + "0xf20c0ef0af68d2cf69e09e241b0211c32264875aadf5483677e53e221ca90573", + "0x77ba703780e366b14f7ea143c2319911c97397fb2a35f4cbff1486f276c483b4", + "0x1dd840bfb6128f00c5239c3164375ea008ea7bf5dc953c144f3971c72fa13050", + "0x0ca150e42d75dafe6437aa92ce4bc59557a7baa8eee01697b78b2bf889ddee4b", + "0x470142189b056c2962e3169f119ac26b43579a91aa27c61354ec283f88c4d205", + "0x61d1b32df70db397fda56f0035968f9d3d2bfd2fe1c3e7ee3dd65ead896be04d", + "0x4cbb9a330c46cbe61c2242813d01e4b9d96c9024c82a817d4b4c7118f30dac5f", + "0x8252357b329a1e68a32c75310704b51974b750062567aa88adc165c185a0633d", + "0x9d3aaeea1952351c07167400958033ec5136e884ebacc52b829b51459746326a", + "0x7a3abb411568a0b5b40909bbf547d5c39c53e839ccd68a86fcdf015ca52ecd0e", + "0xb51056fd9332adc740bcb96d7132c749abf02f1e281d676c451904f3efa38320", + "0x89d4bdebd8b6619a5d6609cd37c4ee4fc544df7a86c75d5f026a065a5053d7ad", + "0x7bfd3be6e1d68dad69c38855b80b289dece0a79ee4b9c6d0dd36cd4eb20fc401", + "0x0ddd4151934060f65f7fbcb7fdb2a617aee279367d4085e10674b16d8a5e4426", + "0x65ee7d3d96e335b086c4f6f5b8e5a93b4d0054f3f264c666acd39bdb86781ff2", + "0x79eda3ff5ecb743404c332e9c8710fe2c22e8233568e27b98e5e13021c0446a0", + "0x117ebf4d1e01bae39b6f95b66d95e057160d2177d24d26d628e5642b83250efd", + "0x29c35bf3a4cd0fcfc685dd5ef82bb23a539bdfa06907e10966829ef2c56d8854", + "0xb30ec9f98ec0cec48714d80d6322ac6badb4d0293c3beea4540da8f1115e0e9f", + "0x9d0ec950a87bb27eccea63196e9c4be8b91ee8cb8f14d58309c317124c8875cf", + "0xc3b5819646075f997c2fd4f79b7e7805440c1ae294dded722ddb22ee7fd7a099", + "0x098cd76c6dabdd013f588a48c75336631af0d14ed3b7748d12c85a7e0e93a313", + "0xe01ccb6a5f21f3c2a1c3761e7700ee64b7ed6192aac8b3f0e160f7b9d3bd0ac1", + "0x6ab889153a958cb336577c13db174174813360284c8f4609409ef57b7240565d", + "0xdf67e4ef6e11e4f52c052820d005d857c0eca882878b0a71bee7f22bdc629d53", + "0xc60703dda6612fbbcd3ba479f28c169b2049d3ab1f597c558149bc062d19313c", + "0x6e749f8217a0a51a926c88060c8d349ccd85d387c802c40b20cb87f51586df1d", + "0xf29fbc40017a9bbfea1c28a74c3063af72a510f9c99c0e981c3fc9d83ddc5bcd", + "0x76cc861f436ee8a3f1c07b644842ed5457563812f60756edaa4927a047ecfc43", + "0x84e7eadae3bfb61d67e53e00aa45449f04bcb50e215835687d63665d6bb7df63", + "0x8deb4b71040ffa0c5cde5675af9b8f9f4982a88bd01981258e871073e19c759b", + "0x3a7ac758caa8e2def1d290c066fad3d7daf68ebdb7f1d5b5230b3c94262315e1", + "0x9319124b08501ed1b53e06290face78c0f7b201fc8f812f59b469f6fd30581aa", + "0xa2855c6f26e090daf60fd17c4bcb771fd5611b9e1413136a3fd21eea2be7a3b2", + "0x82ed06497f1bef352cf027589d608b622569559d29f3cdf652f68cbbfb684c19", + "0x74321929990b5436cdd6e0953bee4fd5bc02f84e19c9a3bfb40addac61fda88d", + "0x47d4b298d5335cdfa6d09c16cf23cb98bfa4672a0fbafdd784590cb705f14daa", + "0x3d7863b734e1ce7d3a7bb0c955704106649890b4d673e744b8aaf8ffed36be6f", + "0x14abd96e4b25c3583df37755c51e384087f639fd5ebdec4fdd50d49017cb90db", + "0xbad65145878c7c313373306d6321256f8bbbd06cf58126f79c356e7ceb6d0301", + "0xc1f71b60be43810973082ae2a0c690e738992a3613b7c8286eea6b211b1b459e", + "0x1d18d20cc0279a7ef9921859fd3d0fdcacd66ee295f0e5bf6812346fe54a014f", + "0xbe49d176e2855dce010fe941b6098d6ef74e271ea846644072b6e508bc239044", + "0x828eb859148f295e5a0b2ba813b43caff82afbf32946e0bb211a6034b93ebfe5", + "0x7402137aa16d58ebad277698c5412c5b756796150594de6ca0f392b04b7848f8", + "0x58c83c4de55a8a562642bbd571d4c23a8847f8bd14e99401680337e474c05fb7", + "0x213aeb2dd7b400827c08dd326699edb7c5d1dc2d10f2f7cd43f4f3363b3a053a", + "0x7c4b1c80296fc55182b032ce8786473d56688777b4603313f990685e6512bb02", + "0x5857ef59c14c702bca8c358b55a2a67291064849e320363f484fe6552d8a4ed7", + "0xc4f927602edf49bd2f50c993bc27ebdae82192ab786a734679b6208b9d0c480f", + "0xf5756d9aa1f0f203011b0fdc18279ec476cd24e9fe3393e870326a4922c8b6f6", + "0xd3d892f6f4ce7862ea7b47995f8e80264f460792682632f8bd2cb01c67570181", + "0x347baa7431a293543af9c144f83b2b8d8103118c81420d61eadea1820903e9e2", + "0x01ab0e1aca21b0875155eaa8eb561ee417127a3afcfdb93dd6a0971e410ebd35", + "0x7c72ced65914db2173b71ce0e3f3ddd08f1dac47bcaae0f9083b164058d5c056", + "0x77a88cd8f15083f876b0f6f928fc4effcd877c837fc2fdb58be16f8172cc7784", + "0xb40653715c8da901293838858c2173213ee3a49d9e85619686f2e2c2ab839c6b", + "0x5d3f9e2521cdc44f2effd25d56778790464ea1ad23d141e93a30bfda7157c9ab", + "0x3e0beddf45d506c7c6c25f5478074d54d7f28f627a8df2eda5db1543dd1e834a", + "0xee28b0e24ca590a5a1655ec6415c1f57dda0183d6b542501d1e964dc61ea3d6b", + "0x3932f898858fb695d39a02c641eed26246be0754b7cedaf91518ee8a2b051fca", + "0xd9f7788a59b6d6e43748e1f1abf8060bd23555fcc5c9b4987977de0641f28fc6", + "0xd5297bfa280857285d58a24f591fa5a7c4b575fe7318cb531a445d24136ebac4", + "0xcae4abea8b7698ae9e55d133a676b5cd611698492fdf0f7d24ae3decd7d1a389", + "0x0aa0ff5bd3e0056d6663bd54ca7663aa2bbea781bfea228a4467f1d0192a7a94", + "0xfc872737974fef46448fab89d5811a61d8758aeec65b20c03a006a98e3754edc", + "0xbe60d4cb85ddd60c07bb1584456852bc36b72cedcd63d5c9b302a09b14cf1bdf", + "0x755aa31ceb9213270dd40124315d413cb053474ed4a60253a5d6dbac512c7744", + "0xb970b237d42706d556c9571b87466457d6e2de4d63fb405c9c7fe3420f35839e", + "0x977e976fa982e2a5ead22edd3dbaedad3e6ae885f00c0f48b4555c63802ee930", + "0xb4db2e220ff78e7a91cfd2cc31140f27d45b2043cd5147e9ddb9fee77c57a5e2", + "0x063e555581897db6caadd7a1c3a1a2a87719f729b0f43b9da7cc86460237cbad", + "0x4405a8f586646aa49d47073bac9c864c7346119a977cc5a154aa6ad70a50f894", + "0x87e09cc5759cc1b358d20955f97ff0e403c31a06d1f6cc6dc96f51a80570db40", + "0x432c4d29b6908bfdcbf466e3ea1cc93b64a6160748d4940ae6f95b45a804916d", + "0x64d99506de841b4b8e741f021be26327fe9d7ed2e4f0f635dd4043b7b174fd26", + "0xfd40a7dcd533928a2ee74ff589ae38231b84e72d7528e90a8c904d8762e07c4c", + "0x907626552f68f88c36192023bada749a6666f9a0b295f58c2e77515baa1e6a2b", + "0xee4c1ea1d8bca82456345d114085f34485bc44ef62aa60a4a74d7c2a0a681e90", + "0x81c59a12b3c1ff323be43f0d9d1fcaba87edbb344493ee1c426cb814b7e11509", + "0x11ac288f0d0dd1bbcfb335081a0ba30a74b6690b0dfb6290312b99450f257448", + "0x82194511f886f7f93b8b243401c34f80afdbfb5a78774b71a4334de6128c7a94", + "0x29f7f0319e09462e906ee0175dd3c10b09600a896cc909e2c0669a90642059ca", + "0x5f747311bd625822725d2d665a3ae4e3d39d0476bab0b4ab4d314b034bb4b581", + "0x82d29ecdbb2b66248fabe328ce0f441c904b0935f0c572fd860b22cef7037e29", + "0xb1ae4eac81c4df41cd26df2dc365a09696eaffb0bea906d3a24921666298f3db", + "0xab305997885a76e7adebc357c78149ab13191eac73807d6bbcf189ec24447eca", + "0xb93e7ee92ceda5b17d5923e967817c84239ae3dfc4f932f28f4ff12e3bba4b25", + "0xdcbea5c2455d6bd4c01ac3da32108436a11d8095af5d02382c12e9adf64ea941", + "0x379af62a4cbc14781860bced0eba058b58167966d5ae31a9545e80eeb8d63207", + "0x61e403db38f76e0d93baeab28958999670da2a94c489502bd2e3b2dc14049e64", + "0xaf921bc1dc0550891d487a700625147493f3a2521545f0c8e2b479578bf5469c", + "0xf18e89c738315e1e071a7595b3e78f142d5e97e6b55b8bacd2de3cd66f5d44c9", + "0xafdad2f30f695ef2e7a959b3c2189e27bf99e161e62bdfb2aa2c6a2cb38f4a33", + "0xbf17fe640225f213c991e813d23e532f5b28425d5e0505442522e7752c916d40", + "0x75a408cbad5625e898f00272476660c2638392103edecf964e17af303d35c67b", + "0x5069c2e3c907e243d4128b4d47e9738273f5f8c2b230b2172ab53787179a66a1", + "0xfb05bd9d9025de9c9b9c1d618f7e3b965b78ef6c05933ea01600e0dde4c920de", + "0x0348dd9d08fc716d85e68ce68508f7565daaae39ff9cfd1242bdb7be4ca9eadb", + "0x356e5fbcfda0909e6881beaf83310addf858aa5c26987eaf6226bec120035557", + "0x2c86f13922af8b1d58416b1fe079176167ee91df9a494396f13c1961b71b1826", + "0x58b5511b329949547f268318f4105580adfff4f25769e50e418bc9a418ea4494", + "0x3115256a0d6e2991da187eb0af2060a4bdb8afc5af246d9399b7cd5861520dcc", + "0x9512ff6fe3a05d2d322286a1ba4eee64c2bf00d7b868b98000cafedfb0f7c963", + "0xe0a81678dd4ce59096b25a2d1d0e56c3610de0b2044655813192f97b36e71f42", + "0x9a796aaf1293ff33270ca51338eb3eb4a180b37a9a6e8e960c310de6cf885f11", + "0x4fcdd484426e7c1311a334b8250f700579b4a62604a4ebd158a1263ab47e1253", + "0x52ffcff66546b02f93ecf999bf048f0e8bd80616e0560984b65c7f946dbd33db", + "0x10b276984aad9404c37747daf9afb88478894e44a38f33f645f9da1f165192d5", + "0xee534544d636177fa1974cdf8f038d807653d7f4841a3f1cdedd39e7fd58fb07", + "0x18ebf306aeab781847e0c3da286ca9fd3cfa5acb3b68cc8f0b96cc271bb5172e", + "0x994e4471831fefd58bb7ba9e03c36cc1449b03841f03dbe9fab64fb2084c5a54", + "0xca6c753d0d81b8b693d7ebb550e4d2718b495f22739930957fb17cbc15cd869c", + "0x351225ff4d086375ed5fac1c0ae4c6cf31752f8e65b8088447d006887f00a42a", + "0x4773707163e4797efec803c6b85afbf8875e789b3257df2b33358774d8971a0e", + "0x6424bf0fa6621a2fb9c166ee73750058fe733ebfd2fff232fac6bc73b55e6357", + "0xa5c1f44a899f63c1450f8ad09055fdf96ef84220fad238727ba0b04d4d6a3754", + "0x2b03c1dbf99334ea961cd71a89d66fe760dfe87817b4880b34b5a9e85c2dd917", + "0x6b13ade490bb62ec4276e334ae01628eaf41dcd7e773a1c13b25810535c4f4b2", + "0x7719de48b8d8c359f0159c87e6fd1dfce479bb886e4b002512c4a3cc2ea6bd05", + "0xed248d16dc7f1ec4f2c7c162149622109fbdf7dc68d1ccbeb90472813684e36e", + "0x2469f1bbaa3a55609ed6d005293b9d332feef0fedb660f3b09734687b48ed88b", + "0xe40e469aea7e30348e37b7c2459954ba02a4968fb713cea60c4bf9fcdd3bbc8d", + "0x66555b4b6a22f8252c71ab1f044f3ffd6474b88bb62fcc55216dfd94f457c916", + "0xf9c6bc9f84e7d0c31db16b7bcd54954427b4b43abb3af59ed122239c2b9f1d07", + "0x5d0471159044b364f1c26fe60154ee5cbbcd87a3c9d5b1fe86b5990f1c095dcb", + "0xda4d4cc6682bf9e162921107d9b6959a0fdbb779067ed659bb5140876527add3", + "0x7025c5eab4bbb5c5a0c8a7e6b845af8c9c3d02ef962e68bc0d0ab8862e2c3562", + "0x6c49e64964290c82a76c34a204bb445a0a00d68853900097325ba2c0c2ca5900", + "0x00e005674c684df70927a02e34cf1dc29bb341730abb46c89a764cc82f4a798a", + "0x3ce484b749d7f4c1b998f50bc10758871fcf426c8d70271c023b0fc45107554f", + "0x76900e52ff88ff356bdf3fcfd22613e064078fec47702a8760d85ddb592111d6", + "0xfc4979821c684ffe76894b18686e80fb3b67c8c317a22d3d25644421ace52acb", + "0xf226c6dfdd8a4d2a1ce8254b16d4ef99c48085fdade102aacb883d3e56e41a06", + "0xf858bca588f24f7efece3e03303ead92f66612723a0f68b6d1a871634974b8fb", + "0x672c9adb58bea50dd89e5d41196c93f4ee712c65681c918a971ac2afca43557b", + "0x1ebfba17221b1b101ab5119477cebb8fa6c2f72b9e282564dcbefdc8aca27688", + "0xec5ec768be531c250cb18850b92217ab32e6b8b9c080d4396f4e03518d328986", + "0xe12f9d598479d2462e429f4e3e249f676b383e51edfdf7ec6006dc23775e1372", + "0x93831b7cf4cc14676927d3aef0ed451dc1cea97945774d397b0588cc06be33c6", + "0xc5548136a5ad06f9a92ff95739223bce42a6bc19a92fbab0dcafcd9a4fae9511", + "0x7f6d793bf0692dd27327e1644cecd04d2dc0269c500ac192b504fa0b415fc23c", + "0xc389a64653eb7f37a0101cb3a2f989bbf03f0f6e07810883843199a33b5c8688", + "0xafd6cba91cc7041ea560ae01f5178828c8b934f349f1f87f6a22a6bd4b68b2d6", + "0xddaa7e0081eb38fcfa889e04af7703bac86baaa0f40aede815da9376657122ec", + "0x3b7c7dd378b00dfa18fc416fe471bfb07ce82c113591e4d1f2ba742409788302", + "0x22152aceee8ac16057189e13f89d118c5555d1061c6276634177071c4e85f4fd", + "0x82bbc14bc483184e2eea54bea9f105d69dee2ffd8d598a181e9894f0c0419e3b", + "0xd9b019cf461627e2142b04ef8cd394f14ef76c3abeb8de18b24e4ed9451bdd2c", + "0x93f6304908849980c14193a9a28b1976193263962bb85c18c45ec0e4c98c7dd3", + "0xd117cd674d8649fff979ed3e20bb63ad3a0bc7395d9428a8f7bd10171f5793b1", + "0x58f9a406c5c1cda4207f4f21def9118b4711ea39d8b93786f03458e5f32b144c", + "0x0120c549d680bf513e54793ad1794e34fd1748897e9b04d57ff8f1f3638dc926", + "0x5340b317835453c590fd71b022f4c984ecdc7e77f63ae694d50531a2cd8874e0", + "0x0a15038665e01f512ae7f9a5eb5d94600192470fe84b4fcc30e43d13a2c820b2", + "0x74815b0ae52ab519317e97cccc47e0b29a3e811451454adf7dbe2e5917497109", + "0x9221b6625678681475dec3689d5aaaa73e1098fda3786a72e04e04591a79c91e", + "0x7f7e9a8e73f9319020ea8ea7186c097910ad88979e1885a37989e1950e4a6c21", + "0x331f70cebd073b64bd396a96084de6da235b99eb18e9b3a608f7674b7c84dabb", + "0xbee7c0dcfaf95f85e6c58821f4aa09dc31285be7dd79160ab16cd68ac16ec96f", + "0x8b9791f9b84251d68b2125b61cd919dee74ede9d9b272a313cdcb3a9a01ec0bd", + "0x4194670a50bc7fb2ad1bd9fe60c3cdbaef8a7f9d5338ada0f4f9da97ecfc33e8", + "0x84a52e69f543539031ebb0aaaeaad905243fdeccfe87f58f38afaa0ff51c3641", + "0x12bbf63c2c6f31b2e57005cf99d7ef172df7ae01581e487f7e405a2eb8b2712b", + "0x6e1c0adfd156c3a64e0f342e0ef852d24780bc0c132a680c4d90bbd83278296a", + "0xf47713191d8afe922e2ec776edb9d9fe421821ecc2c51a4a5d1934e2566b660b", + "0x3d5ab526f48ea24e0fab729855e6fe4537ff1f4a37d423a797f261e936cb489a", + "0x999b153fa9a46778f806bbc1c110293f3f983b85195b55114c4cd605475c01cc", + "0xf4c934c4caff6611fa407b37c7fe60110c5b37ca6476f7da664110ce606ec887", + "0xa0e3ce8072926c2828384be41b8f2eaed77b0abf80b85bad1ac4ecfe50a29d52", + "0x1e0fafbd1b5044023a711acfbfd67f706827fa538f1016dffb14d78d742133d8", + "0x6544bbbe74274109833f0df8f5de938e5020f642f59dc15f44ef131e71364168", + "0x7070469ad96756a3b8eb3edf8af72c34426fd54b543a50bf90f7df4f9e6cf502", + "0x17d3adc89215b44e0ae066793fa92aac625a4625faac2f1af0dd7443ae88263c", + "0xac82f48569287d701ce51f0fb8d9ea9b58389bf1ccb14f51af0150ae5520d067", + "0xa345a1f7a2b62e083a9145bf72156dad96db87cadbb097eba49c1dbef37e7678", + "0x226cda69f3165f38c62fb320575370763c38ce1219612c8fb780d62e3724edc9", + "0x90066ef34898e0bed612ea988b9d7dba8d2752e5e4433eeee338ac46d0ca0e6a", + "0x13a52bc644a897f92b9c04f92153c3af7cbb7a8c8322eec5d2cd7acc955e5f14", + "0xab1151bb1fcfe04cfb138f6115007798156fe6ca34bd2d5450e7260369c46cf2", + "0x1ada842caa8d11d6ddb1f866920ce9d211d12681f0cfeb1fa953412ee72a6202", + "0x0775361415f30fc354811de5a09d152ddea119a45777e324bae06f605aac9a1e", + "0x3341e88e37257fb40d904b52a555e5ab4da77946feee8d0180bf0d02b84b2743", + "0x6de86152df7502a805cfe3ea13e6e92fed6591bb6807bf52ca6cc1ad12581960", + "0x2df8c525fcdb9e3338521ca003ecf34c0accaeb1ef8e8a8c53a4760e2a2f76f5", + "0xbfb79ba6c601d99fe9da4fa5d3156d43361e19d31cee9d8f6d86ccf8fca677ec", + "0x242c88cb05a573e013355f668be14ac02be3366f4529825e970a824b63ec955d", + "0x28cf8683b9301699cbd52ccd2e2382f0214b5375d45ddd1f512418955cbc75e0", + "0x962491665ead2c0a67a89c9cb10a95df482bde95bda60de9f9e26640262d8df7", + "0x89d44ee38abfe8a782b4c8ec4a15fb613da1fb54df1216b401e2b9feb5722640", + "0x22c65f9ad5d54461e990a01a32b3c0b816cb76fb6263916c7439d3a38c1f6e6a", + "0xb9e22056d59bac9dfaa70f3cf7e882ec54d12b5c651faae9db639d514358b19d", + "0x9e87bf3cf128facc840148f5992319455da79eb5b073366ab55935927325deaa", + "0xfda17f28aacb58b521e21980e1690292ec53ace1a331eb3f3e39ab47891b6818", + "0xfc89489cc181a41c11db271d24d745c602d021175bd8a3216466222f36beb894", + "0x70a368c3eec8a26721407652dafb467accd432a781c38c394811d4165da0536a", + "0xfdaacc8fc0d6a88b09f6e82a854eb5846b534cf709f74412a52ae1b73eb71eca", + "0x64dec3cbd894ef0acfbd4c756c57d1158b8735b9daabb8867a8fcb314c0d46d1", + "0x717f95c3cf0ea9fc9b2aa7da862e67dc5734dab7b901ba843fda932c2f4635ab", + "0x9832bf9af748a6a9f92fc7f808a10055c8134f6b9698b7a22c65889629eaa321", + "0x27556bf6b3b9f142af4b8b164dbc7320d838fc2035392f544e8acf891993908f", + "0x698c66e02954a0a3a9e20531427de5e111324dd63a3c17b3c9ff381591b209e2", + "0x15df8156e8722be5454f3a18da8f9c327626dfcadf8a43ca7053c2343b688eb2", + "0xc9012320a383a0daf25db92d3b2551542d09365e52ae17b0b8aa164804cacba8", + "0x3ec2163f659c467408d6885e2ebab399bcfed5e82eeaaa18ba9b11b6a7092c67", + "0x7c3c061c68f913425190d54c5b3085edb6f7b644938067a22d05b07252a2a577", + "0x65e7a85d7c9b44b46249204e20f5ced1725aaaa46c298e3103733116023af990", + "0xec90bbf55a1dc23fd2dce20458e9dc4155d40f35a6508476693f8f33e3c5c603", + "0xf5c3fb3cd7defd40896125d0b0651ea51faf248b1074630d8522267773f70794", + "0x098cd8401364b469a398ce063cd4c0dd245780b80535dda05d1cd318059a0e15", + "0x36a2403988d8284e774c519c6d5d60737de41f5e79a3e68b21c6e3cc31d99e3d", + "0x24c048089205c06055be2af692e5695e0b21c862beb1d2c76b73453be1aea237", + "0x4c6bff0317e1d45668e67bba2e4abd69fab7d49ebcf25b71596eb00b7da022fb", + "0x751d9aa08945bb12fcb312d8d9582cecbdad4ba10443a11c76f2336354db309f", + "0x4d15a64bdfcc838b9673813a073e6dca2e7cb8eef5c2ca9cdea367197d5d77c0", + "0x1857138e6b90b38417d9524923c4afee7815cb4b0a023b5edaa7e1b5d67e956a", + "0x9bb20548865f77267249f8934e8a7ef78630ca2b1a698c20a1831d57c40663d7", + "0x05f1132fc8f3e9b6e1fb8a798324249eb5aa7410e87b28549dcdbbd981995276", + "0xc62c8b41c48fc728ddda25dc5f7f112569b1ed7fdd6c9cb365012b6c92c063ba", + "0x36a336dce4c079c097c13378010261ae60d7614758bb1a644c1431aa535fcfdc", + "0x861762f37bac1e99454d486daa5586b7fc16ed3d5f8a3d4ceb76b2430b07176e", + "0xd52e37befd22d62f41bbfe77d3236bdeec8c1898b66fa74b8cdd6f35a9b02d76", + "0xceefff0fe45933ef72a62168b853824feb4af74ae82804fd635a3cbd554994ee", + "0x2743e9884c5b82e2c96f51859c4488fa62c174285a884d8d5fe37c134cb460e9", + "0xd14b5c588e28af7b69c0f62a2de16a19e10a89b4e0b77fa9eb2220de12431049", + "0x7a6720ca354c4749f0fd338049b84e2c018bda8180885e137b43aea736d013ae", + "0x33d57d2acd57e925d5e72e9a9d98bff821e9c0c3f3ce0862b5e68d1a81578509", + "0x0376d061cd94b3add12e0a224fc702bf0c661ed7540388fe2d1c0e45b33a9575", + "0x1b7f9abc9e995ad6d501085bce4ec8cfa283a6c818f172361839a03463c1c823", + "0x91f920bc30f075c30faf5ca2800a3d98ce11f1ef4dfa59d59c48b0e3c72d77cb", + "0x12bf80752456d779accd274428b53aeb15a1f1a47c0f85150ffeebc3ab1509fb", + "0xf75bc818dd47ea5e36a4007bfdcc855d48e057ffad411bda1874c4ea9290560e", + "0xb3373cdff2cee48761a5646faa2f470bddd2dd7f4e5b3879f5c57233581c11bc", + "0xcde2bb6a64542ae77dd1823ee1abd29e5bbdc9a8a987c4cc0c9e961ec01aa64c", + "0xac9986cffa116e9b974dd5e9eb8951b6ee7ff8feaefe33bbabd072c492098e52", + "0x175ce1d341322690675405440dbad5dc80d5c62db7883bd58887ae4e8991040c", + "0x2607c713b1a38c26ed1ba5574fcc1ec9e8e68a7c269c1cd687d4afb71aa6607a", + "0x1c83dcd846cb1ba5a56311a799bbf6033d3846b62bc022fa8c78a2f045a36b6e", + "0xf07919693e20b7f9b50c0745ded6f76e3b2ae6fd301548b297eae87c4f096d19", + "0xba1e5393889501428a866e4e1f1181eefe7ce96c023341b9a724f243c20efd98", + "0x5c8363770a2fcf8e6e2ba1f384769100490509fa776a609206177a4cc91baf49", + "0xdc1a4b1c138f9e7157f7fe476ca93579f77b436b512d7b1a92cd40137fed5a32", + "0xaf5630fa700a41ea1896d8745c484dc51599a45f4420b155f532acaf70159930", + "0xbc42efe8ef2ad47223310e252763f03081e72d3b0fce31cb8a92e535f918cf7c", + "0xb3c82090aa8e61d3cf66e68324b89bf0c8abb3a90a7689fd0e2af475eec12796", + "0x0b9292e757146f5c82e38b8c704ca9d17bed72c8f05abed2c72e4b749ca95cac", + "0x1f001856caed8f92c04803e3673c36c1e6d44c54fe5a2fa6dadc0f647ce5a5cb", + "0x4f5d9de1ce98d143c5e4230da545a92ce2adef539b28b3ea12b058dc50516396", + "0x92eab7aa903c1c9672cd846dfe59daed08bf7eaac3649acf82cc10d257c4ee83", + "0xfe53e9046375699c9d6d1e97f5394e4d9dc47247962cb12b1f19b14280c36e68", + "0xf2b4013bf20360c30a02719ac84a1fbf1d4f2f75a13708fb33698b404f89643e", + "0xa2c42fab1a55e7ad87d3d6ddd539cc015672bc7d9945a0b095d321ac5f2d269a", + "0xaa19e88d2f0331d9eb6982cf6adc3867765a30aacbad4636c6c14075debb3f14", + "0xdad3369b52216bd1d5670937e8d02011be203600f9e0a5971083478a751c158e", + "0x95606ec86211580a457dbd3ce345582cb63fa1e51bbb26e0fc7f66b346c5b165", + "0x3724ec7e644d1c9217a4530be31b164d132103e137d78ec65d7d2b331a58e176", + "0x3c9a30656517e28897e13397a1aea4320ce012365186c3780c284284188820d8", + "0xb1e5c6e1fd3acb6071ddfa21930749088701625cb28b632605f428034eb40599", + "0x16cab690f62af9c4532518d5d44adc79294509e7d468c8320ddc6a2af947e00b", + "0x77dbcc77ed87f3abfba8593ca42e5566509be4045df7b1360a147380f4923a18", + "0x50a81427038cbbfa9d80e7c8bf81275e87ed12329dccf818e97a2cf8fbf18bb6", + "0x535a32f20b009046f36d7ddd94803075813f018dec533ed87cf106589f1a9365", + "0xc09b4db18f62c39052fe388f8d94aa894cfce591bf868dfdb6d9598015c373ed", + "0xcfd40ebb21db79e7afde2605d7fa23eaab3db5ed9c0fdfa3310b80e839c3d687", + "0xfc99454fc2feecdc233ddfb15f8248d2e5c3c3b47c928a4bc47347cddf4abbe8", + "0x6591ce7a1118faba148011194404fca2a0d6731171ae29a287fc00aeb02adb66", + "0x109290c341c44b3e85d45d772853217e13388f406f95ae6f1127d574ea12ec53", + "0x623a639e40ebb08f05055465be038aadd7f8db549f1eea2ef084afaf199e8a66", + "0xbbf06223a713f88a1f571517792c0af039985c8f15e0fc803b7dd7c464595715", + "0xac7d49ae849acccf45e6318e4cfd18c03416b9bacbde64ded23514d59b716a97", + "0xd62497729af1b32f0e22fdb503a750c85a10299ee966e5c5ab1ac7e71e5524d0", + "0x29c2cf3cc0cdb9799e0593902ee453fba917f096f7eb5d04418ac292d9d40463", + "0xa5524f355a9fd8bfb4bfca14fcfe58d227a0b8d723943ae925bd88613f62927f", + "0x558f4140defa8a45ce60cd2297f60656454fbb1306d416229d07f27f18531f93", + "0xbb3506870630199af605f63e105c9acc9de29869b2c67661f3278d4d33b33d5a", + "0xc3cc4b6e3d14f45f0624652df9aa2aae5bdd6e9824a06df6d66572afc3ae7dae", + "0xe1070ad4c886c4e4e118541e6c140926d2b2463701b293527a91a165418ecab1", + "0x22fe26c7de8606e08d7cc1e0e37a7061c9fc50da3581c1441c0331ae32fa18d9", + "0x71800db5261f61c5525744ada55e570bcd2820eca92f30bb2e83e3f08e03edba", + "0x032839dd738ec7d5e43b84ac14adb11bd08660921c1f12932cb64ffd0179d343", + "0x85a762a2ab18668af249733829cdef9e3787bf2d2e6ab9938644918c0c1b51da", + "0x16d578dac1dd575ff991c2d25e728973c1ebc2b61a3032c8b85b62258667bc1d", + "0x3f1455a483663459733cf450c0f0e16678eb1f5485a6cfb6174630eac026ca6d", + "0x029933e53cad5e16256663fde9bda097abba5d7327e9c0fab07abbd013e14ea0", + "0x657b61028b161a1a3bfca40928375621133b0435893dd1d2562944ca85afdb05", + "0xf541e675935600a62e60bf5bd98093ffebc0169f23629db977dd8771958f3cb5", + "0x8c43b0d7c2293e089724fed36851744200d9b87b6600e3ca351f3f65852e5eaf", + "0x07c6c657a80c5718804544332c2f68b445e8d7fc58f01a650d7a476c036193be", + "0x0d38f9aa48346458b8ec0710b28869f4bf979abb80a4ea0464cdd9da659e0db6", + "0xe39b8a792df028169115125cc8466701df553de20d1ea385f3249a1d1c13703a", + "0x77180591ba49b6118cfc4ef772aa9a1cf2b3d1d67be1f15c308cd0727dfeb068", + "0x088d7d35f2b14bd5d0a1b6f3510ffb4f8ea2d054f3f6b99de8fcd7bc7dcb37cb", + "0xdd0bf242332c127c0e63e535ad3ecae82588ca70eb04973ed89e29a81a65a17d", + "0x218dfd445fd02c980736856e5af70942dcad8a0600fb905f0b4684f317ce4f19", + "0x1574b6fd0411b9d22f10a2d19b0a681d163c7b969e9a608499ca06414e579434", + "0xfb0919cf4bb52733e14989e7c4de84cfe6f06baf792f7936f3d3ea00efe5712f", + "0xceb92288daee1a5e2022206783d3d069b7bd1edc00d3fb6a5841ee1cab207e47", + "0xe2cacbb8bb3bf3877506499ebf8e8ab83306482f87c24ef6ba95dd40a68ebffc", + "0x373dd6cf736c6623843087cc276480576edcbfa873cc8e25dfa6f4ed396ca9f2", + "0xf7872e8c04a5766a8773d1af21d79e63004240b9f9caccbed57f58162e4175f8", + "0xcfe8a827fc4c36fa63990b95b90c68a684d4b792d20b8d786a4e1b1d13d3f935", + "0x7641f61df9b6f40c57815df7ea6ccadd757094a7420438ab310bce4642412ac8", + "0xddc8f2276bea73f13a3b127eb637265190c5655f4a8ab75cee2fe739277dffa9", + "0xd7858cc623ace8f1d0d22128da9729c9e9d3f0b56ef3ccd33464c1096d4f5811", + "0x4230798246b8939b83db483d395829d1d306708d11e783e507dc1e3b49490b3f", + "0x89209a8acd2568a49a7e623b5ef5f43664c41b9d7923d0dfa5c5ef6c7b8799b1", + "0x104b1b2826fa7d1b22770c1bdf6810b5e72d384ebd22cf9faf6ad3f348beb0c0", + "0x1a7c94386ce7d3028d3370aef277d852a7beb4d10127701cc5ce10a1b044018f", + "0xb98519653520206971618cf9b6ce2c1df8e9f471e8889c7b5d57d274281442d6", + "0xc890e325cda72421b2aff2785b0d917b02722e48d7d4b04b0848ae112b2676d3", + "0x571c5944b46c3f9a0cd2370864355d5a8a84688094cb216cf525541c36c11396", + "0x0ce2c597798c13d44ced6fc8d2a25f2e2570f2042a2563a5b9e44e162ca34852", + "0xa6fdfe84cb052109bf80190a9b031b8ef4af89fee72171477eb0cbe77a231350", + "0xb3710d99697ad3eb32af332e1e1466ff14a36eca12f49353134a3ebc89673174", + "0x46dc128448fefeb7356c6a2d4c7d2d067c04aa1973d6d5dc5d0001a08641ef4d", + "0x7e29853c2fb2d83356d63ed3984a068aa77570352cb488982f4852d52a82c2f0", + "0x796684dfac249c4ff804ad476035254b150ced67fd5090a870d684e7343bde65", + "0x3e8e5a22737865fc518ba785a18d3fba861c131411e2795920a1d8714ff76f90", + "0xd60787dd997a22b2faeb6e3257613591f73966e39b477f196566031d7d97f79c", + "0x143b777a1ab7f233c88ac126fecdd2b139a73d27c2374a14f59d6b2a3d274c07", + "0xa0423fa816199bacd23116e13196c2dfea68467f0bb7211a54edf40cf8266a23", + "0xaac1db2e966c0786bbb0c426a40327cb230231f105a27e99c8dc8d5a776f2aa4", + "0xa5925ea9ca18ec46e986133e5bce4381b4bdb34a2929da9266d63fed308330ad", + "0x9486ff72244d82f0521aa89bdd4e4ef287c7c8b9f11919fe5e169eb680162bb0", + "0xe5590a8ad9f00a25d6b1c7bb7972322d4c7aa0d168c2d64dc1c1a2cc3e1b2c5d", + "0xa4d19ff7d20981880824a2212a5ebcde16ed294a1b486648eefdb4e61985e628", + "0x42008316906fde068656372ce9cd086d98cf48ae6c8ebef4cf2c318f6196ee42", + "0xd997400eb0679ee898e3591f612f12fe62a8a512e9f29bb5d892828a717cba44", + "0x8cb77326590d26e47866b96c7b0d4a2cb098e9c3302973c355d4cc6b7bfb9a39", + "0x5aa47047d8dcfdc52cf5eb6850a29e18bdd5458479a62ce73e390da48019908e", + "0xb7db162e7bd3eca38c26b81c280060e0a80afdcb1b1227f2be53a104b7bde92d", + "0x6118fb183a607ad2ba7977b23d55a13a13c23fb4d42ffd025829684619cda56c", + "0x57d6217b90c06b85cb935a7e662a0bfff6bea628d67148fd77cfb6d4aae46b3c", + "0x8f6ad6d46e34c419d675f2e11fd9415dc0051034dd2dad492992cab39a4134e0", + "0xf02b43c671a09c3496057bc12d546331de2bc68cb18c64c4562a7b4ea09400fe", + "0xc0715798ea2098d50a16240d7764ec79ef0a888a46acfac383e72d2e50c6fd45", + "0x3f87cf2fb3973cef48f8727096633c517030c4fe3b80c8de5c46b7aa7688a7b1", + "0xb3eb15c04da4ed796f22c6f9a6d9b650e49092dd775870ffaf4538efaa9143a0", + "0x0858a7432451452d8f99395811d8b9605b6e493875cd8f6efd38ac933f843c21", + "0xe8d6f6cbe3fcbcf1a8b670b57045c9163e28e62c2301518667869fa6154778ac", + "0x134b94a104a8fe9c8fb5b74d01e8137b998f9691844fe8f6a22634d967c70c29", + "0x5ad0ec6ef0efeda0f2a0ad2a693eea176358a6298e0d16014c86e17f45a91418", + "0x1439519977d98a556eb1f32924f6206faf316ded77c7e6624e68e139f99d2ab9", + "0x50095fb3ffea338cf7304154c4603c41eb187b7f19d356f1f97a12aa4009557e", + "0x40d1b045015f62509696d3e0c71ac234ad594c46814d04d7cdc76f91d848de89", + "0x5f1fbf6945d348a53089d2c9d3feae12b7b2981b33ad5242eeba5d8aca474211", + "0x016e294adf2b7ed329e71d054920efc2399eaa9be90ad0edcce1a1ecfda74b2b", + "0x13dc29c28adef710976342863d04ff778fab90c34b36932cdd41d176621c517f", + "0x3cdaee5da98612994b8ab88c32601824112c15dc74f2438fd6dfcf26697c6041", + "0x0792f243e6cfd99f708f30d1dbacebf43a69e3fea671a53eab7580f7ad0cf896", + "0xfd37acc097563f9dbd330592b8b0d84e13460aaa9cb299efbf55b87911a42171", + "0xccc52c8e84bcf512e0641a383bd59565a91d7a2cc4fce191890e17318fd550d8", + "0x42c275730ae7b7931c354cf6825876f09bcb721ef2a49423c7062316c2d6f2fb", + "0xe7fa209c2e52f36d1142265890f2d4cf6a65ef6bcc9aac8b98679c4d9fbf50ca", + "0xbfc25b3401aa288d08193c95645a23509d7f91d186438a713ea7422053615112", + "0x59600d2e03b83317882349f9ba9a29e378c99f5d400b66a4a61dacc45a10a06c", + "0x5bb42c1dcab25fa7119605ee2b039418433659a9d44d2607423077735d06d646", + "0x1c88606c1fb90348b6639e0b5ac351aaa7be9d8e7a54949b04115be31c19b210", + "0x0c3688bb4e69ee1d2f6829d207ce327baf2ad913755ded680006516f29042f0d", + "0xe416bd0839a09b9e043cba3cd29151605c8713c0a87060e721236c42dba557cc", + "0x47e198d26bbeac4883a8faee1409f01cc5bb8f4a3e9103b3d79452a8d0d7256f", + "0xdb13ad2d508c4cfd32da5d0feeb2ccc02551f5f0764496849c2ef79d65f81e46", + "0x28b168561a00f5b4888fb3921702e178289dcb4ad8ff9e6a05f13c7b2063fca5", + "0x2d15236fc32bf37335549ca7b8aed0af93c417dd58ac8943893b37b29c9be194", + "0xfba066e3e867af94ffb35c83d90f91dbca703d2b1e1270d3134adcb269e1d3aa", + "0xb39dc5605015af1563f509d43ca979c0b2e91bfcf92ceee5da72ade5c757cd2c", + "0x3944c7239cb201f6541d75c7d316a48dd13d574e1ddf4176630e90c67c05a9b7", + "0x2abfa889595997cf93345c17b16afec7b1935c25f489a9908571b239dc76585e", + "0x73ee344a77f74f57a2a3fac1ce4bdc060910584adb0188cb7c80c2e31b772aa7", + "0xa627e9f5da335b70be159292845e084fc845263843751fe19f9f1e2bc90b919a", + "0x77461a4012c70824575618bcb3a0d876752b3628266d30ebf032ee0895d6a934", + "0x3c8fd955012a02303155bd221e5416ccaa350c6bf53a7a0fbd481cd48f67aa32", + "0x4d6c89db5620f12ddf98c91597b6fbcce717feb4774a4cfd0429af94ae4ae329", + "0x49e687e61dc125632cd4bcf99284545ee457755ac8908586304eff9bde1e8e09", + "0x330f578fa2bb1b92f568d94c0ddcb12aaeea8a618dc753ab8be143cd0356009e", + "0x30b04622465e3bc19178ba1fdfb3e0c9e552248614357c2372a4d64366b925c4", + "0xcf73d465019666510b2f02790d21d9fc5fd1fe7ca6e670bc00efc0b6407777c5", + "0xfd7819a5d0a680319c54034683f153c89ef8a5175132d82a20e602645cb5b54f", + "0xc9dd44245feac5089313f2940d1d1a27dad3350ddb33c0d32190b44382b99976", + "0x777ce6cc23757f54a5f25323a19731ab48fff867460631afa8119d77d32503ab", + "0x7b6734afac66e9bd705d4366fe75b25ea1033a61dae0075e8cb3c3d7f5383b8f", + "0x2a47d485b255bbe4327c97e996704c9a613ee3dc82c43eac266f36774ca2b866", + "0xb6d6659eef76a48ea53e89b2b44291f908aaafd6937942f0fbf4bf7a80249e17", + "0x8fa106b3bcc701e850b0ed9496a8b3331d1c7dcdc236f7c1750eab30a4eaf5a9", + "0x7f5c12db2b31a5739529dadc239b677a7bc44a9bd84a54174556fb7c91bc4e40", + "0x17f82052564250a89d1693e2c11c23f945051562d9e95d10d9ce07175e8e258d", + "0x48318d87fcd2681f1cb40c94137b43ee955602244da4638b1f182a7c6d75e964", + "0x0f85a07673865086c9637ce92bd1ecefaf9399830b12e65173a5243c792a71ba", + "0x200f34e1e23a98e581457ce0b9667dccc207ef85611258971b40b543a477b32d", + "0xb24111bb847669bea0ebd5b5cbc7c850d0e814577ab5291f7b6bc3a570ac8cdb", + "0xfdbbdf9c55f43933d30a61497dac581c1c999f1730b1fc884965099d4c2ffdae", + "0x163d60e452407f19083203274a9a4b6681bf0c314f48f7cc09d2e4fa4ae26ad3", + "0x7316ec58ab0a808fdab04265125af16582e75c4ecefb70f6d23eea42e072ba13", + "0xc3908756583f8b291a3ae74f4abb96bea69da503887a9b5db8dbfa84d361808a", + "0xbdc3969cabdca434e5a1ce565075d3dbc4ca918a385bc60f62ed7505f1755074", + "0xdf98f4eaca81432edfd51d138a6b85d77f9a219e7565f4987a5b8f34bba40b79", + "0x426a0dfbce9121ea7babb30cd7e8f74605dd781a844403be8def56b45792b7f6", + "0x617cbe91494aef61910ecbac7233faaa1d580e2f1131be446a2e8cc0854849c1", + "0xc68bc3472fe90e10606d2f3a40c117e9730140107b423e5225214998145d7c66", + "0x84c464268ab6581830fb5281310016317919ae759f8151de4e1454c65af27eb1", + "0xa0376b6e3c691729b059e3779f18d52d7c321d528f33f59b0fc37ff34dedb0f8", + "0xe2c6cc9f2c06cebfb32f4eab5e7589c7b47310e44aa577c32a6851c59b80a824", + "0x07a018ca5dbd9d3611f24829000e27f828273988a957f190df6d315706bde47f", + "0x7deb3005e91ce21304fdce15a13a7a001779b7f021a17af7e889c1982c35f2af", + "0x2cc679cb44882cb685ec9a8d9ae3058a61e646c26c6635bc12068820615f450a", + "0xa5351381cac3b4c897825ff5acd817fa2682aca353d6c5df5a0736f940772361", + "0xa8afb3dd19f6c9aaa2b94742ebf50abedf904dd8b513991607e5c5b59539b0af", + "0x9a95f3ff3fb05b834539d98cb8aaf9422a9112f5f232b6aebd3153d7064fad3d", + "0xe2b2dcd9f84e3d913ccdefc439c650036708ec4e8e6d71c57d5a36e29007f00a", + "0xc1434b636f30b48f7a1db83cd094fb46455044a6ca8ed9996cbe1b0586353e56", + "0x32f4583854febc4ce209f90fbec4af4ed5da4cbd06adcfce0683853d7645b43b", + "0x70f338d6a745fccb2700f6632709f8b94120810d4bda076d38ab84dc5a4b60b1", + "0x1ca817244ef70d749235354dbe73bc02adbe1a9bd679531c9529b7f03eb08ce7", + "0x07a568e8a9b53dcf9fd6e7326d4b1d5f243f0dbc49f3332cd1331db5b9f4d49d", + "0xa0aa8b4799e91b0c2585e073d43988edfc581decf56c64b9083f9692956d1f9c", + "0x0e7f230a15895a83f437782ba8695ae81699c84429d30d2dcd22d842d6a36143", + "0xaad29638bcd49431591ee0dbf117e035c35cf0038267e4f2b3a484e4791f4dee", + "0xbf152e8cda2dd12ca52aa7cff7ddebc4e54a2c78bcd2bf6a158f45257333a09e", + "0x7f7fec07a6d7b2200c3e9b2dc66c5c49d2f2badd6604cc5aabc63a3ec5038375", + "0x8ea37350a5d0c81e11b76eb29d269025d28b26bd29a196330465997b3d82e1e3", + "0xba45a6e6042f86544892daa1a7731b9840a9171d3d834926d4d5bdac32889873", + "0x3269e10a8871a97b07dbdcd20eed5cfdc8c5e064d576dfbb508ee4082582913b", + "0xe7fb5297849c3d3eb0b3bd068cd2e9dfac549dc43a44c65e3b2005ba391d8a88", + "0xe42cf98685e159d10a3e4fbc19b6df03d8ad42d0f3d398f826a806a48a87497c", + "0xa448b7bf0faace82dc4255364fd8fd029c5c5d828888cb131e649472c6150775", + "0x1043325717080c977ddb22086d496de9b3308ccc7452665851839863cece60db", + "0xa1e34e462ecf988dfacc1aa371f1b188120ce3c1e06dfa06f639799889bbf5ac", + "0xd4f33c1c390ad6244e6c3b6699579f2f351b1a0b583550fe2f4b189e211c9c30", + "0x4cce900d2ab1dc78e568fb63e02ecd06fef0cd68d7cfe20cf9fa657b62a94dc8", + "0xbf85a695d507b9fc42ef3f81b76483f70f9e8767534a0ff35eb2f3315798d72a", + "0xd96ff1488e2deab994f27f204037bddc099766f1955c916003a4c632b48aa500", + "0xc963ce4671607cec2c36d8050318cafce4f835f20b5a859fdca14844a7e3a456", + "0x2e5838f879f8f698b3a7efeaafeb7ba324940aeb3f8b5bd16aa5ccf8737f4e63", + "0x0fccc49208367d119399101e5e0b1ee6ce5ef0f61f4a9f0389dae06de2038efa", + "0x63920bc887a208585f3ff310990c24c8e594942e371e7c2b59ed53f4d33bd1cc", + "0xd675a402fca8c1f1a9d977365c5269b93d963eb832ca1adc45b1b0251897093a", + "0xbe37d401abe3adad6d87befe126ea1883c4d117ac85b6c27965a1bc320f1bd30", + "0xe7182036132dd24e782cdd5fc41bd0a31b36a3eef1327ac211df3aa5fdc9df2e" + ] } } diff --git a/ethcore/res/ethereum/ropsten.json b/ethcore/res/ethereum/ropsten.json index 953e7fdb42..8c288fd7ea 100644 --- a/ethcore/res/ethereum/ropsten.json +++ b/ethcore/res/ethereum/ropsten.json @@ -62,8 +62,8 @@ "gasLimit": "0x1000000" }, "hardcodedSync": { - "header": "f90217a058893ba2a7f3d1625239b0ffab5b58219412b5fb51a608fc6ae7ff012496db9ba01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942b126e450158f14add6770739a2e6b4037526817a0a46d5b8474c625b4efd3d1d2864d7790770737587aa926fb223945d55a1d0da8a04ff0c821428157d6a4ace26e17d775eac4f42cc7d777898ded413780207fda11a0777f1c1c378807634128348e4f0eeca6a0e7f516ea411690ca04266323f671a4b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000844737e14e834dd801837a1200830186a0845c76311499d883010816846765746888676f312e31312e35856c696e7578a0676e77abeb493056c28a2d8fcd1238da73a29c9d915441fd8b5e36f6e910fa5d8803afeb22c339444f", - "totalDifficulty": "18334236703652990", + "header": "f9021aa0a8da98b6ef1e12b6c49e85b0e965f1ed1688f5e3605f06bb3c6ce4f857aa0bc6a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794635b4764d1939dfacd3a8014726159abc277becca0d03c319fe68a91e22fb3b945a8dfc73b817976e29cf57e6c8425e6a02e9bf034a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000849fe1546f8350d001837a121d80845c9d55f29fde8302020b8f5061726974792d457468657265756d86312e33322e30826c69a04bf72e97bcf64717bfd655e2bca9ed1a5253cce5373268729161b1786ca4710488db3c50627f9321c4", + "totalDifficulty": "18787961645682286", "CHTs": [ "0x614648fc0a459451850bdfe353a932b5ff824e1b568478394f78b3ed5427e37a", "0x1eae561c582dbb7f4e041998e084e165d0332c915d3a6da367638a8d24f3fafc", @@ -2555,7 +2555,102 @@ "0x563d7efb4175fc12dab431175b5097186c2379a5aca1901e39d641d02865d426", "0x1a55cf9842f9008e0730ae9fc6af9f288edba323803d0ae787fc0fdda99be8c9", "0xccdf47cee7142cad27bbf224f0afd1a6e5178345cab510f2f8ee27115ab27ff7", - "0xc5b3582937ad993c5c234d059e6cd3b98f2fa4e3fe4ad591ecb6ae710b51fee9" + "0xc5b3582937ad993c5c234d059e6cd3b98f2fa4e3fe4ad591ecb6ae710b51fee9", + "0xd651ab199355d61c49e63259e6a20d17bf72b27891271e5175a24c23fb2dc29c", + "0x800e1e33b0cd48afc6f8f7c69b85902ad93e94bb290b35a862cbad67706a2f3d", + "0x57c7349a6b630cb52c3c1205165df428ed51e25cc167c08739f86bfa46c69e48", + "0xb393d362daff182dafcce65eda9038fc0c8908b3cb1ec1a1218570211c34e142", + "0xb2f49f7a836cd0db9e4743158ff80dd97d23de7a39a0438d19c79c355339c43c", + "0x3f46776ec25b5c67468c32c1b2ca02910a7f46b4b62b5dc5d0cc6b9d3381b958", + "0x754c4ea722e501668aa48d6151ff423263b8a4e2f33b9e44e189ee4e78462741", + "0x12e79ee2724763a8a7f9196bf4d0e855e0ae3f75f5a697d90a263bf562acc5a3", + "0x407b168fea70128a8090ca86274b0b8e7965f16d54ea2b3bbabb378485b22a02", + "0x0d1557ad0cb1466965e6ee86c5ce887eedf462dbec2e719c5f396f8ed95edf08", + "0x29c3a0db9f83698e6ae703174dbeec06f3d2055eb933799e4ae3bf73f4570dde", + "0x8ade20e56fcacb40f54259696bea1aa04d839b88c503d6775d7b4491e0f9e7fa", + "0x327ef0f173632c5049988b312b1f49e9948b02125f70e117ea127088191c32d5", + "0x2989c11c234b7fc5901e168d7adfa655ff6165098eb94d244b623ba43c6abbd6", + "0x10b56dc8f023de6a8f97696dfe2993b56156a9b35f671438fee5830f52b633b5", + "0x46cd37fffe94a01297f2dcef322ae72f58bbf9f58bc9f930cbf56e73f8d5ce13", + "0x2240214683eafc37396f3078446b43ae96bc576e45db650b953ff87a895ee7d7", + "0x0db4d500e5755cba5b962f6b83942e72fd1504cf52531916084852179669a08d", + "0xafc686a8325a30966db0f54b64a4e7235ea54e300d280a4d2a502651a53424b5", + "0x59d46f6fb8eadcf18e31c9fd0da6844d63a2dc19eeeaf9ad5b80113aca5bc42a", + "0x153ae496364bf7c34c8c967e044cef69e401f0e4aff27b04808e2c299dcf15a8", + "0xc85b8d3156729c7f8ff1989f320464144f4918140d608cf03e7dfd5b51ec2acf", + "0x78fd0613f6f5291d4131152225fbded5464841a119d854a7550a1f178a8cdfc7", + "0x763dc1a000b949a45f792515fed6af70047641fa3d7beeb50b141c27b4f8cd33", + "0x42567a1e6caadaa10a13feff343ae1e2a903564affacc48aebc14f257db58ee1", + "0x62c208337234d101cc95cb6be54c17631e26c956758493f5bb7978faf0ace984", + "0x7977aec997a3029025ef789d3492755c80c2d028046aae8c4b926f247e1981d9", + "0xf927505a0c29231ed187a884af15a82dbc48a1cb002f6d91496f6569c673682d", + "0xefd2c54f6d2483a3dd7b994d8afa5441cfffa956d7da6e81bbd1691e07ac7519", + "0x7bcf94d8927a39dd00558763cdd2edaf40d55728d720dccfa0f5e1e827079cc0", + "0x19c7e5115ec25b14bd85e3d368e15d2bbe60451ed9a02f03770a3e845521b77c", + "0x60e32d48de6979c70dcb3e3f068fc3632aba5844703d50851a34975338b3a837", + "0x6722f01dc1d6dd1f0678e5b527155beb0616e33887697a56ef4cc1bac642f394", + "0x59bf17368d69e0379f0f20ec1b1b856298b8d6b4c36354ee765c8a894e58ab9b", + "0xe2559e7b67a15a3ddfbf1ddc597a1309d1fd780fe26da28aace16ad31754883c", + "0xbf687ac704bf02a3877e72f738691bf5027c21f64c68a50235876a8d015ae682", + "0xde01838df621b7368adf4fda268c827dfaa6753a39d51956c0445a2244585ec1", + "0x4ba14d3860d1dee44904719e45a5bfe54dd1e4c9bdafd0a41279e432a021f2e6", + "0xa2380cb32538cc80e07fda5575ecd7b35e0c12932687bd8002da652ad8c16dc2", + "0x82d0f5c8421d6803e52e3d6a37eea0cd978686792a2f6d175d77e9c75fb4ad86", + "0x23701b29d07c64c998ee4bf8199d5ac0f3d9724af2544cc29665a1d92a6dadce", + "0x8bbd490220c823506e111c668f923d18addf5a23d9b5244103cc135c4335f23d", + "0x190506f2d9decb8f9423662f406e61c99606abdcb369e25a1a89c2bdc44c6158", + "0xb9504b090b276cbbf86349bc4dbb66b46a42ce6ae8d44d5cd7f39773fdf6112a", + "0x38fc273344dc7230790963dfb3dedfabe142c18886d6542d77ace8ed6d117c4f", + "0xc76929e9a3a984f6ab6395c4811f007eb6d73a86fe62f8a1c02e860769f2bcde", + "0xc4fc2465f71d06102d232858cfd9737e6e82311a45b1cb2ac203de80c881a2f4", + "0x34427ee5534de01e7f0510b87e6f45aac6210897472978aee3c051c39776c561", + "0xec4f3c6349dac1e7e43b0541b1132b3d0cc8bd422436f31832184d1aa6f9c822", + "0x024a848067a1156852c78495581392774b00f22e32021ca531afeab1aafb683e", + "0x9bdf793e30326a181d3d8fb3f27818475b755e3d1fea200d8c514cf17024979a", + "0x55a1d92354a31354b4b1d9366e98b27c0467b01a108d67dab7feeeda23f981d9", + "0x74614ac3de92173d07434dd80d83aad5c1d551127896298808ad7fba96051e06", + "0x7bdb77183ca1e7f50d292e50ef701ad3bfff3e6e28d36629c5325da03cb8d013", + "0x3a35dc3d12de1053d204410a577b9e5c36d32fbda761f797aee248c27f7dbb02", + "0x430aaeb1dc02bb792375d1702999cda7c384dde1c6f46ef26f1e26e5a55dfd87", + "0xe12805d1713ba730fec6aae824bdcd0a896c6d5e12b9bfa5b6e0a2c2be251c17", + "0x5a297bd3be2352e56136db83a76c7041ef825128152366b2d8f032abb1d6656f", + "0x111782d82f50ea25d684af38689cea53319f1a88557d82c57e46ee5e75f99c05", + "0xe12520cda10064d74fdefba22b5ff4c5eb95508f77fd7c8c3fe82fb89e165bf6", + "0x6af12e8f4db19aee3865c3d681073e7433d902832bc651b8fc3f5fd038c8bca6", + "0x82a4a2ce19ca3fd99007279d62dadba547b6818607800e963b3bc53c5541298a", + "0xbf3a444d1b15d01a29ea22d05e71021ee3581338ecc9e770ee23ab6549a19d55", + "0x745ff92172b5c83cdd69265b919028b350ef95a01c84810366d630162fd9b07f", + "0x6128cd2ff1be9e56396a676362a2049f3e670c70ad2a77be724c090fd4085f0b", + "0x8ffc6bf8165e52ecf30ec955d4be1bb093e6074c92a527382a8892ffa3d3e7f7", + "0xd65bc11ef24c0fa476640d9effdc57030a86f547b7aa79b209954a6abf4072c4", + "0xcd5b5e184a5c0d1c5bdd12f80736ed1a4530210b4ef5f35dacd3feba722a334a", + "0xa80657ecf79ef03fb919bf312e02d94ab528c1b5c3858332d9bf82f807b1c232", + "0xc67dfe4aca5001e97ba6f401f15b72be85ae45972ba98b965a6dd4954d5c2386", + "0x59201e892aeab9e40aef69945585b81b47a7444ed61ba6c6e23e006103ed7edd", + "0xf535c920c5316f12f0bfedc298fbad028dd84161927414b14243c4c5ddd4f4f1", + "0x66c6e42c8137c043eb49528c718b10e5dbad9164bd3ffcc6b55b4b0501dc507b", + "0xa60b9485cb54818e0b0bfe4faeca923915f85bbac0525d09d96f375d0b2b9f81", + "0x8f9377dddacb6ed605c8ed8ed2bc6e2323a4e5d0c9b29bccdfbd27f57a9ec315", + "0xc48a1940c424c2df4803ba8d5573066ce4bbf0e0fbdaa87abcb2d2f51b0a4602", + "0xc7bce918e9f897aeb1351d2c9cbc2fbc8fd674017cb25c49846b05d609f00ed9", + "0xcdaa86e0c026c91954c6305cb7ce6010560f691a2667baf0e95bc18cd3e067df", + "0xf131e0910a8088fc5b0b1d2e93e31632eec67fa88f75bc4f9c3c1b0a317e1d54", + "0xb4f8d72a85c4c2261c7b00f43b96d7d749d0e53359993f52517da36de4c9559b", + "0x73f84bb4774a81b39b3a10d18c7a2404d21f3efd26301dbb7c8136e96304281e", + "0x5559435a987f1444e4ec78b8530009e49c52431b37c7e9f80ce2e056d44e876a", + "0x070664d11ee10c4e0475a7ece219eb0e606e055ee0fa1266b669e593b5ba1d87", + "0xfdfafeba7b5551d1e2d6f179be5ddfdbd0350bd2e9dfea40e272fb608549e8c2", + "0x50a1356bab9b56d8ed46a3e8f55b8a16af42df6b15fcc68aa548216de484c7eb", + "0x681161a307552ff12175074601005bae0c6f7b38cfa6dcb87975a1df205e28d5", + "0x2b39456efc2e8863197c95a4d6eef5069612cc2aa6414f0991393ffa672a1a15", + "0x571b916a82371fafcb456524655758bd42b4f7b768e13807a1a995e642ec205c", + "0xb2821504201eea0e6040a131a709547fc9afb44ba7bfa6a188201735753ba3b7", + "0xb16a8af1bfdde1fae0e28f29c6db0b361840df4b55e73bddffbc1cc11bcc5584", + "0x1df38b594f536cee38acad293a818bf83fc67830fc71bc19790d7733a2caab60", + "0xebb3e8f76f3b6a95285154dc11d4bd94ac4c3a150383ed69f5373499b1983dc3", + "0xb0919ed300acac5f912f01611a428861db27ffb8129a80495f735f0ac608ab35", + "0x2ee321d9d805b78a97210df2977ab62b352705e308773b90e0f4e923adec377c", + "0xee00cb02e9b86978ae10b119924bbe6c38f730c1d1b621d32c9d697e11105871" ] }, "nodes": [ From 89f828be1c6dc2882ddafb46d96aa71faa65c236 Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Sun, 31 Mar 2019 11:54:19 +0200 Subject: [PATCH 150/168] fix(light account response): update `tx_queue` (#10545) --- rpc/src/v1/helpers/light_fetch.rs | 33 ++++++++++++++++++++++++------- rpc/src/v1/impls/light/eth.rs | 8 ++++---- 2 files changed, 30 insertions(+), 11 deletions(-) diff --git a/rpc/src/v1/helpers/light_fetch.rs b/rpc/src/v1/helpers/light_fetch.rs index 7167a73163..e18695fcb7 100644 --- a/rpc/src/v1/helpers/light_fetch.rs +++ b/rpc/src/v1/helpers/light_fetch.rs @@ -40,12 +40,13 @@ use light::on_demand::{ }; use light::on_demand::error::Error as OnDemandError; use light::request::Field; +use light::TransactionQueue; use sync::{LightNetworkDispatcher, ManageNetwork, LightSyncProvider}; use ethereum_types::{Address, U256}; use hash::H256; -use parking_lot::Mutex; +use parking_lot::{Mutex, RwLock}; use fastmap::H256FastMap; use std::collections::BTreeMap; use types::transaction::{Action, Transaction as EthTransaction, PendingTransaction, SignedTransaction, LocalizedTransaction}; @@ -100,7 +101,7 @@ where on_demand: self.on_demand.clone(), sync: self.sync.clone(), cache: self.cache.clone(), - gas_price_percentile: self.gas_price_percentile + gas_price_percentile: self.gas_price_percentile, } } } @@ -215,7 +216,13 @@ where /// Helper for getting account info at a given block. /// `None` indicates the account doesn't exist at the given block. - pub fn account(&self, address: Address, id: BlockId) -> impl Future, Error = Error> + Send { + pub fn account( + &self, + address: Address, + id: BlockId, + tx_queue: Arc> + ) -> impl Future, Error = Error> + Send { + let mut reqs = Vec::new(); let header_ref = match self.make_header_requests(id, &mut reqs) { Ok(r) => r, @@ -224,14 +231,26 @@ where reqs.push(request::Account { header: header_ref, address }.into()); - Either::B(self.send_requests(reqs, |mut res|match res.pop() { - Some(OnDemandResponse::Account(acc)) => acc, + Either::B(self.send_requests(reqs, move |mut res| match res.pop() { + Some(OnDemandResponse::Account(maybe_account)) => { + if let Some(ref acc) = maybe_account { + let mut txq = tx_queue.write(); + txq.cull(address, acc.nonce); + } + maybe_account + } _ => panic!(WRONG_RESPONSE_AMOUNT_TYPE_PROOF), })) } /// Helper for getting proved execution. - pub fn proved_read_only_execution(&self, req: CallRequest, num: Option) -> impl Future + Send { + pub fn proved_read_only_execution( + &self, + req: CallRequest, + num: Option, + txq: Arc> + ) -> impl Future + Send { + // (21000 G_transaction + 32000 G_create + some marginal to allow a few operations) const START_GAS: u64 = 60_000; @@ -254,7 +273,7 @@ where let from = req.from.unwrap_or_default(); let nonce_fut = match req.nonce { Some(nonce) => Either::A(future::ok(Some(nonce))), - None => Either::B(self.account(from, id).map(|acc| acc.map(|a| a.nonce))), + None => Either::B(self.account(from, id, txq).map(|acc| acc.map(|a| a.nonce))), }; let gas_price_fut = match req.gas_price { diff --git a/rpc/src/v1/impls/light/eth.rs b/rpc/src/v1/impls/light/eth.rs index cd17b06739..73e2b99c61 100644 --- a/rpc/src/v1/impls/light/eth.rs +++ b/rpc/src/v1/impls/light/eth.rs @@ -288,7 +288,7 @@ where } fn balance(&self, address: H160, num: Option) -> BoxFuture { - Box::new(self.fetcher().account(address, num.unwrap_or_default().to_block_id()) + Box::new(self.fetcher().account(address, num.unwrap_or_default().to_block_id(), self.transaction_queue.clone()) .map(|acc| acc.map_or(0.into(), |a| a.balance))) } @@ -305,7 +305,7 @@ where } fn transaction_count(&self, address: H160, num: Option) -> BoxFuture { - Box::new(self.fetcher().account(address, num.unwrap_or_default().to_block_id()) + Box::new(self.fetcher().account(address, num.unwrap_or_default().to_block_id(), self.transaction_queue.clone()) .map(|acc| acc.map_or(0.into(), |a| a.nonce))) } @@ -401,7 +401,7 @@ where } fn call(&self, req: CallRequest, num: Option) -> BoxFuture { - Box::new(self.fetcher().proved_read_only_execution(req, num).and_then(|res| { + Box::new(self.fetcher().proved_read_only_execution(req, num, self.transaction_queue.clone()).and_then(|res| { match res { Ok(exec) => Ok(exec.output.into()), Err(e) => Err(errors::execution(e)), @@ -411,7 +411,7 @@ where fn estimate_gas(&self, req: CallRequest, num: Option) -> BoxFuture { // TODO: binary chop for more accurate estimates. - Box::new(self.fetcher().proved_read_only_execution(req, num).and_then(|res| { + Box::new(self.fetcher().proved_read_only_execution(req, num, self.transaction_queue.clone()).and_then(|res| { match res { Ok(exec) => Ok(exec.refunded + exec.gas_used), Err(e) => Err(errors::execution(e)), From d9673b0d6b1bf44eccab0d68d837594835788004 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Mon, 1 Apr 2019 09:48:51 +0100 Subject: [PATCH 151/168] tx-pool: check transaction readiness before replacing (#10526) * Update to vanilla tx pool error * Prevent a non ready tx replacing a ready tx * Make tests compile * Test ready tx not replaced by future tx * Transaction indirection * Use StateReadiness to calculate Ready in `should_replace` * Test existing txs from same sender are used to compute Readiness * private-tx: Wire up ShouldReplace * Revert "Use StateReadiness to calculate Ready in `should_replace`" This reverts commit af9e69c8 * Make replace generic so it works with private-tx * Rename Replace and add missing docs * ShouldReplace no longer mutable * tx-pool: update to transaction-pool 2.0 from crates.io * tx-pool: generic error type alias * Exit early for first unmatching nonce * Fix private-tx test, use existing write lock * Use read lock for pool scoring --- Cargo.lock | 11 +- ethcore/private-tx/Cargo.toml | 2 +- ethcore/private-tx/src/error.rs | 5 +- .../private-tx/src/private_transactions.rs | 9 +- miner/Cargo.toml | 2 +- miner/src/pool/listener.rs | 2 +- miner/src/pool/local_transactions.rs | 2 +- miner/src/pool/mod.rs | 3 +- miner/src/pool/queue.rs | 28 +- miner/src/pool/replace.rs | 415 ++++++++++++++++++ miner/src/pool/scoring.rs | 171 -------- rpc/Cargo.toml | 2 +- 12 files changed, 449 insertions(+), 203 deletions(-) create mode 100644 miner/src/pool/replace.rs diff --git a/Cargo.lock b/Cargo.lock index 1d43c68c53..c1b7f24796 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -951,7 +951,7 @@ dependencies = [ "rlp 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "trace-time 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "transaction-pool 1.13.3 (registry+https://github.com/rust-lang/crates.io-index)", + "transaction-pool 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1046,7 +1046,7 @@ dependencies = [ "serde_derive 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", "tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "transaction-pool 1.13.3 (registry+https://github.com/rust-lang/crates.io-index)", + "transaction-pool 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "trie-db 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2687,7 +2687,7 @@ dependencies = [ "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-timer 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "transaction-pool 1.13.3 (registry+https://github.com/rust-lang/crates.io-index)", + "transaction-pool 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "transient-hashmap 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "vm 0.1.0", ] @@ -4048,10 +4048,9 @@ dependencies = [ [[package]] name = "transaction-pool" -version = "1.13.3" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "trace-time 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4783,7 +4782,7 @@ dependencies = [ "checksum toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "758664fc71a3a69038656bee8b6be6477d2a6c315a6b81f7081f591bffa4111f" "checksum toolshed 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "450441e131c7663af72e63a33c02a6a1fbaaa8601dc652ed6757813bb55aeec7" "checksum trace-time 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe82f2f0bf1991e163e757baf044282823155dd326e70f44ce2186c3c320cc9" -"checksum transaction-pool 1.13.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e5866e5126b14358f1d7af4bf51a0be677a363799b90e655edcec8254edef1d2" +"checksum transaction-pool 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f8d8bd3123931aa6e49dd03bc8a2400490e14701d779458d1f1fff1f04c6f666" "checksum transient-hashmap 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "aeb4b191d033a35edfce392a38cdcf9790b6cebcb30fa690c312c29da4dc433e" "checksum trezor-sys 1.0.0 (git+https://github.com/paritytech/trezor-sys)" = "" "checksum trie-db 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3c7319e28ca295f27359d944a682f7f65b419158bf1590c92cadc0000258d788" diff --git a/ethcore/private-tx/Cargo.toml b/ethcore/private-tx/Cargo.toml index a50d704ab4..2ce127a8b7 100644 --- a/ethcore/private-tx/Cargo.toml +++ b/ethcore/private-tx/Cargo.toml @@ -36,7 +36,7 @@ serde = "1.0" serde_derive = "1.0" serde_json = "1.0" tiny-keccak = "1.4" -transaction-pool = "1.13.2" +transaction-pool = "2.0" url = "1" [dev-dependencies] diff --git a/ethcore/private-tx/src/error.rs b/ethcore/private-tx/src/error.rs index 8c86bf0cad..eda08b2a56 100644 --- a/ethcore/private-tx/src/error.rs +++ b/ethcore/private-tx/src/error.rs @@ -23,7 +23,10 @@ use ethcore::error::{Error as EthcoreError, ExecutionError}; use types::transaction::Error as TransactionError; use ethkey::Error as KeyError; use ethkey::crypto::Error as CryptoError; -use txpool::{Error as TxPoolError}; +use txpool::VerifiedTransaction; +use private_transactions::VerifiedPrivateTransaction; + +type TxPoolError = txpool::Error<::Hash>; #[derive(Debug, Display)] pub enum Error { diff --git a/ethcore/private-tx/src/private_transactions.rs b/ethcore/private-tx/src/private_transactions.rs index 0182c82dd9..d0456657b0 100644 --- a/ethcore/private-tx/src/private_transactions.rs +++ b/ethcore/private-tx/src/private_transactions.rs @@ -154,7 +154,7 @@ impl Default for VerificationStore { impl VerificationStore { /// Adds private transaction for verification into the store - pub fn add_transaction( + pub fn add_transaction( &self, transaction: UnverifiedTransaction, validator_account: Option
, @@ -164,7 +164,7 @@ impl VerificationStore { let options = self.verification_options.clone(); // Use pool's verifying pipeline for original transaction's verification - let verifier = pool::verifier::Verifier::new(client, options, Default::default(), None); + let verifier = pool::verifier::Verifier::new(client.clone(), options, Default::default(), None); let unverified = pool::verifier::Transaction::Unverified(transaction); let verified_tx = verifier.verify_transaction(unverified)?; let signed_tx: SignedTransaction = verified_tx.signed().clone(); @@ -177,8 +177,9 @@ impl VerificationStore { transaction_hash: signed_hash, transaction_sender: signed_sender, }; - let mut pool = self.verification_pool.write(); - pool.import(verified)?; + let replace = pool::replace::ReplaceByScoreAndReadiness::new( + self.verification_pool.read().scoring().clone(), client); + self.verification_pool.write().import(verified, &replace)?; Ok(()) } diff --git a/miner/Cargo.toml b/miner/Cargo.toml index 02e64ad4f8..f7dfd8f083 100644 --- a/miner/Cargo.toml +++ b/miner/Cargo.toml @@ -32,7 +32,7 @@ parking_lot = "0.7" price-info = { path = "./price-info", optional = true } rlp = { version = "0.3.0", features = ["ethereum"] } trace-time = "0.1" -transaction-pool = "1.13" +transaction-pool = "2.0" [dev-dependencies] env_logger = "0.5" diff --git a/miner/src/pool/listener.rs b/miner/src/pool/listener.rs index fac98b0a17..67034aa523 100644 --- a/miner/src/pool/listener.rs +++ b/miner/src/pool/listener.rs @@ -92,7 +92,7 @@ impl txpool::Listener for Logger { } } - fn rejected(&mut self, _tx: &Arc, reason: &txpool::ErrorKind) { + fn rejected(&mut self, _tx: &Arc, reason: &txpool::Error) { trace!(target: "txqueue", "Rejected {}.", reason); } diff --git a/miner/src/pool/local_transactions.rs b/miner/src/pool/local_transactions.rs index c805484d1c..346877d030 100644 --- a/miner/src/pool/local_transactions.rs +++ b/miner/src/pool/local_transactions.rs @@ -171,7 +171,7 @@ impl txpool::Listener for LocalTransactionsList { } } - fn rejected(&mut self, tx: &Arc, reason: &txpool::ErrorKind) { + fn rejected(&mut self, tx: &Arc, reason: &txpool::Error) { if !tx.priority().is_local() { return; } diff --git a/miner/src/pool/mod.rs b/miner/src/pool/mod.rs index 561b85f4bc..40a226d9fc 100644 --- a/miner/src/pool/mod.rs +++ b/miner/src/pool/mod.rs @@ -27,6 +27,7 @@ mod ready; pub mod client; pub mod local_transactions; +pub mod replace; pub mod scoring; pub mod verifier; @@ -121,7 +122,7 @@ pub trait ScoredTransaction { } /// Verified transaction stored in the pool. -#[derive(Debug, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct VerifiedTransaction { transaction: transaction::PendingTransaction, // TODO [ToDr] hash and sender should go directly from the transaction diff --git a/miner/src/pool/queue.rs b/miner/src/pool/queue.rs index 51c46ad823..ad7c9e6f12 100644 --- a/miner/src/pool/queue.rs +++ b/miner/src/pool/queue.rs @@ -27,7 +27,7 @@ use txpool::{self, Verifier}; use types::transaction; use pool::{ - self, scoring, verifier, client, ready, listener, + self, replace, scoring, verifier, client, ready, listener, PrioritizationStrategy, PendingOrdering, PendingSettings, }; use pool::local_transactions::LocalTransactionsList; @@ -240,7 +240,7 @@ impl TransactionQueue { /// /// Given blockchain and state access (Client) /// verifies and imports transactions to the pool. - pub fn import( + pub fn import( &self, client: C, transactions: Vec, @@ -263,12 +263,14 @@ impl TransactionQueue { }; let verifier = verifier::Verifier::new( - client, + client.clone(), options, self.insertion_id.clone(), transaction_to_replace, ); + let mut replace = replace::ReplaceByScoreAndReadiness::new(self.pool.read().scoring().clone(), client); + let results = transactions .into_iter() .map(|transaction| { @@ -286,7 +288,7 @@ impl TransactionQueue { let imported = verifier .verify_transaction(transaction) .and_then(|verified| { - self.pool.write().import(verified).map_err(convert_error) + self.pool.write().import(verified, &mut replace).map_err(convert_error) }); match imported { @@ -579,17 +581,13 @@ impl TransactionQueue { } } -fn convert_error(err: txpool::Error) -> transaction::Error { - use self::txpool::ErrorKind; - - match *err.kind() { - ErrorKind::AlreadyImported(..) => transaction::Error::AlreadyImported, - ErrorKind::TooCheapToEnter(..) => transaction::Error::LimitReached, - ErrorKind::TooCheapToReplace(..) => transaction::Error::TooCheapToReplace, - ref e => { - warn!(target: "txqueue", "Unknown import error: {:?}", e); - transaction::Error::NotAllowed - }, +fn convert_error(err: txpool::Error) -> transaction::Error { + use self::txpool::Error; + + match err { + Error::AlreadyImported(..) => transaction::Error::AlreadyImported, + Error::TooCheapToEnter(..) => transaction::Error::LimitReached, + Error::TooCheapToReplace(..) => transaction::Error::TooCheapToReplace } } diff --git a/miner/src/pool/replace.rs b/miner/src/pool/replace.rs new file mode 100644 index 0000000000..b1112dcae1 --- /dev/null +++ b/miner/src/pool/replace.rs @@ -0,0 +1,415 @@ +// Copyright 2015-2019 Parity Technologies (UK) Ltd. +// This file is part of Parity Ethereum. + +// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . + +//! Replacing Transactions +//! +//! When queue limits are reached, a new transaction may replace one already +//! in the pool. The decision whether to reject, replace or retain both is +//! delegated to an implementation of `ShouldReplace`. +//! +//! Here we decide based on the sender, the nonce and gas price, and finally +//! on the `Readiness` of the transactions when comparing them + +use std::cmp; + +use ethereum_types::{U256, H160 as Address}; +use txpool::{self, scoring::{Choice, Scoring}, ReplaceTransaction}; +use txpool::VerifiedTransaction; +use super::{client, ScoredTransaction}; + +/// Choose whether to replace based on the sender, the score and finally the +/// `Readiness` of the transactions being compared. +#[derive(Debug)] +pub struct ReplaceByScoreAndReadiness { + scoring: S, + client: C, +} + +impl ReplaceByScoreAndReadiness { + /// Create a new `ReplaceByScoreAndReadiness` + pub fn new(scoring: S, client: C) -> Self { + ReplaceByScoreAndReadiness { scoring, client } + } +} + +impl txpool::ShouldReplace for ReplaceByScoreAndReadiness +where + T: VerifiedTransaction + ScoredTransaction + PartialEq, + S: Scoring, + C: client::NonceClient, +{ + fn should_replace( + &self, + old: &ReplaceTransaction, + new: &ReplaceTransaction, + ) -> Choice { + let both_local = old.priority().is_local() && new.priority().is_local(); + if old.sender() == new.sender() { + // prefer earliest transaction + match new.nonce().cmp(&old.nonce()) { + cmp::Ordering::Equal => self.scoring.choose(&old, &new), + _ if both_local => Choice::InsertNew, + cmp::Ordering::Less => Choice::ReplaceOld, + cmp::Ordering::Greater => Choice::RejectNew, + } + } else if both_local { + Choice::InsertNew + } else { + let old_score = (old.priority(), old.gas_price()); + let new_score = (new.priority(), new.gas_price()); + if new_score > old_score { + let state = &self.client; + // calculate readiness based on state nonce + pooled txs from same sender + let is_ready = |replace: &ReplaceTransaction| { + let mut nonce = state.account_nonce(replace.sender()); + if let Some(txs) = replace.pooled_by_sender { + for tx in txs.iter() { + if nonce == tx.nonce() && *tx.transaction != ***replace.transaction { + nonce = nonce.saturating_add(U256::from(1)) + } else { + break + } + } + } + nonce == replace.nonce() + }; + + if !is_ready(new) && is_ready(old) { + // prevent a ready transaction being replace by a non-ready transaction + Choice::RejectNew + } else { + Choice::ReplaceOld + } + } else { + Choice::RejectNew + } + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + use std::sync::Arc; + use ethkey::{Random, Generator, KeyPair}; + use pool::tests::tx::{Tx, TxExt}; + use pool::tests::client::TestClient; + use pool::scoring::*; + use pool::{PrioritizationStrategy, VerifiedTransaction}; + use txpool::scoring::Choice::*; + use txpool::ShouldReplace; + + fn local_tx_verified(tx: Tx, keypair: &KeyPair) -> VerifiedTransaction { + let mut verified_tx = tx.unsigned().sign(keypair.secret(), None).verified(); + verified_tx.priority = ::pool::Priority::Local; + verified_tx + } + + fn should_replace(replace: &ShouldReplace, old: VerifiedTransaction, new: VerifiedTransaction) -> Choice { + let old_tx = txpool::Transaction { insertion_id: 0, transaction: Arc::new(old) }; + let new_tx = txpool::Transaction { insertion_id: 0, transaction: Arc::new(new) }; + let old = ReplaceTransaction::new(&old_tx, Default::default()); + let new = ReplaceTransaction::new(&new_tx, Default::default()); + replace.should_replace(&old, &new) + } + + #[test] + fn should_always_accept_local_transactions_unless_same_sender_and_nonce() { + let scoring = NonceAndGasPrice(PrioritizationStrategy::GasPriceOnly); + let client = TestClient::new().with_nonce(1); + let replace = ReplaceByScoreAndReadiness::new(scoring, client); + + // same sender txs + let keypair = Random.generate().unwrap(); + + let same_sender_tx1 = local_tx_verified(Tx { + nonce: 1, + gas_price: 1, + ..Default::default() + }, &keypair); + + let same_sender_tx2 = local_tx_verified(Tx { + nonce: 2, + gas_price: 100, + ..Default::default() + }, &keypair); + + let same_sender_tx3 = local_tx_verified(Tx { + nonce: 2, + gas_price: 200, + ..Default::default() + }, &keypair); + + // different sender txs + let sender1 = Random.generate().unwrap(); + let different_sender_tx1 = local_tx_verified(Tx { + nonce: 2, + gas_price: 1, + ..Default::default() + }, &sender1); + + let sender2 = Random.generate().unwrap(); + let different_sender_tx2 = local_tx_verified(Tx { + nonce: 1, + gas_price: 10, + ..Default::default() + }, &sender2); + + assert_eq!(should_replace(&replace, same_sender_tx1.clone(), same_sender_tx2.clone()), InsertNew); + assert_eq!(should_replace(&replace, same_sender_tx2.clone(), same_sender_tx1.clone()), InsertNew); + + assert_eq!(should_replace(&replace, different_sender_tx1.clone(), different_sender_tx2.clone()), InsertNew); + assert_eq!(should_replace(&replace, different_sender_tx2.clone(), different_sender_tx1.clone()), InsertNew); + + // txs with same sender and nonce + assert_eq!(should_replace(&replace, same_sender_tx2.clone(), same_sender_tx3.clone()), ReplaceOld); + assert_eq!(should_replace(&replace, same_sender_tx3.clone(), same_sender_tx2.clone()), RejectNew); + } + + #[test] + fn should_replace_same_sender_by_nonce() { + let scoring = NonceAndGasPrice(PrioritizationStrategy::GasPriceOnly); + let client = TestClient::new().with_nonce(1); + let replace = ReplaceByScoreAndReadiness::new(scoring, client); + + let tx1 = Tx { + nonce: 1, + gas_price: 1, + ..Default::default() + }; + let tx2 = Tx { + nonce: 2, + gas_price: 100, + ..Default::default() + }; + let tx3 = Tx { + nonce: 2, + gas_price: 110, + ..Default::default() + }; + let tx4 = Tx { + nonce: 2, + gas_price: 130, + ..Default::default() + }; + + let keypair = Random.generate().unwrap(); + let txs = vec![tx1, tx2, tx3, tx4].into_iter().map(|tx| { + tx.unsigned().sign(keypair.secret(), None).verified() + }).collect::>(); + + assert_eq!(should_replace(&replace, txs[0].clone(), txs[1].clone()), RejectNew); + assert_eq!(should_replace(&replace, txs[1].clone(), txs[0].clone()), ReplaceOld); + + assert_eq!(should_replace(&replace, txs[1].clone(), txs[2].clone()), RejectNew); + assert_eq!(should_replace(&replace, txs[2].clone(), txs[1].clone()), RejectNew); + + assert_eq!(should_replace(&replace, txs[1].clone(), txs[3].clone()), ReplaceOld); + assert_eq!(should_replace(&replace, txs[3].clone(), txs[1].clone()), RejectNew); + } + + #[test] + fn should_replace_different_sender_by_priority_and_gas_price() { + // given + let scoring = NonceAndGasPrice(PrioritizationStrategy::GasPriceOnly); + let client = TestClient::new().with_nonce(0); + let replace = ReplaceByScoreAndReadiness::new(scoring, client); + + let tx_regular_low_gas = { + let tx = Tx { + nonce: 1, + gas_price: 1, + ..Default::default() + }; + tx.signed().verified() + }; + let tx_regular_high_gas = { + let tx = Tx { + nonce: 2, + gas_price: 10, + ..Default::default() + }; + tx.signed().verified() + }; + let tx_local_low_gas = { + let tx = Tx { + nonce: 2, + gas_price: 1, + ..Default::default() + }; + let mut verified_tx = tx.signed().verified(); + verified_tx.priority = ::pool::Priority::Local; + verified_tx + }; + let tx_local_high_gas = { + let tx = Tx { + nonce: 1, + gas_price: 10, + ..Default::default() + }; + let mut verified_tx = tx.signed().verified(); + verified_tx.priority = ::pool::Priority::Local; + verified_tx + }; + + assert_eq!(should_replace(&replace, tx_regular_low_gas.clone(), tx_regular_high_gas.clone()), ReplaceOld); + assert_eq!(should_replace(&replace, tx_regular_high_gas.clone(), tx_regular_low_gas.clone()), RejectNew); + + assert_eq!(should_replace(&replace, tx_regular_high_gas.clone(), tx_local_low_gas.clone()), ReplaceOld); + assert_eq!(should_replace(&replace, tx_local_low_gas.clone(), tx_regular_high_gas.clone()), RejectNew); + + assert_eq!(should_replace(&replace, tx_local_low_gas.clone(), tx_local_high_gas.clone()), InsertNew); + assert_eq!(should_replace(&replace, tx_local_high_gas.clone(), tx_regular_low_gas.clone()), RejectNew); + } + + #[test] + fn should_not_replace_ready_transaction_with_future_transaction() { + let scoring = NonceAndGasPrice(PrioritizationStrategy::GasPriceOnly); + let client = TestClient::new().with_nonce(1); + let replace = ReplaceByScoreAndReadiness::new(scoring, client); + + let tx_ready_low_score = { + let tx = Tx { + nonce: 1, + gas_price: 1, + ..Default::default() + }; + tx.signed().verified() + }; + let tx_future_high_score = { + let tx = Tx { + nonce: 3, // future nonce + gas_price: 10, + ..Default::default() + }; + tx.signed().verified() + }; + + assert_eq!(should_replace(&replace, tx_ready_low_score, tx_future_high_score), RejectNew); + } + + #[test] + fn should_compute_readiness_with_pooled_transactions_from_the_same_sender_as_the_existing_transaction() { + let scoring = NonceAndGasPrice(PrioritizationStrategy::GasPriceOnly); + let client = TestClient::new().with_nonce(1); + let replace = ReplaceByScoreAndReadiness::new(scoring, client); + + let old_sender = Random.generate().unwrap(); + let tx_old_ready_1 = { + let tx = Tx { + nonce: 1, + gas_price: 1, + ..Default::default() + }; + tx.unsigned().sign(&old_sender.secret(), None).verified() + }; + let tx_old_ready_2 = { + let tx = Tx { + nonce: 2, + gas_price: 1, + ..Default::default() + }; + tx.unsigned().sign(&old_sender.secret(), None).verified() + }; + let tx_old_ready_3 = { + let tx = Tx { + nonce: 3, + gas_price: 1, + ..Default::default() + }; + tx.unsigned().sign(&old_sender.secret(), None).verified() + }; + + let new_tx = { + let tx = Tx { + nonce: 3, // future nonce + gas_price: 10, + ..Default::default() + }; + tx.signed().verified() + }; + + let old_tx = txpool::Transaction { insertion_id: 0, transaction: Arc::new(tx_old_ready_3) }; + let pooled_txs = [ + txpool::Transaction { insertion_id: 0, transaction: Arc::new(tx_old_ready_1) }, + txpool::Transaction { insertion_id: 0, transaction: Arc::new(tx_old_ready_2) }, + ]; + + let new_tx = txpool::Transaction { insertion_id: 0, transaction: Arc::new(new_tx) }; + + let old = ReplaceTransaction::new(&old_tx, Some(&pooled_txs)); + let new = ReplaceTransaction::new(&new_tx, Default::default()); + + assert_eq!(replace.should_replace(&old, &new), RejectNew); + } + + #[test] + fn should_compute_readiness_with_pooled_transactions_from_the_same_sender_as_the_new_transaction() { + let scoring = NonceAndGasPrice(PrioritizationStrategy::GasPriceOnly); + let client = TestClient::new().with_nonce(1); + let replace = ReplaceByScoreAndReadiness::new(scoring, client); + + // current transaction is ready but has a lower gas price than the new one + let old_tx = { + let tx = Tx { + nonce: 1, + gas_price: 1, + ..Default::default() + }; + tx.signed().verified() + }; + + let new_sender = Random.generate().unwrap(); + let tx_new_ready_1 = { + let tx = Tx { + nonce: 1, + gas_price: 1, + ..Default::default() + }; + tx.unsigned().sign(&new_sender.secret(), None).verified() + }; + let tx_new_ready_2 = { + let tx = Tx { + nonce: 2, + gas_price: 1, + ..Default::default() + }; + tx.unsigned().sign(&new_sender.secret(), None).verified() + }; + let tx_new_ready_3 = { + let tx = Tx { + nonce: 3, + gas_price: 10, // hi + ..Default::default() + }; + tx.unsigned().sign(&new_sender.secret(), None).verified() + }; + + let old_tx = txpool::Transaction { insertion_id: 0, transaction: Arc::new(old_tx) }; + + let new_tx = txpool::Transaction { insertion_id: 0, transaction: Arc::new(tx_new_ready_3) }; + let pooled_txs = [ + txpool::Transaction { insertion_id: 0, transaction: Arc::new(tx_new_ready_1) }, + txpool::Transaction { insertion_id: 0, transaction: Arc::new(tx_new_ready_2) }, + ]; + + let old = ReplaceTransaction::new(&old_tx, None); + let new = ReplaceTransaction::new(&new_tx, Some(&pooled_txs)); + + assert_eq!(replace.should_replace(&old, &new), ReplaceOld); + } +} diff --git a/miner/src/pool/scoring.rs b/miner/src/pool/scoring.rs index aff7ac49ef..0360bec354 100644 --- a/miner/src/pool/scoring.rs +++ b/miner/src/pool/scoring.rs @@ -122,29 +122,6 @@ impl

txpool::Scoring

for NonceAndGasPrice where P: ScoredTransaction + txp } } - fn should_replace(&self, old: &P, new: &P) -> scoring::Choice { - let both_local = old.priority().is_local() && new.priority().is_local(); - if old.sender() == new.sender() { - // prefer earliest transaction - match new.nonce().cmp(&old.nonce()) { - cmp::Ordering::Equal => self.choose(old, new), - _ if both_local => scoring::Choice::InsertNew, - cmp::Ordering::Less => scoring::Choice::ReplaceOld, - cmp::Ordering::Greater => scoring::Choice::RejectNew, - } - } else if both_local { - scoring::Choice::InsertNew - } else { - let old_score = (old.priority(), old.gas_price()); - let new_score = (new.priority(), new.gas_price()); - if new_score > old_score { - scoring::Choice::ReplaceOld - } else { - scoring::Choice::RejectNew - } - } - } - fn should_ignore_sender_limit(&self, new: &P) -> bool { new.priority().is_local() } @@ -155,156 +132,8 @@ mod tests { use super::*; use std::sync::Arc; - use ethkey::{Random, Generator, KeyPair}; use pool::tests::tx::{Tx, TxExt}; use txpool::Scoring; - use txpool::scoring::Choice::*; - - fn local_tx_verified(tx: Tx, keypair: &KeyPair) -> VerifiedTransaction { - let mut verified_tx = tx.unsigned().sign(keypair.secret(), None).verified(); - verified_tx.priority = ::pool::Priority::Local; - verified_tx - } - - #[test] - fn should_always_accept_local_transactions_unless_same_sender_and_nonce() { - let scoring = NonceAndGasPrice(PrioritizationStrategy::GasPriceOnly); - - // same sender txs - let keypair = Random.generate().unwrap(); - - let same_sender_tx1 = local_tx_verified(Tx { - nonce: 1, - gas_price: 1, - ..Default::default() - }, &keypair); - - let same_sender_tx2 = local_tx_verified(Tx { - nonce: 2, - gas_price: 100, - ..Default::default() - }, &keypair); - - let same_sender_tx3 = local_tx_verified(Tx { - nonce: 2, - gas_price: 200, - ..Default::default() - }, &keypair); - - // different sender txs - let different_sender_tx1 = local_tx_verified(Tx { - nonce: 2, - gas_price: 1, - ..Default::default() - }, &Random.generate().unwrap()); - - let different_sender_tx2 = local_tx_verified(Tx { - nonce: 1, - gas_price: 10, - ..Default::default() - }, &Random.generate().unwrap()); - - assert_eq!(scoring.should_replace(&same_sender_tx1, &same_sender_tx2), InsertNew); - assert_eq!(scoring.should_replace(&same_sender_tx2, &same_sender_tx1), InsertNew); - - assert_eq!(scoring.should_replace(&different_sender_tx1, &different_sender_tx2), InsertNew); - assert_eq!(scoring.should_replace(&different_sender_tx2, &different_sender_tx1), InsertNew); - - // txs with same sender and nonce - assert_eq!(scoring.should_replace(&same_sender_tx2, &same_sender_tx3), ReplaceOld); - assert_eq!(scoring.should_replace(&same_sender_tx3, &same_sender_tx2), RejectNew); - } - - #[test] - fn should_replace_same_sender_by_nonce() { - let scoring = NonceAndGasPrice(PrioritizationStrategy::GasPriceOnly); - - let tx1 = Tx { - nonce: 1, - gas_price: 1, - ..Default::default() - }; - let tx2 = Tx { - nonce: 2, - gas_price: 100, - ..Default::default() - }; - let tx3 = Tx { - nonce: 2, - gas_price: 110, - ..Default::default() - }; - let tx4 = Tx { - nonce: 2, - gas_price: 130, - ..Default::default() - }; - - let keypair = Random.generate().unwrap(); - let txs = vec![tx1, tx2, tx3, tx4].into_iter().map(|tx| { - tx.unsigned().sign(keypair.secret(), None).verified() - }).collect::>(); - - assert_eq!(scoring.should_replace(&txs[0], &txs[1]), RejectNew); - assert_eq!(scoring.should_replace(&txs[1], &txs[0]), ReplaceOld); - - assert_eq!(scoring.should_replace(&txs[1], &txs[2]), RejectNew); - assert_eq!(scoring.should_replace(&txs[2], &txs[1]), RejectNew); - - assert_eq!(scoring.should_replace(&txs[1], &txs[3]), ReplaceOld); - assert_eq!(scoring.should_replace(&txs[3], &txs[1]), RejectNew); - } - - #[test] - fn should_replace_different_sender_by_priority_and_gas_price() { - // given - let scoring = NonceAndGasPrice(PrioritizationStrategy::GasPriceOnly); - let tx_regular_low_gas = { - let tx = Tx { - nonce: 1, - gas_price: 1, - ..Default::default() - }; - tx.signed().verified() - }; - let tx_regular_high_gas = { - let tx = Tx { - nonce: 2, - gas_price: 10, - ..Default::default() - }; - tx.signed().verified() - }; - let tx_local_low_gas = { - let tx = Tx { - nonce: 2, - gas_price: 1, - ..Default::default() - }; - let mut verified_tx = tx.signed().verified(); - verified_tx.priority = ::pool::Priority::Local; - verified_tx - }; - let tx_local_high_gas = { - let tx = Tx { - nonce: 1, - gas_price: 10, - ..Default::default() - }; - let mut verified_tx = tx.signed().verified(); - verified_tx.priority = ::pool::Priority::Local; - verified_tx - }; - - assert_eq!(scoring.should_replace(&tx_regular_low_gas, &tx_regular_high_gas), ReplaceOld); - assert_eq!(scoring.should_replace(&tx_regular_high_gas, &tx_regular_low_gas), RejectNew); - - assert_eq!(scoring.should_replace(&tx_regular_high_gas, &tx_local_low_gas), ReplaceOld); - assert_eq!(scoring.should_replace(&tx_local_low_gas, &tx_regular_high_gas), RejectNew); - - assert_eq!(scoring.should_replace(&tx_local_low_gas, &tx_local_high_gas), InsertNew); - assert_eq!(scoring.should_replace(&tx_local_high_gas, &tx_regular_low_gas), RejectNew); - } #[test] fn should_calculate_score_correctly() { diff --git a/rpc/Cargo.toml b/rpc/Cargo.toml index aea96f663a..33559a5595 100644 --- a/rpc/Cargo.toml +++ b/rpc/Cargo.toml @@ -70,7 +70,7 @@ ethcore-network = { path = "../util/network" } fake-fetch = { path = "../util/fake-fetch" } macros = { path = "../util/macros" } pretty_assertions = "0.1" -transaction-pool = "1.13" +transaction-pool = "2.0" [features] accounts = ["ethcore-accounts"] From 3c85f29f11364e334a23c879863bad5cbd2f41c5 Mon Sep 17 00:00:00 2001 From: soc1c Date: Tue, 2 Apr 2019 09:37:43 +0200 Subject: [PATCH 152/168] version: betalize 2.5 --- util/version/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/version/Cargo.toml b/util/version/Cargo.toml index 890b4e0a80..4135612a3f 100644 --- a/util/version/Cargo.toml +++ b/util/version/Cargo.toml @@ -10,7 +10,7 @@ build = "build.rs" [package.metadata] # This versions track. Should be changed to `stable` or `beta` when on respective branches. # Used by auto-updater and for Parity version string. -track = "nightly" +track = "beta" # Network specific settings, used ONLY by auto-updater. # Latest supported fork blocks. From b52ac20660782b8c3fddf98d0486c9f89f382a75 Mon Sep 17 00:00:00 2001 From: Talha Cross <47772477+soc1c@users.noreply.github.com> Date: Mon, 8 Apr 2019 11:44:10 +0200 Subject: [PATCH 153/168] beta backports (#10576) * Reject crazy timestamps instead of truncating. * fix(light cull): poll light cull instead of timer (#10559) * fix(light cull): poll light cull instead of timer * fix(grumbles): remove error + updated docs * fix(on-demand request): `expect()` reason * docs(remove misleading info) --- ethcore/types/src/header.rs | 14 +++- parity/light_helpers/mod.rs | 2 - parity/light_helpers/queue_cull.rs | 105 ----------------------------- parity/run.rs | 11 --- rpc/src/v1/helpers/light_fetch.rs | 44 +++++++++++- rpc/src/v1/impls/light/eth.rs | 15 +++-- 6 files changed, 65 insertions(+), 126 deletions(-) delete mode 100644 parity/light_helpers/queue_cull.rs diff --git a/ethcore/types/src/header.rs b/ethcore/types/src/header.rs index 3dfe6ab83b..cfe8f5bb65 100644 --- a/ethcore/types/src/header.rs +++ b/ethcore/types/src/header.rs @@ -16,7 +16,6 @@ //! Block header. -use std::cmp; use hash::{KECCAK_NULL_RLP, KECCAK_EMPTY_LIST_RLP, keccak}; use heapsize::HeapSizeOf; use ethereum_types::{H256, U256, Address, Bloom}; @@ -342,7 +341,7 @@ impl Decodable for Header { number: r.val_at(8)?, gas_limit: r.val_at(9)?, gas_used: r.val_at(10)?, - timestamp: cmp::min(r.val_at::(11)?, u64::max_value().into()).as_u64(), + timestamp: r.val_at(11)?, extra_data: r.val_at(12)?, seal: vec![], hash: keccak(r.as_raw()).into(), @@ -412,4 +411,15 @@ mod tests { assert_eq!(header_rlp, encoded_header); } + + #[test] + fn reject_header_with_large_timestamp() { + // that's rlp of block header created with ethash engine. + // The encoding contains a large timestamp (295147905179352825856) + let header_rlp = "f901f9a0d405da4e66f1445d455195229624e133f5baafe72b5cf7b3c36c12c8146e98b7a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a05fb2b4bfdef7b314451cb138a534d225c922fc0e5fbe25e451142732c3e25c25a088d2ec6b9860aae1a2c3b299f72b6a5d70d7f7ba4722c78f2c49ba96273c2158a007c6fdfa8eea7e86b81f5b0fc0f78f90cc19f4aa60d323151e0cac660199e9a1b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302008003832fefba82524d891000000000000000000080a0a0349d8c3df71f1a48a9df7d03fd5f14aeee7d91332c009ecaff0a71ead405bd88ab4e252a7e8c2a23".from_hex().unwrap(); + + // This should fail decoding timestamp + let header: Result = rlp::decode(&header_rlp); + assert_eq!(header.unwrap_err(), rlp::DecoderError::RlpIsTooBig); + } } diff --git a/parity/light_helpers/mod.rs b/parity/light_helpers/mod.rs index 9a9bbf2cd8..843dd419d4 100644 --- a/parity/light_helpers/mod.rs +++ b/parity/light_helpers/mod.rs @@ -17,7 +17,5 @@ //! Utilities and helpers for the light client. mod epoch_fetch; -mod queue_cull; pub use self::epoch_fetch::EpochFetch; -pub use self::queue_cull::QueueCull; diff --git a/parity/light_helpers/queue_cull.rs b/parity/light_helpers/queue_cull.rs deleted file mode 100644 index 693d8f93cf..0000000000 --- a/parity/light_helpers/queue_cull.rs +++ /dev/null @@ -1,105 +0,0 @@ -// Copyright 2015-2019 Parity Technologies (UK) Ltd. -// This file is part of Parity Ethereum. - -// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . - -//! Service for culling the light client's transaction queue. - -use std::sync::Arc; -use std::time::Duration; - -use ethcore::client::ClientIoMessage; -use sync::{LightSync, LightNetworkDispatcher}; -use io::{IoContext, IoHandler, TimerToken}; - -use light::client::LightChainClient; -use light::on_demand::{request, OnDemand, OnDemandRequester}; -use light::TransactionQueue; - -use futures::{future, Future}; - -use parity_runtime::Executor; - -use parking_lot::RwLock; - -// Attepmt to cull once every 10 minutes. -const TOKEN: TimerToken = 1; -const TIMEOUT: Duration = Duration::from_secs(60 * 10); - -// But make each attempt last only 9 minutes -const PURGE_TIMEOUT: Duration = Duration::from_secs(60 * 9); - -/// Periodically culls the transaction queue of mined transactions. -pub struct QueueCull { - /// A handle to the client, for getting the latest block header. - pub client: Arc, - /// A handle to the sync service. - pub sync: Arc, - /// The on-demand request service. - pub on_demand: Arc, - /// The transaction queue. - pub txq: Arc>, - /// Event loop executor. - pub executor: Executor, -} - -impl IoHandler for QueueCull { - fn initialize(&self, io: &IoContext) { - io.register_timer(TOKEN, TIMEOUT).expect("Error registering timer"); - } - - fn timeout(&self, _io: &IoContext, timer: TimerToken) { - if timer != TOKEN { return } - - let senders = self.txq.read().queued_senders(); - if senders.is_empty() { return } - - let (sync, on_demand, txq) = (self.sync.clone(), self.on_demand.clone(), self.txq.clone()); - let best_header = self.client.best_block_header(); - 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.executor.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() - .map(|&address| request::Account { header: best_header.clone().into(), address: address }) - .collect::>(); - - // when they come in, update each sender to the new nonce. - on_demand.request(ctx, nonce_reqs) - .expect("No back-references; therefore all back-references are valid; qed") - .map(move |accs| { - let txq = txq.write(); - let _ = accs.into_iter() - .map(|maybe_acc| maybe_acc.map_or(start_nonce, |acc| acc.nonce)) - .zip(senders) - .fold(txq, |mut txq, (nonce, addr)| { - txq.cull(addr, nonce); - txq - }); - }) - .map_err(|_| debug!(target: "cull", "OnDemand prematurely closed channel.")) - }); - - match maybe_fetching { - Some(fut) => future::Either::A(fut), - None => { - debug!(target: "cull", "Unable to acquire network context; qed"); - future::Either::B(future::ok(())) - }, - } - }, PURGE_TIMEOUT, || {}) - } -} diff --git a/parity/run.rs b/parity/run.rs index c4a3c75120..ca4ca1af10 100644 --- a/parity/run.rs +++ b/parity/run.rs @@ -295,17 +295,6 @@ fn execute_light_impl(cmd: RunCmd, logger: Arc, on_client_rq // spin up event loop let runtime = Runtime::with_default_thread_count(); - // queue cull service. - let queue_cull = Arc::new(::light_helpers::QueueCull { - client: client.clone(), - sync: light_sync.clone(), - on_demand: on_demand.clone(), - txq: txq.clone(), - executor: runtime.executor(), - }); - - service.register_handler(queue_cull).map_err(|e| format!("Error attaching service: {:?}", e))?; - // start the network. light_sync.start_network(); diff --git a/rpc/src/v1/helpers/light_fetch.rs b/rpc/src/v1/helpers/light_fetch.rs index e18695fcb7..819f566455 100644 --- a/rpc/src/v1/helpers/light_fetch.rs +++ b/rpc/src/v1/helpers/light_fetch.rs @@ -16,8 +16,9 @@ //! Helpers for fetching blockchain data either from the light client or the network. -use std::cmp; use std::clone::Clone; +use std::cmp; +use std::collections::BTreeMap; use std::sync::Arc; use types::basic_account::BasicAccount; @@ -48,7 +49,6 @@ use ethereum_types::{Address, U256}; use hash::H256; use parking_lot::{Mutex, RwLock}; use fastmap::H256FastMap; -use std::collections::BTreeMap; use types::transaction::{Action, Transaction as EthTransaction, PendingTransaction, SignedTransaction, LocalizedTransaction}; use v1::helpers::{CallRequest as CallRequestHelper, errors, dispatch}; @@ -523,6 +523,46 @@ where })) } + /// Helper to cull the `light` transaction queue of mined transactions + pub fn light_cull(&self, txq: Arc>) -> impl Future + Send { + let senders = txq.read().queued_senders(); + if senders.is_empty() { + return Either::B(future::err(errors::internal("No pending local transactions", ""))); + } + + let sync = self.sync.clone(); + let on_demand = self.on_demand.clone(); + let best_header = self.client.best_block_header(); + let start_nonce = self.client.engine().account_start_nonce(best_header.number()); + + let account_request = sync.with_context(move |ctx| { + // fetch the nonce of each sender in the queue. + let nonce_reqs = senders.iter() + .map(|&address| request::Account { header: best_header.clone().into(), address }) + .collect::>(); + + // when they come in, update each sender to the new nonce. + on_demand.request(ctx, nonce_reqs) + .expect(NO_INVALID_BACK_REFS_PROOF) + .map(move |accs| { + let mut txq = txq.write(); + accs.into_iter() + .map(|maybe_acc| maybe_acc.map_or(start_nonce, |acc| acc.nonce)) + .zip(senders) + .for_each(|(nonce, addr)| { + txq.cull(addr, nonce); + }); + }) + .map_err(errors::on_demand_error) + }); + + if let Some(fut) = account_request { + Either::A(fut) + } else { + Either::B(future::err(errors::network_disabled())) + } + } + fn send_requests(&self, reqs: Vec, parse_response: F) -> impl Future + Send where F: FnOnce(Vec) -> T + Send + 'static, T: Send + 'static, diff --git a/rpc/src/v1/impls/light/eth.rs b/rpc/src/v1/impls/light/eth.rs index 73e2b99c61..6467bfbc78 100644 --- a/rpc/src/v1/impls/light/eth.rs +++ b/rpc/src/v1/impls/light/eth.rs @@ -420,15 +420,22 @@ where } fn transaction_by_hash(&self, hash: H256) -> BoxFuture> { - { - let tx_queue = self.transaction_queue.read(); - if let Some(tx) = tx_queue.get(&hash) { + let in_txqueue = self.transaction_queue.read().get(&hash).is_some(); + + // The transaction is in the `local txqueue` then fetch the latest state from the network and attempt + // to cull the transaction queue. + if in_txqueue { + // Note, this will block (relies on HTTP timeout) to make sure `cull` will finish to avoid having to call + // `eth_getTransactionByHash` more than once to ensure the `txqueue` is up to `date` when it is called + if let Err(e) = self.fetcher().light_cull(self.transaction_queue.clone()).wait() { + debug!(target: "cull", "failed because of: {:?}", e); + } + if let Some(tx) = self.transaction_queue.read().get(&hash) { return Box::new(future::ok(Some(Transaction::from_pending( tx.clone(), )))); } } - Box::new(self.fetcher().transaction_by_hash(hash).map(|x| x.map(|(tx, _)| tx))) } From e0141f8324a63fc3ab94df28258fd80879aa2b02 Mon Sep 17 00:00:00 2001 From: Talha Cross <47772477+soc1c@users.noreply.github.com> Date: Fri, 10 May 2019 13:48:52 +0200 Subject: [PATCH 154/168] beta 2.5.1 (#10643) * version: bump beta to 2.5.1 * fix(whisper expiry): current time + work + ttl (#10587) * update bootnodes (#10595) * config: update goerli bootnodes * config: update kotti bootnodes * adds rpc error message for --no-ancient-blocks (#10608) * adds error message for --no-ancient-blocks, closes #10261 * Apply suggestions from code review Co-Authored-By: seunlanlege * Constantinople HF on POA Core (#10606) * Constantinople HF on POA Core Plan Constantinople/St.Petersfork HF on POA Core network at block 8582254. Original PR in POA repository: https://github.com/poanetwork/poa-chain-spec/pull/110 * Remove extra empty line * evm: add some mulmod benches (#10600) * evm: add blockhash_mulmod bench * evm: use num-bigint for mod ops * Clique: zero-fill extradata when the supplied value is less than 32 bytes in length (#10605) * Update kovan.json to switch validator set to POA Consensus Contracts (#10628) * Fix publish docs (#10635) * Fix publish docs * this never should be forced, either way compiling previous versions will produce outdated docs * fix array, var was moved to the group project global variables list * Fix rinkeby petersburg fork (#10632) --- .gitlab-ci.yml | 1 + Cargo.lock | 23 +++++++++---- Cargo.toml | 2 +- ethcore/evm/Cargo.toml | 1 + ethcore/evm/benches/basic.rs | 52 +++++++++++++++++++++++++++++- ethcore/evm/src/interpreter/mod.rs | 35 ++++++++++++++------ ethcore/evm/src/lib.rs | 1 + ethcore/res/ethereum/goerli.json | 10 ++++-- ethcore/res/ethereum/kotti.json | 4 ++- ethcore/res/ethereum/kovan.json | 37 ++++++++++++++------- ethcore/res/ethereum/poacore.json | 5 ++- ethcore/res/ethereum/rinkeby.json | 1 + ethcore/src/engines/clique/mod.rs | 8 +++++ parity/rpc_apis.rs | 2 ++ parity/run.rs | 1 + rpc/src/v1/helpers/errors.rs | 44 ++++++++++++++++--------- rpc/src/v1/impls/eth.rs | 28 +++++++++------- rpc/src/v1/tests/eth.rs | 3 +- util/version/Cargo.toml | 2 +- whisper/src/message.rs | 10 +++--- 20 files changed, 202 insertions(+), 68 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 436b8a156f..3f0ff87078 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -255,6 +255,7 @@ publish-docs: except: - nightly cache: {} + dependencies: [] script: - scripts/gitlab/publish-docs.sh tags: diff --git a/Cargo.lock b/Cargo.lock index c1b7f24796..69cf63f7ad 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1282,6 +1282,7 @@ dependencies = [ "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "memory-cache 0.1.0", + "num-bigint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2346,6 +2347,15 @@ dependencies = [ "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "num-bigint" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "num-integer" version = "0.1.39" @@ -2447,7 +2457,7 @@ dependencies = [ "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", "jni 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "panic_hook 0.1.0", - "parity-ethereum 2.5.0", + "parity-ethereum 2.5.1", "tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-current-thread 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2477,7 +2487,7 @@ dependencies = [ [[package]] name = "parity-ethereum" -version = "2.5.0" +version = "2.5.1" dependencies = [ "ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2530,7 +2540,7 @@ dependencies = [ "parity-rpc 1.12.0", "parity-runtime 0.1.0", "parity-updater 1.12.0", - "parity-version 2.5.0", + "parity-version 2.5.1", "parity-whisper 0.1.0", "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2673,7 +2683,7 @@ dependencies = [ "parity-crypto 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-runtime 0.1.0", "parity-updater 1.12.0", - "parity-version 2.5.0", + "parity-version 2.5.1", "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2771,7 +2781,7 @@ dependencies = [ "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-hash-fetch 1.12.0", "parity-path 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-version 2.5.0", + "parity-version 2.5.1", "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2781,7 +2791,7 @@ dependencies = [ [[package]] name = "parity-version" -version = "2.5.0" +version = "2.5.1" dependencies = [ "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "rlp 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4633,6 +4643,7 @@ dependencies = [ "checksum nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2" "checksum num 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "4703ad64153382334aa8db57c637364c322d3372e097840c72000dabdcf6156e" "checksum num-bigint 0.1.44 (registry+https://github.com/rust-lang/crates.io-index)" = "e63899ad0da84ce718c14936262a41cee2c79c981fc0a0e7c7beb47d5a07e8c1" +"checksum num-bigint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "57450397855d951f1a41305e54851b1a7b8f5d2e349543a02a2effe25459f718" "checksum num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "e83d528d2677f0518c570baf2b7abdcf0cd2d248860b68507bdcb3e91d4c0cea" "checksum num-iter 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "af3fdbbc3291a5464dc57b03860ec37ca6bf915ed6ee385e7c6c052c422b2124" "checksum num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31" diff --git a/Cargo.toml b/Cargo.toml index a783175607..ae5ae8c952 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ description = "Parity Ethereum client" name = "parity-ethereum" # NOTE Make sure to update util/version/Cargo.toml as well -version = "2.5.0" +version = "2.5.1" license = "GPL-3.0" authors = ["Parity Technologies "] diff --git a/ethcore/evm/Cargo.toml b/ethcore/evm/Cargo.toml index cb70c42e42..e40c7485f9 100644 --- a/ethcore/evm/Cargo.toml +++ b/ethcore/evm/Cargo.toml @@ -14,6 +14,7 @@ vm = { path = "../vm" } keccak-hash = "0.1" parking_lot = "0.7" memory-cache = { path = "../../util/memory-cache" } +num-bigint = "0.2" [dev-dependencies] rustc-hex = "1.0" diff --git a/ethcore/evm/benches/basic.rs b/ethcore/evm/benches/basic.rs index f17ba363a5..c86afcc575 100644 --- a/ethcore/evm/benches/basic.rs +++ b/ethcore/evm/benches/basic.rs @@ -45,7 +45,9 @@ criterion_group!( mem_gas_calculation_same_usize, mem_gas_calculation_same_u256, mem_gas_calculation_increasing_usize, - mem_gas_calculation_increasing_u256 + mem_gas_calculation_increasing_u256, + blockhash_mulmod_small, + blockhash_mulmod_large, ); criterion_main!(basic); @@ -150,6 +152,54 @@ fn mem_gas_calculation_increasing(gas: U256, b: &mut Bencher) { }); } +fn blockhash_mulmod_small(b: &mut Criterion) { + b.bench_function("blockhash_mulmod_small", |b| { + let factory = Factory::default(); + let mut ext = FakeExt::new(); + + let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap(); + + b.iter(|| { + let code = black_box( + "6080604052348015600f57600080fd5b5060005a90505b60c881111560de5760017effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80095060017effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80095060017effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80095060017effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80095060017effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8009505a90506016565b506035806100ed6000396000f3fe6080604052600080fdfea165627a7a72305820bde4a0ac6d0fac28fc879244baf8a6a0eda514bc95fb7ecbcaaebf2556e2687c0029".from_hex().unwrap() + ); + + let mut params = ActionParams::default(); + params.address = address.clone(); + params.gas = U256::from(4_000u64); + params.code = Some(Arc::new(code.clone())); + + let vm = factory.create(params, ext.schedule(), 0); + + result(vm.exec(&mut ext).ok().unwrap()) + }); + }); +} + +fn blockhash_mulmod_large(b: &mut Criterion) { + b.bench_function("blockhash_mulmod_large", |b| { + let factory = Factory::default(); + let mut ext = FakeExt::new(); + + let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap(); + + b.iter(|| { + let code = black_box( + "608060405234801561001057600080fd5b5060005a90505b60c8811115610177577efffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff17efffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff08009507efffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff17efffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff08009507efffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff17efffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff08009507efffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff17efffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff08009507efffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff17efffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff08009505a9050610017565b506035806101866000396000f3fe6080604052600080fdfea165627a7a72305820dcaec306f67bb96f3044fff25c9af2ec66f01d0954d0656964f046f42f2780670029".from_hex().unwrap() + ); + + let mut params = ActionParams::default(); + params.address = address.clone(); + params.gas = U256::from(4_000u64); + params.code = Some(Arc::new(code.clone())); + + let vm = factory.create(params, ext.schedule(), 0); + + result(vm.exec(&mut ext).ok().unwrap()) + }); + }); +} + fn result(r: Result) -> U256 { match r { Ok(GasLeft::Known(gas_left)) => gas_left, diff --git a/ethcore/evm/src/interpreter/mod.rs b/ethcore/evm/src/interpreter/mod.rs index d699e61cbe..84231abb57 100644 --- a/ethcore/evm/src/interpreter/mod.rs +++ b/ethcore/evm/src/interpreter/mod.rs @@ -28,7 +28,8 @@ use std::{cmp, mem}; use std::sync::Arc; use hash::keccak; use bytes::Bytes; -use ethereum_types::{U256, U512, H256, Address}; +use ethereum_types::{U256, H256, Address}; +use num_bigint::BigUint; use vm::{ self, ActionParams, ParamsType, ActionValue, CallType, MessageCallResult, @@ -61,6 +62,17 @@ const TWO_POW_96: U256 = U256([0, 0x100000000, 0, 0]); //0x1 00000000 00000000 0 const TWO_POW_224: U256 = U256([0, 0, 0, 0x100000000]); //0x1 00000000 00000000 00000000 00000000 00000000 00000000 00000000 const TWO_POW_248: U256 = U256([0, 0, 0, 0x100000000000000]); //0x1 00000000 00000000 00000000 00000000 00000000 00000000 00000000 000000 +fn to_biguint(x: U256) -> BigUint { + let mut bytes = [0u8; 32]; + x.to_little_endian(&mut bytes); + BigUint::from_bytes_le(&bytes) +} + +fn from_biguint(x: BigUint) -> U256 { + let bytes = x.to_bytes_le(); + U256::from_little_endian(&bytes) +} + /// Abstraction over raw vector of Bytes. Easier state management of PC. struct CodeReader { position: ProgramCounter, @@ -1009,11 +1021,12 @@ impl Interpreter { let c = self.stack.pop_back(); self.stack.push(if !c.is_zero() { - // upcast to 512 - let a5 = U512::from(a); - let res = a5.overflowing_add(U512::from(b)).0; - let x = res % U512::from(c); - U256::from(x) + let a_num = to_biguint(a); + let b_num = to_biguint(b); + let c_num = to_biguint(c); + let res = a_num + b_num; + let x = res % c_num; + from_biguint(x) } else { U256::zero() }); @@ -1024,10 +1037,12 @@ impl Interpreter { let c = self.stack.pop_back(); self.stack.push(if !c.is_zero() { - let a5 = U512::from(a); - let res = a5.overflowing_mul(U512::from(b)).0; - let x = res % U512::from(c); - U256::from(x) + let a_num = to_biguint(a); + let b_num = to_biguint(b); + let c_num = to_biguint(c); + let res = a_num * b_num; + let x = res % c_num; + from_biguint(x) } else { U256::zero() }); diff --git a/ethcore/evm/src/lib.rs b/ethcore/evm/src/lib.rs index 3548a1fe5e..03871864d5 100644 --- a/ethcore/evm/src/lib.rs +++ b/ethcore/evm/src/lib.rs @@ -24,6 +24,7 @@ extern crate vm; extern crate keccak_hash as hash; extern crate memory_cache; extern crate parity_bytes as bytes; +extern crate num_bigint; #[macro_use] extern crate lazy_static; diff --git a/ethcore/res/ethereum/goerli.json b/ethcore/res/ethereum/goerli.json index e3ba75927b..9717099385 100644 --- a/ethcore/res/ethereum/goerli.json +++ b/ethcore/res/ethereum/goerli.json @@ -48,8 +48,14 @@ "timestamp": "0x5c51a607" }, "nodes": [ - "enode://011f758e6552d105183b1761c5e2dea0111bc20fd5f6422bc7f91e0fabbec9a6595caf6239b37feb773dddd3f87240d99d859431891e4a642cf2a0a9e6cbb98a@51.141.78.53:30303", - "enode://176b9417f511d05b6b2cf3e34b756cf0a7096b3094572a8f6ef4cdcb9d1f9d00683bf0f83347eebdf3b81c3521c2332086d9592802230bf528eaf606a1d9677b@13.93.54.137:30303" + "enode://06333009fc9ef3c9e174768e495722a7f98fe7afd4660542e983005f85e556028410fd03278944f44cfe5437b1750b5e6bd1738f700fe7da3626d52010d2954c@51.141.15.254:30303", + "enode://176b9417f511d05b6b2cf3e34b756cf0a7096b3094572a8f6ef4cdcb9d1f9d00683bf0f83347eebdf3b81c3521c2332086d9592802230bf528eaf606a1d9677b@13.93.54.137:30303", + "enode://573b6607cd59f241e30e4c4943fd50e99e2b6f42f9bd5ca111659d309c06741247f4f1e93843ad3e8c8c18b6e2d94c161b7ef67479b3938780a97134b618b5ce@52.56.136.200:30303", + "enode://67913271d14f445689e8310270c304d42f268428f2de7a4ac0275bea97690e021df6f549f462503ff4c7a81d9dd27288867bbfa2271477d0911378b8944fae55@157.230.239.163:30303", + "enode://a87685902a0622e9cf18c68e73a0ea45156ec53e857ef049b185a9db2296ca04d776417bf1901c0b4eacb5b26271d8694e88e3f17c20d49eb77e1a41ab26b5b3@51.141.78.53:30303", + "enode://ae8658da8d255d1992c3ec6e62e11d6e1c5899aa1566504bc1ff96a0c9c8bd44838372be643342553817f5cc7d78f1c83a8093dee13d77b3b0a583c050c81940@18.232.185.151:30303", + "enode://ae8658da8d255d1992c3ec6e62e11d6e1c5899aa1566504bc1ff96a0c9c8bd44838372be643342553817f5cc7d78f1c83a8093dee13d77b3b0a583c050c81940@18.232.185.151:30303", + "enode://b477ca6d507a3f57070783eb62ba838847635f8b1a0cbffb8b7f8173f5894cf550f0225a5c279341e2d862a606e778b57180a4f1db3db78c51eadcfa4fdc6963@40.68.240.160:30303" ], "accounts": { "0x0000000000000000000000000000000000000000": { diff --git a/ethcore/res/ethereum/kotti.json b/ethcore/res/ethereum/kotti.json index 06d1d31ea3..cf531f6a5d 100644 --- a/ethcore/res/ethereum/kotti.json +++ b/ethcore/res/ethereum/kotti.json @@ -38,7 +38,9 @@ }, "nodes": [ "enode://06333009fc9ef3c9e174768e495722a7f98fe7afd4660542e983005f85e556028410fd03278944f44cfe5437b1750b5e6bd1738f700fe7da3626d52010d2954c@51.141.15.254:30303", - "enode://ae8658da8d255d1992c3ec6e62e11d6e1c5899aa1566504bc1ff96a0c9c8bd44838372be643342553817f5cc7d78f1c83a8093dee13d77b3b0a583c050c81940@18.232.185.151:30303" + "enode://93c94e999be5dd854c5d82a7cf5c14822973b5d9badb56ad4974586ec4d4f1995c815af795c20bb6e0a6226d3ee55808435c4dc89baf94ee581141b064d19dfc@80.187.116.161:25720", + "enode://ae8658da8d255d1992c3ec6e62e11d6e1c5899aa1566504bc1ff96a0c9c8bd44838372be643342553817f5cc7d78f1c83a8093dee13d77b3b0a583c050c81940@18.232.185.151:30303", + "enode://b477ca6d507a3f57070783eb62ba838847635f8b1a0cbffb8b7f8173f5894cf550f0225a5c279341e2d862a606e778b57180a4f1db3db78c51eadcfa4fdc6963@40.68.240.160:30303" ], "accounts": { "0x0000000000000000000000000000000000000000": { diff --git a/ethcore/res/ethereum/kovan.json b/ethcore/res/ethereum/kovan.json index 22a1974d32..67da802a95 100644 --- a/ethcore/res/ethereum/kovan.json +++ b/ethcore/res/ethereum/kovan.json @@ -7,17 +7,31 @@ "stepDuration": "0x4", "blockReward": "0x4563918244F40000", "validators": { - "list": [ - "0x00D6Cc1BA9cf89BD2e58009741f4F7325BAdc0ED", - "0x00427feae2419c15b89d1c21af10d1b6650a4d3d", - "0x4Ed9B08e6354C70fE6F8CB0411b0d3246b424d6c", - "0x0020ee4Be0e2027d76603cB751eE069519bA81A1", - "0x0010f94b296a852aaac52ea6c5ac72e03afd032d", - "0x007733a1FE69CF3f2CF989F81C7b4cAc1693387A", - "0x00E6d2b931F55a3f1701c7389d592a7778897879", - "0x00e4a10650e5a6D6001C38ff8E64F97016a1645c", - "0x00a0a24b9f0e5ec7aa4c7389b8302fd0123194de" - ] + "multi": { + "0": { + "list": [ + "0x00D6Cc1BA9cf89BD2e58009741f4F7325BAdc0ED", + "0x00427feae2419c15b89d1c21af10d1b6650a4d3d", + "0x4Ed9B08e6354C70fE6F8CB0411b0d3246b424d6c", + "0x0020ee4Be0e2027d76603cB751eE069519bA81A1", + "0x0010f94b296a852aaac52ea6c5ac72e03afd032d", + "0x007733a1FE69CF3f2CF989F81C7b4cAc1693387A", + "0x00E6d2b931F55a3f1701c7389d592a7778897879", + "0x00e4a10650e5a6D6001C38ff8E64F97016a1645c", + "0x00a0a24b9f0e5ec7aa4c7389b8302fd0123194de" + ] + }, + "10960440": { + "list": [ + "0x00D6Cc1BA9cf89BD2e58009741f4F7325BAdc0ED", + "0x0010f94b296a852aaac52ea6c5ac72e03afd032d", + "0x00a0a24b9f0e5ec7aa4c7389b8302fd0123194de" + ] + }, + "10960500": { + "safeContract": "0xaE71807C1B0a093cB1547b682DC78316D945c9B8" + } + } }, "validateScoreTransition": "0x41a3c4", "validateStepTransition": "0x16e360", @@ -5367,6 +5381,7 @@ } }, "nodes": [ + "enode://f6e37b943bad3a78cb8589b1798d30d210ffd39cfcd2c8f2de4f098467fd49c667980100d919da7ca46cd50505d30989abda87f0b9339377de13d6592c22caf8@34.198.49.72:30303", "enode://56abaf065581a5985b8c5f4f88bd202526482761ba10be9bfdcd14846dd01f652ec33fde0f8c0fd1db19b59a4c04465681fcef50e11380ca88d25996191c52de@40.71.221.215:30303", "enode://d07827483dc47b368eaf88454fb04b41b7452cf454e194e2bd4c14f98a3278fed5d819dbecd0d010407fc7688d941ee1e58d4f9c6354d3da3be92f55c17d7ce3@52.166.117.77:30303", "enode://38e6e7fd416293ed120d567a2675fe078c0205ab0671abf16982ce969823bd1f3443d590c18b321dfae7dcbe1f6ba98ef8702f255c3c9822a188abb82c53adca@51.77.66.187:30303", diff --git a/ethcore/res/ethereum/poacore.json b/ethcore/res/ethereum/poacore.json index 9fc34d22a2..a4fdbcbf10 100644 --- a/ethcore/res/ethereum/poacore.json +++ b/ethcore/res/ethereum/poacore.json @@ -34,7 +34,10 @@ "eip140Transition": "0x0", "eip211Transition": "0x0", "eip214Transition": "0x0", - "eip658Transition": "0x0" + "eip658Transition": "0x0", + "eip145Transition": 8582254, + "eip1014Transition": 8582254, + "eip1052Transition": 8582254 }, "genesis": { "seal": { diff --git a/ethcore/res/ethereum/rinkeby.json b/ethcore/res/ethereum/rinkeby.json index 7d9cc80237..1873617767 100644 --- a/ethcore/res/ethereum/rinkeby.json +++ b/ethcore/res/ethereum/rinkeby.json @@ -25,6 +25,7 @@ "eip1014Transition": "0x37db77", "eip1052Transition": "0x37db77", "eip1283Transition": "0x37db77", + "eip1283DisableTransition": "0x41efd2", "gasLimitBoundDivisor": "0x400", "maxCodeSize": "0x6000", "maxCodeSizeTransition": "0x0", diff --git a/ethcore/src/engines/clique/mod.rs b/ethcore/src/engines/clique/mod.rs index c0fad8e78f..742a7aec4d 100644 --- a/ethcore/src/engines/clique/mod.rs +++ b/ethcore/src/engines/clique/mod.rs @@ -67,6 +67,7 @@ use std::time; use std::time::{Duration, SystemTime, UNIX_EPOCH}; use block::ExecutedBlock; +use bytes::Bytes; use client::{BlockId, EngineClient}; use engines::clique::util::{extract_signers, recover_creator}; use engines::{Engine, EngineError, Seal}; @@ -713,6 +714,13 @@ impl Engine for Clique { header.set_difficulty(DIFF_NOTURN); } } + + let zero_padding_len = VANITY_LENGTH - header.extra_data().len(); + if zero_padding_len > 0 { + let mut resized_extra_data = header.extra_data().clone(); + resized_extra_data.resize(VANITY_LENGTH, 0); + header.set_extra_data(resized_extra_data); + } } else { trace!(target: "engine", "populate_from_parent: no signer registered"); } diff --git a/parity/rpc_apis.rs b/parity/rpc_apis.rs index 288f85ab42..668206174b 100644 --- a/parity/rpc_apis.rs +++ b/parity/rpc_apis.rs @@ -252,6 +252,7 @@ pub struct FullDependencies { pub gas_price_percentile: usize, pub poll_lifetime: u32, pub allow_missing_blocks: bool, + pub no_ancient_blocks: bool, } impl FullDependencies { @@ -303,6 +304,7 @@ impl FullDependencies { gas_price_percentile: self.gas_price_percentile, allow_missing_blocks: self.allow_missing_blocks, allow_experimental_rpcs: self.experimental_rpcs, + no_ancient_blocks: self.no_ancient_blocks } ); handler.extend_with(client.to_delegate()); diff --git a/parity/run.rs b/parity/run.rs index ca4ca1af10..a23f3d032d 100644 --- a/parity/run.rs +++ b/parity/run.rs @@ -742,6 +742,7 @@ fn execute_impl(cmd: RunCmd, logger: Arc, on_client_rq: gas_price_percentile: cmd.gas_price_percentile, poll_lifetime: cmd.poll_lifetime, allow_missing_blocks: cmd.allow_missing_blocks, + no_ancient_blocks: !cmd.download_old_blocks, }); let dependencies = rpc::Dependencies { diff --git a/rpc/src/v1/helpers/errors.rs b/rpc/src/v1/helpers/errors.rs index c04374d656..70c94904b7 100644 --- a/rpc/src/v1/helpers/errors.rs +++ b/rpc/src/v1/helpers/errors.rs @@ -29,6 +29,7 @@ use light::on_demand::error::{Error as OnDemandError, ErrorKind as OnDemandError use ethcore::client::BlockChainClient; use types::blockchain_info::BlockChainInfo; use v1::types::BlockNumber; +use v1::impls::EthClientOptions; mod codes { // NOTE [ToDr] Codes from [-32099, -32000] @@ -221,18 +222,34 @@ pub fn cannot_submit_work(err: EthcoreError) -> Error { } } -pub fn unavailable_block() -> Error { - Error { - code: ErrorCode::ServerError(codes::UNSUPPORTED_REQUEST), - message: "Ancient block sync is still in progress".into(), - data: None, +pub fn unavailable_block(no_ancient_block: bool, by_hash: bool) -> Error { + if no_ancient_block { + Error { + code: ErrorCode::ServerError(codes::UNSUPPORTED_REQUEST), + message: "Looks like you disabled ancient block download, unfortunately the information you're \ + trying to fetch doesn't exist in the db and is probably in the ancient blocks.".into(), + data: None, + } + } else if by_hash { + Error { + code: ErrorCode::ServerError(codes::UNSUPPORTED_REQUEST), + message: "Block information is incomplete while ancient block sync is still in progress, before \ + it's finished we can't determine the existence of requested item.".into(), + data: None, + } + } else { + Error { + code: ErrorCode::ServerError(codes::UNSUPPORTED_REQUEST), + message: "Requested block number is in a range that is not available yet, because the ancient block sync is still in progress.".into(), + data: None, + } } } pub fn check_block_number_existence<'a, T, C>( client: &'a C, num: BlockNumber, - allow_missing_blocks: bool, + options: EthClientOptions, ) -> impl Fn(Option) -> RpcResult> + 'a where C: BlockChainClient, @@ -242,8 +259,8 @@ pub fn check_block_number_existence<'a, T, C>( if let BlockNumber::Num(block_number) = num { // tried to fetch block number and got nothing even though the block number is // less than the latest block number - if block_number < client.chain_info().best_block_number && !allow_missing_blocks { - return Err(unavailable_block()); + if block_number < client.chain_info().best_block_number && !options.allow_missing_blocks { + return Err(unavailable_block(options.no_ancient_blocks, false)); } } } @@ -253,22 +270,17 @@ pub fn check_block_number_existence<'a, T, C>( pub fn check_block_gap<'a, T, C>( client: &'a C, - allow_missing_blocks: bool, + options: EthClientOptions, ) -> impl Fn(Option) -> RpcResult> + 'a where C: BlockChainClient, { move |response| { - if response.is_none() && !allow_missing_blocks { + if response.is_none() && !options.allow_missing_blocks { let BlockChainInfo { ancient_block_hash, .. } = client.chain_info(); // block information was requested, but unfortunately we couldn't find it and there // are gaps in the database ethcore/src/blockchain/blockchain.rs if ancient_block_hash.is_some() { - return Err(Error { - code: ErrorCode::ServerError(codes::UNSUPPORTED_REQUEST), - message: "Block information is incomplete while ancient block sync is still in progress, before \ - it's finished we can't determine the existence of requested item.".into(), - data: None, - }) + return Err(unavailable_block(options.no_ancient_blocks, true)) } } Ok(response) diff --git a/rpc/src/v1/impls/eth.rs b/rpc/src/v1/impls/eth.rs index 32f9c1c57f..734e70a61c 100644 --- a/rpc/src/v1/impls/eth.rs +++ b/rpc/src/v1/impls/eth.rs @@ -54,6 +54,7 @@ use v1::metadata::Metadata; const EXTRA_INFO_PROOF: &str = "Object exists in blockchain (fetched earlier), extra_info is always available if object exists; qed"; /// Eth RPC options +#[derive(Copy, Clone)] pub struct EthClientOptions { /// Return nonce from transaction queue when pending block not available. pub pending_nonce_from_queue: bool, @@ -68,6 +69,8 @@ pub struct EthClientOptions { pub allow_missing_blocks: bool, /// Enable Experimental RPC-Calls pub allow_experimental_rpcs: bool, + /// flag for ancient block sync + pub no_ancient_blocks: bool, } impl EthClientOptions { @@ -89,6 +92,7 @@ impl Default for EthClientOptions { gas_price_percentile: 50, allow_missing_blocks: false, allow_experimental_rpcs: false, + no_ancient_blocks: false, } } } @@ -669,7 +673,7 @@ impl Eth for EthClient< let trx_count = self.client.block(BlockId::Hash(hash)) .map(|block| block.transactions_count().into()); let result = Ok(trx_count) - .and_then(errors::check_block_gap(&*self.client, self.options.allow_missing_blocks)); + .and_then(errors::check_block_gap(&*self.client, self.options)); Box::new(future::done(result)) } @@ -684,7 +688,7 @@ impl Eth for EthClient< .and_then(errors::check_block_number_existence( &*self.client, num, - self.options.allow_missing_blocks + self.options )) } })) @@ -694,7 +698,7 @@ impl Eth for EthClient< let uncle_count = self.client.block(BlockId::Hash(hash)) .map(|block| block.uncles_count().into()); let result = Ok(uncle_count) - .and_then(errors::check_block_gap(&*self.client, self.options.allow_missing_blocks)); + .and_then(errors::check_block_gap(&*self.client, self.options)); Box::new(future::done(result)) } @@ -708,7 +712,7 @@ impl Eth for EthClient< .and_then(errors::check_block_number_existence( &*self.client, num, - self.options.allow_missing_blocks + self.options )) } })) @@ -730,13 +734,13 @@ impl Eth for EthClient< fn block_by_hash(&self, hash: H256, include_txs: bool) -> BoxFuture> { let result = self.rich_block(BlockId::Hash(hash).into(), include_txs) - .and_then(errors::check_block_gap(&*self.client, self.options.allow_missing_blocks)); + .and_then(errors::check_block_gap(&*self.client, self.options)); Box::new(future::done(result)) } fn block_by_number(&self, num: BlockNumber, include_txs: bool) -> BoxFuture> { let result = self.rich_block(num.clone().into(), include_txs).and_then( - errors::check_block_number_existence(&*self.client, num, self.options.allow_missing_blocks)); + errors::check_block_number_existence(&*self.client, num, self.options)); Box::new(future::done(result)) } @@ -746,14 +750,14 @@ impl Eth for EthClient< .map(|t| Transaction::from_pending(t.pending().clone())) }); let result = Ok(tx).and_then( - errors::check_block_gap(&*self.client, self.options.allow_missing_blocks)); + errors::check_block_gap(&*self.client, self.options)); Box::new(future::done(result)) } fn transaction_by_block_hash_and_index(&self, hash: H256, index: Index) -> BoxFuture> { let id = PendingTransactionId::Location(PendingOrBlock::Block(BlockId::Hash(hash)), index.value()); let result = self.transaction(id).and_then( - errors::check_block_gap(&*self.client, self.options.allow_missing_blocks)); + errors::check_block_gap(&*self.client, self.options)); Box::new(future::done(result)) } @@ -767,7 +771,7 @@ impl Eth for EthClient< let transaction_id = PendingTransactionId::Location(block_id, index.value()); let result = self.transaction(transaction_id).and_then( - errors::check_block_number_existence(&*self.client, num, self.options.allow_missing_blocks)); + errors::check_block_number_existence(&*self.client, num, self.options)); Box::new(future::done(result)) } @@ -781,7 +785,7 @@ impl Eth for EthClient< let receipt = self.client.transaction_receipt(TransactionId::Hash(hash)); let result = Ok(receipt.map(Into::into)) - .and_then(errors::check_block_gap(&*self.client, self.options.allow_missing_blocks)); + .and_then(errors::check_block_gap(&*self.client, self.options)); Box::new(future::done(result)) } @@ -789,7 +793,7 @@ impl Eth for EthClient< let result = self.uncle(PendingUncleId { id: PendingOrBlock::Block(BlockId::Hash(hash)), position: index.value() - }).and_then(errors::check_block_gap(&*self.client, self.options.allow_missing_blocks)); + }).and_then(errors::check_block_gap(&*self.client, self.options)); Box::new(future::done(result)) } @@ -806,7 +810,7 @@ impl Eth for EthClient< .and_then(errors::check_block_number_existence( &*self.client, num, - self.options.allow_missing_blocks + self.options )); Box::new(future::done(result)) diff --git a/rpc/src/v1/tests/eth.rs b/rpc/src/v1/tests/eth.rs index 68710ae559..9c2273746f 100644 --- a/rpc/src/v1/tests/eth.rs +++ b/rpc/src/v1/tests/eth.rs @@ -143,7 +143,8 @@ impl EthTester { send_block_number_in_get_work: true, gas_price_percentile: 50, allow_experimental_rpcs: true, - allow_missing_blocks: false + allow_missing_blocks: false, + no_ancient_blocks: false }, ); diff --git a/util/version/Cargo.toml b/util/version/Cargo.toml index 4135612a3f..2c4fdebde5 100644 --- a/util/version/Cargo.toml +++ b/util/version/Cargo.toml @@ -3,7 +3,7 @@ [package] name = "parity-version" # NOTE: this value is used for Parity Ethereum version string (via env CARGO_PKG_VERSION) -version = "2.5.0" +version = "2.5.1" authors = ["Parity Technologies "] build = "build.rs" diff --git a/whisper/src/message.rs b/whisper/src/message.rs index 0fc686e52a..c10d39700f 100644 --- a/whisper/src/message.rs +++ b/whisper/src/message.rs @@ -264,17 +264,17 @@ impl Message { let mut rng = { let mut thread_rng = ::rand::thread_rng(); - XorShiftRng::from_seed(thread_rng.gen::<[u32; 4]>()) }; assert!(params.ttl > 0); let expiry = { - let after_mining = SystemTime::now().checked_sub(Duration::from_millis(params.work)) - .ok_or(Error::TimestampOverflow)?; - let since_epoch = after_mining.duration_since(time::UNIX_EPOCH) - .expect("time after now is after unix epoch; qed"); + let since_epoch = SystemTime::now() + .checked_add(Duration::from_secs(params.ttl)) + .and_then(|t| t.checked_add(Duration::from_millis(params.work))) + .ok_or(Error::TimestampOverflow)? + .duration_since(time::UNIX_EPOCH).expect("time after now is after unix epoch; qed"); // round up the sub-second to next whole second. since_epoch.as_secs() + if since_epoch.subsec_nanos() == 0 { 0 } else { 1 } From c2487cfe07d904623a5ccaf9ade01b74fcbb910a Mon Sep 17 00:00:00 2001 From: Talha Cross <47772477+soc1c@users.noreply.github.com> Date: Tue, 14 May 2019 14:04:54 +0200 Subject: [PATCH 155/168] ci: publish docs debug (#10638) (#10660) --- .gitlab-ci.yml | 1 + scripts/gitlab/publish-docs.sh | 7 +++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 3f0ff87078..5d285844b9 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -260,3 +260,4 @@ publish-docs: - scripts/gitlab/publish-docs.sh tags: - linux-docker + allow_failure: true diff --git a/scripts/gitlab/publish-docs.sh b/scripts/gitlab/publish-docs.sh index 262ea80807..2508c82555 100755 --- a/scripts/gitlab/publish-docs.sh +++ b/scripts/gitlab/publish-docs.sh @@ -51,8 +51,11 @@ commit_files() { upload_files() { echo "__________Upload files__________" - git push -q origin HEAD - git push -q -f --tags + # this version of git (2.7.4) will dump the token on failure + git push -q origin HEAD 2>&1 \ + | sed -r "s|(${GITHUB_USER}):[a-f0-9]+@|\1:REDACTED@|g" + git push -q -f --tags 2>&1 \ + | sed -r "s|(${GITHUB_USER}):[a-f0-9]+@|\1:REDACTED@|g" } RPC_TRAITS_DIR="rpc/src/v1/traits" From adabd8198c05338d841aaffee9eacd790e7b7251 Mon Sep 17 00:00:00 2001 From: Talha Cross <47772477+soc1c@users.noreply.github.com> Date: Tue, 14 May 2019 15:03:29 +0200 Subject: [PATCH 156/168] beta ci: backport missing diff from master (#10661) * ci: publish docs debug (#10638) * ci: backport missing diff from master --- .gitlab-ci.yml | 81 ++++++++++++++++++--------- scripts/gitlab/build-linux.sh | 12 ++-- scripts/gitlab/build-windows.sh | 10 ++-- scripts/gitlab/test-linux.sh | 7 ++- scripts/gitlab/validate-chainspecs.sh | 2 +- 5 files changed, 73 insertions(+), 39 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 5d285844b9..acea999e2e 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -34,37 +34,58 @@ variables: .docker-cache-status: &docker-cache-status variables: CARGO_HOME: "/ci-cache/parity-ethereum/cargo/${CI_JOB_NAME}" + dependencies: [] before_script: - - SCCACHE_ERROR_LOG=/builds/parity/parity-ethereum/sccache_error.log RUST_LOG=sccache::server=debug sccache --start-server + - SCCACHE_ERROR_LOG=/builds/parity/parity-ethereum/sccache_debug.log + RUST_LOG=sccache=debug + sccache --start-server - sccache -s after_script: - - echo "All crate-types:" - - grep 'parse_arguments.*--crate-type' sccache_error.log | sed -re 's/.*"--crate-type", "([^"]+)".*/\1/' | sort | uniq -c - - echo "Non-cacheable reasons:" - - grep CannotCache sccache_error.log | sed -re 's/.*CannotCache\((.+)\).*/\1/' | sort | uniq -c + # sccache debug info + - if test -e sccache_debug.log; + then + echo "_____sccache_debug.log listing start:_____"; + cat sccache_debug.log; + echo "_____sccache_debug.log listing end_____"; + echo "All crate-types:"; + grep 'parse_arguments.*--crate-type' sccache_debug.log | sed -re 's/.*"--crate-type", "([^"]+)".*/\1/' | sort | uniq -c; + echo "_____Non-cacheable reasons:_____"; + grep CannotCache sccache_debug.log | sed -re 's/.*CannotCache\((.+)\).*/\1/' | sort | uniq -c; + else + echo "_____No logs from sccache_____"; + exit 0; + fi tags: - linux-docker +.build-on-linux: &build-on-linux + stage: build + <<: *docker-cache-status + <<: *collect_artifacts + script: + - scripts/gitlab/build-linux.sh + - sccache -s + cargo-check 0 3: stage: test <<: *docker-cache-status script: - - time cargo check --target $CARGO_TARGET --locked --no-default-features + - time cargo check --target $CARGO_TARGET --locked --no-default-features --verbose --color=always - sccache -s cargo-check 1 3: stage: test <<: *docker-cache-status script: - - time cargo check --target $CARGO_TARGET --locked --manifest-path util/io/Cargo.toml --no-default-features + - time cargo check --target $CARGO_TARGET --locked --manifest-path util/io/Cargo.toml --no-default-features --verbose --color=always - sccache -s cargo-check 2 3: stage: test <<: *docker-cache-status script: - - time cargo check --target $CARGO_TARGET --locked --manifest-path util/io/Cargo.toml --features "mio" + - time cargo check --target $CARGO_TARGET --locked --manifest-path util/io/Cargo.toml --features "mio" --verbose --color=always - sccache -s cargo-audit: @@ -72,7 +93,6 @@ cargo-audit: <<: *docker-cache-status script: - cargo audit - - sccache -s validate-chainspecs: stage: test @@ -92,55 +112,64 @@ test-linux: stage: build <<: *docker-cache-status script: - - ./scripts/gitlab/test-linux.sh + - ./scripts/gitlab/test-linux.sh stable - sccache -s -build-android: +test-linux-beta: stage: build - image: parity/rust-parity-ethereum-android-build:stretch - variables: - CARGO_TARGET: armv7-linux-androideabi + only: *releaseable_branches <<: *docker-cache-status - <<: *collect_artifacts script: - - scripts/gitlab/build-linux.sh - tags: - - linux-docker + - ./scripts/gitlab/test-linux.sh beta + - sccache -s -build-linux: &build-linux +test-linux-nightly: stage: build only: *releaseable_branches <<: *docker-cache-status - <<: *collect_artifacts script: - - scripts/gitlab/build-linux.sh + - ./scripts/gitlab/test-linux.sh nightly - sccache -s + allow_failure: true + +build-android: + <<: *build-on-linux + image: parity/rust-parity-ethereum-android-build:stretch + variables: + CARGO_TARGET: armv7-linux-androideabi + +build-linux: + <<: *build-on-linux + only: *releaseable_branches build-linux-i386: - <<: *build-linux + <<: *build-on-linux + only: *releaseable_branches image: parity/rust-parity-ethereum-build:i386 variables: CARGO_TARGET: i686-unknown-linux-gnu build-linux-arm64: - <<: *build-linux + <<: *build-on-linux + only: *releaseable_branches image: parity/rust-parity-ethereum-build:arm64 variables: CARGO_TARGET: aarch64-unknown-linux-gnu build-linux-armhf: - <<: *build-linux + <<: *build-on-linux + only: *releaseable_branches image: parity/rust-parity-ethereum-build:armhf variables: CARGO_TARGET: armv7-unknown-linux-gnueabihf build-darwin: stage: build - only: *releaseable_branches <<: *collect_artifacts + only: *releaseable_branches variables: CARGO_TARGET: x86_64-apple-darwin - CARGO_HOME: "${CI_PROJECT_DIR}/.cargo" + CARGO_HOME: "${CI_PROJECT_DIR}/.cargo" CC: gcc CXX: g++ script: diff --git a/scripts/gitlab/build-linux.sh b/scripts/gitlab/build-linux.sh index f0697080cb..ebd65cd9b3 100755 --- a/scripts/gitlab/build-linux.sh +++ b/scripts/gitlab/build-linux.sh @@ -18,13 +18,13 @@ cat .cargo/config echo "_____ Building target: "$CARGO_TARGET" _____" if [ "${CARGO_TARGET}" = "armv7-linux-androideabi" ] then - time cargo build --target $CARGO_TARGET --release -p parity-clib --features final + time cargo build --target $CARGO_TARGET --verbose --color=always --release -p parity-clib --features final else - time cargo build --target $CARGO_TARGET --release --features final - time cargo build --target $CARGO_TARGET --release -p evmbin - time cargo build --target $CARGO_TARGET --release -p ethstore-cli - time cargo build --target $CARGO_TARGET --release -p ethkey-cli - time cargo build --target $CARGO_TARGET --release -p whisper-cli + time cargo build --target $CARGO_TARGET --verbose --color=always --release --features final + time cargo build --target $CARGO_TARGET --verbose --color=always --release -p evmbin + time cargo build --target $CARGO_TARGET --verbose --color=always --release -p ethstore-cli + time cargo build --target $CARGO_TARGET --verbose --color=always --release -p ethkey-cli + time cargo build --target $CARGO_TARGET --verbose --color=always --release -p whisper-cli fi echo "_____ Post-processing binaries _____" diff --git a/scripts/gitlab/build-windows.sh b/scripts/gitlab/build-windows.sh index 7ddf4453e5..76332124d1 100755 --- a/scripts/gitlab/build-windows.sh +++ b/scripts/gitlab/build-windows.sh @@ -14,11 +14,11 @@ echo "RUSTC_WRAPPER: " $RUSTC_WRAPPER echo "SCCACHE_DIR: " $SCCACHE_DIR echo "_____ Building target: "$CARGO_TARGET" _____" -time cargo build --target $CARGO_TARGET --release --features final -time cargo build --target $CARGO_TARGET --release -p evmbin -time cargo build --target $CARGO_TARGET --release -p ethstore-cli -time cargo build --target $CARGO_TARGET --release -p ethkey-cli -time cargo build --target $CARGO_TARGET --release -p whisper-cli +time cargo build --target $CARGO_TARGET --verbose --release --features final +time cargo build --target $CARGO_TARGET --verbose --release -p evmbin +time cargo build --target $CARGO_TARGET --verbose --release -p ethstore-cli +time cargo build --target $CARGO_TARGET --verbose --release -p ethkey-cli +time cargo build --target $CARGO_TARGET --verbose --release -p whisper-cli echo "__________Sign binaries__________" scripts/gitlab/sign-win.cmd $keyfile $certpass target/$CARGO_TARGET/release/parity.exe diff --git a/scripts/gitlab/test-linux.sh b/scripts/gitlab/test-linux.sh index 6a98d2f7bd..2854508bb5 100755 --- a/scripts/gitlab/test-linux.sh +++ b/scripts/gitlab/test-linux.sh @@ -1,4 +1,6 @@ #!/bin/bash +# ARGUMENT $1 Rust flavor to run test with (stable/beta/nightly) + echo "________Running test-linux.sh________" set -e # fail on any error set -u # treat unset variables as error @@ -8,5 +10,8 @@ OPTIONS="--release" #use nproc `linux only THREADS=$(nproc) +rustup default $1 +rustup show + echo "________Running Parity Full Test Suite________" -time cargo test $OPTIONS --features "$FEATURES" --locked --all --target $CARGO_TARGET -- --test-threads $THREADS +time cargo test $OPTIONS --features "$FEATURES" --locked --all --target $CARGO_TARGET --verbose --color=always -- --test-threads $THREADS diff --git a/scripts/gitlab/validate-chainspecs.sh b/scripts/gitlab/validate-chainspecs.sh index 9b7ef39e72..58391e1312 100755 --- a/scripts/gitlab/validate-chainspecs.sh +++ b/scripts/gitlab/validate-chainspecs.sh @@ -6,7 +6,7 @@ echo "________Running validate_chainspecs.sh________" ERR=0 echo "________Validate chainspecs________" -time cargo build --release -p chainspec +time cargo build --release -p chainspec --verbose --color=always for spec in ethcore/res/*.json; do if ! ./target/release/chainspec "$spec"; then ERR=1; fi From ecbafb2390b67b7a56902150de8c1cab44eb6fd7 Mon Sep 17 00:00:00 2001 From: Talha Cross <47772477+soc1c@users.noreply.github.com> Date: Tue, 11 Jun 2019 20:56:03 +0200 Subject: [PATCH 157/168] backports for beta 2.5.2 (#10737) * version: bump beta to 2.5.2 * [CI] allow cargo audit to fail (#10676) * [CI] allow cargo audit to fail * [.gitlab-ci.yml] add a comment about cargo audit * [Cargo.lock] cargo update -p protobuf * Reset blockchain properly (#10669) * delete BlockDetails from COL_EXTRA * better proofs * added tests * PR suggestions * new image (#10673) * Update publishing (#10644) * docker images are now built on k8s: test run * copy check_sync.sh in build-linux job * copy scripts/docker/hub/* in build-linux job * removed cache var * cleanup, no more nightly dockers * cleanup in dockerfile * some new tags * removed sccsche debug log, cleanup * no_gits, new artifacts dir, changed scripts. Test run. * define version once * one source for TRACK * stop kovan onchain updates * moved changes for two images to a new branch * rename Dockerfile * no need in libudev-dev * enable lto for release builds (#10717) * Use RUSTFLAGS to set the optimization level (#10719) * Use RUSTFLAGS to set the optimization level Cargo has a [quirk]() in how configuration settings are propagated when `cargo test` runs: local code respect the settings in `[profile.test]` but all dependencies use the `[profile.dev]` settings. Here we force `opt-level=3` for all dependencies. * Remove unused profile settings * Maybe like this? * Turn off incremental compilation * Remove colors; try again with overflow-checks on * Use quiet CI machine * Turn overflow checking back on * Be explicit about what options we use * Remove "quiet machine" override * ethcore: enable ECIP-1054 for classic (#10731) * config: enable atlantis on ethereum classic * config: enable atlantis on morden classic * config: enable atlantis on morden classic * config: enable atlantis on kotti classic * ethcore: move kotti fork block to 0xAEF49 * ethcore: move morden fork block to 0x4829BA * ethcore: move classic fork block to 0x81B320 * remove trailing comma * remove trailing comma * fix chainspec * ethcore: move classic fork block to 0x7fffffffffffffff --- .gitlab-ci.yml | 57 ++++++++++--- Cargo.lock | 20 ++--- Cargo.toml | 7 +- ethcore/blockchain/src/blockchain.rs | 23 ++--- ethcore/res/ethereum/classic.json | 120 ++++++++++++++++++++++++--- ethcore/res/ethereum/kotti.json | 57 +++++++++++-- ethcore/res/ethereum/morden.json | 74 ++++++++++++++--- ethcore/src/client/client.rs | 67 ++++++++++----- ethcore/src/tests/client.rs | 22 ++++- scripts/docker/hub/Dockerfile | 44 +++++++--- scripts/docker/hub/publish-docker.sh | 57 +++++++++++++ scripts/gitlab/publish-docker.sh | 22 ----- scripts/gitlab/publish-docs.sh | 4 +- scripts/gitlab/publish-onchain.sh | 9 +- scripts/gitlab/publish-snap.sh | 16 +--- scripts/gitlab/test-linux.sh | 5 +- util/version/Cargo.toml | 2 +- 17 files changed, 456 insertions(+), 150 deletions(-) create mode 100755 scripts/docker/hub/publish-docker.sh delete mode 100755 scripts/gitlab/publish-docker.sh diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index acea999e2e..33cfbd9d9f 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -4,11 +4,13 @@ stages: - publish - optional -image: parity/rust-parity-ethereum-build:xenial +image: parity/parity-ci-linux:latest variables: GIT_STRATEGY: fetch GIT_SUBMODULE_STRATEGY: recursive CI_SERVER_NAME: "GitLab CI" + CARGO_HOME: "/ci-cache/${CI_PROJECT_NAME}/cargo/${CI_JOB_NAME}" + SCCACHE_DIR: "/ci-cache/${CI_PROJECT_NAME}/sccache" CARGO_TARGET: x86_64-unknown-linux-gnu .no_git: &no_git # disable git strategy @@ -30,12 +32,15 @@ variables: expire_in: 1 mos paths: - artifacts/ + - tools/ .docker-cache-status: &docker-cache-status variables: CARGO_HOME: "/ci-cache/parity-ethereum/cargo/${CI_JOB_NAME}" dependencies: [] before_script: + - rustup show + - cargo --version - SCCACHE_ERROR_LOG=/builds/parity/parity-ethereum/sccache_debug.log RUST_LOG=sccache=debug sccache --start-server @@ -44,10 +49,7 @@ variables: # sccache debug info - if test -e sccache_debug.log; then - echo "_____sccache_debug.log listing start:_____"; - cat sccache_debug.log; - echo "_____sccache_debug.log listing end_____"; - echo "All crate-types:"; + echo "_____All crate-types:_____"; grep 'parse_arguments.*--crate-type' sccache_debug.log | sed -re 's/.*"--crate-type", "([^"]+)".*/\1/' | sort | uniq -c; echo "_____Non-cacheable reasons:_____"; grep CannotCache sccache_debug.log | sed -re 's/.*CannotCache\((.+)\).*/\1/' | sort | uniq -c; @@ -65,6 +67,16 @@ variables: script: - scripts/gitlab/build-linux.sh - sccache -s + after_script: + - mkdir -p tools + - cp -r scripts/docker/hub/* ./tools + - cp scripts/gitlab/publish-snap.sh ./tools + - cp scripts/gitlab/publish-onchain.sh ./tools + - cp scripts/gitlab/safe-curl.sh ./tools + - echo v"$(sed -r -n '1,/^version/s/^version\s*=\s*"([^"]+)".*$/\1/p' Cargo.toml)" | + tee ./tools/VERSION + - echo "$(sed -r -n '1,/^track/s/^track\s*=\s*"([^"]+)".*$/\1/p' ./util/version/Cargo.toml)" | + tee ./tools/TRACK cargo-check 0 3: @@ -93,6 +105,7 @@ cargo-audit: <<: *docker-cache-status script: - cargo audit + allow_failure: true # failed cargo audit shouldn't prevent a PR from being merged validate-chainspecs: stage: test @@ -192,19 +205,35 @@ build-windows: publish-docker: stage: publish + <<: *no_git only: *releaseable_branches - cache: {} + except: + variables: + - $SCHEDULE_TAG == "nightly" dependencies: - build-linux - tags: - - shell + environment: + name: parity-build + cache: {} + image: docker:stable + services: + - docker:dind + variables: + DOCKER_HOST: tcp://localhost:2375 + DOCKER_DRIVER: overlay2 + GIT_STRATEGY: none + # DOCKERFILE: tools/Dockerfile + # CONTAINER_IMAGE: parity/parity script: - - scripts/gitlab/publish-docker.sh parity + # we stopped pushing nightlies to dockerhub, will push to own registry prb. + - ./tools/publish-docker.sh + tags: + - kubernetes-parity-build publish-snap: &publish-snap stage: publish + <<: *no_git only: *releaseable_branches - <<: *collect_artifacts image: snapcore/snapcraft variables: BUILD_ARCH: amd64 @@ -214,12 +243,13 @@ publish-snap: &publish-snap tags: - linux-docker script: - - scripts/gitlab/publish-snap.sh + - ./tools/publish-snap.sh publish-snap-i386: <<: *publish-snap variables: BUILD_ARCH: i386 + CARGO_TARGET: i686-unknown-linux-gnu dependencies: - build-linux-i386 @@ -227,6 +257,7 @@ publish-snap-arm64: <<: *publish-snap variables: BUILD_ARCH: arm64 + CARGO_TARGET: aarch64-unknown-linux-gnu dependencies: - build-linux-arm64 @@ -234,11 +265,13 @@ publish-snap-armhf: <<: *publish-snap variables: BUILD_ARCH: armhf + CARGO_TARGET: armv7-unknown-linux-gnueabihf dependencies: - build-linux-armhf publish-onchain: stage: publish + <<: *no_git only: *releaseable_branches cache: {} dependencies: @@ -246,7 +279,7 @@ publish-onchain: - build-darwin - build-windows script: - - scripts/gitlab/publish-onchain.sh + - ./tools/publish-onchain.sh tags: - linux-docker diff --git a/Cargo.lock b/Cargo.lock index 69cf63f7ad..c0f79d9da0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1546,7 +1546,7 @@ dependencies = [ "libusb 0.3.0 (git+https://github.com/paritytech/libusb-rs)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "protobuf 1.7.4 (registry+https://github.com/rust-lang/crates.io-index)", + "protobuf 1.7.5 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "trezor-sys 1.0.0 (git+https://github.com/paritytech/trezor-sys)", @@ -2457,7 +2457,7 @@ dependencies = [ "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", "jni 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "panic_hook 0.1.0", - "parity-ethereum 2.5.1", + "parity-ethereum 2.5.2", "tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-current-thread 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2487,7 +2487,7 @@ dependencies = [ [[package]] name = "parity-ethereum" -version = "2.5.1" +version = "2.5.2" dependencies = [ "ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2540,7 +2540,7 @@ dependencies = [ "parity-rpc 1.12.0", "parity-runtime 0.1.0", "parity-updater 1.12.0", - "parity-version 2.5.1", + "parity-version 2.5.2", "parity-whisper 0.1.0", "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2683,7 +2683,7 @@ dependencies = [ "parity-crypto 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-runtime 0.1.0", "parity-updater 1.12.0", - "parity-version 2.5.1", + "parity-version 2.5.2", "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2781,7 +2781,7 @@ dependencies = [ "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-hash-fetch 1.12.0", "parity-path 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-version 2.5.1", + "parity-version 2.5.2", "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2791,7 +2791,7 @@ dependencies = [ [[package]] name = "parity-version" -version = "2.5.1" +version = "2.5.2" dependencies = [ "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "rlp 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3071,7 +3071,7 @@ dependencies = [ [[package]] name = "protobuf" -version = "1.7.4" +version = "1.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -4076,7 +4076,7 @@ name = "trezor-sys" version = "1.0.0" source = "git+https://github.com/paritytech/trezor-sys#8a401705e58c83db6c29c199d9577b78fde40709" dependencies = [ - "protobuf 1.7.4 (registry+https://github.com/rust-lang/crates.io-index)", + "protobuf 1.7.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4687,7 +4687,7 @@ dependencies = [ "checksum primal-estimate 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "56ea4531dde757b56906493c8604641da14607bf9cdaa80fb9c9cabd2429f8d5" "checksum primal-sieve 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "da2d6ed369bb4b0273aeeb43f07c105c0117717cbae827b20719438eb2eb798c" "checksum proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)" = "3d7b7eaaa90b4a90a932a9ea6666c95a389e424eff347f0f793979289429feee" -"checksum protobuf 1.7.4 (registry+https://github.com/rust-lang/crates.io-index)" = "52fbc45bf6709565e44ef31847eb7407b3c3c80af811ee884a04da071dcca12b" +"checksum protobuf 1.7.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e14ccd6b79ec748412d4f2dfde1a80fa363a67def4062969f8aed3d790a30f28" "checksum pulldown-cmark 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8361e81576d2e02643b04950e487ec172b687180da65c731c03cf336784e6c07" "checksum pwasm-utils 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e9135bed7b452e20dbb395a2d519abaf0c46d60e7ecc02daeeab447d29bada1" "checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0" diff --git a/Cargo.toml b/Cargo.toml index ae5ae8c952..ed34b6862e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ description = "Parity Ethereum client" name = "parity-ethereum" # NOTE Make sure to update util/version/Cargo.toml as well -version = "2.5.1" +version = "2.5.2" license = "GPL-3.0" authors = ["Parity Technologies "] @@ -118,10 +118,13 @@ path = "parity/lib.rs" path = "parity/main.rs" name = "parity" -[profile.dev] +[profile.test] +lto = false +opt-level = 3 # makes tests slower to compile, but faster to run [profile.release] debug = false +lto = true [workspace] # This should only list projects that are not diff --git a/ethcore/blockchain/src/blockchain.rs b/ethcore/blockchain/src/blockchain.rs index de6e8c134a..7ee735f789 100644 --- a/ethcore/blockchain/src/blockchain.rs +++ b/ethcore/blockchain/src/blockchain.rs @@ -668,21 +668,6 @@ impl BlockChain { self.db.key_value().read_with_cache(db::COL_EXTRA, &self.block_details, parent).map_or(false, |d| d.children.contains(hash)) } - /// fetches the list of blocks from best block to n, and n's parent hash - /// where n > 0 - pub fn block_headers_from_best_block(&self, n: u32) -> Option<(Vec, H256)> { - let mut blocks = Vec::with_capacity(n as usize); - let mut hash = self.best_block_hash(); - - for _ in 0..n { - let current_hash = self.block_header_data(&hash)?; - hash = current_hash.parent_hash(); - blocks.push(current_hash); - } - - Some((blocks, hash)) - } - /// Returns a tree route between `from` and `to`, which is a tuple of: /// /// - a vector of hashes of all blocks, ordered from `from` to `to`. @@ -869,6 +854,14 @@ impl BlockChain { } } + /// clears all caches for testing purposes + pub fn clear_cache(&self) { + self.block_bodies.write().clear(); + self.block_details.write().clear(); + self.block_hashes.write().clear(); + self.block_headers.write().clear(); + } + /// Update the best ancient block to the given hash, after checking that /// it's directly linked to the currently known best ancient block pub fn update_best_ancient_block(&self, hash: &H256) { diff --git a/ethcore/res/ethereum/classic.json b/ethcore/res/ethereum/classic.json index 393129c12f..682b752991 100644 --- a/ethcore/res/ethereum/classic.json +++ b/ethcore/res/ethereum/classic.json @@ -8,11 +8,12 @@ "difficultyBoundDivisor": "0x0800", "durationLimit": "0x0d", "blockReward": "0x4563918244F40000", - "homesteadTransition": 1150000, - "ecip1010PauseTransition": 3000000, - "ecip1010ContinueTransition": 5000000, - "ecip1017EraRounds": 5000000, - "bombDefuseTransition": 5900000 + "homesteadTransition": "0x118c30", + "ecip1010PauseTransition": "0x2dc6c0", + "ecip1010ContinueTransition": "0x4c4b40", + "ecip1017EraRounds": "0x4c4b40", + "eip100bTransition": "0x7fffffffffffffff", + "bombDefuseTransition": "0x5a06e0" } } }, @@ -26,11 +27,17 @@ "chainID": "0x3d", "forkBlock": "0x1d4c00", "forkCanonHash": "0x94365e3a8c0b35089c1d1195081fe7489b528a84b22199c916180db8b28ade7f", - "eip150Transition": 2500000, - "eip160Transition": 3000000, + "eip150Transition": "0x2625a0", + "eip160Transition": "0x2dc6c0", "eip161abcTransition": "0x7fffffffffffffff", "eip161dTransition": "0x7fffffffffffffff", - "eip155Transition": 3000000 + "eip155Transition": "0x2dc6c0", + "maxCodeSize": "0x6000", + "maxCodeSizeTransition": "0x7fffffffffffffff", + "eip140Transition": "0x7fffffffffffffff", + "eip211Transition": "0x7fffffffffffffff", + "eip214Transition": "0x7fffffffffffffff", + "eip658Transition": "0x7fffffffffffffff" }, "genesis": { "seal": { @@ -3835,7 +3842,7 @@ "0xc32fd5318214071a41cd8e98499b2b65942c5837c686a06b536146fd0bf294bf", "0xac390c012eecd83fa8f4cc77a59992914b5c95af36b28747e07adea13228acbc" ] - }, + }, "nodes": [ "enode://efd48ad0879eeb7f9cb5e50f33f7bc21e805a72e90361f145baaa22dd75d111e7cd9c93f1b7060dcb30aa1b3e620269336dbf32339fea4c18925a4c15fe642df@18.205.66.229:30303", "enode://5fbfb426fbb46f8b8c1bd3dd140f5b511da558cd37d60844b525909ab82e13a25ee722293c829e52cb65c2305b1637fa9a2ea4d6634a224d5f400bfe244ac0de@162.243.55.45:30303", @@ -3851,10 +3858,97 @@ "enode://5cd218959f8263bc3721d7789070806b0adff1a0ed3f95ec886fb469f9362c7507e3b32b256550b9a7964a23a938e8d42d45a0c34b332bfebc54b29081e83b93@35.187.57.94: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 } } } }, + "0x0000000000000000000000000000000000000001": { + "builtin": { + "name": "ecrecover", + "pricing": { + "linear": { + "base": 3000, + "word": 0 + } + } + } + }, + "0x0000000000000000000000000000000000000002": { + "builtin": { + "name": "sha256", + "pricing": { + "linear": { + "base": 60, + "word": 12 + } + } + } + }, + "0x0000000000000000000000000000000000000003": { + "builtin": { + "name": "ripemd160", + "pricing": { + "linear": { + "base": 600, + "word": 120 + } + } + } + }, + "0x0000000000000000000000000000000000000004": { + "builtin": { + "name": "identity", + "pricing": { + "linear": { + "base": 15, + "word": 3 + } + } + } + }, + "0x0000000000000000000000000000000000000005": { + "builtin": { + "name": "modexp", + "activate_at": "0x7fffffffffffffff", + "pricing": { + "modexp": { + "divisor": 20 + } + } + } + }, + "0x0000000000000000000000000000000000000006": { + "builtin": { + "name": "alt_bn128_add", + "activate_at": "0x7fffffffffffffff", + "pricing": { + "linear": { + "base": 500, + "word": 0 + } + } + } + }, + "0x0000000000000000000000000000000000000007": { + "builtin": { + "name": "alt_bn128_mul", + "activate_at": "0x7fffffffffffffff", + "pricing": { + "linear": { + "base": 40000, + "word": 0 + } + } + } + }, + "0x0000000000000000000000000000000000000008": { + "builtin": { + "name": "alt_bn128_pairing", + "activate_at": "0x7fffffffffffffff", + "pricing": { + "alt_bn128_pairing": { + "base": 100000, + "pair": 80000 + } + } + } + }, "3282791d6fd713f1e94f4bfd565eaa78b3a0599d": { "balance": "1337000000000000000000" }, diff --git a/ethcore/res/ethereum/kotti.json b/ethcore/res/ethereum/kotti.json index cf531f6a5d..690269625b 100644 --- a/ethcore/res/ethereum/kotti.json +++ b/ethcore/res/ethereum/kotti.json @@ -12,12 +12,18 @@ "params": { "accountStartNonce": "0x0", "chainID": "0x6", + "eip140Transition": "0xaef49", "eip150Transition": "0x0", "eip155Transition": "0x0", "eip160Transition": "0x0", - "eip161abcTransition": "0x7fffffffffffffff", - "eip161dTransition": "0x7fffffffffffffff", + "eip161abcTransition": "0xaef49", + "eip161dTransition": "0xaef49", + "eip211Transition": "0xaef49", + "eip214Transition": "0xaef49", + "eip658Transition": "0xaef49", "gasLimitBoundDivisor": "0x400", + "maxCodeSize": "0x6000", + "maxCodeSizeTransition": "0xaef49", "maximumExtraDataSize": "0xffff", "minGasLimit": "0x1388", "networkID": "0x6" @@ -95,16 +101,55 @@ } }, "0x0000000000000000000000000000000000000005": { - "balance": "0x1" + "balance": "0x1", + "builtin": { + "name": "modexp", + "activate_at": "0xaef49", + "pricing": { + "modexp": { + "divisor": 20 + } + } + } }, "0x0000000000000000000000000000000000000006": { - "balance": "0x1" + "balance": "0x1", + "builtin": { + "name": "alt_bn128_add", + "activate_at": "0xaef49", + "pricing": { + "linear": { + "base": 500, + "word": 0 + } + } + } }, "0x0000000000000000000000000000000000000007": { - "balance": "0x1" + "balance": "0x1", + "builtin": { + "name": "alt_bn128_mul", + "activate_at": "0xaef49", + "pricing": { + "linear": { + "base": 40000, + "word": 0 + } + } + } }, "0x0000000000000000000000000000000000000008": { - "balance": "0x1" + "balance": "0x1", + "builtin": { + "name": "alt_bn128_pairing", + "activate_at": "0xaef49", + "pricing": { + "alt_bn128_pairing": { + "base": 100000, + "pair": 80000 + } + } + } }, "0x0000000000000000000000000000000000000009": { "balance": "0x1" diff --git a/ethcore/res/ethereum/morden.json b/ethcore/res/ethereum/morden.json index e626152adc..5ea0f21143 100644 --- a/ethcore/res/ethereum/morden.json +++ b/ethcore/res/ethereum/morden.json @@ -8,11 +8,12 @@ "difficultyBoundDivisor": "0x0800", "durationLimit": "0x0d", "blockReward": "0x4563918244F40000", - "homesteadTransition": 494000, - "ecip1010PauseTransition": 1915000, - "ecip1010ContinueTransition": 3415000, - "ecip1017EraRounds": 2000000, - "bombDefuseTransition": 2300000 + "homesteadTransition": "0x789b0", + "ecip1010PauseTransition": "0x1d3878", + "ecip1010ContinueTransition": "0x341bd8", + "ecip1017EraRounds": "0x1e8480", + "eip100bTransition": "0x4829ba", + "bombDefuseTransition": "0x231860" } } }, @@ -26,11 +27,17 @@ "chainID": "0x3e", "forkBlock": "0x1b34d8", "forkCanonHash": "0xf376243aeff1f256d970714c3de9fd78fa4e63cf63e32a51fe1169e375d98145", - "eip150Transition": 1783000, - "eip160Transition": 1915000, - "eip161abcTransition": "0x7fffffffffffffff", - "eip161dTransition": "0x7fffffffffffffff", - "eip155Transition": 1915000 + "eip150Transition": "0x1b34d8", + "eip160Transition": "0x1d3878", + "eip161abcTransition": "0x4829ba", + "eip161dTransition": "0x4829ba", + "eip155Transition": "0x1d3878", + "maxCodeSize": "0x6000", + "maxCodeSizeTransition": "0x4829ba", + "eip140Transition": "0x4829ba", + "eip211Transition": "0x4829ba", + "eip214Transition": "0x4829ba", + "eip658Transition": "0x4829ba" }, "genesis": { "seal": { @@ -68,6 +75,53 @@ "0000000000000000000000000000000000000002": { "balance": "1", "nonce": "1048576", "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } }, "0000000000000000000000000000000000000003": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } }, "0000000000000000000000000000000000000004": { "balance": "1", "nonce": "1048576", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } }, + "0x0000000000000000000000000000000000000005": { + "builtin": { + "name": "modexp", + "activate_at": "0x4829ba", + "pricing": { + "modexp": { + "divisor": 20 + } + } + } + }, + "0x0000000000000000000000000000000000000006": { + "builtin": { + "name": "alt_bn128_add", + "activate_at": "0x4829ba", + "pricing": { + "linear": { + "base": 500, + "word": 0 + } + } + } + }, + "0x0000000000000000000000000000000000000007": { + "builtin": { + "name": "alt_bn128_mul", + "activate_at": "0x4829ba", + "pricing": { + "linear": { + "base": 40000, + "word": 0 + } + } + } + }, + "0x0000000000000000000000000000000000000008": { + "builtin": { + "name": "alt_bn128_pairing", + "activate_at": "0x4829ba", + "pricing": { + "alt_bn128_pairing": { + "base": 100000, + "pair": 80000 + } + } + } + }, "102e61f5d8f9bc71d0ad4a084df4e65e05ce0e1c": { "balance": "1606938044258990275541962092341162602522202993782792835301376", "nonce": "1048576" } }, "hardcodedSync": { diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index 0b07d71030..4ec65b85e5 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -25,7 +25,7 @@ use blockchain::{BlockReceipts, BlockChain, BlockChainDB, BlockProvider, TreeRou use bytes::Bytes; use call_contract::{CallContract, RegistryInfo}; use ethcore_miner::pool::VerifiedTransaction; -use ethereum_types::{H256, Address, U256}; +use ethereum_types::{H256, H264, Address, U256}; use evm::Schedule; use hash::keccak; use io::IoChannel; @@ -86,7 +86,7 @@ pub use types::blockchain_info::BlockChainInfo; pub use types::block_status::BlockStatus; pub use blockchain::CacheSize as BlockChainCacheSize; pub use verification::QueueInfo as BlockQueueInfo; -use db::Writable; +use db::{Writable, Readable, keys::BlockDetails}; use_contract!(registry, "res/contracts/registrar.json"); @@ -1327,37 +1327,60 @@ impl BlockChainReset for Client { fn reset(&self, num: u32) -> Result<(), String> { if num as u64 > self.pruning_history() { return Err("Attempting to reset to block with pruned state".into()) + } else if num == 0 { + return Err("invalid number of blocks to reset".into()) } - let (blocks_to_delete, best_block_hash) = self.chain.read() - .block_headers_from_best_block(num) - .ok_or("Attempted to reset past genesis block")?; + let mut blocks_to_delete = Vec::with_capacity(num as usize); + let mut best_block_hash = self.chain.read().best_block_hash(); + let mut batch = DBTransaction::with_capacity(blocks_to_delete.len()); - let mut db_transaction = DBTransaction::with_capacity((num + 1) as usize); + for _ in 0..num { + let current_header = self.chain.read().block_header_data(&best_block_hash) + .expect("best_block_hash was fetched from db; block_header_data should exist in db; qed"); + best_block_hash = current_header.parent_hash(); - for hash in &blocks_to_delete { - db_transaction.delete(::db::COL_HEADERS, &hash.hash()); - db_transaction.delete(::db::COL_BODIES, &hash.hash()); - db_transaction.delete(::db::COL_EXTRA, &hash.hash()); + let (number, hash) = (current_header.number(), current_header.hash()); + batch.delete(::db::COL_HEADERS, &hash); + batch.delete(::db::COL_BODIES, &hash); + Writable::delete:: + (&mut batch, ::db::COL_EXTRA, &hash); Writable::delete:: - (&mut db_transaction, ::db::COL_EXTRA, &hash.number()); + (&mut batch, ::db::COL_EXTRA, &number); + + blocks_to_delete.push((number, hash)); } + let hashes = blocks_to_delete.iter().map(|(_, hash)| hash).collect::>(); + info!("Deleting block hashes {}", + Colour::Red + .bold() + .paint(format!("{:#?}", hashes)) + ); + + let mut best_block_details = Readable::read::( + &**self.db.read().key_value(), + ::db::COL_EXTRA, + &best_block_hash + ).expect("block was previously imported; best_block_details should exist; qed"); + + let (_, last_hash) = blocks_to_delete.last() + .expect("num is > 0; blocks_to_delete can't be empty; qed"); + // remove the last block as a child so that it can be re-imported + // ethcore/blockchain/src/blockchain.rs/Blockchain::is_known_child() + best_block_details.children.retain(|h| *h != *last_hash); + batch.write( + ::db::COL_EXTRA, + &best_block_hash, + &best_block_details + ); // update the new best block hash - db_transaction.put(::db::COL_EXTRA, b"best", &*best_block_hash); + batch.put(::db::COL_EXTRA, b"best", &best_block_hash); self.db.read() .key_value() - .write(db_transaction) - .map_err(|err| format!("could not complete reset operation; io error occured: {}", err))?; - - let hashes = blocks_to_delete.iter().map(|b| b.hash()).collect::>(); - - info!("Deleting block hashes {}", - Colour::Red - .bold() - .paint(format!("{:#?}", hashes)) - ); + .write(batch) + .map_err(|err| format!("could not delete blocks; io error occurred: {}", err))?; info!("New best block hash {}", Colour::Green.bold().paint(format!("{:?}", best_block_hash))); diff --git a/ethcore/src/tests/client.rs b/ethcore/src/tests/client.rs index 4d12bb1385..9086d07e08 100644 --- a/ethcore/src/tests/client.rs +++ b/ethcore/src/tests/client.rs @@ -27,7 +27,7 @@ use types::filter::Filter; use types::view; use types::views::BlockView; -use client::{BlockChainClient, Client, ClientConfig, BlockId, ChainInfo, BlockInfo, PrepareOpenBlock, ImportSealedBlock, ImportBlock}; +use client::{BlockChainClient, BlockChainReset, Client, ClientConfig, BlockId, ChainInfo, BlockInfo, PrepareOpenBlock, ImportSealedBlock, ImportBlock}; use ethereum; use executive::{Executive, TransactOptions}; use miner::{Miner, PendingOrdering, MinerService}; @@ -366,3 +366,23 @@ fn transaction_proof() { assert_eq!(state.balance(&Address::default()).unwrap(), 5.into()); assert_eq!(state.balance(&address).unwrap(), 95.into()); } + +#[test] +fn reset_blockchain() { + let client = get_test_client_with_blocks(get_good_dummy_block_seq(19)); + // 19 + genesis block + assert!(client.block_header(BlockId::Number(20)).is_some()); + assert_eq!(client.block_header(BlockId::Number(20)).unwrap().hash(), client.best_block_header().hash()); + + assert!(client.reset(5).is_ok()); + + client.chain().clear_cache(); + + assert!(client.block_header(BlockId::Number(20)).is_none()); + assert!(client.block_header(BlockId::Number(19)).is_none()); + assert!(client.block_header(BlockId::Number(18)).is_none()); + assert!(client.block_header(BlockId::Number(17)).is_none()); + assert!(client.block_header(BlockId::Number(16)).is_none()); + + assert!(client.block_header(BlockId::Number(15)).is_some()); +} diff --git a/scripts/docker/hub/Dockerfile b/scripts/docker/hub/Dockerfile index a18cacf9cc..ac1dd32ee1 100644 --- a/scripts/docker/hub/Dockerfile +++ b/scripts/docker/hub/Dockerfile @@ -1,30 +1,48 @@ FROM ubuntu:xenial -LABEL MAINTAINER="Parity Technologies " -# install tools and dependencies -RUN apt update && apt install -y --no-install-recommends openssl libudev-dev file curl jq +# metadata +ARG VCS_REF +ARG BUILD_DATE + +LABEL io.parity.image.authors="devops-team@parity.io" \ + io.parity.image.vendor="Parity Technologies" \ + io.parity.image.title="parity/parity" \ + io.parity.image.description="Parity Ethereum. The Fastest and most Advanced Ethereum Client." \ + io.parity.image.source="https://github.com/paritytech/parity-ethereum/blob/${VCS_REF}/\ +scripts/docker/hub/Dockerfile" \ + io.parity.image.documentation="https://wiki.parity.io/Parity-Ethereum" \ + io.parity.image.revision="${VCS_REF}" \ + io.parity.image.created="${BUILD_DATE}" # show backtraces ENV RUST_BACKTRACE 1 -# cleanup Docker image -RUN apt autoremove -y \ - && apt clean -y \ - && rm -rf /tmp/* /var/tmp/* /var/lib/apt/lists/* - -RUN groupadd -g 1000 parity \ - && useradd -m -u 1000 -g parity -s /bin/sh parity +# install tools and dependencies +RUN set -eux; \ + apt-get update; \ + apt-get install -y --no-install-recommends \ + file curl jq; \ +# apt cleanup + apt-get autoremove -y; \ + apt-get clean; \ + rm -rf /tmp/* /var/tmp/* /var/lib/apt/lists/*; \ +# add user + groupadd -g 1000 parity; \ + useradd -m -u 1000 -g parity -s /bin/sh parity WORKDIR /home/parity -# add parity-ethereum to docker image +# add parity-ethereum binary to docker image COPY artifacts/x86_64-unknown-linux-gnu/parity /bin/parity - -COPY scripts/docker/hub/check_sync.sh /check_sync.sh +COPY tools/check_sync.sh /check_sync.sh # switch to user parity here USER parity +# check if executable works in this container +RUN parity --version + EXPOSE 5001 8080 8082 8083 8545 8546 8180 30303/tcp 30303/udp ENTRYPOINT ["/bin/parity"] + diff --git a/scripts/docker/hub/publish-docker.sh b/scripts/docker/hub/publish-docker.sh new file mode 100755 index 0000000000..6602d55c23 --- /dev/null +++ b/scripts/docker/hub/publish-docker.sh @@ -0,0 +1,57 @@ +#!/bin/sh + +set -e # fail on any error + +VERSION=$(cat ./tools/VERSION) +echo "Parity Ethereum version = ${VERSION}" + +test "$Docker_Hub_User_Parity" -a "$Docker_Hub_Pass_Parity" \ + || ( echo "no docker credentials provided"; exit 1 ) +docker login -u "$Docker_Hub_User_Parity" -p "$Docker_Hub_Pass_Parity" +echo "__________Docker info__________" +docker info + +# we stopped pushing nightlies to dockerhub, will push to own registry prb. +case "${SCHEDULE_TAG:-${CI_COMMIT_REF_NAME}}" in + "$SCHEDULE_TAG") + echo "Docker TAG - 'parity/parity:${SCHEDULE_TAG}'"; + docker build --no-cache \ + --build-arg VCS_REF="${CI_COMMIT_SHA}" \ + --build-arg BUILD_DATE="$(date -u '+%Y-%m-%dT%H:%M:%SZ')" \ + --tag "parity/parity:${SCHEDULE_TAG}" \ + --file tools/Dockerfile .; + docker push "parity/parity:${SCHEDULE_TAG}";; + "beta") + echo "Docker TAGs - 'parity/parity:beta', 'parity/parity:latest', \ + 'parity/parity:${VERSION}-${CI_COMMIT_REF_NAME}'"; + docker build --no-cache \ + --build-arg VCS_REF="${CI_COMMIT_SHA}" \ + --build-arg BUILD_DATE="$(date -u '+%Y-%m-%dT%H:%M:%SZ')" \ + --tag "parity/parity:beta" \ + --tag "parity/parity:latest" \ + --tag "parity/parity:${VERSION}-${CI_COMMIT_REF_NAME}" \ + --file tools/Dockerfile .; + docker push "parity/parity:beta"; + docker push "parity/parity:latest"; + docker push "parity/parity:${VERSION}-${CI_COMMIT_REF_NAME}";; + "stable") + echo "Docker TAGs - 'parity/parity:${VERSION}-${CI_COMMIT_REF_NAME}', 'parity/parity:stable'"; + docker build --no-cache \ + --build-arg VCS_REF="${CI_COMMIT_SHA}" \ + --build-arg BUILD_DATE="$(date -u '+%Y-%m-%dT%H:%M:%SZ')" \ + --tag "parity/parity:${VERSION}-${CI_COMMIT_REF_NAME}" \ + --tag "parity/parity:stable" \ + --file tools/Dockerfile .; + docker push "parity/parity:${VERSION}-${CI_COMMIT_REF_NAME}"; + docker push "parity/parity:stable";; + *) + echo "Docker TAG - 'parity/parity:${VERSION}-${CI_COMMIT_REF_NAME}'" + docker build --no-cache \ + --build-arg VCS_REF="${CI_COMMIT_SHA}" \ + --build-arg BUILD_DATE="$(date -u '+%Y-%m-%dT%H:%M:%SZ')" \ + --tag "parity/parity:${VERSION}-${CI_COMMIT_REF_NAME}" \ + --file tools/Dockerfile .; + docker push "parity/parity:${VERSION}-${CI_COMMIT_REF_NAME}";; +esac + +docker logout diff --git a/scripts/gitlab/publish-docker.sh b/scripts/gitlab/publish-docker.sh deleted file mode 100755 index e8697fac2e..0000000000 --- a/scripts/gitlab/publish-docker.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/bash -##ARGUMENTS: 1. Docker target -set -e # fail on any error -set -u # treat unset variables as error - -if [ "$CI_COMMIT_REF_NAME" == "master" ]; - then export DOCKER_BUILD_TAG="${SCHEDULE_TAG:-latest}"; - else export DOCKER_BUILD_TAG=$CI_COMMIT_REF_NAME; -fi -docker login -u $Docker_Hub_User_Parity -p $Docker_Hub_Pass_Parity - -echo "__________Docker TAG__________" -echo $DOCKER_BUILD_TAG - -echo "__________Docker target__________" -export DOCKER_TARGET=$1 -echo $DOCKER_TARGET - -echo "__________Docker build and push__________" -docker build --build-arg TARGET=$DOCKER_TARGET --no-cache=true --tag parity/$DOCKER_TARGET:$DOCKER_BUILD_TAG -f scripts/docker/hub/Dockerfile . -docker push parity/$DOCKER_TARGET:$DOCKER_BUILD_TAG -docker logout diff --git a/scripts/gitlab/publish-docs.sh b/scripts/gitlab/publish-docs.sh index 2508c82555..16a781eeb9 100755 --- a/scripts/gitlab/publish-docs.sh +++ b/scripts/gitlab/publish-docs.sh @@ -33,8 +33,8 @@ update_wiki_docs() { setup_git() { echo "__________Set github__________" - git config --global user.email "devops@parity.com" - git config --global user.name "Devops Parity" + git config --global user.email "devops-team@parity.io" + git config --global user.name "Devops Team Parity" } set_remote_wiki() { diff --git a/scripts/gitlab/publish-onchain.sh b/scripts/gitlab/publish-onchain.sh index 588cbdfb57..9c7b866fb4 100755 --- a/scripts/gitlab/publish-onchain.sh +++ b/scripts/gitlab/publish-onchain.sh @@ -7,10 +7,7 @@ echo "__________Register Release__________" DATA="secret=$RELEASES_SECRET" echo "Pushing release to Mainnet" -./scripts/gitlab/safe-curl.sh $DATA "http://update.parity.io:1337/push-release/${SCHEDULE_TAG:-${CI_COMMIT_REF_NAME}}/$CI_COMMIT_SHA" - -echo "Pushing release to Kovan" -./scripts/gitlab/safe-curl.sh $DATA "http://update.parity.io:1338/push-release/${SCHEDULE_TAG:-${CI_COMMIT_REF_NAME}}/$CI_COMMIT_SHA" +./tools/safe-curl.sh $DATA "http://update.parity.io:1337/push-release/${SCHEDULE_TAG:-${CI_COMMIT_REF_NAME}}/$CI_COMMIT_SHA" cd artifacts ls -l | sort -k9 @@ -29,9 +26,7 @@ do case $DIR in x86_64* ) DATA="commit=$CI_COMMIT_SHA&sha3=$sha3&filename=parity$WIN&secret=$RELEASES_SECRET" - ../../scripts/gitlab/safe-curl.sh $DATA "http://update.parity.io:1337/push-build/${SCHEDULE_TAG:-${CI_COMMIT_REF_NAME}}/$DIR" - # Kovan - ../../scripts/gitlab/safe-curl.sh $DATA "http://update.parity.io:1338/push-build/${SCHEDULE_TAG:-${CI_COMMIT_REF_NAME}}/$DIR" + ../../tools/safe-curl.sh $DATA "http://update.parity.io:1337/push-build/${SCHEDULE_TAG:-${CI_COMMIT_REF_NAME}}/$DIR" ;; esac cd .. diff --git a/scripts/gitlab/publish-snap.sh b/scripts/gitlab/publish-snap.sh index 5e0231af00..d9f10ce3ee 100755 --- a/scripts/gitlab/publish-snap.sh +++ b/scripts/gitlab/publish-snap.sh @@ -3,15 +3,11 @@ set -e # fail on any error set -u # treat unset variables as error -# some necromancy: -# gsub(/"/, "", $2) deletes "qoutes" -# gsub(/ /, "", $2) deletes whitespaces -TRACK=`awk -F '=' '/^track/ {gsub(/"/, "", $2); gsub(/ /, "", $2); print $2}' ./util/version/Cargo.toml` -echo Track is: $TRACK # prepare variables -VERSION=v"$(sed -r -n '1,/^version/s/^version = "([^"]+)".*$/\1/p' Cargo.toml)" +TRACK=$(cat ./tools/TRACK) +echo "Track is: ${TRACK}" +VERSION=$(cat ./tools/VERSION) SNAP_PACKAGE="parity_"$VERSION"_"$BUILD_ARCH".snap" -CARGO_TARGET="$(ls artifacts)" # Choose snap release channel based on parity ethereum version track case ${TRACK} in nightly) export GRADE="devel" CHANNEL="edge";; @@ -20,12 +16,8 @@ case ${TRACK} in *) echo "No release" && exit 0;; esac -# Release untagged versions from branches to the candidate snap channel -case ${CI_COMMIT_REF_NAME} in - beta|stable) export GRADE="stable" CHANNEL="candidate";; -esac echo "__________Create snap package__________" -echo "Release channel :" $GRADE " Branch/tag: " $CI_COMMIT_REF_NAME +echo "Release channel :" $GRADE " Branch/tag: " $CI_COMMIT_REF_NAME "Track: " ${TRACK} echo $VERSION:$GRADE:$BUILD_ARCH:$CARGO_TARGET sed -e 's/$VERSION/'"$VERSION"'/g' \ diff --git a/scripts/gitlab/test-linux.sh b/scripts/gitlab/test-linux.sh index 2854508bb5..d7e6da0bb6 100755 --- a/scripts/gitlab/test-linux.sh +++ b/scripts/gitlab/test-linux.sh @@ -6,7 +6,7 @@ set -e # fail on any error set -u # treat unset variables as error FEATURES="json-tests,ci-skip-tests" -OPTIONS="--release" +OPTIONS="" #use nproc `linux only THREADS=$(nproc) @@ -14,4 +14,5 @@ rustup default $1 rustup show echo "________Running Parity Full Test Suite________" -time cargo test $OPTIONS --features "$FEATURES" --locked --all --target $CARGO_TARGET --verbose --color=always -- --test-threads $THREADS +# Why are we using RUSTFLAGS? See https://github.com/paritytech/parity-ethereum/pull/10719 +CARGO_INCREMENTAL=0 RUSTFLAGS="-C opt-level=3 -C overflow-checks=on -C debuginfo=2" time cargo test $OPTIONS --features "$FEATURES" --locked --all --target $CARGO_TARGET --verbose --color=never -- --test-threads $THREADS diff --git a/util/version/Cargo.toml b/util/version/Cargo.toml index 2c4fdebde5..978c604900 100644 --- a/util/version/Cargo.toml +++ b/util/version/Cargo.toml @@ -3,7 +3,7 @@ [package] name = "parity-version" # NOTE: this value is used for Parity Ethereum version string (via env CARGO_PKG_VERSION) -version = "2.5.1" +version = "2.5.2" authors = ["Parity Technologies "] build = "build.rs" From 3fd58bdcbd1bcecfcb513d3206dcbf8e14900531 Mon Sep 17 00:00:00 2001 From: s3krit Date: Tue, 25 Jun 2019 13:38:29 +0000 Subject: [PATCH 158/168] Beta 2.5.3 (#10776) * ethcore/res: activate atlantis classic hf on block 8772000 (#10766) * fix docker tags for publishing (#10741) * fix: aura don't add `SystemTime::now()` (#10720) This commit does the following: - Prevent overflow in `verify_timestamp()` by not adding `now` to found faulty timestamp - Use explicit `CheckedSystemTime::checked_add` to prevent potential consensus issues because SystemTime is platform depedent - remove `#[cfg(not(time_checked_add))]` conditional compilation * Update version * Treat empty account the same as non-exist accounts in EIP-1052 (#10775) * DevP2p: Get node IP address and udp port from Socket, if not included in PING packet (#10705) * get node IP address and udp port from Socket, if not included in PING packet * prevent bootnodes from being added to host nodes * code corrections * code corrections * code corrections * code corrections * docs * code corrections * code corrections * Apply suggestions from code review Co-Authored-By: David * Add a way to signal shutdown to snapshotting threads (#10744) * Add a way to signal shutdown to snapshotting threads * Pass Progress to fat_rlps() so we can abort from there too. * Checking for abort in a single spot * Remove nightly-only weak/strong counts * fix warning * Fix tests * Add dummy impl to abort snapshots * Add another dummy impl for TestSnapshotService * Remove debugging code * Return error instead of the odd Ok(()) Switch to AtomicU64 * revert .as_bytes() change * fix build * fix build maybe --- Cargo.lock | 12 +-- Cargo.toml | 2 +- ethcore/res/ethereum/classic.json | 24 +++--- ethcore/service/src/service.rs | 11 ++- ethcore/src/client/client.rs | 27 ++++-- ethcore/src/engines/authority_round/mod.rs | 14 ++- ethcore/src/engines/clique/block_state.rs | 6 +- ethcore/src/engines/clique/mod.rs | 12 ++- ethcore/src/externalities.rs | 6 +- ethcore/src/lib.rs | 5 +- ethcore/src/snapshot/account.rs | 44 +++++++--- ethcore/src/snapshot/error.rs | 3 + ethcore/src/snapshot/io.rs | 5 +- ethcore/src/snapshot/mod.rs | 90 ++++++++++++-------- ethcore/src/snapshot/service.rs | 27 ++++-- ethcore/src/snapshot/tests/service.rs | 9 +- ethcore/src/snapshot/tests/state.rs | 12 +-- ethcore/src/snapshot/traits.rs | 3 + ethcore/src/verification/verification.rs | 7 +- ethcore/sync/src/tests/snapshot.rs | 2 + parity/configuration.rs | 2 +- parity/lib.rs | 1 - parity/run.rs | 30 +++++-- parity/snapshot.rs | 2 +- rpc/src/v1/tests/helpers/snapshot_service.rs | 1 + scripts/docker/hub/publish-docker.sh | 10 +++ util/network-devp2p/src/discovery.rs | 29 +++++-- util/network-devp2p/src/node_table.rs | 14 ++- util/version/Cargo.toml | 2 +- 29 files changed, 263 insertions(+), 149 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c0f79d9da0..d36117e7cc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2457,7 +2457,7 @@ dependencies = [ "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", "jni 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "panic_hook 0.1.0", - "parity-ethereum 2.5.2", + "parity-ethereum 2.5.3", "tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-current-thread 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2487,7 +2487,7 @@ dependencies = [ [[package]] name = "parity-ethereum" -version = "2.5.2" +version = "2.5.3" dependencies = [ "ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2540,7 +2540,7 @@ dependencies = [ "parity-rpc 1.12.0", "parity-runtime 0.1.0", "parity-updater 1.12.0", - "parity-version 2.5.2", + "parity-version 2.5.3", "parity-whisper 0.1.0", "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2683,7 +2683,7 @@ dependencies = [ "parity-crypto 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-runtime 0.1.0", "parity-updater 1.12.0", - "parity-version 2.5.2", + "parity-version 2.5.3", "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2781,7 +2781,7 @@ dependencies = [ "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-hash-fetch 1.12.0", "parity-path 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-version 2.5.2", + "parity-version 2.5.3", "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2791,7 +2791,7 @@ dependencies = [ [[package]] name = "parity-version" -version = "2.5.2" +version = "2.5.3" dependencies = [ "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "rlp 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index ed34b6862e..162dc27a29 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ description = "Parity Ethereum client" name = "parity-ethereum" # NOTE Make sure to update util/version/Cargo.toml as well -version = "2.5.2" +version = "2.5.3" license = "GPL-3.0" authors = ["Parity Technologies "] diff --git a/ethcore/res/ethereum/classic.json b/ethcore/res/ethereum/classic.json index 682b752991..2750f6f639 100644 --- a/ethcore/res/ethereum/classic.json +++ b/ethcore/res/ethereum/classic.json @@ -12,7 +12,7 @@ "ecip1010PauseTransition": "0x2dc6c0", "ecip1010ContinueTransition": "0x4c4b40", "ecip1017EraRounds": "0x4c4b40", - "eip100bTransition": "0x7fffffffffffffff", + "eip100bTransition": "0x85d9a0", "bombDefuseTransition": "0x5a06e0" } } @@ -29,15 +29,15 @@ "forkCanonHash": "0x94365e3a8c0b35089c1d1195081fe7489b528a84b22199c916180db8b28ade7f", "eip150Transition": "0x2625a0", "eip160Transition": "0x2dc6c0", - "eip161abcTransition": "0x7fffffffffffffff", - "eip161dTransition": "0x7fffffffffffffff", + "eip161abcTransition": "0x85d9a0", + "eip161dTransition": "0x85d9a0", "eip155Transition": "0x2dc6c0", "maxCodeSize": "0x6000", - "maxCodeSizeTransition": "0x7fffffffffffffff", - "eip140Transition": "0x7fffffffffffffff", - "eip211Transition": "0x7fffffffffffffff", - "eip214Transition": "0x7fffffffffffffff", - "eip658Transition": "0x7fffffffffffffff" + "maxCodeSizeTransition": "0x85d9a0", + "eip140Transition": "0x85d9a0", + "eip211Transition": "0x85d9a0", + "eip214Transition": "0x85d9a0", + "eip658Transition": "0x85d9a0" }, "genesis": { "seal": { @@ -3905,7 +3905,7 @@ "0x0000000000000000000000000000000000000005": { "builtin": { "name": "modexp", - "activate_at": "0x7fffffffffffffff", + "activate_at": "0x85d9a0", "pricing": { "modexp": { "divisor": 20 @@ -3916,7 +3916,7 @@ "0x0000000000000000000000000000000000000006": { "builtin": { "name": "alt_bn128_add", - "activate_at": "0x7fffffffffffffff", + "activate_at": "0x85d9a0", "pricing": { "linear": { "base": 500, @@ -3928,7 +3928,7 @@ "0x0000000000000000000000000000000000000007": { "builtin": { "name": "alt_bn128_mul", - "activate_at": "0x7fffffffffffffff", + "activate_at": "0x85d9a0", "pricing": { "linear": { "base": 40000, @@ -3940,7 +3940,7 @@ "0x0000000000000000000000000000000000000008": { "builtin": { "name": "alt_bn128_pairing", - "activate_at": "0x7fffffffffffffff", + "activate_at": "0x85d9a0", "pricing": { "alt_bn128_pairing": { "base": 100000, diff --git a/ethcore/service/src/service.rs b/ethcore/service/src/service.rs index c16a071892..0953970376 100644 --- a/ethcore/service/src/service.rs +++ b/ethcore/service/src/service.rs @@ -30,8 +30,10 @@ use blockchain::{BlockChainDB, BlockChainDBHandler}; use ethcore::client::{Client, ClientConfig, ChainNotify, ClientIoMessage}; use ethcore::miner::Miner; use ethcore::snapshot::service::{Service as SnapshotService, ServiceParams as SnapServiceParams}; -use ethcore::snapshot::{SnapshotService as _SnapshotService, RestorationStatus}; +use ethcore::snapshot::{SnapshotService as _SnapshotService, RestorationStatus, Error as SnapshotError}; use ethcore::spec::Spec; +use ethcore::error::{Error as EthcoreError, ErrorKind}; + use ethcore_private_tx::{self, Importer, Signer}; use Error; @@ -197,6 +199,7 @@ impl ClientService { /// Shutdown the Client Service pub fn shutdown(&self) { + trace!(target: "shutdown", "Shutting down Client Service"); self.snapshot.shutdown(); } } @@ -257,7 +260,11 @@ impl IoHandler for ClientIoHandler { let res = thread::Builder::new().name("Periodic Snapshot".into()).spawn(move || { if let Err(e) = snapshot.take_snapshot(&*client, num) { - warn!("Failed to take snapshot at block #{}: {}", num, e); + match e { + EthcoreError(ErrorKind::Snapshot(SnapshotError::SnapshotAborted), _) => info!("Snapshot aborted"), + _ => warn!("Failed to take snapshot at block #{}: {}", num, e), + } + } }); diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index 4ec65b85e5..047de5580f 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -764,8 +764,8 @@ impl Client { liveness: AtomicBool::new(awake), mode: Mutex::new(config.mode.clone()), chain: RwLock::new(chain), - tracedb: tracedb, - engine: engine, + tracedb, + engine, pruning: config.pruning.clone(), db: RwLock::new(db.clone()), state_db: RwLock::new(state_db), @@ -778,8 +778,8 @@ impl Client { ancient_blocks_import_lock: Default::default(), queue_consensus_message: IoChannelQueue::new(usize::max_value()), last_hashes: RwLock::new(VecDeque::new()), - factories: factories, - history: history, + factories, + history, on_user_defaults_change: Mutex::new(None), registrar_address, exit_handler: Mutex::new(None), @@ -1138,7 +1138,12 @@ impl Client { /// Take a snapshot at the given block. /// If the ID given is "latest", this will default to 1000 blocks behind. - pub fn take_snapshot(&self, writer: W, at: BlockId, p: &snapshot::Progress) -> Result<(), EthcoreError> { + pub fn take_snapshot( + &self, + writer: W, + at: BlockId, + p: &snapshot::Progress, + ) -> Result<(), EthcoreError> { let db = self.state_db.read().journal_db().boxed_clone(); let best_block_number = self.chain_info().best_block_number; let block_number = self.block_number(at).ok_or_else(|| snapshot::Error::InvalidStartingBlock(at))?; @@ -1168,8 +1173,16 @@ impl Client { }; let processing_threads = self.config.snapshot.processing_threads; - snapshot::take_snapshot(&*self.engine, &self.chain.read(), start_hash, db.as_hash_db(), writer, p, processing_threads)?; - + let chunker = self.engine.snapshot_components().ok_or(snapshot::Error::SnapshotsUnsupported)?; + snapshot::take_snapshot( + chunker, + &self.chain.read(), + start_hash, + db.as_hash_db(), + writer, + p, + processing_threads, + )?; Ok(()) } diff --git a/ethcore/src/engines/authority_round/mod.rs b/ethcore/src/engines/authority_round/mod.rs index 36f25144f7..312b58e61c 100644 --- a/ethcore/src/engines/authority_round/mod.rs +++ b/ethcore/src/engines/authority_round/mod.rs @@ -22,7 +22,7 @@ use std::iter::FromIterator; use std::ops::Deref; use std::sync::atomic::{AtomicUsize, AtomicBool, Ordering as AtomicOrdering}; use std::sync::{Weak, Arc}; -use std::time::{UNIX_EPOCH, SystemTime, Duration}; +use std::time::{UNIX_EPOCH, Duration}; use block::*; use client::EngineClient; @@ -42,14 +42,12 @@ use itertools::{self, Itertools}; use rlp::{encode, Decodable, DecoderError, Encodable, RlpStream, Rlp}; use ethereum_types::{H256, H520, Address, U128, U256}; use parking_lot::{Mutex, RwLock}; +use time_utils::CheckedSystemTime; use types::BlockNumber; use types::header::{Header, ExtendedHeader}; use types::ancestry_action::AncestryAction; use unexpected::{Mismatch, OutOfBounds}; -#[cfg(not(time_checked_add))] -use time_utils::CheckedSystemTime; - mod finality; /// `AuthorityRound` params. @@ -578,10 +576,10 @@ fn verify_timestamp(step: &Step, header_step: u64) -> Result<(), BlockError> { // Returning it further won't recover the sync process. trace!(target: "engine", "verify_timestamp: block too early"); - let now = SystemTime::now(); - let found = now.checked_add(Duration::from_secs(oob.found)).ok_or(BlockError::TimestampOverflow)?; - let max = oob.max.and_then(|m| now.checked_add(Duration::from_secs(m))); - let min = oob.min.and_then(|m| now.checked_add(Duration::from_secs(m))); + let found = CheckedSystemTime::checked_add(UNIX_EPOCH, Duration::from_secs(oob.found)) + .ok_or(BlockError::TimestampOverflow)?; + let max = oob.max.and_then(|m| CheckedSystemTime::checked_add(UNIX_EPOCH, Duration::from_secs(m))); + let min = oob.min.and_then(|m| CheckedSystemTime::checked_add(UNIX_EPOCH, Duration::from_secs(m))); let new_oob = OutOfBounds { min, max, found }; diff --git a/ethcore/src/engines/clique/block_state.rs b/ethcore/src/engines/clique/block_state.rs index 4257076c06..6518d8ac24 100644 --- a/ethcore/src/engines/clique/block_state.rs +++ b/ethcore/src/engines/clique/block_state.rs @@ -24,13 +24,11 @@ use engines::clique::{VoteType, DIFF_INTURN, DIFF_NOTURN, NULL_AUTHOR, SIGNING_D use error::{Error, BlockError}; use ethereum_types::{Address, H64}; use rand::Rng; +use time_utils::CheckedSystemTime; use types::BlockNumber; use types::header::Header; use unexpected::Mismatch; -#[cfg(not(feature = "time_checked_add"))] -use time_utils::CheckedSystemTime; - /// Type that keeps track of the state for a given vote // Votes that go against the proposal aren't counted since it's equivalent to not voting #[derive(Copy, Clone, Debug, PartialEq, PartialOrd)] @@ -268,7 +266,7 @@ impl CliqueBlockState { // This is a quite bad API because we must mutate both variables even when already `inturn` fails // That's why we can't return early and must have the `if-else` in the end pub fn calc_next_timestamp(&mut self, timestamp: u64, period: u64) -> Result<(), Error> { - let inturn = UNIX_EPOCH.checked_add(Duration::from_secs(timestamp.saturating_add(period))); + let inturn = CheckedSystemTime::checked_add(UNIX_EPOCH, Duration::from_secs(timestamp.saturating_add(period))); self.next_timestamp_inturn = inturn; diff --git a/ethcore/src/engines/clique/mod.rs b/ethcore/src/engines/clique/mod.rs index 742a7aec4d..8be54da266 100644 --- a/ethcore/src/engines/clique/mod.rs +++ b/ethcore/src/engines/clique/mod.rs @@ -82,12 +82,10 @@ use parking_lot::RwLock; use rand::Rng; use super::signer::EngineSigner; use unexpected::{Mismatch, OutOfBounds}; +use time_utils::CheckedSystemTime; use types::BlockNumber; use types::header::{ExtendedHeader, Header}; -#[cfg(not(feature = "time_checked_add"))] -use time_utils::CheckedSystemTime; - use self::block_state::CliqueBlockState; use self::params::CliqueParams; use self::step_service::StepService; @@ -536,7 +534,7 @@ impl Engine for Clique { // Don't waste time checking blocks from the future { - let limit = SystemTime::now().checked_add(Duration::from_secs(self.period)) + let limit = CheckedSystemTime::checked_add(SystemTime::now(), Duration::from_secs(self.period)) .ok_or(BlockError::TimestampOverflow)?; // This should succeed under the contraints that the system clock works @@ -546,7 +544,7 @@ impl Engine for Clique { let hdr = Duration::from_secs(header.timestamp()); if hdr > limit_as_dur { - let found = UNIX_EPOCH.checked_add(hdr).ok_or(BlockError::TimestampOverflow)?; + let found = CheckedSystemTime::checked_add(UNIX_EPOCH, hdr).ok_or(BlockError::TimestampOverflow)?; Err(BlockError::TemporarilyInvalid(OutOfBounds { min: None, @@ -657,8 +655,8 @@ impl Engine for Clique { // Ensure that the block's timestamp isn't too close to it's parent let limit = parent.timestamp().saturating_add(self.period); if limit > header.timestamp() { - let max = UNIX_EPOCH.checked_add(Duration::from_secs(header.timestamp())); - let found = UNIX_EPOCH.checked_add(Duration::from_secs(limit)) + let max = CheckedSystemTime::checked_add(UNIX_EPOCH, Duration::from_secs(header.timestamp())); + let found = CheckedSystemTime::checked_add(UNIX_EPOCH, Duration::from_secs(limit)) .ok_or(BlockError::TimestampOverflow)?; Err(BlockError::InvalidTimestamp(OutOfBounds { diff --git a/ethcore/src/externalities.rs b/ethcore/src/externalities.rs index 23a4a83c3d..41122afc1d 100644 --- a/ethcore/src/externalities.rs +++ b/ethcore/src/externalities.rs @@ -314,7 +314,11 @@ impl<'a, T: 'a, V: 'a, B: 'a> Ext for Externalities<'a, T, V, B> } fn extcodehash(&self, address: &Address) -> vm::Result> { - Ok(self.state.code_hash(address)?) + if self.state.exists_and_not_null(address)? { + Ok(self.state.code_hash(address)?) + } else { + Ok(None) + } } fn extcodesize(&self, address: &Address) -> vm::Result> { diff --git a/ethcore/src/lib.rs b/ethcore/src/lib.rs index eee076b32e..6578d36071 100644 --- a/ethcore/src/lib.rs +++ b/ethcore/src/lib.rs @@ -15,7 +15,6 @@ // along with Parity Ethereum. If not, see . #![warn(missing_docs, unused_extern_crates)] -#![cfg_attr(feature = "time_checked_add", feature(time_checked_add))] //! Ethcore library //! @@ -100,6 +99,7 @@ extern crate rlp; extern crate rustc_hex; extern crate serde; extern crate stats; +extern crate time_utils; extern crate triehash_ethereum as triehash; extern crate unexpected; extern crate using_queue; @@ -149,9 +149,6 @@ extern crate fetch; #[cfg(all(test, feature = "price-info"))] extern crate parity_runtime; -#[cfg(not(time_checked_add))] -extern crate time_utils; - pub mod block; pub mod builtin; pub mod client; diff --git a/ethcore/src/snapshot/account.rs b/ethcore/src/snapshot/account.rs index ed56e2435b..2a9ac911f1 100644 --- a/ethcore/src/snapshot/account.rs +++ b/ethcore/src/snapshot/account.rs @@ -24,9 +24,10 @@ use ethtrie::{TrieDB, TrieDBMut}; use hash::{KECCAK_EMPTY, KECCAK_NULL_RLP}; use hash_db::HashDB; use rlp::{RlpStream, Rlp}; -use snapshot::Error; +use snapshot::{Error, Progress}; use std::collections::HashSet; use trie::{Trie, TrieMut}; +use std::sync::atomic::Ordering; // An empty account -- these were replaced with RLP null data for a space optimization in v1. const ACC_EMPTY: BasicAccount = BasicAccount { @@ -65,8 +66,16 @@ impl CodeState { // walk the account's storage trie, returning a vector of RLP items containing the // account address hash, account properties and the storage. Each item contains at most `max_storage_items` // storage records split according to snapshot format definition. -pub fn to_fat_rlps(account_hash: &H256, acc: &BasicAccount, acct_db: &AccountDB, used_code: &mut HashSet, first_chunk_size: usize, max_chunk_size: usize) -> Result, Error> { - let db = &(acct_db as &HashDB<_,_>); +pub fn to_fat_rlps( + account_hash: &H256, + acc: &BasicAccount, + acct_db: &AccountDB, + used_code: &mut HashSet, + first_chunk_size: usize, + max_chunk_size: usize, + p: &Progress, +) -> Result, Error> { + let db = &(acct_db as &dyn HashDB<_,_>); let db = TrieDB::new(db, &acc.storage_root)?; let mut chunks = Vec::new(); let mut db_iter = db.iter()?; @@ -112,6 +121,10 @@ pub fn to_fat_rlps(account_hash: &H256, acc: &BasicAccount, acct_db: &AccountDB, } loop { + if p.abort.load(Ordering::SeqCst) { + trace!(target: "snapshot", "to_fat_rlps: aborting snapshot"); + return Err(Error::SnapshotAborted); + } match db_iter.next() { Some(Ok((k, v))) => { let pair = { @@ -211,6 +224,7 @@ mod tests { use types::basic_account::BasicAccount; use test_helpers::get_temp_state_db; use snapshot::tests::helpers::fill_storage; + use snapshot::Progress; use hash::{KECCAK_EMPTY, KECCAK_NULL_RLP, keccak}; use ethereum_types::{H256, Address}; @@ -236,8 +250,8 @@ mod tests { let thin_rlp = ::rlp::encode(&account); assert_eq!(::rlp::decode::(&thin_rlp).unwrap(), account); - - let fat_rlps = to_fat_rlps(&keccak(&addr), &account, &AccountDB::new(db.as_hash_db(), &addr), &mut Default::default(), usize::max_value(), usize::max_value()).unwrap(); + let p = Progress::default(); + let fat_rlps = to_fat_rlps(&keccak(&addr), &account, &AccountDB::new(db.as_hash_db(), &addr), &mut Default::default(), usize::max_value(), usize::max_value(), &p).unwrap(); let fat_rlp = Rlp::new(&fat_rlps[0]).at(1).unwrap(); assert_eq!(from_fat_rlp(&mut AccountDBMut::new(db.as_hash_db_mut(), &addr), fat_rlp, H256::zero()).unwrap().0, account); } @@ -262,7 +276,9 @@ mod tests { let thin_rlp = ::rlp::encode(&account); assert_eq!(::rlp::decode::(&thin_rlp).unwrap(), account); - let fat_rlp = to_fat_rlps(&keccak(&addr), &account, &AccountDB::new(db.as_hash_db(), &addr), &mut Default::default(), usize::max_value(), usize::max_value()).unwrap(); + let p = Progress::default(); + + let fat_rlp = to_fat_rlps(&keccak(&addr), &account, &AccountDB::new(db.as_hash_db(), &addr), &mut Default::default(), usize::max_value(), usize::max_value(), &p).unwrap(); let fat_rlp = Rlp::new(&fat_rlp[0]).at(1).unwrap(); assert_eq!(from_fat_rlp(&mut AccountDBMut::new(db.as_hash_db_mut(), &addr), fat_rlp, H256::zero()).unwrap().0, account); } @@ -287,7 +303,8 @@ mod tests { let thin_rlp = ::rlp::encode(&account); assert_eq!(::rlp::decode::(&thin_rlp).unwrap(), account); - let fat_rlps = to_fat_rlps(&keccak(addr), &account, &AccountDB::new(db.as_hash_db(), &addr), &mut Default::default(), 500, 1000).unwrap(); + let p = Progress::default(); + let fat_rlps = to_fat_rlps(&keccak(addr), &account, &AccountDB::new(db.as_hash_db(), &addr), &mut Default::default(), 500, 1000, &p).unwrap(); let mut root = KECCAK_NULL_RLP; let mut restored_account = None; for rlp in fat_rlps { @@ -319,20 +336,21 @@ mod tests { nonce: 50.into(), balance: 123456789.into(), storage_root: KECCAK_NULL_RLP, - code_hash: code_hash, + code_hash, }; let account2 = BasicAccount { nonce: 400.into(), balance: 98765432123456789usize.into(), storage_root: KECCAK_NULL_RLP, - code_hash: code_hash, + code_hash, }; let mut used_code = HashSet::new(); - - let fat_rlp1 = to_fat_rlps(&keccak(&addr1), &account1, &AccountDB::new(db.as_hash_db(), &addr1), &mut used_code, usize::max_value(), usize::max_value()).unwrap(); - let fat_rlp2 = to_fat_rlps(&keccak(&addr2), &account2, &AccountDB::new(db.as_hash_db(), &addr2), &mut used_code, usize::max_value(), usize::max_value()).unwrap(); + let p1 = Progress::default(); + let p2 = Progress::default(); + let fat_rlp1 = to_fat_rlps(&keccak(&addr1), &account1, &AccountDB::new(db.as_hash_db(), &addr1), &mut used_code, usize::max_value(), usize::max_value(), &p1).unwrap(); + let fat_rlp2 = to_fat_rlps(&keccak(&addr2), &account2, &AccountDB::new(db.as_hash_db(), &addr2), &mut used_code, usize::max_value(), usize::max_value(), &p2).unwrap(); assert_eq!(used_code.len(), 1); let fat_rlp1 = Rlp::new(&fat_rlp1[0]).at(1).unwrap(); @@ -350,6 +368,6 @@ mod tests { #[test] fn encoding_empty_acc() { let mut db = get_temp_state_db(); - assert_eq!(from_fat_rlp(&mut AccountDBMut::new(db.as_hash_db_mut(), &Address::default()), Rlp::new(&::rlp::NULL_RLP), H256::zero()).unwrap(), (ACC_EMPTY, None)); + assert_eq!(from_fat_rlp(&mut AccountDBMut::new(db.as_hash_db_mut(), &Address::zero()), Rlp::new(&::rlp::NULL_RLP), H256::zero()).unwrap(), (ACC_EMPTY, None)); } } diff --git a/ethcore/src/snapshot/error.rs b/ethcore/src/snapshot/error.rs index b71f79f805..6faa19da22 100644 --- a/ethcore/src/snapshot/error.rs +++ b/ethcore/src/snapshot/error.rs @@ -61,6 +61,8 @@ pub enum Error { ChunkTooLarge, /// Snapshots not supported by the consensus engine. SnapshotsUnsupported, + /// Aborted snapshot + SnapshotAborted, /// Bad epoch transition. BadEpochProof(u64), /// Wrong chunk format. @@ -91,6 +93,7 @@ impl fmt::Display for Error { Error::ChunkTooSmall => write!(f, "Chunk size is too small."), Error::ChunkTooLarge => write!(f, "Chunk size is too large."), Error::SnapshotsUnsupported => write!(f, "Snapshots unsupported by consensus engine."), + Error::SnapshotAborted => write!(f, "Snapshot was aborted."), Error::BadEpochProof(i) => write!(f, "Bad epoch proof for transition to epoch {}", i), Error::WrongChunkFormat(ref msg) => write!(f, "Wrong chunk format: {}", msg), Error::UnlinkedAncientBlockChain => write!(f, "Unlinked ancient blocks chain"), diff --git a/ethcore/src/snapshot/io.rs b/ethcore/src/snapshot/io.rs index c5f178cd32..536862e7be 100644 --- a/ethcore/src/snapshot/io.rs +++ b/ethcore/src/snapshot/io.rs @@ -310,10 +310,7 @@ impl LooseReader { dir.pop(); - Ok(LooseReader { - dir: dir, - manifest: manifest, - }) + Ok(LooseReader { dir, manifest }) } } diff --git a/ethcore/src/snapshot/mod.rs b/ethcore/src/snapshot/mod.rs index 19a5f8ce6e..ae7a217099 100644 --- a/ethcore/src/snapshot/mod.rs +++ b/ethcore/src/snapshot/mod.rs @@ -22,7 +22,7 @@ use std::collections::{HashMap, HashSet}; use std::cmp; use std::sync::Arc; -use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering}; +use std::sync::atomic::{AtomicBool, AtomicU64, AtomicUsize, Ordering}; use hash::{keccak, KECCAK_NULL_RLP, KECCAK_EMPTY}; use account_db::{AccountDB, AccountDBMut}; @@ -107,7 +107,7 @@ impl Default for SnapshotConfiguration { fn default() -> Self { SnapshotConfiguration { no_periodic: false, - processing_threads: ::std::cmp::max(1, num_cpus::get() / 2), + processing_threads: ::std::cmp::max(1, num_cpus::get_physical() / 2), } } } @@ -117,8 +117,9 @@ impl Default for SnapshotConfiguration { pub struct Progress { accounts: AtomicUsize, blocks: AtomicUsize, - size: AtomicUsize, // Todo [rob] use Atomicu64 when it stabilizes. + size: AtomicU64, done: AtomicBool, + abort: AtomicBool, } impl Progress { @@ -127,6 +128,7 @@ impl Progress { self.accounts.store(0, Ordering::Release); self.blocks.store(0, Ordering::Release); self.size.store(0, Ordering::Release); + self.abort.store(false, Ordering::Release); // atomic fence here to ensure the others are written first? // logs might very rarely get polluted if not. @@ -140,7 +142,7 @@ impl Progress { pub fn blocks(&self) -> usize { self.blocks.load(Ordering::Acquire) } /// Get the written size of the snapshot in bytes. - pub fn size(&self) -> usize { self.size.load(Ordering::Acquire) } + pub fn size(&self) -> u64 { self.size.load(Ordering::Acquire) } /// Whether the snapshot is complete. pub fn done(&self) -> bool { self.done.load(Ordering::Acquire) } @@ -148,27 +150,28 @@ impl Progress { } /// Take a snapshot using the given blockchain, starting block hash, and database, writing into the given writer. pub fn take_snapshot( - engine: &EthEngine, + chunker: Box, chain: &BlockChain, - block_at: H256, - state_db: &HashDB, + block_hash: H256, + state_db: &dyn HashDB, writer: W, p: &Progress, processing_threads: usize, ) -> Result<(), Error> { - let start_header = chain.block_header_data(&block_at) - .ok_or_else(|| Error::InvalidStartingBlock(BlockId::Hash(block_at)))?; + let start_header = chain.block_header_data(&block_hash) + .ok_or_else(|| Error::InvalidStartingBlock(BlockId::Hash(block_hash)))?; let state_root = start_header.state_root(); - let number = start_header.number(); + let block_number = start_header.number(); - info!("Taking snapshot starting at block {}", number); + info!("Taking snapshot starting at block {}", block_number); + let version = chunker.current_version(); let writer = Mutex::new(writer); - let chunker = engine.snapshot_components().ok_or(Error::SnapshotsUnsupported)?; - let snapshot_version = chunker.current_version(); let (state_hashes, block_hashes) = scope(|scope| -> Result<(Vec, Vec), Error> { let writer = &writer; - let block_guard = scope.spawn(move || chunk_secondary(chunker, chain, block_at, writer, p)); + let block_guard = scope.spawn(move || { + chunk_secondary(chunker, chain, block_hash, writer, p) + }); // The number of threads must be between 1 and SNAPSHOT_SUBPARTS assert!(processing_threads >= 1, "Cannot use less than 1 threads for creating snapshots"); @@ -183,7 +186,7 @@ pub fn take_snapshot( for part in (thread_idx..SNAPSHOT_SUBPARTS).step_by(num_threads) { debug!(target: "snapshot", "Chunking part {} in thread {}", part, thread_idx); - let mut hashes = chunk_state(state_db, &state_root, writer, p, Some(part))?; + let mut hashes = chunk_state(state_db, &state_root, writer, p, Some(part), thread_idx)?; chunk_hashes.append(&mut hashes); } @@ -207,12 +210,12 @@ pub fn take_snapshot( info!(target: "snapshot", "produced {} state chunks and {} block chunks.", state_hashes.len(), block_hashes.len()); let manifest_data = ManifestData { - version: snapshot_version, - state_hashes: state_hashes, - block_hashes: block_hashes, - state_root: state_root, - block_number: number, - block_hash: block_at, + version, + state_hashes, + block_hashes, + state_root, + block_number, + block_hash, }; writer.into_inner().finish(manifest_data)?; @@ -228,7 +231,13 @@ pub fn take_snapshot( /// Secondary chunks are engine-specific, but they intend to corroborate the state data /// in the state chunks. /// Returns a list of chunk hashes, with the first having the blocks furthest from the genesis. -pub fn chunk_secondary<'a>(mut chunker: Box, chain: &'a BlockChain, start_hash: H256, writer: &Mutex, progress: &'a Progress) -> Result, Error> { +pub fn chunk_secondary<'a>( + mut chunker: Box, + chain: &'a BlockChain, + start_hash: H256, + writer: &Mutex, + progress: &'a Progress +) -> Result, Error> { let mut chunk_hashes = Vec::new(); let mut snappy_buffer = vec![0; snappy::max_compressed_len(PREFERRED_CHUNK_SIZE)]; @@ -243,7 +252,7 @@ pub fn chunk_secondary<'a>(mut chunker: Box, chain: &'a Bloc trace!(target: "snapshot", "wrote secondary chunk. hash: {:x}, size: {}, uncompressed size: {}", hash, size, raw_data.len()); - progress.size.fetch_add(size, Ordering::SeqCst); + progress.size.fetch_add(size as u64, Ordering::SeqCst); chunk_hashes.push(hash); Ok(()) }; @@ -266,8 +275,9 @@ struct StateChunker<'a> { rlps: Vec, cur_size: usize, snappy_buffer: Vec, - writer: &'a Mutex, + writer: &'a Mutex, progress: &'a Progress, + thread_idx: usize, } impl<'a> StateChunker<'a> { @@ -297,10 +307,10 @@ impl<'a> StateChunker<'a> { let hash = keccak(&compressed); self.writer.lock().write_state_chunk(hash, compressed)?; - trace!(target: "snapshot", "wrote state chunk. size: {}, uncompressed size: {}", compressed_size, raw_data.len()); + trace!(target: "snapshot", "Thread {} wrote state chunk. size: {}, uncompressed size: {}", self.thread_idx, compressed_size, raw_data.len()); self.progress.accounts.fetch_add(num_entries, Ordering::SeqCst); - self.progress.size.fetch_add(compressed_size, Ordering::SeqCst); + self.progress.size.fetch_add(compressed_size as u64, Ordering::SeqCst); self.hashes.push(hash); self.cur_size = 0; @@ -321,7 +331,14 @@ impl<'a> StateChunker<'a> { /// /// Returns a list of hashes of chunks created, or any error it may /// have encountered. -pub fn chunk_state<'a>(db: &HashDB, root: &H256, writer: &Mutex, progress: &'a Progress, part: Option) -> Result, Error> { +pub fn chunk_state<'a>( + db: &dyn HashDB, + root: &H256, + writer: &Mutex, + progress: &'a Progress, + part: Option, + thread_idx: usize, +) -> Result, Error> { let account_trie = TrieDB::new(&db, &root)?; let mut chunker = StateChunker { @@ -329,8 +346,9 @@ pub fn chunk_state<'a>(db: &HashDB, root: &H256, writer: rlps: Vec::new(), cur_size: 0, snappy_buffer: vec![0; snappy::max_compressed_len(PREFERRED_CHUNK_SIZE)], - writer: writer, - progress: progress, + writer, + progress, + thread_idx, }; let mut used_code = HashSet::new(); @@ -365,7 +383,7 @@ pub fn chunk_state<'a>(db: &HashDB, root: &H256, writer: let account = ::rlp::decode(&*account_data)?; let account_db = AccountDB::from_hash(db, account_key_hash); - let fat_rlps = account::to_fat_rlps(&account_key_hash, &account, &account_db, &mut used_code, PREFERRED_CHUNK_SIZE - chunker.chunk_size(), PREFERRED_CHUNK_SIZE)?; + let fat_rlps = account::to_fat_rlps(&account_key_hash, &account, &account_db, &mut used_code, PREFERRED_CHUNK_SIZE - chunker.chunk_size(), PREFERRED_CHUNK_SIZE, progress)?; for (i, fat_rlp) in fat_rlps.into_iter().enumerate() { if i > 0 { chunker.write_chunk()?; @@ -383,7 +401,7 @@ pub fn chunk_state<'a>(db: &HashDB, root: &H256, writer: /// Used to rebuild the state trie piece by piece. pub struct StateRebuilder { - db: Box, + db: Box, state_root: H256, known_code: HashMap, // code hashes mapped to first account with this code. missing_code: HashMap>, // maps code hashes to lists of accounts missing that code. @@ -393,7 +411,7 @@ pub struct StateRebuilder { impl StateRebuilder { /// Create a new state rebuilder to write into the given backing DB. - pub fn new(db: Arc, pruning: Algorithm) -> Self { + pub fn new(db: Arc, pruning: Algorithm) -> Self { StateRebuilder { db: journaldb::new(db.clone(), pruning, ::db::COL_STATE), state_root: KECCAK_NULL_RLP, @@ -411,7 +429,7 @@ impl StateRebuilder { let mut pairs = Vec::with_capacity(rlp.item_count()?); // initialize the pairs vector with empty values so we have slots to write into. - pairs.resize(rlp.item_count()?, (H256::new(), Vec::new())); + pairs.resize(rlp.item_count()?, (H256::zero(), Vec::new())); let status = rebuild_accounts( self.db.as_hash_db_mut(), @@ -468,7 +486,7 @@ impl StateRebuilder { /// Finalize the restoration. Check for accounts missing code and make a dummy /// journal entry. /// Once all chunks have been fed, there should be nothing missing. - pub fn finalize(mut self, era: u64, id: H256) -> Result, ::error::Error> { + pub fn finalize(mut self, era: u64, id: H256) -> Result, ::error::Error> { let missing = self.missing_code.keys().cloned().collect::>(); if !missing.is_empty() { return Err(Error::MissingCode(missing).into()) } @@ -493,7 +511,7 @@ struct RebuiltStatus { // rebuild a set of accounts and their storage. // returns a status detailing newly-loaded code and accounts missing code. fn rebuild_accounts( - db: &mut HashDB, + db: &mut dyn HashDB, account_fat_rlps: Rlp, out_chunk: &mut [(H256, Bytes)], known_code: &HashMap, @@ -560,7 +578,7 @@ const POW_VERIFY_RATE: f32 = 0.02; /// Verify an old block with the given header, engine, blockchain, body. If `always` is set, it will perform /// the fullest verification possible. If not, it will take a random sample to determine whether it will /// do heavy or light verification. -pub fn verify_old_block(rng: &mut OsRng, header: &Header, engine: &EthEngine, chain: &BlockChain, always: bool) -> Result<(), ::error::Error> { +pub fn verify_old_block(rng: &mut OsRng, header: &Header, engine: &dyn EthEngine, chain: &BlockChain, always: bool) -> Result<(), ::error::Error> { engine.verify_block_basic(header)?; if always || rng.gen::() <= POW_VERIFY_RATE { diff --git a/ethcore/src/snapshot/service.rs b/ethcore/src/snapshot/service.rs index 4b3f196cb1..ddae76a00a 100644 --- a/ethcore/src/snapshot/service.rs +++ b/ethcore/src/snapshot/service.rs @@ -415,7 +415,7 @@ impl Service { _ => break, } - // Writting changes to DB and logging every now and then + // Writing changes to DB and logging every now and then if block_number % 1_000 == 0 { next_db.key_value().write_buffered(batch); next_chain.commit(); @@ -479,16 +479,12 @@ impl Service { let guard = Guard::new(temp_dir.clone()); let res = client.take_snapshot(writer, BlockId::Number(num), &self.progress); - self.taking_snapshot.store(false, Ordering::SeqCst); if let Err(e) = res { if client.chain_info().best_block_number >= num + client.pruning_history() { - // "Cancelled" is mincing words a bit -- what really happened - // is that the state we were snapshotting got pruned out - // before we could finish. - info!("Periodic snapshot failed: block state pruned.\ - Run with a longer `--pruning-history` or with `--no-periodic-snapshot`"); - return Ok(()) + // The state we were snapshotting was pruned before we could finish. + info!("Periodic snapshot failed: block state pruned. Run with a longer `--pruning-history` or with `--no-periodic-snapshot`"); + return Err(e); } else { return Err(e); } @@ -846,14 +842,29 @@ impl SnapshotService for Service { } } + fn abort_snapshot(&self) { + if self.taking_snapshot.load(Ordering::SeqCst) { + trace!(target: "snapshot", "Aborting snapshot – Snapshot under way"); + self.progress.abort.store(true, Ordering::SeqCst); + } + } + fn shutdown(&self) { + trace!(target: "snapshot", "Shut down SnapshotService"); self.abort_restore(); + trace!(target: "snapshot", "Shut down SnapshotService - restore aborted"); + self.abort_snapshot(); + trace!(target: "snapshot", "Shut down SnapshotService - snapshot aborted"); } } impl Drop for Service { fn drop(&mut self) { + trace!(target: "shutdown", "Dropping Service"); self.abort_restore(); + trace!(target: "shutdown", "Dropping Service - restore aborted"); + self.abort_snapshot(); + trace!(target: "shutdown", "Dropping Service - snapshot aborted"); } } diff --git a/ethcore/src/snapshot/tests/service.rs b/ethcore/src/snapshot/tests/service.rs index 37a10048ab..515e5992ff 100644 --- a/ethcore/src/snapshot/tests/service.rs +++ b/ethcore/src/snapshot/tests/service.rs @@ -188,14 +188,15 @@ fn keep_ancient_blocks() { &state_root, &writer, &Progress::default(), - None + None, + 0 ).unwrap(); let manifest = ::snapshot::ManifestData { version: 2, - state_hashes: state_hashes, - state_root: state_root, - block_hashes: block_hashes, + state_hashes, + state_root, + block_hashes, block_number: NUM_BLOCKS, block_hash: best_hash, }; diff --git a/ethcore/src/snapshot/tests/state.rs b/ethcore/src/snapshot/tests/state.rs index fa7df6b619..0d97603324 100644 --- a/ethcore/src/snapshot/tests/state.rs +++ b/ethcore/src/snapshot/tests/state.rs @@ -55,7 +55,7 @@ fn snap_and_restore() { let mut state_hashes = Vec::new(); for part in 0..SNAPSHOT_SUBPARTS { - let mut hashes = chunk_state(&old_db, &state_root, &writer, &Progress::default(), Some(part)).unwrap(); + let mut hashes = chunk_state(&old_db, &state_root, &writer, &Progress::default(), Some(part), 0).unwrap(); state_hashes.append(&mut hashes); } @@ -126,8 +126,8 @@ fn get_code_from_prev_chunk() { let mut make_chunk = |acc, hash| { let mut db = journaldb::new_memory_db(); AccountDBMut::from_hash(&mut db, hash).insert(&code[..]); - - let fat_rlp = account::to_fat_rlps(&hash, &acc, &AccountDB::from_hash(&db, hash), &mut used_code, usize::max_value(), usize::max_value()).unwrap(); + let p = Progress::default(); + let fat_rlp = account::to_fat_rlps(&hash, &acc, &AccountDB::from_hash(&db, hash), &mut used_code, usize::max_value(), usize::max_value(), &p).unwrap(); let mut stream = RlpStream::new_list(1); stream.append_raw(&fat_rlp[0], 1); stream.out() @@ -171,13 +171,13 @@ fn checks_flag() { let state_root = producer.state_root(); let writer = Mutex::new(PackedWriter::new(&snap_file).unwrap()); - let state_hashes = chunk_state(&old_db, &state_root, &writer, &Progress::default(), None).unwrap(); + let state_hashes = chunk_state(&old_db, &state_root, &writer, &Progress::default(), None, 0).unwrap(); writer.into_inner().finish(::snapshot::ManifestData { version: 2, - state_hashes: state_hashes, + state_hashes, block_hashes: Vec::new(), - state_root: state_root, + state_root, block_number: 0, block_hash: H256::default(), }).unwrap(); diff --git a/ethcore/src/snapshot/traits.rs b/ethcore/src/snapshot/traits.rs index bb4ab3b396..aa61b595bf 100644 --- a/ethcore/src/snapshot/traits.rs +++ b/ethcore/src/snapshot/traits.rs @@ -55,6 +55,9 @@ pub trait SnapshotService : Sync + Send { /// no-op if currently restoring. fn restore_block_chunk(&self, hash: H256, chunk: Bytes); + /// Abort in-progress snapshotting if there is one. + fn abort_snapshot(&self); + /// Shutdown the Snapshot Service by aborting any ongoing restore fn shutdown(&self); } diff --git a/ethcore/src/verification/verification.rs b/ethcore/src/verification/verification.rs index 36a847f64a..61d7119249 100644 --- a/ethcore/src/verification/verification.rs +++ b/ethcore/src/verification/verification.rs @@ -40,7 +40,6 @@ use types::{BlockNumber, header::Header}; use types::transaction::SignedTransaction; use verification::queue::kind::blocks::Unverified; -#[cfg(not(time_checked_add))] use time_utils::CheckedSystemTime; /// Preprocessed block data gathered in `verify_block_unordered` call @@ -310,7 +309,7 @@ pub fn verify_header_params(header: &Header, engine: &EthEngine, is_full: bool, // this will resist overflow until `year 2037` let max_time = SystemTime::now() + ACCEPTABLE_DRIFT; let invalid_threshold = max_time + ACCEPTABLE_DRIFT * 9; - let timestamp = UNIX_EPOCH.checked_add(Duration::from_secs(header.timestamp())) + let timestamp = CheckedSystemTime::checked_add(UNIX_EPOCH, Duration::from_secs(header.timestamp())) .ok_or(BlockError::TimestampOverflow)?; if timestamp > invalid_threshold { @@ -334,9 +333,9 @@ fn verify_parent(header: &Header, parent: &Header, engine: &EthEngine) -> Result if !engine.is_timestamp_valid(header.timestamp(), parent.timestamp()) { let now = SystemTime::now(); - let min = now.checked_add(Duration::from_secs(parent.timestamp().saturating_add(1))) + let min = CheckedSystemTime::checked_add(now, Duration::from_secs(parent.timestamp().saturating_add(1))) .ok_or(BlockError::TimestampOverflow)?; - let found = now.checked_add(Duration::from_secs(header.timestamp())) + let found = CheckedSystemTime::checked_add(now, Duration::from_secs(header.timestamp())) .ok_or(BlockError::TimestampOverflow)?; return Err(From::from(BlockError::InvalidTimestamp(OutOfBounds { max: None, min: Some(min), found }))) } diff --git a/ethcore/sync/src/tests/snapshot.rs b/ethcore/sync/src/tests/snapshot.rs index a3aa77d36d..d865adc2ad 100644 --- a/ethcore/sync/src/tests/snapshot.rs +++ b/ethcore/sync/src/tests/snapshot.rs @@ -122,6 +122,8 @@ impl SnapshotService for TestSnapshotService { self.block_restoration_chunks.lock().clear(); } + fn abort_snapshot(&self) {} + fn restore_state_chunk(&self, hash: H256, chunk: Bytes) { if self.restoration_manifest.lock().as_ref().map_or(false, |m| m.state_hashes.iter().any(|h| h == &hash)) { self.state_restoration_chunks.lock().insert(hash, chunk); diff --git a/parity/configuration.rs b/parity/configuration.rs index 198a58c3f9..1a8338637a 100644 --- a/parity/configuration.rs +++ b/parity/configuration.rs @@ -932,7 +932,7 @@ impl Configuration { no_periodic: self.args.flag_no_periodic_snapshot, processing_threads: match self.args.arg_snapshot_threads { Some(threads) if threads > 0 => threads, - _ => ::std::cmp::max(1, num_cpus::get() / 2), + _ => ::std::cmp::max(1, num_cpus::get_physical() / 2), }, }; diff --git a/parity/lib.rs b/parity/lib.rs index 9141bdcade..a88a689470 100644 --- a/parity/lib.rs +++ b/parity/lib.rs @@ -15,7 +15,6 @@ // along with Parity Ethereum. If not, see . //! Ethcore client application. - #![warn(missing_docs)] extern crate ansi_term; diff --git a/parity/run.rs b/parity/run.rs index a23f3d032d..6ddeadbe02 100644 --- a/parity/run.rs +++ b/parity/run.rs @@ -893,17 +893,27 @@ impl RunningClient { // Create a weak reference to the client so that we can wait on shutdown // until it is dropped let weak_client = Arc::downgrade(&client); - // Shutdown and drop the ServiceClient + // Shutdown and drop the ClientService client_service.shutdown(); + trace!(target: "shutdown", "ClientService shut down"); drop(client_service); + trace!(target: "shutdown", "ClientService dropped"); // drop this stuff as soon as exit detected. drop(rpc); + trace!(target: "shutdown", "RPC dropped"); drop(keep_alive); + trace!(target: "shutdown", "KeepAlive dropped"); // to make sure timer does not spawn requests while shutdown is in progress informant.shutdown(); + trace!(target: "shutdown", "Informant shut down"); // just Arc is dropping here, to allow other reference release in its default time drop(informant); + trace!(target: "shutdown", "Informant dropped"); drop(client); + trace!(target: "shutdown", "Client dropped"); + // This may help when debugging ref cycles. Requires nightly-only `#![feature(weak_counts)]` + // trace!(target: "shutdown", "Waiting for refs to Client to shutdown, strong_count={:?}, weak_count={:?}", weak_client.strong_count(), weak_client.weak_count()); + trace!(target: "shutdown", "Waiting for refs to Client to shutdown"); wait_for_drop(weak_client); } } @@ -937,24 +947,30 @@ fn print_running_environment(data_dir: &str, dirs: &Directories, db_dirs: &Datab } fn wait_for_drop(w: Weak) { - let sleep_duration = Duration::from_secs(1); - let warn_timeout = Duration::from_secs(60); - let max_timeout = Duration::from_secs(300); + const SLEEP_DURATION: Duration = Duration::from_secs(1); + const WARN_TIMEOUT: Duration = Duration::from_secs(60); + const MAX_TIMEOUT: Duration = Duration::from_secs(300); let instant = Instant::now(); let mut warned = false; - while instant.elapsed() < max_timeout { + while instant.elapsed() < MAX_TIMEOUT { if w.upgrade().is_none() { return; } - if !warned && instant.elapsed() > warn_timeout { + if !warned && instant.elapsed() > WARN_TIMEOUT { warned = true; warn!("Shutdown is taking longer than expected."); } - thread::sleep(sleep_duration); + thread::sleep(SLEEP_DURATION); + + // When debugging shutdown issues on a nightly build it can help to enable this with the + // `#![feature(weak_counts)]` added to lib.rs (TODO: enable when + // https://github.com/rust-lang/rust/issues/57977 is stable) + // trace!(target: "shutdown", "Waiting for client to drop, strong_count={:?}, weak_count={:?}", w.strong_count(), w.weak_count()); + trace!(target: "shutdown", "Waiting for client to drop"); } warn!("Shutdown timeout reached, exiting uncleanly."); diff --git a/parity/snapshot.rs b/parity/snapshot.rs index 70957762f5..269965c335 100644 --- a/parity/snapshot.rs +++ b/parity/snapshot.rs @@ -261,7 +261,7 @@ impl SnapshotCommand { let cur_size = p.size(); if cur_size != last_size { last_size = cur_size; - let bytes = ::informant::format_bytes(p.size()); + let bytes = ::informant::format_bytes(cur_size as usize); info!("Snapshot: {} accounts {} blocks {}", p.accounts(), p.blocks(), bytes); } diff --git a/rpc/src/v1/tests/helpers/snapshot_service.rs b/rpc/src/v1/tests/helpers/snapshot_service.rs index 5450886bb4..881c434e17 100644 --- a/rpc/src/v1/tests/helpers/snapshot_service.rs +++ b/rpc/src/v1/tests/helpers/snapshot_service.rs @@ -48,6 +48,7 @@ impl SnapshotService for TestSnapshotService { fn status(&self) -> RestorationStatus { self.status.lock().clone() } fn begin_restore(&self, _manifest: ManifestData) { } fn abort_restore(&self) { } + fn abort_snapshot(&self) {} fn restore_state_chunk(&self, _hash: H256, _chunk: Bytes) { } fn restore_block_chunk(&self, _hash: H256, _chunk: Bytes) { } fn shutdown(&self) { } diff --git a/scripts/docker/hub/publish-docker.sh b/scripts/docker/hub/publish-docker.sh index 6602d55c23..84feedb281 100755 --- a/scripts/docker/hub/publish-docker.sh +++ b/scripts/docker/hub/publish-docker.sh @@ -3,7 +3,9 @@ set -e # fail on any error VERSION=$(cat ./tools/VERSION) +TRACK=$(cat ./tools/TRACK) echo "Parity Ethereum version = ${VERSION}" +echo "Parity Ethereum track = ${TRACK}" test "$Docker_Hub_User_Parity" -a "$Docker_Hub_Pass_Parity" \ || ( echo "no docker credentials provided"; exit 1 ) @@ -44,6 +46,14 @@ case "${SCHEDULE_TAG:-${CI_COMMIT_REF_NAME}}" in --file tools/Dockerfile .; docker push "parity/parity:${VERSION}-${CI_COMMIT_REF_NAME}"; docker push "parity/parity:stable";; + v[0-9]*.[0-9]*) + echo "Docker TAG - 'parity/parity:${VERSION}-${TRACK}'" + docker build --no-cache \ + --build-arg VCS_REF="${CI_COMMIT_SHA}" \ + --build-arg BUILD_DATE="$(date -u '+%Y-%m-%dT%H:%M:%SZ')" \ + --tag "parity/parity:${VERSION}-${TRACK}" \ + --file tools/Dockerfile .; + docker push "parity/parity:${VERSION}-${TRACK}";; *) echo "Docker TAG - 'parity/parity:${VERSION}-${CI_COMMIT_REF_NAME}'" docker build --no-cache \ diff --git a/util/network-devp2p/src/discovery.rs b/util/network-devp2p/src/discovery.rs index 7bf8dc62e5..f18469e164 100644 --- a/util/network-devp2p/src/discovery.rs +++ b/util/network-devp2p/src/discovery.rs @@ -168,7 +168,6 @@ pub struct Discovery<'a> { discovery_id: NodeId, discovery_nodes: HashSet, node_buckets: Vec, - // Sometimes we don't want to add nodes to the NodeTable, but still want to // keep track of them to avoid excessive pinging (happens when an unknown node sends // a discovery request to us -- the node might be on a different net). @@ -257,7 +256,7 @@ impl<'a> Discovery<'a> { Ok(()) => None, Err(BucketError::Ourselves) => None, Err(BucketError::NotInTheBucket{node_entry, bucket_distance}) => Some((node_entry, bucket_distance)) - }.map(|(node_entry, bucket_distance)| { + }.and_then(|(node_entry, bucket_distance)| { trace!(target: "discovery", "Adding a new node {:?} into our bucket {}", &node_entry, bucket_distance); let mut added = HashMap::with_capacity(1); @@ -265,7 +264,7 @@ impl<'a> Discovery<'a> { let node_to_ping = { let bucket = &mut self.node_buckets[bucket_distance]; - bucket.nodes.push_front(BucketEntry::new(node_entry)); + bucket.nodes.push_front(BucketEntry::new(node_entry.clone())); if bucket.nodes.len() > BUCKET_SIZE { select_bucket_ping(bucket.nodes.iter()) } else { @@ -275,7 +274,12 @@ impl<'a> Discovery<'a> { if let Some(node) = node_to_ping { self.try_ping(node, PingReason::Default); }; - TableUpdates{added, removed: HashSet::new()} + + if node_entry.endpoint.is_valid_sync_node() { + Some(TableUpdates { added, removed: HashSet::new() }) + } else { + None + } }) } @@ -518,7 +522,18 @@ impl<'a> Discovery<'a> { fn on_ping(&mut self, rlp: &Rlp, node_id: &NodeId, from: &SocketAddr, echo_hash: &[u8]) -> Result, Error> { trace!(target: "discovery", "Got Ping from {:?}", &from); - let ping_from = NodeEndpoint::from_rlp(&rlp.at(1)?)?; + let ping_from = if let Ok(node_endpoint) = NodeEndpoint::from_rlp(&rlp.at(1)?) { + node_endpoint + } else { + let mut address = from.clone(); + // address here is the node's tcp port. If we are unable to get the `NodeEndpoint` from the `ping_from` + // rlp field then this is most likely a BootNode, set the tcp port to 0 because it can not be used for syncing. + address.set_port(0); + NodeEndpoint { + address, + udp_port: from.port() + } + }; let ping_to = NodeEndpoint::from_rlp(&rlp.at(2)?)?; let timestamp: u64 = rlp.val_at(3)?; self.check_timestamp(timestamp)?; @@ -540,7 +555,7 @@ impl<'a> Discovery<'a> { self.send_packet(PACKET_PONG, from, &response.drain())?; let entry = NodeEntry { id: *node_id, endpoint: pong_to.clone() }; - if !entry.endpoint.is_valid() { + if !entry.endpoint.is_valid_discovery_node() { debug!(target: "discovery", "Got bad address: {:?}", entry); } else if !self.is_allowed(&entry) { debug!(target: "discovery", "Address not allowed: {:?}", entry); @@ -728,7 +743,7 @@ impl<'a> Discovery<'a> { trace!(target: "discovery", "Got {} Neighbours from {:?}", results_count, &from); for r in rlp.at(0)?.iter() { let endpoint = NodeEndpoint::from_rlp(&r)?; - if !endpoint.is_valid() { + if !endpoint.is_valid_discovery_node() { debug!(target: "discovery", "Bad address: {:?}", endpoint); continue; } diff --git a/util/network-devp2p/src/node_table.rs b/util/network-devp2p/src/node_table.rs index 3cee93fd9a..db001bfe76 100644 --- a/util/network-devp2p/src/node_table.rs +++ b/util/network-devp2p/src/node_table.rs @@ -103,10 +103,16 @@ impl NodeEndpoint { self.to_rlp(rlp); } - /// Validates that the port is not 0 and address IP is specified - pub fn is_valid(&self) -> bool { - self.udp_port != 0 && self.address.port() != 0 && - match self.address { + /// Validates that the tcp port is not 0 and that the node is a valid discovery node (i.e. `is_valid_discovery_node()` is true). + /// Sync happens over tcp. + pub fn is_valid_sync_node(&self) -> bool { + self.is_valid_discovery_node() && self.address.port() != 0 + } + + /// Validates that the udp port is not 0 and address IP is specified. + /// Peer discovery happens over udp. + pub fn is_valid_discovery_node(&self) -> bool { + self.udp_port != 0 && match self.address { SocketAddr::V4(a) => !a.ip().is_unspecified(), SocketAddr::V6(a) => !a.ip().is_unspecified() } diff --git a/util/version/Cargo.toml b/util/version/Cargo.toml index 978c604900..64239cb466 100644 --- a/util/version/Cargo.toml +++ b/util/version/Cargo.toml @@ -3,7 +3,7 @@ [package] name = "parity-version" # NOTE: this value is used for Parity Ethereum version string (via env CARGO_PKG_VERSION) -version = "2.5.2" +version = "2.5.3" authors = ["Parity Technologies "] build = "build.rs" From d60e6384d7a51531f36c6c97438070d60d4f4f6e Mon Sep 17 00:00:00 2001 From: s3krit Date: Mon, 1 Jul 2019 12:33:35 +0200 Subject: [PATCH 159/168] Beta 2.5.4 (#10827) * cargo update -p smallvec (#10822) Fixes https://github.com/servo/rust-smallvec/issues/148 * Update version to v2.5.3 Signed-off-by: Martin Pugh --- Cargo.lock | 35 ++++++++++++++++------------------- Cargo.toml | 2 +- util/version/Cargo.toml | 2 +- 3 files changed, 18 insertions(+), 21 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d36117e7cc..cf3791840e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -377,7 +377,7 @@ dependencies = [ "crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -900,7 +900,7 @@ dependencies = [ "rlp_derive 0.1.0", "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", "stats 0.1.0", "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "trie-db 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1247,7 +1247,7 @@ dependencies = [ "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", "tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2457,7 +2457,7 @@ dependencies = [ "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", "jni 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "panic_hook 0.1.0", - "parity-ethereum 2.5.3", + "parity-ethereum 2.5.4", "tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-current-thread 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2487,7 +2487,7 @@ dependencies = [ [[package]] name = "parity-ethereum" -version = "2.5.3" +version = "2.5.4" dependencies = [ "ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2540,7 +2540,7 @@ dependencies = [ "parity-rpc 1.12.0", "parity-runtime 0.1.0", "parity-updater 1.12.0", - "parity-version 2.5.3", + "parity-version 2.5.4", "parity-whisper 0.1.0", "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2683,7 +2683,7 @@ dependencies = [ "parity-crypto 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-runtime 0.1.0", "parity-updater 1.12.0", - "parity-version 2.5.3", + "parity-version 2.5.4", "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2781,7 +2781,7 @@ dependencies = [ "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-hash-fetch 1.12.0", "parity-path 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-version 2.5.3", + "parity-version 2.5.4", "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2791,7 +2791,7 @@ dependencies = [ [[package]] name = "parity-version" -version = "2.5.3" +version = "2.5.4" dependencies = [ "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "rlp 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2833,7 +2833,7 @@ dependencies = [ "serde_derive 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", "time-utils 0.1.0", "tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2891,7 +2891,7 @@ dependencies = [ "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2905,7 +2905,7 @@ dependencies = [ "petgraph 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", "thread-id 3.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3058,7 +3058,7 @@ dependencies = [ "hamming 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "primal-bit 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "primal-estimate 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3604,11 +3604,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "smallvec" -version = "0.6.5" +version = "0.6.10" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", -] [[package]] name = "socket2" @@ -4062,7 +4059,7 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", "trace-time 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -4748,7 +4745,7 @@ dependencies = [ "checksum slab 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6dbdd334bd28d328dad1c41b0ea662517883d8880d8533895ef96c8003dec9c4" "checksum slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23" "checksum slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5f9776d6b986f77b35c6cf846c11ad986ff128fe0b2b63a3628e3755e8d3102d" -"checksum smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "153ffa32fd170e9944f7e0838edf824a754ec4c1fc64746fcc9fe1f8fa602e5d" +"checksum smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "ab606a9c5e214920bb66c458cd7be8ef094f813f20fe77a54cc7dbfff220d4b7" "checksum socket2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "c4d11a52082057d87cb5caa31ad812f4504b97ab44732cd8359df2e9ff9f48e7" "checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8" "checksum string 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00caf261d6f90f588f8450b8e1230fa0d5be49ee6140fdfbcb55335aff350970" diff --git a/Cargo.toml b/Cargo.toml index 162dc27a29..27e1b24dcd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ description = "Parity Ethereum client" name = "parity-ethereum" # NOTE Make sure to update util/version/Cargo.toml as well -version = "2.5.3" +version = "2.5.4" license = "GPL-3.0" authors = ["Parity Technologies "] diff --git a/util/version/Cargo.toml b/util/version/Cargo.toml index 64239cb466..90bf9533b7 100644 --- a/util/version/Cargo.toml +++ b/util/version/Cargo.toml @@ -3,7 +3,7 @@ [package] name = "parity-version" # NOTE: this value is used for Parity Ethereum version string (via env CARGO_PKG_VERSION) -version = "2.5.3" +version = "2.5.4" authors = ["Parity Technologies "] build = "build.rs" From 3ebc7697578269dee29fea380407569882a70826 Mon Sep 17 00:00:00 2001 From: s3krit Date: Mon, 8 Jul 2019 12:30:14 +0200 Subject: [PATCH 160/168] version: stabilise v2.5 (#10857) --- Cargo.lock | 12 ++++++------ Cargo.toml | 2 +- util/version/Cargo.toml | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cf3791840e..ca696fea69 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2457,7 +2457,7 @@ dependencies = [ "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", "jni 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "panic_hook 0.1.0", - "parity-ethereum 2.5.4", + "parity-ethereum 2.5.5", "tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-current-thread 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2487,7 +2487,7 @@ dependencies = [ [[package]] name = "parity-ethereum" -version = "2.5.4" +version = "2.5.5" dependencies = [ "ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2540,7 +2540,7 @@ dependencies = [ "parity-rpc 1.12.0", "parity-runtime 0.1.0", "parity-updater 1.12.0", - "parity-version 2.5.4", + "parity-version 2.5.5", "parity-whisper 0.1.0", "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2683,7 +2683,7 @@ dependencies = [ "parity-crypto 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-runtime 0.1.0", "parity-updater 1.12.0", - "parity-version 2.5.4", + "parity-version 2.5.5", "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2781,7 +2781,7 @@ dependencies = [ "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-hash-fetch 1.12.0", "parity-path 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-version 2.5.4", + "parity-version 2.5.5", "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2791,7 +2791,7 @@ dependencies = [ [[package]] name = "parity-version" -version = "2.5.4" +version = "2.5.5" dependencies = [ "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "rlp 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index 27e1b24dcd..ea5b50b9a2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ description = "Parity Ethereum client" name = "parity-ethereum" # NOTE Make sure to update util/version/Cargo.toml as well -version = "2.5.4" +version = "2.5.5" license = "GPL-3.0" authors = ["Parity Technologies "] diff --git a/util/version/Cargo.toml b/util/version/Cargo.toml index 90bf9533b7..4675604b58 100644 --- a/util/version/Cargo.toml +++ b/util/version/Cargo.toml @@ -3,14 +3,14 @@ [package] name = "parity-version" # NOTE: this value is used for Parity Ethereum version string (via env CARGO_PKG_VERSION) -version = "2.5.4" +version = "2.5.5" authors = ["Parity Technologies "] build = "build.rs" [package.metadata] # This versions track. Should be changed to `stable` or `beta` when on respective branches. # Used by auto-updater and for Parity version string. -track = "beta" +track = "stable" # Network specific settings, used ONLY by auto-updater. # Latest supported fork blocks. From ff398fe7ff9c55f7083ae736b8bf23646fcd44f2 Mon Sep 17 00:00:00 2001 From: s3krit Date: Mon, 12 Aug 2019 18:55:11 +0200 Subject: [PATCH 161/168] V2.5.6 stable (#10961) - Fix cargo audit (#10921) - Add support for Energy Web Foundation's new chains (#10957) - Kaspersky AV whitelisting (#10919) - Avast whitelist script (#10900) - Docker images renaming (#10863) - Remove excessive warning (#10831) - Allow --nat extip:your.host.here.org (#10830) - When updating the client or when called from RPC, sleep should mean sleep (#10814) - added new ropsten-bootnode and removed old one (#10794) - ethkey no longer uses byteorder (#10786) - Do not drop the peer with None difficulty (#10772) - docs: Update Readme with TOC, Contributor Guideline. Update Cargo package descriptions (#10652) --- .github/CONTRIBUTING.md | 37 +++- .gitlab-ci.yml | 35 +++- CHANGELOG.md | 233 ++++++++-------------- Cargo.lock | 160 +++++---------- Cargo.toml | 2 +- README.md | 246 ++++++++++++++++++++++-- accounts/Cargo.toml | 2 +- accounts/ethkey/Cargo.toml | 2 +- accounts/ethkey/README.md | 2 +- accounts/ethkey/cli/Cargo.toml | 1 + accounts/ethkey/src/extended.rs | 5 +- accounts/ethkey/src/lib.rs | 1 - accounts/ethstore/Cargo.toml | 1 + accounts/ethstore/cli/Cargo.toml | 1 + chainspec/Cargo.toml | 1 + cli-signer/Cargo.toml | 4 +- cli-signer/rpc-client/Cargo.toml | 4 +- docs/CHANGELOG-2.4.md | 128 ++++++++++++ ethash/Cargo.toml | 1 + ethcore/Cargo.toml | 6 +- ethcore/blockchain/Cargo.toml | 4 +- ethcore/call-contract/Cargo.toml | 1 + ethcore/evm/Cargo.toml | 1 + ethcore/light/Cargo.toml | 2 +- ethcore/node-filter/Cargo.toml | 2 +- ethcore/private-tx/src/encryptor.rs | 2 +- ethcore/res/ethereum/ewc.json | 208 ++++++++++++++++++++ ethcore/res/ethereum/ropsten.json | 2 +- ethcore/res/ethereum/tobalaba.json | 80 -------- ethcore/res/ethereum/volta.json | 202 +++++++++++++++++++ ethcore/service/Cargo.toml | 1 + ethcore/src/client/client.rs | 10 +- ethcore/src/ethereum/mod.rs | 11 +- ethcore/src/executive.rs | 36 ++-- ethcore/src/lib.rs | 2 +- ethcore/src/snapshot/mod.rs | 10 +- ethcore/sync/Cargo.toml | 2 +- ethcore/sync/src/chain/mod.rs | 2 +- ethcore/types/Cargo.toml | 2 +- ethcore/types/src/restoration_status.rs | 2 +- ethcore/vm/Cargo.toml | 1 + ethcore/wasm/Cargo.toml | 1 + ethcore/wasm/run/Cargo.toml | 1 + evmbin/Cargo.toml | 2 +- ipfs/Cargo.toml | 2 +- json/Cargo.toml | 1 + miner/Cargo.toml | 2 +- parity/cli/mod.rs | 2 +- parity/configuration.rs | 44 ++++- parity/logger/Cargo.toml | 2 +- parity/params.rs | 19 +- rpc/Cargo.toml | 2 +- rpc/src/lib.rs | 2 +- rpc/src/v1/helpers/engine_signer.rs | 5 +- scripts/gitlab/publish-av-whitelists.sh | 25 +++ secret-store/Cargo.toml | 2 +- util/version/Cargo.toml | 2 +- whisper/Cargo.toml | 2 +- 58 files changed, 1126 insertions(+), 445 deletions(-) create mode 100644 docs/CHANGELOG-2.4.md create mode 100644 ethcore/res/ethereum/ewc.json delete mode 100644 ethcore/res/ethereum/tobalaba.json create mode 100644 ethcore/res/ethereum/volta.json create mode 100755 scripts/gitlab/publish-av-whitelists.sh diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index b51cca8821..6d58aa9412 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -24,7 +24,42 @@ Also, try to include **steps to reproduce** the issue and expand on the **actual If you would like to contribute to Parity Ethereum, please **fork it**, fix bugs or implement features, and [propose a pull request](https://github.com/paritytech/parity-ethereum/compare). -Please, refer to the [Coding Guide](https://wiki.parity.io/Coding-guide) in our wiki for more details about hacking on Parity. +### Labels & Milestones + +We use [labels](https://github.com/paritytech/parity-ethereum/labels) to manage PRs and issues and communicate the state of a PR. Please familiarize yourself with them. Furthermore we are organizing issues in [milestones](https://github.com/paritytech/parity-ethereum/milestones). Best way to get started is to a pick a ticket from the current milestone tagged [`easy`](https://github.com/paritytech/parity-ethereum/labels/Q2-easy%20%F0%9F%92%83) and get going, or [`mentor`](https://github.com/paritytech/parity-ethereum/labels/Q1-mentor%20%F0%9F%95%BA) and get in contact with the mentor offering their support on that larger task. + +### Rules + +There are a few basic ground-rules for contributors (including the maintainer(s) of the project): + +* **No pushing directly to the master branch**. +* **All modifications** must be made in a **pull-request** to solicit feedback from other contributors. +* Pull-requests cannot be merged before CI runs green and two reviewers have given their approval. +* Contributors should adhere to the [Parity Ethereum Style Guide](https://wiki.parity.io/Parity-Ethereum-Style-Guide). + +### Recommendations + +* **Non-master branch names** *should* be prefixed with a short name moniker, followed by the associated Github Issue ID (if any), and a brief description of the task using the format `--` (e.g. `gavin-123-readme`). The name moniker helps people to inquiry about their unfinished work, and the GitHub Issue ID helps your future self and other developers (particularly those who are onboarding) find out about and understand the original scope of the task, and where it fits into Parity Ethereum [Projects](https://github.com/paritytech/parity-ethereum/projects). +* **Remove stale branches periodically** + +### Preparing Pull Requests + +* If your PR does not alter any logic (e.g. comments, dependencies, docs), then it may be tagged [`insubstantial`](https://github.com/paritytech/parity-ethereum/pulls?q=is%3Aopen+is%3Apr+label%3A%22A2-insubstantial+%F0%9F%91%B6%22). + +* Once a PR is ready for review please add the [`pleasereview`](https://github.com/paritytech/parity-ethereum/pulls?utf8=%E2%9C%93&q=is%3Aopen+is%3Apr+label%3A%22A0-pleasereview+%F0%9F%A4%93%22+) label. + +### Reviewing Pull Requests*: + +* At least two reviewers are required to review PRs (even for PRs tagged [`insubstantial`](https://github.com/paritytech/parity-ethereum/pulls?q=is%3Aopen+is%3Apr+label%3A%22A2-insubstantial+%F0%9F%91%B6%22)). + +When doing a review, make sure to look for any: + +* Buggy behavior. +* Undue maintenance burden. +* Breaking with house coding style. +* Pessimization (i.e. reduction of speed as measured in the projects benchmarks). +* Breaking changes should be carefuly reviewed and tagged as such so they end up in the [changelog](../CHANGELOG.md). +* Uselessness (i.e. it does not strictly add a feature or fix a known issue). ## License. diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 33cfbd9d9f..12ed84a5bd 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -46,7 +46,7 @@ variables: sccache --start-server - sccache -s after_script: - # sccache debug info + # sccache debug info - if test -e sccache_debug.log; then echo "_____All crate-types:_____"; @@ -147,32 +147,32 @@ test-linux-nightly: build-android: <<: *build-on-linux - image: parity/rust-parity-ethereum-android-build:stretch + image: parity/parity-ci-android:stretch variables: CARGO_TARGET: armv7-linux-androideabi build-linux: <<: *build-on-linux - only: *releaseable_branches + # only: *releaseable_branches build-linux-i386: <<: *build-on-linux only: *releaseable_branches - image: parity/rust-parity-ethereum-build:i386 + image: parity/parity-ci-i386:latest variables: CARGO_TARGET: i686-unknown-linux-gnu build-linux-arm64: <<: *build-on-linux only: *releaseable_branches - image: parity/rust-parity-ethereum-build:arm64 + image: parity/parity-ci-arm64:latest variables: CARGO_TARGET: aarch64-unknown-linux-gnu build-linux-armhf: <<: *build-on-linux only: *releaseable_branches - image: parity/rust-parity-ethereum-build:armhf + image: parity/parity-ci-armhf:latest variables: CARGO_TARGET: armv7-unknown-linux-gnueabihf @@ -310,16 +310,31 @@ publish-awss3-release: - linux-docker publish-docs: - stage: publish - image: parity/rust-parity-ethereum-docs:xenial + stage: publish + image: parity/parity-ci-docs:latest only: - tags except: - nightly - cache: {} - dependencies: [] + cache: {} + dependencies: [] script: - scripts/gitlab/publish-docs.sh tags: - linux-docker allow_failure: true + +publish-av-whitelist: + stage: publish + <<: *no_git + only: *releaseable_branches + except: + variables: + - $SCHEDULE_TAG == "nightly" + cache: {} + dependencies: + - build-windows + script: + - scripts/gitlab/publish-av-whitelists.sh + tags: + - linux-docker diff --git a/CHANGELOG.md b/CHANGELOG.md index b986da688c..05b83e82e7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,164 +1,95 @@ -## Parity-Ethereum [v2.4.3](https://github.com/paritytech/parity-ethereum/releases/tag/v2.4.3) (2019-03-22) +## Parity-Ethereum [v2.5.6](https://github.com/paritytech/parity-ethereum/releases/tag/v2.5.5) -Parity-Ethereum 2.4.3-beta is a bugfix release that improves performance and stability. This patch release contains a critical bug fix where serving light clients previously led to client crashes. Upgrading is highly recommended. +Parity-Ethereum v2.5.6-stable is a bugfix release that improves stability. + +* Allow specifying hostnames for node URLs +* Fix a bug where archive nodes were losing peers + +The full list of included changes: + +* Kaspersky AV whitelisting (#10919) +* Avast whitelist script (#10900) +* Docker images renaming (#10863) +* Remove excessive warning (#10831) +* Allow --nat extip:your.host.here.org (#10830) +* When updating the client or when called from RPC, sleep should mean sleep (#10814) +* added new ropsten-bootnode and removed old one (#10794) +* ethkey no longer uses byteorder (#10786) +* Do not drop the peer with None difficulty (#10772) +* docs: Update Readme with TOC, Contributor Guideline. Update Cargo package descriptions (#10652) + +## Parity-Ethereum [v2.5.5](https://github.com/paritytech/parity-ethereum/releases/tag/v2.5.5) + +Parity-Ethereum v2.5.5-stable is a minor release that improves performance and stability. +This release stabilises the 2.5 branch. + +As of today, Parity-Ethereum 2.4 reaches end of life and everyone is +encouraged to upgrade. + +## Parity-Ethereum [v2.5.4](https://github.com/paritytech/parity-ethereum/releases/tag/v2.5.4) + +Parity Ethereum v2.5.4-beta is a security update that addresses servo/rust-smallvec#148 + +The full list of included changes: + +* cargo update -p smallvec ([#10822](https://github.com/paritytech/parity-ethereum/pull/10822)) + +## Parity-Ethereum [v2.5.3](https://github.com/paritytech/parity-ethereum/releases/tag/v2.5.3) + +Parity-Ethereum 2.5.3-beta is a bugfix release that improves performance and stability. + +* EthereumClassic: activate the Atlantis Hardfork +* Clique: fix time overflow +* State tests: treat empty accounts the same as non-existant accounts (EIP 1052) +* Networking: support discovery-only peers (geth bootnodes) +* Snapshotting: fix unclean shutdown while snappshotting is under way The full list of included changes: -- 2.4.3 beta backports ([#10508](https://github.com/paritytech/parity-ethereum/pull/10508)) - - Version: bump beta - - Add additional request tests ([#10503](https://github.com/paritytech/parity-ethereum/pull/10503)) -## Parity-Ethereum [v2.4.2](https://github.com/paritytech/parity-ethereum/releases/tag/v2.4.2) (2019-03-20) +* ethcore/res: activate atlantis classic hf on block 8772000 ([#10766](https://github.com/paritytech/parity-ethereum/pull/10766)) +* fix docker tags for publishing ([#10741](https://github.com/paritytech/parity-ethereum/pull/10741)) +* fix: aura don't add `SystemTime::now()` ([#10720](https://github.com/paritytech/parity-ethereum/pull/10720)) +* Treat empty account the same as non-exist accounts in EIP-1052 ([#10775](https://github.com/paritytech/parity-ethereum/pull/10775)) +* DevP2p: Get node IP address and udp port from Socket, if not included in PING packet ([#10705](https://github.com/paritytech/parity-ethereum/pull/10705)) +* Add a way to signal shutdown to snapshotting threads ([#10744](https://github.com/paritytech/parity-ethereum/pull/10744)) + +## Parity-Ethereum [v2.5.2](https://github.com/paritytech/parity-ethereum/releases/tag/v2.5.2) + +Parity-Ethereum 2.5.2-beta is a bugfix release that improves performance and stability. -Parity-Ethereum 2.4.2-beta is a bugfix release that improves performance and stability. +Among others, it enables the _Atlantis_ hardfork on **Morden** and **Kotti** Classic networks. The full list of included changes: -- 2.4.2 beta backports ([#10488](https://github.com/paritytech/parity-ethereum/pull/10488)) - - Version: bump beta - - Сaching through docker volume ([#10477](https://github.com/paritytech/parity-ethereum/pull/10477)) - - fix win&mac build ([#10486](https://github.com/paritytech/parity-ethereum/pull/10486)) - - fix(extract `timestamp_checked_add` as lib) ([#10383](https://github.com/paritytech/parity-ethereum/pull/10383)) -## Parity-Ethereum [v2.4.1](https://github.com/paritytech/parity-ethereum/releases/tag/v2.4.1) (2019-03-19) +* [CI] allow cargo audit to fail ([#10676](https://github.com/paritytech/parity-ethereum/pull/10676)) +* Reset blockchain properly ([#10669](https://github.com/paritytech/parity-ethereum/pull/10669)) +* new image ([#10673](https://github.com/paritytech/parity-ethereum/pull/10673)) +* Update publishing ([#10644](https://github.com/paritytech/parity-ethereum/pull/10644)) +* enable lto for release builds ([#10717](https://github.com/paritytech/parity-ethereum/pull/10717)) +* Use RUSTFLAGS to set the optimization level ([#10719](https://github.com/paritytech/parity-ethereum/pull/10719)) +* ethcore: enable ECIP-1054 for classic ([#10731](https://github.com/paritytech/parity-ethereum/pull/10731)) -Parity-Ethereum 2.4.1-beta is a bugfix release that improves performance and stability. +## Parity-Ethereum [v2.5.1](https://github.com/paritytech/parity-ethereum/releases/tag/v2.5.1) + +Parity-Ethereum 2.5.1-beta is a bugfix release that improves performance and stability. + +Among others, it enables the Petersburg hardfork on **Rinkeby** and **POA-Core** Network, as well as the **Kovan** Network community hardfork. The full list of included changes: -- 2.4.1 beta backports ([#10471](https://github.com/paritytech/parity-ethereum/pull/10471)) - - Version: bump beta - - Implement parity_versionInfo & parity_setChain on LC; fix parity_setChain ([#10312](https://github.com/paritytech/parity-ethereum/pull/10312)) - - CI publish to aws ([#10446](https://github.com/paritytech/parity-ethereum/pull/10446)) - - CI aws git checkout ([#10451](https://github.com/paritytech/parity-ethereum/pull/10451)) - - Revert "CI aws git checkout ([#10451](https://github.com/paritytech/parity-ethereum/pull/10451))" ([#10456](https://github.com/paritytech/parity-ethereum/pull/10456)) - - Tests parallelized ([#10452](https://github.com/paritytech/parity-ethereum/pull/10452)) - - Ensure static validator set changes are recognized ([#10467](https://github.com/paritytech/parity-ethereum/pull/10467)) - -## Parity-Ethereum [v2.4.0](https://github.com/paritytech/parity-ethereum/releases/tag/v2.4.0) (2019-02-25) - -Parity-Ethereum 2.4.0-beta is our trifortnightly minor version release coming with a lot of new features as well as bugfixes and performance improvements. - -Notable changes: -- Account management is now deprecated ([#10213](https://github.com/paritytech/parity-ethereum/pull/10213)) -- Local accounts can now be specified via CLI ([#9960](https://github.com/paritytech/parity-ethereum/pull/9960)) -- Chains can now be reset to a particular block via CLI ([#9782](https://github.com/paritytech/parity-ethereum/pull/9782)) -- Ethash now additionally implements ProgPoW ([#9762](https://github.com/paritytech/parity-ethereum/pull/9762)) -- The `eip1283DisableTransition` flag was added to revert EIP-1283 ([#10214](https://github.com/paritytech/parity-ethereum/pull/10214)) + +* ci: publish docs debug ([#10638](https://github.com/paritytech/parity-ethereum/pull/10638)) + +## Parity-Ethereum [v2.5.0](https://github.com/paritytech/parity-ethereum/releases/tag/v2.5.0) + +Parity-Ethereum 2.5.0-beta is a minor release that improves performance and stabilizes the 2.5 branch by marking it as beta release. + +- This release adds support for the Clique consensus engine ([#9981](https://github.com/paritytech/parity-ethereum/pull/9981)) + - This enables Parity-Ethereum users to use the Görli, the Kotti Classic, and the legacy Rinkeby testnet. To get started try `parity --chain goerli`; note that light client support is currently not yet fully functional. +- This release removes the dead chain configs for Easthub and Ethereum Social ([#10531](https://github.com/paritytech/parity-ethereum/pull/10531)) + +As of today, Parity-Ethereum 2.3 reaches end of life and everyone is encouraged to upgrade. The full list of included changes: -- More Backports for Beta 2.4.0 ([#10431](https://github.com/paritytech/parity-ethereum/pull/10431)) - - Revert some changes, could be buggy ([#10399](https://github.com/paritytech/parity-ethereum/pull/10399)) - - Ci: clean up gitlab-ci.yml leftovers from previous merge ([#10429](https://github.com/paritytech/parity-ethereum/pull/10429)) - - 10000 > 5000 ([#10422](https://github.com/paritytech/parity-ethereum/pull/10422)) - - Fix underflow in pip, closes [#10419](https://github.com/paritytech/parity-ethereum/pull/10419) ([#10423](https://github.com/paritytech/parity-ethereum/pull/10423)) - - Fix panic when logging directory does not exist, closes [#10420](https://github.com/paritytech/parity-ethereum/pull/10420) ([#10424](https://github.com/paritytech/parity-ethereum/pull/10424)) - - Update hardcoded headers for Foundation, Ropsten, Kovan and Classic ([#10417](https://github.com/paritytech/parity-ethereum/pull/10417)) -- Backports for Beta 2.4.0 ([#10416](https://github.com/paritytech/parity-ethereum/pull/10416)) - - No-git for publish jobs, empty artifacts dir ([#10393](https://github.com/paritytech/parity-ethereum/pull/10393)) - - Snap: reenable i386, arm64, armhf architecture publishing ([#10386](https://github.com/paritytech/parity-ethereum/pull/10386)) - - Tx pool: always accept local transactions ([#10375](https://github.com/paritytech/parity-ethereum/pull/10375)) - - Fix to_pod storage trie value decoding ([#10368](https://github.com/paritytech/parity-ethereum/pull/10368)) -- Version: mark 2.4.0 beta -- Update to latest mem-db, hash-db and trie-db. ([#10314](https://github.com/paritytech/parity-ethereum/pull/10314)) -- Tx pool: always accept local transactions ([#10375](https://github.com/paritytech/parity-ethereum/pull/10375)) -- Fix(trace_main! macro): don't re-export ([#10384](https://github.com/paritytech/parity-ethereum/pull/10384)) -- Exchanged old(azure) bootnodes with new(ovh) ones ([#10309](https://github.com/paritytech/parity-ethereum/pull/10309)) -- Ethash: implement Progpow ([#9762](https://github.com/paritytech/parity-ethereum/pull/9762)) -- Snap: add the removable-media plug ([#10377](https://github.com/paritytech/parity-ethereum/pull/10377)) -- Add message to IO errors ([#10324](https://github.com/paritytech/parity-ethereum/pull/10324)) -- Chore(bump parity-daemonize): require rust >= 1.31 ([#10359](https://github.com/paritytech/parity-ethereum/pull/10359)) -- Secretstore: use in-memory transport in cluster tests ([#9850](https://github.com/paritytech/parity-ethereum/pull/9850)) -- Add fields to `memzero`'s Cargo.toml ([#10362](https://github.com/paritytech/parity-ethereum/pull/10362)) -- Snap: release untagged versions from branches to the candidate snap channel ([#10357](https://github.com/paritytech/parity-ethereum/pull/10357)) -- Fix(compilation warns): `no-default-features` ([#10346](https://github.com/paritytech/parity-ethereum/pull/10346)) -- No volumes are needed, just run -v volume:/path/in/the/container ([#10345](https://github.com/paritytech/parity-ethereum/pull/10345)) -- Fixed misstype ([#10351](https://github.com/paritytech/parity-ethereum/pull/10351)) -- Snap: prefix version and populate candidate channel ([#10343](https://github.com/paritytech/parity-ethereum/pull/10343)) -- Bundle protocol and packet_id together in chain sync ([#10315](https://github.com/paritytech/parity-ethereum/pull/10315)) -- Role back docker build image and docker deploy image to ubuntu:xenial… ([#10338](https://github.com/paritytech/parity-ethereum/pull/10338)) -- Change docker image based on debian instead of ubuntu due to the chan… ([#10336](https://github.com/paritytech/parity-ethereum/pull/10336)) -- Don't add discovery initiators to the node table ([#10305](https://github.com/paritytech/parity-ethereum/pull/10305)) -- Fix(docker): fix not receives SIGINT ([#10059](https://github.com/paritytech/parity-ethereum/pull/10059)) -- Snap: official image / test ([#10168](https://github.com/paritytech/parity-ethereum/pull/10168)) -- Fix(add helper for timestamp overflows) ([#10330](https://github.com/paritytech/parity-ethereum/pull/10330)) -- Additional error for invalid gas ([#10327](https://github.com/paritytech/parity-ethereum/pull/10327)) -- Revive parity_setMinGasPrice RPC call ([#10294](https://github.com/paritytech/parity-ethereum/pull/10294)) -- Add Statetest support for Constantinople Fix ([#10323](https://github.com/paritytech/parity-ethereum/pull/10323)) -- Fix(parity-clib): grumbles that were not addressed in [#9920](https://github.com/paritytech/parity-ethereum/pull/9920) ([#10154](https://github.com/paritytech/parity-ethereum/pull/10154)) -- Fix(light-rpc): Make `light_sync` generic ([#10238](https://github.com/paritytech/parity-ethereum/pull/10238)) -- Fix publish job ([#10317](https://github.com/paritytech/parity-ethereum/pull/10317)) -- Secure WS-RPC: grant access to all apis ([#10246](https://github.com/paritytech/parity-ethereum/pull/10246)) -- Make specification of protocol in SyncRequester::send_request explicit ([#10295](https://github.com/paritytech/parity-ethereum/pull/10295)) -- Fix: parity-clib/examples/cpp/CMakeLists.txt ([#10313](https://github.com/paritytech/parity-ethereum/pull/10313)) -- Ci optimizations ([#10297](https://github.com/paritytech/parity-ethereum/pull/10297)) -- Increase number of requested block bodies in chain sync ([#10247](https://github.com/paritytech/parity-ethereum/pull/10247)) -- Deprecate account management ([#10213](https://github.com/paritytech/parity-ethereum/pull/10213)) -- Properly handle check_epoch_end_signal errors ([#10015](https://github.com/paritytech/parity-ethereum/pull/10015)) -- Fix(osx and windows builds): bump parity-daemonize ([#10291](https://github.com/paritytech/parity-ethereum/pull/10291)) -- Add missing step for Using `systemd` service file ([#10175](https://github.com/paritytech/parity-ethereum/pull/10175)) -- Call private contract methods from another private contract (read-onl… ([#10086](https://github.com/paritytech/parity-ethereum/pull/10086)) -- Update ring to 0.14 ([#10262](https://github.com/paritytech/parity-ethereum/pull/10262)) -- Fix(secret-store): deprecation warning ([#10301](https://github.com/paritytech/parity-ethereum/pull/10301)) -- Update to jsonrpc-derive 10.0.2, fixes aliases bug ([#10300](https://github.com/paritytech/parity-ethereum/pull/10300)) -- Convert to jsonrpc-derive, use jsonrpc-* from crates.io ([#10298](https://github.com/paritytech/parity-ethereum/pull/10298)) -- Fix Windows build ([#10284](https://github.com/paritytech/parity-ethereum/pull/10284)) -- Don't run the CPP example on CI ([#10285](https://github.com/paritytech/parity-ethereum/pull/10285)) -- Additional tests for uint deserialization. ([#10279](https://github.com/paritytech/parity-ethereum/pull/10279)) -- Prevent silent errors in daemon mode ([#10007](https://github.com/paritytech/parity-ethereum/pull/10007)) -- Fix join-set test to be deterministic. ([#10263](https://github.com/paritytech/parity-ethereum/pull/10263)) -- Update CHANGELOG-2.2.md ([#10254](https://github.com/paritytech/parity-ethereum/pull/10254)) -- Macos heapsize force jemalloc ([#10234](https://github.com/paritytech/parity-ethereum/pull/10234)) -- Allow specifying local accounts via CLI ([#9960](https://github.com/paritytech/parity-ethereum/pull/9960)) -- Take in account zero gas price certification when doing transact_cont… ([#10232](https://github.com/paritytech/parity-ethereum/pull/10232)) -- Update CHANGELOG.md ([#10249](https://github.com/paritytech/parity-ethereum/pull/10249)) -- Fix typo: CHANGELOG-2.1 -> CHANGELOG-2.2 ([#10233](https://github.com/paritytech/parity-ethereum/pull/10233)) -- Update copyright year to 2019. ([#10181](https://github.com/paritytech/parity-ethereum/pull/10181)) -- Fixed: types::transaction::SignedTransaction; ([#10229](https://github.com/paritytech/parity-ethereum/pull/10229)) -- Fix(ManageNetwork): replace Range with RangeInclusive ([#10209](https://github.com/paritytech/parity-ethereum/pull/10209)) -- Import rpc transactions sequentially ([#10051](https://github.com/paritytech/parity-ethereum/pull/10051)) -- Enable St-Peters-Fork ("Constantinople Fix") ([#10223](https://github.com/paritytech/parity-ethereum/pull/10223)) -- Add EIP-1283 disable transition ([#10214](https://github.com/paritytech/parity-ethereum/pull/10214)) -- Echo CORS request headers by default ([#10221](https://github.com/paritytech/parity-ethereum/pull/10221)) -- Happy New Year! ([#10211](https://github.com/paritytech/parity-ethereum/pull/10211)) -- Perform stripping during build ([#10208](https://github.com/paritytech/parity-ethereum/pull/10208)) -- Remove CallContract and RegistryInfo re-exports from `ethcore/client` ([#10205](https://github.com/paritytech/parity-ethereum/pull/10205)) -- Extract CallContract and RegistryInfo traits into their own crate ([#10178](https://github.com/paritytech/parity-ethereum/pull/10178)) -- Update the changelogs for 2.1.11, 2.2.6, 2.2.7, and 2.3.0 ([#10197](https://github.com/paritytech/parity-ethereum/pull/10197)) -- Cancel Constantinople HF on POA Core ([#10198](https://github.com/paritytech/parity-ethereum/pull/10198)) -- Adds cli interface to allow reseting chain to a particular block ([#9782](https://github.com/paritytech/parity-ethereum/pull/9782)) -- Run all `igd` methods in its own thread ([#10195](https://github.com/paritytech/parity-ethereum/pull/10195)) -- Pull constantinople on ethereum network ([#10189](https://github.com/paritytech/parity-ethereum/pull/10189)) -- Update for Android cross-compilation. ([#10180](https://github.com/paritytech/parity-ethereum/pull/10180)) -- Version: bump fork blocks for kovan and foundation ([#10186](https://github.com/paritytech/parity-ethereum/pull/10186)) -- Handle the case for contract creation on an empty but exist account w… ([#10065](https://github.com/paritytech/parity-ethereum/pull/10065)) -- Align personal_unlockAccount behaviour when permanent unlock is disab… ([#10060](https://github.com/paritytech/parity-ethereum/pull/10060)) -- Drop `runtime` after others (especially `ws_server`) ([#10179](https://github.com/paritytech/parity-ethereum/pull/10179)) -- Version: bump nightly to 2.4 ([#10165](https://github.com/paritytech/parity-ethereum/pull/10165)) -- Skip locking in statedb for non-canon blocks ([#10141](https://github.com/paritytech/parity-ethereum/pull/10141)) -- Remove reference to ui-interface command-line option ([#10170](https://github.com/paritytech/parity-ethereum/pull/10170)) -- Fix [#9822](https://github.com/paritytech/parity-ethereum/pull/9822): trace_filter does not return failed contract creation ([#10140](https://github.com/paritytech/parity-ethereum/pull/10140)) -- Fix _cannot recursively call into `Core`_ issue ([#10144](https://github.com/paritytech/parity-ethereum/pull/10144)) -- Fix(whisper): correct PoW calculation ([#10166](https://github.com/paritytech/parity-ethereum/pull/10166)) -- Bump JSON-RPC ([#10151](https://github.com/paritytech/parity-ethereum/pull/10151)) -- Ping nodes from discovery ([#10167](https://github.com/paritytech/parity-ethereum/pull/10167)) -- Fix(android): remove dependency to libusb ([#10161](https://github.com/paritytech/parity-ethereum/pull/10161)) -- Refactor(trim_right_matches -> trim_end_matches) ([#10159](https://github.com/paritytech/parity-ethereum/pull/10159)) -- Merge Machine and WithRewards ([#10071](https://github.com/paritytech/parity-ethereum/pull/10071)) - -## Previous releases - -- [CHANGELOG-2.3](docs/CHANGELOG-2.3.md) (_stable_) -- [CHANGELOG-2.2](docs/CHANGELOG-2.2.md) (EOL: 2019-02-25) -- [CHANGELOG-2.1](docs/CHANGELOG-2.1.md) (EOL: 2019-01-16) -- [CHANGELOG-2.0](docs/CHANGELOG-2.0.md) (EOL: 2018-11-15) -- [CHANGELOG-1.11](docs/CHANGELOG-1.11.md) (EOL: 2018-09-19) -- [CHANGELOG-1.10](docs/CHANGELOG-1.10.md) (EOL: 2018-07-18) -- [CHANGELOG-1.9](docs/CHANGELOG-1.9.md) (EOL: 2018-05-09) -- [CHANGELOG-1.8](docs/CHANGELOG-1.8.md) (EOL: 2018-03-22) -- [CHANGELOG-1.7](docs/CHANGELOG-1.7.md) (EOL: 2018-01-25) -- [CHANGELOG-1.6](docs/CHANGELOG-1.6.md) (EOL: 2017-10-15) -- [CHANGELOG-1.5](docs/CHANGELOG-1.5.md) (EOL: 2017-07-28) -- [CHANGELOG-1.4](docs/CHANGELOG-1.4.md) (EOL: 2017-03-13) -- [CHANGELOG-1.3](docs/CHANGELOG-1.3.md) (EOL: 2017-01-19) -- [CHANGELOG-1.2](docs/CHANGELOG-1.2.md) (EOL: 2016-11-07) -- [CHANGELOG-1.1](docs/CHANGELOG-1.1.md) (EOL: 2016-08-12) -- [CHANGELOG-1.0](docs/CHANGELOG-1.0.md) (EOL: 2016-06-24) -- [CHANGELOG-0.9](docs/CHANGELOG-0.9.md) (EOL: 2016-05-02) + +* fix(light cull): poll light cull instead of timer ([#10559](https://github.com/paritytech/parity-ethereum/pull/10559)) + diff --git a/Cargo.lock b/Cargo.lock index ca696fea69..625564013d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -357,102 +357,34 @@ dependencies = [ "thread-scoped 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "crossbeam" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "crossbeam-channel 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-deque 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-epoch 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "crossbeam-channel" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "crossbeam-epoch 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "crossbeam-deque" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "crossbeam-deque" -version = "0.5.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "crossbeam-epoch 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "crossbeam-deque" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "crossbeam-epoch 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-epoch 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "crossbeam-epoch" -version = "0.3.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "memoffset 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "crossbeam-epoch" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.6.1" +name = "crossbeam-queue" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "crossbeam-utils" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -462,10 +394,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "crossbeam-utils" -version = "0.6.2" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -709,7 +642,7 @@ dependencies = [ "byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "common-types 0.1.0", "criterion 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)", "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethabi 6.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -754,7 +687,7 @@ dependencies = [ "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "patricia-trie-ethereum 0.1.0", "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "rayon 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rayon 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "rlp 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "rlp_compress 0.1.0", "rlp_derive 0.1.0", @@ -811,7 +744,7 @@ dependencies = [ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rayon 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rayon 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "rlp 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "rlp_compress 0.1.0", "rlp_derive 0.1.0", @@ -852,7 +785,7 @@ dependencies = [ name = "ethcore-io" version = "1.12.0" dependencies = [ - "crossbeam-deque 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-deque 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1195,7 +1128,6 @@ dependencies = [ name = "ethkey" version = "0.3.0" dependencies = [ - "byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "edit-distance 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "eth-secp256k1 0.5.7 (git+https://github.com/paritytech/rust-secp256k1)", "ethereum-types 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2139,8 +2071,11 @@ dependencies = [ [[package]] name = "memoffset" -version = "0.2.1" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] name = "memory-cache" @@ -2343,7 +2278,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2457,7 +2392,7 @@ dependencies = [ "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", "jni 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "panic_hook 0.1.0", - "parity-ethereum 2.5.5", + "parity-ethereum 2.5.6", "tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-current-thread 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2487,7 +2422,7 @@ dependencies = [ [[package]] name = "parity-ethereum" -version = "2.5.5" +version = "2.5.6" dependencies = [ "ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2540,7 +2475,7 @@ dependencies = [ "parity-rpc 1.12.0", "parity-runtime 0.1.0", "parity-updater 1.12.0", - "parity-version 2.5.5", + "parity-version 2.5.6", "parity-whisper 0.1.0", "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2683,7 +2618,7 @@ dependencies = [ "parity-crypto 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-runtime 0.1.0", "parity-updater 1.12.0", - "parity-version 2.5.5", + "parity-version 2.5.6", "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2781,7 +2716,7 @@ dependencies = [ "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-hash-fetch 1.12.0", "parity-path 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-version 2.5.5", + "parity-version 2.5.6", "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2791,7 +2726,7 @@ dependencies = [ [[package]] name = "parity-version" -version = "2.5.5" +version = "2.5.6" dependencies = [ "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "rlp 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3233,22 +3168,23 @@ dependencies = [ [[package]] name = "rayon" -version = "1.0.2" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-deque 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", "either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rayon-core 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rayon-core 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rayon-core" -version = "1.4.1" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-deque 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3480,6 +3416,11 @@ name = "scopeguard" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "scopeguard" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "sct" version = "0.5.0" @@ -3970,7 +3911,7 @@ name = "tokio-threadpool" version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "crossbeam-deque 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-deque 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4508,17 +4449,11 @@ dependencies = [ "checksum criterion 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "c47d2b548c5647e1a436dc0cb78d4ebf51b6bf7ab101ed76662828bdd4d3a24a" "checksum criterion-plot 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6e649d6aacdbbdb94ec659561a309a71336fc5655ed408f3afd28df2fc0c4f4f" "checksum criterion-stats 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ff43cac80562f91ead0b617c1be74edf350adfaa195809d355de98dfc8f9237d" -"checksum crossbeam 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d7408247b1b87f480890f28b670c5f8d9a8a4274833433fe74dc0dfd46d33650" -"checksum crossbeam-channel 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7b85741761b7f160bc5e7e0c14986ef685b7f8bf9b7ad081c60c604bb4649827" -"checksum crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f739f8c5363aca78cfb059edf753d8f0d36908c348f3d8d1503f03d8b75d9cf3" -"checksum crossbeam-deque 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7792c4a9b5a4222f654e3728a3dd945aacc24d2c3a1a096ed265d80e4929cb9a" -"checksum crossbeam-deque 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3486aefc4c0487b9cb52372c97df0a48b8c249514af1ee99703bf70d2f2ceda1" -"checksum crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "927121f5407de9956180ff5e936fe3cf4324279280001cd56b669d28ee7e9150" -"checksum crossbeam-epoch 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "30fecfcac6abfef8771151f8be4abc9e4edc112c2bcb233314cafde2680536e9" -"checksum crossbeam-epoch 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2449aaa4ec7ef96e5fb24db16024b935df718e9ae1cec0a1e68feeca2efca7b8" -"checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9" +"checksum crossbeam-deque 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "05e44b8cf3e1a625844d1750e1f7820da46044ff6d28f4d43e455ba3e5bb2c13" +"checksum crossbeam-epoch 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "fedcd6772e37f3da2a9af9bf12ebe046c0dfe657992377b4df982a2b54cd37a9" +"checksum crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7c979cd6cfe72335896575c6b5688da489e420d36a27a0b9eb0c73db574b4a4b" "checksum crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "677d453a17e8bd2b913fa38e8b9cf04bcdbb5be790aa294f2389661d72036015" -"checksum crossbeam-utils 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e07fc155212827475223f0bcfae57e945e694fc90950ddf3f6695bbfd5555c72" +"checksum crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "04973fa96e96579258a5091af6003abde64af786b860f18622b82e026cca60e6" "checksum crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a2f4a431c5c9f662e1200b7c7f02c34e91361150e382089a8f2dec3ba680cbda" "checksum crunchy 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c240f247c278fa08a6d4820a6a222bfc6e0d999e51ba67be94f44c905b2161f2" "checksum csv 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6d54f6b0fd69128a2894b1a3e57af5849a0963c1cc77b165d30b896e40296452" @@ -4622,7 +4557,7 @@ dependencies = [ "checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" "checksum memchr 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4b3629fe9fdbff6daa6c33b90f7c08355c1aca05a3d01fa8063b822fcf185f3b" "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 memoffset 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ce6075db033bbbb7ee5a0bbd3a3186bbae616f57fb001c485c7ff77955f8177f" "checksum memory-db 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94da53143d45f6bad3753f532e56ad57a6a26c0ca6881794583310c7cb4c885f" "checksum memory_units 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "71d96e3f3c0b6325d8ccd83c33b28acb183edcb6c67938ba104ec546854b0882" "checksum mime 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)" = "0a907b83e7b9e987032439a387e187119cddafc92d5c2aaeb1d92580a793f630" @@ -4701,8 +4636,8 @@ dependencies = [ "checksum rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" "checksum rand_pcg 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "086bd09a33c7044e56bb44d5bdde5a60e7f119a9e95b0775f545de759a32fe05" "checksum rand_xorshift 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "effa3fcaa47e18db002bdde6060944b6d2f9cfd8db471c30e873448ad9187be3" -"checksum rayon 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "df7a791f788cb4c516f0e091301a29c2b71ef680db5e644a7d68835c8ae6dbfa" -"checksum rayon-core 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b055d1e92aba6877574d8fe604a63c8b5df60f60e5982bf7ccbb1338ea527356" +"checksum rayon 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a4b0186e22767d5b9738a05eab7c6ac90b15db17e5b5f9bd87976dd7d89a10a4" +"checksum rayon-core 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ebbe0df8435ac0c397d467b6cad6d25543d06e8a019ef3f6af3c384597515bd2" "checksum redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "c214e91d3ecf43e9a4e41e578973adeb14b474f2bee858742d127af75a0112b1" "checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" "checksum regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9329abc99e39129fcceabd24cf5d85b4671ef7c29c50e972bc5afe32438ec384" @@ -4728,6 +4663,7 @@ dependencies = [ "checksum same-file 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "10f7794e2fda7f594866840e95f5c5962e886e228e68b6505885811a94dd728c" "checksum scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "332ffa32bf586782a3efaeb58f127980944bbc8c4d6913a86107ac2a5ab24b28" "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" +"checksum scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b42e15e59b18a828bbf5c58ea01debb36b9b096346de35d941dcb89009f24a0d" "checksum sct 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2f5adf8fbd58e1b1b52699dc8bed2630faecb6d8c7bee77d009d6bbe4af569b9" "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" diff --git a/Cargo.toml b/Cargo.toml index ea5b50b9a2..9bd8d16f9a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ description = "Parity Ethereum client" name = "parity-ethereum" # NOTE Make sure to update util/version/Cargo.toml as well -version = "2.5.5" +version = "2.5.6" license = "GPL-3.0" authors = ["Parity Technologies "] diff --git a/README.md b/README.md index 1c0302535f..b244256725 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,24 @@

+## Table of Contents + +1. [Description](#chapter-001) +2. [Technical Overview](#chapter-002) +3. [Building](#chapter-003)
+ 3.1 [Building Dependencies](#chapter-0031)
+ 3.2 [Building from Source Code](#chapter-0032)
+ 3.3 [Simple One-Line Installer for Mac and Linux](#chapter-0033)
+ 3.4 [Starting Parity Ethereum](#chapter-0034) +4. [Documentation](#chapter-004) +5. [Toolchain](#chapter-005) +6. [Community](#chapter-006) +7. [Contributing](#chapter-007) +8. [License](#chapter-008) + + +## 1. Description + **Built for mission-critical use**: Miners, service providers, and exchanges need fast synchronisation and maximum uptime. Parity Ethereum provides the core infrastructure essential for speedy and reliable services. - Clean, modular codebase for easy customisation @@ -15,7 +33,7 @@ - Synchronise in hours, not days with Warp Sync - Modular for light integration into your service or product -## Technical Overview +## 2. Technical Overview Parity Ethereum's goal is to be the fastest, lightest, and most secure Ethereum client. We are developing Parity Ethereum using the sophisticated and cutting-edge **Rust programming language**. Parity Ethereum is licensed under the GPLv3 and can be used for all your Ethereum needs. @@ -25,7 +43,9 @@ If you run into problems while using Parity Ethereum, check out the [wiki for do Parity Ethereum's current beta-release is 2.1. You can download it at [the releases page](https://github.com/paritytech/parity-ethereum/releases) or follow the instructions below to build from source. Please, mind the [CHANGELOG.md](CHANGELOG.md) for a list of all changes between different versions. -## Build Dependencies +## 3. Building + +### 3.1 Build Dependencies Parity Ethereum requires **latest stable Rust version** to build. @@ -58,7 +78,7 @@ Once you have `rustup` installed, then you need to install: Make sure that these binaries are in your `PATH`. After that, you should be able to build Parity Ethereum from source. -## Build from Source Code +### 3.2 Build from Source Code ```bash # download Parity Ethereum code @@ -95,7 +115,7 @@ or $ git checkout beta ``` -## Simple One-Line Installer for Mac and Linux +### 3.3 Simple One-Line Installer for Mac and Linux ```bash bash <(curl https://get.parity.io -L) @@ -107,9 +127,9 @@ The one-line installer always defaults to the latest beta release. To install a bash <(curl https://get.parity.io -L) -r stable ``` -## Start Parity Ethereum +### 3.4 Starting Parity Ethereum -### Manually +#### Manually To start Parity Ethereum manually, just run @@ -119,7 +139,7 @@ $ ./target/release/parity so Parity Ethereum begins syncing the Ethereum blockchain. -### Using `systemd` service file +#### Using `systemd` service file To start Parity Ethereum as a regular user using `systemd` init: @@ -128,17 +148,203 @@ To start Parity Ethereum as a regular user using `systemd` init: 2. Copy release to bin folder, write `sudo install ./target/release/parity /usr/bin/parity` 3. To configure Parity Ethereum, write a `/etc/parity/config.toml` config file, see [Configuring Parity Ethereum](https://paritytech.github.io/wiki/Configuring-Parity) for details. -## Parity Ethereum toolchain +## 4. Documentation + +Official website: https://parity.io + +Be sure to [check out our wiki](https://wiki.parity.io) for more information. + +### Viewing documentation for Parity Ethereum packages + +You can generate documentation for Parity Ethereum Rust packages that automatically opens in your web browser using [rustdoc with Cargo](https://doc.rust-lang.org/rustdoc/what-is-rustdoc.html#using-rustdoc-with-cargo) (of the The Rustdoc Book), by running the the following commands: + +* **All** packages + ``` + cargo doc --open + ``` + +* Specific package + ``` + cargo doc --package --open + ``` + +Replacing `` with one of the following from the details section below (i.e. `cargo doc --package parity-ethereum --open`): + +

+ +* Parity Ethereum (EthCore) Client Application + ```bash + parity-ethereum + ``` +* Parity Ethereum Account Management, Key Management Tool, and Keys Generator + ```bash + ethcore-accounts, ethkey-cli, ethstore, ethstore-cli + ``` +* Parity Chain Specification + ```bash + chainspec + ``` +* Parity CLI Signer Tool & RPC Client + ```bash + cli-signer parity-rpc-client + ``` +* Parity Ethereum Ethash & ProgPoW Implementations + ```bash + ethash + ``` +* Parity (EthCore) Library + ```bash + ethcore + ``` + * Parity Ethereum Blockchain Database, Test Generator, Configuration, +Caching, Importing Blocks, and Block Information + ```bash + ethcore-blockchain + ``` + * Parity Ethereum (EthCore) Contract Calls and Blockchain Service & Registry Information + ```bash + ethcore-call-contract + ``` + * Parity Ethereum (EthCore) Database Access & Utilities, Database Cache Manager + ```bash + ethcore-db + ``` + * Parity Ethereum Virtual Machine (EVM) Rust Implementation + ```bash + evm + ``` + * Parity Ethereum (EthCore) Light Client Implementation + ```bash + ethcore-light + ``` + * Parity Smart Contract based Node Filter, Manage Permissions of Network Connections + ```bash + node-filter + ``` + * Parity Private Transactions + ```bash + ethcore-private-tx + ``` + * Parity Ethereum (EthCore) Client & Network Service Creation & Registration with the I/O Subsystem + ```bash + ethcore-service + ``` + * Parity Ethereum (EthCore) Blockchain Synchronization + ```bash + ethcore-sync + ``` + * Parity Ethereum Common Types + ```bash + common-types + ``` + * Parity Ethereum Virtual Machines (VM) Support Library + ```bash + vm + ``` + * Parity Ethereum WASM Interpreter + ```bash + wasm + ``` + * Parity Ethereum WASM Test Runner + ```bash + pwasm-run-test + ``` + * Parity EVM Implementation + ```bash + evmbin + ``` + * Parity Ethereum IPFS-compatible API + ```bash + parity-ipfs-api + ``` + * Parity Ethereum JSON Deserialization + ```bash + ethjson + ``` + * Parity Ethereum State Machine Generalization for Consensus Engines + ```bash + parity-machine + ``` +* Parity Ethereum (EthCore) Miner Interface + ```bash + ethcore-miner parity-local-store price-info ethcore-stratum using_queue + ``` +* Parity Ethereum (EthCore) Logger Implementation + ```bash + ethcore-logger + ``` +* C bindings library for the Parity Ethereum client + ```bash + parity-clib + ``` +* Parity Ethereum JSON-RPC Servers + ```bash + parity-rpc + ``` +* Parity Ethereum (EthCore) Secret Store + ```bash + ethcore-secretstore + ``` +* Parity Updater Service + ```bash + parity-updater parity-hash-fetch + ``` +* Parity Core Libraries (Parity Util) + ```bash + ethcore-bloom-journal blooms-db dir eip-712 fake-fetch fastmap fetch ethcore-io + journaldb keccak-hasher len-caching-lock macros memory-cache memzero + migration-rocksdb ethcore-network ethcore-network-devp2p panic_hook + patricia-trie-ethereum registrar rlp_compress rlp_derive parity-runtime stats + time-utils triehash-ethereum unexpected parity-version + ``` +* Parity Whisper Protocol Implementation + ```bash + parity-whisper whisper-cli + ``` + +

+ +### Contributing to documentation for Parity Ethereum packages + +[Document source code](https://doc.rust-lang.org/1.9.0/book/documentation.html) for Parity Ethereum packages by annotating the source code with documentation comments. + +Example (generic documentation comment): +```markdown +/// Summary +/// +/// Description +/// +/// # Panics +/// +/// # Errors +/// +/// # Safety +/// +/// # Examples +/// +/// Summary of Example 1 +/// +/// ```rust +/// // insert example 1 code here for use with documentation as tests +/// ``` +/// +``` + +## 5. Toolchain In addition to the Parity Ethereum client, there are additional tools in this repository available: -- [evmbin](https://github.com/paritytech/parity-ethereum/blob/master/evmbin/) - EVM implementation for Parity Ethereum. -- [ethabi](https://github.com/paritytech/ethabi) - Parity Ethereum function calls encoding. -- [ethstore](https://github.com/paritytech/parity-ethereum/blob/master/accounts/ethstore) - Parity Ethereum key management. -- [ethkey](https://github.com/paritytech/parity-ethereum/blob/master/accounts/ethkey) - Parity Ethereum keys generator. -- [whisper](https://github.com/paritytech/parity-ethereum/blob/master/whisper/) - Implementation of Whisper-v2 PoC. +- [evmbin](./evmbin) - Parity Ethereum EVM Implementation. +- [ethstore](./accounts/ethstore) - Parity Ethereum Key Management. +- [ethkey](./accounts/ethkey) - Parity Ethereum Keys Generator. +- [whisper](./whisper) - Parity Ethereum Whisper-v2 PoC Implementation. -## Join the chat! +The following tool is available in a separate repository: +- [ethabi](https://github.com/paritytech/ethabi) - Parity Ethereum Encoding of Function Calls. [Docs here](https://crates.io/crates/ethabi) + +## 6. Community + +### Join the chat! Questions? Get in touch with us on Gitter: [![Gitter: Parity](https://img.shields.io/badge/gitter-parity-4AB495.svg)](https://gitter.im/paritytech/parity) @@ -149,8 +355,14 @@ Questions? Get in touch with us on Gitter: Alternatively, join our community on Matrix: [![Riot: +Parity](https://img.shields.io/badge/riot-%2Bparity%3Amatrix.parity.io-orange.svg)](https://riot.im/app/#/group/+parity:matrix.parity.io) -## Documentation +## 7. Contributing -Official website: https://parity.io +An introduction has been provided in the ["So You Want to be a Core Developer" presentation slides by Hernando Castano](http://tiny.cc/contrib-to-parity-eth). Additional guidelines are provided in [CONTRIBUTING](./.github/CONTRIBUTING.md). -Be sure to [check out our wiki](https://wiki.parity.io) for more information. +### Contributor Code of Conduct + +[CODE_OF_CONDUCT](./.github/CODE_OF_CONDUCT.md) + +## 8. License + +[LICENSE](./LICENSE) diff --git a/accounts/Cargo.toml b/accounts/Cargo.toml index 072593cd10..12100df6ed 100644 --- a/accounts/Cargo.toml +++ b/accounts/Cargo.toml @@ -1,5 +1,5 @@ [package] -description = "Account management for Parity Ethereum" +description = "Parity Ethereum Account Management" homepage = "http://parity.io" license = "GPL-3.0" name = "ethcore-accounts" diff --git a/accounts/ethkey/Cargo.toml b/accounts/ethkey/Cargo.toml index ec784bd11d..8dd391540c 100644 --- a/accounts/ethkey/Cargo.toml +++ b/accounts/ethkey/Cargo.toml @@ -1,10 +1,10 @@ [package] +description = "Parity Ethereum Keys Generator" name = "ethkey" version = "0.3.0" authors = ["Parity Technologies "] [dependencies] -byteorder = "1.0" edit-distance = "2.0" parity-crypto = "0.3.0" eth-secp256k1 = { git = "https://github.com/paritytech/rust-secp256k1" } diff --git a/accounts/ethkey/README.md b/accounts/ethkey/README.md index 6fc98b020d..23c57fa4ca 100644 --- a/accounts/ethkey/README.md +++ b/accounts/ethkey/README.md @@ -5,7 +5,7 @@ Parity Ethereum keys generator. ### Usage ``` -Parity Ethereum keys generator. +Parity Ethereum Keys Generator. Copyright 2015-2019 Parity Technologies (UK) Ltd. Usage: diff --git a/accounts/ethkey/cli/Cargo.toml b/accounts/ethkey/cli/Cargo.toml index d43aa2c5c0..cb57f05053 100644 --- a/accounts/ethkey/cli/Cargo.toml +++ b/accounts/ethkey/cli/Cargo.toml @@ -1,4 +1,5 @@ [package] +description = "Parity Ethereum Keys Generator CLI" name = "ethkey-cli" version = "0.1.0" authors = ["Parity Technologies "] diff --git a/accounts/ethkey/src/extended.rs b/accounts/ethkey/src/extended.rs index 7d02271ebb..401d98f2f6 100644 --- a/accounts/ethkey/src/extended.rs +++ b/accounts/ethkey/src/extended.rs @@ -35,9 +35,8 @@ impl Label for u32 { fn len() -> usize { 4 } fn store(&self, target: &mut [u8]) { - use byteorder::{BigEndian, ByteOrder}; - - BigEndian::write_u32(&mut target[0..4], *self); + let bytes = self.to_be_bytes(); + target[0..4].copy_from_slice(&bytes); } } diff --git a/accounts/ethkey/src/lib.rs b/accounts/ethkey/src/lib.rs index 5c58333c71..2a1968bbea 100644 --- a/accounts/ethkey/src/lib.rs +++ b/accounts/ethkey/src/lib.rs @@ -16,7 +16,6 @@ // #![warn(missing_docs)] -extern crate byteorder; extern crate edit_distance; extern crate parity_crypto; extern crate ethereum_types; diff --git a/accounts/ethstore/Cargo.toml b/accounts/ethstore/Cargo.toml index 4563a80327..c16c4672d4 100644 --- a/accounts/ethstore/Cargo.toml +++ b/accounts/ethstore/Cargo.toml @@ -1,4 +1,5 @@ [package] +description = "Parity Ethereum Key Management" name = "ethstore" version = "0.2.1" authors = ["Parity Technologies "] diff --git a/accounts/ethstore/cli/Cargo.toml b/accounts/ethstore/cli/Cargo.toml index 82858eaa76..9578a75377 100644 --- a/accounts/ethstore/cli/Cargo.toml +++ b/accounts/ethstore/cli/Cargo.toml @@ -1,4 +1,5 @@ [package] +description = "Parity Ethereum Key Management CLI" name = "ethstore-cli" version = "0.1.1" authors = ["Parity Technologies "] diff --git a/chainspec/Cargo.toml b/chainspec/Cargo.toml index 8739ca7dcb..c0308edd32 100644 --- a/chainspec/Cargo.toml +++ b/chainspec/Cargo.toml @@ -1,4 +1,5 @@ [package] +description = "Parity Ethereum Chain Specification" name = "chainspec" version = "0.1.0" authors = ["Marek Kotewicz "] diff --git a/cli-signer/Cargo.toml b/cli-signer/Cargo.toml index 11dd06107e..aa56da6f85 100644 --- a/cli-signer/Cargo.toml +++ b/cli-signer/Cargo.toml @@ -1,10 +1,10 @@ [package] -authors = ["Parity "] -description = "Parity Cli Tool" +description = "Parity Ethereum CLI Signer Tool" homepage = "http://parity.io" license = "GPL-3.0" name = "cli-signer" version = "1.4.0" +authors = ["Parity "] [dependencies] ethereum-types = "0.4" diff --git a/cli-signer/rpc-client/Cargo.toml b/cli-signer/rpc-client/Cargo.toml index 53ec983391..50565c0b34 100644 --- a/cli-signer/rpc-client/Cargo.toml +++ b/cli-signer/rpc-client/Cargo.toml @@ -1,10 +1,10 @@ [package] -authors = ["Parity "] -description = "Parity Rpc Client" +description = "Parity Ethereum RPC Client" homepage = "http://parity.io" license = "GPL-3.0" name = "parity-rpc-client" version = "1.4.0" +authors = ["Parity "] [dependencies] ethereum-types = "0.4" diff --git a/docs/CHANGELOG-2.4.md b/docs/CHANGELOG-2.4.md new file mode 100644 index 0000000000..ad7fc373d9 --- /dev/null +++ b/docs/CHANGELOG-2.4.md @@ -0,0 +1,128 @@ +## Parity-Ethereum [v2.4.9](https://github.com/paritytech/parity-ethereum/releases/tag/v2.4.9) + +Parity Ethereum v2.4.9-stable is a security update which addresses servo/rust-smallvec#148 + +The full list of included changes: + +* cargo update -p smallvec ([#10822](https://github.com/paritytech/parity-ethereum/pull/10822)) + +## Parity-Ethereum [v2.4.8](https://github.com/paritytech/parity-ethereum/releases/tag/v2.4.8) + +Parity-Ethereum 2.4.8-stable is a bugfix release that improves performance and stability. + +* Blockchain: fix reset chain +* State tests: treat empty accounts the same as non-existant accounts (EIP 1052) +* Aura: fix Timestamp Overflow +* Networking: support discovery-only peers (geth bootnodes) +* Snapshotting: fix unclean shutdown while snappshotting is under way + +The full list of included changes: + +* ethcore/res: activate atlantis classic hf on block 8772000 ([#10766](https://github.com/paritytech/parity-ethereum/pull/10766)) +* fix docker tags for publishing ([#10741](https://github.com/paritytech/parity-ethereum/pull/10741)) +* Reset blockchain properly ([#10669](https://github.com/paritytech/parity-ethereum/pull/10669)) +* adds rpc error message for --no-ancient-blocks ([#10608](https://github.com/paritytech/parity-ethereum/pull/10608)) +* Treat empty account the same as non-exist accounts in EIP-1052 ([#10775](https://github.com/paritytech/parity-ethereum/pull/10775)) +* fix: aura don't add `SystemTime::now()` ([#10720](https://github.com/paritytech/parity-ethereum/pull/10720)) +* DevP2p: Get node IP address and udp port from Socket, if not included in PING packet ([#10705](https://github.com/paritytech/parity-ethereum/pull/10705)) +* Revert "fix: aura don't add `SystemTime::now()` ([#10720](https://github.com/paritytech/parity-ethereum/pull/10720))" +* Add a way to signal shutdown to snapshotting threads ([#10744](https://github.com/paritytech/parity-ethereum/pull/10744)) + +## Parity-Ethereum [v2.4.7](https://github.com/paritytech/parity-ethereum/releases/tag/v2.4.7) + +Parity-Ethereum 2.4.7-stable is a bugfix release that improves performance and stability. + +Among others, it enables the _Atlantis_ hardfork on **Morden** and **Kotti** Classic networks. + +The full list of included changes: + +* [CI] allow cargo audit to fail ([#10676](https://github.com/paritytech/parity-ethereum/pull/10676)) +* new image ([#10673](https://github.com/paritytech/parity-ethereum/pull/10673)) +* Update publishing ([#10644](https://github.com/paritytech/parity-ethereum/pull/10644)) +* enable lto for release builds ([#10717](https://github.com/paritytech/parity-ethereum/pull/10717)) +* Use RUSTFLAGS to set the optimization level ([#10719](https://github.com/paritytech/parity-ethereum/pull/10719)) +* ethcore: enable ECIP-1054 for classic ([#10731](https://github.com/paritytech/parity-ethereum/pull/10731)) + +## Parity-Ethereum [v2.4.6](https://github.com/paritytech/parity-ethereum/releases/tag/v2.4.6) + +Parity-Ethereum 2.4.6-stable is a bugfix release that improves performance and stability. + +Among others, it enables the Petersburg hardfork on **Rinkeby** and **POA-Core** Network, as well as the **Kovan** Network community hardfork. + +The full list of included changes: + +* ci: publish docs debug ([#10638](https://github.com/paritytech/parity-ethereum/pull/10638)) + +## Parity-Ethereum [v2.4.5](https://github.com/paritytech/parity-ethereum/releases/tag/v2.4.5) + +Parity-Ethereum 2.4.5-stable is a bugfix release that improves performance and stability. This release improves memory optimizations around timestamp handling and stabilizes the 2.4 release branch. + +As of today, Parity-Ethereum 2.3 reaches end of life and everyone is encouraged to upgrade. + +## Parity-Ethereum [v2.4.4](https://github.com/paritytech/parity-ethereum/releases/tag/v2.4.4) + +Parity-Ethereum 2.4.4-beta is a bugfix release that improves performance and stability. This patch release removes the dead chain configs for Easthub and Ethereum Social. + +The full list of included changes: + +* fix(rpc-types): replace uint and hash with `ethereum_types v0.4` ([#10217](https://github.com/paritytech/parity-ethereum/pull/10217)) +* chore(bump ethereum-types) ([#10396](https://github.com/paritytech/parity-ethereum/pull/10396)) +* fix(light eth_gasPrice): ask network if not in cache ([#10535](https://github.com/paritytech/parity-ethereum/pull/10535)) +* fix(light account response): update `tx_queue` ([#10545](https://github.com/paritytech/parity-ethereum/pull/10545)) +* fix(bump dependencies) ([#10540](https://github.com/paritytech/parity-ethereum/pull/10540)) +* tx-pool: check transaction readiness before replacing ([#10526](https://github.com/paritytech/parity-ethereum/pull/10526)) +* fix #10390 ([#10391](https://github.com/paritytech/parity-ethereum/pull/10391)) +* private-tx: replace error_chain ([#10510](https://github.com/paritytech/parity-ethereum/pull/10510)) + +## Parity-Ethereum [v2.4.3](https://github.com/paritytech/parity-ethereum/releases/tag/v2.4.3) + +Parity-Ethereum 2.4.3-beta is a bugfix release that improves performance and stability. This patch release contains a critical bug fix where serving light clients previously led to client crashes. Upgrading is highly recommended. + +The full list of included changes: + +* Add additional request tests ([#10503](https://github.com/paritytech/parity-ethereum/pull/10503)) + +## Parity-Ethereum [v2.4.2](https://github.com/paritytech/parity-ethereum/releases/tag/v2.4.2) + +Parity-Ethereum 2.4.2-beta is a bugfix release that improves performance and stability. + +The full list of included changes: + +* Сaching through docker volume ([#10477](https://github.com/paritytech/parity-ethereum/pull/10477)) +* fix win&mac build ([#10486](https://github.com/paritytech/parity-ethereum/pull/10486)) +* fix(extract `timestamp_checked_add` as lib) ([#10383](https://github.com/paritytech/parity-ethereum/pull/10383)) + +## Parity-Ethereum [v2.4.1](https://github.com/paritytech/parity-ethereum/releases/tag/v2.4.1) + +Parity-Ethereum 2.4.1-beta is a bugfix release that improves performance and stability. + +The full list of included changes: + +* Implement parity_versionInfo & parity_setChain on LC; fix parity_setChain ([#10312](https://github.com/paritytech/parity-ethereum/pull/10312)) +* CI publish to aws ([#10446](https://github.com/paritytech/parity-ethereum/pull/10446)) +* CI aws git checkout ([#10451](https://github.com/paritytech/parity-ethereum/pull/10451)) +* Revert "CI aws git checkout ([#10451](https://github.com/paritytech/parity-ethereum/pull/10451))" (#10456) +* Revert "CI aws git checkout ([#10451](https://github.com/paritytech/parity-ethereum/pull/10451))" +* Tests parallelized ([#10452](https://github.com/paritytech/parity-ethereum/pull/10452)) +* Ensure static validator set changes are recognized ([#10467](https://github.com/paritytech/parity-ethereum/pull/10467)) + +## Parity-Ethereum [v2.4.0](https://github.com/paritytech/parity-ethereum/releases/tag/v2.4.0) + +Parity-Ethereum 2.4.0-beta is our trifortnightly minor version release coming with a lot of new features as well as bugfixes and performance improvements. + +Notable changes: +- Account management is now deprecated ([#10213](https://github.com/paritytech/parity-ethereum/pull/10213)) +- Local accounts can now be specified via CLI ([#9960](https://github.com/paritytech/parity-ethereum/pull/9960)) +- Chains can now be reset to a particular block via CLI ([#9782](https://github.com/paritytech/parity-ethereum/pull/9782)) +- Ethash now additionally implements ProgPoW ([#9762](https://github.com/paritytech/parity-ethereum/pull/9762)) +- The `eip1283DisableTransition` flag was added to revert EIP-1283 ([#10214](https://github.com/paritytech/parity-ethereum/pull/10214)) + +The full list of included changes: + +* revert some changes, could be buggy ([#10399](https://github.com/paritytech/parity-ethereum/pull/10399)) +* 10000 > 5000 ([#10422](https://github.com/paritytech/parity-ethereum/pull/10422)) +* fix panic when logging directory does not exist, closes #10420 ([#10424](https://github.com/paritytech/parity-ethereum/pull/10424)) +* fix underflow in pip, closes #10419 ([#10423](https://github.com/paritytech/parity-ethereum/pull/10423)) +* ci: clean up gitlab-ci.yml leftovers from previous merge ([#10429](https://github.com/paritytech/parity-ethereum/pull/10429)) +* Update hardcoded headers for Foundation, Ropsten, Kovan and Classic ([#10417](https://github.com/paritytech/parity-ethereum/pull/10417)) + diff --git a/ethash/Cargo.toml b/ethash/Cargo.toml index 929895aca7..59d26e128e 100644 --- a/ethash/Cargo.toml +++ b/ethash/Cargo.toml @@ -1,4 +1,5 @@ [package] +description = "Parity Ethereum Ethash & ProgPoW Implementations" name = "ethash" version = "1.12.0" authors = ["Parity Technologies "] diff --git a/ethcore/Cargo.toml b/ethcore/Cargo.toml index 336d6a0fcc..89a265a3ce 100644 --- a/ethcore/Cargo.toml +++ b/ethcore/Cargo.toml @@ -1,5 +1,5 @@ [package] -description = "Ethcore library" +description = "Parity Ethereum (EthCore) Library" homepage = "http://parity.io" license = "GPL-3.0" name = "ethcore" @@ -12,7 +12,7 @@ blooms-db = { path = "../util/blooms-db", optional = true } bn = { git = "https://github.com/paritytech/bn", default-features = false } byteorder = "1.0" common-types = { path = "types" } -crossbeam = "0.4" +crossbeam-utils = "0.6" env_logger = { version = "0.5", optional = true } error-chain = { version = "0.12", default-features = false } ethabi = "6.0" @@ -55,7 +55,7 @@ parking_lot = "0.7" trie-db = "0.11.0" patricia-trie-ethereum = { path = "../util/patricia-trie-ethereum" } rand = "0.4" -rayon = "1.0" +rayon = "1.1" rlp = { version = "0.3.0", features = ["ethereum"] } rlp_derive = { path = "../util/rlp-derive" } rustc-hex = "1.0" diff --git a/ethcore/blockchain/Cargo.toml b/ethcore/blockchain/Cargo.toml index a263697570..013aeddd53 100644 --- a/ethcore/blockchain/Cargo.toml +++ b/ethcore/blockchain/Cargo.toml @@ -1,5 +1,5 @@ [package] -description = "Ethcore blockchain database" +description = "Parity Ethereum Blockchain Database, Test Generator, Configuration, Caching, Importing Blocks, and Block Information" homepage = "http://parity.io" license = "GPL-3.0" name = "ethcore-blockchain" @@ -19,7 +19,7 @@ kvdb = "0.1" log = "0.4" parity-bytes = "0.1" parking_lot = "0.7" -rayon = "1.0" +rayon = "1.1" rlp = { version = "0.3.0", features = ["ethereum"] } rlp_compress = { path = "../../util/rlp-compress" } rlp_derive = { path = "../../util/rlp-derive" } diff --git a/ethcore/call-contract/Cargo.toml b/ethcore/call-contract/Cargo.toml index 068434a1de..7ee9bb7e65 100644 --- a/ethcore/call-contract/Cargo.toml +++ b/ethcore/call-contract/Cargo.toml @@ -1,4 +1,5 @@ [package] +description = "Parity Ethereum (EthCore) Contract Calls and Blockchain Service & Registry Information" name = "ethcore-call-contract" version = "0.1.0" license = "GPL-3.0" diff --git a/ethcore/evm/Cargo.toml b/ethcore/evm/Cargo.toml index e40c7485f9..67c3be6ff7 100644 --- a/ethcore/evm/Cargo.toml +++ b/ethcore/evm/Cargo.toml @@ -1,4 +1,5 @@ [package] +description = "Parity Ethereum Virtual Machine (EVM) Rust Implementation" name = "evm" version = "0.1.0" authors = ["Parity Technologies "] diff --git a/ethcore/light/Cargo.toml b/ethcore/light/Cargo.toml index 756b76f1f5..bf5866846c 100644 --- a/ethcore/light/Cargo.toml +++ b/ethcore/light/Cargo.toml @@ -1,5 +1,5 @@ [package] -description = "Parity Light Client Implementation" +description = "Parity Ethereum (EthCore) Light Client Implementation (Block Import IO Service, Blockchain Data Fetching, Light Client Header Chain Storage, Parity Light Protocol (PLP) Provider, Light Transaction Queue, CHT Definitions, Light Client Data Cache), Parity Light Protocol (PLP) Implementation, P2P Network I/O and Event Context Generalization, Peer Error Handling & Punishment, Request Load Timer & Distribution Manager, Pending Request Set Storage, Request Credit Management, Light Client Request Types, Request Chain Builder Utility, On-demand Chain Request Service over LES (for RPCs), ResponseGuard Implementation)" homepage = "http://parity.io" license = "GPL-3.0" name = "ethcore-light" diff --git a/ethcore/node-filter/Cargo.toml b/ethcore/node-filter/Cargo.toml index bd18468525..80823290c2 100644 --- a/ethcore/node-filter/Cargo.toml +++ b/ethcore/node-filter/Cargo.toml @@ -1,5 +1,5 @@ [package] -description = "Parity smart network connections" +description = "Parity Smart Contract based Node Filter, Manage Permissions of Network Connections" homepage = "http://parity.io" license = "GPL-3.0" name = "node-filter" diff --git a/ethcore/private-tx/src/encryptor.rs b/ethcore/private-tx/src/encryptor.rs index 597cc88796..6a24cf9300 100644 --- a/ethcore/private-tx/src/encryptor.rs +++ b/ethcore/private-tx/src/encryptor.rs @@ -60,7 +60,7 @@ pub trait Encryptor: Send + Sync + 'static { ) -> Result; } -/// Configurtion for key server encryptor +/// Configuration for key server encryptor #[derive(Default, PartialEq, Debug, Clone)] pub struct EncryptorConfig { /// URL to key server diff --git a/ethcore/res/ethereum/ewc.json b/ethcore/res/ethereum/ewc.json new file mode 100644 index 0000000000..d78e7c383c --- /dev/null +++ b/ethcore/res/ethereum/ewc.json @@ -0,0 +1,208 @@ +{ + "name": "EnergyWebChain", + "engine": { + "authorityRound": { + "params": { + "stepDuration": "5", + "validators": { + "contract": "0x1204700000000000000000000000000000000000" + }, + "maximumUncleCountTransition": "0", + "maximumUncleCount": "0", + "blockRewardContractAddress": "0x1204700000000000000000000000000000000002", + "blockRewardContractTransition": "0" + } + } + }, + "params": { + "networkID": "0xF6", + "maximumExtraDataSize": "0x20", + "gasLimitBoundDivisor": "0x400", + "minGasLimit": "0x1388", + "maxCodeSize": "0x6000", + "eip140Transition": "0x0", + "eip211Transition": "0x0", + "eip214Transition": "0x0", + "eip658Transition": "0x0", + "eip145Transition": "0x0", + "eip1014Transition": "0x0", + "eip1052Transition": "0x0", + "registrar": "0x1204700000000000000000000000000000000006" + }, + "genesis": { + "seal": { + "authorityRound": { + "step": "0x0", + "signature": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + } + }, + "difficulty": "0x20000", + "gasLimit": "0x5B8D80" + }, + "accounts": { + "0x0000000000000000000000000000000000000001": { + "balance": "1", + "builtin": { + "name": "ecrecover", + "activate_at": "0", + "pricing": { + "linear": { + "base": 3000, + "word": 0 + } + } + } + }, + "0x0000000000000000000000000000000000000002": { + "balance": "1", + "builtin": { + "name": "sha256", + "activate_at": "0", + "pricing": { + "linear": { + "base": 60, + "word": 12 + } + } + } + }, + "0x0000000000000000000000000000000000000003": { + "balance": "1", + "builtin": { + "name": "ripemd160", + "activate_at": "0", + "pricing": { + "linear": { + "base": 600, + "word": 120 + } + } + } + }, + "0x0000000000000000000000000000000000000004": { + "balance": "1", + "builtin": { + "name": "identity", + "activate_at": "0", + "pricing": { + "linear": { + "base": 15, + "word": 3 + } + } + } + }, + "0x0000000000000000000000000000000000000005": { + "balance": "1", + "builtin": { + "name": "modexp", + "activate_at": "0", + "pricing": { + "modexp": { + "divisor": 20 + } + } + } + }, + "0x0000000000000000000000000000000000000006": { + "balance": "1", + "builtin": { + "name": "alt_bn128_add", + "activate_at": "0", + "pricing": { + "linear": { + "base": 500, + "word": 0 + } + } + } + }, + "0x0000000000000000000000000000000000000007": { + "balance": "1", + "builtin": { + "name": "alt_bn128_mul", + "activate_at": "0", + "pricing": { + "linear": { + "base": 40000, + "word": 0 + } + } + } + }, + "0x0000000000000000000000000000000000000008": { + "balance": "1", + "builtin": { + "name": "alt_bn128_pairing", + "activate_at": "0", + "pricing": { + "alt_bn128_pairing": { + "base": 100000, + "pair": 80000 + } + } + } + }, + "0x1204700000000000000000000000000000000005": { + "constructor": "0x60806040523480156200001157600080fd5b50604051620024c8380380620024c883398101806040528101908080518201929190602001805190602001909291905050506000825182603282111580156200005a5750818111155b801562000068575060008114155b801562000076575060008214155b15156200008257600080fd5b600092505b8451831015620001bd57600260008685815181101515620000a457fe5b9060200190602002015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16158015620001335750600085848151811015156200011057fe5b9060200190602002015173ffffffffffffffffffffffffffffffffffffffff1614155b15156200013f57600080fd5b60016002600087868151811015156200015457fe5b9060200190602002015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550828060010193505062000087565b8460039080519060200190620001d5929190620001e8565b50836004819055505050505050620002bd565b82805482825590600052602060002090810192821562000264579160200282015b82811115620002635782518260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055509160200191906001019062000209565b5b50905062000273919062000277565b5090565b620002ba91905b80821115620002b657600081816101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055506001016200027e565b5090565b90565b6121fb80620002cd6000396000f30060806040526004361061011d576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063025e7c2714610177578063173825d9146101e457806320ea8d86146102275780632f54bf6e146102545780633411c81c146102af57806354741525146103145780637065cb4814610363578063784547a7146103a65780638b51d13f146103eb5780639ace38c21461042c578063a0e67e2b14610517578063a8abe69a14610583578063b5dc40c314610627578063b77bf600146106a9578063ba51a6df146106d4578063c01a8c8414610701578063c64274741461072e578063d74f8edd146107d5578063dc8452cd14610800578063e20056e61461082b578063ee22610b1461088e575b6000341115610175573373ffffffffffffffffffffffffffffffffffffffff167fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c346040518082815260200191505060405180910390a25b005b34801561018357600080fd5b506101a2600480360381019080803590602001909291905050506108bb565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156101f057600080fd5b50610225600480360381019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506108f9565b005b34801561023357600080fd5b5061025260048036038101908080359060200190929190505050610b92565b005b34801561026057600080fd5b50610295600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610d3a565b604051808215151515815260200191505060405180910390f35b3480156102bb57600080fd5b506102fa60048036038101908080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610d5a565b604051808215151515815260200191505060405180910390f35b34801561032057600080fd5b5061034d600480360381019080803515159060200190929190803515159060200190929190505050610d89565b6040518082815260200191505060405180910390f35b34801561036f57600080fd5b506103a4600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610e1b565b005b3480156103b257600080fd5b506103d160048036038101908080359060200190929190505050611020565b604051808215151515815260200191505060405180910390f35b3480156103f757600080fd5b5061041660048036038101908080359060200190929190505050611105565b6040518082815260200191505060405180910390f35b34801561043857600080fd5b50610457600480360381019080803590602001909291905050506111d0565b604051808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018481526020018060200183151515158152602001828103825284818151815260200191508051906020019080838360005b838110156104d95780820151818401526020810190506104be565b50505050905090810190601f1680156105065780820380516001836020036101000a031916815260200191505b509550505050505060405180910390f35b34801561052357600080fd5b5061052c6112c5565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b8381101561056f578082015181840152602081019050610554565b505050509050019250505060405180910390f35b34801561058f57600080fd5b506105d06004803603810190808035906020019092919080359060200190929190803515159060200190929190803515159060200190929190505050611353565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b838110156106135780820151818401526020810190506105f8565b505050509050019250505060405180910390f35b34801561063357600080fd5b50610652600480360381019080803590602001909291905050506114c4565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b8381101561069557808201518184015260208101905061067a565b505050509050019250505060405180910390f35b3480156106b557600080fd5b506106be611701565b6040518082815260200191505060405180910390f35b3480156106e057600080fd5b506106ff60048036038101908080359060200190929190505050611707565b005b34801561070d57600080fd5b5061072c600480360381019080803590602001909291905050506117c1565b005b34801561073a57600080fd5b506107bf600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050919291929050505061199e565b6040518082815260200191505060405180910390f35b3480156107e157600080fd5b506107ea6119bd565b6040518082815260200191505060405180910390f35b34801561080c57600080fd5b506108156119c2565b6040518082815260200191505060405180910390f35b34801561083757600080fd5b5061088c600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506119c8565b005b34801561089a57600080fd5b506108b960048036038101908080359060200190929190505050611cdd565b005b6003818154811015156108ca57fe5b906000526020600020016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60003073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561093557600080fd5b81600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151561098e57600080fd5b6000600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550600091505b600160038054905003821015610b13578273ffffffffffffffffffffffffffffffffffffffff16600383815481101515610a2157fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415610b06576003600160038054905003815481101515610a7f57fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600383815481101515610ab957fe5b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550610b13565b81806001019250506109eb565b6001600381818054905003915081610b2b91906120fe565b506003805490506004541115610b4a57610b49600380549050611707565b5b8273ffffffffffffffffffffffffffffffffffffffff167f8001553a916ef2f495d26a907cc54d96ed840d7bda71e73194bf5a9df7a76b9060405160405180910390a2505050565b33600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515610beb57600080fd5b81336001600083815260200190815260200160002060008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515610c5657600080fd5b8360008082815260200190815260200160002060030160009054906101000a900460ff16151515610c8657600080fd5b60006001600087815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550843373ffffffffffffffffffffffffffffffffffffffff167ff6a317157440607f36269043eb55f1287a5a19ba2216afeab88cd46cbcfb88e960405160405180910390a35050505050565b60026020528060005260406000206000915054906101000a900460ff1681565b60016020528160005260406000206020528060005260406000206000915091509054906101000a900460ff1681565b600080600090505b600554811015610e1457838015610dc8575060008082815260200190815260200160002060030160009054906101000a900460ff16155b80610dfb5750828015610dfa575060008082815260200190815260200160002060030160009054906101000a900460ff165b5b15610e07576001820191505b8080600101915050610d91565b5092915050565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610e5557600080fd5b80600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151515610eaf57600080fd5b8160008173ffffffffffffffffffffffffffffffffffffffff1614151515610ed657600080fd5b60016003805490500160045460328211158015610ef35750818111155b8015610f00575060008114155b8015610f0d575060008214155b1515610f1857600080fd5b6001600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555060038590806001815401808255809150509060018203906000526020600020016000909192909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550508473ffffffffffffffffffffffffffffffffffffffff167ff39e6e1eb0edcf53c221607b54b00cd28f3196fed0a24994dc308b8f611b682d60405160405180910390a25050505050565b6000806000809150600090505b6003805490508110156110fd5760016000858152602001908152602001600020600060038381548110151561105e57fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16156110dd576001820191505b6004548214156110f057600192506110fe565b808060010191505061102d565b5b5050919050565b600080600090505b6003805490508110156111ca5760016000848152602001908152602001600020600060038381548110151561113e57fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16156111bd576001820191505b808060010191505061110d565b50919050565b60006020528060005260406000206000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690806001015490806002018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156112a85780601f1061127d576101008083540402835291602001916112a8565b820191906000526020600020905b81548152906001019060200180831161128b57829003601f168201915b5050505050908060030160009054906101000a900460ff16905084565b6060600380548060200260200160405190810160405280929190818152602001828054801561134957602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190600101908083116112ff575b5050505050905090565b60608060008060055460405190808252806020026020018201604052801561138a5781602001602082028038833980820191505090505b50925060009150600090505b600554811015611436578580156113cd575060008082815260200190815260200160002060030160009054906101000a900460ff16155b8061140057508480156113ff575060008082815260200190815260200160002060030160009054906101000a900460ff165b5b156114295780838381518110151561141457fe5b90602001906020020181815250506001820191505b8080600101915050611396565b8787036040519080825280602002602001820160405280156114675781602001602082028038833980820191505090505b5093508790505b868110156114b957828181518110151561148457fe5b906020019060200201518489830381518110151561149e57fe5b9060200190602002018181525050808060010191505061146e565b505050949350505050565b6060806000806003805490506040519080825280602002602001820160405280156114fe5781602001602082028038833980820191505090505b50925060009150600090505b60038054905081101561164b5760016000868152602001908152602001600020600060038381548110151561153b57fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161561163e576003818154811015156115c257fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1683838151811015156115fb57fe5b9060200190602002019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250506001820191505b808060010191505061150a565b8160405190808252806020026020018201604052801561167a5781602001602082028038833980820191505090505b509350600090505b818110156116f957828181518110151561169857fe5b9060200190602002015184828151811015156116b057fe5b9060200190602002019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508080600101915050611682565b505050919050565b60055481565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561174157600080fd5b60038054905081603282111580156117595750818111155b8015611766575060008114155b8015611773575060008214155b151561177e57600080fd5b826004819055507fa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a836040518082815260200191505060405180910390a1505050565b33600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151561181a57600080fd5b81600080600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415151561187657600080fd5b82336001600083815260200190815260200160002060008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515156118e257600080fd5b600180600087815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550843373ffffffffffffffffffffffffffffffffffffffff167f4a504a94899432a9846e1aa406dceb1bcfd538bb839071d49d1e5e23f5be30ef60405160405180910390a361199785611cdd565b5050505050565b60006119ab848484611f85565b90506119b6816117c1565b9392505050565b603281565b60045481565b60003073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611a0457600080fd5b82600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515611a5d57600080fd5b82600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151515611ab757600080fd5b600092505b600380549050831015611ba0578473ffffffffffffffffffffffffffffffffffffffff16600384815481101515611aef57fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415611b935783600384815481101515611b4657fe5b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550611ba0565b8280600101935050611abc565b6000600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506001600260008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508473ffffffffffffffffffffffffffffffffffffffff167f8001553a916ef2f495d26a907cc54d96ed840d7bda71e73194bf5a9df7a76b9060405160405180910390a28373ffffffffffffffffffffffffffffffffffffffff167ff39e6e1eb0edcf53c221607b54b00cd28f3196fed0a24994dc308b8f611b682d60405160405180910390a25050505050565b600033600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515611d3857600080fd5b82336001600083815260200190815260200160002060008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515611da357600080fd5b8460008082815260200190815260200160002060030160009054906101000a900460ff16151515611dd357600080fd5b611ddc86611020565b15611f7d57600080878152602001908152602001600020945060018560030160006101000a81548160ff021916908315150217905550611efa8560000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16866001015487600201805460018160011615610100020316600290049050886002018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015611ef05780601f10611ec557610100808354040283529160200191611ef0565b820191906000526020600020905b815481529060010190602001808311611ed357829003601f168201915b50505050506120d7565b15611f3157857f33e13ecb54c3076d8e8bb8c2881800a4d972b792045ffae98fdf46df365fed7560405160405180910390a2611f7c565b857f526441bb6c1aba3c9a4a6ca1d6545da9c2333c8c48343ef398eb858d72b7923660405160405180910390a260008560030160006101000a81548160ff0219169083151502179055505b5b505050505050565b60008360008173ffffffffffffffffffffffffffffffffffffffff1614151515611fae57600080fd5b60055491506080604051908101604052808673ffffffffffffffffffffffffffffffffffffffff1681526020018581526020018481526020016000151581525060008084815260200190815260200160002060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160010155604082015181600201908051906020019061206d92919061212a565b5060608201518160030160006101000a81548160ff0219169083151502179055509050506001600560008282540192505081905550817fc0ba8fe4b176c1714197d43b9cc6bcf797a4a7461c5fe8d0ef6e184ae7601e5160405160405180910390a2509392505050565b6000806040516020840160008287838a8c6187965a03f19250505080915050949350505050565b8154818355818111156121255781836000526020600020918201910161212491906121aa565b5b505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061216b57805160ff1916838001178555612199565b82800160010185558215612199579182015b8281111561219857825182559160200191906001019061217d565b5b5090506121a691906121aa565b5090565b6121cc91905b808211156121c85760008160009055506001016121b0565b5090565b905600a165627a7a72305820b0d992f257e70d565448b927a3ae764342039a864112d5d5bb1ac1bd52e4104e00290000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000060000000000000000000000000cb1437200aea736788f1fc56f327c0456c3598d00000000000000000000000074dd76e24b2cfb43c1b1a4498295d553d0843746000000000000000000000000eeb4ceee443f9e0d17bdbd6daa241681ee5e51c2000000000000000000000000a005caea55375ae20e3aaef746113535503abc1900000000000000000000000090ae948bb410838bff9d024ed849df6a7267dacf000000000000000000000000740a5c5742833bed72489fe6bf7efc9b79428989" + }, + "0x1204700000000000000000000000000000000003": { + "constructor": "0x60806040523480156200001157600080fd5b50604051620024c8380380620024c883398101806040528101908080518201929190602001805190602001909291905050506000825182603282111580156200005a5750818111155b801562000068575060008114155b801562000076575060008214155b15156200008257600080fd5b600092505b8451831015620001bd57600260008685815181101515620000a457fe5b9060200190602002015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16158015620001335750600085848151811015156200011057fe5b9060200190602002015173ffffffffffffffffffffffffffffffffffffffff1614155b15156200013f57600080fd5b60016002600087868151811015156200015457fe5b9060200190602002015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550828060010193505062000087565b8460039080519060200190620001d5929190620001e8565b50836004819055505050505050620002bd565b82805482825590600052602060002090810192821562000264579160200282015b82811115620002635782518260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055509160200191906001019062000209565b5b50905062000273919062000277565b5090565b620002ba91905b80821115620002b657600081816101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055506001016200027e565b5090565b90565b6121fb80620002cd6000396000f30060806040526004361061011d576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063025e7c2714610177578063173825d9146101e457806320ea8d86146102275780632f54bf6e146102545780633411c81c146102af57806354741525146103145780637065cb4814610363578063784547a7146103a65780638b51d13f146103eb5780639ace38c21461042c578063a0e67e2b14610517578063a8abe69a14610583578063b5dc40c314610627578063b77bf600146106a9578063ba51a6df146106d4578063c01a8c8414610701578063c64274741461072e578063d74f8edd146107d5578063dc8452cd14610800578063e20056e61461082b578063ee22610b1461088e575b6000341115610175573373ffffffffffffffffffffffffffffffffffffffff167fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c346040518082815260200191505060405180910390a25b005b34801561018357600080fd5b506101a2600480360381019080803590602001909291905050506108bb565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156101f057600080fd5b50610225600480360381019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506108f9565b005b34801561023357600080fd5b5061025260048036038101908080359060200190929190505050610b92565b005b34801561026057600080fd5b50610295600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610d3a565b604051808215151515815260200191505060405180910390f35b3480156102bb57600080fd5b506102fa60048036038101908080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610d5a565b604051808215151515815260200191505060405180910390f35b34801561032057600080fd5b5061034d600480360381019080803515159060200190929190803515159060200190929190505050610d89565b6040518082815260200191505060405180910390f35b34801561036f57600080fd5b506103a4600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610e1b565b005b3480156103b257600080fd5b506103d160048036038101908080359060200190929190505050611020565b604051808215151515815260200191505060405180910390f35b3480156103f757600080fd5b5061041660048036038101908080359060200190929190505050611105565b6040518082815260200191505060405180910390f35b34801561043857600080fd5b50610457600480360381019080803590602001909291905050506111d0565b604051808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018481526020018060200183151515158152602001828103825284818151815260200191508051906020019080838360005b838110156104d95780820151818401526020810190506104be565b50505050905090810190601f1680156105065780820380516001836020036101000a031916815260200191505b509550505050505060405180910390f35b34801561052357600080fd5b5061052c6112c5565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b8381101561056f578082015181840152602081019050610554565b505050509050019250505060405180910390f35b34801561058f57600080fd5b506105d06004803603810190808035906020019092919080359060200190929190803515159060200190929190803515159060200190929190505050611353565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b838110156106135780820151818401526020810190506105f8565b505050509050019250505060405180910390f35b34801561063357600080fd5b50610652600480360381019080803590602001909291905050506114c4565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b8381101561069557808201518184015260208101905061067a565b505050509050019250505060405180910390f35b3480156106b557600080fd5b506106be611701565b6040518082815260200191505060405180910390f35b3480156106e057600080fd5b506106ff60048036038101908080359060200190929190505050611707565b005b34801561070d57600080fd5b5061072c600480360381019080803590602001909291905050506117c1565b005b34801561073a57600080fd5b506107bf600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050919291929050505061199e565b6040518082815260200191505060405180910390f35b3480156107e157600080fd5b506107ea6119bd565b6040518082815260200191505060405180910390f35b34801561080c57600080fd5b506108156119c2565b6040518082815260200191505060405180910390f35b34801561083757600080fd5b5061088c600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506119c8565b005b34801561089a57600080fd5b506108b960048036038101908080359060200190929190505050611cdd565b005b6003818154811015156108ca57fe5b906000526020600020016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60003073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561093557600080fd5b81600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151561098e57600080fd5b6000600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550600091505b600160038054905003821015610b13578273ffffffffffffffffffffffffffffffffffffffff16600383815481101515610a2157fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415610b06576003600160038054905003815481101515610a7f57fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600383815481101515610ab957fe5b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550610b13565b81806001019250506109eb565b6001600381818054905003915081610b2b91906120fe565b506003805490506004541115610b4a57610b49600380549050611707565b5b8273ffffffffffffffffffffffffffffffffffffffff167f8001553a916ef2f495d26a907cc54d96ed840d7bda71e73194bf5a9df7a76b9060405160405180910390a2505050565b33600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515610beb57600080fd5b81336001600083815260200190815260200160002060008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515610c5657600080fd5b8360008082815260200190815260200160002060030160009054906101000a900460ff16151515610c8657600080fd5b60006001600087815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550843373ffffffffffffffffffffffffffffffffffffffff167ff6a317157440607f36269043eb55f1287a5a19ba2216afeab88cd46cbcfb88e960405160405180910390a35050505050565b60026020528060005260406000206000915054906101000a900460ff1681565b60016020528160005260406000206020528060005260406000206000915091509054906101000a900460ff1681565b600080600090505b600554811015610e1457838015610dc8575060008082815260200190815260200160002060030160009054906101000a900460ff16155b80610dfb5750828015610dfa575060008082815260200190815260200160002060030160009054906101000a900460ff165b5b15610e07576001820191505b8080600101915050610d91565b5092915050565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610e5557600080fd5b80600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151515610eaf57600080fd5b8160008173ffffffffffffffffffffffffffffffffffffffff1614151515610ed657600080fd5b60016003805490500160045460328211158015610ef35750818111155b8015610f00575060008114155b8015610f0d575060008214155b1515610f1857600080fd5b6001600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555060038590806001815401808255809150509060018203906000526020600020016000909192909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550508473ffffffffffffffffffffffffffffffffffffffff167ff39e6e1eb0edcf53c221607b54b00cd28f3196fed0a24994dc308b8f611b682d60405160405180910390a25050505050565b6000806000809150600090505b6003805490508110156110fd5760016000858152602001908152602001600020600060038381548110151561105e57fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16156110dd576001820191505b6004548214156110f057600192506110fe565b808060010191505061102d565b5b5050919050565b600080600090505b6003805490508110156111ca5760016000848152602001908152602001600020600060038381548110151561113e57fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16156111bd576001820191505b808060010191505061110d565b50919050565b60006020528060005260406000206000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690806001015490806002018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156112a85780601f1061127d576101008083540402835291602001916112a8565b820191906000526020600020905b81548152906001019060200180831161128b57829003601f168201915b5050505050908060030160009054906101000a900460ff16905084565b6060600380548060200260200160405190810160405280929190818152602001828054801561134957602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190600101908083116112ff575b5050505050905090565b60608060008060055460405190808252806020026020018201604052801561138a5781602001602082028038833980820191505090505b50925060009150600090505b600554811015611436578580156113cd575060008082815260200190815260200160002060030160009054906101000a900460ff16155b8061140057508480156113ff575060008082815260200190815260200160002060030160009054906101000a900460ff165b5b156114295780838381518110151561141457fe5b90602001906020020181815250506001820191505b8080600101915050611396565b8787036040519080825280602002602001820160405280156114675781602001602082028038833980820191505090505b5093508790505b868110156114b957828181518110151561148457fe5b906020019060200201518489830381518110151561149e57fe5b9060200190602002018181525050808060010191505061146e565b505050949350505050565b6060806000806003805490506040519080825280602002602001820160405280156114fe5781602001602082028038833980820191505090505b50925060009150600090505b60038054905081101561164b5760016000868152602001908152602001600020600060038381548110151561153b57fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161561163e576003818154811015156115c257fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1683838151811015156115fb57fe5b9060200190602002019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250506001820191505b808060010191505061150a565b8160405190808252806020026020018201604052801561167a5781602001602082028038833980820191505090505b509350600090505b818110156116f957828181518110151561169857fe5b9060200190602002015184828151811015156116b057fe5b9060200190602002019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508080600101915050611682565b505050919050565b60055481565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561174157600080fd5b60038054905081603282111580156117595750818111155b8015611766575060008114155b8015611773575060008214155b151561177e57600080fd5b826004819055507fa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a836040518082815260200191505060405180910390a1505050565b33600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151561181a57600080fd5b81600080600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415151561187657600080fd5b82336001600083815260200190815260200160002060008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515156118e257600080fd5b600180600087815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550843373ffffffffffffffffffffffffffffffffffffffff167f4a504a94899432a9846e1aa406dceb1bcfd538bb839071d49d1e5e23f5be30ef60405160405180910390a361199785611cdd565b5050505050565b60006119ab848484611f85565b90506119b6816117c1565b9392505050565b603281565b60045481565b60003073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611a0457600080fd5b82600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515611a5d57600080fd5b82600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151515611ab757600080fd5b600092505b600380549050831015611ba0578473ffffffffffffffffffffffffffffffffffffffff16600384815481101515611aef57fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415611b935783600384815481101515611b4657fe5b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550611ba0565b8280600101935050611abc565b6000600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506001600260008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508473ffffffffffffffffffffffffffffffffffffffff167f8001553a916ef2f495d26a907cc54d96ed840d7bda71e73194bf5a9df7a76b9060405160405180910390a28373ffffffffffffffffffffffffffffffffffffffff167ff39e6e1eb0edcf53c221607b54b00cd28f3196fed0a24994dc308b8f611b682d60405160405180910390a25050505050565b600033600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515611d3857600080fd5b82336001600083815260200190815260200160002060008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515611da357600080fd5b8460008082815260200190815260200160002060030160009054906101000a900460ff16151515611dd357600080fd5b611ddc86611020565b15611f7d57600080878152602001908152602001600020945060018560030160006101000a81548160ff021916908315150217905550611efa8560000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16866001015487600201805460018160011615610100020316600290049050886002018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015611ef05780601f10611ec557610100808354040283529160200191611ef0565b820191906000526020600020905b815481529060010190602001808311611ed357829003601f168201915b50505050506120d7565b15611f3157857f33e13ecb54c3076d8e8bb8c2881800a4d972b792045ffae98fdf46df365fed7560405160405180910390a2611f7c565b857f526441bb6c1aba3c9a4a6ca1d6545da9c2333c8c48343ef398eb858d72b7923660405160405180910390a260008560030160006101000a81548160ff0219169083151502179055505b5b505050505050565b60008360008173ffffffffffffffffffffffffffffffffffffffff1614151515611fae57600080fd5b60055491506080604051908101604052808673ffffffffffffffffffffffffffffffffffffffff1681526020018581526020018481526020016000151581525060008084815260200190815260200160002060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160010155604082015181600201908051906020019061206d92919061212a565b5060608201518160030160006101000a81548160ff0219169083151502179055509050506001600560008282540192505081905550817fc0ba8fe4b176c1714197d43b9cc6bcf797a4a7461c5fe8d0ef6e184ae7601e5160405160405180910390a2509392505050565b6000806040516020840160008287838a8c6187965a03f19250505080915050949350505050565b8154818355818111156121255781836000526020600020918201910161212491906121aa565b5b505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061216b57805160ff1916838001178555612199565b82800160010185558215612199579182015b8281111561219857825182559160200191906001019061217d565b5b5090506121a691906121aa565b5090565b6121cc91905b808211156121c85760008160009055506001016121b0565b5090565b905600a165627a7a72305820b0d992f257e70d565448b927a3ae764342039a864112d5d5bb1ac1bd52e4104e00290000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000060000000000000000000000000cb1437200aea736788f1fc56f327c0456c3598d00000000000000000000000074dd76e24b2cfb43c1b1a4498295d553d0843746000000000000000000000000eeb4ceee443f9e0d17bdbd6daa241681ee5e51c2000000000000000000000000a005caea55375ae20e3aaef746113535503abc1900000000000000000000000090ae948bb410838bff9d024ed849df6a7267dacf000000000000000000000000740a5c5742833bed72489fe6bf7efc9b79428989" + }, + "0x120470000000000000000000000000000000000a": { + "balance": "10901790566666700000000000", + "constructor": "0x60806040523480156200001157600080fd5b50604051620024c8380380620024c883398101806040528101908080518201929190602001805190602001909291905050506000825182603282111580156200005a5750818111155b801562000068575060008114155b801562000076575060008214155b15156200008257600080fd5b600092505b8451831015620001bd57600260008685815181101515620000a457fe5b9060200190602002015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16158015620001335750600085848151811015156200011057fe5b9060200190602002015173ffffffffffffffffffffffffffffffffffffffff1614155b15156200013f57600080fd5b60016002600087868151811015156200015457fe5b9060200190602002015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550828060010193505062000087565b8460039080519060200190620001d5929190620001e8565b50836004819055505050505050620002bd565b82805482825590600052602060002090810192821562000264579160200282015b82811115620002635782518260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055509160200191906001019062000209565b5b50905062000273919062000277565b5090565b620002ba91905b80821115620002b657600081816101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055506001016200027e565b5090565b90565b6121fb80620002cd6000396000f30060806040526004361061011d576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063025e7c2714610177578063173825d9146101e457806320ea8d86146102275780632f54bf6e146102545780633411c81c146102af57806354741525146103145780637065cb4814610363578063784547a7146103a65780638b51d13f146103eb5780639ace38c21461042c578063a0e67e2b14610517578063a8abe69a14610583578063b5dc40c314610627578063b77bf600146106a9578063ba51a6df146106d4578063c01a8c8414610701578063c64274741461072e578063d74f8edd146107d5578063dc8452cd14610800578063e20056e61461082b578063ee22610b1461088e575b6000341115610175573373ffffffffffffffffffffffffffffffffffffffff167fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c346040518082815260200191505060405180910390a25b005b34801561018357600080fd5b506101a2600480360381019080803590602001909291905050506108bb565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156101f057600080fd5b50610225600480360381019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506108f9565b005b34801561023357600080fd5b5061025260048036038101908080359060200190929190505050610b92565b005b34801561026057600080fd5b50610295600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610d3a565b604051808215151515815260200191505060405180910390f35b3480156102bb57600080fd5b506102fa60048036038101908080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610d5a565b604051808215151515815260200191505060405180910390f35b34801561032057600080fd5b5061034d600480360381019080803515159060200190929190803515159060200190929190505050610d89565b6040518082815260200191505060405180910390f35b34801561036f57600080fd5b506103a4600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610e1b565b005b3480156103b257600080fd5b506103d160048036038101908080359060200190929190505050611020565b604051808215151515815260200191505060405180910390f35b3480156103f757600080fd5b5061041660048036038101908080359060200190929190505050611105565b6040518082815260200191505060405180910390f35b34801561043857600080fd5b50610457600480360381019080803590602001909291905050506111d0565b604051808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018481526020018060200183151515158152602001828103825284818151815260200191508051906020019080838360005b838110156104d95780820151818401526020810190506104be565b50505050905090810190601f1680156105065780820380516001836020036101000a031916815260200191505b509550505050505060405180910390f35b34801561052357600080fd5b5061052c6112c5565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b8381101561056f578082015181840152602081019050610554565b505050509050019250505060405180910390f35b34801561058f57600080fd5b506105d06004803603810190808035906020019092919080359060200190929190803515159060200190929190803515159060200190929190505050611353565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b838110156106135780820151818401526020810190506105f8565b505050509050019250505060405180910390f35b34801561063357600080fd5b50610652600480360381019080803590602001909291905050506114c4565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b8381101561069557808201518184015260208101905061067a565b505050509050019250505060405180910390f35b3480156106b557600080fd5b506106be611701565b6040518082815260200191505060405180910390f35b3480156106e057600080fd5b506106ff60048036038101908080359060200190929190505050611707565b005b34801561070d57600080fd5b5061072c600480360381019080803590602001909291905050506117c1565b005b34801561073a57600080fd5b506107bf600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050919291929050505061199e565b6040518082815260200191505060405180910390f35b3480156107e157600080fd5b506107ea6119bd565b6040518082815260200191505060405180910390f35b34801561080c57600080fd5b506108156119c2565b6040518082815260200191505060405180910390f35b34801561083757600080fd5b5061088c600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506119c8565b005b34801561089a57600080fd5b506108b960048036038101908080359060200190929190505050611cdd565b005b6003818154811015156108ca57fe5b906000526020600020016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60003073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561093557600080fd5b81600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151561098e57600080fd5b6000600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550600091505b600160038054905003821015610b13578273ffffffffffffffffffffffffffffffffffffffff16600383815481101515610a2157fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415610b06576003600160038054905003815481101515610a7f57fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600383815481101515610ab957fe5b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550610b13565b81806001019250506109eb565b6001600381818054905003915081610b2b91906120fe565b506003805490506004541115610b4a57610b49600380549050611707565b5b8273ffffffffffffffffffffffffffffffffffffffff167f8001553a916ef2f495d26a907cc54d96ed840d7bda71e73194bf5a9df7a76b9060405160405180910390a2505050565b33600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515610beb57600080fd5b81336001600083815260200190815260200160002060008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515610c5657600080fd5b8360008082815260200190815260200160002060030160009054906101000a900460ff16151515610c8657600080fd5b60006001600087815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550843373ffffffffffffffffffffffffffffffffffffffff167ff6a317157440607f36269043eb55f1287a5a19ba2216afeab88cd46cbcfb88e960405160405180910390a35050505050565b60026020528060005260406000206000915054906101000a900460ff1681565b60016020528160005260406000206020528060005260406000206000915091509054906101000a900460ff1681565b600080600090505b600554811015610e1457838015610dc8575060008082815260200190815260200160002060030160009054906101000a900460ff16155b80610dfb5750828015610dfa575060008082815260200190815260200160002060030160009054906101000a900460ff165b5b15610e07576001820191505b8080600101915050610d91565b5092915050565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610e5557600080fd5b80600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151515610eaf57600080fd5b8160008173ffffffffffffffffffffffffffffffffffffffff1614151515610ed657600080fd5b60016003805490500160045460328211158015610ef35750818111155b8015610f00575060008114155b8015610f0d575060008214155b1515610f1857600080fd5b6001600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555060038590806001815401808255809150509060018203906000526020600020016000909192909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550508473ffffffffffffffffffffffffffffffffffffffff167ff39e6e1eb0edcf53c221607b54b00cd28f3196fed0a24994dc308b8f611b682d60405160405180910390a25050505050565b6000806000809150600090505b6003805490508110156110fd5760016000858152602001908152602001600020600060038381548110151561105e57fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16156110dd576001820191505b6004548214156110f057600192506110fe565b808060010191505061102d565b5b5050919050565b600080600090505b6003805490508110156111ca5760016000848152602001908152602001600020600060038381548110151561113e57fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16156111bd576001820191505b808060010191505061110d565b50919050565b60006020528060005260406000206000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690806001015490806002018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156112a85780601f1061127d576101008083540402835291602001916112a8565b820191906000526020600020905b81548152906001019060200180831161128b57829003601f168201915b5050505050908060030160009054906101000a900460ff16905084565b6060600380548060200260200160405190810160405280929190818152602001828054801561134957602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190600101908083116112ff575b5050505050905090565b60608060008060055460405190808252806020026020018201604052801561138a5781602001602082028038833980820191505090505b50925060009150600090505b600554811015611436578580156113cd575060008082815260200190815260200160002060030160009054906101000a900460ff16155b8061140057508480156113ff575060008082815260200190815260200160002060030160009054906101000a900460ff165b5b156114295780838381518110151561141457fe5b90602001906020020181815250506001820191505b8080600101915050611396565b8787036040519080825280602002602001820160405280156114675781602001602082028038833980820191505090505b5093508790505b868110156114b957828181518110151561148457fe5b906020019060200201518489830381518110151561149e57fe5b9060200190602002018181525050808060010191505061146e565b505050949350505050565b6060806000806003805490506040519080825280602002602001820160405280156114fe5781602001602082028038833980820191505090505b50925060009150600090505b60038054905081101561164b5760016000868152602001908152602001600020600060038381548110151561153b57fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161561163e576003818154811015156115c257fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1683838151811015156115fb57fe5b9060200190602002019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250506001820191505b808060010191505061150a565b8160405190808252806020026020018201604052801561167a5781602001602082028038833980820191505090505b509350600090505b818110156116f957828181518110151561169857fe5b9060200190602002015184828151811015156116b057fe5b9060200190602002019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508080600101915050611682565b505050919050565b60055481565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561174157600080fd5b60038054905081603282111580156117595750818111155b8015611766575060008114155b8015611773575060008214155b151561177e57600080fd5b826004819055507fa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a836040518082815260200191505060405180910390a1505050565b33600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151561181a57600080fd5b81600080600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415151561187657600080fd5b82336001600083815260200190815260200160002060008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515156118e257600080fd5b600180600087815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550843373ffffffffffffffffffffffffffffffffffffffff167f4a504a94899432a9846e1aa406dceb1bcfd538bb839071d49d1e5e23f5be30ef60405160405180910390a361199785611cdd565b5050505050565b60006119ab848484611f85565b90506119b6816117c1565b9392505050565b603281565b60045481565b60003073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611a0457600080fd5b82600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515611a5d57600080fd5b82600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151515611ab757600080fd5b600092505b600380549050831015611ba0578473ffffffffffffffffffffffffffffffffffffffff16600384815481101515611aef57fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415611b935783600384815481101515611b4657fe5b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550611ba0565b8280600101935050611abc565b6000600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506001600260008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508473ffffffffffffffffffffffffffffffffffffffff167f8001553a916ef2f495d26a907cc54d96ed840d7bda71e73194bf5a9df7a76b9060405160405180910390a28373ffffffffffffffffffffffffffffffffffffffff167ff39e6e1eb0edcf53c221607b54b00cd28f3196fed0a24994dc308b8f611b682d60405160405180910390a25050505050565b600033600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515611d3857600080fd5b82336001600083815260200190815260200160002060008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515611da357600080fd5b8460008082815260200190815260200160002060030160009054906101000a900460ff16151515611dd357600080fd5b611ddc86611020565b15611f7d57600080878152602001908152602001600020945060018560030160006101000a81548160ff021916908315150217905550611efa8560000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16866001015487600201805460018160011615610100020316600290049050886002018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015611ef05780601f10611ec557610100808354040283529160200191611ef0565b820191906000526020600020905b815481529060010190602001808311611ed357829003601f168201915b50505050506120d7565b15611f3157857f33e13ecb54c3076d8e8bb8c2881800a4d972b792045ffae98fdf46df365fed7560405160405180910390a2611f7c565b857f526441bb6c1aba3c9a4a6ca1d6545da9c2333c8c48343ef398eb858d72b7923660405160405180910390a260008560030160006101000a81548160ff0219169083151502179055505b5b505050505050565b60008360008173ffffffffffffffffffffffffffffffffffffffff1614151515611fae57600080fd5b60055491506080604051908101604052808673ffffffffffffffffffffffffffffffffffffffff1681526020018581526020018481526020016000151581525060008084815260200190815260200160002060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160010155604082015181600201908051906020019061206d92919061212a565b5060608201518160030160006101000a81548160ff0219169083151502179055509050506001600560008282540192505081905550817fc0ba8fe4b176c1714197d43b9cc6bcf797a4a7461c5fe8d0ef6e184ae7601e5160405160405180910390a2509392505050565b6000806040516020840160008287838a8c6187965a03f19250505080915050949350505050565b8154818355818111156121255781836000526020600020918201910161212491906121aa565b5b505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061216b57805160ff1916838001178555612199565b82800160010185558215612199579182015b8281111561219857825182559160200191906001019061217d565b5b5090506121a691906121aa565b5090565b6121cc91905b808211156121c85760008160009055506001016121b0565b5090565b905600a165627a7a72305820b0d992f257e70d565448b927a3ae764342039a864112d5d5bb1ac1bd52e4104e00290000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000060000000000000000000000000cb1437200aea736788f1fc56f327c0456c3598d00000000000000000000000074dd76e24b2cfb43c1b1a4498295d553d0843746000000000000000000000000eeb4ceee443f9e0d17bdbd6daa241681ee5e51c2000000000000000000000000a005caea55375ae20e3aaef746113535503abc1900000000000000000000000090ae948bb410838bff9d024ed849df6a7267dacf000000000000000000000000740a5c5742833bed72489fe6bf7efc9b79428989" + }, + "0x0cB1437200aea736788f1Fc56F327c0456c3598D": { + "balance": "250000000000000000" + }, + "0x74dd76E24B2CFB43C1b1a4498295d553D0843746": { + "balance": "250000000000000000" + }, + "0xeeB4CEEe443F9e0D17BdBD6Daa241681EE5E51c2": { + "balance": "250000000000000000" + }, + "0xA005caEa55375ae20e3aAEF746113535503ABC19": { + "balance": "250000000000000000" + }, + "0x90ae948bB410838bff9D024ed849dF6A7267Dacf": { + "balance": "250000000000000000" + }, + "0x740a5C5742833bEd72489fE6bf7EFc9B79428989": { + "balance": "250000000000000000" + }, + "0x1204700000000000000000000000000000000001": { + "constructor": "0x60806040523480156200001157600080fd5b5060405162002d7138038062002d71833981018060405260608110156200003757600080fd5b81019080805190602001909291908051906020019092919080516401000000008111156200006457600080fd5b828101905060208101848111156200007b57600080fd5b81518560208202830111640100000000821117156200009957600080fd5b5050929190505050336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415620001e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602481526020018062002d216024913960400191505060405180910390fd5b60018151101562000242576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c81526020018062002d45602c913960400191505060405180910390fd5b62000253836200046160201b60201c565b6200026482620005c360201b60201c565b60008090505b81518110156200040e57600073ffffffffffffffffffffffffffffffffffffffff168282815181106200029957fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614156200032c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f56616c696461746f7220616464726573732063616e6e6f74206265203078300081525060200191505060405180910390fd5b6001600360008484815181106200033f57fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160006101000a81548160ff02191690836003811115620003a057fe5b02179055508060036000848481518110620003b757fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001018190555080806001019150506200026a565b508060029080519060200190620004279291906200064a565b50600260019080546200043c929190620006d9565b506001600060146101000a81548160ff02191690831515021790555050505062000776565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141562000505576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f4e6577206f776e657220616464726573732063616e6e6f74206265203078300081525060200191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b80600560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167fe8ec518081a7aa1fc5d586a5443a858ab130be8b8e39b545172c879a7e242c6b60405160405180910390a250565b828054828255906000526020600020908101928215620006c6579160200282015b82811115620006c55782518260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550916020019190600101906200066b565b5b509050620006d5919062000730565b5090565b8280548282559060005260206000209081019282156200071d5760005260206000209182015b828111156200071c578254825591600101919060010190620006ff565b5b5090506200072c919062000730565b5090565b6200077391905b808211156200076f57600081816101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555060010162000737565b5090565b90565b61259b80620007866000396000f3fe608060405234801561001057600080fd5b50600436106101375760003560e01c80639f723637116100b8578063b98049091161007c578063b980490914610562578063bd21442a146105be578063c805f68b14610681578063d826b7f1146106c5578063f2fde38b14610733578063f3aeac021461077757610137565b80639f723637146103dc578063a00745b61461043b578063a6940b0714610497578063b3f05b97146104e1578063b7ab4db51461050357610137565b8063455701d6116100ff578063455701d6146102c35780634d238c8e1461032257806375286211146103665780638da5cb5b146103705780638f32d59b146103ba57610137565b8063267fa41d1461013c57806334ba3c1b1461019857806340550a1c146101b657806340a141ff146102125780634183495514610256575b600080fd5b61017e6004803603602081101561015257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506107d3565b604051808215151515815260200191505060405180910390f35b6101a0610845565b6040518082815260200191505060405180910390f35b6101f8600480360360208110156101cc57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610852565b604051808215151515815260200191505060405180910390f35b6102546004803603602081101561022857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610933565b005b6102986004803603602081101561026c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610a7e565b604051808360038111156102a857fe5b60ff1681526020018281526020019250505060405180910390f35b6102cb610aaf565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b8381101561030e5780820151818401526020810190506102f3565b505050509050019250505060405180910390f35b6103646004803603602081101561033857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610b3d565b005b61036e610d47565b005b6103786111b2565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6103c26111db565b604051808215151515815260200191505060405180910390f35b6103e4611232565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b8381101561042757808201518184015260208101905061040c565b505050509050019250505060405180910390f35b61047d6004803603602081101561045157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611361565b604051808215151515815260200191505060405180910390f35b61049f611442565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6104e9611468565b604051808215151515815260200191505060405180910390f35b61050b61147b565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b8381101561054e578082015181840152602081019050610533565b505050509050019250505060405180910390f35b6105a46004803603602081101561057857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611509565b604051808215151515815260200191505060405180910390f35b61067f600480360360808110156105d457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561063b57600080fd5b82018360208201111561064d57600080fd5b8035906020019184600183028401116401000000008311171561066f57600080fd5b909192939192939050505061157a565b005b6106c36004803603602081101561069757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506117d6565b005b610731600480360360608110156106db57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611989565b005b6107756004803603602081101561074957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611be3565b005b6107b96004803603602081101561078d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611c69565b604051808215151515815260200191505060405180910390f35b6000600160038111156107e257fe5b600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff16600381111561083d57fe5b149050919050565b6000600180549050905090565b60006001600381111561086157fe5b600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff1660038111156108bc57fe5b148061092c57506003808111156108cf57fe5b600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff16600381111561092a57fe5b145b9050919050565b61093b6111db565b6109ad576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f53656e646572206973206e6f74206f776e65720000000000000000000000000081525060200191505060405180910390fd5b600060149054906101000a900460ff16610a12576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806124e16022913960400191505060405180910390fd5b80610a1c81610852565b610a71576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806124bf6022913960400191505060405180910390fd5b610a7a82611cdb565b5050565b60036020528060005260406000206000915090508060000160009054906101000a900460ff16908060010154905082565b60606002805480602002602001604051908101604052809291908181526020018280548015610b3357602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311610ae9575b5050505050905090565b610b456111db565b610bb7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f53656e646572206973206e6f74206f776e65720000000000000000000000000081525060200191505060405180910390fd5b600060149054906101000a900460ff16610c1c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806124e16022913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610cbf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f56616c696461746f7220616464726573732063616e6e6f74206265203078300081525060200191505060405180910390fd5b610cc881610852565b15610d3b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f546869732076616c696461746f7220697320616c72656164792061637469766581525060200191505060405180910390fd5b610d4481611f2e565b50565b600060149054906101000a900460ff1615610dca576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f56616c696461746f72207365742069732066696e616c697a656400000000000081525060200191505060405180910390fd5b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610e8d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f43616c6c6572206973206e6f74207468652052656c617920636f6e747261637481525060200191505060405180910390fd5b6001600060146101000a81548160ff021916908315150217905550600073ffffffffffffffffffffffffffffffffffffffff16600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415610fbe57600060036000600260016002805490500381548110610f1a57fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905060018160000160006101000a81548160ff02191690836003811115610fa257fe5b02179055506001600280549050038160010181905550506110f1565b600060036000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160006101000a81548160ff0219169083600381111561103f57fe5b0217905550600060036000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101819055506000600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b6002600190805461110392919061238d565b507f8564cd629b15f47dc310d45bcbfc9bcf5420b0d51bf0659a16c67f91d27632536001604051808060200182810382528381815481526020019150805480156111a257602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311611158575b50509250505060405180910390a1565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614905090565b606060018054905060028054905011156112d45760028054806020026020016040519081016040528092919081815260200182805480156112c857602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001906001019080831161127e575b5050505050905061135e565b600180548060200260200160405190810160405280929190818152602001828054801561135657602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001906001019080831161130c575b505050505090505b90565b60006002600381111561137057fe5b600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff1660038111156113cb57fe5b148061143b57506003808111156113de57fe5b600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff16600381111561143957fe5b145b9050919050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600060149054906101000a900460ff1681565b606060018054806020026020016040519081016040528092919081815260200182805480156114ff57602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190600101908083116114b5575b5050505050905090565b600060038081111561151757fe5b600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff16600381111561157257fe5b149050919050565b8461158481610852565b6115d9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806124bf6022913960400191505060405180910390fd5b846115e381610852565b611638576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806124bf6022913960400191505060405180910390fd5b844381106116ae576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f426c6f636b206e756d626572206973206e6f742076616c69640000000000000081525060200191505060405180910390fd5b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611771576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f43616c6c6572206973206e6f74207468652052656c617920636f6e747261637481525060200191505060405180910390fd5b858773ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff167f729a19138e072a5a8d3a56d74ae0b5c84530f09aacd6e12b24c5b2fdc3f8a3d060405160405180910390a45050505050505050565b6117de6111db565b611850576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f53656e646572206973206e6f74206f776e65720000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156118d6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260248152602001806124746024913960400191505060405180910390fd5b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561197d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260408152602001806125036040913960400191505060405180910390fd5b61198681612003565b50565b8261199381610852565b6119e8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806124bf6022913960400191505060405180910390fd5b826119f281610852565b611a47576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806124bf6022913960400191505060405180910390fd5b82438110611abd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f426c6f636b206e756d626572206973206e6f742076616c69640000000000000081525060200191505060405180910390fd5b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611b80576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f43616c6c6572206973206e6f74207468652052656c617920636f6e747261637481525060200191505060405180910390fd5b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fbc459bd9db54016b1966d0fe812bbe0a82cd627ae3eacd01727dc63a432ca41b60405160405180910390a4505050505050565b611beb6111db565b611c5d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f53656e646572206973206e6f74206f776e65720000000000000000000000000081525060200191505060405180910390fd5b611c668161208a565b50565b600060026003811115611c7857fe5b600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff166003811115611cd357fe5b149050919050565b600160028054905011611d39576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260278152602001806124986027913960400191505060405180910390fd5b6000600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010154905060006001600280549050039050600060028281548110611d9c57fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508060028481548110611dd757fe5b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555082600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101819055506002805480919060019003611e7b91906123df565b5060038060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160006101000a81548160ff02191690836003811115611eda57fe5b021790555083600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550611f286121eb565b50505050565b6002600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160006101000a81548160ff02191690836003811115611f8d57fe5b021790555060028190806001815401808255809150509060018203906000526020600020016000909192909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550506120006121eb565b50565b80600560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167fe8ec518081a7aa1fc5d586a5443a858ab130be8b8e39b545172c879a7e242c6b60405160405180910390a250565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561212d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f4e6577206f776e657220616464726573732063616e6e6f74206265203078300081525060200191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60008060146101000a81548160ff021916908315150217905550600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a084718a600143034060026040518363ffffffff1660e01b8152600401808381526020018060200182810382528381815481526020019150805480156122da57602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311612290575b50509350505050602060405180830381600087803b1580156122fb57600080fd5b505af115801561230f573d6000803e3d6000fd5b505050506040513d602081101561232557600080fd5b810190808051906020019092919050505061238b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602d815260200180612543602d913960400191505060405180910390fd5b565b8280548282559060005260206000209081019282156123ce5760005260206000209182015b828111156123cd5782548255916001019190600101906123b2565b5b5090506123db919061240b565b5090565b81548183558181111561240657818360005260206000209182019101612405919061244e565b5b505050565b61244b91905b8082111561244757600081816101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905550600101612411565b5090565b90565b61247091905b8082111561246c576000816000905550600101612454565b5090565b9056fe52656c617920636f6e747261637420616464726573732063616e6e6f74206265203078305468657265206d757374206265206174206c6561737420312076616c696461746f72206c65667441646472657373206973206e6f7420616e206163746976652076616c696461746f7256616c696461746f7220736574206973206e6f742066696e616c697a6564207965744e65772072656c617920636f6e747261637420616464726573732063616e6e6f74206265207468652073616d65206173207468652063757272656e74206f6e6552656c617920636f6e747261637420496e6974696174654368616e67652063616c6c6261636b206661696c6564a165627a7a72305820f9ae418c0431b0892a4b904426be15d82d8486d433a3d6b9814bd5d1a377bb30002952656c617920636f6e747261637420616464726573732063616e6e6f74206265203078305468657265206d757374206265206174206c6561737420312076616c696461746f7220696e697469616c6c790000000000000000000000001204700000000000000000000000000000000005000000000000000000000000120470000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000003000000000000000000000000d65b4c25a4ce1e024ff13425df1e0e574a1a0e9b00000000000000000000000083329c3fd90d7ee2efd546e0dc6453e9172a0643000000000000000000000000de15831ac319dab5eae5fd1fd9d52876c5e50f20" + }, + "0x1204700000000000000000000000000000000000": { + "constructor": "0x608060405273fffffffffffffffffffffffffffffffffffffffe600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555034801561006557600080fd5b506040516040806114d48339810180604052604081101561008557600080fd5b810190808051906020019092919080519060200190929190505050336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a361016b8261018160201b60201c565b61017a816102e260201b60201c565b50506104f4565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610224576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f4e6577206f776e657220616464726573732063616e6e6f74206265203078300081525060200191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b80600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610386576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260158152602001807f416464726573732063616e6e6f7420626520307830000000000000000000000081525060200191505060405180910390fd5b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561042d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260428152602001806114926042913960600191505060405180910390fd5b6000600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905082600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f4fea88aaf04c303804bb211ecc32a00ac8e5f0656bb854cad8a4a2e438256b7460405160405180910390a3505050565b610f8f806105036000396000f3fe608060405234801561001057600080fd5b50600436106100a95760003560e01c8063b7ab4db511610071578063b7ab4db514610209578063bd96567714610268578063c476dd40146102ac578063d3e848f11461034f578063d69f13bb14610399578063f2fde38b146103e7576100a9565b806375286211146100ae5780638da5cb5b146100b85780638f32d59b14610102578063a084718a14610124578063ae3783d6146101bf575b600080fd5b6100b661042b565b005b6100c0610572565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61010a61059b565b604051808215151515815260200191505060405180910390f35b6101a56004803603604081101561013a57600080fd5b81019080803590602001909291908035906020019064010000000081111561016157600080fd5b82018360208201111561017357600080fd5b8035906020019184602083028401116401000000008311171561019557600080fd5b90919293919293905050506105f2565b604051808215151515815260200191505060405180910390f35b6101c761070c565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610211610732565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b83811015610254578082015181840152602081019050610239565b505050509050019250505060405180910390f35b6102aa6004803603602081101561027e57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610832565b005b61034d600480360360608110156102c257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561030957600080fd5b82018360208201111561031b57600080fd5b8035906020019184600183028401116401000000008311171561033d57600080fd5b90919293919293905050506108b8565b005b6103576109e7565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6103e5600480360360408110156103af57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610a0d565b005b610429600480360360208110156103fd57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610b06565b005b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146104ee576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f53656e646572206973206e6f742073797374656d00000000000000000000000081525060200191505060405180910390fd5b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663752862116040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561055857600080fd5b505af115801561056c573d6000803e3d6000fd5b50505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614905090565b6000600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461069a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180610f426022913960400191505060405180910390fd5b837f55252fa6eee4741b4e24a74a70e9c11fd2c2281df8d6ea13126ff845f7825c89848460405180806020018281038252848482818152602001925060200280828437600081840152601f19601f820116905080830192505050935050505060405180910390a2600190509392505050565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6060600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b7ab4db56040518163ffffffff1660e01b815260040160006040518083038186803b15801561079c57600080fd5b505afa1580156107b0573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525060208110156107da57600080fd5b8101908080516401000000008111156107f257600080fd5b8281019050602081018481111561080857600080fd5b815185602082028301116401000000008211171561082557600080fd5b5050929190505050905090565b61083a61059b565b6108ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f53656e646572206973206e6f74206f776e65720000000000000000000000000081525060200191505060405180910390fd5b6108b581610b8c565b50565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bd21442a33868686866040518663ffffffff1660e01b8152600401808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001848152602001806020018281038252848482818152602001925080828437600081840152601f19601f8201169050808301925050509650505050505050600060405180830381600087803b1580156109c957600080fd5b505af11580156109dd573d6000803e3d6000fd5b5050505050505050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d826b7f13384846040518463ffffffff1660e01b8152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050600060405180830381600087803b158015610aea57600080fd5b505af1158015610afe573d6000803e3d6000fd5b505050505050565b610b0e61059b565b610b80576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f53656e646572206973206e6f74206f776e65720000000000000000000000000081525060200191505060405180910390fd5b610b8981610d9e565b50565b80600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610c30576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260158152602001807f416464726573732063616e6e6f7420626520307830000000000000000000000081525060200191505060405180910390fd5b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610cd7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526042815260200180610f006042913960600191505060405180910390fd5b6000600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905082600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f4fea88aaf04c303804bb211ecc32a00ac8e5f0656bb854cad8a4a2e438256b7460405160405180910390a3505050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610e41576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f4e6577206f776e657220616464726573732063616e6e6f74206265203078300081525060200191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505056fe4e65772072656c6179656420636f6e747261637420616464726573732063616e6e6f74206265207468652073616d65206173207468652063757272656e74206f6e6553656e646572206973206e6f74207468652052656c6179656420636f6e7472616374a165627a7a723058204045b88d4bc25183a0d657cfec6f8f8b976fd6aca20ab02e07cc6d76f43e7bd100294e65772072656c6179656420636f6e747261637420616464726573732063616e6e6f74206265207468652073616d65206173207468652063757272656e74206f6e6500000000000000000000000012047000000000000000000000000000000000050000000000000000000000001204700000000000000000000000000000000001" + }, + "0x1204700000000000000000000000000000000002": { + "constructor": "0x608060405273fffffffffffffffffffffffffffffffffffffffe600960006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055503480156200006657600080fd5b5060405160408062001bad833981018060405260408110156200008857600080fd5b810190808051906020019092919080519060200190929190505050620000b36200016360201b60201c565b60786000805490501462000113576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602781526020018062001b866027913960400191505060405180910390fd5b81600b60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600a81905550505062000878565b60405180610f0001604052806704398372e97bae8081526020016704398372e97bae8081526020016704398372e97bae8081526020016704398372e97bae8081526020016704398372e97bae8081526020016704398372e97bae8081526020016704398372e97bae8081526020016704395680a6af46808152602001670438cfa9de4a0e808152602001670437eeee904c06808152602001670436b44ebcb52e8081526020016704351fca638586808152602001670433316184bd0e808152602001670430e914205bc680815260200167042e46e23661ae80815260200167042b4acbc6cec6808152602001670427f4d0d1a30e80815260200167042444f156de868081526020016704203b2d56812e80815260200167041bd784d08b0680815260200167041719f7c4fc0e808152602001670412028633d44680815260200167040c91301d13ae808152602001670406c5f580ba46808152602001670400a0d65ec80e8081526020016703fa21d2b73d068081526020016703f348ea8a192e8081526020016703ec161dd75c868081526020016703e4896c9f070e8081526020016703dca2d6e118c68081526020016703d4625c9d91ae8081526020016703cbc7fdd471c68081526020016703c2d3ba85b90e8081526020016703b98592b167868081526020016703afdd86577d2e8081526020016703a5db9577fa0680815260200167039b7fc012de0e808152602001670390ca06282946808152602001670385ba67b7dbae80815260200167037a50e4c1f54680815260200167036e8d7d46760e8081526020016703627031455e06808152602001670355f900bead2e80815260200167034927ebb2638680815260200167033bfcf220810e80815260200167032e78140905c680815260200167032099516bf1ae80815260200167031260aa4944c6808152602001670303ce1ea0ff0e8081526020016702f4e1ae7320868081526020016702e59b59bfa92e8081526020016702d5fb208699068081526020016702c60102c7f00e8081526020016702b5ad0083ae468081526020016702a4ff19b9d3ae808152602001670293f74e6a6046808152602001670282959e95540e808152602001670270da0a3aaf0680815260200167025ec4915a712e80815260200167024c5533f49a86808152602001670238da1d6b04400081526020016702260c5cdf4d240081526020016702138f83989f90008152602001670201639196fb840081526020016701ef8886da61000081526020016701ddfe6362d0040081526020016701ccc5273048900081526020016701bbdcd242caa40081526020016701ab45649a564000815260200167019afede36eb6400815260200167018b093f188a1000815260200167017b64873f324400815260200167016c10b6aae40000815260200167015d0dcd5b9f4400815260200167014e5bcb51641000815260200167013ffab08c3264008152602001670131ea7d0c0a400081526020016701242b30d0eba4008152602001670116bccbdad6900081526020016701099f4e29cb0400815260200166fcd2b7bdc90000815260200166f0570896d08400815260200166e42c40b4e19000815260200166d8526017fc2400815260200166ccc966c0204000815260200166c19154ad4de400815260200166b6aa29df851000815260200166ac13e656c5c400815260200166a1ce8a1310000081526020016697da151463c4008152602001668e36875ac1100081526020016684e3e0e627e4008152602001667be221b6984000815260200166733149cc1224008152602001666ad1592695900081526020016662c24fc62284008152602001665b042daab900008152602001665396f2d45904008152602001664c7a9f4302900081526020016645af32f6b5a4008152602001663f34adef724000815260200166390b102d386400815260200166333259b00810008152602001662daa8a77e144008152602001662873a284c40000815260200166238da1d6b044008152602001661ef8886da610008152602001661ab45649a5640081526020016616c10b6aae4000815260200166131ea7d0c0a4008152602001660fcd2b7bdc90008152602001660ccc966c0204008152602001660a1ce8a131000081526020016607be221b69840081526020016605b042daab900081526020016603f34adef7240081526020016602873a284c4000815260200166016c10b6aae400815260200165a1ce8a1310008152602001652873a284c4008152506000906078620007e5929190620007fe565b5062080520600181905550607860015402600281905550565b8280548282559060005260206000209081019282156200083d579160200282015b828111156200083c5782518255916020019190600101906200081f565b5b5090506200084c919062000850565b5090565b6200087591905b808211156200087157600081600090555060010162000857565b5090565b90565b6112fe80620008886000396000f3fe608060405234801561001057600080fd5b50600436106101205760003560e01c80634476d66a116100ad57806394f7f62b1161007157806394f7f62b1461045d578063df6a50301461049f578063e6e100db146104bd578063f91c289814610515578063fb1ac5251461068057610120565b80634476d66a146103515780634f4013fb14610393578063553a5c85146103b157806358ceb672146103cf57806360d4b8be146103d957610120565b80631a488047116100f45780631a488047146101f157806330f6eb161461020f57806333ea51a81461027157806337339a16146102b55780633d84b8c1146102f957610120565b8062f380f414610125578063078d8e7a1461016f5780630f411cdb1461019157806318129375146101af575b600080fd5b61012d61069e565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6101776106c4565b604051808215151515815260200191505060405180910390f35b6101996106d4565b6040518082815260200191505060405180910390f35b6101db600480360360208110156101c557600080fd5b81019080803590602001909291905050506106da565b6040518082815260200191505060405180910390f35b6101f96106fb565b6040518082815260200191505060405180910390f35b61025b6004803603604081101561022557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610701565b6040518082815260200191505060405180910390f35b6102b36004803603602081101561028757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610726565b005b6102f7600480360360208110156102cb57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506107a7565b005b61033b6004803603602081101561030f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506108ae565b6040518082815260200191505060405180910390f35b61037d6004803603602081101561036757600080fd5b81019080803590602001909291905050506108c6565b6040518082815260200191505060405180910390f35b61039b6108de565b6040518082815260200191505060405180910390f35b6103b96108e3565b6040518082815260200191505060405180910390f35b6103d76108e9565b005b61041b600480360360208110156103ef57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061094d565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6104896004803603602081101561047357600080fd5b8101908080359060200190929190505050610980565b6040518082815260200191505060405180910390f35b6104a76109c4565b6040518082815260200191505060405180910390f35b6104ff600480360360208110156104d357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506109ca565b6040518082815260200191505060405180910390f35b6105e16004803603604081101561052b57600080fd5b810190808035906020019064010000000081111561054857600080fd5b82018360208201111561055a57600080fd5b8035906020019184602083028401116401000000008311171561057c57600080fd5b90919293919293908035906020019064010000000081111561059d57600080fd5b8201836020820111156105af57600080fd5b803590602001918460208302840111640100000000831117156105d157600080fd5b90919293919293905050506109e2565b604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b8381101561062857808201518184015260208101905061060d565b50505050905001838103825284818151815260200191508051906020019060200280838360005b8381101561066a57808201518184015260208101905061064f565b5050505090500194505050505060405180910390f35b610688610edb565b6040518082815260200191505060405180910390f35b600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60006106cf43610ee1565b905090565b60025481565b600081815481106106e757fe5b906000526020600020016000915090505481565b600a5481565b6008602052816000526040600020602052806000526040600020600091509150505481565b80600c60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461086a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f43616c6c6572206973206e6f742074686520636f6d6d756e6974792066756e6481525060200191505060405180910390fd5b80600b60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60066020528060005260406000206000915090505481565b60076020528060005260406000206000915090505481565b607881565b60035481565b600c60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055565b600c6020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600061098b82610ee1565b1561099957600090506109bf565b600060015483816109a657fe5b04815481106109b157fe5b906000526020600020015490505b919050565b60045481565b60056020528060005260406000206000915090505481565b606080600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610aa8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260188152602001807f43616c6c6572206973206e6f74207468652073797374656d000000000000000081525060200191505060405180910390fd5b838390508686905014610b06576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260258152602001806112ae6025913960400191505060405180910390fd5b60018686905014610b7f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f42656e65666163746f7273206c697374206c656e677468206973206e6f74203181525060200191505060405180910390fd5b600084846000818110610b8e57fe5b9050602002013561ffff1661ffff1614610bf3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602281526020018061128c6022913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff1686866000818110610c1857fe5b9050602002013573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161480610c5c5750610c5b43610ee1565b5b15610cd2576000604051908082528060200260200182016040528015610c915781602001602082028038833980820191505090505b506000604051908082528060200260200182016040528015610cc25781602001602082028038833980820191505090505b5081915080905091509150610ed2565b60606002604051908082528060200260200182016040528015610d045781602001602082028038833980820191505090505b50905060608151604051908082528060200260200182016040528015610d395781602001602082028038833980820191505090505b509050610d6e88886000818110610d4c57fe5b9050602002013573ffffffffffffffffffffffffffffffffffffffff16610ef0565b82600081518110610d7b57fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050610dbe43610980565b81600081518110610dcb57fe5b602002602001018181525050610e02600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16610ef0565b82600181518110610e0f57fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050600a5481600181518110610e5957fe5b602002602001018181525050610e9782600081518110610e7557fe5b602002602001015182600081518110610e8a57fe5b6020026020010151610f9d565b610ec982600181518110610ea757fe5b602002602001015182600181518110610ebc57fe5b6020026020010151611145565b81819350935050505b94509492505050565b60015481565b60006002548210159050919050565b600080600c60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610f935782915050610f98565b809150505b919050565b61100081600860008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060004381526020019081526020016000205461120390919063ffffffff16565b600860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000438152602001908152602001600020819055506110a681600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461120390919063ffffffff16565b600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555061110f81600760004381526020019081526020016000205461120390919063ffffffff16565b600760004381526020019081526020016000208190555061113b8160035461120390919063ffffffff16565b6003819055505050565b61115a8160045461120390919063ffffffff16565b6004819055506111b281600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461120390919063ffffffff16565b600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506111ff8282610f9d565b5050565b600080828401905083811015611281576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f4f766572666c6f77206572726f7200000000000000000000000000000000000081525060200191505060405180910390fd5b809150509291505056fe42656e65666163746f72206973206e6f742074686520626c6f636b20617574686f7242656e65666163746f72732f7479706573206c697374206c656e6774682064696666657273a165627a7a72305820ef1c2590551666e2ac227034529ee69c33ec91868d23c0a0a887d514094ec6030029526577617264206375727665206973206e6f7420746865207265717569726564206c656e67746800000000000000000000000012047000000000000000000000000000000000030000000000000000000000000000000000000000000000000856d3dfb6e26d00" + }, + "0x1204700000000000000000000000000000000004": { + "balance": "41198207933333333690000000", + "constructor": "0x608060405260006001556a22140f53c2d216263ba2803073ffffffffffffffffffffffffffffffffffffffff16311462000085576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260238152602001806200150b6023913960400191505060405180910390fd5b620000956200010260201b60201c565b6a22140f53c2d216263ba28060015414620000fc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180620014ba6028913960400191505060405180910390fd5b62001133565b62000136722d4606b65c033769968bcdc63881b90b0853f569264876ff9c85a7a8ee00635df22bc06200105960201b60201c565b6200016a726e371c454a2d081f3966c180ba2c6165d87de66901c3c03b52c63f027880635df22bc06200105960201b60201c565b6200019e72c2f65230815d30eaa1a4d057bcf0b72fe3cc4e6902a5a058fc295ed00000635df22bc06200105960201b60201c565b620001d37303cccdc799d4dc37d56e3f9dba7f9c210fa1086f6902a5a058fc295ed00000635df22bc06200105960201b60201c565b6200020873047d955877a55fbdac768573a9259f29b103a0666902a5a058fc295ed00000635df22bc06200105960201b60201c565b6200023d7306920bb91f7027176cf373996d39b539ba436d876969e10de76676d0800000635d79dee06200105960201b60201c565b620002727306fdb93aa64f33a8fb40a36c462a3f7a074d632c6901c3c03b52c63f027880635df22bc06200105960201b60201c565b620002a7730ad7ba4af33b485e6f2505c417554631a3e5643f6902a5a058fc295ed00000635df22bc06200105960201b60201c565b620002dc730dd959deb4c458cc2ac379898bf2c99f7a8f399b6901c3c03b52c63f027880635df22bc06200105960201b60201c565b62000311731153818a2eb49f0a71b27313c32814fc02e4db50694220bb939da668600000635df22bc06200105960201b60201c565b6200034773120470000000000000000000000000000000000a6a084595161401484a000000635d79dee06200105960201b60201c565b6200037c7315696134ebeed360dc90dc97ddd00bd07e1c11e96934f086f3b33b68400000635df22bc06200105960201b60201c565b620003b1731f0c30b1aa4c468b5beb02bac8df8f27617a2296692346646590efbaf71200635df22bc06200105960201b60201c565b620003e6732540ded041b6fedc0ff6f0cf26b891ec97c954006901c3c03b52c63f027880635df22bc06200105960201b60201c565b6200041b7325ae7b45d8646580dfcae403d29164729eb8642f691a784379d99db4200000635df22bc06200105960201b60201c565b6200045073349ebc5a6e853df121c84e999081e5992928e64f6934f086f3b33b68400000635df22bc06200105960201b60201c565b62000485733885d15573e45228dd54cd4fde9bfac64d702ed46901c3c03b52c63f027880635df22bc06200105960201b60201c565b620004ba733a9d83766c03c465851a38daa364ef7deccd1ece6934f086f3b33b68400000635df22bc06200105960201b60201c565b620004ef733abaa3f24428d6028f5a7fc5b18ce9d04ccec2296902a5a058fc295ed00000635df22bc06200105960201b60201c565b62000524733c9f867d9b3a595987e198786fa9ab722e5c2f9b6934f086f3b33b68400000635df22bc06200105960201b60201c565b62000559733f11b4ad17fde4695cad64e109ae92a679d87bfc6969e10de76676d0800000635d79dee06200105960201b60201c565b6200058e733f12af735238c6e2fa45efb5b2f3fae82df4c9226901c3c03b52c63f027880635df22bc06200105960201b60201c565b620005c373404bb9c13364522133b363d5c4adb7a88056b19d6902d2cd2bb7a39658b500635df22bc06200105960201b60201c565b620005f873428ab4b019ee3a9b9863b2b4bf1885ce6dff9a736902a5a058fc295ed00000635df22bc06200105960201b60201c565b6200062d7347428fc08e56388372e7c81ad4a1140d932d10966969e10de76676d0800000635d79dee06200105960201b60201c565b620006627348ee57faf61c0b963113e7921e6173629e6bc4436902a5a058fc295ed00000635df22bc06200105960201b60201c565b62000697734d0aa1c3459bf41e3ad4e4f40bbf029cb5723d836934f086f3b33b68400000635df22bc06200105960201b60201c565b620006cc7357f33efad76d4b783cf42c9e6cb08f4425dfe96e6902a5a058fc295ed00000635df22bc06200105960201b60201c565b62000701735b3fb4e1d6040615f3e681bec4c80b5d7c9580716901c3c03b52c63f027880635df22bc06200105960201b60201c565b62000736735fbb9c482034d287c5b3848fc2f9272abdd5bfa26903878076a58c80674b00635df22bc06200105960201b60201c565b6200076b73656e5569bef7781bf0db199d32027766053501ff69438ec266600555e00000635df22bc06200105960201b60201c565b620007a073664f991cdb2ffe6b6a568ede65b0208dbcce6f72691a784379d99db4200000635df22bc06200105960201b60201c565b620007d67369af0912dd44dce2b2373db4021788cbad84ff356a0422ca8b0a00a4250000006360c3f9006200105960201b60201c565b6200080b736a0a5da2a48ea87c2a906c53b3373642c29a4b6c6934f086f3b33b68400000635df22bc06200105960201b60201c565b62000840736cf32cc52e220c023c2d92b1d62310f46a6e2a136901c3c03b52c63f027880635df22bc06200105960201b60201c565b62000875736d516767e4068fc331bdb331fba7578bdb07a68c69234b04a2777d0408ee00635df22bc06200105960201b60201c565b620008aa736dd10e41a7a84fe23ab35fefa2f46c9895f87a2d693c8c4bde2deef1680000635df22bc06200105960201b60201c565b620008df737030892dbf9c2048e796296dda597f145754a1856969e10de76676d0800000635d79dee06200105960201b60201c565b62000914737ed62cf71d519d3bf293ef90829508f92f4ccccb6902a5a058fc295ed00000635df22bc06200105960201b60201c565b6200094a73871ba4266793ad11da537d4857de7ad49eab662b6a017293b0a9e69fd9c00000635df22bc06200105960201b60201c565b6200097f73880e8b0ece0171edd0247f8d13d348d77a6b9b296903878076a58c80674b00635df22bc06200105960201b60201c565b620009b373887f2b16847248bc757b69f3c695f24ff344daf268e9062e03b5c2908780635df22bc06200105960201b60201c565b620009e8738c994ada51d35b8519424368807fb99c103366866969e10de76676d0800000635d79dee06200105960201b60201c565b62000a1d739196e46d664ceda55cb45a2cc5ab5bd1b7e614e26902a5a058fc295ed00000635df22bc06200105960201b60201c565b62000a5273943c85b13f24083ec73815f7ba763b7c42ae02886902a5a058fc295ed00000635df22bc06200105960201b60201c565b62000a87739467b762550673f08b14423f8562048d5e3694226902a5a058fc295ed00000635df22bc06200105960201b60201c565b62000abc73949423db1bfee1ddec99c9d24a12a6ea27cb34896901c3c03b52c63f027880635df22bc06200105960201b60201c565b62000af17396a5eb172efdf262ed6beaaf0e20c6af71831fc96934f086f3b33b68400000635df22bc06200105960201b60201c565b62000b2673a69dca0814eaadc89b6dbe94c5e2110497690f6c6903878076a58c80674b00635df22bc06200105960201b60201c565b62000b5b73a720a8ee90f5013cae9bf7bcac1d153e42815454691a784379d99db4200000635df22bc06200105960201b60201c565b62000b9073b080454f190e76eb8e719560fa8cae50c71bcea96901c3c03b52c63f027880635df22bc06200105960201b60201c565b62000bc573b476ee7d610dae7b23b671ebc7bd6112e97729696902a5a058fc295ed00000635df22bc06200105960201b60201c565b62000bfb73b561618a3ea959a5e363643b267c4cb8fe4b1df76a0422ca8b0a00a4250000006360c3f9006200105960201b60201c565b62000c3073b5b6d8885fbf28f843cc7886de242b811d6952056901c3c03b52c63f027880635df22bc06200105960201b60201c565b62000c6573b61c11b6e42d459efaee8995c44db08507e468e169477d5529f68a63000000635df22bc06200105960201b60201c565b62000c9a73b999004b49c6b907d4278067da5c85195dcd7fc769081e0dddaff653f8b500635df22bc06200105960201b60201c565b62000ccf73be4888c5b021e5f16cd254de2d4eaf17625685c46934f086f3b33b68400000635df22bc06200105960201b60201c565b62000d0473c1d441a2ad43af7b4a3d8e3200d2ceb3a973099d6934f086f3b33b68400000635df22bc06200105960201b60201c565b62000d3973c58a20e290e858542d8e8bb07b600aeb9195fe306903878076a58c80674b00635df22bc06200105960201b60201c565b62000d6f73cfe7964b0b6412b013dc019bdf3afef58be565936a055084cc99f0bdbadd0000635df22bc06200105960201b60201c565b62000da473d33d4f83e85c92e0b53ffe4fc0e18b0e3632c0976901c3c03b52c63f027880635df22bc06200105960201b60201c565b62000dd973d44fb8de580d34f44789408cc9335c9a9ce0ce4d691ad0235eb930a0540000635df22bc06200105960201b60201c565b62000e0e73dacd80d8e1d4f117515caa477ee7599cdfc766196902a5a058fc295ed00000635df22bc06200105960201b60201c565b62000e4373db6cc57168c07b83a00f1f8871538446068824fc691a784379d99db4200000635df22bc06200105960201b60201c565b62000e7873de6b493d368316b9078454e37dce4968482dfbe96969e10de76676d0800000635d79dee06200105960201b60201c565b62000ead73e23c7cb60189bb2fd60625d2c2747b1e68f107766934f086f3b33b68400000635df22bc06200105960201b60201c565b62000ee273e6e8a111c89b05337049de9349c7c4880a396ef1691a784379d99db4200000635df22bc06200105960201b60201c565b62000f1773ebbddf28bf3224791b0510a2ab8813f182fe4e2b6901c3c03b52c63f027880635df22bc06200105960201b60201c565b62000f4c73f4e31018a926f64cb780cb9f5f027377bcfb26fc6907f0e10af47c1c700000635df22bc06200105960201b60201c565b62000f8173f8e6ecb4b0f17576525749bdf85524652cbf002e6901c3c03b52c63f027880635df22bc06200105960201b60201c565b62000fb773fd679097fe0f914642af9857e5799332fe2efa296a01a784379d99db42000000635d79dee06200105960201b60201c565b62000fed73fd7a30d3c2bd017a458610274c275059d308b2e76a01ff1675f219f5a8780000635df22bc06200105960201b60201c565b6200102273ffcf98c62c1bad480ab6846717b173a72e2dd090691a784379d99db4200000635df22bc06200105960201b60201c565b6200105773ffd9b871df6e93803c0877e98fc1722b39c00d786902a5a058fc295ed00000635df22bc06200105960201b60201c565b565b60008060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905060008160000154148015620010b4575060008160010154145b6200110b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526029815260200180620014e26029913960400191505060405180910390fd5b8260016000828254019250508190555082816000018190555081816001018190555050505050565b61037780620011436000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806318a5bbdc14610051578063192e7a7b146100b057806330f0dbe0146100f45780639976e12f14610112575b600080fd5b6100936004803603602081101561006757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610130565b604051808381526020018281526020019250505060405180910390f35b6100f2600480360360208110156100c657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610154565b005b6100fc610336565b6040518082815260200191505060405180910390f35b61011a610345565b6040518082815260200191505060405180910390f35b60006020528060005260406000206000915090508060000154908060010154905082565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090506000816000015411610210576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260158152602001807f417661696c61626c6520616d6f756e742069732030000000000000000000000081525060200191505060405180910390fd5b80600101544211610289576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f486f6c64696e6720706572696f64206973206e6f74206f76657200000000000081525060200191505060405180910390fd5b600081600001549050600082600001819055508273ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f193505050501580156102e2573d6000803e3d6000fd5b508273ffffffffffffffffffffffffffffffffffffffff167f221c08a06b07a64803b3787861a3f276212fcccb51c2e6234077a9b8cb13047a826040518082815260200191505060405180910390a2505050565b6a22140f53c2d216263ba28081565b6001548156fea165627a7a72305820b0165b18a29fae78ec1f58bf69134a67ab02e21d059e757412318d8362284866002954617267657420616d6f756e742073686f756c6420657175616c2061637475616c20616d6f756e74486f6c64696e6720666f72207468697320616464726573732077617320616c7265616479207365742e42616c616e63652073686f756c6420657175616c2074617267657420616d6f756e742e" + }, + "0x1204700000000000000000000000000000000006": { + "constructor": "0x60806040523480156200001157600080fd5b5060405160208062003ed2833981018060405260208110156200003357600080fd5b8101908080519060200190929190505050336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a362000111816200011860201b60201c565b506200027a565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415620001bc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f4e6577206f776e657220616464726573732063616e6e6f74206265203078300081525060200191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b613c48806200028a6000396000f3fe608060405234801561001057600080fd5b50600436106101585760003560e01c806392698814116100c3578063e30bd7401161007c578063e30bd740146109b5578063eadf976014610a72578063ef5454d614610b17578063f25eb5c114610bc8578063f2fde38b14610bd2578063f6d339e414610c1657610158565b80639269881414610705578063ac4e73f91461074b578063ac72c120146107fc578063c3a3582514610842578063deb931a2146108d9578063df57b7421461094757610158565b80636795dbcd116101155780636795dbcd1461041c5780636a1acc3f146104df57806379ce9fac1461059c5780638da5cb5b146106025780638f32d59b1461064c57806390b97fc11461066e57610158565b806306b2ff471461015d57806319362a28146101b9578063267b69221461025e5780633f3935d1146102ff578063432ced04146103905780634f39ca59146103d6575b600080fd5b61019f6004803603602081101561017357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610cd1565b604051808215151515815260200191505060405180910390f35b610244600480360360608110156101cf57600080fd5b8101908080359060200190929190803590602001906401000000008111156101f657600080fd5b82018360208201111561020857600080fd5b8035906020019184600183028401116401000000008311171561022a57600080fd5b909192939192939080359060200190929190505050610d31565b604051808215151515815260200191505060405180910390f35b61028a6004803603602081101561027457600080fd5b8101908080359060200190929190505050610fcb565b604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390f35b6103766004803603602081101561031557600080fd5b810190808035906020019064010000000081111561033257600080fd5b82018360208201111561034457600080fd5b8035906020019184600183028401116401000000008311171561036657600080fd5b909192939192939050505061102f565b604051808215151515815260200191505060405180910390f35b6103bc600480360360208110156103a657600080fd5b810190808035906020019092919050505061134e565b604051808215151515815260200191505060405180910390f35b610402600480360360208110156103ec57600080fd5b8101908080359060200190929190505050611546565b604051808215151515815260200191505060405180910390f35b61049d6004803603604081101561043257600080fd5b81019080803590602001909291908035906020019064010000000081111561045957600080fd5b82018360208201111561046b57600080fd5b8035906020019184600183028401116401000000008311171561048d57600080fd5b9091929391929390505050611a8d565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610521600480360360208110156104f557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611bb2565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610561578082015181840152602081019050610546565b50505050905090810190601f16801561058e5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6105e8600480360360408110156105b257600080fd5b8101908080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611c62565b604051808215151515815260200191505060405180910390f35b61060a611f58565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610654611f81565b604051808215151515815260200191505060405180910390f35b6106ef6004803603604081101561068457600080fd5b8101908080359060200190929190803590602001906401000000008111156106ab57600080fd5b8201836020820111156106bd57600080fd5b803590602001918460018302840111640100000000831117156106df57600080fd5b9091929391929390505050611fd8565b6040518082815260200191505060405180910390f35b6107316004803603602081101561071b57600080fd5b81019080803590602001909291905050506120fa565b604051808215151515815260200191505060405180910390f35b6107e26004803603604081101561076157600080fd5b810190808035906020019064010000000081111561077e57600080fd5b82018360208201111561079057600080fd5b803590602001918460018302840111640100000000831117156107b257600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612245565b604051808215151515815260200191505060405180910390f35b6108286004803603602081101561081257600080fd5b81019080803590602001909291905050506127e7565b604051808215151515815260200191505060405180910390f35b6108c36004803603604081101561085857600080fd5b81019080803590602001909291908035906020019064010000000081111561087f57600080fd5b82018360208201111561089157600080fd5b803590602001918460018302840111640100000000831117156108b357600080fd5b9091929391929390505050612932565b6040518082815260200191505060405180910390f35b610905600480360360208110156108ef57600080fd5b8101908080359060200190929190505050612a57565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6109736004803603602081101561095d57600080fd5b8101908080359060200190929190505050612b72565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6109f7600480360360208110156109cb57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612c8d565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610a37578082015181840152602081019050610a1c565b50505050905090810190601f168015610a645780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610afd60048036036060811015610a8857600080fd5b810190808035906020019092919080359060200190640100000000811115610aaf57600080fd5b820183602082011115610ac157600080fd5b80359060200191846001830284011164010000000083111715610ae357600080fd5b909192939192939080359060200190929190505050612d6e565b604051808215151515815260200191505060405180910390f35b610bae60048036036040811015610b2d57600080fd5b8101908080359060200190640100000000811115610b4a57600080fd5b820183602082011115610b5c57600080fd5b80359060200191846001830284011164010000000083111715610b7e57600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061300b565b604051808215151515815260200191505060405180910390f35b610bd0613281565b005b610c1460048036036020811015610be857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613674565b005b610cb760048036036060811015610c2c57600080fd5b810190808035906020019092919080359060200190640100000000811115610c5357600080fd5b820183602082011115610c6557600080fd5b80359060200191846001830284011164010000000083111715610c8757600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506136fa565b604051808215151515815260200191505060405180910390f35b600080600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002080546001816001161561010002031660029004905014159050919050565b600084600073ffffffffffffffffffffffffffffffffffffffff166001600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415610e0d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f4572726f723a204f6e6c79207768656e20656e7472792072617700000000000081525060200191505060405180910390fd5b853373ffffffffffffffffffffffffffffffffffffffff166001600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610ee5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f4572726f723a204f6e6c79206f776e6572206f6600000000000000000000000081525060200191505060405180910390fd5b83600160008981526020019081526020016000206002018787604051808383808284378083019250505092505050908152602001604051809103902081905550867fb829c3e412537bbe794c048ccb9e4605bb4aaaa8e4d4c15c1a6e0c2adc1716ea878789896040518080602001806020018381038352878782818152602001925080828437600081840152601f19601f8201169050808301925050508381038252858582818152602001925080828437600081840152601f19601f820116905080830192505050965050505050505060405180910390a2600192505050949350505050565b60016020528060005260406000206000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905082565b600082828080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050600073ffffffffffffffffffffffffffffffffffffffff16600160008380519060200120815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415611156576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f4572726f723a204f6e6c79207768656e20656e7472790000000000000000000081525060200191505060405180910390fd5b83838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050503373ffffffffffffffffffffffffffffffffffffffff16600160008380519060200120815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611279576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f4572726f723a204f6e6c79207768656e2070726f706f7365640000000000000081525060200191505060405180910390fd5b8484600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002091906112c7929190613b0e565b503373ffffffffffffffffffffffffffffffffffffffff167f098ae8581bb8bd9af1beaf7f2e9f51f31a8e5a8bfada4e303a645d71d9c91920868660405180806020018281038252848482818152602001925080828437600081840152601f19601f820116905080830192505050935050505060405180910390a260019250505092915050565b600081600073ffffffffffffffffffffffffffffffffffffffff166001600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611429576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f4572726f723a204f6e6c79207768656e20756e7265736572766564000000000081525060200191505060405180910390fd5b611431611f81565b6114a3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f53656e646572206973206e6f74206f776e65720000000000000000000000000081525060200191505060405180910390fd5b336001600085815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055503373ffffffffffffffffffffffffffffffffffffffff16837f4963513eca575aba66fdcd25f267aae85958fe6fb97e75fa25d783f1a091a22160405160405180910390a36001915050919050565b600081600073ffffffffffffffffffffffffffffffffffffffff166001600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415611622576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f4572726f723a204f6e6c79207768656e20656e7472792072617700000000000081525060200191505060405180910390fd5b823373ffffffffffffffffffffffffffffffffffffffff166001600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146116fa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f4572726f723a204f6e6c79206f776e6572206f6600000000000000000000000081525060200191505060405180910390fd5b83600260006001600088815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060405180828054600181600116156101000203166002900480156117cb5780601f106117a95761010080835404028352918201916117cb565b820191906000526020600020905b8154815290600101906020018083116117b7575b5050915050604051809103902014156119da576001600085815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f12491ad95fd945e444d88a894ffad3c21959880a4dcd8af99d4ae4ffc71d4abd600260006001600089815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020604051808060200182810382528381815460018160011615610100020316600290048152602001915080546001816001161561010002031660029004801561194a5780601f1061191f5761010080835404028352916020019161194a565b820191906000526020600020905b81548152906001019060200180831161192d57829003601f168201915b50509250505060405180910390a2600260006001600087815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006119d99190613b8e565b5b60016000858152602001908152602001600020600080820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905550503373ffffffffffffffffffffffffffffffffffffffff16847fef1961b4d2909dc23643b309bfe5c3e5646842d98c3a58517037ef3871185af360405160405180910390a3600192505050919050565b600083600073ffffffffffffffffffffffffffffffffffffffff166001600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415611b69576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f4572726f723a204f6e6c79207768656e20656e7472792072617700000000000081525060200191505060405180910390fd5b60016000868152602001908152602001600020600201848460405180838380828437808301925050509250505090815260200160405180910390205460001c9150509392505050565b60026020528060005260406000206000915090508054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015611c5a5780601f10611c2f57610100808354040283529160200191611c5a565b820191906000526020600020905b815481529060010190602001808311611c3d57829003601f168201915b505050505081565b600082600073ffffffffffffffffffffffffffffffffffffffff166001600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415611d3e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f4572726f723a204f6e6c79207768656e20656e7472792072617700000000000081525060200191505060405180910390fd5b833373ffffffffffffffffffffffffffffffffffffffff166001600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611e16576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f4572726f723a204f6e6c79206f776e6572206f6600000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415611e9c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180613bfc6021913960400191505060405180910390fd5b836001600087815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16867f7b97c62130aa09acbbcbf7482630e756592496f1759eaf702f469cf64dfb779460405160405180910390a460019250505092915050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614905090565b600083600073ffffffffffffffffffffffffffffffffffffffff166001600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614156120b4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f4572726f723a204f6e6c79207768656e20656e7472792072617700000000000081525060200191505060405180910390fd5b6001600086815260200190815260200160002060020184846040518083838082843780830192505050925050509081526020016040518091039020549150509392505050565b600081600073ffffffffffffffffffffffffffffffffffffffff166001600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614156121d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f4572726f723a204f6e6c79207768656e20656e7472792072617700000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff166001600085815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415915050919050565b600083838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050600073ffffffffffffffffffffffffffffffffffffffff16600160008380519060200120815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141561236c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f4572726f723a204f6e6c79207768656e20656e7472790000000000000000000081525060200191505060405180910390fd5b848460405180838380828437808301925050509250505060405180910390203373ffffffffffffffffffffffffffffffffffffffff166001600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614612462576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f4572726f723a204f6e6c79206f776e6572206f6600000000000000000000000081525060200191505060405180910390fd5b6000868660405180838380828437808301925050509250505060405180910390209050600073ffffffffffffffffffffffffffffffffffffffff166001600083815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141580156125d3575080600260006001600085815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060405180828054600181600116156101000203166002900480156125c45780601f106125a25761010080835404028352918201916125c4565b820191906000526020600020905b8154815290600101906020018083116125b0575b50509150506040518091039020145b1561270a57600260006001600084815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006126599190613b8e565b6001600082815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f12491ad95fd945e444d88a894ffad3c21959880a4dcd8af99d4ae4ffc71d4abd888860405180806020018281038252848482818152602001925080828437600081840152601f19601f820116905080830192505050935050505060405180910390a25b846001600083815260200190815260200160002060010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508473ffffffffffffffffffffffffffffffffffffffff167f728435a0031f6a04538fcdd24922a7e06bc7bc945db03e83d22122d1bc5f28df888860405180806020018281038252848482818152602001925080828437600081840152601f19601f820116905080830192505050935050505060405180910390a2600193505050509392505050565b600081600073ffffffffffffffffffffffffffffffffffffffff166001600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614156128c3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f4572726f723a204f6e6c79207768656e20656e7472792072617700000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff166001600085815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415915050919050565b600083600073ffffffffffffffffffffffffffffffffffffffff166001600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415612a0e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f4572726f723a204f6e6c79207768656e20656e7472792072617700000000000081525060200191505060405180910390fd5b60016000868152602001908152602001600020600201848460405180838380828437808301925050509250505090815260200160405180910390205460001c9150509392505050565b600081600073ffffffffffffffffffffffffffffffffffffffff166001600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415612b33576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f4572726f723a204f6e6c79207768656e20656e7472792072617700000000000081525060200191505060405180910390fd5b6001600084815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16915050919050565b600081600073ffffffffffffffffffffffffffffffffffffffff166001600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415612c4e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f4572726f723a204f6e6c79207768656e20656e7472792072617700000000000081525060200191505060405180910390fd5b6001600084815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16915050919050565b6060600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015612d625780601f10612d3757610100808354040283529160200191612d62565b820191906000526020600020905b815481529060010190602001808311612d4557829003601f168201915b50505050509050919050565b600084600073ffffffffffffffffffffffffffffffffffffffff166001600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415612e4a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f4572726f723a204f6e6c79207768656e20656e7472792072617700000000000081525060200191505060405180910390fd5b853373ffffffffffffffffffffffffffffffffffffffff166001600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614612f22576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f4572726f723a204f6e6c79206f776e6572206f6600000000000000000000000081525060200191505060405180910390fd5b8360001b600160008981526020019081526020016000206002018787604051808383808284378083019250505092505050908152602001604051809103902081905550867fb829c3e412537bbe794c048ccb9e4605bb4aaaa8e4d4c15c1a6e0c2adc1716ea878789896040518080602001806020018381038352878782818152602001925080828437600081840152601f19601f8201169050808301925050508381038252858582818152602001925080828437600081840152601f19601f820116905080830192505050965050505050505060405180910390a2600192505050949350505050565b600083838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050600073ffffffffffffffffffffffffffffffffffffffff16600160008380519060200120815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415613132576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f4572726f723a204f6e6c79207768656e20656e7472790000000000000000000081525060200191505060405180910390fd5b61313a611f81565b6131ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f53656e646572206973206e6f74206f776e65720000000000000000000000000081525060200191505060405180910390fd5b8484600260008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002091906131fa929190613b0e565b508273ffffffffffffffffffffffffffffffffffffffff167f098ae8581bb8bd9af1beaf7f2e9f51f31a8e5a8bfada4e303a645d71d9c91920868660405180806020018281038252848482818152602001925080828437600081840152601f19601f820116905080830192505050935050505060405180910390a260019150509392505050565b600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156133545780601f1061332957610100808354040283529160200191613354565b820191906000526020600020905b81548152906001019060200180831161333757829003601f168201915b5050505050600073ffffffffffffffffffffffffffffffffffffffff16600160008380519060200120815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415613439576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f4572726f723a204f6e6c79207768656e20656e7472790000000000000000000081525060200191505060405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff167f12491ad95fd945e444d88a894ffad3c21959880a4dcd8af99d4ae4ffc71d4abd600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060405180806020018281038252838181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156135395780601f1061350e57610100808354040283529160200191613539565b820191906000526020600020905b81548152906001019060200180831161351c57829003601f168201915b50509250505060405180910390a260016000600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060405180828054600181600116156101000203166002900480156135e55780601f106135c35761010080835404028352918201916135e5565b820191906000526020600020905b8154815290600101906020018083116135d1575b50509150506040518091039020815260200190815260200160002060010160006101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006136719190613b8e565b50565b61367c611f81565b6136ee576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f53656e646572206973206e6f74206f776e65720000000000000000000000000081525060200191505060405180910390fd5b6136f7816139ad565b50565b600084600073ffffffffffffffffffffffffffffffffffffffff166001600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614156137d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f4572726f723a204f6e6c79207768656e20656e7472792072617700000000000081525060200191505060405180910390fd5b853373ffffffffffffffffffffffffffffffffffffffff166001600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146138ae576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f4572726f723a204f6e6c79206f776e6572206f6600000000000000000000000081525060200191505060405180910390fd5b8373ffffffffffffffffffffffffffffffffffffffff1660001b600160008981526020019081526020016000206002018787604051808383808284378083019250505092505050908152602001604051809103902081905550867fb829c3e412537bbe794c048ccb9e4605bb4aaaa8e4d4c15c1a6e0c2adc1716ea878789896040518080602001806020018381038352878782818152602001925080828437600081840152601f19601f8201169050808301925050508381038252858582818152602001925080828437600081840152601f19601f820116905080830192505050965050505050505060405180910390a2600192505050949350505050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415613a50576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f4e6577206f776e657220616464726573732063616e6e6f74206265203078300081525060200191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10613b4f57803560ff1916838001178555613b7d565b82800160010185558215613b7d579182015b82811115613b7c578235825591602001919060010190613b61565b5b509050613b8a9190613bd6565b5090565b50805460018160011615610100020316600290046000825580601f10613bb45750613bd3565b601f016020900490600052602060002090810190613bd29190613bd6565b5b50565b613bf891905b80821115613bf4576000816000905550600101613bdc565b5090565b9056fe4572726f723a206e6f207472616e7366657220746f206164647265737320307830a165627a7a72305820fe186a600f547c59523f333a7eb66cd1de74492306acaa3db2cd4c8a1b426b5a00290000000000000000000000001204700000000000000000000000000000000005" + }, + "0x1204700000000000000000000000000000000007": { + "constructor": "0x608060405234801561001057600080fd5b506040516040806108658339810180604052604081101561003057600080fd5b810190808051906020019092919080519060200190929190505050336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3610116816101a160201b60201c565b81600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff167fcc57a97257d7703be97e9d538cb08b3fa1ff2784b776d505942d49a95dc2891460405160405180910390a25050610302565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610244576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f4e6577206f776e657220616464726573732063616e6e6f74206265203078300081525060200191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b610554806103116000396000f3fe608060405234801561001057600080fd5b50600436106100575760003560e01c80636ddc4a071461005c5780638da5cb5b146100a65780638f32d59b146100f0578063f2fde38b14610112578063fe64d6ff14610156575b600080fd5b61006461019a565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6100ae6101c0565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6100f86101e9565b604051808215151515815260200191505060405180910390f35b6101546004803603602081101561012857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610240565b005b6101986004803603602081101561016c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506102c6565b005b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614905090565b6102486101e9565b6102ba576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f53656e646572206973206e6f74206f776e65720000000000000000000000000081525060200191505060405180910390fd5b6102c3816103c7565b50565b6102ce6101e9565b610340576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f53656e646572206973206e6f74206f776e65720000000000000000000000000081525060200191505060405180910390fd5b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167fcc57a97257d7703be97e9d538cb08b3fa1ff2784b776d505942d49a95dc2891460405160405180910390a250565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561046a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f4e6577206f776e657220616464726573732063616e6e6f74206265203078300081525060200191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505056fea165627a7a723058204d73401a5cbb107ba765457948a3c2a2612436446f9125c3696f0f4cc7e06980002900000000000000000000000012047000000000000000000000000000000000090000000000000000000000001204700000000000000000000000000000000005" + }, + "0x1204700000000000000000000000000000000008": { + "constructor": "0x60806040523480156200001157600080fd5b506040516040806200298b8339810180604052620000339190810190620002a8565b336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a381600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555062000141816200014960201b60201c565b5050620003da565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415620001bc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620001b3906200032b565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000815190506200028b81620003a6565b92915050565b600081519050620002a281620003c0565b92915050565b60008060408385031215620002bc57600080fd5b6000620002cc8582860162000291565b9250506020620002df858286016200027a565b9150509250929050565b6000620002f8601f836200034d565b91507f4e6577206f776e657220616464726573732063616e6e6f7420626520307830006000830152602082019050919050565b600060208201905081810360008301526200034681620002e9565b9050919050565b600082825260208201905092915050565b60006200036b8262000386565b9050919050565b60006200037f826200035e565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b620003b1816200035e565b8114620003bd57600080fd5b50565b620003cb8162000372565b8114620003d757600080fd5b50565b6125a180620003ea6000396000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c8063954029c911610097578063eab7ad9211610066578063eab7ad92146102b2578063ee7ee0fd146102ce578063f2fde38b146102fe578063fbd74f841461031a576100f5565b8063954029c91461021a578063a999809f14610236578063b71da0d114610266578063da5393d514610296576100f5565b80636a564261116100d35780636a5642611461017857806370a05b18146101ae5780638da5cb5b146101de5780638f32d59b146101fc576100f5565b80631bab58f5146100fa5780632c5653e21461012a57806332d91c0e14610148575b600080fd5b610114600480360361010f9190810190611d82565b61034a565b60405161012191906123f7565b60405180910390f35b610132610767565b60405161013f919061233a565b60405180910390f35b610162600480360361015d9190810190611d82565b61078d565b60405161016f9190612355565b60405180910390f35b610192600480360361018d9190810190611d82565b61097e565b6040516101a597969594939291906122af565b60405180910390f35b6101c860048036036101c39190810190611d82565b610c2d565b6040516101d5919061228d565b60405180910390f35b6101e6610e1e565b6040516101f39190612257565b60405180910390f35b610204610e47565b6040516102119190612272565b60405180910390f35b610234600480360361022f9190810190611d82565b610e9e565b005b610250600480360361024b9190810190611d82565b610ff5565b60405161025d9190612355565b60405180910390f35b610280600480360361027b9190810190611d82565b6111e6565b60405161028d9190612272565b60405180910390f35b6102b060048036036102ab9190810190611d82565b611276565b005b6102cc60048036036102c79190810190611dd4565b611371565b005b6102e860048036036102e39190810190611d82565b611673565b6040516102f59190612272565b60405180910390f35b61031860048036036103139190810190611d82565b6117d9565b005b610334600480360361032f9190810190611d82565b61182c565b604051610341919061228d565b60405180910390f35b610352611b4b565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636ddc4a076040518163ffffffff1660e01b815260040160206040518083038186803b1580156103ba57600080fd5b505afa1580156103ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506103f29190810190611dab565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461045f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161045690612377565b60405180910390fd5b600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206040518060e0016040529081600082018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156105425780601f1061051757610100808354040283529160200191610542565b820191906000526020600020905b81548152906001019060200180831161052557829003601f168201915b50505050508152602001600182018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156105e45780601f106105b9576101008083540402835291602001916105e4565b820191906000526020600020905b8154815290600101906020018083116105c757829003601f168201915b50505050508152602001600282018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156106865780601f1061065b57610100808354040283529160200191610686565b820191906000526020600020905b81548152906001019060200180831161066957829003601f168201915b50505050508152602001600382018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156107285780601f106106fd57610100808354040283529160200191610728565b820191906000526020600020905b81548152906001019060200180831161070b57829003601f168201915b505050505081526020016004820160009054906101000a900460ff16151515158152602001600582015481526020016006820154815250509050919050565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6060600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636ddc4a076040518163ffffffff1660e01b815260040160206040518083038186803b1580156107f757600080fd5b505afa15801561080b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061082f9190810190611dab565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461089c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161089390612377565b60405180910390fd5b600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206003018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156109725780601f1061094757610100808354040283529160200191610972565b820191906000526020600020905b81548152906001019060200180831161095557829003601f168201915b50505050509050919050565b6001602052806000526040600020600091509050806000018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610a2a5780601f106109ff57610100808354040283529160200191610a2a565b820191906000526020600020905b815481529060010190602001808311610a0d57829003601f168201915b505050505090806001018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610ac85780601f10610a9d57610100808354040283529160200191610ac8565b820191906000526020600020905b815481529060010190602001808311610aab57829003601f168201915b505050505090806002018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610b665780601f10610b3b57610100808354040283529160200191610b66565b820191906000526020600020905b815481529060010190602001808311610b4957829003601f168201915b505050505090806003018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610c045780601f10610bd957610100808354040283529160200191610c04565b820191906000526020600020905b815481529060010190602001808311610be757829003601f168201915b5050505050908060040160009054906101000a900460ff16908060050154908060060154905087565b6060600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636ddc4a076040518163ffffffff1660e01b815260040160206040518083038186803b158015610c9757600080fd5b505afa158015610cab573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610ccf9190810190611dab565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610d3c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d3390612377565b60405180910390fd5b600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206002018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610e125780601f10610de757610100808354040283529160200191610e12565b820191906000526020600020905b815481529060010190602001808311610df557829003601f168201915b50505050509050919050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614905090565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636ddc4a076040518163ffffffff1660e01b815260040160206040518083038186803b158015610f0657600080fd5b505afa158015610f1a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610f3e9190810190611dab565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610fab576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fa290612377565b60405180910390fd5b43600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206006018190555050565b6060600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636ddc4a076040518163ffffffff1660e01b815260040160206040518083038186803b15801561105f57600080fd5b505afa158015611073573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506110979190810190611dab565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611104576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110fb90612377565b60405180910390fd5b600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156111da5780601f106111af576101008083540402835291602001916111da565b820191906000526020600020905b8154815290600101906020018083116111bd57829003601f168201915b50505050509050919050565b6000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060060154600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060050154109050919050565b61127e610e47565b6112bd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112b4906123d7565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561132d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161132490612397565b60405180910390fd5b80600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636ddc4a076040518163ffffffff1660e01b815260040160206040518083038186803b1580156113d957600080fd5b505afa1580156113ed573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506114119190810190611dab565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461147e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161147590612377565b60405180910390fd5b8888600160008d73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000191906114cf929190611b8a565b508686600160008d73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001019190611521929190611c0a565b508484600160008d73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206002019190611573929190611b8a565b508282600160008d73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060030191906115c5929190611c0a565b5080600160008c73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060040160006101000a81548160ff02191690831515021790555043600160008c73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206005018190555050505050505050505050565b6000600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636ddc4a076040518163ffffffff1660e01b815260040160206040518083038186803b1580156116dd57600080fd5b505afa1580156116f1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506117159190810190611dab565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611782576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161177990612377565b60405180910390fd5b600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060040160009054906101000a900460ff169050919050565b6117e1610e47565b611820576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611817906123d7565b60405180910390fd5b61182981611a1d565b50565b6060600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636ddc4a076040518163ffffffff1660e01b815260040160206040518083038186803b15801561189657600080fd5b505afa1580156118aa573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506118ce9190810190611dab565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461193b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161193290612377565b60405180910390fd5b600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015611a115780601f106119e657610100808354040283529160200191611a11565b820191906000526020600020905b8154815290600101906020018083116119f457829003601f168201915b50505050509050919050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611a8d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a84906123b7565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6040518060e001604052806060815260200160608152602001606081526020016060815260200160001515815260200160008152602001600081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10611bcb57803560ff1916838001178555611bf9565b82800160010185558215611bf9579182015b82811115611bf8578235825591602001919060010190611bdd565b5b509050611c069190611c8a565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10611c4b57803560ff1916838001178555611c79565b82800160010185558215611c79579182015b82811115611c78578235825591602001919060010190611c5d565b5b509050611c869190611c8a565b5090565b611cac91905b80821115611ca8576000816000905550600101611c90565b5090565b90565b600081359050611cbe81612539565b92915050565b600081519050611cd381612539565b92915050565b600081359050611ce881612550565b92915050565b60008083601f840112611d0057600080fd5b8235905067ffffffffffffffff811115611d1957600080fd5b602083019150836001820283011115611d3157600080fd5b9250929050565b60008083601f840112611d4a57600080fd5b8235905067ffffffffffffffff811115611d6357600080fd5b602083019150836001820283011115611d7b57600080fd5b9250929050565b600060208284031215611d9457600080fd5b6000611da284828501611caf565b91505092915050565b600060208284031215611dbd57600080fd5b6000611dcb84828501611cc4565b91505092915050565b60008060008060008060008060008060c08b8d031215611df357600080fd5b6000611e018d828e01611caf565b9a505060208b013567ffffffffffffffff811115611e1e57600080fd5b611e2a8d828e01611cee565b995099505060408b013567ffffffffffffffff811115611e4957600080fd5b611e558d828e01611d38565b975097505060608b013567ffffffffffffffff811115611e7457600080fd5b611e808d828e01611cee565b955095505060808b013567ffffffffffffffff811115611e9f57600080fd5b611eab8d828e01611d38565b935093505060a0611ebe8d828e01611cd9565b9150509295989b9194979a5092959850565b611ed981612489565b82525050565b611ee88161249b565b82525050565b611ef78161249b565b82525050565b6000611f0882612424565b611f128185612456565b9350611f228185602086016124f5565b611f2b81612528565b840191505092915050565b6000611f4182612419565b611f4b8185612445565b9350611f5b8185602086016124f5565b611f6481612528565b840191505092915050565b6000611f7a82612419565b611f848185612456565b9350611f948185602086016124f5565b611f9d81612528565b840191505092915050565b611fb1816124d1565b82525050565b6000611fc28261243a565b611fcc8185612478565b9350611fdc8185602086016124f5565b611fe581612528565b840191505092915050565b6000611ffb8261242f565b6120058185612467565b93506120158185602086016124f5565b61201e81612528565b840191505092915050565b60006120348261242f565b61203e8185612478565b935061204e8185602086016124f5565b61205781612528565b840191505092915050565b600061206f601383612478565b91507f4572726f723a206f6e6c794c6f676963204462000000000000000000000000006000830152602082019050919050565b60006120af602983612478565b91507f4572726f723a206e65774c6f6f6b5570206973206e6f7420616c6c6f7765642060008301527f746f2062652030783000000000000000000000000000000000000000000000006020830152604082019050919050565b6000612115601f83612478565b91507f4e6577206f776e657220616464726573732063616e6e6f7420626520307830006000830152602082019050919050565b6000612155601383612478565b91507f53656e646572206973206e6f74206f776e6572000000000000000000000000006000830152602082019050919050565b600060e08301600083015184820360008601526121a58282611f36565b915050602083015184820360208601526121bf8282611ff0565b915050604083015184820360408601526121d98282611f36565b915050606083015184820360608601526121f38282611ff0565b91505060808301516122086080860182611edf565b5060a083015161221b60a0860182612239565b5060c083015161222e60c0860182612239565b508091505092915050565b612242816124c7565b82525050565b612251816124c7565b82525050565b600060208201905061226c6000830184611ed0565b92915050565b60006020820190506122876000830184611eee565b92915050565b600060208201905081810360008301526122a78184611efd565b905092915050565b600060e08201905081810360008301526122c9818a611f6f565b905081810360208301526122dd8189612029565b905081810360408301526122f18188611f6f565b905081810360608301526123058187612029565b90506123146080830186611eee565b61232160a0830185612248565b61232e60c0830184612248565b98975050505050505050565b600060208201905061234f6000830184611fa8565b92915050565b6000602082019050818103600083015261236f8184611fb7565b905092915050565b6000602082019050818103600083015261239081612062565b9050919050565b600060208201905081810360008301526123b0816120a2565b9050919050565b600060208201905081810360008301526123d081612108565b9050919050565b600060208201905081810360008301526123f081612148565b9050919050565b600060208201905081810360008301526124118184612188565b905092915050565b600081519050919050565b600081519050919050565b600081519050919050565b600081519050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b6000612494826124a7565b9050919050565b60008115159050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b60006124dc826124e3565b9050919050565b60006124ee826124a7565b9050919050565b60005b838110156125135780820151818401526020810190506124f8565b83811115612522576000848401525b50505050565b6000601f19601f8301169050919050565b61254281612489565b811461254d57600080fd5b50565b6125598161249b565b811461256457600080fd5b5056fea265627a7a7230582045fea88fa096a11a15a5bb8e9f5993ca3ab8a38132e6c7a04eb7cd5458378c906c6578706572696d656e74616cf5003700000000000000000000000012047000000000000000000000000000000000070000000000000000000000001204700000000000000000000000000000000005" + }, + "0x1204700000000000000000000000000000000009": { + "constructor": "0x60806040523480156200001157600080fd5b506040516040806200208d8339810180604052620000339190810190620002a8565b336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a381600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555062000141816200014960201b60201c565b5050620003da565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415620001bc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620001b3906200032b565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000815190506200028b81620003a6565b92915050565b600081519050620002a281620003c0565b92915050565b60008060408385031215620002bc57600080fd5b6000620002cc8582860162000291565b9250506020620002df858286016200027a565b9150509250929050565b6000620002f8601f836200034d565b91507f4e6577206f776e657220616464726573732063616e6e6f7420626520307830006000830152602082019050919050565b600060208201905081810360008301526200034681620002e9565b9050919050565b600082825260208201905092915050565b60006200036b8262000386565b9050919050565b60006200037f826200035e565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b620003b1816200035e565b8114620003bd57600080fd5b50565b620003cb8162000372565b8114620003d757600080fd5b50565b611ca380620003ea6000396000f3fe608060405234801561001057600080fd5b50600436106100885760003560e01c80638f32d59b1161005b5780638f32d59b14610101578063b71da0d11461011f578063ec2626111461014f578063f2fde38b1461016d57610088565b806312127ed71461008d5780633f67c333146100a957806389c3ce1e146100b35780638da5cb5b146100e3575b600080fd5b6100a760048036036100a2919081019061118d565b610189565b005b6100b16107d7565b005b6100cd60048036036100c89190810190611164565b610a23565b6040516100da91906119c0565b60405180910390f35b6100eb610aee565b6040516100f891906117b7565b60405180910390f35b610109610b17565b604051610116919061186a565b60405180910390f35b61013960048036036101349190810190611164565b610b6e565b604051610146919061186a565b60405180910390f35b610157610c22565b6040516101649190611885565b60405180910390f35b61018760048036036101829190810190611164565b610c48565b005b610191610b17565b6101d0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101c790611940565b60405180910390fd5b600085511415610215576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161020c906118e0565b60405180910390fd5b60008451141561025a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025190611980565b60405180910390fd5b60008351141561029f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610296906118a0565b60405180910390fd5b6000825114156102e4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102db906118c0565b60405180910390fd5b8480519060200120600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663fbd74f84886040518263ffffffff1660e01b815260040161034791906117b7565b60006040518083038186803b15801561035f57600080fd5b505afa158015610373573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525061039c919081019061129f565b8051906020012014801561046c57508380519060200120600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a999809f886040518263ffffffff1660e01b815260040161040e91906117b7565b60006040518083038186803b15801561042657600080fd5b505afa15801561043a573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525061046391908101906112e0565b80519060200120145b801561053457508280519060200120600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a05b18886040518263ffffffff1660e01b81526004016104d691906117b7565b60006040518083038186803b1580156104ee57600080fd5b505afa158015610502573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525061052b919081019061129f565b80519060200120145b80156105fc57508180519060200120600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166332d91c0e886040518263ffffffff1660e01b815260040161059e91906117b7565b60006040518083038186803b1580156105b657600080fd5b505afa1580156105ca573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052506105f391908101906112e0565b80519060200120145b80156106b55750801515600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ee7ee0fd886040518263ffffffff1660e01b815260040161066191906117b7565b60206040518083038186803b15801561067957600080fd5b505afa15801561068d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506106b19190810190611276565b1515145b156106f5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106ec90611960565b60405180910390fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663eab7ad928787878787876040518763ffffffff1660e01b815260040161075a969594939291906117ed565b600060405180830381600087803b15801561077457600080fd5b505af1158015610788573d6000803e3d6000fd5b505050508573ffffffffffffffffffffffffffffffffffffffff167fc9e49a024d50440c73d2d12d0ae05064094dca76b46dc95e99ea6848eb8f27e960405160405180910390a2505050505050565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663fbd74f84336040518263ffffffff1660e01b815260040161083491906117d2565b60006040518083038186803b15801561084c57600080fd5b505afa158015610860573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250610889919081019061129f565b5114156108cb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108c2906119a0565b60405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff1663b71da0d1336040518263ffffffff1660e01b815260040161090491906117d2565b60206040518083038186803b15801561091c57600080fd5b505afa158015610930573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506109549190810190611276565b15610994576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161098b90611900565b60405180910390fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663954029c9336040518263ffffffff1660e01b81526004016109ef91906117d2565b600060405180830381600087803b158015610a0957600080fd5b505af1158015610a1d573d6000803e3d6000fd5b50505050565b610a2b610dc9565b610a33610dc9565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631bab58f5846040518263ffffffff1660e01b8152600401610a8e91906117b7565b60006040518083038186803b158015610aa657600080fd5b505afa158015610aba573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250610ae39190810190611321565b905080915050919050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614905090565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b71da0d1836040518263ffffffff1660e01b8152600401610bcb91906117b7565b60206040518083038186803b158015610be357600080fd5b505afa158015610bf7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610c1b9190810190611276565b9050919050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b610c50610b17565b610c8f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c8690611940565b60405180910390fd5b610c9881610c9b565b50565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610d0b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d0290611920565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6040518060e001604052806060815260200160608152602001606081526020016060815260200160001515815260200160008152602001600081525090565b600081359050610e1781611c24565b92915050565b600081359050610e2c81611c3b565b92915050565b600081519050610e4181611c3b565b92915050565b600082601f830112610e5857600080fd5b8151610e6b610e6682611a0f565b6119e2565b91508082526020830160208301858383011115610e8757600080fd5b610e92838284611be0565b50505092915050565b600082601f830112610eac57600080fd5b8135610ebf610eba82611a3b565b6119e2565b91508082526020830160208301858383011115610edb57600080fd5b610ee6838284611bd1565b50505092915050565b600082601f830112610f0057600080fd5b8151610f13610f0e82611a3b565b6119e2565b91508082526020830160208301858383011115610f2f57600080fd5b610f3a838284611be0565b50505092915050565b600082601f830112610f5457600080fd5b8151610f67610f6282611a67565b6119e2565b91508082526020830160208301858383011115610f8357600080fd5b610f8e838284611be0565b50505092915050565b600082601f830112610fa857600080fd5b8135610fbb610fb682611a93565b6119e2565b91508082526020830160208301858383011115610fd757600080fd5b610fe2838284611bd1565b50505092915050565b600082601f830112610ffc57600080fd5b815161100f61100a82611a93565b6119e2565b9150808252602083016020830185838301111561102b57600080fd5b611036838284611be0565b50505092915050565b600060e0828403121561105157600080fd5b61105b60e06119e2565b9050600082015167ffffffffffffffff81111561107757600080fd5b61108384828501610e47565b600083015250602082015167ffffffffffffffff8111156110a357600080fd5b6110af84828501610f43565b602083015250604082015167ffffffffffffffff8111156110cf57600080fd5b6110db84828501610e47565b604083015250606082015167ffffffffffffffff8111156110fb57600080fd5b61110784828501610f43565b606083015250608061111b84828501610e32565b60808301525060a061112f8482850161114f565b60a08301525060c06111438482850161114f565b60c08301525092915050565b60008151905061115e81611c52565b92915050565b60006020828403121561117657600080fd5b600061118484828501610e08565b91505092915050565b60008060008060008060c087890312156111a657600080fd5b60006111b489828a01610e08565b965050602087013567ffffffffffffffff8111156111d157600080fd5b6111dd89828a01610e9b565b955050604087013567ffffffffffffffff8111156111fa57600080fd5b61120689828a01610f97565b945050606087013567ffffffffffffffff81111561122357600080fd5b61122f89828a01610e9b565b935050608087013567ffffffffffffffff81111561124c57600080fd5b61125889828a01610f97565b92505060a061126989828a01610e1d565b9150509295509295509295565b60006020828403121561128857600080fd5b600061129684828501610e32565b91505092915050565b6000602082840312156112b157600080fd5b600082015167ffffffffffffffff8111156112cb57600080fd5b6112d784828501610eef565b91505092915050565b6000602082840312156112f257600080fd5b600082015167ffffffffffffffff81111561130c57600080fd5b61131884828501610feb565b91505092915050565b60006020828403121561133357600080fd5b600082015167ffffffffffffffff81111561134d57600080fd5b6113598482850161103f565b91505092915050565b61136b81611b77565b82525050565b61137a81611b2f565b82525050565b61138981611b41565b82525050565b61139881611b41565b82525050565b60006113a982611aca565b6113b38185611afc565b93506113c3818560208601611be0565b6113cc81611c13565b840191505092915050565b60006113e282611abf565b6113ec8185611aeb565b93506113fc818560208601611be0565b61140581611c13565b840191505092915050565b61141981611b89565b82525050565b600061142a82611ae0565b6114348185611b1e565b9350611444818560208601611be0565b61144d81611c13565b840191505092915050565b600061146382611ad5565b61146d8185611b0d565b935061147d818560208601611be0565b61148681611c13565b840191505092915050565b600061149e602083611b1e565b91507f436861696e537065635368612073686f756c64206e6f7420626520656d7074796000830152602082019050919050565b60006114de602083611b1e565b91507f436861696e5370656355726c2073686f756c64206e6f7420626520656d7074796000830152602082019050919050565b600061151e601d83611b1e565b91507f446f636b65725368612073686f756c64206e6f7420626520656d7074790000006000830152602082019050919050565b600061155e601883611b1e565b91507f4572726f723a20416c726561647920436f6e6669726d656400000000000000006000830152602082019050919050565b600061159e601f83611b1e565b91507f4e6577206f776e657220616464726573732063616e6e6f7420626520307830006000830152602082019050919050565b60006115de601383611b1e565b91507f53656e646572206973206e6f74206f776e6572000000000000000000000000006000830152602082019050919050565b600061161e602583611b1e565b91507f4572726f723a204e6f206368616e67657320696e20746865207061737365642060008301527f53746174650000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000611684601e83611b1e565b91507f446f636b65724e616d652073686f756c64206e6f7420626520656d70747900006000830152602082019050919050565b60006116c4601f83611b1e565b91507f4572726f723a20596f7520617265206e6f7420612076616c696461746f7221006000830152602082019050919050565b600060e083016000830151848203600086015261171482826113d7565b9150506020830151848203602086015261172e8282611458565b9150506040830151848203604086015261174882826113d7565b915050606083015184820360608601526117628282611458565b91505060808301516117776080860182611380565b5060a083015161178a60a08601826117a8565b5060c083015161179d60c08601826117a8565b508091505092915050565b6117b181611b6d565b82525050565b60006020820190506117cc6000830184611371565b92915050565b60006020820190506117e76000830184611362565b92915050565b600060c0820190506118026000830189611371565b8181036020830152611814818861139e565b90508181036040830152611828818761141f565b9050818103606083015261183c818661139e565b90508181036080830152611850818561141f565b905061185f60a083018461138f565b979650505050505050565b600060208201905061187f600083018461138f565b92915050565b600060208201905061189a6000830184611410565b92915050565b600060208201905081810360008301526118b981611491565b9050919050565b600060208201905081810360008301526118d9816114d1565b9050919050565b600060208201905081810360008301526118f981611511565b9050919050565b6000602082019050818103600083015261191981611551565b9050919050565b6000602082019050818103600083015261193981611591565b9050919050565b60006020820190508181036000830152611959816115d1565b9050919050565b6000602082019050818103600083015261197981611611565b9050919050565b6000602082019050818103600083015261199981611677565b9050919050565b600060208201905081810360008301526119b9816116b7565b9050919050565b600060208201905081810360008301526119da81846116f7565b905092915050565b6000604051905081810181811067ffffffffffffffff82111715611a0557600080fd5b8060405250919050565b600067ffffffffffffffff821115611a2657600080fd5b601f19601f8301169050602081019050919050565b600067ffffffffffffffff821115611a5257600080fd5b601f19601f8301169050602081019050919050565b600067ffffffffffffffff821115611a7e57600080fd5b601f19601f8301169050602081019050919050565b600067ffffffffffffffff821115611aaa57600080fd5b601f19601f8301169050602081019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b600081519050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b6000611b3a82611b4d565b9050919050565b60008115159050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b6000611b8282611bad565b9050919050565b6000611b9482611b9b565b9050919050565b6000611ba682611b4d565b9050919050565b6000611bb882611bbf565b9050919050565b6000611bca82611b4d565b9050919050565b82818337600083830152505050565b60005b83811015611bfe578082015181840152602081019050611be3565b83811115611c0d576000848401525b50505050565b6000601f19601f8301169050919050565b611c2d81611b2f565b8114611c3857600080fd5b50565b611c4481611b41565b8114611c4f57600080fd5b50565b611c5b81611b6d565b8114611c6657600080fd5b5056fea265627a7a7230582070f7a284b1ab092d7cf8a14ca7bf4b7a68d6e2cb8441f82436e624a898b0ebd46c6578706572696d656e74616cf5003700000000000000000000000012047000000000000000000000000000000000080000000000000000000000001204700000000000000000000000000000000005" + } + }, + "nodes": [ + "enode://cc67008e850c4b64702f1664f18704dd23980fb574138588904270739dca3a9c417ac3f97077b0f4e4872a5db109195f7137c156314dbcc724eabd809044553e@ewc-bootnode-02.energyweb.org:30303", + "enode://34f97743b9c07fac84c2db921337f006b5932e14c29df496951bdcfe3fce71e3d1504c25d66156dae01065623849b4fe940168c7e3f21c49b538af0cabb5805f@ewc-bootnode-03.energyweb.org:30303", + "enode://80e49825bb6bdfbf69576fd4a5f7bb173db98c08439bd7a019e2d42548afbb1f70232b74ede42dbd99cc0de3990a0101d49543c1b299027d2fd6f5a2c81eff75@ewc-bootnode-05.energyweb.org:30303", + "enode://1cd00f54ddaa41793d32500f0cb123d43e95f5ed18220c367d5a4db7d111e5fb59f250c397e40977562881875827f022d88a51e51171daaebf916beaa60e2139@ewc-bootnode-06.energyweb.org:30303", + "enode://3a8588bd883ea3bce606b08e7ca71d55717077cb3d25d3c00421ac371fbae286b94f58ba2e739b17b64c4d0d3e19f1b0ae2e47962703b42d7f36f1b9a448d4ea@ewc-bootnode-09.energyweb.org:30303", + "enode://69749dbe7e6f5fceaeb0a16f60353b3ec04825a12400e6d581fe980275e96fecb464276e61d79fc1628e448f1f74da2985d778ea54e0e8e7c64d980f2b3b6a94@ewc-bootnode-10.energyweb.org:30303" + ] +} diff --git a/ethcore/res/ethereum/ropsten.json b/ethcore/res/ethereum/ropsten.json index 8c288fd7ea..b9416dfc27 100644 --- a/ethcore/res/ethereum/ropsten.json +++ b/ethcore/res/ethereum/ropsten.json @@ -2654,7 +2654,7 @@ ] }, "nodes": [ - "enode://6332792c4a00e3e4ee0926ed89e0d27ef985424d97b6a45bf0f23e51f0dcb5e66b875777506458aea7af6f9e4ffb69f43f3778ee73c81ed9d34c51c4b16b0b0f@52.232.243.152:30303", + "enode://d6cb8cba18828397e22e8852324af7e970b57cadbbd94aba6124790d1895728311b1f274e45d44a7a22b4276726903130a11ac2de19af5bc9294998f948eaad4@144.217.72.209:30303", "enode://94c15d1b9e2fe7ce56e458b9a3b672ef11894ddedd0c6f247e0f1d3487f52b66208fb4aeb8179fce6e3a749ea93ed147c37976d67af557508d199d9594c35f09@192.81.208.223:30303", "enode://30b7ab30a01c124a6cceca36863ece12c4f5fa68e3ba9b0b51407ccc002eeed3b3102d20a88f1c1d3c3154e2449317b8ef95090e77b312d5cc39354f86d5d606@52.176.7.10:30303", "enode://865a63255b3bb68023b6bffd5095118fcc13e79dcf014fe4e47e065c350c7cc72af2e53eff895f11ba1bbb6a2b33271c1116ee870f266618eadfc2e78aa7349c@52.176.100.77:30303", diff --git a/ethcore/res/ethereum/tobalaba.json b/ethcore/res/ethereum/tobalaba.json deleted file mode 100644 index 043367cc72..0000000000 --- a/ethcore/res/ethereum/tobalaba.json +++ /dev/null @@ -1,80 +0,0 @@ -{ - "name": "Tobalaba", - "engine": { - "authorityRound": { - "params": { - "stepDuration": "3", - "validators": { - "contract": "0x1000000000000000000000000000000000000005" - }, - "maximumUncleCount": 999999 - } - } - }, - "params": { - "maximumExtraDataSize": "0x20", - "gasLimitBoundDivisor": "0x400", - "minGasLimit": "0x1388", - "networkID": "0x62121", - "eip98Transition": 0, - "wasmActivationTransition": 7250000, - "eip140Transition": 7250000, - "eip211Transition": 7250000, - "eip214Transition": 7250000, - "eip658Transition": 7250000, - - "maxCodeSize": 24576, - "maxCodeSizeTransition": 7250000, - - "registrar": "0xb8624dc8cb3ca3147c178ac4c21734eb49e04071" - }, - "genesis": { - "seal": { - "authorityRound": { - "step": "0x0", - "signature": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - } - }, - "difficulty": "0x20000", - "gasLimit": "0x800000" - }, - "accounts": { - "0x1000000000000000000000000000000000000005": { - "balance": "1", - "constructor": "6060604052341561000f57600080fd5b5b60048054600160a060020a03199081167310000000000000000000000000000000000000061790915560028054909116731000000000000000000000000000000000000007179055600080546001810161006a8382610115565b916000526020600020900160005b8154600160a060020a036101009290920a9182021916734ba15b56452521c0826a35a6f2022e1210fc519b90910217905550600180548082016100bb8382610115565b916000526020600020900160005b8154600160a060020a036101009290920a9182021916734ba15b56452521c0826a35a6f2022e1210fc519b9182021790915560038054600160a060020a0319169091179055505b610160565b8154818355818115116101395760008381526020902061013991810190830161013f565b5b505050565b61015d91905b808211156101595760008155600101610145565b5090565b90565b610a208061016f6000396000f300606060405236156100ee5763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166303aca792811461013d578063063a54c91461016f57806311ae9ed21461019e578063170f9291146102055780631cd3e85814610237578063480b4619146102585780636c1247e5146102bf5780637a1a9e60146102ee578063830f0bc6146103205780638da5cb5b146103525780639b2ae4c614610381578063b6f783f2146103a6578063b7ab4db5146103d5578063c55642be1461043c578063e2de215e1461045d578063fe5d935c1461048c578063ff7a071b146104f3575b34156100f957600080fd5b5b600454600160a060020a0316600036604051808383808284378201915050925050506000604051808303818561646e5a03f4915050151561013a57600080fd5b5b005b341561014857600080fd5b610153600435610518565b604051600160a060020a03909116815260200160405180910390f35b341561017a57600080fd5b61015361054a565b604051600160a060020a03909116815260200160405180910390f35b34156101a957600080fd5b6101b161055a565b60405160208082528190810183818151815260200191508051906020019060200280838360005b838110156101f15780820151818401525b6020016101d8565b505050509050019250505060405180910390f35b341561021057600080fd5b6101536004356105c3565b604051600160a060020a03909116815260200160405180910390f35b341561024257600080fd5b61013a600160a060020a03600435166105f5565b005b341561026357600080fd5b6101b16106d1565b60405160208082528190810183818151815260200191508051906020019060200280838360005b838110156101f15780820151818401525b6020016101d8565b505050509050019250505060405180910390f35b34156102ca57600080fd5b61015361073a565b604051600160a060020a03909116815260200160405180910390f35b34156102f957600080fd5b610153600435610749565b604051600160a060020a03909116815260200160405180910390f35b341561032b57600080fd5b61015360043561077b565b604051600160a060020a03909116815260200160405180910390f35b341561035d57600080fd5b6101536107ad565b604051600160a060020a03909116815260200160405180910390f35b341561038c57600080fd5b6103946107bc565b60405190815260200160405180910390f35b34156103b157600080fd5b6101536107c3565b604051600160a060020a03909116815260200160405180910390f35b34156103e057600080fd5b6101b16107d3565b60405160208082528190810183818151815260200191508051906020019060200280838360005b838110156101f15780820151818401525b6020016101d8565b505050509050019250505060405180910390f35b341561044757600080fd5b61013a600160a060020a036004351661083c565b005b341561046857600080fd5b610153610918565b604051600160a060020a03909116815260200160405180910390f35b341561049757600080fd5b6101b1610927565b60405160208082528190810183818151815260200191508051906020019060200280838360005b838110156101f15780820151818401525b6020016101d8565b505050509050019250505060405180910390f35b34156104fe57600080fd5b610394610990565b60405190815260200160405180910390f35b600180548290811061052657fe5b906000526020600020900160005b915054906101000a9004600160a060020a031681565b600254600160a060020a03165b90565b610562610997565b60018054806020026020016040519081016040528092919081815260200182805480156105b857602002820191906000526020600020905b8154600160a060020a0316815260019091019060200180831161059a575b505050505090505b90565b600080548290811061052657fe5b906000526020600020900160005b915054906101000a9004600160a060020a031681565b60035433600160a060020a0390811691161461061057600080fd5b600254600160a060020a038281169116141561062b57600080fd5b600680546001810161063d83826109a9565b916000526020600020900160005b600280548354600160a060020a036101009490940a848102199091169184160217909255815473ffffffffffffffffffffffffffffffffffffffff1916908416179055507f78603ac34f42fe53d8aad96b7b37aeee79dc7ed07c26f57a13cdf64ac72b0f1181604051600160a060020a03909116815260200160405180910390a15b5b50565b6106d9610997565b60058054806020026020016040519081016040528092919081815260200182805480156105b857602002820191906000526020600020905b8154600160a060020a0316815260019091019060200180831161059a575b505050505090505b90565b600254600160a060020a031681565b600680548290811061052657fe5b906000526020600020900160005b915054906101000a9004600160a060020a031681565b600580548290811061052657fe5b906000526020600020900160005b915054906101000a9004600160a060020a031681565b600354600160a060020a031681565b6001545b90565b600454600160a060020a03165b90565b6107db610997565b60008054806020026020016040519081016040528092919081815260200182805480156105b857602002820191906000526020600020905b8154600160a060020a0316815260019091019060200180831161059a575b505050505090505b90565b60035433600160a060020a0390811691161461085757600080fd5b600454600160a060020a038281169116141561087257600080fd5b600580546001810161088483826109a9565b916000526020600020900160005b600480548354600160a060020a036101009490940a848102199091169184160217909255815473ffffffffffffffffffffffffffffffffffffffff1916908416179055507fadcbcb6339ee0b34abbe8d1524c53b813794e1537a43136c6a7768019599625781604051600160a060020a03909116815260200160405180910390a15b5b50565b600454600160a060020a031681565b61092f610997565b60068054806020026020016040519081016040528092919081815260200182805480156105b857602002820191906000526020600020905b8154600160a060020a0316815260019091019060200180831161059a575b505050505090505b90565b6000545b90565b60206040519081016040526000815290565b8154818355818115116109cd576000838152602090206109cd9181019083016109d3565b5b505050565b61055791905b808211156109ed57600081556001016109d9565b5090565b905600a165627a7a72305820e9d3839061bfeb56c1cc57b2b2ec8dd7882afd848b4ae489c218d6f9674316660029" - }, - "0x1000000000000000000000000000000000000006": { - "balance": "1", - "constructor": "6060604052341561000f57600080fd5b5b60028054600160a060020a0319167310000000000000000000000000000000000000071790555b5b610abb806100476000396000f300606060405236156100885763ffffffff60e060020a60003504166303aca792811461008d578063170f9291146100bf57806340a141ff146100f15780634d238c8e146101125780634d655aff1461013357806375286211146101625780638da5cb5b14610177578063a6f9dae1146101a6578063c476dd40146101c7578063d69f13bb1461022e575b600080fd5b341561009857600080fd5b6100a3600435610252565b604051600160a060020a03909116815260200160405180910390f35b34156100ca57600080fd5b6100a3600435610284565b604051600160a060020a03909116815260200160405180910390f35b34156100fc57600080fd5b610110600160a060020a03600435166102b6565b005b341561011d57600080fd5b610110600160a060020a036004351661064d565b005b341561013e57600080fd5b6100a36107a1565b604051600160a060020a03909116815260200160405180910390f35b341561016d57600080fd5b6101106107b0565b005b341561018257600080fd5b6100a36107ed565b604051600160a060020a03909116815260200160405180910390f35b34156101b157600080fd5b610110600160a060020a03600435166107fc565b005b34156101d257600080fd5b61011060048035600160a060020a03169060248035919060649060443590810190830135806020601f8201819004810201604051908101604052818152929190602084018383808284375094965061084495505050505050565b005b341561023957600080fd5b610110600160a060020a0360043516602435610926565b005b600180548290811061026057fe5b906000526020600020900160005b915054906101000a9004600160a060020a031681565b600080548290811061026057fe5b906000526020600020900160005b915054906101000a9004600160a060020a031681565b60035460009033600160a060020a039081169116146102d457600080fd5b600254600160a060020a031663b31610db8360006040516020015260405160e060020a63ffffffff8416028152600160a060020a039091166004820152602401602060405180830381600087803b151561032d57600080fd5b6102c65a03f1151561033e57600080fd5b50505060405180511515905061035357600080fd5b60008054600019810190811061036557fe5b906000526020600020900160005b9054600254600160a060020a036101009390930a9091048216925082916001911663b31610db8560006040516020015260405160e060020a63ffffffff8416028152600160a060020a039091166004820152602401602060405180830381600087803b15156103e157600080fd5b6102c65a03f115156103f257600080fd5b50505060405180518254909150811061040757fe5b906000526020600020900160005b6101000a815481600160a060020a030219169083600160a060020a0316021790555060018080805490500381548110151561044c57fe5b906000526020600020900160005b81546101009190910a600160a060020a0302191690556001805460001901906104839082610991565b50600254600160a060020a0316635caf5a6a828263b31610db8660006040516020015260405160e060020a63ffffffff8416028152600160a060020a039091166004820152602401602060405180830381600087803b15156104e457600080fd5b6102c65a03f115156104f557600080fd5b5050506040518051905060405160e060020a63ffffffff8516028152600160a060020a0390921660048301526024820152604401600060405180830381600087803b151561054257600080fd5b6102c65a03f1151561055357600080fd5b5050600254600160a060020a03169050635caf5a6a83600060405160e060020a63ffffffff8516028152600160a060020a0390921660048301526024820152604401600060405180830381600087803b15156105ae57600080fd5b6102c65a03f115156105bf57600080fd5b5050506000194301407f55252fa6eee4741b4e24a74a70e9c11fd2c2281df8d6ea13126ff845f7825c89600160405160208082528254908201819052819060408201908490801561063957602002820191906000526020600020905b8154600160a060020a0316815260019091019060200180831161061b575b50509250505060405180910390a25b5b5050565b60035433600160a060020a0390811691161461066857600080fd5b600180548082016106798382610991565b916000526020600020900160005b81546101009190910a600160a060020a0381810219909216858316919091021790915560025460015491169150635caf5a6a9083906000190160405160e060020a63ffffffff8516028152600160a060020a0390921660048301526024820152604401600060405180830381600087803b151561070357600080fd5b6102c65a03f1151561071457600080fd5b5050506000194301407f55252fa6eee4741b4e24a74a70e9c11fd2c2281df8d6ea13126ff845f7825c89600160405160208082528254908201819052819060408201908490801561078e57602002820191906000526020600020905b8154600160a060020a03168152600190910190602001808311610770575b50509250505060405180910390a25b5b50565b600254600160a060020a031681565b73fffffffffffffffffffffffffffffffffffffffe600160a060020a033316146107d957600080fd5b6001805461079d916000916109e5565b505b565b600354600160a060020a031681565b60035433600160a060020a0390811691161461081757600080fd5b6003805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0383161790555b5b50565b73fffffffffffffffffffffffffffffffffffffffe600160a060020a0333161461086d57600080fd5b7f8498b6f07a5f800443a5fd85ac8171cf40cda44faea60caabe9b297d9dfa8424838383604051600160a060020a03841681526020810183905260606040820181815290820183818151815260200191508051906020019080838360005b838110156108e45780820151818401525b6020016108cb565b50505050905090810190601f1680156109115780820380516001836020036101000a031916815260200191505b5094505050505060405180910390a15b505050565b73fffffffffffffffffffffffffffffffffffffffe600160a060020a0333161461094f57600080fd5b81600160a060020a03167f31bc112157435aab6dd7e9a059abea7f0fce172e3e68e272a6375bbb01eb96c18260405190815260200160405180910390a25b5050565b81548183558181151161092157600083815260209020610921918101908301610a36565b5b505050565b81548183558181151161092157600083815260209020610921918101908301610a36565b5b505050565b828054828255906000526020600020908101928215610a255760005260206000209182015b82811115610a25578254825591600101919060010190610a0a565b5b50610a32929150610a57565b5090565b610a5491905b80821115610a325760008155600101610a3c565b5090565b90565b610a5491905b80821115610a3257805473ffffffffffffffffffffffffffffffffffffffff19168155600101610a5d565b5090565b905600a165627a7a72305820cae3ca62c5821766e8122461884affeaabdc6c2fe79f5a3200207a536e5b0e260029" - }, - "0x1000000000000000000000000000000000000007": { - "balance": "1", - "constructor": "6060604052341561000f57600080fd5b5b60018054600160a060020a0319167310000000000000000000000000000000000000051790555b5b6101bb806100476000396000f300606060405263ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166318def8ef811461005e5780635caf5a6a1461008f5780638da5cb5b146100b3578063b31610db146100e2575b600080fd5b341561006957600080fd5b61007d600160a060020a0360043516610113565b60405190815260200160405180910390f35b341561009a57600080fd5b6100b1600160a060020a0360043516602435610125565b005b34156100be57600080fd5b6100c6610161565b604051600160a060020a03909116815260200160405180910390f35b34156100ed57600080fd5b61007d600160a060020a0360043516610170565b60405190815260200160405180910390f35b60006020819052908152604090205481565b60015433600160a060020a0390811691161461014057600080fd5b600160a060020a03821660009081526020819052604090208190555b5b5050565b600154600160a060020a031681565b600160a060020a0381166000908152602081905260409020545b9190505600a165627a7a7230582085b261e548fa6e3065a32e485c6417d200c7145f3548c0097d4c92022ac7fb1e0029" - }, - "0x4ba15b56452521c0826a35a6f2022e1210fc519b": { - "balance": "0x7E37BE2022B2B09472D89C0000" - }, - - "0x0000000000000000000000000000000000000001": { "builtin": { "name": "ecrecover", "activate_at": 7250000, "pricing": { "linear": { "base": 3000, "word": 0 } } } }, - "0x0000000000000000000000000000000000000002": { "builtin": { "name": "sha256", "activate_at": 7250000, "pricing": { "linear": { "base": 60, "word": 12 } } } }, - "0x0000000000000000000000000000000000000003": { "builtin": { "name": "ripemd160", "activate_at": 7250000, "pricing": { "linear": { "base": 600, "word": 120 } } } }, - "0x0000000000000000000000000000000000000004": { "builtin": { "name": "identity", "activate_at": 7250000, "pricing": { "linear": { "base": 15, "word": 3 } } } }, - "0x0000000000000000000000000000000000000005": { "builtin": { "name": "modexp", "activate_at": 7250000, "pricing": { "modexp": { "divisor": 20 } } } }, - "0x0000000000000000000000000000000000000006": { "builtin": { "name": "alt_bn128_add", "activate_at": 7250000, "pricing": { "linear": { "base": 500, "word": 0 } } } }, - "0x0000000000000000000000000000000000000007": { "builtin": { "name": "alt_bn128_mul", "activate_at": 7250000, "pricing": { "linear": { "base": 40000, "word": 0 } } } }, - "0x0000000000000000000000000000000000000008": { "builtin": { "name": "alt_bn128_pairing", "activate_at": 7250000, "pricing": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 } } } } - }, - - "nodes": [ - "enode://a9327d37d07799817d4a3e13d49fb4f5cc1486d4adf3ec8a6b98be62c4d7a5453914a5139dbe124809a388514cb0be37f9fa799539abe2250672f6d3d778b821@18.191.209.251:30303", - "enode://8185e15b0e269e19b9051ba2c3bab9160f0e52a8e5e2cef626013142d957c4256f0b18e80965a9fa9acabdb2ba07890c995ad354cbda0fa812ded5a5ce878321@3.121.61.202:30303", - "enode://38fab1370b042170b37ebd758d07c17b7aa4fd4ff21db8e8f120ade9cf17835ae67fd014a047ee171952fba2a05a90505fedbe98c883b20e4501d437aec8b831@3.122.42.125:30303", - "enode://d2fdbd9efe681080410775dbe986014e21a6a096b6dfd7d2c499f3b893951adf3aae0164392404f6269d231192735bd0c8da3d022639e8a36d8d17299daa632a@3.122.18.27:30303", - "enode://9745ffa93cde2a0e22528fbd4a4f8b5102035ab8c7a781918c9ef92dee6e5a21635dfd106ccfbcf24f4fdd52e8fb513b7f3f55ced90c9b61f2cd756bccd7f660@18.210.141.224:30303", - "enode://4c36427e744783bcbc595a7fbbe785951130d8d4fe9f2206c78538fcf43fb19172df8a577c4ae0c91b7627b057bdf148666a7e4e428650e677f9c443e59479e4@3.86.127.87:30303", - "enode://b447c1eaad456996ae4ce965a01d543b8f4b0d7e78e23d2cc2d328fe0e0b87dac55eaebe9a27ae24fb879cf056b52b11d967d37a731f5f5987ec4fc0dfb4d908@34.236.121.163:30303", - "enode://916dba32ba88b7a5554d862b5a01b5eddf805788545f2ba6ee682f1cfe08eac132b71a4d725bc73c7b687496e525bf414e7d90cd223dacebe1946e3bb464bca0@18.136.95.237:30303", - "enode://a46393687ee9fbe798aba517d8f92443e45ed7e5ea85aa996c62998088607d57b000001945063045584861652802325d93828cef29a9eb966772f75521dff8c6@3.0.157.214:30303", - "enode://94b92761837031a7afbbc7e6a4363baf6c5f04c7766ab63f4f5b47c98be30faef6e5e91d30cc08dd682a6dc16cdd4f85ec6843f4ac9f18887d4da20b04878ea6@52.220.46.9:30303" - ] -} diff --git a/ethcore/res/ethereum/volta.json b/ethcore/res/ethereum/volta.json new file mode 100644 index 0000000000..d43d6c0685 --- /dev/null +++ b/ethcore/res/ethereum/volta.json @@ -0,0 +1,202 @@ +{ + "name": "Volta", + "engine": { + "authorityRound": { + "params": { + "stepDuration": "5", + "validators": { + "contract": "0x1204700000000000000000000000000000000000" + }, + "maximumUncleCountTransition": "0", + "maximumUncleCount": "0", + "blockRewardContractAddress": "0x1204700000000000000000000000000000000002", + "blockRewardContractTransition": "0" + } + } + }, + "params": { + "networkID": "0x12047", + "maximumExtraDataSize": "0x20", + "gasLimitBoundDivisor": "0x400", + "minGasLimit": "0x1388", + "maxCodeSize": "0x6000", + "eip140Transition": "0x0", + "eip211Transition": "0x0", + "eip214Transition": "0x0", + "eip658Transition": "0x0", + "eip145Transition": "0x0", + "eip1014Transition": "0x0", + "eip1052Transition": "0x0", + "registrar": "0x1204700000000000000000000000000000000006" + }, + "genesis": { + "seal": { + "authorityRound": { + "step": "0x0", + "signature": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + } + }, + "difficulty": "0x20000", + "gasLimit": "0x5B8D80" + }, + "accounts": { + "0x0000000000000000000000000000000000000001": { + "balance": "1", + "builtin": { + "name": "ecrecover", + "activate_at": "0", + "pricing": { + "linear": { + "base": 3000, + "word": 0 + } + } + } + }, + "0x0000000000000000000000000000000000000002": { + "balance": "1", + "builtin": { + "name": "sha256", + "activate_at": "0", + "pricing": { + "linear": { + "base": 60, + "word": 12 + } + } + } + }, + "0x0000000000000000000000000000000000000003": { + "balance": "1", + "builtin": { + "name": "ripemd160", + "activate_at": "0", + "pricing": { + "linear": { + "base": 600, + "word": 120 + } + } + } + }, + "0x0000000000000000000000000000000000000004": { + "balance": "1", + "builtin": { + "name": "identity", + "activate_at": "0", + "pricing": { + "linear": { + "base": 15, + "word": 3 + } + } + } + }, + "0x0000000000000000000000000000000000000005": { + "balance": "1", + "builtin": { + "name": "modexp", + "activate_at": "0", + "pricing": { + "modexp": { + "divisor": 20 + } + } + } + }, + "0x0000000000000000000000000000000000000006": { + "balance": "1", + "builtin": { + "name": "alt_bn128_add", + "activate_at": "0", + "pricing": { + "linear": { + "base": 500, + "word": 0 + } + } + } + }, + "0x0000000000000000000000000000000000000007": { + "balance": "1", + "builtin": { + "name": "alt_bn128_mul", + "activate_at": "0", + "pricing": { + "linear": { + "base": 40000, + "word": 0 + } + } + } + }, + "0x0000000000000000000000000000000000000008": { + "balance": "1", + "builtin": { + "name": "alt_bn128_pairing", + "activate_at": "0", + "pricing": { + "alt_bn128_pairing": { + "base": 100000, + "pair": 80000 + } + } + } + }, + "0x1204700000000000000000000000000000000005": { + "constructor": "0x606060405234156200001057600080fd5b6040516200240138038062002401833981016040528080518201919060200180519060200190919050505b600082518260328211158015620000525750818111155b801562000060575060008114155b80156200006e575060008214155b15156200007a57600080fd5b600092505b8451831015620001b6576002600086858151811015156200009c57fe5b9060200190602002015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161580156200012b5750600085848151811015156200010857fe5b9060200190602002015173ffffffffffffffffffffffffffffffffffffffff1614155b15156200013757600080fd5b60016002600087868151811015156200014c57fe5b9060200190602002015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505b82806001019350506200007f565b8460039080519060200190620001ce929190620001e3565b50836004819055505b5b5050505050620002b8565b8280548282559060005260206000209081019282156200025f579160200282015b828111156200025e5782518260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055509160200191906001019062000204565b5b5090506200026e919062000272565b5090565b620002b591905b80821115620002b157600081816101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555060010162000279565b5090565b90565b61213980620002c86000396000f3006060604052361561011b576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063025e7c2714610177578063173825d9146101da57806320ea8d86146102135780632f54bf6e146102365780633411c81c1461028757806354741525146102e15780637065cb4814610325578063784547a71461035e5780638b51d13f146103995780639ace38c2146103d0578063a0e67e2b146104ce578063a8abe69a14610539578063b5dc40c3146105d1578063b77bf6001461064a578063ba51a6df14610673578063c01a8c8414610696578063c6427474146106b9578063d74f8edd14610752578063dc8452cd1461077b578063e20056e6146107a4578063ee22610b146107fc575b5b6000341115610174573373ffffffffffffffffffffffffffffffffffffffff167fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c346040518082815260200191505060405180910390a25b5b005b341561018257600080fd5b610198600480803590602001909190505061081f565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156101e557600080fd5b610211600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190505061085f565b005b341561021e57600080fd5b6102346004808035906020019091905050610b02565b005b341561024157600080fd5b61026d600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610cae565b604051808215151515815260200191505060405180910390f35b341561029257600080fd5b6102c7600480803590602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610cce565b604051808215151515815260200191505060405180910390f35b34156102ec57600080fd5b61030f600480803515159060200190919080351515906020019091905050610cfd565b6040518082815260200191505060405180910390f35b341561033057600080fd5b61035c600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610d91565b005b341561036957600080fd5b61037f6004808035906020019091905050610f99565b604051808215151515815260200191505060405180910390f35b34156103a457600080fd5b6103ba6004808035906020019091905050611081565b6040518082815260200191505060405180910390f35b34156103db57600080fd5b6103f16004808035906020019091905050611150565b604051808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200184815260200180602001831515151581526020018281038252848181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156104bc5780601f10610491576101008083540402835291602001916104bc565b820191906000526020600020905b81548152906001019060200180831161049f57829003601f168201915b50509550505050505060405180910390f35b34156104d957600080fd5b6104e16111ac565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b838110156105255780820151818401525b602081019050610509565b505050509050019250505060405180910390f35b341561054457600080fd5b610579600480803590602001909190803590602001909190803515159060200190919080351515906020019091905050611241565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b838110156105bd5780820151818401525b6020810190506105a1565b505050509050019250505060405180910390f35b34156105dc57600080fd5b6105f260048080359060200190919050506113a2565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b838110156106365780820151818401525b60208101905061061a565b505050509050019250505060405180910390f35b341561065557600080fd5b61065d6115d3565b6040518082815260200191505060405180910390f35b341561067e57600080fd5b61069460048080359060200190919050506115d9565b005b34156106a157600080fd5b6106b76004808035906020019091905050611696565b005b34156106c457600080fd5b61073c600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091905050611877565b6040518082815260200191505060405180910390f35b341561075d57600080fd5b610765611897565b6040518082815260200191505060405180910390f35b341561078657600080fd5b61078e61189c565b6040518082815260200191505060405180910390f35b34156107af57600080fd5b6107fa600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506118a2565b005b341561080757600080fd5b61081d6004808035906020019091905050611bc0565b005b60038181548110151561082e57fe5b906000526020600020900160005b915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60003073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561089b57600080fd5b81600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615156108f457600080fd5b6000600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550600091505b600160038054905003821015610a80578273ffffffffffffffffffffffffffffffffffffffff1660038381548110151561098757fe5b906000526020600020900160005b9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415610a725760036001600380549050038154811015156109e757fe5b906000526020600020900160005b9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600383815481101515610a2357fe5b906000526020600020900160005b6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550610a80565b5b8180600101925050610951565b6001600381818054905003915081610a989190611fe8565b506003805490506004541115610ab757610ab66003805490506115d9565b5b8273ffffffffffffffffffffffffffffffffffffffff167f8001553a916ef2f495d26a907cc54d96ed840d7bda71e73194bf5a9df7a76b9060405160405180910390a25b5b505b5050565b33600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515610b5b57600080fd5b81336001600083815260200190815260200160002060008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515610bc657600080fd5b8360008082815260200190815260200160002060030160009054906101000a900460ff16151515610bf657600080fd5b60006001600087815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550843373ffffffffffffffffffffffffffffffffffffffff167ff6a317157440607f36269043eb55f1287a5a19ba2216afeab88cd46cbcfb88e960405160405180910390a35b5b505b50505b5050565b60026020528060005260406000206000915054906101000a900460ff1681565b60016020528160005260406000206020528060005260406000206000915091509054906101000a900460ff1681565b600080600090505b600554811015610d8957838015610d3c575060008082815260200190815260200160002060030160009054906101000a900460ff16155b80610d6f5750828015610d6e575060008082815260200190815260200160002060030160009054906101000a900460ff165b5b15610d7b576001820191505b5b8080600101915050610d05565b5b5092915050565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610dcb57600080fd5b80600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151515610e2557600080fd5b8160008173ffffffffffffffffffffffffffffffffffffffff1614151515610e4c57600080fd5b60016003805490500160045460328211158015610e695750818111155b8015610e76575060008114155b8015610e83575060008214155b1515610e8e57600080fd5b6001600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555060038054806001018281610efa9190612014565b916000526020600020900160005b87909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550508473ffffffffffffffffffffffffffffffffffffffff167ff39e6e1eb0edcf53c221607b54b00cd28f3196fed0a24994dc308b8f611b682d60405160405180910390a25b5b50505b505b505b50565b6000806000809150600090505b60038054905081101561107957600160008581526020019081526020016000206000600383815481101515610fd757fe5b906000526020600020900160005b9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615611058576001820191505b60045482141561106b576001925061107a565b5b8080600101915050610fa6565b5b5050919050565b600080600090505b600380549050811015611149576001600084815260200190815260200160002060006003838154811015156110ba57fe5b906000526020600020900160005b9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161561113b576001820191505b5b8080600101915050611089565b5b50919050565b60006020528060005260406000206000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169080600101549080600201908060030160009054906101000a900460ff16905084565b6111b4612040565b600380548060200260200160405190810160405280929190818152602001828054801561123657602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190600101908083116111ec575b505050505090505b90565b611249612054565b611251612054565b6000806005546040518059106112645750595b908082528060200260200182016040525b50925060009150600090505b600554811015611322578580156112b8575060008082815260200190815260200160002060030160009054906101000a900460ff16155b806112eb57508480156112ea575060008082815260200190815260200160002060030160009054906101000a900460ff165b5b15611314578083838151811015156112ff57fe5b90602001906020020181815250506001820191505b5b8080600101915050611281565b8787036040518059106113325750595b908082528060200260200182016040525b5093508790505b8681101561139657828181518110151561136057fe5b906020019060200201518489830381518110151561137a57fe5b90602001906020020181815250505b808060010191505061134a565b5b505050949350505050565b6113aa612040565b6113b2612040565b6000806003805490506040518059106113c85750595b908082528060200260200182016040525b50925060009150600090505b60038054905081101561152b5760016000868152602001908152602001600020600060038381548110151561141657fe5b906000526020600020900160005b9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161561151d5760038181548110151561149f57fe5b906000526020600020900160005b9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1683838151811015156114da57fe5b9060200190602002019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250506001820191505b5b80806001019150506113e5565b816040518059106115395750595b908082528060200260200182016040525b509350600090505b818110156115ca57828181518110151561156857fe5b90602001906020020151848281518110151561158057fe5b9060200190602002019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b8080600101915050611552565b5b505050919050565b60055481565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561161357600080fd5b600380549050816032821115801561162b5750818111155b8015611638575060008114155b8015611645575060008214155b151561165057600080fd5b826004819055507fa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a836040518082815260200191505060405180910390a15b5b50505b50565b33600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615156116ef57600080fd5b81600080600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415151561174b57600080fd5b82336001600083815260200190815260200160002060008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515156117b757600080fd5b600180600087815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550843373ffffffffffffffffffffffffffffffffffffffff167f4a504a94899432a9846e1aa406dceb1bcfd538bb839071d49d1e5e23f5be30ef60405160405180910390a361186c85611bc0565b5b5b50505b505b5050565b6000611884848484611e6c565b905061188f81611696565b5b9392505050565b603281565b60045481565b60003073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156118de57600080fd5b82600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151561193757600080fd5b82600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615151561199157600080fd5b600092505b600380549050831015611a7f578473ffffffffffffffffffffffffffffffffffffffff166003848154811015156119c957fe5b906000526020600020900160005b9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415611a715783600384815481101515611a2257fe5b906000526020600020900160005b6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550611a7f565b5b8280600101935050611996565b6000600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506001600260008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508473ffffffffffffffffffffffffffffffffffffffff167f8001553a916ef2f495d26a907cc54d96ed840d7bda71e73194bf5a9df7a76b9060405160405180910390a28373ffffffffffffffffffffffffffffffffffffffff167ff39e6e1eb0edcf53c221607b54b00cd28f3196fed0a24994dc308b8f611b682d60405160405180910390a25b5b505b505b505050565b600033600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515611c1b57600080fd5b82336001600083815260200190815260200160002060008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515611c8657600080fd5b8460008082815260200190815260200160002060030160009054906101000a900460ff16151515611cb657600080fd5b611cbf86610f99565b15611e6057600080878152602001908152602001600020945060018560030160006101000a81548160ff021916908315150217905550611ddd8560000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16866001015487600201805460018160011615610100020316600290049050886002018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015611dd35780601f10611da857610100808354040283529160200191611dd3565b820191906000526020600020905b815481529060010190602001808311611db657829003601f168201915b5050505050611fc0565b15611e1457857f33e13ecb54c3076d8e8bb8c2881800a4d972b792045ffae98fdf46df365fed7560405160405180910390a2611e5f565b857f526441bb6c1aba3c9a4a6ca1d6545da9c2333c8c48343ef398eb858d72b7923660405160405180910390a260008560030160006101000a81548160ff0219169083151502179055505b5b5b5b505b50505b505050565b60008360008173ffffffffffffffffffffffffffffffffffffffff1614151515611e9557600080fd5b60055491506080604051908101604052808673ffffffffffffffffffffffffffffffffffffffff1681526020018581526020018481526020016000151581525060008084815260200190815260200160002060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550602082015181600101556040820151816002019080519060200190611f54929190612068565b5060608201518160030160006101000a81548160ff0219169083151502179055509050506001600560008282540192505081905550817fc0ba8fe4b176c1714197d43b9cc6bcf797a4a7461c5fe8d0ef6e184ae7601e5160405160405180910390a25b5b509392505050565b6000806040516020840160008287838a8c6187965a03f1925050508091505b50949350505050565b81548183558181151161200f5781836000526020600020918201910161200e91906120e8565b5b505050565b81548183558181151161203b5781836000526020600020918201910161203a91906120e8565b5b505050565b602060405190810160405280600081525090565b602060405190810160405280600081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106120a957805160ff19168380011785556120d7565b828001600101855582156120d7579182015b828111156120d65782518255916020019190600101906120bb565b5b5090506120e491906120e8565b5090565b61210a91905b808211156121065760008160009055506001016120ee565b5090565b905600a165627a7a72305820f1129b699b3017535535a920e15503cd06af1f5c77637c0637cc29355b1dad3400290000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000040000000000000000000000000cb1437200aea736788f1fc56f327c0456c3598d00000000000000000000000074dd76e24b2cfb43c1b1a4498295d553d0843746000000000000000000000000eeb4ceee443f9e0d17bdbd6daa241681ee5e51c2000000000000000000000000a005caea55375ae20e3aaef746113535503abc19" + }, + "0x1204700000000000000000000000000000000003": { + "constructor": "0x606060405234156200001057600080fd5b6040516200240138038062002401833981016040528080518201919060200180519060200190919050505b600082518260328211158015620000525750818111155b801562000060575060008114155b80156200006e575060008214155b15156200007a57600080fd5b600092505b8451831015620001b6576002600086858151811015156200009c57fe5b9060200190602002015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161580156200012b5750600085848151811015156200010857fe5b9060200190602002015173ffffffffffffffffffffffffffffffffffffffff1614155b15156200013757600080fd5b60016002600087868151811015156200014c57fe5b9060200190602002015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505b82806001019350506200007f565b8460039080519060200190620001ce929190620001e3565b50836004819055505b5b5050505050620002b8565b8280548282559060005260206000209081019282156200025f579160200282015b828111156200025e5782518260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055509160200191906001019062000204565b5b5090506200026e919062000272565b5090565b620002b591905b80821115620002b157600081816101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555060010162000279565b5090565b90565b61213980620002c86000396000f3006060604052361561011b576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063025e7c2714610177578063173825d9146101da57806320ea8d86146102135780632f54bf6e146102365780633411c81c1461028757806354741525146102e15780637065cb4814610325578063784547a71461035e5780638b51d13f146103995780639ace38c2146103d0578063a0e67e2b146104ce578063a8abe69a14610539578063b5dc40c3146105d1578063b77bf6001461064a578063ba51a6df14610673578063c01a8c8414610696578063c6427474146106b9578063d74f8edd14610752578063dc8452cd1461077b578063e20056e6146107a4578063ee22610b146107fc575b5b6000341115610174573373ffffffffffffffffffffffffffffffffffffffff167fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c346040518082815260200191505060405180910390a25b5b005b341561018257600080fd5b610198600480803590602001909190505061081f565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156101e557600080fd5b610211600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190505061085f565b005b341561021e57600080fd5b6102346004808035906020019091905050610b02565b005b341561024157600080fd5b61026d600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610cae565b604051808215151515815260200191505060405180910390f35b341561029257600080fd5b6102c7600480803590602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610cce565b604051808215151515815260200191505060405180910390f35b34156102ec57600080fd5b61030f600480803515159060200190919080351515906020019091905050610cfd565b6040518082815260200191505060405180910390f35b341561033057600080fd5b61035c600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610d91565b005b341561036957600080fd5b61037f6004808035906020019091905050610f99565b604051808215151515815260200191505060405180910390f35b34156103a457600080fd5b6103ba6004808035906020019091905050611081565b6040518082815260200191505060405180910390f35b34156103db57600080fd5b6103f16004808035906020019091905050611150565b604051808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200184815260200180602001831515151581526020018281038252848181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156104bc5780601f10610491576101008083540402835291602001916104bc565b820191906000526020600020905b81548152906001019060200180831161049f57829003601f168201915b50509550505050505060405180910390f35b34156104d957600080fd5b6104e16111ac565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b838110156105255780820151818401525b602081019050610509565b505050509050019250505060405180910390f35b341561054457600080fd5b610579600480803590602001909190803590602001909190803515159060200190919080351515906020019091905050611241565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b838110156105bd5780820151818401525b6020810190506105a1565b505050509050019250505060405180910390f35b34156105dc57600080fd5b6105f260048080359060200190919050506113a2565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b838110156106365780820151818401525b60208101905061061a565b505050509050019250505060405180910390f35b341561065557600080fd5b61065d6115d3565b6040518082815260200191505060405180910390f35b341561067e57600080fd5b61069460048080359060200190919050506115d9565b005b34156106a157600080fd5b6106b76004808035906020019091905050611696565b005b34156106c457600080fd5b61073c600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091905050611877565b6040518082815260200191505060405180910390f35b341561075d57600080fd5b610765611897565b6040518082815260200191505060405180910390f35b341561078657600080fd5b61078e61189c565b6040518082815260200191505060405180910390f35b34156107af57600080fd5b6107fa600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506118a2565b005b341561080757600080fd5b61081d6004808035906020019091905050611bc0565b005b60038181548110151561082e57fe5b906000526020600020900160005b915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60003073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561089b57600080fd5b81600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615156108f457600080fd5b6000600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550600091505b600160038054905003821015610a80578273ffffffffffffffffffffffffffffffffffffffff1660038381548110151561098757fe5b906000526020600020900160005b9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415610a725760036001600380549050038154811015156109e757fe5b906000526020600020900160005b9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600383815481101515610a2357fe5b906000526020600020900160005b6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550610a80565b5b8180600101925050610951565b6001600381818054905003915081610a989190611fe8565b506003805490506004541115610ab757610ab66003805490506115d9565b5b8273ffffffffffffffffffffffffffffffffffffffff167f8001553a916ef2f495d26a907cc54d96ed840d7bda71e73194bf5a9df7a76b9060405160405180910390a25b5b505b5050565b33600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515610b5b57600080fd5b81336001600083815260200190815260200160002060008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515610bc657600080fd5b8360008082815260200190815260200160002060030160009054906101000a900460ff16151515610bf657600080fd5b60006001600087815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550843373ffffffffffffffffffffffffffffffffffffffff167ff6a317157440607f36269043eb55f1287a5a19ba2216afeab88cd46cbcfb88e960405160405180910390a35b5b505b50505b5050565b60026020528060005260406000206000915054906101000a900460ff1681565b60016020528160005260406000206020528060005260406000206000915091509054906101000a900460ff1681565b600080600090505b600554811015610d8957838015610d3c575060008082815260200190815260200160002060030160009054906101000a900460ff16155b80610d6f5750828015610d6e575060008082815260200190815260200160002060030160009054906101000a900460ff165b5b15610d7b576001820191505b5b8080600101915050610d05565b5b5092915050565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610dcb57600080fd5b80600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151515610e2557600080fd5b8160008173ffffffffffffffffffffffffffffffffffffffff1614151515610e4c57600080fd5b60016003805490500160045460328211158015610e695750818111155b8015610e76575060008114155b8015610e83575060008214155b1515610e8e57600080fd5b6001600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555060038054806001018281610efa9190612014565b916000526020600020900160005b87909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550508473ffffffffffffffffffffffffffffffffffffffff167ff39e6e1eb0edcf53c221607b54b00cd28f3196fed0a24994dc308b8f611b682d60405160405180910390a25b5b50505b505b505b50565b6000806000809150600090505b60038054905081101561107957600160008581526020019081526020016000206000600383815481101515610fd757fe5b906000526020600020900160005b9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615611058576001820191505b60045482141561106b576001925061107a565b5b8080600101915050610fa6565b5b5050919050565b600080600090505b600380549050811015611149576001600084815260200190815260200160002060006003838154811015156110ba57fe5b906000526020600020900160005b9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161561113b576001820191505b5b8080600101915050611089565b5b50919050565b60006020528060005260406000206000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169080600101549080600201908060030160009054906101000a900460ff16905084565b6111b4612040565b600380548060200260200160405190810160405280929190818152602001828054801561123657602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190600101908083116111ec575b505050505090505b90565b611249612054565b611251612054565b6000806005546040518059106112645750595b908082528060200260200182016040525b50925060009150600090505b600554811015611322578580156112b8575060008082815260200190815260200160002060030160009054906101000a900460ff16155b806112eb57508480156112ea575060008082815260200190815260200160002060030160009054906101000a900460ff165b5b15611314578083838151811015156112ff57fe5b90602001906020020181815250506001820191505b5b8080600101915050611281565b8787036040518059106113325750595b908082528060200260200182016040525b5093508790505b8681101561139657828181518110151561136057fe5b906020019060200201518489830381518110151561137a57fe5b90602001906020020181815250505b808060010191505061134a565b5b505050949350505050565b6113aa612040565b6113b2612040565b6000806003805490506040518059106113c85750595b908082528060200260200182016040525b50925060009150600090505b60038054905081101561152b5760016000868152602001908152602001600020600060038381548110151561141657fe5b906000526020600020900160005b9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161561151d5760038181548110151561149f57fe5b906000526020600020900160005b9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1683838151811015156114da57fe5b9060200190602002019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250506001820191505b5b80806001019150506113e5565b816040518059106115395750595b908082528060200260200182016040525b509350600090505b818110156115ca57828181518110151561156857fe5b90602001906020020151848281518110151561158057fe5b9060200190602002019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b8080600101915050611552565b5b505050919050565b60055481565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561161357600080fd5b600380549050816032821115801561162b5750818111155b8015611638575060008114155b8015611645575060008214155b151561165057600080fd5b826004819055507fa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a836040518082815260200191505060405180910390a15b5b50505b50565b33600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615156116ef57600080fd5b81600080600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415151561174b57600080fd5b82336001600083815260200190815260200160002060008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515156117b757600080fd5b600180600087815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550843373ffffffffffffffffffffffffffffffffffffffff167f4a504a94899432a9846e1aa406dceb1bcfd538bb839071d49d1e5e23f5be30ef60405160405180910390a361186c85611bc0565b5b5b50505b505b5050565b6000611884848484611e6c565b905061188f81611696565b5b9392505050565b603281565b60045481565b60003073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156118de57600080fd5b82600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151561193757600080fd5b82600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615151561199157600080fd5b600092505b600380549050831015611a7f578473ffffffffffffffffffffffffffffffffffffffff166003848154811015156119c957fe5b906000526020600020900160005b9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415611a715783600384815481101515611a2257fe5b906000526020600020900160005b6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550611a7f565b5b8280600101935050611996565b6000600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506001600260008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508473ffffffffffffffffffffffffffffffffffffffff167f8001553a916ef2f495d26a907cc54d96ed840d7bda71e73194bf5a9df7a76b9060405160405180910390a28373ffffffffffffffffffffffffffffffffffffffff167ff39e6e1eb0edcf53c221607b54b00cd28f3196fed0a24994dc308b8f611b682d60405160405180910390a25b5b505b505b505050565b600033600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515611c1b57600080fd5b82336001600083815260200190815260200160002060008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515611c8657600080fd5b8460008082815260200190815260200160002060030160009054906101000a900460ff16151515611cb657600080fd5b611cbf86610f99565b15611e6057600080878152602001908152602001600020945060018560030160006101000a81548160ff021916908315150217905550611ddd8560000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16866001015487600201805460018160011615610100020316600290049050886002018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015611dd35780601f10611da857610100808354040283529160200191611dd3565b820191906000526020600020905b815481529060010190602001808311611db657829003601f168201915b5050505050611fc0565b15611e1457857f33e13ecb54c3076d8e8bb8c2881800a4d972b792045ffae98fdf46df365fed7560405160405180910390a2611e5f565b857f526441bb6c1aba3c9a4a6ca1d6545da9c2333c8c48343ef398eb858d72b7923660405160405180910390a260008560030160006101000a81548160ff0219169083151502179055505b5b5b5b505b50505b505050565b60008360008173ffffffffffffffffffffffffffffffffffffffff1614151515611e9557600080fd5b60055491506080604051908101604052808673ffffffffffffffffffffffffffffffffffffffff1681526020018581526020018481526020016000151581525060008084815260200190815260200160002060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550602082015181600101556040820151816002019080519060200190611f54929190612068565b5060608201518160030160006101000a81548160ff0219169083151502179055509050506001600560008282540192505081905550817fc0ba8fe4b176c1714197d43b9cc6bcf797a4a7461c5fe8d0ef6e184ae7601e5160405160405180910390a25b5b509392505050565b6000806040516020840160008287838a8c6187965a03f1925050508091505b50949350505050565b81548183558181151161200f5781836000526020600020918201910161200e91906120e8565b5b505050565b81548183558181151161203b5781836000526020600020918201910161203a91906120e8565b5b505050565b602060405190810160405280600081525090565b602060405190810160405280600081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106120a957805160ff19168380011785556120d7565b828001600101855582156120d7579182015b828111156120d65782518255916020019190600101906120bb565b5b5090506120e491906120e8565b5090565b61210a91905b808211156121065760008160009055506001016120ee565b5090565b905600a165627a7a72305820f1129b699b3017535535a920e15503cd06af1f5c77637c0637cc29355b1dad3400290000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000040000000000000000000000000cb1437200aea736788f1fc56f327c0456c3598d00000000000000000000000074dd76e24b2cfb43c1b1a4498295d553d0843746000000000000000000000000eeb4ceee443f9e0d17bdbd6daa241681ee5e51c2000000000000000000000000a005caea55375ae20e3aaef746113535503abc19" + }, + "0x120470000000000000000000000000000000000a": { + "balance": "11310499300000000000000000", + "constructor": "0x606060405234156200001057600080fd5b6040516200240138038062002401833981016040528080518201919060200180519060200190919050505b600082518260328211158015620000525750818111155b801562000060575060008114155b80156200006e575060008214155b15156200007a57600080fd5b600092505b8451831015620001b6576002600086858151811015156200009c57fe5b9060200190602002015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161580156200012b5750600085848151811015156200010857fe5b9060200190602002015173ffffffffffffffffffffffffffffffffffffffff1614155b15156200013757600080fd5b60016002600087868151811015156200014c57fe5b9060200190602002015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505b82806001019350506200007f565b8460039080519060200190620001ce929190620001e3565b50836004819055505b5b5050505050620002b8565b8280548282559060005260206000209081019282156200025f579160200282015b828111156200025e5782518260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055509160200191906001019062000204565b5b5090506200026e919062000272565b5090565b620002b591905b80821115620002b157600081816101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555060010162000279565b5090565b90565b61213980620002c86000396000f3006060604052361561011b576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063025e7c2714610177578063173825d9146101da57806320ea8d86146102135780632f54bf6e146102365780633411c81c1461028757806354741525146102e15780637065cb4814610325578063784547a71461035e5780638b51d13f146103995780639ace38c2146103d0578063a0e67e2b146104ce578063a8abe69a14610539578063b5dc40c3146105d1578063b77bf6001461064a578063ba51a6df14610673578063c01a8c8414610696578063c6427474146106b9578063d74f8edd14610752578063dc8452cd1461077b578063e20056e6146107a4578063ee22610b146107fc575b5b6000341115610174573373ffffffffffffffffffffffffffffffffffffffff167fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c346040518082815260200191505060405180910390a25b5b005b341561018257600080fd5b610198600480803590602001909190505061081f565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156101e557600080fd5b610211600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190505061085f565b005b341561021e57600080fd5b6102346004808035906020019091905050610b02565b005b341561024157600080fd5b61026d600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610cae565b604051808215151515815260200191505060405180910390f35b341561029257600080fd5b6102c7600480803590602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610cce565b604051808215151515815260200191505060405180910390f35b34156102ec57600080fd5b61030f600480803515159060200190919080351515906020019091905050610cfd565b6040518082815260200191505060405180910390f35b341561033057600080fd5b61035c600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610d91565b005b341561036957600080fd5b61037f6004808035906020019091905050610f99565b604051808215151515815260200191505060405180910390f35b34156103a457600080fd5b6103ba6004808035906020019091905050611081565b6040518082815260200191505060405180910390f35b34156103db57600080fd5b6103f16004808035906020019091905050611150565b604051808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200184815260200180602001831515151581526020018281038252848181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156104bc5780601f10610491576101008083540402835291602001916104bc565b820191906000526020600020905b81548152906001019060200180831161049f57829003601f168201915b50509550505050505060405180910390f35b34156104d957600080fd5b6104e16111ac565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b838110156105255780820151818401525b602081019050610509565b505050509050019250505060405180910390f35b341561054457600080fd5b610579600480803590602001909190803590602001909190803515159060200190919080351515906020019091905050611241565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b838110156105bd5780820151818401525b6020810190506105a1565b505050509050019250505060405180910390f35b34156105dc57600080fd5b6105f260048080359060200190919050506113a2565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b838110156106365780820151818401525b60208101905061061a565b505050509050019250505060405180910390f35b341561065557600080fd5b61065d6115d3565b6040518082815260200191505060405180910390f35b341561067e57600080fd5b61069460048080359060200190919050506115d9565b005b34156106a157600080fd5b6106b76004808035906020019091905050611696565b005b34156106c457600080fd5b61073c600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091905050611877565b6040518082815260200191505060405180910390f35b341561075d57600080fd5b610765611897565b6040518082815260200191505060405180910390f35b341561078657600080fd5b61078e61189c565b6040518082815260200191505060405180910390f35b34156107af57600080fd5b6107fa600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506118a2565b005b341561080757600080fd5b61081d6004808035906020019091905050611bc0565b005b60038181548110151561082e57fe5b906000526020600020900160005b915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60003073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561089b57600080fd5b81600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615156108f457600080fd5b6000600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550600091505b600160038054905003821015610a80578273ffffffffffffffffffffffffffffffffffffffff1660038381548110151561098757fe5b906000526020600020900160005b9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415610a725760036001600380549050038154811015156109e757fe5b906000526020600020900160005b9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600383815481101515610a2357fe5b906000526020600020900160005b6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550610a80565b5b8180600101925050610951565b6001600381818054905003915081610a989190611fe8565b506003805490506004541115610ab757610ab66003805490506115d9565b5b8273ffffffffffffffffffffffffffffffffffffffff167f8001553a916ef2f495d26a907cc54d96ed840d7bda71e73194bf5a9df7a76b9060405160405180910390a25b5b505b5050565b33600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515610b5b57600080fd5b81336001600083815260200190815260200160002060008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515610bc657600080fd5b8360008082815260200190815260200160002060030160009054906101000a900460ff16151515610bf657600080fd5b60006001600087815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550843373ffffffffffffffffffffffffffffffffffffffff167ff6a317157440607f36269043eb55f1287a5a19ba2216afeab88cd46cbcfb88e960405160405180910390a35b5b505b50505b5050565b60026020528060005260406000206000915054906101000a900460ff1681565b60016020528160005260406000206020528060005260406000206000915091509054906101000a900460ff1681565b600080600090505b600554811015610d8957838015610d3c575060008082815260200190815260200160002060030160009054906101000a900460ff16155b80610d6f5750828015610d6e575060008082815260200190815260200160002060030160009054906101000a900460ff165b5b15610d7b576001820191505b5b8080600101915050610d05565b5b5092915050565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610dcb57600080fd5b80600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151515610e2557600080fd5b8160008173ffffffffffffffffffffffffffffffffffffffff1614151515610e4c57600080fd5b60016003805490500160045460328211158015610e695750818111155b8015610e76575060008114155b8015610e83575060008214155b1515610e8e57600080fd5b6001600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555060038054806001018281610efa9190612014565b916000526020600020900160005b87909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550508473ffffffffffffffffffffffffffffffffffffffff167ff39e6e1eb0edcf53c221607b54b00cd28f3196fed0a24994dc308b8f611b682d60405160405180910390a25b5b50505b505b505b50565b6000806000809150600090505b60038054905081101561107957600160008581526020019081526020016000206000600383815481101515610fd757fe5b906000526020600020900160005b9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615611058576001820191505b60045482141561106b576001925061107a565b5b8080600101915050610fa6565b5b5050919050565b600080600090505b600380549050811015611149576001600084815260200190815260200160002060006003838154811015156110ba57fe5b906000526020600020900160005b9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161561113b576001820191505b5b8080600101915050611089565b5b50919050565b60006020528060005260406000206000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169080600101549080600201908060030160009054906101000a900460ff16905084565b6111b4612040565b600380548060200260200160405190810160405280929190818152602001828054801561123657602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190600101908083116111ec575b505050505090505b90565b611249612054565b611251612054565b6000806005546040518059106112645750595b908082528060200260200182016040525b50925060009150600090505b600554811015611322578580156112b8575060008082815260200190815260200160002060030160009054906101000a900460ff16155b806112eb57508480156112ea575060008082815260200190815260200160002060030160009054906101000a900460ff165b5b15611314578083838151811015156112ff57fe5b90602001906020020181815250506001820191505b5b8080600101915050611281565b8787036040518059106113325750595b908082528060200260200182016040525b5093508790505b8681101561139657828181518110151561136057fe5b906020019060200201518489830381518110151561137a57fe5b90602001906020020181815250505b808060010191505061134a565b5b505050949350505050565b6113aa612040565b6113b2612040565b6000806003805490506040518059106113c85750595b908082528060200260200182016040525b50925060009150600090505b60038054905081101561152b5760016000868152602001908152602001600020600060038381548110151561141657fe5b906000526020600020900160005b9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161561151d5760038181548110151561149f57fe5b906000526020600020900160005b9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1683838151811015156114da57fe5b9060200190602002019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250506001820191505b5b80806001019150506113e5565b816040518059106115395750595b908082528060200260200182016040525b509350600090505b818110156115ca57828181518110151561156857fe5b90602001906020020151848281518110151561158057fe5b9060200190602002019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b8080600101915050611552565b5b505050919050565b60055481565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561161357600080fd5b600380549050816032821115801561162b5750818111155b8015611638575060008114155b8015611645575060008214155b151561165057600080fd5b826004819055507fa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a836040518082815260200191505060405180910390a15b5b50505b50565b33600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615156116ef57600080fd5b81600080600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415151561174b57600080fd5b82336001600083815260200190815260200160002060008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515156117b757600080fd5b600180600087815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550843373ffffffffffffffffffffffffffffffffffffffff167f4a504a94899432a9846e1aa406dceb1bcfd538bb839071d49d1e5e23f5be30ef60405160405180910390a361186c85611bc0565b5b5b50505b505b5050565b6000611884848484611e6c565b905061188f81611696565b5b9392505050565b603281565b60045481565b60003073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156118de57600080fd5b82600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151561193757600080fd5b82600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615151561199157600080fd5b600092505b600380549050831015611a7f578473ffffffffffffffffffffffffffffffffffffffff166003848154811015156119c957fe5b906000526020600020900160005b9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415611a715783600384815481101515611a2257fe5b906000526020600020900160005b6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550611a7f565b5b8280600101935050611996565b6000600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506001600260008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508473ffffffffffffffffffffffffffffffffffffffff167f8001553a916ef2f495d26a907cc54d96ed840d7bda71e73194bf5a9df7a76b9060405160405180910390a28373ffffffffffffffffffffffffffffffffffffffff167ff39e6e1eb0edcf53c221607b54b00cd28f3196fed0a24994dc308b8f611b682d60405160405180910390a25b5b505b505b505050565b600033600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515611c1b57600080fd5b82336001600083815260200190815260200160002060008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515611c8657600080fd5b8460008082815260200190815260200160002060030160009054906101000a900460ff16151515611cb657600080fd5b611cbf86610f99565b15611e6057600080878152602001908152602001600020945060018560030160006101000a81548160ff021916908315150217905550611ddd8560000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16866001015487600201805460018160011615610100020316600290049050886002018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015611dd35780601f10611da857610100808354040283529160200191611dd3565b820191906000526020600020905b815481529060010190602001808311611db657829003601f168201915b5050505050611fc0565b15611e1457857f33e13ecb54c3076d8e8bb8c2881800a4d972b792045ffae98fdf46df365fed7560405160405180910390a2611e5f565b857f526441bb6c1aba3c9a4a6ca1d6545da9c2333c8c48343ef398eb858d72b7923660405160405180910390a260008560030160006101000a81548160ff0219169083151502179055505b5b5b5b505b50505b505050565b60008360008173ffffffffffffffffffffffffffffffffffffffff1614151515611e9557600080fd5b60055491506080604051908101604052808673ffffffffffffffffffffffffffffffffffffffff1681526020018581526020018481526020016000151581525060008084815260200190815260200160002060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550602082015181600101556040820151816002019080519060200190611f54929190612068565b5060608201518160030160006101000a81548160ff0219169083151502179055509050506001600560008282540192505081905550817fc0ba8fe4b176c1714197d43b9cc6bcf797a4a7461c5fe8d0ef6e184ae7601e5160405160405180910390a25b5b509392505050565b6000806040516020840160008287838a8c6187965a03f1925050508091505b50949350505050565b81548183558181151161200f5781836000526020600020918201910161200e91906120e8565b5b505050565b81548183558181151161203b5781836000526020600020918201910161203a91906120e8565b5b505050565b602060405190810160405280600081525090565b602060405190810160405280600081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106120a957805160ff19168380011785556120d7565b828001600101855582156120d7579182015b828111156120d65782518255916020019190600101906120bb565b5b5090506120e491906120e8565b5090565b61210a91905b808211156121065760008160009055506001016120ee565b5090565b905600a165627a7a72305820f1129b699b3017535535a920e15503cd06af1f5c77637c0637cc29355b1dad3400290000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000040000000000000000000000000cb1437200aea736788f1fc56f327c0456c3598d00000000000000000000000074dd76e24b2cfb43c1b1a4498295d553d0843746000000000000000000000000eeb4ceee443f9e0d17bdbd6daa241681ee5e51c2000000000000000000000000a005caea55375ae20e3aaef746113535503abc19" + }, + "0x0cB1437200aea736788f1Fc56F327c0456c3598D": { + "balance": "250000000000000000" + }, + "0x74dd76E24B2CFB43C1b1a4498295d553D0843746": { + "balance": "250000000000000000" + }, + "0xeeB4CEEe443F9e0D17BdBD6Daa241681EE5E51c2": { + "balance": "250000000000000000" + }, + "0xA005caEa55375ae20e3aAEF746113535503ABC19": { + "balance": "250000000000000000" + }, + "0x1204700000000000000000000000000000000001": { + "constructor": "0x60806040523480156200001157600080fd5b5060405162002f1538038062002f15833981018060405260608110156200003757600080fd5b81019080805190602001909291908051906020019092919080516401000000008111156200006457600080fd5b828101905060208101848111156200007b57600080fd5b81518560208202830111640100000000821117156200009957600080fd5b5050929190505050336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415620001e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602481526020018062002ec56024913960400191505060405180910390fd5b60018151101562000242576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c81526020018062002ee9602c913960400191505060405180910390fd5b6200025c8362000473640100000000026401000000009004565b6200027682620005d5640100000000026401000000009004565b60008090505b81518110156200042057600073ffffffffffffffffffffffffffffffffffffffff16828281518110620002ab57fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614156200033e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f56616c696461746f7220616464726573732063616e6e6f74206265203078300081525060200191505060405180910390fd5b6001600360008484815181106200035157fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160006101000a81548160ff02191690836003811115620003b257fe5b02179055508060036000848481518110620003c957fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001018190555080806001019150506200027c565b508060029080519060200190620004399291906200065c565b50600260019080546200044e929190620006eb565b506001600060146101000a81548160ff02191690831515021790555050505062000788565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141562000517576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f4e6577206f776e657220616464726573732063616e6e6f74206265203078300081525060200191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b80600560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167fe8ec518081a7aa1fc5d586a5443a858ab130be8b8e39b545172c879a7e242c6b60405160405180910390a250565b828054828255906000526020600020908101928215620006d8579160200282015b82811115620006d75782518260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550916020019190600101906200067d565b5b509050620006e7919062000742565b5090565b8280548282559060005260206000209081019282156200072f5760005260206000209182015b828111156200072e57825482559160010191906001019062000711565b5b5090506200073e919062000742565b5090565b6200078591905b808211156200078157600081816101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555060010162000749565b5090565b90565b61272d80620007986000396000f3fe608060405234801561001057600080fd5b506004361061015f576000357c0100000000000000000000000000000000000000000000000000000000900480639f723637116100d5578063b980490911610099578063b980490914610594578063bd21442a146105f0578063c805f68b146106b3578063d826b7f1146106f7578063f2fde38b14610765578063f3aeac02146107a95761015f565b80639f7236371461040e578063a00745b61461046d578063a6940b07146104c9578063b3f05b9714610513578063b7ab4db5146105355761015f565b8063455701d611610127578063455701d6146102eb5780634d238c8e1461034a578063715018a61461038e57806375286211146103985780638da5cb5b146103a25780638f32d59b146103ec5761015f565b8063267fa41d1461016457806334ba3c1b146101c057806340550a1c146101de57806340a141ff1461023a578063418349551461027e575b600080fd5b6101a66004803603602081101561017a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610805565b604051808215151515815260200191505060405180910390f35b6101c8610877565b6040518082815260200191505060405180910390f35b610220600480360360208110156101f457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610884565b604051808215151515815260200191505060405180910390f35b61027c6004803603602081101561025057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610965565b005b6102c06004803603602081101561029457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610ab0565b604051808360038111156102d057fe5b60ff1681526020018281526020019250505060405180910390f35b6102f3610ae1565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b8381101561033657808201518184015260208101905061031b565b505050509050019250505060405180910390f35b61038c6004803603602081101561036057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610b6f565b005b610396610d79565b005b6103a0610eb2565b005b6103aa611328565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6103f4611351565b604051808215151515815260200191505060405180910390f35b6104166113a8565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b8381101561045957808201518184015260208101905061043e565b505050509050019250505060405180910390f35b6104af6004803603602081101561048357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506114d7565b604051808215151515815260200191505060405180910390f35b6104d16115b8565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61051b6115de565b604051808215151515815260200191505060405180910390f35b61053d6115f1565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b83811015610580578082015181840152602081019050610565565b505050509050019250505060405180910390f35b6105d6600480360360208110156105aa57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061167f565b604051808215151515815260200191505060405180910390f35b6106b16004803603608081101561060657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561066d57600080fd5b82018360208201111561067f57600080fd5b803590602001918460018302840111640100000000831117156106a157600080fd5b90919293919293905050506116f0565b005b6106f5600480360360208110156106c957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061194c565b005b6107636004803603606081101561070d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611aff565b005b6107a76004803603602081101561077b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611d59565b005b6107eb600480360360208110156107bf57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611ddf565b604051808215151515815260200191505060405180910390f35b60006001600381111561081457fe5b600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff16600381111561086f57fe5b149050919050565b6000600180549050905090565b60006001600381111561089357fe5b600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff1660038111156108ee57fe5b148061095e575060038081111561090157fe5b600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff16600381111561095c57fe5b145b9050919050565b61096d611351565b6109df576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f53656e646572206973206e6f74206f776e65720000000000000000000000000081525060200191505060405180910390fd5b600060149054906101000a900460ff16610a44576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806126736022913960400191505060405180910390fd5b80610a4e81610884565b610aa3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806126516022913960400191505060405180910390fd5b610aac82611e51565b5050565b60036020528060005260406000206000915090508060000160009054906101000a900460ff16908060010154905082565b60606002805480602002602001604051908101604052809291908181526020018280548015610b6557602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311610b1b575b5050505050905090565b610b77611351565b610be9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f53656e646572206973206e6f74206f776e65720000000000000000000000000081525060200191505060405180910390fd5b600060149054906101000a900460ff16610c4e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806126736022913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610cf1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f56616c696461746f7220616464726573732063616e6e6f74206265203078300081525060200191505060405180910390fd5b610cfa81610884565b15610d6d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f546869732076616c696461746f7220697320616c72656164792061637469766581525060200191505060405180910390fd5b610d76816120a4565b50565b610d81611351565b610df3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f53656e646572206973206e6f74206f776e65720000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a360008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b600060149054906101000a900460ff1615610f35576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f56616c696461746f72207365742069732066696e616c697a656400000000000081525060200191505060405180910390fd5b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610ff8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f43616c6c6572206973206e6f74207468652052656c617920636f6e747261637481525060200191505060405180910390fd5b6001600060146101000a81548160ff02191690831515021790555060008090505b6002805490508110156110dd576000600360006002848154811061103957fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905060018160000160006101000a81548160ff021916908360038111156110c157fe5b0217905550818160010181905550508080600101915050611019565b50600073ffffffffffffffffffffffffffffffffffffffff16600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461126757600060036000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160006101000a81548160ff021916908360038111156111b557fe5b0217905550600060036000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101819055506000600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b6002600190805461127992919061251f565b507f8564cd629b15f47dc310d45bcbfc9bcf5420b0d51bf0659a16c67f91d276325360016040518080602001828103825283818154815260200191508054801561131857602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190600101908083116112ce575b50509250505060405180910390a1565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614905090565b6060600180549050600280549050111561144a57600280548060200260200160405190810160405280929190818152602001828054801561143e57602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190600101908083116113f4575b505050505090506114d4565b60018054806020026020016040519081016040528092919081815260200182805480156114cc57602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311611482575b505050505090505b90565b6000600260038111156114e657fe5b600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff16600381111561154157fe5b14806115b1575060038081111561155457fe5b600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff1660038111156115af57fe5b145b9050919050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600060149054906101000a900460ff1681565b6060600180548060200260200160405190810160405280929190818152602001828054801561167557602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001906001019080831161162b575b5050505050905090565b600060038081111561168d57fe5b600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff1660038111156116e857fe5b149050919050565b846116fa81610884565b61174f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806126516022913960400191505060405180910390fd5b8461175981610884565b6117ae576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806126516022913960400191505060405180910390fd5b84438110611824576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f426c6f636b206e756d626572206973206e6f742076616c69640000000000000081525060200191505060405180910390fd5b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146118e7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f43616c6c6572206973206e6f74207468652052656c617920636f6e747261637481525060200191505060405180910390fd5b858773ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff167f729a19138e072a5a8d3a56d74ae0b5c84530f09aacd6e12b24c5b2fdc3f8a3d060405160405180910390a45050505050505050565b611954611351565b6119c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f53656e646572206973206e6f74206f776e65720000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611a4c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260248152602001806126066024913960400191505060405180910390fd5b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611af3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260408152602001806126956040913960400191505060405180910390fd5b611afc81612179565b50565b82611b0981610884565b611b5e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806126516022913960400191505060405180910390fd5b82611b6881610884565b611bbd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806126516022913960400191505060405180910390fd5b82438110611c33576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f426c6f636b206e756d626572206973206e6f742076616c69640000000000000081525060200191505060405180910390fd5b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611cf6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f43616c6c6572206973206e6f74207468652052656c617920636f6e747261637481525060200191505060405180910390fd5b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fbc459bd9db54016b1966d0fe812bbe0a82cd627ae3eacd01727dc63a432ca41b60405160405180910390a4505050505050565b611d61611351565b611dd3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f53656e646572206973206e6f74206f776e65720000000000000000000000000081525060200191505060405180910390fd5b611ddc81612200565b50565b600060026003811115611dee57fe5b600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff166003811115611e4957fe5b149050919050565b600160028054905011611eaf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602781526020018061262a6027913960400191505060405180910390fd5b6000600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010154905060006001600280549050039050600060028281548110611f1257fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508060028481548110611f4d57fe5b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555082600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101819055506002805480919060019003611ff19190612571565b5060038060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160006101000a81548160ff0219169083600381111561205057fe5b021790555083600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555061209e612361565b50505050565b6002600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160006101000a81548160ff0219169083600381111561210357fe5b021790555060028190806001815401808255809150509060018203906000526020600020016000909192909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050612176612361565b50565b80600560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167fe8ec518081a7aa1fc5d586a5443a858ab130be8b8e39b545172c879a7e242c6b60405160405180910390a250565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156122a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f4e6577206f776e657220616464726573732063616e6e6f74206265203078300081525060200191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60008060146101000a81548160ff021916908315150217905550600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a084718a600143034060026040518363ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018083815260200180602001828103825283818154815260200191508054801561246c57602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311612422575b50509350505050602060405180830381600087803b15801561248d57600080fd5b505af11580156124a1573d6000803e3d6000fd5b505050506040513d60208110156124b757600080fd5b810190808051906020019092919050505061251d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602d8152602001806126d5602d913960400191505060405180910390fd5b565b8280548282559060005260206000209081019282156125605760005260206000209182015b8281111561255f578254825591600101919060010190612544565b5b50905061256d919061259d565b5090565b8154818355818111156125985781836000526020600020918201910161259791906125e0565b5b505050565b6125dd91905b808211156125d957600081816101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055506001016125a3565b5090565b90565b61260291905b808211156125fe5760008160009055506001016125e6565b5090565b9056fe52656c617920636f6e747261637420616464726573732063616e6e6f74206265203078305468657265206d757374206265206174206c6561737420312076616c696461746f72206c65667441646472657373206973206e6f7420616e206163746976652076616c696461746f7256616c696461746f7220736574206973206e6f742066696e616c697a6564207965744e65772072656c617920636f6e747261637420616464726573732063616e6e6f74206265207468652073616d65206173207468652063757272656e74206f6e6552656c617920636f6e747261637420496e6974696174654368616e67652063616c6c6261636b206661696c6564a165627a7a72305820c6b083565ee91eecaf8e5a6f14e1677206b36466bdfe0248a47919657b68255b002952656c617920636f6e747261637420616464726573732063616e6e6f74206265203078305468657265206d757374206265206174206c6561737420312076616c696461746f7220696e697469616c6c79000000000000000000000000120470000000000000000000000000000000000500000000000000000000000012047000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000300000000000000000000000036f67dd84e7327c10c7ead6c429a47189798fbdc00000000000000000000000020df7a4e8408add37c6a5c4afc1b1509924619fe00000000000000000000000077901f14183b1669c80e8c6137ff6721c9a26b25" + }, + "0x1204700000000000000000000000000000000000": { + "constructor": "0x608060405273fffffffffffffffffffffffffffffffffffffffe600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555034801561006557600080fd5b506040516040806116c18339810180604052604081101561008557600080fd5b810190808051906020019092919080519060200190929190505050336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a361017482610193640100000000026401000000009004565b61018c816102f4640100000000026401000000009004565b5050610506565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610236576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f4e6577206f776e657220616464726573732063616e6e6f74206265203078300081525060200191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b80600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610398576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260158152602001807f416464726573732063616e6e6f7420626520307830000000000000000000000081525060200191505060405180910390fd5b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561043f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252604281526020018061167f6042913960600191505060405180910390fd5b6000600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905082600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f4fea88aaf04c303804bb211ecc32a00ac8e5f0656bb854cad8a4a2e438256b7460405160405180910390a3505050565b61116a806105156000396000f3fe608060405234801561001057600080fd5b50600436106100d1576000357c010000000000000000000000000000000000000000000000000000000090048063b7ab4db51161008e578063b7ab4db51461023b578063bd9656771461029a578063c476dd40146102de578063d3e848f114610381578063d69f13bb146103cb578063f2fde38b14610419576100d1565b8063715018a6146100d657806375286211146100e05780638da5cb5b146100ea5780638f32d59b14610134578063a084718a14610156578063ae3783d6146101f1575b600080fd5b6100de61045d565b005b6100e8610596565b005b6100f26106f9565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61013c610722565b604051808215151515815260200191505060405180910390f35b6101d76004803603604081101561016c57600080fd5b81019080803590602001909291908035906020019064010000000081111561019357600080fd5b8201836020820111156101a557600080fd5b803590602001918460208302840111640100000000831117156101c757600080fd5b9091929391929390505050610779565b604051808215151515815260200191505060405180910390f35b6101f9610893565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6102436108b9565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b8381101561028657808201518184015260208101905061026b565b505050509050019250505060405180910390f35b6102dc600480360360208110156102b057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506109d5565b005b61037f600480360360608110156102f457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561033b57600080fd5b82018360208201111561034d57600080fd5b8035906020019184600183028401116401000000008311171561036f57600080fd5b9091929391929390505050610a5b565b005b610389610ba6565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610417600480360360408110156103e157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610bcc565b005b61045b6004803603602081101561042f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610ce1565b005b610465610722565b6104d7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f53656e646572206973206e6f74206f776e65720000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a360008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610659576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f53656e646572206973206e6f742073797374656d00000000000000000000000081525060200191505060405180910390fd5b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663752862116040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401600060405180830381600087803b1580156106df57600080fd5b505af11580156106f3573d6000803e3d6000fd5b50505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614905090565b6000600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610821576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602281526020018061111d6022913960400191505060405180910390fd5b837f55252fa6eee4741b4e24a74a70e9c11fd2c2281df8d6ea13126ff845f7825c89848460405180806020018281038252848482818152602001925060200280828437600081840152601f19601f820116905080830192505050935050505060405180910390a2600190509392505050565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6060600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b7ab4db56040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160006040518083038186803b15801561093f57600080fd5b505afa158015610953573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250602081101561097d57600080fd5b81019080805164010000000081111561099557600080fd5b828101905060208101848111156109ab57600080fd5b81518560208202830111640100000000821117156109c857600080fd5b5050929190505050905090565b6109dd610722565b610a4f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f53656e646572206973206e6f74206f776e65720000000000000000000000000081525060200191505060405180910390fd5b610a5881610d67565b50565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bd21442a33868686866040518663ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001848152602001806020018281038252848482818152602001925080828437600081840152601f19601f8201169050808301925050509650505050505050600060405180830381600087803b158015610b8857600080fd5b505af1158015610b9c573d6000803e3d6000fd5b5050505050505050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d826b7f13384846040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050600060405180830381600087803b158015610cc557600080fd5b505af1158015610cd9573d6000803e3d6000fd5b505050505050565b610ce9610722565b610d5b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f53656e646572206973206e6f74206f776e65720000000000000000000000000081525060200191505060405180910390fd5b610d6481610f79565b50565b80600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610e0b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260158152602001807f416464726573732063616e6e6f7420626520307830000000000000000000000081525060200191505060405180910390fd5b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610eb2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260428152602001806110db6042913960600191505060405180910390fd5b6000600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905082600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f4fea88aaf04c303804bb211ecc32a00ac8e5f0656bb854cad8a4a2e438256b7460405160405180910390a3505050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561101c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f4e6577206f776e657220616464726573732063616e6e6f74206265203078300081525060200191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505056fe4e65772072656c6179656420636f6e747261637420616464726573732063616e6e6f74206265207468652073616d65206173207468652063757272656e74206f6e6553656e646572206973206e6f74207468652052656c6179656420636f6e7472616374a165627a7a72305820df8e72037cf9237ba09d135b3962a00a0186ba17dcbbe421274543975b2c346100294e65772072656c6179656420636f6e747261637420616464726573732063616e6e6f74206265207468652073616d65206173207468652063757272656e74206f6e6500000000000000000000000012047000000000000000000000000000000000050000000000000000000000001204700000000000000000000000000000000001" + }, + "0x1204700000000000000000000000000000000002": { + "constructor": "0x608060405273fffffffffffffffffffffffffffffffffffffffe600960006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055503480156200006657600080fd5b5060405160408062001b22833981018060405260408110156200008857600080fd5b810190808051906020019092919080519060200190929190505050620000bc6200010c640100000000026401000000009004565b81600b60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600a81905550505062000825565b60405180610f0001604052806704398372e97bae8081526020016704398372e97bae8081526020016704398372e97bae8081526020016704398372e97bae8081526020016704398372e97bae8081526020016704398372e97bae8081526020016704398372e97bae8081526020016704395680a6af46808152602001670438cfa9de4a0e808152602001670437eeee904c06808152602001670436b44ebcb52e8081526020016704351fca638586808152602001670433316184bd0e808152602001670430e914205bc680815260200167042e46e23661ae80815260200167042b4acbc6cec6808152602001670427f4d0d1a30e80815260200167042444f156de868081526020016704203b2d56812e80815260200167041bd784d08b0680815260200167041719f7c4fc0e808152602001670412028633d44680815260200167040c91301d13ae808152602001670406c5f580ba46808152602001670400a0d65ec80e8081526020016703fa21d2b73d068081526020016703f348ea8a192e8081526020016703ec161dd75c868081526020016703e4896c9f070e8081526020016703dca2d6e118c68081526020016703d4625c9d91ae8081526020016703cbc7fdd471c68081526020016703c2d3ba85b90e8081526020016703b98592b167868081526020016703afdd86577d2e8081526020016703a5db9577fa0680815260200167039b7fc012de0e808152602001670390ca06282946808152602001670385ba67b7dbae80815260200167037a50e4c1f54680815260200167036e8d7d46760e8081526020016703627031455e06808152602001670355f900bead2e80815260200167034927ebb2638680815260200167033bfcf220810e80815260200167032e78140905c680815260200167032099516bf1ae80815260200167031260aa4944c6808152602001670303ce1ea0ff0e8081526020016702f4e1ae7320868081526020016702e59b59bfa92e8081526020016702d5fb208699068081526020016702c60102c7f00e8081526020016702b5ad0083ae468081526020016702a4ff19b9d3ae808152602001670293f74e6a6046808152602001670282959e95540e808152602001670270da0a3aaf0680815260200167025ec4915a712e80815260200167024c5533f49a86808152602001670238da1d6b04400081526020016702260c5cdf4d240081526020016702138f83989f90008152602001670201639196fb840081526020016701ef8886da61000081526020016701ddfe6362d0040081526020016701ccc5273048900081526020016701bbdcd242caa40081526020016701ab45649a564000815260200167019afede36eb6400815260200167018b093f188a1000815260200167017b64873f324400815260200167016c10b6aae40000815260200167015d0dcd5b9f4400815260200167014e5bcb51641000815260200167013ffab08c3264008152602001670131ea7d0c0a400081526020016701242b30d0eba4008152602001670116bccbdad6900081526020016701099f4e29cb0400815260200166fcd2b7bdc90000815260200166f0570896d08400815260200166e42c40b4e19000815260200166d8526017fc2400815260200166ccc966c0204000815260200166c19154ad4de400815260200166b6aa29df851000815260200166ac13e656c5c400815260200166a1ce8a1310000081526020016697da151463c4008152602001668e36875ac1100081526020016684e3e0e627e4008152602001667be221b6984000815260200166733149cc1224008152602001666ad1592695900081526020016662c24fc62284008152602001665b042daab900008152602001665396f2d45904008152602001664c7a9f4302900081526020016645af32f6b5a4008152602001663f34adef724000815260200166390b102d386400815260200166333259b00810008152602001662daa8a77e144008152602001662873a284c40000815260200166238da1d6b044008152602001661ef8886da610008152602001661ab45649a5640081526020016616c10b6aae4000815260200166131ea7d0c0a4008152602001660fcd2b7bdc90008152602001660ccc966c0204008152602001660a1ce8a131000081526020016607be221b69840081526020016605b042daab900081526020016603f34adef7240081526020016602873a284c4000815260200166016c10b6aae400815260200165a1ce8a1310008152602001652873a284c40081525060009060786200078e929190620007ab565b506208052060018190555060008054905060015402600281905550565b828054828255906000526020600020908101928215620007ea579160200282015b82811115620007e9578251825591602001919060010190620007cc565b5b509050620007f99190620007fd565b5090565b6200082291905b808211156200081e57600081600090555060010162000804565b5090565b90565b6112ed80620008356000396000f3fe608060405234801561001057600080fd5b5060043610610132576000357c0100000000000000000000000000000000000000000000000000000000900480634476d66a116100bf57806394f7f62b1161008e57806394f7f62b14610451578063df6a503014610493578063e6e100db146104b1578063f91c289814610509578063fb1ac5251461067457610132565b80634476d66a14610363578063553a5c85146103a557806358ceb672146103c357806360d4b8be146103cd57610132565b80631a488047116101065780631a4880471461020357806330f6eb161461022157806333ea51a81461028357806337339a16146102c75780633d84b8c11461030b57610132565b8062f380f414610137578063078d8e7a146101815780630f411cdb146101a357806318129375146101c1575b600080fd5b61013f610692565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6101896106b8565b604051808215151515815260200191505060405180910390f35b6101ab6106c8565b6040518082815260200191505060405180910390f35b6101ed600480360360208110156101d757600080fd5b81019080803590602001909291905050506106ce565b6040518082815260200191505060405180910390f35b61020b6106ef565b6040518082815260200191505060405180910390f35b61026d6004803603604081101561023757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506106f5565b6040518082815260200191505060405180910390f35b6102c56004803603602081101561029957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061071a565b005b610309600480360360208110156102dd57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061079b565b005b61034d6004803603602081101561032157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506108a2565b6040518082815260200191505060405180910390f35b61038f6004803603602081101561037957600080fd5b81019080803590602001909291905050506108ba565b6040518082815260200191505060405180910390f35b6103ad6108d2565b6040518082815260200191505060405180910390f35b6103cb6108d8565b005b61040f600480360360208110156103e357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061093c565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61047d6004803603602081101561046757600080fd5b810190808035906020019092919050505061096f565b6040518082815260200191505060405180910390f35b61049b6109b3565b6040518082815260200191505060405180910390f35b6104f3600480360360208110156104c757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506109b9565b6040518082815260200191505060405180910390f35b6105d56004803603604081101561051f57600080fd5b810190808035906020019064010000000081111561053c57600080fd5b82018360208201111561054e57600080fd5b8035906020019184602083028401116401000000008311171561057057600080fd5b90919293919293908035906020019064010000000081111561059157600080fd5b8201836020820111156105a357600080fd5b803590602001918460208302840111640100000000831117156105c557600080fd5b90919293919293905050506109d1565b604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b8381101561061c578082015181840152602081019050610601565b50505050905001838103825284818151815260200191508051906020019060200280838360005b8381101561065e578082015181840152602081019050610643565b5050505090500194505050505060405180910390f35b61067c610eca565b6040518082815260200191505060405180910390f35b600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60006106c343610ed0565b905090565b60025481565b600081815481106106db57fe5b906000526020600020016000915090505481565b600a5481565b6008602052816000526040600020602052806000526040600020600091509150505481565b80600c60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461085e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f43616c6c6572206973206e6f742074686520636f6d6d756e6974792066756e6481525060200191505060405180910390fd5b80600b60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60066020528060005260406000206000915090505481565b60076020528060005260406000206000915090505481565b60035481565b600c60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055565b600c6020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600061097a82610ed0565b1561098857600090506109ae565b6000600154838161099557fe5b04815481106109a057fe5b906000526020600020015490505b919050565b60045481565b60056020528060005260406000206000915090505481565b606080600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610a97576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260188152602001807f43616c6c6572206973206e6f74207468652073797374656d000000000000000081525060200191505060405180910390fd5b838390508686905014610af5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602581526020018061129d6025913960400191505060405180910390fd5b60018686905014610b6e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f42656e65666163746f7273206c697374206c656e677468206973206e6f74203181525060200191505060405180910390fd5b600084846000818110610b7d57fe5b9050602002013561ffff1661ffff1614610be2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602281526020018061127b6022913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff1686866000818110610c0757fe5b9050602002013573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161480610c4b5750610c4a43610ed0565b5b15610cc1576000604051908082528060200260200182016040528015610c805781602001602082028038833980820191505090505b506000604051908082528060200260200182016040528015610cb15781602001602082028038833980820191505090505b5081915080905091509150610ec1565b60606002604051908082528060200260200182016040528015610cf35781602001602082028038833980820191505090505b50905060608151604051908082528060200260200182016040528015610d285781602001602082028038833980820191505090505b509050610d5d88886000818110610d3b57fe5b9050602002013573ffffffffffffffffffffffffffffffffffffffff16610edf565b82600081518110610d6a57fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050610dad4361096f565b81600081518110610dba57fe5b602002602001018181525050610df1600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16610edf565b82600181518110610dfe57fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050600a5481600181518110610e4857fe5b602002602001018181525050610e8682600081518110610e6457fe5b602002602001015182600081518110610e7957fe5b6020026020010151610f8c565b610eb882600181518110610e9657fe5b602002602001015182600181518110610eab57fe5b6020026020010151611134565b81819350935050505b94509492505050565b60015481565b60006002548210159050919050565b600080600c60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610f825782915050610f87565b809150505b919050565b610fef81600860008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000438152602001908152602001600020546111f290919063ffffffff16565b600860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060004381526020019081526020016000208190555061109581600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546111f290919063ffffffff16565b600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506110fe8160076000438152602001908152602001600020546111f290919063ffffffff16565b600760004381526020019081526020016000208190555061112a816003546111f290919063ffffffff16565b6003819055505050565b611149816004546111f290919063ffffffff16565b6004819055506111a181600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546111f290919063ffffffff16565b600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506111ee8282610f8c565b5050565b600080828401905083811015611270576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f4f766572666c6f77206572726f7200000000000000000000000000000000000081525060200191505060405180910390fd5b809150509291505056fe42656e65666163746f72206973206e6f742074686520626c6f636b20617574686f7242656e65666163746f72732f7479706573206c697374206c656e6774682064696666657273a165627a7a723058209c17c14dc9f6fcdd3ddef3913263be4e76376e948facfc131a975ceda79ba0d6002900000000000000000000000012047000000000000000000000000000000000030000000000000000000000000000000000000000000000000856d3dfb6e26d00" + }, + "0x1204700000000000000000000000000000000004": { + "balance": "40789499640000000000000000", + "constructor": "0x608060405260006001556a21bd8334ca74c3834c00003073ffffffffffffffffffffffffffffffffffffffff16311462000085576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602381526020018062001b5b6023913960400191505060405180910390fd5b6200009e6200010b640100000000026401000000009004565b6a21bd8334ca74c3834c00006001541462000105576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602881526020018062001b0a6028913960400191505060405180910390fd5b620017b4565b6200014a73120470000000000000000000000000000000000a6a084595161401484a000000635d408564620016da640100000000026401000000009004565b62000188735a3977e000000000000000000000000000000000691a784379d99db4200000635db8d244620016da640100000000026401000000009004565b620001c673aae0debd2a4c519364e6098537145369913b26ec6901c761ff4c24e9210000635db8d244620016da640100000000026401000000009004565b620002047336874a6000000000000000000000000000000000691a784379d99db4200000635db8d244620016da640100000000026401000000009004565b6200024273108dd64c9e0d603d56304e97656e011831ed07ff6901c761ff4c24e9210000635db8d244620016da640100000000026401000000009004565b6200028073294f3750000000000000000000000000000000006934f086f3b33b68400000635db8d244620016da640100000000026401000000009004565b620002be732fb294a0000000000000000000000000000000006902d2cd1fdffd73150000635db8d244620016da640100000000026401000000009004565b620002fc73102fb040000000000000000000000000000000006901c3c02f7b2019f50000635db8d244620016da640100000000026401000000009004565b6200033a732b250010000000000000000000000000000000006902a5a058fc295ed00000635db8d244620016da640100000000026401000000009004565b620003787335c468d000000000000000000000000000000000696abafbb89b2adcd80000635db8d244620016da640100000000026401000000009004565b620003b673c8be7a00000000000000000000000000000000006901c3c02f7b2019f50000635db8d244620016da640100000000026401000000009004565b620003f47353f3170000000000000000000000000000000000692004e50f922be25a0000635db8d244620016da640100000000026401000000009004565b6200043373dc918900000000000000000000000000000000006a0215a6ea9b07d650380000635db8d244620016da640100000000026401000000009004565b6200047173b476ee7d610dae7b23b671ebc7bd6112e97729696902a5a058fc295ed00000635db8d244620016da640100000000026401000000009004565b620004af732908b900000000000000000000000000000000006969e10de76676d0800000635d408564620016da640100000000026401000000009004565b620004ed733b2ef740000000000000000000000000000000006901c3c02f7b2019f50000635db8d244620016da640100000000026401000000009004565b6200052b731153818a2eb49f0a71b27313c32814fc02e4db50694220bb939da668600000635db8d244620016da640100000000026401000000009004565b6200056973330d6100000000000000000000000000000000006923466459b949a9950000635db8d244620016da640100000000026401000000009004565b620005a7733e5518c20876eab3a42969d032fa7c30599af912691a784379d99db4200000635db8d244620016da640100000000026401000000009004565b620005e57357f33efad76d4b783cf42c9e6cb08f4425dfe96e6902a5a058fc295ed00000635db8d244620016da640100000000026401000000009004565b6200062373a87e88f0bbc43468cb657294f2479c6f35179b80692004e50f922be25a0000635db8d244620016da640100000000026401000000009004565b62000661734cebef90000000000000000000000000000000006934f086f3b33b68400000635db8d244620016da640100000000026401000000009004565b6200069f73511909cef97475819de66b645f13464285c227ce6934f086f3b33b68400000635db8d244620016da640100000000026401000000009004565b620006dd7322fc2310000000000000000000000000000000006902a5a058fc295ed00000635db8d244620016da640100000000026401000000009004565b6200071b7347919fb8d4e7e360bef0d5a7a2411593dbcc0e776902a5a058fc295ed00000635db8d244620016da640100000000026401000000009004565b6200075973949423db1bfee1ddec99c9d24a12a6ea27cb34896901c3c02f7b2019f50000635db8d244620016da640100000000026401000000009004565b620007977343ec5680000000000000000000000000000000006907f0e10af47c1c700000635db8d244620016da640100000000026401000000009004565b620007d57367cf1c40622f39fa067b614f13aad6da5dd95f326969e10de76676d0800000635d408564620016da640100000000026401000000009004565b620008137310b9390000000000000000000000000000000000692ab13175efe0a8630000635db8d244620016da640100000000026401000000009004565b620008517376b707604cbd862050b938739637b7bde1b7ad486901c3c02f7b2019f50000635db8d244620016da640100000000026401000000009004565b6200088f73568075f0000000000000000000000000000000006934f086f3b33b68400000635db8d244620016da640100000000026401000000009004565b620008cd73d44fb8de580d34f44789408cc9335c9a9ce0ce4d691ad0235eb930a0540000635db8d244620016da640100000000026401000000009004565b6200090a727801b12345b6f10b69263cd6d4fc50b58c8d80696d688e69e3a9742b0000635db8d244620016da640100000000026401000000009004565b62000948735d66a150000000000000000000000000000000006969e10de76676d0800000635d408564620016da640100000000026401000000009004565b62000987731d258680000000000000000000000000000000006a020057f2c74d5a91080000635db8d244620016da640100000000026401000000009004565b620009c57330e311c00000000000000000000000000000000069355d7ddc4d956e6c0000635db8d244620016da640100000000026401000000009004565b62000a0373428ab4b019ee3a9b9863b2b4bf1885ce6dff9a736902a5a058fc295ed00000635db8d244620016da640100000000026401000000009004565b62000a41738081f20000000000000000000000000000000000691a784379d99db4200000635db8d244620016da640100000000026401000000009004565b62000a7f735305c8071b604da7fb45059e7ebfa1d674ddfc3569038780827d32a3ab0000635db8d244620016da640100000000026401000000009004565b62000abd7335007170000000000000000000000000000000006901c3c02f7b2019f50000635db8d244620016da640100000000026401000000009004565b62000afc733484c850000000000000000000000000000000006a0422ca8b0a00a42500000063608a9f84620016da640100000000026401000000009004565b62000b3a73ffd9b871df6e93803c0877e98fc1722b39c00d786902a5a058fc295ed00000635db8d244620016da640100000000026401000000009004565b62000b787396a5eb172efdf262ed6beaaf0e20c6af71831fc96934f086f3b33b68400000635db8d244620016da640100000000026401000000009004565b62000bb6732dd2e140000000000000000000000000000000006901c3c02f7b2019f50000635db8d244620016da640100000000026401000000009004565b62000bf473656e5569bef7781bf0db199d32027766053501ff69438ec266600555e00000635db8d244620016da640100000000026401000000009004565b62000c32731d53db7000000000000000000000000000000000691a784379d99db4200000635db8d244620016da640100000000026401000000009004565b62000c7073b5b6d8885fbf28f843cc7886de242b811d6952056901c3c02f7b2019f50000635db8d244620016da640100000000026401000000009004565b62000cae734549ef8e287b94f1c0a8b88f55ed8707d74d843c6934f086f3b33b68400000635db8d244620016da640100000000026401000000009004565b62000cec73dacd80d8e1d4f117515caa477ee7599cdfc766196902a5a058fc295ed00000635db8d244620016da640100000000026401000000009004565b62000d2a731f603e000000000000000000000000000000000069d3c21bcecceda1000000635db8d244620016da640100000000026401000000009004565b62000d68735548f000000000000000000000000000000000006902ab1310b5b095920000635db8d244620016da640100000000026401000000009004565b62000da6735bb9ba00000000000000000000000000000000006934f086f3b33b68400000635db8d244620016da640100000000026401000000009004565b62000de4736dd10e41a7a84fe23ab35fefa2f46c9895f87a2d693c8c4bde2deef1680000635db8d244620016da640100000000026401000000009004565b62000e227316337db0000000000000000000000000000000006901c3c02f7b2019f50000635db8d244620016da640100000000026401000000009004565b62000e6073b999004b49c6b907d4278067da5c85195dcd7fc769081e0dd1d85030b50000635db8d244620016da640100000000026401000000009004565b62000e9e733dbb2290000000000000000000000000000000006934f086f3b33b68400000635db8d244620016da640100000000026401000000009004565b62000edc73559da540000000000000000000000000000000006934f086f3b33b68400000635db8d244620016da640100000000026401000000009004565b62000f1a733a9d83766c03c465851a38daa364ef7deccd1ece6934f086f3b33b68400000635db8d244620016da640100000000026401000000009004565b62000f5873b61c11b6e42d459efaee8995c44db08507e468e169477d5529f68a63000000635db8d244620016da640100000000026401000000009004565b62000f9673e803d7955a911106cb8fd79049a2374ff059000369038780827d32a3ab0000635db8d244620016da640100000000026401000000009004565b62000fd473509b057000000000000000000000000000000000691aaebeee26cab7360000635db8d244620016da640100000000026401000000009004565b620010127383980db85394d7c1610f37a90be744432368bad4692393a931b168245d0000635db8d244620016da640100000000026401000000009004565b6200105073db6cc57168c07b83a00f1f8871538446068824fc691a784379d99db4200000635db8d244620016da640100000000026401000000009004565b6200108e735035fba0000000000000000000000000000000006934f086f3b33b68400000635db8d244620016da640100000000026401000000009004565b620010cc73d96c8300000000000000000000000000000000006901c3c02f7b2019f50000635db8d244620016da640100000000026401000000009004565b6200110b7331178cd0000000000000000000000000000000006a042b4dd5360faca070000063608a9f84620016da640100000000026401000000009004565b62001149732f531158e2305ed4fb4144a2f4085e3d96e1982e6934f086f3b33b68400000635db8d244620016da640100000000026401000000009004565b62001188735d5da310000000000000000000000000000000006a017293b0a9e69fd9c00000635db8d244620016da640100000000026401000000009004565b620011c67318b9347000000000000000000000000000000000696abafbb89b2adcd80000635d408564620016da640100000000026401000000009004565b62001203722d4606b65c033769968bcdc63881b90b0853f5692648770b742bb90b0000635db8d244620016da640100000000026401000000009004565b62001241731faa8d10000000000000000000000000000000006969e10de76676d0800000635d408564620016da640100000000026401000000009004565b6200127f7333445720000000000000000000000000000000006902a5a058fc295ed00000635db8d244620016da640100000000026401000000009004565b620012bd730d1d4e623d10f9fba5db95830f7d3839406c6af26901c3c02f7b2019f50000635db8d244620016da640100000000026401000000009004565b620012fa72c2f65230815d30eaa1a4d057bcf0b72fe3cc4e6902a5a058fc295ed00000635db8d244620016da640100000000026401000000009004565b62001338739c3a5ec7bd63ecac1b92abe4b01b12ffd50bf3f26969e10de76676d0800000635d408564620016da640100000000026401000000009004565b620013767345635660000000000000000000000000000000006969e10de76676d0800000635d408564620016da640100000000026401000000009004565b620013b2739be61e41490f5227080fa1adbe3ec0a973d59732678ac7230489e80000635cc83884620016da640100000000026401000000009004565b620013f073572f91b0000000000000000000000000000000006934f086f3b33b68400000635db8d244620016da640100000000026401000000009004565b6200142e7339350e4a75d1e50a5072950325328884c11c12326901c761ff4c24e9210000635db8d244620016da640100000000026401000000009004565b6200146c733c96a530000000000000000000000000000000006969e10de76676d0800000635d408564620016da640100000000026401000000009004565b620014aa730ad7ba4af33b485e6f2505c417554631a3e5643f6902a5a058fc295ed00000635db8d244620016da640100000000026401000000009004565b620014e8735eea7250000000000000000000000000000000006901c3c02f7b2019f50000635db8d244620016da640100000000026401000000009004565b62001526733ab790e0000000000000000000000000000000006902a5a058fc295ed00000635db8d244620016da640100000000026401000000009004565b62001564734cf84620000000000000000000000000000000006902a5a058fc295ed00000635db8d244620016da640100000000026401000000009004565b620015a2735425f6f0000000000000000000000000000000006969e10de76676d0800000635d408564620016da640100000000026401000000009004565b620015e0736d516767e4068fc331bdb331fba7578bdb07a68c69234b04ae4f23156b0000635db8d244620016da640100000000026401000000009004565b6200161e73106a8ff0000000000000000000000000000000006902a5a058fc295ed00000635db8d244620016da640100000000026401000000009004565b6200165c73102fb9400000000000000000000000000000000069038780827d32a3ab0000635db8d244620016da640100000000026401000000009004565b6200169a737ed62cf71d519d3bf293ef90829508f92f4ccccb6902a5a058fc295ed00000635db8d244620016da640100000000026401000000009004565b620016d873199a8c5000000000000000000000000000000000691a784379d99db4200000635db8d244620016da640100000000026401000000009004565b565b60008060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090506000816000015414801562001735575060008160010154145b6200178c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602981526020018062001b326029913960400191505060405180910390fd5b8260016000828254019250508190555082816000018190555081816001018190555050505050565b61034680620017c46000396000f3fe608060405234801561001057600080fd5b5060043610610069576000357c01000000000000000000000000000000000000000000000000000000009004806318a5bbdc1461006e578063192e7a7b146100cd57806330f0dbe0146101115780639976e12f1461012f575b600080fd5b6100b06004803603602081101561008457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061014d565b604051808381526020018281526020019250505060405180910390f35b61010f600480360360208110156100e357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610171565b005b610119610305565b6040518082815260200191505060405180910390f35b610137610314565b6040518082815260200191505060405180910390f35b60006020528060005260406000206000915090508060000154908060010154905082565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050600081600001541161022d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260158152602001807f417661696c61626c6520616d6f756e742069732030000000000000000000000081525060200191505060405180910390fd5b806001015442116102a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f486f6c64696e6720706572696f64206973206e6f74206f76657200000000000081525060200191505060405180910390fd5b600081600001549050600082600001819055508273ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f193505050501580156102ff573d6000803e3d6000fd5b50505050565b6a21bd8334ca74c3834c000081565b6001548156fea165627a7a7230582078bf501dd1d053c49557b82491b940e47ebf94b95608375e22da53fcc7120a1a002954617267657420616d6f756e742073686f756c6420657175616c2061637475616c20616d6f756e74486f6c64696e6720666f72207468697320616464726573732077617320616c7265616479207365742e42616c616e63652073686f756c6420657175616c2074617267657420616d6f756e742e" + }, + "0x1204700000000000000000000000000000000006": { + "constructor": "0x6080604052670de0b6b3a76400006003553480156200001d57600080fd5b5060405160208062003e58833981018060405260208110156200003f57600080fd5b8101908080519060200190929190505050336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a362000126816200012d640100000000026401000000009004565b506200028f565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415620001d1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f4e6577206f776e657220616464726573732063616e6e6f74206265203078300081525060200191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b613bb9806200029f6000396000f3fe6080604052600436106101d4576000357c0100000000000000000000000000000000000000000000000000000000900480639269881411610109578063df57b742116100a7578063ef5454d611610081578063ef5454d614610d59578063f25eb5c114610e17578063f2fde38b14610e2e578063f6d339e414610e7f576101d4565b8063df57b74214610b62578063e30bd74014610bdd578063eadf976014610ca7576101d4565b8063ac72c120116100e3578063ac72c120146109c5578063c3a3582514610a18578063ddca3f4314610abc578063deb931a214610ae7576101d4565b806392698814146108855780639890220b146108d8578063ac4e73f914610907576101d4565b806369fe0e2d1161017657806379ce9fac1161015057806379ce9fac146106e85780638da5cb5b1461075b5780638f32d59b146107b257806390b97fc1146107e1576101d4565b806369fe0e2d146105b45780636a1acc3f14610607578063715018a6146106d1576101d4565b80633f3935d1116101b25780633f3935d1146103ad578063432ced041461044b5780634f39ca59146104915780636795dbcd146104e4576101d4565b806306b2ff47146101d957806319362a2814610242578063267b6922146102f4575b600080fd5b3480156101e557600080fd5b50610228600480360360208110156101fc57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610f47565b604051808215151515815260200191505060405180910390f35b34801561024e57600080fd5b506102da6004803603606081101561026557600080fd5b81019080803590602001909291908035906020019064010000000081111561028c57600080fd5b82018360208201111561029e57600080fd5b803590602001918460018302840111640100000000831117156102c057600080fd5b909192939192939080359060200190929190505050610fa7565b604051808215151515815260200191505060405180910390f35b34801561030057600080fd5b5061032d6004803603602081101561031757600080fd5b81019080803590602001909291905050506111ff565b604051808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182151515158152602001935050505060405180910390f35b3480156103b957600080fd5b50610431600480360360208110156103d057600080fd5b81019080803590602001906401000000008111156103ed57600080fd5b8201836020820111156103ff57600080fd5b8035906020019184600183028401116401000000008311171561042157600080fd5b9091929391929390505050611276565b604051808215151515815260200191505060405180910390f35b6104776004803603602081101561046157600080fd5b8101908080359060200190929190505050611553565b604051808215151515815260200191505060405180910390f35b34801561049d57600080fd5b506104ca600480360360208110156104b457600080fd5b810190808035906020019092919050505061185c565b604051808215151515815260200191505060405180910390f35b3480156104f057600080fd5b506105726004803603604081101561050757600080fd5b81019080803590602001909291908035906020019064010000000081111561052e57600080fd5b82018360208201111561054057600080fd5b8035906020019184600183028401116401000000008311171561056257600080fd5b9091929391929390505050611acc565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156105c057600080fd5b506105ed600480360360208110156105d757600080fd5b8101908080359060200190929190505050611bb0565b604051808215151515815260200191505060405180910390f35b34801561061357600080fd5b506106566004803603602081101561062a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611c73565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561069657808201518184015260208101905061067b565b50505050905090810190601f1680156106c35780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156106dd57600080fd5b506106e6611d23565b005b3480156106f457600080fd5b506107416004803603604081101561070b57600080fd5b8101908080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611e5c565b604051808215151515815260200191505060405180910390f35b34801561076757600080fd5b5061077061208a565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156107be57600080fd5b506107c76120b3565b604051808215151515815260200191505060405180910390f35b3480156107ed57600080fd5b5061086f6004803603604081101561080457600080fd5b81019080803590602001909291908035906020019064010000000081111561082b57600080fd5b82018360208201111561083d57600080fd5b8035906020019184600183028401116401000000008311171561085f57600080fd5b909192939192939050505061210a565b6040518082815260200191505060405180910390f35b34801561089157600080fd5b506108be600480360360208110156108a857600080fd5b81019080803590602001909291905050506121ea565b604051808215151515815260200191505060405180910390f35b3480156108e457600080fd5b506108ed6122f3565b604051808215151515815260200191505060405180910390f35b34801561091357600080fd5b506109ab6004803603604081101561092a57600080fd5b810190808035906020019064010000000081111561094757600080fd5b82018360208201111561095957600080fd5b8035906020019184600183028401116401000000008311171561097b57600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612422565b604051808215151515815260200191505060405180910390f35b3480156109d157600080fd5b506109fe600480360360208110156109e857600080fd5b8101908080359060200190929190505050612982565b604051808215151515815260200191505060405180910390f35b348015610a2457600080fd5b50610aa660048036036040811015610a3b57600080fd5b810190808035906020019092919080359060200190640100000000811115610a6257600080fd5b820183602082011115610a7457600080fd5b80359060200191846001830284011164010000000083111715610a9657600080fd5b9091929391929390505050612a8b565b6040518082815260200191505060405180910390f35b348015610ac857600080fd5b50610ad1612b6f565b6040518082815260200191505060405180910390f35b348015610af357600080fd5b50610b2060048036036020811015610b0a57600080fd5b8101908080359060200190929190505050612b75565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b348015610b6e57600080fd5b50610b9b60048036036020811015610b8557600080fd5b8101908080359060200190929190505050612c4e565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b348015610be957600080fd5b50610c2c60048036036020811015610c0057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612d27565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610c6c578082015181840152602081019050610c51565b50505050905090810190601f168015610c995780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b348015610cb357600080fd5b50610d3f60048036036060811015610cca57600080fd5b810190808035906020019092919080359060200190640100000000811115610cf157600080fd5b820183602082011115610d0357600080fd5b80359060200191846001830284011164010000000083111715610d2557600080fd5b909192939192939080359060200190929190505050612e08565b604051808215151515815260200191505060405180910390f35b348015610d6557600080fd5b50610dfd60048036036040811015610d7c57600080fd5b8101908080359060200190640100000000811115610d9957600080fd5b820183602082011115610dab57600080fd5b80359060200191846001830284011164010000000083111715610dcd57600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613063565b604051808215151515815260200191505060405180910390f35b348015610e2357600080fd5b50610e2c613297565b005b348015610e3a57600080fd5b50610e7d60048036036020811015610e5157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613648565b005b348015610e8b57600080fd5b50610f2d60048036036060811015610ea257600080fd5b810190808035906020019092919080359060200190640100000000811115610ec957600080fd5b820183602082011115610edb57600080fd5b80359060200191846001830284011164010000000083111715610efd57600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506136ce565b604051808215151515815260200191505060405180910390f35b600080600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002080546001816001161561010002031660029004905014159050919050565b6000846001600082815260200190815260200160002060010160149054906101000a900460ff1615611041576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f4572726f723a204f6e6c79207768656e20656e7472792072617700000000000081525060200191505060405180910390fd5b853373ffffffffffffffffffffffffffffffffffffffff166001600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611119576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f4572726f723a204f6e6c79206f776e6572206f6600000000000000000000000081525060200191505060405180910390fd5b83600160008981526020019081526020016000206002018787604051808383808284378083019250505092505050908152602001604051809103902081905550867fb829c3e412537bbe794c048ccb9e4605bb4aaaa8e4d4c15c1a6e0c2adc1716ea878789896040518080602001806020018381038352878782818152602001925080828437600081840152601f19601f8201169050808301925050508381038252858582818152602001925080828437600081840152601f19601f820116905080830192505050965050505050505060405180910390a2600192505050949350505050565b60016020528060005260406000206000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060010160149054906101000a900460ff16905083565b600082828080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050600160008280519060200120815260200190815260200160002060010160149054906101000a900460ff161561135b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f4572726f723a204f6e6c79207768656e20656e7472790000000000000000000081525060200191505060405180910390fd5b83838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050503373ffffffffffffffffffffffffffffffffffffffff16600160008380519060200120815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461147e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f4572726f723a204f6e6c79207768656e2070726f706f7365640000000000000081525060200191505060405180910390fd5b8484600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002091906114cc929190613aa0565b503373ffffffffffffffffffffffffffffffffffffffff167f098ae8581bb8bd9af1beaf7f2e9f51f31a8e5a8bfada4e303a645d71d9c91920868660405180806020018281038252848482818152602001925080828437600081840152601f19601f820116905080830192505050935050505060405180910390a260019250505092915050565b6000816001600082815260200190815260200160002060010160149054906101000a900460ff16156115ed576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f4572726f723a204f6e6c79207768656e20656e7472792072617700000000000081525060200191505060405180910390fd5b82600073ffffffffffffffffffffffffffffffffffffffff166001600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146116c6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f4572726f723a204f6e6c79207768656e20756e7265736572766564000000000081525060200191505060405180910390fd5b60035434101561173e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f4572726f723a206f6e6c79207768656e2066656520706169640000000000000081525060200191505060405180910390fd5b6117466120b3565b6117b8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f53656e646572206973206e6f74206f776e65720000000000000000000000000081525060200191505060405180910390fd5b336001600086815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055503373ffffffffffffffffffffffffffffffffffffffff16847f4963513eca575aba66fdcd25f267aae85958fe6fb97e75fa25d783f1a091a22160405160405180910390a3600192505050919050565b6000816001600082815260200190815260200160002060010160149054906101000a900460ff16156118f6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f4572726f723a204f6e6c79207768656e20656e7472792072617700000000000081525060200191505060405180910390fd5b823373ffffffffffffffffffffffffffffffffffffffff166001600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146119ce576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f4572726f723a204f6e6c79206f776e6572206f6600000000000000000000000081525060200191505060405180910390fd5b600260006001600087815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000611a4f9190613b20565b600180600086815260200190815260200160002060010160146101000a81548160ff0219169083151502179055503373ffffffffffffffffffffffffffffffffffffffff16847fef1961b4d2909dc23643b309bfe5c3e5646842d98c3a58517037ef3871185af360405160405180910390a3600192505050919050565b6000836001600082815260200190815260200160002060010160149054906101000a900460ff1615611b66576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f4572726f723a204f6e6c79207768656e20656e7472792072617700000000000081525060200191505060405180910390fd5b600160008681526020019081526020016000206002018484604051808383808284378083019250505092505050908152602001604051809103902054600190049150509392505050565b6000611bba6120b3565b611c2c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f53656e646572206973206e6f74206f776e65720000000000000000000000000081525060200191505060405180910390fd5b816003819055507f6bbc57480a46553fa4d156ce702beef5f3ad66303b0ed1a5d4cb44966c6584c3826040518082815260200191505060405180910390a160019050919050565b60026020528060005260406000206000915090508054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015611d1b5780601f10611cf057610100808354040283529160200191611d1b565b820191906000526020600020905b815481529060010190602001808311611cfe57829003601f168201915b505050505081565b611d2b6120b3565b611d9d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f53656e646572206973206e6f74206f776e65720000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a360008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b6000826001600082815260200190815260200160002060010160149054906101000a900460ff1615611ef6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f4572726f723a204f6e6c79207768656e20656e7472792072617700000000000081525060200191505060405180910390fd5b833373ffffffffffffffffffffffffffffffffffffffff166001600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611fce576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f4572726f723a204f6e6c79206f776e6572206f6600000000000000000000000081525060200191505060405180910390fd5b836001600087815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16867f7b97c62130aa09acbbcbf7482630e756592496f1759eaf702f469cf64dfb779460405160405180910390a460019250505092915050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614905090565b6000836001600082815260200190815260200160002060010160149054906101000a900460ff16156121a4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f4572726f723a204f6e6c79207768656e20656e7472792072617700000000000081525060200191505060405180910390fd5b6001600086815260200190815260200160002060020184846040518083838082843780830192505050925050509081526020016040518091039020549150509392505050565b6000816001600082815260200190815260200160002060010160149054906101000a900460ff1615612284576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f4572726f723a204f6e6c79207768656e20656e7472792072617700000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff166001600085815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415915050919050565b60006122fd6120b3565b61236f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f53656e646572206973206e6f74206f776e65720000000000000000000000000081525060200191505060405180910390fd5b7fdef931299fe61d176f949118058530c1f3f539dcb6950b4e372c9b835c33ca073073ffffffffffffffffffffffffffffffffffffffff16316040518082815260200191505060405180910390a13373ffffffffffffffffffffffffffffffffffffffff166108fc3073ffffffffffffffffffffffffffffffffffffffff16319081150290604051600060405180830381858888f1935050505015801561241a573d6000803e3d6000fd5b506001905090565b600083838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050600160008280519060200120815260200190815260200160002060010160149054906101000a900460ff1615612507576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f4572726f723a204f6e6c79207768656e20656e7472790000000000000000000081525060200191505060405180910390fd5b848460405180838380828437808301925050509250505060405180910390203373ffffffffffffffffffffffffffffffffffffffff166001600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146125fd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f4572726f723a204f6e6c79206f776e6572206f6600000000000000000000000081525060200191505060405180910390fd5b6000868660405180838380828437808301925050509250505060405180910390209050600073ffffffffffffffffffffffffffffffffffffffff166001600083815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415801561276e575080600260006001600085815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020604051808280546001816001161561010002031660029004801561275f5780601f1061273d57610100808354040283529182019161275f565b820191906000526020600020905b81548152906001019060200180831161274b575b50509150506040518091039020145b156128a557600260006001600084815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006127f49190613b20565b6001600082815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f12491ad95fd945e444d88a894ffad3c21959880a4dcd8af99d4ae4ffc71d4abd888860405180806020018281038252848482818152602001925080828437600081840152601f19601f820116905080830192505050935050505060405180910390a25b846001600083815260200190815260200160002060010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508473ffffffffffffffffffffffffffffffffffffffff167f728435a0031f6a04538fcdd24922a7e06bc7bc945db03e83d22122d1bc5f28df888860405180806020018281038252848482818152602001925080828437600081840152601f19601f820116905080830192505050935050505060405180910390a2600193505050509392505050565b6000816001600082815260200190815260200160002060010160149054906101000a900460ff1615612a1c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f4572726f723a204f6e6c79207768656e20656e7472792072617700000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff166001600085815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415915050919050565b6000836001600082815260200190815260200160002060010160149054906101000a900460ff1615612b25576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f4572726f723a204f6e6c79207768656e20656e7472792072617700000000000081525060200191505060405180910390fd5b600160008681526020019081526020016000206002018484604051808383808284378083019250505092505050908152602001604051809103902054600190049150509392505050565b60035481565b6000816001600082815260200190815260200160002060010160149054906101000a900460ff1615612c0f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f4572726f723a204f6e6c79207768656e20656e7472792072617700000000000081525060200191505060405180910390fd5b6001600084815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16915050919050565b6000816001600082815260200190815260200160002060010160149054906101000a900460ff1615612ce8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f4572726f723a204f6e6c79207768656e20656e7472792072617700000000000081525060200191505060405180910390fd5b6001600084815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16915050919050565b6060600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015612dfc5780601f10612dd157610100808354040283529160200191612dfc565b820191906000526020600020905b815481529060010190602001808311612ddf57829003601f168201915b50505050509050919050565b6000846001600082815260200190815260200160002060010160149054906101000a900460ff1615612ea2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f4572726f723a204f6e6c79207768656e20656e7472792072617700000000000081525060200191505060405180910390fd5b853373ffffffffffffffffffffffffffffffffffffffff166001600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614612f7a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f4572726f723a204f6e6c79206f776e6572206f6600000000000000000000000081525060200191505060405180910390fd5b83600102600160008981526020019081526020016000206002018787604051808383808284378083019250505092505050908152602001604051809103902081905550867fb829c3e412537bbe794c048ccb9e4605bb4aaaa8e4d4c15c1a6e0c2adc1716ea878789896040518080602001806020018381038352878782818152602001925080828437600081840152601f19601f8201169050808301925050508381038252858582818152602001925080828437600081840152601f19601f820116905080830192505050965050505050505060405180910390a2600192505050949350505050565b600083838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050600160008280519060200120815260200190815260200160002060010160149054906101000a900460ff1615613148576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f4572726f723a204f6e6c79207768656e20656e7472790000000000000000000081525060200191505060405180910390fd5b6131506120b3565b6131c2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f53656e646572206973206e6f74206f776e65720000000000000000000000000081525060200191505060405180910390fd5b8484600260008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209190613210929190613aa0565b508273ffffffffffffffffffffffffffffffffffffffff167f098ae8581bb8bd9af1beaf7f2e9f51f31a8e5a8bfada4e303a645d71d9c91920868660405180806020018281038252848482818152602001925080828437600081840152601f19601f820116905080830192505050935050505060405180910390a260019150509392505050565b600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561336a5780601f1061333f5761010080835404028352916020019161336a565b820191906000526020600020905b81548152906001019060200180831161334d57829003601f168201915b5050505050600160008280519060200120815260200190815260200160002060010160149054906101000a900460ff161561340d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f4572726f723a204f6e6c79207768656e20656e7472790000000000000000000081525060200191505060405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff167f12491ad95fd945e444d88a894ffad3c21959880a4dcd8af99d4ae4ffc71d4abd600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020604051808060200182810382528381815460018160011615610100020316600290048152602001915080546001816001161561010002031660029004801561350d5780601f106134e25761010080835404028352916020019161350d565b820191906000526020600020905b8154815290600101906020018083116134f057829003601f168201915b50509250505060405180910390a260016000600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060405180828054600181600116156101000203166002900480156135b95780601f106135975761010080835404028352918201916135b9565b820191906000526020600020905b8154815290600101906020018083116135a5575b50509150506040518091039020815260200190815260200160002060010160006101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006136459190613b20565b50565b6136506120b3565b6136c2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f53656e646572206973206e6f74206f776e65720000000000000000000000000081525060200191505060405180910390fd5b6136cb8161393f565b50565b6000846001600082815260200190815260200160002060010160149054906101000a900460ff1615613768576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f4572726f723a204f6e6c79207768656e20656e7472792072617700000000000081525060200191505060405180910390fd5b853373ffffffffffffffffffffffffffffffffffffffff166001600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614613840576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f4572726f723a204f6e6c79206f776e6572206f6600000000000000000000000081525060200191505060405180910390fd5b8373ffffffffffffffffffffffffffffffffffffffff16600102600160008981526020019081526020016000206002018787604051808383808284378083019250505092505050908152602001604051809103902081905550867fb829c3e412537bbe794c048ccb9e4605bb4aaaa8e4d4c15c1a6e0c2adc1716ea878789896040518080602001806020018381038352878782818152602001925080828437600081840152601f19601f8201169050808301925050508381038252858582818152602001925080828437600081840152601f19601f820116905080830192505050965050505050505060405180910390a2600192505050949350505050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156139e2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f4e6577206f776e657220616464726573732063616e6e6f74206265203078300081525060200191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10613ae157803560ff1916838001178555613b0f565b82800160010185558215613b0f579182015b82811115613b0e578235825591602001919060010190613af3565b5b509050613b1c9190613b68565b5090565b50805460018160011615610100020316600290046000825580601f10613b465750613b65565b601f016020900490600052602060002090810190613b649190613b68565b5b50565b613b8a91905b80821115613b86576000816000905550600101613b6e565b5090565b9056fea165627a7a723058201b0da92162b975c882f9c56423cbea6ec9afb46d8dccc92abe125e91c84d52de00290000000000000000000000001204700000000000000000000000000000000005" + }, + "0x1204700000000000000000000000000000000007": { + "constructor": "0x608060405234801561001057600080fd5b50604051604080610a5f833981018060405261002f919081019061028d565b336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a381600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506101448161014b640100000000026401000000009004565b505061036c565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156101bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101b290610309565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000610285825161033a565b905092915050565b600080604083850312156102a057600080fd5b60006102ae85828601610279565b92505060206102bf85828601610279565b9150509250929050565b60006102d6601f83610329565b91507f4e6577206f776e657220616464726573732063616e6e6f7420626520307830006000830152602082019050919050565b60006020820190508181036000830152610322816102c9565b9050919050565b600082825260208201905092915050565b60006103458261034c565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6106e48061037b6000396000f3fe608060405234801561001057600080fd5b506004361061007f576000357c0100000000000000000000000000000000000000000000000000000000900480636ddc4a0714610084578063715018a6146100a25780638da5cb5b146100ac5780638f32d59b146100ca578063f2fde38b146100e8578063fe64d6ff14610104575b600080fd5b61008c610120565b60405161009991906105b3565b60405180910390f35b6100aa610146565b005b6100b461024c565b6040516100c191906105b3565b60405180910390f35b6100d2610275565b6040516100df91906105ce565b60405180910390f35b61010260048036036100fd91908101906104ec565b6102cc565b005b61011e600480360361011991908101906104ec565b61031f565b005b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b61014e610275565b61018d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161018490610609565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a360008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614905090565b6102d4610275565b610313576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161030a90610609565b60405180910390fd5b61031c816103aa565b50565b610327610275565b610366576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161035d90610609565b60405180910390fd5b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561041a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610411906105e9565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60006104e48235610678565b905092915050565b6000602082840312156104fe57600080fd5b600061050c848285016104d8565b91505092915050565b61051e8161063a565b82525050565b61052d8161064c565b82525050565b6000610540601f83610629565b91507f4e6577206f776e657220616464726573732063616e6e6f7420626520307830006000830152602082019050919050565b6000610580601383610629565b91507f53656e646572206973206e6f74206f776e6572000000000000000000000000006000830152602082019050919050565b60006020820190506105c86000830184610515565b92915050565b60006020820190506105e36000830184610524565b92915050565b6000602082019050818103600083015261060281610533565b9050919050565b6000602082019050818103600083015261062281610573565b9050919050565b600082825260208201905092915050565b600061064582610658565b9050919050565b60008115159050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006106838261068a565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff8216905091905056fea265627a7a723058207424d262effee3c4b2cfbe03927ef8931223cda85f89bf647b88b2f7e64cc5516c6578706572696d656e74616cf5003700000000000000000000000012047000000000000000000000000000000000090000000000000000000000001204700000000000000000000000000000000005" + }, + "0x1204700000000000000000000000000000000008": { + "constructor": "0x60806040523480156200001157600080fd5b5060405160408062002b838339810180604052620000339190810190620002af565b336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a381600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506200014a8162000152640100000000026401000000009004565b5050620003ad565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415620001c5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620001bc9062000332565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600062000291825162000365565b905092915050565b6000620002a7825162000379565b905092915050565b60008060408385031215620002c357600080fd5b6000620002d38582860162000299565b9250506020620002e68582860162000283565b9150509250929050565b6000620002ff601f8362000354565b91507f4e6577206f776e657220616464726573732063616e6e6f7420626520307830006000830152602082019050919050565b600060208201905081810360008301526200034d81620002f0565b9050919050565b600082825260208201905092915050565b600062000372826200038d565b9050919050565b6000620003868262000365565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6127c680620003bd6000396000f3fe608060405234801561001057600080fd5b506004361061011d576000357c010000000000000000000000000000000000000000000000000000000090048063954029c9116100b4578063eab7ad9211610083578063eab7ad92146102e4578063ee7ee0fd14610300578063f2fde38b14610330578063fbd74f841461034c5761011d565b8063954029c91461024c578063a999809f14610268578063b71da0d114610298578063da5393d5146102c85761011d565b806370a05b18116100f057806370a05b18146101d6578063715018a6146102065780638da5cb5b146102105780638f32d59b1461022e5761011d565b80631bab58f5146101225780632c5653e21461015257806332d91c0e146101705780636a564261146101a0575b600080fd5b61013c60048036036101379190810190611f97565b61037c565b604051610149919061260c565b60405180910390f35b61015a6107b5565b604051610167919061254f565b60405180910390f35b61018a60048036036101859190810190611f97565b6107db565b604051610197919061256a565b60405180910390f35b6101ba60048036036101b59190810190611f97565b6109e8565b6040516101cd97969594939291906124c4565b60405180910390f35b6101f060048036036101eb9190810190611f97565b610c97565b6040516101fd91906124a2565b60405180910390f35b61020e610ea4565b005b610218610faa565b604051610225919061246c565b60405180910390f35b610236610fd3565b6040516102439190612487565b60405180910390f35b61026660048036036102619190810190611f97565b61102a565b005b610282600480360361027d9190810190611f97565b61119d565b60405161028f919061256a565b60405180910390f35b6102b260048036036102ad9190810190611f97565b6113aa565b6040516102bf9190612487565b60405180910390f35b6102e260048036036102dd9190810190611f97565b61143a565b005b6102fe60048036036102f99190810190611fe9565b611535565b005b61031a60048036036103159190810190611f97565b611853565b6040516103279190612487565b60405180910390f35b61034a60048036036103459190810190611f97565b6119d5565b005b61036660048036036103619190810190611f97565b611a28565b60405161037391906124a2565b60405180910390f35b610384611d63565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636ddc4a076040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b15801561040857600080fd5b505afa15801561041c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506104409190810190611fc0565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146104ad576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104a49061258c565b60405180910390fd5b600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206040518060e0016040529081600082018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156105905780601f1061056557610100808354040283529160200191610590565b820191906000526020600020905b81548152906001019060200180831161057357829003601f168201915b50505050508152602001600182018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156106325780601f1061060757610100808354040283529160200191610632565b820191906000526020600020905b81548152906001019060200180831161061557829003601f168201915b50505050508152602001600282018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156106d45780601f106106a9576101008083540402835291602001916106d4565b820191906000526020600020905b8154815290600101906020018083116106b757829003601f168201915b50505050508152602001600382018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156107765780601f1061074b57610100808354040283529160200191610776565b820191906000526020600020905b81548152906001019060200180831161075957829003601f168201915b505050505081526020016004820160009054906101000a900460ff16151515158152602001600582015481526020016006820154815250509050919050565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6060600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636ddc4a076040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b15801561086157600080fd5b505afa158015610875573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506108999190810190611fc0565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610906576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108fd9061258c565b60405180910390fd5b600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206003018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156109dc5780601f106109b1576101008083540402835291602001916109dc565b820191906000526020600020905b8154815290600101906020018083116109bf57829003601f168201915b50505050509050919050565b6001602052806000526040600020600091509050806000018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610a945780601f10610a6957610100808354040283529160200191610a94565b820191906000526020600020905b815481529060010190602001808311610a7757829003601f168201915b505050505090806001018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610b325780601f10610b0757610100808354040283529160200191610b32565b820191906000526020600020905b815481529060010190602001808311610b1557829003601f168201915b505050505090806002018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610bd05780601f10610ba557610100808354040283529160200191610bd0565b820191906000526020600020905b815481529060010190602001808311610bb357829003601f168201915b505050505090806003018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610c6e5780601f10610c4357610100808354040283529160200191610c6e565b820191906000526020600020905b815481529060010190602001808311610c5157829003601f168201915b5050505050908060040160009054906101000a900460ff16908060050154908060060154905087565b6060600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636ddc4a076040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b158015610d1d57600080fd5b505afa158015610d31573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610d559190810190611fc0565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610dc2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610db99061258c565b60405180910390fd5b600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206002018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610e985780601f10610e6d57610100808354040283529160200191610e98565b820191906000526020600020905b815481529060010190602001808311610e7b57829003601f168201915b50505050509050919050565b610eac610fd3565b610eeb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ee2906125ec565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a360008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614905090565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636ddc4a076040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b1580156110ae57600080fd5b505afa1580156110c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506110e69190810190611fc0565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611153576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161114a9061258c565b60405180910390fd5b43600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206006018190555050565b6060600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636ddc4a076040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b15801561122357600080fd5b505afa158015611237573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061125b9190810190611fc0565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146112c8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112bf9061258c565b60405180910390fd5b600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001018054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561139e5780601f106113735761010080835404028352916020019161139e565b820191906000526020600020905b81548152906001019060200180831161138157829003601f168201915b50505050509050919050565b6000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060060154600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060050154109050919050565b611442610fd3565b611481576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611478906125ec565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156114f1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114e8906125ac565b60405180910390fd5b80600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636ddc4a076040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b1580156115b957600080fd5b505afa1580156115cd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506115f19190810190611fc0565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461165e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116559061258c565b60405180910390fd5b8888600160008d73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000191906116af929190611da2565b508686600160008d73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001019190611701929190611e22565b508484600160008d73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206002019190611753929190611da2565b508282600160008d73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060030191906117a5929190611e22565b5080600160008c73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060040160006101000a81548160ff02191690831515021790555043600160008c73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206005018190555050505050505050505050565b6000600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636ddc4a076040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b1580156118d957600080fd5b505afa1580156118ed573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506119119190810190611fc0565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461197e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119759061258c565b60405180910390fd5b600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060040160009054906101000a900460ff169050919050565b6119dd610fd3565b611a1c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a13906125ec565b60405180910390fd5b611a2581611c35565b50565b6060600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636ddc4a076040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b158015611aae57600080fd5b505afa158015611ac2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611ae69190810190611fc0565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611b53576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b4a9061258c565b60405180910390fd5b600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015611c295780601f10611bfe57610100808354040283529160200191611c29565b820191906000526020600020905b815481529060010190602001808311611c0c57829003601f168201915b50505050509050919050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611ca5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c9c906125cc565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6040518060e001604052806060815260200160608152602001606081526020016060815260200160001515815260200160008152602001600081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10611de357803560ff1916838001178555611e11565b82800160010185558215611e11579182015b82811115611e10578235825591602001919060010190611df5565b5b509050611e1e9190611ea2565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10611e6357803560ff1916838001178555611e91565b82800160010185558215611e91579182015b82811115611e90578235825591602001919060010190611e75565b5b509050611e9e9190611ea2565b5090565b611ec491905b80821115611ec0576000816000905550600101611ea8565b5090565b90565b6000611ed382356126e6565b905092915050565b6000611ee782516126e6565b905092915050565b6000611efb82356126f8565b905092915050565b60008083601f840112611f1557600080fd5b8235905067ffffffffffffffff811115611f2e57600080fd5b602083019150836001820283011115611f4657600080fd5b9250929050565b60008083601f840112611f5f57600080fd5b8235905067ffffffffffffffff811115611f7857600080fd5b602083019150836001820283011115611f9057600080fd5b9250929050565b600060208284031215611fa957600080fd5b6000611fb784828501611ec7565b91505092915050565b600060208284031215611fd257600080fd5b6000611fe084828501611edb565b91505092915050565b60008060008060008060008060008060c08b8d03121561200857600080fd5b60006120168d828e01611ec7565b9a505060208b013567ffffffffffffffff81111561203357600080fd5b61203f8d828e01611f03565b995099505060408b013567ffffffffffffffff81111561205e57600080fd5b61206a8d828e01611f4d565b975097505060608b013567ffffffffffffffff81111561208957600080fd5b6120958d828e01611f03565b955095505060808b013567ffffffffffffffff8111156120b457600080fd5b6120c08d828e01611f4d565b935093505060a06120d38d828e01611eef565b9150509295989b9194979a5092959850565b6120ee8161269e565b82525050565b6120fd816126b0565b82525050565b61210c816126b0565b82525050565b600061211d82612639565b612127818561266b565b9350612137818560208601612748565b6121408161277b565b840191505092915050565b60006121568261262e565b612160818561265a565b9350612170818560208601612748565b6121798161277b565b840191505092915050565b600061218f8261262e565b612199818561266b565b93506121a9818560208601612748565b6121b28161277b565b840191505092915050565b6121c681612724565b82525050565b60006121d78261264f565b6121e1818561268d565b93506121f1818560208601612748565b6121fa8161277b565b840191505092915050565b600061221082612644565b61221a818561267c565b935061222a818560208601612748565b6122338161277b565b840191505092915050565b600061224982612644565b612253818561268d565b9350612263818560208601612748565b61226c8161277b565b840191505092915050565b600061228460138361268d565b91507f4572726f723a206f6e6c794c6f676963204462000000000000000000000000006000830152602082019050919050565b60006122c460298361268d565b91507f4572726f723a206e65774c6f6f6b5570206973206e6f7420616c6c6f7765642060008301527f746f2062652030783000000000000000000000000000000000000000000000006020830152604082019050919050565b600061232a601f8361268d565b91507f4e6577206f776e657220616464726573732063616e6e6f7420626520307830006000830152602082019050919050565b600061236a60138361268d565b91507f53656e646572206973206e6f74206f776e6572000000000000000000000000006000830152602082019050919050565b600060e08301600083015184820360008601526123ba828261214b565b915050602083015184820360208601526123d48282612205565b915050604083015184820360408601526123ee828261214b565b915050606083015184820360608601526124088282612205565b915050608083015161241d60808601826120f4565b5060a083015161243060a086018261244e565b5060c083015161244360c086018261244e565b508091505092915050565b612457816126dc565b82525050565b612466816126dc565b82525050565b600060208201905061248160008301846120e5565b92915050565b600060208201905061249c6000830184612103565b92915050565b600060208201905081810360008301526124bc8184612112565b905092915050565b600060e08201905081810360008301526124de818a612184565b905081810360208301526124f2818961223e565b905081810360408301526125068188612184565b9050818103606083015261251a818761223e565b90506125296080830186612103565b61253660a083018561245d565b61254360c083018461245d565b98975050505050505050565b600060208201905061256460008301846121bd565b92915050565b6000602082019050818103600083015261258481846121cc565b905092915050565b600060208201905081810360008301526125a581612277565b9050919050565b600060208201905081810360008301526125c5816122b7565b9050919050565b600060208201905081810360008301526125e58161231d565b9050919050565b600060208201905081810360008301526126058161235d565b9050919050565b60006020820190508181036000830152612626818461239d565b905092915050565b600081519050919050565b600081519050919050565b600081519050919050565b600081519050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b60006126a9826126bc565b9050919050565b60008115159050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b60006126f182612704565b9050919050565b60008115159050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061272f82612736565b9050919050565b6000612741826126bc565b9050919050565b60005b8381101561276657808201518184015260208101905061274b565b83811115612775576000848401525b50505050565b6000601f19601f830116905091905056fea265627a7a723058207e60ec05ac38073f6d98c9cff2cce094d00db0238d6d4b0c183253539a43fe2b6c6578706572696d656e74616cf5003700000000000000000000000012047000000000000000000000000000000000070000000000000000000000001204700000000000000000000000000000000005" + }, + "0x1204700000000000000000000000000000000009": { + "constructor": "0x60806040523480156200001157600080fd5b50604051604080620021cc8339810180604052620000339190810190620002af565b336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a381600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506200014a8162000152640100000000026401000000009004565b5050620003ad565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415620001c5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620001bc9062000332565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600062000291825162000365565b905092915050565b6000620002a7825162000379565b905092915050565b60008060408385031215620002c357600080fd5b6000620002d38582860162000299565b9250506020620002e68582860162000283565b9150509250929050565b6000620002ff601f8362000354565b91507f4e6577206f776e657220616464726573732063616e6e6f7420626520307830006000830152602082019050919050565b600060208201905081810360008301526200034d81620002f0565b9050919050565b600082825260208201905092915050565b600062000372826200038d565b9050919050565b6000620003868262000365565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b611e0f80620003bd6000396000f3fe608060405234801561001057600080fd5b50600436106100b0576000357c0100000000000000000000000000000000000000000000000000000000900480638da5cb5b116100835780638da5cb5b146101155780638f32d59b14610133578063b71da0d114610151578063ec26261114610181578063f2fde38b1461019f576100b0565b806312127ed7146100b55780633f67c333146100d1578063715018a6146100db57806389c3ce1e146100e5575b600080fd5b6100cf60048036036100ca9190810190611450565b6101bb565b005b6100d96109dd565b005b6100e3610b98565b005b6100ff60048036036100fa9190810190611427565b610c9e565b60405161010c9190611b14565b60405180910390f35b61011d610d85565b60405161012a91906119ab565b60405180910390f35b61013b610dae565b6040516101489190611a5e565b60405180910390f35b61016b60048036036101669190810190611427565b610e05565b6040516101789190611a5e565b60405180910390f35b610189610ed5565b6040516101969190611a79565b60405180910390f35b6101b960048036036101b49190810190611427565b610efb565b005b6101c3610dae565b610202576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101f990611ab4565b60405180910390fd5b6002856040516102129190611994565b602060405180830381855afa15801561022f573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052506102529190810190611562565b6002600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663fbd74f84896040518263ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004016102cb91906119ab565b60006040518083038186803b1580156102e357600080fd5b505afa1580156102f7573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250610320919081019061158b565b60405161032d9190611994565b602060405180830381855afa15801561034a573d6000803e3d6000fd5b5050506040513d601f19601f8201168201806040525061036d9190810190611562565b1480156104e257506002846040516103859190611994565b602060405180830381855afa1580156103a2573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052506103c59190810190611562565b6002600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a999809f896040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040161043e91906119ab565b60006040518083038186803b15801561045657600080fd5b505afa15801561046a573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525061049391908101906115cc565b6040516104a09190611994565b602060405180830381855afa1580156104bd573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052506104e09190810190611562565b145b801561065657506002836040516104f99190611994565b602060405180830381855afa158015610516573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052506105399190810190611562565b6002600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a05b18896040518263ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004016105b291906119ab565b60006040518083038186803b1580156105ca57600080fd5b505afa1580156105de573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250610607919081019061158b565b6040516106149190611994565b602060405180830381855afa158015610631573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052506106549190810190611562565b145b80156107ca575060028260405161066d9190611994565b602060405180830381855afa15801561068a573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052506106ad9190810190611562565b6002600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166332d91c0e896040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040161072691906119ab565b60006040518083038186803b15801561073e57600080fd5b505afa158015610752573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525061077b91908101906115cc565b6040516107889190611994565b602060405180830381855afa1580156107a5573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052506107c89190810190611562565b145b801561089f5750801515600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ee7ee0fd886040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040161084b91906119ab565b60206040518083038186803b15801561086357600080fd5b505afa158015610877573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061089b9190810190611539565b1515145b156108df576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108d690611ad4565b60405180910390fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663eab7ad928787878787876040518763ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401610960969594939291906119e1565b600060405180830381600087803b15801561097a57600080fd5b505af115801561098e573d6000803e3d6000fd5b505050508573ffffffffffffffffffffffffffffffffffffffff167fc9e49a024d50440c73d2d12d0ae05064094dca76b46dc95e99ea6848eb8f27e960405160405180910390a2505050505050565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663fbd74f84336040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401610a5691906119c6565b60006040518083038186803b158015610a6e57600080fd5b505afa158015610a82573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250610aab919081019061158b565b511415610aed576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ae490611af4565b60405180910390fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663954029c9336040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401610b6491906119c6565b600060405180830381600087803b158015610b7e57600080fd5b505af1158015610b92573d6000803e3d6000fd5b50505050565b610ba0610dae565b610bdf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bd690611ab4565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a360008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b610ca661107c565b610cae61107c565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631bab58f5846040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401610d2591906119ab565b60006040518083038186803b158015610d3d57600080fd5b505afa158015610d51573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250610d7a919081019061160d565b905080915050919050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614905090565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b71da0d1836040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401610e7e91906119ab565b60206040518083038186803b158015610e9657600080fd5b505afa158015610eaa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610ece9190810190611539565b9050919050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b610f03610dae565b610f42576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f3990611ab4565b60405180910390fd5b610f4b81610f4e565b50565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610fbe576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fb590611a94565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6040518060e001604052806060815260200160608152602001606081526020016060815260200160001515815260200160008152602001600081525090565b60006110c78235611cd6565b905092915050565b60006110db8235611ce8565b905092915050565b60006110ef8251611ce8565b905092915050565b60006111038251611cf4565b905092915050565b600082601f83011261111c57600080fd5b815161112f61112a82611b63565b611b36565b9150808252602083016020830185838301111561114b57600080fd5b611156838284611d91565b50505092915050565b600082601f83011261117057600080fd5b813561118361117e82611b8f565b611b36565b9150808252602083016020830185838301111561119f57600080fd5b6111aa838284611d82565b50505092915050565b600082601f8301126111c457600080fd5b81516111d76111d282611b8f565b611b36565b915080825260208301602083018583830111156111f357600080fd5b6111fe838284611d91565b50505092915050565b600082601f83011261121857600080fd5b815161122b61122682611bbb565b611b36565b9150808252602083016020830185838301111561124757600080fd5b611252838284611d91565b50505092915050565b600082601f83011261126c57600080fd5b813561127f61127a82611be7565b611b36565b9150808252602083016020830185838301111561129b57600080fd5b6112a6838284611d82565b50505092915050565b600082601f8301126112c057600080fd5b81516112d36112ce82611be7565b611b36565b915080825260208301602083018583830111156112ef57600080fd5b6112fa838284611d91565b50505092915050565b600060e0828403121561131557600080fd5b61131f60e0611b36565b9050600082015167ffffffffffffffff81111561133b57600080fd5b6113478482850161110b565b600083015250602082015167ffffffffffffffff81111561136757600080fd5b61137384828501611207565b602083015250604082015167ffffffffffffffff81111561139357600080fd5b61139f8482850161110b565b604083015250606082015167ffffffffffffffff8111156113bf57600080fd5b6113cb84828501611207565b60608301525060806113df848285016110e3565b60808301525060a06113f384828501611413565b60a08301525060c061140784828501611413565b60c08301525092915050565b600061141f8251611d1e565b905092915050565b60006020828403121561143957600080fd5b6000611447848285016110bb565b91505092915050565b60008060008060008060c0878903121561146957600080fd5b600061147789828a016110bb565b965050602087013567ffffffffffffffff81111561149457600080fd5b6114a089828a0161115f565b955050604087013567ffffffffffffffff8111156114bd57600080fd5b6114c989828a0161125b565b945050606087013567ffffffffffffffff8111156114e657600080fd5b6114f289828a0161115f565b935050608087013567ffffffffffffffff81111561150f57600080fd5b61151b89828a0161125b565b92505060a061152c89828a016110cf565b9150509295509295509295565b60006020828403121561154b57600080fd5b6000611559848285016110e3565b91505092915050565b60006020828403121561157457600080fd5b6000611582848285016110f7565b91505092915050565b60006020828403121561159d57600080fd5b600082015167ffffffffffffffff8111156115b757600080fd5b6115c3848285016111b3565b91505092915050565b6000602082840312156115de57600080fd5b600082015167ffffffffffffffff8111156115f857600080fd5b611604848285016112af565b91505092915050565b60006020828403121561161f57600080fd5b600082015167ffffffffffffffff81111561163957600080fd5b61164584828501611303565b91505092915050565b61165781611d28565b82525050565b61166681611c8e565b82525050565b61167581611ca0565b82525050565b61168481611ca0565b82525050565b600061169582611c1e565b61169f8185611c50565b93506116af818560208601611d91565b6116b881611dc4565b840191505092915050565b60006116ce82611c1e565b6116d88185611c61565b93506116e8818560208601611d91565b80840191505092915050565b60006116ff82611c13565b6117098185611c3f565b9350611719818560208601611d91565b61172281611dc4565b840191505092915050565b61173681611d3a565b82525050565b600061174782611c34565b6117518185611c7d565b9350611761818560208601611d91565b61176a81611dc4565b840191505092915050565b600061178082611c29565b61178a8185611c6c565b935061179a818560208601611d91565b6117a381611dc4565b840191505092915050565b60006117bb601f83611c7d565b91507f4e6577206f776e657220616464726573732063616e6e6f7420626520307830006000830152602082019050919050565b60006117fb601383611c7d565b91507f53656e646572206973206e6f74206f776e6572000000000000000000000000006000830152602082019050919050565b600061183b602583611c7d565b91507f4572726f723a204e6f206368616e67657320696e20746865207061737365642060008301527f53746174650000000000000000000000000000000000000000000000000000006020830152604082019050919050565b60006118a1601f83611c7d565b91507f4572726f723a20596f7520617265206e6f7420612076616c696461746f7221006000830152602082019050919050565b600060e08301600083015184820360008601526118f182826116f4565b9150506020830151848203602086015261190b8282611775565b9150506040830151848203604086015261192582826116f4565b9150506060830151848203606086015261193f8282611775565b9150506080830151611954608086018261166c565b5060a083015161196760a0860182611985565b5060c083015161197a60c0860182611985565b508091505092915050565b61198e81611ccc565b82525050565b60006119a082846116c3565b915081905092915050565b60006020820190506119c0600083018461165d565b92915050565b60006020820190506119db600083018461164e565b92915050565b600060c0820190506119f6600083018961165d565b8181036020830152611a08818861168a565b90508181036040830152611a1c818761173c565b90508181036060830152611a30818661168a565b90508181036080830152611a44818561173c565b9050611a5360a083018461167b565b979650505050505050565b6000602082019050611a73600083018461167b565b92915050565b6000602082019050611a8e600083018461172d565b92915050565b60006020820190508181036000830152611aad816117ae565b9050919050565b60006020820190508181036000830152611acd816117ee565b9050919050565b60006020820190508181036000830152611aed8161182e565b9050919050565b60006020820190508181036000830152611b0d81611894565b9050919050565b60006020820190508181036000830152611b2e81846118d4565b905092915050565b6000604051905081810181811067ffffffffffffffff82111715611b5957600080fd5b8060405250919050565b600067ffffffffffffffff821115611b7a57600080fd5b601f19601f8301169050602081019050919050565b600067ffffffffffffffff821115611ba657600080fd5b601f19601f8301169050602081019050919050565b600067ffffffffffffffff821115611bd257600080fd5b601f19601f8301169050602081019050919050565b600067ffffffffffffffff821115611bfe57600080fd5b601f19601f8301169050602081019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b600081519050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b6000611c9982611cac565b9050919050565b60008115159050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b6000611ce182611cfe565b9050919050565b60008115159050919050565b6000819050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b6000611d3382611d5e565b9050919050565b6000611d4582611d4c565b9050919050565b6000611d5782611cac565b9050919050565b6000611d6982611d70565b9050919050565b6000611d7b82611cac565b9050919050565b82818337600083830152505050565b60005b83811015611daf578082015181840152602081019050611d94565b83811115611dbe576000848401525b50505050565b6000601f19601f830116905091905056fea265627a7a723058204ed2d756516ea8df8dbc4fbf2bd76bb43e93ab01c8c274fc9169dfd0be6254d06c6578706572696d656e74616cf5003700000000000000000000000012047000000000000000000000000000000000080000000000000000000000001204700000000000000000000000000000000005" + } + }, + "nodes": [ + "enode://59c9250cb805409e84c9cd0038e97d8e5e4605b928663675869ebdfd4c251d80ccad76267a5eb2f4362ddceb5ec671f7595463adfc0a12e9f68dbf233072db41@54.70.158.106:30303", + "enode://e487ebacbdad3418905d2ed7f009fa5dbd17d73880854884acc604c0afc1a60a396aa90cb2741278c555a4e30ffc6ffc1c29e83840aa22009ec92fe53f81ec04@99.81.92.124:30303", + "enode://563f12602a117201b39ebeea108185abb15d9286830c074640c9fccbaaaabcc7fe2c95682cc43f95b95059f6d0dc4c9becbc1b2bd78e0c5ef5fddff07d85ba0e@54.201.62.74:30303", + "enode://5903b3acebdc4a34800f6923e5f3aec3ca7e5d1285bec4adb9f20ebb0f87a3bebdd748b1849ca1108a9f1e37ff9ced0b475292b8effc29e95d49ec438f244b02@3.121.165.10:30303", + "enode://8f8e35a6dcacfee946f46447b4703c84f4e485e478143997f86b1834e1b0bb78dab363d700dff3147442b9d3e2a1c521f79340c436eb7245a97c7fe385b89a5d@54.93.159.98:30303", + "enode://bd228aa03cf4a88491c81c5f3ab4a1437df3b463081cc93943c4d3ab37f1e4f8081c6995eca076f717d4fdf9a277c750bd0289477ac151f1e2b024747dcd1747@52.31.129.130:30303" + ] +} diff --git a/ethcore/service/Cargo.toml b/ethcore/service/Cargo.toml index 7db0ad2770..c0be41038b 100644 --- a/ethcore/service/Cargo.toml +++ b/ethcore/service/Cargo.toml @@ -1,4 +1,5 @@ [package] +description = "Parity Ethereum (EthCore) Client & Network Service Creation & Registration with the I/O Subsystem" name = "ethcore-service" version = "0.1.0" authors = ["Parity Technologies "] diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index 047de5580f..12372b83ee 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -1109,7 +1109,7 @@ impl Client { let mut ss = self.sleep_state.lock(); if let Some(t) = ss.last_activity { if Instant::now() > t + timeout { - self.sleep(); + self.sleep(false); ss.last_activity = None; } } @@ -1119,7 +1119,7 @@ impl Client { let now = Instant::now(); if let Some(t) = ss.last_activity { if now > t + timeout { - self.sleep(); + self.sleep(false); ss.last_activity = None; ss.last_autosleep = Some(now); } @@ -1218,10 +1218,10 @@ impl Client { } } - fn sleep(&self) { + fn sleep(&self, force: bool) { if self.liveness.load(AtomicOrdering::Relaxed) { // only sleep if the import queue is mostly empty. - if self.queue_info().total_queue_size() <= MAX_QUEUE_SIZE_TO_SLEEP_ON { + if force || (self.queue_info().total_queue_size() <= MAX_QUEUE_SIZE_TO_SLEEP_ON) { self.liveness.store(false, AtomicOrdering::Relaxed); self.notify(|n| n.stop()); info!(target: "mode", "sleep: Sleeping."); @@ -1730,7 +1730,7 @@ impl BlockChainClient for Client { } match new_mode { Mode::Active => self.wake_up(), - Mode::Off => self.sleep(), + Mode::Off => self.sleep(true), _ => {(*self.sleep_state.lock()).last_activity = Some(Instant::now()); } } } diff --git a/ethcore/src/ethereum/mod.rs b/ethcore/src/ethereum/mod.rs index d85fbf9b7b..cfd2ac5cc4 100644 --- a/ethcore/src/ethereum/mod.rs +++ b/ethcore/src/ethereum/mod.rs @@ -57,9 +57,14 @@ pub fn new_poanet<'a, T: Into>>(params: T) -> Spec { load(params.into(), include_bytes!("../../res/ethereum/poacore.json")) } -/// Create a new Tobalaba mainnet chain spec. -pub fn new_tobalaba<'a, T: Into>>(params: T) -> Spec { - load(params.into(), include_bytes!("../../res/ethereum/tobalaba.json")) +/// Create a new Volta mainnet chain spec. +pub fn new_volta<'a, T: Into>>(params: T) -> Spec { + load(params.into(), include_bytes!("../../res/ethereum/volta.json")) +} + +/// Create a new EWC mainnet chain spec. +pub fn new_ewc<'a, T: Into>>(params: T) -> Spec { + load(params.into(), include_bytes!("../../res/ethereum/ewc.json")) } /// Create a new Expanse mainnet chain spec. diff --git a/ethcore/src/executive.rs b/ethcore/src/executive.rs index 68d4edc794..f96cd7687c 100644 --- a/ethcore/src/executive.rs +++ b/ethcore/src/executive.rs @@ -33,7 +33,7 @@ use externalities::*; use trace::{self, Tracer, VMTracer}; use types::transaction::{Action, SignedTransaction}; use transaction_ext::Transaction; -use crossbeam; +use crossbeam_utils::thread; pub use executed::{Executed, ExecutionResult}; #[cfg(debug_assertions)] @@ -976,11 +976,18 @@ impl<'a, B: 'a + StateBackend> Executive<'a, B> { if stack_depth != depth_threshold { self.call_with_stack_depth(params, substate, stack_depth, tracer, vm_tracer) } else { - crossbeam::scope(|scope| { - scope.builder().stack_size(::std::cmp::max(self.schedule.max_depth.saturating_sub(depth_threshold) * STACK_SIZE_PER_DEPTH, local_stack_size)).spawn(move || { - self.call_with_stack_depth(params, substate, stack_depth, tracer, vm_tracer) - }).expect("Sub-thread creation cannot fail; the host might run out of resources; qed") - }).join().expect("Sub-thread never panics; qed") + thread::scope(|scope| { + let stack_size = cmp::max(self.schedule.max_depth.saturating_sub(depth_threshold) * STACK_SIZE_PER_DEPTH, local_stack_size); + scope.builder() + .stack_size(stack_size) + .spawn(|_| { + self.call_with_stack_depth(params, substate, stack_depth, tracer, vm_tracer) + }) + .expect("Sub-thread creation cannot fail; the host might run out of resources; qed") + .join() + }) + .expect("Sub-thread never panics; qed") + .expect("Sub-thread never panics; qed") } } @@ -1060,11 +1067,18 @@ impl<'a, B: 'a + StateBackend> Executive<'a, B> { if stack_depth != depth_threshold { self.create_with_stack_depth(params, substate, stack_depth, tracer, vm_tracer) } else { - crossbeam::scope(|scope| { - scope.builder().stack_size(::std::cmp::max(self.schedule.max_depth.saturating_sub(depth_threshold) * STACK_SIZE_PER_DEPTH, local_stack_size)).spawn(move || { - self.create_with_stack_depth(params, substate, stack_depth, tracer, vm_tracer) - }).expect("Sub-thread creation cannot fail; the host might run out of resources; qed") - }).join().expect("Sub-thread never panics; qed") + thread::scope(|scope| { + let stack_size = cmp::max(self.schedule.max_depth.saturating_sub(depth_threshold) * STACK_SIZE_PER_DEPTH, local_stack_size); + scope.builder() + .stack_size(stack_size) + .spawn(|_| { + self.create_with_stack_depth(params, substate, stack_depth, tracer, vm_tracer) + }) + .expect("Sub-thread creation cannot fail; the host might run out of resources; qed") + .join() + }) + .expect("Sub-thread never panics; qed") + .expect("Sub-thread never panics; qed") } } diff --git a/ethcore/src/lib.rs b/ethcore/src/lib.rs index 6578d36071..2ad8e29e59 100644 --- a/ethcore/src/lib.rs +++ b/ethcore/src/lib.rs @@ -61,7 +61,7 @@ extern crate ansi_term; extern crate bn; extern crate byteorder; extern crate common_types as types; -extern crate crossbeam; +extern crate crossbeam_utils; extern crate ethabi; extern crate ethash; extern crate ethcore_blockchain as blockchain; diff --git a/ethcore/src/snapshot/mod.rs b/ethcore/src/snapshot/mod.rs index ae7a217099..79b4eae949 100644 --- a/ethcore/src/snapshot/mod.rs +++ b/ethcore/src/snapshot/mod.rs @@ -50,7 +50,7 @@ use self::io::SnapshotWriter; use super::state_db::StateDB; use super::state::Account as StateAccount; -use crossbeam::scope; +use crossbeam_utils::thread; use rand::{Rng, OsRng}; pub use self::error::Error; @@ -167,9 +167,9 @@ pub fn take_snapshot( let version = chunker.current_version(); let writer = Mutex::new(writer); - let (state_hashes, block_hashes) = scope(|scope| -> Result<(Vec, Vec), Error> { + let (state_hashes, block_hashes) = thread::scope(|scope| -> Result<(Vec, Vec), Error> { let writer = &writer; - let block_guard = scope.spawn(move || { + let block_guard = scope.spawn(move |_| { chunk_secondary(chunker, chain, block_hash, writer, p) }); @@ -181,7 +181,7 @@ pub fn take_snapshot( let mut state_guards = Vec::with_capacity(num_threads as usize); for thread_idx in 0..num_threads { - let state_guard = scope.spawn(move || -> Result, Error> { + let state_guard = scope.spawn(move |_| -> Result, Error> { let mut chunk_hashes = Vec::new(); for part in (thread_idx..SNAPSHOT_SUBPARTS).step_by(num_threads) { @@ -205,7 +205,7 @@ pub fn take_snapshot( debug!(target: "snapshot", "Took a snapshot of {} accounts", p.accounts.load(Ordering::SeqCst)); Ok((state_hashes, block_hashes)) - })?; + }).expect("Sub-thread never panics; qed")?; info!(target: "snapshot", "produced {} state chunks and {} block chunks.", state_hashes.len(), block_hashes.len()); diff --git a/ethcore/sync/Cargo.toml b/ethcore/sync/Cargo.toml index bc7a80e670..66515ef3ba 100644 --- a/ethcore/sync/Cargo.toml +++ b/ethcore/sync/Cargo.toml @@ -1,5 +1,5 @@ [package] -description = "Ethcore blockchain sync" +description = "Parity Ethereum (EthCore) Blockchain Synchronization (Strategy, Blockchain Downloader, Blockchain Synchronization Implementation of Ethereum Protocol, Propagating Data to Peers, Requesting Data from Peers, Supplying Data in Response to Peer Requests, Handling Peer Responses, Matching Packet IDs and Protocol, Light Client Synchronization of Header Chain, Header Download State Machine, Light Decoding & Verifying Header Responses, Private Transaction Handling, Synchronization Snapshot Service to Download & Verify Block Chunks, Peer Connection Management and Blockchain Client I/O Interface for Synchronization Handler, Transaction Statistics)" name = "ethcore-sync" version = "1.12.0" license = "GPL-3.0" diff --git a/ethcore/sync/src/chain/mod.rs b/ethcore/sync/src/chain/mod.rs index 81f1ccffe9..58359f062f 100644 --- a/ethcore/sync/src/chain/mod.rs +++ b/ethcore/sync/src/chain/mod.rs @@ -962,7 +962,7 @@ impl ChainSync { } // Only ask for old blocks if the peer has an equal or higher difficulty - let equal_or_higher_difficulty = peer_difficulty.map_or(false, |pd| pd >= syncing_difficulty); + let equal_or_higher_difficulty = peer_difficulty.map_or(true, |pd| pd >= syncing_difficulty); if force || equal_or_higher_difficulty { if let Some(request) = self.old_blocks.as_mut().and_then(|d| d.request_blocks(peer_id, io, num_active_peers)) { diff --git a/ethcore/types/Cargo.toml b/ethcore/types/Cargo.toml index e3f9bd1db6..0d2cef5152 100644 --- a/ethcore/types/Cargo.toml +++ b/ethcore/types/Cargo.toml @@ -1,6 +1,6 @@ [package] +description = "Parity Ethereum Common Types" name = "common-types" -description = "Common types used throughout the codebase" version = "0.1.0" authors = ["Parity Technologies "] diff --git a/ethcore/types/src/restoration_status.rs b/ethcore/types/src/restoration_status.rs index dea342a310..b36ec7ef4a 100644 --- a/ethcore/types/src/restoration_status.rs +++ b/ethcore/types/src/restoration_status.rs @@ -21,7 +21,7 @@ pub enum RestorationStatus { /// No restoration. Inactive, - /// Restoration is initalizing + /// Restoration is initializing Initializing { /// Number of chunks done/imported chunks_done: u32, diff --git a/ethcore/vm/Cargo.toml b/ethcore/vm/Cargo.toml index 19b84a6ecc..0e77ea0212 100644 --- a/ethcore/vm/Cargo.toml +++ b/ethcore/vm/Cargo.toml @@ -1,4 +1,5 @@ [package] +description = "Virtual Machines (VM) Support Library" name = "vm" version = "0.1.0" authors = ["Parity Technologies "] diff --git a/ethcore/wasm/Cargo.toml b/ethcore/wasm/Cargo.toml index 02aa978d7b..e724a6a4cf 100644 --- a/ethcore/wasm/Cargo.toml +++ b/ethcore/wasm/Cargo.toml @@ -1,4 +1,5 @@ [package] +description = "WASM Interpreter" name = "wasm" version = "0.1.0" authors = ["Parity Technologies "] diff --git a/ethcore/wasm/run/Cargo.toml b/ethcore/wasm/run/Cargo.toml index 9260d1eee8..eee0d5fa32 100644 --- a/ethcore/wasm/run/Cargo.toml +++ b/ethcore/wasm/run/Cargo.toml @@ -1,4 +1,5 @@ [package] +description = "Parity WASM Test Run" name = "pwasm-run-test" version = "0.1.0" authors = ["Parity Technologies "] diff --git a/evmbin/Cargo.toml b/evmbin/Cargo.toml index 95b532366c..dd6a3aad04 100644 --- a/evmbin/Cargo.toml +++ b/evmbin/Cargo.toml @@ -1,6 +1,6 @@ [package] +description = "Parity EVM Implementation" name = "evmbin" -description = "Parity's EVM implementation" version = "0.1.0" authors = ["Parity Technologies "] diff --git a/ipfs/Cargo.toml b/ipfs/Cargo.toml index 23dc8d6898..3c0fcd7947 100644 --- a/ipfs/Cargo.toml +++ b/ipfs/Cargo.toml @@ -1,5 +1,5 @@ [package] -description = "Parity IPFS-compatible API" +description = "Parity Ethereum IPFS-compatible API" name = "parity-ipfs-api" version = "1.12.0" license = "GPL-3.0" diff --git a/json/Cargo.toml b/json/Cargo.toml index 2a6d8c7f36..164ee6bce4 100644 --- a/json/Cargo.toml +++ b/json/Cargo.toml @@ -1,4 +1,5 @@ [package] +description = "Parity Ethereum JSON Deserialization" name = "ethjson" version = "0.1.0" authors = ["Parity Technologies "] diff --git a/miner/Cargo.toml b/miner/Cargo.toml index f7dfd8f083..25d8e14c8b 100644 --- a/miner/Cargo.toml +++ b/miner/Cargo.toml @@ -1,5 +1,5 @@ [package] -description = "Parity Miner interface." +description = "Parity Ethereum Miner Interface." name = "ethcore-miner" homepage = "http://parity.io" license = "GPL-3.0" diff --git a/parity/cli/mod.rs b/parity/cli/mod.rs index 561f547712..754e557b59 100644 --- a/parity/cli/mod.rs +++ b/parity/cli/mod.rs @@ -300,7 +300,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 ethereum, classic, poacore, tobalaba, expanse, musicoin, ellaism, mix, callisto, morden, ropsten, kovan, rinkeby, goerli, kotti, poasokol, testnet, or dev.", + "Specify the blockchain type. CHAIN may be either a JSON chain specification file or ethereum, classic, poacore, volta, ewc, expanse, musicoin, ellaism, mix, callisto, morden, ropsten, kovan, rinkeby, goerli, kotti, poasokol, testnet, 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/configuration.rs b/parity/configuration.rs index 1a8338637a..c2f18150b2 100644 --- a/parity/configuration.rs +++ b/parity/configuration.rs @@ -16,7 +16,7 @@ use std::time::Duration; use std::io::Read; -use std::net::SocketAddr; +use std::net::{SocketAddr, ToSocketAddrs}; use std::num::NonZeroU32; use std::path::PathBuf; use std::collections::{HashSet, BTreeMap}; @@ -725,9 +725,18 @@ impl Configuration { let port = self.args.arg_ports_shift + self.args.arg_port; let listen_address = SocketAddr::new(self.interface(&self.args.arg_interface).parse().unwrap(), port); let public_address = if self.args.arg_nat.starts_with("extip:") { - let host = &self.args.arg_nat[6..]; - let host = host.parse().map_err(|_| format!("Invalid host given with `--nat extip:{}`", host))?; - Some(SocketAddr::new(host, port)) + let host = self.args.arg_nat[6..].split(':').next().expect("split has at least one part; qed"); + let host = format!("{}:{}", host, port); + match host.to_socket_addrs() { + Ok(mut addr_iter) => { + if let Some(addr) = addr_iter.next() { + Some(addr) + } else { + return Err(format!("Invalid host given with `--nat extip:{}`", &self.args.arg_nat[6..])) + } + }, + Err(_) => return Err(format!("Invalid host given with `--nat extip:{}`", &self.args.arg_nat[6..])) + } } else { None }; @@ -1839,6 +1848,33 @@ mod tests { assert_eq!(conf1.ipfs_config().port, 5002); } + #[test] + fn should_resolve_external_nat_hosts() { + // Ip works + let conf = parse(&["parity", "--nat", "extip:1.1.1.1"]); + assert_eq!(conf.net_addresses().unwrap().1.unwrap().ip().to_string(), "1.1.1.1"); + assert_eq!(conf.net_addresses().unwrap().1.unwrap().port(), 30303); + + // Ip with port works, port is discarded + let conf = parse(&["parity", "--nat", "extip:192.168.1.1:123"]); + assert_eq!(conf.net_addresses().unwrap().1.unwrap().ip().to_string(), "192.168.1.1"); + assert_eq!(conf.net_addresses().unwrap().1.unwrap().port(), 30303); + + // Hostname works + let conf = parse(&["parity", "--nat", "extip:ethereum.org"]); + assert!(conf.net_addresses().unwrap().1.is_some()); + assert_eq!(conf.net_addresses().unwrap().1.unwrap().port(), 30303); + + // Hostname works, garbage at the end is discarded + let conf = parse(&["parity", "--nat", "extip:ethereum.org:whatever bla bla 123"]); + assert!(conf.net_addresses().unwrap().1.is_some()); + assert_eq!(conf.net_addresses().unwrap().1.unwrap().port(), 30303); + + // Garbage is error + let conf = parse(&["parity", "--nat", "extip:blabla"]); + assert!(conf.net_addresses().is_err()); + } + #[test] fn should_expose_all_servers() { // given diff --git a/parity/logger/Cargo.toml b/parity/logger/Cargo.toml index 17c8c4396d..217bcf48a6 100644 --- a/parity/logger/Cargo.toml +++ b/parity/logger/Cargo.toml @@ -1,5 +1,5 @@ [package] -description = "Log implementation for Parity" +description = "Parity Ethereum Logger Implementation" name = "ethcore-logger" version = "1.12.0" license = "GPL-3.0" diff --git a/parity/params.rs b/parity/params.rs index d01f784616..a8164dd261 100644 --- a/parity/params.rs +++ b/parity/params.rs @@ -36,7 +36,8 @@ pub enum SpecType { Foundation, Classic, Poanet, - Tobalaba, + Volta, + Ewc, Expanse, Musicoin, Ellaism, @@ -67,7 +68,8 @@ impl str::FromStr for SpecType { "ethereum" | "frontier" | "homestead" | "byzantium" | "foundation" | "mainnet" => SpecType::Foundation, "classic" | "frontier-dogmatic" | "homestead-dogmatic" => SpecType::Classic, "poanet" | "poacore" => SpecType::Poanet, - "tobalaba" => SpecType::Tobalaba, + "volta" => SpecType::Volta, + "ewc" | "energyweb" => SpecType::Ewc, "expanse" => SpecType::Expanse, "musicoin" => SpecType::Musicoin, "ellaism" => SpecType::Ellaism, @@ -93,7 +95,8 @@ impl fmt::Display for SpecType { SpecType::Foundation => "foundation", SpecType::Classic => "classic", SpecType::Poanet => "poanet", - SpecType::Tobalaba => "tobalaba", + SpecType::Volta => "volta", + SpecType::Ewc => "energyweb", SpecType::Expanse => "expanse", SpecType::Musicoin => "musicoin", SpecType::Ellaism => "ellaism", @@ -119,7 +122,8 @@ impl SpecType { SpecType::Foundation => Ok(ethereum::new_foundation(params)), SpecType::Classic => Ok(ethereum::new_classic(params)), SpecType::Poanet => Ok(ethereum::new_poanet(params)), - SpecType::Tobalaba => Ok(ethereum::new_tobalaba(params)), + SpecType::Volta => Ok(ethereum::new_volta(params)), + SpecType::Ewc => Ok(ethereum::new_ewc(params)), SpecType::Expanse => Ok(ethereum::new_expanse(params)), SpecType::Musicoin => Ok(ethereum::new_musicoin(params)), SpecType::Ellaism => Ok(ethereum::new_ellaism(params)), @@ -376,7 +380,9 @@ mod tests { assert_eq!(SpecType::Classic, "homestead-dogmatic".parse().unwrap()); assert_eq!(SpecType::Poanet, "poanet".parse().unwrap()); assert_eq!(SpecType::Poanet, "poacore".parse().unwrap()); - assert_eq!(SpecType::Tobalaba, "tobalaba".parse().unwrap()); + assert_eq!(SpecType::Volta, "volta".parse().unwrap()); + assert_eq!(SpecType::Ewc, "ewc".parse().unwrap()); + assert_eq!(SpecType::Ewc, "energyweb".parse().unwrap()); assert_eq!(SpecType::Expanse, "expanse".parse().unwrap()); assert_eq!(SpecType::Musicoin, "musicoin".parse().unwrap()); assert_eq!(SpecType::Ellaism, "ellaism".parse().unwrap()); @@ -405,7 +411,8 @@ mod tests { assert_eq!(format!("{}", SpecType::Foundation), "foundation"); assert_eq!(format!("{}", SpecType::Classic), "classic"); assert_eq!(format!("{}", SpecType::Poanet), "poanet"); - assert_eq!(format!("{}", SpecType::Tobalaba), "tobalaba"); + assert_eq!(format!("{}", SpecType::Volta), "volta"); + assert_eq!(format!("{}", SpecType::Ewc), "energyweb"); assert_eq!(format!("{}", SpecType::Expanse), "expanse"); assert_eq!(format!("{}", SpecType::Musicoin), "musicoin"); assert_eq!(format!("{}", SpecType::Ellaism), "ellaism"); diff --git a/rpc/Cargo.toml b/rpc/Cargo.toml index 33559a5595..4d796263c1 100644 --- a/rpc/Cargo.toml +++ b/rpc/Cargo.toml @@ -1,5 +1,5 @@ [package] -description = "Parity JSON-RPC servers." +description = "Parity Ethereum JSON-RPC Servers (WS, HTTP, IPC)" name = "parity-rpc" version = "1.12.0" license = "GPL-3.0" diff --git a/rpc/src/lib.rs b/rpc/src/lib.rs index a537cb2942..6c0ce2a011 100644 --- a/rpc/src/lib.rs +++ b/rpc/src/lib.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Parity Ethereum. If not, see . -//! Parity RPC. +//! Parity Ethereum JSON-RPC Servers (WS, HTTP, IPC). #![warn(missing_docs, unused_extern_crates)] #![cfg_attr(feature = "cargo-clippy", warn(clippy::all, clippy::pedantic))] diff --git a/rpc/src/v1/helpers/engine_signer.rs b/rpc/src/v1/helpers/engine_signer.rs index f993d15f23..56cead696c 100644 --- a/rpc/src/v1/helpers/engine_signer.rs +++ b/rpc/src/v1/helpers/engine_signer.rs @@ -37,10 +37,7 @@ impl ethcore::engines::EngineSigner for EngineSigner { fn sign(&self, message: ethkey::Message) -> Result { match self.accounts.sign(self.address, Some(self.password.clone()), message) { Ok(ok) => Ok(ok), - Err(e) => { - warn!("Unable to sign consensus message: {:?}", e); - Err(ethkey::Error::InvalidSecret) - }, + Err(e) => Err(ethkey::Error::InvalidSecret), } } diff --git a/scripts/gitlab/publish-av-whitelists.sh b/scripts/gitlab/publish-av-whitelists.sh new file mode 100755 index 0000000000..3c5dde8075 --- /dev/null +++ b/scripts/gitlab/publish-av-whitelists.sh @@ -0,0 +1,25 @@ +#!/bin/bash +set -e + +target_filename="parity-${CI_COMMIT_TAG:-${CI_COMMIT_REF_NAME}}.exe" +apt -y update +apt -y install ftp + +echo "__________Publish Windows binaries to Avast Whitelisting program__________" + +ftp -pinv whitelisting.avast.com <"] build = "build.rs" diff --git a/whisper/Cargo.toml b/whisper/Cargo.toml index 97aa8f23ac..bc29051b23 100644 --- a/whisper/Cargo.toml +++ b/whisper/Cargo.toml @@ -1,8 +1,8 @@ [package] +description = "Parity Ethereum Whisper Protocol Implementation" name = "parity-whisper" version = "0.1.0" authors = ["Parity Technologies "] -description = "Whisper Protocol implementation for Parity" [dependencies] bitflags = "0.9" From 6bd7db96fece97d945da9af83fc5a1bc7ff2eb46 Mon Sep 17 00:00:00 2001 From: s3krit Date: Thu, 29 Aug 2019 12:06:49 +0200 Subject: [PATCH 162/168] v2.5.7 stable (#11006) * [trace] check mem diff within range (#11002) * Update version (v2.5.7-stable) --- Cargo.lock | 14 +++++++------- Cargo.toml | 2 +- ethcore/src/trace/executive_tracer.rs | 15 ++++++++++++++- util/version/Cargo.toml | 2 +- 4 files changed, 23 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 625564013d..16dac7aede 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2278,7 +2278,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2392,7 +2392,7 @@ dependencies = [ "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", "jni 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "panic_hook 0.1.0", - "parity-ethereum 2.5.6", + "parity-ethereum 2.5.7", "tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-current-thread 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2422,7 +2422,7 @@ dependencies = [ [[package]] name = "parity-ethereum" -version = "2.5.6" +version = "2.5.7" dependencies = [ "ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2475,7 +2475,7 @@ dependencies = [ "parity-rpc 1.12.0", "parity-runtime 0.1.0", "parity-updater 1.12.0", - "parity-version 2.5.6", + "parity-version 2.5.7", "parity-whisper 0.1.0", "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2618,7 +2618,7 @@ dependencies = [ "parity-crypto 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-runtime 0.1.0", "parity-updater 1.12.0", - "parity-version 2.5.6", + "parity-version 2.5.7", "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2716,7 +2716,7 @@ dependencies = [ "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-hash-fetch 1.12.0", "parity-path 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-version 2.5.6", + "parity-version 2.5.7", "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2726,7 +2726,7 @@ dependencies = [ [[package]] name = "parity-version" -version = "2.5.6" +version = "2.5.7" dependencies = [ "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "rlp 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index 9bd8d16f9a..28e26fadf6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ description = "Parity Ethereum client" name = "parity-ethereum" # NOTE Make sure to update util/version/Cargo.toml as well -version = "2.5.6" +version = "2.5.7" license = "GPL-3.0" authors = ["Parity Technologies "] diff --git a/ethcore/src/trace/executive_tracer.rs b/ethcore/src/trace/executive_tracer.rs index 015deaea03..dbb2bc1eca 100644 --- a/ethcore/src/trace/executive_tracer.rs +++ b/ethcore/src/trace/executive_tracer.rs @@ -18,6 +18,7 @@ use ethereum_types::{U256, Address}; use vm::{Error as VmError, ActionParams}; +use log::{debug, warn}; use trace::trace::{Call, Create, Action, Res, CreateResult, CallResult, VMTrace, VMOperation, VMExecutedOperation, MemoryDiff, StorageDiff, Suicide, Reward, RewardType}; use trace::{Tracer, VMTracer, FlatTrace}; @@ -245,7 +246,19 @@ impl VMTracer for ExecutiveVMTracer { } fn trace_executed(&mut self, gas_used: U256, stack_push: &[U256], mem: &[u8]) { - let mem_diff = self.last_mem_written.take().map(|(o, s)| (o, &(mem[o..o+s]))); + let mem_diff = self.last_mem_written.take().map(|(o, s)| { + if o + s > mem.len() { + warn!( + target: "trace", + "Last mem written is out of bounds {} (mem is {})", + o + s, + mem.len(), + ); + (o, &[][..]) + } else { + (o, &(mem[o..o+s])) + } + }); let store_diff = self.last_store_written.take(); Self::with_trace_in_depth(&mut self.data, self.depth, move |trace| { let ex = VMExecutedOperation { diff --git a/util/version/Cargo.toml b/util/version/Cargo.toml index 5cfd5b8b9f..77f159dc99 100644 --- a/util/version/Cargo.toml +++ b/util/version/Cargo.toml @@ -3,7 +3,7 @@ [package] name = "parity-version" # NOTE: this value is used for Parity Ethereum version string (via env CARGO_PKG_VERSION) -version = "2.5.6" +version = "2.5.7" authors = ["Parity Technologies "] build = "build.rs" From 45f27cec34e6d3e1d2afa4d3b445db8d043d607a Mon Sep 17 00:00:00 2001 From: s3krit Date: Thu, 12 Sep 2019 18:43:53 +0200 Subject: [PATCH 163/168] v2.5.8-stable (#11041) * add more tx tests (#11038) * Fix parallel transactions race-condition (#10995) * Add blake2_f precompile (#11017) * [trace] introduce trace failed to Ext (#11019) * Edit publish-onchain.sh to use https (#11016) * Fix deadlock in network-devp2p (#11013) * EIP 1108: Reduce alt_bn128 precompile gas costs (#11008) * xDai chain support and nodes list update (#10989) * EIP 2028: transaction gas lowered from 68 to 16 (#10987) * EIP-1344 Add CHAINID op-code (#10983) * manual publish jobs for releases, no changes for nightlies (#10977) * [blooms-db] Fix benchmarks (#10974) * Verify transaction against its block during import (#10954) * Better error message for rpc gas price errors (#10931) * tx-pool: accept local tx with higher gas price when pool full (#10901) * Fix fork choice (#10837) * Cleanup unused vm dependencies (#10787) * Fix compilation on recent nightlies (#10991) --- .gitlab-ci.yml | 78 ++- Cargo.lock | 117 +++- Cargo.toml | 2 +- accounts/ethkey/Cargo.toml | 2 +- accounts/ethkey/cli/Cargo.toml | 2 +- accounts/ethstore/Cargo.toml | 2 +- ethcore/Cargo.toml | 2 + ethcore/blockchain/Cargo.toml | 6 +- ethcore/blockchain/src/blockchain.rs | 78 ++- ethcore/blockchain/src/generator.rs | 33 +- ethcore/evm/Cargo.toml | 1 + ethcore/evm/src/factory.rs | 2 +- ethcore/evm/src/instructions.rs | 10 +- ethcore/evm/src/interpreter/mod.rs | 72 +- ethcore/evm/src/lib.rs | 2 + ethcore/evm/src/tests.rs | 23 +- ethcore/private-tx/Cargo.toml | 2 +- ethcore/res/authority_round.json | 47 +- ...authority_round_block_reward_contract.json | 47 +- ethcore/res/basic_authority.json | 47 +- ethcore/res/constructor.json | 47 +- ethcore/res/ethereum/byzantium_test.json | 44 +- ethcore/res/ethereum/callisto.json | 47 +- ethcore/res/ethereum/classic.json | 19 +- ethcore/res/ethereum/constantinople_test.json | 44 +- ethcore/res/ethereum/eip210_test.json | 44 +- ethcore/res/ethereum/ellaism.json | 44 +- ethcore/res/ethereum/ewc.json | 23 +- ethcore/res/ethereum/expanse.json | 44 +- ethcore/res/ethereum/foundation.json | 19 +- ethcore/res/ethereum/goerli.json | 25 +- ethcore/res/ethereum/kotti.json | 19 +- ethcore/res/ethereum/kovan.json | 21 +- ethcore/res/ethereum/kovan_wasm_test.json | 44 +- ethcore/res/ethereum/mcip3_test.json | 47 +- ethcore/res/ethereum/mix.json | 44 +- ethcore/res/ethereum/morden.json | 19 +- ethcore/res/ethereum/musicoin.json | 47 +- ethcore/res/ethereum/poacore.json | 46 +- ethcore/res/ethereum/poasokol.json | 46 +- ethcore/res/ethereum/rinkeby.json | 22 +- ethcore/res/ethereum/ropsten.json | 19 +- ethcore/res/ethereum/st_peters_test.json | 44 +- ethcore/res/ethereum/transition_test.json | 45 +- ethcore/res/ethereum/volta.json | 27 +- ethcore/res/ethereum/xdai.json | 157 +++++ ethcore/res/instant_seal.json | 47 +- ethcore/res/null.json | 47 +- ethcore/src/builtin.rs | 619 +++++++++++++----- ethcore/src/client/mod.rs | 2 +- ethcore/src/engines/instant_seal.rs | 22 +- ethcore/src/ethereum/mod.rs | 5 + ethcore/src/executive.rs | 3 +- ethcore/src/externalities.rs | 8 + ethcore/src/json_tests/executive.rs | 2 + ethcore/src/lib.rs | 4 + ethcore/src/machine/impls.rs | 2 +- ethcore/src/miner/miner.rs | 12 +- ethcore/src/miner/pool_client.rs | 11 +- ethcore/src/spec/spec.rs | 18 +- ethcore/src/trace/executive_tracer.rs | 39 +- ethcore/src/trace/mod.rs | 3 + ethcore/types/Cargo.toml | 5 +- ethcore/types/src/transaction/error.rs | 16 +- ethcore/types/src/transaction/transaction.rs | 20 +- ethcore/vm/Cargo.toml | 3 - ethcore/vm/src/env_info.rs | 2 +- ethcore/vm/src/ext.rs | 7 + ethcore/vm/src/lib.rs | 1 - ethcore/vm/src/schedule.rs | 14 +- ethcore/vm/src/tests.rs | 21 +- ipfs/src/lib.rs | 26 +- json/src/spec/builtin.rs | 36 + json/src/spec/params.rs | 4 + miner/Cargo.toml | 2 +- miner/src/pool/queue.rs | 2 +- miner/src/pool/replace.rs | 98 +++ miner/src/pool/tests/mod.rs | 16 +- miner/src/pool/verifier.rs | 6 +- parity/cli/mod.rs | 2 +- parity/cli/usage_header.txt | 7 +- parity/cli/version.txt | 7 +- parity/params.rs | 6 + rpc/Cargo.toml | 2 +- rpc/src/v1/helpers/errors.rs | 7 +- scripts/gitlab/publish-onchain.sh | 4 +- util/EIP-152/Cargo.toml | 14 + util/EIP-152/src/lib.rs | 192 ++++++ util/blooms-db/benches/blooms.rs | 16 +- util/blooms-db/src/db.rs | 2 +- util/network-devp2p/src/host.rs | 16 +- util/version/Cargo.toml | 2 +- 92 files changed, 2483 insertions(+), 539 deletions(-) create mode 100644 ethcore/res/ethereum/xdai.json create mode 100644 util/EIP-152/Cargo.toml create mode 100644 util/EIP-152/src/lib.rs diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 12ed84a5bd..e5bcd95960 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -13,10 +13,6 @@ variables: SCCACHE_DIR: "/ci-cache/${CI_PROJECT_NAME}/sccache" CARGO_TARGET: x86_64-unknown-linux-gnu -.no_git: &no_git # disable git strategy - variables: - GIT_STRATEGY: none - GIT_SUBMODULE_STRATEGY: none .releaseable_branches: # list of git refs for building GitLab artifacts (think "pre-release binaries") only: &releaseable_branches @@ -205,11 +201,10 @@ build-windows: publish-docker: stage: publish - <<: *no_git only: *releaseable_branches except: - variables: - - $SCHEDULE_TAG == "nightly" + - nightly + when: manual dependencies: - build-linux environment: @@ -219,23 +214,24 @@ publish-docker: services: - docker:dind variables: + GIT_STRATEGY: none DOCKER_HOST: tcp://localhost:2375 DOCKER_DRIVER: overlay2 GIT_STRATEGY: none # DOCKERFILE: tools/Dockerfile # CONTAINER_IMAGE: parity/parity script: - # we stopped pushing nightlies to dockerhub, will push to own registry prb. - ./tools/publish-docker.sh tags: - kubernetes-parity-build -publish-snap: &publish-snap +publish-snap-nightly: &publish-snap stage: publish - <<: *no_git - only: *releaseable_branches + only: + - nightly image: snapcore/snapcraft variables: + GIT_STRATEGY: none BUILD_ARCH: amd64 cache: {} dependencies: @@ -245,7 +241,12 @@ publish-snap: &publish-snap script: - ./tools/publish-snap.sh -publish-snap-i386: +publish-snap-manually: + <<: *publish-snap + only: *releaseable_branches + when: manual + +publish-snap-i386-nightly: &publish-snap-i386 <<: *publish-snap variables: BUILD_ARCH: i386 @@ -253,7 +254,12 @@ publish-snap-i386: dependencies: - build-linux-i386 -publish-snap-arm64: +publish-snap-i386-manually: + <<: *publish-snap-i386 + only: *releaseable_branches + when: manual + +publish-snap-arm64-nightly: &publish-snap-arm64 <<: *publish-snap variables: BUILD_ARCH: arm64 @@ -261,7 +267,12 @@ publish-snap-arm64: dependencies: - build-linux-arm64 -publish-snap-armhf: +publish-snap-arm64-manually: + <<: *publish-snap-arm64 + only: *releaseable_branches + when: manual + +publish-snap-armhf-nightly: &publish-snap-armhf <<: *publish-snap variables: BUILD_ARCH: armhf @@ -269,11 +280,18 @@ publish-snap-armhf: dependencies: - build-linux-armhf -publish-onchain: - stage: publish - <<: *no_git +publish-snap-armhf-manually: + <<: *publish-snap-armhf only: *releaseable_branches + when: manual + +publish-onchain-nightly: &publish-onchain + stage: publish + only: + - nightly cache: {} + variables: + GIT_STRATEGY: none dependencies: - build-linux - build-darwin @@ -283,11 +301,18 @@ publish-onchain: tags: - linux-docker -publish-awss3-release: +publish-onchain-manually: + <<: *publish-onchain + only: *releaseable_branches + when: manual + +publish-release-awss3-nightly: &publish-release-awss3 image: parity/awscli:latest stage: publish - only: *releaseable_branches - <<: *no_git + only: + - nightly + variables: + GIT_STRATEGY: none cache: {} dependencies: - build-linux @@ -309,6 +334,11 @@ publish-awss3-release: tags: - linux-docker +publish-release-awss3-manually: + <<: *publish-release-awss3 + only: *releaseable_branches + when: manual + publish-docs: stage: publish image: parity/parity-ci-docs:latest @@ -316,6 +346,7 @@ publish-docs: - tags except: - nightly + when: manual cache: {} dependencies: [] script: @@ -326,11 +357,12 @@ publish-docs: publish-av-whitelist: stage: publish - <<: *no_git + variables: + GIT_STRATEGY: none only: *releaseable_branches except: - variables: - - $SCHEDULE_TAG == "nightly" + - nightly + when: manual cache: {} dependencies: - build-windows diff --git a/Cargo.lock b/Cargo.lock index 16dac7aede..22bbd6657d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -497,6 +497,13 @@ name = "edit-distance" version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "eip-152" +version = "0.1.0" +dependencies = [ + "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "eip-712" version = "0.1.0" @@ -643,6 +650,7 @@ dependencies = [ "common-types 0.1.0", "criterion 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", + "eip-152 0.1.0", "env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)", "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethabi 6.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -664,6 +672,7 @@ dependencies = [ "fetch 0.1.0", "hash-db 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.4.2 (git+https://github.com/cheme/heapsize.git?branch=ec-macfix)", + "hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", "journaldb 0.2.0", "keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -729,7 +738,7 @@ dependencies = [ name = "ethcore-blockchain" version = "0.1.0" dependencies = [ - "ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", + "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "blooms-db 0.1.0", "common-types 0.1.0", "env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)", @@ -744,12 +753,14 @@ dependencies = [ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "rayon 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "rlp 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "rlp_compress 0.1.0", "rlp_derive 0.1.0", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "triehash-ethereum 0.2.0", ] [[package]] @@ -884,7 +895,7 @@ dependencies = [ "rlp 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "trace-time 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "transaction-pool 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "transaction-pool 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -979,7 +990,7 @@ dependencies = [ "serde_derive 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", "tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "transaction-pool 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "transaction-pool 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "trie-db 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1135,7 +1146,7 @@ dependencies = [ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "memzero 0.1.0", "parity-crypto 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-wordlist 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-wordlist 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1152,7 +1163,7 @@ dependencies = [ "env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)", "ethkey 0.3.0", "panic_hook 0.1.0", - "parity-wordlist 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-wordlist 1.3.0 (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.89 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1172,7 +1183,7 @@ dependencies = [ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-crypto 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-wordlist 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-wordlist 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1210,6 +1221,7 @@ dependencies = [ "criterion 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", "ethereum-types 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.4.2 (git+https://github.com/cheme/heapsize.git?branch=ec-macfix)", + "hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1511,6 +1523,23 @@ name = "hex" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "hex-literal" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "hex-literal-impl 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro-hack 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "hex-literal-impl" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro-hack 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "hidapi" version = "0.3.1" @@ -2392,7 +2421,7 @@ dependencies = [ "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", "jni 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "panic_hook 0.1.0", - "parity-ethereum 2.5.7", + "parity-ethereum 2.5.8", "tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-current-thread 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2422,7 +2451,7 @@ dependencies = [ [[package]] name = "parity-ethereum" -version = "2.5.7" +version = "2.5.8" dependencies = [ "ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2475,7 +2504,7 @@ dependencies = [ "parity-rpc 1.12.0", "parity-runtime 0.1.0", "parity-updater 1.12.0", - "parity-version 2.5.7", + "parity-version 2.5.8", "parity-whisper 0.1.0", "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2618,7 +2647,7 @@ dependencies = [ "parity-crypto 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-runtime 0.1.0", "parity-updater 1.12.0", - "parity-version 2.5.7", + "parity-version 2.5.8", "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2632,7 +2661,7 @@ dependencies = [ "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-timer 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "transaction-pool 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "transaction-pool 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "transient-hashmap 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "vm 0.1.0", ] @@ -2716,7 +2745,7 @@ dependencies = [ "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-hash-fetch 1.12.0", "parity-path 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-version 2.5.7", + "parity-version 2.5.8", "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2726,7 +2755,7 @@ dependencies = [ [[package]] name = "parity-version" -version = "2.5.7" +version = "2.5.8" dependencies = [ "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "rlp 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2775,12 +2804,11 @@ dependencies = [ [[package]] name = "parity-wordlist" -version = "1.2.1" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2996,6 +3024,16 @@ dependencies = [ "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "proc-macro-hack" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "proc-macro2" version = "0.4.20" @@ -3004,6 +3042,14 @@ dependencies = [ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "proc-macro2" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "protobuf" version = "1.7.5" @@ -3061,6 +3107,14 @@ dependencies = [ "proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "quote" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rand" version = "0.3.22" @@ -3601,6 +3655,16 @@ dependencies = [ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "syn" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "synom" version = "0.11.3" @@ -3996,7 +4060,7 @@ dependencies = [ [[package]] name = "transaction-pool" -version = "2.0.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4141,6 +4205,11 @@ name = "unicode-xid" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "unicode-xid" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "unreachable" version = "1.0.0" @@ -4224,15 +4293,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "vm" version = "0.1.0" dependencies = [ - "byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "ethereum-types 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "ethjson 0.1.0", "keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "patricia-trie-ethereum 0.1.0", "rlp 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "trie-db 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4503,6 +4569,8 @@ dependencies = [ "checksum heapsize 0.4.2 (git+https://github.com/cheme/heapsize.git?branch=ec-macfix)" = "" "checksum heck 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ea04fa3ead4e05e51a7c806fc07271fdbde4e246a6c6d1efd52e72230b771b82" "checksum hex 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d6a22814455d41612f41161581c2883c0c6a1c41852729b17d5ed88f01e153aa" +"checksum hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "961de220ec9a91af2e1e5bd80d02109155695e516771762381ef8581317066e0" +"checksum hex-literal-impl 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9d4c5c844e2fee0bf673d54c2c177f1713b3d2af2ff6e666b49cb7572e6cf42d" "checksum hidapi 0.3.1 (git+https://github.com/paritytech/hidapi-rs)" = "" "checksum home 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "80dff82fb58cfbbc617fb9a9184b010be0529201553cda50ad04372bc2333aff" "checksum http 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "1a10e5b573b9a0146545010f50772b9e8b1dd0a256564cc4307694c68832a2f5" @@ -4597,7 +4665,7 @@ dependencies = [ "checksum parity-snappy-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1a413d51e5e1927320c9de992998e4a279dffb8c8a7363570198bd8383e66f1b" "checksum parity-tokio-ipc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "eb002c2d3539ccd3b82bd915ec060028d4ab350ad203dbffa20028c1e483af5b" "checksum parity-wasm 0.31.3 (registry+https://github.com/rust-lang/crates.io-index)" = "511379a8194230c2395d2f5fa627a5a7e108a9f976656ce723ae68fca4097bfc" -"checksum parity-wordlist 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf13102febd98f4ad416a526b42deb82daf482626ba6ab10d0ebf8f45327514c" +"checksum parity-wordlist 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "573d08f0d3bc8a6ffcdac1de2725b5daeed8db26345a9c12d91648e2d6457f3e" "checksum parity-ws 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2fec5048fba72a2e01baeb0d08089db79aead4b57e2443df172fb1840075a233" "checksum parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f0802bff09003b291ba756dc7e79313e51cc31667e94afbe847def490424cde5" "checksum parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ab41b4aed082705d1056416ae4468b6ea99d52599ecf3169b00088d43113e337" @@ -4618,13 +4686,16 @@ dependencies = [ "checksum primal-check 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8e65f96c0a171f887198c274392c99a116ef65aa7f53f3b6d4902f493965c2d1" "checksum primal-estimate 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "56ea4531dde757b56906493c8604641da14607bf9cdaa80fb9c9cabd2429f8d5" "checksum primal-sieve 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "da2d6ed369bb4b0273aeeb43f07c105c0117717cbae827b20719438eb2eb798c" +"checksum proc-macro-hack 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e688f31d92ffd7c1ddc57a1b4e6d773c0f2a14ee437a4b0a4f5a69c80eb221c8" "checksum proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)" = "3d7b7eaaa90b4a90a932a9ea6666c95a389e424eff347f0f793979289429feee" +"checksum proc-macro2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e98a83a9f9b331f54b924e68a66acb1bb35cb01fb0a23645139967abefb697e8" "checksum protobuf 1.7.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e14ccd6b79ec748412d4f2dfde1a80fa363a67def4062969f8aed3d790a30f28" "checksum pulldown-cmark 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8361e81576d2e02643b04950e487ec172b687180da65c731c03cf336784e6c07" "checksum pwasm-utils 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e9135bed7b452e20dbb395a2d519abaf0c46d60e7ecc02daeeab447d29bada1" "checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0" "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" "checksum quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "dd636425967c33af890042c483632d33fa7a18f19ad1d7ea72e8998c6ef8dea5" +"checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe" "checksum rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "15a732abf9d20f0ad8eeb6f909bf6868722d9a06e1e50802b6a70351f40b4eb1" "checksum rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8356f47b32624fef5b3301c1be97e5944ecdd595409cc5da11d05f211db6cfbd" "checksum rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e464cd887e869cddcae8792a4ee31d23c7edd516700695608f5b98c67ee0131c" @@ -4688,6 +4759,7 @@ dependencies = [ "checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550" "checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" "checksum syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)" = "f92e629aa1d9c827b2bb8297046c1ccffc57c99b947a680d3ccff1f136a3bee9" +"checksum syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "66850e97125af79138385e9b88339cbcd037e3f28ceab8c5ad98e64f0f1f80bf" "checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" "checksum synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "73687139bf99285483c96ac0add482c3776528beac1d97d444f6e91f203a2015" "checksum target_info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c63f48baada5c52e65a29eef93ab4f8982681b67f9e8d29c7b05abcfec2b9ffe" @@ -4726,7 +4798,7 @@ dependencies = [ "checksum toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "758664fc71a3a69038656bee8b6be6477d2a6c315a6b81f7081f591bffa4111f" "checksum toolshed 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "450441e131c7663af72e63a33c02a6a1fbaaa8601dc652ed6757813bb55aeec7" "checksum trace-time 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe82f2f0bf1991e163e757baf044282823155dd326e70f44ce2186c3c320cc9" -"checksum transaction-pool 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f8d8bd3123931aa6e49dd03bc8a2400490e14701d779458d1f1fff1f04c6f666" +"checksum transaction-pool 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "454adc482e32785c3beab9415dd0f3c689f29cc2d16717eb62f6a784d53544b4" "checksum transient-hashmap 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "aeb4b191d033a35edfce392a38cdcf9790b6cebcb30fa690c312c29da4dc433e" "checksum trezor-sys 1.0.0 (git+https://github.com/paritytech/trezor-sys)" = "" "checksum trie-db 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3c7319e28ca295f27359d944a682f7f65b419158bf1590c92cadc0000258d788" @@ -4745,6 +4817,7 @@ dependencies = [ "checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526" "checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" +"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" "checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" "checksum untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "55cd1f4b4e96b46aeb8d4855db4a7a9bd96eeeb5c6a1ab54593328761642ce2f" "checksum url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2a321979c09843d272956e73700d12c4e7d3d92b2ee112b31548aef0d4efc5a6" diff --git a/Cargo.toml b/Cargo.toml index 28e26fadf6..caf8bd68cd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ description = "Parity Ethereum client" name = "parity-ethereum" # NOTE Make sure to update util/version/Cargo.toml as well -version = "2.5.7" +version = "2.5.8" license = "GPL-3.0" authors = ["Parity Technologies "] diff --git a/accounts/ethkey/Cargo.toml b/accounts/ethkey/Cargo.toml index 8dd391540c..c10949622c 100644 --- a/accounts/ethkey/Cargo.toml +++ b/accounts/ethkey/Cargo.toml @@ -12,7 +12,7 @@ ethereum-types = "0.4" lazy_static = "1.0" log = "0.4" memzero = { path = "../../util/memzero" } -parity-wordlist = "1.2" +parity-wordlist = "1.3" quick-error = "1.2.2" rand = "0.4" rustc-hex = "1.0" diff --git a/accounts/ethkey/cli/Cargo.toml b/accounts/ethkey/cli/Cargo.toml index cb57f05053..c1d44897cc 100644 --- a/accounts/ethkey/cli/Cargo.toml +++ b/accounts/ethkey/cli/Cargo.toml @@ -9,7 +9,7 @@ docopt = "1.0" env_logger = "0.5" ethkey = { path = "../" } panic_hook = { path = "../../../util/panic-hook" } -parity-wordlist="1.2" +parity-wordlist="1.3" rustc-hex = "1.0" serde = "1.0" serde_derive = "1.0" diff --git a/accounts/ethstore/Cargo.toml b/accounts/ethstore/Cargo.toml index c16c4672d4..af497bcff3 100644 --- a/accounts/ethstore/Cargo.toml +++ b/accounts/ethstore/Cargo.toml @@ -21,7 +21,7 @@ parity-crypto = "0.3.0" ethereum-types = "0.4" dir = { path = "../../util/dir" } smallvec = "0.6" -parity-wordlist = "1.0" +parity-wordlist = "1.3" tempdir = "0.3" lazy_static = "1.2.0" diff --git a/ethcore/Cargo.toml b/ethcore/Cargo.toml index 89a265a3ce..16013d5479 100644 --- a/ethcore/Cargo.toml +++ b/ethcore/Cargo.toml @@ -13,6 +13,7 @@ bn = { git = "https://github.com/paritytech/bn", default-features = false } byteorder = "1.0" common-types = { path = "types" } crossbeam-utils = "0.6" +eip-152 = { version = "0.1", path = "../util/EIP-152" } env_logger = { version = "0.5", optional = true } error-chain = { version = "0.12", default-features = false } ethabi = "6.0" @@ -77,6 +78,7 @@ criterion = "0.2" env_logger = "0.5" ethcore-accounts = { path = "../accounts" } fetch = { path = "../util/fetch" } +hex-literal = "0.2.1" kvdb-rocksdb = "0.1.3" parity-runtime = { path = "../util/runtime" } rlp_compress = { path = "../util/rlp-compress" } diff --git a/ethcore/blockchain/Cargo.toml b/ethcore/blockchain/Cargo.toml index 013aeddd53..be434c51e1 100644 --- a/ethcore/blockchain/Cargo.toml +++ b/ethcore/blockchain/Cargo.toml @@ -8,26 +8,28 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -ansi_term = "0.10" +ansi_term = "0.11" blooms-db = { path = "../../util/blooms-db" } common-types = { path = "../types" } ethcore-db = { path = "../db" } ethereum-types = "0.4" heapsize = "0.4" itertools = "0.5" +keccak-hash = "0.1" kvdb = "0.1" log = "0.4" parity-bytes = "0.1" parking_lot = "0.7" +rand = "0.6" rayon = "1.1" rlp = { version = "0.3.0", features = ["ethereum"] } rlp_compress = { path = "../../util/rlp-compress" } rlp_derive = { path = "../../util/rlp-derive" } +triehash-ethereum = { version = "0.2", path = "../../util/triehash-ethereum" } [dev-dependencies] env_logger = "0.5" ethkey = { path = "../../accounts/ethkey" } -keccak-hash = "0.1" rustc-hex = "1.0" tempdir = "0.3" kvdb-memorydb = "0.1" diff --git a/ethcore/blockchain/src/blockchain.rs b/ethcore/blockchain/src/blockchain.rs index 7ee735f789..c5759d3462 100644 --- a/ethcore/blockchain/src/blockchain.rs +++ b/ethcore/blockchain/src/blockchain.rs @@ -713,6 +713,10 @@ impl BlockChain { /// /// If the tree route verges into pruned or unknown blocks, /// `None` is returned. + /// + /// `is_from_route_finalized` returns whether the `from` part of the + /// route contains a finalized block. This only holds if the two parts (from + /// and to) are on different branches, ie. on 2 different forks. pub fn tree_route(&self, from: H256, to: H256) -> Option { let mut from_branch = vec![]; let mut is_from_route_finalized = false; @@ -726,9 +730,9 @@ impl BlockChain { // reset from && to to the same level while from_details.number > to_details.number { from_branch.push(current_from); + is_from_route_finalized = is_from_route_finalized || from_details.is_finalized; current_from = from_details.parent.clone(); from_details = self.block_details(&from_details.parent)?; - is_from_route_finalized = is_from_route_finalized || from_details.is_finalized; } while to_details.number > from_details.number { @@ -742,9 +746,9 @@ impl BlockChain { // move to shared parent while current_from != current_to { from_branch.push(current_from); + is_from_route_finalized = is_from_route_finalized || from_details.is_finalized; current_from = from_details.parent.clone(); from_details = self.block_details(&from_details.parent)?; - is_from_route_finalized = is_from_route_finalized || from_details.is_finalized; to_branch.push(current_to); current_to = to_details.parent.clone(); @@ -2491,4 +2495,74 @@ mod tests { assert_eq!(bc.epoch_transition_for(fork_hash).unwrap().block_number, 0); } } + + #[test] + fn tree_rout_with_finalization() { + let genesis = BlockBuilder::genesis(); + let a = genesis.add_block(); + // First branch + let a1 = a.add_block_with_random_transactions(); + let a2 = a1.add_block_with_random_transactions(); + let a3 = a2.add_block_with_random_transactions(); + // Second branch + let b1 = a.add_block_with_random_transactions(); + let b2 = b1.add_block_with_random_transactions(); + + let a_hash = a.last().hash(); + let a1_hash = a1.last().hash(); + let a2_hash = a2.last().hash(); + let a3_hash = a3.last().hash(); + let b2_hash = b2.last().hash(); + + let bootstrap_chain = |blocks: Vec<&BlockBuilder>| { + let db = new_db(); + let bc = new_chain(genesis.last().encoded(), db.clone()); + let mut batch = db.key_value().transaction(); + for block in blocks { + insert_block_batch(&mut batch, &bc, block.last().encoded(), vec![]); + bc.commit(); + } + db.key_value().write(batch).unwrap(); + (db, bc) + }; + + let mark_finalized = |block_hash: H256, db: &Arc, bc: &BlockChain| { + let mut batch = db.key_value().transaction(); + bc.mark_finalized(&mut batch, block_hash).unwrap(); + bc.commit(); + db.key_value().write(batch).unwrap(); + }; + + // Case 1: fork, with finalized common ancestor + { + let (db, bc) = bootstrap_chain(vec![&a, &a1, &a2, &a3, &b1, &b2]); + assert_eq!(bc.best_block_hash(), a3_hash); + assert_eq!(bc.block_hash(2).unwrap(), a1_hash); + + mark_finalized(a_hash, &db, &bc); + assert!(!bc.tree_route(a3_hash, b2_hash).unwrap().is_from_route_finalized); + assert!(!bc.tree_route(b2_hash, a3_hash).unwrap().is_from_route_finalized); + } + + // Case 2: fork with a finalized block on a branch + { + let (db, bc) = bootstrap_chain(vec![&a, &a1, &a2, &a3, &b1, &b2]); + assert_eq!(bc.best_block_hash(), a3_hash); + assert_eq!(bc.block_hash(2).unwrap(), a1_hash); + + mark_finalized(a2_hash, &db, &bc); + assert!(bc.tree_route(a3_hash, b2_hash).unwrap().is_from_route_finalized); + assert!(!bc.tree_route(b2_hash, a3_hash).unwrap().is_from_route_finalized); + } + + // Case 3: no-fork, with a finalized block + { + let (db, bc) = bootstrap_chain(vec![&a, &a1, &a2]); + assert_eq!(bc.best_block_hash(), a2_hash); + + mark_finalized(a1_hash, &db, &bc); + assert!(!bc.tree_route(a1_hash, a2_hash).unwrap().is_from_route_finalized); + assert!(!bc.tree_route(a2_hash, a1_hash).unwrap().is_from_route_finalized); + } + } } diff --git a/ethcore/blockchain/src/generator.rs b/ethcore/blockchain/src/generator.rs index 32ec2802df..e5161d4098 100644 --- a/ethcore/blockchain/src/generator.rs +++ b/ethcore/blockchain/src/generator.rs @@ -21,11 +21,13 @@ use ethereum_types::{U256, H256, Bloom}; use common_types::encoded; use common_types::header::Header; -use common_types::transaction::SignedTransaction; +use common_types::transaction::{SignedTransaction, Transaction, Action}; use common_types::view; use common_types::views::BlockView; +use keccak_hash::keccak; use rlp::encode; use rlp_derive::RlpEncodable; +use triehash_ethereum::ordered_trie_root; /// Helper structure, used for encoding blocks. #[derive(Default, Clone, RlpEncodable)] @@ -136,6 +138,29 @@ impl BlockBuilder { }) } + /// Add a block with randomly generated transactions. + #[inline] + pub fn add_block_with_random_transactions(&self) -> Self { + // Maximum of ~50 transactions + let count = rand::random::() as usize / 5; + let transactions = std::iter::repeat_with(|| { + let data_len = rand::random::(); + let data = std::iter::repeat_with(|| rand::random::()) + .take(data_len as usize) + .collect::>(); + Transaction { + nonce: 0.into(), + gas_price: 0.into(), + gas: 100_000.into(), + action: Action::Create, + value: 100.into(), + data, + }.sign(&keccak("").into(), None) + }).take(count); + + self.add_block_with_transactions(transactions) + } + /// Add a block with given transactions. #[inline] pub fn add_block_with_transactions(&self, transactions: T) -> Self @@ -166,11 +191,15 @@ impl BlockBuilder { let mut block = Block::default(); let metadata = get_metadata(); let block_number = parent_number + 1; + let transactions = metadata.transactions; + let transactions_root = ordered_trie_root(transactions.iter().map(rlp::encode)); + block.header.set_parent_hash(parent_hash); block.header.set_number(block_number); block.header.set_log_bloom(metadata.bloom); block.header.set_difficulty(metadata.difficulty); - block.transactions = metadata.transactions; + block.header.set_transactions_root(transactions_root); + block.transactions = transactions; parent_hash = block.hash(); parent_number = block_number; diff --git a/ethcore/evm/Cargo.toml b/ethcore/evm/Cargo.toml index 67c3be6ff7..b5f4d0685f 100644 --- a/ethcore/evm/Cargo.toml +++ b/ethcore/evm/Cargo.toml @@ -20,6 +20,7 @@ num-bigint = "0.2" [dev-dependencies] rustc-hex = "1.0" criterion = "0.2" +hex-literal = "0.2.0" [features] evm-debug = [] diff --git a/ethcore/evm/src/factory.rs b/ethcore/evm/src/factory.rs index 484b2852fe..5dbaf4f829 100644 --- a/ethcore/evm/src/factory.rs +++ b/ethcore/evm/src/factory.rs @@ -47,7 +47,7 @@ impl Factory { /// for caching jump destinations. pub fn new(evm: VMType, cache_size: usize) -> Self { Factory { - evm: evm, + evm, evm_cache: Arc::new(SharedCache::new(cache_size)), } } diff --git a/ethcore/evm/src/instructions.rs b/ethcore/evm/src/instructions.rs index 0cdbb5687d..1580f7b591 100644 --- a/ethcore/evm/src/instructions.rs +++ b/ethcore/evm/src/instructions.rs @@ -149,6 +149,8 @@ enum_with_from_u8! { DIFFICULTY = 0x44, #[doc = "get the block's gas limit"] GASLIMIT = 0x45, + #[doc = "get chain ID"] + CHAINID = 0x46, #[doc = "remove item from stack"] POP = 0x50, @@ -442,12 +444,7 @@ pub struct InstructionInfo { impl InstructionInfo { /// Create new instruction info. pub fn new(name: &'static str, args: usize, ret: usize, tier: GasPriceTier) -> Self { - InstructionInfo { - name: name, - args: args, - ret: ret, - tier: tier - } + InstructionInfo { name, args, ret, tier } } } @@ -504,6 +501,7 @@ lazy_static! { arr[NUMBER as usize] = Some(InstructionInfo::new("NUMBER", 0, 1, GasPriceTier::Base)); arr[DIFFICULTY as usize] = Some(InstructionInfo::new("DIFFICULTY", 0, 1, GasPriceTier::Base)); arr[GASLIMIT as usize] = Some(InstructionInfo::new("GASLIMIT", 0, 1, GasPriceTier::Base)); + arr[CHAINID as usize] = Some(InstructionInfo::new("CHAINID", 0, 1, GasPriceTier::Base)); arr[POP as usize] = Some(InstructionInfo::new("POP", 1, 0, GasPriceTier::Base)); arr[MLOAD as usize] = Some(InstructionInfo::new("MLOAD", 1, 1, GasPriceTier::VeryLow)); arr[MSTORE as usize] = Some(InstructionInfo::new("MSTORE", 2, 0, GasPriceTier::VeryLow)); diff --git a/ethcore/evm/src/interpreter/mod.rs b/ethcore/evm/src/interpreter/mod.rs index 84231abb57..0513f5c9aa 100644 --- a/ethcore/evm/src/interpreter/mod.rs +++ b/ethcore/evm/src/interpreter/mod.rs @@ -119,8 +119,6 @@ enum InstructionResult { Trap(TrapKind), } -enum Never {} - /// ActionParams without code, so that it can be feed into CodeReader. #[derive(Debug)] struct InterpreterParams { @@ -178,12 +176,6 @@ pub enum InterpreterResult { Trap(TrapKind), } -impl From for InterpreterResult { - fn from(error: vm::Error) -> InterpreterResult { - InterpreterResult::Done(Err(error)) - } -} - /// Intepreter EVM implementation pub struct Interpreter { mem: Vec, @@ -294,6 +286,8 @@ impl Interpreter { cache, params, reader, informant, valid_jump_destinations, gasometer, stack, done: false, + // Overridden in `step_inner` based on + // the result of `ext.trace_next_instruction`. do_trace: true, mem: Vec::new(), return_data: ReturnData::empty(), @@ -316,7 +310,7 @@ impl Interpreter { } else if self.reader.len() == 0 { InterpreterResult::Done(Ok(GasLeft::Known(self.gasometer.as_ref().expect("Gasometer None case is checked above; qed").current_gas.as_u256()))) } else { - self.step_inner(ext).err().expect("step_inner never returns Ok(()); qed") + self.step_inner(ext) }; if let &InterpreterResult::Done(_) = &result { @@ -328,7 +322,7 @@ impl Interpreter { /// Inner helper function for step. #[inline(always)] - fn step_inner(&mut self, ext: &mut vm::Ext) -> Result { + fn step_inner(&mut self, ext: &mut dyn vm::Ext) -> InterpreterResult { let result = match self.resume_result.take() { Some(result) => result, None => { @@ -343,22 +337,31 @@ impl Interpreter { let instruction = match instruction { Some(i) => i, - None => return Err(InterpreterResult::Done(Err(vm::Error::BadInstruction { + None => return InterpreterResult::Done(Err(vm::Error::BadInstruction { instruction: opcode - }))), + })), }; let info = instruction.info(); self.last_stack_ret_len = info.ret; - self.verify_instruction(ext, instruction, info)?; + if let Err(e) = self.verify_instruction(ext, instruction, info) { + return InterpreterResult::Done(Err(e)); + }; // Calculate gas cost - let requirements = self.gasometer.as_mut().expect(GASOMETER_PROOF).requirements(ext, instruction, info, &self.stack, self.mem.size())?; + let requirements = match self.gasometer.as_mut().expect(GASOMETER_PROOF).requirements(ext, instruction, info, &self.stack, self.mem.size()) { + Ok(t) => t, + Err(e) => return InterpreterResult::Done(Err(e)), + }; if self.do_trace { ext.trace_prepare_execute(self.reader.position - 1, opcode, requirements.gas_cost.as_u256(), Self::mem_written(instruction, &self.stack), Self::store_written(instruction, &self.stack)); } - - self.gasometer.as_mut().expect(GASOMETER_PROOF).verify_gas(&requirements.gas_cost)?; + if let Err(e) = self.gasometer.as_mut().expect(GASOMETER_PROOF).verify_gas(&requirements.gas_cost) { + if self.do_trace { + ext.trace_failed(); + } + return InterpreterResult::Done(Err(e)); + } self.mem.expand(requirements.memory_required_size); self.gasometer.as_mut().expect(GASOMETER_PROOF).current_mem_gas = requirements.memory_total_gas; self.gasometer.as_mut().expect(GASOMETER_PROOF).current_gas = self.gasometer.as_mut().expect(GASOMETER_PROOF).current_gas - requirements.gas_cost; @@ -367,18 +370,24 @@ impl Interpreter { // Execute instruction let current_gas = self.gasometer.as_mut().expect(GASOMETER_PROOF).current_gas; - let result = self.exec_instruction( + let result = match self.exec_instruction( current_gas, ext, instruction, requirements.provide_gas - )?; - + ) { + Err(x) => { + if self.do_trace { + ext.trace_failed(); + } + return InterpreterResult::Done(Err(x)); + }, + Ok(x) => x, + }; evm_debug!({ self.informant.after_instruction(instruction) }); - result }, }; if let InstructionResult::Trap(trap) = result { - return Err(InterpreterResult::Trap(trap)); + return InterpreterResult::Trap(trap); } if let InstructionResult::UnusedGas(ref gas) = result { @@ -400,28 +409,31 @@ impl Interpreter { self.valid_jump_destinations = Some(self.cache.jump_destinations(&self.params.code_hash, &self.reader.code)); } let jump_destinations = self.valid_jump_destinations.as_ref().expect("jump_destinations are initialized on first jump; qed"); - let pos = self.verify_jump(position, jump_destinations)?; + let pos = match self.verify_jump(position, jump_destinations) { + Ok(x) => x, + Err(e) => return InterpreterResult::Done(Err(e)) + }; self.reader.position = pos; }, InstructionResult::StopExecutionNeedsReturn {gas, init_off, init_size, apply} => { let mem = mem::replace(&mut self.mem, Vec::new()); - return Err(InterpreterResult::Done(Ok(GasLeft::NeedsReturn { + return InterpreterResult::Done(Ok(GasLeft::NeedsReturn { gas_left: gas.as_u256(), data: mem.into_return_data(init_off, init_size), apply_state: apply - }))); + })); }, InstructionResult::StopExecution => { - return Err(InterpreterResult::Done(Ok(GasLeft::Known(self.gasometer.as_mut().expect(GASOMETER_PROOF).current_gas.as_u256())))); + return InterpreterResult::Done(Ok(GasLeft::Known(self.gasometer.as_mut().expect(GASOMETER_PROOF).current_gas.as_u256()))); }, _ => {}, } if self.reader.position >= self.reader.len() { - return Err(InterpreterResult::Done(Ok(GasLeft::Known(self.gasometer.as_mut().expect(GASOMETER_PROOF).current_gas.as_u256())))); + return InterpreterResult::Done(Ok(GasLeft::Known(self.gasometer.as_mut().expect(GASOMETER_PROOF).current_gas.as_u256()))); } - Err(InterpreterResult::Continue) + InterpreterResult::Continue } fn verify_instruction(&self, ext: &vm::Ext, instruction: Instruction, info: &InstructionInfo) -> vm::Result<()> { @@ -433,7 +445,8 @@ impl Interpreter { ((instruction == instructions::RETURNDATACOPY || instruction == instructions::RETURNDATASIZE) && !schedule.have_return_data) || (instruction == instructions::REVERT && !schedule.have_revert) || ((instruction == instructions::SHL || instruction == instructions::SHR || instruction == instructions::SAR) && !schedule.have_bitwise_shifting) || - (instruction == instructions::EXTCODEHASH && !schedule.have_extcodehash) + (instruction == instructions::EXTCODEHASH && !schedule.have_extcodehash) || + (instruction == instructions::CHAINID && !schedule.have_chain_id) { return Err(vm::Error::BadInstruction { instruction: instruction as u8 @@ -848,6 +861,9 @@ impl Interpreter { instructions::GASLIMIT => { self.stack.push(ext.env_info().gas_limit.clone()); }, + instructions::CHAINID => { + self.stack.push(ext.chain_id().into()) + }, // Stack instructions diff --git a/ethcore/evm/src/lib.rs b/ethcore/evm/src/lib.rs index 03871864d5..6e9409375b 100644 --- a/ethcore/evm/src/lib.rs +++ b/ethcore/evm/src/lib.rs @@ -34,6 +34,8 @@ extern crate log; #[cfg(test)] extern crate rustc_hex; +#[cfg(test)] +extern crate hex_literal; pub mod evm; pub mod interpreter; diff --git a/ethcore/evm/src/tests.rs b/ethcore/evm/src/tests.rs index dd039311eb..40b6a7561c 100644 --- a/ethcore/evm/src/tests.rs +++ b/ethcore/evm/src/tests.rs @@ -25,6 +25,7 @@ use vm::{self, ActionParams, ActionValue, Ext}; use vm::tests::{FakeExt, FakeCall, FakeCallType, test_finalize}; use factory::Factory; use vmtype::VMType; +use hex_literal::hex; evm_test!{test_add: test_add_int} fn test_add(factory: super::Factory) { @@ -130,6 +131,27 @@ fn test_sender(factory: super::Factory) { assert_store(&ext, 0, "000000000000000000000000cd1722f2947def4cf144679da39c4c32bdc35681"); } +evm_test!{test_chain_id: test_chain_id_int} +fn test_chain_id(factory: super::Factory) { + // 46 CHAINID + // 60 00 PUSH 0 + // 55 SSTORE + let code = hex!("46 60 00 55").to_vec(); + + let mut params = ActionParams::default(); + params.gas = U256::from(100_000); + params.code = Some(Arc::new(code)); + let mut ext = FakeExt::new_istanbul().with_chain_id(9); + + let gas_left = { + let vm = factory.create(params, ext.schedule(), ext.depth()); + test_finalize(vm.exec(&mut ext).ok().unwrap()).unwrap() + }; + + assert_eq!(gas_left, U256::from(79_995)); + assert_store(&ext, 0, "0000000000000000000000000000000000000000000000000000000000000009"); +} + evm_test!{test_extcodecopy: test_extcodecopy_int} fn test_extcodecopy(factory: super::Factory) { // 33 - sender @@ -262,7 +284,6 @@ fn test_calldataload(factory: super::Factory) { assert_eq!(gas_left, U256::from(79_991)); assert_store(&ext, 0, "23ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff23"); - } evm_test!{test_author: test_author_int} diff --git a/ethcore/private-tx/Cargo.toml b/ethcore/private-tx/Cargo.toml index 2ce127a8b7..ae8f83d872 100644 --- a/ethcore/private-tx/Cargo.toml +++ b/ethcore/private-tx/Cargo.toml @@ -36,7 +36,7 @@ serde = "1.0" serde_derive = "1.0" serde_json = "1.0" tiny-keccak = "1.4" -transaction-pool = "2.0" +transaction-pool = "2.0.1" url = "1" [dev-dependencies] diff --git a/ethcore/res/authority_round.json b/ethcore/res/authority_round.json index 8d54244379..33afa45871 100644 --- a/ethcore/res/authority_round.json +++ b/ethcore/res/authority_round.json @@ -46,9 +46,50 @@ "0000000000000000000000000000000000000003": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } }, "0000000000000000000000000000000000000004": { "balance": "1", "nonce": "1048576", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } }, "0000000000000000000000000000000000000005": { "balance": "1", "builtin": { "name": "modexp", "activate_at": 0, "pricing": { "modexp": { "divisor": 20 } } } }, - "0000000000000000000000000000000000000006": { "balance": "1", "builtin": { "name": "alt_bn128_add", "activate_at": 0, "pricing": { "linear": { "base": 500, "word": 0 } } } }, - "0000000000000000000000000000000000000007": { "balance": "1", "builtin": { "name": "alt_bn128_mul", "activate_at": 0, "pricing": { "linear": { "base": 40000, "word": 0 } } } }, - "0000000000000000000000000000000000000008": { "balance": "1", "builtin": { "name": "alt_bn128_pairing", "activate_at": 0, "pricing": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 } } } }, + "0000000000000000000000000000000000000006": { + "balance": "1", + "builtin": { + "name": "alt_bn128_add", + "activate_at": 0, + "eip1108_transition": "0x7fffffffffffff", + "pricing": { + "alt_bn128_const_operations": { + "price": 500, + "eip1108_transition_price": 150 + } + } + } + }, + "0000000000000000000000000000000000000007": { + "balance": "1", + "builtin": { + "name": "alt_bn128_mul", + "activate_at": 0, + "eip1108_transition": "0x7fffffffffffff", + "pricing": { + "alt_bn128_const_operations": { + "price": 40000, + "eip1108_transition_price": 6000 + } + } + } + }, + "0000000000000000000000000000000000000008": { + "balance": "1", + "builtin": { + "name": "alt_bn128_pairing", + "activate_at": 0, + "eip1108_transition": "0x7fffffffffffff", + "pricing": { + "alt_bn128_pairing": { + "base": 100000, + "pair": 80000, + "eip1108_transition_base": 45000, + "eip1108_transition_pair": 34000 + } + } + } + }, "9cce34f7ab185c7aba1b7c8140d620b4bda941d6": { "balance": "1606938044258990275541962092341162602522202993782792835301376", "nonce": "1048576" } } } diff --git a/ethcore/res/authority_round_block_reward_contract.json b/ethcore/res/authority_round_block_reward_contract.json index 3195773123..73893d44d1 100644 --- a/ethcore/res/authority_round_block_reward_contract.json +++ b/ethcore/res/authority_round_block_reward_contract.json @@ -49,9 +49,50 @@ "0000000000000000000000000000000000000003": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } }, "0000000000000000000000000000000000000004": { "balance": "1", "nonce": "1048576", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } }, "0000000000000000000000000000000000000005": { "balance": "1", "builtin": { "name": "modexp", "activate_at": 0, "pricing": { "modexp": { "divisor": 20 } } } }, - "0000000000000000000000000000000000000006": { "balance": "1", "builtin": { "name": "alt_bn128_add", "activate_at": 0, "pricing": { "linear": { "base": 500, "word": 0 } } } }, - "0000000000000000000000000000000000000007": { "balance": "1", "builtin": { "name": "alt_bn128_mul", "activate_at": 0, "pricing": { "linear": { "base": 40000, "word": 0 } } } }, - "0000000000000000000000000000000000000008": { "balance": "1", "builtin": { "name": "alt_bn128_pairing", "activate_at": 0, "pricing": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 } } } }, + "0000000000000000000000000000000000000006": { + "balance": "1", + "builtin": { + "name": "alt_bn128_add", + "activate_at": 0, + "eip1108_transition": "0x7fffffffffffff", + "pricing": { + "alt_bn128_const_operations": { + "price": 500, + "eip1108_transition_price": 150 + } + } + } + }, + "0000000000000000000000000000000000000007": { + "balance": "1", + "builtin": { + "name": "alt_bn128_mul", + "activate_at": 0, + "eip1108_transition": "0x7fffffffffffff", + "pricing": { + "alt_bn128_const_operations": { + "price": 40000, + "eip1108_transition_price": 6000 + } + } + } + }, + "0000000000000000000000000000000000000008": { + "balance": "1", + "builtin": { + "name": "alt_bn128_pairing", + "activate_at": 0, + "eip1108_transition": "0x7fffffffffffff", + "pricing": { + "alt_bn128_pairing": { + "base": 100000, + "pair": 80000, + "eip1108_transition_base": 45000, + "eip1108_transition_pair": 34000 + } + } + } + }, "9cce34f7ab185c7aba1b7c8140d620b4bda941d6": { "balance": "1606938044258990275541962092341162602522202993782792835301376", "nonce": "1048576" }, "0000000000000000000000000000000000000042": { "balance": "1", diff --git a/ethcore/res/basic_authority.json b/ethcore/res/basic_authority.json index 35711be011..2d92355e3a 100644 --- a/ethcore/res/basic_authority.json +++ b/ethcore/res/basic_authority.json @@ -38,9 +38,50 @@ "0000000000000000000000000000000000000003": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } }, "0000000000000000000000000000000000000004": { "balance": "1", "nonce": "1048576", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } }, "0000000000000000000000000000000000000005": { "balance": "1", "builtin": { "name": "modexp", "activate_at": 0, "pricing": { "modexp": { "divisor": 20 } } } }, - "0000000000000000000000000000000000000006": { "balance": "1", "builtin": { "name": "alt_bn128_add", "activate_at": 0, "pricing": { "linear": { "base": 500, "word": 0 } } } }, - "0000000000000000000000000000000000000007": { "balance": "1", "builtin": { "name": "alt_bn128_mul", "activate_at": 0, "pricing": { "linear": { "base": 40000, "word": 0 } } } }, - "0000000000000000000000000000000000000008": { "balance": "1", "builtin": { "name": "alt_bn128_pairing", "activate_at": 0, "pricing": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 } } } }, + "0000000000000000000000000000000000000006": { + "balance": "1", + "builtin": { + "name": "alt_bn128_add", + "activate_at": "0x0", + "eip1108_transition": "0x7fffffffffffff", + "pricing": { + "alt_bn128_const_operations": { + "price": 500, + "eip1108_transition_price": 150 + } + } + } + }, + "0000000000000000000000000000000000000007": { + "balance": "1", + "builtin": { + "name": "alt_bn128_mul", + "activate_at": "0x0", + "eip1108_transition": "0x7fffffffffffff", + "pricing": { + "alt_bn128_const_operations": { + "price": 40000, + "eip1108_transition_price": 6000 + } + } + } + }, + "0000000000000000000000000000000000000008": { + "balance": "1", + "builtin": { + "name": "alt_bn128_pairing", + "activate_at": "0x0", + "eip1108_transition": "0x7fffffffffffff", + "pricing": { + "alt_bn128_pairing": { + "base": 100000, + "pair": 80000, + "eip1108_transition_base": 45000, + "eip1108_transition_pair": 34000 + } + } + } + }, "9cce34f7ab185c7aba1b7c8140d620b4bda941d6": { "balance": "1606938044258990275541962092341162602522202993782792835301376", "nonce": "1048576" } } } diff --git a/ethcore/res/constructor.json b/ethcore/res/constructor.json index f4e22ea2d8..1383337351 100644 --- a/ethcore/res/constructor.json +++ b/ethcore/res/constructor.json @@ -34,9 +34,50 @@ "0000000000000000000000000000000000000003": { "balance": "1", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } }, "0000000000000000000000000000000000000004": { "balance": "1", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } }, "0000000000000000000000000000000000000005": { "balance": "1", "builtin": { "name": "modexp", "activate_at": 0, "pricing": { "modexp": { "divisor": 20 } } } }, - "0000000000000000000000000000000000000006": { "balance": "1", "builtin": { "name": "alt_bn128_add", "activate_at": 0, "pricing": { "linear": { "base": 500, "word": 0 } } } }, - "0000000000000000000000000000000000000007": { "balance": "1", "builtin": { "name": "alt_bn128_mul", "activate_at": 0, "pricing": { "linear": { "base": 40000, "word": 0 } } } }, - "0000000000000000000000000000000000000008": { "balance": "1", "builtin": { "name": "alt_bn128_pairing", "activate_at": 0, "pricing": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 } } } }, + "0000000000000000000000000000000000000006": { + "balance": "1", + "builtin": { + "name": "alt_bn128_add", + "activate_at": 0, + "eip1108_transition": "0x7fffffffffffff", + "pricing": { + "alt_bn128_const_operations": { + "price": 500, + "eip1108_transition_price": 150 + } + } + } + }, + "0000000000000000000000000000000000000007": { + "balance": "1", + "builtin": { + "name": "alt_bn128_mul", + "activate_at": 0, + "eip1108_transition": "0x7fffffffffffff", + "pricing": { + "alt_bn128_const_operations": { + "price": 40000, + "eip1108_transition_price": 6000 + } + } + } + }, + "0000000000000000000000000000000000000008": { + "balance": "1", + "builtin": { + "name": "alt_bn128_pairing", + "activate_at": 0, + "eip1108_transition": "0x7fffffffffffff", + "pricing": { + "alt_bn128_pairing": { + "base": 100000, + "pair": 80000, + "eip1108_transition_base": 45000, + "eip1108_transition_pair": 34000 + } + } + } + }, "0000000000000000000000000000000000001337": { "balance": "1", "constructor": "60606040526000805460ff19166001179055346000575b6075806100246000396000f300606060405263ffffffff60e060020a60003504166394b91deb81146022575b6000565b34600057602c6040565b604080519115158252519081900360200190f35b60005460ff16815600a165627a7a723058207882eb60ebce23178b3fa06d4cd8e5adc17711937ccddacb18a04abca2a2c9ee0029" } } } diff --git a/ethcore/res/ethereum/byzantium_test.json b/ethcore/res/ethereum/byzantium_test.json index 9fdde9d13e..b4df953739 100644 --- a/ethcore/res/ethereum/byzantium_test.json +++ b/ethcore/res/ethereum/byzantium_test.json @@ -54,8 +54,46 @@ "0000000000000000000000000000000000000003": { "balance": "1", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } }, "0000000000000000000000000000000000000004": { "balance": "1", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } }, "0000000000000000000000000000000000000005": { "builtin": { "name": "modexp", "activate_at": "0x00", "pricing": { "modexp": { "divisor": 20 } } } }, - "0000000000000000000000000000000000000006": { "builtin": { "name": "alt_bn128_add", "activate_at": "0x00", "pricing": { "linear": { "base": 500, "word": 0 } } } }, - "0000000000000000000000000000000000000007": { "builtin": { "name": "alt_bn128_mul", "activate_at": "0x00", "pricing": { "linear": { "base": 40000, "word": 0 } } } }, - "0000000000000000000000000000000000000008": { "builtin": { "name": "alt_bn128_pairing", "activate_at": "0x00", "pricing": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 } } } } + "0000000000000000000000000000000000000006": { + "builtin": { + "name": "alt_bn128_add", + "activate_at": "0x00", + "eip1108_transition": "0x7fffffffffffff", + "pricing": { + "alt_bn128_const_operations": { + "price": 500, + "eip1108_transition_price": 150 + } + } + } + }, + "0000000000000000000000000000000000000007": { + "builtin": { + "name": "alt_bn128_mul", + "activate_at": "0x00", + "eip1108_transition": "0x7fffffffffffff", + "pricing": { + "alt_bn128_const_operations": { + "price": 40000, + "eip1108_transition_price": 6000 + } + } + } + }, + "0000000000000000000000000000000000000008": { + "builtin": { + "name": "alt_bn128_pairing", + "activate_at": "0x00", + "eip1108_transition": "0x7fffffffffffff", + "pricing": { + "alt_bn128_pairing": { + "base": 100000, + "pair": 80000, + "eip1108_transition_base": 45000, + "eip1108_transition_pair": 34000 + } + } + } + } } } diff --git a/ethcore/res/ethereum/callisto.json b/ethcore/res/ethereum/callisto.json index 3513e8bb76..02dc3d2763 100644 --- a/ethcore/res/ethereum/callisto.json +++ b/ethcore/res/ethereum/callisto.json @@ -72,9 +72,50 @@ "0000000000000000000000000000000000000003": { "balance": "1", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } }, "0000000000000000000000000000000000000004": { "balance": "1", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } }, "0000000000000000000000000000000000000005": { "balance": "1", "builtin": { "name": "modexp", "activate_at": 20, "pricing": { "modexp": { "divisor": 20 } } } }, - "0000000000000000000000000000000000000006": { "balance": "1", "builtin": { "name": "alt_bn128_add", "activate_at": 20, "pricing": { "linear": { "base": 500, "word": 0 } } } }, - "0000000000000000000000000000000000000007": { "balance": "1", "builtin": { "name": "alt_bn128_mul", "activate_at": 20, "pricing": { "linear": { "base": 40000, "word": 0 } } } }, - "0000000000000000000000000000000000000008": { "balance": "1", "builtin": { "name": "alt_bn128_pairing", "activate_at": 20, "pricing": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 } } } }, + "0000000000000000000000000000000000000006": { + "balance": "1", + "builtin": { + "name": "alt_bn128_add", + "activate_at": 20, + "eip1108_transition": "0x7fffffffffffff", + "pricing": { + "alt_bn128_const_operations": { + "price": 500, + "eip1108_transition_price": 150 + } + } + } + }, + "0000000000000000000000000000000000000007": { + "balance": "1", + "builtin": { + "name": "alt_bn128_mul", + "activate_at": 20, + "eip1108_transition": "0x7fffffffffffff", + "pricing": { + "alt_bn128_const_operations": { + "price": 40000, + "eip1108_transition_price": 6000 + } + } + } + }, + "0000000000000000000000000000000000000008": { + "balance": "1", + "builtin": { + "name": "alt_bn128_pairing", + "activate_at": 20, + "eip1108_transition": "0x7fffffffffffff", + "pricing": { + "alt_bn128_pairing": { + "base": 100000, + "pair": 80000, + "eip1108_transition_base": 45000, + "eip1108_transition_pair": 34000 + } + } + } + }, "183394f52b2c8c034835edba3bcececa6f60b5a8": { "balance": "100491852286952719463755404" } diff --git a/ethcore/res/ethereum/classic.json b/ethcore/res/ethereum/classic.json index 2750f6f639..f824f7667d 100644 --- a/ethcore/res/ethereum/classic.json +++ b/ethcore/res/ethereum/classic.json @@ -3917,10 +3917,11 @@ "builtin": { "name": "alt_bn128_add", "activate_at": "0x85d9a0", + "eip1108_transition": "0x7fffffffffffff", "pricing": { - "linear": { - "base": 500, - "word": 0 + "alt_bn128_const_operations": { + "price": 500, + "eip1108_transition_price": 150 } } } @@ -3929,10 +3930,11 @@ "builtin": { "name": "alt_bn128_mul", "activate_at": "0x85d9a0", + "eip1108_transition": "0x7fffffffffffff", "pricing": { - "linear": { - "base": 40000, - "word": 0 + "alt_bn128_const_operations": { + "price": 40000, + "eip1108_transition_price": 6000 } } } @@ -3941,10 +3943,13 @@ "builtin": { "name": "alt_bn128_pairing", "activate_at": "0x85d9a0", + "eip1108_transition": "0x7fffffffffffff", "pricing": { "alt_bn128_pairing": { "base": 100000, - "pair": 80000 + "pair": 80000, + "eip1108_transition_base": 45000, + "eip1108_transition_pair": 34000 } } } diff --git a/ethcore/res/ethereum/constantinople_test.json b/ethcore/res/ethereum/constantinople_test.json index b6db5cddb9..c61711e7a7 100644 --- a/ethcore/res/ethereum/constantinople_test.json +++ b/ethcore/res/ethereum/constantinople_test.json @@ -58,8 +58,46 @@ "0000000000000000000000000000000000000003": { "balance": "1", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } }, "0000000000000000000000000000000000000004": { "balance": "1", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } }, "0000000000000000000000000000000000000005": { "builtin": { "name": "modexp", "activate_at": "0x00", "pricing": { "modexp": { "divisor": 20 } } } }, - "0000000000000000000000000000000000000006": { "builtin": { "name": "alt_bn128_add", "activate_at": "0x00", "pricing": { "linear": { "base": 500, "word": 0 } } } }, - "0000000000000000000000000000000000000007": { "builtin": { "name": "alt_bn128_mul", "activate_at": "0x00", "pricing": { "linear": { "base": 40000, "word": 0 } } } }, - "0000000000000000000000000000000000000008": { "builtin": { "name": "alt_bn128_pairing", "activate_at": "0x00", "pricing": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 } } } } + "0000000000000000000000000000000000000006": { + "builtin": { + "name": "alt_bn128_add", + "activate_at": "0x00", + "eip1108_transition": "0x7fffffffffffff", + "pricing": { + "alt_bn128_const_operations": { + "price": 500, + "eip1108_transition_price": 150 + } + } + } + }, + "0000000000000000000000000000000000000007": { + "builtin": { + "name": "alt_bn128_mul", + "activate_at": "0x00", + "eip1108_transition": "0x7fffffffffffff", + "pricing": { + "alt_bn128_const_operations": { + "price": 40000, + "eip1108_transition_price": 6000 + } + } + } + }, + "0000000000000000000000000000000000000008": { + "builtin": { + "name": "alt_bn128_pairing", + "activate_at": "0x00", + "eip1108_transition": "0x7fffffffffffff", + "pricing": { + "alt_bn128_pairing": { + "base": 100000, + "pair": 80000, + "eip1108_transition_base": 45000, + "eip1108_transition_pair": 34000 + } + } + } + } } } diff --git a/ethcore/res/ethereum/eip210_test.json b/ethcore/res/ethereum/eip210_test.json index adf7f2964e..782e99e5e9 100644 --- a/ethcore/res/ethereum/eip210_test.json +++ b/ethcore/res/ethereum/eip210_test.json @@ -46,8 +46,46 @@ "0000000000000000000000000000000000000003": { "balance": "1", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } }, "0000000000000000000000000000000000000004": { "balance": "1", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } }, "0000000000000000000000000000000000000005": { "builtin": { "name": "modexp", "activate_at": "0x00", "pricing": { "modexp": { "divisor": 100 } } } }, - "0000000000000000000000000000000000000006": { "builtin": { "name": "alt_bn128_add", "activate_at": "0x00", "pricing": { "linear": { "base": 500, "word": 0 } } } }, - "0000000000000000000000000000000000000007": { "builtin": { "name": "alt_bn128_mul", "activate_at": "0x00", "pricing": { "linear": { "base": 2000, "word": 0 } } } }, - "0000000000000000000000000000000000000008": { "builtin": { "name": "alt_bn128_pairing", "activate_at": "0x00", "pricing": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 } } } } + "0000000000000000000000000000000000000006": { + "builtin": { + "name": "alt_bn128_add", + "activate_at": "0x00", + "eip1108_transition": "0x7fffffffffffff", + "pricing": { + "alt_bn128_const_operations": { + "price": 500, + "eip1108_transition_price": 150 + } + } + } + }, + "0000000000000000000000000000000000000007": { + "builtin": { + "name": "alt_bn128_mul", + "activate_at": "0x00", + "eip1108_transition": "0x7fffffffffffff", + "pricing": { + "alt_bn128_const_operations": { + "price": 40000, + "eip1108_transition_price": 6000 + } + } + } + }, + "0000000000000000000000000000000000000008": { + "builtin": { + "name": "alt_bn128_pairing", + "activate_at": "0x00", + "eip1108_transition": "0x7fffffffffffff", + "pricing": { + "alt_bn128_pairing": { + "base": 100000, + "pair": 80000, + "eip1108_transition_base": 45000, + "eip1108_transition_pair": 34000 + } + } + } + } } } diff --git a/ethcore/res/ethereum/ellaism.json b/ethcore/res/ethereum/ellaism.json index 946b340f93..d1333fb7f3 100644 --- a/ethcore/res/ethereum/ellaism.json +++ b/ethcore/res/ethereum/ellaism.json @@ -66,8 +66,46 @@ "0000000000000000000000000000000000000003": { "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } }, "0000000000000000000000000000000000000004": { "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } }, "0000000000000000000000000000000000000005": { "builtin": { "name": "modexp", "activate_at": 2000000, "pricing": { "modexp": { "divisor": 20 } } } }, - "0000000000000000000000000000000000000006": { "builtin": { "name": "alt_bn128_add", "activate_at": 2000000, "pricing": { "linear": { "base": 500, "word": 0 } } } }, - "0000000000000000000000000000000000000007": { "builtin": { "name": "alt_bn128_mul", "activate_at": 2000000, "pricing": { "linear": { "base": 40000, "word": 0 } } } }, - "0000000000000000000000000000000000000008": { "builtin": { "name": "alt_bn128_pairing", "activate_at": 2000000, "pricing": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 } } } } + "0000000000000000000000000000000000000006": { + "builtin": { + "name": "alt_bn128_add", + "activate_at": 2000000, + "eip1108_transition": "0x7fffffffffffff", + "pricing": { + "alt_bn128_const_operations": { + "price": 500, + "eip1108_transition_price": 150 + } + } + } + }, + "0000000000000000000000000000000000000007": { + "builtin": { + "name": "alt_bn128_mul", + "activate_at": 2000000, + "eip1108_transition": "0x7fffffffffffff", + "pricing": { + "alt_bn128_const_operations": { + "price": 40000, + "eip1108_transition_price": 6000 + } + } + } + }, + "0000000000000000000000000000000000000008": { + "builtin": { + "name": "alt_bn128_pairing", + "activate_at": 2000000, + "eip1108_transition": "0x7fffffffffffff", + "pricing": { + "alt_bn128_pairing": { + "base": 100000, + "pair": 80000, + "eip1108_transition_base": 45000, + "eip1108_transition_pair": 34000 + } + } + } + } } } diff --git a/ethcore/res/ethereum/ewc.json b/ethcore/res/ethereum/ewc.json index d78e7c383c..1290526504 100644 --- a/ethcore/res/ethereum/ewc.json +++ b/ethcore/res/ethereum/ewc.json @@ -109,11 +109,12 @@ "builtin": { "name": "alt_bn128_add", "activate_at": "0", + "eip1108_transition": "0x7fffffffffffff", "pricing": { - "linear": { - "base": 500, - "word": 0 - } + "alt_bn128_const_operations": { + "price": 500, + "eip1108_transition_price": 150 + } } } }, @@ -122,10 +123,11 @@ "builtin": { "name": "alt_bn128_mul", "activate_at": "0", + "eip1108_transition": "0x7fffffffffffff", "pricing": { - "linear": { - "base": 40000, - "word": 0 + "alt_bn128_const_operations": { + "price": 40000, + "eip1108_transition_price": 6000 } } } @@ -135,12 +137,15 @@ "builtin": { "name": "alt_bn128_pairing", "activate_at": "0", + "eip1108_transition": "0x7fffffffffffff", "pricing": { "alt_bn128_pairing": { "base": 100000, - "pair": 80000 + "pair": 80000, + "eip1108_transition_base": 45000, + "eip1108_transition_pair": 34000 } - } + } } }, "0x1204700000000000000000000000000000000005": { diff --git a/ethcore/res/ethereum/expanse.json b/ethcore/res/ethereum/expanse.json index 073d8fe483..5b950e28b0 100644 --- a/ethcore/res/ethereum/expanse.json +++ b/ethcore/res/ethereum/expanse.json @@ -76,9 +76,47 @@ "0000000000000000000000000000000000000003": { "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } }, "0000000000000000000000000000000000000004": { "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } }, "0000000000000000000000000000000000000005": { "builtin": { "name": "modexp", "activate_at": "0xC3500", "pricing": { "modexp": { "divisor": 20 } } } }, - "0000000000000000000000000000000000000006": { "builtin": { "name": "alt_bn128_add", "activate_at": "0xC3500", "pricing": { "linear": { "base": 500, "word": 0 } } } }, - "0000000000000000000000000000000000000007": { "builtin": { "name": "alt_bn128_mul", "activate_at": "0xC3500", "pricing": { "linear": { "base": 40000, "word": 0 } } } }, - "0000000000000000000000000000000000000008": { "builtin": { "name": "alt_bn128_pairing", "activate_at": "0xC3500", "pricing": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 } } } }, + "0000000000000000000000000000000000000006": { + "builtin": { + "name": "alt_bn128_add", + "activate_at": "0xC3500", + "eip1108_transition": "0x7fffffffffffff", + "pricing": { + "alt_bn128_const_operations": { + "price": 500, + "eip1108_transition_price": 150 + } + } + } + }, + "0000000000000000000000000000000000000007": { + "builtin": { + "name": "alt_bn128_mul", + "activate_at": "0xC3500", + "eip1108_transition": "0x7fffffffffffff", + "pricing": { + "alt_bn128_const_operations": { + "price": 40000, + "eip1108_transition_price": 6000 + } + } + } + }, + "0000000000000000000000000000000000000008": { + "builtin": { + "name": "alt_bn128_pairing", + "activate_at": "0xC3500", + "eip1108_transition": "0x7fffffffffffff", + "pricing": { + "alt_bn128_pairing": { + "base": 100000, + "pair": 80000, + "eip1108_transition_base": 45000, + "eip1108_transition_pair": 34000 + } + } + } + }, "bb94f0ceb32257275b2a7a9c094c13e469b4563e": { "balance": "10000000000000000000000000" }, diff --git a/ethcore/res/ethereum/foundation.json b/ethcore/res/ethereum/foundation.json index 5a7fd3be31..f55e5492b8 100644 --- a/ethcore/res/ethereum/foundation.json +++ b/ethcore/res/ethereum/foundation.json @@ -3921,10 +3921,11 @@ "builtin": { "name": "alt_bn128_add", "activate_at": "0x42ae50", + "eip1108_transition": "0x7fffffffffffff", "pricing": { - "linear": { - "base": 500, - "word": 0 + "alt_bn128_const_operations": { + "price": 500, + "eip1108_transition_price": 150 } } } @@ -3933,10 +3934,11 @@ "builtin": { "name": "alt_bn128_mul", "activate_at": "0x42ae50", + "eip1108_transition": "0x7fffffffffffff", "pricing": { - "linear": { - "base": 40000, - "word": 0 + "alt_bn128_const_operations": { + "price": 40000, + "eip1108_transition_price": 6000 } } } @@ -3945,10 +3947,13 @@ "builtin": { "name": "alt_bn128_pairing", "activate_at": "0x42ae50", + "eip1108_transition": "0x7fffffffffffff", "pricing": { "alt_bn128_pairing": { "base": 100000, - "pair": 80000 + "pair": 80000, + "eip1108_transition_base": 45000, + "eip1108_transition_pair": 34000 } } } diff --git a/ethcore/res/ethereum/goerli.json b/ethcore/res/ethereum/goerli.json index 9717099385..2a0fdc0cab 100644 --- a/ethcore/res/ethereum/goerli.json +++ b/ethcore/res/ethereum/goerli.json @@ -125,11 +125,12 @@ "balance": "0x1", "builtin": { "name": "alt_bn128_add", - "activate_at": "0x0", + "activate_at": "0x00", + "eip1108_transition": "0x7fffffffffffff", "pricing": { - "linear": { - "base": 500, - "word": 0 + "alt_bn128_const_operations": { + "price": 500, + "eip1108_transition_price": 150 } } } @@ -138,11 +139,12 @@ "balance": "0x1", "builtin": { "name": "alt_bn128_mul", - "activate_at": "0x0", + "activate_at": "0x00", + "eip1108_transition": "0x7fffffffffffff", "pricing": { - "linear": { - "base": 40000, - "word": 0 + "alt_bn128_const_operations": { + "price": 40000, + "eip1108_transition_price": 6000 } } } @@ -151,11 +153,14 @@ "balance": "0x1", "builtin": { "name": "alt_bn128_pairing", - "activate_at": "0x0", + "activate_at": "0x00", + "eip1108_transition": "0x7fffffffffffff", "pricing": { "alt_bn128_pairing": { "base": 100000, - "pair": 80000 + "pair": 80000, + "eip1108_transition_base": 45000, + "eip1108_transition_pair": 34000 } } } diff --git a/ethcore/res/ethereum/kotti.json b/ethcore/res/ethereum/kotti.json index 690269625b..bc696a7db5 100644 --- a/ethcore/res/ethereum/kotti.json +++ b/ethcore/res/ethereum/kotti.json @@ -117,10 +117,11 @@ "builtin": { "name": "alt_bn128_add", "activate_at": "0xaef49", + "eip1108_transition": "0x7fffffffffffff", "pricing": { - "linear": { - "base": 500, - "word": 0 + "alt_bn128_const_operations": { + "price": 500, + "eip1108_transition_price": 150 } } } @@ -130,10 +131,11 @@ "builtin": { "name": "alt_bn128_mul", "activate_at": "0xaef49", + "eip1108_transition": "0x7fffffffffffff", "pricing": { - "linear": { - "base": 40000, - "word": 0 + "alt_bn128_const_operations": { + "price": 40000, + "eip1108_transition_price": 6000 } } } @@ -143,10 +145,13 @@ "builtin": { "name": "alt_bn128_pairing", "activate_at": "0xaef49", + "eip1108_transition": "0x7fffffffffffff", "pricing": { "alt_bn128_pairing": { "base": 100000, - "pair": 80000 + "pair": 80000, + "eip1108_transition_base": 45000, + "eip1108_transition_pair": 34000 } } } diff --git a/ethcore/res/ethereum/kovan.json b/ethcore/res/ethereum/kovan.json index 67da802a95..7e9bf76169 100644 --- a/ethcore/res/ethereum/kovan.json +++ b/ethcore/res/ethereum/kovan.json @@ -5344,10 +5344,11 @@ "builtin": { "name": "alt_bn128_add", "activate_at": "0x4d50f8", + "eip1108_transition": "0x7fffffffffffff", "pricing": { - "linear": { - "base": 500, - "word": 0 + "alt_bn128_const_operations": { + "price": 500, + "eip1108_transition_price": 150 } } } @@ -5356,10 +5357,11 @@ "builtin": { "name": "alt_bn128_mul", "activate_at": "0x4d50f8", + "eip1108_transition": "0x7fffffffffffff", "pricing": { - "linear": { - "base": 40000, - "word": 0 + "alt_bn128_const_operations": { + "price": 40000, + "eip1108_transition_price": 6000 } } } @@ -5368,10 +5370,13 @@ "builtin": { "name": "alt_bn128_pairing", "activate_at": "0x4d50f8", + "eip1108_transition": "0x7fffffffffffff", "pricing": { "alt_bn128_pairing": { "base": 100000, - "pair": 80000 + "pair": 80000, + "eip1108_transition_base": 45000, + "eip1108_transition_pair": 34000 } } } @@ -5382,6 +5387,8 @@ }, "nodes": [ "enode://f6e37b943bad3a78cb8589b1798d30d210ffd39cfcd2c8f2de4f098467fd49c667980100d919da7ca46cd50505d30989abda87f0b9339377de13d6592c22caf8@34.198.49.72:30303", + "enode://16898006ba2cd4fa8bf9a3dfe32684c178fa861df144bfc21fe800dc4838a03e342056951fa9fd533dcb0be1219e306106442ff2cf1f7e9f8faa5f2fc1a3aa45@116.203.116.241:30303", + "enode://2909846f78c37510cc0e306f185323b83bb2209e5ff4fdd279d93c60e3f365e3c6e62ad1d2133ff11f9fd6d23ad9c3dad73bb974d53a22f7d1ac5b7dea79d0b0@3.217.96.11:30303", "enode://56abaf065581a5985b8c5f4f88bd202526482761ba10be9bfdcd14846dd01f652ec33fde0f8c0fd1db19b59a4c04465681fcef50e11380ca88d25996191c52de@40.71.221.215:30303", "enode://d07827483dc47b368eaf88454fb04b41b7452cf454e194e2bd4c14f98a3278fed5d819dbecd0d010407fc7688d941ee1e58d4f9c6354d3da3be92f55c17d7ce3@52.166.117.77:30303", "enode://38e6e7fd416293ed120d567a2675fe078c0205ab0671abf16982ce969823bd1f3443d590c18b321dfae7dcbe1f6ba98ef8702f255c3c9822a188abb82c53adca@51.77.66.187:30303", diff --git a/ethcore/res/ethereum/kovan_wasm_test.json b/ethcore/res/ethereum/kovan_wasm_test.json index a4e19b5dd7..54c4a1b83f 100644 --- a/ethcore/res/ethereum/kovan_wasm_test.json +++ b/ethcore/res/ethereum/kovan_wasm_test.json @@ -60,9 +60,47 @@ "0x0000000000000000000000000000000000000003": { "balance": "1", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } }, "0x0000000000000000000000000000000000000004": { "balance": "1", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } }, "0x0000000000000000000000000000000000000005": { "builtin": { "name": "modexp", "activate_at": 5067000, "pricing": { "modexp": { "divisor": 20 } } } }, - "0x0000000000000000000000000000000000000006": { "builtin": { "name": "alt_bn128_add", "activate_at": 5067000, "pricing": { "linear": { "base": 500, "word": 0 } } } }, - "0x0000000000000000000000000000000000000007": { "builtin": { "name": "alt_bn128_mul", "activate_at": 5067000, "pricing": { "linear": { "base": 40000, "word": 0 } } } }, - "0x0000000000000000000000000000000000000008": { "builtin": { "name": "alt_bn128_pairing", "activate_at": 5067000, "pricing": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 } } } }, + "0x0000000000000000000000000000000000000006": { + "builtin": { + "name": "alt_bn128_add", + "activate_at": 5067000, + "eip1108_transition": "0x7fffffffffffff", + "pricing": { + "alt_bn128_const_operations": { + "price": 500, + "eip1108_transition_price": 150 + } + } + } + }, + "0x0000000000000000000000000000000000000007": { + "builtin": { + "name": "alt_bn128_mul", + "activate_at": 5067000, + "eip1108_transition": "0x7fffffffffffff", + "pricing": { + "alt_bn128_const_operations": { + "price": 40000, + "eip1108_transition_price": 6000 + } + } + } + }, + "0x0000000000000000000000000000000000000008": { + "builtin": { + "name": "alt_bn128_pairing", + "activate_at": 5067000, + "eip1108_transition": "0x7fffffffffffff", + "pricing": { + "alt_bn128_pairing": { + "base": 100000, + "pair": 80000, + "eip1108_transition_base": 45000, + "eip1108_transition_pair": 34000 + } + } + } + }, "0x00521965e7bd230323c423d96c657db5b79d099f": { "balance": "1606938044258990275541962092341162602522202993782792835301376" } }, "nodes": [ diff --git a/ethcore/res/ethereum/mcip3_test.json b/ethcore/res/ethereum/mcip3_test.json index 4fafcb09d7..8f1426b992 100644 --- a/ethcore/res/ethereum/mcip3_test.json +++ b/ethcore/res/ethereum/mcip3_test.json @@ -120,38 +120,43 @@ } } }, - "0000000000000000000000000000000000000006":{ - "builtin":{ - "name":"alt_bn128_add", + "0000000000000000000000000000000000000006": { + "builtin": { + "name": "alt_bn128_add", "activate_at":"0x7fffffffffffff", - "pricing":{ - "linear":{ - "base":500, - "word":0 + "eip1108_transition": "0x7fffffffffffff", + "pricing": { + "alt_bn128_const_operations": { + "price": 500, + "eip1108_transition_price": 150 } } } }, - "0000000000000000000000000000000000000007":{ - "builtin":{ - "name":"alt_bn128_mul", + "0000000000000000000000000000000000000007": { + "builtin": { + "name": "alt_bn128_mul", "activate_at":"0x7fffffffffffff", - "pricing":{ - "linear":{ - "base":40000, - "word":0 + "eip1108_transition": "0x7fffffffffffff", + "pricing": { + "alt_bn128_const_operations": { + "price": 40000, + "eip1108_transition_price": 6000 } } } }, - "0000000000000000000000000000000000000008":{ - "builtin":{ - "name":"alt_bn128_pairing", + "0000000000000000000000000000000000000008": { + "builtin": { + "name": "alt_bn128_pairing", "activate_at":"0x7fffffffffffff", - "pricing":{ - "alt_bn128_pairing":{ - "base":100000, - "pair":80000 + "eip1108_transition": "0x7fffffffffffff", + "pricing": { + "alt_bn128_pairing": { + "base": 100000, + "pair": 80000, + "eip1108_transition_base": 45000, + "eip1108_transition_pair": 34000 } } } diff --git a/ethcore/res/ethereum/mix.json b/ethcore/res/ethereum/mix.json index 7cdffdda27..f788191c96 100644 --- a/ethcore/res/ethereum/mix.json +++ b/ethcore/res/ethereum/mix.json @@ -62,9 +62,47 @@ "0000000000000000000000000000000000000003": { "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } }, "0000000000000000000000000000000000000004": { "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } }, "0000000000000000000000000000000000000005": { "builtin": { "name": "modexp", "activate_at": 3000000, "pricing": { "modexp": { "divisor": 20 } } } }, - "0000000000000000000000000000000000000006": { "builtin": { "name": "alt_bn128_add", "activate_at": 3000000, "pricing": { "linear": { "base": 500, "word": 0 } } } }, - "0000000000000000000000000000000000000007": { "builtin": { "name": "alt_bn128_mul", "activate_at": 3000000, "pricing": { "linear": { "base": 40000, "word": 0 } } } }, - "0000000000000000000000000000000000000008": { "builtin": { "name": "alt_bn128_pairing", "activate_at": 3000000, "pricing": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 } } } }, + "0000000000000000000000000000000000000006": { + "builtin": { + "name": "alt_bn128_add", + "activate_at": 3000000, + "eip1108_transition": "0x7fffffffffffff", + "pricing": { + "alt_bn128_const_operations": { + "price": 500, + "eip1108_transition_price": 150 + } + } + } + }, + "0000000000000000000000000000000000000007": { + "builtin": { + "name": "alt_bn128_mul", + "activate_at": 3000000, + "eip1108_transition": "0x7fffffffffffff", + "pricing": { + "alt_bn128_const_operations": { + "price": 40000, + "eip1108_transition_price": 6000 + } + } + } + }, + "0000000000000000000000000000000000000008": { + "builtin": { + "name": "alt_bn128_pairing", + "activate_at": 3000000, + "eip1108_transition": "0x7fffffffffffff", + "pricing": { + "alt_bn128_pairing": { + "base": 100000, + "pair": 80000, + "eip1108_transition_base": 45000, + "eip1108_transition_pair": 34000 + } + } + } + }, "97c7f4f8f0bbf384578a9f5754ae73f37ff49ec2": { "balance": "55000000000000000000000000" } } } diff --git a/ethcore/res/ethereum/morden.json b/ethcore/res/ethereum/morden.json index 5ea0f21143..a4be222c16 100644 --- a/ethcore/res/ethereum/morden.json +++ b/ethcore/res/ethereum/morden.json @@ -90,10 +90,11 @@ "builtin": { "name": "alt_bn128_add", "activate_at": "0x4829ba", + "eip1108_transition": "0x7fffffffffffff", "pricing": { - "linear": { - "base": 500, - "word": 0 + "alt_bn128_const_operations": { + "price": 500, + "eip1108_transition_price": 150 } } } @@ -102,10 +103,11 @@ "builtin": { "name": "alt_bn128_mul", "activate_at": "0x4829ba", + "eip1108_transition": "0x7fffffffffffff", "pricing": { - "linear": { - "base": 40000, - "word": 0 + "alt_bn128_const_operations": { + "price": 40000, + "eip1108_transition_price": 6000 } } } @@ -114,10 +116,13 @@ "builtin": { "name": "alt_bn128_pairing", "activate_at": "0x4829ba", + "eip1108_transition": "0x7fffffffffffff", "pricing": { "alt_bn128_pairing": { "base": 100000, - "pair": 80000 + "pair": 80000, + "eip1108_transition_base": 45000, + "eip1108_transition_pair": 34000 } } } diff --git a/ethcore/res/ethereum/musicoin.json b/ethcore/res/ethereum/musicoin.json index 109432e58f..a7cc956b47 100644 --- a/ethcore/res/ethereum/musicoin.json +++ b/ethcore/res/ethereum/musicoin.json @@ -128,38 +128,43 @@ } } }, - "0000000000000000000000000000000000000006":{ - "builtin":{ - "name":"alt_bn128_add", + "0000000000000000000000000000000000000006": { + "builtin": { + "name": "alt_bn128_add", "activate_at":"0x21e88e", - "pricing":{ - "linear":{ - "base":500, - "word":0 + "eip1108_transition": "0x7fffffffffffff", + "pricing": { + "alt_bn128_const_operations": { + "price": 500, + "eip1108_transition_price": 150 } } } }, - "0000000000000000000000000000000000000007":{ - "builtin":{ - "name":"alt_bn128_mul", + "0000000000000000000000000000000000000007": { + "builtin": { + "name": "alt_bn128_mul", "activate_at":"0x21e88e", - "pricing":{ - "linear":{ - "base":40000, - "word":0 + "eip1108_transition": "0x7fffffffffffff", + "pricing": { + "alt_bn128_const_operations": { + "price": 40000, + "eip1108_transition_price": 6000 } } } }, - "0000000000000000000000000000000000000008":{ - "builtin":{ - "name":"alt_bn128_pairing", + "0000000000000000000000000000000000000008": { + "builtin": { + "name": "alt_bn128_pairing", "activate_at":"0x21e88e", - "pricing":{ - "alt_bn128_pairing":{ - "base":100000, - "pair":80000 + "eip1108_transition": "0x7fffffffffffff", + "pricing": { + "alt_bn128_pairing": { + "base": 100000, + "pair": 80000, + "eip1108_transition_base": 45000, + "eip1108_transition_pair": 34000 } } } diff --git a/ethcore/res/ethereum/poacore.json b/ethcore/res/ethereum/poacore.json index a4fdbcbf10..0b1f0f4677 100644 --- a/ethcore/res/ethereum/poacore.json +++ b/ethcore/res/ethereum/poacore.json @@ -51,7 +51,6 @@ }, "nodes": [ "enode://6e3d1b39cbd2a9c4f053a27e68fd90d0bac83691dfdc4a13c59f2555078a71e63c5daaee5a82aa6db500512760a5456f86076bf8bbe8011c27c82ed7d6f5fb26@45.77.140.210:30303", - "enode://f4698ad485a027497e1cc992bb5f7cecee2b32a44c47202738d8d0eecfab719541988d0cbcbc5ea94c6c959e5cddeb85fc6ae75fb63dc3bf87cdbe9e6f615e9d@206.156.242.64:30303", "enode://31dffed97f8fed1f34fe66453280a89cbeeda60cf28f6fbb212ebbefd7c7566a02c1c7d5c00bbbb49b9fa8a49f157e0f786f379ca9bcbf2fea24de70d70a22b6@206.156.242.61:30303", "enode://6bdc7553ab2e4914cb47774c1e6d8c8f47ac7c3981891f85f65d06f208ea1bc4d3bf982b330950e0a0cd127efd7145c4df7113159a1d4a06ed722e6c16d0ac6c@45.32.215.190:30303", "enode://872d82a24144bc007658fb6fac0dcdfb9b63aeb05ef563a06d0186f2d1e5ffbfc5c4f1244891a8a86ef70682b9d24382e654b305224883698862e2df647a4d23@45.76.236.247:30303", @@ -60,10 +59,47 @@ ], "accounts": { "0000000000000000000000000000000000000005": { "builtin": { "name": "modexp", "activate_at": "0x0", "pricing": { "modexp": { "divisor": 20 } } } }, - "0000000000000000000000000000000000000006": { "builtin": { "name": "alt_bn128_add", "activate_at": "0x0", "pricing": { "linear": { "base": 500, "word": 0 } } } }, - "0000000000000000000000000000000000000007": { "builtin": { "name": "alt_bn128_mul", "activate_at": "0x0", "pricing": { "linear": { "base": 40000, "word": 0 } } } }, - "0000000000000000000000000000000000000008": { "builtin": { "name": "alt_bn128_pairing", "activate_at": "0x0", "pricing": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 } } } }, - + "0000000000000000000000000000000000000006": { + "builtin": { + "name": "alt_bn128_add", + "activate_at": "0x0", + "eip1108_transition": "0x7fffffffffffff", + "pricing": { + "alt_bn128_const_operations": { + "price": 500, + "eip1108_transition_price": 150 + } + } + } + }, + "0000000000000000000000000000000000000007": { + "builtin": { + "name": "alt_bn128_mul", + "activate_at": "0x0", + "eip1108_transition": "0x7fffffffffffff", + "pricing": { + "alt_bn128_const_operations": { + "price": 40000, + "eip1108_transition_price": 6000 + } + } + } + }, + "0000000000000000000000000000000000000008": { + "builtin": { + "name": "alt_bn128_pairing", + "activate_at": "0x0", + "eip1108_transition": "0x7fffffffffffff", + "pricing": { + "alt_bn128_pairing": { + "base": 100000, + "pair": 80000, + "eip1108_transition_base": 45000, + "eip1108_transition_pair": 34000 + } + } + } + }, "0x0000000000000000000000000000000000000001": { "balance": "1", "builtin": { diff --git a/ethcore/res/ethereum/poasokol.json b/ethcore/res/ethereum/poasokol.json index 8ee91c90c0..9caef0bc94 100644 --- a/ethcore/res/ethereum/poasokol.json +++ b/ethcore/res/ethereum/poasokol.json @@ -58,16 +58,54 @@ "enode://8e0af07c86ec36590bb6368e7ad0c45b6dc658f5fb66ec68889a614affddda5e021bd513bcf4fb2fae4a3bbe08cf0de84f037cd58478a89665dfce1ded2595c7@34.236.37.74:30303", "enode://f1a5100a81cb73163ae450c584d06b1f644aa4fad4486c6aeb4c384b343c54bb66c744aa5f133af66ea1b25f0f4a454f04878f3e96ee4cd2390c047396d6357b@209.97.158.4:30303", "enode://0d1e0372f63a3f0b82d66635ea101ecc0f6797788a078805cc933dd93e6a22f7c9fa51ab4e2d21da02d04480ef19f3bbb9a2b41dd1c262085d295a354bb8b0f9@18.217.47.209:30303", - "enode://ab083db73da15b3995ac9c68035cdb32901835a823cb848fccb672e43dd21f14428706118d6fe5b921d8e741f122f35aad0255bc86807b1d17bcfa1e86e40a14@165.227.37.104:30303", + "enode://875e1bd1b98019a5d6d588c23f68534b75462dd6ecbb3dd058221dbf7aa923f0ab782ab93bb82d42edc9996f7f0816a318bdc761e55c02b95e1169cef66f7edc@159.203.24.35:30303", "enode://8e0af07c86ec36590bb6368e7ad0c45b6dc658f5fb66ec68889a614affddda5e021bd513bcf4fb2fae4a3bbe08cf0de84f037cd58478a89665dfce1ded2595c7@34.236.37.74:30303", "enode://182ee200ca134dc4d6390f3d5aadbcd80df0f7f24335830335d142573eacce4eeb919d30e82c5df588034e167e6ba6dd11187502ac9264a71005127f6b146a99@159.203.95.241:30303", "enode://b022ff70b5fcaf9596ae5efed99a8198b4ae0578ee9d17b733609d803a75cef95d3a2a18e50dca9a7c3b26139f158c59eaf8b5fb8d1d331c9a46934a78acabe8@206.189.76.128:30303" ], "accounts": { "0000000000000000000000000000000000000005": { "builtin": { "name": "modexp", "activate_at": "0x0", "pricing": { "modexp": { "divisor": 20 } } } }, - "0000000000000000000000000000000000000006": { "builtin": { "name": "alt_bn128_add", "activate_at": "0x0", "pricing": { "linear": { "base": 500, "word": 0 } } } }, - "0000000000000000000000000000000000000007": { "builtin": { "name": "alt_bn128_mul", "activate_at": "0x0", "pricing": { "linear": { "base": 40000, "word": 0 } } } }, - "0000000000000000000000000000000000000008": { "builtin": { "name": "alt_bn128_pairing", "activate_at": "0x0", "pricing": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 } } } }, + "0000000000000000000000000000000000000006": { + "builtin": { + "name": "alt_bn128_add", + "activate_at": "0x0", + "eip1108_transition": "0x7fffffffffffff", + "pricing": { + "alt_bn128_const_operations": { + "price": 500, + "eip1108_transition_price": 150 + } + } + } + }, + "0000000000000000000000000000000000000007": { + "builtin": { + "name": "alt_bn128_mul", + "activate_at": "0x0", + "eip1108_transition": "0x7fffffffffffff", + "pricing": { + "alt_bn128_const_operations": { + "price": 40000, + "eip1108_transition_price": 6000 + } + } + } + }, + "0000000000000000000000000000000000000008": { + "builtin": { + "name": "alt_bn128_pairing", + "activate_at": "0x0", + "eip1108_transition": "0x7fffffffffffff", + "pricing": { + "alt_bn128_pairing": { + "base": 100000, + "pair": 80000, + "eip1108_transition_base": 45000, + "eip1108_transition_pair": 34000 + } + } + } + }, "0x0000000000000000000000000000000000000001": { "balance": "1", diff --git a/ethcore/res/ethereum/rinkeby.json b/ethcore/res/ethereum/rinkeby.json index 1873617767..b6c7abe20d 100644 --- a/ethcore/res/ethereum/rinkeby.json +++ b/ethcore/res/ethereum/rinkeby.json @@ -117,40 +117,42 @@ } }, "0x0000000000000000000000000000000000000006": { - "balance": "0x1", "builtin": { "name": "alt_bn128_add", "activate_at": "0xfcc25", + "eip1108_transition": "0x7fffffffffffff", "pricing": { - "linear": { - "base": 500, - "word": 0 + "alt_bn128_const_operations": { + "price": 500, + "eip1108_transition_price": 150 } } } }, "0x0000000000000000000000000000000000000007": { - "balance": "0x1", "builtin": { "name": "alt_bn128_mul", "activate_at": "0xfcc25", + "eip1108_transition": "0x7fffffffffffff", "pricing": { - "linear": { - "base": 40000, - "word": 0 + "alt_bn128_const_operations": { + "price": 40000, + "eip1108_transition_price": 6000 } } } }, "0x0000000000000000000000000000000000000008": { - "balance": "0x1", "builtin": { "name": "alt_bn128_pairing", "activate_at": "0xfcc25", + "eip1108_transition": "0x7fffffffffffff", "pricing": { "alt_bn128_pairing": { "base": 100000, - "pair": 80000 + "pair": 80000, + "eip1108_transition_base": 45000, + "eip1108_transition_pair": 34000 } } } diff --git a/ethcore/res/ethereum/ropsten.json b/ethcore/res/ethereum/ropsten.json index b9416dfc27..2d23a0a297 100644 --- a/ethcore/res/ethereum/ropsten.json +++ b/ethcore/res/ethereum/ropsten.json @@ -2735,10 +2735,11 @@ "builtin": { "name": "alt_bn128_add", "activate_at": "0x19f0a0", + "eip1108_transition": "0x7fffffffffffff", "pricing": { - "linear": { - "base": 500, - "word": 0 + "alt_bn128_const_operations": { + "price": 500, + "eip1108_transition_price": 150 } } } @@ -2749,10 +2750,11 @@ "builtin": { "name": "alt_bn128_mul", "activate_at": "0x19f0a0", + "eip1108_transition": "0x7fffffffffffff", "pricing": { - "linear": { - "base": 40000, - "word": 0 + "alt_bn128_const_operations": { + "price": 40000, + "eip1108_transition_price": 6000 } } } @@ -2763,10 +2765,13 @@ "builtin": { "name": "alt_bn128_pairing", "activate_at": "0x19f0a0", + "eip1108_transition": "0x7fffffffffffff", "pricing": { "alt_bn128_pairing": { "base": 100000, - "pair": 80000 + "pair": 80000, + "eip1108_transition_base": 45000, + "eip1108_transition_pair": 34000 } } } diff --git a/ethcore/res/ethereum/st_peters_test.json b/ethcore/res/ethereum/st_peters_test.json index ee88008f66..9ae2f74894 100644 --- a/ethcore/res/ethereum/st_peters_test.json +++ b/ethcore/res/ethereum/st_peters_test.json @@ -58,8 +58,46 @@ "0000000000000000000000000000000000000003": { "balance": "1", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } }, "0000000000000000000000000000000000000004": { "balance": "1", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } }, "0000000000000000000000000000000000000005": { "builtin": { "name": "modexp", "activate_at": "0x00", "pricing": { "modexp": { "divisor": 20 } } } }, - "0000000000000000000000000000000000000006": { "builtin": { "name": "alt_bn128_add", "activate_at": "0x00", "pricing": { "linear": { "base": 500, "word": 0 } } } }, - "0000000000000000000000000000000000000007": { "builtin": { "name": "alt_bn128_mul", "activate_at": "0x00", "pricing": { "linear": { "base": 40000, "word": 0 } } } }, - "0000000000000000000000000000000000000008": { "builtin": { "name": "alt_bn128_pairing", "activate_at": "0x00", "pricing": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 } } } } + "0000000000000000000000000000000000000006": { + "builtin": { + "name": "alt_bn128_add", + "activate_at": "0x0", + "eip1108_transition": "0x7fffffffffffff", + "pricing": { + "alt_bn128_const_operations": { + "price": 500, + "eip1108_transition_price": 150 + } + } + } + }, + "0000000000000000000000000000000000000007": { + "builtin": { + "name": "alt_bn128_mul", + "activate_at": "0x0", + "eip1108_transition": "0x7fffffffffffff", + "pricing": { + "alt_bn128_const_operations": { + "price": 40000, + "eip1108_transition_price": 6000 + } + } + } + }, + "0000000000000000000000000000000000000008": { + "builtin": { + "name": "alt_bn128_pairing", + "activate_at": "0x0", + "eip1108_transition": "0x7fffffffffffff", + "pricing": { + "alt_bn128_pairing": { + "base": 100000, + "pair": 80000, + "eip1108_transition_base": 45000, + "eip1108_transition_pair": 34000 + } + } + } + } } } diff --git a/ethcore/res/ethereum/transition_test.json b/ethcore/res/ethereum/transition_test.json index 3f1c420dd6..bc28ebd509 100644 --- a/ethcore/res/ethereum/transition_test.json +++ b/ethcore/res/ethereum/transition_test.json @@ -57,9 +57,46 @@ "0000000000000000000000000000000000000002": { "balance": "1", "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } }, "0000000000000000000000000000000000000003": { "balance": "1", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } }, "0000000000000000000000000000000000000004": { "balance": "1", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } }, - "0000000000000000000000000000000000000005": { "builtin": { "name": "modexp", "activate_at": "5", "pricing": { "modexp": { "divisor": 100 } } } }, - "0000000000000000000000000000000000000006": { "builtin": { "name": "alt_bn128_add", "activate_at": "5", "pricing": { "linear": { "base": 500, "word": 0 } } } }, - "0000000000000000000000000000000000000007": { "builtin": { "name": "alt_bn128_mul", "activate_at": "5", "pricing": { "linear": { "base": 2000, "word": 0 } } } }, - "0000000000000000000000000000000000000008": { "builtin": { "name": "alt_bn128_pairing", "activate_at": "5", "pricing": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 } } } } + "0000000000000000000000000000000000000006": { + "builtin": { + "name": "alt_bn128_add", + "activate_at": "5", + "eip1108_transition": "0x7fffffffffffff", + "pricing": { + "alt_bn128_const_operations": { + "price": 500, + "eip1108_transition_price": 150 + } + } + } + }, + "0000000000000000000000000000000000000007": { + "builtin": { + "name": "alt_bn128_mul", + "activate_at": "5", + "eip1108_transition": "0x7fffffffffffff", + "pricing": { + "alt_bn128_const_operations": { + "price": 40000, + "eip1108_transition_price": 6000 + } + } + } + }, + "0000000000000000000000000000000000000008": { + "builtin": { + "name": "alt_bn128_pairing", + "activate_at": "5", + "eip1108_transition": "0x7fffffffffffff", + "pricing": { + "alt_bn128_pairing": { + "base": 100000, + "pair": 80000, + "eip1108_transition_base": 45000, + "eip1108_transition_pair": 34000 + } + } + } + } } } diff --git a/ethcore/res/ethereum/volta.json b/ethcore/res/ethereum/volta.json index d43d6c0685..9ac6f9afa4 100644 --- a/ethcore/res/ethereum/volta.json +++ b/ethcore/res/ethereum/volta.json @@ -109,40 +109,45 @@ "builtin": { "name": "alt_bn128_add", "activate_at": "0", + "eip1108_transition": "0x7fffffffffffff", "pricing": { - "linear": { - "base": 500, - "word": 0 + "alt_bn128_const_operations": { + "price": 500, + "eip1108_transition_price": 150 } } } - }, - "0x0000000000000000000000000000000000000007": { + }, + "0x0000000000000000000000000000000000000007": { "balance": "1", "builtin": { "name": "alt_bn128_mul", "activate_at": "0", + "eip1108_transition": "0x7fffffffffffff", "pricing": { - "linear": { - "base": 40000, - "word": 0 + "alt_bn128_const_operations": { + "price": 40000, + "eip1108_transition_price": 6000 } } - } + } }, "0x0000000000000000000000000000000000000008": { "balance": "1", "builtin": { "name": "alt_bn128_pairing", "activate_at": "0", + "eip1108_transition": "0x7fffffffffffff", "pricing": { "alt_bn128_pairing": { "base": 100000, - "pair": 80000 + "pair": 80000, + "eip1108_transition_base": 45000, + "eip1108_transition_pair": 34000 } } } - }, + }, "0x1204700000000000000000000000000000000005": { "constructor": "0x606060405234156200001057600080fd5b6040516200240138038062002401833981016040528080518201919060200180519060200190919050505b600082518260328211158015620000525750818111155b801562000060575060008114155b80156200006e575060008214155b15156200007a57600080fd5b600092505b8451831015620001b6576002600086858151811015156200009c57fe5b9060200190602002015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161580156200012b5750600085848151811015156200010857fe5b9060200190602002015173ffffffffffffffffffffffffffffffffffffffff1614155b15156200013757600080fd5b60016002600087868151811015156200014c57fe5b9060200190602002015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505b82806001019350506200007f565b8460039080519060200190620001ce929190620001e3565b50836004819055505b5b5050505050620002b8565b8280548282559060005260206000209081019282156200025f579160200282015b828111156200025e5782518260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055509160200191906001019062000204565b5b5090506200026e919062000272565b5090565b620002b591905b80821115620002b157600081816101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555060010162000279565b5090565b90565b61213980620002c86000396000f3006060604052361561011b576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063025e7c2714610177578063173825d9146101da57806320ea8d86146102135780632f54bf6e146102365780633411c81c1461028757806354741525146102e15780637065cb4814610325578063784547a71461035e5780638b51d13f146103995780639ace38c2146103d0578063a0e67e2b146104ce578063a8abe69a14610539578063b5dc40c3146105d1578063b77bf6001461064a578063ba51a6df14610673578063c01a8c8414610696578063c6427474146106b9578063d74f8edd14610752578063dc8452cd1461077b578063e20056e6146107a4578063ee22610b146107fc575b5b6000341115610174573373ffffffffffffffffffffffffffffffffffffffff167fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c346040518082815260200191505060405180910390a25b5b005b341561018257600080fd5b610198600480803590602001909190505061081f565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156101e557600080fd5b610211600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190505061085f565b005b341561021e57600080fd5b6102346004808035906020019091905050610b02565b005b341561024157600080fd5b61026d600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610cae565b604051808215151515815260200191505060405180910390f35b341561029257600080fd5b6102c7600480803590602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610cce565b604051808215151515815260200191505060405180910390f35b34156102ec57600080fd5b61030f600480803515159060200190919080351515906020019091905050610cfd565b6040518082815260200191505060405180910390f35b341561033057600080fd5b61035c600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610d91565b005b341561036957600080fd5b61037f6004808035906020019091905050610f99565b604051808215151515815260200191505060405180910390f35b34156103a457600080fd5b6103ba6004808035906020019091905050611081565b6040518082815260200191505060405180910390f35b34156103db57600080fd5b6103f16004808035906020019091905050611150565b604051808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200184815260200180602001831515151581526020018281038252848181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156104bc5780601f10610491576101008083540402835291602001916104bc565b820191906000526020600020905b81548152906001019060200180831161049f57829003601f168201915b50509550505050505060405180910390f35b34156104d957600080fd5b6104e16111ac565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b838110156105255780820151818401525b602081019050610509565b505050509050019250505060405180910390f35b341561054457600080fd5b610579600480803590602001909190803590602001909190803515159060200190919080351515906020019091905050611241565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b838110156105bd5780820151818401525b6020810190506105a1565b505050509050019250505060405180910390f35b34156105dc57600080fd5b6105f260048080359060200190919050506113a2565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b838110156106365780820151818401525b60208101905061061a565b505050509050019250505060405180910390f35b341561065557600080fd5b61065d6115d3565b6040518082815260200191505060405180910390f35b341561067e57600080fd5b61069460048080359060200190919050506115d9565b005b34156106a157600080fd5b6106b76004808035906020019091905050611696565b005b34156106c457600080fd5b61073c600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091905050611877565b6040518082815260200191505060405180910390f35b341561075d57600080fd5b610765611897565b6040518082815260200191505060405180910390f35b341561078657600080fd5b61078e61189c565b6040518082815260200191505060405180910390f35b34156107af57600080fd5b6107fa600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506118a2565b005b341561080757600080fd5b61081d6004808035906020019091905050611bc0565b005b60038181548110151561082e57fe5b906000526020600020900160005b915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60003073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561089b57600080fd5b81600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615156108f457600080fd5b6000600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550600091505b600160038054905003821015610a80578273ffffffffffffffffffffffffffffffffffffffff1660038381548110151561098757fe5b906000526020600020900160005b9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415610a725760036001600380549050038154811015156109e757fe5b906000526020600020900160005b9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600383815481101515610a2357fe5b906000526020600020900160005b6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550610a80565b5b8180600101925050610951565b6001600381818054905003915081610a989190611fe8565b506003805490506004541115610ab757610ab66003805490506115d9565b5b8273ffffffffffffffffffffffffffffffffffffffff167f8001553a916ef2f495d26a907cc54d96ed840d7bda71e73194bf5a9df7a76b9060405160405180910390a25b5b505b5050565b33600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515610b5b57600080fd5b81336001600083815260200190815260200160002060008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515610bc657600080fd5b8360008082815260200190815260200160002060030160009054906101000a900460ff16151515610bf657600080fd5b60006001600087815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550843373ffffffffffffffffffffffffffffffffffffffff167ff6a317157440607f36269043eb55f1287a5a19ba2216afeab88cd46cbcfb88e960405160405180910390a35b5b505b50505b5050565b60026020528060005260406000206000915054906101000a900460ff1681565b60016020528160005260406000206020528060005260406000206000915091509054906101000a900460ff1681565b600080600090505b600554811015610d8957838015610d3c575060008082815260200190815260200160002060030160009054906101000a900460ff16155b80610d6f5750828015610d6e575060008082815260200190815260200160002060030160009054906101000a900460ff165b5b15610d7b576001820191505b5b8080600101915050610d05565b5b5092915050565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610dcb57600080fd5b80600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151515610e2557600080fd5b8160008173ffffffffffffffffffffffffffffffffffffffff1614151515610e4c57600080fd5b60016003805490500160045460328211158015610e695750818111155b8015610e76575060008114155b8015610e83575060008214155b1515610e8e57600080fd5b6001600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555060038054806001018281610efa9190612014565b916000526020600020900160005b87909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550508473ffffffffffffffffffffffffffffffffffffffff167ff39e6e1eb0edcf53c221607b54b00cd28f3196fed0a24994dc308b8f611b682d60405160405180910390a25b5b50505b505b505b50565b6000806000809150600090505b60038054905081101561107957600160008581526020019081526020016000206000600383815481101515610fd757fe5b906000526020600020900160005b9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615611058576001820191505b60045482141561106b576001925061107a565b5b8080600101915050610fa6565b5b5050919050565b600080600090505b600380549050811015611149576001600084815260200190815260200160002060006003838154811015156110ba57fe5b906000526020600020900160005b9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161561113b576001820191505b5b8080600101915050611089565b5b50919050565b60006020528060005260406000206000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169080600101549080600201908060030160009054906101000a900460ff16905084565b6111b4612040565b600380548060200260200160405190810160405280929190818152602001828054801561123657602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190600101908083116111ec575b505050505090505b90565b611249612054565b611251612054565b6000806005546040518059106112645750595b908082528060200260200182016040525b50925060009150600090505b600554811015611322578580156112b8575060008082815260200190815260200160002060030160009054906101000a900460ff16155b806112eb57508480156112ea575060008082815260200190815260200160002060030160009054906101000a900460ff165b5b15611314578083838151811015156112ff57fe5b90602001906020020181815250506001820191505b5b8080600101915050611281565b8787036040518059106113325750595b908082528060200260200182016040525b5093508790505b8681101561139657828181518110151561136057fe5b906020019060200201518489830381518110151561137a57fe5b90602001906020020181815250505b808060010191505061134a565b5b505050949350505050565b6113aa612040565b6113b2612040565b6000806003805490506040518059106113c85750595b908082528060200260200182016040525b50925060009150600090505b60038054905081101561152b5760016000868152602001908152602001600020600060038381548110151561141657fe5b906000526020600020900160005b9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161561151d5760038181548110151561149f57fe5b906000526020600020900160005b9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1683838151811015156114da57fe5b9060200190602002019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250506001820191505b5b80806001019150506113e5565b816040518059106115395750595b908082528060200260200182016040525b509350600090505b818110156115ca57828181518110151561156857fe5b90602001906020020151848281518110151561158057fe5b9060200190602002019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b8080600101915050611552565b5b505050919050565b60055481565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561161357600080fd5b600380549050816032821115801561162b5750818111155b8015611638575060008114155b8015611645575060008214155b151561165057600080fd5b826004819055507fa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a836040518082815260200191505060405180910390a15b5b50505b50565b33600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615156116ef57600080fd5b81600080600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415151561174b57600080fd5b82336001600083815260200190815260200160002060008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515156117b757600080fd5b600180600087815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550843373ffffffffffffffffffffffffffffffffffffffff167f4a504a94899432a9846e1aa406dceb1bcfd538bb839071d49d1e5e23f5be30ef60405160405180910390a361186c85611bc0565b5b5b50505b505b5050565b6000611884848484611e6c565b905061188f81611696565b5b9392505050565b603281565b60045481565b60003073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156118de57600080fd5b82600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151561193757600080fd5b82600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615151561199157600080fd5b600092505b600380549050831015611a7f578473ffffffffffffffffffffffffffffffffffffffff166003848154811015156119c957fe5b906000526020600020900160005b9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415611a715783600384815481101515611a2257fe5b906000526020600020900160005b6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550611a7f565b5b8280600101935050611996565b6000600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506001600260008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508473ffffffffffffffffffffffffffffffffffffffff167f8001553a916ef2f495d26a907cc54d96ed840d7bda71e73194bf5a9df7a76b9060405160405180910390a28373ffffffffffffffffffffffffffffffffffffffff167ff39e6e1eb0edcf53c221607b54b00cd28f3196fed0a24994dc308b8f611b682d60405160405180910390a25b5b505b505b505050565b600033600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515611c1b57600080fd5b82336001600083815260200190815260200160002060008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515611c8657600080fd5b8460008082815260200190815260200160002060030160009054906101000a900460ff16151515611cb657600080fd5b611cbf86610f99565b15611e6057600080878152602001908152602001600020945060018560030160006101000a81548160ff021916908315150217905550611ddd8560000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16866001015487600201805460018160011615610100020316600290049050886002018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015611dd35780601f10611da857610100808354040283529160200191611dd3565b820191906000526020600020905b815481529060010190602001808311611db657829003601f168201915b5050505050611fc0565b15611e1457857f33e13ecb54c3076d8e8bb8c2881800a4d972b792045ffae98fdf46df365fed7560405160405180910390a2611e5f565b857f526441bb6c1aba3c9a4a6ca1d6545da9c2333c8c48343ef398eb858d72b7923660405160405180910390a260008560030160006101000a81548160ff0219169083151502179055505b5b5b5b505b50505b505050565b60008360008173ffffffffffffffffffffffffffffffffffffffff1614151515611e9557600080fd5b60055491506080604051908101604052808673ffffffffffffffffffffffffffffffffffffffff1681526020018581526020018481526020016000151581525060008084815260200190815260200160002060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550602082015181600101556040820151816002019080519060200190611f54929190612068565b5060608201518160030160006101000a81548160ff0219169083151502179055509050506001600560008282540192505081905550817fc0ba8fe4b176c1714197d43b9cc6bcf797a4a7461c5fe8d0ef6e184ae7601e5160405160405180910390a25b5b509392505050565b6000806040516020840160008287838a8c6187965a03f1925050508091505b50949350505050565b81548183558181151161200f5781836000526020600020918201910161200e91906120e8565b5b505050565b81548183558181151161203b5781836000526020600020918201910161203a91906120e8565b5b505050565b602060405190810160405280600081525090565b602060405190810160405280600081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106120a957805160ff19168380011785556120d7565b828001600101855582156120d7579182015b828111156120d65782518255916020019190600101906120bb565b5b5090506120e491906120e8565b5090565b61210a91905b808211156121065760008160009055506001016120ee565b5090565b905600a165627a7a72305820f1129b699b3017535535a920e15503cd06af1f5c77637c0637cc29355b1dad3400290000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000040000000000000000000000000cb1437200aea736788f1fc56f327c0456c3598d00000000000000000000000074dd76e24b2cfb43c1b1a4498295d553d0843746000000000000000000000000eeb4ceee443f9e0d17bdbd6daa241681ee5e51c2000000000000000000000000a005caea55375ae20e3aaef746113535503abc19" }, diff --git a/ethcore/res/ethereum/xdai.json b/ethcore/res/ethereum/xdai.json new file mode 100644 index 0000000000..ac2a40e148 --- /dev/null +++ b/ethcore/res/ethereum/xdai.json @@ -0,0 +1,157 @@ +{ + "name": "xDai Chain", + "dataDir": "xdai", + "engine": { + "authorityRound": { + "params": { + "stepDuration": 5, + "blockReward": "0x0", + "maximumUncleCountTransition": 0, + "maximumUncleCount": 0, + "validators": { + "multi": { + "0": { + "list": ["0xcace5b3c29211740e595850e80478416ee77ca21"] + }, + "1300": { + "safeContract": "0x22e1229a2c5b95a60983b5577f745a603284f535" + } + } + }, + "blockRewardContractAddress": "0x867305d19606aadba405ce534e303d0e225f9556", + "blockRewardContractTransition": 1310 + } + } + }, + "params": { + "gasLimitBoundDivisor": "0x400", + "maximumExtraDataSize": "0x20", + "minGasLimit": "0x1388", + "networkID": "100", + "eip140Transition": "0x0", + "eip211Transition": "0x0", + "eip214Transition": "0x0", + "eip658Transition": "0x0", + "eip145Transition": 1604400, + "eip1014Transition": 1604400, + "eip1052Transition": 1604400, + "eip1283Transition": 1604400, + "eip1283DisableTransition": 2508800, + "registrar": "0x1ec97dc137f5168af053c24460a1200502e1a9d2" + }, + "genesis": { + "seal": { + "authorityRound": { + "step": "0x0", + "signature": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + } + }, + "difficulty": "0x20000", + "gasLimit": "0x989680" + }, + "accounts": { + "0000000000000000000000000000000000000005": { + "builtin": { + "name": "modexp", + "activate_at": "0x0", + "pricing": { + "modexp": { + "divisor": 20 + } + } + } + }, + "0000000000000000000000000000000000000006": { + "builtin": { + "name": "alt_bn128_add", + "activate_at": "0x0", + "eip1108_transition": "0x7fffffffffffff", + "pricing": { + "alt_bn128_const_operations": { + "price": 500, + "eip1108_transition_price": 150 + } + } + } + }, + "0000000000000000000000000000000000000007": { + "builtin": { + "name": "alt_bn128_mul", + "activate_at": "0x0", + "eip1108_transition": "0x7fffffffffffff", + "pricing": { + "alt_bn128_const_operations": { + "price": 40000, + "eip1108_transition_price": 6000 + } + } + } + }, + "0000000000000000000000000000000000000008": { + "builtin": { + "name": "alt_bn128_pairing", + "activate_at": "0x0", + "eip1108_transition": "0x7fffffffffffff", + "pricing": { + "alt_bn128_pairing": { + "base": 100000, + "pair": 80000, + "eip1108_transition_base": 45000, + "eip1108_transition_pair": 34000 + } + } + } + }, + "0x0000000000000000000000000000000000000001": { + "balance": "1", + "builtin": { + "name": "ecrecover", + "pricing": { + "linear": { + "base": 3000, + "word": 0 + } + } + } + }, + "0x0000000000000000000000000000000000000002": { + "balance": "1", + "builtin": { + "name": "sha256", + "pricing": { + "linear": { + "base": 60, + "word": 12 + } + } + } + }, + "0x0000000000000000000000000000000000000003": { + "balance": "1", + "builtin": { + "name": "ripemd160", + "pricing": { + "linear": { + "base": 600, + "word": 120 + } + } + } + }, + "0x0000000000000000000000000000000000000004": { + "balance": "1", + "builtin": { + "name": "identity", + "pricing": { + "linear": { + "base": 15, + "word": 3 + } + } + } + } + }, + "nodes": [ + "enode://66786c15390cb4fef3743571e12ec54ca343e7f119018136d68b670edd93604eedf74e5013dc5c2439f89e0e05593e29c409a97e155ea4165c6b832de131ef1e@3.214.113.185:30303" + ] +} diff --git a/ethcore/res/instant_seal.json b/ethcore/res/instant_seal.json index 3ec998f0e5..baafeb5bdf 100644 --- a/ethcore/res/instant_seal.json +++ b/ethcore/res/instant_seal.json @@ -43,9 +43,50 @@ "0000000000000000000000000000000000000003": { "balance": "1", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } }, "0000000000000000000000000000000000000004": { "balance": "1", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } }, "0000000000000000000000000000000000000005": { "balance": "1", "builtin": { "name": "modexp", "activate_at": 0, "pricing": { "modexp": { "divisor": 20 } } } }, - "0000000000000000000000000000000000000006": { "balance": "1", "builtin": { "name": "alt_bn128_add", "activate_at": 0, "pricing": { "linear": { "base": 500, "word": 0 } } } }, - "0000000000000000000000000000000000000007": { "balance": "1", "builtin": { "name": "alt_bn128_mul", "activate_at": 0, "pricing": { "linear": { "base": 40000, "word": 0 } } } }, - "0000000000000000000000000000000000000008": { "balance": "1", "builtin": { "name": "alt_bn128_pairing", "activate_at": 0, "pricing": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 } } } }, + "0000000000000000000000000000000000000006": { + "balance": "1", + "builtin": { + "name": "alt_bn128_add", + "activate_at": 0, + "eip1108_transition": "0x7fffffffffffff", + "pricing": { + "alt_bn128_const_operations": { + "price": 500, + "eip1108_transition_price": 150 + } + } + } + }, + "0000000000000000000000000000000000000007": { + "balance": "1", + "builtin": { + "name": "alt_bn128_mul", + "activate_at": 0, + "eip1108_transition": "0x7fffffffffffff", + "pricing": { + "alt_bn128_const_operations": { + "price": 40000, + "eip1108_transition_price": 6000 + } + } + } + }, + "0000000000000000000000000000000000000008": { + "balance": "1", + "builtin": { + "name": "alt_bn128_pairing", + "activate_at": 0, + "eip1108_transition": "0x7fffffffffffff", + "pricing": { + "alt_bn128_pairing": { + "base": 100000, + "pair": 80000, + "eip1108_transition_base": 45000, + "eip1108_transition_pair": 34000 + } + } + } + }, "0000000000000000000000000000000000001337": { "balance": "1", "constructor": "0x606060405233600060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550670de0b6b3a764000060035534610000575b612904806100666000396000f3006060604052361561013c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306b2ff471461014157806313af40351461018c57806319362a28146101bf5780633f3935d114610248578063432ced04146102b75780634f39ca59146102eb5780636795dbcd1461032457806369fe0e2d146103c857806379ce9fac146103fd5780638da5cb5b1461045557806390b97fc1146104a457806392698814146105245780639890220b1461055d578063ac4e73f914610584578063ac72c12014610612578063c3a358251461064b578063ddca3f43146106c3578063deb931a2146106e6578063df57b74214610747578063e30bd740146107a8578063eadf976014610862578063ef5454d6146108e7578063f25eb5c114610975578063f6d339e414610984575b610000565b3461000057610172600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610a1f565b604051808215151515815260200191505060405180910390f35b34610000576101bd600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610a81565b005b346100005761022e60048080356000191690602001909190803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509190803560001916906020019091905050610ba2565b604051808215151515815260200191505060405180910390f35b346100005761029d600480803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091905050610dc9565b604051808215151515815260200191505060405180910390f35b6102d1600480803560001916906020019091905050611035565b604051808215151515815260200191505060405180910390f35b346100005761030a60048080356000191690602001909190505061115f565b604051808215151515815260200191505060405180910390f35b346100005761038660048080356000191690602001909190803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091905050611378565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34610000576103e3600480803590602001909190505061140d565b604051808215151515815260200191505060405180910390f35b346100005761043b60048080356000191690602001909190803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506114b4565b604051808215151515815260200191505060405180910390f35b34610000576104626115fb565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b346100005761050660048080356000191690602001909190803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091905050611621565b60405180826000191660001916815260200191505060405180910390f35b34610000576105436004808035600019169060200190919050506116b2565b604051808215151515815260200191505060405180910390f35b346100005761056a611715565b604051808215151515815260200191505060405180910390f35b34610000576105f8600480803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050611824565b604051808215151515815260200191505060405180910390f35b3461000057610631600480803560001916906020019091905050611d8b565b604051808215151515815260200191505060405180910390f35b34610000576106ad60048080356000191690602001909190803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091905050611dee565b6040518082815260200191505060405180910390f35b34610000576106d0611e83565b6040518082815260200191505060405180910390f35b3461000057610705600480803560001916906020019091905050611e89565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3461000057610766600480803560001916906020019091905050611ed2565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34610000576107d9600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050611f1b565b6040518080602001828103825283818151815260200191508051906020019080838360008314610828575b80518252602083111561082857602082019150602081019050602083039250610804565b505050905090810190601f1680156108545780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34610000576108cd60048080356000191690602001909190803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509190803590602001909190505061200c565b604051808215151515815260200191505060405180910390f35b346100005761095b600480803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050612236565b604051808215151515815260200191505060405180910390f35b3461000057610982612425565b005b3461000057610a0560048080356000191690602001909190803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050612698565b604051808215151515815260200191505060405180910390f35b60006000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805460018160011615610100020316600290049050141590505b919050565b600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610add57610b9f565b8073ffffffffffffffffffffffffffffffffffffffff16600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f70aea8d848e8a90fb7661b227dc522eb6395c3dac71b63cb59edd5c9899b236460405180905060405180910390a380600060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b5b50565b6000833373ffffffffffffffffffffffffffffffffffffffff1660016000836000191660001916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141515610c1d57610dc1565b82600160008760001916600019168152602001908152602001600020600201856040518082805190602001908083835b60208310610c705780518252602082019150602081019050602083039250610c4d565b6001836020036101000a03801982511681845116808217855250505050505090500191505090815260200160405180910390208160001916905550836040518082805190602001908083835b60208310610cdf5780518252602082019150602081019050602083039250610cbc565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051809103902085600019167fb829c3e412537bbe794c048ccb9e4605bb4aaaa8e4d4c15c1a6e0c2adc1716ea866040518080602001828103825283818151815260200191508051906020019080838360008314610d82575b805182526020831115610d8257602082019150602081019050602083039250610d5e565b505050905090810190601f168015610dae5780820380516001836020036101000a031916815260200191505b509250505060405180910390a3600191505b5b509392505050565b6000813373ffffffffffffffffffffffffffffffffffffffff1660016000836040518082805190602001908083835b60208310610e1b5780518252602082019150602081019050602083039250610df8565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390206000191660001916815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141515610ea45761102f565b82600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10610f2d57805160ff1916838001178555610f5b565b82800160010185558215610f5b579182015b82811115610f5a578251825591602001919060010190610f3f565b5b509050610f8091905b80821115610f7c576000816000905550600101610f64565b5090565b50503373ffffffffffffffffffffffffffffffffffffffff16836040518082805190602001908083835b60208310610fcd5780518252602082019150602081019050602083039250610faa565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390207f098ae8581bb8bd9af1beaf7f2e9f51f31a8e5a8bfada4e303a645d71d9c9192060405180905060405180910390a3600191505b5b50919050565b600081600060016000836000191660001916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614151561109b57611159565b6003543410156110aa57611158565b3360016000856000191660001916815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055503373ffffffffffffffffffffffffffffffffffffffff1683600019167f4963513eca575aba66fdcd25f267aae85958fe6fb97e75fa25d783f1a091a22160405180905060405180910390a3600191505b5b5b50919050565b6000813373ffffffffffffffffffffffffffffffffffffffff1660016000836000191660001916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415156111da57611372565b6002600060016000866000191660001916815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805460018160011615610100020316600290046000825580601f1061127c57506112b3565b601f0160209004906000526020600020908101906112b291905b808211156112ae576000816000905550600101611296565b5090565b5b5060016000846000191660001916815260200190815260200160002060006000820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905550503373ffffffffffffffffffffffffffffffffffffffff1683600019167fef1961b4d2909dc23643b309bfe5c3e5646842d98c3a58517037ef3871185af360405180905060405180910390a3600191505b5b50919050565b6000600160008460001916600019168152602001908152602001600020600201826040518082805190602001908083835b602083106113cc57805182526020820191506020810190506020830392506113a9565b6001836020036101000a0380198251168184511680821785525050505050509050019150509081526020016040518091039020546001900490505b92915050565b6000600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561146b576114af565b816003819055507f6bbc57480a46553fa4d156ce702beef5f3ad66303b0ed1a5d4cb44966c6584c3826040518082815260200191505060405180910390a1600190505b5b919050565b6000823373ffffffffffffffffffffffffffffffffffffffff1660016000836000191660001916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614151561152f576115f4565b8260016000866000191660001916815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1685600019167f7b97c62130aa09acbbcbf7482630e756592496f1759eaf702f469cf64dfb779460405180905060405180910390a4600191505b5b5092915050565b600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600160008460001916600019168152602001908152602001600020600201826040518082805190602001908083835b602083106116755780518252602082019150602081019050602083039250611652565b6001836020036101000a03801982511681845116808217855250505050505090500191505090815260200160405180910390205490505b92915050565b6000600060016000846000191660001916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141590505b919050565b6000600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561177357611821565b7fdef931299fe61d176f949118058530c1f3f539dcb6950b4e372c9b835c33ca073073ffffffffffffffffffffffffffffffffffffffff16316040518082815260200191505060405180910390a13373ffffffffffffffffffffffffffffffffffffffff166108fc3073ffffffffffffffffffffffffffffffffffffffff16319081150290604051809050600060405180830381858888f19350505050151561181b57610000565b600190505b5b90565b60006000836040518082805190602001908083835b6020831061185c5780518252602082019150602081019050602083039250611839565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390203373ffffffffffffffffffffffffffffffffffffffff1660016000836000191660001916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614151561190157611d83565b846040518082805190602001908083835b602083106119355780518252602082019150602081019050602083039250611912565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390209150600060016000846000191660001916815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614158015611ab4575081600019166002600060016000866000191660001916815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206040518082805460018160011615610100020316600290048015611aa15780601f10611a7f576101008083540402835291820191611aa1565b820191906000526020600020905b815481529060010190602001808311611a8d575b5050915050604051809103902060001916145b15611c79576002600060016000856000191660001916815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805460018160011615610100020316600290046000825580601f10611b5b5750611b92565b601f016020900490600052602060002090810190611b9191905b80821115611b8d576000816000905550600101611b75565b5090565b5b5060016000836000191660001916815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16856040518082805190602001908083835b60208310611c1c5780518252602082019150602081019050602083039250611bf9565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390207f12491ad95fd945e444d88a894ffad3c21959880a4dcd8af99d4ae4ffc71d4abd60405180905060405180910390a35b8360016000846000191660001916815260200190815260200160002060010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508373ffffffffffffffffffffffffffffffffffffffff16856040518082805190602001908083835b60208310611d215780518252602082019150602081019050602083039250611cfe565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390207f728435a0031f6a04538fcdd24922a7e06bc7bc945db03e83d22122d1bc5f28df60405180905060405180910390a3600192505b5b505092915050565b6000600060016000846000191660001916815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141590505b919050565b6000600160008460001916600019168152602001908152602001600020600201826040518082805190602001908083835b60208310611e425780518252602082019150602081019050602083039250611e1f565b6001836020036101000a0380198251168184511680821785525050505050509050019150509081526020016040518091039020546001900490505b92915050565b60035481565b600060016000836000191660001916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505b919050565b600060016000836000191660001916815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505b919050565b6020604051908101604052806000815250600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015611fff5780601f10611fd457610100808354040283529160200191611fff565b820191906000526020600020905b815481529060010190602001808311611fe257829003601f168201915b505050505090505b919050565b6000833373ffffffffffffffffffffffffffffffffffffffff1660016000836000191660001916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415156120875761222e565b82600102600160008760001916600019168152602001908152602001600020600201856040518082805190602001908083835b602083106120dd57805182526020820191506020810190506020830392506120ba565b6001836020036101000a03801982511681845116808217855250505050505090500191505090815260200160405180910390208160001916905550836040518082805190602001908083835b6020831061214c5780518252602082019150602081019050602083039250612129565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051809103902085600019167fb829c3e412537bbe794c048ccb9e4605bb4aaaa8e4d4c15c1a6e0c2adc1716ea8660405180806020018281038252838181518152602001915080519060200190808383600083146121ef575b8051825260208311156121ef576020820191506020810190506020830392506121cb565b505050905090810190601f16801561221b5780820380516001836020036101000a031916815260200191505b509250505060405180910390a3600191505b5b509392505050565b6000600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156122945761241f565b82600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061231d57805160ff191683800117855561234b565b8280016001018555821561234b579182015b8281111561234a57825182559160200191906001019061232f565b5b50905061237091905b8082111561236c576000816000905550600101612354565b5090565b50508173ffffffffffffffffffffffffffffffffffffffff16836040518082805190602001908083835b602083106123bd578051825260208201915060208101905060208303925061239a565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390207f098ae8581bb8bd9af1beaf7f2e9f51f31a8e5a8bfada4e303a645d71d9c9192060405180905060405180910390a3600190505b5b92915050565b3373ffffffffffffffffffffffffffffffffffffffff16600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060405180828054600181600116156101000203166002900480156124d65780601f106124b45761010080835404028352918201916124d6565b820191906000526020600020905b8154815290600101906020018083116124c2575b505091505060405180910390207f12491ad95fd945e444d88a894ffad3c21959880a4dcd8af99d4ae4ffc71d4abd60405180905060405180910390a360016000600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060405180828054600181600116156101000203166002900480156125b05780601f1061258e5761010080835404028352918201916125b0565b820191906000526020600020905b81548152906001019060200180831161259c575b505091505060405180910390206000191660001916815260200190815260200160002060010160006101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805460018160011615610100020316600290046000825580601f1061265d5750612694565b601f01602090049060005260206000209081019061269391905b8082111561268f576000816000905550600101612677565b5090565b5b505b565b6000833373ffffffffffffffffffffffffffffffffffffffff1660016000836000191660001916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141515612713576128d0565b8273ffffffffffffffffffffffffffffffffffffffff16600102600160008760001916600019168152602001908152602001600020600201856040518082805190602001908083835b6020831061277f578051825260208201915060208101905060208303925061275c565b6001836020036101000a03801982511681845116808217855250505050505090500191505090815260200160405180910390208160001916905550836040518082805190602001908083835b602083106127ee57805182526020820191506020810190506020830392506127cb565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051809103902085600019167fb829c3e412537bbe794c048ccb9e4605bb4aaaa8e4d4c15c1a6e0c2adc1716ea866040518080602001828103825283818151815260200191508051906020019080838360008314612891575b8051825260208311156128915760208201915060208101905060208303925061286d565b505050905090810190601f1680156128bd5780820380516001836020036101000a031916815260200191505b509250505060405180910390a3600191505b5b5093925050505600a165627a7a7230582066b2da4773a0f1d81efe071c66b51c46868a871661efd18c0f629353ff4c1f9b0029" }, "00a329c0648769a73afac7f9381e08fb43dbea72": { "balance": "1606938044258990275541962092341162602522202993782792835301376" } } diff --git a/ethcore/res/null.json b/ethcore/res/null.json index 7fa41a8def..5128f26c59 100644 --- a/ethcore/res/null.json +++ b/ethcore/res/null.json @@ -36,9 +36,50 @@ "0000000000000000000000000000000000000003": { "balance": "1", "nonce": "0", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } }, "0000000000000000000000000000000000000004": { "balance": "1", "nonce": "0", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } }, "0000000000000000000000000000000000000005": { "balance": "1", "builtin": { "name": "modexp", "activate_at": 0, "pricing": { "modexp": { "divisor": 20 } } } }, - "0000000000000000000000000000000000000006": { "balance": "1", "builtin": { "name": "alt_bn128_add", "activate_at": 0, "pricing": { "linear": { "base": 500, "word": 0 } } } }, - "0000000000000000000000000000000000000007": { "balance": "1", "builtin": { "name": "alt_bn128_mul", "activate_at": 0, "pricing": { "linear": { "base": 40000, "word": 0 } } } }, - "0000000000000000000000000000000000000008": { "balance": "1", "builtin": { "name": "alt_bn128_pairing", "activate_at": 0, "pricing": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 } } } }, + "0000000000000000000000000000000000000006": { + "balance": "1", + "builtin": { + "name": "alt_bn128_add", + "activate_at": 0, + "eip1108_transition": "0x7fffffffffffff", + "pricing": { + "alt_bn128_const_operations": { + "price": 500, + "eip1108_transition_price": 150 + } + } + } + }, + "0000000000000000000000000000000000000007": { + "balance": "1", + "builtin": { + "name": "alt_bn128_mul", + "activate_at": 0, + "eip1108_transition": "0x7fffffffffffff", + "pricing": { + "alt_bn128_const_operations": { + "price": 40000, + "eip1108_transition_price": 6000 + } + } + } + }, + "0000000000000000000000000000000000000008": { + "balance": "1", + "builtin": { + "name": "alt_bn128_pairing", + "activate_at": 0, + "eip1108_transition": "0x7fffffffffffff", + "pricing": { + "alt_bn128_pairing": { + "base": 100000, + "pair": 80000, + "eip1108_transition_base": 45000, + "eip1108_transition_pair": 34000 + } + } + } + }, "9cce34f7ab185c7aba1b7c8140d620b4bda941d6": { "balance": "1606938044258990275541962092341162602522202993782792835301376", "nonce": "0" } } } diff --git a/ethcore/src/builtin.rs b/ethcore/src/builtin.rs index 499e3c8f6c..407ae4865d 100644 --- a/ethcore/src/builtin.rs +++ b/ethcore/src/builtin.rs @@ -16,21 +16,26 @@ //! Standard built-in contracts. -use std::cmp::{max, min}; -use std::io::{self, Read}; - -use byteorder::{ByteOrder, BigEndian}; -use parity_crypto::digest; -use num::{BigUint, Zero, One}; - -use hash::keccak; +use std::{ + cmp::{max, min}, + io::{self, Read, Cursor}, + mem::size_of, +}; + +use bn; +use byteorder::{BigEndian, LittleEndian, ByteOrder, ReadBytesExt}; use ethereum_types::{H256, U256}; -use bytes::BytesRef; -use ethkey::{Signature, recover as ec_recover}; use ethjson; +use ethkey::{Signature, recover as ec_recover}; +use hash::keccak; +use log::{warn, trace}; +use num::{BigUint, Zero, One}; +use bytes::BytesRef; +use parity_crypto::digest; +use eip_152::compress; /// Execution error. -#[derive(Debug)] +#[derive(Debug, PartialEq)] pub struct Error(pub &'static str); impl From<&'static str> for Error { @@ -52,9 +57,27 @@ pub trait Impl: Send + Sync { } /// A gas pricing scheme for built-in contracts. -pub trait Pricer: Send + Sync { - /// The gas cost of running this built-in for the given input data. - fn cost(&self, input: &[u8]) -> U256; +// TODO: refactor this trait, see https://github.com/paritytech/parity-ethereum/issues/11014 +trait Pricer: Send + Sync { + /// The gas cost of running this built-in for the given input data at block number `at` + fn cost(&self, input: &[u8], at: u64) -> U256; +} + +/// Pricing for the Blake2 compression function (aka "F"). +/// Computes the price as a fixed cost per round where the number of rounds is part of the input +/// byte slice. +pub type Blake2FPricer = u64; + +impl Pricer for Blake2FPricer { + fn cost(&self, input: &[u8], _at: u64) -> U256 { + use std::convert::TryInto; + let (rounds_bytes, _) = input.split_at(std::mem::size_of::()); + // Returning zero if the conversion fails is fine because `execute()` will check the length + // and bail with the appropriate error. + let rounds = u32::from_be_bytes(rounds_bytes.try_into().unwrap_or([0u8; 4])); +// U256::from(*self as u128 * rounds as u128) + U256::from(*self as u64 * rounds as u64) + } } /// A linear pricing model. This computes a price using a base cost and a cost per-word. @@ -69,26 +92,56 @@ struct ModexpPricer { } impl Pricer for Linear { - fn cost(&self, input: &[u8]) -> U256 { + fn cost(&self, input: &[u8], _at: u64) -> U256 { U256::from(self.base) + U256::from(self.word) * U256::from((input.len() + 31) / 32) } } -/// A alt_bn128_parinig pricing model. This computes a price using a base cost and a cost per pair. -struct AltBn128PairingPricer { +/// alt_bn128 constant operations (add and mul) pricing model. +struct AltBn128ConstOperations { + price: usize, + eip1108_transition_at: u64, + eip1108_transition_price: usize, +} + +impl Pricer for AltBn128ConstOperations { + fn cost(&self, _input: &[u8], at: u64) -> U256 { + if at >= self.eip1108_transition_at { + self.eip1108_transition_price.into() + } else { + self.price.into() + } + } +} + +/// alt_bn128 pairing price +#[derive(Debug, Copy, Clone)] +struct AltBn128PairingPrice { base: usize, pair: usize, } +/// alt_bn128_pairing pricing model. This computes a price using a base cost and a cost per pair. +struct AltBn128PairingPricer { + price: AltBn128PairingPrice, + eip1108_transition_at: u64, + eip1108_transition_price: AltBn128PairingPrice, +} + impl Pricer for AltBn128PairingPricer { - fn cost(&self, input: &[u8]) -> U256 { - let cost = U256::from(self.base) + U256::from(self.pair) * U256::from(input.len() / 192); - cost + fn cost(&self, input: &[u8], at: u64) -> U256 { + let price = if at >= self.eip1108_transition_at { + self.eip1108_transition_price + } else { + self.price + }; + + U256::from(price.base) + U256::from(price.pair) * U256::from(input.len() / 192) } } impl Pricer for ModexpPricer { - fn cost(&self, input: &[u8]) -> U256 { + fn cost(&self, input: &[u8], _at: u64) -> U256 { let mut reader = input.chain(io::repeat(0)); let mut buf = [0; 32]; @@ -157,14 +210,16 @@ impl ModexpPricer { /// /// Unless `is_active` is true, pub struct Builtin { - pricer: Box, - native: Box, + pricer: Box, + native: Box, activate_at: u64, } impl Builtin { /// Simple forwarder for cost. - pub fn cost(&self, input: &[u8]) -> U256 { self.pricer.cost(input) } + pub fn cost(&self, input: &[u8], at: u64) -> U256 { + self.pricer.cost(input, at) + } /// Simple forwarder for execute. pub fn execute(&self, input: &[u8], output: &mut BytesRef) -> Result<(), Error> { @@ -172,12 +227,17 @@ impl Builtin { } /// Whether the builtin is activated at the given block number. - pub fn is_active(&self, at: u64) -> bool { at >= self.activate_at } + pub fn is_active(&self, at: u64) -> bool { + at >= self.activate_at + } } impl From for Builtin { fn from(b: ethjson::spec::Builtin) -> Self { - let pricer: Box = match b.pricing { + let pricer: Box = match b.pricing { + ethjson::spec::Pricing::Blake2F(cost_per_round) => { + Box::new(cost_per_round) + }, ethjson::spec::Pricing::Linear(linear) => { Box::new(Linear { base: linear.base, @@ -187,7 +247,7 @@ impl From for Builtin { ethjson::spec::Pricing::Modexp(exp) => { Box::new(ModexpPricer { divisor: if exp.divisor == 0 { - warn!("Zero modexp divisor specified. Falling back to default."); + warn!(target: "builtin", "Zero modexp divisor specified. Falling back to default."); 10 } else { exp.divisor @@ -196,31 +256,46 @@ impl From for Builtin { } ethjson::spec::Pricing::AltBn128Pairing(pricer) => { Box::new(AltBn128PairingPricer { - base: pricer.base, - pair: pricer.pair, + price: AltBn128PairingPrice { + base: pricer.base, + pair: pricer.pair, + }, + eip1108_transition_at: b.eip1108_transition.map_or(u64::max_value(), Into::into), + eip1108_transition_price: AltBn128PairingPrice { + base: pricer.eip1108_transition_base, + pair: pricer.eip1108_transition_pair, + }, + }) + } + ethjson::spec::Pricing::AltBn128ConstOperations(pricer) => { + Box::new(AltBn128ConstOperations { + price: pricer.price, + eip1108_transition_price: pricer.eip1108_transition_price, + eip1108_transition_at: b.eip1108_transition.map_or(u64::max_value(), Into::into) }) } }; Builtin { - pricer: pricer, + pricer, native: ethereum_builtin(&b.name), - activate_at: b.activate_at.map(Into::into).unwrap_or(0), + activate_at: b.activate_at.map_or(0, Into::into), } } } /// Ethereum built-in factory. -pub fn ethereum_builtin(name: &str) -> Box { +pub fn ethereum_builtin(name: &str) -> Box { match name { - "identity" => Box::new(Identity) as Box, - "ecrecover" => Box::new(EcRecover) as Box, - "sha256" => Box::new(Sha256) as Box, - "ripemd160" => Box::new(Ripemd160) as Box, - "modexp" => Box::new(ModexpImpl) as Box, - "alt_bn128_add" => Box::new(Bn128AddImpl) as Box, - "alt_bn128_mul" => Box::new(Bn128MulImpl) as Box, - "alt_bn128_pairing" => Box::new(Bn128PairingImpl) as Box, + "identity" => Box::new(Identity) as Box, + "ecrecover" => Box::new(EcRecover) as Box, + "sha256" => Box::new(Sha256) as Box, + "ripemd160" => Box::new(Ripemd160) as Box, + "modexp" => Box::new(ModexpImpl) as Box, + "alt_bn128_add" => Box::new(Bn128AddImpl) as Box, + "alt_bn128_mul" => Box::new(Bn128MulImpl) as Box, + "alt_bn128_pairing" => Box::new(Bn128PairingImpl) as Box, + "blake2_f" => Box::new(Blake2F) as Box, _ => panic!("invalid builtin name: {}", name), } } @@ -232,6 +307,10 @@ pub fn ethereum_builtin(name: &str) -> Box { // - sha256 // - ripemd160 // - modexp (EIP198) +// - alt_bn128_add +// - alt_bn128_mul +// - alt_bn128_pairing +// - blake2_f (The Blake2 compression function F, EIP-152) #[derive(Debug)] struct Identity; @@ -257,8 +336,11 @@ struct Bn128MulImpl; #[derive(Debug)] struct Bn128PairingImpl; +#[derive(Debug)] +struct Blake2F; + impl Impl for Identity { - fn execute(&self, input: &[u8], output: &mut BytesRef) -> Result<(), Error> { +fn execute(&self, input: &[u8], output: &mut BytesRef) -> Result<(), Error> { output.write(0, input); Ok(()) } @@ -302,6 +384,60 @@ impl Impl for Sha256 { } } +impl Impl for Blake2F { + /// Format of `input`: + /// [4 bytes for rounds][64 bytes for h][128 bytes for m][8 bytes for t_0][8 bytes for t_1][1 byte for f] + fn execute(&self, input: &[u8], output: &mut BytesRef) -> Result<(), Error> { + const BLAKE2_F_ARG_LEN: usize = 213; + const PROOF: &str = "Checked the length of the input above; qed"; + + if input.len() != BLAKE2_F_ARG_LEN { + trace!(target: "builtin", "input length for Blake2 F precompile should be exactly 213 bytes, was {}", input.len()); + return Err("input length for Blake2 F precompile should be exactly 213 bytes".into()) + } + + let mut cursor = Cursor::new(input); + let rounds = cursor.read_u32::().expect(PROOF); + + // state vector, h + let mut h = [0u64; 8]; + for state_word in h.iter_mut() { + *state_word = cursor.read_u64::().expect(PROOF); + } + + // message block vector, m + let mut m = [0u64; 16]; + for msg_word in m.iter_mut() { + *msg_word = cursor.read_u64::().expect(PROOF); + } + + // 2w-bit offset counter, t + let t = [ + cursor.read_u64::().expect(PROOF), + cursor.read_u64::().expect(PROOF), + ]; + + // final block indicator flag, "f" + let f = match input.last() { + Some(1) => true, + Some(0) => false, + _ => { + trace!(target: "builtin", "incorrect final block indicator flag, was: {:?}", input.last()); + return Err("incorrect final block indicator flag".into()) + } + }; + + compress(&mut h, m, t, f, rounds as usize); + + let mut output_buf = [0u8; 8 * size_of::()]; + for (i, state_word) in h.iter().enumerate() { + output_buf[i*8..(i+1)*8].copy_from_slice(&state_word.to_le_bytes()); + } + output.write(0, &output_buf[..]); + Ok(()) + } +} + impl Impl for Ripemd160 { fn execute(&self, input: &[u8], output: &mut BytesRef) -> Result<(), Error> { let hash = digest::ripemd160(input); @@ -450,7 +586,7 @@ impl Impl for Bn128AddImpl { if let Some(sum) = AffineG1::from_jacobian(p1 + p2) { // point not at infinity sum.x().to_big_endian(&mut write_buf[0..32]).expect("Cannot fail since 0..32 is 32-byte length"); - sum.y().to_big_endian(&mut write_buf[32..64]).expect("Cannot fail since 32..64 is 32-byte length");; + sum.y().to_big_endian(&mut write_buf[32..64]).expect("Cannot fail since 32..64 is 32-byte length"); } output.write(0, &write_buf); @@ -471,7 +607,7 @@ impl Impl for Bn128MulImpl { if let Some(sum) = AffineG1::from_jacobian(p * fr) { // point not at infinity sum.x().to_big_endian(&mut write_buf[0..32]).expect("Cannot fail since 0..32 is 32-byte length"); - sum.y().to_big_endian(&mut write_buf[32..64]).expect("Cannot fail since 32..64 is 32-byte length");; + sum.y().to_big_endian(&mut write_buf[32..64]).expect("Cannot fail since 32..64 is 32-byte length"); } output.write(0, &write_buf); Ok(()) @@ -489,7 +625,7 @@ impl Impl for Bn128PairingImpl { } if let Err(err) = self.execute_with_error(input, output) { - trace!("Pairining error: {:?}", err); + trace!(target: "builtin", "Pairing error: {:?}", err); return Err(err) } Ok(()) @@ -558,12 +694,120 @@ impl Bn128PairingImpl { #[cfg(test)] mod tests { - use super::{Builtin, Linear, ethereum_builtin, Pricer, ModexpPricer, modexp as me}; - use ethjson; use ethereum_types::U256; - use bytes::BytesRef; - use rustc_hex::FromHex; + use ethjson::uint::Uint; use num::{BigUint, Zero, One}; + use bytes::BytesRef; +use hex_literal::hex; + use super::{Builtin, Linear, ethereum_builtin, Pricer, ModexpPricer, modexp as me}; + + #[test] + fn blake2f_cost() { + let f = Builtin { + pricer: Box::new(123), + native: ethereum_builtin("blake2_f"), + activate_at: 0, + }; + // 5 rounds + let input = hex!("0000000548c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001"); + let mut output = [0u8; 64]; + f.execute(&input[..], &mut BytesRef::Fixed(&mut output[..])).unwrap(); + + assert_eq!(f.cost(&input[..], 0), U256::from(123*5)); + } + + #[test] + fn blake2_f_is_err_on_invalid_length() { + let blake2 = ethereum_builtin("blake2_f"); + // Test vector 1 and expected output from https://github.com/ethereum/EIPs/blob/master/EIPS/eip-152.md#test-vector-1 + let input = hex!("00000c48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001"); + let mut out = [0u8; 64]; + + let result = blake2.execute(&input[..], &mut BytesRef::Fixed(&mut out[..])); + assert!(result.is_err()); + assert_eq!(result.unwrap_err(), "input length for Blake2 F precompile should be exactly 213 bytes".into()); + } + + #[test] + fn blake2_f_is_err_on_invalid_length_2() { + let blake2 = ethereum_builtin("blake2_f"); + // Test vector 2 and expected output from https://github.com/ethereum/EIPs/blob/master/EIPS/eip-152.md#test-vector-2 + let input = hex!("000000000c48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001"); + let mut out = [0u8; 64]; + + let result = blake2.execute(&input[..], &mut BytesRef::Fixed(&mut out[..])); + assert!(result.is_err()); + assert_eq!(result.unwrap_err(), "input length for Blake2 F precompile should be exactly 213 bytes".into()); + } + + #[test] + fn blake2_f_is_err_on_bad_finalization_flag() { + let blake2 = ethereum_builtin("blake2_f"); + // Test vector 3 and expected output from https://github.com/ethereum/EIPs/blob/master/EIPS/eip-152.md#test-vector-3 + let input = hex!("0000000c48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000002"); + let mut out = [0u8; 64]; + + let result = blake2.execute(&input[..], &mut BytesRef::Fixed(&mut out[..])); + assert!(result.is_err()); + assert_eq!(result.unwrap_err(), "incorrect final block indicator flag".into()); + } + + #[test] + fn blake2_f_zero_rounds_is_ok_test_vector_4() { + let blake2 = ethereum_builtin("blake2_f"); + // Test vector 4 and expected output from https://github.com/ethereum/EIPs/blob/master/EIPS/eip-152.md#test-vector-4 + let input = hex!("0000000048c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001"); + let expected = hex!("08c9bcf367e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d282e6ad7f520e511f6c3e2b8c68059b9442be0454267ce079217e1319cde05b"); + let mut output = [0u8; 64]; + blake2.execute(&input[..], &mut BytesRef::Fixed(&mut output[..])).unwrap(); + assert_eq!(&output[..], &expected[..]); + } + + #[test] + fn blake2_f_test_vector_5() { + let blake2 = ethereum_builtin("blake2_f"); + // Test vector 5 and expected output from https://github.com/ethereum/EIPs/blob/master/EIPS/eip-152.md#test-vector-5 + let input = hex!("0000000c48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001"); + let expected = hex!("ba80a53f981c4d0d6a2797b69f12f6e94c212f14685ac4b74b12bb6fdbffa2d17d87c5392aab792dc252d5de4533cc9518d38aa8dbf1925ab92386edd4009923"); + let mut out = [0u8; 64]; + blake2.execute(&input[..], &mut BytesRef::Fixed(&mut out[..])).unwrap(); + assert_eq!(&out[..], &expected[..]); + } + + #[test] + fn blake2_f_test_vector_6() { + let blake2 = ethereum_builtin("blake2_f"); + // Test vector 6 and expected output from https://github.com/ethereum/EIPs/blob/master/EIPS/eip-152.md#test-vector-6 + let input = hex!("0000000c48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000"); + let expected = hex!("75ab69d3190a562c51aef8d88f1c2775876944407270c42c9844252c26d2875298743e7f6d5ea2f2d3e8d226039cd31b4e426ac4f2d3d666a610c2116fde4735"); + let mut out = [0u8; 64]; + blake2.execute(&input[..], &mut BytesRef::Fixed(&mut out[..])).unwrap(); + assert_eq!(&out[..], &expected[..]); + } + + #[test] + fn blake2_f_test_vector_7() { + let blake2 = ethereum_builtin("blake2_f"); + // Test vector 7 and expected output from https://github.com/ethereum/EIPs/blob/master/EIPS/eip-152.md#test-vector-7 + let input = hex!("0000000148c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001"); + let expected = hex!("b63a380cb2897d521994a85234ee2c181b5f844d2c624c002677e9703449d2fba551b3a8333bcdf5f2f7e08993d53923de3d64fcc68c034e717b9293fed7a421"); + let mut out = [0u8; 64]; + blake2.execute(&input[..], &mut BytesRef::Fixed(&mut out[..])).unwrap(); + assert_eq!(&out[..], &expected[..]); + } + + #[ignore] + #[test] + fn blake2_f_test_vector_8() { + let blake2 = ethereum_builtin("blake2_f"); + // Test vector 8 and expected output from https://github.com/ethereum/EIPs/blob/master/EIPS/eip-152.md#test-vector-8 + // Note this test is slow, 4294967295/0xffffffff rounds take a while. + let input = hex!("ffffffff48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001"); + let expected = hex!("fc59093aafa9ab43daae0e914c57635c5402d8e3d2130eb9b3cc181de7f0ecf9b22bf99a7815ce16419e200e01846e6b5df8cc7703041bbceb571de6631d2615"); + let mut out = [0u8; 64]; + blake2.execute(&input[..], &mut BytesRef::Fixed(&mut out[..])).unwrap(); + assert_eq!(&out[..], &expected[..]); + } #[test] fn modexp_func() { @@ -626,19 +870,19 @@ mod tests { let mut o = [255u8; 32]; f.execute(&i[..], &mut BytesRef::Fixed(&mut o[..])).expect("Builtin should not fail"); - assert_eq!(&o[..], &(FromHex::from_hex("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855").unwrap())[..]); + assert_eq!(&o[..], hex!("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855")); let mut o8 = [255u8; 8]; f.execute(&i[..], &mut BytesRef::Fixed(&mut o8[..])).expect("Builtin should not fail"); - assert_eq!(&o8[..], &(FromHex::from_hex("e3b0c44298fc1c14").unwrap())[..]); + assert_eq!(&o8[..], hex!("e3b0c44298fc1c14")); let mut o34 = [255u8; 34]; f.execute(&i[..], &mut BytesRef::Fixed(&mut o34[..])).expect("Builtin should not fail"); - assert_eq!(&o34[..], &(FromHex::from_hex("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855ffff").unwrap())[..]); + assert_eq!(&o34[..], &hex!("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855ffff")[..]); let mut ov = vec![]; f.execute(&i[..], &mut BytesRef::Flexible(&mut ov)).expect("Builtin should not fail"); - assert_eq!(&ov[..], &(FromHex::from_hex("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855").unwrap())[..]); + assert_eq!(&ov[..], &hex!("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855")[..]); } #[test] @@ -649,59 +893,59 @@ mod tests { let mut o = [255u8; 32]; f.execute(&i[..], &mut BytesRef::Fixed(&mut o[..])).expect("Builtin should not fail"); - assert_eq!(&o[..], &(FromHex::from_hex("0000000000000000000000009c1185a5c5e9fc54612808977ee8f548b2258d31").unwrap())[..]); + assert_eq!(&o[..], &hex!("0000000000000000000000009c1185a5c5e9fc54612808977ee8f548b2258d31")[..]); let mut o8 = [255u8; 8]; f.execute(&i[..], &mut BytesRef::Fixed(&mut o8[..])).expect("Builtin should not fail"); - assert_eq!(&o8[..], &(FromHex::from_hex("0000000000000000").unwrap())[..]); + assert_eq!(&o8[..], &hex!("0000000000000000")[..]); let mut o34 = [255u8; 34]; f.execute(&i[..], &mut BytesRef::Fixed(&mut o34[..])).expect("Builtin should not fail"); - assert_eq!(&o34[..], &(FromHex::from_hex("0000000000000000000000009c1185a5c5e9fc54612808977ee8f548b2258d31ffff").unwrap())[..]); + assert_eq!(&o34[..], &hex!("0000000000000000000000009c1185a5c5e9fc54612808977ee8f548b2258d31ffff")[..]); } #[test] fn ecrecover() { let f = ethereum_builtin("ecrecover"); - let i = FromHex::from_hex("47173285a8d7341e5e972fc677286384f802f8ef42a5ec5f03bbfa254cb01fad000000000000000000000000000000000000000000000000000000000000001b650acf9d3f5f0a2c799776a1254355d5f4061762a237396a99a0e0e3fc2bcd6729514a0dacb2e623ac4abd157cb18163ff942280db4d5caad66ddf941ba12e03").unwrap(); + let i = hex!("47173285a8d7341e5e972fc677286384f802f8ef42a5ec5f03bbfa254cb01fad000000000000000000000000000000000000000000000000000000000000001b650acf9d3f5f0a2c799776a1254355d5f4061762a237396a99a0e0e3fc2bcd6729514a0dacb2e623ac4abd157cb18163ff942280db4d5caad66ddf941ba12e03"); let mut o = [255u8; 32]; f.execute(&i[..], &mut BytesRef::Fixed(&mut o[..])).expect("Builtin should not fail"); - assert_eq!(&o[..], &(FromHex::from_hex("000000000000000000000000c08b5542d177ac6686946920409741463a15dddb").unwrap())[..]); + assert_eq!(&o[..], &hex!("000000000000000000000000c08b5542d177ac6686946920409741463a15dddb")[..]); let mut o8 = [255u8; 8]; f.execute(&i[..], &mut BytesRef::Fixed(&mut o8[..])).expect("Builtin should not fail"); - assert_eq!(&o8[..], &(FromHex::from_hex("0000000000000000").unwrap())[..]); + assert_eq!(&o8[..], &hex!("0000000000000000")[..]); let mut o34 = [255u8; 34]; f.execute(&i[..], &mut BytesRef::Fixed(&mut o34[..])).expect("Builtin should not fail"); - assert_eq!(&o34[..], &(FromHex::from_hex("000000000000000000000000c08b5542d177ac6686946920409741463a15dddbffff").unwrap())[..]); + assert_eq!(&o34[..], &hex!("000000000000000000000000c08b5542d177ac6686946920409741463a15dddbffff")[..]); - let i_bad = FromHex::from_hex("47173285a8d7341e5e972fc677286384f802f8ef42a5ec5f03bbfa254cb01fad000000000000000000000000000000000000000000000000000000000000001a650acf9d3f5f0a2c799776a1254355d5f4061762a237396a99a0e0e3fc2bcd6729514a0dacb2e623ac4abd157cb18163ff942280db4d5caad66ddf941ba12e03").unwrap(); + let i_bad = hex!("47173285a8d7341e5e972fc677286384f802f8ef42a5ec5f03bbfa254cb01fad000000000000000000000000000000000000000000000000000000000000001a650acf9d3f5f0a2c799776a1254355d5f4061762a237396a99a0e0e3fc2bcd6729514a0dacb2e623ac4abd157cb18163ff942280db4d5caad66ddf941ba12e03"); let mut o = [255u8; 32]; f.execute(&i_bad[..], &mut BytesRef::Fixed(&mut o[..])).expect("Builtin should not fail"); - assert_eq!(&o[..], &(FromHex::from_hex("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap())[..]); + assert_eq!(&o[..], &hex!("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")[..]); - let i_bad = FromHex::from_hex("47173285a8d7341e5e972fc677286384f802f8ef42a5ec5f03bbfa254cb01fad000000000000000000000000000000000000000000000000000000000000001b000000000000000000000000000000000000000000000000000000000000001b0000000000000000000000000000000000000000000000000000000000000000").unwrap(); + let i_bad = hex!("47173285a8d7341e5e972fc677286384f802f8ef42a5ec5f03bbfa254cb01fad000000000000000000000000000000000000000000000000000000000000001b000000000000000000000000000000000000000000000000000000000000001b0000000000000000000000000000000000000000000000000000000000000000"); let mut o = [255u8; 32]; f.execute(&i_bad[..], &mut BytesRef::Fixed(&mut o[..])).expect("Builtin should not fail"); - assert_eq!(&o[..], &(FromHex::from_hex("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap())[..]); + assert_eq!(&o[..], &hex!("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")[..]); - let i_bad = FromHex::from_hex("47173285a8d7341e5e972fc677286384f802f8ef42a5ec5f03bbfa254cb01fad000000000000000000000000000000000000000000000000000000000000001b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001b").unwrap(); + let i_bad = hex!("47173285a8d7341e5e972fc677286384f802f8ef42a5ec5f03bbfa254cb01fad000000000000000000000000000000000000000000000000000000000000001b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001b"); let mut o = [255u8; 32]; f.execute(&i_bad[..], &mut BytesRef::Fixed(&mut o[..])).expect("Builtin should not fail"); - assert_eq!(&o[..], &(FromHex::from_hex("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap())[..]); + assert_eq!(&o[..], &hex!("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")[..]); - let i_bad = FromHex::from_hex("47173285a8d7341e5e972fc677286384f802f8ef42a5ec5f03bbfa254cb01fad000000000000000000000000000000000000000000000000000000000000001bffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000000000000000000000000000000000001b").unwrap(); + let i_bad = hex!("47173285a8d7341e5e972fc677286384f802f8ef42a5ec5f03bbfa254cb01fad000000000000000000000000000000000000000000000000000000000000001bffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000000000000000000000000000000000001b"); let mut o = [255u8; 32]; f.execute(&i_bad[..], &mut BytesRef::Fixed(&mut o[..])).expect("Builtin should not fail"); - assert_eq!(&o[..], &(FromHex::from_hex("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap())[..]); + assert_eq!(&o[..], &hex!("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")[..]); - let i_bad = FromHex::from_hex("47173285a8d7341e5e972fc677286384f802f8ef42a5ec5f03bbfa254cb01fad000000000000000000000000000000000000000000000000000000000000001b000000000000000000000000000000000000000000000000000000000000001bffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap(); + let i_bad = hex!("47173285a8d7341e5e972fc677286384f802f8ef42a5ec5f03bbfa254cb01fad000000000000000000000000000000000000000000000000000000000000001b000000000000000000000000000000000000000000000000000000000000001bffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); let mut o = [255u8; 32]; f.execute(&i_bad[..], &mut BytesRef::Fixed(&mut o[..])).expect("Builtin should not fail"); - assert_eq!(&o[..], &(FromHex::from_hex("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap())[..]); + assert_eq!(&o[..], &hex!("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")[..]); // TODO: Should this (corrupted version of the above) fail rather than returning some address? /* let i_bad = FromHex::from_hex("48173285a8d7341e5e972fc677286384f802f8ef42a5ec5f03bbfa254cb01fad000000000000000000000000000000000000000000000000000000000000001b650acf9d3f5f0a2c799776a1254355d5f4061762a237396a99a0e0e3fc2bcd6729514a0dacb2e623ac4abd157cb18163ff942280db4d5caad66ddf941ba12e03").unwrap(); @@ -721,103 +965,103 @@ mod tests { // test for potential gas cost multiplication overflow { - let input = FromHex::from_hex("0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000003b27bafd00000000000000000000000000000000000000000000000000000000503c8ac3").unwrap(); + let input = hex!("0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000003b27bafd00000000000000000000000000000000000000000000000000000000503c8ac3"); let expected_cost = U256::max_value(); - assert_eq!(f.cost(&input[..]), expected_cost.into()); + assert_eq!(f.cost(&input[..], 0), expected_cost.into()); } // test for potential exp len overflow { - let input = FromHex::from_hex("\ - 00000000000000000000000000000000000000000000000000000000000000ff\ - 2a1e530000000000000000000000000000000000000000000000000000000000\ + let input = hex!(" + 00000000000000000000000000000000000000000000000000000000000000ff + 2a1e530000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000" - ).unwrap(); + ); let mut output = vec![0u8; 32]; - let expected = FromHex::from_hex("0000000000000000000000000000000000000000000000000000000000000000").unwrap(); + let expected = hex!("0000000000000000000000000000000000000000000000000000000000000000"); let expected_cost = U256::max_value(); f.execute(&input[..], &mut BytesRef::Fixed(&mut output[..])).expect("Builtin should fail"); assert_eq!(output, expected); - assert_eq!(f.cost(&input[..]), expected_cost.into()); + assert_eq!(f.cost(&input[..], 0), expected_cost.into()); } // fermat's little theorem example. { - let input = FromHex::from_hex("\ - 0000000000000000000000000000000000000000000000000000000000000001\ - 0000000000000000000000000000000000000000000000000000000000000020\ - 0000000000000000000000000000000000000000000000000000000000000020\ - 03\ - fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2e\ + let input = hex!(" + 0000000000000000000000000000000000000000000000000000000000000001 + 0000000000000000000000000000000000000000000000000000000000000020 + 0000000000000000000000000000000000000000000000000000000000000020 + 03 + fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2e fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f" - ).unwrap(); + ); let mut output = vec![0u8; 32]; - let expected = FromHex::from_hex("0000000000000000000000000000000000000000000000000000000000000001").unwrap(); + let expected = hex!("0000000000000000000000000000000000000000000000000000000000000001"); let expected_cost = 13056; f.execute(&input[..], &mut BytesRef::Fixed(&mut output[..])).expect("Builtin should not fail"); assert_eq!(output, expected); - assert_eq!(f.cost(&input[..]), expected_cost.into()); + assert_eq!(f.cost(&input[..], 0), expected_cost.into()); } // second example from EIP: zero base. { - let input = FromHex::from_hex("\ - 0000000000000000000000000000000000000000000000000000000000000000\ - 0000000000000000000000000000000000000000000000000000000000000020\ - 0000000000000000000000000000000000000000000000000000000000000020\ - fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2e\ + let input = hex!(" + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000020 + 0000000000000000000000000000000000000000000000000000000000000020 + fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2e fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f" - ).unwrap(); + ); let mut output = vec![0u8; 32]; - let expected = FromHex::from_hex("0000000000000000000000000000000000000000000000000000000000000000").unwrap(); + let expected = hex!("0000000000000000000000000000000000000000000000000000000000000000"); let expected_cost = 13056; f.execute(&input[..], &mut BytesRef::Fixed(&mut output[..])).expect("Builtin should not fail"); assert_eq!(output, expected); - assert_eq!(f.cost(&input[..]), expected_cost.into()); + assert_eq!(f.cost(&input[..], 0), expected_cost.into()); } // another example from EIP: zero-padding { - let input = FromHex::from_hex("\ - 0000000000000000000000000000000000000000000000000000000000000001\ - 0000000000000000000000000000000000000000000000000000000000000002\ - 0000000000000000000000000000000000000000000000000000000000000020\ - 03\ - ffff\ + let input = hex!(" + 0000000000000000000000000000000000000000000000000000000000000001 + 0000000000000000000000000000000000000000000000000000000000000002 + 0000000000000000000000000000000000000000000000000000000000000020 + 03 + ffff 80" - ).unwrap(); + ); let mut output = vec![0u8; 32]; - let expected = FromHex::from_hex("3b01b01ac41f2d6e917c6d6a221ce793802469026d9ab7578fa2e79e4da6aaab").unwrap(); + let expected = hex!("3b01b01ac41f2d6e917c6d6a221ce793802469026d9ab7578fa2e79e4da6aaab"); let expected_cost = 768; f.execute(&input[..], &mut BytesRef::Fixed(&mut output[..])).expect("Builtin should not fail"); assert_eq!(output, expected); - assert_eq!(f.cost(&input[..]), expected_cost.into()); + assert_eq!(f.cost(&input[..], 0), expected_cost.into()); } // zero-length modulus. { - let input = FromHex::from_hex("\ - 0000000000000000000000000000000000000000000000000000000000000001\ - 0000000000000000000000000000000000000000000000000000000000000002\ - 0000000000000000000000000000000000000000000000000000000000000000\ - 03\ + let input = hex!(" + 0000000000000000000000000000000000000000000000000000000000000001 + 0000000000000000000000000000000000000000000000000000000000000002 + 0000000000000000000000000000000000000000000000000000000000000000 + 03 ffff" - ).unwrap(); + ); let mut output = vec![]; let expected_cost = 0; f.execute(&input[..], &mut BytesRef::Flexible(&mut output)).expect("Builtin should not fail"); assert_eq!(output.len(), 0); // shouldn't have written any output. - assert_eq!(f.cost(&input[..]), expected_cost.into()); + assert_eq!(f.cost(&input[..], 0), expected_cost.into()); } } @@ -832,21 +1076,21 @@ mod tests { // zero-points additions { - let input = FromHex::from_hex("\ - 0000000000000000000000000000000000000000000000000000000000000000\ - 0000000000000000000000000000000000000000000000000000000000000000\ - 0000000000000000000000000000000000000000000000000000000000000000\ + let input = hex!(" + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000" - ).unwrap(); + ); let mut output = vec![0u8; 64]; - let expected = FromHex::from_hex("\ - 0000000000000000000000000000000000000000000000000000000000000000\ + let expected = hex!(" + 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000" - ).unwrap(); + ); f.execute(&input[..], &mut BytesRef::Fixed(&mut output[..])).expect("Builtin should not fail"); - assert_eq!(output, expected); + assert_eq!(output, &expected[..]); } // no input, should not fail @@ -855,23 +1099,23 @@ mod tests { let input = BytesRef::Fixed(&mut empty); let mut output = vec![0u8; 64]; - let expected = FromHex::from_hex("\ - 0000000000000000000000000000000000000000000000000000000000000000\ + let expected = hex!(" + 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000" - ).unwrap(); + ); f.execute(&input[..], &mut BytesRef::Fixed(&mut output[..])).expect("Builtin should not fail"); - assert_eq!(output, expected); + assert_eq!(output, &expected[..]); } // should fail - point not on curve { - let input = FromHex::from_hex("\ - 1111111111111111111111111111111111111111111111111111111111111111\ - 1111111111111111111111111111111111111111111111111111111111111111\ - 1111111111111111111111111111111111111111111111111111111111111111\ + let input = hex!(" + 1111111111111111111111111111111111111111111111111111111111111111 + 1111111111111111111111111111111111111111111111111111111111111111 + 1111111111111111111111111111111111111111111111111111111111111111 1111111111111111111111111111111111111111111111111111111111111111" - ).unwrap(); + ); let mut output = vec![0u8; 64]; @@ -891,29 +1135,29 @@ mod tests { // zero-point multiplication { - let input = FromHex::from_hex("\ - 0000000000000000000000000000000000000000000000000000000000000000\ - 0000000000000000000000000000000000000000000000000000000000000000\ + let input = hex!(" + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 0200000000000000000000000000000000000000000000000000000000000000" - ).unwrap(); + ); let mut output = vec![0u8; 64]; - let expected = FromHex::from_hex("\ - 0000000000000000000000000000000000000000000000000000000000000000\ + let expected = hex!(" + 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000" - ).unwrap(); + ); f.execute(&input[..], &mut BytesRef::Fixed(&mut output[..])).expect("Builtin should not fail"); - assert_eq!(output, expected); + assert_eq!(output, &expected[..]); } // should fail - point not on curve { - let input = FromHex::from_hex("\ - 1111111111111111111111111111111111111111111111111111111111111111\ - 1111111111111111111111111111111111111111111111111111111111111111\ + let input = hex!(" + 1111111111111111111111111111111111111111111111111111111111111111 + 1111111111111111111111111111111111111111111111111111111111111111 0f00000000000000000000000000000000000000000000000000000000000000" - ).unwrap(); + ); let mut output = vec![0u8; 64]; @@ -954,16 +1198,12 @@ mod tests { } } - fn bytes(s: &'static str) -> Vec { - FromHex::from_hex(s).expect("static str should contain valid hex bytes") - } - #[test] fn bn128_pairing_empty() { // should not fail, because empty input is a valid input of 0 elements empty_test( builtin_pairing(), - bytes("0000000000000000000000000000000000000000000000000000000000000001"), + hex!("0000000000000000000000000000000000000000000000000000000000000001").to_vec(), ); } @@ -972,12 +1212,12 @@ mod tests { // should fail - point not on curve error_test( builtin_pairing(), - &bytes("\ - 1111111111111111111111111111111111111111111111111111111111111111\ - 1111111111111111111111111111111111111111111111111111111111111111\ - 1111111111111111111111111111111111111111111111111111111111111111\ - 1111111111111111111111111111111111111111111111111111111111111111\ - 1111111111111111111111111111111111111111111111111111111111111111\ + &hex!(" + 1111111111111111111111111111111111111111111111111111111111111111 + 1111111111111111111111111111111111111111111111111111111111111111 + 1111111111111111111111111111111111111111111111111111111111111111 + 1111111111111111111111111111111111111111111111111111111111111111 + 1111111111111111111111111111111111111111111111111111111111111111 1111111111111111111111111111111111111111111111111111111111111111" ), Some("not on curve"), @@ -989,9 +1229,9 @@ mod tests { // should fail - input length is invalid error_test( builtin_pairing(), - &bytes("\ - 1111111111111111111111111111111111111111111111111111111111111111\ - 1111111111111111111111111111111111111111111111111111111111111111\ + &hex!(" + 1111111111111111111111111111111111111111111111111111111111111111 + 1111111111111111111111111111111111111111111111111111111111111111 111111111111111111111111111111" ), Some("Invalid input length"), @@ -1008,7 +1248,7 @@ mod tests { fn is_active() { let pricer = Box::new(Linear { base: 10, word: 20} ); let b = Builtin { - pricer: pricer as Box, + pricer: pricer as Box, native: ethereum_builtin("identity"), activate_at: 100_000, }; @@ -1022,15 +1262,15 @@ mod tests { fn from_named_linear() { let pricer = Box::new(Linear { base: 10, word: 20 }); let b = Builtin { - pricer: pricer as Box, + pricer: pricer as Box, native: ethereum_builtin("identity"), activate_at: 1, }; - assert_eq!(b.cost(&[0; 0]), U256::from(10)); - assert_eq!(b.cost(&[0; 1]), U256::from(30)); - assert_eq!(b.cost(&[0; 32]), U256::from(30)); - assert_eq!(b.cost(&[0; 33]), U256::from(50)); + assert_eq!(b.cost(&[0; 0], 0), U256::from(10)); + assert_eq!(b.cost(&[0; 1], 0), U256::from(30)); + assert_eq!(b.cost(&[0; 32], 0), U256::from(30)); + assert_eq!(b.cost(&[0; 33], 0), U256::from(50)); let i = [0u8, 1, 2, 3]; let mut o = [255u8; 4]; @@ -1047,16 +1287,67 @@ mod tests { word: 20, }), activate_at: None, + eip1108_transition: None, }); - assert_eq!(b.cost(&[0; 0]), U256::from(10)); - assert_eq!(b.cost(&[0; 1]), U256::from(30)); - assert_eq!(b.cost(&[0; 32]), U256::from(30)); - assert_eq!(b.cost(&[0; 33]), U256::from(50)); + assert_eq!(b.cost(&[0; 0], 0), U256::from(10)); + assert_eq!(b.cost(&[0; 1], 0), U256::from(30)); + assert_eq!(b.cost(&[0; 32], 0), U256::from(30)); + assert_eq!(b.cost(&[0; 33], 0), U256::from(50)); let i = [0u8, 1, 2, 3]; let mut o = [255u8; 4]; b.execute(&i[..], &mut BytesRef::Fixed(&mut o[..])).expect("Builtin should not fail"); assert_eq!(i, o); } + + #[test] + fn bn128_pairing_eip1108_transition() { + let b = Builtin::from(ethjson::spec::Builtin { + name: "alt_bn128_pairing".to_owned(), + pricing: ethjson::spec::Pricing::AltBn128Pairing(ethjson::spec::builtin::AltBn128Pairing { + base: 100_000, + pair: 80_000, + eip1108_transition_base: 45_000, + eip1108_transition_pair: 34_000, + }), + activate_at: Some(Uint(U256::from(10))), + eip1108_transition: Some(Uint(U256::from(20))), + }); + + assert_eq!(b.cost(&[0; 192 * 3], 10), U256::from(340_000), "80 000 * 3 + 100 000 == 340 000"); + assert_eq!(b.cost(&[0; 192 * 7], 20), U256::from(283_000), "34 000 * 7 + 45 000 == 283 000"); + } + + #[test] + fn bn128_add_eip1108_transition() { + let b = Builtin::from(ethjson::spec::Builtin { + name: "alt_bn128_add".to_owned(), + pricing: ethjson::spec::Pricing::AltBn128ConstOperations(ethjson::spec::builtin::AltBn128ConstOperations { + price: 500, + eip1108_transition_price: 150, + }), + activate_at: Some(Uint(U256::from(10))), + eip1108_transition: Some(Uint(U256::from(20))), + }); + + assert_eq!(b.cost(&[0; 192], 10), U256::from(500)); + assert_eq!(b.cost(&[0; 10], 20), U256::from(150), "after istanbul hardfork gas cost for add should be 150"); + } + + #[test] + fn bn128_mul_eip1108_transition() { + let b = Builtin::from(ethjson::spec::Builtin { + name: "alt_bn128_mul".to_owned(), + pricing: ethjson::spec::Pricing::AltBn128ConstOperations(ethjson::spec::builtin::AltBn128ConstOperations { + price: 40_000, + eip1108_transition_price: 6000, + }), + activate_at: Some(Uint(U256::from(10))), + eip1108_transition: Some(Uint(U256::from(20))), + }); + + assert_eq!(b.cost(&[0; 192], 10), U256::from(40_000)); + assert_eq!(b.cost(&[0; 10], 20), U256::from(6_000), "after istanbul hardfork gas cost for mul should be 6 000"); + } } diff --git a/ethcore/src/client/mod.rs b/ethcore/src/client/mod.rs index 51b4f53db8..d710a6b4dd 100644 --- a/ethcore/src/client/mod.rs +++ b/ethcore/src/client/mod.rs @@ -54,7 +54,7 @@ pub use vm::{LastHashes, EnvInfo}; pub use error::TransactionImportError; pub use verification::VerifierType; -mod traits; +pub mod traits; mod chain_notify; mod private_notify; diff --git a/ethcore/src/engines/instant_seal.rs b/ethcore/src/engines/instant_seal.rs index a578c990b3..ec6f42bc7d 100644 --- a/ethcore/src/engines/instant_seal.rs +++ b/ethcore/src/engines/instant_seal.rs @@ -18,6 +18,7 @@ use engines::{Engine, Seal}; use machine::Machine; use types::header::{Header, ExtendedHeader}; use block::ExecutedBlock; +use std::sync::atomic::{AtomicU64, Ordering}; /// `InstantSeal` params. #[derive(Default, Debug, PartialEq)] @@ -39,13 +40,16 @@ impl From<::ethjson::spec::InstantSealParams> for InstantSealParams { pub struct InstantSeal { params: InstantSealParams, machine: M, + last_sealed_block: AtomicU64, } impl InstantSeal { /// Returns new instance of InstantSeal over the given state machine. pub fn new(params: InstantSealParams, machine: M) -> Self { InstantSeal { - params, machine, + params, + machine, + last_sealed_block: AtomicU64::new(0), } } } @@ -60,11 +64,19 @@ impl Engine for InstantSeal { fn seals_internally(&self) -> Option { Some(true) } fn generate_seal(&self, block: &ExecutedBlock, _parent: &Header) -> Seal { - if block.transactions.is_empty() { - Seal::None - } else { - Seal::Regular(Vec::new()) + if !block.transactions.is_empty() { + let block_number = block.header.number(); + let last_sealed_block = self.last_sealed_block.load(Ordering::SeqCst); + // Return a regular seal if the given block is _higher_ than + // the last sealed one + if block_number > last_sealed_block { + let prev_last_sealed_block = self.last_sealed_block.compare_and_swap(last_sealed_block, block_number, Ordering::SeqCst); + if prev_last_sealed_block == last_sealed_block { + return Seal::Regular(Vec::new()) + } + } } + Seal::None } fn verify_local_seal(&self, _header: &Header) -> Result<(), M::Error> { diff --git a/ethcore/src/ethereum/mod.rs b/ethcore/src/ethereum/mod.rs index cfd2ac5cc4..b0810ee4aa 100644 --- a/ethcore/src/ethereum/mod.rs +++ b/ethcore/src/ethereum/mod.rs @@ -57,6 +57,11 @@ pub fn new_poanet<'a, T: Into>>(params: T) -> Spec { load(params.into(), include_bytes!("../../res/ethereum/poacore.json")) } +/// Create a new xDai chain spec. +pub fn new_xdai<'a, T: Into>>(params: T) -> Spec { + load(params.into(), include_bytes!("../../res/ethereum/xdai.json")) +} + /// Create a new Volta mainnet chain spec. pub fn new_volta<'a, T: Into>>(params: T) -> Spec { load(params.into(), include_bytes!("../../res/ethereum/volta.json")) diff --git a/ethcore/src/executive.rs b/ethcore/src/executive.rs index f96cd7687c..cac6dc7638 100644 --- a/ethcore/src/executive.rs +++ b/ethcore/src/executive.rs @@ -395,7 +395,8 @@ impl<'a> CallCreateExecutive<'a> { let default = []; let data = if let Some(ref d) = params.data { d as &[u8] } else { &default as &[u8] }; - let cost = builtin.cost(data); + // NOTE(niklasad1): block number is used by `builtin alt_bn128 ops` to enable eip1108 + let cost = builtin.cost(data, self.info.number); if cost <= params.gas { let mut builtin_out_buffer = Vec::new(); let result = { diff --git a/ethcore/src/externalities.rs b/ethcore/src/externalities.rs index 41122afc1d..27ef053650 100644 --- a/ethcore/src/externalities.rs +++ b/ethcore/src/externalities.rs @@ -399,6 +399,10 @@ impl<'a, T: 'a, V: 'a, B: 'a> Ext for Externalities<'a, T, V, B> self.env_info } + fn chain_id(&self) -> u64 { + self.machine.params().chain_id + } + fn depth(&self) -> usize { self.depth } @@ -419,6 +423,10 @@ impl<'a, T: 'a, V: 'a, B: 'a> Ext for Externalities<'a, T, V, B> self.vm_tracer.trace_prepare_execute(pc, instruction, gas_cost, mem_written, store_written) } + fn trace_failed(&mut self) { + self.vm_tracer.trace_failed(); + } + fn trace_executed(&mut self, gas_used: U256, stack_push: &[U256], mem: &[u8]) { self.vm_tracer.trace_executed(gas_used, stack_push, mem) } diff --git a/ethcore/src/json_tests/executive.rs b/ethcore/src/json_tests/executive.rs index cd9e8f2aec..0dae76e414 100644 --- a/ethcore/src/json_tests/executive.rs +++ b/ethcore/src/json_tests/executive.rs @@ -210,6 +210,8 @@ impl<'a, T: 'a, V: 'a, B: 'a> Ext for TestExt<'a, T, V, B> self.ext.env_info() } + fn chain_id(&self) -> u64 { 0 } + fn depth(&self) -> usize { 0 } diff --git a/ethcore/src/lib.rs b/ethcore/src/lib.rs index 2ad8e29e59..4437ec6883 100644 --- a/ethcore/src/lib.rs +++ b/ethcore/src/lib.rs @@ -62,6 +62,7 @@ extern crate bn; extern crate byteorder; extern crate common_types as types; extern crate crossbeam_utils; +extern crate eip_152; extern crate ethabi; extern crate ethash; extern crate ethcore_blockchain as blockchain; @@ -120,6 +121,9 @@ extern crate blooms_db; extern crate env_logger; #[cfg(test)] extern crate rlp_compress; +#[cfg(test)] +#[macro_use] +extern crate hex_literal; #[macro_use] extern crate ethabi_derive; diff --git a/ethcore/src/machine/impls.rs b/ethcore/src/machine/impls.rs index 72f20ecdf7..fca611d4e8 100644 --- a/ethcore/src/machine/impls.rs +++ b/ethcore/src/machine/impls.rs @@ -474,7 +474,7 @@ mod tests { #[test] fn should_disallow_unsigned_transactions() { - let rlp = "ea80843b9aca0083015f90948921ebb5f79e9e3920abe571004d0b1d5119c154865af3107a400080038080".into(); + let rlp = "ea80843b9aca0083015f90948921ebb5f79e9e3920abe571004d0b1d5119c154865af3107a400080038080"; let transaction: UnverifiedTransaction = ::rlp::decode(&::rustc_hex::FromHex::from_hex(rlp).unwrap()).unwrap(); let spec = ::ethereum::new_ropsten_test(); let ethparams = get_default_ethash_extensions(); diff --git a/ethcore/src/miner/miner.rs b/ethcore/src/miner/miner.rs index d9d4570a72..f31973c13c 100644 --- a/ethcore/src/miner/miner.rs +++ b/ethcore/src/miner/miner.rs @@ -31,7 +31,7 @@ use ethcore_miner::work_notify::NotifyWork; use ethereum_types::{H256, U256, Address}; use io::IoChannel; use miner::pool_client::{PoolClient, CachedNonceClient, NonceCache}; -use miner; +use miner::{self, MinerService}; use parking_lot::{Mutex, RwLock}; use rayon::prelude::*; use types::transaction::{ @@ -52,6 +52,7 @@ use client::{ BlockChain, ChainInfo, BlockProducer, SealedBlockImporter, Nonce, TransactionInfo, TransactionId }; use client::{BlockId, ClientIoMessage}; +use client::traits::EngineClient; use engines::{EthEngine, Seal, EngineSigner}; use error::{Error, ErrorKind}; use executed::ExecutionError; @@ -494,7 +495,7 @@ impl Miner { let sender = transaction.sender(); // Re-verify transaction again vs current state. - let result = client.verify_signed(&transaction) + let result = client.verify_for_pending_block(&transaction, &open_block.header) .map_err(|e| e.into()) .and_then(|_| { open_block.push_transaction(transaction, None) @@ -830,7 +831,6 @@ impl Miner { /// Prepare pending block, check whether sealing is needed, and then update sealing. fn prepare_and_update_sealing(&self, chain: &C) { - use miner::MinerService; // Make sure to do it after transaction is imported and lock is dropped. // We need to create pending block and enable sealing. @@ -1307,6 +1307,9 @@ impl miner::MinerService for Miner { service_transaction_checker.as_ref(), ); queue.cull(client); + if is_internal_import { + chain.update_sealing(); + } }; if let Err(e) = channel.send(ClientIoMessage::execute(cull)) { @@ -1314,6 +1317,9 @@ impl miner::MinerService for Miner { } } else { self.transaction_queue.cull(client); + if is_internal_import { + self.update_sealing(chain); + } } } if let Some(ref service_transaction_checker) = self.service_transaction_checker { diff --git a/ethcore/src/miner/pool_client.rs b/ethcore/src/miner/pool_client.rs index 60e93dee8a..93cc0e8cfb 100644 --- a/ethcore/src/miner/pool_client.rs +++ b/ethcore/src/miner/pool_client.rs @@ -113,11 +113,13 @@ impl<'a, C: 'a> PoolClient<'a, C> where } } - /// Verifies if signed transaction is executable. + /// Verifies transaction against its block (before its import into this block) + /// Also Verifies if signed transaction is executable. /// /// This should perform any verifications that rely on chain status. - pub fn verify_signed(&self, tx: &SignedTransaction) -> Result<(), transaction::Error> { - self.engine.machine().verify_transaction(&tx, &self.best_block_header, self.chain) + pub fn verify_for_pending_block(&self, tx: &SignedTransaction, header: &Header) -> Result<(), transaction::Error> { + self.engine.machine().verify_transaction_basic(tx, header)?; + self.engine.machine().verify_transaction(tx, &self.best_block_header, self.chain) } } @@ -138,8 +140,7 @@ impl<'a, C: 'a> pool::client::Client for PoolClient<'a, C> where self.engine.verify_transaction_basic(&tx, &self.best_block_header)?; let tx = self.engine.verify_transaction_unordered(tx, &self.best_block_header)?; - self.verify_signed(&tx)?; - + self.engine.machine().verify_transaction(&tx, &self.best_block_header, self.chain)?; Ok(tx) } diff --git a/ethcore/src/spec/spec.rs b/ethcore/src/spec/spec.rs index fe32c0d87e..3384f0321e 100644 --- a/ethcore/src/spec/spec.rs +++ b/ethcore/src/spec/spec.rs @@ -65,7 +65,7 @@ fn fmt_err(f: F) -> String { /// we define a "bugfix" hard fork as any hard fork which /// you would put on-by-default in a new chain. #[derive(Debug, PartialEq, Default)] -#[cfg_attr(test, derive(Clone))] +#[cfg_attr(any(test, feature = "test-helpers"), derive(Clone))] pub struct CommonParams { /// Account start nonce. pub account_start_nonce: U256, @@ -123,6 +123,10 @@ pub struct CommonParams { pub eip1283_disable_transition: BlockNumber, /// Number of first block where EIP-1014 rules begin. pub eip1014_transition: BlockNumber, + /// Number of first block where EIP-1344 rules begin: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1344.md + pub eip1344_transition: BlockNumber, + /// Number of first block where EIP-2028 rules begin. + pub eip2028_transition: BlockNumber, /// Number of first block where dust cleanup rules (EIP-168 and EIP169) begin. pub dust_protection_transition: BlockNumber, /// Nonce cap increase per block. Nonce cap is only checked if dust protection is enabled. @@ -189,7 +193,11 @@ impl CommonParams { schedule.have_return_data = block_number >= self.eip211_transition; schedule.have_bitwise_shifting = block_number >= self.eip145_transition; schedule.have_extcodehash = block_number >= self.eip1052_transition; + schedule.have_chain_id = block_number >= self.eip1344_transition; schedule.eip1283 = block_number >= self.eip1283_transition && !(block_number >= self.eip1283_disable_transition); + if block_number >= self.eip2028_transition { + schedule.tx_data_non_zero_gas = 16; + } if block_number >= self.eip210_transition { schedule.blockhash_gas = 800; } @@ -308,6 +316,14 @@ impl From for CommonParams { BlockNumber::max_value, Into::into, ), + eip1344_transition: p.eip1344_transition.map_or_else( + BlockNumber::max_value, + Into::into, + ), + eip2028_transition: p.eip2028_transition.map_or_else( + BlockNumber::max_value, + Into::into, + ), dust_protection_transition: p.dust_protection_transition.map_or_else( BlockNumber::max_value, Into::into, diff --git a/ethcore/src/trace/executive_tracer.rs b/ethcore/src/trace/executive_tracer.rs index dbb2bc1eca..1653011c32 100644 --- a/ethcore/src/trace/executive_tracer.rs +++ b/ethcore/src/trace/executive_tracer.rs @@ -16,6 +16,7 @@ //! Simple executive tracer. +use std::cmp::min; use ethereum_types::{U256, Address}; use vm::{Error as VmError, ActionParams}; use log::{debug, warn}; @@ -194,12 +195,16 @@ impl Tracer for ExecutiveTracer { } } +struct TraceData { + mem_written: Option<(usize, usize)>, + store_written: Option<(U256, U256)>, +} + /// Simple VM tracer. Traces all operations. pub struct ExecutiveVMTracer { data: VMTrace, depth: usize, - last_mem_written: Option<(usize, usize)>, - last_store_written: Option<(U256, U256)>, + trace_stack: Vec, } impl ExecutiveVMTracer { @@ -213,8 +218,7 @@ impl ExecutiveVMTracer { subs: vec![], }, depth: 0, - last_mem_written: None, - last_store_written: None, + trace_stack: vec![], } } @@ -241,30 +245,27 @@ impl VMTracer for ExecutiveVMTracer { executed: None, }); }); - self.last_mem_written = mem_written; - self.last_store_written = store_written; + self.trace_stack.push(TraceData { mem_written, store_written }); + } + + fn trace_failed(&mut self) { + let _ = self.trace_stack.pop().expect("pushed in trace_prepare_execute; qed"); } fn trace_executed(&mut self, gas_used: U256, stack_push: &[U256], mem: &[u8]) { - let mem_diff = self.last_mem_written.take().map(|(o, s)| { + let TraceData { mem_written, store_written } = self.trace_stack.pop().expect("pushed in trace_prepare_execute; qed"); + let mem_diff = mem_written.map(|(o, s)| { if o + s > mem.len() { - warn!( - target: "trace", - "Last mem written is out of bounds {} (mem is {})", - o + s, - mem.len(), - ); - (o, &[][..]) - } else { - (o, &(mem[o..o+s])) + warn!(target: "trace", "mem_written is out of bounds"); } + (o, &mem[min(mem.len(), o)..min(o + s, mem.len())]) }); - let store_diff = self.last_store_written.take(); + let store_diff = store_written; Self::with_trace_in_depth(&mut self.data, self.depth, move |trace| { let ex = VMExecutedOperation { gas_used: gas_used, - stack_push: stack_push.iter().cloned().collect(), - mem_diff: mem_diff.map(|(s, r)| MemoryDiff { offset: s, data: r.iter().cloned().collect() }), + stack_push: stack_push.to_vec(), + mem_diff: mem_diff.map(|(s, r)| MemoryDiff { offset: s, data: r.to_vec() }), store_diff: store_diff.map(|(l, v)| StorageDiff { location: l, value: v }), }; trace.operations.last_mut().expect("trace_executed is always called after a trace_prepare_execute; trace.operations cannot be empty; qed").executed = Some(ex); diff --git a/ethcore/src/trace/mod.rs b/ethcore/src/trace/mod.rs index d358661475..98521dbb0c 100644 --- a/ethcore/src/trace/mod.rs +++ b/ethcore/src/trace/mod.rs @@ -85,6 +85,9 @@ pub trait VMTracer: Send { /// Trace the preparation to execute a single valid instruction. fn trace_prepare_execute(&mut self, _pc: usize, _instruction: u8, _gas_cost: U256, _mem_written: Option<(usize, usize)>, _store_written: Option<(U256, U256)>) {} + /// Trace the execution failure of a single instruction. + fn trace_failed(&mut self) {} + /// Trace the finalised execution of a single valid instruction. fn trace_executed(&mut self, _gas_used: U256, _stack_push: &[U256], _mem: &[u8]) {} diff --git a/ethcore/types/Cargo.toml b/ethcore/types/Cargo.toml index 0d2cef5152..1d831278f8 100644 --- a/ethcore/types/Cargo.toml +++ b/ethcore/types/Cargo.toml @@ -16,4 +16,7 @@ rlp_derive = { path = "../../util/rlp-derive" } unexpected = { path = "../../util/unexpected" } [dev-dependencies] -rustc-hex= "1.0" +rustc-hex = "1.0" + +[features] +test-helpers = [] diff --git a/ethcore/types/src/transaction/error.rs b/ethcore/types/src/transaction/error.rs index ab10636643..68c0b2c0fe 100644 --- a/ethcore/types/src/transaction/error.rs +++ b/ethcore/types/src/transaction/error.rs @@ -28,9 +28,6 @@ pub enum Error { AlreadyImported, /// Transaction is not valid anymore (state already has higher nonce) Old, - /// Transaction has too low fee - /// (there is already a transaction with the same sender-nonce but higher gas price) - TooCheapToReplace, /// Transaction was not imported to the queue because limit has been reached. LimitReached, /// Transaction's gas price is below threshold. @@ -40,6 +37,14 @@ pub enum Error { /// Transaction gas price got: U256, }, + /// Transaction has too low fee + /// (there is already a transaction with the same sender-nonce but higher gas price) + TooCheapToReplace { + /// previous transaction's gas price + prev: Option, + /// new transaction's gas price + new: Option, + }, /// Transaction's gas is below currently set minimal gas requirement. InsufficientGas { /// Minimal expected gas @@ -99,7 +104,10 @@ impl fmt::Display for Error { let msg = match *self { AlreadyImported => "Already imported".into(), Old => "No longer valid".into(), - TooCheapToReplace => "Gas price too low to replace".into(), + TooCheapToReplace { prev, new } => + format!("Gas price too low to replace, previous tx gas: {:?}, new tx gas: {:?}", + prev, new + ), LimitReached => "Transaction limit reached".into(), InsufficientGasPrice { minimal, got } => format!("Insufficient gas price. Min={}, Given={}", minimal, got), diff --git a/ethcore/types/src/transaction/transaction.rs b/ethcore/types/src/transaction/transaction.rs index 248bc26462..439880089e 100644 --- a/ethcore/types/src/transaction/transaction.rs +++ b/ethcore/types/src/transaction/transaction.rs @@ -53,7 +53,11 @@ impl Default for Action { impl rlp::Decodable for Action { fn decode(rlp: &Rlp) -> Result { if rlp.is_empty() { - Ok(Action::Create) + if rlp.is_data() { + Ok(Action::Create) + } else { + Err(DecoderError::RlpExpectedToBeData) + } } else { Ok(Action::Call(rlp.as_val()?)) } @@ -572,6 +576,20 @@ mod tests { assert_eq!(t.chain_id(), None); } + #[test] + fn empty_atom_as_create_action() { + let empty_atom = [0x80]; + let action: Action = rlp::decode(&empty_atom).unwrap(); + assert_eq!(action, Action::Create); + } + + #[test] + fn empty_list_as_create_action_rejected() { + let empty_list = [0xc0]; + let action: Result = rlp::decode(&empty_list); + assert_eq!(action, Err(DecoderError::RlpExpectedToBeData)); + } + #[test] fn signing_eip155_zero_chainid() { use ethkey::{Random, Generator}; diff --git a/ethcore/vm/Cargo.toml b/ethcore/vm/Cargo.toml index 0e77ea0212..34b086bce0 100644 --- a/ethcore/vm/Cargo.toml +++ b/ethcore/vm/Cargo.toml @@ -5,12 +5,9 @@ version = "0.1.0" authors = ["Parity Technologies "] [dependencies] -byteorder = "1.0" parity-bytes = "0.1" ethereum-types = "0.4" -trie-db = "0.11.0" patricia-trie-ethereum = { path = "../../util/patricia-trie-ethereum" } -log = "0.4" ethjson = { path = "../../json" } rlp = { version = "0.3.0", features = ["ethereum"] } keccak-hash = "0.1" diff --git a/ethcore/vm/src/env_info.rs b/ethcore/vm/src/env_info.rs index e5bd3f64e3..addfa62898 100644 --- a/ethcore/vm/src/env_info.rs +++ b/ethcore/vm/src/env_info.rs @@ -65,7 +65,7 @@ impl From for EnvInfo { fn from(e: ethjson::vm::Env) -> Self { let number = e.number.into(); EnvInfo { - number: number, + number, author: e.author.into(), difficulty: e.difficulty.into(), gas_limit: e.gas_limit.into(), diff --git a/ethcore/vm/src/ext.rs b/ethcore/vm/src/ext.rs index 9b499fcab4..3c3a2335bc 100644 --- a/ethcore/vm/src/ext.rs +++ b/ethcore/vm/src/ext.rs @@ -144,6 +144,9 @@ pub trait Ext { /// Returns environment info. fn env_info(&self) -> &EnvInfo; + /// Returns the chain ID of the blockchain + fn chain_id(&self) -> u64; + /// Returns current depth of execution. /// /// If contract A calls contract B, and contract B calls C, @@ -160,8 +163,12 @@ pub trait Ext { fn trace_next_instruction(&mut self, _pc: usize, _instruction: u8, _current_gas: U256) -> bool { false } /// Prepare to trace an operation. Passthrough for the VM trace. + /// For each call of `trace_prepare_execute` either `trace_failed` or `trace_executed` MUST be called. fn trace_prepare_execute(&mut self, _pc: usize, _instruction: u8, _gas_cost: U256, _mem_written: Option<(usize, usize)>, _store_written: Option<(U256, U256)>) {} + /// Trace the execution failure of a single instruction. + fn trace_failed(&mut self) {} + /// Trace the finalised execution of a single instruction. fn trace_executed(&mut self, _gas_used: U256, _stack_push: &[U256], _mem: &[u8]) {} diff --git a/ethcore/vm/src/lib.rs b/ethcore/vm/src/lib.rs index f239e40568..4204ff92dc 100644 --- a/ethcore/vm/src/lib.rs +++ b/ethcore/vm/src/lib.rs @@ -22,7 +22,6 @@ extern crate ethjson; extern crate rlp; extern crate keccak_hash as hash; extern crate patricia_trie_ethereum as ethtrie; -extern crate trie_db as trie; mod action_params; mod call_type; diff --git a/ethcore/vm/src/schedule.rs b/ethcore/vm/src/schedule.rs index d1dc3b5aad..764487e92b 100644 --- a/ethcore/vm/src/schedule.rs +++ b/ethcore/vm/src/schedule.rs @@ -84,7 +84,7 @@ pub struct Schedule { pub tx_create_gas: usize, /// Additional cost for empty data transaction pub tx_data_zero_gas: usize, - /// Aditional cost for non-empty data transaction + /// Additional cost for non-empty data transaction pub tx_data_non_zero_gas: usize, /// Gas price for copying memory pub copy_gas: usize, @@ -115,6 +115,8 @@ pub struct Schedule { pub have_return_data: bool, /// SHL, SHR, SAR opcodes enabled. pub have_bitwise_shifting: bool, + /// CHAINID opcode enabled. + pub have_chain_id: bool, /// Kill basic accounts below this balance if touched. pub kill_dust: CleanDustMode, /// Enable EIP-1283 rules @@ -209,6 +211,7 @@ impl Schedule { have_revert: false, have_return_data: false, have_bitwise_shifting: false, + have_chain_id: false, have_extcodehash: false, stack_limit: 1024, max_depth: 1024, @@ -275,6 +278,14 @@ impl Schedule { schedule } + /// Schedule for the Istanbul fork of the Ethereum main net. + pub fn new_istanbul() -> Schedule { + let mut schedule = Self::new_constantinople(); + schedule.have_chain_id = true; + schedule.tx_data_non_zero_gas = 16; + schedule + } + fn new(efcd: bool, hdc: bool, tcg: usize) -> Schedule { Schedule { exceptional_failed_code_deposit: efcd, @@ -283,6 +294,7 @@ impl Schedule { have_revert: false, have_return_data: false, have_bitwise_shifting: false, + have_chain_id: false, have_extcodehash: false, stack_limit: 1024, max_depth: 1024, diff --git a/ethcore/vm/src/tests.rs b/ethcore/vm/src/tests.rs index 306ad871da..5684a234ac 100644 --- a/ethcore/vm/src/tests.rs +++ b/ethcore/vm/src/tests.rs @@ -67,6 +67,8 @@ pub struct FakeExt { pub balances: HashMap, pub tracing: bool, pub is_static: bool, + + chain_id: u64, } // similar to the normal `finalize` function, but ignoring NeedsReturn. @@ -98,11 +100,24 @@ impl FakeExt { ext } + /// New fake externalities with Istanbul schedule rules + pub fn new_istanbul() -> Self { + let mut ext = FakeExt::default(); + ext.schedule = Schedule::new_istanbul(); + ext + } + /// Alter fake externalities to allow wasm pub fn with_wasm(mut self) -> Self { self.schedule.wasm = Some(Default::default()); self } + + /// Set chain ID + pub fn with_chain_id(mut self, chain_id: u64) -> Self { + self.chain_id = chain_id; + self + } } impl Ext for FakeExt { @@ -200,7 +215,7 @@ impl Ext for FakeExt { fn log(&mut self, topics: Vec, data: &[u8]) -> Result<()> { self.logs.push(FakeLogEntry { - topics: topics, + topics, data: data.to_vec() }); Ok(()) @@ -223,6 +238,10 @@ impl Ext for FakeExt { &self.info } + fn chain_id(&self) -> u64 { + self.chain_id + } + fn depth(&self) -> usize { self.depth } diff --git a/ipfs/src/lib.rs b/ipfs/src/lib.rs index 0ba6a86d02..0a3d83432a 100644 --- a/ipfs/src/lib.rs +++ b/ipfs/src/lib.rs @@ -22,7 +22,7 @@ extern crate rlp; extern crate ethcore; extern crate parity_bytes as bytes; extern crate ethereum_types; -extern crate jsonrpc_core as core; +extern crate jsonrpc_core; extern crate jsonrpc_http_server as http; pub mod error; @@ -32,8 +32,8 @@ use std::thread; use std::sync::{mpsc, Arc}; use std::net::{SocketAddr, IpAddr}; -use core::futures::future::{self, FutureResult}; -use core::futures::{self, Future}; +use jsonrpc_core::futures::future::{self, FutureResult}; +use jsonrpc_core::futures::{self, Future}; use ethcore::client::BlockChainClient; use http::hyper::{self, server, Method, StatusCode, Body, header::{self, HeaderValue}, @@ -51,19 +51,19 @@ pub struct IpfsHandler { /// Hostnames allowed in the `Host` request header allowed_hosts: Option>, /// Reference to the Blockchain Client - client: Arc, + client: Arc, } impl IpfsHandler { - pub fn client(&self) -> &BlockChainClient { + pub fn client(&self) -> &dyn BlockChainClient { &*self.client } - pub fn new(cors: DomainsValidation, hosts: DomainsValidation, client: Arc) -> Self { + pub fn new(cors: DomainsValidation, hosts: DomainsValidation, client: Arc) -> Self { IpfsHandler { cors_domains: cors.into(), allowed_hosts: hosts.into(), - client: client, + client, } } pub fn on_request(&self, req: hyper::Request) -> (Option, Out) { @@ -154,7 +154,7 @@ pub fn start_server( interface: String, cors: DomainsValidation, hosts: DomainsValidation, - client: Arc + client: Arc ) -> Result { let ip: IpAddr = interface.parse().map_err(|_| ServerError::InvalidInterface)?; @@ -182,12 +182,12 @@ pub fn start_server( }; let server = server_bldr - .serve(new_service) - .map_err(|_| ()) - .select(shutdown_signal.map_err(|_| ())) - .then(|_| Ok(())); + .serve(new_service) + .map_err(|_| ()) + .select(shutdown_signal.map_err(|_| ())) + .then(|_| Ok(())); - hyper::rt::run(server); + hyper::rt::run(server); send(Ok(())); }); diff --git a/json/src/spec/builtin.rs b/json/src/spec/builtin.rs index 930e0bc9a1..20ebbc3c63 100644 --- a/json/src/spec/builtin.rs +++ b/json/src/spec/builtin.rs @@ -18,6 +18,9 @@ use uint::Uint; +/// Price per round of Blake2 compression. +pub type Blake2F = u64; + /// Linear pricing. #[derive(Debug, PartialEq, Deserialize, Clone)] #[serde(deny_unknown_fields)] @@ -36,6 +39,16 @@ pub struct Modexp { pub divisor: usize, } +/// Pricing for constant alt_bn128 operations (ECADD and ECMUL) +#[derive(Debug, PartialEq, Deserialize, Clone)] +#[serde(deny_unknown_fields)] +pub struct AltBn128ConstOperations { + /// price + pub price: usize, + /// EIP 1108 transition price + pub eip1108_transition_price: usize, +} + /// Pricing for alt_bn128_pairing. #[derive(Debug, PartialEq, Deserialize, Clone)] #[serde(deny_unknown_fields)] @@ -44,6 +57,10 @@ pub struct AltBn128Pairing { pub base: usize, /// Price per point pair. pub pair: usize, + /// EIP 1108 transition base price + pub eip1108_transition_base: usize, + /// EIP 1108 transition price per point pair + pub eip1108_transition_pair: usize, } /// Pricing variants. @@ -51,12 +68,16 @@ pub struct AltBn128Pairing { #[serde(deny_unknown_fields)] #[serde(rename_all = "snake_case")] pub enum Pricing { + /// Pricing for Blake2 compression function: each call costs the same amount per round. + Blake2F(Blake2F), /// Linear pricing. Linear(Linear), /// Pricing for modular exponentiation. Modexp(Modexp), /// Pricing for alt_bn128_pairing exponentiation. AltBn128Pairing(AltBn128Pairing), + /// Pricing for constant alt_bn128 operations + AltBn128ConstOperations(AltBn128ConstOperations), } /// Spec builtin. @@ -69,6 +90,8 @@ pub struct Builtin { pub pricing: Pricing, /// Activation block. pub activate_at: Option, + /// EIP 1108 + pub eip1108_transition: Option, } #[cfg(test)] @@ -89,6 +112,19 @@ mod tests { assert!(deserialized.activate_at.is_none()); } + #[test] + fn deserialization_blake2_f_builtin() { + let s = r#"{ + "name": "blake2_f", + "activate_at": "0xffffff", + "pricing": { "blake2_f": 123 } + }"#; + let deserialized: Builtin = serde_json::from_str(s).unwrap(); + assert_eq!(deserialized.name, "blake2_f"); + assert_eq!(deserialized.pricing, Pricing::Blake2F(123)); + assert!(deserialized.activate_at.is_some()); + } + #[test] fn activate_at() { let s = r#"{ diff --git a/json/src/spec/params.rs b/json/src/spec/params.rs index 765384a6b9..7f48c3e9f4 100644 --- a/json/src/spec/params.rs +++ b/json/src/spec/params.rs @@ -94,6 +94,10 @@ pub struct Params { /// See `CommonParams` docs. pub eip1014_transition: Option, /// See `CommonParams` docs. + pub eip1344_transition: Option, + /// See `CommonParams` docs. + pub eip2028_transition: Option, + /// See `CommonParams` docs. pub dust_protection_transition: Option, /// See `CommonParams` docs. pub nonce_cap_increment: Option, diff --git a/miner/Cargo.toml b/miner/Cargo.toml index 25d8e14c8b..7432b10512 100644 --- a/miner/Cargo.toml +++ b/miner/Cargo.toml @@ -32,7 +32,7 @@ parking_lot = "0.7" price-info = { path = "./price-info", optional = true } rlp = { version = "0.3.0", features = ["ethereum"] } trace-time = "0.1" -transaction-pool = "2.0" +transaction-pool = "2.0.1" [dev-dependencies] env_logger = "0.5" diff --git a/miner/src/pool/queue.rs b/miner/src/pool/queue.rs index ad7c9e6f12..58966df859 100644 --- a/miner/src/pool/queue.rs +++ b/miner/src/pool/queue.rs @@ -587,7 +587,7 @@ fn convert_error(err: txpool::Error) -> transa match err { Error::AlreadyImported(..) => transaction::Error::AlreadyImported, Error::TooCheapToEnter(..) => transaction::Error::LimitReached, - Error::TooCheapToReplace(..) => transaction::Error::TooCheapToReplace + Error::TooCheapToReplace(..) => transaction::Error::TooCheapToReplace { prev: None, new: None } } } diff --git a/miner/src/pool/replace.rs b/miner/src/pool/replace.rs index b1112dcae1..0655af5999 100644 --- a/miner/src/pool/replace.rs +++ b/miner/src/pool/replace.rs @@ -71,6 +71,20 @@ where let old_score = (old.priority(), old.gas_price()); let new_score = (new.priority(), new.gas_price()); if new_score > old_score { + // Check if this is a replacement transaction. + // + // With replacement transactions we can safely return `InsertNew` here, because + // we don't need to remove `old` (worst transaction in the pool) since `new` will replace + // some other transaction in the pool so we will never go above limit anyway. + if let Some(txs) = new.pooled_by_sender { + if let Ok(index) = txs.binary_search_by(|old| self.scoring.compare(old, new)) { + return match self.scoring.choose(&txs[index], new) { + Choice::ReplaceOld => Choice::InsertNew, + choice => choice, + } + } + } + let state = &self.client; // calculate readiness based on state nonce + pooled txs from same sender let is_ready = |replace: &ReplaceTransaction| { @@ -412,4 +426,88 @@ mod tests { assert_eq!(replace.should_replace(&old, &new), ReplaceOld); } + + #[test] + fn should_accept_local_tx_with_same_sender_and_nonce_with_better_gas_price() { + let scoring = NonceAndGasPrice(PrioritizationStrategy::GasPriceOnly); + let client = TestClient::new().with_nonce(1); + let replace = ReplaceByScoreAndReadiness::new(scoring, client); + + // current transaction is ready + let old_tx = { + let tx = Tx { + nonce: 1, + gas_price: 1, + ..Default::default() + }; + tx.signed().verified() + }; + + let new_sender = Random.generate().unwrap(); + let tx_new_ready_1 = local_tx_verified(Tx { + nonce: 1, + gas_price: 1, + ..Default::default() + }, &new_sender); + + let tx_new_ready_2 = local_tx_verified(Tx { + nonce: 1, + gas_price: 2, // same nonce, higher gas price + ..Default::default() + }, &new_sender); + + let old_tx = txpool::Transaction { insertion_id: 0, transaction: Arc::new(old_tx) }; + + let new_tx = txpool::Transaction { insertion_id: 0, transaction: Arc::new(tx_new_ready_2) }; + let pooled_txs = [ + txpool::Transaction { insertion_id: 0, transaction: Arc::new(tx_new_ready_1) }, + ]; + + let old = ReplaceTransaction::new(&old_tx, None); + let new = ReplaceTransaction::new(&new_tx, Some(&pooled_txs)); + + assert_eq!(replace.should_replace(&old, &new), InsertNew); + } + + #[test] + fn should_reject_local_tx_with_same_sender_and_nonce_with_worse_gas_price() { + let scoring = NonceAndGasPrice(PrioritizationStrategy::GasPriceOnly); + let client = TestClient::new().with_nonce(1); + let replace = ReplaceByScoreAndReadiness::new(scoring, client); + + // current transaction is ready + let old_tx = { + let tx = Tx { + nonce: 1, + gas_price: 1, + ..Default::default() + }; + tx.signed().verified() + }; + + let new_sender = Random.generate().unwrap(); + let tx_new_ready_1 = local_tx_verified(Tx { + nonce: 1, + gas_price: 2, + ..Default::default() + }, &new_sender); + + let tx_new_ready_2 = local_tx_verified(Tx { + nonce: 1, + gas_price: 1, // same nonce, lower gas price + ..Default::default() + }, &new_sender); + + let old_tx = txpool::Transaction { insertion_id: 0, transaction: Arc::new(old_tx) }; + + let new_tx = txpool::Transaction { insertion_id: 0, transaction: Arc::new(tx_new_ready_2) }; + let pooled_txs = [ + txpool::Transaction { insertion_id: 0, transaction: Arc::new(tx_new_ready_1) }, + ]; + + let old = ReplaceTransaction::new(&old_tx, None); + let new = ReplaceTransaction::new(&new_tx, Some(&pooled_txs)); + + assert_eq!(replace.should_replace(&old, &new), RejectNew); + } } diff --git a/miner/src/pool/tests/mod.rs b/miner/src/pool/tests/mod.rs index 0eb223dba0..1df1be4ce7 100644 --- a/miner/src/pool/tests/mod.rs +++ b/miner/src/pool/tests/mod.rs @@ -91,10 +91,10 @@ fn should_return_correct_nonces_when_dropped_because_of_limit() { // then assert_eq!(res, vec![Ok(()), Ok(())]); assert_eq!(res2, vec![ - // The error here indicates reaching the limit - // and minimal effective gas price taken into account. - Err(transaction::Error::InsufficientGasPrice { minimal: 2.into(), got: 1.into() }), - Ok(()) + // The error here indicates reaching the limit + // and minimal effective gas price taken into account. + Err(transaction::Error::TooCheapToReplace { prev: Some(2.into()), new: Some(1.into()) }), + Ok(()) ]); assert_eq!(txq.status().status.transaction_count, 3); // tx2 transaction got dropped because of limit @@ -585,7 +585,7 @@ fn should_not_replace_same_transaction_if_the_fee_is_less_than_minimal_bump() { let res = txq.import(client.clone(), vec![tx2, tx4].local()); // then - assert_eq!(res, vec![Err(transaction::Error::TooCheapToReplace), Ok(())]); + assert_eq!(res, vec![Err(transaction::Error::TooCheapToReplace { prev: None, new: None }), Ok(())]); assert_eq!(txq.status().status.transaction_count, 2); assert_eq!(txq.pending(client.clone(), PendingSettings::all_prioritized(0, 0))[0].signed().gas_price, U256::from(20)); assert_eq!(txq.pending(client.clone(), PendingSettings::all_prioritized(0, 0))[1].signed().gas_price, U256::from(2)); @@ -1027,9 +1027,9 @@ fn should_reject_early_in_case_gas_price_is_less_than_min_effective() { let client = TestClient::new(); let tx1 = Tx::default().signed().unverified(); let res = txq.import(client.clone(), vec![tx1]); - assert_eq!(res, vec![Err(transaction::Error::InsufficientGasPrice { - minimal: 2.into(), - got: 1.into(), + assert_eq!(res, vec![Err(transaction::Error::TooCheapToReplace { + prev: Some(2.into()), + new: Some(1.into()), })]); assert!(!client.was_verification_triggered()); diff --git a/miner/src/pool/verifier.rs b/miner/src/pool/verifier.rs index 1fded37630..51232e967a 100644 --- a/miner/src/pool/verifier.rs +++ b/miner/src/pool/verifier.rs @@ -231,9 +231,9 @@ impl txpool::Verifier for Verifier. diff --git a/parity/cli/version.txt b/parity/cli/version.txt index 85ef190f12..26eae78ddf 100644 --- a/parity/cli/version.txt +++ b/parity/cli/version.txt @@ -1,9 +1,10 @@ -Parity Ethereum +Parity Ethereum Client. version {} Copyright 2015-2019 Parity Technologies (UK) Ltd. License GPLv3+: GNU GPL version 3 or later . This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. -By Wood/Paronyan/Kotewicz/Drwięga/Volf - Habermeier/Czaban/Greeff/Gotchac/Redmann +By Wood/Paronyan/Kotewicz/Drwięga/Volf/Greeff + Habermeier/Czaban/Gotchac/Redman/Nikolsky + Schoedon/Tang/Adolfsson/Silva/Palm/Hirsz et al. diff --git a/parity/params.rs b/parity/params.rs index a8164dd261..f17cae2c57 100644 --- a/parity/params.rs +++ b/parity/params.rs @@ -36,6 +36,7 @@ pub enum SpecType { Foundation, Classic, Poanet, + Xdai, Volta, Ewc, Expanse, @@ -68,6 +69,7 @@ impl str::FromStr for SpecType { "ethereum" | "frontier" | "homestead" | "byzantium" | "foundation" | "mainnet" => SpecType::Foundation, "classic" | "frontier-dogmatic" | "homestead-dogmatic" => SpecType::Classic, "poanet" | "poacore" => SpecType::Poanet, + "xdai" => SpecType::Xdai, "volta" => SpecType::Volta, "ewc" | "energyweb" => SpecType::Ewc, "expanse" => SpecType::Expanse, @@ -95,6 +97,7 @@ impl fmt::Display for SpecType { SpecType::Foundation => "foundation", SpecType::Classic => "classic", SpecType::Poanet => "poanet", + SpecType::Xdai => "xdai", SpecType::Volta => "volta", SpecType::Ewc => "energyweb", SpecType::Expanse => "expanse", @@ -122,6 +125,7 @@ impl SpecType { SpecType::Foundation => Ok(ethereum::new_foundation(params)), SpecType::Classic => Ok(ethereum::new_classic(params)), SpecType::Poanet => Ok(ethereum::new_poanet(params)), + SpecType::Xdai => Ok(ethereum::new_xdai(params)), SpecType::Volta => Ok(ethereum::new_volta(params)), SpecType::Ewc => Ok(ethereum::new_ewc(params)), SpecType::Expanse => Ok(ethereum::new_expanse(params)), @@ -380,6 +384,7 @@ mod tests { assert_eq!(SpecType::Classic, "homestead-dogmatic".parse().unwrap()); assert_eq!(SpecType::Poanet, "poanet".parse().unwrap()); assert_eq!(SpecType::Poanet, "poacore".parse().unwrap()); + assert_eq!(SpecType::Xdai, "xdai".parse().unwrap()); assert_eq!(SpecType::Volta, "volta".parse().unwrap()); assert_eq!(SpecType::Ewc, "ewc".parse().unwrap()); assert_eq!(SpecType::Ewc, "energyweb".parse().unwrap()); @@ -411,6 +416,7 @@ mod tests { assert_eq!(format!("{}", SpecType::Foundation), "foundation"); assert_eq!(format!("{}", SpecType::Classic), "classic"); assert_eq!(format!("{}", SpecType::Poanet), "poanet"); + assert_eq!(format!("{}", SpecType::Xdai), "xdai"); assert_eq!(format!("{}", SpecType::Volta), "volta"); assert_eq!(format!("{}", SpecType::Ewc), "energyweb"); assert_eq!(format!("{}", SpecType::Expanse), "expanse"); diff --git a/rpc/Cargo.toml b/rpc/Cargo.toml index 4d796263c1..04de73c73b 100644 --- a/rpc/Cargo.toml +++ b/rpc/Cargo.toml @@ -70,7 +70,7 @@ ethcore-network = { path = "../util/network" } fake-fetch = { path = "../util/fake-fetch" } macros = { path = "../util/macros" } pretty_assertions = "0.1" -transaction-pool = "2.0" +transaction-pool = "2.0.1" [features] accounts = ["ethcore-accounts"] diff --git a/rpc/src/v1/helpers/errors.rs b/rpc/src/v1/helpers/errors.rs index 70c94904b7..6adb114f36 100644 --- a/rpc/src/v1/helpers/errors.rs +++ b/rpc/src/v1/helpers/errors.rs @@ -408,8 +408,11 @@ pub fn transaction_message(error: &TransactionError) -> String { match *error { AlreadyImported => "Transaction with the same hash was already imported.".into(), Old => "Transaction nonce is too low. Try incrementing the nonce.".into(), - TooCheapToReplace => { - "Transaction gas price is too low. There is another transaction with same nonce in the queue. Try increasing the gas price or incrementing the nonce.".into() + TooCheapToReplace { prev, new } => { + format!("Transaction gas price {} is too low. There is another transaction with same nonce in the queue{}. Try increasing the gas price or incrementing the nonce.", + new.map(|gas| format!("{}wei", gas)).unwrap_or("supplied".into()), + prev.map(|gas| format!(" with gas price: {}wei", gas)).unwrap_or("".into()) + ) } LimitReached => { "There are too many transactions in the queue. Your transaction was dropped due to limit. Try increasing the fee.".into() diff --git a/scripts/gitlab/publish-onchain.sh b/scripts/gitlab/publish-onchain.sh index 9c7b866fb4..9c2ac1dbbc 100755 --- a/scripts/gitlab/publish-onchain.sh +++ b/scripts/gitlab/publish-onchain.sh @@ -7,7 +7,7 @@ echo "__________Register Release__________" DATA="secret=$RELEASES_SECRET" echo "Pushing release to Mainnet" -./tools/safe-curl.sh $DATA "http://update.parity.io:1337/push-release/${SCHEDULE_TAG:-${CI_COMMIT_REF_NAME}}/$CI_COMMIT_SHA" +./tools/safe-curl.sh $DATA "https://update.parity.io/push-release/${SCHEDULE_TAG:-${CI_COMMIT_REF_NAME}}/$CI_COMMIT_SHA" cd artifacts ls -l | sort -k9 @@ -26,7 +26,7 @@ do case $DIR in x86_64* ) DATA="commit=$CI_COMMIT_SHA&sha3=$sha3&filename=parity$WIN&secret=$RELEASES_SECRET" - ../../tools/safe-curl.sh $DATA "http://update.parity.io:1337/push-build/${SCHEDULE_TAG:-${CI_COMMIT_REF_NAME}}/$DIR" + ../../tools/safe-curl.sh $DATA "https://update.parity.io/push-build/${SCHEDULE_TAG:-${CI_COMMIT_REF_NAME}}/$DIR" ;; esac cd .. diff --git a/util/EIP-152/Cargo.toml b/util/EIP-152/Cargo.toml new file mode 100644 index 0000000000..fe65d01109 --- /dev/null +++ b/util/EIP-152/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "eip-152" +version = "0.1.0" +authors = ["Parity Technologies "] +repository = "https://github.com/paritytech/parity-ethereum" +documentation = "https://docs.rs/eip-152" +readme = "README.md" +description = "eip-512 blake2 F compression function" +keywords = ["eip-152", "eip152", "eip"] +license = "GPL-3.0" +edition = "2018" + +[dependencies] +rustc-hex = "2.0.1" diff --git a/util/EIP-152/src/lib.rs b/util/EIP-152/src/lib.rs new file mode 100644 index 0000000000..fd68b9072d --- /dev/null +++ b/util/EIP-152/src/lib.rs @@ -0,0 +1,192 @@ +// Copyright 2015-2019 Parity Technologies (UK) Ltd. +// This file is part of Parity Ethereum. + +// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . + +/// The precomputed values for BLAKE2b [from the spec](https://tools.ietf.org/html/rfc7693#section-2.7) +/// There are 10 16-byte arrays - one for each round +/// the entries are calculated from the sigma constants. +const SIGMA: [[usize; 16]; 10] = [ + [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], + [14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3], + [11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4], + [ 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8], + [ 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13], + [ 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9], + [12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11], + [13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10], + [ 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5], + [10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0], +]; + + +/// IV is the initialization vector for BLAKE2b. See https://tools.ietf.org/html/rfc7693#section-2.6 +/// for details. +const IV: [u64; 8] = [ + 0x6a09e667f3bcc908, 0xbb67ae8584caa73b, 0x3c6ef372fe94f82b, 0xa54ff53a5f1d36f1, + 0x510e527fade682d1, 0x9b05688c2b3e6c1f, 0x1f83d9abfb41bd6b, 0x5be0cd19137e2179, +]; + + +#[inline(always)] +/// The G mixing function. See https://tools.ietf.org/html/rfc7693#section-3.1 +fn g(v: &mut [u64], a: usize, b: usize, c: usize, d: usize, x: u64, y: u64) { + v[a] = v[a].wrapping_add(v[b]).wrapping_add(x); + v[d] = (v[d] ^ v[a]).rotate_right(32); + v[c] = v[c].wrapping_add(v[d]); + v[b] = (v[b] ^ v[c]).rotate_right(24); + v[a] = v[a].wrapping_add(v[b]).wrapping_add(y); + v[d] = (v[d] ^ v[a]).rotate_right(16); + v[c] = v[c].wrapping_add(v[d]); + v[b] = (v[b] ^ v[c]).rotate_right(63); +} + +/// The Blake2 compression function F. See https://tools.ietf.org/html/rfc7693#section-3.2 +/// Takes as an argument the state vector `h`, message block vector `m`, offset counter `t`, final +/// block indicator flag `f`, and number of rounds `rounds`. The state vector provided as the first +/// parameter is modified by the function. +pub fn compress(h: &mut [u64; 8], m: [u64; 16], t: [u64; 2], f: bool, rounds: usize) { + let mut v = [0u64; 16]; + v[..h.len()].copy_from_slice(h); // First half from state. + v[h.len()..].copy_from_slice(&IV); // Second half from IV. + + v[12] ^= t[0]; + v[13] ^= t[1]; + + if f { + v[14] = !v[14] // Invert all bits if the last-block-flag is set. + } + for i in 0..rounds { + // Message word selection permutation for this round. + let s = &SIGMA[i % 10]; + g(&mut v, 0, 4, 8, 12, m[s[0]], m[s[1]]); + g(&mut v, 1, 5, 9, 13, m[s[2]], m[s[3]]); + g(&mut v, 2, 6, 10, 14, m[s[4]], m[s[5]]); + g(&mut v, 3, 7, 11, 15, m[s[6]], m[s[7]]); + + g(&mut v, 0, 5, 10, 15, m[s[8]], m[s[9]]); + g(&mut v, 1, 6, 11, 12, m[s[10]], m[s[11]]); + g(&mut v, 2, 7, 8, 13, m[s[12]], m[s[13]]); + g(&mut v, 3, 4, 9, 14, m[s[14]], m[s[15]]); + } + + for i in 0..8 { + h[i] ^= v[i] ^ v[i + 8]; + } +} + + +#[cfg(test)] +mod tests { + use crate::compress; + use rustc_hex::FromHex; + + #[test] + fn test_blake2_f() { + // test from https://github.com/ethereum/EIPs/blob/master/EIPS/eip-152.md#example-usage-in-solidity + let mut h_in = [ + 0x6a09e667f2bdc948_u64, 0xbb67ae8584caa73b_u64, + 0x3c6ef372fe94f82b_u64, 0xa54ff53a5f1d36f1_u64, + 0x510e527fade682d1_u64, 0x9b05688c2b3e6c1f_u64, + 0x1f83d9abfb41bd6b_u64, 0x5be0cd19137e2179_u64, + ]; + + let m = [ + 0x0000000000636261_u64, 0x0000000000000000_u64, 0x0000000000000000_u64, + 0x0000000000000000_u64, 0x0000000000000000_u64, 0x0000000000000000_u64, + 0x0000000000000000_u64, 0x0000000000000000_u64, 0x0000000000000000_u64, + 0x0000000000000000_u64, 0x0000000000000000_u64, 0x0000000000000000_u64, + 0x0000000000000000_u64, 0x0000000000000000_u64, 0x0000000000000000_u64, + 0x0000000000000000_u64, + ]; + let c = [3, 0]; + let f = true; + let rounds = 12; + let h_out: [u64; 8] = [ + 0x0D4D1C983FA580BA_u64, 0xE9F6129FB697276A_u64, 0xB7C45A68142F214C_u64, + 0xD1A2FFDB6FBB124B_u64, 0x2D79AB2A39C5877D_u64, 0x95CC3345DED552C2_u64, + 0x5A92F1DBA88AD318_u64, 0x239900D4ED8623B9_u64, + ]; + + compress(&mut h_in, m, c, f, rounds); + + assert_eq!(h_in, h_out); + } + + fn to_u64_slice(vec: &[u8], slice: &mut [u64]) { + vec.chunks(8).enumerate().for_each(|(index, val)| { + slice[index] = u64::from_le_bytes([val[0], val[1], val[2], val[3], val[4], val[5], val[6], val[7]]) + }) + } + + #[test] + fn test_vectors_from_eip() { + let vec = vec![ + ( + // Test vector 4 + "0000000048c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001", + "08c9bcf367e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d282e6ad7f520e511f6c3e2b8c68059b9442be0454267ce079217e1319cde05b", + ), + ( // test vector 5 + "0000000c48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001", + "ba80a53f981c4d0d6a2797b69f12f6e94c212f14685ac4b74b12bb6fdbffa2d17d87c5392aab792dc252d5de4533cc9518d38aa8dbf1925ab92386edd4009923", + ), + ( + // Test vector 6 + "0000000c48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000", + "75ab69d3190a562c51aef8d88f1c2775876944407270c42c9844252c26d2875298743e7f6d5ea2f2d3e8d226039cd31b4e426ac4f2d3d666a610c2116fde4735", + ), + ( + // Test vector 7 + "0000000148c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001", + "b63a380cb2897d521994a85234ee2c181b5f844d2c624c002677e9703449d2fba551b3a8333bcdf5f2f7e08993d53923de3d64fcc68c034e717b9293fed7a421", + ), + // Test vector 8 – u32::MAX rounds – too slow to run +// ( +// "ffffffff48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001", +// "fc59093aafa9ab43daae0e914c57635c5402d8e3d2130eb9b3cc181de7f0ecf9b22bf99a7815ce16419e200e01846e6b5df8cc7703041bbceb571de6631d2615", +// ), + ]; + for (hex, output) in vec { + let hex = hex; + let bytes: Vec = hex.from_hex().unwrap(); + + assert_eq!(bytes.len(), 213); + + let mut h = [0u64; 8]; + let mut m = [0u64; 16]; + let mut t = [0u64; 2]; + + let rounds = u32::from_be_bytes([bytes[0], bytes[1], bytes[2], bytes[3]]); + let f = match bytes[212] { + 1 => true, + 0 => false, + _ => unreachable!() + }; + + to_u64_slice(&bytes[4..68], &mut h); + to_u64_slice(&bytes[68..196], &mut m); + to_u64_slice(&bytes[196..212], &mut t); + + compress(&mut h, m, t, f, rounds as usize); + + let output: Vec = output.from_hex().unwrap(); + + let mut out = [0u64; 8]; + to_u64_slice(&output[..], &mut out); + + assert_eq!(out, h); + } + } +} diff --git a/util/blooms-db/benches/blooms.rs b/util/blooms-db/benches/blooms.rs index 1cb3bad543..4a0c54fbdb 100644 --- a/util/blooms-db/benches/blooms.rs +++ b/util/blooms-db/benches/blooms.rs @@ -31,8 +31,8 @@ use ethbloom::Bloom; fn blooms_filter_1_million_ok(b: &mut Bencher) { let tempdir = TempDir::new("").unwrap(); let database = Database::open(tempdir.path()).unwrap(); - database.insert_blooms(999_999, iter::once(&Bloom::from(0))).unwrap(); - let bloom = Bloom::from(0x001); + database.insert_blooms(999_999, iter::once(&Bloom::zero())).unwrap(); + let bloom = Bloom::from_low_u64_be(0x001); database.insert_blooms(200_000, iter::once(&bloom)).unwrap(); database.insert_blooms(400_000, iter::once(&bloom)).unwrap(); database.insert_blooms(600_000, iter::once(&bloom)).unwrap(); @@ -48,9 +48,9 @@ fn blooms_filter_1_million_ok(b: &mut Bencher) { fn blooms_filter_1_million_miss(b: &mut Bencher) { let tempdir = TempDir::new("").unwrap(); let database = Database::open(tempdir.path()).unwrap(); - database.insert_blooms(999_999, iter::once(&Bloom::from(0))).unwrap(); - let bloom = Bloom::from(0x001); - let bad_bloom = Bloom::from(0x0001); + database.insert_blooms(999_999, iter::once(&Bloom::zero())).unwrap(); + let bloom = Bloom::from_low_u64_be(0x001); + let bad_bloom = Bloom::from_low_u64_be(0x0001); database.insert_blooms(200_000, iter::once(&bloom)).unwrap(); database.insert_blooms(400_000, iter::once(&bloom)).unwrap(); database.insert_blooms(600_000, iter::once(&bloom)).unwrap(); @@ -66,9 +66,9 @@ fn blooms_filter_1_million_miss(b: &mut Bencher) { fn blooms_filter_1_million_miss_and_ok(b: &mut Bencher) { let tempdir = TempDir::new("").unwrap(); let database = Database::open(tempdir.path()).unwrap(); - database.insert_blooms(999_999, iter::once(&Bloom::from(0))).unwrap(); - let bloom = Bloom::from(0x001); - let bad_bloom = Bloom::from(0x0001); + database.insert_blooms(999_999, iter::once(&Bloom::zero())).unwrap(); + let bloom = Bloom::from_low_u64_be(0x001); + let bad_bloom = Bloom::from_low_u64_be(0x0001); database.insert_blooms(200_000, iter::once(&bloom)).unwrap(); database.insert_blooms(400_000, iter::once(&bloom)).unwrap(); database.insert_blooms(600_000, iter::once(&bloom)).unwrap(); diff --git a/util/blooms-db/src/db.rs b/util/blooms-db/src/db.rs index 7d003f7e27..2a05ec8123 100644 --- a/util/blooms-db/src/db.rs +++ b/util/blooms-db/src/db.rs @@ -21,7 +21,7 @@ use ethbloom; use file::{File, FileIterator}; -fn other_io_err(e: E) -> io::Error where E: Into> { +fn other_io_err(e: E) -> io::Error where E: Into> { io::Error::new(io::ErrorKind::Other, e) } diff --git a/util/network-devp2p/src/host.rs b/util/network-devp2p/src/host.rs index f067260ceb..572f073a0d 100644 --- a/util/network-devp2p/src/host.rs +++ b/util/network-devp2p/src/host.rs @@ -254,6 +254,8 @@ struct ProtocolTimer { } /// Root IO handler. Manages protocol handlers, IO timers and network connections. +/// +/// NOTE: must keep the lock in order of: reserved_nodes (rwlock) -> session (mutex, from sessions) pub struct Host { pub info: RwLock, udp_socket: Mutex>, @@ -715,12 +717,13 @@ impl Host { let session_result = session.lock().readable(io, &self.info.read()); match session_result { Err(e) => { + let reserved_nodes = self.reserved_nodes.read(); let s = session.lock(); trace!(target: "network", "Session read error: {}:{:?} ({:?}) {:?}", token, s.id(), s.remote_addr(), e); match *e.kind() { ErrorKind::Disconnect(DisconnectReason::IncompatibleProtocol) | ErrorKind::Disconnect(DisconnectReason::UselessPeer) => { if let Some(id) = s.id() { - if !self.reserved_nodes.read().contains(id) { + if !reserved_nodes.contains(id) { let mut nodes = self.nodes.write(); nodes.note_failure(&id); nodes.mark_as_useless(id); @@ -734,6 +737,7 @@ impl Host { }, Ok(SessionData::Ready) => { let (_, egress_count, ingress_count) = self.session_count(); + let reserved_nodes = self.reserved_nodes.read(); let mut s = session.lock(); let (min_peers, mut max_peers, reserved_only, self_id) = { let info = self.info.read(); @@ -758,7 +762,7 @@ impl Host { if reserved_only || (s.info.originated && egress_count > min_peers) || (!s.info.originated && ingress_count > max_ingress) { - if !self.reserved_nodes.read().contains(&id) { + if !reserved_nodes.contains(&id) { // only proceed if the connecting peer is reserved. trace!(target: "network", "Disconnecting non-reserved peer {:?}", id); s.disconnect(io, DisconnectReason::TooManyPeers); @@ -973,7 +977,8 @@ impl Host { for i in to_remove { trace!(target: "network", "Removed from node table: {}", i); } - self.nodes.write().update(node_changes, &*self.reserved_nodes.read()); + let reserved_nodes = self.reserved_nodes.read(); + self.nodes.write().update(node_changes, &*reserved_nodes); } pub fn with_context(&self, protocol: ProtocolId, io: &IoContext, action: F) where F: FnOnce(&NetworkContextTrait) { @@ -1059,8 +1064,9 @@ impl IoHandler for Host { }, NODE_TABLE => { trace!(target: "network", "Refreshing node table"); - self.nodes.write().clear_useless(); - self.nodes.write().save(); + let mut nodes = self.nodes.write(); + nodes.clear_useless(); + nodes.save(); }, _ => match self.timers.read().get(&token).cloned() { Some(timer) => match self.handlers.read().get(&timer.protocol).cloned() { diff --git a/util/version/Cargo.toml b/util/version/Cargo.toml index 77f159dc99..db0cae57ed 100644 --- a/util/version/Cargo.toml +++ b/util/version/Cargo.toml @@ -3,7 +3,7 @@ [package] name = "parity-version" # NOTE: this value is used for Parity Ethereum version string (via env CARGO_PKG_VERSION) -version = "2.5.7" +version = "2.5.8" authors = ["Parity Technologies "] build = "build.rs" From 24a4fdf40556048b61c63fb1ede782d72ce64edb Mon Sep 17 00:00:00 2001 From: David Date: Fri, 13 Sep 2019 11:53:49 +0200 Subject: [PATCH 164/168] Don't build rpc with ethcore test-helpers (#11048) --- rpc/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpc/Cargo.toml b/rpc/Cargo.toml index 04de73c73b..e95c48cb96 100644 --- a/rpc/Cargo.toml +++ b/rpc/Cargo.toml @@ -36,7 +36,7 @@ jsonrpc-pubsub = "10.0.1" common-types = { path = "../ethcore/types" } ethash = { path = "../ethash" } -ethcore = { path = "../ethcore", features = ["test-helpers"] } +ethcore = { path = "../ethcore" } ethcore-accounts = { path = "../accounts", optional = true } ethcore-light = { path = "../ethcore/light" } ethcore-logger = { path = "../parity/logger" } From 7c7b181ca07e7a2f76737a2115c8e6cafe940a80 Mon Sep 17 00:00:00 2001 From: s3krit Date: Fri, 13 Sep 2019 15:46:03 +0200 Subject: [PATCH 165/168] v2.5.8-stable (rev2) (#11051) * EIP 1884 Re-pricing of trie-size dependent operations (#10992) * Implement EIP-1283 reenable transition, EIP-1706 and EIP-2200 (#10191) --- ethcore/evm/src/evm.rs | 18 ++++++++----- ethcore/evm/src/instructions.rs | 3 +++ ethcore/evm/src/interpreter/gasometer.rs | 3 +++ ethcore/evm/src/interpreter/mod.rs | 15 ++++++++--- ethcore/evm/src/tests.rs | 26 +++++++++++++++++++ ethcore/src/spec/spec.rs | 33 ++++++++++++++++++++++-- ethcore/vm/src/ext.rs | 2 +- ethcore/vm/src/return_data.rs | 6 +---- ethcore/vm/src/schedule.rs | 28 +++++++++++++++++--- json/src/spec/params.rs | 6 +++++ 10 files changed, 120 insertions(+), 20 deletions(-) diff --git a/ethcore/evm/src/evm.rs b/ethcore/evm/src/evm.rs index f8a08b2b2e..3c88155f2f 100644 --- a/ethcore/evm/src/evm.rs +++ b/ethcore/evm/src/evm.rs @@ -44,12 +44,18 @@ pub trait Finalize { impl Finalize for Result { fn finalize(self, ext: E) -> Result { match self { - Ok(GasLeft::Known(gas_left)) => Ok(FinalizationResult { gas_left: gas_left, apply_state: true, return_data: ReturnData::empty() }), - Ok(GasLeft::NeedsReturn { gas_left, data, apply_state }) => ext.ret(&gas_left, &data, apply_state).map(|gas_left| FinalizationResult { - gas_left: gas_left, - apply_state: apply_state, - return_data: data, - }), + Ok(GasLeft::Known(gas_left)) => { + Ok(FinalizationResult { + gas_left, + apply_state: true, + return_data: ReturnData::empty() + }) + }, + Ok(GasLeft::NeedsReturn { gas_left, data, apply_state }) => { + ext.ret(&gas_left, &data, apply_state).map(|gas_left| + FinalizationResult { gas_left, apply_state, return_data: data } + ) + }, Err(err) => Err(err), } } diff --git a/ethcore/evm/src/instructions.rs b/ethcore/evm/src/instructions.rs index 1580f7b591..b0a66c159e 100644 --- a/ethcore/evm/src/instructions.rs +++ b/ethcore/evm/src/instructions.rs @@ -151,6 +151,8 @@ enum_with_from_u8! { GASLIMIT = 0x45, #[doc = "get chain ID"] CHAINID = 0x46, + #[doc = "get balance of own account"] + SELFBALANCE = 0x47, #[doc = "remove item from stack"] POP = 0x50, @@ -502,6 +504,7 @@ lazy_static! { arr[DIFFICULTY as usize] = Some(InstructionInfo::new("DIFFICULTY", 0, 1, GasPriceTier::Base)); arr[GASLIMIT as usize] = Some(InstructionInfo::new("GASLIMIT", 0, 1, GasPriceTier::Base)); arr[CHAINID as usize] = Some(InstructionInfo::new("CHAINID", 0, 1, GasPriceTier::Base)); + arr[SELFBALANCE as usize] = Some(InstructionInfo::new("SELFBALANCE", 0, 1, GasPriceTier::Low)); arr[POP as usize] = Some(InstructionInfo::new("POP", 1, 0, GasPriceTier::Base)); arr[MLOAD as usize] = Some(InstructionInfo::new("MLOAD", 1, 1, GasPriceTier::VeryLow)); arr[MSTORE as usize] = Some(InstructionInfo::new("MSTORE", 2, 0, GasPriceTier::VeryLow)); diff --git a/ethcore/evm/src/interpreter/gasometer.rs b/ethcore/evm/src/interpreter/gasometer.rs index 26fec2d937..b90540d9e9 100644 --- a/ethcore/evm/src/interpreter/gasometer.rs +++ b/ethcore/evm/src/interpreter/gasometer.rs @@ -121,6 +121,9 @@ impl Gasometer { Request::Gas(Gas::from(1)) }, instructions::SSTORE => { + if schedule.eip1706 && self.current_gas <= Gas::from(schedule.call_stipend) { + return Err(vm::Error::OutOfGas); + } let address = H256::from(stack.peek(0)); let newval = stack.peek(1); let val = U256::from(&*ext.storage_at(&address)?); diff --git a/ethcore/evm/src/interpreter/mod.rs b/ethcore/evm/src/interpreter/mod.rs index 0513f5c9aa..21e7b463b2 100644 --- a/ethcore/evm/src/interpreter/mod.rs +++ b/ethcore/evm/src/interpreter/mod.rs @@ -308,7 +308,12 @@ impl Interpreter { let result = if self.gasometer.is_none() { InterpreterResult::Done(Err(vm::Error::OutOfGas)) } else if self.reader.len() == 0 { - InterpreterResult::Done(Ok(GasLeft::Known(self.gasometer.as_ref().expect("Gasometer None case is checked above; qed").current_gas.as_u256()))) + let current_gas = self.gasometer + .as_ref() + .expect("Gasometer None case is checked above; qed") + .current_gas + .as_u256(); + InterpreterResult::Done(Ok(GasLeft::Known(current_gas))) } else { self.step_inner(ext) }; @@ -317,7 +322,7 @@ impl Interpreter { self.done = true; self.informant.done(); } - return result; + result } /// Inner helper function for step. @@ -446,7 +451,8 @@ impl Interpreter { (instruction == instructions::REVERT && !schedule.have_revert) || ((instruction == instructions::SHL || instruction == instructions::SHR || instruction == instructions::SAR) && !schedule.have_bitwise_shifting) || (instruction == instructions::EXTCODEHASH && !schedule.have_extcodehash) || - (instruction == instructions::CHAINID && !schedule.have_chain_id) + (instruction == instructions::CHAINID && !schedule.have_chain_id) || + (instruction == instructions::SELFBALANCE && !schedule.have_selfbalance) { return Err(vm::Error::BadInstruction { instruction: instruction as u8 @@ -864,6 +870,9 @@ impl Interpreter { instructions::CHAINID => { self.stack.push(ext.chain_id().into()) }, + instructions::SELFBALANCE => { + self.stack.push(ext.balance(&self.params.address)?); + } // Stack instructions diff --git a/ethcore/evm/src/tests.rs b/ethcore/evm/src/tests.rs index 40b6a7561c..73a176ee09 100644 --- a/ethcore/evm/src/tests.rs +++ b/ethcore/evm/src/tests.rs @@ -109,6 +109,32 @@ fn test_origin(factory: super::Factory) { assert_store(&ext, 0, "000000000000000000000000cd1722f2947def4cf144679da39c4c32bdc35681"); } +evm_test!{test_selfbalance: test_selfbalance_int} +fn test_selfbalance(factory: super::Factory) { + let own_addr = Address::from_str("1337000000000000000000000000000000000000").unwrap(); + // 47 SELFBALANCE + // 60 ff PUSH ff + // 55 SSTORE + let code = hex!("47 60 ff 55").to_vec(); + + let mut params = ActionParams::default(); + params.address = own_addr.clone(); + params.gas = U256::from(100_000); + params.code = Some(Arc::new(code)); + let mut ext = FakeExt::new_istanbul(); + ext.balances = { + let mut x = HashMap::new(); + x.insert(own_addr, U256::from(1_025)); // 0x401 + x + }; + let gas_left = { + let vm = factory.create(params, ext.schedule(), ext.depth()); + test_finalize(vm.exec(&mut ext).ok().unwrap()).unwrap() + }; + assert_eq!(gas_left, U256::from(79_992)); // TODO[dvdplm]: do the sums here, SELFBALANCE-5 + PUSH1-3 + ONEBYTE-4 + SSTORE-?? = 100_000 - 79_992 + assert_store(&ext, 0xff, "0000000000000000000000000000000000000000000000000000000000000401"); +} + evm_test!{test_sender: test_sender_int} fn test_sender(factory: super::Factory) { let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap(); diff --git a/ethcore/src/spec/spec.rs b/ethcore/src/spec/spec.rs index 3384f0321e..ec3a8f4aba 100644 --- a/ethcore/src/spec/spec.rs +++ b/ethcore/src/spec/spec.rs @@ -65,7 +65,7 @@ fn fmt_err(f: F) -> String { /// we define a "bugfix" hard fork as any hard fork which /// you would put on-by-default in a new chain. #[derive(Debug, PartialEq, Default)] -#[cfg_attr(any(test, feature = "test-helpers"), derive(Clone))] +#[cfg_attr(any(test, feature = "test-helpers"), derive(Clone))] pub struct CommonParams { /// Account start nonce. pub account_start_nonce: U256, @@ -121,10 +121,16 @@ pub struct CommonParams { pub eip1283_transition: BlockNumber, /// Number of first block where EIP-1283 rules end. pub eip1283_disable_transition: BlockNumber, + /// Number of first block where EIP-1283 rules re-enabled. + pub eip1283_reenable_transition: BlockNumber, /// Number of first block where EIP-1014 rules begin. pub eip1014_transition: BlockNumber, + /// Number of first block where EIP-1706 rules begin. + pub eip1706_transition: BlockNumber, /// Number of first block where EIP-1344 rules begin: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1344.md pub eip1344_transition: BlockNumber, + /// Number of first block where EIP-1884 rules begin:https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1884.md + pub eip1884_transition: BlockNumber, /// Number of first block where EIP-2028 rules begin. pub eip2028_transition: BlockNumber, /// Number of first block where dust cleanup rules (EIP-168 and EIP169) begin. @@ -194,7 +200,18 @@ impl CommonParams { schedule.have_bitwise_shifting = block_number >= self.eip145_transition; schedule.have_extcodehash = block_number >= self.eip1052_transition; schedule.have_chain_id = block_number >= self.eip1344_transition; - schedule.eip1283 = block_number >= self.eip1283_transition && !(block_number >= self.eip1283_disable_transition); + schedule.eip1283 = + (block_number >= self.eip1283_transition && + !(block_number >= self.eip1283_disable_transition)) || + block_number >= self.eip1283_reenable_transition; + schedule.eip1706 = block_number >= self.eip1706_transition; + + if block_number >= self.eip1884_transition { + schedule.have_selfbalance = true; + schedule.sload_gas = 800; + schedule.balance_gas = 700; + schedule.extcodehash_gas = 700; + } if block_number >= self.eip2028_transition { schedule.tx_data_non_zero_gas = 16; } @@ -312,6 +329,14 @@ impl From for CommonParams { BlockNumber::max_value, Into::into, ), + eip1283_reenable_transition: p.eip1283_reenable_transition.map_or_else( + BlockNumber::max_value, + Into::into, + ), + eip1706_transition: p.eip1706_transition.map_or_else( + BlockNumber::max_value, + Into::into, + ), eip1014_transition: p.eip1014_transition.map_or_else( BlockNumber::max_value, Into::into, @@ -320,6 +345,10 @@ impl From for CommonParams { BlockNumber::max_value, Into::into, ), + eip1884_transition: p.eip1884_transition.map_or_else( + BlockNumber::max_value, + Into::into, + ), eip2028_transition: p.eip2028_transition.map_or_else( BlockNumber::max_value, Into::into, diff --git a/ethcore/vm/src/ext.rs b/ethcore/vm/src/ext.rs index 3c3a2335bc..247758c1e5 100644 --- a/ethcore/vm/src/ext.rs +++ b/ethcore/vm/src/ext.rs @@ -91,7 +91,7 @@ pub trait Ext { /// Creates new contract. /// - /// Returns gas_left and contract address if contract creation was succesfull. + /// Returns gas_left and contract address if contract creation was successful. fn create( &mut self, gas: &U256, diff --git a/ethcore/vm/src/return_data.rs b/ethcore/vm/src/return_data.rs index 85fdb361db..38ac23ffdc 100644 --- a/ethcore/vm/src/return_data.rs +++ b/ethcore/vm/src/return_data.rs @@ -44,11 +44,7 @@ impl ReturnData { } /// Create `ReturnData` from give buffer and slice. pub fn new(mem: Vec, offset: usize, size: usize) -> Self { - ReturnData { - mem: mem, - offset: offset, - size: size, - } + ReturnData { mem, offset, size } } } diff --git a/ethcore/vm/src/schedule.rs b/ethcore/vm/src/schedule.rs index 764487e92b..6fad8351e6 100644 --- a/ethcore/vm/src/schedule.rs +++ b/ethcore/vm/src/schedule.rs @@ -15,8 +15,17 @@ // along with Parity Ethereum. If not, see . //! Cost schedule and other parameterisations for the EVM. +use std::collections::HashMap; +use ethereum_types::U256; + +/// Definition of schedules that can be applied to a version. +#[derive(Debug)] +pub enum VersionedSchedule { + PWasm, +} /// Definition of the cost schedule and other parameterisations for the EVM. +#[derive(Debug)] pub struct Schedule { /// Does it support exceptional failed code deposit pub exceptional_failed_code_deposit: bool, @@ -117,10 +126,14 @@ pub struct Schedule { pub have_bitwise_shifting: bool, /// CHAINID opcode enabled. pub have_chain_id: bool, + /// SELFBALANCE opcode enabled. + pub have_selfbalance: bool, /// Kill basic accounts below this balance if touched. pub kill_dust: CleanDustMode, /// Enable EIP-1283 rules pub eip1283: bool, + /// Enable EIP-1706 rules + pub eip1706: bool, /// VM execution does not increase null signed address nonce if this field is true. pub keep_unsigned_nonce: bool, /// Wasm extra schedule settings, if wasm activated @@ -128,6 +141,7 @@ pub struct Schedule { } /// Wasm cost table +#[derive(Debug)] pub struct WasmCosts { /// Default opcode cost pub regular: u32, @@ -181,7 +195,7 @@ impl Default for WasmCosts { } /// Dust accounts cleanup mode. -#[derive(PartialEq, Eq)] +#[derive(Debug, PartialEq, Eq)] pub enum CleanDustMode { /// Dust cleanup is disabled. Off, @@ -212,6 +226,7 @@ impl Schedule { have_return_data: false, have_bitwise_shifting: false, have_chain_id: false, + have_selfbalance: false, have_extcodehash: false, stack_limit: 1024, max_depth: 1024, @@ -256,6 +271,7 @@ impl Schedule { have_static_call: false, kill_dust: CleanDustMode::Off, eip1283: false, + eip1706: false, keep_unsigned_nonce: false, wasm: None, } @@ -281,8 +297,12 @@ impl Schedule { /// Schedule for the Istanbul fork of the Ethereum main net. pub fn new_istanbul() -> Schedule { let mut schedule = Self::new_constantinople(); - schedule.have_chain_id = true; - schedule.tx_data_non_zero_gas = 16; + schedule.have_chain_id = true; // EIP 1344 + schedule.tx_data_non_zero_gas = 16; // EIP 2028 + schedule.sload_gas = 800; // EIP 1884 + schedule.balance_gas = 700; // EIP 1884 + schedule.extcodehash_gas = 700; // EIP 1884 + schedule.have_selfbalance = true; // EIP 1884 schedule } @@ -295,6 +315,7 @@ impl Schedule { have_return_data: false, have_bitwise_shifting: false, have_chain_id: false, + have_selfbalance: false, have_extcodehash: false, stack_limit: 1024, max_depth: 1024, @@ -339,6 +360,7 @@ impl Schedule { have_static_call: false, kill_dust: CleanDustMode::Off, eip1283: false, + eip1706: false, keep_unsigned_nonce: false, wasm: None, } diff --git a/json/src/spec/params.rs b/json/src/spec/params.rs index 7f48c3e9f4..e8b3ded8a9 100644 --- a/json/src/spec/params.rs +++ b/json/src/spec/params.rs @@ -92,10 +92,16 @@ pub struct Params { /// See `CommonParams` docs. pub eip1283_disable_transition: Option, /// See `CommonParams` docs. + pub eip1283_reenable_transition: Option, + /// See `CommonParams` docs. pub eip1014_transition: Option, /// See `CommonParams` docs. + pub eip1706_transition: Option, + /// See `CommonParams` docs. pub eip1344_transition: Option, /// See `CommonParams` docs. + pub eip1884_transition: Option, + /// See `CommonParams` docs. pub eip2028_transition: Option, /// See `CommonParams` docs. pub dust_protection_transition: Option, From c52a6c8fb7188ee01fcf90d8094eac339470767f Mon Sep 17 00:00:00 2001 From: s3krit Date: Mon, 16 Sep 2019 12:00:04 +0200 Subject: [PATCH 166/168] update CHANGELOG.md (#11057) --- CHANGELOG.md | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 05b83e82e7..f8799c194e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,39 @@ -## Parity-Ethereum [v2.5.6](https://github.com/paritytech/parity-ethereum/releases/tag/v2.5.5) +## Parity-Ethereum [v2.5.8](https://github.com/paritytech/parity-ethereum/releases/tag/v2.5.8) + +Parity Ethereum v2.5.8-stable is a patch release that improves security, stability and performance. + +* The most noteworthy improvement in this release is incorporating all the EIPs required for the Istanbul hard fork. +* This release also fixes certain security and performance issues, one of which was suspected to be consensus-threatening but turned out to be benign. Thanks to Martin Holst Swende and Felix Lange from the Ethereum Foundation for bringing the suspicious issue to our attention. + +The full list of included changes: + +* add more tx tests (#11038) +* Fix parallel transactions race-condition (#10995) +* Add blake2_f precompile (#11017) +* [trace] introduce trace failed to Ext (#11019) +* Edit publish-onchain.sh to use https (#11016) +* Fix deadlock in network-devp2p (#11013) +* EIP 1108: Reduce alt_bn128 precompile gas costs (#11008) +* xDai chain support and nodes list update (#10989) +* EIP 2028: transaction gas lowered from 68 to 16 (#10987) +* EIP-1344 Add CHAINID op-code (#10983) +* manual publish jobs for releases, no changes for nightlies (#10977) +* [blooms-db] Fix benchmarks (#10974) +* Verify transaction against its block during import (#10954) +* Better error message for rpc gas price errors (#10931) +* tx-pool: accept local tx with higher gas price when pool full (#10901) +* Fix fork choice (#10837) +* Cleanup unused vm dependencies (#10787) +* Fix compilation on recent nightlies (#10991) +* Don't build rpc with ethcore test-helpers (#11048) +* EIP 1884 Re-pricing of trie-size dependent operations (#10992) +* Implement EIP-1283 reenable transition, EIP-1706 and EIP-2200 (#10191) + +## Parity-Ethereum [v2.5.7](https://github.com/paritytech/parity-ethereum/releases/tag/v2.5.7) + +Parity Ethereum v2.5.7-stable is a bugfix release that fixes a potential DoS attack in the trace_call RPC method. This is a critical upgrade for anyone running Parity nodes with RPC exposed to the public internet (and highly recommended for anyone else). For details see this blog post. + +## Parity-Ethereum [v2.5.6](https://github.com/paritytech/parity-ethereum/releases/tag/v2.5.6) Parity-Ethereum v2.5.6-stable is a bugfix release that improves stability. From b2277f65e40df4664d294b768dd12ac8ed5c7c8d Mon Sep 17 00:00:00 2001 From: s3krit Date: Thu, 26 Sep 2019 11:03:39 +0200 Subject: [PATCH 167/168] v2.5.9-stable (#11089) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * ethcore/res: activate Istanbul on Ropsten, Görli, Rinkeby, Kovan (#11068) * ethcore/res: activate Istanbul on Ropsten block 6485846 * ethcore/res: activate Istanbul on Goerli block 1561651 * ethcore/res: use hex values for Istanbul specs * ethcore/res: fix trailing comma * ethcore/res: be pedantic about EIP-1283 in Petersburg and Istanbul test specs * ethcore/res: activate Istanbul on Rinkeby block 5435345 * ethcore/res: activate Istanbul on Kovan block 14111141 * ethcore/res: fix kovan istanbul number to 0xd751a5 * [json-spec] make blake2 pricing spec more readable (#11034) * [json-spec] make blake2 pricing spec more readable * [ethcore] fix compilation * Manual backport of #11033 --- ethcore/res/ethereum/goerli.json | 22 ++++- ethcore/res/ethereum/istanbul_test.json | 120 +++++++++++++++++++++++ ethcore/res/ethereum/kovan.json | 22 ++++- ethcore/res/ethereum/rinkeby.json | 22 ++++- ethcore/res/ethereum/ropsten.json | 24 ++++- ethcore/res/ethereum/st_peters_test.json | 1 + ethcore/src/builtin.rs | 4 +- ethcore/src/client/evm_test_client.rs | 1 + ethcore/src/ethereum/mod.rs | 6 ++ evmbin/src/main.rs | 5 +- json/src/spec/builtin.rs | 11 ++- json/src/spec/spec.rs | 1 + 12 files changed, 215 insertions(+), 24 deletions(-) create mode 100644 ethcore/res/ethereum/istanbul_test.json diff --git a/ethcore/res/ethereum/goerli.json b/ethcore/res/ethereum/goerli.json index 2a0fdc0cab..e7aaa4c485 100644 --- a/ethcore/res/ethereum/goerli.json +++ b/ethcore/res/ethereum/goerli.json @@ -26,6 +26,11 @@ "eip1052Transition": "0x0", "eip1283Transition": "0x0", "eip1283DisableTransition": "0x0", + "eip1283ReenableTransition": "0x17d433", + "eip1344Transition": "0x17d433", + "eip1706Transition": "0x17d433", + "eip1884Transition": "0x17d433", + "eip2028Transition": "0x17d433", "gasLimitBoundDivisor": "0x400", "maxCodeSize": "0x6000", "maxCodeSizeTransition": "0x0", @@ -126,7 +131,7 @@ "builtin": { "name": "alt_bn128_add", "activate_at": "0x00", - "eip1108_transition": "0x7fffffffffffff", + "eip1108_transition": "0x17d433", "pricing": { "alt_bn128_const_operations": { "price": 500, @@ -140,7 +145,7 @@ "builtin": { "name": "alt_bn128_mul", "activate_at": "0x00", - "eip1108_transition": "0x7fffffffffffff", + "eip1108_transition": "0x17d433", "pricing": { "alt_bn128_const_operations": { "price": 40000, @@ -154,7 +159,7 @@ "builtin": { "name": "alt_bn128_pairing", "activate_at": "0x00", - "eip1108_transition": "0x7fffffffffffff", + "eip1108_transition": "0x17d433", "pricing": { "alt_bn128_pairing": { "base": 100000, @@ -166,7 +171,16 @@ } }, "0x0000000000000000000000000000000000000009": { - "balance": "0x1" + "balance": "0x1", + "builtin": { + "name": "blake2_f", + "activate_at": "0x17d433", + "pricing": { + "blake2_f": { + "gas_per_round": 1 + } + } + } }, "0x000000000000000000000000000000000000000a": { "balance": "0x1" diff --git a/ethcore/res/ethereum/istanbul_test.json b/ethcore/res/ethereum/istanbul_test.json new file mode 100644 index 0000000000..1276dc4c53 --- /dev/null +++ b/ethcore/res/ethereum/istanbul_test.json @@ -0,0 +1,120 @@ +{ + "name": "Istanbul (test)", + "engine": { + "Ethash": { + "params": { + "minimumDifficulty": "0x020000", + "difficultyBoundDivisor": "0x0800", + "durationLimit": "0x0d", + "blockReward": "0x1BC16D674EC80000", + "homesteadTransition": "0x0", + "eip100bTransition": "0x0", + "difficultyBombDelays": { + "0": 5000000 + } + } + } + }, + "params": { + "gasLimitBoundDivisor": "0x0400", + "registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b", + "accountStartNonce": "0x00", + "maximumExtraDataSize": "0x20", + "minGasLimit": "0x1388", + "networkID" : "0x1", + "maxCodeSize": 24576, + "maxCodeSizeTransition": "0x0", + "eip150Transition": "0x0", + "eip160Transition": "0x0", + "eip161abcTransition": "0x0", + "eip161dTransition": "0x0", + "eip140Transition": "0x0", + "eip211Transition": "0x0", + "eip214Transition": "0x0", + "eip155Transition": "0x0", + "eip658Transition": "0x0", + "eip145Transition": "0x0", + "eip1014Transition": "0x0", + "eip1052Transition": "0x0", + "eip1283Transition": "0x0", + "eip1283DisableTransition": "0x0", + "eip1283ReenableTransition": "0x0", + "eip1344Transition": "0x0", + "eip1706Transition": "0x0", + "eip1884Transition": "0x0", + "eip2028Transition": "0x0" + }, + "genesis": { + "seal": { + "ethereum": { + "nonce": "0x0000000000000042", + "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + }, + "difficulty": "0x400000000", + "author": "0x0000000000000000000000000000000000000000", + "timestamp": "0x00", + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "extraData": "0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa", + "gasLimit": "0x1388" + }, + "accounts": { + "0000000000000000000000000000000000000001": { "balance": "1", "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } }, + "0000000000000000000000000000000000000002": { "balance": "1", "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } }, + "0000000000000000000000000000000000000003": { "balance": "1", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } }, + "0000000000000000000000000000000000000004": { "balance": "1", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } }, + "0000000000000000000000000000000000000005": { "builtin": { "name": "modexp", "activate_at": "0x00", "pricing": { "modexp": { "divisor": 20 } } } }, + "0000000000000000000000000000000000000006": { + "builtin": { + "name": "alt_bn128_add", + "activate_at": "0x00", + "eip1108_transition": "0x0", + "pricing": { + "alt_bn128_const_operations": { + "price": 500, + "eip1108_transition_price": 150 + } + } + } + }, + "0000000000000000000000000000000000000007": { + "builtin": { + "name": "alt_bn128_mul", + "activate_at": "0x00", + "eip1108_transition": "0x0", + "pricing": { + "alt_bn128_const_operations": { + "price": 40000, + "eip1108_transition_price": 6000 + } + } + } + }, + "0000000000000000000000000000000000000008": { + "builtin": { + "name": "alt_bn128_pairing", + "activate_at": "0x00", + "eip1108_transition": "0x0", + "pricing": { + "alt_bn128_pairing": { + "base": 100000, + "pair": 80000, + "eip1108_transition_base": 45000, + "eip1108_transition_pair": 34000 + } + } + } + }, + "0000000000000000000000000000000000000009": { + "builtin": { + "name": "blake2_f", + "activate_at": "0x00", + "pricing": { + "blake2_f": { + "gas_per_round": 1 + } + } + } + } + } +} diff --git a/ethcore/res/ethereum/kovan.json b/ethcore/res/ethereum/kovan.json index 7e9bf76169..34755e3ec2 100644 --- a/ethcore/res/ethereum/kovan.json +++ b/ethcore/res/ethereum/kovan.json @@ -64,6 +64,11 @@ "eip1052Transition": "0x8c6180", "eip1283Transition": "0x8c6180", "eip1283DisableTransition": "0x9c7b61", + "eip1283ReenableTransition": "0xd751a5", + "eip1344Transition": "0xd751a5", + "eip1706Transition": "0xd751a5", + "eip1884Transition": "0xd751a5", + "eip2028Transition": "0xd751a5", "kip4Transition": "0x8c6180", "kip6Transition": "0x8c6180" }, @@ -5344,7 +5349,7 @@ "builtin": { "name": "alt_bn128_add", "activate_at": "0x4d50f8", - "eip1108_transition": "0x7fffffffffffff", + "eip1108_transition": "0xd751a5", "pricing": { "alt_bn128_const_operations": { "price": 500, @@ -5357,7 +5362,7 @@ "builtin": { "name": "alt_bn128_mul", "activate_at": "0x4d50f8", - "eip1108_transition": "0x7fffffffffffff", + "eip1108_transition": "0xd751a5", "pricing": { "alt_bn128_const_operations": { "price": 40000, @@ -5370,7 +5375,7 @@ "builtin": { "name": "alt_bn128_pairing", "activate_at": "0x4d50f8", - "eip1108_transition": "0x7fffffffffffff", + "eip1108_transition": "0xd751a5", "pricing": { "alt_bn128_pairing": { "base": 100000, @@ -5381,6 +5386,17 @@ } } }, + "0x0000000000000000000000000000000000000009": { + "builtin": { + "name": "blake2_f", + "activate_at": "0xd751a5", + "pricing": { + "blake2_f": { + "gas_per_round": 1 + } + } + } + }, "0x00521965e7bd230323c423d96c657db5b79d099f": { "balance": "1606938044258990275541962092341162602522202993782792835301376" } diff --git a/ethcore/res/ethereum/rinkeby.json b/ethcore/res/ethereum/rinkeby.json index b6c7abe20d..3945b88118 100644 --- a/ethcore/res/ethereum/rinkeby.json +++ b/ethcore/res/ethereum/rinkeby.json @@ -26,6 +26,11 @@ "eip1052Transition": "0x37db77", "eip1283Transition": "0x37db77", "eip1283DisableTransition": "0x41efd2", + "eip1283ReenableTransition": "0x52efd1", + "eip1344Transition": "0x52efd1", + "eip1706Transition": "0x52efd1", + "eip1884Transition": "0x52efd1", + "eip2028Transition": "0x52efd1", "gasLimitBoundDivisor": "0x400", "maxCodeSize": "0x6000", "maxCodeSizeTransition": "0x0", @@ -120,7 +125,7 @@ "builtin": { "name": "alt_bn128_add", "activate_at": "0xfcc25", - "eip1108_transition": "0x7fffffffffffff", + "eip1108_transition": "0x52efd1", "pricing": { "alt_bn128_const_operations": { "price": 500, @@ -133,7 +138,7 @@ "builtin": { "name": "alt_bn128_mul", "activate_at": "0xfcc25", - "eip1108_transition": "0x7fffffffffffff", + "eip1108_transition": "0x52efd1", "pricing": { "alt_bn128_const_operations": { "price": 40000, @@ -146,7 +151,7 @@ "builtin": { "name": "alt_bn128_pairing", "activate_at": "0xfcc25", - "eip1108_transition": "0x7fffffffffffff", + "eip1108_transition": "0x52efd1", "pricing": { "alt_bn128_pairing": { "base": 100000, @@ -158,7 +163,16 @@ } }, "0x0000000000000000000000000000000000000009": { - "balance": "0x1" + "balance": "0x1", + "builtin": { + "name": "blake2_f", + "activate_at": "0x52efd1", + "pricing": { + "blake2_f": { + "gas_per_round": 1 + } + } + } }, "0x000000000000000000000000000000000000000a": { "balance": "0x1" diff --git a/ethcore/res/ethereum/ropsten.json b/ethcore/res/ethereum/ropsten.json index 2d23a0a297..aefca8682c 100644 --- a/ethcore/res/ethereum/ropsten.json +++ b/ethcore/res/ethereum/ropsten.json @@ -45,7 +45,12 @@ "eip1014Transition": "0x408b70", "eip1052Transition": "0x408b70", "eip1283Transition": "0x408b70", - "eip1283DisableTransition": "0x4b5e82" + "eip1283DisableTransition": "0x4b5e82", + "eip1283ReenableTransition": "0x62f756", + "eip1344Transition": "0x62f756", + "eip1706Transition": "0x62f756", + "eip1884Transition": "0x62f756", + "eip2028Transition": "0x62f756" }, "genesis": { "seal": { @@ -2735,7 +2740,7 @@ "builtin": { "name": "alt_bn128_add", "activate_at": "0x19f0a0", - "eip1108_transition": "0x7fffffffffffff", + "eip1108_transition": "0x62f756", "pricing": { "alt_bn128_const_operations": { "price": 500, @@ -2750,7 +2755,7 @@ "builtin": { "name": "alt_bn128_mul", "activate_at": "0x19f0a0", - "eip1108_transition": "0x7fffffffffffff", + "eip1108_transition": "0x62f756", "pricing": { "alt_bn128_const_operations": { "price": 40000, @@ -2765,7 +2770,7 @@ "builtin": { "name": "alt_bn128_pairing", "activate_at": "0x19f0a0", - "eip1108_transition": "0x7fffffffffffff", + "eip1108_transition": "0x62f756", "pricing": { "alt_bn128_pairing": { "base": 100000, @@ -2777,7 +2782,16 @@ } }, "0x0000000000000000000000000000000000000009": { - "balance": "0x1" + "balance": "0x1", + "builtin": { + "name": "blake2_f", + "activate_at": "0x62f756", + "pricing": { + "blake2_f": { + "gas_per_round": 1 + } + } + } }, "0x000000000000000000000000000000000000000a": { "balance": "0x0" diff --git a/ethcore/res/ethereum/st_peters_test.json b/ethcore/res/ethereum/st_peters_test.json index 9ae2f74894..768e6057fd 100644 --- a/ethcore/res/ethereum/st_peters_test.json +++ b/ethcore/res/ethereum/st_peters_test.json @@ -36,6 +36,7 @@ "eip145Transition": "0x0", "eip1014Transition": "0x0", "eip1052Transition": "0x0", + "eip1283Transition": "0x0", "eip1283DisableTransition": "0x0" }, "genesis": { diff --git a/ethcore/src/builtin.rs b/ethcore/src/builtin.rs index 407ae4865d..bca2aeeaac 100644 --- a/ethcore/src/builtin.rs +++ b/ethcore/src/builtin.rs @@ -235,8 +235,8 @@ impl Builtin { impl From for Builtin { fn from(b: ethjson::spec::Builtin) -> Self { let pricer: Box = match b.pricing { - ethjson::spec::Pricing::Blake2F(cost_per_round) => { - Box::new(cost_per_round) + ethjson::spec::Pricing::Blake2F { gas_per_round } => { + Box::new(gas_per_round) }, ethjson::spec::Pricing::Linear(linear) => { Box::new(Linear { diff --git a/ethcore/src/client/evm_test_client.rs b/ethcore/src/client/evm_test_client.rs index d6c03e65a9..d65e20691e 100644 --- a/ethcore/src/client/evm_test_client.rs +++ b/ethcore/src/client/evm_test_client.rs @@ -94,6 +94,7 @@ impl<'a> EvmTestClient<'a> { ForkSpec::Byzantium => Some(ethereum::new_byzantium_test()), ForkSpec::Constantinople => Some(ethereum::new_constantinople_test()), ForkSpec::ConstantinopleFix => Some(ethereum::new_constantinople_fix_test()), + ForkSpec::Istanbul => Some(ethereum::new_istanbul_test()), ForkSpec::EIP158ToByzantiumAt5 => Some(ethereum::new_transition_test()), ForkSpec::FrontierToHomesteadAt5 | ForkSpec::HomesteadToDaoAt5 | ForkSpec::HomesteadToEIP150At5 => None, } diff --git a/ethcore/src/ethereum/mod.rs b/ethcore/src/ethereum/mod.rs index b0810ee4aa..f66eb453ad 100644 --- a/ethcore/src/ethereum/mod.rs +++ b/ethcore/src/ethereum/mod.rs @@ -166,6 +166,9 @@ pub fn new_constantinople_test() -> Spec { load(None, include_bytes!("../../res/ /// Create a new Foundation St. Peter's (Contantinople Fix) era spec. pub fn new_constantinople_fix_test() -> Spec { load(None, include_bytes!("../../res/ethereum/st_peters_test.json")) } +/// Create a new Foundation Istanbul era spec. +pub fn new_istanbul_test() -> Spec { load(None, include_bytes!("../../res/ethereum/istanbul_test.json")) } + /// Create a new Musicoin-MCIP3-era spec. pub fn new_mcip3_test() -> Spec { load(None, include_bytes!("../../res/ethereum/mcip3_test.json")) } @@ -189,6 +192,9 @@ pub fn new_constantinople_test_machine() -> EthereumMachine { load_machine(inclu /// Create a new Foundation St. Peter's (Contantinople Fix) era spec. pub fn new_constantinople_fix_test_machine() -> EthereumMachine { load_machine(include_bytes!("../../res/ethereum/st_peters_test.json")) } +/// Create a new Foundation Istanbul era spec. +pub fn new_istanbul_test_machine() -> EthereumMachine { load_machine(include_bytes!("../../res/ethereum/istanbul_test.json")) } + /// Create a new Musicoin-MCIP3-era spec. pub fn new_mcip3_test_machine() -> EthereumMachine { load_machine(include_bytes!("../../res/ethereum/mcip3_test.json")) } diff --git a/evmbin/src/main.rs b/evmbin/src/main.rs index 6e1260189e..48c1e85817 100644 --- a/evmbin/src/main.rs +++ b/evmbin/src/main.rs @@ -83,8 +83,11 @@ Transaction options: --gas-price WEI Supplied gas price as hex (without 0x). State test options: + --chain CHAIN Run only from specific chain name (i.e. one of EIP150, EIP158, + Frontier, Homestead, Byzantium, Constantinople, + ConstantinopleFix, Istanbul, EIP158ToByzantiumAt5, FrontierToHomesteadAt5, + HomesteadToDaoAt5, HomesteadToEIP150At5). --only NAME Runs only a single test matching the name. - --chain CHAIN Run only tests from specific chain. General options: --json Display verbose results in JSON. diff --git a/json/src/spec/builtin.rs b/json/src/spec/builtin.rs index 20ebbc3c63..c4f9f4e1ec 100644 --- a/json/src/spec/builtin.rs +++ b/json/src/spec/builtin.rs @@ -18,8 +18,6 @@ use uint::Uint; -/// Price per round of Blake2 compression. -pub type Blake2F = u64; /// Linear pricing. #[derive(Debug, PartialEq, Deserialize, Clone)] @@ -69,7 +67,10 @@ pub struct AltBn128Pairing { #[serde(rename_all = "snake_case")] pub enum Pricing { /// Pricing for Blake2 compression function: each call costs the same amount per round. - Blake2F(Blake2F), + Blake2F { + /// Price per round of Blake2 compression function. + gas_per_round: u64, + }, /// Linear pricing. Linear(Linear), /// Pricing for modular exponentiation. @@ -117,11 +118,11 @@ mod tests { let s = r#"{ "name": "blake2_f", "activate_at": "0xffffff", - "pricing": { "blake2_f": 123 } + "pricing": { "blake2_f": { "gas_per_round": 123 } } }"#; let deserialized: Builtin = serde_json::from_str(s).unwrap(); assert_eq!(deserialized.name, "blake2_f"); - assert_eq!(deserialized.pricing, Pricing::Blake2F(123)); + assert_eq!(deserialized.pricing, Pricing::Blake2F { gas_per_round: 123 }); assert!(deserialized.activate_at.is_some()); } diff --git a/json/src/spec/spec.rs b/json/src/spec/spec.rs index 68824cad99..013320c27d 100644 --- a/json/src/spec/spec.rs +++ b/json/src/spec/spec.rs @@ -31,6 +31,7 @@ pub enum ForkSpec { Byzantium, Constantinople, ConstantinopleFix, + Istanbul, EIP158ToByzantiumAt5, FrontierToHomesteadAt5, HomesteadToDaoAt5, From 06c7096054764ccca1672182be4de98372cc7ebb Mon Sep 17 00:00:00 2001 From: s3krit Date: Thu, 26 Sep 2019 12:38:49 +0200 Subject: [PATCH 168/168] Update CHANGELOG.md and version (#11093) * Update CHANGELOG.md and version --- CHANGELOG.md | 9 +++++++++ Cargo.lock | 12 ++++++------ Cargo.toml | 2 +- util/version/Cargo.toml | 2 +- 4 files changed, 17 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f8799c194e..8ba5eb20b1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +## Parity-Ethereum [v2.5.9](https://github.com/paritytech/parity-ethereum/releases/tag/v2.5.8) + +Parity Ethereum v2.5.9-stable is a patch release that adds the block numbers for activating the Istanbul hardfork on test networks: Ropsten, Görli, Rinkeby and Kovan. + +The full list of included changes: + +* ethcore/res: activate Istanbul on Ropsten, Görli, Rinkeby, Kovan (#11068) +* [json-spec] make blake2 pricing spec more readable (#11034) + ## Parity-Ethereum [v2.5.8](https://github.com/paritytech/parity-ethereum/releases/tag/v2.5.8) Parity Ethereum v2.5.8-stable is a patch release that improves security, stability and performance. diff --git a/Cargo.lock b/Cargo.lock index 22bbd6657d..59e3334987 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2421,7 +2421,7 @@ dependencies = [ "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", "jni 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "panic_hook 0.1.0", - "parity-ethereum 2.5.8", + "parity-ethereum 2.5.9", "tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-current-thread 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2451,7 +2451,7 @@ dependencies = [ [[package]] name = "parity-ethereum" -version = "2.5.8" +version = "2.5.9" dependencies = [ "ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2504,7 +2504,7 @@ dependencies = [ "parity-rpc 1.12.0", "parity-runtime 0.1.0", "parity-updater 1.12.0", - "parity-version 2.5.8", + "parity-version 2.5.9", "parity-whisper 0.1.0", "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2647,7 +2647,7 @@ dependencies = [ "parity-crypto 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-runtime 0.1.0", "parity-updater 1.12.0", - "parity-version 2.5.8", + "parity-version 2.5.9", "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2745,7 +2745,7 @@ dependencies = [ "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-hash-fetch 1.12.0", "parity-path 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-version 2.5.8", + "parity-version 2.5.9", "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2755,7 +2755,7 @@ dependencies = [ [[package]] name = "parity-version" -version = "2.5.8" +version = "2.5.9" dependencies = [ "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "rlp 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index caf8bd68cd..560512b346 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ description = "Parity Ethereum client" name = "parity-ethereum" # NOTE Make sure to update util/version/Cargo.toml as well -version = "2.5.8" +version = "2.5.9" license = "GPL-3.0" authors = ["Parity Technologies "] diff --git a/util/version/Cargo.toml b/util/version/Cargo.toml index db0cae57ed..b824894bfb 100644 --- a/util/version/Cargo.toml +++ b/util/version/Cargo.toml @@ -3,7 +3,7 @@ [package] name = "parity-version" # NOTE: this value is used for Parity Ethereum version string (via env CARGO_PKG_VERSION) -version = "2.5.8" +version = "2.5.9" authors = ["Parity Technologies "] build = "build.rs"