merge with master

This commit is contained in:
Robert Habermeier 2016-07-12 13:09:42 +02:00
commit 60302acb94
35 changed files with 367 additions and 113 deletions

20
Cargo.lock generated
View File

@ -3,7 +3,7 @@ name = "parity"
version = "1.3.0"
dependencies = [
"ansi_term 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
"clippy 0.0.78 (registry+https://github.com/rust-lang/crates.io-index)",
"clippy 0.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
"ctrlc 1.1.1 (git+https://github.com/ethcore/rust-ctrlc.git)",
"daemonize 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"docopt 0.6.80 (registry+https://github.com/rust-lang/crates.io-index)",
@ -129,15 +129,15 @@ dependencies = [
[[package]]
name = "clippy"
version = "0.0.78"
version = "0.0.79"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"clippy_lints 0.0.78 (registry+https://github.com/rust-lang/crates.io-index)",
"clippy_lints 0.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "clippy_lints"
version = "0.0.78"
version = "0.0.79"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -239,7 +239,7 @@ name = "ethcore"
version = "1.3.0"
dependencies = [
"bloomchain 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"clippy 0.0.78 (registry+https://github.com/rust-lang/crates.io-index)",
"clippy 0.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
"env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"ethash 1.3.0",
@ -267,7 +267,7 @@ dependencies = [
name = "ethcore-dapps"
version = "1.3.0"
dependencies = [
"clippy 0.0.78 (registry+https://github.com/rust-lang/crates.io-index)",
"clippy 0.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
"ethcore-rpc 1.3.0",
"ethcore-util 1.3.0",
"hyper 0.9.4 (git+https://github.com/ethcore/hyper)",
@ -343,7 +343,7 @@ dependencies = [
name = "ethcore-rpc"
version = "1.3.0"
dependencies = [
"clippy 0.0.78 (registry+https://github.com/rust-lang/crates.io-index)",
"clippy 0.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
"ethash 1.3.0",
"ethcore 1.3.0",
"ethcore-devtools 1.3.0",
@ -367,7 +367,7 @@ dependencies = [
name = "ethcore-signer"
version = "1.3.0"
dependencies = [
"clippy 0.0.78 (registry+https://github.com/rust-lang/crates.io-index)",
"clippy 0.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
"env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"ethcore-rpc 1.3.0",
"ethcore-util 1.3.0",
@ -387,7 +387,7 @@ dependencies = [
"arrayvec 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
"bigint 0.1.0",
"chrono 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)",
"clippy 0.0.78 (registry+https://github.com/rust-lang/crates.io-index)",
"clippy 0.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
"elastic-array 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
@ -459,7 +459,7 @@ dependencies = [
name = "ethsync"
version = "1.3.0"
dependencies = [
"clippy 0.0.78 (registry+https://github.com/rust-lang/crates.io-index)",
"clippy 0.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
"env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"ethcore 1.3.0",
"ethcore-util 1.3.0",

View File

@ -22,7 +22,7 @@ fdlimit = { path = "util/fdlimit" }
num_cpus = "0.2"
number_prefix = "0.2"
rpassword = "0.2.1"
clippy = { version = "0.0.78", optional = true}
clippy = { version = "0.0.79", optional = true}
ethcore = { path = "ethcore" }
ethcore-util = { path = "util" }
ethsync = { path = "sync" }

View File

@ -29,7 +29,7 @@ parity-dapps-wallet = { git = "https://github.com/ethcore/parity-dapps-wallet-rs
parity-dapps-dao = { git = "https://github.com/ethcore/parity-dapps-dao-rs.git", version = "0.4.0", optional = true }
parity-dapps-makerotc = { git = "https://github.com/ethcore/parity-dapps-makerotc-rs.git", version = "0.3.0", optional = true }
mime_guess = { version = "1.6.1" }
clippy = { version = "0.0.78", optional = true}
clippy = { version = "0.0.79", optional = true}
[build-dependencies]
serde_codegen = { version = "0.7.0", optional = true }

View File

@ -12,7 +12,7 @@ syntex = "*"
ethcore-ipc-codegen = { path = "../ipc/codegen" }
[dependencies]
clippy = { version = "0.0.78", optional = true}
clippy = { version = "0.0.79", optional = true}
ethcore-devtools = { path = "../devtools" }
ethcore-ipc = { path = "../ipc/rpc" }
rocksdb = { git = "https://github.com/ethcore/rust-rocksdb" }

View File

@ -60,7 +60,7 @@ impl WriteCache {
self.entries.insert(key, WriteCacheEntry::Remove);
}
fn get(&self, key: &Vec<u8>) -> Option<Vec<u8>> {
fn get(&self, key: &[u8]) -> Option<Vec<u8>> {
self.entries.get(key).and_then(
|vec_ref| match vec_ref {
&WriteCacheEntry::Write(ref val) => Some(val.clone()),

View File

@ -22,7 +22,7 @@ ethcore-util = { path = "../util" }
evmjit = { path = "../evmjit", optional = true }
ethash = { path = "../ethash" }
num_cpus = "0.2"
clippy = { version = "0.0.78", optional = true}
clippy = { version = "0.0.79", optional = true}
crossbeam = "0.2.9"
lazy_static = "0.2"
ethcore-devtools = { path = "../devtools" }

View File

@ -16,8 +16,6 @@
//! Blockchain block.
#![cfg_attr(feature="dev", allow(ptr_arg))] // Because of &LastHashes -> &Vec<_>
use common::*;
use engine::*;
use state::*;
@ -76,11 +74,11 @@ pub struct BlockRefMut<'a> {
/// Block header.
pub header: &'a mut Header,
/// Block transactions.
pub transactions: &'a Vec<SignedTransaction>,
pub transactions: &'a [SignedTransaction],
/// Block uncles.
pub uncles: &'a Vec<Header>,
pub uncles: &'a [Header],
/// Transaction receipts.
pub receipts: &'a Vec<Receipt>,
pub receipts: &'a [Receipt],
/// State.
pub state: &'a mut State,
/// Traces.
@ -92,11 +90,11 @@ pub struct BlockRef<'a> {
/// Block header.
pub header: &'a Header,
/// Block transactions.
pub transactions: &'a Vec<SignedTransaction>,
pub transactions: &'a [SignedTransaction],
/// Block uncles.
pub uncles: &'a Vec<Header>,
pub uncles: &'a [Header],
/// Transaction receipts.
pub receipts: &'a Vec<Receipt>,
pub receipts: &'a [Receipt],
/// State.
pub state: &'a State,
/// Traces.
@ -152,16 +150,16 @@ pub trait IsBlock {
fn state(&self) -> &State { &self.block().state }
/// Get all information on transactions in this block.
fn transactions(&self) -> &Vec<SignedTransaction> { &self.block().base.transactions }
fn transactions(&self) -> &[SignedTransaction] { &self.block().base.transactions }
/// Get all information on receipts in this block.
fn receipts(&self) -> &Vec<Receipt> { &self.block().receipts }
fn receipts(&self) -> &[Receipt] { &self.block().receipts }
/// Get all information concerning transaction tracing in this block.
fn traces(&self) -> &Option<Vec<Trace>> { &self.block().traces }
/// Get all uncles in this block.
fn uncles(&self) -> &Vec<Header> { &self.block().base.uncles }
fn uncles(&self) -> &[Header] { &self.block().base.uncles }
}
/// Trait for a object that has a state database.

View File

@ -426,7 +426,7 @@ impl Client {
};
// Commit results
let receipts = block.receipts().clone();
let receipts = block.receipts().to_owned();
let traces = From::from(block.traces().clone().unwrap_or_else(Vec::new));
// CHECK! I *think* this is fine, even if the state_root is equal to another

View File

@ -107,6 +107,9 @@ pub trait CostType: ops::Mul<Output=Self> + ops::Div<Output=Self> + ops::Add<Out
fn overflow_add(self, other: Self) -> (Self, bool);
/// Multiple with overflow
fn overflow_mul(self, other: Self) -> (Self, bool);
/// Single-step full multiplication and division: `self*other/div`
/// Should not overflow on intermediate steps
fn overflow_mul_div(self, other: Self, div: Self) -> (Self, bool);
}
impl CostType for U256 {
@ -129,6 +132,17 @@ impl CostType for U256 {
fn overflow_mul(self, other: Self) -> (Self, bool) {
Uint::overflowing_mul(self, other)
}
fn overflow_mul_div(self, other: Self, div: Self) -> (Self, bool) {
let x = self.full_mul(other);
let (U512(parts), o) = Uint::overflowing_div(x, U512::from(div));
let overflow = (parts[4] | parts[5] | parts[6] | parts[7]) > 0;
(
U256([parts[0], parts[1], parts[2], parts[3]]),
o | overflow
)
}
}
impl CostType for usize {
@ -154,6 +168,14 @@ impl CostType for usize {
fn overflow_mul(self, other: Self) -> (Self, bool) {
self.overflowing_mul(other)
}
fn overflow_mul_div(self, other: Self, div: Self) -> (Self, bool) {
let (c, o) = U128::from(self).overflowing_mul(U128::from(other));
let (U128(parts), o1) = c.overflowing_div(U128::from(div));
let result = parts[0] as usize;
let overflow = o | o1 | (parts[1] > 0) | (parts[0] > result as u64);
(result, overflow)
}
}
/// Evm interface
@ -164,3 +186,41 @@ pub trait Evm {
/// to compute the final gas left.
fn exec(&mut self, params: ActionParams, ext: &mut Ext) -> Result<GasLeft>;
}
#[test]
fn should_calculate_overflow_mul_div_without_overflow() {
// given
let num = 10_000_000;
// when
let (res1, o1) = U256::from(num).overflow_mul_div(U256::from(num), U256::from(num));
let (res2, o2) = num.overflow_mul_div(num, num);
// then
assert_eq!(res1, U256::from(num));
assert!(!o1);
assert_eq!(res2, num);
assert!(!o2);
}
#[test]
fn should_calculate_overflow_mul_div_with_overflow() {
// given
let max = ::std::u64::MAX;
let num1 = U256([max, max, max, max]);
let num2 = ::std::usize::MAX;
// when
let (res1, o1) = num1.overflow_mul_div(num1, num1 - U256::from(2));
let (res2, o2) = num2.overflow_mul_div(num2, num2 - 2);
// then
// (x+2)^2/x = (x^2 + 4x + 4)/x = x + 4 + 4/x ~ (MAX-2) + 4 + 0 = 1
assert_eq!(res2, 1);
assert!(o2);
assert_eq!(res1, U256::from(1));
assert!(o1);
}

View File

@ -68,6 +68,9 @@ impl<Gas: CostType> Gasometer<Gas> {
let default_gas = Gas::from(schedule.tier_step_gas[tier]);
let cost = match instruction {
instructions::JUMPDEST => {
InstructionCost::Gas(Gas::from(1))
},
instructions::SSTORE => {
let address = H256::from(stack.peek(0));
let newval = stack.peek(1);
@ -106,9 +109,6 @@ impl<Gas: CostType> Gasometer<Gas> {
instructions::EXTCODECOPY => {
InstructionCost::GasMemCopy(default_gas, try!(self.mem_needed(stack.peek(1), stack.peek(3))), try!(Gas::from_u256(*stack.peek(3))))
},
instructions::JUMPDEST => {
InstructionCost::Gas(Gas::from(1))
},
instructions::LOG0...instructions::LOG4 => {
let no_of_topics = instructions::get_log_topics(instruction);
let log_gas = schedule.log_gas + schedule.log_topic_gas * no_of_topics;
@ -199,14 +199,12 @@ impl<Gas: CostType> Gasometer<Gas> {
let s = mem_size >> 5;
// s * memory_gas + s * s / quad_coeff_div
let a = overflowing!(s.overflow_mul(Gas::from(schedule.memory_gas)));
// We need to go to U512 to calculate s*s/quad_coeff_div
let b = U512::from(s.as_u256()) * U512::from(s.as_u256()) / U512::from(schedule.quad_coeff_div);
if b > U512::from(!U256::zero()) {
Err(evm::Error::OutOfGas)
} else {
Ok(overflowing!(a.overflow_add(try!(Gas::from_u256(U256::from(b))))))
}
// Calculate s*s/quad_coeff_div
let b = overflowing!(s.overflow_mul_div(s, Gas::from(schedule.quad_coeff_div)));
Ok(overflowing!(a.overflow_add(b)))
};
let current_mem_size = Gas::from(current_mem_size);
let req_mem_size_rounded = (overflowing!(mem_size.overflow_add(Gas::from(31 as usize))) >> 5) << 5;

View File

@ -143,7 +143,7 @@ impl Header {
/// Get the difficulty field of the header.
pub fn difficulty(&self) -> &U256 { &self.difficulty }
/// Get the seal field of the header.
pub fn seal(&self) -> &Vec<Bytes> { &self.seal }
pub fn seal(&self) -> &[Bytes] { &self.seal }
// TODO: seal_at, set_seal_at &c.

View File

@ -98,7 +98,7 @@ const V7_VERSION_KEY: &'static [u8] = &[ b'j', b'v', b'e', b'r', 0, 0, 0, 0, 0,
const DB_VERSION: u32 = 0x203;
const PADDING : [u8; 10] = [0u8; 10];
/// Version for OverlayRecent database.
/// Version for `OverlayRecent` database.
/// more involved than the archive version because of journaling.
#[derive(Default)]
pub struct OverlayRecentV7 {

View File

@ -665,7 +665,7 @@ impl MinerService for Miner {
};
match (&self.options.pending_set, sealing_set) {
(&PendingSet::AlwaysQueue, _) | (&PendingSet::SealingOrElseQueue, None) => queue.top_transactions(),
(_, sealing) => sealing.map_or_else(Vec::new, |s| s.transactions().clone()),
(_, sealing) => sealing.map_or_else(Vec::new, |s| s.transactions().to_owned()),
}
}
@ -702,7 +702,7 @@ impl MinerService for Miner {
.iter()
.map(|t| t.hash());
let receipts = pending.receipts().clone().into_iter();
let receipts = pending.receipts().iter().cloned();
hashes.zip(receipts).collect()
},

View File

@ -143,7 +143,7 @@ impl Spec {
}
/// Get the known knodes of the network in enode format.
pub fn nodes(&self) -> &Vec<String> { &self.nodes }
pub fn nodes(&self) -> &[String] { &self.nodes }
/// Get the configured Network ID.
pub fn network_id(&self) -> U256 { self.params.network_id }

View File

@ -4,6 +4,14 @@ description = "Parity's EVM implementation"
version = "0.1.0"
authors = ["Ethcore <admin@ethcore.io>"]
[lib]
name = "evm"
path = "./src/main.rs"
[[bin]]
name = "evm"
path = "./src/main.rs"
[dependencies]
rustc-serialize = "0.3"
docopt = { version = "0.6" }

24
evmbin/bench.sh Executable file
View File

@ -0,0 +1,24 @@
#!/bin/bash
set -x
set -e
cargo build --release
# LOOP TEST
CODE1=606060405260005b620f42408112156019575b6001016007565b600081905550600680602b6000396000f3606060405200
ethvm --code $CODE1
echo "^^^^ ethvm"
./target/release/evm stats --code $CODE1 --gas 4402000
echo "^^^^ usize"
./target/release/evm stats --code $CODE1
echo "^^^^ U256"
# RNG TEST
CODE2=6060604052600360056007600b60005b620f4240811215607f5767ffe7649d5eca84179490940267f47ed85c4b9a6379019367f8e5dd9a5c994bba9390930267f91d87e4b8b74e55019267ff97f6f3b29cda529290920267f393ada8dd75c938019167fe8d437c45bb3735830267f47d9a7b5428ffec019150600101600f565b838518831882186000555050505050600680609a6000396000f3606060405200
ethvm --code $CODE2
echo "^^^^ ethvm"
./target/release/evm stats --code $CODE2 --gas 143020115
echo "^^^^ usize"
./target/release/evm stats --code $CODE2
echo "^^^^ U256"

85
evmbin/benches/mod.rs Normal file
View File

@ -0,0 +1,85 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! benchmarking for EVM
//! should be started with:
//! ```bash
//! multirust run nightly cargo bench
//! ```
#![feature(test)]
extern crate test;
extern crate ethcore;
extern crate evm;
extern crate ethcore_util;
extern crate rustc_serialize;
use self::test::{Bencher, black_box};
use evm::run_vm;
use ethcore::action_params::ActionParams;
use ethcore_util::{U256, Uint};
use rustc_serialize::hex::FromHex;
#[bench]
fn simple_loop_usize(b: &mut Bencher) {
simple_loop(U256::from(::std::usize::MAX), b)
}
#[bench]
fn simple_loop_u256(b: &mut Bencher) {
simple_loop(!U256::zero(), b)
}
fn simple_loop(gas: U256, b: &mut Bencher) {
let code = black_box(
"606060405260005b620042408112156019575b6001016007565b600081905550600680602b6000396000f3606060405200".from_hex().unwrap()
);
b.iter(|| {
let mut params = ActionParams::default();
params.gas = gas;
params.code = Some(code.clone());
run_vm(params)
});
}
#[bench]
fn rng_usize(b: &mut Bencher) {
rng(U256::from(::std::usize::MAX), b)
}
#[bench]
fn rng_u256(b: &mut Bencher) {
rng(!U256::zero(), b)
}
fn rng(gas: U256, b: &mut Bencher) {
let code = black_box(
"6060604052600360056007600b60005b62004240811215607f5767ffe7649d5eca84179490940267f47ed85c4b9a6379019367f8e5dd9a5c994bba9390930267f91d87e4b8b74e55019267ff97f6f3b29cda529290920267f393ada8dd75c938019167fe8d437c45bb3735830267f47d9a7b5428ffec019150600101600f565b838518831882186000555050505050600680609a6000396000f3606060405200".from_hex().unwrap()
);
b.iter(|| {
let mut params = ActionParams::default();
params.gas = gas;
params.code = Some(code.clone());
run_vm(params)
});
}

View File

@ -17,6 +17,7 @@
//! Parity EVM interpreter binary.
#![warn(missing_docs)]
#![allow(dead_code)]
extern crate ethcore;
extern crate rustc_serialize;
extern crate docopt;
@ -25,7 +26,7 @@ extern crate ethcore_util as util;
mod ext;
use std::time::Instant;
use std::time::{Instant, Duration};
use std::str::FromStr;
use docopt::Docopt;
use util::{U256, FromHex, Uint, Bytes};
@ -58,6 +59,15 @@ fn main() {
params.code = Some(args.code());
params.data = args.data();
let result = run_vm(params);
println!("Gas used: {:?}", result.gas_used);
println!("Output: {:?}", result.output);
println!("Time: {}.{:.9}s", result.time.as_secs(), result.time.subsec_nanos());
}
/// Execute VM with given `ActionParams`
pub fn run_vm(params: ActionParams) -> ExecutionResults {
let initial_gas = params.gas;
let factory = Factory::new(VMType::Interpreter);
let mut vm = factory.create(params.gas);
let mut ext = ext::FakeExt::default();
@ -66,9 +76,21 @@ fn main() {
let gas_left = vm.exec(params, &mut ext).finalize(ext).expect("OK");
let duration = start.elapsed();
println!("Gas used: {:?}", args.gas() - gas_left);
println!("Output: {:?}", "");
println!("Time: {}.{:.9}s", duration.as_secs(), duration.subsec_nanos());
ExecutionResults {
gas_used: initial_gas - gas_left,
output: Vec::new(),
time: duration,
}
}
/// VM execution results
pub struct ExecutionResults {
/// Used gas
pub gas_used: U256,
/// Output as bytes
pub output: Vec<u8>,
/// Time Taken
pub time: Duration,
}
#[derive(Debug, RustcDecodable)]

View File

@ -62,24 +62,10 @@ pub fn expand_ipc_implementation(
};
push_client(cx, &builder, &interface_map, push);
push_handshake_struct(cx, push);
push(Annotatable::Item(interface_map.item));
}
fn push_handshake_struct(cx: &ExtCtxt, push: &mut FnMut(Annotatable)) {
let handshake_item = quote_item!(cx,
#[derive(Binary)]
pub struct BinHandshake {
api_version: String,
protocol_version: String,
reserved: Vec<u8>,
}
).unwrap();
push(Annotatable::Item(handshake_item));
}
fn field_name(builder: &aster::AstBuilder, arg: &Arg) -> ast::Ident {
match arg.pat.node {
PatKind::Ident(_, ref ident, _) => builder.id(ident.node),
@ -601,15 +587,14 @@ fn push_client_implementation(
let handshake_item = quote_impl_item!(cx,
pub fn handshake(&self) -> Result<(), ::ipc::Error> {
let payload = BinHandshake {
protocol_version: $item_ident::protocol_version().to_string(),
api_version: $item_ident::api_version().to_string(),
reserved: vec![0u8; 64],
let payload = ::ipc::Handshake {
protocol_version: $item_ident::protocol_version(),
api_version: $item_ident::api_version(),
};
::ipc::invoke(
0,
&Some(::ipc::binary::serialize(&payload).unwrap()),
&Some(::ipc::binary::serialize(&::ipc::BinHandshake::from(payload)).unwrap()),
&mut *self.socket.write().unwrap());
let mut result = vec![0u8; 1];
@ -673,18 +658,15 @@ fn implement_handshake_arm(
) -> (ast::Arm, ast::Arm)
{
let handshake_deserialize = quote_stmt!(&cx,
let handshake_payload = ::ipc::binary::deserialize_from::<BinHandshake, _>(r).unwrap();
let handshake_payload = ::ipc::binary::deserialize_from::<::ipc::BinHandshake, _>(r).unwrap();
);
let handshake_deserialize_buf = quote_stmt!(&cx,
let handshake_payload = ::ipc::binary::deserialize::<BinHandshake>(buf).unwrap();
let handshake_payload = ::ipc::binary::deserialize::<::ipc::BinHandshake>(buf).unwrap();
);
let handshake_serialize = quote_expr!(&cx,
::ipc::binary::serialize::<bool>(&Self::handshake(&::ipc::Handshake {
api_version: ::semver::Version::parse(&handshake_payload.api_version).unwrap(),
protocol_version: ::semver::Version::parse(&handshake_payload.protocol_version).unwrap(),
})).unwrap()
::ipc::binary::serialize::<bool>(&Self::handshake(&handshake_payload.to_semver())).unwrap()
);
(

View File

@ -8,6 +8,6 @@ license = "GPL-3.0"
[dependencies]
ethcore-devtools = { path = "../../devtools" }
semver = "0.2.0"
nanomsg = { git = "https://github.com/ethcore/nanomsg.rs.git" }
ethcore-util = { path = "../../util" }
semver = "0.2"

View File

@ -21,6 +21,7 @@ use util::numbers::{U256, U512, H256, H2048, Address};
use std::mem;
use std::collections::{VecDeque, BTreeMap};
use std::ops::Range;
use super::Handshake;
#[derive(Debug)]
pub struct BinaryConvertError;
@ -554,6 +555,61 @@ macro_rules! binary_fixed_size {
}
}
/// Fixed-sized version of Handshake struct
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct BinHandshake {
api_version: BinVersion,
protocol_version: BinVersion,
}
/// Shorten version of semver Version without `pre` and `build` information
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct BinVersion {
pub major: u64,
pub minor: u64,
pub patch: u64,
}
impl From<Handshake> for BinHandshake {
fn from(other: Handshake) -> Self {
BinHandshake {
api_version: BinVersion::from(other.api_version),
protocol_version: BinVersion::from(other.protocol_version),
}
}
}
impl BinHandshake {
pub fn to_semver(self) -> Handshake {
Handshake {
api_version: self.api_version.to_semver(),
protocol_version: self.protocol_version.to_semver(),
}
}
}
impl BinVersion {
pub fn to_semver(self) -> ::semver::Version {
::semver::Version {
major: self.major,
minor: self.minor,
patch: self.patch,
pre: vec![],
build: vec![],
}
}
}
impl From<::semver::Version> for BinVersion {
fn from(other: ::semver::Version) -> Self {
BinVersion {
major: other.major,
minor: other.minor,
patch: other.patch,
}
}
}
binary_fixed_size!(u64);
binary_fixed_size!(u32);
binary_fixed_size!(usize);
@ -564,6 +620,7 @@ binary_fixed_size!(U512);
binary_fixed_size!(H256);
binary_fixed_size!(H2048);
binary_fixed_size!(Address);
binary_fixed_size!(BinHandshake);
#[test]
fn vec_serialize() {
@ -706,8 +763,6 @@ fn serialize_opt_vec() {
#[test]
fn serialize_opt_vec_payload() {
use std::io::Cursor;
let optional_vec: Option<Vec<u8>> = None;
let payload = serialize(&optional_vec).unwrap();
@ -776,3 +831,23 @@ fn serialize_btree() {
assert_eq!(res[&1u64], 5u64);
}
#[test]
fn serialize_handshake() {
use std::io::{Cursor, SeekFrom, Seek};
let mut buff = Cursor::new(Vec::new());
let handshake = Handshake {
api_version: ::semver::Version::parse("1.2.0").unwrap(),
protocol_version: ::semver::Version::parse("1.2.0").unwrap(),
};
serialize_into(&BinHandshake::from(handshake.clone()), &mut buff).unwrap();
buff.seek(SeekFrom::Start(0)).unwrap();
let res = deserialize_from::<BinHandshake, _>(&mut buff).unwrap().to_semver();
assert_eq!(res, handshake);
}

View File

@ -20,6 +20,7 @@ use std::io::{Read, Write};
use std::marker::Sync;
use semver::Version;
#[derive(Debug, PartialEq, Eq, Clone)]
/// Handshake for client and server to negotiate api/protocol version
pub struct Handshake {
pub protocol_version: Version,

View File

@ -24,4 +24,4 @@ extern crate ethcore_util as util;
pub mod interface;
pub mod binary;
pub use interface::{IpcInterface, IpcSocket, invoke, IpcConfig, Handshake, Error, WithSocket};
pub use binary::{BinaryConvertable, BinaryConvertError};
pub use binary::{BinaryConvertable, BinaryConvertError, BinHandshake};

View File

@ -10,7 +10,7 @@ rustc-serialize = "0.3"
serde = "0.7.0"
serde_json = "0.7.0"
serde_macros = { version = "0.7.0", optional = true }
clippy = { version = "0.0.78", optional = true}
clippy = { version = "0.0.79", optional = true}
[build-dependencies]
serde_codegen = { version = "0.7.0", optional = true }

View File

@ -40,9 +40,9 @@ impl Into<Vec<u8>> for Bytes {
}
impl Deref for Bytes {
type Target = Vec<u8>;
type Target = [u8];
fn deref(&self) -> &Vec<u8> {
fn deref(&self) -> &[u8] {
&self.0
}
}

View File

@ -238,7 +238,7 @@ impl Configuration {
})
}).collect(),
Some(_) => Vec::new(),
None => spec.nodes().clone(),
None => spec.nodes().to_owned(),
}
}

View File

@ -23,7 +23,7 @@ ethcore-devtools = { path = "../devtools" }
rustc-serialize = "0.3"
transient-hashmap = "0.1"
serde_macros = { version = "0.7.0", optional = true }
clippy = { version = "0.0.78", optional = true}
clippy = { version = "0.0.79", optional = true}
json-ipc-server = { git = "https://github.com/ethcore/json-ipc-server.git" }
ethcore-ipc = { path = "../ipc/rpc" }

View File

@ -508,7 +508,7 @@ impl<C, S, 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(&vec![] as &Vec<String>),
Params::None => to_value(&(&[] as &[String])),
_ => Err(Error::invalid_params())
}
}

View File

@ -20,7 +20,7 @@ ethcore-util = { path = "../util" }
ethcore-rpc = { path = "../rpc" }
parity-minimal-sysui = { git = "https://github.com/ethcore/parity-dapps-minimal-sysui-rs.git", version = "0.2.0" }
clippy = { version = "0.0.78", optional = true}
clippy = { version = "0.0.79", optional = true}
[features]
dev = ["clippy"]

View File

@ -25,11 +25,11 @@ use std::str::FromStr;
use jsonrpc_core::IoHandler;
use util::H256;
fn origin_is_allowed(self_origin: &str, header: Option<&Vec<u8>>) -> bool {
fn origin_is_allowed(self_origin: &str, header: Option<&[u8]>) -> bool {
match header {
None => false,
Some(h) => {
let v = String::from_utf8(h.clone()).ok();
let v = String::from_utf8(h.to_owned()).ok();
match v {
Some(ref origin) if origin.starts_with("chrome-extension://") => true,
Some(ref origin) if origin.starts_with(self_origin) => true,
@ -84,8 +84,8 @@ pub struct Session {
impl ws::Handler for Session {
fn on_request(&mut self, req: &ws::Request) -> ws::Result<(ws::Response)> {
let origin = req.header("origin").or_else(|| req.header("Origin"));
let host = req.header("host").or_else(|| req.header("Host"));
let origin = req.header("origin").or_else(|| req.header("Origin")).map(|x| &x[..]);
let host = req.header("host").or_else(|| req.header("Host")).map(|x| &x[..]);
// Check request origin and host header.
if !origin_is_allowed(&self.self_origin, origin) && !(origin.is_none() && origin_is_allowed(&self.self_origin, host)) {

View File

@ -10,7 +10,7 @@ authors = ["Ethcore <admin@ethcore.io"]
[dependencies]
ethcore-util = { path = "../util" }
ethcore = { path = "../ethcore" }
clippy = { version = "0.0.78", optional = true}
clippy = { version = "0.0.79", optional = true}
log = "0.3"
env_logger = "0.3"
time = "0.1.34"

View File

@ -27,7 +27,7 @@ itertools = "0.4"
crossbeam = "0.2"
slab = "0.2"
sha3 = { path = "sha3" }
clippy = { version = "0.0.78", optional = true}
clippy = { version = "0.0.79", optional = true}
igd = "0.5.0"
ethcore-devtools = { path = "../devtools" }
libc = "0.2.7"

View File

@ -242,7 +242,7 @@ pub enum FromBytesError {
}
/// Value that can be serialized from bytes array
pub trait FromRawBytes : Sized {
pub trait FromRawBytes: Sized {
/// function that will instantiate and initialize object from slice
fn from_bytes(d: &[u8]) -> Result<Self, FromBytesError>;
}
@ -255,7 +255,7 @@ impl<T> FromRawBytes for T where T: FixedHash {
Ordering::Equal => ()
};
let mut res: Self = unsafe { mem::uninitialized() };
let mut res = T::zero();
res.copy_raw(bytes);
Ok(res)
}
@ -271,7 +271,7 @@ macro_rules! sized_binary_map {
::std::cmp::Ordering::Greater => return Err(FromBytesError::TooLong),
::std::cmp::Ordering::Equal => ()
};
let mut res: Self = unsafe { ::std::mem::uninitialized() };
let mut res: Self = 0;
res.copy_raw(bytes);
Ok(res)
}
@ -298,7 +298,7 @@ sized_binary_map!(u32);
sized_binary_map!(u64);
/// Value that can be serialized from variable-length byte array
pub trait FromRawBytesVariable : Sized {
pub trait FromRawBytesVariable: Sized {
/// Create value from slice
fn from_bytes_variable(bytes: &[u8]) -> Result<Self, FromBytesError>;
}
@ -326,7 +326,7 @@ impl<T> FromRawBytesVariable for Vec<T> where T: FromRawBytes {
let size_of_t = mem::size_of::<T>();
let length_in_chunks = bytes.len() / size_of_t;
let mut result = Vec::with_capacity(length_in_chunks );
let mut result = Vec::with_capacity(length_in_chunks);
unsafe { result.set_len(length_in_chunks) };
for i in 0..length_in_chunks {
*result.get_mut(i).unwrap() = try!(T::from_bytes(
@ -339,7 +339,7 @@ impl<T> FromRawBytesVariable for Vec<T> where T: FromRawBytes {
impl<V1, T2> FromRawBytes for (V1, T2) where V1: FromRawBytesVariable, T2: FromRawBytes {
fn from_bytes(bytes: &[u8]) -> Result<Self, FromBytesError> {
let header = 8usize;
let mut map: (u64, ) = unsafe { mem::uninitialized() };
let mut map: (u64, ) = (0,);
if bytes.len() < header { return Err(FromBytesError::NotLongEnough); }
map.copy_raw(&bytes[0..header]);
@ -358,7 +358,7 @@ impl<V1, V2, T3> FromRawBytes for (V1, V2, T3)
{
fn from_bytes(bytes: &[u8]) -> Result<Self, FromBytesError> {
let header = 16usize;
let mut map: (u64, u64, ) = unsafe { mem::uninitialized() };
let mut map: (u64, u64, ) = (0, 0,);
if bytes.len() < header { return Err(FromBytesError::NotLongEnough); }
map.copy_raw(&bytes[0..header]);
@ -373,7 +373,7 @@ impl<V1, V2, T3> FromRawBytes for (V1, V2, T3)
}
}
impl<'a, V1, T2> ToBytesWithMap for (&'a Vec<V1>, &'a T2) where V1: ToBytesWithMap, T2: ToBytesWithMap {
impl<'a, V1, X1, T2> ToBytesWithMap for (X1, &'a T2) where V1: ToBytesWithMap, X1: Deref<Target=[V1]>, T2: ToBytesWithMap {
fn to_bytes_map(&self) -> Vec<u8> {
let header = 8usize;
let v1_size = mem::size_of::<V1>();
@ -390,9 +390,9 @@ impl<'a, V1, T2> ToBytesWithMap for (&'a Vec<V1>, &'a T2) where V1: ToBytesWithM
}
impl<'a, V1, V2, T3> ToBytesWithMap for (&'a Vec<V1>, &'a Vec<V2>, &'a T3)
where V1: ToBytesWithMap,
V2: ToBytesWithMap,
impl<'a, V1, X1, V2, X2, T3> ToBytesWithMap for (X1, X2, &'a T3)
where V1: ToBytesWithMap, X1: Deref<Target=[V1]>,
V2: ToBytesWithMap, X2: Deref<Target=[V2]>,
T3: ToBytesWithMap
{
fn to_bytes_map(&self) -> Vec<u8> {
@ -433,7 +433,7 @@ pub trait ToBytesWithMap {
impl<T> ToBytesWithMap for T where T: FixedHash {
fn to_bytes_map(&self) -> Vec<u8> {
self.as_slice().to_vec()
self.as_slice().to_owned()
}
}
@ -493,7 +493,7 @@ fn populate_big_types() {
fn raw_bytes_from_tuple() {
type Tup = (Vec<u16>, u16);
let tup = (vec![1u16, 1u16, 1u16, 1u16], 10u16);
let tup: (&[u16], u16) = (&[1; 4], 10);
let bytes = vec![
// map
8u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
@ -505,18 +505,19 @@ fn raw_bytes_from_tuple() {
// 10u16
10u8, 0u8];
let tup_from = Tup::from_bytes(&bytes).unwrap();
assert_eq!(tup, tup_from);
let (v, x) = Tup::from_bytes(&bytes).unwrap();
assert_eq!(tup, (&v[..], x));
let tup_from = (v, x);
let tup_to = (&tup_from.0, &tup_from.1);
let tup_to = (tup_from.0, &tup_from.1);
let bytes_to = tup_to.to_bytes_map();
assert_eq!(bytes_to, bytes);
}
#[test]
fn bytes_map_from_triple() {
let data = (vec![2u16; 6], vec![6u32; 3], 12u64);
let bytes_map = (&data.0, &data.1, &data.2).to_bytes_map();
let data: (&[u16], &[u32], u64) = (&[2; 6], &[6; 3], 12u64);
let bytes_map = (data.0, data.1, &data.2).to_bytes_map();
assert_eq!(bytes_map, vec![
// data map 2 x u64
12, 0, 0, 0, 0, 0, 0, 0,

View File

@ -195,7 +195,7 @@ fn hash256rlp(input: &[(Vec<u8>, Vec<u8>)], pre_len: usize, stream: &mut RlpStre
}
// take slices
let key: &Vec<u8> = &input[0].0;
let key: &[u8] = &input[0].0;
let value: &[u8] = &input[0].1;
// if the slice contains just one item, append the suffix of the key

View File

@ -28,12 +28,12 @@
/// assert_eq!(a.shared_prefix_len(&b), 3);
/// }
/// ```
pub trait SharedPrefix <T> {
pub trait SharedPrefix<T> {
/// Get common prefix length
fn shared_prefix_len(&self, elem: &[T]) -> usize;
}
impl <T> SharedPrefix<T> for Vec<T> where T: Eq {
impl<T> SharedPrefix<T> for [T] where T: Eq {
fn shared_prefix_len(&self, elem: &[T]) -> usize {
use std::cmp;
let len = cmp::min(self.len(), elem.len());