Merge branch 'master' into json_tests_split
This commit is contained in:
commit
7aba3032c8
14
.travis.yml
14
.travis.yml
@ -4,11 +4,13 @@ language: rust
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- /^beta-.*$/
|
||||
- /^stable-.*$/
|
||||
matrix:
|
||||
fast_finish: true
|
||||
include:
|
||||
- rust: nightly
|
||||
env: FEATURES="--features ethcore/json-tests" KCOV_FEATURES="" TARGETS="-p ethash -p ethcore-util -p ethcore -p ethsync -p ethcore-rpc -p parity"
|
||||
env: FEATURES="--features ethcore/json-tests" KCOV_FEATURES="" TARGETS="-p ethash -p ethcore-util -p ethcore -p ethsync -p ethcore-rpc -p parity" ARCHIVE_SUFFIX="-${TRAVIS_OS_NAME}-${TRAVIS_TAG}"
|
||||
cache:
|
||||
apt: true
|
||||
directories:
|
||||
@ -30,6 +32,7 @@ script:
|
||||
- cargo build --release --verbose ${FEATURES}
|
||||
- cargo test --release --verbose ${FEATURES} ${TARGETS}
|
||||
- cargo bench --no-run ${FEATURES} ${TARGETS}
|
||||
- tar cvzf parity${ARCHIVE_SUFFIX}.tar.gz -C target/release parity
|
||||
after_success: |
|
||||
wget https://github.com/SimonKagstrom/kcov/archive/master.tar.gz &&
|
||||
tar xzf master.tar.gz && mkdir kcov-master/build && cd kcov-master/build && cmake .. && make && make install DESTDIR=../tmp && cd ../.. &&
|
||||
@ -53,3 +56,12 @@ env:
|
||||
global:
|
||||
- secure: 3sUjNi9mhdL5h1GTm8LONnDN/SYvUHT+WSkMl93h3nYiLCQXk8eZaPS98AS7oOaTsfW4UvnwckVFCFl49ttInsv4cd/TkAxmrJHe6kPyS9/4NWUdmP8BjicbBvL/ioSdXMECMEYzPDLV+I3KhtC2LcB6ceDEl/XwMOJlzbGf7RbtcXGVQgMLqSYY1YKjQA4vbT5nFgIS/sZu3Z9yFgN0GafnihKcizqoHhdJjs/zxmX+qJepnC6o3V6KcFnS7QHhM1JOr85twE6S422UlvNaEb5ovwLPqmOl5+fA+6shbx4AxFTY6E9Iors+OVY/JliFhrqOdCt0i2P1FUHN4kbGZQkf0rphN/ZOI2uKNFTOyXiPvppfo/ZemKmcqkwkqP9+lf5QqYmtE6hsAYagxn49xJZILl8tAYbdqxF5gxa+TEVrfsBFtz/Sv3q8QhKQNPAmjEcKyMatyEreLUIFEpFTGIco8jN4eXeSoLRdJ+Z75ihttfQWhNfUDgNL30iQLy0AgFSsh/cyb5M8y9lxrGDzDTogvaiKGwr/V45sPkcXWCkmOgMdINqBB6ZtdL3bGHdyjmYj+y3btjf3aP11k++BL0fXIaKn25aS/p/9iyGb1FyGCM03o4ZRQ3YhTOvfMRfRGf6nWbaMx9upv8o5ShSdysewhrnh3082r7u896ny1Ho=
|
||||
- secure: 0/FeVvFl3AhBW0TCPoujY9zOAYoUNMlAz3XjC04vlc4Ksfx0lGU3KFi97LlALxMWV0lfwQc7ixSe2vTgQVQuLVSU9XEW40fQgEjJlmLca2RcRx1kfzJDypuWSiCME7MWmLPH0ac4COdTDS1z5WGggv5YB7GQPCzFvcmOOaPYtF29ngCtkyB2HmNkY/W3omHFEk7Si6bsmOSHZiOAhivPl6ixnGpFyTEKPyraMMqPIj5rbEGkzgeLTiXf2ur143n/tnSr8tmP1MfQi9yS8/ONidMqnxUeuLkeNnb82zj9pVJhVXq0xF44WXJ8Za1jm0ByiTakgqpm8Juk822qjvtNulJ1XZW/fyZQZaN1dy3uq5Ud3W8wS9M7VIVl8CoXozzDpIsdPeUAtkAxeHBsZqL1vAH2yC1YJA7HPySMYzCjYqkJ2r62xYk0gXmNXphfU+F/X/rHzHsTMJPONJ54HQwu12m7zVlKIYBGHgEXg/HAM/g4ljUzl6WWR/nHH/tQM8ND/8FpHluJSZJWacq/1QNhVdTq2x6cqws2fs5A7nVpccR9+6RRgYgv6+YS2LxvFzByuZveGGoKif+uMECXN876j40araUqU528Yz9i8bHJlnM3coRBndaLNWByLcUyXCB9r9IUosUu41rr+L2mVzkSDm0GicuNCzqvzYQ9Q6QY4uQ=
|
||||
|
||||
deploy:
|
||||
provider: releases
|
||||
api_key:
|
||||
secure: 3sUjNi9mhdL5h1GTm8LONnDN/SYvUHT+WSkMl93h3nYiLCQXk8eZaPS98AS7oOaTsfW4UvnwckVFCFl49ttInsv4cd/TkAxmrJHe6kPyS9/4NWUdmP8BjicbBvL/ioSdXMECMEYzPDLV+I3KhtC2LcB6ceDEl/XwMOJlzbGf7RbtcXGVQgMLqSYY1YKjQA4vbT5nFgIS/sZu3Z9yFgN0GafnihKcizqoHhdJjs/zxmX+qJepnC6o3V6KcFnS7QHhM1JOr85twE6S422UlvNaEb5ovwLPqmOl5+fA+6shbx4AxFTY6E9Iors+OVY/JliFhrqOdCt0i2P1FUHN4kbGZQkf0rphN/ZOI2uKNFTOyXiPvppfo/ZemKmcqkwkqP9+lf5QqYmtE6hsAYagxn49xJZILl8tAYbdqxF5gxa+TEVrfsBFtz/Sv3q8QhKQNPAmjEcKyMatyEreLUIFEpFTGIco8jN4eXeSoLRdJ+Z75ihttfQWhNfUDgNL30iQLy0AgFSsh/cyb5M8y9lxrGDzDTogvaiKGwr/V45sPkcXWCkmOgMdINqBB6ZtdL3bGHdyjmYj+y3btjf3aP11k++BL0fXIaKn25aS/p/9iyGb1FyGCM03o4ZRQ3YhTOvfMRfRGf6nWbaMx9upv8o5ShSdysewhrnh3082r7u896ny1Ho=
|
||||
skip_cleanup: true
|
||||
file: parity${ARCHIVE_SUFFIX}.tar.gz
|
||||
on:
|
||||
tags: true
|
||||
|
@ -9,6 +9,7 @@ use engine::Engine;
|
||||
use views::*;
|
||||
use header::*;
|
||||
use service::*;
|
||||
use client::BlockStatus;
|
||||
|
||||
/// Block queue status
|
||||
#[derive(Debug)]
|
||||
@ -41,7 +42,7 @@ pub struct BlockQueue {
|
||||
deleting: Arc<AtomicBool>,
|
||||
ready_signal: Arc<QueueSignal>,
|
||||
empty: Arc<Condvar>,
|
||||
processing: HashSet<H256>
|
||||
processing: RwLock<HashSet<H256>>
|
||||
}
|
||||
|
||||
struct UnVerifiedBlock {
|
||||
@ -106,7 +107,7 @@ impl BlockQueue {
|
||||
verification: verification.clone(),
|
||||
verifiers: verifiers,
|
||||
deleting: deleting.clone(),
|
||||
processing: HashSet::new(),
|
||||
processing: RwLock::new(HashSet::new()),
|
||||
empty: empty.clone(),
|
||||
}
|
||||
}
|
||||
@ -196,11 +197,22 @@ impl BlockQueue {
|
||||
}
|
||||
}
|
||||
|
||||
/// Check if the block is currently in the queue
|
||||
pub fn block_status(&self, hash: &H256) -> BlockStatus {
|
||||
if self.processing.read().unwrap().contains(&hash) {
|
||||
return BlockStatus::Queued;
|
||||
}
|
||||
if self.verification.lock().unwrap().bad.contains(&hash) {
|
||||
return BlockStatus::Bad;
|
||||
}
|
||||
BlockStatus::Unknown
|
||||
}
|
||||
|
||||
/// Add a block to the queue.
|
||||
pub fn import_block(&mut self, bytes: Bytes) -> ImportResult {
|
||||
let header = BlockView::new(&bytes).header();
|
||||
let h = header.hash();
|
||||
if self.processing.contains(&h) {
|
||||
if self.processing.read().unwrap().contains(&h) {
|
||||
return Err(ImportError::AlreadyQueued);
|
||||
}
|
||||
{
|
||||
@ -217,7 +229,7 @@ impl BlockQueue {
|
||||
|
||||
match verify_block_basic(&header, &bytes, self.engine.deref().deref()) {
|
||||
Ok(()) => {
|
||||
self.processing.insert(h.clone());
|
||||
self.processing.write().unwrap().insert(h.clone());
|
||||
self.verification.lock().unwrap().unverified.push_back(UnVerifiedBlock { header: header, bytes: bytes });
|
||||
self.more_to_verify.notify_all();
|
||||
Ok(h)
|
||||
@ -235,10 +247,12 @@ impl BlockQueue {
|
||||
let mut verification_lock = self.verification.lock().unwrap();
|
||||
let mut verification = verification_lock.deref_mut();
|
||||
verification.bad.insert(hash.clone());
|
||||
self.processing.write().unwrap().remove(&hash);
|
||||
let mut new_verified = VecDeque::new();
|
||||
for block in verification.verified.drain(..) {
|
||||
if verification.bad.contains(&block.header.parent_hash) {
|
||||
verification.bad.insert(block.header.hash());
|
||||
self.processing.write().unwrap().remove(&block.header.hash());
|
||||
}
|
||||
else {
|
||||
new_verified.push_back(block);
|
||||
@ -247,6 +261,15 @@ impl BlockQueue {
|
||||
verification.verified = new_verified;
|
||||
}
|
||||
|
||||
/// Mark given block as processed
|
||||
pub fn mark_as_good(&mut self, hashes: &[H256]) {
|
||||
let mut processing = self.processing.write().unwrap();
|
||||
for h in hashes {
|
||||
processing.remove(&h);
|
||||
}
|
||||
//TODO: reward peers
|
||||
}
|
||||
|
||||
/// Removes up to `max` verified blocks from the queue
|
||||
pub fn drain(&mut self, max: usize) -> Vec<PreVerifiedBlock> {
|
||||
let mut verification = self.verification.lock().unwrap();
|
||||
@ -254,7 +277,6 @@ impl BlockQueue {
|
||||
let mut result = Vec::with_capacity(count);
|
||||
for _ in 0..count {
|
||||
let block = verification.verified.pop_front().unwrap();
|
||||
self.processing.remove(&block.header.hash());
|
||||
result.push(block);
|
||||
}
|
||||
self.ready_signal.reset();
|
||||
@ -294,6 +316,7 @@ mod tests {
|
||||
use block_queue::*;
|
||||
use tests::helpers::*;
|
||||
use error::*;
|
||||
use views::*;
|
||||
|
||||
fn get_test_queue() -> BlockQueue {
|
||||
let spec = get_test_spec();
|
||||
@ -339,11 +362,14 @@ mod tests {
|
||||
#[test]
|
||||
fn returns_ok_for_drained_duplicates() {
|
||||
let mut queue = get_test_queue();
|
||||
if let Err(e) = queue.import_block(get_good_dummy_block()) {
|
||||
let block = get_good_dummy_block();
|
||||
let hash = BlockView::new(&block).header().hash().clone();
|
||||
if let Err(e) = queue.import_block(block) {
|
||||
panic!("error importing block that is valid by definition({:?})", e);
|
||||
}
|
||||
queue.flush();
|
||||
queue.drain(10);
|
||||
queue.mark_as_good(&[ hash ]);
|
||||
|
||||
if let Err(e) = queue.import_block(get_good_dummy_block()) {
|
||||
panic!("error importing block that has already been drained ({:?})", e);
|
||||
|
@ -17,7 +17,7 @@ use verification::*;
|
||||
use block::*;
|
||||
|
||||
/// General block status
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Eq, PartialEq)]
|
||||
pub enum BlockStatus {
|
||||
/// Part of the blockchain.
|
||||
InChain,
|
||||
@ -206,6 +206,7 @@ impl Client {
|
||||
let mut bad = HashSet::new();
|
||||
let _import_lock = self.import_lock.lock();
|
||||
let blocks = self.block_queue.write().unwrap().drain(128);
|
||||
let mut good_blocks = Vec::with_capacity(128);
|
||||
for block in blocks {
|
||||
if bad.contains(&block.header.parent_hash) {
|
||||
self.block_queue.write().unwrap().mark_as_bad(&block.header.hash());
|
||||
@ -258,6 +259,8 @@ impl Client {
|
||||
break;
|
||||
}
|
||||
|
||||
good_blocks.push(header.hash().clone());
|
||||
|
||||
self.chain.write().unwrap().insert_block(&block.bytes); //TODO: err here?
|
||||
let ancient = if header.number() >= HISTORY { Some(header.number() - HISTORY) } else { None };
|
||||
match result.drain().commit(header.number(), &header.hash(), ancient.map(|n|(n, self.chain.read().unwrap().block_hash(n).unwrap()))) {
|
||||
@ -271,6 +274,7 @@ impl Client {
|
||||
trace!(target: "client", "Imported #{} ({})", header.number(), header.hash());
|
||||
ret += 1;
|
||||
}
|
||||
self.block_queue.write().unwrap().mark_as_good(&good_blocks);
|
||||
ret
|
||||
}
|
||||
|
||||
@ -325,7 +329,11 @@ impl BlockChainClient for Client {
|
||||
}
|
||||
|
||||
fn block_status(&self, hash: &H256) -> BlockStatus {
|
||||
if self.chain.read().unwrap().is_known(&hash) { BlockStatus::InChain } else { BlockStatus::Unknown }
|
||||
if self.chain.read().unwrap().is_known(&hash) {
|
||||
BlockStatus::InChain
|
||||
} else {
|
||||
self.block_queue.read().unwrap().block_status(hash)
|
||||
}
|
||||
}
|
||||
|
||||
fn block_total_difficulty(&self, hash: &H256) -> Option<U256> {
|
||||
@ -372,6 +380,9 @@ impl BlockChainClient for Client {
|
||||
if self.chain.read().unwrap().is_known(&header.hash()) {
|
||||
return Err(ImportError::AlreadyInChain);
|
||||
}
|
||||
if self.block_status(&header.parent_hash) == BlockStatus::Unknown {
|
||||
return Err(ImportError::UnknownParent);
|
||||
}
|
||||
self.block_queue.write().unwrap().import_block(bytes)
|
||||
}
|
||||
|
||||
|
@ -130,14 +130,16 @@ pub enum BlockError {
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
/// TODO [arkpar] Please document me
|
||||
/// Import to the block queue result
|
||||
pub enum ImportError {
|
||||
/// TODO [arkpar] Please document me
|
||||
/// Bad block detected
|
||||
Bad(Option<Error>),
|
||||
/// TODO [arkpar] Please document me
|
||||
/// Already in the block chain
|
||||
AlreadyInChain,
|
||||
/// TODO [arkpar] Please document me
|
||||
/// Already in the block queue
|
||||
AlreadyQueued,
|
||||
/// Unknown parent
|
||||
UnknownParent,
|
||||
}
|
||||
|
||||
impl From<Error> for ImportError {
|
||||
|
@ -15,31 +15,30 @@ pub enum Error {
|
||||
/// `BadJumpDestination` is returned when execution tried to move
|
||||
/// to position that wasn't marked with JUMPDEST instruction
|
||||
BadJumpDestination {
|
||||
/// TODO [Tomusdrw] Please document me
|
||||
/// Position the code tried to jump to.
|
||||
destination: usize
|
||||
},
|
||||
/// `BadInstructions` is returned when given instruction is not supported
|
||||
BadInstruction {
|
||||
/// TODO [Tomusdrw] Please document me
|
||||
/// Unrecognized opcode
|
||||
instruction: u8,
|
||||
},
|
||||
/// `StackUnderflow` when there is not enough stack elements to execute instruction
|
||||
/// First parameter says how many elements were needed and the second how many were actually on Stack
|
||||
StackUnderflow {
|
||||
/// TODO [Tomusdrw] Please document me
|
||||
/// Invoked instruction
|
||||
instruction: &'static str,
|
||||
/// TODO [Tomusdrw] Please document me
|
||||
/// How many stack elements was requested by instruction
|
||||
wanted: usize,
|
||||
/// TODO [Tomusdrw] Please document me
|
||||
/// How many elements were on stack
|
||||
on_stack: usize
|
||||
},
|
||||
/// When execution would exceed defined Stack Limit
|
||||
OutOfStack {
|
||||
/// TODO [Tomusdrw] Please document me
|
||||
/// Invoked instruction
|
||||
instruction: &'static str,
|
||||
/// TODO [Tomusdrw] Please document me
|
||||
wanted: usize,
|
||||
/// TODO [Tomusdrw] Please document me
|
||||
/// How many stack elements instruction wanted to push
|
||||
wanted: usize,
|
||||
/// What was the stack limit
|
||||
limit: usize
|
||||
},
|
||||
/// Returned on evm internal error. Should never be ignored during development.
|
||||
|
@ -5,12 +5,12 @@ use std::fmt;
|
||||
use evm::Evm;
|
||||
|
||||
#[derive(Clone)]
|
||||
/// TODO [Tomusdrw] Please document me
|
||||
/// Type of EVM to use.
|
||||
pub enum VMType {
|
||||
/// TODO [Tomusdrw] Please document me
|
||||
#[allow(dead_code)] // crated only by jit
|
||||
/// JIT EVM
|
||||
Jit,
|
||||
/// TODO [Tomusdrw] Please document me
|
||||
/// RUST EVM
|
||||
Interpreter
|
||||
}
|
||||
|
||||
|
@ -1,11 +1,10 @@
|
||||
///! Rust VM implementation
|
||||
|
||||
use common::*;
|
||||
use evm;
|
||||
use super::instructions as instructions;
|
||||
use super::instructions::Instruction;
|
||||
use std::marker::Copy;
|
||||
use evm::{MessageCallResult, ContractCreateResult};
|
||||
use evm::{self, MessageCallResult, ContractCreateResult};
|
||||
|
||||
#[cfg(not(feature = "evm-debug"))]
|
||||
macro_rules! evm_debug {
|
||||
|
@ -150,7 +150,7 @@ fn test_add(factory: super::Factory) {
|
||||
};
|
||||
|
||||
assert_eq!(gas_left, U256::from(79_988));
|
||||
assert_eq!(ext.store.get(&H256::new()).unwrap(), &H256::from_str("fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe").unwrap());
|
||||
assert_store(&ext, 0, "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe");
|
||||
}
|
||||
|
||||
evm_test!{test_sha3: test_sha3_jit, test_sha3_int}
|
||||
@ -170,7 +170,7 @@ fn test_sha3(factory: super::Factory) {
|
||||
};
|
||||
|
||||
assert_eq!(gas_left, U256::from(79_961));
|
||||
assert_eq!(ext.store.get(&H256::new()).unwrap(), &H256::from_str("c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470").unwrap());
|
||||
assert_store(&ext, 0, "c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470");
|
||||
}
|
||||
|
||||
evm_test!{test_address: test_address_jit, test_address_int}
|
||||
@ -190,7 +190,7 @@ fn test_address(factory: super::Factory) {
|
||||
};
|
||||
|
||||
assert_eq!(gas_left, U256::from(79_995));
|
||||
assert_eq!(ext.store.get(&H256::new()).unwrap(), &H256::from_str("0000000000000000000000000f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap());
|
||||
assert_store(&ext, 0, "0000000000000000000000000f572e5295c57f15886f9b263e2f6d2d6c7b5ec6");
|
||||
}
|
||||
|
||||
evm_test!{test_origin: test_origin_jit, test_origin_int}
|
||||
@ -212,7 +212,7 @@ fn test_origin(factory: super::Factory) {
|
||||
};
|
||||
|
||||
assert_eq!(gas_left, U256::from(79_995));
|
||||
assert_eq!(ext.store.get(&H256::new()).unwrap(), &H256::from_str("000000000000000000000000cd1722f2947def4cf144679da39c4c32bdc35681").unwrap());
|
||||
assert_store(&ext, 0, "000000000000000000000000cd1722f2947def4cf144679da39c4c32bdc35681");
|
||||
}
|
||||
|
||||
// TODO [todr] Fails with Signal 11 on JIT
|
||||
@ -235,7 +235,7 @@ fn test_sender(factory: super::Factory) {
|
||||
};
|
||||
|
||||
assert_eq!(gas_left, U256::from(79_995));
|
||||
assert_eq!(ext.store.get(&H256::new()).unwrap(), &H256::from_str("000000000000000000000000cd1722f2947def4cf144679da39c4c32bdc35681").unwrap());
|
||||
assert_store(&ext, 0, "000000000000000000000000cd1722f2947def4cf144679da39c4c32bdc35681");
|
||||
}
|
||||
|
||||
evm_test!{test_extcodecopy: test_extcodecopy_jit, test_extcodecopy_int}
|
||||
@ -270,7 +270,7 @@ fn test_extcodecopy(factory: super::Factory) {
|
||||
};
|
||||
|
||||
assert_eq!(gas_left, U256::from(79_935));
|
||||
assert_eq!(ext.store.get(&H256::new()).unwrap(), &H256::from_str("6005600055000000000000000000000000000000000000000000000000000000").unwrap());
|
||||
assert_store(&ext, 0, "6005600055000000000000000000000000000000000000000000000000000000");
|
||||
}
|
||||
|
||||
evm_test!{test_log_empty: test_log_empty_jit, test_log_empty_int}
|
||||
@ -369,7 +369,7 @@ fn test_calldataload(factory: super::Factory) {
|
||||
};
|
||||
|
||||
assert_eq!(gas_left, U256::from(79_991));
|
||||
assert_eq!(ext.store.get(&H256::new()).unwrap(), &H256::from_str("23ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff23").unwrap());
|
||||
assert_store(&ext, 0, "23ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff23");
|
||||
|
||||
}
|
||||
|
||||
@ -390,7 +390,7 @@ fn test_author(factory: super::Factory) {
|
||||
};
|
||||
|
||||
assert_eq!(gas_left, U256::from(79_995));
|
||||
assert_eq!(ext.store.get(&H256::new()).unwrap(), &H256::from_str("0000000000000000000000000f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap());
|
||||
assert_store(&ext, 0, "0000000000000000000000000f572e5295c57f15886f9b263e2f6d2d6c7b5ec6");
|
||||
}
|
||||
|
||||
evm_test!{test_timestamp: test_timestamp_jit, test_timestamp_int}
|
||||
@ -410,7 +410,7 @@ fn test_timestamp(factory: super::Factory) {
|
||||
};
|
||||
|
||||
assert_eq!(gas_left, U256::from(79_995));
|
||||
assert_eq!(ext.store.get(&H256::new()).unwrap(), &H256::from_str("0000000000000000000000000000000000000000000000000000000000001234").unwrap());
|
||||
assert_store(&ext, 0, "0000000000000000000000000000000000000000000000000000000000001234");
|
||||
}
|
||||
|
||||
evm_test!{test_number: test_number_jit, test_number_int}
|
||||
@ -430,7 +430,7 @@ fn test_number(factory: super::Factory) {
|
||||
};
|
||||
|
||||
assert_eq!(gas_left, U256::from(79_995));
|
||||
assert_eq!(ext.store.get(&H256::new()).unwrap(), &H256::from_str("0000000000000000000000000000000000000000000000000000000000001234").unwrap());
|
||||
assert_store(&ext, 0, "0000000000000000000000000000000000000000000000000000000000001234");
|
||||
}
|
||||
|
||||
evm_test!{test_difficulty: test_difficulty_jit, test_difficulty_int}
|
||||
@ -450,7 +450,7 @@ fn test_difficulty(factory: super::Factory) {
|
||||
};
|
||||
|
||||
assert_eq!(gas_left, U256::from(79_995));
|
||||
assert_eq!(ext.store.get(&H256::new()).unwrap(), &H256::from_str("0000000000000000000000000000000000000000000000000000000000001234").unwrap());
|
||||
assert_store(&ext, 0, "0000000000000000000000000000000000000000000000000000000000001234");
|
||||
}
|
||||
|
||||
evm_test!{test_gas_limit: test_gas_limit_jit, test_gas_limit_int}
|
||||
@ -470,6 +470,321 @@ fn test_gas_limit(factory: super::Factory) {
|
||||
};
|
||||
|
||||
assert_eq!(gas_left, U256::from(79_995));
|
||||
assert_eq!(ext.store.get(&H256::new()).unwrap(), &H256::from_str("0000000000000000000000000000000000000000000000000000000000001234").unwrap());
|
||||
assert_store(&ext, 0, "0000000000000000000000000000000000000000000000000000000000001234");
|
||||
}
|
||||
|
||||
evm_test!{test_mul: test_mul_jit, test_mul_int}
|
||||
fn test_mul(factory: super::Factory) {
|
||||
let code = "65012365124623626543219002600055".from_hex().unwrap();
|
||||
|
||||
let mut params = ActionParams::default();
|
||||
params.gas = U256::from(100_000);
|
||||
params.code = Some(code);
|
||||
let mut ext = FakeExt::new();
|
||||
|
||||
let gas_left = {
|
||||
let vm = factory.create();
|
||||
vm.exec(params, &mut ext).unwrap()
|
||||
};
|
||||
|
||||
assert_store(&ext, 0, "000000000000000000000000000000000000000000000000734349397b853383");
|
||||
assert_eq!(gas_left, U256::from(79_983));
|
||||
}
|
||||
|
||||
evm_test!{test_sub: test_sub_jit, test_sub_int}
|
||||
fn test_sub(factory: super::Factory) {
|
||||
let code = "65012365124623626543219003600055".from_hex().unwrap();
|
||||
|
||||
let mut params = ActionParams::default();
|
||||
params.gas = U256::from(100_000);
|
||||
params.code = Some(code);
|
||||
let mut ext = FakeExt::new();
|
||||
|
||||
let gas_left = {
|
||||
let vm = factory.create();
|
||||
vm.exec(params, &mut ext).unwrap()
|
||||
};
|
||||
|
||||
assert_store(&ext, 0, "0000000000000000000000000000000000000000000000000000012364ad0302");
|
||||
assert_eq!(gas_left, U256::from(79_985));
|
||||
}
|
||||
|
||||
evm_test!{test_div: test_div_jit, test_div_int}
|
||||
fn test_div(factory: super::Factory) {
|
||||
let code = "65012365124623626543219004600055".from_hex().unwrap();
|
||||
|
||||
let mut params = ActionParams::default();
|
||||
params.gas = U256::from(100_000);
|
||||
params.code = Some(code);
|
||||
let mut ext = FakeExt::new();
|
||||
|
||||
let gas_left = {
|
||||
let vm = factory.create();
|
||||
vm.exec(params, &mut ext).unwrap()
|
||||
};
|
||||
|
||||
assert_store(&ext, 0, "000000000000000000000000000000000000000000000000000000000002e0ac");
|
||||
assert_eq!(gas_left, U256::from(79_983));
|
||||
}
|
||||
|
||||
evm_test!{test_div_zero: test_div_zero_jit, test_div_zero_int}
|
||||
fn test_div_zero(factory: super::Factory) {
|
||||
let code = "6501236512462360009004600055".from_hex().unwrap();
|
||||
|
||||
let mut params = ActionParams::default();
|
||||
params.gas = U256::from(100_000);
|
||||
params.code = Some(code);
|
||||
let mut ext = FakeExt::new();
|
||||
|
||||
let gas_left = {
|
||||
let vm = factory.create();
|
||||
vm.exec(params, &mut ext).unwrap()
|
||||
};
|
||||
|
||||
assert_store(&ext, 0, "0000000000000000000000000000000000000000000000000000000000000000");
|
||||
assert_eq!(gas_left, U256::from(94_983));
|
||||
}
|
||||
|
||||
evm_test!{test_mod: test_mod_jit, test_mod_int}
|
||||
fn test_mod(factory: super::Factory) {
|
||||
let code = "650123651246236265432290066000556501236512462360009006600155".from_hex().unwrap();
|
||||
|
||||
let mut params = ActionParams::default();
|
||||
params.gas = U256::from(100_000);
|
||||
params.code = Some(code);
|
||||
let mut ext = FakeExt::new();
|
||||
|
||||
let gas_left = {
|
||||
let vm = factory.create();
|
||||
vm.exec(params, &mut ext).unwrap()
|
||||
};
|
||||
|
||||
assert_store(&ext, 0, "0000000000000000000000000000000000000000000000000000000000076b4b");
|
||||
assert_store(&ext, 1, "0000000000000000000000000000000000000000000000000000000000000000");
|
||||
assert_eq!(gas_left, U256::from(74_966));
|
||||
}
|
||||
|
||||
evm_test!{test_smod: test_smod_jit, test_smod_int}
|
||||
fn test_smod(factory: super::Factory) {
|
||||
let code = "650123651246236265432290076000556501236512462360009007600155".from_hex().unwrap();
|
||||
|
||||
let mut params = ActionParams::default();
|
||||
params.gas = U256::from(100_000);
|
||||
params.code = Some(code);
|
||||
let mut ext = FakeExt::new();
|
||||
|
||||
let gas_left = {
|
||||
let vm = factory.create();
|
||||
vm.exec(params, &mut ext).unwrap()
|
||||
};
|
||||
|
||||
assert_store(&ext, 0, "0000000000000000000000000000000000000000000000000000000000076b4b");
|
||||
assert_store(&ext, 1, "0000000000000000000000000000000000000000000000000000000000000000");
|
||||
assert_eq!(gas_left, U256::from(74_966));
|
||||
}
|
||||
|
||||
evm_test!{test_sdiv: test_sdiv_jit, test_sdiv_int}
|
||||
fn test_sdiv(factory: super::Factory) {
|
||||
let code = "650123651246236265432290056000556501236512462360009005600155".from_hex().unwrap();
|
||||
|
||||
let mut params = ActionParams::default();
|
||||
params.gas = U256::from(100_000);
|
||||
params.code = Some(code);
|
||||
let mut ext = FakeExt::new();
|
||||
|
||||
let gas_left = {
|
||||
let vm = factory.create();
|
||||
vm.exec(params, &mut ext).unwrap()
|
||||
};
|
||||
|
||||
assert_store(&ext, 0, "000000000000000000000000000000000000000000000000000000000002e0ac");
|
||||
assert_store(&ext, 1, "0000000000000000000000000000000000000000000000000000000000000000");
|
||||
assert_eq!(gas_left, U256::from(74_966));
|
||||
}
|
||||
|
||||
evm_test!{test_exp: test_exp_jit, test_exp_int}
|
||||
fn test_exp(factory: super::Factory) {
|
||||
let code = "6016650123651246230a6000556001650123651246230a6001556000650123651246230a600255".from_hex().unwrap();
|
||||
|
||||
let mut params = ActionParams::default();
|
||||
params.gas = U256::from(100_000);
|
||||
params.code = Some(code);
|
||||
let mut ext = FakeExt::new();
|
||||
|
||||
let gas_left = {
|
||||
let vm = factory.create();
|
||||
vm.exec(params, &mut ext).unwrap()
|
||||
};
|
||||
|
||||
assert_store(&ext, 0, "90fd23767b60204c3d6fc8aec9e70a42a3f127140879c133a20129a597ed0c59");
|
||||
assert_store(&ext, 1, "0000000000000000000000000000000000000000000000000000012365124623");
|
||||
assert_store(&ext, 2, "0000000000000000000000000000000000000000000000000000000000000001");
|
||||
assert_eq!(gas_left, U256::from(39_923));
|
||||
}
|
||||
|
||||
evm_test!{test_comparison: test_comparison_jit, test_comparison_int}
|
||||
fn test_comparison(factory: super::Factory) {
|
||||
let code = "601665012365124623818181811060005511600155146002556415235412358014600355".from_hex().unwrap();
|
||||
|
||||
let mut params = ActionParams::default();
|
||||
params.gas = U256::from(100_000);
|
||||
params.code = Some(code);
|
||||
let mut ext = FakeExt::new();
|
||||
|
||||
let gas_left = {
|
||||
let vm = factory.create();
|
||||
vm.exec(params, &mut ext).unwrap()
|
||||
};
|
||||
|
||||
assert_store(&ext, 0, "0000000000000000000000000000000000000000000000000000000000000000");
|
||||
assert_store(&ext, 1, "0000000000000000000000000000000000000000000000000000000000000001");
|
||||
assert_store(&ext, 2, "0000000000000000000000000000000000000000000000000000000000000000");
|
||||
assert_store(&ext, 3, "0000000000000000000000000000000000000000000000000000000000000001");
|
||||
assert_eq!(gas_left, U256::from(49_952));
|
||||
}
|
||||
|
||||
evm_test!{test_signed_comparison: test_signed_comparison_jit, test_signed_comparison_int}
|
||||
fn test_signed_comparison(factory: super::Factory) {
|
||||
let code = "60106000036010818112600055136001556010601060000381811260025513600355".from_hex().unwrap();
|
||||
|
||||
let mut params = ActionParams::default();
|
||||
params.gas = U256::from(100_000);
|
||||
params.code = Some(code);
|
||||
let mut ext = FakeExt::new();
|
||||
|
||||
let gas_left = {
|
||||
let vm = factory.create();
|
||||
vm.exec(params, &mut ext).unwrap()
|
||||
};
|
||||
|
||||
assert_store(&ext, 0, "0000000000000000000000000000000000000000000000000000000000000000");
|
||||
assert_store(&ext, 1, "0000000000000000000000000000000000000000000000000000000000000001");
|
||||
assert_store(&ext, 2, "0000000000000000000000000000000000000000000000000000000000000001");
|
||||
assert_store(&ext, 3, "0000000000000000000000000000000000000000000000000000000000000000");
|
||||
assert_eq!(gas_left, U256::from(49_940));
|
||||
}
|
||||
|
||||
evm_test!{test_bitops: test_bitops_jit, test_bitops_int}
|
||||
fn test_bitops(factory: super::Factory) {
|
||||
let code = "60ff610ff08181818116600055176001551860025560008015600355198015600455600555".from_hex().unwrap();
|
||||
|
||||
let mut params = ActionParams::default();
|
||||
params.gas = U256::from(150_000);
|
||||
params.code = Some(code);
|
||||
let mut ext = FakeExt::new();
|
||||
|
||||
let gas_left = {
|
||||
let vm = factory.create();
|
||||
vm.exec(params, &mut ext).unwrap()
|
||||
};
|
||||
|
||||
assert_store(&ext, 0, "00000000000000000000000000000000000000000000000000000000000000f0");
|
||||
assert_store(&ext, 1, "0000000000000000000000000000000000000000000000000000000000000fff");
|
||||
assert_store(&ext, 2, "0000000000000000000000000000000000000000000000000000000000000f0f");
|
||||
assert_store(&ext, 3, "0000000000000000000000000000000000000000000000000000000000000001");
|
||||
assert_store(&ext, 4, "0000000000000000000000000000000000000000000000000000000000000000");
|
||||
assert_store(&ext, 5, "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
|
||||
assert_eq!(gas_left, U256::from(44_937));
|
||||
}
|
||||
|
||||
evm_test!{test_addmod_mulmod: test_addmod_mulmod_jit, test_addmod_mulmod_int}
|
||||
fn test_addmod_mulmod(factory: super::Factory) {
|
||||
let code = "60ff60f060108282820860005509600155600060f0601082828208196002550919600355".from_hex().unwrap();
|
||||
|
||||
let mut params = ActionParams::default();
|
||||
params.gas = U256::from(100_000);
|
||||
params.code = Some(code);
|
||||
let mut ext = FakeExt::new();
|
||||
|
||||
let gas_left = {
|
||||
let vm = factory.create();
|
||||
vm.exec(params, &mut ext).unwrap()
|
||||
};
|
||||
|
||||
assert_store(&ext, 0, "0000000000000000000000000000000000000000000000000000000000000001");
|
||||
assert_store(&ext, 1, "000000000000000000000000000000000000000000000000000000000000000f");
|
||||
assert_store(&ext, 2, "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
|
||||
assert_store(&ext, 3, "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
|
||||
assert_eq!(gas_left, U256::from(19_914));
|
||||
}
|
||||
|
||||
evm_test!{test_byte: test_byte_jit, test_byte_int}
|
||||
fn test_byte(factory: super::Factory) {
|
||||
let code = "60f061ffff1a600055610fff601f1a600155".from_hex().unwrap();
|
||||
|
||||
let mut params = ActionParams::default();
|
||||
params.gas = U256::from(100_000);
|
||||
params.code = Some(code);
|
||||
let mut ext = FakeExt::new();
|
||||
|
||||
let gas_left = {
|
||||
let vm = factory.create();
|
||||
vm.exec(params, &mut ext).unwrap()
|
||||
};
|
||||
|
||||
assert_store(&ext, 0, "0000000000000000000000000000000000000000000000000000000000000000");
|
||||
assert_store(&ext, 1, "00000000000000000000000000000000000000000000000000000000000000ff");
|
||||
assert_eq!(gas_left, U256::from(74_976));
|
||||
}
|
||||
|
||||
evm_test!{test_signextend: test_signextend_jit, test_signextend_int}
|
||||
fn test_signextend(factory: super::Factory) {
|
||||
let code = "610fff60020b60005560ff60200b600155".from_hex().unwrap();
|
||||
|
||||
let mut params = ActionParams::default();
|
||||
params.gas = U256::from(100_000);
|
||||
params.code = Some(code);
|
||||
let mut ext = FakeExt::new();
|
||||
|
||||
let gas_left = {
|
||||
let vm = factory.create();
|
||||
vm.exec(params, &mut ext).unwrap()
|
||||
};
|
||||
|
||||
assert_store(&ext, 0, "0000000000000000000000000000000000000000000000000000000000000fff");
|
||||
assert_store(&ext, 1, "00000000000000000000000000000000000000000000000000000000000000ff");
|
||||
assert_eq!(gas_left, U256::from(59_972));
|
||||
}
|
||||
|
||||
|
||||
evm_test!{test_badinstruction: test_badinstruction_jit, test_badinstruction_int}
|
||||
fn test_badinstruction(factory: super::Factory) {
|
||||
let code = "af".from_hex().unwrap();
|
||||
|
||||
let mut params = ActionParams::default();
|
||||
params.gas = U256::from(100_000);
|
||||
params.code = Some(code);
|
||||
let mut ext = FakeExt::new();
|
||||
|
||||
let err = {
|
||||
let vm = factory.create();
|
||||
vm.exec(params, &mut ext).unwrap_err()
|
||||
};
|
||||
|
||||
match err {
|
||||
evm::Error::BadInstruction { instruction: 0xaf } => (),
|
||||
_ => assert!(false, "Expected bad instruction")
|
||||
}
|
||||
}
|
||||
evm_test!{test_pop: test_pop_jit, test_pop_int}
|
||||
fn test_pop(factory: super::Factory) {
|
||||
let code = "60f060aa50600055".from_hex().unwrap();
|
||||
|
||||
let mut params = ActionParams::default();
|
||||
params.gas = U256::from(100_000);
|
||||
params.code = Some(code);
|
||||
let mut ext = FakeExt::new();
|
||||
|
||||
let gas_left = {
|
||||
let vm = factory.create();
|
||||
vm.exec(params, &mut ext).unwrap()
|
||||
};
|
||||
|
||||
assert_store(&ext, 0, "00000000000000000000000000000000000000000000000000000000000000f0");
|
||||
assert_eq!(gas_left, U256::from(79_989));
|
||||
}
|
||||
|
||||
fn assert_store(ext: &FakeExt, pos: u64, val: &str) {
|
||||
assert_eq!(ext.store.get(&H256::from(pos)).unwrap(), &H256::from_str(val).unwrap());
|
||||
}
|
||||
|
||||
|
466
install-deps.sh
Executable file
466
install-deps.sh
Executable file
@ -0,0 +1,466 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
function run_installer()
|
||||
{
|
||||
####### Init vars
|
||||
|
||||
HOMEBREW_PREFIX=/usr/local
|
||||
HOMEBREW_CACHE=/Library/Caches/Homebrew
|
||||
HOMEBREW_REPO=https://github.com/Homebrew/homebrew
|
||||
OSX_REQUIERED_VERSION="10.7.0"
|
||||
|
||||
|
||||
declare OS_TYPE
|
||||
declare OSX_VERSION
|
||||
declare GIT_PATH
|
||||
declare RUBY_PATH
|
||||
declare BREW_PATH
|
||||
declare INSTALL_FILES=""
|
||||
|
||||
errorMessages=""
|
||||
isOsVersion=false
|
||||
isGit=false
|
||||
isRuby=false
|
||||
isBrew=false
|
||||
canContinue=true
|
||||
depCount=0
|
||||
depFound=0
|
||||
|
||||
|
||||
|
||||
####### Setup colors
|
||||
|
||||
red=`tput setaf 1`
|
||||
green=`tput setaf 2`
|
||||
yellow=`tput setaf 3`
|
||||
blue=`tput setaf 4`
|
||||
magenta=`tput setaf 5`
|
||||
cyan=`tput setaf 6`
|
||||
white=`tput setaf 7`
|
||||
b=`tput bold`
|
||||
u=`tput sgr 0 1`
|
||||
ul=`tput smul`
|
||||
xl=`tput rmul`
|
||||
stou=`tput smso`
|
||||
xtou=`tput rmso`
|
||||
dim=`tput dim`
|
||||
reverse=`tput rev`
|
||||
reset=`tput sgr0`
|
||||
|
||||
|
||||
function head() {
|
||||
echo "${blue}${b}==>${white} $1${reset}"
|
||||
}
|
||||
|
||||
function info() {
|
||||
echo "${blue}${b}==>${reset} $1"
|
||||
}
|
||||
|
||||
function successHeading() {
|
||||
echo "${green}${b}==> $1${reset}"
|
||||
}
|
||||
|
||||
function success() {
|
||||
echo "${green}${b}==>${reset}${green} $1${reset}"
|
||||
}
|
||||
|
||||
function error() {
|
||||
echo "${red}==> ${u}${b}${red}$1${reset}"
|
||||
}
|
||||
|
||||
function smallError() {
|
||||
echo "${red}==>${reset} $1"
|
||||
}
|
||||
|
||||
function green() {
|
||||
echo "${green}$1${reset}"
|
||||
}
|
||||
|
||||
function red() {
|
||||
echo "${red}$1${reset}"
|
||||
}
|
||||
|
||||
function check() {
|
||||
echo "${green}${bold} ✓${reset} $1${reset}"
|
||||
}
|
||||
|
||||
function uncheck() {
|
||||
echo "${red}${bold} ✘${reset} $1${reset}"
|
||||
}
|
||||
|
||||
|
||||
|
||||
####### Setup methods
|
||||
|
||||
function wait_for_user() {
|
||||
while :
|
||||
do
|
||||
read -p "${blue}==>${reset} $1 [Y/n] " imp
|
||||
case $imp in
|
||||
[yY] ) echo; break ;;
|
||||
'' ) echo; break ;;
|
||||
[nN] ) abortInstall "${red}==>${reset} Process stopped by user. To resume the install run the one-liner command again." ;;
|
||||
* ) echo "Unrecognized option provided. Please provide either 'Y' or 'N'";
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
|
||||
function exe() {
|
||||
echo "\$ $@"; "$@"
|
||||
}
|
||||
|
||||
function detectOS() {
|
||||
if [[ "$OSTYPE" == "linux-gnu" ]]
|
||||
then
|
||||
OS_TYPE="linux"
|
||||
get_linux_dependencies
|
||||
elif [[ "$OSTYPE" == "darwin"* ]]
|
||||
then
|
||||
OS_TYPE="osx"
|
||||
get_osx_dependencies
|
||||
else
|
||||
OS_TYPE="win"
|
||||
abortInstall "${red}==>${reset} ${b}OS not supported:${reset} parity one-liner currently support OS X and Linux.\nFor instructions on installing parity on other platforms please visit ${u}${blue}http://ethcore.io/${reset}"
|
||||
fi
|
||||
|
||||
echo
|
||||
|
||||
if [[ $depCount == $depFound ]]
|
||||
then
|
||||
green "Found all dependencies ($depFound/$depCount)"
|
||||
else
|
||||
if [[ $canContinue == true ]]
|
||||
then
|
||||
red "Some dependencies are missing ($depFound/$depCount)"
|
||||
elif [[ $canContinue == false && $depFound == 0 ]]
|
||||
then
|
||||
red "All dependencies are missing and cannot be auto-installed ($depFound/$depCount)"
|
||||
abortInstall "$errorMessages";
|
||||
elif [[ $canContinue == false ]]
|
||||
then
|
||||
red "Some dependencies which cannot be auto-installed are missing ($depFound/$depCount)"
|
||||
abortInstall "$errorMessages";
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
function get_osx_dependencies()
|
||||
{
|
||||
macos_version
|
||||
find_git
|
||||
find_ruby
|
||||
find_brew
|
||||
}
|
||||
|
||||
function macos_version()
|
||||
{
|
||||
declare -a reqVersion
|
||||
declare -a localVersion
|
||||
|
||||
depCount=$((depCount+1))
|
||||
OSX_VERSION=`/usr/bin/sw_vers -productVersion 2>/dev/null`
|
||||
|
||||
if [ -z "$OSX_VERSION" ]
|
||||
then
|
||||
uncheck "OS X version not supported 🔥"
|
||||
isOsVersion=false
|
||||
canContinue=false
|
||||
else
|
||||
IFS='.' read -a localVersion <<< "$OSX_VERSION"
|
||||
IFS='.' read -a reqVersion <<< "$OSX_REQUIERED_VERSION"
|
||||
|
||||
if (( ${reqVersion[0]} <= ${localVersion[0]} )) && (( ${reqVersion[1]} <= ${localVersion[1]} ))
|
||||
then
|
||||
check "OS X Version ${OSX_VERSION}"
|
||||
isOsVersion=true
|
||||
depFound=$((depFound+1))
|
||||
return
|
||||
else
|
||||
uncheck "OS X version not supported"
|
||||
isOsVersion=false
|
||||
canContinue=false
|
||||
fi
|
||||
fi
|
||||
|
||||
errorMessages+="${red}==>${reset} ${b}Mac OS version too old:${reset} eth requires OS X version ${red}$OSX_REQUIERED_VERSION${reset} at least in order to run.\n"
|
||||
errorMessages+=" Please update the OS and reload the install process.\n"
|
||||
}
|
||||
|
||||
function find_eth()
|
||||
{
|
||||
ETH_PATH=`which eth 2>/dev/null`
|
||||
|
||||
if [[ -f $ETH_PATH ]]
|
||||
then
|
||||
check "Found eth: $ETH_PATH"
|
||||
echo "$($ETH_PATH -V)"
|
||||
isEth=true
|
||||
else
|
||||
uncheck "Eth is missing"
|
||||
isEth=false
|
||||
fi
|
||||
}
|
||||
|
||||
function find_git()
|
||||
{
|
||||
depCount=$((depCount+1))
|
||||
|
||||
GIT_PATH=`which git 2>/dev/null`
|
||||
|
||||
if [[ -f $GIT_PATH ]]
|
||||
then
|
||||
check "$($GIT_PATH --version)"
|
||||
isGit=true
|
||||
depFound=$((depFound+1))
|
||||
else
|
||||
uncheck "Git is missing"
|
||||
isGit=false
|
||||
fi
|
||||
}
|
||||
|
||||
function find_ruby()
|
||||
{
|
||||
depCount=$((depCount+1))
|
||||
|
||||
RUBY_PATH=`which ruby 2>/dev/null`
|
||||
|
||||
if [[ -f $RUBY_PATH ]]
|
||||
then
|
||||
RUBY_VERSION=`ruby -e "print RUBY_VERSION"`
|
||||
check "Ruby ${RUBY_VERSION}"
|
||||
isRuby=true
|
||||
depFound=$((depFound+1))
|
||||
else
|
||||
uncheck "Ruby is missing 🔥"
|
||||
isRuby=false
|
||||
canContinue=false
|
||||
errorMessages+="${red}==>${reset} ${b}Couldn't find Ruby:${reset} Brew requires Ruby which could not be found.\n"
|
||||
errorMessages+=" Please install Ruby using these instructions ${u}${blue}https://www.ruby-lang.org/en/documentation/installation/${reset}.\n"
|
||||
fi
|
||||
}
|
||||
|
||||
function find_brew()
|
||||
{
|
||||
BREW_PATH=`which brew 2>/dev/null`
|
||||
|
||||
if [[ -f $BREW_PATH ]]
|
||||
then
|
||||
check "$($BREW_PATH -v)"
|
||||
isBrew=true
|
||||
depFound=$((depFound+1))
|
||||
else
|
||||
uncheck "Homebrew is missing"
|
||||
isBrew=false
|
||||
|
||||
INSTALL_FILES+="${blue}${dim}==> Homebrew:${reset}\n"
|
||||
INSTALL_FILES+=" ${blue}${dim}➜${reset} $HOMEBREW_PREFIX/bin/brew\n"
|
||||
INSTALL_FILES+=" ${blue}${dim}➜${reset} $HOMEBREW_PREFIX/Library\n"
|
||||
INSTALL_FILES+=" ${blue}${dim}➜${reset} $HOMEBREW_PREFIX/share/man/man1/brew.1\n"
|
||||
fi
|
||||
|
||||
depCount=$((depCount+1))
|
||||
}
|
||||
|
||||
function install_brew()
|
||||
{
|
||||
if [[ $isBrew == false ]]
|
||||
then
|
||||
head "Installing Homebrew"
|
||||
|
||||
if [[ $isRuby == true ]]
|
||||
then
|
||||
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
|
||||
else
|
||||
cd /usr
|
||||
|
||||
if [[ ! -d $HOMEBREW_PREFIX ]]
|
||||
then
|
||||
sudo mkdir $HOMEBREW_PREFIX
|
||||
sudo chmod g+rwx $HOMEBREW_PREFIX
|
||||
fi
|
||||
|
||||
if [[ ! -d $HOMEBREW_CACHE ]]
|
||||
then
|
||||
sudo mkdir $HOMEBREW_CACHE
|
||||
sudo chmod g+rwx $HOMEBREW_CACHE
|
||||
fi
|
||||
|
||||
DEVELOPER_DIR=`/usr/bin/xcode-select -print-path 2>/dev/null`
|
||||
|
||||
if [[ ! $(ls -A $DEVELOPER_DIR) || ! -f $DEVELOPER_DIR/usr/bin/git ]]
|
||||
then
|
||||
info "Installing the Command Line Tools (expect a GUI popup):"
|
||||
sudo /usr/bin/xcode-select --install
|
||||
|
||||
echo "Press any key when the installation has completed"
|
||||
fi
|
||||
|
||||
cd $HOMEBREW_PREFIX
|
||||
|
||||
bash -o pipefail -c "curl -fsSL ${HOMEBREW_REPO}/tarball/master | tar xz -m --strip 1"
|
||||
fi
|
||||
|
||||
find_brew
|
||||
echo
|
||||
|
||||
if [[ $isBrew == false ]]
|
||||
then
|
||||
abortInstall "Couldn't install brew"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
function osx_installer()
|
||||
{
|
||||
osx_dependency_installer
|
||||
|
||||
info "Updating brew"
|
||||
exe brew update
|
||||
echo
|
||||
|
||||
info "Installing rocksdb"
|
||||
exe brew install rocksdb
|
||||
info "Installing multirust"
|
||||
exe brew install multirust
|
||||
sudo multirust update nightly
|
||||
sudo multirust default nightly
|
||||
echo
|
||||
}
|
||||
|
||||
function osx_dependency_installer()
|
||||
{
|
||||
if [[ $isGit == false ]];
|
||||
then
|
||||
echo "Installing Git"
|
||||
fi
|
||||
|
||||
if [[ $isRuby == false ]];
|
||||
then
|
||||
echo "Installing Ruby"
|
||||
fi
|
||||
|
||||
if [[ $isBrew == false ]];
|
||||
then
|
||||
install_brew
|
||||
fi
|
||||
}
|
||||
|
||||
function get_linux_dependencies()
|
||||
{
|
||||
find_apt
|
||||
}
|
||||
|
||||
function find_apt()
|
||||
{
|
||||
APT_PATH=`which apt-get 2>/dev/null`
|
||||
|
||||
if [[ -f $APT_PATH ]]
|
||||
then
|
||||
check "apt-get"
|
||||
echo "$($APT_PATH -v)"
|
||||
isApt=true
|
||||
else
|
||||
uncheck "apt-get is missing"
|
||||
isApt=false
|
||||
fi
|
||||
}
|
||||
function linux_rocksdb_installer()
|
||||
{
|
||||
oldpwd=`pwd`
|
||||
cd /tmp
|
||||
exe git clone --branch v4.1 --depth=1 https://github.com/facebook/rocksdb.git
|
||||
cd rocksdb
|
||||
exe make shared_lib
|
||||
sudo cp -a librocksdb.so* /usr/lib
|
||||
sudo ldconfig
|
||||
cd /tmp
|
||||
rm -rf /tmp/rocksdb
|
||||
cd $oldpwd
|
||||
}
|
||||
|
||||
function linux_installer()
|
||||
{
|
||||
info "Installing git"
|
||||
sudo apt-get install -q -y git
|
||||
echo
|
||||
|
||||
info "Installing rocksdb"
|
||||
linux_rocksdb_installer
|
||||
echo
|
||||
|
||||
info "Installing multirust"
|
||||
curl -sf https://raw.githubusercontent.com/brson/multirust/master/blastoff.sh | sudo sh -s -- --yes
|
||||
sudo multirust update nightly
|
||||
sudo multirust default nightly
|
||||
echo
|
||||
}
|
||||
|
||||
function install()
|
||||
{
|
||||
echo
|
||||
head "Installing Parity build dependencies"
|
||||
|
||||
if [[ $OS_TYPE == "osx" ]]
|
||||
then
|
||||
osx_installer
|
||||
elif [[ $OS_TYPE == "linux" ]]
|
||||
then
|
||||
linux_installer
|
||||
fi
|
||||
}
|
||||
|
||||
function verify_installation()
|
||||
{
|
||||
info "Verifying installation"
|
||||
# find_eth
|
||||
|
||||
# if [[ $isEth == false ]]
|
||||
# then
|
||||
# abortInstall
|
||||
# fi
|
||||
}
|
||||
|
||||
function abortInstall()
|
||||
{
|
||||
echo
|
||||
error "Installation failed"
|
||||
echo -e "$1"
|
||||
echo
|
||||
exit 0
|
||||
}
|
||||
|
||||
function finish()
|
||||
{
|
||||
# echo
|
||||
# successHeading "Installation successful!"
|
||||
# head "Next steps"
|
||||
# info "Run ${cyan}\`\`${reset} to get started.${reset}"
|
||||
# echo
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Check dependencies
|
||||
head "Checking OS dependencies"
|
||||
detectOS
|
||||
|
||||
echo
|
||||
head "In addition to the parity build dependencies, this script will install:"
|
||||
echo "$INSTALL_FILES"
|
||||
echo
|
||||
|
||||
# Prompt user to continue or abort
|
||||
wait_for_user "${b}OK,${reset} let's go!"
|
||||
|
||||
# Install dependencies and eth
|
||||
install
|
||||
|
||||
# Check installation
|
||||
verify_installation
|
||||
|
||||
# Display goodby message
|
||||
finish
|
||||
}
|
||||
|
||||
run_installer
|
@ -13,4 +13,5 @@ ethcore = { path = ".." }
|
||||
clippy = "0.0.37"
|
||||
log = "0.3"
|
||||
env_logger = "0.3"
|
||||
time = "0.1.34"
|
||||
|
||||
|
@ -22,6 +22,7 @@ use range_collection::{RangeCollection, ToUsize, FromUsize};
|
||||
use ethcore::error::*;
|
||||
use ethcore::block::Block;
|
||||
use io::SyncIo;
|
||||
use time;
|
||||
|
||||
impl ToUsize for BlockNumber {
|
||||
fn to_usize(&self) -> usize {
|
||||
@ -61,6 +62,8 @@ const RECEIPTS_PACKET: u8 = 0x10;
|
||||
|
||||
const NETWORK_ID: U256 = ONE_U256; //TODO: get this from parent
|
||||
|
||||
const CONNECTION_TIMEOUT_SEC: f64 = 30f64;
|
||||
|
||||
struct Header {
|
||||
/// Header data
|
||||
data: Bytes,
|
||||
@ -138,6 +141,8 @@ struct PeerInfo {
|
||||
asking: PeerAsking,
|
||||
/// A set of block numbers being requested
|
||||
asking_blocks: Vec<BlockNumber>,
|
||||
/// Request timestamp
|
||||
ask_time: f64,
|
||||
}
|
||||
|
||||
/// Blockchain sync handler.
|
||||
@ -250,6 +255,7 @@ impl ChainSync {
|
||||
genesis: try!(r.val_at(4)),
|
||||
asking: PeerAsking::Nothing,
|
||||
asking_blocks: Vec::new(),
|
||||
ask_time: 0f64,
|
||||
};
|
||||
|
||||
trace!(target: "sync", "New peer {} (protocol: {}, network: {:?}, difficulty: {:?}, latest:{}, genesis:{})", peer_id, peer.protocol_version, peer.network_id, peer.difficulty, peer.latest, peer.genesis);
|
||||
@ -408,6 +414,7 @@ impl ChainSync {
|
||||
trace!(target: "sync", "{} -> NewBlock ({})", peer_id, h);
|
||||
let header_view = HeaderView::new(header_rlp.as_raw());
|
||||
// TODO: Decompose block and add to self.headers and self.bodies instead
|
||||
let mut unknown = false;
|
||||
if header_view.number() == From::from(self.last_imported_block + 1) {
|
||||
match io.chain().import_block(block_rlp.as_raw().to_vec()) {
|
||||
Err(ImportError::AlreadyInChain) => {
|
||||
@ -416,6 +423,10 @@ impl ChainSync {
|
||||
Err(ImportError::AlreadyQueued) => {
|
||||
trace!(target: "sync", "New block already queued {:?}", h);
|
||||
},
|
||||
Err(ImportError::UnknownParent) => {
|
||||
unknown = true;
|
||||
trace!(target: "sync", "New block with unknown parent {:?}", h);
|
||||
},
|
||||
Ok(_) => {
|
||||
trace!(target: "sync", "New block queued {:?}", h);
|
||||
},
|
||||
@ -426,6 +437,9 @@ impl ChainSync {
|
||||
};
|
||||
}
|
||||
else {
|
||||
unknown = true;
|
||||
}
|
||||
if unknown {
|
||||
trace!(target: "sync", "New block unknown {:?}", h);
|
||||
//TODO: handle too many unknown blocks
|
||||
let difficulty: U256 = try!(r.val_at(1));
|
||||
@ -795,6 +809,7 @@ impl ChainSync {
|
||||
Ok(_) => {
|
||||
let mut peer = self.peers.get_mut(&peer_id).unwrap();
|
||||
peer.asking = asking;
|
||||
peer.ask_time = time::precise_time_s();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -969,6 +984,16 @@ impl ChainSync {
|
||||
})
|
||||
}
|
||||
|
||||
/// Handle peer timeouts
|
||||
pub fn maintain_peers(&self, io: &mut SyncIo) {
|
||||
let tick = time::precise_time_s();
|
||||
for (peer_id, peer) in &self.peers {
|
||||
if peer.asking != PeerAsking::Nothing && (tick - peer.ask_time) > CONNECTION_TIMEOUT_SEC {
|
||||
io.disconnect_peer(*peer_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Maintain other peers. Send out any new blocks and transactions
|
||||
pub fn _maintain_sync(&mut self, _io: &mut SyncIo) {
|
||||
}
|
||||
|
@ -9,6 +9,8 @@ use ethcore::service::SyncMessage;
|
||||
pub trait SyncIo {
|
||||
/// Disable a peer
|
||||
fn disable_peer(&mut self, peer_id: PeerId);
|
||||
/// Disconnect peer
|
||||
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<u8>) -> Result<(), UtilError>;
|
||||
/// Send a packet to a peer.
|
||||
@ -42,6 +44,10 @@ impl<'s, 'h> SyncIo for NetSyncIo<'s, 'h> {
|
||||
self.network.disable_peer(peer_id);
|
||||
}
|
||||
|
||||
fn disconnect_peer(&mut self, peer_id: PeerId) {
|
||||
self.network.disconnect_peer(peer_id);
|
||||
}
|
||||
|
||||
fn respond(&mut self, packet_id: PacketId, data: Vec<u8>) -> Result<(), UtilError>{
|
||||
self.network.respond(packet_id, data)
|
||||
}
|
||||
|
@ -33,11 +33,13 @@ extern crate log;
|
||||
extern crate ethcore_util as util;
|
||||
extern crate ethcore;
|
||||
extern crate env_logger;
|
||||
extern crate time;
|
||||
|
||||
use std::ops::*;
|
||||
use std::sync::*;
|
||||
use ethcore::client::Client;
|
||||
use util::network::{NetworkProtocolHandler, NetworkService, NetworkContext, PeerId};
|
||||
use util::io::TimerToken;
|
||||
use chain::ChainSync;
|
||||
use ethcore::service::SyncMessage;
|
||||
use io::NetSyncIo;
|
||||
@ -87,7 +89,8 @@ impl EthSync {
|
||||
}
|
||||
|
||||
impl NetworkProtocolHandler<SyncMessage> for EthSync {
|
||||
fn initialize(&self, _io: &NetworkContext<SyncMessage>) {
|
||||
fn initialize(&self, io: &NetworkContext<SyncMessage>) {
|
||||
io.register_timer(0, 1000).expect("Error registering sync timer");
|
||||
}
|
||||
|
||||
fn read(&self, io: &NetworkContext<SyncMessage>, peer: &PeerId, packet_id: u8, data: &[u8]) {
|
||||
@ -101,6 +104,10 @@ impl NetworkProtocolHandler<SyncMessage> for EthSync {
|
||||
fn disconnected(&self, io: &NetworkContext<SyncMessage>, peer: &PeerId) {
|
||||
self.sync.write().unwrap().on_peer_aborting(&mut NetSyncIo::new(io, self.chain.deref()), *peer);
|
||||
}
|
||||
|
||||
fn timeout(&self, io: &NetworkContext<SyncMessage>, _timer: TimerToken) {
|
||||
self.sync.write().unwrap().maintain_peers(&mut NetSyncIo::new(io, self.chain.deref()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -209,6 +209,9 @@ impl<'p> SyncIo for TestIo<'p> {
|
||||
fn disable_peer(&mut self, _peer_id: PeerId) {
|
||||
}
|
||||
|
||||
fn disconnect_peer(&mut self, _peer_id: PeerId) {
|
||||
}
|
||||
|
||||
fn respond(&mut self, packet_id: PacketId, data: Vec<u8>) -> Result<(), UtilError> {
|
||||
self.queue.push_back(TestPacket {
|
||||
data: data,
|
||||
|
@ -207,6 +207,12 @@ pub struct EncryptedConnection {
|
||||
}
|
||||
|
||||
impl EncryptedConnection {
|
||||
|
||||
/// Get socket token
|
||||
pub fn token(&self) -> StreamToken {
|
||||
self.connection.token
|
||||
}
|
||||
|
||||
/// Create an encrypted connection out of the handshake. Consumes a handshake object.
|
||||
pub fn new(mut handshake: Handshake) -> Result<EncryptedConnection, UtilError> {
|
||||
let shared = try!(crypto::ecdh::agree(handshake.ecdhe.secret(), &handshake.remote_public));
|
||||
|
@ -5,17 +5,17 @@ use rlp::*;
|
||||
pub enum DisconnectReason
|
||||
{
|
||||
DisconnectRequested,
|
||||
//TCPError,
|
||||
//BadProtocol,
|
||||
_TCPError,
|
||||
_BadProtocol,
|
||||
UselessPeer,
|
||||
//TooManyPeers,
|
||||
//DuplicatePeer,
|
||||
//IncompatibleProtocol,
|
||||
//NullIdentity,
|
||||
//ClientQuit,
|
||||
//UnexpectedIdentity,
|
||||
//LocalIdentity,
|
||||
//PingTimeout,
|
||||
_TooManyPeers,
|
||||
_DuplicatePeer,
|
||||
_IncompatibleProtocol,
|
||||
_NullIdentity,
|
||||
_ClientQuit,
|
||||
_UnexpectedIdentity,
|
||||
_LocalIdentity,
|
||||
PingTimeout,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -19,6 +19,7 @@ use io::*;
|
||||
use network::NetworkProtocolHandler;
|
||||
use network::node::*;
|
||||
use network::stats::NetworkStats;
|
||||
use network::error::DisconnectReason;
|
||||
|
||||
type Slab<T> = ::slab::Slab<T, usize>;
|
||||
|
||||
@ -108,6 +109,8 @@ pub enum NetworkIoMessage<Message> where Message: Send + Sync + Clone {
|
||||
/// Timer delay in milliseconds.
|
||||
delay: u64,
|
||||
},
|
||||
/// Disconnect a peer
|
||||
Disconnect(PeerId),
|
||||
/// User message
|
||||
User(Message),
|
||||
}
|
||||
@ -181,8 +184,14 @@ impl<'s, Message> NetworkContext<'s, Message> where Message: Send + Sync + Clone
|
||||
}
|
||||
|
||||
/// Disable current protocol capability for given peer. If no capabilities left peer gets disconnected.
|
||||
pub fn disable_peer(&self, _peer: PeerId) {
|
||||
pub fn disable_peer(&self, peer: PeerId) {
|
||||
//TODO: remove capability, disconnect if no capabilities left
|
||||
self.disconnect_peer(peer);
|
||||
}
|
||||
|
||||
/// Disconnect peer. Reconnect can be attempted later.
|
||||
pub fn disconnect_peer(&self, peer: PeerId) {
|
||||
self.io.message(NetworkIoMessage::Disconnect(peer));
|
||||
}
|
||||
|
||||
/// Register a new IO timer. 'IoHandler::timeout' will be called with the token.
|
||||
@ -332,6 +341,7 @@ impl<Message> Host<Message> where Message: Send + Sync + Clone {
|
||||
}
|
||||
|
||||
fn maintain_network(&self, io: &IoContext<NetworkIoMessage<Message>>) {
|
||||
self.keep_alive(io);
|
||||
self.connect_peers(io);
|
||||
}
|
||||
|
||||
@ -343,6 +353,21 @@ impl<Message> Host<Message> where Message: Send + Sync + Clone {
|
||||
self.connections.read().unwrap().iter().any(|e| match *e.lock().unwrap().deref() { ConnectionEntry::Handshake(ref h) => h.id.eq(&id), _ => false })
|
||||
}
|
||||
|
||||
fn keep_alive(&self, io: &IoContext<NetworkIoMessage<Message>>) {
|
||||
let mut to_kill = Vec::new();
|
||||
for e in self.connections.write().unwrap().iter_mut() {
|
||||
if let ConnectionEntry::Session(ref mut s) = *e.lock().unwrap().deref_mut() {
|
||||
if !s.keep_alive() {
|
||||
s.disconnect(DisconnectReason::PingTimeout);
|
||||
to_kill.push(s.token());
|
||||
}
|
||||
}
|
||||
}
|
||||
for p in to_kill {
|
||||
self.kill_connection(p, io);
|
||||
}
|
||||
}
|
||||
|
||||
fn connect_peers(&self, io: &IoContext<NetworkIoMessage<Message>>) {
|
||||
struct NodeInfo {
|
||||
id: NodeId,
|
||||
@ -684,6 +709,15 @@ impl<Message> IoHandler<NetworkIoMessage<Message>> for Host<Message> where Messa
|
||||
self.timers.write().unwrap().insert(handler_token, ProtocolTimer { protocol: protocol, token: *token });
|
||||
io.register_timer(handler_token, *delay).expect("Error registering timer");
|
||||
},
|
||||
NetworkIoMessage::Disconnect(ref peer) => {
|
||||
if let Some(connection) = self.connections.read().unwrap().get(*peer).cloned() {
|
||||
match *connection.lock().unwrap().deref_mut() {
|
||||
ConnectionEntry::Handshake(_) => {},
|
||||
ConnectionEntry::Session(ref mut s) => { s.disconnect(DisconnectReason::DisconnectRequested); }
|
||||
}
|
||||
}
|
||||
self.kill_connection(*peer, io);
|
||||
},
|
||||
NetworkIoMessage::User(ref message) => {
|
||||
for (p, h) in self.handlers.read().unwrap().iter() {
|
||||
h.message(&NetworkContext::new(io, p, None, self.connections.clone()), &message);
|
||||
|
@ -21,7 +21,7 @@ impl<Message> NetworkService<Message> where Message: Send + Sync + Clone + 'stat
|
||||
let host = Arc::new(Host::new(config));
|
||||
let stats = host.stats().clone();
|
||||
let host_info = host.client_version();
|
||||
info!("NetworkService::start(): id={:?}", host.client_id());
|
||||
info!("Host ID={:?}", host.client_id());
|
||||
try!(io_service.register_handler(host));
|
||||
Ok(NetworkService {
|
||||
io_service: io_service,
|
||||
|
@ -4,10 +4,14 @@ use rlp::*;
|
||||
use network::connection::{EncryptedConnection, Packet};
|
||||
use network::handshake::Handshake;
|
||||
use error::*;
|
||||
use io::{IoContext};
|
||||
use io::{IoContext, StreamToken};
|
||||
use network::error::{NetworkError, DisconnectReason};
|
||||
use network::host::*;
|
||||
use network::node::NodeId;
|
||||
use time;
|
||||
|
||||
const PING_TIMEOUT_SEC: u64 = 30;
|
||||
const PING_INTERVAL_SEC: u64 = 30;
|
||||
|
||||
/// Peer session over encrypted connection.
|
||||
/// When created waits for Hello packet exchange and signals ready state.
|
||||
@ -19,6 +23,8 @@ pub struct Session {
|
||||
connection: EncryptedConnection,
|
||||
/// Session ready flag. Set after successfull Hello packet exchange
|
||||
had_hello: bool,
|
||||
ping_time_ns: u64,
|
||||
pong_time_ns: Option<u64>,
|
||||
}
|
||||
|
||||
/// Structure used to report various session events.
|
||||
@ -47,6 +53,8 @@ pub struct SessionInfo {
|
||||
pub protocol_version: u32,
|
||||
/// Peer protocol capabilities
|
||||
capabilities: Vec<SessionCapabilityInfo>,
|
||||
/// Peer ping delay in milliseconds
|
||||
pub ping_ms: Option<u64>,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
@ -95,10 +103,13 @@ impl Session {
|
||||
client_version: String::new(),
|
||||
protocol_version: 0,
|
||||
capabilities: Vec::new(),
|
||||
ping_ms: None,
|
||||
},
|
||||
ping_time_ns: 0,
|
||||
pong_time_ns: None,
|
||||
};
|
||||
try!(session.write_hello(host));
|
||||
try!(session.write_ping());
|
||||
try!(session.send_ping());
|
||||
Ok(session)
|
||||
}
|
||||
|
||||
@ -141,7 +152,7 @@ impl Session {
|
||||
while protocol != self.info.capabilities[i].protocol {
|
||||
i += 1;
|
||||
if i == self.info.capabilities.len() {
|
||||
debug!(target: "net", "Unkown protocol: {:?}", protocol);
|
||||
debug!(target: "net", "Unknown protocol: {:?}", protocol);
|
||||
return Ok(())
|
||||
}
|
||||
}
|
||||
@ -152,6 +163,26 @@ impl Session {
|
||||
self.connection.send_packet(&rlp.out())
|
||||
}
|
||||
|
||||
/// Keep this session alive. Returns false if ping timeout happened
|
||||
pub fn keep_alive(&mut self) -> bool {
|
||||
let timed_out = if let Some(pong) = self.pong_time_ns {
|
||||
pong - self.ping_time_ns > PING_TIMEOUT_SEC * 1000_000_000
|
||||
} else {
|
||||
time::precise_time_ns() - self.ping_time_ns > PING_TIMEOUT_SEC * 1000_000_000
|
||||
};
|
||||
|
||||
if !timed_out && time::precise_time_ns() - self.ping_time_ns > PING_INTERVAL_SEC * 1000_000_000 {
|
||||
if let Err(e) = self.send_ping() {
|
||||
debug!("Error sending ping message: {:?}", e);
|
||||
}
|
||||
}
|
||||
!timed_out
|
||||
}
|
||||
|
||||
pub fn token(&self) -> StreamToken {
|
||||
self.connection.token()
|
||||
}
|
||||
|
||||
fn read_packet(&mut self, packet: Packet, host: &HostInfo) -> Result<SessionData, UtilError> {
|
||||
if packet.data.len() < 2 {
|
||||
return Err(From::from(NetworkError::BadProtocol));
|
||||
@ -168,7 +199,12 @@ impl Session {
|
||||
},
|
||||
PACKET_DISCONNECT => Err(From::from(NetworkError::Disconnect(DisconnectReason::DisconnectRequested))),
|
||||
PACKET_PING => {
|
||||
try!(self.write_pong());
|
||||
try!(self.send_pong());
|
||||
Ok(SessionData::None)
|
||||
},
|
||||
PACKET_PONG => {
|
||||
self.pong_time_ns = Some(time::precise_time_ns());
|
||||
self.info.ping_ms = Some((self.pong_time_ns.unwrap() - self.ping_time_ns) / 1000_000);
|
||||
Ok(SessionData::None)
|
||||
},
|
||||
PACKET_GET_PEERS => Ok(SessionData::None), //TODO;
|
||||
@ -178,7 +214,7 @@ impl Session {
|
||||
while packet_id < self.info.capabilities[i].id_offset {
|
||||
i += 1;
|
||||
if i == self.info.capabilities.len() {
|
||||
debug!(target: "net", "Unkown packet: {:?}", packet_id);
|
||||
debug!(target: "net", "Unknown packet: {:?}", packet_id);
|
||||
return Ok(SessionData::None)
|
||||
}
|
||||
}
|
||||
@ -189,7 +225,7 @@ impl Session {
|
||||
Ok(SessionData::Packet { data: packet.data, protocol: protocol, packet_id: pid } )
|
||||
},
|
||||
_ => {
|
||||
debug!(target: "net", "Unkown packet: {:?}", packet_id);
|
||||
debug!(target: "net", "Unknown packet: {:?}", packet_id);
|
||||
Ok(SessionData::None)
|
||||
}
|
||||
}
|
||||
@ -255,15 +291,20 @@ impl Session {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn write_ping(&mut self) -> Result<(), UtilError> {
|
||||
self.send(try!(Session::prepare(PACKET_PING)))
|
||||
/// Senf ping packet
|
||||
pub fn send_ping(&mut self) -> Result<(), UtilError> {
|
||||
try!(self.send(try!(Session::prepare(PACKET_PING))));
|
||||
self.ping_time_ns = time::precise_time_ns();
|
||||
self.pong_time_ns = None;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn write_pong(&mut self) -> Result<(), UtilError> {
|
||||
fn send_pong(&mut self) -> Result<(), UtilError> {
|
||||
self.send(try!(Session::prepare(PACKET_PONG)))
|
||||
}
|
||||
|
||||
fn disconnect(&mut self, reason: DisconnectReason) -> NetworkError {
|
||||
/// Disconnect this session
|
||||
pub fn disconnect(&mut self, reason: DisconnectReason) -> NetworkError {
|
||||
let mut rlp = RlpStream::new();
|
||||
rlp.append(&(PACKET_DISCONNECT as u32));
|
||||
rlp.begin_list(1);
|
||||
|
Loading…
Reference in New Issue
Block a user