merge with master
This commit is contained in:
commit
60302acb94
20
Cargo.lock
generated
20
Cargo.lock
generated
@ -3,7 +3,7 @@ name = "parity"
|
|||||||
version = "1.3.0"
|
version = "1.3.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ansi_term 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"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)",
|
"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)",
|
"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)",
|
"docopt 0.6.80 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -129,15 +129,15 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clippy"
|
name = "clippy"
|
||||||
version = "0.0.78"
|
version = "0.0.79"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
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]]
|
[[package]]
|
||||||
name = "clippy_lints"
|
name = "clippy_lints"
|
||||||
version = "0.0.78"
|
version = "0.0.79"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -239,7 +239,7 @@ name = "ethcore"
|
|||||||
version = "1.3.0"
|
version = "1.3.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bloomchain 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"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)",
|
"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)",
|
"env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ethash 1.3.0",
|
"ethash 1.3.0",
|
||||||
@ -267,7 +267,7 @@ dependencies = [
|
|||||||
name = "ethcore-dapps"
|
name = "ethcore-dapps"
|
||||||
version = "1.3.0"
|
version = "1.3.0"
|
||||||
dependencies = [
|
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-rpc 1.3.0",
|
||||||
"ethcore-util 1.3.0",
|
"ethcore-util 1.3.0",
|
||||||
"hyper 0.9.4 (git+https://github.com/ethcore/hyper)",
|
"hyper 0.9.4 (git+https://github.com/ethcore/hyper)",
|
||||||
@ -343,7 +343,7 @@ dependencies = [
|
|||||||
name = "ethcore-rpc"
|
name = "ethcore-rpc"
|
||||||
version = "1.3.0"
|
version = "1.3.0"
|
||||||
dependencies = [
|
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",
|
"ethash 1.3.0",
|
||||||
"ethcore 1.3.0",
|
"ethcore 1.3.0",
|
||||||
"ethcore-devtools 1.3.0",
|
"ethcore-devtools 1.3.0",
|
||||||
@ -367,7 +367,7 @@ dependencies = [
|
|||||||
name = "ethcore-signer"
|
name = "ethcore-signer"
|
||||||
version = "1.3.0"
|
version = "1.3.0"
|
||||||
dependencies = [
|
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)",
|
"env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ethcore-rpc 1.3.0",
|
"ethcore-rpc 1.3.0",
|
||||||
"ethcore-util 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)",
|
"arrayvec 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"bigint 0.1.0",
|
"bigint 0.1.0",
|
||||||
"chrono 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
"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)",
|
"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)",
|
"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)",
|
"env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -459,7 +459,7 @@ dependencies = [
|
|||||||
name = "ethsync"
|
name = "ethsync"
|
||||||
version = "1.3.0"
|
version = "1.3.0"
|
||||||
dependencies = [
|
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)",
|
"env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ethcore 1.3.0",
|
"ethcore 1.3.0",
|
||||||
"ethcore-util 1.3.0",
|
"ethcore-util 1.3.0",
|
||||||
|
@ -22,7 +22,7 @@ fdlimit = { path = "util/fdlimit" }
|
|||||||
num_cpus = "0.2"
|
num_cpus = "0.2"
|
||||||
number_prefix = "0.2"
|
number_prefix = "0.2"
|
||||||
rpassword = "0.2.1"
|
rpassword = "0.2.1"
|
||||||
clippy = { version = "0.0.78", optional = true}
|
clippy = { version = "0.0.79", optional = true}
|
||||||
ethcore = { path = "ethcore" }
|
ethcore = { path = "ethcore" }
|
||||||
ethcore-util = { path = "util" }
|
ethcore-util = { path = "util" }
|
||||||
ethsync = { path = "sync" }
|
ethsync = { path = "sync" }
|
||||||
|
@ -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-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 }
|
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" }
|
mime_guess = { version = "1.6.1" }
|
||||||
clippy = { version = "0.0.78", optional = true}
|
clippy = { version = "0.0.79", optional = true}
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
serde_codegen = { version = "0.7.0", optional = true }
|
serde_codegen = { version = "0.7.0", optional = true }
|
||||||
|
@ -12,7 +12,7 @@ syntex = "*"
|
|||||||
ethcore-ipc-codegen = { path = "../ipc/codegen" }
|
ethcore-ipc-codegen = { path = "../ipc/codegen" }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clippy = { version = "0.0.78", optional = true}
|
clippy = { version = "0.0.79", optional = true}
|
||||||
ethcore-devtools = { path = "../devtools" }
|
ethcore-devtools = { path = "../devtools" }
|
||||||
ethcore-ipc = { path = "../ipc/rpc" }
|
ethcore-ipc = { path = "../ipc/rpc" }
|
||||||
rocksdb = { git = "https://github.com/ethcore/rust-rocksdb" }
|
rocksdb = { git = "https://github.com/ethcore/rust-rocksdb" }
|
||||||
|
@ -60,7 +60,7 @@ impl WriteCache {
|
|||||||
self.entries.insert(key, WriteCacheEntry::Remove);
|
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(
|
self.entries.get(key).and_then(
|
||||||
|vec_ref| match vec_ref {
|
|vec_ref| match vec_ref {
|
||||||
&WriteCacheEntry::Write(ref val) => Some(val.clone()),
|
&WriteCacheEntry::Write(ref val) => Some(val.clone()),
|
||||||
|
@ -22,7 +22,7 @@ ethcore-util = { path = "../util" }
|
|||||||
evmjit = { path = "../evmjit", optional = true }
|
evmjit = { path = "../evmjit", optional = true }
|
||||||
ethash = { path = "../ethash" }
|
ethash = { path = "../ethash" }
|
||||||
num_cpus = "0.2"
|
num_cpus = "0.2"
|
||||||
clippy = { version = "0.0.78", optional = true}
|
clippy = { version = "0.0.79", optional = true}
|
||||||
crossbeam = "0.2.9"
|
crossbeam = "0.2.9"
|
||||||
lazy_static = "0.2"
|
lazy_static = "0.2"
|
||||||
ethcore-devtools = { path = "../devtools" }
|
ethcore-devtools = { path = "../devtools" }
|
||||||
|
@ -16,8 +16,6 @@
|
|||||||
|
|
||||||
//! Blockchain block.
|
//! Blockchain block.
|
||||||
|
|
||||||
#![cfg_attr(feature="dev", allow(ptr_arg))] // Because of &LastHashes -> &Vec<_>
|
|
||||||
|
|
||||||
use common::*;
|
use common::*;
|
||||||
use engine::*;
|
use engine::*;
|
||||||
use state::*;
|
use state::*;
|
||||||
@ -76,11 +74,11 @@ pub struct BlockRefMut<'a> {
|
|||||||
/// Block header.
|
/// Block header.
|
||||||
pub header: &'a mut Header,
|
pub header: &'a mut Header,
|
||||||
/// Block transactions.
|
/// Block transactions.
|
||||||
pub transactions: &'a Vec<SignedTransaction>,
|
pub transactions: &'a [SignedTransaction],
|
||||||
/// Block uncles.
|
/// Block uncles.
|
||||||
pub uncles: &'a Vec<Header>,
|
pub uncles: &'a [Header],
|
||||||
/// Transaction receipts.
|
/// Transaction receipts.
|
||||||
pub receipts: &'a Vec<Receipt>,
|
pub receipts: &'a [Receipt],
|
||||||
/// State.
|
/// State.
|
||||||
pub state: &'a mut State,
|
pub state: &'a mut State,
|
||||||
/// Traces.
|
/// Traces.
|
||||||
@ -92,11 +90,11 @@ pub struct BlockRef<'a> {
|
|||||||
/// Block header.
|
/// Block header.
|
||||||
pub header: &'a Header,
|
pub header: &'a Header,
|
||||||
/// Block transactions.
|
/// Block transactions.
|
||||||
pub transactions: &'a Vec<SignedTransaction>,
|
pub transactions: &'a [SignedTransaction],
|
||||||
/// Block uncles.
|
/// Block uncles.
|
||||||
pub uncles: &'a Vec<Header>,
|
pub uncles: &'a [Header],
|
||||||
/// Transaction receipts.
|
/// Transaction receipts.
|
||||||
pub receipts: &'a Vec<Receipt>,
|
pub receipts: &'a [Receipt],
|
||||||
/// State.
|
/// State.
|
||||||
pub state: &'a State,
|
pub state: &'a State,
|
||||||
/// Traces.
|
/// Traces.
|
||||||
@ -152,16 +150,16 @@ pub trait IsBlock {
|
|||||||
fn state(&self) -> &State { &self.block().state }
|
fn state(&self) -> &State { &self.block().state }
|
||||||
|
|
||||||
/// Get all information on transactions in this block.
|
/// 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.
|
/// 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.
|
/// Get all information concerning transaction tracing in this block.
|
||||||
fn traces(&self) -> &Option<Vec<Trace>> { &self.block().traces }
|
fn traces(&self) -> &Option<Vec<Trace>> { &self.block().traces }
|
||||||
|
|
||||||
/// Get all uncles in this block.
|
/// 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.
|
/// Trait for a object that has a state database.
|
||||||
|
@ -426,7 +426,7 @@ impl Client {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Commit results
|
// 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));
|
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
|
// CHECK! I *think* this is fine, even if the state_root is equal to another
|
||||||
|
@ -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);
|
fn overflow_add(self, other: Self) -> (Self, bool);
|
||||||
/// Multiple with overflow
|
/// Multiple with overflow
|
||||||
fn overflow_mul(self, other: Self) -> (Self, bool);
|
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 {
|
impl CostType for U256 {
|
||||||
@ -129,6 +132,17 @@ impl CostType for U256 {
|
|||||||
fn overflow_mul(self, other: Self) -> (Self, bool) {
|
fn overflow_mul(self, other: Self) -> (Self, bool) {
|
||||||
Uint::overflowing_mul(self, other)
|
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 {
|
impl CostType for usize {
|
||||||
@ -154,6 +168,14 @@ impl CostType for usize {
|
|||||||
fn overflow_mul(self, other: Self) -> (Self, bool) {
|
fn overflow_mul(self, other: Self) -> (Self, bool) {
|
||||||
self.overflowing_mul(other)
|
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
|
/// Evm interface
|
||||||
@ -164,3 +186,41 @@ pub trait Evm {
|
|||||||
/// to compute the final gas left.
|
/// to compute the final gas left.
|
||||||
fn exec(&mut self, params: ActionParams, ext: &mut Ext) -> Result<GasLeft>;
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -68,6 +68,9 @@ impl<Gas: CostType> Gasometer<Gas> {
|
|||||||
let default_gas = Gas::from(schedule.tier_step_gas[tier]);
|
let default_gas = Gas::from(schedule.tier_step_gas[tier]);
|
||||||
|
|
||||||
let cost = match instruction {
|
let cost = match instruction {
|
||||||
|
instructions::JUMPDEST => {
|
||||||
|
InstructionCost::Gas(Gas::from(1))
|
||||||
|
},
|
||||||
instructions::SSTORE => {
|
instructions::SSTORE => {
|
||||||
let address = H256::from(stack.peek(0));
|
let address = H256::from(stack.peek(0));
|
||||||
let newval = stack.peek(1);
|
let newval = stack.peek(1);
|
||||||
@ -106,9 +109,6 @@ impl<Gas: CostType> Gasometer<Gas> {
|
|||||||
instructions::EXTCODECOPY => {
|
instructions::EXTCODECOPY => {
|
||||||
InstructionCost::GasMemCopy(default_gas, try!(self.mem_needed(stack.peek(1), stack.peek(3))), try!(Gas::from_u256(*stack.peek(3))))
|
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 => {
|
instructions::LOG0...instructions::LOG4 => {
|
||||||
let no_of_topics = instructions::get_log_topics(instruction);
|
let no_of_topics = instructions::get_log_topics(instruction);
|
||||||
let log_gas = schedule.log_gas + schedule.log_topic_gas * no_of_topics;
|
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;
|
let s = mem_size >> 5;
|
||||||
// s * memory_gas + s * s / quad_coeff_div
|
// s * memory_gas + s * s / quad_coeff_div
|
||||||
let a = overflowing!(s.overflow_mul(Gas::from(schedule.memory_gas)));
|
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);
|
// Calculate s*s/quad_coeff_div
|
||||||
if b > U512::from(!U256::zero()) {
|
let b = overflowing!(s.overflow_mul_div(s, Gas::from(schedule.quad_coeff_div)));
|
||||||
Err(evm::Error::OutOfGas)
|
Ok(overflowing!(a.overflow_add(b)))
|
||||||
} else {
|
|
||||||
Ok(overflowing!(a.overflow_add(try!(Gas::from_u256(U256::from(b))))))
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let current_mem_size = Gas::from(current_mem_size);
|
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;
|
let req_mem_size_rounded = (overflowing!(mem_size.overflow_add(Gas::from(31 as usize))) >> 5) << 5;
|
||||||
|
|
||||||
|
@ -143,7 +143,7 @@ impl Header {
|
|||||||
/// Get the difficulty field of the header.
|
/// Get the difficulty field of the header.
|
||||||
pub fn difficulty(&self) -> &U256 { &self.difficulty }
|
pub fn difficulty(&self) -> &U256 { &self.difficulty }
|
||||||
/// Get the seal field of the header.
|
/// 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.
|
// TODO: seal_at, set_seal_at &c.
|
||||||
|
|
||||||
|
@ -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 DB_VERSION: u32 = 0x203;
|
||||||
const PADDING : [u8; 10] = [0u8; 10];
|
const PADDING : [u8; 10] = [0u8; 10];
|
||||||
|
|
||||||
/// Version for OverlayRecent database.
|
/// Version for `OverlayRecent` database.
|
||||||
/// more involved than the archive version because of journaling.
|
/// more involved than the archive version because of journaling.
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct OverlayRecentV7 {
|
pub struct OverlayRecentV7 {
|
||||||
@ -258,4 +258,4 @@ impl Migration for OverlayRecentV7 {
|
|||||||
try!(self.walk_journal(source));
|
try!(self.walk_journal(source));
|
||||||
self.migrate_journal(source, batch, dest)
|
self.migrate_journal(source, batch, dest)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -665,7 +665,7 @@ impl MinerService for Miner {
|
|||||||
};
|
};
|
||||||
match (&self.options.pending_set, sealing_set) {
|
match (&self.options.pending_set, sealing_set) {
|
||||||
(&PendingSet::AlwaysQueue, _) | (&PendingSet::SealingOrElseQueue, None) => queue.top_transactions(),
|
(&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()
|
.iter()
|
||||||
.map(|t| t.hash());
|
.map(|t| t.hash());
|
||||||
|
|
||||||
let receipts = pending.receipts().clone().into_iter();
|
let receipts = pending.receipts().iter().cloned();
|
||||||
|
|
||||||
hashes.zip(receipts).collect()
|
hashes.zip(receipts).collect()
|
||||||
},
|
},
|
||||||
|
@ -143,7 +143,7 @@ impl Spec {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get the known knodes of the network in enode format.
|
/// 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.
|
/// Get the configured Network ID.
|
||||||
pub fn network_id(&self) -> U256 { self.params.network_id }
|
pub fn network_id(&self) -> U256 { self.params.network_id }
|
||||||
|
@ -4,6 +4,14 @@ description = "Parity's EVM implementation"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
authors = ["Ethcore <admin@ethcore.io>"]
|
authors = ["Ethcore <admin@ethcore.io>"]
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
name = "evm"
|
||||||
|
path = "./src/main.rs"
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "evm"
|
||||||
|
path = "./src/main.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
rustc-serialize = "0.3"
|
rustc-serialize = "0.3"
|
||||||
docopt = { version = "0.6" }
|
docopt = { version = "0.6" }
|
||||||
|
24
evmbin/bench.sh
Executable file
24
evmbin/bench.sh
Executable 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
85
evmbin/benches/mod.rs
Normal 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)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
@ -17,6 +17,7 @@
|
|||||||
//! Parity EVM interpreter binary.
|
//! Parity EVM interpreter binary.
|
||||||
|
|
||||||
#![warn(missing_docs)]
|
#![warn(missing_docs)]
|
||||||
|
#![allow(dead_code)]
|
||||||
extern crate ethcore;
|
extern crate ethcore;
|
||||||
extern crate rustc_serialize;
|
extern crate rustc_serialize;
|
||||||
extern crate docopt;
|
extern crate docopt;
|
||||||
@ -25,7 +26,7 @@ extern crate ethcore_util as util;
|
|||||||
|
|
||||||
mod ext;
|
mod ext;
|
||||||
|
|
||||||
use std::time::Instant;
|
use std::time::{Instant, Duration};
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use docopt::Docopt;
|
use docopt::Docopt;
|
||||||
use util::{U256, FromHex, Uint, Bytes};
|
use util::{U256, FromHex, Uint, Bytes};
|
||||||
@ -58,6 +59,15 @@ fn main() {
|
|||||||
params.code = Some(args.code());
|
params.code = Some(args.code());
|
||||||
params.data = args.data();
|
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 factory = Factory::new(VMType::Interpreter);
|
||||||
let mut vm = factory.create(params.gas);
|
let mut vm = factory.create(params.gas);
|
||||||
let mut ext = ext::FakeExt::default();
|
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 gas_left = vm.exec(params, &mut ext).finalize(ext).expect("OK");
|
||||||
let duration = start.elapsed();
|
let duration = start.elapsed();
|
||||||
|
|
||||||
println!("Gas used: {:?}", args.gas() - gas_left);
|
ExecutionResults {
|
||||||
println!("Output: {:?}", "");
|
gas_used: initial_gas - gas_left,
|
||||||
println!("Time: {}.{:.9}s", duration.as_secs(), duration.subsec_nanos());
|
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)]
|
#[derive(Debug, RustcDecodable)]
|
||||||
|
@ -62,24 +62,10 @@ pub fn expand_ipc_implementation(
|
|||||||
};
|
};
|
||||||
|
|
||||||
push_client(cx, &builder, &interface_map, push);
|
push_client(cx, &builder, &interface_map, push);
|
||||||
push_handshake_struct(cx, push);
|
|
||||||
|
|
||||||
push(Annotatable::Item(interface_map.item));
|
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 {
|
fn field_name(builder: &aster::AstBuilder, arg: &Arg) -> ast::Ident {
|
||||||
match arg.pat.node {
|
match arg.pat.node {
|
||||||
PatKind::Ident(_, ref ident, _) => builder.id(ident.node),
|
PatKind::Ident(_, ref ident, _) => builder.id(ident.node),
|
||||||
@ -601,15 +587,14 @@ fn push_client_implementation(
|
|||||||
|
|
||||||
let handshake_item = quote_impl_item!(cx,
|
let handshake_item = quote_impl_item!(cx,
|
||||||
pub fn handshake(&self) -> Result<(), ::ipc::Error> {
|
pub fn handshake(&self) -> Result<(), ::ipc::Error> {
|
||||||
let payload = BinHandshake {
|
let payload = ::ipc::Handshake {
|
||||||
protocol_version: $item_ident::protocol_version().to_string(),
|
protocol_version: $item_ident::protocol_version(),
|
||||||
api_version: $item_ident::api_version().to_string(),
|
api_version: $item_ident::api_version(),
|
||||||
reserved: vec![0u8; 64],
|
|
||||||
};
|
};
|
||||||
|
|
||||||
::ipc::invoke(
|
::ipc::invoke(
|
||||||
0,
|
0,
|
||||||
&Some(::ipc::binary::serialize(&payload).unwrap()),
|
&Some(::ipc::binary::serialize(&::ipc::BinHandshake::from(payload)).unwrap()),
|
||||||
&mut *self.socket.write().unwrap());
|
&mut *self.socket.write().unwrap());
|
||||||
|
|
||||||
let mut result = vec![0u8; 1];
|
let mut result = vec![0u8; 1];
|
||||||
@ -673,18 +658,15 @@ fn implement_handshake_arm(
|
|||||||
) -> (ast::Arm, ast::Arm)
|
) -> (ast::Arm, ast::Arm)
|
||||||
{
|
{
|
||||||
let handshake_deserialize = quote_stmt!(&cx,
|
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_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,
|
let handshake_serialize = quote_expr!(&cx,
|
||||||
::ipc::binary::serialize::<bool>(&Self::handshake(&::ipc::Handshake {
|
::ipc::binary::serialize::<bool>(&Self::handshake(&handshake_payload.to_semver())).unwrap()
|
||||||
api_version: ::semver::Version::parse(&handshake_payload.api_version).unwrap(),
|
|
||||||
protocol_version: ::semver::Version::parse(&handshake_payload.protocol_version).unwrap(),
|
|
||||||
})).unwrap()
|
|
||||||
);
|
);
|
||||||
|
|
||||||
(
|
(
|
||||||
|
@ -8,6 +8,6 @@ license = "GPL-3.0"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
ethcore-devtools = { path = "../../devtools" }
|
ethcore-devtools = { path = "../../devtools" }
|
||||||
semver = "0.2.0"
|
|
||||||
nanomsg = { git = "https://github.com/ethcore/nanomsg.rs.git" }
|
nanomsg = { git = "https://github.com/ethcore/nanomsg.rs.git" }
|
||||||
ethcore-util = { path = "../../util" }
|
ethcore-util = { path = "../../util" }
|
||||||
|
semver = "0.2"
|
||||||
|
@ -21,6 +21,7 @@ use util::numbers::{U256, U512, H256, H2048, Address};
|
|||||||
use std::mem;
|
use std::mem;
|
||||||
use std::collections::{VecDeque, BTreeMap};
|
use std::collections::{VecDeque, BTreeMap};
|
||||||
use std::ops::Range;
|
use std::ops::Range;
|
||||||
|
use super::Handshake;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct BinaryConvertError;
|
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!(u64);
|
||||||
binary_fixed_size!(u32);
|
binary_fixed_size!(u32);
|
||||||
binary_fixed_size!(usize);
|
binary_fixed_size!(usize);
|
||||||
@ -564,6 +620,7 @@ binary_fixed_size!(U512);
|
|||||||
binary_fixed_size!(H256);
|
binary_fixed_size!(H256);
|
||||||
binary_fixed_size!(H2048);
|
binary_fixed_size!(H2048);
|
||||||
binary_fixed_size!(Address);
|
binary_fixed_size!(Address);
|
||||||
|
binary_fixed_size!(BinHandshake);
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn vec_serialize() {
|
fn vec_serialize() {
|
||||||
@ -706,8 +763,6 @@ fn serialize_opt_vec() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn serialize_opt_vec_payload() {
|
fn serialize_opt_vec_payload() {
|
||||||
use std::io::Cursor;
|
|
||||||
|
|
||||||
let optional_vec: Option<Vec<u8>> = None;
|
let optional_vec: Option<Vec<u8>> = None;
|
||||||
let payload = serialize(&optional_vec).unwrap();
|
let payload = serialize(&optional_vec).unwrap();
|
||||||
|
|
||||||
@ -776,3 +831,23 @@ fn serialize_btree() {
|
|||||||
|
|
||||||
assert_eq!(res[&1u64], 5u64);
|
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);
|
||||||
|
|
||||||
|
}
|
||||||
|
@ -20,6 +20,7 @@ use std::io::{Read, Write};
|
|||||||
use std::marker::Sync;
|
use std::marker::Sync;
|
||||||
use semver::Version;
|
use semver::Version;
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||||
/// Handshake for client and server to negotiate api/protocol version
|
/// Handshake for client and server to negotiate api/protocol version
|
||||||
pub struct Handshake {
|
pub struct Handshake {
|
||||||
pub protocol_version: Version,
|
pub protocol_version: Version,
|
||||||
|
@ -24,4 +24,4 @@ extern crate ethcore_util as util;
|
|||||||
pub mod interface;
|
pub mod interface;
|
||||||
pub mod binary;
|
pub mod binary;
|
||||||
pub use interface::{IpcInterface, IpcSocket, invoke, IpcConfig, Handshake, Error, WithSocket};
|
pub use interface::{IpcInterface, IpcSocket, invoke, IpcConfig, Handshake, Error, WithSocket};
|
||||||
pub use binary::{BinaryConvertable, BinaryConvertError};
|
pub use binary::{BinaryConvertable, BinaryConvertError, BinHandshake};
|
||||||
|
@ -10,7 +10,7 @@ rustc-serialize = "0.3"
|
|||||||
serde = "0.7.0"
|
serde = "0.7.0"
|
||||||
serde_json = "0.7.0"
|
serde_json = "0.7.0"
|
||||||
serde_macros = { version = "0.7.0", optional = true }
|
serde_macros = { version = "0.7.0", optional = true }
|
||||||
clippy = { version = "0.0.78", optional = true}
|
clippy = { version = "0.0.79", optional = true}
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
serde_codegen = { version = "0.7.0", optional = true }
|
serde_codegen = { version = "0.7.0", optional = true }
|
||||||
|
@ -40,9 +40,9 @@ impl Into<Vec<u8>> for Bytes {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Deref for Bytes {
|
impl Deref for Bytes {
|
||||||
type Target = Vec<u8>;
|
type Target = [u8];
|
||||||
|
|
||||||
fn deref(&self) -> &Vec<u8> {
|
fn deref(&self) -> &[u8] {
|
||||||
&self.0
|
&self.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -238,7 +238,7 @@ impl Configuration {
|
|||||||
})
|
})
|
||||||
}).collect(),
|
}).collect(),
|
||||||
Some(_) => Vec::new(),
|
Some(_) => Vec::new(),
|
||||||
None => spec.nodes().clone(),
|
None => spec.nodes().to_owned(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ ethcore-devtools = { path = "../devtools" }
|
|||||||
rustc-serialize = "0.3"
|
rustc-serialize = "0.3"
|
||||||
transient-hashmap = "0.1"
|
transient-hashmap = "0.1"
|
||||||
serde_macros = { version = "0.7.0", optional = true }
|
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" }
|
json-ipc-server = { git = "https://github.com/ethcore/json-ipc-server.git" }
|
||||||
ethcore-ipc = { path = "../ipc/rpc" }
|
ethcore-ipc = { path = "../ipc/rpc" }
|
||||||
|
|
||||||
|
@ -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> {
|
fn compilers(&self, params: Params) -> Result<Value, Error> {
|
||||||
try!(self.active());
|
try!(self.active());
|
||||||
match params {
|
match params {
|
||||||
Params::None => to_value(&vec![] as &Vec<String>),
|
Params::None => to_value(&(&[] as &[String])),
|
||||||
_ => Err(Error::invalid_params())
|
_ => Err(Error::invalid_params())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ ethcore-util = { path = "../util" }
|
|||||||
ethcore-rpc = { path = "../rpc" }
|
ethcore-rpc = { path = "../rpc" }
|
||||||
parity-minimal-sysui = { git = "https://github.com/ethcore/parity-dapps-minimal-sysui-rs.git", version = "0.2.0" }
|
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]
|
[features]
|
||||||
dev = ["clippy"]
|
dev = ["clippy"]
|
||||||
|
@ -25,11 +25,11 @@ use std::str::FromStr;
|
|||||||
use jsonrpc_core::IoHandler;
|
use jsonrpc_core::IoHandler;
|
||||||
use util::H256;
|
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 {
|
match header {
|
||||||
None => false,
|
None => false,
|
||||||
Some(h) => {
|
Some(h) => {
|
||||||
let v = String::from_utf8(h.clone()).ok();
|
let v = String::from_utf8(h.to_owned()).ok();
|
||||||
match v {
|
match v {
|
||||||
Some(ref origin) if origin.starts_with("chrome-extension://") => true,
|
Some(ref origin) if origin.starts_with("chrome-extension://") => true,
|
||||||
Some(ref origin) if origin.starts_with(self_origin) => true,
|
Some(ref origin) if origin.starts_with(self_origin) => true,
|
||||||
@ -84,8 +84,8 @@ pub struct Session {
|
|||||||
|
|
||||||
impl ws::Handler for Session {
|
impl ws::Handler for Session {
|
||||||
fn on_request(&mut self, req: &ws::Request) -> ws::Result<(ws::Response)> {
|
fn on_request(&mut self, req: &ws::Request) -> ws::Result<(ws::Response)> {
|
||||||
let origin = req.header("origin").or_else(|| req.header("Origin"));
|
let origin = req.header("origin").or_else(|| req.header("Origin")).map(|x| &x[..]);
|
||||||
let host = req.header("host").or_else(|| req.header("Host"));
|
let host = req.header("host").or_else(|| req.header("Host")).map(|x| &x[..]);
|
||||||
|
|
||||||
// Check request origin and host header.
|
// Check request origin and host header.
|
||||||
if !origin_is_allowed(&self.self_origin, origin) && !(origin.is_none() && origin_is_allowed(&self.self_origin, host)) {
|
if !origin_is_allowed(&self.self_origin, origin) && !(origin.is_none() && origin_is_allowed(&self.self_origin, host)) {
|
||||||
|
@ -10,7 +10,7 @@ authors = ["Ethcore <admin@ethcore.io"]
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
ethcore-util = { path = "../util" }
|
ethcore-util = { path = "../util" }
|
||||||
ethcore = { path = "../ethcore" }
|
ethcore = { path = "../ethcore" }
|
||||||
clippy = { version = "0.0.78", optional = true}
|
clippy = { version = "0.0.79", optional = true}
|
||||||
log = "0.3"
|
log = "0.3"
|
||||||
env_logger = "0.3"
|
env_logger = "0.3"
|
||||||
time = "0.1.34"
|
time = "0.1.34"
|
||||||
|
@ -27,7 +27,7 @@ itertools = "0.4"
|
|||||||
crossbeam = "0.2"
|
crossbeam = "0.2"
|
||||||
slab = "0.2"
|
slab = "0.2"
|
||||||
sha3 = { path = "sha3" }
|
sha3 = { path = "sha3" }
|
||||||
clippy = { version = "0.0.78", optional = true}
|
clippy = { version = "0.0.79", optional = true}
|
||||||
igd = "0.5.0"
|
igd = "0.5.0"
|
||||||
ethcore-devtools = { path = "../devtools" }
|
ethcore-devtools = { path = "../devtools" }
|
||||||
libc = "0.2.7"
|
libc = "0.2.7"
|
||||||
|
@ -242,7 +242,7 @@ pub enum FromBytesError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Value that can be serialized from bytes array
|
/// 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
|
/// function that will instantiate and initialize object from slice
|
||||||
fn from_bytes(d: &[u8]) -> Result<Self, FromBytesError>;
|
fn from_bytes(d: &[u8]) -> Result<Self, FromBytesError>;
|
||||||
}
|
}
|
||||||
@ -255,7 +255,7 @@ impl<T> FromRawBytes for T where T: FixedHash {
|
|||||||
Ordering::Equal => ()
|
Ordering::Equal => ()
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut res: Self = unsafe { mem::uninitialized() };
|
let mut res = T::zero();
|
||||||
res.copy_raw(bytes);
|
res.copy_raw(bytes);
|
||||||
Ok(res)
|
Ok(res)
|
||||||
}
|
}
|
||||||
@ -271,7 +271,7 @@ macro_rules! sized_binary_map {
|
|||||||
::std::cmp::Ordering::Greater => return Err(FromBytesError::TooLong),
|
::std::cmp::Ordering::Greater => return Err(FromBytesError::TooLong),
|
||||||
::std::cmp::Ordering::Equal => ()
|
::std::cmp::Ordering::Equal => ()
|
||||||
};
|
};
|
||||||
let mut res: Self = unsafe { ::std::mem::uninitialized() };
|
let mut res: Self = 0;
|
||||||
res.copy_raw(bytes);
|
res.copy_raw(bytes);
|
||||||
Ok(res)
|
Ok(res)
|
||||||
}
|
}
|
||||||
@ -298,7 +298,7 @@ sized_binary_map!(u32);
|
|||||||
sized_binary_map!(u64);
|
sized_binary_map!(u64);
|
||||||
|
|
||||||
/// Value that can be serialized from variable-length byte array
|
/// Value that can be serialized from variable-length byte array
|
||||||
pub trait FromRawBytesVariable : Sized {
|
pub trait FromRawBytesVariable: Sized {
|
||||||
/// Create value from slice
|
/// Create value from slice
|
||||||
fn from_bytes_variable(bytes: &[u8]) -> Result<Self, FromBytesError>;
|
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 size_of_t = mem::size_of::<T>();
|
||||||
let length_in_chunks = bytes.len() / 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) };
|
unsafe { result.set_len(length_in_chunks) };
|
||||||
for i in 0..length_in_chunks {
|
for i in 0..length_in_chunks {
|
||||||
*result.get_mut(i).unwrap() = try!(T::from_bytes(
|
*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 {
|
impl<V1, T2> FromRawBytes for (V1, T2) where V1: FromRawBytesVariable, T2: FromRawBytes {
|
||||||
fn from_bytes(bytes: &[u8]) -> Result<Self, FromBytesError> {
|
fn from_bytes(bytes: &[u8]) -> Result<Self, FromBytesError> {
|
||||||
let header = 8usize;
|
let header = 8usize;
|
||||||
let mut map: (u64, ) = unsafe { mem::uninitialized() };
|
let mut map: (u64, ) = (0,);
|
||||||
|
|
||||||
if bytes.len() < header { return Err(FromBytesError::NotLongEnough); }
|
if bytes.len() < header { return Err(FromBytesError::NotLongEnough); }
|
||||||
map.copy_raw(&bytes[0..header]);
|
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> {
|
fn from_bytes(bytes: &[u8]) -> Result<Self, FromBytesError> {
|
||||||
let header = 16usize;
|
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); }
|
if bytes.len() < header { return Err(FromBytesError::NotLongEnough); }
|
||||||
map.copy_raw(&bytes[0..header]);
|
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> {
|
fn to_bytes_map(&self) -> Vec<u8> {
|
||||||
let header = 8usize;
|
let header = 8usize;
|
||||||
let v1_size = mem::size_of::<V1>();
|
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)
|
impl<'a, V1, X1, V2, X2, T3> ToBytesWithMap for (X1, X2, &'a T3)
|
||||||
where V1: ToBytesWithMap,
|
where V1: ToBytesWithMap, X1: Deref<Target=[V1]>,
|
||||||
V2: ToBytesWithMap,
|
V2: ToBytesWithMap, X2: Deref<Target=[V2]>,
|
||||||
T3: ToBytesWithMap
|
T3: ToBytesWithMap
|
||||||
{
|
{
|
||||||
fn to_bytes_map(&self) -> Vec<u8> {
|
fn to_bytes_map(&self) -> Vec<u8> {
|
||||||
@ -433,7 +433,7 @@ pub trait ToBytesWithMap {
|
|||||||
|
|
||||||
impl<T> ToBytesWithMap for T where T: FixedHash {
|
impl<T> ToBytesWithMap for T where T: FixedHash {
|
||||||
fn to_bytes_map(&self) -> Vec<u8> {
|
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() {
|
fn raw_bytes_from_tuple() {
|
||||||
type Tup = (Vec<u16>, u16);
|
type Tup = (Vec<u16>, u16);
|
||||||
|
|
||||||
let tup = (vec![1u16, 1u16, 1u16, 1u16], 10u16);
|
let tup: (&[u16], u16) = (&[1; 4], 10);
|
||||||
let bytes = vec![
|
let bytes = vec![
|
||||||
// map
|
// map
|
||||||
8u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
|
8u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
|
||||||
@ -505,18 +505,19 @@ fn raw_bytes_from_tuple() {
|
|||||||
// 10u16
|
// 10u16
|
||||||
10u8, 0u8];
|
10u8, 0u8];
|
||||||
|
|
||||||
let tup_from = Tup::from_bytes(&bytes).unwrap();
|
let (v, x) = Tup::from_bytes(&bytes).unwrap();
|
||||||
assert_eq!(tup, tup_from);
|
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();
|
let bytes_to = tup_to.to_bytes_map();
|
||||||
assert_eq!(bytes_to, bytes);
|
assert_eq!(bytes_to, bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn bytes_map_from_triple() {
|
fn bytes_map_from_triple() {
|
||||||
let data = (vec![2u16; 6], vec![6u32; 3], 12u64);
|
let data: (&[u16], &[u32], u64) = (&[2; 6], &[6; 3], 12u64);
|
||||||
let bytes_map = (&data.0, &data.1, &data.2).to_bytes_map();
|
let bytes_map = (data.0, data.1, &data.2).to_bytes_map();
|
||||||
assert_eq!(bytes_map, vec![
|
assert_eq!(bytes_map, vec![
|
||||||
// data map 2 x u64
|
// data map 2 x u64
|
||||||
12, 0, 0, 0, 0, 0, 0, 0,
|
12, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
@ -195,7 +195,7 @@ fn hash256rlp(input: &[(Vec<u8>, Vec<u8>)], pre_len: usize, stream: &mut RlpStre
|
|||||||
}
|
}
|
||||||
|
|
||||||
// take slices
|
// take slices
|
||||||
let key: &Vec<u8> = &input[0].0;
|
let key: &[u8] = &input[0].0;
|
||||||
let value: &[u8] = &input[0].1;
|
let value: &[u8] = &input[0].1;
|
||||||
|
|
||||||
// if the slice contains just one item, append the suffix of the key
|
// if the slice contains just one item, append the suffix of the key
|
||||||
|
@ -17,23 +17,23 @@
|
|||||||
//! Vector extensions.
|
//! Vector extensions.
|
||||||
|
|
||||||
/// Returns len of prefix shared with elem
|
/// Returns len of prefix shared with elem
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// extern crate ethcore_util as util;
|
/// extern crate ethcore_util as util;
|
||||||
/// use util::vector::SharedPrefix;
|
/// use util::vector::SharedPrefix;
|
||||||
///
|
///
|
||||||
/// fn main () {
|
/// fn main () {
|
||||||
/// let a = vec![1,2,3,3,5];
|
/// let a = vec![1,2,3,3,5];
|
||||||
/// let b = vec![1,2,3];
|
/// let b = vec![1,2,3];
|
||||||
/// assert_eq!(a.shared_prefix_len(&b), 3);
|
/// assert_eq!(a.shared_prefix_len(&b), 3);
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub trait SharedPrefix <T> {
|
pub trait SharedPrefix<T> {
|
||||||
/// Get common prefix length
|
/// Get common prefix length
|
||||||
fn shared_prefix_len(&self, elem: &[T]) -> usize;
|
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 {
|
fn shared_prefix_len(&self, elem: &[T]) -> usize {
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
let len = cmp::min(self.len(), elem.len());
|
let len = cmp::min(self.len(), elem.len());
|
||||||
@ -58,7 +58,7 @@ mod test {
|
|||||||
let b = vec![1,2,3];
|
let b = vec![1,2,3];
|
||||||
assert_eq!(a.shared_prefix_len(&b), 3);
|
assert_eq!(a.shared_prefix_len(&b), 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_shared_prefix3() {
|
fn test_shared_prefix3() {
|
||||||
let a = vec![1,2,3,4,5,6];
|
let a = vec![1,2,3,4,5,6];
|
||||||
|
Loading…
Reference in New Issue
Block a user