Merge branch 'master' of github.com:ethcore/parity into jsonrpc2

This commit is contained in:
debris 2016-02-09 17:45:51 +01:00
commit 3abe5e941f
13 changed files with 429 additions and 251 deletions

11
.editorconfig Normal file
View File

@ -0,0 +1,11 @@
root = true
[*]
indent_style=tab
indent_size=tab
tab_width=4
end_of_line=lf
charset=utf-8
trim_trailing_whitespace=true
max_line_length=120
insert_final_newline=true

View File

@ -18,6 +18,7 @@ ethcore = { path = "ethcore" }
ethsync = { path = "sync" } ethsync = { path = "sync" }
ethcore-rpc = { path = "rpc", optional = true } ethcore-rpc = { path = "rpc", optional = true }
fdlimit = { path = "util/fdlimit" } fdlimit = { path = "util/fdlimit" }
target_info = "0.1"
[features] [features]
default = ["rpc"] default = ["rpc"]

View File

@ -30,7 +30,7 @@
"enode://a979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c@52.16.188.185:30303", "enode://a979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c@52.16.188.185:30303",
"enode://de471bccee3d042261d52e9bff31458daecc406142b401d4cd848f677479f73104b9fdeb090af9583d3391b7f10cb2ba9e26865dd5fca4fcdc0fb1e3b723c786@54.94.239.50:30303", "enode://de471bccee3d042261d52e9bff31458daecc406142b401d4cd848f677479f73104b9fdeb090af9583d3391b7f10cb2ba9e26865dd5fca4fcdc0fb1e3b723c786@54.94.239.50:30303",
"enode://1118980bf48b0a3640bdba04e0fe78b1add18e1cd99bf22d53daac1fd9972ad650df52176e7c7d89d1114cfef2bc23a2959aa54998a46afcf7d91809f0855082@52.74.57.123:30303", "enode://1118980bf48b0a3640bdba04e0fe78b1add18e1cd99bf22d53daac1fd9972ad650df52176e7c7d89d1114cfef2bc23a2959aa54998a46afcf7d91809f0855082@52.74.57.123:30303",
"enode://859bbe6926fc161d218f62bd2efe0b4f6980205c00a5b928ccee39c94c440b73a054ece5db36beddd71963fbd296af61ec72a591f72a2299f9a046bd6d6ce1a9@parity-node-zero.ethcore.io:30303" "enode://248f12bc8b18d5289358085520ac78cd8076485211e6d96ab0bc93d6cd25442db0ce3a937dc404f64f207b0b9aed50e25e98ce32af5ac7cb321ff285b97de485@parity-node-zero.ethcore.io:30303"
], ],
"accounts": { "accounts": {
"0000000000000000000000000000000000000001": { "builtin": { "name": "ecrecover", "linear": { "base": 3000, "word": 0 } } }, "0000000000000000000000000000000000000001": { "builtin": { "name": "ecrecover", "linear": { "base": 3000, "word": 0 } } },

View File

@ -23,8 +23,6 @@ use spec::*;
use engine::*; use engine::*;
use evm::Schedule; use evm::Schedule;
use evm::Factory; use evm::Factory;
#[cfg(test)]
use tests::helpers::*;
/// Engine using Ethash proof-of-work consensus algorithm, suitable for Ethereum /// Engine using Ethash proof-of-work consensus algorithm, suitable for Ethereum
/// mainnet chains in the Olympic, Frontier and Homestead eras. /// mainnet chains in the Olympic, Frontier and Homestead eras.
@ -49,6 +47,17 @@ impl Ethash {
}) })
} }
#[cfg(test)]
fn new_test(spec: Spec) -> Ethash {
Ethash {
spec: spec,
pow: EthashManager::new(),
factory: Factory::default(),
u64_params: RwLock::new(HashMap::new()),
u256_params: RwLock::new(HashMap::new())
}
}
fn u64_param(&self, name: &str) -> u64 { fn u64_param(&self, name: &str) -> u64 {
*self.u64_params.write().unwrap().entry(name.to_owned()).or_insert_with(|| *self.u64_params.write().unwrap().entry(name.to_owned()).or_insert_with(||
self.spec().engine_params.get(name).map_or(0u64, |a| decode(&a))) self.spec().engine_params.get(name).map_or(0u64, |a| decode(&a)))
@ -123,6 +132,11 @@ impl Engine for Ethash {
fn verify_block_basic(&self, header: &Header, _block: Option<&[u8]>) -> result::Result<(), Error> { fn verify_block_basic(&self, header: &Header, _block: Option<&[u8]>) -> result::Result<(), Error> {
// check the seal fields. // check the seal fields.
if header.seal.len() != self.seal_fields() {
return Err(From::from(BlockError::InvalidSealArity(
Mismatch { expected: self.seal_fields(), found: header.seal.len() }
)));
}
try!(UntrustedRlp::new(&header.seal[0]).as_val::<H256>()); try!(UntrustedRlp::new(&header.seal[0]).as_val::<H256>());
try!(UntrustedRlp::new(&header.seal[1]).as_val::<H64>()); try!(UntrustedRlp::new(&header.seal[1]).as_val::<H64>());
@ -143,6 +157,11 @@ impl Engine for Ethash {
} }
fn verify_block_unordered(&self, header: &Header, _block: Option<&[u8]>) -> result::Result<(), Error> { fn verify_block_unordered(&self, header: &Header, _block: Option<&[u8]>) -> result::Result<(), Error> {
if header.seal.len() != self.seal_fields() {
return Err(From::from(BlockError::InvalidSealArity(
Mismatch { expected: self.seal_fields(), found: header.seal.len() }
)));
}
let result = self.pow.compute_light(header.number as u64, &Ethash::to_ethash(header.bare_hash()), header.nonce().low_u64()); let result = self.pow.compute_light(header.number as u64, &Ethash::to_ethash(header.bare_hash()), header.nonce().low_u64());
let mix = Ethash::from_ethash(result.mix_hash); let mix = Ethash::from_ethash(result.mix_hash);
let difficulty = Ethash::boundary_to_difficulty(&Ethash::from_ethash(result.value)); let difficulty = Ethash::boundary_to_difficulty(&Ethash::from_ethash(result.value));
@ -156,6 +175,11 @@ impl Engine for Ethash {
} }
fn verify_block_family(&self, header: &Header, parent: &Header, _block: Option<&[u8]>) -> result::Result<(), Error> { fn verify_block_family(&self, header: &Header, parent: &Header, _block: Option<&[u8]>) -> result::Result<(), Error> {
// we should not calculate difficulty for genesis blocks
if header.number() == 0 {
return Err(From::from(BlockError::RidiculousNumber(OutOfBounds { min: Some(1), max: None, found: header.number() })));
}
// Check difficulty is correct given the two timestamps. // Check difficulty is correct given the two timestamps.
let expected_difficulty = self.calculate_difficuty(header, parent); let expected_difficulty = self.calculate_difficuty(header, parent);
if header.difficulty != expected_difficulty { if header.difficulty != expected_difficulty {
@ -242,38 +266,236 @@ impl Header {
} }
} }
#[test] #[cfg(test)]
fn on_close_block() { mod tests {
extern crate ethash;
use common::*;
use block::*;
use engine::*;
use tests::helpers::*;
use super::*; use super::*;
let engine = new_morden().to_engine().unwrap(); use super::super::new_morden;
let genesis_header = engine.spec().genesis_header();
let mut db_result = get_temp_journal_db(); #[test]
let mut db = db_result.take(); fn on_close_block() {
engine.spec().ensure_db_good(&mut db); let engine = new_morden().to_engine().unwrap();
let last_hashes = vec![genesis_header.hash()]; let genesis_header = engine.spec().genesis_header();
let b = OpenBlock::new(engine.deref(), db, &genesis_header, &last_hashes, Address::zero(), vec![]); let mut db_result = get_temp_journal_db();
let b = b.close(); let mut db = db_result.take();
assert_eq!(b.state().balance(&Address::zero()), U256::from_str("4563918244f40000").unwrap()); engine.spec().ensure_db_good(&mut db);
let last_hashes = vec![genesis_header.hash()];
let b = OpenBlock::new(engine.deref(), db, &genesis_header, &last_hashes, Address::zero(), vec![]);
let b = b.close();
assert_eq!(b.state().balance(&Address::zero()), U256::from_str("4563918244f40000").unwrap());
}
#[test]
fn on_close_block_with_uncle() {
let engine = new_morden().to_engine().unwrap();
let genesis_header = engine.spec().genesis_header();
let mut db_result = get_temp_journal_db();
let mut db = db_result.take();
engine.spec().ensure_db_good(&mut db);
let last_hashes = vec![genesis_header.hash()];
let mut b = OpenBlock::new(engine.deref(), db, &genesis_header, &last_hashes, Address::zero(), vec![]);
let mut uncle = Header::new();
let uncle_author = address_from_hex("ef2d6d194084c2de36e0dabfce45d046b37d1106");
uncle.author = uncle_author.clone();
b.push_uncle(uncle).unwrap();
let b = b.close();
assert_eq!(b.state().balance(&Address::zero()), U256::from_str("478eae0e571ba000").unwrap());
assert_eq!(b.state().balance(&uncle_author), U256::from_str("3cb71f51fc558000").unwrap());
}
#[test]
fn has_valid_metadata() {
let engine = Ethash::new_boxed(new_morden());
assert!(!engine.name().is_empty());
assert!(engine.version().major >= 1);
}
#[test]
fn can_return_params() {
let engine = Ethash::new_test(new_morden());
assert!(engine.u64_param("durationLimit") > 0);
assert!(engine.u256_param("minimumDifficulty") > U256::zero());
}
#[test]
fn can_return_factory() {
let engine = Ethash::new_test(new_morden());
engine.vm_factory();
}
#[test]
fn can_return_schedule() {
let engine = Ethash::new_test(new_morden());
let schedule = engine.schedule(&EnvInfo {
number: 10000000,
author: x!(0),
timestamp: 0,
difficulty: x!(0),
last_hashes: vec![],
gas_used: x!(0),
gas_limit: x!(0)
});
assert!(schedule.stack_limit > 0);
let schedule = engine.schedule(&EnvInfo {
number: 100,
author: x!(0),
timestamp: 0,
difficulty: x!(0),
last_hashes: vec![],
gas_used: x!(0),
gas_limit: x!(0)
});
assert!(!schedule.have_delegate_call);
}
#[test]
fn can_do_seal_verification_fail() {
let engine = Ethash::new_test(new_morden());
let header: Header = Header::default();
let verify_result = engine.verify_block_basic(&header, None);
match verify_result {
Err(Error::Block(BlockError::InvalidSealArity(_))) => {},
Err(_) => { panic!("should be block seal-arity mismatch error (got {:?})", verify_result); },
_ => { panic!("Should be error, got Ok"); },
}
}
#[test]
fn can_do_difficulty_verification_fail() {
let engine = Ethash::new_test(new_morden());
let mut header: Header = Header::default();
header.set_seal(vec![rlp::encode(&H256::zero()).to_vec(), rlp::encode(&H64::zero()).to_vec()]);
let verify_result = engine.verify_block_basic(&header, None);
match verify_result {
Err(Error::Block(BlockError::DifficultyOutOfBounds(_))) => {},
Err(_) => { panic!("should be block difficulty error (got {:?})", verify_result); },
_ => { panic!("Should be error, got Ok"); },
}
}
#[test]
fn can_do_proof_of_work_verification_fail() {
let engine = Ethash::new_test(new_morden());
let mut header: Header = Header::default();
header.set_seal(vec![rlp::encode(&H256::zero()).to_vec(), rlp::encode(&H64::zero()).to_vec()]);
header.set_difficulty(U256::from_str("ffffffffffffffffffffffffffffffffffffffffffffaaaaaaaaaaaaaaaaaaaa").unwrap());
let verify_result = engine.verify_block_basic(&header, None);
match verify_result {
Err(Error::Block(BlockError::InvalidProofOfWork(_))) => {},
Err(_) => { panic!("should be invalid proof of work error (got {:?})", verify_result); },
_ => { panic!("Should be error, got Ok"); },
}
}
#[test]
fn can_do_seal_unordered_verification_fail() {
let engine = Ethash::new_test(new_morden());
let header: Header = Header::default();
let verify_result = engine.verify_block_unordered(&header, None);
match verify_result {
Err(Error::Block(BlockError::InvalidSealArity(_))) => {},
Err(_) => { panic!("should be block seal-arity mismatch error (got {:?})", verify_result); },
_ => { panic!("Should be error, got Ok"); },
}
}
#[test]
fn can_do_seal256_verification_fail() {
let engine = Ethash::new_test(new_morden());
let mut header: Header = Header::default();
header.set_seal(vec![rlp::encode(&H256::zero()).to_vec(), rlp::encode(&H64::zero()).to_vec()]);
let verify_result = engine.verify_block_unordered(&header, None);
match verify_result {
Err(Error::Block(BlockError::MismatchedH256SealElement(_))) => {},
Err(_) => { panic!("should be invalid 256-bit seal fail (got {:?})", verify_result); },
_ => { panic!("Should be error, got Ok"); },
}
}
#[test]
fn can_do_proof_of_work_unordered_verification_fail() {
let engine = Ethash::new_test(new_morden());
let mut header: Header = Header::default();
header.set_seal(vec![rlp::encode(&H256::from("b251bd2e0283d0658f2cadfdc8ca619b5de94eca5742725e2e757dd13ed7503d")).to_vec(), rlp::encode(&H64::zero()).to_vec()]);
header.set_difficulty(U256::from_str("ffffffffffffffffffffffffffffffffffffffffffffaaaaaaaaaaaaaaaaaaaa").unwrap());
let verify_result = engine.verify_block_unordered(&header, None);
match verify_result {
Err(Error::Block(BlockError::InvalidProofOfWork(_))) => {},
Err(_) => { panic!("should be invalid proof-of-work fail (got {:?})", verify_result); },
_ => { panic!("Should be error, got Ok"); },
}
}
#[test]
fn can_verify_block_family_genesis_fail() {
let engine = Ethash::new_test(new_morden());
let header: Header = Header::default();
let parent_header: Header = Header::default();
let verify_result = engine.verify_block_family(&header, &parent_header, None);
match verify_result {
Err(Error::Block(BlockError::RidiculousNumber(_))) => {},
Err(_) => { panic!("should be invalid block number fail (got {:?})", verify_result); },
_ => { panic!("Should be error, got Ok"); },
}
}
#[test]
fn can_verify_block_family_difficulty_fail() {
let engine = Ethash::new_test(new_morden());
let mut header: Header = Header::default();
header.set_number(2);
let mut parent_header: Header = Header::default();
parent_header.set_number(1);
let verify_result = engine.verify_block_family(&header, &parent_header, None);
match verify_result {
Err(Error::Block(BlockError::InvalidDifficulty(_))) => {},
Err(_) => { panic!("should be invalid difficulty fail (got {:?})", verify_result); },
_ => { panic!("Should be error, got Ok"); },
}
}
#[test]
fn can_verify_block_family_gas_fail() {
let engine = Ethash::new_test(new_morden());
let mut header: Header = Header::default();
header.set_number(2);
header.set_difficulty(U256::from_str("0000000000000000000000000000000000000000000000000000000000020000").unwrap());
let mut parent_header: Header = Header::default();
parent_header.set_number(1);
let verify_result = engine.verify_block_family(&header, &parent_header, None);
match verify_result {
Err(Error::Block(BlockError::InvalidGasLimit(_))) => {},
Err(_) => { panic!("should be invalid difficulty fail (got {:?})", verify_result); },
_ => { panic!("Should be error, got Ok"); },
}
}
// TODO: difficulty test
} }
#[test]
fn on_close_block_with_uncle() {
use super::*;
let engine = new_morden().to_engine().unwrap();
let genesis_header = engine.spec().genesis_header();
let mut db_result = get_temp_journal_db();
let mut db = db_result.take();
engine.spec().ensure_db_good(&mut db);
let last_hashes = vec![genesis_header.hash()];
let mut b = OpenBlock::new(engine.deref(), db, &genesis_header, &last_hashes, Address::zero(), vec![]);
let mut uncle = Header::new();
let uncle_author = address_from_hex("ef2d6d194084c2de36e0dabfce45d046b37d1106");
uncle.author = uncle_author.clone();
b.push_uncle(uncle).unwrap();
let b = b.close();
assert_eq!(b.state().balance(&Address::zero()), U256::from_str("478eae0e571ba000").unwrap());
assert_eq!(b.state().balance(&uncle_author), U256::from_str("3cb71f51fc558000").unwrap());
}
// TODO: difficulty test

View File

@ -159,11 +159,13 @@ macro_rules! evm_test_ignore(
#[test] #[test]
#[ignore] #[ignore]
#[cfg(feature = "jit")] #[cfg(feature = "jit")]
#[cfg(feature = "ignored-tests")]
fn $name_jit() { fn $name_jit() {
$name_test(Factory::new(VMType::Jit)); $name_test(Factory::new(VMType::Jit));
} }
#[test] #[test]
#[ignore] #[ignore]
#[cfg(feature = "ignored-tests")]
fn $name_int() { fn $name_int() {
$name_test(Factory::new(VMType::Interpreter)); $name_test(Factory::new(VMType::Interpreter));
} }

View File

@ -360,6 +360,7 @@ impl<'a> Executive<'a> {
} }
#[cfg(test)] #[cfg(test)]
#[allow(dead_code)]
mod tests { mod tests {
use super::*; use super::*;
use common::*; use common::*;
@ -599,6 +600,7 @@ mod tests {
} }
// test is incorrect, mk // test is incorrect, mk
// TODO: fix (preferred) or remove
evm_test_ignore!{test_aba_calls: test_aba_calls_jit, test_aba_calls_int} evm_test_ignore!{test_aba_calls: test_aba_calls_jit, test_aba_calls_int}
fn test_aba_calls(factory: Factory) { fn test_aba_calls(factory: Factory) {
// 60 00 - push 0 // 60 00 - push 0
@ -659,6 +661,7 @@ mod tests {
} }
// test is incorrect, mk // test is incorrect, mk
// TODO: fix (preferred) or remove
evm_test_ignore!{test_recursive_bomb1: test_recursive_bomb1_jit, test_recursive_bomb1_int} evm_test_ignore!{test_recursive_bomb1: test_recursive_bomb1_jit, test_recursive_bomb1_int}
fn test_recursive_bomb1(factory: Factory) { fn test_recursive_bomb1(factory: Factory) {
// 60 01 - push 1 // 60 01 - push 1
@ -704,6 +707,7 @@ mod tests {
} }
// test is incorrect, mk // test is incorrect, mk
// TODO: fix (preferred) or remove
evm_test_ignore!{test_transact_simple: test_transact_simple_jit, test_transact_simple_int} evm_test_ignore!{test_transact_simple: test_transact_simple_jit, test_transact_simple_int}
fn test_transact_simple(factory: Factory) { fn test_transact_simple(factory: Factory) {
let keypair = KeyPair::create().unwrap(); let keypair = KeyPair::create().unwrap();
@ -902,5 +906,4 @@ mod tests {
} }
} }
} }
} }

View File

@ -20,7 +20,6 @@ mod test_common;
mod transaction; mod transaction;
mod executive; mod executive;
mod state; mod state;
mod client;
mod chain; mod chain;
mod homestead_state; mod homestead_state;
mod homestead_chain; mod homestead_chain;

View File

@ -15,8 +15,8 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
use client::{BlockChainClient,Client}; use client::{BlockChainClient,Client};
use super::test_common::*;
use tests::helpers::*; use tests::helpers::*;
use common::*;
#[test] #[test]
fn created() { fn created() {

View File

@ -14,7 +14,6 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
#[cfg(feature = "json-tests")]
use client::{BlockChainClient, Client}; use client::{BlockChainClient, Client};
use std::env; use std::env;
use common::*; use common::*;
@ -134,7 +133,6 @@ pub fn create_test_block_with_data(header: &Header, transactions: &[&SignedTrans
rlp.out() rlp.out()
} }
#[cfg(feature = "json-tests")]
pub fn generate_dummy_client(block_number: u32) -> GuardedTempResult<Arc<Client>> { pub fn generate_dummy_client(block_number: u32) -> GuardedTempResult<Arc<Client>> {
let dir = RandomTempPath::new(); let dir = RandomTempPath::new();
@ -174,7 +172,6 @@ pub fn generate_dummy_client(block_number: u32) -> GuardedTempResult<Arc<Client>
} }
} }
#[cfg(feature = "json-tests")]
pub fn get_test_client_with_blocks(blocks: Vec<Bytes>) -> GuardedTempResult<Arc<Client>> { pub fn get_test_client_with_blocks(blocks: Vec<Bytes>) -> GuardedTempResult<Arc<Client>> {
let dir = RandomTempPath::new(); let dir = RandomTempPath::new();
let client = Client::new(get_test_spec(), dir.as_path(), IoChannel::disconnected()).unwrap(); let client = Client::new(get_test_spec(), dir.as_path(), IoChannel::disconnected()).unwrap();
@ -271,7 +268,6 @@ pub fn get_good_dummy_block() -> Bytes {
create_test_block(&block_header) create_test_block(&block_header)
} }
#[cfg(feature = "json-tests")]
pub fn get_bad_state_dummy_block() -> Bytes { pub fn get_bad_state_dummy_block() -> Bytes {
let mut block_header = Header::new(); let mut block_header = Header::new();
let test_spec = get_test_spec(); let test_spec = get_test_spec();

View File

@ -15,3 +15,4 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
pub mod helpers; pub mod helpers;
mod client;

View File

@ -1,6 +1,6 @@
#!/usr/bin/env bash #!/usr/bin/env bash
PARITY_DEB_URL=https://github.com/ethcore/parity/releases/download/beta-0.9/parity_0.9.0-0_amd64.deb PARITY_DEB_URL=https://github.com/ethcore/parity/releases/download/beta-0.9/parity_linux_0.9.0-0_amd64.deb
function run_installer() function run_installer()
@ -47,6 +47,7 @@ function run_installer()
dim=`tput dim` dim=`tput dim`
reverse=`tput rev` reverse=`tput rev`
reset=`tput sgr0` reset=`tput sgr0`
n=$'\n'
function head() { function head() {
@ -94,13 +95,19 @@ function run_installer()
####### Setup methods ####### Setup methods
function wait_for_user() { function wait_for_user() {
if [[ $( ask_user "$1" ) == false ]]; then
abort_install "${red}==>${reset} Process stopped by user. To resume the install run the one-liner command again."
fi
}
function ask_user() {
while : while :
do do
read -p "${blue}==>${reset} $1 [Y/n] " imp read -p "${blue}==>${reset} $1 [Y/n] " imp
case $imp in case $imp in
[yY] ) return 0; break ;; [yY] ) echo true; break ;;
'' ) echo; break ;; '' ) echo true; break ;;
[nN] ) return 1 ;; [nN] ) echo false; break ;;
* ) echo "Unrecognized option provided. Please provide either 'Y' or 'N'"; * ) echo "Unrecognized option provided. Please provide either 'Y' or 'N'";
esac esac
done done
@ -114,11 +121,19 @@ function run_installer()
return return
done done
} }
function exe() { function exe() {
echo "\$ $@"; "$@" echo "\$ $@"; "$@"
} }
function sudo() {
if $isSudo; then
`which sudo` "$@"
else
"$@"
fi
}
function detectOS() { function detectOS() {
if [[ "$OSTYPE" == "linux-gnu" ]] if [[ "$OSTYPE" == "linux-gnu" ]]
then then
@ -130,7 +145,7 @@ function run_installer()
get_osx_dependencies get_osx_dependencies
else else
OS_TYPE="win" 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}" abortInstall "${red}==>${reset} ${b}OS not supported:${reset} parity one-liner currently support OS X and Linux.${n}For instructions on installing parity on other platforms please visit ${u}${blue}http://ethcore.io/${reset}"
fi fi
echo echo
@ -184,8 +199,8 @@ function run_installer()
fi fi
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+="${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" errorMessages+=" Please update the OS and reload the install process.${n}"
} }
function get_osx_dependencies() function get_osx_dependencies()
@ -201,16 +216,19 @@ function run_installer()
source /etc/lsb-release source /etc/lsb-release
if [[ $DISTRIB_ID == "Ubuntu" ]]; then if [[ $DISTRIB_ID == "Ubuntu" ]]; then
if [[ $DISTRIB_RELEASE == "14.04" ]]; then if [[ $DISTRIB_RELEASE == "14.04" || $DISTRIB_RELEASE == "15.04" || $DISTRIB_RELEASE == "15.10" ]]; then
check "Ubuntu-14.04" check "Ubuntu"
isUbuntu1404=true isUbuntu=true
else else
check "Ubuntu, but not 14.04" check "Ubuntu, but version not supported"
isUbuntu1404=false
errorMessages+="${red}==>${reset} ${b}Ubuntu version not supported:${reset} This script requires Ubuntu version 14.04, 15.04 or 15.10.${n}"
errorMessages+=" Please either upgrade your Ubuntu installation or using the get-deps.ethcore.io script instead, which can help you build Parity.${n}"
fi fi
else else
check "Ubuntu not found" check "Ubuntu not found"
isUbuntu1404=false errorMessages+="${red}==>${reset} ${b}Linux distribution not supported:${reset} This script requires Ubuntu version 14.04, 15.04 or 15.10.${n}"
errorMessages+=" Please either use this on an Ubuntu installation or instead use the get-deps.ethcore.io script, which can help you build Parity.${n}"
fi fi
} }
@ -218,15 +236,12 @@ function run_installer()
{ {
linux_version linux_version
find_multirust
find_rocksdb find_rocksdb
find_curl find_curl
find_git
find_make
find_gcc
find_apt find_apt
find_sudo
} }
function find_brew() function find_brew()
@ -242,10 +257,10 @@ function run_installer()
uncheck "Homebrew is missing" uncheck "Homebrew is missing"
isBrew=false isBrew=false
INSTALL_FILES+="${blue}${dim}==> Homebrew:${reset}\n" INSTALL_FILES+="${blue}${dim}==> Homebrew:${reset}${n}"
INSTALL_FILES+=" ${blue}${dim}${reset} $HOMEBREW_PREFIX/bin/brew\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/Library${n}"
INSTALL_FILES+=" ${blue}${dim}${reset} $HOMEBREW_PREFIX/share/man/man1/brew.1\n" INSTALL_FILES+=" ${blue}${dim}${reset} $HOMEBREW_PREFIX/share/man/man1/brew.1${n}"
fi fi
depCount=$((depCount+1)) depCount=$((depCount+1))
@ -267,11 +282,57 @@ function run_installer()
uncheck "Ruby is missing 🔥" uncheck "Ruby is missing 🔥"
isRuby=false isRuby=false
canContinue=false canContinue=false
errorMessages+="${red}==>${reset} ${b}Couldn't find Ruby:${reset} Brew requires Ruby which could not be found.\n" 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" errorMessages+=" Please install Ruby using these instructions ${u}${blue}https://www.ruby-lang.org/en/documentation/installation/${reset}.${n}"
fi fi
} }
function find_sudo()
{
depCount=$((depCount+1))
SUDO_PATH=`which sudo 2>/dev/null`
if [[ -f $SUDO_PATH ]]
then
depFound=$((depFound+1))
check "sudo"
isSudo=true
else
uncheck "sudo is missing"
if [[ `whoami` == "root" ]]; then
if [[ $isApt == false && $isMultirust == false ]]; then
canContinue=false
errorMessages+="${red}==>${reset} ${b}Couldn't find sudo:${reset} Sudo is needed for the installation of multirust.${n}"
errorMessages+=" Please ensure you have sudo installed or alternatively install multirust manually.${n}"
fi
isSudo=false
INSTALL_FILES+="${blue}${dim}==>${reset}\tsudo${n}"
else
canContinue=false
errorMessages+="${red}==>${reset} ${b}Couldn't find sudo:${reset} Root access is needed for parts of this installation.${n}"
errorMessages+=" Please ensure you have sudo installed or alternatively run this script as root.${n}"
fi
fi
}
function find_curl()
{
depCount=$((depCount+1))
CURL_PATH=`which curl 2>/dev/null`
if [[ -f $CURL_PATH ]]
then
depFound=$((depFound+1))
check "curl"
isCurl=true
else
uncheck "curl is missing"
isCurl=false
INSTALL_FILES+="${blue}${dim}==>${reset}\tcurl${n}"
fi
}
function find_rocksdb() function find_rocksdb()
{ {
depCount=$((depCount+1)) depCount=$((depCount+1))
@ -282,33 +343,7 @@ function run_installer()
else else
uncheck "librocksdb is missing" uncheck "librocksdb is missing"
isRocksDB=false isRocksDB=false
INSTALL_FILES+="${blue}${dim}==>${reset}\tlibrocksdb\n" INSTALL_FILES+="${blue}${dim}==>${reset}\tlibrocksdb${n}"
fi
}
function find_multirust()
{
depCount=$((depCount+2))
MULTIRUST_PATH=`which multirust 2>/dev/null`
if [[ -f $MULTIRUST_PATH ]]; then
depFound=$((depFound+1))
check "multirust"
isMultirust=true
if [[ $(multirust show-default 2>/dev/null | grep nightly | wc -l) == 4 ]]; then
depFound=$((depFound+1))
check "rust nightly"
isMultirustNightly=true
else
uncheck "rust is not nightly"
isMultirustNightly=false
INSTALL_FILES+="${blue}${dim}==>${reset}\tmultirust -> rust nightly\n"
fi
else
uncheck "multirust is missing"
uncheck "rust nightly is missing"
isMultirust=false
isMultirustNightly=false
INSTALL_FILES+="${blue}${dim}==>${reset}\tmultirust\n"
fi fi
} }
@ -327,112 +362,12 @@ function run_installer()
uncheck "apt-get is missing" uncheck "apt-get is missing"
isApt=false isApt=false
if [[ $isGCC == false || $isGit == false || $isMake == false || $isCurl == false ]]; then canContinue=false
canContinue=false errorMessages+="${red}==>${reset} ${b}Couldn't find apt-get:${reset} We can only use apt-get in order to grab our dependencies.${n}"
errorMessages+="${red}==>${reset} ${b}Couldn't find apt-get:${reset} We can only use apt-get in order to grab our dependencies.\n" errorMessages+=" Please switch to a distribution such as Debian or Ubuntu or manually install the missing packages.${n}"
errorMessages+=" Please switch to a distribution such as Debian or Ubuntu or manually install the missing packages.\n"
fi
fi fi
} }
function find_gcc()
{
depCount=$((depCount+1))
GCC_PATH=`which g++ 2>/dev/null`
if [[ -f $GCC_PATH ]]
then
depFound=$((depFound+1))
check "g++"
isGCC=true
else
uncheck "g++ is missing"
isGCC=false
INSTALL_FILES+="${blue}${dim}==>${reset}\tg++\n"
fi
}
function find_git()
{
depCount=$((depCount+1))
GIT_PATH=`which git 2>/dev/null`
if [[ -f $GIT_PATH ]]
then
depFound=$((depFound+1))
check "git"
isGit=true
else
uncheck "git is missing"
isGit=false
INSTALL_FILES+="${blue}${dim}==>${reset}\tgit\n"
fi
}
function find_make()
{
depCount=$((depCount+1))
MAKE_PATH=`which make 2>/dev/null`
if [[ -f $MAKE_PATH ]]
then
depFound=$((depFound+1))
check "make"
isMake=true
else
uncheck "make is missing"
isMake=false
INSTALL_FILES+="${blue}${dim}==>${reset}\tmake\n"
fi
}
function find_curl()
{
depCount=$((depCount+1))
CURL_PATH=`which curl 2>/dev/null`
if [[ -f $CURL_PATH ]]
then
depFound=$((depFound+1))
check "curl"
isCurl=true
else
uncheck "curl is missing"
isCurl=false
INSTALL_FILES+="${blue}${dim}==>${reset}\tcurl\n"
fi
}
function ubuntu1404_rocksdb_installer()
{
sudo apt-get update -qq
sudo apt-get install -qq -y software-properties-common
sudo apt-add-repository -y ppa:giskou/librocksdb
sudo apt-get -f -y install
sudo apt-get update -qq
sudo apt-get install -qq -y librocksdb
}
function linux_rocksdb_installer()
{
if [[ $isUbuntu1404 == true ]]; then
ubuntu1404_rocksdb_installer
else
oldpwd=`pwd`
cd /tmp
exe git clone --branch v4.2 --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
fi
}
function verify_installation() function verify_installation()
{ {
ETH_PATH=`which parity 2>/dev/null` ETH_PATH=`which parity 2>/dev/null`
@ -451,14 +386,10 @@ function run_installer()
info "Verifying installation" info "Verifying installation"
if [[ $OS_TYPE == "linux" ]]; then if [[ $OS_TYPE == "linux" ]]; then
find_curl
find_git
find_make
find_gcc
find_rocksdb find_rocksdb
find_multirust find_apt
if [[ $isCurl == false || $isGit == false || $isMake == false || $isGCC == false || $isRocksDB == false || $isMultirustNightly == false ]]; then if [[ $isRocksDB == false || $isApt == false ]]; then
abortInstall abortInstall
fi fi
fi fi
@ -466,43 +397,29 @@ function run_installer()
function linux_deps_installer() function linux_deps_installer()
{ {
if [[ $isGCC == false || $isGit == false || $isMake == false || $isCurl == false ]]; then if [[ $isRocksDB == false || $isCurl == false ]]; then
info "Installing build dependencies..." info "Preparing apt..."
sudo apt-get update -qq sudo apt-get update -qq
if [[ $isGit == false ]]; then
sudo apt-get install -q -y git
fi
if [[ $isGCC == false ]]; then
sudo apt-get install -q -y g++ gcc
fi
if [[ $isMake == false ]]; then
sudo apt-get install -q -y make
fi
if [[ $isCurl == false ]]; then
sudo apt-get install -q -y curl
fi
echo echo
fi fi
if [[ $isRocksDB == false ]]; then if [[ $isRocksDB == false ]]; then
info "Installing rocksdb..." info "Installing rocksdb..."
linux_rocksdb_installer
sudo apt-get install -qq -y software-properties-common
sudo apt-add-repository -y ppa:ethcore/ethcore
sudo apt-get -f -y install
sudo apt-get update -qq
sudo apt-get install -qq -y librocksdb
echo echo
fi fi
if [[ $isMultirust == false ]]; then if [[ $isCurl == false ]]; then
info "Installing multirust..." info "Installing curl..."
curl -sf https://raw.githubusercontent.com/brson/multirust/master/blastoff.sh | sudo sh -s -- --yes sudo apt-get install -q -y curl
echo echo
fi fi
if [[ $isMultirustNightly == false ]]; then
info "Installing rust nightly..."
sudo multirust update nightly
sudo multirust default nightly
echo
fi
} }
function linux_installer() function linux_installer()
@ -513,7 +430,7 @@ function run_installer()
info "Installing parity" info "Installing parity"
file=/tmp/parity.deb file=/tmp/parity.deb
wget $PARITY_DEB_URL -qO $file curl -L $PARITY_DEB_URL > $file
sudo dpkg -i $file sudo dpkg -i $file
rm $file rm $file
} }
@ -644,8 +561,8 @@ EOL
{ {
echo echo
successHeading "All done" successHeading "All done"
# head "Next steps" head "Next steps"
# info "Run ${cyan}\`\`${reset} to get started.${reset}" info "Run ${cyan}\`parity -j\`${reset} to start the Parity Ethereum client.${reset}"
echo echo
exit 0 exit 0
} }
@ -661,11 +578,9 @@ EOL
fi fi
#DEBUG #DEBUG
head "${b}OK,${reset} let's install Parity now!" head "${b}OK,${reset} let's install Parity now!"
if wait_for_user "${b}Last chance!${reset} Sure you want to install this software?" if [[ $(ask_user "${b}Last chance!${reset} Sure you want to install this software?") == true ]]; then
then
install install
echo echo
echo echo
@ -673,19 +588,12 @@ EOL
finish finish
fi fi
if [[ $OS_TYPE == "linux" && $DISTRIB_ID == "Ubuntu" ]]; then
if [[ $(ask_user "${b}Netstats${reset} Would you like to download, install and configure a Netstats client?${n}${b}${red}WARNING: ${reset}${red}This will need a secret and reconfigure any existing node/NPM installation you have.${reset} ") == true ]]; then
if [[ $OS_TYPE == "linux" ]]
then
echo "Netstats:"
head "Would you like to install and configure a netstats client?"
if wait_for_user "${b}OK,${reset} let's go!"
then
install_netstats install_netstats
fi fi
fi fi
# Display goodbye message # Display goodbye message
finish finish
} }

