Extract some parts of miner from ethcore. (#7353)

* Move miner away from ethcore.

* Fix ethcore to use miner/transaction.

* Fix tests and warnings.

* fixed incorrect merge of the test in the documentation
This commit is contained in:
Tomasz Drwięga 2018-01-11 17:49:10 +01:00 committed by Marek Kotewicz
parent 9a12945304
commit f044b61f42
74 changed files with 778 additions and 522 deletions

51
Cargo.lock generated
View File

@ -475,7 +475,9 @@ dependencies = [
"ethcore-devtools 1.9.0", "ethcore-devtools 1.9.0",
"ethcore-io 1.9.0", "ethcore-io 1.9.0",
"ethcore-logger 1.9.0", "ethcore-logger 1.9.0",
"ethcore-miner 1.9.0",
"ethcore-stratum 1.9.0", "ethcore-stratum 1.9.0",
"ethcore-transaction 0.1.0",
"ethereum-types 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "ethereum-types 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"ethjson 0.1.0", "ethjson 0.1.0",
"ethkey 0.3.0", "ethkey 0.3.0",
@ -485,7 +487,6 @@ dependencies = [
"hardware-wallet 1.9.0", "hardware-wallet 1.9.0",
"hashdb 0.1.1", "hashdb 0.1.1",
"heapsize 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.10.0-a.0 (git+https://github.com/paritytech/hyper)",
"itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)",
"journaldb 0.1.0", "journaldb 0.1.0",
"keccak-hash 0.1.0", "keccak-hash 0.1.0",
@ -493,7 +494,6 @@ dependencies = [
"kvdb-memorydb 0.1.0", "kvdb-memorydb 0.1.0",
"kvdb-rocksdb 0.1.0", "kvdb-rocksdb 0.1.0",
"lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"linked-hash-map 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"lru-cache 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "lru-cache 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"macros 0.1.0", "macros 0.1.0",
@ -516,9 +516,7 @@ dependencies = [
"semantic_version 0.1.0", "semantic_version 0.1.0",
"snappy 0.1.0 (git+https://github.com/paritytech/rust-snappy)", "snappy 0.1.0 (git+https://github.com/paritytech/rust-snappy)",
"stats 0.1.0", "stats 0.1.0",
"table 0.1.0",
"time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)",
"transient-hashmap 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"triehash 0.1.0", "triehash 0.1.0",
"unexpected 0.1.0", "unexpected 0.1.0",
"using_queue 0.1.0", "using_queue 0.1.0",
@ -565,6 +563,7 @@ dependencies = [
"ethcore-bytes 0.1.0", "ethcore-bytes 0.1.0",
"ethcore-io 1.9.0", "ethcore-io 1.9.0",
"ethcore-network 1.9.0", "ethcore-network 1.9.0",
"ethcore-transaction 0.1.0",
"ethereum-types 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "ethereum-types 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"evm 0.1.0", "evm 0.1.0",
"futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
@ -609,6 +608,28 @@ dependencies = [
"time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "ethcore-miner"
version = "1.9.0"
dependencies = [
"common-types 0.1.0",
"ethash 1.9.0",
"ethcore-transaction 0.1.0",
"ethereum-types 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"ethkey 0.3.0",
"futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.10.0-a.0 (git+https://github.com/paritytech/hyper)",
"keccak-hash 0.1.0",
"linked-hash-map 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"native-contracts 0.1.0",
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"table 0.1.0",
"transient-hashmap 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "ethcore-network" name = "ethcore-network"
version = "1.9.0" version = "1.9.0"
@ -695,6 +716,21 @@ dependencies = [
"tokio-io 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "ethcore-transaction"
version = "0.1.0"
dependencies = [
"ethereum-types 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"ethjson 0.1.0",
"ethkey 0.3.0",
"evm 0.1.0",
"heapsize 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"keccak-hash 0.1.0",
"rlp 0.2.1",
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"unexpected 0.1.0",
]
[[package]] [[package]]
name = "ethcrypto" name = "ethcrypto"
version = "0.1.0" version = "0.1.0"
@ -811,6 +847,7 @@ dependencies = [
"ethcore-io 1.9.0", "ethcore-io 1.9.0",
"ethcore-light 1.9.0", "ethcore-light 1.9.0",
"ethcore-network 1.9.0", "ethcore-network 1.9.0",
"ethcore-transaction 0.1.0",
"ethereum-types 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "ethereum-types 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"ethkey 0.3.0", "ethkey 0.3.0",
"heapsize 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
@ -854,6 +891,7 @@ dependencies = [
"docopt 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "docopt 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
"ethcore 1.9.0", "ethcore 1.9.0",
"ethcore-bytes 0.1.0", "ethcore-bytes 0.1.0",
"ethcore-transaction 0.1.0",
"ethereum-types 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "ethereum-types 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"ethjson 0.1.0", "ethjson 0.1.0",
"evm 0.1.0", "evm 0.1.0",
@ -1897,9 +1935,11 @@ dependencies = [
"ethcore-io 1.9.0", "ethcore-io 1.9.0",
"ethcore-light 1.9.0", "ethcore-light 1.9.0",
"ethcore-logger 1.9.0", "ethcore-logger 1.9.0",
"ethcore-miner 1.9.0",
"ethcore-network 1.9.0", "ethcore-network 1.9.0",
"ethcore-secretstore 1.0.0", "ethcore-secretstore 1.0.0",
"ethcore-stratum 1.9.0", "ethcore-stratum 1.9.0",
"ethcore-transaction 0.1.0",
"ethereum-types 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "ethereum-types 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"ethkey 0.3.0", "ethkey 0.3.0",
"ethsync 1.9.0", "ethsync 1.9.0",
@ -2053,6 +2093,7 @@ version = "0.1.0"
dependencies = [ dependencies = [
"ethcore 1.9.0", "ethcore 1.9.0",
"ethcore-io 1.9.0", "ethcore-io 1.9.0",
"ethcore-transaction 0.1.0",
"ethkey 0.3.0", "ethkey 0.3.0",
"kvdb 0.1.0", "kvdb 0.1.0",
"kvdb-memorydb 0.1.0", "kvdb-memorydb 0.1.0",
@ -2091,7 +2132,9 @@ dependencies = [
"ethcore-io 1.9.0", "ethcore-io 1.9.0",
"ethcore-light 1.9.0", "ethcore-light 1.9.0",
"ethcore-logger 1.9.0", "ethcore-logger 1.9.0",
"ethcore-miner 1.9.0",
"ethcore-network 1.9.0", "ethcore-network 1.9.0",
"ethcore-transaction 0.1.0",
"ethcrypto 0.1.0", "ethcrypto 0.1.0",
"ethereum-types 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "ethereum-types 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"ethjson 0.1.0", "ethjson 0.1.0",

View File

@ -35,12 +35,14 @@ jsonrpc-core = { git = "https://github.com/paritytech/jsonrpc.git", branch = "pa
ethsync = { path = "sync" } ethsync = { path = "sync" }
ethcore = { path = "ethcore" } ethcore = { path = "ethcore" }
ethcore-bytes = { path = "util/bytes" } ethcore-bytes = { path = "util/bytes" }
ethcore-io = { path = "util/io" }
ethcore-devtools = { path = "devtools" } ethcore-devtools = { path = "devtools" }
ethcore-io = { path = "util/io" }
ethcore-light = { path = "ethcore/light" } ethcore-light = { path = "ethcore/light" }
ethcore-logger = { path = "logger" } ethcore-logger = { path = "logger" }
ethcore-stratum = { path = "stratum" } ethcore-miner = { path = "miner" }
ethcore-network = { path = "util/network" } ethcore-network = { path = "util/network" }
ethcore-stratum = { path = "stratum" }
ethcore-transaction = { path = "ethcore/transaction" }
ethereum-types = "0.1" ethereum-types = "0.1"
node-filter = { path = "ethcore/node_filter" } node-filter = { path = "ethcore/node_filter" }
ethkey = { path = "ethkey" } ethkey = { path = "ethkey" }
@ -119,9 +121,11 @@ members = [
"chainspec", "chainspec",
"dapps/js-glue", "dapps/js-glue",
"ethcore/wasm/run", "ethcore/wasm/run",
"ethcore/types",
"ethkey/cli", "ethkey/cli",
"ethstore/cli", "ethstore/cli",
"evmbin", "evmbin",
"miner",
"transaction-pool", "transaction-pool",
"whisper", "whisper",
] ]

View File

@ -22,7 +22,9 @@ 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-logger = { path = "../logger" } ethcore-logger = { path = "../logger" }
ethcore-miner = { path = "../miner" }
ethcore-stratum = { path = "../stratum" } ethcore-stratum = { path = "../stratum" }
ethcore-transaction = { path = "./transaction" }
ethereum-types = "0.1" ethereum-types = "0.1"
memory-cache = { path = "../util/memory_cache" } memory-cache = { path = "../util/memory_cache" }
ethjson = { path = "../json" } ethjson = { path = "../json" }
@ -32,10 +34,8 @@ evm = { path = "evm" }
futures = "0.1" futures = "0.1"
hardware-wallet = { path = "../hw" } hardware-wallet = { path = "../hw" }
heapsize = "0.4" heapsize = "0.4"
hyper = { git = "https://github.com/paritytech/hyper", default-features = false }
itertools = "0.5" itertools = "0.5"
lazy_static = "0.2" lazy_static = "0.2"
linked-hash-map = "0.5"
log = "0.3" log = "0.3"
lru-cache = "0.1" lru-cache = "0.1"
native-contracts = { path = "native_contracts" } native-contracts = { path = "native_contracts" }
@ -59,9 +59,7 @@ rust-crypto = "0.2.34"
rustc-hex = "1.0" rustc-hex = "1.0"
stats = { path = "../util/stats" } stats = { path = "../util/stats" }
time = "0.1" time = "0.1"
transient-hashmap = "0.4"
using_queue = { path = "../util/using_queue" } using_queue = { path = "../util/using_queue" }
table = { path = "../util/table" }
bloomable = { path = "../util/bloomable" } bloomable = { path = "../util/bloomable" }
vm = { path = "vm" } vm = { path = "vm" }
wasm = { path = "wasm" } wasm = { path = "wasm" }
@ -79,7 +77,7 @@ jit = ["evm/jit"]
evm-debug = ["slow-blocks"] evm-debug = ["slow-blocks"]
evm-debug-tests = ["evm-debug", "evm/evm-debug-tests"] evm-debug-tests = ["evm-debug", "evm/evm-debug-tests"]
slow-blocks = [] # Use SLOW_TX_DURATION="50" (compile time!) to track transactions over 50ms slow-blocks = [] # Use SLOW_TX_DURATION="50" (compile time!) to track transactions over 50ms
json-tests = [] json-tests = ["ethcore-transaction/json-tests"]
test-heavy = [] test-heavy = []
default = [] default = []
benches = [] benches = []

View File

@ -10,6 +10,7 @@ authors = ["Parity Technologies <admin@parity.io>"]
log = "0.3" log = "0.3"
ethcore = { path = ".."} ethcore = { path = ".."}
ethcore-bytes = { path = "../../util/bytes" } ethcore-bytes = { path = "../../util/bytes" }
ethcore-transaction = { path = "../transaction" }
ethereum-types = "0.1" ethereum-types = "0.1"
memorydb = { path = "../../util/memorydb" } memorydb = { path = "../../util/memorydb" }
patricia-trie = { path = "../../util/patricia_trie" } patricia-trie = { path = "../../util/patricia_trie" }

View File

@ -57,6 +57,7 @@ extern crate bincode;
extern crate ethcore_io as io; extern crate ethcore_io as io;
extern crate ethcore_network as network; extern crate ethcore_network as network;
extern crate ethcore_bytes as bytes; extern crate ethcore_bytes as bytes;
extern crate ethcore_transaction as transaction;
extern crate ethereum_types; extern crate ethereum_types;
extern crate ethcore; extern crate ethcore;
extern crate evm; extern crate evm;

View File

@ -18,7 +18,7 @@
//! //!
//! This uses a "Provider" to answer requests. //! This uses a "Provider" to answer requests.
use ethcore::transaction::UnverifiedTransaction; use transaction::UnverifiedTransaction;
use io::TimerToken; use io::TimerToken;
use network::{HostInfo, NetworkProtocolHandler, NetworkContext, PeerId}; use network::{HostInfo, NetworkProtocolHandler, NetworkContext, PeerId};

View File

@ -20,9 +20,9 @@
use ethcore::blockchain_info::BlockChainInfo; use ethcore::blockchain_info::BlockChainInfo;
use ethcore::client::{EachBlockWith, TestBlockChainClient}; use ethcore::client::{EachBlockWith, TestBlockChainClient};
use ethcore::ids::BlockId; use ethcore::ids::BlockId;
use ethcore::transaction::{Action, PendingTransaction};
use ethcore::encoded; use ethcore::encoded;
use network::{PeerId, NodeId}; use network::{PeerId, NodeId};
use transaction::{Action, PendingTransaction};
use net::context::IoContext; use net::context::IoContext;
use net::status::{Capabilities, Status}; use net::status::{Capabilities, Status};

View File

@ -24,7 +24,7 @@ use ethcore::engines::{EthEngine, StateDependentProof};
use ethcore::machine::EthereumMachine; use ethcore::machine::EthereumMachine;
use ethcore::receipt::Receipt; use ethcore::receipt::Receipt;
use ethcore::state::{self, ProvedExecution}; use ethcore::state::{self, ProvedExecution};
use ethcore::transaction::SignedTransaction; use transaction::SignedTransaction;
use vm::EnvInfo; use vm::EnvInfo;
use hash::{KECCAK_NULL_RLP, KECCAK_EMPTY, KECCAK_EMPTY_LIST_RLP, keccak}; use hash::{KECCAK_NULL_RLP, KECCAK_EMPTY, KECCAK_EMPTY_LIST_RLP, keccak};

View File

@ -21,11 +21,11 @@ use std::sync::Arc;
use ethcore::blockchain_info::BlockChainInfo; use ethcore::blockchain_info::BlockChainInfo;
use ethcore::client::{BlockChainClient, ProvingBlockChainClient}; use ethcore::client::{BlockChainClient, ProvingBlockChainClient};
use ethcore::transaction::PendingTransaction;
use ethcore::ids::BlockId;
use ethcore::encoded; use ethcore::encoded;
use ethcore::ids::BlockId;
use ethereum_types::H256; use ethereum_types::H256;
use parking_lot::RwLock; use parking_lot::RwLock;
use transaction::PendingTransaction;
use cht::{self, BlockInfo}; use cht::{self, BlockInfo};
use client::{LightChainClient, AsLightClient}; use client::{LightChainClient, AsLightClient};
@ -260,7 +260,7 @@ impl<T: ProvingBlockChainClient + ?Sized> Provider for T {
} }
fn transaction_proof(&self, req: request::CompleteExecutionRequest) -> Option<request::ExecutionResponse> { fn transaction_proof(&self, req: request::CompleteExecutionRequest) -> Option<request::ExecutionResponse> {
use ethcore::transaction::Transaction; use transaction::Transaction;
let id = BlockId::Hash(req.block_hash); let id = BlockId::Hash(req.block_hash);
let nonce = match self.nonce(&req.from, id.clone()) { let nonce = match self.nonce(&req.from, id.clone()) {

View File

@ -26,8 +26,7 @@
use std::collections::{BTreeMap, HashMap}; use std::collections::{BTreeMap, HashMap};
use std::collections::hash_map::Entry; use std::collections::hash_map::Entry;
use ethcore::error::{TransactionError, TransactionImportResult}; use transaction::{self, Condition, PendingTransaction, SignedTransaction};
use ethcore::transaction::{Condition, PendingTransaction, SignedTransaction};
use ethereum_types::{H256, U256, Address}; use ethereum_types::{H256, U256, Address};
use plain_hasher::H256FastMap; use plain_hasher::H256FastMap;
@ -123,13 +122,13 @@ pub struct TransactionQueue {
impl TransactionQueue { impl TransactionQueue {
/// Import a pending transaction to be queued. /// Import a pending transaction to be queued.
pub fn import(&mut self, tx: PendingTransaction) -> Result<TransactionImportResult, TransactionError> { pub fn import(&mut self, tx: PendingTransaction) -> Result<transaction::ImportResult, transaction::Error> {
let sender = tx.sender(); let sender = tx.sender();
let hash = tx.hash(); let hash = tx.hash();
let nonce = tx.nonce; let nonce = tx.nonce;
let tx_info = TransactionInfo::from(&tx); let tx_info = TransactionInfo::from(&tx);
if self.by_hash.contains_key(&hash) { return Err(TransactionError::AlreadyImported) } if self.by_hash.contains_key(&hash) { return Err(transaction::Error::AlreadyImported) }
let res = match self.by_account.entry(sender) { let res = match self.by_account.entry(sender) {
Entry::Vacant(entry) => { Entry::Vacant(entry) => {
@ -139,14 +138,14 @@ impl TransactionQueue {
future: BTreeMap::new(), future: BTreeMap::new(),
}); });
TransactionImportResult::Current transaction::ImportResult::Current
} }
Entry::Occupied(mut entry) => { Entry::Occupied(mut entry) => {
let acct_txs = entry.get_mut(); let acct_txs = entry.get_mut();
if &nonce < acct_txs.cur_nonce.value() { if &nonce < acct_txs.cur_nonce.value() {
// don't accept txs from before known current nonce. // don't accept txs from before known current nonce.
if acct_txs.cur_nonce.is_known() { if acct_txs.cur_nonce.is_known() {
return Err(TransactionError::Old) return Err(transaction::Error::Old)
} }
// lower our assumption until corrected later. // lower our assumption until corrected later.
@ -161,7 +160,7 @@ impl TransactionQueue {
let old = ::std::mem::replace(&mut acct_txs.current[idx], tx_info); let old = ::std::mem::replace(&mut acct_txs.current[idx], tx_info);
self.by_hash.remove(&old.hash); self.by_hash.remove(&old.hash);
TransactionImportResult::Current transaction::ImportResult::Current
} }
Err(idx) => { Err(idx) => {
let cur_len = acct_txs.current.len(); let cur_len = acct_txs.current.len();
@ -183,13 +182,13 @@ impl TransactionQueue {
acct_txs.future.insert(future_nonce, future); acct_txs.future.insert(future_nonce, future);
} }
TransactionImportResult::Current transaction::ImportResult::Current
} else if idx == cur_len && acct_txs.current.last().map_or(false, |f| f.nonce + 1.into() != nonce) { } else if idx == cur_len && acct_txs.current.last().map_or(false, |f| f.nonce + 1.into() != nonce) {
trace!(target: "txqueue", "Queued future transaction for {}, nonce={}", sender, nonce); trace!(target: "txqueue", "Queued future transaction for {}, nonce={}", sender, nonce);
let future_nonce = nonce; let future_nonce = nonce;
acct_txs.future.insert(future_nonce, tx_info); acct_txs.future.insert(future_nonce, tx_info);
TransactionImportResult::Future transaction::ImportResult::Future
} else { } else {
trace!(target: "txqueue", "Queued current transaction for {}, nonce={}", sender, nonce); trace!(target: "txqueue", "Queued current transaction for {}, nonce={}", sender, nonce);
@ -197,7 +196,7 @@ impl TransactionQueue {
acct_txs.current.insert(idx, tx_info); acct_txs.current.insert(idx, tx_info);
acct_txs.adjust_future(); acct_txs.adjust_future();
TransactionImportResult::Current transaction::ImportResult::Current
} }
} }
} }
@ -331,7 +330,7 @@ impl TransactionQueue {
mod tests { mod tests {
use super::TransactionQueue; use super::TransactionQueue;
use ethereum_types::Address; use ethereum_types::Address;
use ethcore::transaction::{Transaction, PendingTransaction, Condition}; use transaction::{Transaction, PendingTransaction, Condition};
#[test] #[test]
fn queued_senders() { fn queued_senders() {

View File

@ -1094,7 +1094,7 @@ pub mod block_body {
impl Decodable for Response { impl Decodable for Response {
fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> { fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
use ethcore::header::Header as FullHeader; use ethcore::header::Header as FullHeader;
use ethcore::transaction::UnverifiedTransaction; use transaction::UnverifiedTransaction;
// check body validity. // check body validity.
let _: Vec<UnverifiedTransaction> = rlp.list_at(0)?; let _: Vec<UnverifiedTransaction> = rlp.list_at(0)?;
@ -1410,7 +1410,7 @@ pub mod contract_code {
/// A request for proof of execution. /// A request for proof of execution.
pub mod execution { pub mod execution {
use super::{Field, NoSuchOutput, OutputKind, Output}; use super::{Field, NoSuchOutput, OutputKind, Output};
use ethcore::transaction::Action; use transaction::Action;
use rlp::{Encodable, Decodable, DecoderError, RlpStream, UntrustedRlp}; use rlp::{Encodable, Decodable, DecoderError, RlpStream, UntrustedRlp};
use ethereum_types::{H256, U256, Address}; use ethereum_types::{H256, U256, Address};
use kvdb::DBValue; use kvdb::DBValue;
@ -1755,7 +1755,7 @@ mod tests {
#[test] #[test]
fn body_roundtrip() { fn body_roundtrip() {
use ethcore::transaction::{Transaction, UnverifiedTransaction}; use transaction::{Transaction, UnverifiedTransaction};
let req = IncompleteBodyRequest { let req = IncompleteBodyRequest {
hash: Field::Scalar(Default::default()), hash: Field::Scalar(Default::default()),
}; };
@ -1850,7 +1850,7 @@ mod tests {
let req = IncompleteExecutionRequest { let req = IncompleteExecutionRequest {
block_hash: Field::Scalar(Default::default()), block_hash: Field::Scalar(Default::default()),
from: Default::default(), from: Default::default(),
action: ::ethcore::transaction::Action::Create, action: ::transaction::Action::Create,
gas: 100_000.into(), gas: 100_000.into(),
gas_price: 0.into(), gas_price: 0.into(),
value: 100_000_001.into(), value: 100_000_001.into(),
@ -1880,7 +1880,7 @@ mod tests {
let reqs: Vec<_> = (0..10).map(|_| IncompleteExecutionRequest { let reqs: Vec<_> = (0..10).map(|_| IncompleteExecutionRequest {
block_hash: Field::Scalar(Default::default()), block_hash: Field::Scalar(Default::default()),
from: Default::default(), from: Default::default(),
action: ::ethcore::transaction::Action::Create, action: ::transaction::Action::Create,
gas: 100_000.into(), gas: 100_000.into(),
gas_price: 0.into(), gas_price: 0.into(),
value: 100_000_001.into(), value: 100_000_001.into(),

View File

@ -30,14 +30,14 @@ use unexpected::{Mismatch, OutOfBounds};
use basic_types::{LogBloom, Seal}; use basic_types::{LogBloom, Seal};
use vm::{EnvInfo, LastHashes}; use vm::{EnvInfo, LastHashes};
use engines::EthEngine; use engines::EthEngine;
use error::{Error, BlockError, TransactionError}; use error::{Error, BlockError};
use factory::Factories; use factory::Factories;
use header::Header; use header::Header;
use receipt::{Receipt, TransactionOutcome}; use receipt::{Receipt, TransactionOutcome};
use state::State; use state::State;
use state_db::StateDB; use state_db::StateDB;
use trace::FlatTrace; use trace::FlatTrace;
use transaction::{UnverifiedTransaction, SignedTransaction}; use transaction::{UnverifiedTransaction, SignedTransaction, Error as TransactionError};
use verification::PreverifiedBlock; use verification::PreverifiedBlock;
use views::BlockView; use views::BlockView;
@ -737,7 +737,12 @@ mod tests {
) -> Result<LockedBlock, Error> { ) -> Result<LockedBlock, Error> {
let block = BlockView::new(block_bytes); let block = BlockView::new(block_bytes);
let header = block.header(); let header = block.header();
let transactions: Result<Vec<_>, Error> = block.transactions().into_iter().map(SignedTransaction::new).collect(); let transactions: Result<Vec<_>, Error> = block
.transactions()
.into_iter()
.map(SignedTransaction::new)
.map(|r| r.map_err(Into::into))
.collect();
let transactions = transactions?; let transactions = transactions?;
{ {

View File

@ -55,7 +55,7 @@ use futures::{future, Future};
use header::{BlockNumber, Header}; use header::{BlockNumber, Header};
use io::*; use io::*;
use log_entry::LocalizedLogEntry; use log_entry::LocalizedLogEntry;
use miner::{Miner, MinerService, TransactionImportResult}; use miner::{Miner, MinerService};
use native_contracts::Registry; use native_contracts::Registry;
use parking_lot::{Mutex, RwLock, MutexGuard}; use parking_lot::{Mutex, RwLock, MutexGuard};
use rand::OsRng; use rand::OsRng;
@ -69,7 +69,7 @@ use state::{self, State};
use trace; use trace;
use trace::{TraceDB, ImportRequest as TraceImportRequest, LocalizedTrace, Database as TraceDatabase}; use trace::{TraceDB, ImportRequest as TraceImportRequest, LocalizedTrace, Database as TraceDatabase};
use trace::FlatTransactionTraces; use trace::FlatTransactionTraces;
use transaction::{LocalizedTransaction, UnverifiedTransaction, SignedTransaction, Transaction, PendingTransaction, Action}; use transaction::{self, LocalizedTransaction, UnverifiedTransaction, SignedTransaction, Transaction, PendingTransaction, Action};
use types::filter::Filter; use types::filter::Filter;
use types::mode::Mode as IpcMode; use types::mode::Mode as IpcMode;
use verification; use verification;
@ -1813,7 +1813,7 @@ impl BlockChainClient for Client {
}) })
} }
fn transact_contract(&self, address: Address, data: Bytes) -> Result<TransactionImportResult, EthcoreError> { fn transact_contract(&self, address: Address, data: Bytes) -> Result<transaction::ImportResult, EthcoreError> {
let transaction = Transaction { let transaction = Transaction {
nonce: self.latest_nonce(&self.miner.author()), nonce: self.latest_nonce(&self.miner.author()),
action: Action::Call(address), action: Action::Call(address),

View File

@ -203,7 +203,7 @@ impl<'a> EvmTestClient<'a> {
if let Err(error) = is_ok { if let Err(error) = is_ok {
return TransactResult::Err { return TransactResult::Err {
state_root: *self.state.root(), state_root: *self.state.root(),
error, error: error.into(),
}; };
} }

View File

@ -42,7 +42,7 @@ pub use types::call_analytics::CallAnalytics;
pub use executive::{Executed, Executive, TransactOptions}; pub use executive::{Executed, Executive, TransactOptions};
pub use vm::{LastHashes, EnvInfo}; pub use vm::{LastHashes, EnvInfo};
pub use error::{BlockImportError, TransactionImportError, TransactionImportResult}; pub use error::{BlockImportError, TransactionImportError};
pub use verification::VerifierType; pub use verification::VerifierType;
mod traits; mod traits;

View File

@ -32,7 +32,7 @@ use bytes::Bytes;
use rlp::*; use rlp::*;
use ethkey::{Generator, Random}; use ethkey::{Generator, Random};
use devtools::*; use devtools::*;
use transaction::{Transaction, LocalizedTransaction, PendingTransaction, SignedTransaction, Action}; use transaction::{self, Transaction, LocalizedTransaction, PendingTransaction, SignedTransaction, Action};
use blockchain::TreeRoute; use blockchain::TreeRoute;
use client::{ use client::{
BlockChainClient, MiningBlockChainClient, BlockChainInfo, BlockStatus, BlockId, BlockChainClient, MiningBlockChainClient, BlockChainInfo, BlockStatus, BlockId,
@ -48,7 +48,7 @@ use blockchain::extras::BlockReceipts;
use error::{ImportResult, Error as EthcoreError}; use error::{ImportResult, Error as EthcoreError};
use evm::{Factory as EvmFactory, VMType}; use evm::{Factory as EvmFactory, VMType};
use vm::Schedule; use vm::Schedule;
use miner::{Miner, MinerService, TransactionImportResult}; use miner::{Miner, MinerService};
use spec::Spec; use spec::Spec;
use types::basic_account::BasicAccount; use types::basic_account::BasicAccount;
use types::mode::Mode; use types::mode::Mode;
@ -337,7 +337,7 @@ impl TestBlockChainClient {
let hash = signed_tx.hash(); let hash = signed_tx.hash();
let res = self.miner.import_external_transactions(self, vec![signed_tx.into()]); let res = self.miner.import_external_transactions(self, vec![signed_tx.into()]);
let res = res.into_iter().next().unwrap().expect("Successful import"); let res = res.into_iter().next().unwrap().expect("Successful import");
assert_eq!(res, TransactionImportResult::Current); assert_eq!(res, transaction::ImportResult::Current);
hash hash
} }
@ -771,7 +771,7 @@ impl BlockChainClient for TestBlockChainClient {
fn call_contract(&self, _id: BlockId, _address: Address, _data: Bytes) -> Result<Bytes, String> { Ok(vec![]) } fn call_contract(&self, _id: BlockId, _address: Address, _data: Bytes) -> Result<Bytes, String> { Ok(vec![]) }
fn transact_contract(&self, address: Address, data: Bytes) -> Result<TransactionImportResult, EthcoreError> { fn transact_contract(&self, address: Address, data: Bytes) -> Result<transaction::ImportResult, EthcoreError> {
let transaction = Transaction { let transaction = Transaction {
nonce: self.latest_nonce(&self.miner.author()), nonce: self.latest_nonce(&self.miner.author()),
action: Action::Call(address), action: Action::Call(address),

View File

@ -21,8 +21,7 @@ use block::{OpenBlock, SealedBlock, ClosedBlock};
use blockchain::TreeRoute; use blockchain::TreeRoute;
use encoded; use encoded;
use vm::LastHashes; use vm::LastHashes;
use error::{ImportResult, CallError, Error as EthcoreError}; use error::{ImportResult, CallError, Error as EthcoreError, BlockImportError};
use error::{TransactionImportResult, BlockImportError};
use evm::{Factory as EvmFactory, Schedule}; use evm::{Factory as EvmFactory, Schedule};
use executive::Executed; use executive::Executed;
use filter::Filter; use filter::Filter;
@ -30,7 +29,7 @@ use header::{BlockNumber};
use log_entry::LocalizedLogEntry; use log_entry::LocalizedLogEntry;
use receipt::LocalizedReceipt; use receipt::LocalizedReceipt;
use trace::LocalizedTrace; use trace::LocalizedTrace;
use transaction::{LocalizedTransaction, PendingTransaction, SignedTransaction}; use transaction::{LocalizedTransaction, PendingTransaction, SignedTransaction, ImportResult as TransactionImportResult};
use verification::queue::QueueInfo as BlockQueueInfo; use verification::queue::QueueInfo as BlockQueueInfo;
use ethereum_types::{H256, U256, Address}; use ethereum_types::{H256, U256, Address};

View File

@ -31,92 +31,10 @@ use snapshot::Error as SnapshotError;
use engines::EngineError; use engines::EngineError;
use ethkey::Error as EthkeyError; use ethkey::Error as EthkeyError;
use account_provider::SignError as AccountsError; use account_provider::SignError as AccountsError;
use transaction::Error as TransactionError;
pub use executed::{ExecutionError, CallError}; pub use executed::{ExecutionError, CallError};
#[derive(Debug, PartialEq, Clone, Copy)]
/// Errors concerning transaction processing.
pub enum TransactionError {
/// Transaction is already imported to the queue
AlreadyImported,
/// Transaction is not valid anymore (state already has higher nonce)
Old,
/// Transaction has too low fee
/// (there is already a transaction with the same sender-nonce but higher gas price)
TooCheapToReplace,
/// Transaction was not imported to the queue because limit has been reached.
LimitReached,
/// Transaction's gas price is below threshold.
InsufficientGasPrice {
/// Minimal expected gas price
minimal: U256,
/// Transaction gas price
got: U256,
},
/// Transaction's gas is below currently set minimal gas requirement.
InsufficientGas {
/// Minimal expected gas
minimal: U256,
/// Transaction gas
got: U256,
},
/// Sender doesn't have enough funds to pay for this transaction
InsufficientBalance {
/// Senders balance
balance: U256,
/// Transaction cost
cost: U256,
},
/// Transactions gas is higher then current gas limit
GasLimitExceeded {
/// Current gas limit
limit: U256,
/// Declared transaction gas
got: U256,
},
/// Transaction's gas limit (aka gas) is invalid.
InvalidGasLimit(OutOfBounds<U256>),
/// Transaction sender is banned.
SenderBanned,
/// Transaction receipient is banned.
RecipientBanned,
/// Contract creation code is banned.
CodeBanned,
/// Invalid chain ID given.
InvalidChainId,
/// Not enough permissions given by permission contract.
NotAllowed,
}
impl fmt::Display for TransactionError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use self::TransactionError::*;
let msg = match *self {
AlreadyImported => "Already imported".into(),
Old => "No longer valid".into(),
TooCheapToReplace => "Gas price too low to replace".into(),
LimitReached => "Transaction limit reached".into(),
InsufficientGasPrice { minimal, got } =>
format!("Insufficient gas price. Min={}, Given={}", minimal, got),
InsufficientGas { minimal, got } =>
format!("Insufficient gas. Min={}, Given={}", minimal, got),
InsufficientBalance { balance, cost } =>
format!("Insufficient balance for transaction. Balance={}, Cost={}",
balance, cost),
GasLimitExceeded { limit, got } =>
format!("Gas limit exceeded. Limit={}, Given={}", limit, got),
InvalidGasLimit(ref err) => format!("Invalid gas limit. {}", err),
SenderBanned => "Sender is temporarily banned.".into(),
RecipientBanned => "Recipient is temporarily banned.".into(),
CodeBanned => "Contract code is temporarily banned.".into(),
InvalidChainId => "Transaction of this chain ID is not allowed on this chain.".into(),
NotAllowed => "Sender does not have permissions to execute this type of transction".into(),
};
f.write_fmt(format_args!("Transaction error ({})", msg))
}
}
#[derive(Debug, PartialEq, Clone, Copy, Eq)] #[derive(Debug, PartialEq, Clone, Copy, Eq)]
/// Errors concerning block processing. /// Errors concerning block processing.
pub enum BlockError { pub enum BlockError {
@ -270,15 +188,6 @@ impl From<Error> for BlockImportError {
} }
} }
/// Represents the result of importing transaction.
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum TransactionImportResult {
/// Transaction was imported to current queue.
Current,
/// Transaction was imported to future queue.
Future
}
/// Api-level error for transaction import /// Api-level error for transaction import
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum TransactionImportError { pub enum TransactionImportError {

View File

@ -42,8 +42,10 @@ fn do_json_test(json_data: &[u8]) -> Vec<String> {
let rlp: Vec<u8> = test.rlp.into(); let rlp: Vec<u8> = test.rlp.into();
let res = UntrustedRlp::new(&rlp) let res = UntrustedRlp::new(&rlp)
.as_val() .as_val()
.map_err(From::from) .map_err(::error::Error::from)
.and_then(|t: UnverifiedTransaction| t.validate(schedule, schedule.have_delegate_call, allow_chain_id_of_one, allow_unsigned)); .and_then(|t: UnverifiedTransaction| {
t.validate(schedule, schedule.have_delegate_call, allow_chain_id_of_one, allow_unsigned).map_err(Into::into)
});
fail_unless(test.transaction.is_none() == res.is_err(), "Validity different"); fail_unless(test.transaction.is_none() == res.is_err(), "Validity different");
if let (Some(tx), Some(sender)) = (test.transaction, test.sender) { if let (Some(tx), Some(sender)) = (test.transaction, test.sender) {

View File

@ -66,16 +66,16 @@ extern crate ethcore_devtools as devtools;
extern crate ethcore_io as io; extern crate ethcore_io as io;
extern crate ethcore_bytes as bytes; extern crate ethcore_bytes as bytes;
extern crate ethcore_logger; extern crate ethcore_logger;
extern crate ethcore_miner;
extern crate ethcore_stratum; extern crate ethcore_stratum;
extern crate ethcore_transaction as transaction;
extern crate ethereum_types; extern crate ethereum_types;
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 hashdb;
extern crate hyper;
extern crate itertools; extern crate itertools;
extern crate linked_hash_map;
extern crate lru_cache; extern crate lru_cache;
extern crate native_contracts; extern crate native_contracts;
extern crate num_cpus; extern crate num_cpus;
@ -106,9 +106,7 @@ extern crate rlp_derive;
extern crate rustc_hex; extern crate rustc_hex;
extern crate stats; extern crate stats;
extern crate time; extern crate time;
extern crate transient_hashmap;
extern crate using_queue; extern crate using_queue;
extern crate table;
extern crate bloomable; extern crate bloomable;
extern crate vm; extern crate vm;
extern crate wasm; extern crate wasm;
@ -149,7 +147,6 @@ pub mod spec;
pub mod state; pub mod state;
pub mod timer; pub mod timer;
pub mod trace; pub mod trace;
pub mod transaction;
pub mod verification; pub mod verification;
pub mod views; pub mod views;

View File

@ -23,13 +23,13 @@ use std::sync::Arc;
use block::ExecutedBlock; use block::ExecutedBlock;
use builtin::Builtin; use builtin::Builtin;
use client::BlockChainClient; use client::BlockChainClient;
use error::{Error, TransactionError}; use error::Error;
use executive::Executive; use executive::Executive;
use header::{BlockNumber, Header}; use header::{BlockNumber, Header};
use spec::CommonParams; use spec::CommonParams;
use state::{CleanupMode, Substate}; use state::{CleanupMode, Substate};
use trace::{NoopTracer, NoopVMTracer, Tracer, ExecutiveTracer, RewardType}; use trace::{NoopTracer, NoopVMTracer, Tracer, ExecutiveTracer, RewardType};
use transaction::{SYSTEM_ADDRESS, UnverifiedTransaction, SignedTransaction}; use transaction::{self, SYSTEM_ADDRESS, UnverifiedTransaction, SignedTransaction};
use tx_filter::TransactionFilter; use tx_filter::TransactionFilter;
use ethereum_types::{U256, Address}; use ethereum_types::{U256, Address};
@ -341,7 +341,7 @@ impl EthereumMachine {
/// Verify a particular transaction is valid, regardless of order. /// Verify a particular transaction is valid, regardless of order.
pub fn verify_transaction_unordered(&self, t: UnverifiedTransaction, _header: &Header) -> Result<SignedTransaction, Error> { pub fn verify_transaction_unordered(&self, t: UnverifiedTransaction, _header: &Header) -> Result<SignedTransaction, Error> {
SignedTransaction::new(t) Ok(SignedTransaction::new(t)?)
} }
/// Does basic verification of the transaction. /// Does basic verification of the transaction.
@ -369,7 +369,7 @@ impl EthereumMachine {
pub fn verify_transaction(&self, t: &SignedTransaction, header: &Header, client: &BlockChainClient) -> Result<(), Error> { pub fn verify_transaction(&self, t: &SignedTransaction, header: &Header, client: &BlockChainClient) -> Result<(), Error> {
if let Some(ref filter) = self.tx_filter.as_ref() { if let Some(ref filter) = self.tx_filter.as_ref() {
if !filter.transaction_allowed(header.parent_hash(), t, client) { if !filter.transaction_allowed(header.parent_hash(), t, client) {
return Err(TransactionError::NotAllowed.into()) return Err(transaction::Error::NotAllowed.into())
} }
} }

View File

@ -18,32 +18,47 @@ use std::time::{Instant, Duration};
use std::collections::{BTreeMap, HashSet}; use std::collections::{BTreeMap, HashSet};
use std::sync::Arc; use std::sync::Arc;
use account_provider::{AccountProvider, SignError as AccountError};
use ansi_term::Colour;
use ethereum_types::{H256, U256, Address}; use ethereum_types::{H256, U256, Address};
use parking_lot::{Mutex, RwLock}; use parking_lot::{Mutex, RwLock};
use bytes::Bytes; use bytes::Bytes;
use timer::PerfTimer; use engines::{EthEngine, Seal};
use using_queue::{UsingQueue, GetAction};
use account_provider::{AccountProvider, SignError as AccountError};
use state::State;
use client::{MiningBlockChainClient, BlockId, TransactionId};
use client::TransactionImportResult;
use executive::contract_address;
use block::{ClosedBlock, IsBlock, Block};
use error::*; use error::*;
use transaction::{Action, UnverifiedTransaction, PendingTransaction, SignedTransaction, Condition as TransactionCondition}; use ethcore_miner::banning_queue::{BanningTransactionQueue, Threshold};
use ethcore_miner::local_transactions::{Status as LocalTransactionStatus};
use ethcore_miner::transaction_queue::{
TransactionQueue,
RemovalReason,
TransactionDetailsProvider as TransactionQueueDetailsProvider,
PrioritizationStrategy,
AccountDetails,
TransactionOrigin,
};
use ethcore_miner::work_notify::{WorkPoster, NotifyWork};
use ethcore_miner::service_transaction_checker::ServiceTransactionChecker;
use miner::{MinerService, MinerStatus};
use price_info::fetch::Client as FetchClient;
use price_info::{Client as PriceInfoClient, PriceInfo};
use timer::PerfTimer;
use transaction::{
Action,
UnverifiedTransaction,
PendingTransaction,
SignedTransaction,
Condition as TransactionCondition,
ImportResult as TransactionImportResult,
Error as TransactionError,
};
use using_queue::{UsingQueue, GetAction};
use block::{ClosedBlock, IsBlock, Block};
use client::{MiningBlockChainClient, BlockId, TransactionId};
use executive::contract_address;
use header::{Header, BlockNumber};
use receipt::{Receipt, RichReceipt}; use receipt::{Receipt, RichReceipt};
use spec::Spec; use spec::Spec;
use engines::{EthEngine, Seal}; use state::State;
use miner::{MinerService, MinerStatus, TransactionQueue, RemovalReason, TransactionQueueDetailsProvider, PrioritizationStrategy,
AccountDetails, TransactionOrigin};
use miner::banning_queue::{BanningTransactionQueue, Threshold};
use miner::work_notify::{WorkPoster, NotifyWork};
use miner::local_transactions::{Status as LocalTransactionStatus};
use miner::service_transaction_checker::ServiceTransactionChecker;
use price_info::{Client as PriceInfoClient, PriceInfo};
use price_info::fetch::Client as FetchClient;
use header::{Header, BlockNumber};
use ansi_term::Colour;
/// Different possible definitions for pending transaction set. /// Different possible definitions for pending transaction set.
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
@ -711,10 +726,10 @@ impl Miner {
let details_provider = TransactionDetailsProvider::new(client, &self.service_transaction_action); let details_provider = TransactionDetailsProvider::new(client, &self.service_transaction_action);
match origin { match origin {
TransactionOrigin::Local | TransactionOrigin::RetractedBlock => { TransactionOrigin::Local | TransactionOrigin::RetractedBlock => {
transaction_queue.add(transaction, origin, insertion_time, condition.clone(), &details_provider) Ok(transaction_queue.add(transaction, origin, insertion_time, condition.clone(), &details_provider)?)
}, },
TransactionOrigin::External => { TransactionOrigin::External => {
transaction_queue.add_with_banlist(transaction, insertion_time, &details_provider) Ok(transaction_queue.add_with_banlist(transaction, insertion_time, &details_provider)?)
}, },
} }
}, },
@ -1218,18 +1233,28 @@ enum ServiceTransactionAction {
impl ServiceTransactionAction { impl ServiceTransactionAction {
pub fn update_from_chain_client(&self, client: &MiningBlockChainClient) { pub fn update_from_chain_client(&self, client: &MiningBlockChainClient) {
if let ServiceTransactionAction::Check(ref checker) = *self { if let ServiceTransactionAction::Check(ref checker) = *self {
checker.update_from_chain_client(client); checker.update_from_chain_client(&client);
} }
} }
pub fn check(&self, client: &MiningBlockChainClient, tx: &SignedTransaction) -> Result<bool, String> { pub fn check(&self, client: &MiningBlockChainClient, tx: &SignedTransaction) -> Result<bool, String> {
match *self { match *self {
ServiceTransactionAction::Refuse => Err("configured to refuse service transactions".to_owned()), ServiceTransactionAction::Refuse => Err("configured to refuse service transactions".to_owned()),
ServiceTransactionAction::Check(ref checker) => checker.check(client, tx), ServiceTransactionAction::Check(ref checker) => checker.check(&client, tx),
} }
} }
} }
impl<'a> ::ethcore_miner::service_transaction_checker::ContractCaller for &'a MiningBlockChainClient {
fn registry_address(&self, name: &str) -> Option<Address> {
MiningBlockChainClient::registry_address(*self, name.into())
}
fn call_contract(&self, block: BlockId, address: Address, data: Vec<u8>) -> Result<Vec<u8>, String> {
MiningBlockChainClient::call_contract(*self, block, address, data)
}
}
struct TransactionDetailsProvider<'a> { struct TransactionDetailsProvider<'a> {
client: &'a MiningBlockChainClient, client: &'a MiningBlockChainClient,
service_transaction_action: &'a ServiceTransactionAction, service_transaction_action: &'a ServiceTransactionAction,
@ -1263,20 +1288,16 @@ impl<'a> TransactionQueueDetailsProvider for TransactionDetailsProvider<'a> {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use std::sync::Arc;
use std::time::Duration;
use rustc_hex::FromHex;
use hash::keccak;
use super::super::{MinerService, PrioritizationStrategy};
use super::*; use super::*;
use block::IsBlock; use ethcore_miner::transaction_queue::PrioritizationStrategy;
use ethereum_types::U256; use ethereum_types::U256;
use ethkey::{Generator, Random}; use ethkey::{Generator, Random};
use client::{BlockChainClient, TestBlockChainClient, EachBlockWith, TransactionImportResult}; use hash::keccak;
use header::BlockNumber; use rustc_hex::FromHex;
use transaction::{SignedTransaction, Transaction, PendingTransaction, Action}; use transaction::Transaction;
use spec::Spec;
use client::{BlockChainClient, TestBlockChainClient, EachBlockWith};
use miner::MinerService;
use tests::helpers::{generate_dummy_client, generate_dummy_client_with_spec_and_accounts}; use tests::helpers::{generate_dummy_client, generate_dummy_client_with_spec_and_accounts};
#[test] #[test]

View File

@ -38,34 +38,24 @@
//! } //! }
//! ``` //! ```
mod banning_queue;
mod external;
mod local_transactions;
mod miner; mod miner;
mod service_transaction_checker;
mod transaction_queue;
mod work_notify;
mod stratum; mod stratum;
pub use self::external::{ExternalMiner, ExternalMinerService};
pub use self::miner::{Miner, MinerOptions, Banning, PendingSet, GasPricer, GasPriceCalibratorOptions, GasLimit}; pub use self::miner::{Miner, MinerOptions, Banning, PendingSet, GasPricer, GasPriceCalibratorOptions, GasLimit};
pub use self::transaction_queue::{TransactionQueue, RemovalReason, TransactionDetailsProvider as TransactionQueueDetailsProvider,
PrioritizationStrategy, AccountDetails, TransactionOrigin};
pub use self::local_transactions::{Status as LocalTransactionStatus};
pub use client::TransactionImportResult;
pub use self::work_notify::NotifyWork;
pub use self::stratum::{Stratum, Error as StratumError, Options as StratumOptions}; pub use self::stratum::{Stratum, Error as StratumError, Options as StratumOptions};
pub use ethcore_miner::local_transactions::Status as LocalTransactionStatus;
use std::collections::BTreeMap; use std::collections::BTreeMap;
use ethereum_types::{H256, U256, Address}; use ethereum_types::{H256, U256, Address};
use bytes::Bytes; use bytes::Bytes;
use client::{MiningBlockChainClient};
use block::ClosedBlock; use block::ClosedBlock;
use client::{MiningBlockChainClient};
use error::{Error};
use header::BlockNumber; use header::BlockNumber;
use receipt::{RichReceipt, Receipt}; use receipt::{RichReceipt, Receipt};
use error::{Error}; use transaction::{UnverifiedTransaction, PendingTransaction, ImportResult as TransactionImportResult};
use transaction::{UnverifiedTransaction, PendingTransaction};
/// Miner client API /// Miner client API
pub trait MinerService : Send + Sync { pub trait MinerService : Send + Sync {

View File

@ -16,22 +16,22 @@
//! Client-side stratum job dispatcher and mining notifier handler //! Client-side stratum job dispatcher and mining notifier handler
use ethcore_stratum::{
JobDispatcher, PushWorkHandler,
Stratum as StratumService, Error as StratumServiceError,
};
use std::sync::{Arc, Weak}; use std::sync::{Arc, Weak};
use std::net::{SocketAddr, AddrParseError}; use std::net::{SocketAddr, AddrParseError};
use std::fmt; use std::fmt;
use block::IsBlock;
use client::Client;
use ethereum_types::{H64, H256, clean_0x, U256}; use ethereum_types::{H64, H256, clean_0x, U256};
use ethereum::ethash::Ethash; use ethereum::ethash::Ethash;
use ethash::SeedHashCompute; use ethash::SeedHashCompute;
use parking_lot::Mutex; use ethcore_miner::work_notify::NotifyWork;
use ethcore_stratum::{
JobDispatcher, PushWorkHandler,
Stratum as StratumService, Error as StratumServiceError,
};
use miner::{self, Miner, MinerService}; use miner::{self, Miner, MinerService};
use client::Client; use parking_lot::Mutex;
use block::IsBlock;
use rlp::encode; use rlp::encode;
/// Configures stratum server options. /// Configures stratum server options.
@ -213,7 +213,7 @@ impl From<AddrParseError> for Error {
fn from(err: AddrParseError) -> Error { Error::Address(err) } fn from(err: AddrParseError) -> Error { Error::Address(err) }
} }
impl super::work_notify::NotifyWork for Stratum { impl NotifyWork for Stratum {
fn notify(&self, pow_hash: H256, difficulty: U256, number: u64) { fn notify(&self, pow_hash: H256, difficulty: U256, number: u64) {
trace!(target: "stratum", "Notify work"); trace!(target: "stratum", "Notify work");
@ -248,7 +248,7 @@ impl Stratum {
/// Start STRATUM job dispatcher and register it in the miner /// Start STRATUM job dispatcher and register it in the miner
pub fn register(cfg: &Options, miner: Arc<Miner>, client: Weak<Client>) -> Result<(), Error> { pub fn register(cfg: &Options, miner: Arc<Miner>, client: Weak<Client>) -> Result<(), Error> {
let stratum = miner::Stratum::start(cfg, Arc::downgrade(&miner.clone()), client)?; let stratum = miner::Stratum::start(cfg, Arc::downgrade(&miner.clone()), client)?;
miner.push_notifier(Box::new(stratum) as Box<miner::NotifyWork>); miner.push_notifier(Box::new(stratum) as Box<NotifyWork>);
Ok(()) Ok(())
} }
} }

View File

@ -332,27 +332,21 @@ fn verify_block_integrity(block: &[u8], transactions_root: &H256, uncles_hash: &
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*;
use std::collections::{BTreeMap, HashMap}; use std::collections::{BTreeMap, HashMap};
use hash::keccak;
use ethereum_types::{H256, H2048, U256}; use ethereum_types::{H256, H2048, U256};
use triehash::ordered_trie_root; use blockchain::extras::{BlockDetails, TransactionAddress, BlockReceipts};
use unexpected::{Mismatch, OutOfBounds};
use bytes::Bytes;
use ethkey::{Random, Generator};
use header::*;
use verification::*;
use blockchain::extras::*;
use error::*;
use error::BlockError::*;
use views::*;
use blockchain::*;
use engines::EthEngine;
use spec::*;
use transaction::*;
use tests::helpers::*;
use types::log_entry::{LogEntry, LocalizedLogEntry};
use time::get_time;
use encoded; use encoded;
use hash::keccak;
use engines::EthEngine;
use error::BlockError::*;
use ethkey::{Random, Generator};
use spec::{CommonParams, Spec};
use tests::helpers::{create_test_block_with_data, create_test_block};
use time::get_time;
use transaction::{SignedTransaction, Transaction, UnverifiedTransaction, Action};
use types::log_entry::{LogEntry, LocalizedLogEntry};
fn check_ok(result: Result<(), Error>) { fn check_ok(result: Result<(), Error>) {
result.unwrap_or_else(|e| panic!("Block verification failed: {:?}", e)); result.unwrap_or_else(|e| panic!("Block verification failed: {:?}", e));

View File

@ -0,0 +1,21 @@
[package]
name = "ethcore-transaction"
description = "Transaction type"
version = "0.1.0"
authors = ["Parity Technologies <admin@parity.io>"]
[dependencies]
ethjson = { path = "../../json" }
ethkey = { path = "../../ethkey" }
evm = { path = "../evm" }
heapsize = "0.4"
keccak-hash = { path = "../../util/hash" }
rlp = { path = "../../util/rlp" }
unexpected = { path = "../../util/unexpected" }
ethereum-types = "0.1"
[dev-dependencies]
rustc-hex= "1.0"
[features]
json-tests = []

View File

@ -0,0 +1,114 @@
// 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 std::fmt;
use ethereum_types::U256;
use ethkey;
use unexpected::OutOfBounds;
#[derive(Debug, PartialEq, Clone)]
/// Errors concerning transaction processing.
pub enum Error {
/// Transaction is already imported to the queue
AlreadyImported,
/// Transaction is not valid anymore (state already has higher nonce)
Old,
/// Transaction has too low fee
/// (there is already a transaction with the same sender-nonce but higher gas price)
TooCheapToReplace,
/// Transaction was not imported to the queue because limit has been reached.
LimitReached,
/// Transaction's gas price is below threshold.
InsufficientGasPrice {
/// Minimal expected gas price
minimal: U256,
/// Transaction gas price
got: U256,
},
/// Transaction's gas is below currently set minimal gas requirement.
InsufficientGas {
/// Minimal expected gas
minimal: U256,
/// Transaction gas
got: U256,
},
/// Sender doesn't have enough funds to pay for this transaction
InsufficientBalance {
/// Senders balance
balance: U256,
/// Transaction cost
cost: U256,
},
/// Transactions gas is higher then current gas limit
GasLimitExceeded {
/// Current gas limit
limit: U256,
/// Declared transaction gas
got: U256,
},
/// Transaction's gas limit (aka gas) is invalid.
InvalidGasLimit(OutOfBounds<U256>),
/// Transaction sender is banned.
SenderBanned,
/// Transaction receipient is banned.
RecipientBanned,
/// Contract creation code is banned.
CodeBanned,
/// Invalid chain ID given.
InvalidChainId,
/// Not enough permissions given by permission contract.
NotAllowed,
/// Signature error
InvalidSignature(String),
}
impl From<ethkey::Error> for Error {
fn from(err: ethkey::Error) -> Self {
Error::InvalidSignature(format!("{}", err))
}
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use self::Error::*;
let msg = match *self {
AlreadyImported => "Already imported".into(),
Old => "No longer valid".into(),
TooCheapToReplace => "Gas price too low to replace".into(),
LimitReached => "Transaction limit reached".into(),
InsufficientGasPrice { minimal, got } =>
format!("Insufficient gas price. Min={}, Given={}", minimal, got),
InsufficientGas { minimal, got } =>
format!("Insufficient gas. Min={}, Given={}", minimal, got),
InsufficientBalance { balance, cost } =>
format!("Insufficient balance for transaction. Balance={}, Cost={}",
balance, cost),
GasLimitExceeded { limit, got } =>
format!("Gas limit exceeded. Limit={}, Given={}", limit, got),
InvalidGasLimit(ref err) => format!("Invalid gas limit. {}", err),
SenderBanned => "Sender is temporarily banned.".into(),
RecipientBanned => "Recipient is temporarily banned.".into(),
CodeBanned => "Contract code is temporarily banned.".into(),
InvalidChainId => "Transaction of this chain ID is not allowed on this chain.".into(),
InvalidSignature(ref err) => format!("Transaction has invalid signature: {}.", err),
NotAllowed => "Sender does not have permissions to execute this type of transction".into(),
};
f.write_fmt(format_args!("Transaction error ({})", msg))
}
}

View File

@ -0,0 +1,46 @@
// 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/>.
//! Ethereum Transactions
extern crate ethereum_types;
extern crate ethjson;
extern crate ethkey;
extern crate evm;
extern crate heapsize;
extern crate keccak_hash as hash;
extern crate rlp;
extern crate unexpected;
#[cfg(test)]
extern crate rustc_hex;
mod error;
mod transaction;
pub use error::Error;
pub use transaction::*;
// TODO [ToDr] Move to miner!
/// Represents the result of importing transaction.
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum ImportResult {
/// Transaction was imported to current queue.
Current,
/// Transaction was imported to future queue.
Future
}

View File

@ -17,16 +17,18 @@
//! Transaction data structure. //! Transaction data structure.
use std::ops::Deref; use std::ops::Deref;
use rlp::*; use ethereum_types::{H256, H160, Address, U256};
use error;
use ethjson;
use ethkey::{self, Signature, Secret, Public, recover, public_to_address};
use evm::Schedule;
use hash::keccak; use hash::keccak;
use heapsize::HeapSizeOf; use heapsize::HeapSizeOf;
use ethereum_types::{H256, H160, Address, U256}; use rlp::{self, RlpStream, UntrustedRlp, DecoderError, Encodable};
use bytes::Bytes; // use rlp::*;
use ethkey::{Signature, Secret, Public, recover, public_to_address, Error as EthkeyError};
use error::*; type Bytes = Vec<u8>;
use evm::Schedule; type BlockNumber = u64;
use header::BlockNumber;
use ethjson;
/// Fake address for unsigned transactions as defined by EIP-86. /// Fake address for unsigned transactions as defined by EIP-86.
pub const UNSIGNED_SENDER: Address = H160([0xff; 20]); pub const UNSIGNED_SENDER: Address = H160([0xff; 20]);
@ -48,7 +50,7 @@ impl Default for Action {
fn default() -> Action { Action::Create } fn default() -> Action { Action::Create }
} }
impl Decodable for Action { impl rlp::Decodable for Action {
fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> { fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
if rlp.is_empty() { if rlp.is_empty() {
Ok(Action::Create) Ok(Action::Create)
@ -58,7 +60,7 @@ impl Decodable for Action {
} }
} }
impl Encodable for Action { impl rlp::Encodable for Action {
fn rlp_append(&self, s: &mut RlpStream) { fn rlp_append(&self, s: &mut RlpStream) {
match *self { match *self {
Action::Create => s.append_internal(&""), Action::Create => s.append_internal(&""),
@ -270,7 +272,7 @@ impl Deref for UnverifiedTransaction {
} }
} }
impl Decodable for UnverifiedTransaction { impl rlp::Decodable for UnverifiedTransaction {
fn decode(d: &UntrustedRlp) -> Result<Self, DecoderError> { fn decode(d: &UntrustedRlp) -> Result<Self, DecoderError> {
if d.item_count()? != 9 { if d.item_count()? != 9 {
return Err(DecoderError::RlpIncorrectListLen); return Err(DecoderError::RlpIncorrectListLen);
@ -293,7 +295,7 @@ impl Decodable for UnverifiedTransaction {
} }
} }
impl Encodable for UnverifiedTransaction { impl rlp::Encodable for UnverifiedTransaction {
fn rlp_append(&self, s: &mut RlpStream) { self.rlp_append_sealed_transaction(s) } fn rlp_append(&self, s: &mut RlpStream) { self.rlp_append_sealed_transaction(s) }
} }
@ -350,9 +352,9 @@ impl UnverifiedTransaction {
} }
/// Checks whether the signature has a low 's' value. /// Checks whether the signature has a low 's' value.
pub fn check_low_s(&self) -> Result<(), Error> { pub fn check_low_s(&self) -> Result<(), ethkey::Error> {
if !self.signature().is_low_s() { if !self.signature().is_low_s() {
Err(EthkeyError::InvalidSignature.into()) Err(ethkey::Error::InvalidSignature.into())
} else { } else {
Ok(()) Ok(())
} }
@ -364,39 +366,40 @@ impl UnverifiedTransaction {
} }
/// Recovers the public key of the sender. /// Recovers the public key of the sender.
pub fn recover_public(&self) -> Result<Public, Error> { pub fn recover_public(&self) -> Result<Public, ethkey::Error> {
Ok(recover(&self.signature(), &self.unsigned.hash(self.chain_id()))?) Ok(recover(&self.signature(), &self.unsigned.hash(self.chain_id()))?)
} }
/// Do basic validation, checking for valid signature and minimum gas, /// Do basic validation, checking for valid signature and minimum gas,
// TODO: consider use in block validation. // TODO: consider use in block validation.
#[cfg(test)]
#[cfg(feature = "json-tests")] #[cfg(feature = "json-tests")]
pub fn validate(self, schedule: &Schedule, require_low: bool, allow_chain_id_of_one: bool, allow_empty_signature: bool) -> Result<UnverifiedTransaction, Error> { pub fn validate(self, schedule: &Schedule, require_low: bool, allow_chain_id_of_one: bool, allow_empty_signature: bool)
-> Result<UnverifiedTransaction, error::Error>
{
let chain_id = if allow_chain_id_of_one { Some(1) } else { None }; let chain_id = if allow_chain_id_of_one { Some(1) } else { None };
self.verify_basic(require_low, chain_id, allow_empty_signature)?; self.verify_basic(require_low, chain_id, allow_empty_signature)?;
if !allow_empty_signature || !self.is_unsigned() { if !allow_empty_signature || !self.is_unsigned() {
self.recover_public()?; self.recover_public()?;
} }
if self.gas < U256::from(self.gas_required(&schedule)) { if self.gas < U256::from(self.gas_required(&schedule)) {
return Err(TransactionError::InvalidGasLimit(::unexpected::OutOfBounds{min: Some(U256::from(self.gas_required(&schedule))), max: None, found: self.gas}).into()) return Err(error::Error::InvalidGasLimit(::unexpected::OutOfBounds{min: Some(U256::from(self.gas_required(&schedule))), max: None, found: self.gas}).into())
} }
Ok(self) Ok(self)
} }
/// Verify basic signature params. Does not attempt sender recovery. /// Verify basic signature params. Does not attempt sender recovery.
pub fn verify_basic(&self, check_low_s: bool, chain_id: Option<u64>, allow_empty_signature: bool) -> Result<(), Error> { pub fn verify_basic(&self, check_low_s: bool, chain_id: Option<u64>, allow_empty_signature: bool) -> Result<(), error::Error> {
if check_low_s && !(allow_empty_signature && self.is_unsigned()) { if check_low_s && !(allow_empty_signature && self.is_unsigned()) {
self.check_low_s()?; self.check_low_s()?;
} }
// EIP-86: Transactions of this form MUST have gasprice = 0, nonce = 0, value = 0, and do NOT increment the nonce of account 0. // EIP-86: Transactions of this form MUST have gasprice = 0, nonce = 0, value = 0, and do NOT increment the nonce of account 0.
if allow_empty_signature && self.is_unsigned() && !(self.gas_price.is_zero() && self.value.is_zero() && self.nonce.is_zero()) { if allow_empty_signature && self.is_unsigned() && !(self.gas_price.is_zero() && self.value.is_zero() && self.nonce.is_zero()) {
return Err(EthkeyError::InvalidSignature.into()) return Err(ethkey::Error::InvalidSignature.into())
} }
match (self.chain_id(), chain_id) { match (self.chain_id(), chain_id) {
(None, _) => {}, (None, _) => {},
(Some(n), Some(m)) if n == m => {}, (Some(n), Some(m)) if n == m => {},
_ => return Err(TransactionError::InvalidChainId.into()), _ => return Err(error::Error::InvalidChainId),
}; };
Ok(()) Ok(())
} }
@ -416,7 +419,7 @@ impl HeapSizeOf for SignedTransaction {
} }
} }
impl Encodable for SignedTransaction { impl rlp::Encodable for SignedTransaction {
fn rlp_append(&self, s: &mut RlpStream) { self.transaction.rlp_append_sealed_transaction(s) } fn rlp_append(&self, s: &mut RlpStream) { self.transaction.rlp_append_sealed_transaction(s) }
} }
@ -435,7 +438,7 @@ impl From<SignedTransaction> for UnverifiedTransaction {
impl SignedTransaction { impl SignedTransaction {
/// Try to verify transaction and recover sender. /// Try to verify transaction and recover sender.
pub fn new(transaction: UnverifiedTransaction) -> Result<Self, Error> { pub fn new(transaction: UnverifiedTransaction) -> Result<Self, ethkey::Error> {
if transaction.is_unsigned() { if transaction.is_unsigned() {
Ok(SignedTransaction { Ok(SignedTransaction {
transaction: transaction, transaction: transaction,
@ -556,7 +559,7 @@ mod tests {
#[test] #[test]
fn sender_test() { fn sender_test() {
let t: UnverifiedTransaction = decode(&::rustc_hex::FromHex::from_hex("f85f800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804").unwrap()); let t: UnverifiedTransaction = rlp::decode(&::rustc_hex::FromHex::from_hex("f85f800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804").unwrap());
assert_eq!(t.data, b""); assert_eq!(t.data, b"");
assert_eq!(t.gas, U256::from(0x5208u64)); assert_eq!(t.gas, U256::from(0x5208u64));
assert_eq!(t.gas_price, U256::from(0x01u64)); assert_eq!(t.gas_price, U256::from(0x01u64));
@ -625,10 +628,10 @@ mod tests {
use rustc_hex::FromHex; use rustc_hex::FromHex;
let test_vector = |tx_data: &str, address: &'static str| { let test_vector = |tx_data: &str, address: &'static str| {
let signed = decode(&FromHex::from_hex(tx_data).unwrap()); let signed = rlp::decode(&FromHex::from_hex(tx_data).unwrap());
let signed = SignedTransaction::new(signed).unwrap(); let signed = SignedTransaction::new(signed).unwrap();
assert_eq!(signed.sender(), address.into()); assert_eq!(signed.sender(), address.into());
flushln!("chainid: {:?}", signed.chain_id()); println!("chainid: {:?}", signed.chain_id());
}; };
test_vector("f864808504a817c800825208943535353535353535353535353535353535353535808025a0044852b2a670ade5407e78fb2863c51de9fcb96542a07186fe3aeda6bb8a116da0044852b2a670ade5407e78fb2863c51de9fcb96542a07186fe3aeda6bb8a116d", "0xf0f6f18bca1b28cd68e4357452947e021241e9ce"); test_vector("f864808504a817c800825208943535353535353535353535353535353535353535808025a0044852b2a670ade5407e78fb2863c51de9fcb96542a07186fe3aeda6bb8a116da0044852b2a670ade5407e78fb2863c51de9fcb96542a07186fe3aeda6bb8a116d", "0xf0f6f18bca1b28cd68e4357452947e021241e9ce");

View File

@ -17,11 +17,11 @@
//! Log entry type definition. //! Log entry type definition.
use std::ops::Deref; use std::ops::Deref;
use hash::keccak;
use heapsize::HeapSizeOf;
use bytes::Bytes;
use ethereum_types::{H256, Address, LogBloom}; use ethereum_types::{H256, Address, LogBloom};
use bloomable::Bloomable; use bloomable::Bloomable;
use bytes::Bytes;
use hash::keccak;
use heapsize::HeapSizeOf;
use {BlockNumber}; use {BlockNumber};
use ethjson; use ethjson;

View File

@ -9,17 +9,18 @@ name = "parity-evm"
path = "./src/main.rs" path = "./src/main.rs"
[dependencies] [dependencies]
rustc-hex = "1.0"
docopt = "0.8" docopt = "0.8"
serde = "1.0"
serde_derive = "1.0"
ethcore = { path = "../ethcore" } ethcore = { path = "../ethcore" }
ethjson = { path = "../json" } ethjson = { path = "../json" }
ethcore-bytes = { path = "../util/bytes" } ethcore-bytes = { path = "../util/bytes" }
ethcore-transaction = { path = "../ethcore/transaction" }
ethereum-types = "0.1" ethereum-types = "0.1"
evm = { path = "../ethcore/evm" } evm = { path = "../ethcore/evm" }
vm = { path = "../ethcore/vm" }
panic_hook = { path = "../panic_hook" } panic_hook = { path = "../panic_hook" }
rustc-hex = "1.0"
serde = "1.0"
serde_derive = "1.0"
vm = { path = "../ethcore/vm" }
[dev-dependencies] [dev-dependencies]
pretty_assertions = "0.1" pretty_assertions = "0.1"

View File

@ -18,9 +18,10 @@
use std::time::{Instant, Duration}; use std::time::{Instant, Duration};
use ethereum_types::{H256, U256}; use ethereum_types::{H256, U256};
use ethcore::{trace, spec, transaction, pod_state};
use ethcore::client::{self, EvmTestClient, EvmTestError, TransactResult}; use ethcore::client::{self, EvmTestClient, EvmTestError, TransactResult};
use ethcore::{trace, spec, pod_state};
use ethjson; use ethjson;
use transaction;
use vm::ActionParams; use vm::ActionParams;
/// VM execution informant /// VM execution informant

View File

@ -25,6 +25,7 @@ extern crate serde;
#[macro_use] #[macro_use]
extern crate serde_derive; extern crate serde_derive;
extern crate docopt; extern crate docopt;
extern crate ethcore_transaction as transaction;
extern crate ethcore_bytes as bytes; extern crate ethcore_bytes as bytes;
extern crate ethereum_types; extern crate ethereum_types;
extern crate vm; extern crate vm;

View File

@ -5,14 +5,15 @@ version = "0.1.0"
authors = ["Parity Technologies <admin@parity.io>"] authors = ["Parity Technologies <admin@parity.io>"]
[dependencies] [dependencies]
ethcore-io = { path = "../util/io" }
ethcore = { path = "../ethcore" } ethcore = { path = "../ethcore" }
rlp = { path = "../util/rlp" } ethcore-io = { path = "../util/io" }
ethcore-transaction = { path = "../ethcore/transaction" }
kvdb = { path = "../util/kvdb" } kvdb = { path = "../util/kvdb" }
log = "0.3"
rlp = { path = "../util/rlp" }
serde = "1.0" serde = "1.0"
serde_derive = "1.0" serde_derive = "1.0"
serde_json = "1.0" serde_json = "1.0"
log = "0.3"
[dev-dependencies] [dev-dependencies]
ethkey = { path = "../ethkey" } ethkey = { path = "../ethkey" }

View File

@ -19,7 +19,7 @@
use std::sync::Arc; use std::sync::Arc;
use std::fmt; use std::fmt;
use ethcore::transaction::{ use transaction::{
SignedTransaction, PendingTransaction, UnverifiedTransaction, SignedTransaction, PendingTransaction, UnverifiedTransaction,
Condition as TransactionCondition Condition as TransactionCondition
}; };
@ -29,6 +29,7 @@ use rlp::UntrustedRlp;
use kvdb::KeyValueDB; use kvdb::KeyValueDB;
extern crate ethcore; extern crate ethcore;
extern crate ethcore_transaction as transaction;
extern crate ethcore_io as io; extern crate ethcore_io as io;
extern crate rlp; extern crate rlp;
extern crate serde_json; extern crate serde_json;
@ -231,7 +232,7 @@ mod tests {
use super::NodeInfo; use super::NodeInfo;
use std::sync::Arc; use std::sync::Arc;
use ethcore::transaction::{Transaction, Condition, PendingTransaction}; use transaction::{Transaction, Condition, PendingTransaction};
use ethkey::{Brain, Generator}; use ethkey::{Brain, Generator};
// we want to test: round-trip of good transactions. // we want to test: round-trip of good transactions.

27
miner/Cargo.toml Normal file
View File

@ -0,0 +1,27 @@
[package]
description = "Parity Miner interface."
name = "ethcore-miner"
homepage = "http://parity.io"
license = "GPL-3.0"
version = "1.9.0"
authors = ["Parity Technologies <admin@parity.io>"]
[dependencies]
# TODO [ToDr] Rewrite using reqwest
hyper = { git = "https://github.com/paritytech/hyper", default-features = false }
common-types = { path = "../ethcore/types" }
ethash = { path = "../ethash" }
ethcore-transaction = { path = "../ethcore/transaction" }
ethereum-types = "0.1"
ethkey = { path = "../ethkey" }
futures = "0.1"
heapsize = "0.4"
keccak-hash = { path = "../util/hash" }
linked-hash-map = "0.5"
log = "0.3"
native-contracts = { path = "../ethcore/native_contracts" }
parking_lot = "0.4"
rustc-hex = "1.0"
table = { path = "../util/table" }
transient-hashmap = "0.4"

View File

@ -19,13 +19,12 @@
use std::time::Duration; use std::time::Duration;
use std::ops::{Deref, DerefMut}; use std::ops::{Deref, DerefMut};
use transaction::{SignedTransaction, Action};
use transient_hashmap::TransientHashMap;
use miner::{TransactionQueue, TransactionQueueDetailsProvider, TransactionImportResult, TransactionOrigin};
use miner::transaction_queue::QueuingInstant;
use error::{Error, TransactionError};
use ethereum_types::{H256, U256, Address}; use ethereum_types::{H256, U256, Address};
use hash::keccak; use hash::keccak;
use transaction::{self, SignedTransaction, Action};
use transient_hashmap::TransientHashMap;
use transaction_queue::{TransactionQueue, TransactionDetailsProvider, TransactionOrigin, QueuingInstant};
type Count = u16; type Count = u16;
@ -80,8 +79,8 @@ impl BanningTransactionQueue {
&mut self, &mut self,
transaction: SignedTransaction, transaction: SignedTransaction,
time: QueuingInstant, time: QueuingInstant,
details_provider: &TransactionQueueDetailsProvider, details_provider: &TransactionDetailsProvider,
) -> Result<TransactionImportResult, Error> { ) -> Result<transaction::ImportResult, transaction::Error> {
if let Threshold::BanAfter(threshold) = self.ban_threshold { if let Threshold::BanAfter(threshold) = self.ban_threshold {
// NOTE In all checks use direct query to avoid increasing ban timeout. // NOTE In all checks use direct query to avoid increasing ban timeout.
@ -90,7 +89,7 @@ impl BanningTransactionQueue {
let count = self.senders_bans.direct().get(&sender).cloned().unwrap_or(0); let count = self.senders_bans.direct().get(&sender).cloned().unwrap_or(0);
if count > threshold { if count > threshold {
debug!(target: "txqueue", "Ignoring transaction {:?} because sender is banned.", transaction.hash()); debug!(target: "txqueue", "Ignoring transaction {:?} because sender is banned.", transaction.hash());
return Err(Error::Transaction(TransactionError::SenderBanned)); return Err(transaction::Error::SenderBanned);
} }
// Check recipient // Check recipient
@ -98,7 +97,7 @@ impl BanningTransactionQueue {
let count = self.recipients_bans.direct().get(&recipient).cloned().unwrap_or(0); let count = self.recipients_bans.direct().get(&recipient).cloned().unwrap_or(0);
if count > threshold { if count > threshold {
debug!(target: "txqueue", "Ignoring transaction {:?} because recipient is banned.", transaction.hash()); debug!(target: "txqueue", "Ignoring transaction {:?} because recipient is banned.", transaction.hash());
return Err(Error::Transaction(TransactionError::RecipientBanned)); return Err(transaction::Error::RecipientBanned);
} }
} }
@ -108,7 +107,7 @@ impl BanningTransactionQueue {
let count = self.codes_bans.direct().get(&code_hash).cloned().unwrap_or(0); let count = self.codes_bans.direct().get(&code_hash).cloned().unwrap_or(0);
if count > threshold { if count > threshold {
debug!(target: "txqueue", "Ignoring transaction {:?} because code is banned.", transaction.hash()); debug!(target: "txqueue", "Ignoring transaction {:?} because code is banned.", transaction.hash());
return Err(Error::Transaction(TransactionError::CodeBanned)); return Err(transaction::Error::CodeBanned);
} }
} }
} }
@ -209,17 +208,11 @@ impl DerefMut for BanningTransactionQueue {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use std::time::Duration; use super::*;
use rustc_hex::FromHex;
use hash::keccak;
use super::{BanningTransactionQueue, Threshold};
use ethkey::{Random, Generator}; use ethkey::{Random, Generator};
use transaction::{Transaction, SignedTransaction, Action}; use rustc_hex::FromHex;
use error::{Error, TransactionError}; use transaction_queue::test::DummyTransactionDetailsProvider;
use client::TransactionImportResult;
use miner::{TransactionQueue, TransactionOrigin};
use ethereum_types::{U256, Address}; use ethereum_types::{U256, Address};
use miner::transaction_queue::test::DummyTransactionDetailsProvider;
fn queue() -> BanningTransactionQueue { fn queue() -> BanningTransactionQueue {
BanningTransactionQueue::new(TransactionQueue::default(), Threshold::BanAfter(1), Duration::from_secs(180)) BanningTransactionQueue::new(TransactionQueue::default(), Threshold::BanAfter(1), Duration::from_secs(180))
@ -231,7 +224,7 @@ mod tests {
fn transaction(action: Action) -> SignedTransaction { fn transaction(action: Action) -> SignedTransaction {
let keypair = Random.generate().unwrap(); let keypair = Random.generate().unwrap();
Transaction { transaction::Transaction {
action: action, action: action,
value: U256::from(100), value: U256::from(100),
data: "3331600055".from_hex().unwrap(), data: "3331600055".from_hex().unwrap(),
@ -241,12 +234,8 @@ mod tests {
}.sign(keypair.secret(), None) }.sign(keypair.secret(), None)
} }
fn unwrap_err(res: Result<TransactionImportResult, Error>) -> TransactionError { fn unwrap_err(res: Result<transaction::ImportResult, transaction::Error>) -> transaction::Error {
match res { res.unwrap_err()
Err(Error::Transaction(e)) => e,
Ok(x) => panic!("Expected error, got: Ok({:?})", x),
Err(e) => panic!("Unexpected error type returned by queue: {:?}", e),
}
} }
#[test] #[test]
@ -273,7 +262,7 @@ mod tests {
assert!(!banlist1, "Threshold not reached yet."); assert!(!banlist1, "Threshold not reached yet.");
// Insert once // Insert once
let import1 = txq.add_with_banlist(tx.clone(), 0, &default_tx_provider()).unwrap(); let import1 = txq.add_with_banlist(tx.clone(), 0, &default_tx_provider()).unwrap();
assert_eq!(import1, TransactionImportResult::Current); assert_eq!(import1, transaction::ImportResult::Current);
// when // when
let banlist2 = txq.ban_sender(tx.sender()); let banlist2 = txq.ban_sender(tx.sender());
@ -281,7 +270,7 @@ mod tests {
// then // then
assert!(banlist2, "Threshold should be reached - banned."); assert!(banlist2, "Threshold should be reached - banned.");
assert_eq!(unwrap_err(import2), TransactionError::SenderBanned); assert_eq!(unwrap_err(import2), transaction::Error::SenderBanned);
// Should also remove transacion from the queue // Should also remove transacion from the queue
assert_eq!(txq.find(&tx.hash()), None); assert_eq!(txq.find(&tx.hash()), None);
} }
@ -297,7 +286,7 @@ mod tests {
assert!(!banlist1, "Threshold not reached yet."); assert!(!banlist1, "Threshold not reached yet.");
// Insert once // Insert once
let import1 = txq.add_with_banlist(tx.clone(), 0, &default_tx_provider()).unwrap(); let import1 = txq.add_with_banlist(tx.clone(), 0, &default_tx_provider()).unwrap();
assert_eq!(import1, TransactionImportResult::Current); assert_eq!(import1, transaction::ImportResult::Current);
// when // when
let banlist2 = txq.ban_recipient(recipient); let banlist2 = txq.ban_recipient(recipient);
@ -305,7 +294,7 @@ mod tests {
// then // then
assert!(banlist2, "Threshold should be reached - banned."); assert!(banlist2, "Threshold should be reached - banned.");
assert_eq!(unwrap_err(import2), TransactionError::RecipientBanned); assert_eq!(unwrap_err(import2), transaction::Error::RecipientBanned);
} }
#[test] #[test]
@ -319,7 +308,7 @@ mod tests {
assert!(!banlist1, "Threshold not reached yet."); assert!(!banlist1, "Threshold not reached yet.");
// Insert once // Insert once
let import1 = txq.add_with_banlist(tx.clone(), 0, &default_tx_provider()).unwrap(); let import1 = txq.add_with_banlist(tx.clone(), 0, &default_tx_provider()).unwrap();
assert_eq!(import1, TransactionImportResult::Current); assert_eq!(import1, transaction::ImportResult::Current);
// when // when
let banlist2 = txq.ban_codehash(codehash); let banlist2 = txq.ban_codehash(codehash);
@ -327,6 +316,6 @@ mod tests {
// then // then
assert!(banlist2, "Threshold should be reached - banned."); assert!(banlist2, "Threshold should be reached - banned.");
assert_eq!(unwrap_err(import2), TransactionError::CodeBanned); assert_eq!(unwrap_err(import2), transaction::Error::CodeBanned);
} }
} }

View File

@ -14,6 +14,8 @@
// 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/>.
//! External Miner hashrate tracker.
use std::collections::HashMap; use std::collections::HashMap;
use std::sync::Arc; use std::sync::Arc;
use std::time::{Instant, Duration}; use std::time::{Instant, Duration};

47
miner/src/lib.rs Normal file
View File

@ -0,0 +1,47 @@
// 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/>.
#![warn(missing_docs)]
//! Miner module
//! Keeps track of transactions and mined block.
extern crate common_types as types;
extern crate ethereum_types;
extern crate ethcore_transaction as transaction;
extern crate futures;
extern crate heapsize;
extern crate keccak_hash as hash;
extern crate linked_hash_map;
extern crate native_contracts;
extern crate parking_lot;
extern crate table;
extern crate transient_hashmap;
#[macro_use]
extern crate log;
#[cfg(test)]
extern crate rustc_hex;
#[cfg(test)]
extern crate ethkey;
pub mod banning_queue;
pub mod external;
pub mod local_transactions;
pub mod service_transaction_checker;
pub mod transaction_queue;
pub mod work_notify;

View File

@ -16,10 +16,9 @@
//! Local Transactions List. //! Local Transactions List.
use linked_hash_map::LinkedHashMap;
use transaction::{SignedTransaction, PendingTransaction};
use error::TransactionError;
use ethereum_types::{H256, U256}; use ethereum_types::{H256, U256};
use linked_hash_map::LinkedHashMap;
use transaction::{self, SignedTransaction, PendingTransaction};
/// Status of local transaction. /// Status of local transaction.
/// Can indicate that the transaction is currently part of the queue (`Pending/Future`) /// Can indicate that the transaction is currently part of the queue (`Pending/Future`)
@ -37,7 +36,7 @@ pub enum Status {
/// Replaced because of higher gas price of another transaction. /// Replaced because of higher gas price of another transaction.
Replaced(SignedTransaction, U256, H256), Replaced(SignedTransaction, U256, H256),
/// Transaction was never accepted to the queue. /// Transaction was never accepted to the queue.
Rejected(SignedTransaction, TransactionError), Rejected(SignedTransaction, transaction::Error),
/// Transaction is invalid. /// Transaction is invalid.
Invalid(SignedTransaction), Invalid(SignedTransaction),
/// Transaction was canceled. /// Transaction was canceled.
@ -64,6 +63,7 @@ impl Default for LocalTransactionsList {
} }
impl LocalTransactionsList { impl LocalTransactionsList {
/// Create a new list of local transactions.
pub fn new(max_old: usize) -> Self { pub fn new(max_old: usize) -> Self {
LocalTransactionsList { LocalTransactionsList {
max_old: max_old, max_old: max_old,
@ -71,58 +71,68 @@ impl LocalTransactionsList {
} }
} }
/// Mark transaction with given hash as pending.
pub fn mark_pending(&mut self, hash: H256) { pub fn mark_pending(&mut self, hash: H256) {
debug!(target: "own_tx", "Imported to Current (hash {:?})", hash); debug!(target: "own_tx", "Imported to Current (hash {:?})", hash);
self.clear_old(); self.clear_old();
self.transactions.insert(hash, Status::Pending); self.transactions.insert(hash, Status::Pending);
} }
/// Mark transaction with given hash as future.
pub fn mark_future(&mut self, hash: H256) { pub fn mark_future(&mut self, hash: H256) {
debug!(target: "own_tx", "Imported to Future (hash {:?})", hash); debug!(target: "own_tx", "Imported to Future (hash {:?})", hash);
self.transactions.insert(hash, Status::Future); self.transactions.insert(hash, Status::Future);
self.clear_old(); self.clear_old();
} }
pub fn mark_rejected(&mut self, tx: SignedTransaction, err: TransactionError) { /// Mark given transaction as rejected from the queue.
pub fn mark_rejected(&mut self, tx: SignedTransaction, err: transaction::Error) {
debug!(target: "own_tx", "Transaction rejected (hash {:?}): {:?}", tx.hash(), err); debug!(target: "own_tx", "Transaction rejected (hash {:?}): {:?}", tx.hash(), err);
self.transactions.insert(tx.hash(), Status::Rejected(tx, err)); self.transactions.insert(tx.hash(), Status::Rejected(tx, err));
self.clear_old(); self.clear_old();
} }
/// Mark the transaction as replaced by transaction with given hash.
pub fn mark_replaced(&mut self, tx: SignedTransaction, gas_price: U256, hash: H256) { pub fn mark_replaced(&mut self, tx: SignedTransaction, gas_price: U256, hash: H256) {
debug!(target: "own_tx", "Transaction replaced (hash {:?}) by {:?} (new gas price: {:?})", tx.hash(), hash, gas_price); debug!(target: "own_tx", "Transaction replaced (hash {:?}) by {:?} (new gas price: {:?})", tx.hash(), hash, gas_price);
self.transactions.insert(tx.hash(), Status::Replaced(tx, gas_price, hash)); self.transactions.insert(tx.hash(), Status::Replaced(tx, gas_price, hash));
self.clear_old(); self.clear_old();
} }
/// Mark transaction as invalid.
pub fn mark_invalid(&mut self, tx: SignedTransaction) { pub fn mark_invalid(&mut self, tx: SignedTransaction) {
warn!(target: "own_tx", "Transaction marked invalid (hash {:?})", tx.hash()); warn!(target: "own_tx", "Transaction marked invalid (hash {:?})", tx.hash());
self.transactions.insert(tx.hash(), Status::Invalid(tx)); self.transactions.insert(tx.hash(), Status::Invalid(tx));
self.clear_old(); self.clear_old();
} }
/// Mark transaction as canceled.
pub fn mark_canceled(&mut self, tx: PendingTransaction) { pub fn mark_canceled(&mut self, tx: PendingTransaction) {
warn!(target: "own_tx", "Transaction canceled (hash {:?})", tx.hash()); warn!(target: "own_tx", "Transaction canceled (hash {:?})", tx.hash());
self.transactions.insert(tx.hash(), Status::Canceled(tx)); self.transactions.insert(tx.hash(), Status::Canceled(tx));
self.clear_old(); self.clear_old();
} }
/// Mark transaction as dropped because of limit.
pub fn mark_dropped(&mut self, tx: SignedTransaction) { pub fn mark_dropped(&mut self, tx: SignedTransaction) {
warn!(target: "own_tx", "Transaction dropped (hash {:?})", tx.hash()); warn!(target: "own_tx", "Transaction dropped (hash {:?})", tx.hash());
self.transactions.insert(tx.hash(), Status::Dropped(tx)); self.transactions.insert(tx.hash(), Status::Dropped(tx));
self.clear_old(); self.clear_old();
} }
/// Mark transaction as mined.
pub fn mark_mined(&mut self, tx: SignedTransaction) { pub fn mark_mined(&mut self, tx: SignedTransaction) {
info!(target: "own_tx", "Transaction mined (hash {:?})", tx.hash()); info!(target: "own_tx", "Transaction mined (hash {:?})", tx.hash());
self.transactions.insert(tx.hash(), Status::Mined(tx)); self.transactions.insert(tx.hash(), Status::Mined(tx));
self.clear_old(); self.clear_old();
} }
/// Returns true if the transaction is already in local transactions.
pub fn contains(&self, hash: &H256) -> bool { pub fn contains(&self, hash: &H256) -> bool {
self.transactions.contains_key(hash) self.transactions.contains_key(hash)
} }
/// Return a map of all currently stored transactions.
pub fn all_transactions(&self) -> &LinkedHashMap<H256, Status> { pub fn all_transactions(&self) -> &LinkedHashMap<H256, Status> {
&self.transactions &self.transactions
} }
@ -152,10 +162,9 @@ impl LocalTransactionsList {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*;
use ethereum_types::U256; use ethereum_types::U256;
use ethkey::{Random, Generator}; use ethkey::{Random, Generator};
use transaction::{Action, Transaction, SignedTransaction};
use super::{LocalTransactionsList, Status};
#[test] #[test]
fn should_add_transaction_as_pending() { fn should_add_transaction_as_pending() {
@ -199,8 +208,8 @@ mod tests {
fn new_tx(nonce: U256) -> SignedTransaction { fn new_tx(nonce: U256) -> SignedTransaction {
let keypair = Random.generate().unwrap(); let keypair = Random.generate().unwrap();
Transaction { transaction::Transaction {
action: Action::Create, action: transaction::Action::Create,
value: U256::from(100), value: U256::from(100),
data: Default::default(), data: Default::default(),
gas: U256::from(10), gas: U256::from(10),

View File

@ -14,17 +14,26 @@
// 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 client::MiningBlockChainClient; //! A service transactions contract checker.
use transaction::SignedTransaction;
use types::ids::BlockId;
use futures::{future, Future}; use futures::{future, Future};
use native_contracts::ServiceTransactionChecker as Contract; use native_contracts::ServiceTransactionChecker as Contract;
use ethereum_types::U256; use ethereum_types::{U256, Address};
use parking_lot::Mutex; use parking_lot::Mutex;
use transaction::SignedTransaction;
use types::ids::BlockId;
const SERVICE_TRANSACTION_CONTRACT_REGISTRY_NAME: &'static str = "service_transaction_checker"; const SERVICE_TRANSACTION_CONTRACT_REGISTRY_NAME: &'static str = "service_transaction_checker";
/// A contract calling interface.
pub trait ContractCaller {
/// Returns address of contract from the registry, given it's name
fn registry_address(&self, name: &str) -> Option<Address>;
/// Executes a contract call at given block.
fn call_contract(&self, BlockId, Address, Vec<u8>) -> Result<Vec<u8>, String>;
}
/// Service transactions checker. /// Service transactions checker.
#[derive(Default)] #[derive(Default)]
pub struct ServiceTransactionChecker { pub struct ServiceTransactionChecker {
@ -33,10 +42,10 @@ pub struct ServiceTransactionChecker {
impl ServiceTransactionChecker { impl ServiceTransactionChecker {
/// Try to create instance, reading contract address from given chain client. /// Try to create instance, reading contract address from given chain client.
pub fn update_from_chain_client(&self, client: &MiningBlockChainClient) { pub fn update_from_chain_client(&self, client: &ContractCaller) {
let mut contract = self.contract.lock(); let mut contract = self.contract.lock();
if contract.is_none() { if contract.is_none() {
*contract = client.registry_address(SERVICE_TRANSACTION_CONTRACT_REGISTRY_NAME.to_owned()) *contract = client.registry_address(SERVICE_TRANSACTION_CONTRACT_REGISTRY_NAME)
.and_then(|contract_addr| { .and_then(|contract_addr| {
trace!(target: "txqueue", "Configuring for service transaction checker contract from {}", contract_addr); trace!(target: "txqueue", "Configuring for service transaction checker contract from {}", contract_addr);
@ -46,7 +55,7 @@ impl ServiceTransactionChecker {
} }
/// Checks if service transaction can be appended to the transaction queue. /// Checks if service transaction can be appended to the transaction queue.
pub fn check(&self, client: &MiningBlockChainClient, tx: &SignedTransaction) -> Result<bool, String> { pub fn check(&self, client: &ContractCaller, tx: &SignedTransaction) -> Result<bool, String> {
debug_assert_eq!(tx.gas_price, U256::zero()); debug_assert_eq!(tx.gas_price, U256::zero());
if let Some(ref contract) = *self.contract.lock() { if let Some(ref contract) = *self.contract.lock() {

View File

@ -25,20 +25,21 @@
//! //!
//! ```rust //! ```rust
//! extern crate ethereum_types; //! extern crate ethereum_types;
//! extern crate ethcore; //! extern crate ethcore_miner as miner;
//! extern crate ethcore_transaction as transaction;
//! extern crate ethkey; //! extern crate ethkey;
//! extern crate rustc_hex; //! extern crate rustc_hex;
//! //!
//! use ethereum_types::{U256, Address}; //! use ethereum_types::{U256, Address};
//! use ethkey::{Random, Generator}; //! use ethkey::{Random, Generator};
//! use ethcore::miner::{TransactionQueue, RemovalReason, TransactionQueueDetailsProvider, AccountDetails, TransactionOrigin}; //! use miner::transaction_queue::{TransactionQueue, TransactionDetailsProvider, AccountDetails, TransactionOrigin, RemovalReason};
//! use ethcore::transaction::*; //! use transaction::*;
//! use rustc_hex::FromHex; //! use rustc_hex::FromHex;
//! //!
//! #[derive(Default)] //! #[derive(Default)]
//! struct DummyTransactionDetailsProvider; //! struct DummyTransactionDetailsProvider;
//! //!
//! impl TransactionQueueDetailsProvider for DummyTransactionDetailsProvider { //! impl TransactionDetailsProvider for DummyTransactionDetailsProvider {
//! fn fetch_account(&self, _address: &Address) -> AccountDetails { //! fn fetch_account(&self, _address: &Address) -> AccountDetails {
//! AccountDetails { //! AccountDetails {
//! nonce: U256::from(10), //! nonce: U256::from(10),
@ -100,19 +101,19 @@
//! 4. `remove_old` is used as convenient method to update the state nonce for all senders in the queue. //! 4. `remove_old` is used as convenient method to update the state nonce for all senders in the queue.
//! - Invokes `cull` with latest state nonce for all senders. //! - Invokes `cull` with latest state nonce for all senders.
use std::ops::Deref;
use std::cmp::Ordering; use std::cmp::Ordering;
use std::cmp; use std::cmp;
use std::collections::{HashSet, HashMap, BTreeSet, BTreeMap}; use std::collections::{HashSet, HashMap, BTreeSet, BTreeMap};
use linked_hash_map::LinkedHashMap; use std::ops::Deref;
use heapsize::HeapSizeOf;
use ethereum_types::{H256, U256, Address}; use ethereum_types::{H256, U256, Address};
use heapsize::HeapSizeOf;
use linked_hash_map::LinkedHashMap;
use local_transactions::{LocalTransactionsList, Status as LocalTransactionStatus};
use table::Table; use table::Table;
use transaction::*; use transaction::{self, SignedTransaction, PendingTransaction};
use error::{Error, TransactionError};
use client::TransactionImportResult; type BlockNumber = u64;
use header::BlockNumber;
use miner::local_transactions::{LocalTransactionsList, Status as LocalTransactionStatus};
/// Transaction origin /// Transaction origin
#[derive(Clone, Copy, Debug, PartialEq, Eq)] #[derive(Clone, Copy, Debug, PartialEq, Eq)]
@ -281,7 +282,7 @@ struct VerifiedTransaction {
/// Transaction origin. /// Transaction origin.
origin: TransactionOrigin, origin: TransactionOrigin,
/// Delay until specified condition is met. /// Delay until specified condition is met.
condition: Option<Condition>, condition: Option<transaction::Condition>,
/// Insertion time /// Insertion time
insertion_time: QueuingInstant, insertion_time: QueuingInstant,
/// ID assigned upon insertion, should be unique. /// ID assigned upon insertion, should be unique.
@ -292,7 +293,7 @@ impl VerifiedTransaction {
fn new( fn new(
transaction: SignedTransaction, transaction: SignedTransaction,
origin: TransactionOrigin, origin: TransactionOrigin,
condition: Option<Condition>, condition: Option<transaction::Condition>,
insertion_time: QueuingInstant, insertion_time: QueuingInstant,
insertion_id: u64, insertion_id: u64,
) -> Self { ) -> Self {
@ -705,31 +706,28 @@ impl TransactionQueue {
tx: SignedTransaction, tx: SignedTransaction,
origin: TransactionOrigin, origin: TransactionOrigin,
time: QueuingInstant, time: QueuingInstant,
condition: Option<Condition>, condition: Option<transaction::Condition>,
details_provider: &TransactionDetailsProvider, details_provider: &TransactionDetailsProvider,
) -> Result<TransactionImportResult, Error> { ) -> Result<transaction::ImportResult, transaction::Error> {
if origin == TransactionOrigin::Local { if origin == TransactionOrigin::Local {
let hash = tx.hash(); let hash = tx.hash();
let cloned_tx = tx.clone(); let cloned_tx = tx.clone();
let result = self.add_internal(tx, origin, time, condition, details_provider); let result = self.add_internal(tx, origin, time, condition, details_provider);
match result { match result {
Ok(TransactionImportResult::Current) => { Ok(transaction::ImportResult::Current) => {
self.local_transactions.mark_pending(hash); self.local_transactions.mark_pending(hash);
}, },
Ok(TransactionImportResult::Future) => { Ok(transaction::ImportResult::Future) => {
self.local_transactions.mark_future(hash); self.local_transactions.mark_future(hash);
}, },
Err(Error::Transaction(ref err)) => { Err(ref err) => {
// Sometimes transactions are re-imported, so // Sometimes transactions are re-imported, so
// don't overwrite transactions if they are already on the list // don't overwrite transactions if they are already on the list
if !self.local_transactions.contains(&hash) { if !self.local_transactions.contains(&hash) {
self.local_transactions.mark_rejected(cloned_tx, err.clone()); self.local_transactions.mark_rejected(cloned_tx, err.clone());
} }
}, },
Err(_) => {
self.local_transactions.mark_invalid(cloned_tx);
},
} }
result result
} else { } else {
@ -743,9 +741,9 @@ impl TransactionQueue {
tx: SignedTransaction, tx: SignedTransaction,
origin: TransactionOrigin, origin: TransactionOrigin,
time: QueuingInstant, time: QueuingInstant,
condition: Option<Condition>, condition: Option<transaction::Condition>,
details_provider: &TransactionDetailsProvider, details_provider: &TransactionDetailsProvider,
) -> Result<TransactionImportResult, Error> { ) -> Result<transaction::ImportResult, transaction::Error> {
if origin != TransactionOrigin::Local && tx.gas_price < self.minimal_gas_price { if origin != TransactionOrigin::Local && tx.gas_price < self.minimal_gas_price {
// if it is non-service-transaction => drop // if it is non-service-transaction => drop
let is_service_transaction = tx.gas_price.is_zero(); let is_service_transaction = tx.gas_price.is_zero();
@ -757,10 +755,10 @@ impl TransactionQueue {
self.minimal_gas_price self.minimal_gas_price
); );
return Err(Error::Transaction(TransactionError::InsufficientGasPrice { return Err(transaction::Error::InsufficientGasPrice {
minimal: self.minimal_gas_price, minimal: self.minimal_gas_price,
got: tx.gas_price, got: tx.gas_price,
})); });
} }
let is_service_transaction_accepted = match details_provider.is_service_transaction_acceptable(&tx) { let is_service_transaction_accepted = match details_provider.is_service_transaction_acceptable(&tx) {
@ -786,10 +784,10 @@ impl TransactionQueue {
}; };
if !is_service_transaction_accepted { if !is_service_transaction_accepted {
return Err(Error::Transaction(TransactionError::InsufficientGasPrice { return Err(transaction::Error::InsufficientGasPrice {
minimal: self.minimal_gas_price, minimal: self.minimal_gas_price,
got: tx.gas_price, got: tx.gas_price,
})); });
} }
} }
@ -802,10 +800,10 @@ impl TransactionQueue {
full_queues_lowest full_queues_lowest
); );
return Err(Error::Transaction(TransactionError::InsufficientGasPrice { return Err(transaction::Error::InsufficientGasPrice {
minimal: full_queues_lowest, minimal: full_queues_lowest,
got: tx.gas_price, got: tx.gas_price,
})); });
} }
let gas_limit = cmp::min(self.tx_gas_limit, self.block_gas_limit); let gas_limit = cmp::min(self.tx_gas_limit, self.block_gas_limit);
@ -817,10 +815,10 @@ impl TransactionQueue {
self.block_gas_limit, self.block_gas_limit,
self.tx_gas_limit self.tx_gas_limit
); );
return Err(Error::Transaction(TransactionError::GasLimitExceeded { return Err(transaction::Error::GasLimitExceeded {
limit: gas_limit, limit: gas_limit,
got: tx.gas, got: tx.gas,
})); });
} }
let minimal_gas = details_provider.estimate_gas_required(&tx); let minimal_gas = details_provider.estimate_gas_required(&tx);
@ -832,10 +830,10 @@ impl TransactionQueue {
minimal_gas, minimal_gas,
); );
return Err(Error::Transaction(TransactionError::InsufficientGas { return Err(transaction::Error::InsufficientGas {
minimal: minimal_gas, minimal: minimal_gas,
got: tx.gas, got: tx.gas,
})); });
} }
let client_account = details_provider.fetch_account(&tx.sender()); let client_account = details_provider.fetch_account(&tx.sender());
@ -848,17 +846,17 @@ impl TransactionQueue {
cost cost
); );
return Err(Error::Transaction(TransactionError::InsufficientBalance { return Err(transaction::Error::InsufficientBalance {
cost: cost, cost: cost,
balance: client_account.balance balance: client_account.balance
})); });
} }
tx.check_low_s()?; tx.check_low_s()?;
// No invalid transactions beyond this point. // No invalid transactions beyond this point.
let id = self.next_transaction_id; let id = self.next_transaction_id;
self.next_transaction_id += 1; self.next_transaction_id += 1;
let vtx = VerifiedTransaction::new(tx, origin, condition, time, id); let vtx = VerifiedTransaction::new(tx, origin, condition, time, id);
let r = self.import_tx(vtx, client_account.nonce).map_err(Error::Transaction); let r = self.import_tx(vtx, client_account.nonce);
assert_eq!(self.future.by_priority.len() + self.current.by_priority.len(), self.by_hash.len()); assert_eq!(self.future.by_priority.len() + self.current.by_priority.len(), self.by_hash.len());
r r
} }
@ -1140,8 +1138,8 @@ impl TransactionQueue {
} }
} }
let delay = match tx.condition { let delay = match tx.condition {
Some(Condition::Number(n)) => n > best_block, Some(transaction::Condition::Number(n)) => n > best_block,
Some(Condition::Timestamp(t)) => t > best_timestamp, Some(transaction::Condition::Timestamp(t)) => t > best_timestamp,
None => false, None => false,
}; };
if delay { if delay {
@ -1254,12 +1252,13 @@ impl TransactionQueue {
/// iff `(address, nonce)` is the same but `gas_price` is higher. /// iff `(address, nonce)` is the same but `gas_price` is higher.
/// ///
/// Returns `true` when transaction was imported successfuly /// Returns `true` when transaction was imported successfuly
fn import_tx(&mut self, tx: VerifiedTransaction, state_nonce: U256) -> Result<TransactionImportResult, TransactionError> { fn import_tx(&mut self, tx: VerifiedTransaction, state_nonce: U256) -> Result<transaction::ImportResult,
transaction::Error> {
if self.by_hash.get(&tx.hash()).is_some() { if self.by_hash.get(&tx.hash()).is_some() {
// Transaction is already imported. // Transaction is already imported.
trace!(target: "txqueue", "Dropping already imported transaction: {:?}", tx.hash()); trace!(target: "txqueue", "Dropping already imported transaction: {:?}", tx.hash());
return Err(TransactionError::AlreadyImported); return Err(transaction::Error::AlreadyImported);
} }
let min_gas_price = (self.minimal_gas_price, self.strategy); let min_gas_price = (self.minimal_gas_price, self.strategy);
@ -1273,7 +1272,7 @@ impl TransactionQueue {
if nonce < state_nonce { if nonce < state_nonce {
// Droping transaction // Droping transaction
trace!(target: "txqueue", "Dropping old transaction: {:?} (nonce: {} < {})", tx.hash(), nonce, state_nonce); trace!(target: "txqueue", "Dropping old transaction: {:?} (nonce: {} < {})", tx.hash(), nonce, state_nonce);
return Err(TransactionError::Old); return Err(transaction::Error::Old);
} }
// Update nonces of transactions in future (remove old transactions) // Update nonces of transactions in future (remove old transactions)
@ -1304,7 +1303,7 @@ impl TransactionQueue {
debug!(target: "txqueue", "Importing transaction to future: {:?}", hash); debug!(target: "txqueue", "Importing transaction to future: {:?}", hash);
debug!(target: "txqueue", "status: {:?}", self.status()); debug!(target: "txqueue", "status: {:?}", self.status());
return Ok(TransactionImportResult::Future); return Ok(transaction::ImportResult::Future);
} }
// We might have filled a gap - move some more transactions from future // We might have filled a gap - move some more transactions from future
@ -1328,7 +1327,7 @@ impl TransactionQueue {
debug!(target: "txqueue", "Imported transaction to current: {:?}", hash); debug!(target: "txqueue", "Imported transaction to current: {:?}", hash);
debug!(target: "txqueue", "status: {:?}", self.status()); debug!(target: "txqueue", "status: {:?}", self.status());
Ok(TransactionImportResult::Current) Ok(transaction::ImportResult::Current)
} }
/// Updates /// Updates
@ -1415,19 +1414,20 @@ impl TransactionQueue {
} }
} }
fn check_too_cheap(is_in: bool) -> Result<(), TransactionError> { fn check_too_cheap(is_in: bool) -> Result<(), transaction::Error> {
if is_in { if is_in {
Ok(()) Ok(())
} else { } else {
Err(TransactionError::TooCheapToReplace) Err(transaction::Error::TooCheapToReplace)
} }
} }
fn check_if_removed(sender: &Address, nonce: &U256, dropped: Option<HashMap<Address, U256>>) -> Result<(), TransactionError> { fn check_if_removed(sender: &Address, nonce: &U256, dropped: Option<HashMap<Address, U256>>) -> Result<(),
transaction::Error> {
match dropped { match dropped {
Some(ref dropped) => match dropped.get(sender) { Some(ref dropped) => match dropped.get(sender) {
Some(min) if nonce >= min => { Some(min) if nonce >= min => {
Err(TransactionError::LimitReached) Err(transaction::Error::LimitReached)
}, },
_ => Ok(()), _ => Ok(()),
}, },
@ -1438,16 +1438,11 @@ fn check_if_removed(sender: &Address, nonce: &U256, dropped: Option<HashMap<Addr
#[cfg(test)] #[cfg(test)]
pub mod test { pub mod test {
use rustc_hex::FromHex;
use table::Table;
use ethereum_types::{U256, Address}; use ethereum_types::{U256, Address};
use ethkey::{Random, Generator};
use error::{Error, TransactionError};
use super::*; use super::*;
use super::{TransactionSet, TransactionOrder, VerifiedTransaction}; use ethkey::{Random, Generator};
use miner::local_transactions::LocalTransactionsList; use rustc_hex::FromHex;
use client::TransactionImportResult; use transaction::Transaction;
use transaction::{SignedTransaction, Transaction, Action, Condition};
pub struct DummyTransactionDetailsProvider { pub struct DummyTransactionDetailsProvider {
account_details: AccountDetails, account_details: AccountDetails,
@ -1509,11 +1504,8 @@ pub mod test {
} }
} }
fn unwrap_tx_err(err: Result<TransactionImportResult, Error>) -> TransactionError { fn unwrap_tx_err(err: Result<transaction::ImportResult, transaction::Error>) -> transaction::Error {
match err.unwrap_err() { err.unwrap_err()
Error::Transaction(e) => e,
_ => panic!("Expected transaction error!"),
}
} }
fn default_nonce() -> U256 { 123.into() } fn default_nonce() -> U256 { 123.into() }
@ -1522,7 +1514,7 @@ pub mod test {
fn new_unsigned_tx(nonce: U256, gas: U256, gas_price: U256) -> Transaction { fn new_unsigned_tx(nonce: U256, gas: U256, gas_price: U256) -> Transaction {
Transaction { Transaction {
action: Action::Create, action: transaction::Action::Create,
value: U256::from(100), value: U256::from(100),
data: "3331600055".from_hex().unwrap(), data: "3331600055".from_hex().unwrap(),
gas: gas, gas: gas,
@ -1632,11 +1624,11 @@ pub mod test {
// We may want to reconsider this in the near future so leaving this code in as a // We may want to reconsider this in the near future so leaving this code in as a
// possible alternative. // possible alternative.
/* /*
assert_eq!(res.unwrap(), TransactionImportResult::Current); assert_eq!(res.unwrap(), transaction::ImportResult::Current);
assert_eq!(txq.status().pending, 2); assert_eq!(txq.status().pending, 2);
assert_eq!(txq.last_nonce(&sender), Some(nonce)); assert_eq!(txq.last_nonce(&sender), Some(nonce));
*/ */
assert_eq!(unwrap_tx_err(res), TransactionError::InsufficientGasPrice { assert_eq!(unwrap_tx_err(res), transaction::Error::InsufficientGasPrice {
minimal: 2.into(), minimal: 2.into(),
got: 1.into(), got: 1.into(),
}); });
@ -1785,14 +1777,14 @@ pub mod test {
// First insert one transaction to future // First insert one transaction to future
let res = txq.add(tx, TransactionOrigin::External, 0, None, &default_tx_provider().with_account_nonce(prev_nonce)); let res = txq.add(tx, TransactionOrigin::External, 0, None, &default_tx_provider().with_account_nonce(prev_nonce));
assert_eq!(res.unwrap(), TransactionImportResult::Future); assert_eq!(res.unwrap(), transaction::ImportResult::Future);
assert_eq!(txq.status().future, 1); assert_eq!(txq.status().future, 1);
// now import second transaction to current // now import second transaction to current
let res = txq.add(tx2.clone(), TransactionOrigin::External, 0, None, &default_tx_provider()); let res = txq.add(tx2.clone(), TransactionOrigin::External, 0, None, &default_tx_provider());
// and then there should be only one transaction in current (the one with higher gas_price) // and then there should be only one transaction in current (the one with higher gas_price)
assert_eq!(res.unwrap(), TransactionImportResult::Current); assert_eq!(res.unwrap(), transaction::ImportResult::Current);
assert_eq!(txq.status().pending, 1); assert_eq!(txq.status().pending, 1);
assert_eq!(txq.status().future, 0); assert_eq!(txq.status().future, 0);
assert_eq!(txq.current.by_priority.len(), 1); assert_eq!(txq.current.by_priority.len(), 1);
@ -1810,14 +1802,14 @@ pub mod test {
// First insert one transaction to future // First insert one transaction to future
let res = txq.add(tx.clone(), TransactionOrigin::External, 0, None, &default_tx_provider().with_account_nonce(prev_nonce)); let res = txq.add(tx.clone(), TransactionOrigin::External, 0, None, &default_tx_provider().with_account_nonce(prev_nonce));
assert_eq!(res.unwrap(), TransactionImportResult::Future); assert_eq!(res.unwrap(), transaction::ImportResult::Future);
assert_eq!(txq.status().future, 1); assert_eq!(txq.status().future, 1);
// now import second transaction to current // now import second transaction to current
let res = txq.add(tx2.clone(), TransactionOrigin::External, 0, None, &default_tx_provider()); let res = txq.add(tx2.clone(), TransactionOrigin::External, 0, None, &default_tx_provider());
// then // then
assert_eq!(res.unwrap(), TransactionImportResult::Current); assert_eq!(res.unwrap(), transaction::ImportResult::Current);
assert_eq!(txq.status().pending, 2); assert_eq!(txq.status().pending, 2);
assert_eq!(txq.status().future, 0); assert_eq!(txq.status().future, 0);
assert_eq!(txq.current.by_priority.len(), 2); assert_eq!(txq.current.by_priority.len(), 2);
@ -1837,7 +1829,7 @@ pub mod test {
let res = txq.add(tx, TransactionOrigin::External, 0, None, &default_tx_provider()); let res = txq.add(tx, TransactionOrigin::External, 0, None, &default_tx_provider());
// then // then
assert_eq!(res.unwrap(), TransactionImportResult::Current); assert_eq!(res.unwrap(), transaction::ImportResult::Current);
let stats = txq.status(); let stats = txq.status();
assert_eq!(stats.pending, 1); assert_eq!(stats.pending, 1);
} }
@ -1859,13 +1851,13 @@ pub mod test {
let res4 = txq.add(tx4, TransactionOrigin::External, 0, None, &default_tx_provider()); let res4 = txq.add(tx4, TransactionOrigin::External, 0, None, &default_tx_provider());
// then // then
assert_eq!(res1.unwrap(), TransactionImportResult::Current); assert_eq!(res1.unwrap(), transaction::ImportResult::Current);
assert_eq!(res2.unwrap(), TransactionImportResult::Current); assert_eq!(res2.unwrap(), transaction::ImportResult::Current);
assert_eq!(unwrap_tx_err(res3), TransactionError::InsufficientGasPrice { assert_eq!(unwrap_tx_err(res3), transaction::Error::InsufficientGasPrice {
minimal: U256::from(15), minimal: U256::from(15),
got: U256::from(10), got: U256::from(10),
}); });
assert_eq!(res4.unwrap(), TransactionImportResult::Current); assert_eq!(res4.unwrap(), transaction::ImportResult::Current);
let stats = txq.status(); let stats = txq.status();
assert_eq!(stats.pending, 3); assert_eq!(stats.pending, 3);
assert_eq!(txq.top_transactions()[0].gas, 40000.into()); assert_eq!(txq.top_transactions()[0].gas, 40000.into());
@ -1893,10 +1885,10 @@ pub mod test {
let res4 = txq.add(tx4, TransactionOrigin::External, 0, None, &default_tx_provider()); let res4 = txq.add(tx4, TransactionOrigin::External, 0, None, &default_tx_provider());
// then // then
assert_eq!(res1.unwrap(), TransactionImportResult::Current); assert_eq!(res1.unwrap(), transaction::ImportResult::Current);
assert_eq!(res2.unwrap(), TransactionImportResult::Current); assert_eq!(res2.unwrap(), transaction::ImportResult::Current);
assert_eq!(res3.unwrap(), TransactionImportResult::Current); assert_eq!(res3.unwrap(), transaction::ImportResult::Current);
assert_eq!(res4.unwrap(), TransactionImportResult::Current); assert_eq!(res4.unwrap(), transaction::ImportResult::Current);
let stats = txq.status(); let stats = txq.status();
assert_eq!(stats.pending, 4); assert_eq!(stats.pending, 4);
assert_eq!(txq.top_transactions()[0].gas, 30_000.into()); assert_eq!(txq.top_transactions()[0].gas, 30_000.into());
@ -1936,7 +1928,7 @@ pub mod test {
let res = txq.add(tx, TransactionOrigin::External, 0, None, &default_tx_provider()); let res = txq.add(tx, TransactionOrigin::External, 0, None, &default_tx_provider());
// then // then
assert_eq!(unwrap_tx_err(res), TransactionError::GasLimitExceeded { assert_eq!(unwrap_tx_err(res), transaction::Error::GasLimitExceeded {
limit: U256::from(50_000), limit: U256::from(50_000),
got: gas, got: gas,
}); });
@ -1960,7 +1952,7 @@ pub mod test {
let res = txq.add(tx, TransactionOrigin::External, 0, None, &default_tx_provider().with_account(account)); let res = txq.add(tx, TransactionOrigin::External, 0, None, &default_tx_provider().with_account(account));
// then // then
assert_eq!(unwrap_tx_err(res), TransactionError::InsufficientBalance { assert_eq!(unwrap_tx_err(res), transaction::Error::InsufficientBalance {
balance: U256::from(1), balance: U256::from(1),
cost: U256::from(100_100), cost: U256::from(100_100),
}); });
@ -1980,7 +1972,7 @@ pub mod test {
let res = txq.add(tx, TransactionOrigin::External, 0, None, &default_tx_provider()); let res = txq.add(tx, TransactionOrigin::External, 0, None, &default_tx_provider());
// then // then
assert_eq!(unwrap_tx_err(res), TransactionError::InsufficientGasPrice { assert_eq!(unwrap_tx_err(res), transaction::Error::InsufficientGasPrice {
minimal: U256::from(2), minimal: U256::from(2),
got: U256::from(1), got: U256::from(1),
}); });
@ -2000,7 +1992,7 @@ pub mod test {
let res = txq.add(tx, TransactionOrigin::Local, 0, None, &default_tx_provider()); let res = txq.add(tx, TransactionOrigin::Local, 0, None, &default_tx_provider());
// then // then
assert_eq!(res.unwrap(), TransactionImportResult::Current); assert_eq!(res.unwrap(), transaction::ImportResult::Current);
let stats = txq.status(); let stats = txq.status();
assert_eq!(stats.pending, 1); assert_eq!(stats.pending, 1);
assert_eq!(stats.future, 0); assert_eq!(stats.future, 0);
@ -2235,8 +2227,8 @@ pub mod test {
let res2 = txq.add(tx2.clone(), TransactionOrigin::External, 0, None, &default_tx_provider()).unwrap(); let res2 = txq.add(tx2.clone(), TransactionOrigin::External, 0, None, &default_tx_provider()).unwrap();
// then // then
assert_eq!(res1, TransactionImportResult::Current); assert_eq!(res1, transaction::ImportResult::Current);
assert_eq!(res2, TransactionImportResult::Future); assert_eq!(res2, transaction::ImportResult::Future);
let stats = txq.status(); let stats = txq.status();
assert_eq!(stats.pending, 1); assert_eq!(stats.pending, 1);
assert_eq!(stats.future, 1); assert_eq!(stats.future, 1);
@ -2253,12 +2245,12 @@ pub mod test {
let (tx, tx2) = new_tx_pair_default(1.into(), 0.into()); let (tx, tx2) = new_tx_pair_default(1.into(), 0.into());
// when // when
let res1 = txq.add(tx.clone(), TransactionOrigin::External, 0, Some(Condition::Number(1)), &default_tx_provider()).unwrap(); let res1 = txq.add(tx.clone(), TransactionOrigin::External, 0, Some(transaction::Condition::Number(1)), &default_tx_provider()).unwrap();
let res2 = txq.add(tx2.clone(), TransactionOrigin::External, 0, None, &default_tx_provider()).unwrap(); let res2 = txq.add(tx2.clone(), TransactionOrigin::External, 0, None, &default_tx_provider()).unwrap();
// then // then
assert_eq!(res1, TransactionImportResult::Current); assert_eq!(res1, transaction::ImportResult::Current);
assert_eq!(res2, TransactionImportResult::Current); assert_eq!(res2, transaction::ImportResult::Current);
let top = txq.top_transactions_at(0, 0, None); let top = txq.top_transactions_at(0, 0, None);
assert_eq!(top.len(), 0); assert_eq!(top.len(), 0);
let top = txq.top_transactions_at(1, 0, None); let top = txq.top_transactions_at(1, 0, None);
@ -2396,7 +2388,7 @@ pub mod test {
// then // then
let t = txq.top_transactions(); let t = txq.top_transactions();
assert_eq!(unwrap_tx_err(res), TransactionError::InsufficientGasPrice { minimal: 2.into(), got: 1.into() }); assert_eq!(unwrap_tx_err(res), transaction::Error::InsufficientGasPrice { minimal: 2.into(), got: 1.into() });
assert_eq!(txq.status().pending, 1); assert_eq!(txq.status().pending, 1);
assert_eq!(t.len(), 1); assert_eq!(t.len(), 1);
assert_eq!(t[0], tx); assert_eq!(t[0], tx);
@ -2478,7 +2470,7 @@ pub mod test {
let res = txq.add(tx, TransactionOrigin::External, 0, None, &default_tx_provider().with_account_nonce(last_nonce)); let res = txq.add(tx, TransactionOrigin::External, 0, None, &default_tx_provider().with_account_nonce(last_nonce));
// then // then
assert_eq!(unwrap_tx_err(res), TransactionError::Old); assert_eq!(unwrap_tx_err(res), transaction::Error::Old);
let stats = txq.status(); let stats = txq.status();
assert_eq!(stats.pending, 0); assert_eq!(stats.pending, 0);
assert_eq!(stats.future, 0); assert_eq!(stats.future, 0);
@ -2498,7 +2490,7 @@ pub mod test {
let res = txq.add(tx2.clone(), TransactionOrigin::External, 0, None, &default_tx_provider().with_account_nonce(nonce)); let res = txq.add(tx2.clone(), TransactionOrigin::External, 0, None, &default_tx_provider().with_account_nonce(nonce));
// then // then
assert_eq!(unwrap_tx_err(res), TransactionError::AlreadyImported); assert_eq!(unwrap_tx_err(res), transaction::Error::AlreadyImported);
let stats = txq.status(); let stats = txq.status();
assert_eq!(stats.future, 1); assert_eq!(stats.future, 1);
assert_eq!(stats.pending, 0); assert_eq!(stats.pending, 0);
@ -2548,8 +2540,6 @@ pub mod test {
#[test] #[test]
fn should_not_replace_same_transaction_if_the_fee_is_less_than_minimal_bump() { fn should_not_replace_same_transaction_if_the_fee_is_less_than_minimal_bump() {
use ethcore_logger::init_log;
init_log();
// given // given
let mut txq = TransactionQueue::default(); let mut txq = TransactionQueue::default();
let keypair = Random.generate().unwrap(); let keypair = Random.generate().unwrap();
@ -2565,7 +2555,7 @@ pub mod test {
let res = txq.add(tx2, TransactionOrigin::External, 0, None, &default_tx_provider()); let res = txq.add(tx2, TransactionOrigin::External, 0, None, &default_tx_provider());
// then // then
assert_eq!(unwrap_tx_err(res), TransactionError::TooCheapToReplace); assert_eq!(unwrap_tx_err(res), transaction::Error::TooCheapToReplace);
let stats = txq.status(); let stats = txq.status();
assert_eq!(stats.pending, 1); assert_eq!(stats.pending, 1);
assert_eq!(stats.future, 0); assert_eq!(stats.future, 0);
@ -2574,8 +2564,6 @@ pub mod test {
#[test] #[test]
fn should_replace_same_transaction_when_has_higher_fee() { fn should_replace_same_transaction_when_has_higher_fee() {
use ethcore_logger::init_log;
init_log();
// given // given
let mut txq = TransactionQueue::default(); let mut txq = TransactionQueue::default();
let keypair = Random.generate().unwrap(); let keypair = Random.generate().unwrap();
@ -2697,9 +2685,9 @@ pub mod test {
// when // when
// Insert first transaction // Insert first transaction
assert_eq!(txq.add(tx1, TransactionOrigin::External, 0, None, &default_tx_provider().with_account_nonce(nonce1)).unwrap(), TransactionImportResult::Current); assert_eq!(txq.add(tx1, TransactionOrigin::External, 0, None, &default_tx_provider().with_account_nonce(nonce1)).unwrap(), transaction::ImportResult::Current);
// Second should go to future // Second should go to future
assert_eq!(txq.add(tx2, TransactionOrigin::External, 0, None, &default_tx_provider().with_account_nonce(nonce1)).unwrap(), TransactionImportResult::Future); assert_eq!(txq.add(tx2, TransactionOrigin::External, 0, None, &default_tx_provider().with_account_nonce(nonce1)).unwrap(), transaction::ImportResult::Future);
// Now block is imported // Now block is imported
txq.cull(sender, nonce2 - U256::from(1)); txq.cull(sender, nonce2 - U256::from(1));
// tx2 should be not be promoted to current // tx2 should be not be promoted to current
@ -2718,9 +2706,10 @@ pub mod test {
assert_eq!(txq.has_local_pending_transactions(), false); assert_eq!(txq.has_local_pending_transactions(), false);
// when // when
assert_eq!(txq.add(tx1, TransactionOrigin::External, 0, None, &default_tx_provider()).unwrap(), TransactionImportResult::Current); assert_eq!(txq.add(tx1, TransactionOrigin::External, 0, None, &default_tx_provider()).unwrap(), transaction::ImportResult::Current);
assert_eq!(txq.has_local_pending_transactions(), false); assert_eq!(txq.has_local_pending_transactions(), false);
assert_eq!(txq.add(tx2, TransactionOrigin::Local, 0, None, &default_tx_provider()).unwrap(), TransactionImportResult::Current); assert_eq!(txq.add(tx2, TransactionOrigin::Local, 0, None, &default_tx_provider()).unwrap(),
transaction::ImportResult::Current);
// then // then
assert_eq!(txq.has_local_pending_transactions(), true); assert_eq!(txq.has_local_pending_transactions(), true);
@ -2740,8 +2729,8 @@ pub mod test {
let prev_nonce = default_account_details().nonce - U256::one(); let prev_nonce = default_account_details().nonce - U256::one();
// when // when
assert_eq!(txq.add(tx2, TransactionOrigin::External, 0, None, &default_tx_provider().with_account_nonce(prev_nonce)).unwrap(), TransactionImportResult::Future); assert_eq!(txq.add(tx2, TransactionOrigin::External, 0, None, &default_tx_provider().with_account_nonce(prev_nonce)).unwrap(), transaction::ImportResult::Future);
assert_eq!(txq.add(tx1.clone(), TransactionOrigin::External, 0, None, &default_tx_provider().with_account_nonce(prev_nonce)).unwrap(), TransactionImportResult::Future); assert_eq!(txq.add(tx1.clone(), TransactionOrigin::External, 0, None, &default_tx_provider().with_account_nonce(prev_nonce)).unwrap(), transaction::ImportResult::Future);
// then // then
assert_eq!(txq.future.by_priority.len(), 1); assert_eq!(txq.future.by_priority.len(), 1);
@ -2777,7 +2766,7 @@ pub mod test {
// then // then
assert_eq!(txq.last_nonce(&sender).unwrap(), 125.into()); assert_eq!(txq.last_nonce(&sender).unwrap(), 125.into());
assert_eq!(res.unwrap(), TransactionImportResult::Current); assert_eq!(res.unwrap(), transaction::ImportResult::Current);
assert_eq!(txq.current.by_priority.len(), 3); assert_eq!(txq.current.by_priority.len(), 3);
} }
@ -2793,8 +2782,8 @@ pub mod test {
let res2 = txq.add(tx2, TransactionOrigin::Local, 0, None, &default_tx_provider().with_tx_gas_required(high_gas)); let res2 = txq.add(tx2, TransactionOrigin::Local, 0, None, &default_tx_provider().with_tx_gas_required(high_gas));
// then // then
assert_eq!(res1.unwrap(), TransactionImportResult::Current); assert_eq!(res1.unwrap(), transaction::ImportResult::Current);
assert_eq!(unwrap_tx_err(res2), TransactionError::InsufficientGas { assert_eq!(unwrap_tx_err(res2), transaction::Error::InsufficientGas {
minimal: 100_001.into(), minimal: 100_001.into(),
got: 100_000.into(), got: 100_000.into(),
}); });
@ -2872,12 +2861,12 @@ pub mod test {
// when // when
assert_eq!(unwrap_tx_err(txq.add(tx1, TransactionOrigin::External, 0, None, &default_tx_provider())), assert_eq!(unwrap_tx_err(txq.add(tx1, TransactionOrigin::External, 0, None, &default_tx_provider())),
TransactionError::InsufficientGasPrice { transaction::Error::InsufficientGasPrice {
minimal: 100.into(), minimal: 100.into(),
got: 0.into(), got: 0.into(),
}); });
assert_eq!(unwrap_tx_err(txq.add(tx2, TransactionOrigin::RetractedBlock, 0, None, &default_tx_provider())), assert_eq!(unwrap_tx_err(txq.add(tx2, TransactionOrigin::RetractedBlock, 0, None, &default_tx_provider())),
TransactionError::InsufficientGasPrice { transaction::Error::InsufficientGasPrice {
minimal: 100.into(), minimal: 100.into(),
got: 0.into(), got: 0.into(),
}); });
@ -2896,7 +2885,7 @@ pub mod test {
// when // when
let details_provider = default_tx_provider().service_transaction_checker_returns_error("Contract error"); let details_provider = default_tx_provider().service_transaction_checker_returns_error("Contract error");
assert_eq!(unwrap_tx_err(txq.add(tx, TransactionOrigin::External, 0, None, &details_provider)), assert_eq!(unwrap_tx_err(txq.add(tx, TransactionOrigin::External, 0, None, &details_provider)),
TransactionError::InsufficientGasPrice { transaction::Error::InsufficientGasPrice {
minimal: 100.into(), minimal: 100.into(),
got: 0.into(), got: 0.into(),
}); });

View File

@ -14,19 +14,22 @@
// 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/>.
//! Sends HTTP notifications to a list of URLs every time new work is available.
extern crate ethash;
extern crate hyper; extern crate hyper;
use self::hyper::header::ContentType;
use self::hyper::method::Method;
use self::hyper::client::{Request, Response, Client};
use self::hyper::{Next, Url};
use self::hyper::net::HttpStream;
use self::ethash::SeedHashCompute;
use std::io::Write; use std::io::Write;
use hyper::header::ContentType;
use hyper::method::Method;
use hyper::client::{Request, Response, Client};
use hyper::{Next};
use hyper::net::HttpStream;
use ethash::SeedHashCompute;
use hyper::Url;
use ethereum_types::{H256, U256}; use ethereum_types::{H256, U256};
use parking_lot::Mutex; use parking_lot::Mutex;
use ethereum::ethash::Ethash;
/// Trait for notifying about new mining work /// Trait for notifying about new mining work
pub trait NotifyWork : Send + Sync { pub trait NotifyWork : Send + Sync {
@ -34,6 +37,7 @@ pub trait NotifyWork : Send + Sync {
fn notify(&self, pow_hash: H256, difficulty: U256, number: u64); fn notify(&self, pow_hash: H256, difficulty: U256, number: u64);
} }
/// POSTs info about new work to given urls.
pub struct WorkPoster { pub struct WorkPoster {
urls: Vec<Url>, urls: Vec<Url>,
client: Mutex<Client<PostHandler>>, client: Mutex<Client<PostHandler>>,
@ -41,6 +45,7 @@ pub struct WorkPoster {
} }
impl WorkPoster { impl WorkPoster {
/// Create new `WorkPoster`.
pub fn new(urls: &[String]) -> Self { pub fn new(urls: &[String]) -> Self {
let urls = urls.into_iter().filter_map(|u| { let urls = urls.into_iter().filter_map(|u| {
match Url::parse(u) { match Url::parse(u) {
@ -67,10 +72,19 @@ impl WorkPoster {
} }
} }
/// Convert an Ethash difficulty to the target boundary. Basically just `f(x) = 2^256 / x`.
fn difficulty_to_boundary(difficulty: &U256) -> H256 {
if *difficulty <= U256::one() {
U256::max_value().into()
} else {
(((U256::one() << 255) / *difficulty) << 1).into()
}
}
impl NotifyWork for WorkPoster { impl NotifyWork for WorkPoster {
fn notify(&self, pow_hash: H256, difficulty: U256, number: u64) { fn notify(&self, pow_hash: H256, difficulty: U256, number: u64) {
// TODO: move this to engine // TODO: move this to engine
let target = Ethash::difficulty_to_boundary(&difficulty); let target = difficulty_to_boundary(&difficulty);
let seed_hash = &self.seed_compute.lock().hash_block_number(number); let seed_hash = &self.seed_compute.lock().hash_block_number(number);
let seed_hash = H256::from_slice(&seed_hash[..]); let seed_hash = H256::from_slice(&seed_hash[..]);
let body = format!( let body = format!(

View File

@ -1137,7 +1137,8 @@ mod tests {
use devtools::{RandomTempPath}; use devtools::{RandomTempPath};
use ethcore::client::{VMType, BlockId}; use ethcore::client::{VMType, BlockId};
use ethcore::miner::{MinerOptions, PrioritizationStrategy}; use ethcore::miner::MinerOptions;
use miner::transaction_queue::PrioritizationStrategy;
use parity_rpc::NetworkSettings; use parity_rpc::NetworkSettings;
use updater::{UpdatePolicy, UpdateFilter, ReleaseTrack}; use updater::{UpdatePolicy, UpdateFilter, ReleaseTrack};

View File

@ -17,10 +17,10 @@
use std::path::PathBuf; use std::path::PathBuf;
use std::sync::Arc; use std::sync::Arc;
use bytes::Bytes;
use dir::default_data_path; use dir::default_data_path;
use dir::helpers::replace_home; use dir::helpers::replace_home;
use ethcore::client::{Client, BlockChainClient, BlockId}; use ethcore::client::{Client, BlockChainClient, BlockId};
use ethcore::transaction::{Transaction, Action};
use ethsync::LightSync; use ethsync::LightSync;
use futures::{future, IntoFuture, Future}; use futures::{future, IntoFuture, Future};
use hash_fetch::fetch::Client as FetchClient; use hash_fetch::fetch::Client as FetchClient;
@ -30,8 +30,8 @@ use light::on_demand::{self, OnDemand};
use node_health::{SyncStatus, NodeHealth}; use node_health::{SyncStatus, NodeHealth};
use rpc; use rpc;
use rpc_apis::SignerService; use rpc_apis::SignerService;
use transaction::{Transaction, Action};
use ethereum_types::Address; use ethereum_types::Address;
use bytes::Bytes;
#[derive(Debug, PartialEq, Clone)] #[derive(Debug, PartialEq, Clone)]
pub struct Configuration { pub struct Configuration {

View File

@ -22,7 +22,8 @@ use ethereum_types::{U256, clean_0x, Address};
use kvdb_rocksdb::CompactionProfile; use kvdb_rocksdb::CompactionProfile;
use journaldb::Algorithm; use journaldb::Algorithm;
use ethcore::client::{Mode, BlockId, VMType, DatabaseCompactionProfile, ClientConfig, VerifierType}; use ethcore::client::{Mode, BlockId, VMType, DatabaseCompactionProfile, ClientConfig, VerifierType};
use ethcore::miner::{PendingSet, GasLimit, PrioritizationStrategy}; use ethcore::miner::{PendingSet, GasLimit};
use miner::transaction_queue::PrioritizationStrategy;
use cache::CacheConfig; use cache::CacheConfig;
use dir::DatabaseDirectories; use dir::DatabaseDirectories;
use dir::helpers::replace_home; use dir::helpers::replace_home;

View File

@ -47,12 +47,14 @@ extern crate time;
extern crate toml; extern crate toml;
extern crate ethcore; extern crate ethcore;
extern crate ethcore_bytes as bytes;
extern crate ethcore_devtools as devtools; extern crate ethcore_devtools as devtools;
extern crate ethcore_io as io; extern crate ethcore_io as io;
extern crate ethcore_light as light; extern crate ethcore_light as light;
extern crate ethcore_logger; extern crate ethcore_logger;
extern crate ethcore_bytes as bytes; extern crate ethcore_miner as miner;
extern crate ethcore_network as network; extern crate ethcore_network as network;
extern crate ethcore_transaction as transaction;
extern crate ethereum_types; extern crate ethereum_types;
extern crate migration as migr; extern crate migration as migr;
extern crate kvdb; extern crate kvdb;

View File

@ -24,21 +24,22 @@ pub use parity_rpc::dapps::{DappsService, LocalDapp};
use ethcore::account_provider::AccountProvider; use ethcore::account_provider::AccountProvider;
use ethcore::client::Client; use ethcore::client::Client;
use ethcore::miner::{Miner, ExternalMiner}; use ethcore::miner::Miner;
use ethcore::snapshot::SnapshotService; use ethcore::snapshot::SnapshotService;
use ethcore_logger::RotatingLogger; use ethcore_logger::RotatingLogger;
use ethsync::{ManageNetwork, SyncProvider, LightSync}; use ethsync::{ManageNetwork, SyncProvider, LightSync};
use hash_fetch::fetch::Client as FetchClient; use hash_fetch::fetch::Client as FetchClient;
use jsonrpc_core::{self as core, MetaIoHandler}; use jsonrpc_core::{self as core, MetaIoHandler};
use light::{TransactionQueue as LightTransactionQueue, Cache as LightDataCache};
use light::client::LightChainClient; use light::client::LightChainClient;
use light::{TransactionQueue as LightTransactionQueue, Cache as LightDataCache};
use miner::external::ExternalMiner;
use node_health::NodeHealth; use node_health::NodeHealth;
use parity_reactor; use parity_reactor;
use parity_rpc::dispatch::{FullDispatcher, LightDispatcher}; use parity_rpc::dispatch::{FullDispatcher, LightDispatcher};
use parity_rpc::informant::{ActivityNotifier, ClientNotifier}; use parity_rpc::informant::{ActivityNotifier, ClientNotifier};
use parity_rpc::{Metadata, NetworkSettings, Host}; use parity_rpc::{Metadata, NetworkSettings, Host};
use updater::Updater;
use parking_lot::{Mutex, RwLock}; use parking_lot::{Mutex, RwLock};
use updater::Updater;
#[derive(Debug, PartialEq, Clone, Eq, Hash)] #[derive(Debug, PartialEq, Clone, Eq, Hash)]
pub enum Api { pub enum Api {

View File

@ -18,31 +18,32 @@ use std::fmt;
use std::sync::{Arc, Weak}; use std::sync::{Arc, Weak};
use std::net::{TcpListener}; use std::net::{TcpListener};
use ansi_term::Colour;
use ctrlc::CtrlC; use ctrlc::CtrlC;
use ethcore_logger::{Config as LogConfig, RotatingLogger};
use ethcore::account_provider::{AccountProvider, AccountProviderSettings}; use ethcore::account_provider::{AccountProvider, AccountProviderSettings};
use ethcore::client::{Client, Mode, DatabaseCompactionProfile, VMType, BlockChainClient}; use ethcore::client::{Client, Mode, DatabaseCompactionProfile, VMType, BlockChainClient};
use ethcore::ethstore::ethkey; use ethcore::ethstore::ethkey;
use ethcore::miner::{Miner, MinerService, ExternalMiner, MinerOptions}; use ethcore::miner::{Miner, MinerService, MinerOptions};
use ethcore::miner::{StratumOptions, Stratum}; use ethcore::miner::{StratumOptions, Stratum};
use ethcore::service::ClientService; use ethcore::service::ClientService;
use ethcore::snapshot; use ethcore::snapshot;
use ethcore::spec::{SpecParams, OptimizeFor}; use ethcore::spec::{SpecParams, OptimizeFor};
use ethcore::verification::queue::VerifierSettings; use ethcore::verification::queue::VerifierSettings;
use ethcore_logger::{Config as LogConfig, RotatingLogger};
use ethsync::{self, SyncConfig}; use ethsync::{self, SyncConfig};
use fdlimit::raise_fd_limit; use fdlimit::raise_fd_limit;
use hash_fetch::fetch::{Fetch, Client as FetchClient}; use hash_fetch::fetch::{Fetch, Client as FetchClient};
use informant::{Informant, LightNodeInformantData, FullNodeInformantData}; use informant::{Informant, LightNodeInformantData, FullNodeInformantData};
use journaldb::Algorithm;
use light::Cache as LightDataCache; use light::Cache as LightDataCache;
use miner::external::ExternalMiner;
use node_filter::NodeFilter;
use node_health; use node_health;
use parity_reactor::EventLoop; use parity_reactor::EventLoop;
use parity_rpc::{NetworkSettings, informant, is_major_importing}; use parity_rpc::{NetworkSettings, informant, is_major_importing};
use updater::{UpdatePolicy, Updater};
use ansi_term::Colour;
use parity_version::version;
use parking_lot::{Condvar, Mutex}; use parking_lot::{Condvar, Mutex};
use node_filter::NodeFilter; use updater::{UpdatePolicy, Updater};
use journaldb::Algorithm; use parity_version::version;
use params::{ use params::{
SpecType, Pruning, AccountsConfig, GasPricerConfig, MinerExtras, Switch, SpecType, Pruning, AccountsConfig, GasPricerConfig, MinerExtras, Switch,
@ -156,7 +157,7 @@ struct FullNodeInfo {
} }
impl ::local_store::NodeInfo for FullNodeInfo { impl ::local_store::NodeInfo for FullNodeInfo {
fn pending_transactions(&self) -> Vec<::ethcore::transaction::PendingTransaction> { fn pending_transactions(&self) -> Vec<::transaction::PendingTransaction> {
let miner = match self.miner.as_ref() { let miner = match self.miner.as_ref() {
Some(m) => m, Some(m) => m,
None => return Vec::new(), None => return Vec::new(),

View File

@ -36,20 +36,25 @@ jsonrpc-ipc-server = { git = "https://github.com/paritytech/jsonrpc.git", branch
jsonrpc-macros = { git = "https://github.com/paritytech/jsonrpc.git", branch = "parity-1.9" } jsonrpc-macros = { git = "https://github.com/paritytech/jsonrpc.git", branch = "parity-1.9" }
jsonrpc-pubsub = { git = "https://github.com/paritytech/jsonrpc.git", branch = "parity-1.9" } jsonrpc-pubsub = { git = "https://github.com/paritytech/jsonrpc.git", branch = "parity-1.9" }
ethcore-io = { path = "../util/io" }
ethcore-bytes = { path = "../util/bytes" }
ethereum-types = "0.1"
ethcore = { path = "../ethcore" }
ethcrypto = { path = "../ethcrypto" }
ethkey = { path = "../ethkey" }
ethstore = { path = "../ethstore" }
ethash = { path = "../ethash" } ethash = { path = "../ethash" }
ethsync = { path = "../sync" } ethcore = { path = "../ethcore" }
ethjson = { path = "../json" } ethcore-bytes = { path = "../util/bytes" }
ethcore-devtools = { path = "../devtools" } ethcore-devtools = { path = "../devtools" }
ethcore-io = { path = "../util/io" }
ethcore-light = { path = "../ethcore/light" } ethcore-light = { path = "../ethcore/light" }
ethcore-logger = { path = "../logger" } ethcore-logger = { path = "../logger" }
ethcore-miner = { path = "../miner" }
ethcore-transaction = { path = "../ethcore/transaction" }
ethereum-types = "0.1"
ethcrypto = { path = "../ethcrypto" }
ethjson = { path = "../json" }
ethkey = { path = "../ethkey" }
ethstore = { path = "../ethstore" }
ethsync = { path = "../sync" }
fetch = { path = "../util/fetch" } fetch = { path = "../util/fetch" }
hardware-wallet = { path = "../hw" }
keccak-hash = { path = "../util/hash" }
node-health = { path = "../dapps/node-health" } node-health = { path = "../dapps/node-health" }
parity-reactor = { path = "../util/reactor" } parity-reactor = { path = "../util/reactor" }
parity-updater = { path = "../updater" } parity-updater = { path = "../updater" }
@ -57,8 +62,6 @@ parity-version = { path = "../util/version" }
rlp = { path = "../util/rlp" } rlp = { path = "../util/rlp" }
stats = { path = "../util/stats" } stats = { path = "../util/stats" }
vm = { path = "../ethcore/vm" } vm = { path = "../ethcore/vm" }
keccak-hash = { path = "../util/hash" }
hardware-wallet = { path = "../hw" }
[dev-dependencies] [dev-dependencies]
pretty_assertions = "0.1" pretty_assertions = "0.1"

View File

@ -50,6 +50,8 @@ extern crate ethcore_bytes as bytes;
extern crate ethcore_devtools as devtools; extern crate ethcore_devtools as devtools;
extern crate ethcore_io as io; extern crate ethcore_io as io;
extern crate ethcore_light as light; extern crate ethcore_light as light;
extern crate ethcore_miner as miner;
extern crate ethcore_transaction as transaction;
extern crate ethcrypto as crypto; extern crate ethcrypto as crypto;
extern crate ethereum_types; extern crate ethereum_types;
extern crate ethkey; extern crate ethkey;

View File

@ -36,9 +36,9 @@ use ethsync::LightSync;
use ethcore::ids::BlockId; use ethcore::ids::BlockId;
use ethcore::miner::MinerService; use ethcore::miner::MinerService;
use ethcore::client::MiningBlockChainClient; use ethcore::client::MiningBlockChainClient;
use ethcore::transaction::{Action, SignedTransaction, PendingTransaction, Transaction};
use ethcore::account_provider::AccountProvider; use ethcore::account_provider::AccountProvider;
use crypto::DEFAULT_MAC; use crypto::DEFAULT_MAC;
use transaction::{Action, SignedTransaction, PendingTransaction, Transaction};
use jsonrpc_core::{BoxFuture, Result, Error}; use jsonrpc_core::{BoxFuture, Result, Error};
use jsonrpc_core::futures::{future, Future, Poll, Async}; use jsonrpc_core::futures::{future, Future, Poll, Async};
@ -411,7 +411,6 @@ impl Dispatcher for LightDispatcher {
let hash = signed_transaction.transaction.hash(); let hash = signed_transaction.transaction.hash();
self.transaction_queue.write().import(signed_transaction) self.transaction_queue.write().import(signed_transaction)
.map_err(Into::into)
.map_err(errors::transaction) .map_err(errors::transaction)
.map(|_| hash) .map(|_| hash)
} }

View File

@ -17,10 +17,12 @@
//! RPC Error codes and error objects //! RPC Error codes and error objects
use std::fmt; use std::fmt;
use rlp::DecoderError;
use ethcore::error::{Error as EthcoreError, CallError, TransactionError};
use ethcore::account_provider::{SignError as AccountError}; use ethcore::account_provider::{SignError as AccountError};
use ethcore::error::{Error as EthcoreError, CallError};
use jsonrpc_core::{futures, Error, ErrorCode, Value}; use jsonrpc_core::{futures, Error, ErrorCode, Value};
use rlp::DecoderError;
use transaction::Error as TransactionError;
mod codes { mod codes {
// NOTE [ToDr] Codes from [-32099, -32000] // NOTE [ToDr] Codes from [-32099, -32000]
@ -287,7 +289,7 @@ pub fn password(error: AccountError) -> Error {
} }
pub fn transaction_message(error: TransactionError) -> String { pub fn transaction_message(error: TransactionError) -> String {
use ethcore::error::TransactionError::*; use self::TransactionError::*;
match error { match error {
AlreadyImported => "Transaction with the same hash was already imported.".into(), AlreadyImported => "Transaction with the same hash was already imported.".into(),
@ -310,6 +312,7 @@ pub fn transaction_message(error: TransactionError) -> String {
GasLimitExceeded { limit, got } => { GasLimitExceeded { limit, got } => {
format!("Transaction cost exceeds current gas limit. Limit: {}, got: {}. Try decreasing supplied gas.", limit, got) format!("Transaction cost exceeds current gas limit. Limit: {}, got: {}. Try decreasing supplied gas.", limit, got)
}, },
InvalidSignature(sig) => format!("Invalid signature: {}", sig),
InvalidChainId => "Invalid chain id.".into(), InvalidChainId => "Invalid chain id.".into(),
InvalidGasLimit(_) => "Supplied gas is beyond limit.".into(), InvalidGasLimit(_) => "Supplied gas is beyond limit.".into(),
SenderBanned => "Sender is banned in local queue.".into(), SenderBanned => "Sender is banned in local queue.".into(),
@ -319,8 +322,8 @@ pub fn transaction_message(error: TransactionError) -> String {
} }
} }
pub fn transaction(error: EthcoreError) -> Error { pub fn transaction<T: Into<EthcoreError>>(error: T) -> Error {
let error = error.into();
if let EthcoreError::Transaction(e) = error { if let EthcoreError::Transaction(e) = error {
Error { Error {
code: ErrorCode::ServerError(codes::TRANSACTION_ERROR), code: ErrorCode::ServerError(codes::TRANSACTION_ERROR),

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 ethcore::transaction::{Transaction, SignedTransaction, Action}; use transaction::{Transaction, SignedTransaction, Action};
use ethereum_types::U256; use ethereum_types::U256;
use jsonrpc_core::Error; use jsonrpc_core::Error;

View File

@ -23,7 +23,6 @@ use ethcore::encoded;
use ethcore::executed::{Executed, ExecutionError}; use ethcore::executed::{Executed, ExecutionError};
use ethcore::ids::BlockId; use ethcore::ids::BlockId;
use ethcore::filter::Filter as EthcoreFilter; use ethcore::filter::Filter as EthcoreFilter;
use ethcore::transaction::{Action, Transaction as EthTransaction, SignedTransaction, LocalizedTransaction};
use ethcore::receipt::Receipt; use ethcore::receipt::Receipt;
use jsonrpc_core::{BoxFuture, Result}; use jsonrpc_core::{BoxFuture, Result};
@ -41,6 +40,7 @@ use ethsync::LightSync;
use ethereum_types::{U256, Address}; use ethereum_types::{U256, Address};
use hash::H256; use hash::H256;
use parking_lot::Mutex; use parking_lot::Mutex;
use transaction::{Action, Transaction as EthTransaction, SignedTransaction, LocalizedTransaction};
use v1::helpers::{CallRequest as CallRequestHelper, errors, dispatch}; use v1::helpers::{CallRequest as CallRequestHelper, errors, dispatch};
use v1::types::{BlockNumber, CallRequest, Log, Transaction}; use v1::types::{BlockNumber, CallRequest, Log, Transaction};

View File

@ -33,10 +33,11 @@ use ethcore::ethereum::Ethash;
use ethcore::filter::Filter as EthcoreFilter; use ethcore::filter::Filter as EthcoreFilter;
use ethcore::header::{Header as BlockHeader, BlockNumber as EthBlockNumber}; use ethcore::header::{Header as BlockHeader, BlockNumber as EthBlockNumber};
use ethcore::log_entry::LogEntry; use ethcore::log_entry::LogEntry;
use ethcore::miner::{MinerService, ExternalMinerService}; use ethcore::miner::MinerService;
use ethcore::transaction::SignedTransaction;
use ethcore::snapshot::SnapshotService; use ethcore::snapshot::SnapshotService;
use ethsync::{SyncProvider}; use ethsync::{SyncProvider};
use miner::external::ExternalMinerService;
use transaction::SignedTransaction;
use jsonrpc_core::{BoxFuture, Result}; use jsonrpc_core::{BoxFuture, Result};
use jsonrpc_core::futures::future; use jsonrpc_core::futures::future;

View File

@ -30,14 +30,14 @@ use light::on_demand::{request, OnDemand};
use ethcore::account_provider::{AccountProvider, DappId}; use ethcore::account_provider::{AccountProvider, DappId};
use ethcore::encoded; use ethcore::encoded;
use ethcore::ids::BlockId;
use ethcore::filter::Filter as EthcoreFilter; use ethcore::filter::Filter as EthcoreFilter;
use ethcore::transaction::SignedTransaction; use ethcore::ids::BlockId;
use ethsync::LightSync; use ethsync::LightSync;
use rlp::UntrustedRlp;
use hash::{KECCAK_NULL_RLP, KECCAK_EMPTY_LIST_RLP}; use hash::{KECCAK_NULL_RLP, KECCAK_EMPTY_LIST_RLP};
use ethereum_types::U256; use ethereum_types::U256;
use parking_lot::{RwLock, Mutex}; use parking_lot::{RwLock, Mutex};
use rlp::UntrustedRlp;
use transaction::SignedTransaction;
use v1::impls::eth_filter::Filterable; use v1::impls::eth_filter::Filterable;
use v1::helpers::{errors, limit_logs}; use v1::helpers::{errors, limit_logs};
@ -367,7 +367,6 @@ impl<T: LightChainClient + 'static> Eth for EthClient<T> {
self.transaction_queue.write().import(signed.into()) self.transaction_queue.write().import(signed.into())
.map(|_| hash) .map(|_| hash)
.map_err(Into::into)
.map_err(errors::transaction) .map_err(errors::transaction)
}) })
.map(Into::into) .map(Into::into)

View File

@ -17,12 +17,12 @@
//! Account management (personal) rpc implementation //! Account management (personal) rpc implementation
use std::sync::Arc; use std::sync::Arc;
use ethcore::account_provider::AccountProvider;
use ethcore::transaction::PendingTransaction;
use bytes::{Bytes, ToPretty}; use bytes::{Bytes, ToPretty};
use ethcore::account_provider::AccountProvider;
use transaction::PendingTransaction;
use ethereum_types::{H520, U128, Address}; use ethereum_types::{H520, U128, Address};
use ethkey::{public_to_address, recover, Signature}; use ethkey::{public_to_address, recover, Signature};
use jsonrpc_core::{BoxFuture, Result}; use jsonrpc_core::{BoxFuture, Result};
use jsonrpc_core::futures::{future, Future}; use jsonrpc_core::futures::{future, Future};
use v1::helpers::errors; use v1::helpers::errors;

View File

@ -19,11 +19,11 @@
use std::sync::Arc; use std::sync::Arc;
use ethcore::account_provider::AccountProvider; use ethcore::account_provider::AccountProvider;
use ethcore::transaction::{SignedTransaction, PendingTransaction};
use ethkey; use ethkey;
use parity_reactor::Remote; use parity_reactor::Remote;
use rlp::UntrustedRlp;
use parking_lot::Mutex; use parking_lot::Mutex;
use rlp::UntrustedRlp;
use transaction::{SignedTransaction, PendingTransaction};
use jsonrpc_core::{Result, BoxFuture, Error}; use jsonrpc_core::{Result, BoxFuture, Error};
use jsonrpc_core::futures::{future, Future, IntoFuture}; use jsonrpc_core::futures::{future, Future, IntoFuture};

View File

@ -19,8 +19,8 @@
use std::sync::Arc; use std::sync::Arc;
use ethcore::client::{MiningBlockChainClient, CallAnalytics, TransactionId, TraceId}; use ethcore::client::{MiningBlockChainClient, CallAnalytics, TransactionId, TraceId};
use ethcore::transaction::SignedTransaction;
use rlp::UntrustedRlp; use rlp::UntrustedRlp;
use transaction::SignedTransaction;
use jsonrpc_core::Result; use jsonrpc_core::Result;
use jsonrpc_macros::Trailing; use jsonrpc_macros::Trailing;

View File

@ -25,13 +25,15 @@ use ethcore::block::Block;
use ethcore::client::{BlockChainClient, Client, ClientConfig}; use ethcore::client::{BlockChainClient, Client, ClientConfig};
use ethcore::ethereum; use ethcore::ethereum;
use ethcore::ids::BlockId; use ethcore::ids::BlockId;
use ethcore::miner::{MinerOptions, Banning, GasPricer, MinerService, ExternalMiner, Miner, PendingSet, PrioritizationStrategy, GasLimit}; use ethcore::miner::{MinerOptions, Banning, GasPricer, MinerService, Miner, PendingSet, GasLimit};
use ethcore::spec::{Genesis, Spec}; use ethcore::spec::{Genesis, Spec};
use ethcore::views::BlockView; use ethcore::views::BlockView;
use ethjson::blockchain::BlockChain; use ethjson::blockchain::BlockChain;
use ethjson::state::test::ForkSpec; use ethjson::state::test::ForkSpec;
use io::IoChannel; use io::IoChannel;
use kvdb_memorydb; use kvdb_memorydb;
use miner::external::ExternalMiner;
use miner::transaction_queue::PrioritizationStrategy;
use parking_lot::Mutex; use parking_lot::Mutex;
use jsonrpc_core::IoHandler; use jsonrpc_core::IoHandler;

View File

@ -20,15 +20,16 @@ use std::collections::{BTreeMap, HashMap};
use std::collections::hash_map::Entry; use std::collections::hash_map::Entry;
use ethereum_types::{H256, U256, Address}; use ethereum_types::{H256, U256, Address};
use bytes::Bytes; use bytes::Bytes;
use parking_lot::{RwLock, Mutex};
use ethcore::error::Error;
use ethcore::client::MiningBlockChainClient;
use ethcore::block::ClosedBlock;
use ethcore::header::BlockNumber;
use ethcore::transaction::{UnverifiedTransaction, SignedTransaction, PendingTransaction};
use ethcore::receipt::{Receipt, RichReceipt};
use ethcore::miner::{MinerService, MinerStatus, TransactionImportResult, LocalTransactionStatus};
use ethcore::account_provider::SignError as AccountError; use ethcore::account_provider::SignError as AccountError;
use ethcore::block::ClosedBlock;
use ethcore::client::MiningBlockChainClient;
use ethcore::error::Error;
use ethcore::header::BlockNumber;
use ethcore::miner::{MinerService, MinerStatus};
use miner::local_transactions::Status as LocalTransactionStatus;
use ethcore::receipt::{Receipt, RichReceipt};
use parking_lot::{RwLock, Mutex};
use transaction::{UnverifiedTransaction, SignedTransaction, PendingTransaction, ImportResult as TransactionImportResult};
/// Test miner service. /// Test miner service.
pub struct TestMinerService { pub struct TestMinerService {

View File

@ -18,20 +18,21 @@ use std::str::FromStr;
use std::collections::HashMap; use std::collections::HashMap;
use std::sync::Arc; use std::sync::Arc;
use std::time::{Instant, Duration}; use std::time::{Instant, Duration};
use rustc_hex::{FromHex, ToHex};
use time::get_time;
use rlp;
use ethereum_types::{H256, U256, Address}; use ethereum_types::{H256, U256, Address};
use parking_lot::Mutex; use parking_lot::Mutex;
use ethkey::Secret;
use ethcore::account_provider::AccountProvider; use ethcore::account_provider::AccountProvider;
use ethcore::client::{TestBlockChainClient, EachBlockWith, Executed, TransactionId}; use ethcore::client::{TestBlockChainClient, EachBlockWith, Executed, TransactionId};
use ethcore::log_entry::{LocalizedLogEntry, LogEntry}; use ethcore::log_entry::{LocalizedLogEntry, LogEntry};
use ethcore::miner::MinerService;
use ethcore::receipt::{LocalizedReceipt, TransactionOutcome}; use ethcore::receipt::{LocalizedReceipt, TransactionOutcome};
use ethcore::transaction::{Transaction, Action}; use ethkey::Secret;
use ethcore::miner::{ExternalMiner, MinerService};
use ethsync::SyncState; use ethsync::SyncState;
use miner::external::ExternalMiner;
use rlp;
use rustc_hex::{FromHex, ToHex};
use time::get_time;
use transaction::{Transaction, Action};
use jsonrpc_core::IoHandler; use jsonrpc_core::IoHandler;
use v1::{Eth, EthClient, EthClientOptions, EthFilter, EthFilterClient, EthSigning, SigningUnsafeClient}; use v1::{Eth, EthClient, EthClientOptions, EthFilter, EthFilterClient, EthSigning, SigningUnsafeClient};
@ -539,7 +540,7 @@ fn rpc_eth_transaction_count_by_number_pending() {
fn rpc_eth_pending_transaction_by_hash() { fn rpc_eth_pending_transaction_by_hash() {
use ethereum_types::H256; use ethereum_types::H256;
use rlp; use rlp;
use ethcore::transaction::SignedTransaction; use transaction::SignedTransaction;
let tester = EthTester::default(); let tester = EthTester::default();
{ {

View File

@ -212,7 +212,7 @@ fn rpc_parity_set_hash_content() {
#[test] #[test]
fn rpc_parity_remove_transaction() { fn rpc_parity_remove_transaction() {
use ethcore::transaction::{Transaction, Action}; use transaction::{Transaction, Action};
let miner = miner_service(); let miner = miner_service();
let client = client_service(); let client = client_service();

View File

@ -21,9 +21,9 @@ use bytes::ToPretty;
use ethereum_types::{U256, Address}; use ethereum_types::{U256, Address};
use ethcore::account_provider::AccountProvider; use ethcore::account_provider::AccountProvider;
use ethcore::client::TestBlockChainClient; use ethcore::client::TestBlockChainClient;
use ethcore::transaction::{Action, Transaction};
use jsonrpc_core::IoHandler; use jsonrpc_core::IoHandler;
use parking_lot::Mutex; use parking_lot::Mutex;
use transaction::{Action, Transaction};
use v1::{PersonalClient, Personal, Metadata}; use v1::{PersonalClient, Personal, Metadata};
use v1::helpers::nonce; use v1::helpers::nonce;

View File

@ -21,10 +21,10 @@ use bytes::ToPretty;
use ethcore::account_provider::AccountProvider; use ethcore::account_provider::AccountProvider;
use ethcore::client::TestBlockChainClient; use ethcore::client::TestBlockChainClient;
use ethcore::transaction::{Transaction, Action, SignedTransaction};
use parity_reactor::EventLoop; use parity_reactor::EventLoop;
use parking_lot::Mutex; use parking_lot::Mutex;
use rlp::encode; use rlp::encode;
use transaction::{Transaction, Action, SignedTransaction};
use serde_json; use serde_json;
use jsonrpc_core::IoHandler; use jsonrpc_core::IoHandler;

View File

@ -32,13 +32,13 @@ use v1::tests::mocked::parity;
use ethereum_types::{U256, Address}; use ethereum_types::{U256, Address};
use bytes::ToPretty; use bytes::ToPretty;
use ethkey::Secret;
use ethcore::account_provider::AccountProvider; use ethcore::account_provider::AccountProvider;
use ethcore::client::TestBlockChainClient; use ethcore::client::TestBlockChainClient;
use ethcore::transaction::{Transaction, Action, SignedTransaction}; use ethkey::Secret;
use ethstore::ethkey::{Generator, Random}; use ethstore::ethkey::{Generator, Random};
use serde_json;
use parking_lot::Mutex; use parking_lot::Mutex;
use serde_json;
use transaction::{Transaction, Action, SignedTransaction};
use parity_reactor::Remote; use parity_reactor::Remote;

View File

@ -18,7 +18,7 @@ use serde::{Serialize, Serializer};
use serde::ser::SerializeStruct; use serde::ser::SerializeStruct;
use ethcore::miner; use ethcore::miner;
use ethcore::{contract_address, CreateContractAddress}; use ethcore::{contract_address, CreateContractAddress};
use ethcore::transaction::{LocalizedTransaction, Action, PendingTransaction, SignedTransaction}; use transaction::{LocalizedTransaction, Action, PendingTransaction, SignedTransaction};
use v1::helpers::errors; use v1::helpers::errors;
use v1::types::{Bytes, H160, H256, U256, H512, U64, TransactionCondition}; use v1::types::{Bytes, H160, H256, U256, H512, U64, TransactionCondition};

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 ethcore; use transaction;
/// Represents condition on minimum block number or block timestamp. /// Represents condition on minimum block number or block timestamp.
#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)] #[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)]
@ -28,27 +28,26 @@ pub enum TransactionCondition {
Timestamp(u64), Timestamp(u64),
} }
impl Into<ethcore::transaction::Condition> for TransactionCondition { impl Into<transaction::Condition> for TransactionCondition {
fn into(self) -> ethcore::transaction::Condition { fn into(self) -> transaction::Condition {
match self { match self {
TransactionCondition::Number(n) => ethcore::transaction::Condition::Number(n), TransactionCondition::Number(n) => transaction::Condition::Number(n),
TransactionCondition::Timestamp(n) => ethcore::transaction::Condition::Timestamp(n), TransactionCondition::Timestamp(n) => transaction::Condition::Timestamp(n),
} }
} }
} }
impl From<ethcore::transaction::Condition> for TransactionCondition { impl From<transaction::Condition> for TransactionCondition {
fn from(condition: ethcore::transaction::Condition) -> Self { fn from(condition: transaction::Condition) -> Self {
match condition { match condition {
ethcore::transaction::Condition::Number(n) => TransactionCondition::Number(n), transaction::Condition::Number(n) => TransactionCondition::Number(n),
ethcore::transaction::Condition::Timestamp(n) => TransactionCondition::Timestamp(n), transaction::Condition::Timestamp(n) => TransactionCondition::Timestamp(n),
} }
} }
} }
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use ethcore;
use super::*; use super::*;
use serde_json; use serde_json;
@ -61,8 +60,8 @@ mod tests {
#[test] #[test]
fn condition_into() { fn condition_into() {
assert_eq!(ethcore::transaction::Condition::Number(100), TransactionCondition::Number(100).into()); assert_eq!(transaction::Condition::Number(100), TransactionCondition::Number(100).into());
assert_eq!(ethcore::transaction::Condition::Timestamp(100), TransactionCondition::Timestamp(100).into()); assert_eq!(transaction::Condition::Timestamp(100), TransactionCondition::Timestamp(100).into());
} }
} }

View File

@ -11,7 +11,8 @@ authors = ["Parity Technologies <admin@parity.io>"]
ethcore-bytes = { path = "../util/bytes" } ethcore-bytes = { path = "../util/bytes" }
ethcore-network = { path = "../util/network" } ethcore-network = { path = "../util/network" }
ethcore-io = { path = "../util/io" } ethcore-io = { path = "../util/io" }
ethcore-light = { path = "../ethcore/light"} ethcore-light = { path = "../ethcore/light" }
ethcore-transaction = { path = "../ethcore/transaction" }
ethcore = { path = "../ethcore" } ethcore = { path = "../ethcore" }
ethereum-types = "0.1" ethereum-types = "0.1"
plain_hasher = { path = "../util/plain_hasher" } plain_hasher = { path = "../util/plain_hasher" }

View File

@ -440,7 +440,7 @@ impl ChainNotify for EthSync {
struct TxRelay(Arc<BlockChainClient>); struct TxRelay(Arc<BlockChainClient>);
impl LightHandler for TxRelay { impl LightHandler for TxRelay {
fn on_transactions(&self, ctx: &EventContext, relay: &[::ethcore::transaction::UnverifiedTransaction]) { fn on_transactions(&self, ctx: &EventContext, relay: &[::transaction::UnverifiedTransaction]) {
trace!(target: "pip", "Relaying {} transactions from peer {}", relay.len(), ctx.peer()); trace!(target: "pip", "Relaying {} transactions from peer {}", relay.len(), ctx.peer());
self.0.queue_transactions(relay.iter().map(|tx| ::rlp::encode(tx).into_vec()).collect(), ctx.peer()) self.0.queue_transactions(relay.iter().map(|tx| ::rlp::encode(tx).into_vec()).collect(), ctx.peer())
} }

View File

@ -102,7 +102,7 @@ use ethcore::header::{BlockNumber, Header as BlockHeader};
use ethcore::client::{BlockChainClient, BlockStatus, BlockId, BlockChainInfo, BlockImportError, BlockQueueInfo}; use ethcore::client::{BlockChainClient, BlockStatus, BlockId, BlockChainInfo, BlockImportError, BlockQueueInfo};
use ethcore::error::*; use ethcore::error::*;
use ethcore::snapshot::{ManifestData, RestorationStatus}; use ethcore::snapshot::{ManifestData, RestorationStatus};
use ethcore::transaction::PendingTransaction; use transaction::PendingTransaction;
use sync_io::SyncIo; use sync_io::SyncIo;
use time; use time;
use super::SyncConfig; use super::SyncConfig;
@ -2233,8 +2233,8 @@ mod tests {
use super::{PeerInfo, PeerAsking}; use super::{PeerInfo, PeerAsking};
use ethcore::header::*; use ethcore::header::*;
use ethcore::client::{BlockChainClient, EachBlockWith, TestBlockChainClient}; use ethcore::client::{BlockChainClient, EachBlockWith, TestBlockChainClient};
use ethcore::transaction::UnverifiedTransaction;
use ethcore::miner::MinerService; use ethcore::miner::MinerService;
use transaction::UnverifiedTransaction;
fn get_dummy_block(order: u32, parent_hash: H256) -> Bytes { fn get_dummy_block(order: u32, parent_hash: H256) -> Bytes {
let mut header = Header::new(); let mut header = Header::new();

View File

@ -24,6 +24,7 @@
extern crate ethcore_network as network; extern crate ethcore_network as network;
extern crate ethcore_bytes as bytes; extern crate ethcore_bytes as bytes;
extern crate ethcore_io as io; extern crate ethcore_io as io;
extern crate ethcore_transaction as transaction;
extern crate ethcore; extern crate ethcore;
extern crate ethereum_types; extern crate ethereum_types;
extern crate env_logger; extern crate env_logger;

View File

@ -22,9 +22,9 @@ use ethcore::client::{BlockChainClient, Client};
use ethcore::service::ClientIoMessage; use ethcore::service::ClientIoMessage;
use ethcore::spec::Spec; use ethcore::spec::Spec;
use ethcore::miner::MinerService; use ethcore::miner::MinerService;
use ethcore::transaction::*;
use ethcore::account_provider::AccountProvider; use ethcore::account_provider::AccountProvider;
use ethkey::{KeyPair, Secret}; use ethkey::{KeyPair, Secret};
use transaction::{Action, PendingTransaction, Transaction};
use super::helpers::*; use super::helpers::*;
use SyncConfig; use SyncConfig;