Merge branch 'master' into sync-svc

This commit is contained in:
NikVolf
2016-07-16 15:57:30 +02:00
51 changed files with 28433 additions and 1011 deletions

View File

@@ -18,6 +18,8 @@
extern crate ethash;
use std::io::{Write};
use std::process::{Command, Stdio};
use std::thread;
use std::time::{Instant, Duration};
use std::sync::{Arc, Weak};
@@ -28,7 +30,7 @@ use jsonrpc_core::*;
use util::numbers::*;
use util::sha3::*;
use util::rlp::{encode, decode, UntrustedRlp, View};
use util::Mutex;
use util::{FromHex, Mutex};
use ethcore::account_provider::AccountProvider;
use ethcore::client::{MiningBlockChainClient, BlockID, TransactionID, UncleID};
use ethcore::header::Header as BlockHeader;
@@ -255,6 +257,12 @@ impl<C, S: ?Sized, M, EM> EthClient<C, S, M, EM> where
}
}
#[cfg(windows)]
static SOLC: &'static str = "solc.exe";
#[cfg(not(windows))]
static SOLC: &'static str = "solc";
impl<C, S: ?Sized, M, EM> Eth for EthClient<C, S, M, EM> where
C: MiningBlockChainClient + 'static,
S: SyncProvider + 'static,
@@ -508,7 +516,13 @@ impl<C, S: ?Sized, M, EM> Eth for EthClient<C, S, M, EM> where
fn compilers(&self, params: Params) -> Result<Value, Error> {
try!(self.active());
match params {
Params::None => to_value(&(&[] as &[String])),
Params::None => {
let mut compilers = vec![];
if Command::new(SOLC).output().is_ok() {
compilers.push("solidity".to_owned())
}
to_value(&compilers)
}
_ => Err(Error::invalid_params())
}
}
@@ -647,8 +661,28 @@ impl<C, S: ?Sized, M, EM> Eth for EthClient<C, S, M, EM> where
rpc_unimplemented!()
}
fn compile_solidity(&self, _: Params) -> Result<Value, Error> {
fn compile_solidity(&self, params: Params) -> Result<Value, Error> {
try!(self.active());
rpc_unimplemented!()
from_params::<(String, )>(params)
.and_then(|(code, )| {
let maybe_child = Command::new(SOLC)
.arg("--bin")
.arg("--optimize")
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.stderr(Stdio::null())
.spawn();
if let Ok(mut child) = maybe_child {
if let Ok(_) = child.stdin.as_mut().expect("we called child.stdin(Stdio::piped()) before spawn; qed").write_all(code.as_bytes()) {
if let Ok(output) = child.wait_with_output() {
let s = String::from_utf8_lossy(&output.stdout);
if let Some(hex) = s.lines().skip_while(|ref l| !l.contains("Binary")).skip(1).next() {
return to_value(&Bytes::new(hex.from_hex().unwrap_or(vec![])));
}
}
}
}
Err(Error::invalid_params())
})
}
}

View File

@@ -201,7 +201,10 @@ const TRANSACTION_COUNT_SPEC: &'static [u8] = br#"{
"durationLimit": "0x0d",
"blockReward": "0x4563918244F40000",
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
"frontierCompatibilityModeLimit": "0xffffffffffffffff"
"frontierCompatibilityModeLimit": "0xffffffffffffffff",
"daoHardforkTransition": "0xffffffffffffffff",
"daoHardforkBeneficiary": "0x0000000000000000000000000000000000000000",
"daoHardforkAccounts": []
}
}
},

View File

@@ -707,6 +707,11 @@ fn rpc_eth_compilers() {
assert_eq!(EthTester::default().io.handle_request(request), Some(response.to_owned()));
}
// These tests are incorrect: their output is undefined as long as eth_getCompilers is [].
// Will ignore for now, but should probably be replaced by more substantial tests which check
// the output of eth_getCompilers to determine whether to test. CI systems can then be preinstalled
// with solc/serpent/lllc and they'll be proper again.
#[ignore]
#[test]
fn rpc_eth_compile_lll() {
let request = r#"{"jsonrpc": "2.0", "method": "eth_compileLLL", "params": [], "id": 1}"#;
@@ -715,6 +720,7 @@ fn rpc_eth_compile_lll() {
assert_eq!(EthTester::default().io.handle_request(request), Some(response.to_owned()));
}
#[ignore]
#[test]
fn rpc_eth_compile_solidity() {
let request = r#"{"jsonrpc": "2.0", "method": "eth_compileSolidity", "params": [], "id": 1}"#;
@@ -723,6 +729,7 @@ fn rpc_eth_compile_solidity() {
assert_eq!(EthTester::default().io.handle_request(request), Some(response.to_owned()));
}
#[ignore]
#[test]
fn rpc_eth_compile_serpent() {
let request = r#"{"jsonrpc": "2.0", "method": "eth_compileSerpent", "params": [], "id": 1}"#;

View File

@@ -32,7 +32,7 @@ fn client_service() -> Arc<TestBlockChainClient> {
}
fn logger() -> Arc<RotatingLogger> {
Arc::new(RotatingLogger::new("rpc=trace".to_owned(), false))
Arc::new(RotatingLogger::new("rpc=trace".to_owned()))
}
fn settings() -> Arc<NetworkSettings> {

View File

@@ -28,7 +28,7 @@ pub enum BlockNumber {
/// Earliest block (genesis)
Earliest,
/// Pending block (being mined)
Pending
Pending,
}
impl Deserialize for BlockNumber {
@@ -63,8 +63,8 @@ impl Into<BlockID> for BlockNumber {
match self {
BlockNumber::Num(n) => BlockID::Number(n),
BlockNumber::Earliest => BlockID::Earliest,
// TODO: change this once blockid support pendingst,
BlockNumber::Pending | BlockNumber::Latest => BlockID::Latest,
BlockNumber::Latest => BlockID::Latest,
BlockNumber::Pending => BlockID::Pending,
}
}
}
@@ -87,7 +87,7 @@ mod tests {
assert_eq!(BlockID::Number(100), BlockNumber::Num(100).into());
assert_eq!(BlockID::Earliest, BlockNumber::Earliest.into());
assert_eq!(BlockID::Latest, BlockNumber::Latest.into());
assert_eq!(BlockID::Latest, BlockNumber::Pending.into());
assert_eq!(BlockID::Pending, BlockNumber::Pending.into());
}
}