View File

@ -29,6 +29,7 @@ extern crate log as rlog;
extern crate env_logger; extern crate env_logger;
extern crate ctrlc; extern crate ctrlc;
extern crate fdlimit; extern crate fdlimit;
extern crate target_info;
#[cfg(feature = "rpc")] #[cfg(feature = "rpc")]
extern crate ethcore_rpc as rpc; extern crate ethcore_rpc as rpc;
@ -39,23 +40,25 @@ use rlog::{LogLevelFilter};
use env_logger::LogBuilder; use env_logger::LogBuilder;
use ctrlc::CtrlC; use ctrlc::CtrlC;
use util::*; use util::*;
use ethcore::spec::*;
use ethcore::client::*; use ethcore::client::*;
use ethcore::service::{ClientService, NetSyncMessage}; use ethcore::service::{ClientService, NetSyncMessage};
use ethcore::ethereum; use ethcore::ethereum;
use ethcore::blockchain::CacheSize; use ethcore::blockchain::CacheSize;
use ethsync::EthSync; use ethsync::EthSync;
use target_info::Target;
docopt!(Args derive Debug, " docopt!(Args derive Debug, "
Parity. Ethereum Client. Parity. Ethereum Client.
By Wood/Paronyan/Kotewicz/Drwięga/Volf.
Copyright 2015, 2016 Ethcore (UK) Limited
Usage: Usage:
parity [options] parity [options] [ <enode>... ]
parity [options] <enode>...
Options: Options:
-l --logging LOGGING Specify the logging level. --chain CHAIN Specify the blockchain type. CHAIN may be either a JSON chain specification file
-j --jsonrpc Enable the JSON-RPC API sever. or frontier, mainnet, morden, or testnet [default: frontier].
--jsonrpc-url URL Specify URL for JSON-RPC API server [default: 127.0.0.1:8545].
--listen-address URL Specify the IP/port on which to listen for peers [default: 0.0.0.0:30304]. --listen-address URL Specify the IP/port on which to listen for peers [default: 0.0.0.0:30304].
--public-address URL Specify the IP/port on which peers may connect [default: 0.0.0.0:30304]. --public-address URL Specify the IP/port on which peers may connect [default: 0.0.0.0:30304].
@ -64,6 +67,11 @@ Options:
--cache-pref-size BYTES Specify the prefered size of the blockchain cache in bytes [default: 16384]. --cache-pref-size BYTES Specify the prefered size of the blockchain cache in bytes [default: 16384].
--cache-max-size BYTES Specify the maximum size of the blockchain cache in bytes [default: 262144]. --cache-max-size BYTES Specify the maximum size of the blockchain cache in bytes [default: 262144].
-j --jsonrpc Enable the JSON-RPC API sever.
--jsonrpc-url URL Specify URL for JSON-RPC API server [default: 127.0.0.1:8545].
-l --logging LOGGING Specify the logging level.
-v --version Show information about version.
-h --help Show this screen. -h --help Show this screen.
", flag_cache_pref_size: usize, flag_cache_max_size: usize, flag_address: Option<String>); ", flag_cache_pref_size: usize, flag_cache_max_size: usize, flag_address: Option<String>);
@ -100,10 +108,28 @@ fn setup_rpc_server(_client: Arc<Client>, _sync: Arc<EthSync>, _url: &str) {
fn main() { fn main() {
let args: Args = Args::docopt().decode().unwrap_or_else(|e| e.exit()); let args: Args = Args::docopt().decode().unwrap_or_else(|e| e.exit());
if args.flag_version {
println!("
Parity version {} ({}-{}-{})
Copyright 2015, 2016 Ethcore (UK) Limited
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
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.
", env!("CARGO_PKG_VERSION"), Target::arch(), Target::env(), Target::os());
return;
}
setup_log(&args.flag_logging); setup_log(&args.flag_logging);
unsafe { ::fdlimit::raise_fd_limit(); } unsafe { ::fdlimit::raise_fd_limit(); }
let spec = ethereum::new_frontier(); let spec = match args.flag_chain.as_ref() {
"frontier" | "mainnet" => ethereum::new_frontier(),
"morden" | "testnet" => ethereum::new_morden(),
"olympic" => ethereum::new_olympic(),
f => Spec::from_json_utf8(contents(f).expect("Couldn't read chain specification file. Sure it exists?").as_ref()),
};
let init_nodes = match args.arg_enode.len() { let init_nodes = match args.arg_enode.len() {
0 => spec.nodes().clone(), 0 => spec.nodes().clone(),
_ => args.arg_enode.clone(), _ => args.arg_enode.clone(),

View File

@ -16,6 +16,7 @@
//! Diff misc. //! Diff misc.
use std::fs::File;
use common::*; use common::*;
#[derive(Debug,Clone,PartialEq,Eq)] #[derive(Debug,Clone,PartialEq,Eq)]
@ -53,3 +54,11 @@ pub enum Filth {
/// Data has been changed. /// Data has been changed.
Dirty, Dirty,
} }
/// Read the whole contents of a file `name`.
pub fn contents(name: &str) -> Result<Bytes, UtilError> {
let mut file = try!(File::open(name));
let mut ret: Vec<u8> = Vec::new();
try!(file.read_to_end(&mut ret));
Ok(ret)
}