Merge pull request #1887 from ethcore/stable-staging

Backports to stable
This commit is contained in:
Marek Kotewicz 2016-08-09 13:51:33 +02:00 committed by GitHub
commit a66fd116e4
7 changed files with 120 additions and 59 deletions

84
Cargo.lock generated
View File

@ -104,14 +104,17 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "byteorder"
version = "0.5.2"
name = "bytes"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "bytes"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
version = "0.4.0-dev"
source = "git+https://github.com/carllerche/bytes#6529f6392a9717585b8d67e1db96e6fa0fb6cb1f"
dependencies = [
"stable-heap 0.1.0 (git+https://github.com/carllerche/stable-heap?rev=3c5cd1ca47)",
]
[[package]]
name = "cfg-if"
@ -164,7 +167,7 @@ version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
"url 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"url 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -293,7 +296,7 @@ dependencies = [
"serde_codegen 0.7.9 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"syntex 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)",
"url 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"url 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -370,7 +373,7 @@ dependencies = [
"parity-dapps-signer 0.6.0 (git+https://github.com/ethcore/parity-ui.git)",
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"ws 0.5.0 (git+https://github.com/ethcore/ws-rs.git?branch=stable)",
"ws 0.5.2 (git+https://github.com/ethcore/ws-rs.git?branch=mio-upstream-stable)",
]
[[package]]
@ -563,7 +566,7 @@ dependencies = [
"traitobject 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"unicase 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"url 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"url 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"vecio 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -605,7 +608,7 @@ dependencies = [
"lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"mio 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"miow 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"miow 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"slab 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -721,7 +724,7 @@ dependencies = [
"bytes 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"miow 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"miow 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"net2 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)",
"nix 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"slab 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
@ -737,7 +740,7 @@ dependencies = [
"bytes 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"miow 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"miow 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"net2 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)",
"nix 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"slab 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
@ -745,9 +748,24 @@ dependencies = [
"winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "mio"
version = "0.6.0-dev"
source = "git+https://github.com/carllerche/mio?rev=62ec763c9cc34d8a452ed0392c575c50ddd5fc8d#62ec763c9cc34d8a452ed0392c575c50ddd5fc8d"
dependencies = [
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"miow 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"net2 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)",
"nix 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"slab 0.2.0 (git+https://github.com/carllerche/slab?rev=5476efcafb)",
"winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "miow"
version = "0.1.2"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -795,6 +813,19 @@ dependencies = [
"libc 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "nix"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"semver 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)",
"void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "nodrop"
version = "0.1.6"
@ -1193,11 +1224,8 @@ dependencies = [
[[package]]
name = "sha1"
version = "0.1.1"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byteorder 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "sha3"
@ -1211,6 +1239,11 @@ name = "slab"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "slab"
version = "0.2.0"
source = "git+https://github.com/carllerche/slab?rev=5476efcafb#5476efcafbc5ef4d7315b1bea3f756d8a1fe975e"
[[package]]
name = "slab"
version = "0.2.0"
@ -1230,6 +1263,11 @@ name = "spmc"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "stable-heap"
version = "0.1.0"
source = "git+https://github.com/carllerche/stable-heap?rev=3c5cd1ca47#3c5cd1ca4706f167a1de85658b5af0d6d3e65165"
[[package]]
name = "strsim"
version = "0.3.0"
@ -1386,7 +1424,7 @@ dependencies = [
[[package]]
name = "url"
version = "1.1.1"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"idna 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1450,15 +1488,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "ws"
version = "0.5.0"
source = "git+https://github.com/ethcore/ws-rs.git?branch=stable#a876fc115c3ef50a17c8822c9bd2f6e94473e005"
version = "0.5.2"
source = "git+https://github.com/ethcore/ws-rs.git?branch=mio-upstream-stable#afbff59776ce16ccec5ee9e218b8891830ee6fdf"
dependencies = [
"bytes 0.4.0-dev (git+https://github.com/carllerche/bytes)",
"httparse 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"mio 0.5.1 (git+https://github.com/ethcore/mio?branch=v0.5.x)",
"mio 0.6.0-dev (git+https://github.com/carllerche/mio?rev=62ec763c9cc34d8a452ed0392c575c50ddd5fc8d)",
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
"sha1 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"url 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"sha1 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"slab 0.2.0 (git+https://github.com/carllerche/slab?rev=5476efcafb)",
"url 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]

View File

@ -96,12 +96,10 @@ pub struct Miner {
// NOTE [ToDr] When locking always lock in this order!
transaction_queue: Mutex<TransactionQueue>,
sealing_work: Mutex<SealingWork>,
// for sealing...
options: MinerOptions,
next_allowed_reseal: Mutex<Instant>,
sealing_block_last_request: Mutex<u64>,
// for sealing...
options: MinerOptions,
gas_range_target: RwLock<(U256, U256)>,
author: RwLock<Address>,
extra_data: RwLock<Bytes>,
@ -651,11 +649,11 @@ impl MinerService for Miner {
fn update_sealing(&self, chain: &MiningBlockChainClient) {
trace!(target: "miner", "update_sealing");
let requires_reseal = {
let has_local_transactions = self.transaction_queue.lock().unwrap().has_local_pending_transactions();
let mut sealing_work = self.sealing_work.lock().unwrap();
if sealing_work.enabled {
trace!(target: "miner", "update_sealing: sealing enabled");
let current_no = chain.chain_info().best_block_number;
let has_local_transactions = self.transaction_queue.lock().unwrap().has_local_pending_transactions();
let last_request = *self.sealing_block_last_request.lock().unwrap();
let should_disable_sealing = !self.forced_sealing()
&& !has_local_transactions

View File

@ -40,7 +40,8 @@ pub fn verify_block_basic(header: &Header, bytes: &[u8], engine: &Engine) -> Res
try!(verify_header(&header, engine));
try!(verify_block_integrity(bytes, &header.transactions_root, &header.uncles_hash));
try!(engine.verify_block_basic(&header, Some(bytes)));
for u in Rlp::new(bytes).at(2).iter().map(|rlp| rlp.as_val::<Header>()) {
for u in try!(UntrustedRlp::new(bytes).at(2)).iter().map(|rlp| rlp.as_val::<Header>()) {
let u = try!(u);
try!(verify_header(&u, engine));
try!(engine.verify_block_basic(&u, None));
}
@ -58,8 +59,8 @@ pub fn verify_block_basic(header: &Header, bytes: &[u8], engine: &Engine) -> Res
/// Returns a `PreverifiedBlock` structure populated with transactions
pub fn verify_block_unordered(header: Header, bytes: Bytes, engine: &Engine) -> Result<PreverifiedBlock, Error> {
try!(engine.verify_block_unordered(&header, Some(&bytes)));
for u in Rlp::new(&bytes).at(2).iter().map(|rlp| rlp.as_val::<Header>()) {
try!(engine.verify_block_unordered(&u, None));
for u in try!(UntrustedRlp::new(&bytes).at(2)).iter().map(|rlp| rlp.as_val::<Header>()) {
try!(engine.verify_block_unordered(&try!(u), None));
}
// Verify transactions.
let mut transactions = Vec::new();
@ -84,7 +85,7 @@ pub fn verify_block_family(header: &Header, bytes: &[u8], engine: &Engine, bc: &
try!(verify_parent(&header, &parent));
try!(engine.verify_block_family(&header, &parent, Some(bytes)));
let num_uncles = Rlp::new(bytes).at(2).item_count();
let num_uncles = try!(UntrustedRlp::new(bytes).at(2)).item_count();
if num_uncles != 0 {
if num_uncles > engine.maximum_uncle_count() {
return Err(From::from(BlockError::TooManyUncles(OutOfBounds { min: None, max: Some(engine.maximum_uncle_count()), found: num_uncles })));
@ -106,7 +107,8 @@ pub fn verify_block_family(header: &Header, bytes: &[u8], engine: &Engine, bc: &
}
}
for uncle in Rlp::new(bytes).at(2).iter().map(|rlp| rlp.as_val::<Header>()) {
for uncle in try!(UntrustedRlp::new(bytes).at(2)).iter().map(|rlp| rlp.as_val::<Header>()) {
let uncle = try!(uncle);
if excluded.contains(&uncle.hash()) {
return Err(From::from(BlockError::UncleInChain(uncle.hash())))
}
@ -210,13 +212,13 @@ fn verify_parent(header: &Header, parent: &Header) -> Result<(), Error> {
/// Verify block data against header: transactions root and uncles hash.
fn verify_block_integrity(block: &[u8], transactions_root: &H256, uncles_hash: &H256) -> Result<(), Error> {
let block = Rlp::new(block);
let tx = block.at(1);
let block = UntrustedRlp::new(block);
let tx = try!(block.at(1));
let expected_root = &ordered_trie_root(tx.iter().map(|r| r.as_raw().to_vec()).collect()); //TODO: get rid of vectors here
if expected_root != transactions_root {
return Err(From::from(BlockError::InvalidTransactionsRoot(Mismatch { expected: expected_root.clone(), found: transactions_root.clone() })))
}
let expected_uncles = &block.at(2).as_raw().sha3();
let expected_uncles = &try!(block.at(2)).as_raw().sha3();
if expected_uncles != uncles_hash {
return Err(From::from(BlockError::InvalidUnclesHash(Mismatch { expected: expected_uncles.clone(), found: uncles_hash.clone() })))
}

View File

@ -15,7 +15,7 @@ rand = "0.3.14"
jsonrpc-core = "2.0"
log = "0.3"
env_logger = "0.3"
ws = { git = "https://github.com/ethcore/ws-rs.git", branch = "stable" }
ws = { git = "https://github.com/ethcore/ws-rs.git", branch = "mio-upstream-stable" }
ethcore-util = { path = "../util" }
ethcore-rpc = { path = "../rpc" }
parity-dapps-signer = { git = "https://github.com/ethcore/parity-ui.git", version = "0.6", optional = true}

View File

@ -46,7 +46,7 @@ impl TimeProvider for DefaultTimeProvider {
}
/// No of seconds the hash is valid
const TIME_THRESHOLD: u64 = 2;
const TIME_THRESHOLD: u64 = 7;
const TOKEN_LENGTH: usize = 16;
/// Manages authorization codes for `SignerUIs`
@ -102,7 +102,7 @@ impl<T: TimeProvider> AuthCodes<T> {
let now = self.now.now();
// check time
if time >= now + TIME_THRESHOLD || time <= now - TIME_THRESHOLD {
warn!(target: "signer", "Received old authentication request.");
warn!(target: "signer", "Received old authentication request. ({} vs {})", now, time);
return false;
}
@ -169,8 +169,8 @@ mod tests {
fn should_return_false_if_hash_is_valid_but_time_is_invalid() {
// given
let code = "23521352asdfasdfadf";
let time = 105;
let time2 = 95;
let time = 107;
let time2 = 93;
let codes = AuthCodes::new(vec![code.into()], || 100);
// when

View File

@ -142,7 +142,9 @@ impl ws::Handler for Session {
fn on_message(&mut self, msg: ws::Message) -> ws::Result<()> {
let req = try!(msg.as_text());
match self.handler.handle_request(req) {
Some(res) => self.out.send(res),
Some(res) => {
self.out.send(res)
},
None => Ok(()),
}
}

View File

@ -193,6 +193,16 @@ enum PeerAsking {
Heads,
}
#[derive(Clone, Eq, PartialEq)]
enum ForkConfirmation {
/// Fork block confirmation pending.
Unconfirmed,
/// Peers chain is too short to confirm the fork.
TooShort,
/// Fork is confurmed.
Confirmed,
}
#[derive(Clone)]
/// Syncing peer information
struct PeerInfo {
@ -218,13 +228,17 @@ struct PeerInfo {
ask_time: f64,
/// Pending request is expird and result should be ignored
expired: bool,
/// Peer fork confirmed
confirmed: bool,
/// Peer fork confirmation status
confirmation: ForkConfirmation,
}
impl PeerInfo {
fn is_available(&self) -> bool {
self.confirmed && !self.expired
fn can_sync(&self) -> bool {
self.confirmation == ForkConfirmation::Confirmed && !self.expired
}
fn is_allowed(&self) -> bool {
self.confirmation != ForkConfirmation::Unconfirmed && !self.expired
}
}
@ -301,8 +315,8 @@ impl ChainSync {
highest_block_number: self.highest_block.map(|n| max(n, self.last_imported_block)),
blocks_received: if self.last_imported_block > self.starting_block { self.last_imported_block - self.starting_block } else { 0 },
blocks_total: match self.highest_block { Some(x) if x > self.starting_block => x - self.starting_block, _ => 0 },
num_peers: self.peers.values().filter(|p| p.confirmed).count(),
num_active_peers: self.peers.values().filter(|p| p.confirmed && p.asking != PeerAsking::Nothing).count(),
num_peers: self.peers.values().filter(|p| p.is_allowed()).count(),
num_active_peers: self.peers.values().filter(|p| p.is_allowed() && p.asking != PeerAsking::Nothing).count(),
mem_used:
self.blocks.heap_size()
+ self.peers.heap_size_of_children()
@ -324,7 +338,7 @@ impl ChainSync {
p.asking_blocks.clear();
p.asking_hash = None;
// mark any pending requests as expired
if p.asking != PeerAsking::Nothing && p.confirmed {
if p.asking != PeerAsking::Nothing && p.is_allowed() {
p.expired = true;
}
}
@ -378,7 +392,7 @@ impl ChainSync {
asking_hash: None,
ask_time: 0f64,
expired: false,
confirmed: self.fork_block.is_none(),
confirmation: if self.fork_block.is_none() { ForkConfirmation::Confirmed } else { ForkConfirmation::Unconfirmed },
};
trace!(target: "sync", "New peer {} (protocol: {}, network: {:?}, difficulty: {:?}, latest:{}, genesis:{})", peer_id, peer.protocol_version, peer.network_id, peer.difficulty, peer.latest_hash, peer.genesis);
@ -421,14 +435,19 @@ impl ChainSync {
Some(ref mut peer) if peer.asking == PeerAsking::ForkHeader => {
let item_count = r.item_count();
if item_count == 0 || (item_count == 1 && try!(r.at(0)).as_raw().sha3() == self.fork_block.unwrap().1) {
trace!(target: "sync", "{}: Confirmed peer", peer_id);
peer.asking = PeerAsking::Nothing;
peer.confirmed = true;
if item_count == 0 {
trace!(target: "sync", "{}: Chain is too short to confirm the block", peer_id);
peer.confirmation = ForkConfirmation::TooShort;
} else {
trace!(target: "sync", "{}: Confirmed peer", peer_id);
peer.confirmation = ForkConfirmation::Confirmed;
}
true
} else {
trace!(target: "sync", "{}: Fork mismatch", peer_id);
io.disconnect_peer(peer_id);
false
return Ok(());
}
},
_ => false,
@ -580,7 +599,7 @@ impl ChainSync {
/// Called by peer once it has new block bodies
#[cfg_attr(feature="dev", allow(cyclomatic_complexity))]
fn on_peer_new_block(&mut self, io: &mut SyncIo, peer_id: PeerId, r: &UntrustedRlp) -> Result<(), PacketDecodeError> {
if !self.peers.get(&peer_id).map_or(false, |p| p.confirmed) {
if !self.peers.get(&peer_id).map_or(false, |p| p.can_sync()) {
trace!(target: "sync", "Ignoring new block from unconfirmed peer {}", peer_id);
return Ok(());
}
@ -648,7 +667,7 @@ impl ChainSync {
/// Handles `NewHashes` packet. Initiates headers download for any unknown hashes.
fn on_peer_new_hashes(&mut self, io: &mut SyncIo, peer_id: PeerId, r: &UntrustedRlp) -> Result<(), PacketDecodeError> {
if !self.peers.get(&peer_id).map_or(false, |p| p.confirmed) {
if !self.peers.get(&peer_id).map_or(false, |p| p.can_sync()) {
trace!(target: "sync", "Ignoring new hashes from unconfirmed peer {}", peer_id);
return Ok(());
}
@ -735,7 +754,7 @@ impl ChainSync {
/// Resume downloading
fn continue_sync(&mut self, io: &mut SyncIo) {
let mut peers: Vec<(PeerId, U256)> = self.peers.iter().filter_map(|(k, p)|
if p.is_available() { Some((*k, p.difficulty.unwrap_or_else(U256::zero))) } else { None }).collect();
if p.can_sync() { Some((*k, p.difficulty.unwrap_or_else(U256::zero))) } else { None }).collect();
thread_rng().shuffle(&mut peers); //TODO: sort by rating
trace!(target: "sync", "Syncing with {}/{} peers", self.active_peers.len(), peers.len());
for (p, _) in peers {
@ -743,7 +762,7 @@ impl ChainSync {
self.sync_peer(io, p, false);
}
}
if self.state != SyncState::Waiting && !self.peers.values().any(|p| p.asking != PeerAsking::Nothing && p.is_available()) {
if self.state != SyncState::Waiting && !self.peers.values().any(|p| p.asking != PeerAsking::Nothing && p.can_sync()) {
self.complete_sync();
}
}
@ -769,7 +788,7 @@ impl ChainSync {
}
let (peer_latest, peer_difficulty) = {
let peer = self.peers.get_mut(&peer_id).unwrap();
if peer.asking != PeerAsking::Nothing || !peer.is_available() {
if peer.asking != PeerAsking::Nothing || !peer.can_sync() {
return;
}
if self.state == SyncState::Waiting {
@ -1031,7 +1050,7 @@ impl ChainSync {
if !io.is_chain_queue_empty() {
return Ok(());
}
if !self.peers.get(&peer_id).map_or(false, |p| p.confirmed) {
if !self.peers.get(&peer_id).map_or(false, |p| p.can_sync()) {
trace!(target: "sync", "{} Ignoring transactions from unconfirmed/unknown peer", peer_id);
}
@ -1687,7 +1706,7 @@ mod tests {
asking_hash: None,
ask_time: 0f64,
expired: false,
confirmed: true,
confirmation: super::ForkConfirmation::Confirmed,
});
sync
}