Merge branch 'master' into ui-2

# Conflicts:
#	js/package-lock.json
#	js/src/Application/application.js
#	js/src/api/rpc/parity/parity.js
#	js/src/api/subscriptions/manager.spec.js
#	js/src/api/subscriptions/personal.spec.js
#	js/src/jsonrpc/interfaces/parity.js
#	js/src/mobx/hardwareStore.js
#	js/src/mobx/hardwareStore.spec.js
#	js/src/modals/index.js
#	js/src/redux/providers/signerMiddleware.spec.js
#	js/src/ui/SelectionList/selectionList.css
#	js/src/views/Account/account.spec.js
#	js/src/views/Accounts/accounts.spec.js
#	js/src/views/Application/Extension/store.js
#	js/src/views/Signer/components/SignRequest/signRequest.spec.js
This commit is contained in:
Jaco Greeff 2017-09-18 11:44:09 +02:00
commit db9a70d008
234 changed files with 3871 additions and 1918 deletions

1904
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -35,6 +35,7 @@ jsonrpc-core = { git = "https://github.com/paritytech/jsonrpc.git", branch = "pa
ethsync = { path = "sync" } ethsync = { path = "sync" }
ethcore = { path = "ethcore" } ethcore = { path = "ethcore" }
ethcore-util = { path = "util" } ethcore-util = { path = "util" }
ethcore-bytes = { path = "util/bytes" }
ethcore-bigint = { path = "util/bigint" } ethcore-bigint = { path = "util/bigint" }
ethcore-io = { path = "util/io" } ethcore-io = { path = "util/io" }
ethcore-devtools = { path = "devtools" } ethcore-devtools = { path = "devtools" }

View File

@ -32,6 +32,7 @@ jsonrpc-http-server = { git = "https://github.com/paritytech/jsonrpc.git", branc
ethcore-util = { path = "../util" } ethcore-util = { path = "../util" }
ethcore-bigint = { path = "../util/bigint" } ethcore-bigint = { path = "../util/bigint" }
ethcore-bytes = { path = "../util/bytes" }
fetch = { path = "../util/fetch" } fetch = { path = "../util/fetch" }
node-health = { path = "./node-health" } node-health = { path = "./node-health" }
parity-hash-fetch = { path = "../hash-fetch" } parity-hash-fetch = { path = "../hash-fetch" }

View File

@ -261,7 +261,7 @@ impl<R: URLHint + 'static, F: Fetch> Fetcher for ContentFetcher<F, R> {
mod tests { mod tests {
use std::env; use std::env;
use std::sync::Arc; use std::sync::Arc;
use util::Bytes; use bytes::Bytes;
use fetch::{Fetch, Client}; use fetch::{Fetch, Client};
use futures::{future, Future, BoxFuture}; use futures::{future, Future, BoxFuture};
use hash_fetch::urlhint::{URLHint, URLHintResult}; use hash_fetch::urlhint::{URLHint, URLHintResult};

View File

@ -39,6 +39,7 @@ extern crate jsonrpc_http_server;
extern crate ethcore_util as util; extern crate ethcore_util as util;
extern crate ethcore_bigint as bigint; extern crate ethcore_bigint as bigint;
extern crate ethcore_bytes as bytes;
extern crate fetch; extern crate fetch;
extern crate node_health; extern crate node_health;
extern crate parity_dapps_glue as parity_dapps; extern crate parity_dapps_glue as parity_dapps;

View File

@ -21,7 +21,8 @@ use rustc_hex::FromHex;
use hash_fetch::urlhint::ContractClient; use hash_fetch::urlhint::ContractClient;
use bigint::hash::H256; use bigint::hash::H256;
use util::{Bytes, Address, ToPretty}; use util::Address;
use bytes::{Bytes, ToPretty};
use parking_lot::Mutex; use parking_lot::Mutex;
const REGISTRAR: &'static str = "8e4e9b13d4b45cb0befc93c3061b1408f67316b2"; const REGISTRAR: &'static str = "8e4e9b13d4b45cb0befc93c3061b1408f67316b2";

View File

@ -23,6 +23,10 @@ env_logger = "0.4"
ethabi = "2.0" ethabi = "2.0"
ethash = { path = "../ethash" } ethash = { path = "../ethash" }
ethcore-bloom-journal = { path = "../util/bloom" } ethcore-bloom-journal = { path = "../util/bloom" }
ethcore-bytes = { path = "../util/bytes" }
hashdb = { path = "../util/hashdb" }
memorydb = { path = "../util/memorydb" }
patricia_trie = { path = "../util/patricia_trie" }
ethcore-devtools = { path = "../devtools" } ethcore-devtools = { path = "../devtools" }
ethcore-io = { path = "../util/io" } ethcore-io = { path = "../util/io" }
ethcore-ipc = { path = "../ipc/rpc" } ethcore-ipc = { path = "../ipc/rpc" }

97
ethcore/benches/evm.rs Normal file
View File

@ -0,0 +1,97 @@
// Copyright 2015-2017 Parity Technologies (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/>.
#![feature(test)]
extern crate test;
extern crate ethcore_util as util;
extern crate rand;
extern crate bn;
extern crate crypto;
extern crate rustc_serialize;
extern crate ethkey;
use self::test::{Bencher};
use rand::{StdRng};
#[bench]
fn bn_128_pairing(b: &mut Bencher) {
use bn::{pairing, G1, G2, Fr, Group};
let rng = &mut ::rand::thread_rng();
let sk0 = Fr::random(rng);
let sk1 = Fr::random(rng);
let pk0 = G1::one() * sk0;
let pk1 = G2::one() * sk1;
b.iter(|| {
let _ = pairing(pk0, pk1);
});
}
#[bench]
fn bn_128_mul(b: &mut Bencher) {
use bn::{AffineG1, G1, Fr, Group};
let mut rng = StdRng::new().unwrap();
let p: G1 = G1::random(&mut rng);
let fr = Fr::random(&mut rng);
b.iter(|| {
let _ = AffineG1::from_jacobian(p * fr);
});
}
#[bench]
fn sha256(b: &mut Bencher) {
use crypto::sha2::Sha256;
use crypto::digest::Digest;
let mut input: [u8; 256] = [0; 256];
let mut out = [0; 32];
b.iter(|| {
let mut sha = Sha256::new();
sha.input(&input);
sha.result(&mut input[0..32]);
});
}
#[bench]
fn ecrecover(b: &mut Bencher) {
use rustc_serialize::hex::FromHex;
use ethkey::{Signature, recover as ec_recover};
use util::H256;
let input = FromHex::from_hex("47173285a8d7341e5e972fc677286384f802f8ef42a5ec5f03bbfa254cb01fad000000000000000000000000000000000000000000000000000000000000001b650acf9d3f5f0a2c799776a1254355d5f4061762a237396a99a0e0e3fc2bcd6729514a0dacb2e623ac4abd157cb18163ff942280db4d5caad66ddf941ba12e03").unwrap();
let hash = H256::from_slice(&input[0..32]);
let v = H256::from_slice(&input[32..64]);
let r = H256::from_slice(&input[64..96]);
let s = H256::from_slice(&input[96..128]);
let bit = match v[31] {
27 | 28 if &v.0[..31] == &[0; 31] => v[31] - 27,
_ => { return; },
};
let s = Signature::from_rsv(&r, &s, bit);
b.iter(|| {
let _ = ec_recover(&s, &hash);
});
}

View File

@ -17,7 +17,6 @@
//! Evm interface. //! Evm interface.
use std::{ops, cmp, fmt}; use std::{ops, cmp, fmt};
use bigint::prelude::{U128, U256, U512}; use bigint::prelude::{U128, U256, U512};
use vm::{Ext, Result, ReturnData, GasLeft, Error}; use vm::{Ext, Result, ReturnData, GasLeft, Error};
@ -46,7 +45,7 @@ impl Finalize for Result<GasLeft> {
fn finalize<E: Ext>(self, ext: E) -> Result<FinalizationResult> { fn finalize<E: Ext>(self, ext: E) -> Result<FinalizationResult> {
match self { match self {
Ok(GasLeft::Known(gas_left)) => Ok(FinalizationResult { gas_left: gas_left, apply_state: true, return_data: ReturnData::empty() }), Ok(GasLeft::Known(gas_left)) => Ok(FinalizationResult { gas_left: gas_left, apply_state: true, return_data: ReturnData::empty() }),
Ok(GasLeft::NeedsReturn {gas_left, data, apply_state}) => ext.ret(&gas_left, &data).map(|gas_left| FinalizationResult { Ok(GasLeft::NeedsReturn {gas_left, data, apply_state}) => ext.ret(&gas_left, &data, apply_state).map(|gas_left| FinalizationResult {
gas_left: gas_left, gas_left: gas_left,
apply_state: apply_state, apply_state: apply_state,
return_data: data, return_data: data,

View File

@ -328,6 +328,9 @@ impl<Cost: CostType> Interpreter<Cost> {
let contract_code = self.mem.read_slice(init_off, init_size); let contract_code = self.mem.read_slice(init_off, init_size);
let can_create = ext.balance(&params.address)? >= endowment && ext.depth() < ext.schedule().max_depth; let can_create = ext.balance(&params.address)? >= endowment && ext.depth() < ext.schedule().max_depth;
// clear return data buffer before creating new call frame.
self.return_data = ReturnData::empty();
if !can_create { if !can_create {
stack.push(U256::zero()); stack.push(U256::zero());
return Ok(InstructionResult::UnusedGas(create_gas)); return Ok(InstructionResult::UnusedGas(create_gas));
@ -339,10 +342,18 @@ impl<Cost: CostType> Interpreter<Cost> {
stack.push(address_to_u256(address)); stack.push(address_to_u256(address));
Ok(InstructionResult::UnusedGas(Cost::from_u256(gas_left).expect("Gas left cannot be greater."))) Ok(InstructionResult::UnusedGas(Cost::from_u256(gas_left).expect("Gas left cannot be greater.")))
}, },
ContractCreateResult::Reverted(gas_left, return_data) => {
stack.push(U256::zero());
self.return_data = return_data;
Ok(InstructionResult::UnusedGas(Cost::from_u256(gas_left).expect("Gas left cannot be greater.")))
},
ContractCreateResult::Failed => { ContractCreateResult::Failed => {
stack.push(U256::zero()); stack.push(U256::zero());
Ok(InstructionResult::Ok) Ok(InstructionResult::Ok)
} },
ContractCreateResult::FailedInStaticCall => {
Err(vm::Error::MutableCallInStaticContext)
},
}; };
}, },
instructions::CALL | instructions::CALLCODE | instructions::DELEGATECALL | instructions::STATICCALL => { instructions::CALL | instructions::CALLCODE | instructions::DELEGATECALL | instructions::STATICCALL => {
@ -353,8 +364,10 @@ impl<Cost: CostType> Interpreter<Cost> {
let code_address = stack.pop_back(); let code_address = stack.pop_back();
let code_address = u256_to_address(&code_address); let code_address = u256_to_address(&code_address);
let value = if instruction == instructions::DELEGATECALL || instruction == instructions::STATICCALL { let value = if instruction == instructions::DELEGATECALL {
None None
} else if instruction == instructions::STATICCALL {
Some(U256::zero())
} else { } else {
Some(stack.pop_back()) Some(stack.pop_back())
}; };
@ -373,6 +386,9 @@ impl<Cost: CostType> Interpreter<Cost> {
// Get sender & receive addresses, check if we have balance // Get sender & receive addresses, check if we have balance
let (sender_address, receive_address, has_balance, call_type) = match instruction { let (sender_address, receive_address, has_balance, call_type) = match instruction {
instructions::CALL => { instructions::CALL => {
if ext.is_static() && value.map_or(false, |v| !v.is_zero()) {
return Err(vm::Error::MutableCallInStaticContext);
}
let has_balance = ext.balance(&params.address)? >= value.expect("value set for all but delegate call; qed"); let has_balance = ext.balance(&params.address)? >= value.expect("value set for all but delegate call; qed");
(&params.address, &code_address, has_balance, CallType::Call) (&params.address, &code_address, has_balance, CallType::Call)
}, },
@ -381,10 +397,13 @@ impl<Cost: CostType> Interpreter<Cost> {
(&params.address, &params.address, has_balance, CallType::CallCode) (&params.address, &params.address, has_balance, CallType::CallCode)
}, },
instructions::DELEGATECALL => (&params.sender, &params.address, true, CallType::DelegateCall), instructions::DELEGATECALL => (&params.sender, &params.address, true, CallType::DelegateCall),
instructions::STATICCALL => (&params.sender, &params.address, true, CallType::StaticCall), instructions::STATICCALL => (&params.address, &code_address, true, CallType::StaticCall),
_ => panic!(format!("Unexpected instruction {} in CALL branch.", instruction)) _ => panic!(format!("Unexpected instruction {} in CALL branch.", instruction))
}; };
// clear return data buffer before creating new call frame.
self.return_data = ReturnData::empty();
let can_call = has_balance && ext.depth() < ext.schedule().max_depth; let can_call = has_balance && ext.depth() < ext.schedule().max_depth;
if !can_call { if !can_call {
stack.push(U256::zero()); stack.push(U256::zero());
@ -403,12 +422,17 @@ impl<Cost: CostType> Interpreter<Cost> {
MessageCallResult::Success(gas_left, data) => { MessageCallResult::Success(gas_left, data) => {
stack.push(U256::one()); stack.push(U256::one());
self.return_data = data; self.return_data = data;
Ok(InstructionResult::UnusedGas(Cost::from_u256(gas_left).expect("Gas left cannot be greater then current one"))) Ok(InstructionResult::UnusedGas(Cost::from_u256(gas_left).expect("Gas left cannot be greater than current one")))
},
MessageCallResult::Reverted(gas_left, data) => {
stack.push(U256::zero());
self.return_data = data;
Ok(InstructionResult::UnusedGas(Cost::from_u256(gas_left).expect("Gas left cannot be greater than current one")))
}, },
MessageCallResult::Failed => { MessageCallResult::Failed => {
stack.push(U256::zero()); stack.push(U256::zero());
Ok(InstructionResult::Ok) Ok(InstructionResult::Ok)
} },
}; };
}, },
instructions::RETURN => { instructions::RETURN => {
@ -546,6 +570,14 @@ impl<Cost: CostType> Interpreter<Cost> {
Self::copy_data_to_memory(&mut self.mem, stack, params.data.as_ref().map_or_else(|| &[] as &[u8], |d| &*d as &[u8])); Self::copy_data_to_memory(&mut self.mem, stack, params.data.as_ref().map_or_else(|| &[] as &[u8], |d| &*d as &[u8]));
}, },
instructions::RETURNDATACOPY => { instructions::RETURNDATACOPY => {
{
let source_offset = stack.peek(1);
let size = stack.peek(2);
let return_data_len = U256::from(self.return_data.len());
if source_offset.overflow_add(*size).0 > return_data_len {
return Err(vm::Error::OutOfBounds);
}
}
Self::copy_data_to_memory(&mut self.mem, stack, &*self.return_data); Self::copy_data_to_memory(&mut self.mem, stack, &*self.return_data);
}, },
instructions::CODECOPY => { instructions::CODECOPY => {

View File

@ -15,6 +15,9 @@ log = "0.3"
ethcore = { path = ".."} ethcore = { path = ".."}
ethcore-util = { path = "../../util" } ethcore-util = { path = "../../util" }
ethcore-bigint = { path = "../../util/bigint" } ethcore-bigint = { path = "../../util/bigint" }
ethcore-bytes = { path = "../../util/bytes" }
memorydb = { path = "../../util/memorydb" }
patricia_trie = { path = "../../util/patricia_trie" }
ethcore-network = { path = "../../util/network" } ethcore-network = { path = "../../util/network" }
ethcore-io = { path = "../../util/io" } ethcore-io = { path = "../../util/io" }
ethcore-ipc = { path = "../../ipc/rpc", optional = true } ethcore-ipc = { path = "../../ipc/rpc", optional = true }

View File

@ -23,8 +23,9 @@
use ethcore::ids::BlockId; use ethcore::ids::BlockId;
use bigint::prelude::U256; use bigint::prelude::U256;
use bigint::hash::H256; use bigint::hash::H256;
use util::{Bytes, HashDB, MemoryDB}; use util::{HashDB, MemoryDB};
use util::trie::{self, TrieMut, TrieDBMut, Trie, TrieDB, Recorder}; use bytes::Bytes;
use trie::{self, TrieMut, TrieDBMut, Trie, TrieDB, Recorder};
use rlp::{RlpStream, UntrustedRlp}; use rlp::{RlpStream, UntrustedRlp};
// encode a key. // encode a key.

View File

@ -71,11 +71,14 @@ extern crate ethcore_io as io;
extern crate ethcore_network as network; extern crate ethcore_network as network;
extern crate ethcore_util as util; extern crate ethcore_util as util;
extern crate ethcore_bigint as bigint; extern crate ethcore_bigint as bigint;
extern crate ethcore_bytes as bytes;
extern crate ethcore; extern crate ethcore;
extern crate evm; extern crate evm;
extern crate heapsize; extern crate heapsize;
extern crate futures; extern crate futures;
extern crate itertools; extern crate itertools;
extern crate memorydb;
extern crate patricia_trie as trie;
extern crate rand; extern crate rand;
extern crate rlp; extern crate rlp;
extern crate parking_lot; extern crate parking_lot;

View File

@ -33,9 +33,10 @@ use rlp::{RlpStream, UntrustedRlp};
use bigint::prelude::U256; use bigint::prelude::U256;
use bigint::hash::H256; use bigint::hash::H256;
use parking_lot::Mutex; use parking_lot::Mutex;
use util::{Address, Bytes, DBValue, HashDB}; use util::{Address, DBValue, HashDB};
use util::memorydb::MemoryDB; use bytes::Bytes;
use util::trie::{Trie, TrieDB, TrieError}; use memorydb::MemoryDB;
use trie::{Trie, TrieDB, TrieError};
const SUPPLIED_MATCHES: &'static str = "supplied responses always match produced requests; enforced by `check_response`; qed"; const SUPPLIED_MATCHES: &'static str = "supplied responses always match produced requests; enforced by `check_response`; qed";
@ -896,8 +897,8 @@ mod tests {
use bigint::hash::H256; use bigint::hash::H256;
use util::{MemoryDB, Address}; use util::{MemoryDB, Address};
use parking_lot::Mutex; use parking_lot::Mutex;
use util::trie::{Trie, TrieMut, SecTrieDB, SecTrieDBMut}; use trie::{Trie, TrieMut, SecTrieDB, SecTrieDBMut};
use util::trie::recorder::Recorder; use trie::recorder::Recorder;
use hash::keccak; use hash::keccak;
use ethcore::client::{BlockChainClient, TestBlockChainClient, EachBlockWith}; use ethcore::client::{BlockChainClient, TestBlockChainClient, EachBlockWith};
@ -973,6 +974,7 @@ mod tests {
fn check_receipts() { fn check_receipts() {
let receipts = (0..5).map(|_| Receipt { let receipts = (0..5).map(|_| Receipt {
state_root: Some(H256::random()), state_root: Some(H256::random()),
status_code: None,
gas_used: 21_000u64.into(), gas_used: 21_000u64.into(),
log_bloom: Default::default(), log_bloom: Default::default(),
logs: Vec::new(), logs: Vec::new(),

View File

@ -789,7 +789,7 @@ pub mod header_proof {
use rlp::{Encodable, Decodable, DecoderError, RlpStream, UntrustedRlp}; use rlp::{Encodable, Decodable, DecoderError, RlpStream, UntrustedRlp};
use bigint::prelude::U256; use bigint::prelude::U256;
use bigint::hash::H256; use bigint::hash::H256;
use util::Bytes; use bytes::Bytes;
/// Potentially incomplete header proof request. /// Potentially incomplete header proof request.
#[derive(Debug, Clone, PartialEq, Eq, RlpEncodable, RlpDecodable)] #[derive(Debug, Clone, PartialEq, Eq, RlpEncodable, RlpDecodable)]
@ -1120,7 +1120,7 @@ pub mod account {
use super::{Field, NoSuchOutput, OutputKind, Output}; use super::{Field, NoSuchOutput, OutputKind, Output};
use bigint::prelude::U256; use bigint::prelude::U256;
use bigint::hash::H256; use bigint::hash::H256;
use util::Bytes; use bytes::Bytes;
/// Potentially incomplete request for an account proof. /// Potentially incomplete request for an account proof.
#[derive(Debug, Clone, PartialEq, Eq, RlpEncodable, RlpDecodable)] #[derive(Debug, Clone, PartialEq, Eq, RlpEncodable, RlpDecodable)]
@ -1220,7 +1220,7 @@ pub mod account {
pub mod storage { pub mod storage {
use super::{Field, NoSuchOutput, OutputKind, Output}; use super::{Field, NoSuchOutput, OutputKind, Output};
use bigint::hash::H256; use bigint::hash::H256;
use util::Bytes; use bytes::Bytes;
/// Potentially incomplete request for an storage proof. /// Potentially incomplete request for an storage proof.
#[derive(Debug, Clone, PartialEq, Eq, RlpEncodable, RlpDecodable)] #[derive(Debug, Clone, PartialEq, Eq, RlpEncodable, RlpDecodable)]
@ -1329,7 +1329,7 @@ pub mod storage {
pub mod contract_code { pub mod contract_code {
use super::{Field, NoSuchOutput, OutputKind, Output}; use super::{Field, NoSuchOutput, OutputKind, Output};
use bigint::hash::H256; use bigint::hash::H256;
use util::Bytes; use bytes::Bytes;
/// Potentially incomplete contract code request. /// Potentially incomplete contract code request.
#[derive(Debug, Clone, PartialEq, Eq, RlpEncodable, RlpDecodable)] #[derive(Debug, Clone, PartialEq, Eq, RlpEncodable, RlpDecodable)]
@ -1417,7 +1417,8 @@ pub mod execution {
use rlp::{Encodable, Decodable, DecoderError, RlpStream, UntrustedRlp}; use rlp::{Encodable, Decodable, DecoderError, RlpStream, UntrustedRlp};
use bigint::prelude::U256; use bigint::prelude::U256;
use bigint::hash::H256; use bigint::hash::H256;
use util::{Bytes, Address, DBValue}; use util::{Address, DBValue};
use bytes::Bytes;
/// Potentially incomplete execution proof request. /// Potentially incomplete execution proof request.
#[derive(Debug, Clone, PartialEq, Eq, RlpEncodable, RlpDecodable)] #[derive(Debug, Clone, PartialEq, Eq, RlpEncodable, RlpDecodable)]
@ -1541,7 +1542,7 @@ pub mod epoch_signal {
use super::{Field, NoSuchOutput, OutputKind, Output}; use super::{Field, NoSuchOutput, OutputKind, Output};
use rlp::{Encodable, Decodable, DecoderError, RlpStream, UntrustedRlp}; use rlp::{Encodable, Decodable, DecoderError, RlpStream, UntrustedRlp};
use bigint::hash::H256; use bigint::hash::H256;
use util::Bytes; use bytes::Bytes;
/// Potentially incomplete epoch signal request. /// Potentially incomplete epoch signal request.
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq)]

View File

@ -10,6 +10,7 @@ authors = ["Parity Technologies <admin@parity.io>"]
ethcore = { path = ".."} ethcore = { path = ".."}
ethcore-util = { path = "../../util" } ethcore-util = { path = "../../util" }
ethcore-bigint = { path = "../../util/bigint" } ethcore-bigint = { path = "../../util/bigint" }
ethcore-bytes = { path = "../../util/bytes" }
ethcore-io = { path = "../../util/io" } ethcore-io = { path = "../../util/io" }
ethcore-network = { path = "../../util/network" } ethcore-network = { path = "../../util/network" }
native-contracts = { path = "../native_contracts" } native-contracts = { path = "../native_contracts" }

View File

@ -19,6 +19,7 @@
extern crate ethcore; extern crate ethcore;
extern crate ethcore_util as util; extern crate ethcore_util as util;
extern crate ethcore_bigint as bigint; extern crate ethcore_bigint as bigint;
extern crate ethcore_bytes as bytes;
extern crate ethcore_network as network; extern crate ethcore_network as network;
extern crate native_contracts; extern crate native_contracts;
extern crate futures; extern crate futures;
@ -32,7 +33,8 @@ use native_contracts::PeerSet as Contract;
use network::{NodeId, ConnectionFilter, ConnectionDirection}; use network::{NodeId, ConnectionFilter, ConnectionDirection};
use ethcore::client::{BlockChainClient, BlockId, ChainNotify}; use ethcore::client::{BlockChainClient, BlockId, ChainNotify};
use bigint::hash::H256; use bigint::hash::H256;
use util::{Address, Bytes}; use util::Address;
use bytes::Bytes;
use parking_lot::Mutex; use parking_lot::Mutex;
use futures::Future; use futures::Future;

View File

@ -0,0 +1,60 @@
{
"name": "Byzantium (Test)",
"engine": {
"Ethash": {
"params": {
"minimumDifficulty": "0x020000",
"difficultyBoundDivisor": "0x0800",
"durationLimit": "0x0d",
"homesteadTransition": "0x0",
"eip150Transition": "0x0",
"eip160Transition": "0x0",
"eip161abcTransition": "0x0",
"eip161dTransition": "0x0",
"maxCodeSize": 24576,
"eip649Reward": "0x29A2241AF62C0000",
"eip100bTransition": "0x0",
"eip649Transition": "0x0"
}
}
},
"params": {
"gasLimitBoundDivisor": "0x0400",
"blockReward": "0x4563918244F40000",
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
"accountStartNonce": "0x00",
"maximumExtraDataSize": "0x20",
"minGasLimit": "0x1388",
"networkID" : "0x1",
"eip98Transition": "0xffffffffffffffff",
"eip140Transition": "0x0",
"eip211Transition": "0x0",
"eip214Transition": "0x0",
"eip155Transition": "0x0",
"eip658Transition": "0x0"
},
"genesis": {
"seal": {
"ethereum": {
"nonce": "0x0000000000000042",
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000"
}
},
"difficulty": "0x400000000",
"author": "0x0000000000000000000000000000000000000000",
"timestamp": "0x00",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"extraData": "0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa",
"gasLimit": "0x1388"
},
"accounts": {
"0000000000000000000000000000000000000001": { "balance": "1", "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } },
"0000000000000000000000000000000000000002": { "balance": "1", "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } },
"0000000000000000000000000000000000000003": { "balance": "1", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } },
"0000000000000000000000000000000000000004": { "balance": "1", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } },
"0000000000000000000000000000000000000005": { "builtin": { "name": "modexp", "activate_at": "0x00", "pricing": { "modexp": { "divisor": 20 } } } },
"0000000000000000000000000000000000000006": { "builtin": { "name": "alt_bn128_add", "activate_at": "0x00", "pricing": { "linear": { "base": 500, "word": 0 } } } },
"0000000000000000000000000000000000000007": { "builtin": { "name": "alt_bn128_mul", "activate_at": "0x00", "pricing": { "linear": { "base": 40000, "word": 0 } } } },
"0000000000000000000000000000000000000008": { "builtin": { "name": "alt_bn128_pairing", "activate_at": "0x00", "pricing": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 } } } }
}
}

View File

@ -1,18 +1,20 @@
{ {
"name": "Metropolis (Test)", "name": "Byzantium (Test)",
"engine": { "engine": {
"Ethash": { "Ethash": {
"params": { "params": {
"minimumDifficulty": "0x020000", "minimumDifficulty": "0x020000",
"difficultyBoundDivisor": "0x0800", "difficultyBoundDivisor": "0x0800",
"durationLimit": "0x0d", "durationLimit": "0x0d",
"homesteadTransition": "0x0", "homesteadTransition": "0x0",
"eip150Transition": "0x0", "eip150Transition": "0x0",
"eip160Transition": "0x0", "eip160Transition": "0x0",
"eip161abcTransition": "0x0", "eip161abcTransition": "0x0",
"eip161dTransition": "0x0", "eip161dTransition": "0x0",
"maxCodeSize": 24576 "maxCodeSize": 24576,
"eip649Reward": "0x29A2241AF62C0000",
"eip100bTransition": "0x0",
"eip649Transition": "0x0"
} }
} }
}, },
@ -24,11 +26,13 @@
"maximumExtraDataSize": "0x20", "maximumExtraDataSize": "0x20",
"minGasLimit": "0x1388", "minGasLimit": "0x1388",
"networkID" : "0x1", "networkID" : "0x1",
"eip98Transition": "0x0", "eip98Transition": "0xffffffffffffffff",
"eip86Transition": "0x0",
"eip140Transition": "0x0", "eip140Transition": "0x0",
"eip210Transition": "0x0", "eip210Transition": "0x0",
"eip155Transition": "0x0" "eip211Transition": "0x0",
"eip214Transition": "0x0",
"eip155Transition": "0x0",
"eip658Transition": "0x0"
}, },
"genesis": { "genesis": {
"seal": { "seal": {
@ -48,6 +52,10 @@
"0000000000000000000000000000000000000001": { "balance": "1", "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } }, "0000000000000000000000000000000000000001": { "balance": "1", "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } },
"0000000000000000000000000000000000000002": { "balance": "1", "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } }, "0000000000000000000000000000000000000002": { "balance": "1", "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } },
"0000000000000000000000000000000000000003": { "balance": "1", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } }, "0000000000000000000000000000000000000003": { "balance": "1", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } },
"0000000000000000000000000000000000000004": { "balance": "1", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } } "0000000000000000000000000000000000000004": { "balance": "1", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } },
"0000000000000000000000000000000000000005": { "builtin": { "name": "modexp", "activate_at": "0x00", "pricing": { "modexp": { "divisor": 100 } } } },
"0000000000000000000000000000000000000006": { "builtin": { "name": "alt_bn128_add", "activate_at": "0x00", "pricing": { "linear": { "base": 500, "word": 0 } } } },
"0000000000000000000000000000000000000007": { "builtin": { "name": "alt_bn128_mul", "activate_at": "0x00", "pricing": { "linear": { "base": 2000, "word": 0 } } } },
"0000000000000000000000000000000000000008": { "builtin": { "name": "alt_bn128_pairing", "activate_at": "0x00", "pricing": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 } } } }
} }
} }

View File

@ -191,10 +191,10 @@
"0000000000000000000000000000000000000002": { "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } }, "0000000000000000000000000000000000000002": { "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } },
"0000000000000000000000000000000000000003": { "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } }, "0000000000000000000000000000000000000003": { "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } },
"0000000000000000000000000000000000000004": { "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } }, "0000000000000000000000000000000000000004": { "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } },
"0000000000000000000000000000000000000005": { "builtin": { "name": "modexp", "activate_at": "0x7fffffffffffff", "pricing": { "modexp": { "divisor": 20 } } } }, "0000000000000000000000000000000000000005": { "builtin": { "name": "modexp", "activate_at": "0x7fffffffffffff", "pricing": { "modexp": { "divisor": 100 } } } },
"0000000000000000000000000000000000000006": { "builtin": { "name": "bn128_add", "activate_at": "0x7fffffffffffff", "pricing": { "linear": { "base": 999999, "word": 0 } } } }, "0000000000000000000000000000000000000006": { "builtin": { "name": "alt_bn128_add", "activate_at": "0x7fffffffffffff", "pricing": { "linear": { "base": 500, "word": 0 } } } },
"0000000000000000000000000000000000000007": { "builtin": { "name": "bn128_mul", "activate_at": "0x7fffffffffffff", "pricing": { "linear": { "base": 999999, "word": 0 } } } }, "0000000000000000000000000000000000000007": { "builtin": { "name": "alt_bn128_mul", "activate_at": "0x7fffffffffffff", "pricing": { "linear": { "base": 2000, "word": 0 } } } },
"0000000000000000000000000000000000000008": { "builtin": { "name": "bn128_pairing", "activate_at": "0x7fffffffffffff", "pricing": { "linear": { "base": 999999, "word": 0 } } } }, "0000000000000000000000000000000000000008": { "builtin": { "name": "alt_bn128_pairing", "activate_at": "0x7fffffffffffff", "pricing": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 } } } },
"3282791d6fd713f1e94f4bfd565eaa78b3a0599d": { "3282791d6fd713f1e94f4bfd565eaa78b3a0599d": {
"balance": "1337000000000000000000" "balance": "1337000000000000000000"
}, },

View File

@ -1,136 +1,20 @@
{ {
"name": "EIP150.1b hard-fork consensus test", "name": "Transition consensus test spec template",
"engine": { "engine": {
"Ethash": { "Ethash": {
"params": { "params": {
"minimumDifficulty": "0x020000", "minimumDifficulty": "0x020000",
"difficultyBoundDivisor": "0x0800", "difficultyBoundDivisor": "0x0800",
"durationLimit": "0x0d", "durationLimit": "0x0d",
"homesteadTransition": "0x5", "homesteadTransition": "0",
"daoHardforkTransition": "0x8", "eip150Transition": "0",
"daoHardforkBeneficiary": "0xbf4ed7b27f1d666546e30d74d50d173d20bca754", "eip160Transition": "0",
"daoHardforkAccounts": [ "eip161abcTransition": "0",
"0xd4fe7bc31cedb7bfb8a345f31e668033056b2728", "eip161dTransition": "0",
"0xb3fb0e5aba0e20e5c49d252dfd30e102b171a425", "maxCodeSize": 24576,
"0x2c19c7f9ae8b751e37aeb2d93a699722395ae18f", "eip649Reward": "0x29A2241AF62C0000",
"0xecd135fa4f61a655311e86238c92adcd779555d2", "eip100bTransition": "5",
"0x1975bd06d486162d5dc297798dfc41edd5d160a7", "eip649Transition": "5"
"0xa3acf3a1e16b1d7c315e23510fdd7847b48234f6",
"0x319f70bab6845585f412ec7724b744fec6095c85",
"0x06706dd3f2c9abf0a21ddcc6941d9b86f0596936",
"0x5c8536898fbb74fc7445814902fd08422eac56d0",
"0x6966ab0d485353095148a2155858910e0965b6f9",
"0x779543a0491a837ca36ce8c635d6154e3c4911a6",
"0x2a5ed960395e2a49b1c758cef4aa15213cfd874c",
"0x5c6e67ccd5849c0d29219c4f95f1a7a93b3f5dc5",
"0x9c50426be05db97f5d64fc54bf89eff947f0a321",
"0x200450f06520bdd6c527622a273333384d870efb",
"0xbe8539bfe837b67d1282b2b1d61c3f723966f049",
"0x6b0c4d41ba9ab8d8cfb5d379c69a612f2ced8ecb",
"0xf1385fb24aad0cd7432824085e42aff90886fef5",
"0xd1ac8b1ef1b69ff51d1d401a476e7e612414f091",
"0x8163e7fb499e90f8544ea62bbf80d21cd26d9efd",
"0x51e0ddd9998364a2eb38588679f0d2c42653e4a6",
"0x627a0a960c079c21c34f7612d5d230e01b4ad4c7",
"0xf0b1aa0eb660754448a7937c022e30aa692fe0c5",
"0x24c4d950dfd4dd1902bbed3508144a54542bba94",
"0x9f27daea7aca0aa0446220b98d028715e3bc803d",
"0xa5dc5acd6a7968a4554d89d65e59b7fd3bff0f90",
"0xd9aef3a1e38a39c16b31d1ace71bca8ef58d315b",
"0x63ed5a272de2f6d968408b4acb9024f4cc208ebf",
"0x6f6704e5a10332af6672e50b3d9754dc460dfa4d",
"0x77ca7b50b6cd7e2f3fa008e24ab793fd56cb15f6",
"0x492ea3bb0f3315521c31f273e565b868fc090f17",
"0x0ff30d6de14a8224aa97b78aea5388d1c51c1f00",
"0x9ea779f907f0b315b364b0cfc39a0fde5b02a416",
"0xceaeb481747ca6c540a000c1f3641f8cef161fa7",
"0xcc34673c6c40e791051898567a1222daf90be287",
"0x579a80d909f346fbfb1189493f521d7f48d52238",
"0xe308bd1ac5fda103967359b2712dd89deffb7973",
"0x4cb31628079fb14e4bc3cd5e30c2f7489b00960c",
"0xac1ecab32727358dba8962a0f3b261731aad9723",
"0x4fd6ace747f06ece9c49699c7cabc62d02211f75",
"0x440c59b325d2997a134c2c7c60a8c61611212bad",
"0x4486a3d68fac6967006d7a517b889fd3f98c102b",
"0x9c15b54878ba618f494b38f0ae7443db6af648ba",
"0x27b137a85656544b1ccb5a0f2e561a5703c6a68f",
"0x21c7fdb9ed8d291d79ffd82eb2c4356ec0d81241",
"0x23b75c2f6791eef49c69684db4c6c1f93bf49a50",
"0x1ca6abd14d30affe533b24d7a21bff4c2d5e1f3b",
"0xb9637156d330c0d605a791f1c31ba5890582fe1c",
"0x6131c42fa982e56929107413a9d526fd99405560",
"0x1591fc0f688c81fbeb17f5426a162a7024d430c2",
"0x542a9515200d14b68e934e9830d91645a980dd7a",
"0xc4bbd073882dd2add2424cf47d35213405b01324",
"0x782495b7b3355efb2833d56ecb34dc22ad7dfcc4",
"0x58b95c9a9d5d26825e70a82b6adb139d3fd829eb",
"0x3ba4d81db016dc2890c81f3acec2454bff5aada5",
"0xb52042c8ca3f8aa246fa79c3feaa3d959347c0ab",
"0xe4ae1efdfc53b73893af49113d8694a057b9c0d1",
"0x3c02a7bc0391e86d91b7d144e61c2c01a25a79c5",
"0x0737a6b837f97f46ebade41b9bc3e1c509c85c53",
"0x97f43a37f595ab5dd318fb46e7a155eae057317a",
"0x52c5317c848ba20c7504cb2c8052abd1fde29d03",
"0x4863226780fe7c0356454236d3b1c8792785748d",
"0x5d2b2e6fcbe3b11d26b525e085ff818dae332479",
"0x5f9f3392e9f62f63b8eac0beb55541fc8627f42c",
"0x057b56736d32b86616a10f619859c6cd6f59092a",
"0x9aa008f65de0b923a2a4f02012ad034a5e2e2192",
"0x304a554a310c7e546dfe434669c62820b7d83490",
"0x914d1b8b43e92723e64fd0a06f5bdb8dd9b10c79",
"0x4deb0033bb26bc534b197e61d19e0733e5679784",
"0x07f5c1e1bc2c93e0402f23341973a0e043f7bf8a",
"0x35a051a0010aba705c9008d7a7eff6fb88f6ea7b",
"0x4fa802324e929786dbda3b8820dc7834e9134a2a",
"0x9da397b9e80755301a3b32173283a91c0ef6c87e",
"0x8d9edb3054ce5c5774a420ac37ebae0ac02343c6",
"0x0101f3be8ebb4bbd39a2e3b9a3639d4259832fd9",
"0x5dc28b15dffed94048d73806ce4b7a4612a1d48f",
"0xbcf899e6c7d9d5a215ab1e3444c86806fa854c76",
"0x12e626b0eebfe86a56d633b9864e389b45dcb260",
"0xa2f1ccba9395d7fcb155bba8bc92db9bafaeade7",
"0xec8e57756626fdc07c63ad2eafbd28d08e7b0ca5",
"0xd164b088bd9108b60d0ca3751da4bceb207b0782",
"0x6231b6d0d5e77fe001c2a460bd9584fee60d409b",
"0x1cba23d343a983e9b5cfd19496b9a9701ada385f",
"0xa82f360a8d3455c5c41366975bde739c37bfeb8a",
"0x9fcd2deaff372a39cc679d5c5e4de7bafb0b1339",
"0x005f5cee7a43331d5a3d3eec71305925a62f34b6",
"0x0e0da70933f4c7849fc0d203f5d1d43b9ae4532d",
"0xd131637d5275fd1a68a3200f4ad25c71a2a9522e",
"0xbc07118b9ac290e4622f5e77a0853539789effbe",
"0x47e7aa56d6bdf3f36be34619660de61275420af8",
"0xacd87e28b0c9d1254e868b81cba4cc20d9a32225",
"0xadf80daec7ba8dcf15392f1ac611fff65d94f880",
"0x5524c55fb03cf21f549444ccbecb664d0acad706",
"0x40b803a9abce16f50f36a77ba41180eb90023925",
"0xfe24cdd8648121a43a7c86d289be4dd2951ed49f",
"0x17802f43a0137c506ba92291391a8a8f207f487d",
"0x253488078a4edf4d6f42f113d1e62836a942cf1a",
"0x86af3e9626fce1957c82e88cbf04ddf3a2ed7915",
"0xb136707642a4ea12fb4bae820f03d2562ebff487",
"0xdbe9b615a3ae8709af8b93336ce9b477e4ac0940",
"0xf14c14075d6c4ed84b86798af0956deef67365b5",
"0xca544e5c4687d109611d0f8f928b53a25af72448",
"0xaeeb8ff27288bdabc0fa5ebb731b6f409507516c",
"0xcbb9d3703e651b0d496cdefb8b92c25aeb2171f7",
"0x6d87578288b6cb5549d5076a207456a1f6a63dc0",
"0xb2c6f0dfbb716ac562e2d85d6cb2f8d5ee87603e",
"0xaccc230e8a6e5be9160b8cdf2864dd2a001c28b6",
"0x2b3455ec7fedf16e646268bf88846bd7a2319bb2",
"0x4613f3bca5c44ea06337a9e439fbc6d42e501d0a",
"0xd343b217de44030afaa275f54d31a9317c7f441e",
"0x84ef4b2357079cd7a7c69fd7a37cd0609a679106",
"0xda2fef9e4a3230988ff17df2165440f37e8b1708",
"0xf4c64518ea10f995918a454158c6b61407ea345c",
"0x7602b46df5390e432ef1c307d4f2c9ff6d65cc97",
"0xbb9bc244d798123fde783fcc1c72d3bb8c189413",
"0x807640a13483f8ac783c557fcdf27be11ea4ac7a"
],
"eip150Transition": "0xa",
"eip160Transition": "0x7fffffffffffffff",
"eip161abcTransition": "0x7fffffffffffffff",
"eip161dTransition": "0x7fffffffffffffff"
} }
} }
}, },
@ -142,9 +26,12 @@
"maximumExtraDataSize": "0x20", "maximumExtraDataSize": "0x20",
"minGasLimit": "0x1388", "minGasLimit": "0x1388",
"networkID" : "0x1", "networkID" : "0x1",
"eip98Transition": "0x7fffffffffffff", "eip98Transition": "5",
"eip86Transition": "0x7fffffffffffff", "eip140Transition": "5",
"eip155Transition": "0x7fffffffffffffff" "eip211Transition": "5",
"eip214Transition": "5",
"eip155Transition": "5",
"eip658Transition": "5"
}, },
"genesis": { "genesis": {
"seal": { "seal": {
@ -161,9 +48,13 @@
"gasLimit": "0x1388" "gasLimit": "0x1388"
}, },
"accounts": { "accounts": {
"0000000000000000000000000000000000000001": { "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } }, "0000000000000000000000000000000000000001": { "balance": "1", "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } },
"0000000000000000000000000000000000000002": { "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } }, "0000000000000000000000000000000000000002": { "balance": "1", "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } },
"0000000000000000000000000000000000000003": { "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } }, "0000000000000000000000000000000000000003": { "balance": "1", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } },
"0000000000000000000000000000000000000004": { "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } } "0000000000000000000000000000000000000004": { "balance": "1", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } },
"0000000000000000000000000000000000000005": { "builtin": { "name": "modexp", "activate_at": "5", "pricing": { "modexp": { "divisor": 100 } } } },
"0000000000000000000000000000000000000006": { "builtin": { "name": "alt_bn128_add", "activate_at": "5", "pricing": { "linear": { "base": 500, "word": 0 } } } },
"0000000000000000000000000000000000000007": { "builtin": { "name": "alt_bn128_mul", "activate_at": "5", "pricing": { "linear": { "base": 2000, "word": 0 } } } },
"0000000000000000000000000000000000000008": { "builtin": { "name": "alt_bn128_pairing", "activate_at": "5", "pricing": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 } } } }
} }
} }

View File

@ -31,7 +31,8 @@ use ethstore::{
use ethstore::dir::MemoryDirectory; use ethstore::dir::MemoryDirectory;
use ethstore::ethkey::{Address, Message, Public, Secret, Random, Generator}; use ethstore::ethkey::{Address, Message, Public, Secret, Random, Generator};
use ethjson::misc::AccountMeta; use ethjson::misc::AccountMeta;
use hardware_wallet::{Error as HardwareError, HardwareWalletManager, KeyPath}; use hardware_wallet::{Error as HardwareError, HardwareWalletManager, KeyPath, TransactionInfo};
use super::transaction::{Action, Transaction};
pub use ethstore::ethkey::Signature; pub use ethstore::ethkey::Signature;
pub use ethstore::{Derivation, IndexDerivation, KeyFile}; pub use ethstore::{Derivation, IndexDerivation, KeyFile};
@ -288,6 +289,24 @@ impl AccountProvider {
Ok(accounts.into_iter().map(|a| a.address).collect()) Ok(accounts.into_iter().map(|a| a.address).collect())
} }
/// Get a list of paths to locked hardware wallets
pub fn locked_hardware_accounts(&self) -> Result<Vec<String>, SignError> {
match self.hardware_store.as_ref().map(|h| h.list_locked_wallets()) {
None => Err(SignError::NotFound),
Some(Err(e)) => Err(SignError::Hardware(e)),
Some(Ok(s)) => Ok(s),
}
}
/// Provide a pin to a locked hardware wallet on USB path to unlock it
pub fn hardware_pin_matrix_ack(&self, path: &str, pin: &str) -> Result<bool, SignError> {
match self.hardware_store.as_ref().map(|h| h.pin_matrix_ack(path, pin)) {
None => Err(SignError::NotFound),
Some(Err(e)) => Err(SignError::Hardware(e)),
Some(Ok(s)) => Ok(s),
}
}
/// Sets addresses of accounts exposed for unknown dapps. /// Sets addresses of accounts exposed for unknown dapps.
/// `None` means that all accounts will be visible. /// `None` means that all accounts will be visible.
/// If not `None` or empty it will also override default account. /// If not `None` or empty it will also override default account.
@ -779,8 +798,20 @@ impl AccountProvider {
} }
/// Sign transaction with hardware wallet. /// Sign transaction with hardware wallet.
pub fn sign_with_hardware(&self, address: Address, transaction: &[u8]) -> Result<Signature, SignError> { pub fn sign_with_hardware(&self, address: Address, transaction: &Transaction, chain_id: Option<u64>, rlp_encoded_transaction: &[u8]) -> Result<Signature, SignError> {
match self.hardware_store.as_ref().map(|s| s.sign_transaction(&address, transaction)) { let t_info = TransactionInfo {
nonce: transaction.nonce,
gas_price: transaction.gas_price,
gas_limit: transaction.gas,
to: match transaction.action {
Action::Create => None,
Action::Call(ref to) => Some(to.clone()),
},
value: transaction.value,
data: transaction.data.to_vec(),
chain_id: chain_id,
};
match self.hardware_store.as_ref().map(|s| s.sign_transaction(&address, &t_info, rlp_encoded_transaction)) {
None | Some(Err(HardwareError::KeyNotFound)) => Err(SignError::NotFound), None | Some(Err(HardwareError::KeyNotFound)) => Err(SignError::NotFound),
Some(Err(e)) => Err(From::from(e)), Some(Err(e)) => Err(From::from(e)),
Some(Ok(s)) => Ok(s), Some(Ok(s)) => Ok(s),

View File

@ -25,7 +25,8 @@ use triehash::ordered_trie_root;
use rlp::{UntrustedRlp, RlpStream, Encodable, Decodable, DecoderError}; use rlp::{UntrustedRlp, RlpStream, Encodable, Decodable, DecoderError};
use bigint::prelude::U256; use bigint::prelude::U256;
use bigint::hash::H256; use bigint::hash::H256;
use util::{Bytes, Address}; use util::Address;
use bytes::Bytes;
use unexpected::{Mismatch, OutOfBounds}; use unexpected::{Mismatch, OutOfBounds};
use basic_types::{LogBloom, Seal}; use basic_types::{LogBloom, Seal};

View File

@ -16,7 +16,7 @@
use bigint::prelude::U256; use bigint::prelude::U256;
use bigint::hash::H256; use bigint::hash::H256;
use util::Bytes; use bytes::Bytes;
use header::BlockNumber; use header::BlockNumber;
/// Best block info. /// Best block info.

View File

@ -25,6 +25,7 @@ use heapsize::HeapSizeOf;
use bigint::prelude::U256; use bigint::prelude::U256;
use bigint::hash::{H256, H2048}; use bigint::hash::{H256, H2048};
use parking_lot::{Mutex, RwLock}; use parking_lot::{Mutex, RwLock};
use bytes::Bytes;
use util::*; use util::*;
use rlp::*; use rlp::*;
use header::*; use header::*;
@ -2048,6 +2049,7 @@ mod tests {
let bc = new_chain(&genesis, db.clone()); let bc = new_chain(&genesis, db.clone());
insert_block(&db, &bc, &b1, vec![Receipt { insert_block(&db, &bc, &b1, vec![Receipt {
state_root: Some(H256::default()), state_root: Some(H256::default()),
status_code: None,
gas_used: 10_000.into(), gas_used: 10_000.into(),
log_bloom: Default::default(), log_bloom: Default::default(),
logs: vec![ logs: vec![
@ -2057,6 +2059,7 @@ mod tests {
}, },
Receipt { Receipt {
state_root: Some(H256::default()), state_root: Some(H256::default()),
status_code: None,
gas_used: 10_000.into(), gas_used: 10_000.into(),
log_bloom: Default::default(), log_bloom: Default::default(),
logs: vec![ logs: vec![
@ -2066,6 +2069,7 @@ mod tests {
insert_block(&db, &bc, &b2, vec![ insert_block(&db, &bc, &b2, vec![
Receipt { Receipt {
state_root: Some(H256::default()), state_root: Some(H256::default()),
status_code: None,
gas_used: 10_000.into(), gas_used: 10_000.into(),
log_bloom: Default::default(), log_bloom: Default::default(),
logs: vec![ logs: vec![

View File

@ -16,7 +16,7 @@
use rlp::*; use rlp::*;
use bigint::hash::{H256, H2048}; use bigint::hash::{H256, H2048};
use util::bytes::Bytes; use bytes::Bytes;
use header::Header; use header::Header;
use transaction::SignedTransaction; use transaction::SignedTransaction;

View File

@ -15,7 +15,7 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
use bigint::hash::H256; use bigint::hash::H256;
use util::bytes::Bytes; use bytes::Bytes;
use views::BlockView; use views::BlockView;
#[derive(Default, Clone)] #[derive(Default, Clone)]

View File

@ -16,7 +16,7 @@
use bigint::prelude::U256; use bigint::prelude::U256;
use bigint::hash::H2048; use bigint::hash::H2048;
use util::Bytes; use bytes::Bytes;
use header::BlockNumber; use header::BlockNumber;
use transaction::SignedTransaction; use transaction::SignedTransaction;
use super::fork::Fork; use super::fork::Fork;

View File

@ -26,7 +26,7 @@ use num::{BigUint, Zero, One};
use hash::keccak; use hash::keccak;
use bigint::prelude::U256; use bigint::prelude::U256;
use bigint::hash::H256; use bigint::hash::H256;
use util::BytesRef; use bytes::BytesRef;
use ethkey::{Signature, recover as ec_recover}; use ethkey::{Signature, recover as ec_recover};
use ethjson; use ethjson;
@ -64,7 +64,7 @@ struct Linear {
} }
/// A special pricing model for modular exponentiation. /// A special pricing model for modular exponentiation.
struct Modexp { struct ModexpPricer {
divisor: usize, divisor: usize,
} }
@ -74,7 +74,20 @@ impl Pricer for Linear {
} }
} }
impl Pricer for Modexp { /// A alt_bn128_parinig pricing model. This computes a price using a base cost and a cost per pair.
struct AltBn128PairingPricer {
base: usize,
pair: usize,
}
impl Pricer for AltBn128PairingPricer {
fn cost(&self, input: &[u8]) -> U256 {
let cost = U256::from(self.base) + U256::from(self.pair) * U256::from(input.len() / 192);
cost
}
}
impl Pricer for ModexpPricer {
fn cost(&self, input: &[u8]) -> U256 { fn cost(&self, input: &[u8]) -> U256 {
let mut reader = input.chain(io::repeat(0)); let mut reader = input.chain(io::repeat(0));
let mut buf = [0; 32]; let mut buf = [0; 32];
@ -88,17 +101,49 @@ impl Pricer for Modexp {
let exp_len = read_len(); let exp_len = read_len();
let mod_len = read_len(); let mod_len = read_len();
// floor(max(length_of_MODULUS, length_of_BASE) ** 2 * max(length_of_EXPONENT, 1) / GQUADDIVISOR) let max_len = U256::from(u32::max_value() / 2);
// TODO: is saturating the best behavior here? if base_len > max_len || mod_len > max_len {
return U256::max_value();
}
let base_len = base_len.low_u64();
let exp_len = exp_len.low_u64();
let mod_len = mod_len.low_u64();
let m = max(mod_len, base_len); let m = max(mod_len, base_len);
match m.overflowing_mul(m) { if m == 0 {
(_, true) => U256::max_value(), return U256::zero();
(val, _) => { }
match val.overflowing_mul(max(exp_len, U256::one())) { // read fist 32-byte word of the exponent.
(_, true) => U256::max_value(), let exp_low = if base_len + 96 >= input.len() as u64 { U256::zero() } else {
(val, _) => val / (self.divisor as u64).into() let mut buf = [0; 32];
} let mut reader = input[(96 + base_len as usize)..].chain(io::repeat(0));
} let len = min(exp_len, 32) as usize;
reader.read_exact(&mut buf[(32 - len)..]).expect("reading from zero-extended memory cannot fail; qed");
U256::from(H256::from_slice(&buf[..]))
};
let adjusted_exp_len = Self::adjusted_exp_len(exp_len, exp_low);
(Self::mult_complexity(m) * max(adjusted_exp_len, 1) / self.divisor as u64).into()
}
}
impl ModexpPricer {
fn adjusted_exp_len(len: u64, exp_low: U256) -> u64 {
let bit_index = if exp_low.is_zero() { 0 } else { (255 - exp_low.leading_zeros()) as u64 };
if len <= 32 {
bit_index
}
else {
8 * (len - 32) + bit_index
}
}
fn mult_complexity(x: u64) -> u64 {
match x {
x if x <= 64 => x * x,
x if x <= 1024 => (x * x) / 4 + 96 * x - 3072,
x => (x * x) / 16 + 480 * x - 199680,
} }
} }
} }
@ -138,7 +183,7 @@ impl From<ethjson::spec::Builtin> for Builtin {
}) })
} }
ethjson::spec::Pricing::Modexp(exp) => { ethjson::spec::Pricing::Modexp(exp) => {
Box::new(Modexp { Box::new(ModexpPricer {
divisor: if exp.divisor == 0 { divisor: if exp.divisor == 0 {
warn!("Zero modexp divisor specified. Falling back to default."); warn!("Zero modexp divisor specified. Falling back to default.");
10 10
@ -147,6 +192,12 @@ impl From<ethjson::spec::Builtin> for Builtin {
} }
}) })
} }
ethjson::spec::Pricing::AltBn128Pairing(pricer) => {
Box::new(AltBn128PairingPricer {
base: pricer.base,
pair: pricer.pair,
})
}
}; };
Builtin { Builtin {
@ -165,9 +216,9 @@ fn ethereum_builtin(name: &str) -> Box<Impl> {
"sha256" => Box::new(Sha256) as Box<Impl>, "sha256" => Box::new(Sha256) as Box<Impl>,
"ripemd160" => Box::new(Ripemd160) as Box<Impl>, "ripemd160" => Box::new(Ripemd160) as Box<Impl>,
"modexp" => Box::new(ModexpImpl) as Box<Impl>, "modexp" => Box::new(ModexpImpl) as Box<Impl>,
"bn128_add" => Box::new(Bn128AddImpl) as Box<Impl>, "alt_bn128_add" => Box::new(Bn128AddImpl) as Box<Impl>,
"bn128_mul" => Box::new(Bn128MulImpl) as Box<Impl>, "alt_bn128_mul" => Box::new(Bn128MulImpl) as Box<Impl>,
"bn128_pairing" => Box::new(Bn128PairingImpl) as Box<Impl>, "alt_bn128_pairing" => Box::new(Bn128PairingImpl) as Box<Impl>,
_ => panic!("invalid builtin name: {}", name), _ => panic!("invalid builtin name: {}", name),
} }
} }
@ -273,11 +324,16 @@ impl Impl for Ripemd160 {
fn modexp(mut base: BigUint, mut exp: BigUint, modulus: BigUint) -> BigUint { fn modexp(mut base: BigUint, mut exp: BigUint, modulus: BigUint) -> BigUint {
use num::Integer; use num::Integer;
match (base.is_zero(), exp.is_zero()) { if modulus <= BigUint::one() { // n^m % 0 || n^m % 1
(_, true) => return BigUint::one(), // n^0 % m return BigUint::zero();
(true, false) => return BigUint::zero(), // 0^n % m, n>0 }
(false, false) if modulus <= BigUint::one() => return BigUint::zero(), // a^b % 1 = 0.
_ => {} if exp.is_zero() { // n^0 % m
return BigUint::one();
}
if base.is_zero() { // 0^n % m, n>0
return BigUint::zero();
} }
let mut result = BigUint::one(); let mut result = BigUint::one();
@ -293,7 +349,6 @@ fn modexp(mut base: BigUint, mut exp: BigUint, modulus: BigUint) -> BigUint {
exp = exp >> 1; exp = exp >> 1;
base = (base.clone() * base) % &modulus; base = (base.clone() * base) % &modulus;
} }
result result
} }
@ -314,19 +369,25 @@ impl Impl for ModexpImpl {
let exp_len = read_len(&mut reader); let exp_len = read_len(&mut reader);
let mod_len = read_len(&mut reader); let mod_len = read_len(&mut reader);
// read the numbers themselves. // Gas formula allows arbitrary large exp_len when base and modulus are empty, so we need to handle empty base first.
let mut buf = vec![0; max(mod_len, max(base_len, exp_len))]; let r = if base_len == 0 && mod_len == 0 {
let mut read_num = |len| { BigUint::zero()
reader.read_exact(&mut buf[..len]).expect("reading from zero-extended memory cannot fail; qed"); } else {
BigUint::from_bytes_be(&buf[..len]) // read the numbers themselves.
let mut buf = vec![0; max(mod_len, max(base_len, exp_len))];
let mut read_num = |len| {
reader.read_exact(&mut buf[..len]).expect("reading from zero-extended memory cannot fail; qed");
BigUint::from_bytes_be(&buf[..len])
};
let base = read_num(base_len);
let exp = read_num(exp_len);
let modulus = read_num(mod_len);
modexp(base, exp, modulus)
}; };
let base = read_num(base_len);
let exp = read_num(exp_len);
let modulus = read_num(mod_len);
// write output to given memory, left padded and same length as the modulus. // write output to given memory, left padded and same length as the modulus.
let bytes = modexp(base, exp, modulus).to_bytes_be(); let bytes = r.to_bytes_be();
// always true except in the case of zero-length modulus, which leads to // always true except in the case of zero-length modulus, which leads to
// output of length and value 1. // output of length and value 1.
@ -356,7 +417,6 @@ fn read_point(reader: &mut io::Chain<&[u8], io::Repeat>) -> Result<::bn::G1, Err
reader.read_exact(&mut buf[..]).expect("reading from zero-extended memory cannot fail; qed"); reader.read_exact(&mut buf[..]).expect("reading from zero-extended memory cannot fail; qed");
let py = Fq::from_slice(&buf[0..32]).map_err(|_| Error::from("Invalid point y coordinate"))?; let py = Fq::from_slice(&buf[0..32]).map_err(|_| Error::from("Invalid point y coordinate"))?;
Ok( Ok(
if px == Fq::zero() && py == Fq::zero() { if px == Fq::zero() && py == Fq::zero() {
G1::zero() G1::zero()
@ -407,50 +467,29 @@ impl Impl for Bn128MulImpl {
} }
} }
mod bn128_gen {
use bn::{AffineG1, AffineG2, Fq, Fq2, G1, G2, Gt, pairing};
lazy_static! {
pub static ref P1: G1 = G1::from(AffineG1::new(
Fq::from_str("1").expect("1 is a valid field element"),
Fq::from_str("2").expect("2 is a valid field element"),
).expect("Generator P1(1, 2) is a valid curve point"));
}
lazy_static! {
pub static ref P2: G2 = G2::from(AffineG2::new(
Fq2::new(
Fq::from_str("10857046999023057135944570762232829481370756359578518086990519993285655852781")
.expect("a valid field element"),
Fq::from_str("11559732032986387107991004021392285783925812861821192530917403151452391805634")
.expect("a valid field element"),
),
Fq2::new(
Fq::from_str("8495653923123431417604973247489272438418190587263600148770280649306958101930")
.expect("a valid field element"),
Fq::from_str("4082367875863433681332203403145435568316851327593401208105741076214120093531")
.expect("a valid field element"),
),
).expect("the generator P2(10857046999023057135944570762232829481370756359578518086990519993285655852781 + 11559732032986387107991004021392285783925812861821192530917403151452391805634i, 8495653923123431417604973247489272438418190587263600148770280649306958101930 + 4082367875863433681332203403145435568316851327593401208105741076214120093531i) is a valid curve point"));
}
lazy_static! {
pub static ref P1_P2_PAIRING: Gt = pairing(P1.clone(), P2.clone());
}
}
impl Impl for Bn128PairingImpl { impl Impl for Bn128PairingImpl {
/// Can fail if: /// Can fail if:
/// - input length is not a multiple of 192 /// - input length is not a multiple of 192
/// - any of odd points does not belong to bn128 curve /// - any of odd points does not belong to bn128 curve
/// - any of even points does not belong to the twisted bn128 curve over the field F_p^2 = F_p[i] / (i^2 + 1) /// - any of even points does not belong to the twisted bn128 curve over the field F_p^2 = F_p[i] / (i^2 + 1)
fn execute(&self, input: &[u8], output: &mut BytesRef) -> Result<(), Error> { fn execute(&self, input: &[u8], output: &mut BytesRef) -> Result<(), Error> {
use bn::{AffineG1, AffineG2, Fq, Fq2, pairing, G1, G2, Gt};
let elements = input.len() / 192; // (a, b_a, b_b - each 64-byte affine coordinates)
if input.len() % 192 != 0 { if input.len() % 192 != 0 {
return Err("Invalid input length, must be multiple of 192 (3 * (32*2))".into()) return Err("Invalid input length, must be multiple of 192 (3 * (32*2))".into())
} }
if let Err(err) = self.execute_with_error(input, output) {
trace!("Pairining error: {:?}", err);
return Err(err)
}
Ok(())
}
}
impl Bn128PairingImpl {
fn execute_with_error(&self, input: &[u8], output: &mut BytesRef) -> Result<(), Error> {
use bn::{AffineG1, AffineG2, Fq, Fq2, pairing, G1, G2, Gt, Group};
let elements = input.len() / 192; // (a, b_a, b_b - each 64-byte affine coordinates)
let ret_val = if input.len() == 0 { let ret_val = if input.len() == 0 {
U256::one() U256::one()
} else { } else {
@ -462,34 +501,36 @@ impl Impl for Bn128PairingImpl {
let a_y = Fq::from_slice(&input[idx*192+32..idx*192+64]) let a_y = Fq::from_slice(&input[idx*192+32..idx*192+64])
.map_err(|_| Error::from("Invalid a argument y coordinate"))?; .map_err(|_| Error::from("Invalid a argument y coordinate"))?;
let b_b_x = Fq::from_slice(&input[idx*192+64..idx*192+96]) let b_a_y = Fq::from_slice(&input[idx*192+64..idx*192+96])
.map_err(|_| Error::from("Invalid b argument imaginary coeff x coordinate"))?; .map_err(|_| Error::from("Invalid b argument imaginary coeff x coordinate"))?;
let b_b_y = Fq::from_slice(&input[idx*192+96..idx*192+128]) let b_a_x = Fq::from_slice(&input[idx*192+96..idx*192+128])
.map_err(|_| Error::from("Invalid b argument imaginary coeff y coordinate"))?; .map_err(|_| Error::from("Invalid b argument imaginary coeff y coordinate"))?;
let b_a_x = Fq::from_slice(&input[idx*192+128..idx*192+160]) let b_b_y = Fq::from_slice(&input[idx*192+128..idx*192+160])
.map_err(|_| Error::from("Invalid b argument real coeff x coordinate"))?; .map_err(|_| Error::from("Invalid b argument real coeff x coordinate"))?;
let b_a_y = Fq::from_slice(&input[idx*192+160..idx*192+192]) let b_b_x = Fq::from_slice(&input[idx*192+160..idx*192+192])
.map_err(|_| Error::from("Invalid b argument real coeff y coordinate"))?; .map_err(|_| Error::from("Invalid b argument real coeff y coordinate"))?;
vals.push(( let b_a = Fq2::new(b_a_x, b_a_y);
G1::from( let b_b = Fq2::new(b_b_x, b_b_y);
AffineG1::new(a_x, a_y).map_err(|_| Error::from("Invalid a argument - not on curve"))? let b = if b_a.is_zero() && b_b.is_zero() {
), G2::zero()
G2::from( } else {
AffineG2::new( G2::from(AffineG2::new(b_a, b_b).map_err(|_| Error::from("Invalid b argument - not on curve"))?)
Fq2::new(b_a_x, b_a_y), };
Fq2::new(b_b_x, b_b_y), let a = if a_x.is_zero() && a_y.is_zero() {
).map_err(|_| Error::from("Invalid b argument - not on curve"))? G1::zero()
), } else {
)); G1::from(AffineG1::new(a_x, a_y).map_err(|_| Error::from("Invalid a argument - not on curve"))?)
};
vals.push((a, b));
}; };
let mul = vals.into_iter().fold(Gt::one(), |s, (a, b)| s * pairing(a, b)); let mul = vals.into_iter().fold(Gt::one(), |s, (a, b)| s * pairing(a, b));
if mul == *bn128_gen::P1_P2_PAIRING { if mul == Gt::one() {
U256::one() U256::one()
} else { } else {
U256::zero() U256::zero()
@ -506,10 +547,10 @@ impl Impl for Bn128PairingImpl {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::{Builtin, Linear, ethereum_builtin, Pricer, Modexp, modexp as me}; use super::{Builtin, Linear, ethereum_builtin, Pricer, ModexpPricer, modexp as me};
use ethjson; use ethjson;
use bigint::prelude::U256; use bigint::prelude::U256;
use util::BytesRef; use bytes::BytesRef;
use rustc_hex::FromHex; use rustc_hex::FromHex;
use num::{BigUint, Zero, One}; use num::{BigUint, Zero, One};
@ -662,7 +703,7 @@ mod tests {
fn modexp() { fn modexp() {
let f = Builtin { let f = Builtin {
pricer: Box::new(Modexp { divisor: 20 }), pricer: Box::new(ModexpPricer { divisor: 20 }),
native: ethereum_builtin("modexp"), native: ethereum_builtin("modexp"),
activate_at: 0, activate_at: 0,
}; };
@ -679,7 +720,7 @@ mod tests {
let mut output = vec![0u8; 32]; let mut output = vec![0u8; 32];
let expected = FromHex::from_hex("0000000000000000000000000000000000000000000000000000000000000001").unwrap(); let expected = FromHex::from_hex("0000000000000000000000000000000000000000000000000000000000000001").unwrap();
let expected_cost = 1638; let expected_cost = 13056;
f.execute(&input[..], &mut BytesRef::Fixed(&mut output[..])).expect("Builtin should not fail"); f.execute(&input[..], &mut BytesRef::Fixed(&mut output[..])).expect("Builtin should not fail");
assert_eq!(output, expected); assert_eq!(output, expected);
@ -690,15 +731,15 @@ mod tests {
{ {
let input = FromHex::from_hex("\ let input = FromHex::from_hex("\
0000000000000000000000000000000000000000000000000000000000000000\ 0000000000000000000000000000000000000000000000000000000000000000\
0000000000000000000000000000000000000000000000000000000000000020\ 0000000000000000000000000000000000000000000000000000000000000020\
0000000000000000000000000000000000000000000000000000000000000020\ 0000000000000000000000000000000000000000000000000000000000000020\
fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2e\ fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2e\
fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f" fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f"
).unwrap(); ).unwrap();
let mut output = vec![0u8; 32]; let mut output = vec![0u8; 32];
let expected = FromHex::from_hex("0000000000000000000000000000000000000000000000000000000000000000").unwrap(); let expected = FromHex::from_hex("0000000000000000000000000000000000000000000000000000000000000000").unwrap();
let expected_cost = 1638; let expected_cost = 13056;
f.execute(&input[..], &mut BytesRef::Fixed(&mut output[..])).expect("Builtin should not fail"); f.execute(&input[..], &mut BytesRef::Fixed(&mut output[..])).expect("Builtin should not fail");
assert_eq!(output, expected); assert_eq!(output, expected);
@ -718,7 +759,7 @@ mod tests {
let mut output = vec![0u8; 32]; let mut output = vec![0u8; 32];
let expected = FromHex::from_hex("3b01b01ac41f2d6e917c6d6a221ce793802469026d9ab7578fa2e79e4da6aaab").unwrap(); let expected = FromHex::from_hex("3b01b01ac41f2d6e917c6d6a221ce793802469026d9ab7578fa2e79e4da6aaab").unwrap();
let expected_cost = 102; let expected_cost = 768;
f.execute(&input[..], &mut BytesRef::Fixed(&mut output[..])).expect("Builtin should not fail"); f.execute(&input[..], &mut BytesRef::Fixed(&mut output[..])).expect("Builtin should not fail");
assert_eq!(output, expected); assert_eq!(output, expected);
@ -749,7 +790,7 @@ mod tests {
let f = Builtin { let f = Builtin {
pricer: Box::new(Linear { base: 0, word: 0 }), pricer: Box::new(Linear { base: 0, word: 0 }),
native: ethereum_builtin("bn128_add"), native: ethereum_builtin("alt_bn128_add"),
activate_at: 0, activate_at: 0,
}; };
@ -810,7 +851,7 @@ mod tests {
let f = Builtin { let f = Builtin {
pricer: Box::new(Linear { base: 0, word: 0 }), pricer: Box::new(Linear { base: 0, word: 0 }),
native: ethereum_builtin("bn128_mul"), native: ethereum_builtin("alt_bn128_mul"),
activate_at: 0, activate_at: 0,
}; };
@ -850,7 +891,7 @@ mod tests {
fn builtin_pairing() -> Builtin { fn builtin_pairing() -> Builtin {
Builtin { Builtin {
pricer: Box::new(Linear { base: 0, word: 0 }), pricer: Box::new(Linear { base: 0, word: 0 }),
native: ethereum_builtin("bn128_pairing"), native: ethereum_builtin("alt_bn128_pairing"),
activate_at: 0, activate_at: 0,
} }
} }

View File

@ -16,7 +16,7 @@
use ipc::IpcConfig; use ipc::IpcConfig;
use bigint::hash::H256; use bigint::hash::H256;
use util::Bytes; use bytes::Bytes;
/// Represents what has to be handled by actor listening to chain events /// Represents what has to be handled by actor listening to chain events
#[ipc] #[ipc]

View File

@ -25,11 +25,10 @@ use itertools::Itertools;
// util // util
use hash::keccak; use hash::keccak;
use timer::PerfTimer; use timer::PerfTimer;
use util::UtilError; use bytes::Bytes;
use util::Bytes; use util::{journaldb, DBValue};
use util::{journaldb, DBValue, TrieFactory, Trie}; use util::{Address, UtilError};
use util::Address; use trie::{TrieSpec, TrieFactory, Trie};
use util::trie::TrieSpec;
use util::kvdb::*; use util::kvdb::*;
// other // other
@ -2141,11 +2140,13 @@ mod tests {
}]; }];
let receipts = vec![Receipt { let receipts = vec![Receipt {
state_root: state_root, state_root: state_root,
status_code: None,
gas_used: 5.into(), gas_used: 5.into(),
log_bloom: Default::default(), log_bloom: Default::default(),
logs: vec![logs[0].clone()], logs: vec![logs[0].clone()],
}, Receipt { }, Receipt {
state_root: state_root, state_root: state_root,
status_code: None,
gas_used: gas_used, gas_used: gas_used,
log_bloom: Default::default(), log_bloom: Default::default(),
logs: logs.clone(), logs: logs.clone(),

View File

@ -17,7 +17,7 @@
use util::UtilError; use util::UtilError;
use std::fmt::{Display, Formatter, Error as FmtError}; use std::fmt::{Display, Formatter, Error as FmtError};
use util::trie::TrieError; use trie::TrieError;
/// Client configuration errors. /// Client configuration errors.
#[derive(Debug)] #[derive(Debug)]

View File

@ -20,18 +20,20 @@ use std::fmt;
use std::sync::Arc; use std::sync::Arc;
use bigint::prelude::U256; use bigint::prelude::U256;
use bigint::hash::H256; use bigint::hash::H256;
use util::{self, journaldb, trie}; use util::journaldb;
use trie;
use bytes;
use util::kvdb::{self, KeyValueDB}; use util::kvdb::{self, KeyValueDB};
use {state, state_db, client, executive, trace, transaction, db, spec, pod_state}; use {state, state_db, client, executive, trace, transaction, db, spec, pod_state};
use factory::Factories; use factory::Factories;
use evm::{self, VMType}; use evm::{self, VMType, FinalizationResult};
use vm::{self, ActionParams}; use vm::{self, ActionParams};
/// EVM test Error. /// EVM test Error.
#[derive(Debug)] #[derive(Debug)]
pub enum EvmTestError { pub enum EvmTestError {
/// Trie integrity error. /// Trie integrity error.
Trie(util::TrieError), Trie(trie::TrieError),
/// EVM error. /// EVM error.
Evm(vm::Error), Evm(vm::Error),
/// Initialization error. /// Initialization error.
@ -70,7 +72,8 @@ lazy_static! {
pub static ref HOMESTEAD: spec::Spec = ethereum::new_homestead_test(); pub static ref HOMESTEAD: spec::Spec = ethereum::new_homestead_test();
pub static ref EIP150: spec::Spec = ethereum::new_eip150_test(); pub static ref EIP150: spec::Spec = ethereum::new_eip150_test();
pub static ref EIP161: spec::Spec = ethereum::new_eip161_test(); pub static ref EIP161: spec::Spec = ethereum::new_eip161_test();
pub static ref _METROPOLIS: spec::Spec = ethereum::new_metropolis_test(); pub static ref BYZANTIUM: spec::Spec = ethereum::new_byzantium_test();
pub static ref BYZANTIUM_TRANSITION: spec::Spec = ethereum::new_transition_test();
} }
/// Simplified, single-block EVM test client. /// Simplified, single-block EVM test client.
@ -87,7 +90,10 @@ impl<'a> EvmTestClient<'a> {
ForkSpec::Homestead => Some(&*HOMESTEAD), ForkSpec::Homestead => Some(&*HOMESTEAD),
ForkSpec::EIP150 => Some(&*EIP150), ForkSpec::EIP150 => Some(&*EIP150),
ForkSpec::EIP158 => Some(&*EIP161), ForkSpec::EIP158 => Some(&*EIP161),
ForkSpec::Metropolis | ForkSpec::Byzantium | ForkSpec::Constantinople => None, ForkSpec::Byzantium => Some(&*BYZANTIUM),
ForkSpec::EIP158ToByzantiumAt5 => Some(&BYZANTIUM_TRANSITION),
ForkSpec::FrontierToHomesteadAt5 | ForkSpec::HomesteadToDaoAt5 | ForkSpec::HomesteadToEIP150At5 => None,
_ => None,
} }
} }
@ -160,7 +166,7 @@ impl<'a> EvmTestClient<'a> {
/// Execute the VM given ActionParams and tracer. /// Execute the VM given ActionParams and tracer.
/// Returns amount of gas left and the output. /// Returns amount of gas left and the output.
pub fn call<T: trace::VMTracer>(&mut self, params: ActionParams, vm_tracer: &mut T) pub fn call<T: trace::VMTracer>(&mut self, params: ActionParams, vm_tracer: &mut T)
-> Result<(U256, Vec<u8>), EvmTestError> -> Result<FinalizationResult, EvmTestError>
{ {
let genesis = self.spec.genesis_header(); let genesis = self.spec.genesis_header();
let info = client::EnvInfo { let info = client::EnvInfo {
@ -176,15 +182,13 @@ impl<'a> EvmTestClient<'a> {
let mut tracer = trace::NoopTracer; let mut tracer = trace::NoopTracer;
let mut output = vec![]; let mut output = vec![];
let mut executive = executive::Executive::new(&mut self.state, &info, &*self.spec.engine); let mut executive = executive::Executive::new(&mut self.state, &info, &*self.spec.engine);
let (gas_left, _) = executive.call( executive.call(
params, params,
&mut substate, &mut substate,
util::BytesRef::Flexible(&mut output), bytes::BytesRef::Flexible(&mut output),
&mut tracer, &mut tracer,
vm_tracer, vm_tracer,
).map_err(EvmTestError::Evm)?; ).map_err(EvmTestError::Evm)
Ok((gas_left, output))
} }
/// Executes a SignedTransaction within context of the provided state and `EnvInfo`. /// Executes a SignedTransaction within context of the provided state and `EnvInfo`.
@ -210,10 +214,13 @@ impl<'a> EvmTestClient<'a> {
let result = self.state.apply_with_tracing(&env_info, &*self.spec.engine, &transaction, tracer, vm_tracer); let result = self.state.apply_with_tracing(&env_info, &*self.spec.engine, &transaction, tracer, vm_tracer);
match result { match result {
Ok(result) => TransactResult::Ok { Ok(result) => {
state_root: *self.state.root(), self.state.commit().ok();
gas_left: initial_gas - result.receipt.gas_used, TransactResult::Ok {
output: result.output state_root: *self.state.root(),
gas_left: initial_gas - result.receipt.gas_used,
output: result.output
}
}, },
Err(error) => TransactResult::Err { Err(error) => TransactResult::Err {
state_root: *self.state.root(), state_root: *self.state.root(),

View File

@ -27,6 +27,7 @@ use bigint::prelude::U256;
use bigint::hash::H256; use bigint::hash::H256;
use parking_lot::RwLock; use parking_lot::RwLock;
use util::*; use util::*;
use bytes::Bytes;
use rlp::*; use rlp::*;
use ethkey::{Generator, Random}; use ethkey::{Generator, Random};
use devtools::*; use devtools::*;
@ -618,6 +619,7 @@ impl BlockChainClient for TestBlockChainClient {
if *hash > H256::from("f000000000000000000000000000000000000000000000000000000000000000") { if *hash > H256::from("f000000000000000000000000000000000000000000000000000000000000000") {
let receipt = BlockReceipts::new(vec![Receipt::new( let receipt = BlockReceipts::new(vec![Receipt::new(
Some(H256::zero()), Some(H256::zero()),
None,
U256::zero(), U256::zero(),
vec![])]); vec![])]);
let mut rlp = RlpStream::new(); let mut rlp = RlpStream::new();

View File

@ -36,8 +36,9 @@ use verification::queue::QueueInfo as BlockQueueInfo;
use bigint::prelude::U256; use bigint::prelude::U256;
use bigint::hash::H256; use bigint::hash::H256;
use util::{Address, Bytes}; use util::Address;
use util::hashdb::DBValue; use bytes::Bytes;
use hashdb::DBValue;
use types::ids::*; use types::ids::*;
use types::basic_account::BasicAccount; use types::basic_account::BasicAccount;

View File

@ -48,6 +48,7 @@ use semantic_version::SemanticVersion;
use parking_lot::{Mutex, RwLock}; use parking_lot::{Mutex, RwLock};
use unexpected::{Mismatch, OutOfBounds}; use unexpected::{Mismatch, OutOfBounds};
use util::*; use util::*;
use bytes::Bytes;
mod finality; mod finality;

View File

@ -59,10 +59,11 @@ use bigint::hash::H256;
use semantic_version::SemanticVersion; use semantic_version::SemanticVersion;
use util::*; use util::*;
use unexpected::{Mismatch, OutOfBounds}; use unexpected::{Mismatch, OutOfBounds};
use bytes::Bytes;
/// Default EIP-210 contrat code. /// Default EIP-210 contrat code.
/// As defined in https://github.com/ethereum/EIPs/pull/210/commits/9df24a3714af42e3bf350265bdc75b486c909d7f#diff-e02a92c2fb96c1a1bfb05e4c6e2ef5daR49 /// As defined in https://github.com/ethereum/EIPs/pull/210
pub const DEFAULT_BLOCKHASH_CONTRACT: &'static str = "73fffffffffffffffffffffffffffffffffffffffe33141561007a57600143036020526000356101006020510755600061010060205107141561005057600035610100610100602051050761010001555b6000620100006020510714156100755760003561010062010000602051050761020001555b610161565b436000351215801561008c5780610095565b623567e0600035125b9050156100a757600060605260206060f35b610100600035430312156100ca57610100600035075460805260206080f3610160565b62010000600035430312156100e857600061010060003507146100eb565b60005b1561010d576101006101006000350507610100015460a052602060a0f361015f565b63010000006000354303121561012d576000620100006000350714610130565b60005b1561015357610100620100006000350507610200015460c052602060c0f361015e565b600060e052602060e0f35b5b5b5b5b"; pub const DEFAULT_BLOCKHASH_CONTRACT: &'static str = "73fffffffffffffffffffffffffffffffffffffffe33141561006a5760014303600035610100820755610100810715156100455760003561010061010083050761010001555b6201000081071515610064576000356101006201000083050761020001555b5061013e565b4360003512151561008457600060405260206040f361013d565b61010060003543031315156100a857610100600035075460605260206060f361013c565b6101006000350715156100c55762010000600035430313156100c8565b60005b156100ea576101006101006000350507610100015460805260206080f361013b565b620100006000350715156101095763010000006000354303131561010c565b60005b1561012f57610100620100006000350507610200015460a052602060a0f361013a565b600060c052602060c0f35b5b5b5b5b";
/// Voting errors. /// Voting errors.
#[derive(Debug)] #[derive(Debug)]
@ -420,6 +421,7 @@ pub mod common {
use bigint::prelude::U256; use bigint::prelude::U256;
use bigint::hash::H256; use bigint::hash::H256;
use util::*; use util::*;
use bytes::{Bytes, BytesRef};
use super::Engine; use super::Engine;
/// Execute a call as the system address. /// Execute a call as the system address.

View File

@ -20,6 +20,7 @@ use std::cmp;
use hash::keccak; use hash::keccak;
use bigint::hash::{H256, H520}; use bigint::hash::{H256, H520};
use util::*; use util::*;
use bytes::Bytes;
use super::{Height, View, BlockHash, Step}; use super::{Height, View, BlockHash, Step};
use error::Error; use error::Error;
use header::Header; use header::Header;

View File

@ -36,6 +36,7 @@ use parking_lot::RwLock;
use util::*; use util::*;
use unexpected::{OutOfBounds, Mismatch}; use unexpected::{OutOfBounds, Mismatch};
use client::EngineClient; use client::EngineClient;
use bytes::Bytes;
use error::{Error, BlockError}; use error::{Error, BlockError};
use header::{Header, BlockNumber}; use header::{Header, BlockNumber};
use builtin::Builtin; use builtin::Builtin;
@ -775,6 +776,7 @@ mod tests {
use std::str::FromStr; use std::str::FromStr;
use rustc_hex::FromHex; use rustc_hex::FromHex;
use util::*; use util::*;
use bytes::Bytes;
use block::*; use block::*;
use error::{Error, BlockError}; use error::{Error, BlockError};
use header::Header; use header::Header;

View File

@ -21,6 +21,7 @@ use std::sync::Weak;
use bigint::hash::H256; use bigint::hash::H256;
use parking_lot::RwLock; use parking_lot::RwLock;
use util::*; use util::*;
use bytes::Bytes;
use futures::Future; use futures::Future;
use native_contracts::ValidatorReport as Provider; use native_contracts::ValidatorReport as Provider;
@ -139,6 +140,7 @@ mod tests {
use hash::keccak; use hash::keccak;
use bigint::hash::H520; use bigint::hash::H520;
use util::*; use util::*;
use bytes::ToPretty;
use rlp::encode; use rlp::encode;
use spec::Spec; use spec::Spec;
use header::Header; use header::Header;

View File

@ -26,7 +26,8 @@ mod multi;
use std::sync::Weak; use std::sync::Weak;
use ids::BlockId; use ids::BlockId;
use bigint::hash::H256; use bigint::hash::H256;
use util::{Bytes, Address}; use util::Address;
use bytes::Bytes;
use ethjson::spec::ValidatorSet as ValidatorSpec; use ethjson::spec::ValidatorSet as ValidatorSpec;
use client::EngineClient; use client::EngineClient;
use header::{Header, BlockNumber}; use header::{Header, BlockNumber};

View File

@ -21,7 +21,8 @@ use std::sync::Weak;
use engines::{Call, Engine}; use engines::{Call, Engine};
use bigint::hash::H256; use bigint::hash::H256;
use parking_lot::RwLock; use parking_lot::RwLock;
use util::{Bytes, Address}; use util::Address;
use bytes::Bytes;
use ids::BlockId; use ids::BlockId;
use header::{BlockNumber, Header}; use header::{BlockNumber, Header};
use client::EngineClient; use client::EngineClient;

View File

@ -26,6 +26,7 @@ use bigint::hash::{H160, H256};
use parking_lot::{Mutex, RwLock}; use parking_lot::{Mutex, RwLock};
use util::*; use util::*;
use bytes::Bytes;
use util::cache::MemoryLruCache; use util::cache::MemoryLruCache;
use unexpected::Mismatch; use unexpected::Mismatch;
use rlp::{UntrustedRlp, RlpStream}; use rlp::{UntrustedRlp, RlpStream};

View File

@ -21,7 +21,8 @@ use std::sync::Arc;
use std::sync::atomic::{AtomicUsize, Ordering as AtomicOrdering}; use std::sync::atomic::{AtomicUsize, Ordering as AtomicOrdering};
use heapsize::HeapSizeOf; use heapsize::HeapSizeOf;
use bigint::hash::H256; use bigint::hash::H256;
use util::{Bytes, Address}; use util::Address;
use bytes::Bytes;
use engines::{Call, Engine}; use engines::{Call, Engine};
use header::{Header, BlockNumber}; use header::{Header, BlockNumber};

View File

@ -22,6 +22,7 @@ use std::hash::Hash;
use bigint::hash::{H256, H520}; use bigint::hash::{H256, H520};
use parking_lot:: RwLock; use parking_lot:: RwLock;
use util::*; use util::*;
use bytes::Bytes;
use rlp::{Encodable, RlpStream}; use rlp::{Encodable, RlpStream};
pub trait Message: Clone + PartialEq + Eq + Hash + Encodable + Debug { pub trait Message: Clone + PartialEq + Eq + Hash + Encodable + Debug {

View File

@ -21,6 +21,7 @@ use bigint::prelude::U256;
use bigint::hash::H256; use bigint::hash::H256;
use util::*; use util::*;
use unexpected::{Mismatch, OutOfBounds}; use unexpected::{Mismatch, OutOfBounds};
use trie::TrieError;
use io::*; use io::*;
use header::BlockNumber; use header::BlockNumber;
use basic_types::LogBloom; use basic_types::LogBloom;

View File

@ -51,6 +51,7 @@ const SNAPSHOT_BLOCKS: u64 = 5000;
/// Maximum number of blocks allowed in an ethash snapshot. /// Maximum number of blocks allowed in an ethash snapshot.
const MAX_SNAPSHOT_BLOCKS: u64 = 30000; const MAX_SNAPSHOT_BLOCKS: u64 = 30000;
const DEFAULT_EIP649_DELAY: u64 = 3_000_000;
/// Ethash params. /// Ethash params.
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
@ -105,6 +106,12 @@ pub struct EthashParams {
pub min_gas_price_transition: u64, pub min_gas_price_transition: u64,
/// Do not alow transactions with lower gas price. /// Do not alow transactions with lower gas price.
pub min_gas_price: U256, pub min_gas_price: U256,
/// EIP-649 transition block.
pub eip649_transition: u64,
/// EIP-649 bomb delay.
pub eip649_delay: u64,
/// EIP-649 base reward.
pub eip649_reward: Option<U256>,
} }
impl From<ethjson::spec::EthashParams> for EthashParams { impl From<ethjson::spec::EthashParams> for EthashParams {
@ -135,6 +142,9 @@ impl From<ethjson::spec::EthashParams> for EthashParams {
max_gas_limit: p.max_gas_limit.map_or(U256::max_value(), Into::into), max_gas_limit: p.max_gas_limit.map_or(U256::max_value(), Into::into),
min_gas_price_transition: p.min_gas_price_transition.map_or(u64::max_value(), Into::into), min_gas_price_transition: p.min_gas_price_transition.map_or(u64::max_value(), Into::into),
min_gas_price: p.min_gas_price.map_or(U256::zero(), Into::into), min_gas_price: p.min_gas_price.map_or(U256::zero(), Into::into),
eip649_transition: p.eip649_transition.map_or(u64::max_value(), Into::into),
eip649_delay: p.eip649_delay.map_or(DEFAULT_EIP649_DELAY, Into::into),
eip649_reward: p.eip649_reward.map(Into::into),
} }
} }
} }
@ -215,8 +225,10 @@ impl Engine for Arc<Ethash> {
} else if block_number < self.ethash_params.eip150_transition { } else if block_number < self.ethash_params.eip150_transition {
Schedule::new_homestead() Schedule::new_homestead()
} else { } else {
/// There's no max_code_size transition so we tie it to eip161abc
let max_code_size = if block_number >= self.ethash_params.eip161abc_transition { self.ethash_params.max_code_size as usize } else { usize::max_value() };
let mut schedule = Schedule::new_post_eip150( let mut schedule = Schedule::new_post_eip150(
self.ethash_params.max_code_size as usize, max_code_size,
block_number >= self.ethash_params.eip160_transition, block_number >= self.ethash_params.eip160_transition,
block_number >= self.ethash_params.eip161abc_transition, block_number >= self.ethash_params.eip161abc_transition,
block_number >= self.ethash_params.eip161d_transition); block_number >= self.ethash_params.eip161d_transition);
@ -296,9 +308,14 @@ impl Engine for Arc<Ethash> {
/// This assumes that all uncles are valid uncles (i.e. of at least one generation before the current). /// This assumes that all uncles are valid uncles (i.e. of at least one generation before the current).
fn on_close_block(&self, block: &mut ExecutedBlock) -> Result<(), Error> { fn on_close_block(&self, block: &mut ExecutedBlock) -> Result<(), Error> {
use std::ops::Shr; use std::ops::Shr;
let reward = self.params().block_reward;
let tracing_enabled = block.tracing_enabled(); let tracing_enabled = block.tracing_enabled();
let fields = block.fields_mut(); let fields = block.fields_mut();
let reward = if fields.header.number() >= self.ethash_params.eip649_transition {
self.ethash_params.eip649_reward.unwrap_or(self.params().block_reward)
} else {
self.params().block_reward
};
let eras_rounds = self.ethash_params.ecip1017_era_rounds; let eras_rounds = self.ethash_params.ecip1017_era_rounds;
let (eras, reward) = ecip1017_eras_block_reward(eras_rounds, reward, fields.header.number()); let (eras, reward) = ecip1017_eras_block_reward(eras_rounds, reward, fields.header.number());
let mut tracer = ExecutiveTracer::default(); let mut tracer = ExecutiveTracer::default();
@ -500,7 +517,7 @@ fn ecip1017_eras_block_reward(era_rounds: u64, mut reward: U256, block_number:u6
#[cfg_attr(feature="dev", allow(wrong_self_convention))] #[cfg_attr(feature="dev", allow(wrong_self_convention))]
impl Ethash { impl Ethash {
fn calculate_difficulty(&self, header: &Header, parent: &Header) -> U256 { fn calculate_difficulty(&self, header: &Header, parent: &Header) -> U256 {
const EXP_DIFF_PERIOD: u64 = 100000; const EXP_DIFF_PERIOD: u64 = 100_000;
if header.number() == 0 { if header.number() == 0 {
panic!("Can't calculate genesis block difficulty"); panic!("Can't calculate genesis block difficulty");
} }
@ -550,7 +567,11 @@ impl Ethash {
target = cmp::max(min_difficulty, target); target = cmp::max(min_difficulty, target);
if header.number() < self.ethash_params.bomb_defuse_transition { if header.number() < self.ethash_params.bomb_defuse_transition {
if header.number() < self.ethash_params.ecip1010_pause_transition { if header.number() < self.ethash_params.ecip1010_pause_transition {
let period = ((parent.number() + 1) / EXP_DIFF_PERIOD) as usize; let mut number = header.number();
if number >= self.ethash_params.eip649_transition {
number = number.saturating_sub(self.ethash_params.eip649_delay);
}
let period = (number / EXP_DIFF_PERIOD) as usize;
if period > 1 { if period > 1 {
target = cmp::max(min_difficulty, target + (U256::from(1) << (period - 2))); target = cmp::max(min_difficulty, target + (U256::from(1) << (period - 2)));
} }

View File

@ -87,8 +87,11 @@ pub fn new_transition_test() -> Spec { load(None, include_bytes!("../../res/ethe
/// Create a new Foundation Mainnet chain spec without genesis accounts. /// Create a new Foundation Mainnet chain spec without genesis accounts.
pub fn new_mainnet_like() -> Spec { load(None, include_bytes!("../../res/ethereum/frontier_like_test.json")) } pub fn new_mainnet_like() -> Spec { load(None, include_bytes!("../../res/ethereum/frontier_like_test.json")) }
/// Create a new Foundation Metropolis era spec. /// Create a new Foundation Byzantium era spec.
pub fn new_metropolis_test() -> Spec { load(None, include_bytes!("../../res/ethereum/metropolis_test.json")) } pub fn new_byzantium_test() -> Spec { load(None, include_bytes!("../../res/ethereum/byzantium_test.json")) }
/// Create a new Foundation Constantinople era spec.
pub fn new_constantinople_test() -> Spec { load(None, include_bytes!("../../res/ethereum/constantinople_test.json")) }
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {

View File

@ -17,7 +17,9 @@
//! Transaction execution format module. //! Transaction execution format module.
use bigint::prelude::{U256, U512}; use bigint::prelude::{U256, U512};
use util::{Bytes, Address, trie}; use util::Address;
use bytes::Bytes;
use trie;
use vm; use vm;
use trace::{VMTrace, FlatTrace}; use trace::{VMTrace, FlatTrace};
use log_entry::LogEntry; use log_entry::LogEntry;

View File

@ -21,6 +21,7 @@ use hash::keccak;
use bigint::prelude::{U256, U512}; use bigint::prelude::{U256, U512};
use bigint::hash::H256; use bigint::hash::H256;
use util::*; use util::*;
use bytes::{Bytes, BytesRef};
use state::{Backend as StateBackend, State, Substate, CleanupMode}; use state::{Backend as StateBackend, State, Substate, CleanupMode};
use engines::Engine; use engines::Engine;
use vm::EnvInfo; use vm::EnvInfo;
@ -290,7 +291,7 @@ impl<'a, B: 'a + StateBackend, E: Engine + ?Sized> Executive<'a, B, E> {
let mut substate = Substate::new(); let mut substate = Substate::new();
// NOTE: there can be no invalid transactions from this point. // NOTE: there can be no invalid transactions from this point.
if !t.is_unsigned() { if !schedule.eip86 || !t.is_unsigned() {
self.state.inc_nonce(&sender)?; self.state.inc_nonce(&sender)?;
} }
self.state.sub_balance(&sender, &U256::from(gas_cost), &mut substate.to_cleanup_mode(&schedule))?; self.state.sub_balance(&sender, &U256::from(gas_cost), &mut substate.to_cleanup_mode(&schedule))?;
@ -382,12 +383,12 @@ impl<'a, B: 'a + StateBackend, E: Engine + ?Sized> Executive<'a, B, E> {
mut output: BytesRef, mut output: BytesRef,
tracer: &mut T, tracer: &mut T,
vm_tracer: &mut V vm_tracer: &mut V
) -> vm::Result<(U256, ReturnData)> where T: Tracer, V: VMTracer { ) -> vm::Result<FinalizationResult> where T: Tracer, V: VMTracer {
trace!("Executive::call(params={:?}) self.env_info={:?}", params, self.info); trace!("Executive::call(params={:?}) self.env_info={:?}, static={}", params, self.info, self.static_flag);
if (params.call_type == CallType::StaticCall || if (params.call_type == CallType::StaticCall ||
((params.call_type == CallType::Call || params.call_type == CallType::DelegateCall) && ((params.call_type == CallType::Call) &&
self.static_flag)) self.static_flag))
&& params.value.value() > 0.into() { && params.value.value() > 0.into() {
return Err(vm::Error::MutableCallInStaticContext); return Err(vm::Error::MutableCallInStaticContext);
} }
@ -440,7 +441,11 @@ impl<'a, B: 'a + StateBackend, E: Engine + ?Sized> Executive<'a, B, E> {
); );
} }
Ok((params.gas - cost, ReturnData::empty())) Ok(FinalizationResult {
gas_left: params.gas - cost,
return_data: ReturnData::new(output.to_owned(), 0, output.len()),
apply_state: true,
})
} }
} else { } else {
// just drain the whole gas // just drain the whole gas
@ -487,13 +492,17 @@ impl<'a, B: 'a + StateBackend, E: Engine + ?Sized> Executive<'a, B, E> {
self.enact_result(&res, substate, unconfirmed_substate); self.enact_result(&res, substate, unconfirmed_substate);
trace!(target: "executive", "enacted: substate={:?}\n", substate); trace!(target: "executive", "enacted: substate={:?}\n", substate);
res.map(|r| (r.gas_left, r.return_data)) res
} else { } else {
// otherwise it's just a basic transaction, only do tracing, if necessary. // otherwise it's just a basic transaction, only do tracing, if necessary.
self.state.discard_checkpoint(); self.state.discard_checkpoint();
tracer.trace_call(trace_info, U256::zero(), trace_output, vec![]); tracer.trace_call(trace_info, U256::zero(), trace_output, vec![]);
Ok((params.gas, ReturnData::empty())) Ok(FinalizationResult {
gas_left: params.gas,
return_data: ReturnData::empty(),
apply_state: true,
})
} }
} }
} }
@ -508,13 +517,18 @@ impl<'a, B: 'a + StateBackend, E: Engine + ?Sized> Executive<'a, B, E> {
output: &mut Option<Bytes>, output: &mut Option<Bytes>,
tracer: &mut T, tracer: &mut T,
vm_tracer: &mut V, vm_tracer: &mut V,
) -> vm::Result<(U256, ReturnData)> where T: Tracer, V: VMTracer { ) -> vm::Result<FinalizationResult> where T: Tracer, V: VMTracer {
let scheme = self.engine.create_address_scheme(self.info.number); // EIP-684: If a contract creation is attempted, due to either a creation transaction or the
if scheme != CreateContractAddress::FromSenderAndNonce && self.state.exists_and_has_code(&params.address)? { // CREATE (or future CREATE2) opcode, and the destination address already has either
// nonzero nonce, or nonempty code, then the creation throws immediately, with exactly
// the same behavior as would arise if the first byte in the init code were an invalid
// opcode. This applies retroactively starting from genesis.
if self.state.exists_and_has_code_or_nonce(&params.address)? {
return Err(vm::Error::OutOfGas); return Err(vm::Error::OutOfGas);
} }
trace!("Executive::create(params={:?}) self.env_info={:?}, static={}", params, self.info, self.static_flag);
if params.call_type == CallType::StaticCall || self.static_flag { if params.call_type == CallType::StaticCall || self.static_flag {
let trace_info = tracer.prepare_trace_create(&params); let trace_info = tracer.prepare_trace_create(&params);
tracer.trace_failed_create(trace_info, vec![], vm::Error::MutableCallInStaticContext.into()); tracer.trace_failed_create(trace_info, vec![], vm::Error::MutableCallInStaticContext.into());
@ -564,7 +578,7 @@ impl<'a, B: 'a + StateBackend, E: Engine + ?Sized> Executive<'a, B, E> {
}; };
self.enact_result(&res, substate, unconfirmed_substate); self.enact_result(&res, substate, unconfirmed_substate);
res.map(|r| (r.gas_left, r.return_data)) res
} }
/// Finalizes the transaction (does refunds and suicides). /// Finalizes the transaction (does refunds and suicides).
@ -572,7 +586,7 @@ impl<'a, B: 'a + StateBackend, E: Engine + ?Sized> Executive<'a, B, E> {
&mut self, &mut self,
t: &SignedTransaction, t: &SignedTransaction,
mut substate: Substate, mut substate: Substate,
result: vm::Result<(U256, ReturnData)>, result: vm::Result<FinalizationResult>,
output: Bytes, output: Bytes,
trace: Vec<FlatTrace>, trace: Vec<FlatTrace>,
vm_trace: Option<VMTrace> vm_trace: Option<VMTrace>
@ -586,7 +600,7 @@ impl<'a, B: 'a + StateBackend, E: Engine + ?Sized> Executive<'a, B, E> {
let refunds_bound = sstore_refunds + suicide_refunds; let refunds_bound = sstore_refunds + suicide_refunds;
// real ammount to refund // real ammount to refund
let gas_left_prerefund = match result { Ok((x, _)) => x, _ => 0.into() }; let gas_left_prerefund = match result { Ok(FinalizationResult{ gas_left, .. }) => gas_left, _ => 0.into() };
let refunded = cmp::min(refunds_bound, (t.gas - gas_left_prerefund) >> 1); let refunded = cmp::min(refunds_bound, (t.gas - gas_left_prerefund) >> 1);
let gas_left = gas_left_prerefund + refunded; let gas_left = gas_left_prerefund + refunded;
@ -630,9 +644,9 @@ impl<'a, B: 'a + StateBackend, E: Engine + ?Sized> Executive<'a, B, E> {
state_diff: None, state_diff: None,
}) })
}, },
_ => { Ok(r) => {
Ok(Executed { Ok(Executed {
exception: None, exception: if r.apply_state { None } else { Some(vm::Error::Reverted) },
gas: t.gas, gas: t.gas,
gas_used: gas_used, gas_used: gas_used,
refunded: refunded, refunded: refunded,
@ -658,6 +672,8 @@ impl<'a, B: 'a + StateBackend, E: Engine + ?Sized> Executive<'a, B, E> {
| Err(vm::Error::Wasm {..}) | Err(vm::Error::Wasm {..})
| Err(vm::Error::OutOfStack {..}) | Err(vm::Error::OutOfStack {..})
| Err(vm::Error::MutableCallInStaticContext) | Err(vm::Error::MutableCallInStaticContext)
| Err(vm::Error::OutOfBounds)
| Err(vm::Error::Reverted)
| Ok(FinalizationResult { apply_state: false, .. }) => { | Ok(FinalizationResult { apply_state: false, .. }) => {
self.state.revert_to_checkpoint(); self.state.revert_to_checkpoint();
}, },
@ -680,7 +696,7 @@ mod tests {
use bigint::prelude::{U256, U512}; use bigint::prelude::{U256, U512};
use bigint::hash::H256; use bigint::hash::H256;
use util::Address; use util::Address;
use util::bytes::BytesRef; use bytes::BytesRef;
use vm::{ActionParams, ActionValue, CallType, EnvInfo, CreateContractAddress}; use vm::{ActionParams, ActionValue, CallType, EnvInfo, CreateContractAddress};
use evm::{Factory, VMType}; use evm::{Factory, VMType};
use error::ExecutionError; use error::ExecutionError;
@ -715,7 +731,7 @@ mod tests {
let engine = TestEngine::new(0); let engine = TestEngine::new(0);
let mut substate = Substate::new(); let mut substate = Substate::new();
let (gas_left, _) = { let FinalizationResult { gas_left, .. } = {
let mut ex = Executive::new(&mut state, &info, &engine); let mut ex = Executive::new(&mut state, &info, &engine);
ex.create(params, &mut substate, &mut None, &mut NoopTracer, &mut NoopVMTracer).unwrap() ex.create(params, &mut substate, &mut None, &mut NoopTracer, &mut NoopVMTracer).unwrap()
}; };
@ -773,7 +789,7 @@ mod tests {
let engine = TestEngine::new(0); let engine = TestEngine::new(0);
let mut substate = Substate::new(); let mut substate = Substate::new();
let (gas_left, _) = { let FinalizationResult { gas_left, .. } = {
let mut ex = Executive::new(&mut state, &info, &engine); let mut ex = Executive::new(&mut state, &info, &engine);
ex.create(params, &mut substate, &mut None, &mut NoopTracer, &mut NoopVMTracer).unwrap() ex.create(params, &mut substate, &mut None, &mut NoopTracer, &mut NoopVMTracer).unwrap()
}; };
@ -831,7 +847,7 @@ mod tests {
let mut tracer = ExecutiveTracer::default(); let mut tracer = ExecutiveTracer::default();
let mut vm_tracer = ExecutiveVMTracer::toplevel(); let mut vm_tracer = ExecutiveVMTracer::toplevel();
let (gas_left, _) = { let FinalizationResult { gas_left, .. } = {
let mut ex = Executive::new(&mut state, &info, &engine); let mut ex = Executive::new(&mut state, &info, &engine);
let output = BytesRef::Fixed(&mut[0u8;0]); let output = BytesRef::Fixed(&mut[0u8;0]);
ex.call(params, &mut substate, output, &mut tracer, &mut vm_tracer).unwrap() ex.call(params, &mut substate, output, &mut tracer, &mut vm_tracer).unwrap()
@ -940,7 +956,7 @@ mod tests {
let mut tracer = ExecutiveTracer::default(); let mut tracer = ExecutiveTracer::default();
let mut vm_tracer = ExecutiveVMTracer::toplevel(); let mut vm_tracer = ExecutiveVMTracer::toplevel();
let (gas_left, _) = { let FinalizationResult { gas_left, .. } = {
let mut ex = Executive::new(&mut state, &info, &engine); let mut ex = Executive::new(&mut state, &info, &engine);
ex.create(params.clone(), &mut substate, &mut None, &mut tracer, &mut vm_tracer).unwrap() ex.create(params.clone(), &mut substate, &mut None, &mut tracer, &mut vm_tracer).unwrap()
}; };
@ -1025,7 +1041,7 @@ mod tests {
let engine = TestEngine::new(0); let engine = TestEngine::new(0);
let mut substate = Substate::new(); let mut substate = Substate::new();
let (gas_left, _) = { let FinalizationResult { gas_left, .. } = {
let mut ex = Executive::new(&mut state, &info, &engine); let mut ex = Executive::new(&mut state, &info, &engine);
ex.create(params, &mut substate, &mut None, &mut NoopTracer, &mut NoopVMTracer).unwrap() ex.create(params, &mut substate, &mut None, &mut NoopTracer, &mut NoopVMTracer).unwrap()
}; };
@ -1136,7 +1152,7 @@ mod tests {
let engine = TestEngine::new(0); let engine = TestEngine::new(0);
let mut substate = Substate::new(); let mut substate = Substate::new();
let (gas_left, _) = { let FinalizationResult { gas_left, .. } = {
let mut ex = Executive::new(&mut state, &info, &engine); let mut ex = Executive::new(&mut state, &info, &engine);
ex.call(params, &mut substate, BytesRef::Fixed(&mut []), &mut NoopTracer, &mut NoopVMTracer).unwrap() ex.call(params, &mut substate, BytesRef::Fixed(&mut []), &mut NoopTracer, &mut NoopVMTracer).unwrap()
}; };
@ -1180,7 +1196,7 @@ mod tests {
let engine = TestEngine::new(0); let engine = TestEngine::new(0);
let mut substate = Substate::new(); let mut substate = Substate::new();
let (gas_left, _) = { let FinalizationResult { gas_left, .. } = {
let mut ex = Executive::new(&mut state, &info, &engine); let mut ex = Executive::new(&mut state, &info, &engine);
ex.call(params, &mut substate, BytesRef::Fixed(&mut []), &mut NoopTracer, &mut NoopVMTracer).unwrap() ex.call(params, &mut substate, BytesRef::Fixed(&mut []), &mut NoopTracer, &mut NoopVMTracer).unwrap()
}; };
@ -1381,11 +1397,11 @@ mod tests {
let mut state = get_temp_state_with_factory(factory); let mut state = get_temp_state_with_factory(factory);
state.add_balance(&sender, &U256::from_str("152d02c7e14af68000000").unwrap(), CleanupMode::NoEmpty).unwrap(); state.add_balance(&sender, &U256::from_str("152d02c7e14af68000000").unwrap(), CleanupMode::NoEmpty).unwrap();
let info = EnvInfo::default(); let info = EnvInfo::default();
let engine = TestEngine::new_metropolis(); let engine = TestEngine::new_byzantium();
let mut substate = Substate::new(); let mut substate = Substate::new();
let mut output = [0u8; 14]; let mut output = [0u8; 14];
let (result, _) = { let FinalizationResult { gas_left: result, .. } = {
let mut ex = Executive::new(&mut state, &info, &engine); let mut ex = Executive::new(&mut state, &info, &engine);
ex.call(params, &mut substate, BytesRef::Fixed(&mut output), &mut NoopTracer, &mut NoopVMTracer).unwrap() ex.call(params, &mut substate, BytesRef::Fixed(&mut output), &mut NoopTracer, &mut NoopVMTracer).unwrap()
}; };

View File

@ -20,6 +20,7 @@ use std::sync::Arc;
use bigint::prelude::U256; use bigint::prelude::U256;
use bigint::hash::H256; use bigint::hash::H256;
use util::*; use util::*;
use bytes::{Bytes, BytesRef};
use state::{Backend as StateBackend, State, Substate, CleanupMode}; use state::{Backend as StateBackend, State, Substate, CleanupMode};
use engines::Engine; use engines::Engine;
use executive::*; use executive::*;
@ -28,6 +29,7 @@ use vm::{
Ext, ContractCreateResult, MessageCallResult, CreateContractAddress, Ext, ContractCreateResult, MessageCallResult, CreateContractAddress,
ReturnData ReturnData
}; };
use evm::FinalizationResult;
use transaction::UNSIGNED_SENDER; use transaction::UNSIGNED_SENDER;
use trace::{Tracer, VMTracer}; use trace::{Tracer, VMTracer};
@ -126,6 +128,10 @@ impl<'a, T: 'a, V: 'a, B: 'a, E: 'a> Ext for Externalities<'a, T, V, B, E>
} }
} }
fn is_static(&self) -> bool {
return self.static_flag
}
fn exists(&self, address: &Address) -> vm::Result<bool> { fn exists(&self, address: &Address) -> vm::Result<bool> {
self.state.exists(address).map_err(Into::into) self.state.exists(address).map_err(Into::into)
} }
@ -215,21 +221,27 @@ impl<'a, T: 'a, V: 'a, B: 'a, E: 'a> Ext for Externalities<'a, T, V, B, E>
call_type: CallType::None, call_type: CallType::None,
}; };
if params.sender != UNSIGNED_SENDER { if !self.static_flag {
if let Err(e) = self.state.inc_nonce(&self.origin_info.address) { if !self.schedule.eip86 || params.sender != UNSIGNED_SENDER {
debug!(target: "ext", "Database corruption encountered: {:?}", e); if let Err(e) = self.state.inc_nonce(&self.origin_info.address) {
return ContractCreateResult::Failed debug!(target: "ext", "Database corruption encountered: {:?}", e);
return ContractCreateResult::Failed
}
} }
} }
let mut ex = Executive::from_parent(self.state, self.env_info, self.engine, self.depth, self.static_flag); let mut ex = Executive::from_parent(self.state, self.env_info, self.engine, self.depth, self.static_flag);
// TODO: handle internal error separately // TODO: handle internal error separately
match ex.create(params, self.substate, &mut None, self.tracer, self.vm_tracer) { match ex.create(params, self.substate, &mut None, self.tracer, self.vm_tracer) {
Ok((gas_left, _)) => { Ok(FinalizationResult{ gas_left, apply_state: true, .. }) => {
self.substate.contracts_created.push(address.clone()); self.substate.contracts_created.push(address.clone());
ContractCreateResult::Created(address, gas_left) ContractCreateResult::Created(address, gas_left)
}, },
_ => ContractCreateResult::Failed Ok(FinalizationResult{ gas_left, apply_state: false, return_data }) => {
ContractCreateResult::Reverted(gas_left, return_data)
},
Err(vm::Error::MutableCallInStaticContext) => ContractCreateResult::FailedInStaticCall,
_ => ContractCreateResult::Failed,
} }
} }
@ -274,7 +286,8 @@ impl<'a, T: 'a, V: 'a, B: 'a, E: 'a> Ext for Externalities<'a, T, V, B, E>
let mut ex = Executive::from_parent(self.state, self.env_info, self.engine, self.depth, self.static_flag); let mut ex = Executive::from_parent(self.state, self.env_info, self.engine, self.depth, self.static_flag);
match ex.call(params, self.substate, BytesRef::Fixed(output), self.tracer, self.vm_tracer) { match ex.call(params, self.substate, BytesRef::Fixed(output), self.tracer, self.vm_tracer) {
Ok((gas_left, return_data)) => MessageCallResult::Success(gas_left, return_data), Ok(FinalizationResult{ gas_left, return_data, apply_state: true }) => MessageCallResult::Success(gas_left, return_data),
Ok(FinalizationResult{ gas_left, return_data, apply_state: false }) => MessageCallResult::Reverted(gas_left, return_data),
_ => MessageCallResult::Failed _ => MessageCallResult::Failed
} }
} }
@ -288,7 +301,7 @@ impl<'a, T: 'a, V: 'a, B: 'a, E: 'a> Ext for Externalities<'a, T, V, B, E>
} }
#[cfg_attr(feature="dev", allow(match_ref_pats))] #[cfg_attr(feature="dev", allow(match_ref_pats))]
fn ret(mut self, gas: &U256, data: &ReturnData) -> vm::Result<U256> fn ret(mut self, gas: &U256, data: &ReturnData, apply_state: bool) -> vm::Result<U256>
where Self: Sized { where Self: Sized {
let handle_copy = |to: &mut Option<&mut Bytes>| { let handle_copy = |to: &mut Option<&mut Bytes>| {
to.as_mut().map(|b| **b = data.to_vec()); to.as_mut().map(|b| **b = data.to_vec());
@ -308,7 +321,7 @@ impl<'a, T: 'a, V: 'a, B: 'a, E: 'a> Ext for Externalities<'a, T, V, B, E>
vec.extend_from_slice(&*data); vec.extend_from_slice(&*data);
Ok(*gas) Ok(*gas)
}, },
OutputPolicy::InitContract(ref mut copy) => { OutputPolicy::InitContract(ref mut copy) if apply_state => {
let return_cost = U256::from(data.len()) * U256::from(self.schedule.create_data_gas); let return_cost = U256::from(data.len()) * U256::from(self.schedule.create_data_gas);
if return_cost > *gas || data.len() > self.schedule.create_data_limit { if return_cost > *gas || data.len() > self.schedule.create_data_limit {
return match self.schedule.exceptional_failed_code_deposit { return match self.schedule.exceptional_failed_code_deposit {
@ -316,12 +329,13 @@ impl<'a, T: 'a, V: 'a, B: 'a, E: 'a> Ext for Externalities<'a, T, V, B, E>
false => Ok(*gas) false => Ok(*gas)
} }
} }
handle_copy(copy); handle_copy(copy);
self.state.init_code(&self.origin_info.address, data.to_vec())?; self.state.init_code(&self.origin_info.address, data.to_vec())?;
Ok(*gas - return_cost) Ok(*gas - return_cost)
} },
OutputPolicy::InitContract(_) => {
Ok(*gas)
},
} }
} }

View File

@ -14,7 +14,7 @@
// 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/>.
use util::trie::TrieFactory; use trie::TrieFactory;
use evm::Factory as EvmFactory; use evm::Factory as EvmFactory;
use account_db::Factory as AccountFactory; use account_db::Factory as AccountFactory;

View File

@ -23,6 +23,7 @@ use heapsize::HeapSizeOf;
use bigint::prelude::U256; use bigint::prelude::U256;
use bigint::hash::H256; use bigint::hash::H256;
use util::*; use util::*;
use bytes::Bytes;
use basic_types::{LogBloom, ZERO_LOGBLOOM}; use basic_types::{LogBloom, ZERO_LOGBLOOM};
use time::get_time; use time::get_time;
use rlp::*; use rlp::*;

View File

@ -15,16 +15,14 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
use std::sync::Arc; use std::sync::Arc;
use client::{BlockChainClient, Client, ClientConfig}; use client::{EvmTestClient, BlockChainClient, Client, ClientConfig};
use block::Block; use block::Block;
use ethereum;
use tests::helpers::*;
use spec::Genesis; use spec::Genesis;
use ethjson; use ethjson;
use miner::Miner; use miner::Miner;
use io::IoChannel; use io::IoChannel;
pub fn json_chain_test(json_data: &[u8], era: ChainEra) -> Vec<String> { pub fn json_chain_test(json_data: &[u8]) -> Vec<String> {
::ethcore_logger::init_log(); ::ethcore_logger::init_log();
let tests = ethjson::blockchain::Test::load(json_data).unwrap(); let tests = ethjson::blockchain::Test::load(json_data).unwrap();
let mut failed = Vec::new(); let mut failed = Vec::new();
@ -42,15 +40,16 @@ pub fn json_chain_test(json_data: &[u8], era: ChainEra) -> Vec<String> {
flush!(" - {}...", name); flush!(" - {}...", name);
let spec = { let spec = {
let mut spec = match EvmTestClient::spec_from_json(&blockchain.network) {
Some(spec) => (*spec).clone(),
None => {
println!(" - {} | {:?} Ignoring tests because of missing spec", name, blockchain.network);
continue;
}
};
let genesis = Genesis::from(blockchain.genesis()); let genesis = Genesis::from(blockchain.genesis());
let state = From::from(blockchain.pre_state.clone()); let state = From::from(blockchain.pre_state.clone());
let mut spec = match era {
ChainEra::Frontier => ethereum::new_frontier_test(),
ChainEra::Homestead => ethereum::new_homestead_test(),
ChainEra::Eip150 => ethereum::new_eip150_test(),
ChainEra::_Eip161 => ethereum::new_eip161_test(),
ChainEra::TransitionTest => ethereum::new_transition_test(),
};
spec.set_genesis_state(state).expect("Failed to overwrite genesis state"); spec.set_genesis_state(state).expect("Failed to overwrite genesis state");
spec.overwrite_genesis_params(genesis); spec.overwrite_genesis_params(genesis);
assert!(spec.is_state_root_valid()); assert!(spec.is_state_root_valid());
@ -86,67 +85,69 @@ pub fn json_chain_test(json_data: &[u8], era: ChainEra) -> Vec<String> {
failed failed
} }
mod frontier_era_tests { mod block_tests {
use tests::helpers::*;
use super::json_chain_test; use super::json_chain_test;
fn do_json_test(json_data: &[u8]) -> Vec<String> { fn do_json_test(json_data: &[u8]) -> Vec<String> {
json_chain_test(json_data, ChainEra::Frontier) json_chain_test(json_data)
} }
declare_test!{BlockchainTests_bcBlockGasLimitTest, "BlockchainTests/bcBlockGasLimitTest"} declare_test!{BlockchainTests_bcBlockGasLimitTest, "BlockchainTests/bcBlockGasLimitTest"}
declare_test!{BlockchainTests_bcForkBlockTest, "BlockchainTests/bcForkBlockTest"} declare_test!{BlockchainTests_bcExploitTest, "BlockchainTests/bcExploitTest"}
declare_test!{BlockchainTests_bcForgedTest, "BlockchainTests/bcForgedTest"}
declare_test!{BlockchainTests_bcForkStressTest, "BlockchainTests/bcForkStressTest"} declare_test!{BlockchainTests_bcForkStressTest, "BlockchainTests/bcForkStressTest"}
declare_test!{BlockchainTests_bcForkUncle, "BlockchainTests/bcForkUncle"}
declare_test!{BlockchainTests_bcGasPricerTest, "BlockchainTests/bcGasPricerTest"} declare_test!{BlockchainTests_bcGasPricerTest, "BlockchainTests/bcGasPricerTest"}
declare_test!{BlockchainTests_bcInvalidHeaderTest, "BlockchainTests/bcInvalidHeaderTest"} declare_test!{BlockchainTests_bcInvalidHeaderTest, "BlockchainTests/bcInvalidHeaderTest"}
// TODO [ToDr] Ignored because of incorrect JSON (https://github.com/ethereum/tests/pull/113)
declare_test!{ignore => BlockchainTests_bcInvalidRLPTest, "BlockchainTests/bcInvalidRLPTest"}
declare_test!{BlockchainTests_bcMultiChainTest, "BlockchainTests/bcMultiChainTest"} declare_test!{BlockchainTests_bcMultiChainTest, "BlockchainTests/bcMultiChainTest"}
declare_test!{BlockchainTests_bcRPC_API_Test, "BlockchainTests/bcRPC_API_Test"} declare_test!{BlockchainTests_bcRandomBlockhashTest, "BlockchainTests/bcRandomBlockhashTest"}
declare_test!{BlockchainTests_bcStateTest, "BlockchainTests/bcStateTest"}
declare_test!{BlockchainTests_bcTotalDifficultyTest, "BlockchainTests/bcTotalDifficultyTest"} declare_test!{BlockchainTests_bcTotalDifficultyTest, "BlockchainTests/bcTotalDifficultyTest"}
declare_test!{BlockchainTests_bcUncleHeaderValiditiy, "BlockchainTests/bcUncleHeaderValiditiy"} declare_test!{BlockchainTests_bcUncleHeaderValiditiy, "BlockchainTests/bcUncleHeaderValiditiy"}
declare_test!{BlockchainTests_bcUncleTest, "BlockchainTests/bcUncleTest"} declare_test!{BlockchainTests_bcUncleTest, "BlockchainTests/bcUncleTest"}
declare_test!{BlockchainTests_bcValidBlockTest, "BlockchainTests/bcValidBlockTest"} declare_test!{BlockchainTests_bcValidBlockTest, "BlockchainTests/bcValidBlockTest"}
declare_test!{BlockchainTests_bcWalletTest, "BlockchainTests/bcWalletTest"} declare_test!{BlockchainTests_bcWalletTest, "BlockchainTests/bcWalletTest"}
declare_test!{BlockchainTests_RandomTests_bl10251623GO, "BlockchainTests/RandomTests/bl10251623GO"} declare_test!{BlockchainTests_GeneralStateTest_stAttackTest, "BlockchainTests/GeneralStateTests/stAttackTest/"}
declare_test!{BlockchainTests_RandomTests_bl201507071825GO, "BlockchainTests/RandomTests/bl201507071825GO"} declare_test!{BlockchainTests_GeneralStateTest_stBadOpcodeTest, "BlockchainTests/GeneralStateTests/stBadOpcode/"}
declare_test!{BlockchainTests_GeneralStateTest_stCallCodes, "BlockchainTests/GeneralStateTests/stCallCodes/"}
declare_test!{BlockchainTests_GeneralStateTest_stCallDelegateCodesCallCodeHomestead, "BlockchainTests/GeneralStateTests/stCallDelegateCodesCallCodeHomestead/"}
declare_test!{BlockchainTests_GeneralStateTest_stCallDelegateCodesHomestead, "BlockchainTests/GeneralStateTests/stCallDelegateCodesHomestead/"}
declare_test!{BlockchainTests_GeneralStateTest_stChangedEIP150, "BlockchainTests/GeneralStateTests/stChangedEIP150/"}
declare_test!{BlockchainTests_GeneralStateTest_stCodeSizeLimit, "BlockchainTests/GeneralStateTests/stCodeSizeLimit/"}
declare_test!{BlockchainTests_GeneralStateTest_stCreateTest, "BlockchainTests/GeneralStateTests/stCreateTest/"}
declare_test!{BlockchainTests_GeneralStateTest_stDelegatecallTestHomestead, "BlockchainTests/GeneralStateTests/stDelegatecallTestHomestead/"}
declare_test!{BlockchainTests_GeneralStateTest_stEIP150singleCodeGasPrices, "BlockchainTests/GeneralStateTests/stEIP150singleCodeGasPrices/"}
declare_test!{BlockchainTests_GeneralStateTest_stEIP150Specific, "BlockchainTests/GeneralStateTests/stEIP150Specific/"}
declare_test!{BlockchainTests_GeneralStateTest_stEIP158Specific, "BlockchainTests/GeneralStateTests/stEIP158Specific/"}
declare_test!{BlockchainTests_GeneralStateTest_stExample, "BlockchainTests/GeneralStateTests/stExample/"}
declare_test!{BlockchainTests_GeneralStateTest_stHomesteadSpecific, "BlockchainTests/GeneralStateTests/stHomesteadSpecific/"}
declare_test!{BlockchainTests_GeneralStateTest_stInitCodeTest, "BlockchainTests/GeneralStateTests/stInitCodeTest/"}
declare_test!{BlockchainTests_GeneralStateTest_stLogTests, "BlockchainTests/GeneralStateTests/stLogTests/"}
declare_test!{BlockchainTests_GeneralStateTest_stMemExpandingEIP150Calls, "BlockchainTests/GeneralStateTests/stMemExpandingEIP150Calls/"}
declare_test!{heavy => BlockchainTests_GeneralStateTest_stMemoryStressTest, "BlockchainTests/GeneralStateTests/stMemoryStressTest/"}
declare_test!{BlockchainTests_GeneralStateTest_stMemoryTest, "BlockchainTests/GeneralStateTests/stMemoryTest/"}
declare_test!{BlockchainTests_GeneralStateTest_stNonZeroCallsTest, "BlockchainTests/GeneralStateTests/stNonZeroCallsTest/"}
declare_test!{BlockchainTests_GeneralStateTest_stPreCompiledContracts, "BlockchainTests/GeneralStateTests/stPreCompiledContracts/"}
declare_test!{heavy => BlockchainTests_GeneralStateTest_stQuadraticComplexityTest, "BlockchainTests/GeneralStateTests/stQuadraticComplexityTest/"}
declare_test!{BlockchainTests_GeneralStateTest_stRandom, "BlockchainTests/GeneralStateTests/stRandom/"}
declare_test!{BlockchainTests_GeneralStateTest_stRecursiveCreate, "BlockchainTests/GeneralStateTests/stRecursiveCreate/"}
declare_test!{BlockchainTests_GeneralStateTest_stRefundTest, "BlockchainTests/GeneralStateTests/stRefundTest/"}
declare_test!{BlockchainTests_GeneralStateTest_stReturnDataTest, "BlockchainTests/GeneralStateTests/stReturnDataTest/"}
declare_test!{BlockchainTests_GeneralStateTest_stRevertTest, "BlockchainTests/GeneralStateTests/stRevertTest/"}
declare_test!{BlockchainTests_GeneralStateTest_stSolidityTest, "BlockchainTests/GeneralStateTests/stSolidityTest/"}
declare_test!{BlockchainTests_GeneralStateTest_stSpecialTest, "BlockchainTests/GeneralStateTests/stSpecialTest/"}
declare_test!{BlockchainTests_GeneralStateTest_stStackTests, "BlockchainTests/GeneralStateTests/stStackTests/"}
declare_test!{BlockchainTests_GeneralStateTest_stStaticCall, "BlockchainTests/GeneralStateTests/stStaticCall/"}
declare_test!{BlockchainTests_GeneralStateTest_stSystemOperationsTest, "BlockchainTests/GeneralStateTests/stSystemOperationsTest/"}
declare_test!{BlockchainTests_GeneralStateTest_stTransactionTest, "BlockchainTests/GeneralStateTests/stTransactionTest/"}
declare_test!{BlockchainTests_GeneralStateTest_stTransitionTest, "BlockchainTests/GeneralStateTests/stTransitionTest/"}
declare_test!{BlockchainTests_GeneralStateTest_stWalletTest, "BlockchainTests/GeneralStateTests/stWalletTest/"}
declare_test!{BlockchainTests_GeneralStateTest_stZeroCallsRevert, "BlockchainTests/GeneralStateTests/stZeroCallsRevert/"}
declare_test!{BlockchainTests_GeneralStateTest_stZeroCallsTest, "BlockchainTests/GeneralStateTests/stZeroCallsTest/"}
declare_test!{BlockchainTests_GeneralStateTest_stZeroKnowledge, "BlockchainTests/GeneralStateTests/stZeroKnowledge/"}
declare_test!{BlockchainTests_TransitionTests_bcEIP158ToByzantium, "BlockchainTests/TransitionTests/bcEIP158ToByzantium/"}
declare_test!{BlockchainTests_TransitionTests_bcFrontierToHomestead, "BlockchainTests/TransitionTests/bcFrontierToHomestead/"}
declare_test!{BlockchainTests_TransitionTests_bcHomesteadToDao, "BlockchainTests/TransitionTests/bcHomesteadToDao/"}
declare_test!{BlockchainTests_TransitionTests_bcHomesteadToEIP150, "BlockchainTests/TransitionTests/bcHomesteadToEIP150/"}
} }
mod transition_tests {
use tests::helpers::*;
use super::json_chain_test;
fn do_json_test(json_data: &[u8]) -> Vec<String> {
json_chain_test(json_data, ChainEra::TransitionTest)
}
declare_test!{BlockchainTests_TestNetwork_bcSimpleTransitionTest, "BlockchainTests/TestNetwork/bcSimpleTransitionTest"}
declare_test!{BlockchainTests_TestNetwork_bcTheDaoTest, "BlockchainTests/TestNetwork/bcTheDaoTest"}
declare_test!{BlockchainTests_TestNetwork_bcEIP150Test, "BlockchainTests/TestNetwork/bcEIP150Test"}
}
mod eip150_blockchain_tests {
use tests::helpers::*;
use super::json_chain_test;
fn do_json_test(json_data: &[u8]) -> Vec<String> {
json_chain_test(json_data, ChainEra::Eip150)
}
declare_test!{BlockchainTests_EIP150_bcBlockGasLimitTest, "BlockchainTests/EIP150/bcBlockGasLimitTest"}
declare_test!{BlockchainTests_EIP150_bcForkStressTest, "BlockchainTests/EIP150/bcForkStressTest"}
declare_test!{BlockchainTests_EIP150_bcGasPricerTest, "BlockchainTests/EIP150/bcGasPricerTest"}
declare_test!{BlockchainTests_EIP150_bcInvalidHeaderTest, "BlockchainTests/EIP150/bcInvalidHeaderTest"}
declare_test!{BlockchainTests_EIP150_bcInvalidRLPTest, "BlockchainTests/EIP150/bcInvalidRLPTest"}
declare_test!{BlockchainTests_EIP150_bcMultiChainTest, "BlockchainTests/EIP150/bcMultiChainTest"}
declare_test!{BlockchainTests_EIP150_bcRPC_API_Test, "BlockchainTests/EIP150/bcRPC_API_Test"}
declare_test!{BlockchainTests_EIP150_bcStateTest, "BlockchainTests/EIP150/bcStateTest"}
declare_test!{BlockchainTests_EIP150_bcTotalDifficultyTest, "BlockchainTests/EIP150/bcTotalDifficultyTest"}
declare_test!{BlockchainTests_EIP150_bcUncleHeaderValiditiy, "BlockchainTests/EIP150/bcUncleHeaderValiditiy"}
declare_test!{BlockchainTests_EIP150_bcUncleTest, "BlockchainTests/EIP150/bcUncleTest"}
declare_test!{BlockchainTests_EIP150_bcValidBlockTest, "BlockchainTests/EIP150/bcValidBlockTest"}
declare_test!{BlockchainTests_EIP150_bcWalletTest, "BlockchainTests/EIP150/bcWalletTest"}
}

View File

@ -30,6 +30,10 @@ use tests::helpers::*;
use ethjson; use ethjson;
use trace::{Tracer, NoopTracer}; use trace::{Tracer, NoopTracer};
use trace::{VMTracer, NoopVMTracer}; use trace::{VMTracer, NoopVMTracer};
use bytes::{Bytes, BytesRef};
use trie;
use rlp::RlpStream;
use hash::keccak;
#[derive(Debug, PartialEq, Clone)] #[derive(Debug, PartialEq, Clone)]
struct CallCreate { struct CallCreate {
@ -160,8 +164,8 @@ impl<'a, T: 'a, V: 'a, B: 'a, E: 'a> Ext for TestExt<'a, T, V, B, E>
self.ext.log(topics, data) self.ext.log(topics, data)
} }
fn ret(self, gas: &U256, data: &ReturnData) -> Result<U256, vm::Error> { fn ret(self, gas: &U256, data: &ReturnData, apply_state: bool) -> Result<U256, vm::Error> {
self.ext.ret(gas, data) self.ext.ret(gas, data, apply_state)
} }
fn suicide(&mut self, refund_address: &Address) -> vm::Result<()> { fn suicide(&mut self, refund_address: &Address) -> vm::Result<()> {
@ -180,6 +184,10 @@ impl<'a, T: 'a, V: 'a, B: 'a, E: 'a> Ext for TestExt<'a, T, V, B, E>
0 0
} }
fn is_static(&self) -> bool {
false
}
fn inc_sstore_clears(&mut self) { fn inc_sstore_clears(&mut self) {
self.ext.inc_sstore_clears() self.ext.inc_sstore_clears()
} }
@ -253,6 +261,14 @@ fn do_json_test_for(vm_type: &VMType, json_data: &[u8]) -> Vec<String> {
(res.finalize(ex), callcreates) (res.finalize(ex), callcreates)
}; };
let log_hash = {
let mut rlp = RlpStream::new_list(substate.logs.len());
for l in &substate.logs {
rlp.append(l);
}
keccak(&rlp.drain())
};
match res { match res {
Err(_) => fail_unless(out_of_gas, "didn't expect to run out of gas."), Err(_) => fail_unless(out_of_gas, "didn't expect to run out of gas."),
Ok(res) => { Ok(res) => {
@ -260,6 +276,7 @@ fn do_json_test_for(vm_type: &VMType, json_data: &[u8]) -> Vec<String> {
fail_unless(Some(res.gas_left) == vm.gas_left.map(Into::into), "gas_left is incorrect"); fail_unless(Some(res.gas_left) == vm.gas_left.map(Into::into), "gas_left is incorrect");
let vm_output: Option<Vec<u8>> = vm.output.map(Into::into); let vm_output: Option<Vec<u8>> = vm.output.map(Into::into);
fail_unless(Some(output) == vm_output, "output is incorrect"); fail_unless(Some(output) == vm_output, "output is incorrect");
fail_unless(Some(log_hash) == vm.logs.map(|h| h.0), "logs are incorrect");
for (address, account) in vm.post_state.unwrap().into_iter() { for (address, account) in vm.post_state.unwrap().into_iter() {
let address = address.into(); let address = address.into();
@ -293,15 +310,15 @@ fn do_json_test_for(vm_type: &VMType, json_data: &[u8]) -> Vec<String> {
} }
declare_test!{ExecutiveTests_vmArithmeticTest, "VMTests/vmArithmeticTest"} declare_test!{ExecutiveTests_vmArithmeticTest, "VMTests/vmArithmeticTest"}
declare_test!{ExecutiveTests_vmBitwiseLogicOperationTest, "VMTests/vmBitwiseLogicOperationTest"} declare_test!{ExecutiveTests_vmBitwiseLogicOperationTest, "VMTests/vmBitwiseLogicOperation"}
declare_test!{ExecutiveTests_vmBlockInfoTest, "VMTests/vmBlockInfoTest"} declare_test!{ExecutiveTests_vmBlockInfoTest, "VMTests/vmBlockInfoTest"}
// TODO [todr] Fails with Signal 11 when using JIT // TODO [todr] Fails with Signal 11 when using JIT
declare_test!{ExecutiveTests_vmEnvironmentalInfoTest, "VMTests/vmEnvironmentalInfoTest"} declare_test!{ExecutiveTests_vmEnvironmentalInfoTest, "VMTests/vmEnvironmentalInfo"}
declare_test!{ExecutiveTests_vmIOandFlowOperationsTest, "VMTests/vmIOandFlowOperationsTest"} declare_test!{ExecutiveTests_vmIOandFlowOperationsTest, "VMTests/vmIOandFlowOperations"}
declare_test!{heavy => ExecutiveTests_vmInputLimits, "VMTests/vmInputLimits"}
declare_test!{ExecutiveTests_vmLogTest, "VMTests/vmLogTest"} declare_test!{ExecutiveTests_vmLogTest, "VMTests/vmLogTest"}
declare_test!{ExecutiveTests_vmPerformanceTest, "VMTests/vmPerformanceTest"} declare_test!{heavy => ExecutiveTests_vmPerformance, "VMTests/vmPerformance"}
declare_test!{ExecutiveTests_vmPushDupSwapTest, "VMTests/vmPushDupSwapTest"} declare_test!{ExecutiveTests_vmPushDupSwapTest, "VMTests/vmPushDupSwapTest"}
declare_test!{ExecutiveTests_vmRandomTest, "VMTests/vmRandomTest"}
declare_test!{ExecutiveTests_vmSha3Test, "VMTests/vmSha3Test"} declare_test!{ExecutiveTests_vmSha3Test, "VMTests/vmSha3Test"}
declare_test!{ExecutiveTests_vmSystemOperationsTest, "VMTests/vmSystemOperationsTest"} declare_test!{ExecutiveTests_vmSystemOperationsTest, "VMTests/vmSystemOperations"}
declare_test!{ExecutiveTests_vmtests, "VMTests/vmtests"} declare_test!{ExecutiveTests_vmTests, "VMTests/vmTests"}

View File

@ -1,39 +0,0 @@
// Copyright 2015-2017 Parity Technologies (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/>.
use super::chain::json_chain_test;
use tests::helpers::*;
fn do_json_test(json_data: &[u8]) -> Vec<String> {
json_chain_test(json_data, ChainEra::Homestead)
}
declare_test!{BlockchainTests_Homestead_bcBlockGasLimitTest, "BlockchainTests/Homestead/bcBlockGasLimitTest"}
declare_test!{BlockchainTests_Homestead_bcForkStressTest, "BlockchainTests/Homestead/bcForkStressTest"}
declare_test!{BlockchainTests_Homestead_bcGasPricerTest, "BlockchainTests/Homestead/bcGasPricerTest"}
declare_test!{BlockchainTests_Homestead_bcInvalidHeaderTest, "BlockchainTests/Homestead/bcInvalidHeaderTest"}
declare_test!{BlockchainTests_Homestead_bcInvalidRLPTest, "BlockchainTests/Homestead/bcInvalidRLPTest"}
declare_test!{BlockchainTests_Homestead_bcMultiChainTest, "BlockchainTests/Homestead/bcMultiChainTest"}
declare_test!{BlockchainTests_Homestead_bcRPC_API_Test, "BlockchainTests/Homestead/bcRPC_API_Test"}
declare_test!{BlockchainTests_Homestead_bcStateTest, "BlockchainTests/Homestead/bcStateTest"}
declare_test!{BlockchainTests_Homestead_bcTotalDifficultyTest, "BlockchainTests/Homestead/bcTotalDifficultyTest"}
declare_test!{BlockchainTests_Homestead_bcUncleHeaderValiditiy, "BlockchainTests/Homestead/bcUncleHeaderValiditiy"}
declare_test!{BlockchainTests_Homestead_bcUncleTest, "BlockchainTests/Homestead/bcUncleTest"}
declare_test!{BlockchainTests_Homestead_bcValidBlockTest, "BlockchainTests/Homestead/bcValidBlockTest"}
declare_test!{BlockchainTests_Homestead_bcWalletTest, "BlockchainTests/Homestead/bcWalletTest"}
declare_test!{BlockchainTests_Homestead_bcShanghaiLove, "BlockchainTests/Homestead/bcShanghaiLove"}
declare_test!{BlockchainTests_Homestead_bcSuicideIssue, "BlockchainTests/Homestead/bcSuicideIssue"}
declare_test!{BlockchainTests_Homestead_bcExploitTest, "BlockchainTests/Homestead/bcExploitTest"}

View File

@ -21,5 +21,4 @@ mod transaction;
mod executive; mod executive;
mod state; mod state;
mod chain; mod chain;
mod homestead_chain;
mod trie; mod trie;

View File

@ -97,9 +97,8 @@ mod state_tests {
} }
declare_test!{GeneralStateTest_stAttackTest, "GeneralStateTests/stAttackTest/"} declare_test!{GeneralStateTest_stAttackTest, "GeneralStateTests/stAttackTest/"}
declare_test!{GeneralStateTest_stBoundsTest, "GeneralStateTests/stBoundsTest/"} declare_test!{GeneralStateTest_stBadOpcodeTest, "GeneralStateTests/stBadOpcode/"}
declare_test!{GeneralStateTest_stCallCodes, "GeneralStateTests/stCallCodes/"} declare_test!{GeneralStateTest_stCallCodes, "GeneralStateTests/stCallCodes/"}
declare_test!{skip => [ "createJS_ExampleContract" ], GeneralStateTest_stCallCreateCallCodeTest, "GeneralStateTests/stCallCreateCallCodeTest/"}
declare_test!{GeneralStateTest_stCallDelegateCodesCallCodeHomestead, "GeneralStateTests/stCallDelegateCodesCallCodeHomestead/"} declare_test!{GeneralStateTest_stCallDelegateCodesCallCodeHomestead, "GeneralStateTests/stCallDelegateCodesCallCodeHomestead/"}
declare_test!{GeneralStateTest_stCallDelegateCodesHomestead, "GeneralStateTests/stCallDelegateCodesHomestead/"} declare_test!{GeneralStateTest_stCallDelegateCodesHomestead, "GeneralStateTests/stCallDelegateCodesHomestead/"}
declare_test!{GeneralStateTest_stChangedEIP150, "GeneralStateTests/stChangedEIP150/"} declare_test!{GeneralStateTest_stChangedEIP150, "GeneralStateTests/stChangedEIP150/"}
@ -108,6 +107,7 @@ mod state_tests {
declare_test!{GeneralStateTest_stDelegatecallTestHomestead, "GeneralStateTests/stDelegatecallTestHomestead/"} declare_test!{GeneralStateTest_stDelegatecallTestHomestead, "GeneralStateTests/stDelegatecallTestHomestead/"}
declare_test!{GeneralStateTest_stEIP150singleCodeGasPrices, "GeneralStateTests/stEIP150singleCodeGasPrices/"} declare_test!{GeneralStateTest_stEIP150singleCodeGasPrices, "GeneralStateTests/stEIP150singleCodeGasPrices/"}
declare_test!{GeneralStateTest_stEIP150Specific, "GeneralStateTests/stEIP150Specific/"} declare_test!{GeneralStateTest_stEIP150Specific, "GeneralStateTests/stEIP150Specific/"}
declare_test!{GeneralStateTest_stEIP158Specific, "GeneralStateTests/stEIP158Specific/"}
declare_test!{GeneralStateTest_stExample, "GeneralStateTests/stExample/"} declare_test!{GeneralStateTest_stExample, "GeneralStateTests/stExample/"}
declare_test!{GeneralStateTest_stHomesteadSpecific, "GeneralStateTests/stHomesteadSpecific/"} declare_test!{GeneralStateTest_stHomesteadSpecific, "GeneralStateTests/stHomesteadSpecific/"}
declare_test!{GeneralStateTest_stInitCodeTest, "GeneralStateTests/stInitCodeTest/"} declare_test!{GeneralStateTest_stInitCodeTest, "GeneralStateTests/stInitCodeTest/"}
@ -121,15 +121,18 @@ mod state_tests {
declare_test!{GeneralStateTest_stRandom, "GeneralStateTests/stRandom/"} declare_test!{GeneralStateTest_stRandom, "GeneralStateTests/stRandom/"}
declare_test!{GeneralStateTest_stRecursiveCreate, "GeneralStateTests/stRecursiveCreate/"} declare_test!{GeneralStateTest_stRecursiveCreate, "GeneralStateTests/stRecursiveCreate/"}
declare_test!{GeneralStateTest_stRefundTest, "GeneralStateTests/stRefundTest/"} declare_test!{GeneralStateTest_stRefundTest, "GeneralStateTests/stRefundTest/"}
declare_test!{skip => [ "RevertDepthCreateAddressCollision" ], GeneralStateTest_stRevertTest, "GeneralStateTests/stRevertTest/"} declare_test!{GeneralStateTest_stReturnDataTest, "GeneralStateTests/stReturnDataTest/"}
declare_test!{GeneralStateTest_stRevertTest, "GeneralStateTests/stRevertTest/"}
declare_test!{GeneralStateTest_stSolidityTest, "GeneralStateTests/stSolidityTest/"} declare_test!{GeneralStateTest_stSolidityTest, "GeneralStateTests/stSolidityTest/"}
declare_test!{GeneralStateTest_stSpecialTest, "GeneralStateTests/stSpecialTest/"} declare_test!{GeneralStateTest_stSpecialTest, "GeneralStateTests/stSpecialTest/"}
declare_test!{GeneralStateTest_stStackTests, "GeneralStateTests/stStackTests/"} declare_test!{GeneralStateTest_stStackTests, "GeneralStateTests/stStackTests/"}
declare_test!{GeneralStateTest_stStaticCall, "GeneralStateTests/stStaticCall/"}
declare_test!{GeneralStateTest_stSystemOperationsTest, "GeneralStateTests/stSystemOperationsTest/"} declare_test!{GeneralStateTest_stSystemOperationsTest, "GeneralStateTests/stSystemOperationsTest/"}
declare_test!{GeneralStateTest_stTransactionTest, "GeneralStateTests/stTransactionTest/"} declare_test!{GeneralStateTest_stTransactionTest, "GeneralStateTests/stTransactionTest/"}
declare_test!{GeneralStateTest_stTransitionTest, "GeneralStateTests/stTransitionTest/"} declare_test!{GeneralStateTest_stTransitionTest, "GeneralStateTests/stTransitionTest/"}
declare_test!{GeneralStateTest_stWalletTest, "GeneralStateTests/stWalletTest/"} declare_test!{GeneralStateTest_stWalletTest, "GeneralStateTests/stWalletTest/"}
declare_test!{GeneralStateTest_stZeroCallsRevert, "GeneralStateTests/stZeroCallsRevert/"} declare_test!{GeneralStateTest_stZeroCallsRevert, "GeneralStateTests/stZeroCallsRevert/"}
declare_test!{GeneralStateTest_stZeroCallsTest, "GeneralStateTests/stZeroCallsTest/"} declare_test!{GeneralStateTest_stZeroCallsTest, "GeneralStateTests/stZeroCallsTest/"}
declare_test!{GeneralStateTest_stZeroKnowledge, "GeneralStateTests/stZeroKnowledge/"}
} }

View File

@ -25,7 +25,7 @@ fn do_json_test(json_data: &[u8]) -> Vec<String> {
let mut failed = Vec::new(); let mut failed = Vec::new();
let frontier_schedule = evm::Schedule::new_frontier(); let frontier_schedule = evm::Schedule::new_frontier();
let homestead_schedule = evm::Schedule::new_homestead(); let homestead_schedule = evm::Schedule::new_homestead();
let metropolis_schedule = evm::Schedule::new_metropolis(); let byzantium_schedule = evm::Schedule::new_byzantium();
for (name, test) in tests.into_iter() { for (name, test) in tests.into_iter() {
let mut fail_unless = |cond: bool, title: &str| if !cond { failed.push(name.clone()); println!("Transaction failed: {:?}: {:?}", name, title); }; let mut fail_unless = |cond: bool, title: &str| if !cond { failed.push(name.clone()); println!("Transaction failed: {:?}: {:?}", name, title); };
@ -34,7 +34,7 @@ fn do_json_test(json_data: &[u8]) -> Vec<String> {
None => &frontier_schedule, None => &frontier_schedule,
Some(x) if x < 1_150_000 => &frontier_schedule, Some(x) if x < 1_150_000 => &frontier_schedule,
Some(x) if x < 3_000_000 => &homestead_schedule, Some(x) if x < 3_000_000 => &homestead_schedule,
Some(_) => &metropolis_schedule Some(_) => &byzantium_schedule
}; };
let allow_chain_id_of_one = number.map_or(false, |n| n >= 2_675_000); let allow_chain_id_of_one = number.map_or(false, |n| n >= 2_675_000);
let allow_unsigned = number.map_or(false, |n| n >= 3_000_000); let allow_unsigned = number.map_or(false, |n| n >= 3_000_000);
@ -75,18 +75,13 @@ fn do_json_test(json_data: &[u8]) -> Vec<String> {
failed failed
} }
declare_test!{TransactionTests_ttTransactionTest, "TransactionTests/ttTransactionTest"} declare_test!{TransactionTests_ttEip155VitaliksHomesead, "TransactionTests/ttEip155VitaliksHomesead"}
declare_test!{heavy => TransactionTests_tt10mbDataField, "TransactionTests/tt10mbDataField"} declare_test!{TransactionTests_ttEip155VitaliksEip158, "TransactionTests/ttEip155VitaliksEip158"}
declare_test!{TransactionTests_ttWrongRLPTransaction, "TransactionTests/ttWrongRLPTransaction"} declare_test!{TransactionTests_ttEip158, "TransactionTests/ttEip158"}
declare_test!{TransactionTests_Homestead_ttTransactionTest, "TransactionTests/Homestead/ttTransactionTest"} declare_test!{TransactionTests_ttFrontier, "TransactionTests/ttFrontier"}
declare_test!{heavy => TransactionTests_Homestead_tt10mbDataField, "TransactionTests/Homestead/tt10mbDataField"} declare_test!{TransactionTests_ttHomestead, "TransactionTests/ttHomestead"}
declare_test!{TransactionTests_Homestead_ttWrongRLPTransaction, "TransactionTests/Homestead/ttWrongRLPTransaction"} declare_test!{TransactionTests_ttVRuleEip158, "TransactionTests/ttVRuleEip158"}
declare_test!{TransactionTests_RandomTests_tr201506052141PYTHON, "TransactionTests/RandomTests/tr201506052141PYTHON"} declare_test!{TransactionTests_ttWrongRLPFrontier, "TransactionTests/ttWrongRLPFrontier"}
declare_test!{TransactionTests_Homestead_ttTransactionTestEip155VitaliksTests, "TransactionTests/Homestead/ttTransactionTestEip155VitaliksTests"} declare_test!{TransactionTests_ttWrongRLPHomestead, "TransactionTests/ttWrongRLPHomestead"}
declare_test!{TransactionTests_EIP155_ttTransactionTest, "TransactionTests/EIP155/ttTransactionTest"} declare_test!{TransactionTests_ttConstantinople, "TransactionTests/ttConstantinople"}
declare_test!{TransactionTests_EIP155_ttTransactionTestEip155VitaliksTests, "TransactionTests/EIP155/ttTransactionTestEip155VitaliksTests"} declare_test!{TransactionTests_ttSpecConstantinople, "TransactionTests/ttSpecConstantinople"}
declare_test!{TransactionTests_EIP155_ttTransactionTestVRule, "TransactionTests/EIP155/ttTransactionTestVRule"}
declare_test!{TransactionTests_Metropolis_ttMetropolisTest, "TransactionTests/Metropolis/ttMetropolisTest"}
declare_test!{TransactionTests_Metropolis_ttTransactionTest, "TransactionTests/Metropolis/ttTransactionTest"}
declare_test!{TransactionTests_Metropolis_ttTransactionTestZeroSig, "TransactionTests/Metropolis/ttTransactionTestZeroSig"}

View File

@ -15,9 +15,9 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
use ethjson; use ethjson;
use util::trie::{TrieFactory, TrieSpec}; use trie::{TrieFactory, TrieSpec};
use bigint::hash::H256; use bigint::hash::H256;
use util::memorydb::MemoryDB; use memorydb::MemoryDB;
fn test_trie(json: &[u8], trie: TrieSpec) -> Vec<String> { fn test_trie(json: &[u8], trie: TrieSpec) -> Vec<String> {
let tests = ethjson::trie::Test::load(json).unwrap(); let tests = ethjson::trie::Test::load(json).unwrap();
@ -49,7 +49,7 @@ fn test_trie(json: &[u8], trie: TrieSpec) -> Vec<String> {
} }
mod generic { mod generic {
use util::trie::TrieSpec; use trie::TrieSpec;
fn do_json_test(json: &[u8]) -> Vec<String> { fn do_json_test(json: &[u8]) -> Vec<String> {
super::test_trie(json, TrieSpec::Generic) super::test_trie(json, TrieSpec::Generic)
@ -60,7 +60,7 @@ mod generic {
} }
mod secure { mod secure {
use util::trie::TrieSpec; use trie::TrieSpec;
fn do_json_test(json: &[u8]) -> Vec<String> { fn do_json_test(json: &[u8]) -> Vec<String> {
super::test_trie(json, TrieSpec::Secure) super::test_trie(json, TrieSpec::Secure)

View File

@ -86,12 +86,14 @@ extern crate ethcore_devtools as devtools;
extern crate ethcore_io as io; extern crate ethcore_io as io;
extern crate ethcore_ipc_nano as nanoipc; extern crate ethcore_ipc_nano as nanoipc;
extern crate ethcore_bigint as bigint; extern crate ethcore_bigint as bigint;
extern crate ethcore_bytes as bytes;
extern crate ethcore_logger; extern crate ethcore_logger;
extern crate ethcore_stratum; extern crate ethcore_stratum;
extern crate ethjson; extern crate ethjson;
extern crate ethkey; extern crate ethkey;
extern crate futures; extern crate futures;
extern crate hardware_wallet; extern crate hardware_wallet;
extern crate hashdb;
extern crate hyper; extern crate hyper;
extern crate itertools; extern crate itertools;
extern crate linked_hash_map; extern crate linked_hash_map;
@ -106,6 +108,8 @@ extern crate rayon;
extern crate rlp; extern crate rlp;
extern crate hash; extern crate hash;
extern crate heapsize; extern crate heapsize;
extern crate memorydb;
extern crate patricia_trie as trie;
extern crate triehash; extern crate triehash;
extern crate ansi_term; extern crate ansi_term;
extern crate semantic_version; extern crate semantic_version;

View File

@ -20,7 +20,8 @@
use std::collections::HashMap; use std::collections::HashMap;
use bigint::hash::H256; use bigint::hash::H256;
use util::{Address, Bytes}; use util::Address;
use bytes::Bytes;
use util::kvdb::Database; use util::kvdb::Database;
use util::migration::{Batch, Config, Error, Migration, SimpleMigration, Progress}; use util::migration::{Batch, Config, Error, Migration, SimpleMigration, Progress};
use hash::keccak; use hash::keccak;

View File

@ -19,13 +19,13 @@
use std::sync::Arc; use std::sync::Arc;
use db::{COL_EXTRA, COL_HEADERS, COL_STATE}; use db::{COL_EXTRA, COL_HEADERS, COL_STATE};
use state_db::{ACCOUNT_BLOOM_SPACE, DEFAULT_ACCOUNT_PRESET, StateDB}; use state_db::{ACCOUNT_BLOOM_SPACE, DEFAULT_ACCOUNT_PRESET, StateDB};
use util::trie::TrieDB; use trie::TrieDB;
use views::HeaderView; use views::HeaderView;
use bloom_journal::Bloom; use bloom_journal::Bloom;
use util::migration::{Error, Migration, Progress, Batch, Config}; use util::migration::{Error, Migration, Progress, Batch, Config};
use util::journaldb; use util::journaldb;
use bigint::hash::H256; use bigint::hash::H256;
use util::Trie; use trie::Trie;
use util::{Database, DBTransaction}; use util::{Database, DBTransaction};
/// Account bloom upgrade routine. If bloom already present, does nothing. /// Account bloom upgrade routine. If bloom already present, does nothing.

View File

@ -22,6 +22,7 @@ use bigint::prelude::U256;
use bigint::hash::H256; use bigint::hash::H256;
use parking_lot::{Mutex, RwLock}; use parking_lot::{Mutex, RwLock};
use util::*; use util::*;
use bytes::Bytes;
use timer::PerfTimer; use timer::PerfTimer;
use using_queue::{UsingQueue, GetAction}; use using_queue::{UsingQueue, GetAction};
use account_provider::{AccountProvider, SignError as AccountError}; use account_provider::{AccountProvider, SignError as AccountError};

View File

@ -63,7 +63,8 @@ pub use self::stratum::{Stratum, Error as StratumError, Options as StratumOption
use std::collections::BTreeMap; use std::collections::BTreeMap;
use bigint::prelude::U256; use bigint::prelude::U256;
use bigint::hash::H256; use bigint::hash::H256;
use util::{Address, Bytes}; use util::Address;
use bytes::Bytes;
use client::{MiningBlockChainClient}; use client::{MiningBlockChainClient};
use block::ClosedBlock; use block::ClosedBlock;
use header::BlockNumber; use header::BlockNumber;

View File

@ -22,6 +22,8 @@ use bigint::prelude::U256;
use bigint::hash::H256; use bigint::hash::H256;
use triehash::sec_trie_root; use triehash::sec_trie_root;
use util::*; use util::*;
use bytes::Bytes;
use trie::TrieFactory;
use state::Account; use state::Account;
use ethjson; use ethjson;
use types::account_diff::*; use types::account_diff::*;

View File

@ -20,6 +20,7 @@ use std::sync::Arc;
use std::path::Path; use std::path::Path;
use bigint::hash::H256; use bigint::hash::H256;
use util::*; use util::*;
use bytes::Bytes;
use io::*; use io::*;
use spec::Spec; use spec::Spec;
use error::*; use error::*;

View File

@ -23,8 +23,9 @@ use hash::{KECCAK_EMPTY, KECCAK_NULL_RLP};
use bigint::prelude::U256; use bigint::prelude::U256;
use bigint::hash::H256; use bigint::hash::H256;
use util::{Bytes, HashDB}; use util::HashDB;
use util::trie::{TrieDB, Trie}; use bytes::Bytes;
use trie::{TrieDB, Trie};
use rlp::{RlpStream, UntrustedRlp}; use rlp::{RlpStream, UntrustedRlp};
use std::collections::HashSet; use std::collections::HashSet;
@ -151,7 +152,7 @@ pub fn from_fat_rlp(
rlp: UntrustedRlp, rlp: UntrustedRlp,
mut storage_root: H256, mut storage_root: H256,
) -> Result<(BasicAccount, Option<Bytes>), Error> { ) -> Result<(BasicAccount, Option<Bytes>), Error> {
use util::{TrieDBMut, TrieMut}; use trie::{TrieDBMut, TrieMut};
// check for special case of empty account. // check for special case of empty account.
if rlp.is_empty() { if rlp.is_empty() {

View File

@ -23,7 +23,7 @@ use hash::keccak;
use views::BlockView; use views::BlockView;
use rlp::{DecoderError, RlpStream, UntrustedRlp}; use rlp::{DecoderError, RlpStream, UntrustedRlp};
use bigint::hash::H256; use bigint::hash::H256;
use util::Bytes; use bytes::Bytes;
use triehash::ordered_trie_root; use triehash::ordered_trie_root;
const HEADER_FIELDS: usize = 8; const HEADER_FIELDS: usize = 8;
@ -140,7 +140,8 @@ mod tests {
use bigint::prelude::U256; use bigint::prelude::U256;
use bigint::hash::H256; use bigint::hash::H256;
use util::{Address, Bytes}; use util::Address;
use bytes::Bytes;
fn encode_block(b: &Block) -> Bytes { fn encode_block(b: &Block) -> Bytes {
b.rlp_bytes(::basic_types::Seal::With) b.rlp_bytes(::basic_types::Seal::With)

View File

@ -34,7 +34,8 @@ use snapshot::{Error, ManifestData};
use itertools::{Position, Itertools}; use itertools::{Position, Itertools};
use rlp::{RlpStream, UntrustedRlp}; use rlp::{RlpStream, UntrustedRlp};
use bigint::hash::H256; use bigint::hash::H256;
use util::{Bytes, KeyValueDB}; use util::KeyValueDB;
use bytes::Bytes;
/// Snapshot creation and restoration for PoA chains. /// Snapshot creation and restoration for PoA chains.
/// Chunk format: /// Chunk format:

View File

@ -31,7 +31,8 @@ use engines::Engine;
use snapshot::{Error, ManifestData}; use snapshot::{Error, ManifestData};
use snapshot::block::AbridgedBlock; use snapshot::block::AbridgedBlock;
use bigint::hash::H256; use bigint::hash::H256;
use util::{Bytes, KeyValueDB}; use util::KeyValueDB;
use bytes::Bytes;
use rlp::{RlpStream, UntrustedRlp}; use rlp::{RlpStream, UntrustedRlp};
use rand::OsRng; use rand::OsRng;

View File

@ -21,7 +21,7 @@ use std::fmt;
use ids::BlockId; use ids::BlockId;
use bigint::hash::H256; use bigint::hash::H256;
use util::trie::TrieError; use trie::TrieError;
use rlp::DecoderError; use rlp::DecoderError;
/// Snapshot-related errors. /// Snapshot-related errors.

View File

@ -25,7 +25,7 @@ use std::io::{self, Read, Seek, SeekFrom, Write};
use std::fs::{self, File}; use std::fs::{self, File};
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use util::Bytes; use bytes::Bytes;
use bigint::hash::H256; use bigint::hash::H256;
use rlp::{RlpStream, UntrustedRlp}; use rlp::{RlpStream, UntrustedRlp};

View File

@ -32,11 +32,12 @@ use ids::BlockId;
use bigint::prelude::U256; use bigint::prelude::U256;
use bigint::hash::H256; use bigint::hash::H256;
use util::{Bytes, HashDB, DBValue, snappy}; use util::{HashDB, DBValue, snappy};
use bytes::Bytes;
use parking_lot::Mutex; use parking_lot::Mutex;
use util::journaldb::{self, Algorithm, JournalDB}; use util::journaldb::{self, Algorithm, JournalDB};
use util::kvdb::KeyValueDB; use util::kvdb::KeyValueDB;
use util::trie::{TrieDB, TrieDBMut, Trie, TrieMut}; use trie::{TrieDB, TrieDBMut, Trie, TrieMut};
use rlp::{RlpStream, UntrustedRlp}; use rlp::{RlpStream, UntrustedRlp};
use bloom_journal::Bloom; use bloom_journal::Bloom;

View File

@ -37,7 +37,8 @@ use io::IoChannel;
use bigint::hash::H256; use bigint::hash::H256;
use parking_lot::{Mutex, RwLock, RwLockReadGuard}; use parking_lot::{Mutex, RwLock, RwLockReadGuard};
use util::{Bytes, UtilError}; use util::UtilError;
use bytes::Bytes;
use util::journaldb::Algorithm; use util::journaldb::Algorithm;
use util::kvdb::{Database, DatabaseConfig}; use util::kvdb::{Database, DatabaseConfig};
use util::snappy; use util::snappy;
@ -161,7 +162,7 @@ impl Restoration {
// finish up restoration. // finish up restoration.
fn finalize(mut self, engine: &Engine) -> Result<(), Error> { fn finalize(mut self, engine: &Engine) -> Result<(), Error> {
use util::trie::TrieError; use trie::TrieError;
if !self.is_done() { return Ok(()) } if !self.is_done() { return Ok(()) }

View File

@ -16,7 +16,7 @@
use super::{ManifestData, RestorationStatus}; use super::{ManifestData, RestorationStatus};
use bigint::hash::H256; use bigint::hash::H256;
use util::Bytes; use bytes::Bytes;
use ipc::IpcConfig; use ipc::IpcConfig;
/// The interface for a snapshot network service. /// The interface for a snapshot network service.

View File

@ -33,10 +33,10 @@ use rand::Rng;
use util::{DBValue, KeyValueDB}; use util::{DBValue, KeyValueDB};
use bigint::hash::H256; use bigint::hash::H256;
use util::hashdb::HashDB; use hashdb::HashDB;
use util::journaldb; use util::journaldb;
use util::trie::{Alphabet, StandardMap, SecTrieDBMut, TrieMut, ValueMode}; use trie::{Alphabet, StandardMap, SecTrieDBMut, TrieMut, ValueMode};
use util::trie::{TrieDB, TrieDBMut, Trie}; use trie::{TrieDB, TrieDBMut, Trie};
// the proportion of accounts we will alter each tick. // the proportion of accounts we will alter each tick.
const ACCOUNT_CHURN: f32 = 0.01; const ACCOUNT_CHURN: f32 = 0.01;

View File

@ -28,7 +28,7 @@ use rand::{XorShiftRng, SeedableRng};
use bigint::hash::H256; use bigint::hash::H256;
use util::journaldb::{self, Algorithm}; use util::journaldb::{self, Algorithm};
use util::kvdb::{Database, DatabaseConfig}; use util::kvdb::{Database, DatabaseConfig};
use util::memorydb::MemoryDB; use memorydb::MemoryDB;
use parking_lot::Mutex; use parking_lot::Mutex;
use devtools::RandomTempPath; use devtools::RandomTempPath;
@ -99,7 +99,7 @@ fn get_code_from_prev_chunk() {
use rlp::RlpStream; use rlp::RlpStream;
use bigint::prelude::U256; use bigint::prelude::U256;
use bigint::hash::H256; use bigint::hash::H256;
use util::HashDB; use hashdb::HashDB;
use account_db::{AccountDBMut, AccountDB}; use account_db::{AccountDBMut, AccountDB};

View File

@ -23,7 +23,7 @@ use service::ClientIoMessage;
use io::IoChannel; use io::IoChannel;
use bigint::hash::H256; use bigint::hash::H256;
use util::Bytes; use bytes::Bytes;
use std::sync::Arc; use std::sync::Arc;

View File

@ -43,6 +43,7 @@ use bigint::prelude::U256;
use bigint::hash::{H256, H2048}; use bigint::hash::{H256, H2048};
use parking_lot::RwLock; use parking_lot::RwLock;
use util::*; use util::*;
use bytes::Bytes;
/// Parameters common to ethereum-like blockchains. /// Parameters common to ethereum-like blockchains.
/// NOTE: when adding bugfix hard-fork parameters, /// NOTE: when adding bugfix hard-fork parameters,
@ -69,6 +70,8 @@ pub struct CommonParams {
pub fork_block: Option<(BlockNumber, H256)>, pub fork_block: Option<(BlockNumber, H256)>,
/// Number of first block where EIP-98 rules begin. /// Number of first block where EIP-98 rules begin.
pub eip98_transition: BlockNumber, pub eip98_transition: BlockNumber,
/// Number of first block where EIP-658 rules begin.
pub eip658_transition: BlockNumber,
/// Number of first block where EIP-155 rules begin. /// Number of first block where EIP-155 rules begin.
pub eip155_transition: BlockNumber, pub eip155_transition: BlockNumber,
/// Validate block receipts root. /// Validate block receipts root.
@ -124,7 +127,7 @@ impl CommonParams {
schedule.have_static_call = block_number >= self.eip214_transition; schedule.have_static_call = block_number >= self.eip214_transition;
schedule.have_return_data = block_number >= self.eip211_transition; schedule.have_return_data = block_number >= self.eip211_transition;
if block_number >= self.eip210_transition { if block_number >= self.eip210_transition {
schedule.blockhash_gas = 350; schedule.blockhash_gas = 800;
} }
if block_number >= self.dust_protection_transition { if block_number >= self.dust_protection_transition {
schedule.kill_dust = match self.remove_dust_contracts { schedule.kill_dust = match self.remove_dust_contracts {
@ -171,6 +174,7 @@ impl From<ethjson::spec::Params> for CommonParams {
eip210_contract_gas: p.eip210_contract_gas.map_or(1000000.into(), Into::into), eip210_contract_gas: p.eip210_contract_gas.map_or(1000000.into(), Into::into),
eip211_transition: p.eip211_transition.map_or(BlockNumber::max_value(), Into::into), eip211_transition: p.eip211_transition.map_or(BlockNumber::max_value(), Into::into),
eip214_transition: p.eip214_transition.map_or(BlockNumber::max_value(), Into::into), eip214_transition: p.eip214_transition.map_or(BlockNumber::max_value(), Into::into),
eip658_transition: p.eip658_transition.map_or(BlockNumber::max_value(), Into::into),
dust_protection_transition: p.dust_protection_transition.map_or(BlockNumber::max_value(), Into::into), dust_protection_transition: p.dust_protection_transition.map_or(BlockNumber::max_value(), Into::into),
nonce_cap_increment: p.nonce_cap_increment.map_or(64, Into::into), nonce_cap_increment: p.nonce_cap_increment.map_or(64, Into::into),
remove_dust_contracts: p.remove_dust_contracts.unwrap_or(false), remove_dust_contracts: p.remove_dust_contracts.unwrap_or(false),
@ -228,7 +232,33 @@ pub struct Spec {
genesis_state: PodState, genesis_state: PodState,
} }
fn load_from<T: AsRef<Path>>(cache_dir: T, s: ethjson::spec::Spec) -> Result<Spec, Error> { #[cfg(test)]
impl Clone for Spec {
fn clone(&self) -> Spec {
Spec {
name: self.name.clone(),
engine: self.engine.clone(),
data_dir: self.data_dir.clone(),
nodes: self.nodes.clone(),
parent_hash: self.parent_hash.clone(),
transactions_root: self.transactions_root.clone(),
receipts_root: self.receipts_root.clone(),
author: self.author.clone(),
difficulty: self.difficulty.clone(),
gas_limit: self.gas_limit.clone(),
gas_used: self.gas_used.clone(),
timestamp: self.timestamp.clone(),
extra_data: self.extra_data.clone(),
seal_rlp: self.seal_rlp.clone(),
constructors: self.constructors.clone(),
state_root_memo: RwLock::new(*self.state_root_memo.read()),
genesis_state: self.genesis_state.clone(),
}
}
}
/// Load from JSON object.
pub fn load_from<T: AsRef<Path>>(cache_dir: T, s: ethjson::spec::Spec) -> Result<Spec, Error> {
let builtins = s.accounts.builtins().into_iter().map(|p| (p.0.into(), From::from(p.1))).collect(); let builtins = s.accounts.builtins().into_iter().map(|p| (p.0.into(), From::from(p.1))).collect();
let g = Genesis::from(s.genesis); let g = Genesis::from(s.genesis);
let GenericSeal(seal_rlp) = g.seal.into(); let GenericSeal(seal_rlp) = g.seal.into();

View File

@ -23,6 +23,9 @@ use hash::{KECCAK_EMPTY, KECCAK_NULL_RLP, keccak};
use bigint::prelude::U256; use bigint::prelude::U256;
use bigint::hash::H256; use bigint::hash::H256;
use util::*; use util::*;
use bytes::{Bytes, ToPretty};
use trie;
use trie::{SecTrieDB, Trie, TrieFactory, TrieError};
use pod_account::*; use pod_account::*;
use rlp::*; use rlp::*;
use lru_cache::LruCache; use lru_cache::LruCache;
@ -450,8 +453,8 @@ impl Account {
/// `storage_key` is the hash of the desired storage key, meaning /// `storage_key` is the hash of the desired storage key, meaning
/// this will only work correctly under a secure trie. /// this will only work correctly under a secure trie.
pub fn prove_storage(&self, db: &HashDB, storage_key: H256) -> Result<(Vec<Bytes>, H256), Box<TrieError>> { pub fn prove_storage(&self, db: &HashDB, storage_key: H256) -> Result<(Vec<Bytes>, H256), Box<TrieError>> {
use util::trie::{Trie, TrieDB}; use trie::{Trie, TrieDB};
use util::trie::recorder::Recorder; use trie::recorder::Recorder;
let mut recorder = Recorder::new(); let mut recorder = Recorder::new();
@ -475,6 +478,7 @@ impl fmt::Debug for Account {
mod tests { mod tests {
use rlp::{UntrustedRlp, RlpType, Compressible}; use rlp::{UntrustedRlp, RlpType, Compressible};
use util::*; use util::*;
use bytes::Bytes;
use super::*; use super::*;
use account_db::*; use account_db::*;

View File

@ -28,7 +28,7 @@ use state::Account;
use bigint::hash::H256; use bigint::hash::H256;
use parking_lot::Mutex; use parking_lot::Mutex;
use util::{Address, MemoryDB}; use util::{Address, MemoryDB};
use util::hashdb::{AsHashDB, HashDB, DBValue}; use hashdb::{AsHashDB, HashDB, DBValue};
/// State backend. See module docs for more details. /// State backend. See module docs for more details.
pub trait Backend: Send { pub trait Backend: Send {

View File

@ -45,9 +45,12 @@ use evm::{Factory as EvmFactory};
use bigint::prelude::U256; use bigint::prelude::U256;
use bigint::hash::H256; use bigint::hash::H256;
use util::*; use util::*;
use bytes::Bytes;
use trie;
use trie::{Trie, TrieError, TrieDB};
use trie::recorder::Recorder;
use util::trie;
use util::trie::recorder::Recorder;
mod account; mod account;
mod substate; mod substate;
@ -500,9 +503,10 @@ impl<B: Backend> State<B> {
self.ensure_cached(a, RequireCache::None, false, |a| a.map_or(false, |a| !a.is_null())) self.ensure_cached(a, RequireCache::None, false, |a| a.map_or(false, |a| !a.is_null()))
} }
/// Determine whether an account exists and has code. /// Determine whether an account exists and has code or non-zero nonce.
pub fn exists_and_has_code(&self, a: &Address) -> trie::Result<bool> { pub fn exists_and_has_code_or_nonce(&self, a: &Address) -> trie::Result<bool> {
self.ensure_cached(a, RequireCache::CodeSize, false, |a| a.map_or(false, |a| a.code_size().map_or(false, |size| size != 0))) self.ensure_cached(a, RequireCache::CodeSize, false,
|a| a.map_or(false, |a| a.code_hash() != KECCAK_EMPTY || *a.nonce() != self.account_start_nonce))
} }
/// Get the balance of account `a`. /// Get the balance of account `a`.
@ -694,15 +698,26 @@ impl<B: Backend> State<B> {
let options = TransactOptions::new(tracer, vm_tracer); let options = TransactOptions::new(tracer, vm_tracer);
let e = self.execute(env_info, engine, t, options, false)?; let e = self.execute(env_info, engine, t, options, false)?;
let state_root = if env_info.number < engine.params().eip98_transition || env_info.number < engine.params().validate_receipts_transition { let eip658 = env_info.number >= engine.params().eip658_transition;
let no_intermediate_commits =
eip658 ||
(env_info.number >= engine.params().eip98_transition && env_info.number >= engine.params().validate_receipts_transition);
let state_root = if no_intermediate_commits {
None
} else {
self.commit()?; self.commit()?;
Some(self.root().clone()) Some(self.root().clone())
};
let status_byte = if eip658 {
Some(if e.exception.is_some() { 0 } else { 1 })
} else { } else {
None None
}; };
let output = e.output; let output = e.output;
let receipt = Receipt::new(state_root, e.cumulative_gas_used, e.logs); let receipt = Receipt::new(state_root, status_byte, e.cumulative_gas_used, e.logs);
trace!(target: "state", "Transaction receipt: {:?}", receipt); trace!(target: "state", "Transaction receipt: {:?}", receipt);
Ok(ApplyOutcome { Ok(ApplyOutcome {

View File

@ -21,7 +21,7 @@ use util::cache::MemoryLruCache;
use util::journaldb::JournalDB; use util::journaldb::JournalDB;
use util::kvdb::KeyValueDB; use util::kvdb::KeyValueDB;
use bigint::hash::H256; use bigint::hash::H256;
use util::hashdb::HashDB; use hashdb::HashDB;
use state::{self, Account}; use state::{self, Account};
use header::BlockNumber; use header::BlockNumber;
use hash::keccak; use hash::keccak;

View File

@ -14,6 +14,7 @@ use rustc_hex::FromHex;
use bigint::hash::H256; use bigint::hash::H256;
use util::*; use util::*;
use bytes::BytesRef;
evm_test!{test_blockhash_eip210: test_blockhash_eip210_jit, test_blockhash_eip210_int} evm_test!{test_blockhash_eip210: test_blockhash_eip210_jit, test_blockhash_eip210_int}
fn test_blockhash_eip210(factory: Factory) { fn test_blockhash_eip210(factory: Factory) {
@ -23,7 +24,7 @@ fn test_blockhash_eip210(factory: Factory) {
let test_blockhash_contract = "73fffffffffffffffffffffffffffffffffffffffe33141561007a57600143036020526000356101006020510755600061010060205107141561005057600035610100610100602051050761010001555b6000620100006020510714156100755760003561010062010000602051050761020001555b61014a565b4360003512151561009057600060405260206040f35b610100600035430312156100b357610100600035075460605260206060f3610149565b62010000600035430312156100d157600061010060003507146100d4565b60005b156100f6576101006101006000350507610100015460805260206080f3610148565b630100000060003543031215610116576000620100006000350714610119565b60005b1561013c57610100620100006000350507610200015460a052602060a0f3610147565b600060c052602060c0f35b5b5b5b5b"; let test_blockhash_contract = "73fffffffffffffffffffffffffffffffffffffffe33141561007a57600143036020526000356101006020510755600061010060205107141561005057600035610100610100602051050761010001555b6000620100006020510714156100755760003561010062010000602051050761020001555b61014a565b4360003512151561009057600060405260206040f35b610100600035430312156100b357610100600035075460605260206060f3610149565b62010000600035430312156100d157600061010060003507146100d4565b60005b156100f6576101006101006000350507610100015460805260206080f3610148565b630100000060003543031215610116576000620100006000350714610119565b60005b1561013c57610100620100006000350507610200015460a052602060a0f3610147565b600060c052602060c0f35b5b5b5b5b";
let blockhash_contract_code = Arc::new(test_blockhash_contract.from_hex().unwrap()); let blockhash_contract_code = Arc::new(test_blockhash_contract.from_hex().unwrap());
let blockhash_contract_code_hash = keccak(blockhash_contract_code.as_ref()); let blockhash_contract_code_hash = keccak(blockhash_contract_code.as_ref());
let engine = TestEngine::new_metropolis(); let engine = TestEngine::new_constantinople();
let mut env_info = EnvInfo::default(); let mut env_info = EnvInfo::default();
// populate state with 256 last hashes // populate state with 256 last hashes

View File

@ -23,6 +23,7 @@ use client::{BlockChainClient, Client, ClientConfig};
use bigint::prelude::U256; use bigint::prelude::U256;
use bigint::hash::H256; use bigint::hash::H256;
use util::*; use util::*;
use bytes::Bytes;
use spec::*; use spec::*;
use account_provider::AccountProvider; use account_provider::AccountProvider;
use state_db::StateDB; use state_db::StateDB;
@ -41,15 +42,6 @@ use transaction::{Action, Transaction, SignedTransaction};
use rlp::{self, RlpStream}; use rlp::{self, RlpStream};
use views::BlockView; use views::BlockView;
#[cfg(feature = "json-tests")]
pub enum ChainEra {
Frontier,
Homestead,
Eip150,
_Eip161,
TransitionTest,
}
pub struct TestEngine { pub struct TestEngine {
engine: Arc<Engine>, engine: Arc<Engine>,
max_depth: usize, max_depth: usize,
@ -63,9 +55,16 @@ impl TestEngine {
} }
} }
pub fn new_metropolis() -> TestEngine { pub fn new_byzantium() -> TestEngine {
TestEngine { TestEngine {
engine: ethereum::new_metropolis_test().engine, engine: ethereum::new_byzantium_test().engine,
max_depth: 0,
}
}
pub fn new_constantinople() -> TestEngine {
TestEngine {
engine: ethereum::new_constantinople_test().engine,
max_depth: 0, max_depth: 0,
} }
} }
@ -426,5 +425,8 @@ pub fn get_default_ethash_params() -> EthashParams {
max_gas_limit: U256::max_value(), max_gas_limit: U256::max_value(),
min_gas_price_transition: u64::max_value(), min_gas_price_transition: u64::max_value(),
min_gas_price: U256::zero(), min_gas_price: U256::zero(),
eip649_transition: u64::max_value(),
eip649_delay: 3_000_000,
eip649_reward: None,
} }
} }

View File

@ -17,7 +17,8 @@
//! Simple executive tracer. //! Simple executive tracer.
use bigint::prelude::U256; use bigint::prelude::U256;
use util::{Bytes, Address}; use util::Address;
use bytes::Bytes;
use vm::ActionParams; use vm::ActionParams;
use trace::trace::{Call, Create, Action, Res, CreateResult, CallResult, VMTrace, VMOperation, VMExecutedOperation, MemoryDiff, StorageDiff, Suicide, Reward, RewardType}; use trace::trace::{Call, Create, Action, Res, CreateResult, CallResult, VMTrace, VMOperation, VMExecutedOperation, MemoryDiff, StorageDiff, Suicide, Reward, RewardType};
use trace::{Tracer, VMTracer, FlatTrace, TraceError}; use trace::{Tracer, VMTracer, FlatTrace, TraceError};

View File

@ -39,7 +39,8 @@ pub use self::types::filter::{Filter, AddressesFilter};
use bigint::prelude::U256; use bigint::prelude::U256;
use bigint::hash::H256; use bigint::hash::H256;
use util::{Bytes, Address, DBTransaction}; use util::{Address, DBTransaction};
use bytes::Bytes;
use self::trace::{Call, Create}; use self::trace::{Call, Create};
use vm::ActionParams; use vm::ActionParams;
use header::BlockNumber; use header::BlockNumber;

View File

@ -17,7 +17,8 @@
//! Nonoperative tracer. //! Nonoperative tracer.
use bigint::prelude::U256; use bigint::prelude::U256;
use util::{Bytes, Address}; use util::Address;
use bytes::Bytes;
use vm::ActionParams; use vm::ActionParams;
use trace::{Tracer, VMTracer, FlatTrace, TraceError}; use trace::{Tracer, VMTracer, FlatTrace, TraceError};
use trace::trace::{Call, Create, VMTrace, RewardType}; use trace::trace::{Call, Create, VMTrace, RewardType};

View File

@ -43,6 +43,10 @@ pub enum Error {
MutableCallInStaticContext, MutableCallInStaticContext,
/// Wasm error /// Wasm error
Wasm, Wasm,
/// Contract tried to access past the return data buffer.
OutOfBounds,
/// Execution has been reverted with REVERT instruction.
Reverted,
} }
impl<'a> From<&'a VmError> for Error { impl<'a> From<&'a VmError> for Error {
@ -57,6 +61,8 @@ impl<'a> From<&'a VmError> for Error {
VmError::Wasm { .. } => Error::Wasm, VmError::Wasm { .. } => Error::Wasm,
VmError::Internal(_) => Error::Internal, VmError::Internal(_) => Error::Internal,
VmError::MutableCallInStaticContext => Error::MutableCallInStaticContext, VmError::MutableCallInStaticContext => Error::MutableCallInStaticContext,
VmError::OutOfBounds => Error::OutOfBounds,
VmError::Reverted => Error::Reverted,
} }
} }
} }
@ -80,6 +86,8 @@ impl fmt::Display for Error {
Wasm => "Wasm runtime error", Wasm => "Wasm runtime error",
Internal => "Internal error", Internal => "Internal error",
MutableCallInStaticContext => "Mutable Call In Static Context", MutableCallInStaticContext => "Mutable Call In Static Context",
OutOfBounds => "Out of bounds",
Reverted => "Reverted",
}; };
message.fmt(f) message.fmt(f)
} }
@ -98,6 +106,8 @@ impl Encodable for Error {
BuiltIn => 6, BuiltIn => 6,
MutableCallInStaticContext => 7, MutableCallInStaticContext => 7,
Wasm => 8, Wasm => 8,
OutOfBounds => 9,
Reverted => 10,
}; };
s.append_internal(&value); s.append_internal(&value);
@ -118,6 +128,8 @@ impl Decodable for Error {
6 => Ok(BuiltIn), 6 => Ok(BuiltIn),
7 => Ok(MutableCallInStaticContext), 7 => Ok(MutableCallInStaticContext),
8 => Ok(Wasm), 8 => Ok(Wasm),
9 => Ok(OutOfBounds),
10 => Ok(Reverted),
_ => Err(DecoderError::Custom("Invalid error type")), _ => Err(DecoderError::Custom("Invalid error type")),
} }
} }

View File

@ -17,7 +17,8 @@
//! Tracing datatypes. //! Tracing datatypes.
use bigint::prelude::U256; use bigint::prelude::U256;
use util::{Bytes, Address}; use util::Address;
use bytes::Bytes;
use hash::keccak; use hash::keccak;
use bloomable::Bloomable; use bloomable::Bloomable;
use rlp::*; use rlp::*;

View File

@ -22,7 +22,8 @@ use hash::keccak;
use heapsize::HeapSizeOf; use heapsize::HeapSizeOf;
use bigint::prelude::U256; use bigint::prelude::U256;
use bigint::hash::H256; use bigint::hash::H256;
use util::{Address, Bytes}; use util::Address;
use bytes::Bytes;
use ethkey::{Signature, Secret, Public, recover, public_to_address, Error as EthkeyError}; use ethkey::{Signature, Secret, Public, recover, public_to_address, Error as EthkeyError};
use error::*; use error::*;
use evm::Schedule; use evm::Schedule;

View File

@ -22,7 +22,8 @@ use std::collections::hash_map::Entry;
use bigint::hash::H256; use bigint::hash::H256;
use native_contracts::TransactAcl as Contract; use native_contracts::TransactAcl as Contract;
use client::{EngineClient, BlockId, ChainNotify}; use client::{EngineClient, BlockId, ChainNotify};
use util::{Address, Bytes}; use util::Address;
use bytes::Bytes;
use parking_lot::{Mutex, RwLock}; use parking_lot::{Mutex, RwLock};
use futures::{self, Future}; use futures::{self, Future};
use spec::CommonParams; use spec::CommonParams;

View File

@ -77,7 +77,7 @@ pub mod blocks {
use heapsize::HeapSizeOf; use heapsize::HeapSizeOf;
use bigint::prelude::U256; use bigint::prelude::U256;
use bigint::hash::H256; use bigint::hash::H256;
use util::Bytes; use bytes::Bytes;
/// A mode for verifying blocks. /// A mode for verifying blocks.
pub struct Blocks; pub struct Blocks;

View File

@ -26,8 +26,8 @@ use hash::keccak;
use triehash::ordered_trie_root; use triehash::ordered_trie_root;
use heapsize::HeapSizeOf; use heapsize::HeapSizeOf;
use bigint::hash::H256; use bigint::hash::H256;
use util::*;
use unexpected::{Mismatch, OutOfBounds}; use unexpected::{Mismatch, OutOfBounds};
use bytes::Bytes;
use engines::Engine; use engines::Engine;
use error::{BlockError, Error}; use error::{BlockError, Error};
use blockchain::*; use blockchain::*;
@ -276,7 +276,7 @@ mod tests {
use bigint::hash::{H256, H2048}; use bigint::hash::{H256, H2048};
use triehash::ordered_trie_root; use triehash::ordered_trie_root;
use unexpected::{Mismatch, OutOfBounds}; use unexpected::{Mismatch, OutOfBounds};
use util::*; use bytes::Bytes;
use ethkey::{Random, Generator}; use ethkey::{Random, Generator};
use header::*; use header::*;
use verification::*; use verification::*;

View File

@ -18,7 +18,7 @@
use hash::keccak; use hash::keccak;
use bigint::hash::H256; use bigint::hash::H256;
use util::*; use bytes::Bytes;
use header::*; use header::*;
use transaction::*; use transaction::*;
use super::{TransactionView, HeaderView}; use super::{TransactionView, HeaderView};

View File

@ -18,7 +18,7 @@
use hash::keccak; use hash::keccak;
use bigint::hash::H256; use bigint::hash::H256;
use util::*; use bytes::Bytes;
use header::*; use header::*;
use transaction::*; use transaction::*;
use super::{TransactionView, HeaderView}; use super::{TransactionView, HeaderView};

View File

@ -19,7 +19,8 @@
use hash::keccak; use hash::keccak;
use bigint::prelude::U256; use bigint::prelude::U256;
use bigint::hash::{H256, H2048}; use bigint::hash::{H256, H2048};
use util::{Bytes, Address}; use util::Address;
use bytes::Bytes;
use rlp::Rlp; use rlp::Rlp;
use header::BlockNumber; use header::BlockNumber;

View File

@ -17,7 +17,7 @@
//! View onto transaction rlp //! View onto transaction rlp
use bigint::prelude::U256; use bigint::prelude::U256;
use bigint::hash::H256; use bigint::hash::H256;
use util::Bytes; use bytes::Bytes;
use hash::keccak; use hash::keccak;
use rlp::Rlp; use rlp::Rlp;

View File

@ -7,6 +7,7 @@ authors = ["Parity Technologies <admin@parity.io>"]
[dependencies] [dependencies]
rlp = { path = "../../util/rlp" } rlp = { path = "../../util/rlp" }
rlp_derive = { path = "../../util/rlp_derive" } rlp_derive = { path = "../../util/rlp_derive" }
ethcore-bytes = { path = "../../util/bytes" }
ethcore-util = { path = "../../util" } ethcore-util = { path = "../../util" }
ethcore-bigint = { path = "../../util/bigint" } ethcore-bigint = { path = "../../util/bigint" }
ethjson = { path = "../../json" } ethjson = { path = "../../json" }

Some files were not shown because too many files have changed in this diff Show More