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:
parent
9a12945304
commit
f044b61f42
51
Cargo.lock
generated
51
Cargo.lock
generated
@ -475,7 +475,9 @@ dependencies = [
|
||||
"ethcore-devtools 1.9.0",
|
||||
"ethcore-io 1.9.0",
|
||||
"ethcore-logger 1.9.0",
|
||||
"ethcore-miner 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)",
|
||||
"ethjson 0.1.0",
|
||||
"ethkey 0.3.0",
|
||||
@ -485,7 +487,6 @@ dependencies = [
|
||||
"hardware-wallet 1.9.0",
|
||||
"hashdb 0.1.1",
|
||||
"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)",
|
||||
"journaldb 0.1.0",
|
||||
"keccak-hash 0.1.0",
|
||||
@ -493,7 +494,6 @@ dependencies = [
|
||||
"kvdb-memorydb 0.1.0",
|
||||
"kvdb-rocksdb 0.1.0",
|
||||
"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)",
|
||||
"lru-cache 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"macros 0.1.0",
|
||||
@ -516,9 +516,7 @@ dependencies = [
|
||||
"semantic_version 0.1.0",
|
||||
"snappy 0.1.0 (git+https://github.com/paritytech/rust-snappy)",
|
||||
"stats 0.1.0",
|
||||
"table 0.1.0",
|
||||
"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",
|
||||
"unexpected 0.1.0",
|
||||
"using_queue 0.1.0",
|
||||
@ -565,6 +563,7 @@ dependencies = [
|
||||
"ethcore-bytes 0.1.0",
|
||||
"ethcore-io 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)",
|
||||
"evm 0.1.0",
|
||||
"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)",
|
||||
]
|
||||
|
||||
[[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]]
|
||||
name = "ethcore-network"
|
||||
version = "1.9.0"
|
||||
@ -695,6 +716,21 @@ dependencies = [
|
||||
"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]]
|
||||
name = "ethcrypto"
|
||||
version = "0.1.0"
|
||||
@ -811,6 +847,7 @@ dependencies = [
|
||||
"ethcore-io 1.9.0",
|
||||
"ethcore-light 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)",
|
||||
"ethkey 0.3.0",
|
||||
"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)",
|
||||
"ethcore 1.9.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)",
|
||||
"ethjson 0.1.0",
|
||||
"evm 0.1.0",
|
||||
@ -1897,9 +1935,11 @@ dependencies = [
|
||||
"ethcore-io 1.9.0",
|
||||
"ethcore-light 1.9.0",
|
||||
"ethcore-logger 1.9.0",
|
||||
"ethcore-miner 1.9.0",
|
||||
"ethcore-network 1.9.0",
|
||||
"ethcore-secretstore 1.0.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)",
|
||||
"ethkey 0.3.0",
|
||||
"ethsync 1.9.0",
|
||||
@ -2053,6 +2093,7 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"ethcore 1.9.0",
|
||||
"ethcore-io 1.9.0",
|
||||
"ethcore-transaction 0.1.0",
|
||||
"ethkey 0.3.0",
|
||||
"kvdb 0.1.0",
|
||||
"kvdb-memorydb 0.1.0",
|
||||
@ -2091,7 +2132,9 @@ dependencies = [
|
||||
"ethcore-io 1.9.0",
|
||||
"ethcore-light 1.9.0",
|
||||
"ethcore-logger 1.9.0",
|
||||
"ethcore-miner 1.9.0",
|
||||
"ethcore-network 1.9.0",
|
||||
"ethcore-transaction 0.1.0",
|
||||
"ethcrypto 0.1.0",
|
||||
"ethereum-types 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethjson 0.1.0",
|
||||
|
@ -35,12 +35,14 @@ jsonrpc-core = { git = "https://github.com/paritytech/jsonrpc.git", branch = "pa
|
||||
ethsync = { path = "sync" }
|
||||
ethcore = { path = "ethcore" }
|
||||
ethcore-bytes = { path = "util/bytes" }
|
||||
ethcore-io = { path = "util/io" }
|
||||
ethcore-devtools = { path = "devtools" }
|
||||
ethcore-io = { path = "util/io" }
|
||||
ethcore-light = { path = "ethcore/light" }
|
||||
ethcore-logger = { path = "logger" }
|
||||
ethcore-stratum = { path = "stratum" }
|
||||
ethcore-miner = { path = "miner" }
|
||||
ethcore-network = { path = "util/network" }
|
||||
ethcore-stratum = { path = "stratum" }
|
||||
ethcore-transaction = { path = "ethcore/transaction" }
|
||||
ethereum-types = "0.1"
|
||||
node-filter = { path = "ethcore/node_filter" }
|
||||
ethkey = { path = "ethkey" }
|
||||
@ -119,9 +121,11 @@ members = [
|
||||
"chainspec",
|
||||
"dapps/js-glue",
|
||||
"ethcore/wasm/run",
|
||||
"ethcore/types",
|
||||
"ethkey/cli",
|
||||
"ethstore/cli",
|
||||
"evmbin",
|
||||
"miner",
|
||||
"transaction-pool",
|
||||
"whisper",
|
||||
]
|
||||
|
@ -22,7 +22,9 @@ patricia-trie = { path = "../util/patricia_trie" }
|
||||
ethcore-devtools = { path = "../devtools" }
|
||||
ethcore-io = { path = "../util/io" }
|
||||
ethcore-logger = { path = "../logger" }
|
||||
ethcore-miner = { path = "../miner" }
|
||||
ethcore-stratum = { path = "../stratum" }
|
||||
ethcore-transaction = { path = "./transaction" }
|
||||
ethereum-types = "0.1"
|
||||
memory-cache = { path = "../util/memory_cache" }
|
||||
ethjson = { path = "../json" }
|
||||
@ -32,10 +34,8 @@ evm = { path = "evm" }
|
||||
futures = "0.1"
|
||||
hardware-wallet = { path = "../hw" }
|
||||
heapsize = "0.4"
|
||||
hyper = { git = "https://github.com/paritytech/hyper", default-features = false }
|
||||
itertools = "0.5"
|
||||
lazy_static = "0.2"
|
||||
linked-hash-map = "0.5"
|
||||
log = "0.3"
|
||||
lru-cache = "0.1"
|
||||
native-contracts = { path = "native_contracts" }
|
||||
@ -59,9 +59,7 @@ rust-crypto = "0.2.34"
|
||||
rustc-hex = "1.0"
|
||||
stats = { path = "../util/stats" }
|
||||
time = "0.1"
|
||||
transient-hashmap = "0.4"
|
||||
using_queue = { path = "../util/using_queue" }
|
||||
table = { path = "../util/table" }
|
||||
bloomable = { path = "../util/bloomable" }
|
||||
vm = { path = "vm" }
|
||||
wasm = { path = "wasm" }
|
||||
@ -79,7 +77,7 @@ jit = ["evm/jit"]
|
||||
evm-debug = ["slow-blocks"]
|
||||
evm-debug-tests = ["evm-debug", "evm/evm-debug-tests"]
|
||||
slow-blocks = [] # Use SLOW_TX_DURATION="50" (compile time!) to track transactions over 50ms
|
||||
json-tests = []
|
||||
json-tests = ["ethcore-transaction/json-tests"]
|
||||
test-heavy = []
|
||||
default = []
|
||||
benches = []
|
||||
|
@ -10,6 +10,7 @@ authors = ["Parity Technologies <admin@parity.io>"]
|
||||
log = "0.3"
|
||||
ethcore = { path = ".."}
|
||||
ethcore-bytes = { path = "../../util/bytes" }
|
||||
ethcore-transaction = { path = "../transaction" }
|
||||
ethereum-types = "0.1"
|
||||
memorydb = { path = "../../util/memorydb" }
|
||||
patricia-trie = { path = "../../util/patricia_trie" }
|
||||
|
@ -57,6 +57,7 @@ extern crate bincode;
|
||||
extern crate ethcore_io as io;
|
||||
extern crate ethcore_network as network;
|
||||
extern crate ethcore_bytes as bytes;
|
||||
extern crate ethcore_transaction as transaction;
|
||||
extern crate ethereum_types;
|
||||
extern crate ethcore;
|
||||
extern crate evm;
|
||||
|
@ -18,7 +18,7 @@
|
||||
//!
|
||||
//! This uses a "Provider" to answer requests.
|
||||
|
||||
use ethcore::transaction::UnverifiedTransaction;
|
||||
use transaction::UnverifiedTransaction;
|
||||
|
||||
use io::TimerToken;
|
||||
use network::{HostInfo, NetworkProtocolHandler, NetworkContext, PeerId};
|
||||
|
@ -20,9 +20,9 @@
|
||||
use ethcore::blockchain_info::BlockChainInfo;
|
||||
use ethcore::client::{EachBlockWith, TestBlockChainClient};
|
||||
use ethcore::ids::BlockId;
|
||||
use ethcore::transaction::{Action, PendingTransaction};
|
||||
use ethcore::encoded;
|
||||
use network::{PeerId, NodeId};
|
||||
use transaction::{Action, PendingTransaction};
|
||||
|
||||
use net::context::IoContext;
|
||||
use net::status::{Capabilities, Status};
|
||||
|
@ -24,7 +24,7 @@ use ethcore::engines::{EthEngine, StateDependentProof};
|
||||
use ethcore::machine::EthereumMachine;
|
||||
use ethcore::receipt::Receipt;
|
||||
use ethcore::state::{self, ProvedExecution};
|
||||
use ethcore::transaction::SignedTransaction;
|
||||
use transaction::SignedTransaction;
|
||||
use vm::EnvInfo;
|
||||
use hash::{KECCAK_NULL_RLP, KECCAK_EMPTY, KECCAK_EMPTY_LIST_RLP, keccak};
|
||||
|
||||
|
@ -21,11 +21,11 @@ use std::sync::Arc;
|
||||
|
||||
use ethcore::blockchain_info::BlockChainInfo;
|
||||
use ethcore::client::{BlockChainClient, ProvingBlockChainClient};
|
||||
use ethcore::transaction::PendingTransaction;
|
||||
use ethcore::ids::BlockId;
|
||||
use ethcore::encoded;
|
||||
use ethcore::ids::BlockId;
|
||||
use ethereum_types::H256;
|
||||
use parking_lot::RwLock;
|
||||
use transaction::PendingTransaction;
|
||||
|
||||
use cht::{self, BlockInfo};
|
||||
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> {
|
||||
use ethcore::transaction::Transaction;
|
||||
use transaction::Transaction;
|
||||
|
||||
let id = BlockId::Hash(req.block_hash);
|
||||
let nonce = match self.nonce(&req.from, id.clone()) {
|
||||
|
@ -26,8 +26,7 @@
|
||||
use std::collections::{BTreeMap, HashMap};
|
||||
use std::collections::hash_map::Entry;
|
||||
|
||||
use ethcore::error::{TransactionError, TransactionImportResult};
|
||||
use ethcore::transaction::{Condition, PendingTransaction, SignedTransaction};
|
||||
use transaction::{self, Condition, PendingTransaction, SignedTransaction};
|
||||
use ethereum_types::{H256, U256, Address};
|
||||
use plain_hasher::H256FastMap;
|
||||
|
||||
@ -123,13 +122,13 @@ pub struct TransactionQueue {
|
||||
|
||||
impl TransactionQueue {
|
||||
/// 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 hash = tx.hash();
|
||||
let nonce = tx.nonce;
|
||||
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) {
|
||||
Entry::Vacant(entry) => {
|
||||
@ -139,14 +138,14 @@ impl TransactionQueue {
|
||||
future: BTreeMap::new(),
|
||||
});
|
||||
|
||||
TransactionImportResult::Current
|
||||
transaction::ImportResult::Current
|
||||
}
|
||||
Entry::Occupied(mut entry) => {
|
||||
let acct_txs = entry.get_mut();
|
||||
if &nonce < acct_txs.cur_nonce.value() {
|
||||
// don't accept txs from before known current nonce.
|
||||
if acct_txs.cur_nonce.is_known() {
|
||||
return Err(TransactionError::Old)
|
||||
return Err(transaction::Error::Old)
|
||||
}
|
||||
|
||||
// lower our assumption until corrected later.
|
||||
@ -161,7 +160,7 @@ impl TransactionQueue {
|
||||
let old = ::std::mem::replace(&mut acct_txs.current[idx], tx_info);
|
||||
self.by_hash.remove(&old.hash);
|
||||
|
||||
TransactionImportResult::Current
|
||||
transaction::ImportResult::Current
|
||||
}
|
||||
Err(idx) => {
|
||||
let cur_len = acct_txs.current.len();
|
||||
@ -183,13 +182,13 @@ impl TransactionQueue {
|
||||
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) {
|
||||
trace!(target: "txqueue", "Queued future transaction for {}, nonce={}", sender, nonce);
|
||||
let future_nonce = nonce;
|
||||
acct_txs.future.insert(future_nonce, tx_info);
|
||||
|
||||
TransactionImportResult::Future
|
||||
transaction::ImportResult::Future
|
||||
} else {
|
||||
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.adjust_future();
|
||||
|
||||
TransactionImportResult::Current
|
||||
transaction::ImportResult::Current
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -331,7 +330,7 @@ impl TransactionQueue {
|
||||
mod tests {
|
||||
use super::TransactionQueue;
|
||||
use ethereum_types::Address;
|
||||
use ethcore::transaction::{Transaction, PendingTransaction, Condition};
|
||||
use transaction::{Transaction, PendingTransaction, Condition};
|
||||
|
||||
#[test]
|
||||
fn queued_senders() {
|
||||
|
@ -1094,7 +1094,7 @@ pub mod block_body {
|
||||
impl Decodable for Response {
|
||||
fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
|
||||
use ethcore::header::Header as FullHeader;
|
||||
use ethcore::transaction::UnverifiedTransaction;
|
||||
use transaction::UnverifiedTransaction;
|
||||
|
||||
// check body validity.
|
||||
let _: Vec<UnverifiedTransaction> = rlp.list_at(0)?;
|
||||
@ -1410,7 +1410,7 @@ pub mod contract_code {
|
||||
/// A request for proof of execution.
|
||||
pub mod execution {
|
||||
use super::{Field, NoSuchOutput, OutputKind, Output};
|
||||
use ethcore::transaction::Action;
|
||||
use transaction::Action;
|
||||
use rlp::{Encodable, Decodable, DecoderError, RlpStream, UntrustedRlp};
|
||||
use ethereum_types::{H256, U256, Address};
|
||||
use kvdb::DBValue;
|
||||
@ -1755,7 +1755,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn body_roundtrip() {
|
||||
use ethcore::transaction::{Transaction, UnverifiedTransaction};
|
||||
use transaction::{Transaction, UnverifiedTransaction};
|
||||
let req = IncompleteBodyRequest {
|
||||
hash: Field::Scalar(Default::default()),
|
||||
};
|
||||
@ -1850,7 +1850,7 @@ mod tests {
|
||||
let req = IncompleteExecutionRequest {
|
||||
block_hash: Field::Scalar(Default::default()),
|
||||
from: Default::default(),
|
||||
action: ::ethcore::transaction::Action::Create,
|
||||
action: ::transaction::Action::Create,
|
||||
gas: 100_000.into(),
|
||||
gas_price: 0.into(),
|
||||
value: 100_000_001.into(),
|
||||
@ -1880,7 +1880,7 @@ mod tests {
|
||||
let reqs: Vec<_> = (0..10).map(|_| IncompleteExecutionRequest {
|
||||
block_hash: Field::Scalar(Default::default()),
|
||||
from: Default::default(),
|
||||
action: ::ethcore::transaction::Action::Create,
|
||||
action: ::transaction::Action::Create,
|
||||
gas: 100_000.into(),
|
||||
gas_price: 0.into(),
|
||||
value: 100_000_001.into(),
|
||||
|
@ -30,14 +30,14 @@ use unexpected::{Mismatch, OutOfBounds};
|
||||
use basic_types::{LogBloom, Seal};
|
||||
use vm::{EnvInfo, LastHashes};
|
||||
use engines::EthEngine;
|
||||
use error::{Error, BlockError, TransactionError};
|
||||
use error::{Error, BlockError};
|
||||
use factory::Factories;
|
||||
use header::Header;
|
||||
use receipt::{Receipt, TransactionOutcome};
|
||||
use state::State;
|
||||
use state_db::StateDB;
|
||||
use trace::FlatTrace;
|
||||
use transaction::{UnverifiedTransaction, SignedTransaction};
|
||||
use transaction::{UnverifiedTransaction, SignedTransaction, Error as TransactionError};
|
||||
use verification::PreverifiedBlock;
|
||||
use views::BlockView;
|
||||
|
||||
@ -737,7 +737,12 @@ mod tests {
|
||||
) -> Result<LockedBlock, Error> {
|
||||
let block = BlockView::new(block_bytes);
|
||||
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?;
|
||||
|
||||
{
|
||||
|
@ -55,7 +55,7 @@ use futures::{future, Future};
|
||||
use header::{BlockNumber, Header};
|
||||
use io::*;
|
||||
use log_entry::LocalizedLogEntry;
|
||||
use miner::{Miner, MinerService, TransactionImportResult};
|
||||
use miner::{Miner, MinerService};
|
||||
use native_contracts::Registry;
|
||||
use parking_lot::{Mutex, RwLock, MutexGuard};
|
||||
use rand::OsRng;
|
||||
@ -69,7 +69,7 @@ use state::{self, State};
|
||||
use trace;
|
||||
use trace::{TraceDB, ImportRequest as TraceImportRequest, LocalizedTrace, Database as TraceDatabase};
|
||||
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::mode::Mode as IpcMode;
|
||||
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 {
|
||||
nonce: self.latest_nonce(&self.miner.author()),
|
||||
action: Action::Call(address),
|
||||
|
@ -203,7 +203,7 @@ impl<'a> EvmTestClient<'a> {
|
||||
if let Err(error) = is_ok {
|
||||
return TransactResult::Err {
|
||||
state_root: *self.state.root(),
|
||||
error,
|
||||
error: error.into(),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -42,7 +42,7 @@ pub use types::call_analytics::CallAnalytics;
|
||||
pub use executive::{Executed, Executive, TransactOptions};
|
||||
pub use vm::{LastHashes, EnvInfo};
|
||||
|
||||
pub use error::{BlockImportError, TransactionImportError, TransactionImportResult};
|
||||
pub use error::{BlockImportError, TransactionImportError};
|
||||
pub use verification::VerifierType;
|
||||
|
||||
mod traits;
|
||||
|
@ -32,7 +32,7 @@ use bytes::Bytes;
|
||||
use rlp::*;
|
||||
use ethkey::{Generator, Random};
|
||||
use devtools::*;
|
||||
use transaction::{Transaction, LocalizedTransaction, PendingTransaction, SignedTransaction, Action};
|
||||
use transaction::{self, Transaction, LocalizedTransaction, PendingTransaction, SignedTransaction, Action};
|
||||
use blockchain::TreeRoute;
|
||||
use client::{
|
||||
BlockChainClient, MiningBlockChainClient, BlockChainInfo, BlockStatus, BlockId,
|
||||
@ -48,7 +48,7 @@ use blockchain::extras::BlockReceipts;
|
||||
use error::{ImportResult, Error as EthcoreError};
|
||||
use evm::{Factory as EvmFactory, VMType};
|
||||
use vm::Schedule;
|
||||
use miner::{Miner, MinerService, TransactionImportResult};
|
||||
use miner::{Miner, MinerService};
|
||||
use spec::Spec;
|
||||
use types::basic_account::BasicAccount;
|
||||
use types::mode::Mode;
|
||||
@ -337,7 +337,7 @@ impl TestBlockChainClient {
|
||||
let hash = signed_tx.hash();
|
||||
let res = self.miner.import_external_transactions(self, vec![signed_tx.into()]);
|
||||
let res = res.into_iter().next().unwrap().expect("Successful import");
|
||||
assert_eq!(res, TransactionImportResult::Current);
|
||||
assert_eq!(res, transaction::ImportResult::Current);
|
||||
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 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 {
|
||||
nonce: self.latest_nonce(&self.miner.author()),
|
||||
action: Action::Call(address),
|
||||
|
@ -21,8 +21,7 @@ use block::{OpenBlock, SealedBlock, ClosedBlock};
|
||||
use blockchain::TreeRoute;
|
||||
use encoded;
|
||||
use vm::LastHashes;
|
||||
use error::{ImportResult, CallError, Error as EthcoreError};
|
||||
use error::{TransactionImportResult, BlockImportError};
|
||||
use error::{ImportResult, CallError, Error as EthcoreError, BlockImportError};
|
||||
use evm::{Factory as EvmFactory, Schedule};
|
||||
use executive::Executed;
|
||||
use filter::Filter;
|
||||
@ -30,7 +29,7 @@ use header::{BlockNumber};
|
||||
use log_entry::LocalizedLogEntry;
|
||||
use receipt::LocalizedReceipt;
|
||||
use trace::LocalizedTrace;
|
||||
use transaction::{LocalizedTransaction, PendingTransaction, SignedTransaction};
|
||||
use transaction::{LocalizedTransaction, PendingTransaction, SignedTransaction, ImportResult as TransactionImportResult};
|
||||
use verification::queue::QueueInfo as BlockQueueInfo;
|
||||
|
||||
use ethereum_types::{H256, U256, Address};
|
||||
|
@ -31,92 +31,10 @@ use snapshot::Error as SnapshotError;
|
||||
use engines::EngineError;
|
||||
use ethkey::Error as EthkeyError;
|
||||
use account_provider::SignError as AccountsError;
|
||||
use transaction::Error as TransactionError;
|
||||
|
||||
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)]
|
||||
/// Errors concerning block processing.
|
||||
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
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum TransactionImportError {
|
||||
|
@ -42,8 +42,10 @@ fn do_json_test(json_data: &[u8]) -> Vec<String> {
|
||||
let rlp: Vec<u8> = test.rlp.into();
|
||||
let res = UntrustedRlp::new(&rlp)
|
||||
.as_val()
|
||||
.map_err(From::from)
|
||||
.and_then(|t: UnverifiedTransaction| t.validate(schedule, schedule.have_delegate_call, allow_chain_id_of_one, allow_unsigned));
|
||||
.map_err(::error::Error::from)
|
||||
.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");
|
||||
if let (Some(tx), Some(sender)) = (test.transaction, test.sender) {
|
||||
|
@ -66,16 +66,16 @@ extern crate ethcore_devtools as devtools;
|
||||
extern crate ethcore_io as io;
|
||||
extern crate ethcore_bytes as bytes;
|
||||
extern crate ethcore_logger;
|
||||
extern crate ethcore_miner;
|
||||
extern crate ethcore_stratum;
|
||||
extern crate ethcore_transaction as transaction;
|
||||
extern crate ethereum_types;
|
||||
extern crate ethjson;
|
||||
extern crate ethkey;
|
||||
extern crate futures;
|
||||
extern crate hardware_wallet;
|
||||
extern crate hashdb;
|
||||
extern crate hyper;
|
||||
extern crate itertools;
|
||||
extern crate linked_hash_map;
|
||||
extern crate lru_cache;
|
||||
extern crate native_contracts;
|
||||
extern crate num_cpus;
|
||||
@ -106,9 +106,7 @@ extern crate rlp_derive;
|
||||
extern crate rustc_hex;
|
||||
extern crate stats;
|
||||
extern crate time;
|
||||
extern crate transient_hashmap;
|
||||
extern crate using_queue;
|
||||
extern crate table;
|
||||
extern crate bloomable;
|
||||
extern crate vm;
|
||||
extern crate wasm;
|
||||
@ -149,7 +147,6 @@ pub mod spec;
|
||||
pub mod state;
|
||||
pub mod timer;
|
||||
pub mod trace;
|
||||
pub mod transaction;
|
||||
pub mod verification;
|
||||
pub mod views;
|
||||
|
||||
|
@ -23,13 +23,13 @@ use std::sync::Arc;
|
||||
use block::ExecutedBlock;
|
||||
use builtin::Builtin;
|
||||
use client::BlockChainClient;
|
||||
use error::{Error, TransactionError};
|
||||
use error::Error;
|
||||
use executive::Executive;
|
||||
use header::{BlockNumber, Header};
|
||||
use spec::CommonParams;
|
||||
use state::{CleanupMode, Substate};
|
||||
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 ethereum_types::{U256, Address};
|
||||
@ -341,7 +341,7 @@ impl EthereumMachine {
|
||||
|
||||
/// Verify a particular transaction is valid, regardless of order.
|
||||
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.
|
||||
@ -369,7 +369,7 @@ impl EthereumMachine {
|
||||
pub fn verify_transaction(&self, t: &SignedTransaction, header: &Header, client: &BlockChainClient) -> Result<(), Error> {
|
||||
if let Some(ref filter) = self.tx_filter.as_ref() {
|
||||
if !filter.transaction_allowed(header.parent_hash(), t, client) {
|
||||
return Err(TransactionError::NotAllowed.into())
|
||||
return Err(transaction::Error::NotAllowed.into())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -18,32 +18,47 @@ use std::time::{Instant, Duration};
|
||||
use std::collections::{BTreeMap, HashSet};
|
||||
use std::sync::Arc;
|
||||
|
||||
use account_provider::{AccountProvider, SignError as AccountError};
|
||||
use ansi_term::Colour;
|
||||
use ethereum_types::{H256, U256, Address};
|
||||
use parking_lot::{Mutex, RwLock};
|
||||
use bytes::Bytes;
|
||||
use timer::PerfTimer;
|
||||
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 engines::{EthEngine, Seal};
|
||||
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 spec::Spec;
|
||||
use engines::{EthEngine, Seal};
|
||||
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;
|
||||
use state::State;
|
||||
|
||||
/// Different possible definitions for pending transaction set.
|
||||
#[derive(Debug, PartialEq)]
|
||||
@ -711,10 +726,10 @@ impl Miner {
|
||||
let details_provider = TransactionDetailsProvider::new(client, &self.service_transaction_action);
|
||||
match origin {
|
||||
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 => {
|
||||
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 {
|
||||
pub fn update_from_chain_client(&self, client: &MiningBlockChainClient) {
|
||||
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> {
|
||||
match *self {
|
||||
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> {
|
||||
client: &'a MiningBlockChainClient,
|
||||
service_transaction_action: &'a ServiceTransactionAction,
|
||||
@ -1263,20 +1288,16 @@ impl<'a> TransactionQueueDetailsProvider for TransactionDetailsProvider<'a> {
|
||||
|
||||
#[cfg(test)]
|
||||
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 block::IsBlock;
|
||||
use ethcore_miner::transaction_queue::PrioritizationStrategy;
|
||||
use ethereum_types::U256;
|
||||
use ethkey::{Generator, Random};
|
||||
use client::{BlockChainClient, TestBlockChainClient, EachBlockWith, TransactionImportResult};
|
||||
use header::BlockNumber;
|
||||
use transaction::{SignedTransaction, Transaction, PendingTransaction, Action};
|
||||
use spec::Spec;
|
||||
use hash::keccak;
|
||||
use rustc_hex::FromHex;
|
||||
use transaction::Transaction;
|
||||
|
||||
use client::{BlockChainClient, TestBlockChainClient, EachBlockWith};
|
||||
use miner::MinerService;
|
||||
use tests::helpers::{generate_dummy_client, generate_dummy_client_with_spec_and_accounts};
|
||||
|
||||
#[test]
|
||||
|
@ -38,34 +38,24 @@
|
||||
//! }
|
||||
//! ```
|
||||
|
||||
mod banning_queue;
|
||||
mod external;
|
||||
mod local_transactions;
|
||||
mod miner;
|
||||
mod service_transaction_checker;
|
||||
mod transaction_queue;
|
||||
mod work_notify;
|
||||
mod stratum;
|
||||
|
||||
pub use self::external::{ExternalMiner, ExternalMinerService};
|
||||
|
||||
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 ethcore_miner::local_transactions::Status as LocalTransactionStatus;
|
||||
|
||||
use std::collections::BTreeMap;
|
||||
use ethereum_types::{H256, U256, Address};
|
||||
use bytes::Bytes;
|
||||
use client::{MiningBlockChainClient};
|
||||
|
||||
use block::ClosedBlock;
|
||||
use client::{MiningBlockChainClient};
|
||||
use error::{Error};
|
||||
use header::BlockNumber;
|
||||
use receipt::{RichReceipt, Receipt};
|
||||
use error::{Error};
|
||||
use transaction::{UnverifiedTransaction, PendingTransaction};
|
||||
use transaction::{UnverifiedTransaction, PendingTransaction, ImportResult as TransactionImportResult};
|
||||
|
||||
/// Miner client API
|
||||
pub trait MinerService : Send + Sync {
|
||||
|
@ -16,22 +16,22 @@
|
||||
|
||||
//! 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::net::{SocketAddr, AddrParseError};
|
||||
use std::fmt;
|
||||
|
||||
use block::IsBlock;
|
||||
use client::Client;
|
||||
use ethereum_types::{H64, H256, clean_0x, U256};
|
||||
use ethereum::ethash::Ethash;
|
||||
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 client::Client;
|
||||
use block::IsBlock;
|
||||
use parking_lot::Mutex;
|
||||
use rlp::encode;
|
||||
|
||||
/// Configures stratum server options.
|
||||
@ -213,7 +213,7 @@ impl From<AddrParseError> for Error {
|
||||
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) {
|
||||
trace!(target: "stratum", "Notify work");
|
||||
|
||||
@ -248,7 +248,7 @@ impl Stratum {
|
||||
/// Start STRATUM job dispatcher and register it in the miner
|
||||
pub fn register(cfg: &Options, miner: Arc<Miner>, client: Weak<Client>) -> Result<(), Error> {
|
||||
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(())
|
||||
}
|
||||
}
|
||||
|
@ -332,27 +332,21 @@ fn verify_block_integrity(block: &[u8], transactions_root: &H256, uncles_hash: &
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
use std::collections::{BTreeMap, HashMap};
|
||||
use hash::keccak;
|
||||
use ethereum_types::{H256, H2048, U256};
|
||||
use triehash::ordered_trie_root;
|
||||
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 blockchain::extras::{BlockDetails, TransactionAddress, BlockReceipts};
|
||||
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>) {
|
||||
result.unwrap_or_else(|e| panic!("Block verification failed: {:?}", e));
|
||||
|
21
ethcore/transaction/Cargo.toml
Normal file
21
ethcore/transaction/Cargo.toml
Normal 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 = []
|
114
ethcore/transaction/src/error.rs
Normal file
114
ethcore/transaction/src/error.rs
Normal 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))
|
||||
}
|
||||
}
|
||||
|
46
ethcore/transaction/src/lib.rs
Normal file
46
ethcore/transaction/src/lib.rs
Normal 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
|
||||
}
|
@ -17,16 +17,18 @@
|
||||
//! Transaction data structure.
|
||||
|
||||
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 heapsize::HeapSizeOf;
|
||||
use ethereum_types::{H256, H160, Address, U256};
|
||||
use bytes::Bytes;
|
||||
use ethkey::{Signature, Secret, Public, recover, public_to_address, Error as EthkeyError};
|
||||
use error::*;
|
||||
use evm::Schedule;
|
||||
use header::BlockNumber;
|
||||
use ethjson;
|
||||
use rlp::{self, RlpStream, UntrustedRlp, DecoderError, Encodable};
|
||||
// use rlp::*;
|
||||
|
||||
type Bytes = Vec<u8>;
|
||||
type BlockNumber = u64;
|
||||
|
||||
/// Fake address for unsigned transactions as defined by EIP-86.
|
||||
pub const UNSIGNED_SENDER: Address = H160([0xff; 20]);
|
||||
@ -48,7 +50,7 @@ impl Default for Action {
|
||||
fn default() -> Action { Action::Create }
|
||||
}
|
||||
|
||||
impl Decodable for Action {
|
||||
impl rlp::Decodable for Action {
|
||||
fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
|
||||
if rlp.is_empty() {
|
||||
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) {
|
||||
match *self {
|
||||
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> {
|
||||
if d.item_count()? != 9 {
|
||||
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) }
|
||||
}
|
||||
|
||||
@ -350,9 +352,9 @@ impl UnverifiedTransaction {
|
||||
}
|
||||
|
||||
/// 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() {
|
||||
Err(EthkeyError::InvalidSignature.into())
|
||||
Err(ethkey::Error::InvalidSignature.into())
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
@ -364,39 +366,40 @@ impl UnverifiedTransaction {
|
||||
}
|
||||
|
||||
/// 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()))?)
|
||||
}
|
||||
|
||||
/// Do basic validation, checking for valid signature and minimum gas,
|
||||
// TODO: consider use in block validation.
|
||||
#[cfg(test)]
|
||||
#[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 };
|
||||
self.verify_basic(require_low, chain_id, allow_empty_signature)?;
|
||||
if !allow_empty_signature || !self.is_unsigned() {
|
||||
self.recover_public()?;
|
||||
}
|
||||
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)
|
||||
}
|
||||
|
||||
/// 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()) {
|
||||
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.
|
||||
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) {
|
||||
(None, _) => {},
|
||||
(Some(n), Some(m)) if n == m => {},
|
||||
_ => return Err(TransactionError::InvalidChainId.into()),
|
||||
_ => return Err(error::Error::InvalidChainId),
|
||||
};
|
||||
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) }
|
||||
}
|
||||
|
||||
@ -435,7 +438,7 @@ impl From<SignedTransaction> for UnverifiedTransaction {
|
||||
|
||||
impl SignedTransaction {
|
||||
/// 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() {
|
||||
Ok(SignedTransaction {
|
||||
transaction: transaction,
|
||||
@ -556,7 +559,7 @@ mod tests {
|
||||
|
||||
#[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.gas, U256::from(0x5208u64));
|
||||
assert_eq!(t.gas_price, U256::from(0x01u64));
|
||||
@ -625,10 +628,10 @@ mod tests {
|
||||
use rustc_hex::FromHex;
|
||||
|
||||
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();
|
||||
assert_eq!(signed.sender(), address.into());
|
||||
flushln!("chainid: {:?}", signed.chain_id());
|
||||
println!("chainid: {:?}", signed.chain_id());
|
||||
};
|
||||
|
||||
test_vector("f864808504a817c800825208943535353535353535353535353535353535353535808025a0044852b2a670ade5407e78fb2863c51de9fcb96542a07186fe3aeda6bb8a116da0044852b2a670ade5407e78fb2863c51de9fcb96542a07186fe3aeda6bb8a116d", "0xf0f6f18bca1b28cd68e4357452947e021241e9ce");
|
@ -17,11 +17,11 @@
|
||||
//! Log entry type definition.
|
||||
|
||||
use std::ops::Deref;
|
||||
use hash::keccak;
|
||||
use heapsize::HeapSizeOf;
|
||||
use bytes::Bytes;
|
||||
use ethereum_types::{H256, Address, LogBloom};
|
||||
use bloomable::Bloomable;
|
||||
use bytes::Bytes;
|
||||
use hash::keccak;
|
||||
use heapsize::HeapSizeOf;
|
||||
|
||||
use {BlockNumber};
|
||||
use ethjson;
|
||||
|
@ -9,17 +9,18 @@ name = "parity-evm"
|
||||
path = "./src/main.rs"
|
||||
|
||||
[dependencies]
|
||||
rustc-hex = "1.0"
|
||||
docopt = "0.8"
|
||||
serde = "1.0"
|
||||
serde_derive = "1.0"
|
||||
ethcore = { path = "../ethcore" }
|
||||
ethjson = { path = "../json" }
|
||||
ethcore-bytes = { path = "../util/bytes" }
|
||||
ethcore-transaction = { path = "../ethcore/transaction" }
|
||||
ethereum-types = "0.1"
|
||||
evm = { path = "../ethcore/evm" }
|
||||
vm = { path = "../ethcore/vm" }
|
||||
panic_hook = { path = "../panic_hook" }
|
||||
rustc-hex = "1.0"
|
||||
serde = "1.0"
|
||||
serde_derive = "1.0"
|
||||
vm = { path = "../ethcore/vm" }
|
||||
|
||||
[dev-dependencies]
|
||||
pretty_assertions = "0.1"
|
||||
|
@ -18,9 +18,10 @@
|
||||
|
||||
use std::time::{Instant, Duration};
|
||||
use ethereum_types::{H256, U256};
|
||||
use ethcore::{trace, spec, transaction, pod_state};
|
||||
use ethcore::client::{self, EvmTestClient, EvmTestError, TransactResult};
|
||||
use ethcore::{trace, spec, pod_state};
|
||||
use ethjson;
|
||||
use transaction;
|
||||
use vm::ActionParams;
|
||||
|
||||
/// VM execution informant
|
||||
|
@ -25,6 +25,7 @@ extern crate serde;
|
||||
#[macro_use]
|
||||
extern crate serde_derive;
|
||||
extern crate docopt;
|
||||
extern crate ethcore_transaction as transaction;
|
||||
extern crate ethcore_bytes as bytes;
|
||||
extern crate ethereum_types;
|
||||
extern crate vm;
|
||||
|
@ -5,14 +5,15 @@ version = "0.1.0"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
|
||||
[dependencies]
|
||||
ethcore-io = { path = "../util/io" }
|
||||
ethcore = { path = "../ethcore" }
|
||||
rlp = { path = "../util/rlp" }
|
||||
ethcore-io = { path = "../util/io" }
|
||||
ethcore-transaction = { path = "../ethcore/transaction" }
|
||||
kvdb = { path = "../util/kvdb" }
|
||||
log = "0.3"
|
||||
rlp = { path = "../util/rlp" }
|
||||
serde = "1.0"
|
||||
serde_derive = "1.0"
|
||||
serde_json = "1.0"
|
||||
log = "0.3"
|
||||
|
||||
[dev-dependencies]
|
||||
ethkey = { path = "../ethkey" }
|
||||
|
@ -19,7 +19,7 @@
|
||||
use std::sync::Arc;
|
||||
use std::fmt;
|
||||
|
||||
use ethcore::transaction::{
|
||||
use transaction::{
|
||||
SignedTransaction, PendingTransaction, UnverifiedTransaction,
|
||||
Condition as TransactionCondition
|
||||
};
|
||||
@ -29,6 +29,7 @@ use rlp::UntrustedRlp;
|
||||
use kvdb::KeyValueDB;
|
||||
|
||||
extern crate ethcore;
|
||||
extern crate ethcore_transaction as transaction;
|
||||
extern crate ethcore_io as io;
|
||||
extern crate rlp;
|
||||
extern crate serde_json;
|
||||
@ -231,7 +232,7 @@ mod tests {
|
||||
use super::NodeInfo;
|
||||
|
||||
use std::sync::Arc;
|
||||
use ethcore::transaction::{Transaction, Condition, PendingTransaction};
|
||||
use transaction::{Transaction, Condition, PendingTransaction};
|
||||
use ethkey::{Brain, Generator};
|
||||
|
||||
// we want to test: round-trip of good transactions.
|
||||
|
27
miner/Cargo.toml
Normal file
27
miner/Cargo.toml
Normal 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"
|
@ -19,13 +19,12 @@
|
||||
|
||||
use std::time::Duration;
|
||||
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 hash::keccak;
|
||||
use transaction::{self, SignedTransaction, Action};
|
||||
use transient_hashmap::TransientHashMap;
|
||||
|
||||
use transaction_queue::{TransactionQueue, TransactionDetailsProvider, TransactionOrigin, QueuingInstant};
|
||||
|
||||
type Count = u16;
|
||||
|
||||
@ -80,8 +79,8 @@ impl BanningTransactionQueue {
|
||||
&mut self,
|
||||
transaction: SignedTransaction,
|
||||
time: QueuingInstant,
|
||||
details_provider: &TransactionQueueDetailsProvider,
|
||||
) -> Result<TransactionImportResult, Error> {
|
||||
details_provider: &TransactionDetailsProvider,
|
||||
) -> Result<transaction::ImportResult, transaction::Error> {
|
||||
if let Threshold::BanAfter(threshold) = self.ban_threshold {
|
||||
// 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);
|
||||
if count > threshold {
|
||||
debug!(target: "txqueue", "Ignoring transaction {:?} because sender is banned.", transaction.hash());
|
||||
return Err(Error::Transaction(TransactionError::SenderBanned));
|
||||
return Err(transaction::Error::SenderBanned);
|
||||
}
|
||||
|
||||
// Check recipient
|
||||
@ -98,7 +97,7 @@ impl BanningTransactionQueue {
|
||||
let count = self.recipients_bans.direct().get(&recipient).cloned().unwrap_or(0);
|
||||
if count > threshold {
|
||||
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);
|
||||
if count > threshold {
|
||||
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)]
|
||||
mod tests {
|
||||
use std::time::Duration;
|
||||
use rustc_hex::FromHex;
|
||||
use hash::keccak;
|
||||
use super::{BanningTransactionQueue, Threshold};
|
||||
use super::*;
|
||||
use ethkey::{Random, Generator};
|
||||
use transaction::{Transaction, SignedTransaction, Action};
|
||||
use error::{Error, TransactionError};
|
||||
use client::TransactionImportResult;
|
||||
use miner::{TransactionQueue, TransactionOrigin};
|
||||
use rustc_hex::FromHex;
|
||||
use transaction_queue::test::DummyTransactionDetailsProvider;
|
||||
use ethereum_types::{U256, Address};
|
||||
use miner::transaction_queue::test::DummyTransactionDetailsProvider;
|
||||
|
||||
fn queue() -> BanningTransactionQueue {
|
||||
BanningTransactionQueue::new(TransactionQueue::default(), Threshold::BanAfter(1), Duration::from_secs(180))
|
||||
@ -231,7 +224,7 @@ mod tests {
|
||||
|
||||
fn transaction(action: Action) -> SignedTransaction {
|
||||
let keypair = Random.generate().unwrap();
|
||||
Transaction {
|
||||
transaction::Transaction {
|
||||
action: action,
|
||||
value: U256::from(100),
|
||||
data: "3331600055".from_hex().unwrap(),
|
||||
@ -241,12 +234,8 @@ mod tests {
|
||||
}.sign(keypair.secret(), None)
|
||||
}
|
||||
|
||||
fn unwrap_err(res: Result<TransactionImportResult, Error>) -> TransactionError {
|
||||
match res {
|
||||
Err(Error::Transaction(e)) => e,
|
||||
Ok(x) => panic!("Expected error, got: Ok({:?})", x),
|
||||
Err(e) => panic!("Unexpected error type returned by queue: {:?}", e),
|
||||
}
|
||||
fn unwrap_err(res: Result<transaction::ImportResult, transaction::Error>) -> transaction::Error {
|
||||
res.unwrap_err()
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -273,7 +262,7 @@ mod tests {
|
||||
assert!(!banlist1, "Threshold not reached yet.");
|
||||
// Insert once
|
||||
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
|
||||
let banlist2 = txq.ban_sender(tx.sender());
|
||||
@ -281,7 +270,7 @@ mod tests {
|
||||
|
||||
// then
|
||||
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
|
||||
assert_eq!(txq.find(&tx.hash()), None);
|
||||
}
|
||||
@ -297,7 +286,7 @@ mod tests {
|
||||
assert!(!banlist1, "Threshold not reached yet.");
|
||||
// Insert once
|
||||
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
|
||||
let banlist2 = txq.ban_recipient(recipient);
|
||||
@ -305,7 +294,7 @@ mod tests {
|
||||
|
||||
// then
|
||||
assert!(banlist2, "Threshold should be reached - banned.");
|
||||
assert_eq!(unwrap_err(import2), TransactionError::RecipientBanned);
|
||||
assert_eq!(unwrap_err(import2), transaction::Error::RecipientBanned);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -319,7 +308,7 @@ mod tests {
|
||||
assert!(!banlist1, "Threshold not reached yet.");
|
||||
// Insert once
|
||||
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
|
||||
let banlist2 = txq.ban_codehash(codehash);
|
||||
@ -327,6 +316,6 @@ mod tests {
|
||||
|
||||
// then
|
||||
assert!(banlist2, "Threshold should be reached - banned.");
|
||||
assert_eq!(unwrap_err(import2), TransactionError::CodeBanned);
|
||||
assert_eq!(unwrap_err(import2), transaction::Error::CodeBanned);
|
||||
}
|
||||
}
|
@ -14,6 +14,8 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
//! External Miner hashrate tracker.
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
use std::time::{Instant, Duration};
|
47
miner/src/lib.rs
Normal file
47
miner/src/lib.rs
Normal 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;
|
@ -16,10 +16,9 @@
|
||||
|
||||
//! Local Transactions List.
|
||||
|
||||
use linked_hash_map::LinkedHashMap;
|
||||
use transaction::{SignedTransaction, PendingTransaction};
|
||||
use error::TransactionError;
|
||||
use ethereum_types::{H256, U256};
|
||||
use linked_hash_map::LinkedHashMap;
|
||||
use transaction::{self, SignedTransaction, PendingTransaction};
|
||||
|
||||
/// Status of local transaction.
|
||||
/// 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(SignedTransaction, U256, H256),
|
||||
/// Transaction was never accepted to the queue.
|
||||
Rejected(SignedTransaction, TransactionError),
|
||||
Rejected(SignedTransaction, transaction::Error),
|
||||
/// Transaction is invalid.
|
||||
Invalid(SignedTransaction),
|
||||
/// Transaction was canceled.
|
||||
@ -64,6 +63,7 @@ impl Default for LocalTransactionsList {
|
||||
}
|
||||
|
||||
impl LocalTransactionsList {
|
||||
/// Create a new list of local transactions.
|
||||
pub fn new(max_old: usize) -> Self {
|
||||
LocalTransactionsList {
|
||||
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) {
|
||||
debug!(target: "own_tx", "Imported to Current (hash {:?})", hash);
|
||||
self.clear_old();
|
||||
self.transactions.insert(hash, Status::Pending);
|
||||
}
|
||||
|
||||
/// Mark transaction with given hash as future.
|
||||
pub fn mark_future(&mut self, hash: H256) {
|
||||
debug!(target: "own_tx", "Imported to Future (hash {:?})", hash);
|
||||
self.transactions.insert(hash, Status::Future);
|
||||
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);
|
||||
self.transactions.insert(tx.hash(), Status::Rejected(tx, err));
|
||||
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) {
|
||||
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.clear_old();
|
||||
}
|
||||
|
||||
/// Mark transaction as invalid.
|
||||
pub fn mark_invalid(&mut self, tx: SignedTransaction) {
|
||||
warn!(target: "own_tx", "Transaction marked invalid (hash {:?})", tx.hash());
|
||||
self.transactions.insert(tx.hash(), Status::Invalid(tx));
|
||||
self.clear_old();
|
||||
}
|
||||
|
||||
/// Mark transaction as canceled.
|
||||
pub fn mark_canceled(&mut self, tx: PendingTransaction) {
|
||||
warn!(target: "own_tx", "Transaction canceled (hash {:?})", tx.hash());
|
||||
self.transactions.insert(tx.hash(), Status::Canceled(tx));
|
||||
self.clear_old();
|
||||
}
|
||||
|
||||
/// Mark transaction as dropped because of limit.
|
||||
pub fn mark_dropped(&mut self, tx: SignedTransaction) {
|
||||
warn!(target: "own_tx", "Transaction dropped (hash {:?})", tx.hash());
|
||||
self.transactions.insert(tx.hash(), Status::Dropped(tx));
|
||||
self.clear_old();
|
||||
}
|
||||
|
||||
/// Mark transaction as mined.
|
||||
pub fn mark_mined(&mut self, tx: SignedTransaction) {
|
||||
info!(target: "own_tx", "Transaction mined (hash {:?})", tx.hash());
|
||||
self.transactions.insert(tx.hash(), Status::Mined(tx));
|
||||
self.clear_old();
|
||||
}
|
||||
|
||||
/// Returns true if the transaction is already in local transactions.
|
||||
pub fn contains(&self, hash: &H256) -> bool {
|
||||
self.transactions.contains_key(hash)
|
||||
}
|
||||
|
||||
/// Return a map of all currently stored transactions.
|
||||
pub fn all_transactions(&self) -> &LinkedHashMap<H256, Status> {
|
||||
&self.transactions
|
||||
}
|
||||
@ -152,10 +162,9 @@ impl LocalTransactionsList {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use ethereum_types::U256;
|
||||
use ethkey::{Random, Generator};
|
||||
use transaction::{Action, Transaction, SignedTransaction};
|
||||
use super::{LocalTransactionsList, Status};
|
||||
|
||||
#[test]
|
||||
fn should_add_transaction_as_pending() {
|
||||
@ -199,8 +208,8 @@ mod tests {
|
||||
|
||||
fn new_tx(nonce: U256) -> SignedTransaction {
|
||||
let keypair = Random.generate().unwrap();
|
||||
Transaction {
|
||||
action: Action::Create,
|
||||
transaction::Transaction {
|
||||
action: transaction::Action::Create,
|
||||
value: U256::from(100),
|
||||
data: Default::default(),
|
||||
gas: U256::from(10),
|
@ -14,17 +14,26 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use client::MiningBlockChainClient;
|
||||
use transaction::SignedTransaction;
|
||||
use types::ids::BlockId;
|
||||
//! A service transactions contract checker.
|
||||
|
||||
use futures::{future, Future};
|
||||
use native_contracts::ServiceTransactionChecker as Contract;
|
||||
use ethereum_types::U256;
|
||||
use ethereum_types::{U256, Address};
|
||||
use parking_lot::Mutex;
|
||||
use transaction::SignedTransaction;
|
||||
use types::ids::BlockId;
|
||||
|
||||
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.
|
||||
#[derive(Default)]
|
||||
pub struct ServiceTransactionChecker {
|
||||
@ -33,10 +42,10 @@ pub struct ServiceTransactionChecker {
|
||||
|
||||
impl ServiceTransactionChecker {
|
||||
/// 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();
|
||||
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| {
|
||||
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.
|
||||
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());
|
||||
|
||||
if let Some(ref contract) = *self.contract.lock() {
|
@ -25,20 +25,21 @@
|
||||
//!
|
||||
//! ```rust
|
||||
//! extern crate ethereum_types;
|
||||
//! extern crate ethcore;
|
||||
//! extern crate ethcore_miner as miner;
|
||||
//! extern crate ethcore_transaction as transaction;
|
||||
//! extern crate ethkey;
|
||||
//! extern crate rustc_hex;
|
||||
//!
|
||||
//! use ethereum_types::{U256, Address};
|
||||
//! use ethkey::{Random, Generator};
|
||||
//! use ethcore::miner::{TransactionQueue, RemovalReason, TransactionQueueDetailsProvider, AccountDetails, TransactionOrigin};
|
||||
//! use ethcore::transaction::*;
|
||||
//! use miner::transaction_queue::{TransactionQueue, TransactionDetailsProvider, AccountDetails, TransactionOrigin, RemovalReason};
|
||||
//! use transaction::*;
|
||||
//! use rustc_hex::FromHex;
|
||||
//!
|
||||
//! #[derive(Default)]
|
||||
//! struct DummyTransactionDetailsProvider;
|
||||
//!
|
||||
//! impl TransactionQueueDetailsProvider for DummyTransactionDetailsProvider {
|
||||
//! impl TransactionDetailsProvider for DummyTransactionDetailsProvider {
|
||||
//! fn fetch_account(&self, _address: &Address) -> AccountDetails {
|
||||
//! AccountDetails {
|
||||
//! 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.
|
||||
//! - Invokes `cull` with latest state nonce for all senders.
|
||||
|
||||
use std::ops::Deref;
|
||||
use std::cmp::Ordering;
|
||||
use std::cmp;
|
||||
use std::collections::{HashSet, HashMap, BTreeSet, BTreeMap};
|
||||
use linked_hash_map::LinkedHashMap;
|
||||
use heapsize::HeapSizeOf;
|
||||
use std::ops::Deref;
|
||||
|
||||
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 transaction::*;
|
||||
use error::{Error, TransactionError};
|
||||
use client::TransactionImportResult;
|
||||
use header::BlockNumber;
|
||||
use miner::local_transactions::{LocalTransactionsList, Status as LocalTransactionStatus};
|
||||
use transaction::{self, SignedTransaction, PendingTransaction};
|
||||
|
||||
type BlockNumber = u64;
|
||||
|
||||
/// Transaction origin
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
@ -281,7 +282,7 @@ struct VerifiedTransaction {
|
||||
/// Transaction origin.
|
||||
origin: TransactionOrigin,
|
||||
/// Delay until specified condition is met.
|
||||
condition: Option<Condition>,
|
||||
condition: Option<transaction::Condition>,
|
||||
/// Insertion time
|
||||
insertion_time: QueuingInstant,
|
||||
/// ID assigned upon insertion, should be unique.
|
||||
@ -292,7 +293,7 @@ impl VerifiedTransaction {
|
||||
fn new(
|
||||
transaction: SignedTransaction,
|
||||
origin: TransactionOrigin,
|
||||
condition: Option<Condition>,
|
||||
condition: Option<transaction::Condition>,
|
||||
insertion_time: QueuingInstant,
|
||||
insertion_id: u64,
|
||||
) -> Self {
|
||||
@ -705,31 +706,28 @@ impl TransactionQueue {
|
||||
tx: SignedTransaction,
|
||||
origin: TransactionOrigin,
|
||||
time: QueuingInstant,
|
||||
condition: Option<Condition>,
|
||||
condition: Option<transaction::Condition>,
|
||||
details_provider: &TransactionDetailsProvider,
|
||||
) -> Result<TransactionImportResult, Error> {
|
||||
) -> Result<transaction::ImportResult, transaction::Error> {
|
||||
if origin == TransactionOrigin::Local {
|
||||
let hash = tx.hash();
|
||||
let cloned_tx = tx.clone();
|
||||
|
||||
let result = self.add_internal(tx, origin, time, condition, details_provider);
|
||||
match result {
|
||||
Ok(TransactionImportResult::Current) => {
|
||||
Ok(transaction::ImportResult::Current) => {
|
||||
self.local_transactions.mark_pending(hash);
|
||||
},
|
||||
Ok(TransactionImportResult::Future) => {
|
||||
Ok(transaction::ImportResult::Future) => {
|
||||
self.local_transactions.mark_future(hash);
|
||||
},
|
||||
Err(Error::Transaction(ref err)) => {
|
||||
Err(ref err) => {
|
||||
// Sometimes transactions are re-imported, so
|
||||
// don't overwrite transactions if they are already on the list
|
||||
if !self.local_transactions.contains(&hash) {
|
||||
self.local_transactions.mark_rejected(cloned_tx, err.clone());
|
||||
}
|
||||
},
|
||||
Err(_) => {
|
||||
self.local_transactions.mark_invalid(cloned_tx);
|
||||
},
|
||||
}
|
||||
result
|
||||
} else {
|
||||
@ -743,9 +741,9 @@ impl TransactionQueue {
|
||||
tx: SignedTransaction,
|
||||
origin: TransactionOrigin,
|
||||
time: QueuingInstant,
|
||||
condition: Option<Condition>,
|
||||
condition: Option<transaction::Condition>,
|
||||
details_provider: &TransactionDetailsProvider,
|
||||
) -> Result<TransactionImportResult, Error> {
|
||||
) -> Result<transaction::ImportResult, transaction::Error> {
|
||||
if origin != TransactionOrigin::Local && tx.gas_price < self.minimal_gas_price {
|
||||
// if it is non-service-transaction => drop
|
||||
let is_service_transaction = tx.gas_price.is_zero();
|
||||
@ -757,10 +755,10 @@ impl TransactionQueue {
|
||||
self.minimal_gas_price
|
||||
);
|
||||
|
||||
return Err(Error::Transaction(TransactionError::InsufficientGasPrice {
|
||||
return Err(transaction::Error::InsufficientGasPrice {
|
||||
minimal: self.minimal_gas_price,
|
||||
got: tx.gas_price,
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
let is_service_transaction_accepted = match details_provider.is_service_transaction_acceptable(&tx) {
|
||||
@ -786,10 +784,10 @@ impl TransactionQueue {
|
||||
};
|
||||
|
||||
if !is_service_transaction_accepted {
|
||||
return Err(Error::Transaction(TransactionError::InsufficientGasPrice {
|
||||
return Err(transaction::Error::InsufficientGasPrice {
|
||||
minimal: self.minimal_gas_price,
|
||||
got: tx.gas_price,
|
||||
}));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -802,10 +800,10 @@ impl TransactionQueue {
|
||||
full_queues_lowest
|
||||
);
|
||||
|
||||
return Err(Error::Transaction(TransactionError::InsufficientGasPrice {
|
||||
return Err(transaction::Error::InsufficientGasPrice {
|
||||
minimal: full_queues_lowest,
|
||||
got: tx.gas_price,
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
let gas_limit = cmp::min(self.tx_gas_limit, self.block_gas_limit);
|
||||
@ -817,10 +815,10 @@ impl TransactionQueue {
|
||||
self.block_gas_limit,
|
||||
self.tx_gas_limit
|
||||
);
|
||||
return Err(Error::Transaction(TransactionError::GasLimitExceeded {
|
||||
return Err(transaction::Error::GasLimitExceeded {
|
||||
limit: gas_limit,
|
||||
got: tx.gas,
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
let minimal_gas = details_provider.estimate_gas_required(&tx);
|
||||
@ -832,10 +830,10 @@ impl TransactionQueue {
|
||||
minimal_gas,
|
||||
);
|
||||
|
||||
return Err(Error::Transaction(TransactionError::InsufficientGas {
|
||||
return Err(transaction::Error::InsufficientGas {
|
||||
minimal: minimal_gas,
|
||||
got: tx.gas,
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
let client_account = details_provider.fetch_account(&tx.sender());
|
||||
@ -848,17 +846,17 @@ impl TransactionQueue {
|
||||
cost
|
||||
);
|
||||
|
||||
return Err(Error::Transaction(TransactionError::InsufficientBalance {
|
||||
return Err(transaction::Error::InsufficientBalance {
|
||||
cost: cost,
|
||||
balance: client_account.balance
|
||||
}));
|
||||
});
|
||||
}
|
||||
tx.check_low_s()?;
|
||||
// No invalid transactions beyond this point.
|
||||
let id = self.next_transaction_id;
|
||||
self.next_transaction_id += 1;
|
||||
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());
|
||||
r
|
||||
}
|
||||
@ -1140,8 +1138,8 @@ impl TransactionQueue {
|
||||
}
|
||||
}
|
||||
let delay = match tx.condition {
|
||||
Some(Condition::Number(n)) => n > best_block,
|
||||
Some(Condition::Timestamp(t)) => t > best_timestamp,
|
||||
Some(transaction::Condition::Number(n)) => n > best_block,
|
||||
Some(transaction::Condition::Timestamp(t)) => t > best_timestamp,
|
||||
None => false,
|
||||
};
|
||||
if delay {
|
||||
@ -1254,12 +1252,13 @@ impl TransactionQueue {
|
||||
/// iff `(address, nonce)` is the same but `gas_price` is higher.
|
||||
///
|
||||
/// 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() {
|
||||
// Transaction is already imported.
|
||||
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);
|
||||
@ -1273,7 +1272,7 @@ impl TransactionQueue {
|
||||
if nonce < state_nonce {
|
||||
// Droping transaction
|
||||
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)
|
||||
@ -1304,7 +1303,7 @@ impl TransactionQueue {
|
||||
|
||||
debug!(target: "txqueue", "Importing transaction to future: {:?}", hash);
|
||||
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
|
||||
@ -1328,7 +1327,7 @@ impl TransactionQueue {
|
||||
|
||||
debug!(target: "txqueue", "Imported transaction to current: {:?}", hash);
|
||||
debug!(target: "txqueue", "status: {:?}", self.status());
|
||||
Ok(TransactionImportResult::Current)
|
||||
Ok(transaction::ImportResult::Current)
|
||||
}
|
||||
|
||||
/// 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 {
|
||||
Ok(())
|
||||
} 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 {
|
||||
Some(ref dropped) => match dropped.get(sender) {
|
||||
Some(min) if nonce >= min => {
|
||||
Err(TransactionError::LimitReached)
|
||||
Err(transaction::Error::LimitReached)
|
||||
},
|
||||
_ => Ok(()),
|
||||
},
|
||||
@ -1438,16 +1438,11 @@ fn check_if_removed(sender: &Address, nonce: &U256, dropped: Option<HashMap<Addr
|
||||
|
||||
#[cfg(test)]
|
||||
pub mod test {
|
||||
use rustc_hex::FromHex;
|
||||
use table::Table;
|
||||
use ethereum_types::{U256, Address};
|
||||
use ethkey::{Random, Generator};
|
||||
use error::{Error, TransactionError};
|
||||
use super::*;
|
||||
use super::{TransactionSet, TransactionOrder, VerifiedTransaction};
|
||||
use miner::local_transactions::LocalTransactionsList;
|
||||
use client::TransactionImportResult;
|
||||
use transaction::{SignedTransaction, Transaction, Action, Condition};
|
||||
use ethkey::{Random, Generator};
|
||||
use rustc_hex::FromHex;
|
||||
use transaction::Transaction;
|
||||
|
||||
pub struct DummyTransactionDetailsProvider {
|
||||
account_details: AccountDetails,
|
||||
@ -1509,11 +1504,8 @@ pub mod test {
|
||||
}
|
||||
}
|
||||
|
||||
fn unwrap_tx_err(err: Result<TransactionImportResult, Error>) -> TransactionError {
|
||||
match err.unwrap_err() {
|
||||
Error::Transaction(e) => e,
|
||||
_ => panic!("Expected transaction error!"),
|
||||
}
|
||||
fn unwrap_tx_err(err: Result<transaction::ImportResult, transaction::Error>) -> transaction::Error {
|
||||
err.unwrap_err()
|
||||
}
|
||||
|
||||
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 {
|
||||
Transaction {
|
||||
action: Action::Create,
|
||||
action: transaction::Action::Create,
|
||||
value: U256::from(100),
|
||||
data: "3331600055".from_hex().unwrap(),
|
||||
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
|
||||
// possible alternative.
|
||||
/*
|
||||
assert_eq!(res.unwrap(), TransactionImportResult::Current);
|
||||
assert_eq!(res.unwrap(), transaction::ImportResult::Current);
|
||||
assert_eq!(txq.status().pending, 2);
|
||||
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(),
|
||||
got: 1.into(),
|
||||
});
|
||||
@ -1785,14 +1777,14 @@ pub mod test {
|
||||
|
||||
// First insert one transaction to future
|
||||
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);
|
||||
|
||||
// now import second transaction to current
|
||||
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)
|
||||
assert_eq!(res.unwrap(), TransactionImportResult::Current);
|
||||
assert_eq!(res.unwrap(), transaction::ImportResult::Current);
|
||||
assert_eq!(txq.status().pending, 1);
|
||||
assert_eq!(txq.status().future, 0);
|
||||
assert_eq!(txq.current.by_priority.len(), 1);
|
||||
@ -1810,14 +1802,14 @@ pub mod test {
|
||||
|
||||
// First insert one transaction to future
|
||||
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);
|
||||
|
||||
// now import second transaction to current
|
||||
let res = txq.add(tx2.clone(), TransactionOrigin::External, 0, None, &default_tx_provider());
|
||||
|
||||
// then
|
||||
assert_eq!(res.unwrap(), TransactionImportResult::Current);
|
||||
assert_eq!(res.unwrap(), transaction::ImportResult::Current);
|
||||
assert_eq!(txq.status().pending, 2);
|
||||
assert_eq!(txq.status().future, 0);
|
||||
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());
|
||||
|
||||
// then
|
||||
assert_eq!(res.unwrap(), TransactionImportResult::Current);
|
||||
assert_eq!(res.unwrap(), transaction::ImportResult::Current);
|
||||
let stats = txq.status();
|
||||
assert_eq!(stats.pending, 1);
|
||||
}
|
||||
@ -1859,13 +1851,13 @@ pub mod test {
|
||||
let res4 = txq.add(tx4, TransactionOrigin::External, 0, None, &default_tx_provider());
|
||||
|
||||
// then
|
||||
assert_eq!(res1.unwrap(), TransactionImportResult::Current);
|
||||
assert_eq!(res2.unwrap(), TransactionImportResult::Current);
|
||||
assert_eq!(unwrap_tx_err(res3), TransactionError::InsufficientGasPrice {
|
||||
assert_eq!(res1.unwrap(), transaction::ImportResult::Current);
|
||||
assert_eq!(res2.unwrap(), transaction::ImportResult::Current);
|
||||
assert_eq!(unwrap_tx_err(res3), transaction::Error::InsufficientGasPrice {
|
||||
minimal: U256::from(15),
|
||||
got: U256::from(10),
|
||||
});
|
||||
assert_eq!(res4.unwrap(), TransactionImportResult::Current);
|
||||
assert_eq!(res4.unwrap(), transaction::ImportResult::Current);
|
||||
let stats = txq.status();
|
||||
assert_eq!(stats.pending, 3);
|
||||
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());
|
||||
|
||||
// then
|
||||
assert_eq!(res1.unwrap(), TransactionImportResult::Current);
|
||||
assert_eq!(res2.unwrap(), TransactionImportResult::Current);
|
||||
assert_eq!(res3.unwrap(), TransactionImportResult::Current);
|
||||
assert_eq!(res4.unwrap(), TransactionImportResult::Current);
|
||||
assert_eq!(res1.unwrap(), transaction::ImportResult::Current);
|
||||
assert_eq!(res2.unwrap(), transaction::ImportResult::Current);
|
||||
assert_eq!(res3.unwrap(), transaction::ImportResult::Current);
|
||||
assert_eq!(res4.unwrap(), transaction::ImportResult::Current);
|
||||
let stats = txq.status();
|
||||
assert_eq!(stats.pending, 4);
|
||||
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());
|
||||
|
||||
// then
|
||||
assert_eq!(unwrap_tx_err(res), TransactionError::GasLimitExceeded {
|
||||
assert_eq!(unwrap_tx_err(res), transaction::Error::GasLimitExceeded {
|
||||
limit: U256::from(50_000),
|
||||
got: gas,
|
||||
});
|
||||
@ -1960,7 +1952,7 @@ pub mod test {
|
||||
let res = txq.add(tx, TransactionOrigin::External, 0, None, &default_tx_provider().with_account(account));
|
||||
|
||||
// then
|
||||
assert_eq!(unwrap_tx_err(res), TransactionError::InsufficientBalance {
|
||||
assert_eq!(unwrap_tx_err(res), transaction::Error::InsufficientBalance {
|
||||
balance: U256::from(1),
|
||||
cost: U256::from(100_100),
|
||||
});
|
||||
@ -1980,7 +1972,7 @@ pub mod test {
|
||||
let res = txq.add(tx, TransactionOrigin::External, 0, None, &default_tx_provider());
|
||||
|
||||
// then
|
||||
assert_eq!(unwrap_tx_err(res), TransactionError::InsufficientGasPrice {
|
||||
assert_eq!(unwrap_tx_err(res), transaction::Error::InsufficientGasPrice {
|
||||
minimal: U256::from(2),
|
||||
got: U256::from(1),
|
||||
});
|
||||
@ -2000,7 +1992,7 @@ pub mod test {
|
||||
let res = txq.add(tx, TransactionOrigin::Local, 0, None, &default_tx_provider());
|
||||
|
||||
// then
|
||||
assert_eq!(res.unwrap(), TransactionImportResult::Current);
|
||||
assert_eq!(res.unwrap(), transaction::ImportResult::Current);
|
||||
let stats = txq.status();
|
||||
assert_eq!(stats.pending, 1);
|
||||
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();
|
||||
|
||||
// then
|
||||
assert_eq!(res1, TransactionImportResult::Current);
|
||||
assert_eq!(res2, TransactionImportResult::Future);
|
||||
assert_eq!(res1, transaction::ImportResult::Current);
|
||||
assert_eq!(res2, transaction::ImportResult::Future);
|
||||
let stats = txq.status();
|
||||
assert_eq!(stats.pending, 1);
|
||||
assert_eq!(stats.future, 1);
|
||||
@ -2253,12 +2245,12 @@ pub mod test {
|
||||
let (tx, tx2) = new_tx_pair_default(1.into(), 0.into());
|
||||
|
||||
// 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();
|
||||
|
||||
// then
|
||||
assert_eq!(res1, TransactionImportResult::Current);
|
||||
assert_eq!(res2, TransactionImportResult::Current);
|
||||
assert_eq!(res1, transaction::ImportResult::Current);
|
||||
assert_eq!(res2, transaction::ImportResult::Current);
|
||||
let top = txq.top_transactions_at(0, 0, None);
|
||||
assert_eq!(top.len(), 0);
|
||||
let top = txq.top_transactions_at(1, 0, None);
|
||||
@ -2396,7 +2388,7 @@ pub mod test {
|
||||
|
||||
// then
|
||||
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!(t.len(), 1);
|
||||
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));
|
||||
|
||||
// then
|
||||
assert_eq!(unwrap_tx_err(res), TransactionError::Old);
|
||||
assert_eq!(unwrap_tx_err(res), transaction::Error::Old);
|
||||
let stats = txq.status();
|
||||
assert_eq!(stats.pending, 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));
|
||||
|
||||
// then
|
||||
assert_eq!(unwrap_tx_err(res), TransactionError::AlreadyImported);
|
||||
assert_eq!(unwrap_tx_err(res), transaction::Error::AlreadyImported);
|
||||
let stats = txq.status();
|
||||
assert_eq!(stats.future, 1);
|
||||
assert_eq!(stats.pending, 0);
|
||||
@ -2548,8 +2540,6 @@ pub mod test {
|
||||
|
||||
#[test]
|
||||
fn should_not_replace_same_transaction_if_the_fee_is_less_than_minimal_bump() {
|
||||
use ethcore_logger::init_log;
|
||||
init_log();
|
||||
// given
|
||||
let mut txq = TransactionQueue::default();
|
||||
let keypair = Random.generate().unwrap();
|
||||
@ -2565,7 +2555,7 @@ pub mod test {
|
||||
let res = txq.add(tx2, TransactionOrigin::External, 0, None, &default_tx_provider());
|
||||
|
||||
// then
|
||||
assert_eq!(unwrap_tx_err(res), TransactionError::TooCheapToReplace);
|
||||
assert_eq!(unwrap_tx_err(res), transaction::Error::TooCheapToReplace);
|
||||
let stats = txq.status();
|
||||
assert_eq!(stats.pending, 1);
|
||||
assert_eq!(stats.future, 0);
|
||||
@ -2574,8 +2564,6 @@ pub mod test {
|
||||
|
||||
#[test]
|
||||
fn should_replace_same_transaction_when_has_higher_fee() {
|
||||
use ethcore_logger::init_log;
|
||||
init_log();
|
||||
// given
|
||||
let mut txq = TransactionQueue::default();
|
||||
let keypair = Random.generate().unwrap();
|
||||
@ -2697,9 +2685,9 @@ pub mod test {
|
||||
|
||||
// when
|
||||
// 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
|
||||
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
|
||||
txq.cull(sender, nonce2 - U256::from(1));
|
||||
// tx2 should be not be promoted to current
|
||||
@ -2718,9 +2706,10 @@ pub mod test {
|
||||
assert_eq!(txq.has_local_pending_transactions(), false);
|
||||
|
||||
// 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.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
|
||||
assert_eq!(txq.has_local_pending_transactions(), true);
|
||||
@ -2740,8 +2729,8 @@ pub mod test {
|
||||
let prev_nonce = default_account_details().nonce - U256::one();
|
||||
|
||||
// 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(tx1.clone(), 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(), transaction::ImportResult::Future);
|
||||
|
||||
// then
|
||||
assert_eq!(txq.future.by_priority.len(), 1);
|
||||
@ -2777,7 +2766,7 @@ pub mod test {
|
||||
|
||||
// then
|
||||
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);
|
||||
}
|
||||
|
||||
@ -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));
|
||||
|
||||
// then
|
||||
assert_eq!(res1.unwrap(), TransactionImportResult::Current);
|
||||
assert_eq!(unwrap_tx_err(res2), TransactionError::InsufficientGas {
|
||||
assert_eq!(res1.unwrap(), transaction::ImportResult::Current);
|
||||
assert_eq!(unwrap_tx_err(res2), transaction::Error::InsufficientGas {
|
||||
minimal: 100_001.into(),
|
||||
got: 100_000.into(),
|
||||
});
|
||||
@ -2872,12 +2861,12 @@ pub mod test {
|
||||
|
||||
// when
|
||||
assert_eq!(unwrap_tx_err(txq.add(tx1, TransactionOrigin::External, 0, None, &default_tx_provider())),
|
||||
TransactionError::InsufficientGasPrice {
|
||||
transaction::Error::InsufficientGasPrice {
|
||||
minimal: 100.into(),
|
||||
got: 0.into(),
|
||||
});
|
||||
assert_eq!(unwrap_tx_err(txq.add(tx2, TransactionOrigin::RetractedBlock, 0, None, &default_tx_provider())),
|
||||
TransactionError::InsufficientGasPrice {
|
||||
transaction::Error::InsufficientGasPrice {
|
||||
minimal: 100.into(),
|
||||
got: 0.into(),
|
||||
});
|
||||
@ -2896,7 +2885,7 @@ pub mod test {
|
||||
// when
|
||||
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)),
|
||||
TransactionError::InsufficientGasPrice {
|
||||
transaction::Error::InsufficientGasPrice {
|
||||
minimal: 100.into(),
|
||||
got: 0.into(),
|
||||
});
|
@ -14,19 +14,22 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// 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;
|
||||
|
||||
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 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 parking_lot::Mutex;
|
||||
use ethereum::ethash::Ethash;
|
||||
|
||||
/// Trait for notifying about new mining work
|
||||
pub trait NotifyWork : Send + Sync {
|
||||
@ -34,6 +37,7 @@ pub trait NotifyWork : Send + Sync {
|
||||
fn notify(&self, pow_hash: H256, difficulty: U256, number: u64);
|
||||
}
|
||||
|
||||
/// POSTs info about new work to given urls.
|
||||
pub struct WorkPoster {
|
||||
urls: Vec<Url>,
|
||||
client: Mutex<Client<PostHandler>>,
|
||||
@ -41,6 +45,7 @@ pub struct WorkPoster {
|
||||
}
|
||||
|
||||
impl WorkPoster {
|
||||
/// Create new `WorkPoster`.
|
||||
pub fn new(urls: &[String]) -> Self {
|
||||
let urls = urls.into_iter().filter_map(|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 {
|
||||
fn notify(&self, pow_hash: H256, difficulty: U256, number: u64) {
|
||||
// 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 = H256::from_slice(&seed_hash[..]);
|
||||
let body = format!(
|
@ -1137,7 +1137,8 @@ mod tests {
|
||||
|
||||
use devtools::{RandomTempPath};
|
||||
use ethcore::client::{VMType, BlockId};
|
||||
use ethcore::miner::{MinerOptions, PrioritizationStrategy};
|
||||
use ethcore::miner::MinerOptions;
|
||||
use miner::transaction_queue::PrioritizationStrategy;
|
||||
use parity_rpc::NetworkSettings;
|
||||
use updater::{UpdatePolicy, UpdateFilter, ReleaseTrack};
|
||||
|
||||
|
@ -17,10 +17,10 @@
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
|
||||
use bytes::Bytes;
|
||||
use dir::default_data_path;
|
||||
use dir::helpers::replace_home;
|
||||
use ethcore::client::{Client, BlockChainClient, BlockId};
|
||||
use ethcore::transaction::{Transaction, Action};
|
||||
use ethsync::LightSync;
|
||||
use futures::{future, IntoFuture, Future};
|
||||
use hash_fetch::fetch::Client as FetchClient;
|
||||
@ -30,8 +30,8 @@ use light::on_demand::{self, OnDemand};
|
||||
use node_health::{SyncStatus, NodeHealth};
|
||||
use rpc;
|
||||
use rpc_apis::SignerService;
|
||||
use transaction::{Transaction, Action};
|
||||
use ethereum_types::Address;
|
||||
use bytes::Bytes;
|
||||
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub struct Configuration {
|
||||
|
@ -22,7 +22,8 @@ use ethereum_types::{U256, clean_0x, Address};
|
||||
use kvdb_rocksdb::CompactionProfile;
|
||||
use journaldb::Algorithm;
|
||||
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 dir::DatabaseDirectories;
|
||||
use dir::helpers::replace_home;
|
||||
|
@ -47,12 +47,14 @@ extern crate time;
|
||||
extern crate toml;
|
||||
|
||||
extern crate ethcore;
|
||||
extern crate ethcore_bytes as bytes;
|
||||
extern crate ethcore_devtools as devtools;
|
||||
extern crate ethcore_io as io;
|
||||
extern crate ethcore_light as light;
|
||||
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_transaction as transaction;
|
||||
extern crate ethereum_types;
|
||||
extern crate migration as migr;
|
||||
extern crate kvdb;
|
||||
|
@ -24,21 +24,22 @@ pub use parity_rpc::dapps::{DappsService, LocalDapp};
|
||||
|
||||
use ethcore::account_provider::AccountProvider;
|
||||
use ethcore::client::Client;
|
||||
use ethcore::miner::{Miner, ExternalMiner};
|
||||
use ethcore::miner::Miner;
|
||||
use ethcore::snapshot::SnapshotService;
|
||||
use ethcore_logger::RotatingLogger;
|
||||
use ethsync::{ManageNetwork, SyncProvider, LightSync};
|
||||
use hash_fetch::fetch::Client as FetchClient;
|
||||
use jsonrpc_core::{self as core, MetaIoHandler};
|
||||
use light::{TransactionQueue as LightTransactionQueue, Cache as LightDataCache};
|
||||
use light::client::LightChainClient;
|
||||
use light::{TransactionQueue as LightTransactionQueue, Cache as LightDataCache};
|
||||
use miner::external::ExternalMiner;
|
||||
use node_health::NodeHealth;
|
||||
use parity_reactor;
|
||||
use parity_rpc::dispatch::{FullDispatcher, LightDispatcher};
|
||||
use parity_rpc::informant::{ActivityNotifier, ClientNotifier};
|
||||
use parity_rpc::{Metadata, NetworkSettings, Host};
|
||||
use updater::Updater;
|
||||
use parking_lot::{Mutex, RwLock};
|
||||
use updater::Updater;
|
||||
|
||||
#[derive(Debug, PartialEq, Clone, Eq, Hash)]
|
||||
pub enum Api {
|
||||
|
@ -18,31 +18,32 @@ use std::fmt;
|
||||
use std::sync::{Arc, Weak};
|
||||
use std::net::{TcpListener};
|
||||
|
||||
use ansi_term::Colour;
|
||||
use ctrlc::CtrlC;
|
||||
use ethcore_logger::{Config as LogConfig, RotatingLogger};
|
||||
use ethcore::account_provider::{AccountProvider, AccountProviderSettings};
|
||||
use ethcore::client::{Client, Mode, DatabaseCompactionProfile, VMType, BlockChainClient};
|
||||
use ethcore::ethstore::ethkey;
|
||||
use ethcore::miner::{Miner, MinerService, ExternalMiner, MinerOptions};
|
||||
use ethcore::miner::{Miner, MinerService, MinerOptions};
|
||||
use ethcore::miner::{StratumOptions, Stratum};
|
||||
use ethcore::service::ClientService;
|
||||
use ethcore::snapshot;
|
||||
use ethcore::spec::{SpecParams, OptimizeFor};
|
||||
use ethcore::verification::queue::VerifierSettings;
|
||||
use ethcore_logger::{Config as LogConfig, RotatingLogger};
|
||||
use ethsync::{self, SyncConfig};
|
||||
use fdlimit::raise_fd_limit;
|
||||
use hash_fetch::fetch::{Fetch, Client as FetchClient};
|
||||
use informant::{Informant, LightNodeInformantData, FullNodeInformantData};
|
||||
use journaldb::Algorithm;
|
||||
use light::Cache as LightDataCache;
|
||||
use miner::external::ExternalMiner;
|
||||
use node_filter::NodeFilter;
|
||||
use node_health;
|
||||
use parity_reactor::EventLoop;
|
||||
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 node_filter::NodeFilter;
|
||||
use journaldb::Algorithm;
|
||||
use updater::{UpdatePolicy, Updater};
|
||||
use parity_version::version;
|
||||
|
||||
use params::{
|
||||
SpecType, Pruning, AccountsConfig, GasPricerConfig, MinerExtras, Switch,
|
||||
@ -156,7 +157,7 @@ struct 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() {
|
||||
Some(m) => m,
|
||||
None => return Vec::new(),
|
||||
|
@ -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-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" }
|
||||
ethsync = { path = "../sync" }
|
||||
ethjson = { path = "../json" }
|
||||
ethcore = { path = "../ethcore" }
|
||||
ethcore-bytes = { path = "../util/bytes" }
|
||||
ethcore-devtools = { path = "../devtools" }
|
||||
ethcore-io = { path = "../util/io" }
|
||||
ethcore-light = { path = "../ethcore/light" }
|
||||
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" }
|
||||
hardware-wallet = { path = "../hw" }
|
||||
keccak-hash = { path = "../util/hash" }
|
||||
node-health = { path = "../dapps/node-health" }
|
||||
parity-reactor = { path = "../util/reactor" }
|
||||
parity-updater = { path = "../updater" }
|
||||
@ -57,8 +62,6 @@ parity-version = { path = "../util/version" }
|
||||
rlp = { path = "../util/rlp" }
|
||||
stats = { path = "../util/stats" }
|
||||
vm = { path = "../ethcore/vm" }
|
||||
keccak-hash = { path = "../util/hash" }
|
||||
hardware-wallet = { path = "../hw" }
|
||||
|
||||
[dev-dependencies]
|
||||
pretty_assertions = "0.1"
|
||||
|
@ -50,6 +50,8 @@ extern crate ethcore_bytes as bytes;
|
||||
extern crate ethcore_devtools as devtools;
|
||||
extern crate ethcore_io as io;
|
||||
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 ethereum_types;
|
||||
extern crate ethkey;
|
||||
|
@ -36,9 +36,9 @@ use ethsync::LightSync;
|
||||
use ethcore::ids::BlockId;
|
||||
use ethcore::miner::MinerService;
|
||||
use ethcore::client::MiningBlockChainClient;
|
||||
use ethcore::transaction::{Action, SignedTransaction, PendingTransaction, Transaction};
|
||||
use ethcore::account_provider::AccountProvider;
|
||||
use crypto::DEFAULT_MAC;
|
||||
use transaction::{Action, SignedTransaction, PendingTransaction, Transaction};
|
||||
|
||||
use jsonrpc_core::{BoxFuture, Result, Error};
|
||||
use jsonrpc_core::futures::{future, Future, Poll, Async};
|
||||
@ -411,7 +411,6 @@ impl Dispatcher for LightDispatcher {
|
||||
let hash = signed_transaction.transaction.hash();
|
||||
|
||||
self.transaction_queue.write().import(signed_transaction)
|
||||
.map_err(Into::into)
|
||||
.map_err(errors::transaction)
|
||||
.map(|_| hash)
|
||||
}
|
||||
|
@ -17,10 +17,12 @@
|
||||
//! RPC Error codes and error objects
|
||||
|
||||
use std::fmt;
|
||||
use rlp::DecoderError;
|
||||
use ethcore::error::{Error as EthcoreError, CallError, TransactionError};
|
||||
|
||||
use ethcore::account_provider::{SignError as AccountError};
|
||||
use ethcore::error::{Error as EthcoreError, CallError};
|
||||
use jsonrpc_core::{futures, Error, ErrorCode, Value};
|
||||
use rlp::DecoderError;
|
||||
use transaction::Error as TransactionError;
|
||||
|
||||
mod codes {
|
||||
// NOTE [ToDr] Codes from [-32099, -32000]
|
||||
@ -287,7 +289,7 @@ pub fn password(error: AccountError) -> Error {
|
||||
}
|
||||
|
||||
pub fn transaction_message(error: TransactionError) -> String {
|
||||
use ethcore::error::TransactionError::*;
|
||||
use self::TransactionError::*;
|
||||
|
||||
match error {
|
||||
AlreadyImported => "Transaction with the same hash was already imported.".into(),
|
||||
@ -310,6 +312,7 @@ pub fn transaction_message(error: TransactionError) -> String {
|
||||
GasLimitExceeded { 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(),
|
||||
InvalidGasLimit(_) => "Supplied gas is beyond limit.".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 {
|
||||
Error {
|
||||
code: ErrorCode::ServerError(codes::TRANSACTION_ERROR),
|
||||
|
@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// 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 jsonrpc_core::Error;
|
||||
|
@ -23,7 +23,6 @@ use ethcore::encoded;
|
||||
use ethcore::executed::{Executed, ExecutionError};
|
||||
use ethcore::ids::BlockId;
|
||||
use ethcore::filter::Filter as EthcoreFilter;
|
||||
use ethcore::transaction::{Action, Transaction as EthTransaction, SignedTransaction, LocalizedTransaction};
|
||||
use ethcore::receipt::Receipt;
|
||||
|
||||
use jsonrpc_core::{BoxFuture, Result};
|
||||
@ -41,6 +40,7 @@ use ethsync::LightSync;
|
||||
use ethereum_types::{U256, Address};
|
||||
use hash::H256;
|
||||
use parking_lot::Mutex;
|
||||
use transaction::{Action, Transaction as EthTransaction, SignedTransaction, LocalizedTransaction};
|
||||
|
||||
use v1::helpers::{CallRequest as CallRequestHelper, errors, dispatch};
|
||||
use v1::types::{BlockNumber, CallRequest, Log, Transaction};
|
||||
|
@ -33,10 +33,11 @@ use ethcore::ethereum::Ethash;
|
||||
use ethcore::filter::Filter as EthcoreFilter;
|
||||
use ethcore::header::{Header as BlockHeader, BlockNumber as EthBlockNumber};
|
||||
use ethcore::log_entry::LogEntry;
|
||||
use ethcore::miner::{MinerService, ExternalMinerService};
|
||||
use ethcore::transaction::SignedTransaction;
|
||||
use ethcore::miner::MinerService;
|
||||
use ethcore::snapshot::SnapshotService;
|
||||
use ethsync::{SyncProvider};
|
||||
use miner::external::ExternalMinerService;
|
||||
use transaction::SignedTransaction;
|
||||
|
||||
use jsonrpc_core::{BoxFuture, Result};
|
||||
use jsonrpc_core::futures::future;
|
||||
|
@ -30,14 +30,14 @@ use light::on_demand::{request, OnDemand};
|
||||
|
||||
use ethcore::account_provider::{AccountProvider, DappId};
|
||||
use ethcore::encoded;
|
||||
use ethcore::ids::BlockId;
|
||||
use ethcore::filter::Filter as EthcoreFilter;
|
||||
use ethcore::transaction::SignedTransaction;
|
||||
use ethcore::ids::BlockId;
|
||||
use ethsync::LightSync;
|
||||
use rlp::UntrustedRlp;
|
||||
use hash::{KECCAK_NULL_RLP, KECCAK_EMPTY_LIST_RLP};
|
||||
use ethereum_types::U256;
|
||||
use parking_lot::{RwLock, Mutex};
|
||||
use rlp::UntrustedRlp;
|
||||
use transaction::SignedTransaction;
|
||||
|
||||
use v1::impls::eth_filter::Filterable;
|
||||
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())
|
||||
.map(|_| hash)
|
||||
.map_err(Into::into)
|
||||
.map_err(errors::transaction)
|
||||
})
|
||||
.map(Into::into)
|
||||
|
@ -17,12 +17,12 @@
|
||||
//! Account management (personal) rpc implementation
|
||||
use std::sync::Arc;
|
||||
|
||||
use ethcore::account_provider::AccountProvider;
|
||||
use ethcore::transaction::PendingTransaction;
|
||||
|
||||
use bytes::{Bytes, ToPretty};
|
||||
use ethcore::account_provider::AccountProvider;
|
||||
use transaction::PendingTransaction;
|
||||
use ethereum_types::{H520, U128, Address};
|
||||
use ethkey::{public_to_address, recover, Signature};
|
||||
|
||||
use jsonrpc_core::{BoxFuture, Result};
|
||||
use jsonrpc_core::futures::{future, Future};
|
||||
use v1::helpers::errors;
|
||||
|
@ -19,11 +19,11 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use ethcore::account_provider::AccountProvider;
|
||||
use ethcore::transaction::{SignedTransaction, PendingTransaction};
|
||||
use ethkey;
|
||||
use parity_reactor::Remote;
|
||||
use rlp::UntrustedRlp;
|
||||
use parking_lot::Mutex;
|
||||
use rlp::UntrustedRlp;
|
||||
use transaction::{SignedTransaction, PendingTransaction};
|
||||
|
||||
use jsonrpc_core::{Result, BoxFuture, Error};
|
||||
use jsonrpc_core::futures::{future, Future, IntoFuture};
|
||||
|
@ -19,8 +19,8 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use ethcore::client::{MiningBlockChainClient, CallAnalytics, TransactionId, TraceId};
|
||||
use ethcore::transaction::SignedTransaction;
|
||||
use rlp::UntrustedRlp;
|
||||
use transaction::SignedTransaction;
|
||||
|
||||
use jsonrpc_core::Result;
|
||||
use jsonrpc_macros::Trailing;
|
||||
|
@ -25,13 +25,15 @@ use ethcore::block::Block;
|
||||
use ethcore::client::{BlockChainClient, Client, ClientConfig};
|
||||
use ethcore::ethereum;
|
||||
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::views::BlockView;
|
||||
use ethjson::blockchain::BlockChain;
|
||||
use ethjson::state::test::ForkSpec;
|
||||
use io::IoChannel;
|
||||
use kvdb_memorydb;
|
||||
use miner::external::ExternalMiner;
|
||||
use miner::transaction_queue::PrioritizationStrategy;
|
||||
use parking_lot::Mutex;
|
||||
|
||||
use jsonrpc_core::IoHandler;
|
||||
|
@ -20,15 +20,16 @@ use std::collections::{BTreeMap, HashMap};
|
||||
use std::collections::hash_map::Entry;
|
||||
use ethereum_types::{H256, U256, Address};
|
||||
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::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.
|
||||
pub struct TestMinerService {
|
||||
|
@ -18,20 +18,21 @@ use std::str::FromStr;
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
use std::time::{Instant, Duration};
|
||||
use rustc_hex::{FromHex, ToHex};
|
||||
use time::get_time;
|
||||
use rlp;
|
||||
|
||||
use ethereum_types::{H256, U256, Address};
|
||||
use parking_lot::Mutex;
|
||||
use ethkey::Secret;
|
||||
use ethcore::account_provider::AccountProvider;
|
||||
use ethcore::client::{TestBlockChainClient, EachBlockWith, Executed, TransactionId};
|
||||
use ethcore::log_entry::{LocalizedLogEntry, LogEntry};
|
||||
use ethcore::miner::MinerService;
|
||||
use ethcore::receipt::{LocalizedReceipt, TransactionOutcome};
|
||||
use ethcore::transaction::{Transaction, Action};
|
||||
use ethcore::miner::{ExternalMiner, MinerService};
|
||||
use ethkey::Secret;
|
||||
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 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() {
|
||||
use ethereum_types::H256;
|
||||
use rlp;
|
||||
use ethcore::transaction::SignedTransaction;
|
||||
use transaction::SignedTransaction;
|
||||
|
||||
let tester = EthTester::default();
|
||||
{
|
||||
|
@ -212,7 +212,7 @@ fn rpc_parity_set_hash_content() {
|
||||
|
||||
#[test]
|
||||
fn rpc_parity_remove_transaction() {
|
||||
use ethcore::transaction::{Transaction, Action};
|
||||
use transaction::{Transaction, Action};
|
||||
|
||||
let miner = miner_service();
|
||||
let client = client_service();
|
||||
|
@ -21,9 +21,9 @@ use bytes::ToPretty;
|
||||
use ethereum_types::{U256, Address};
|
||||
use ethcore::account_provider::AccountProvider;
|
||||
use ethcore::client::TestBlockChainClient;
|
||||
use ethcore::transaction::{Action, Transaction};
|
||||
use jsonrpc_core::IoHandler;
|
||||
use parking_lot::Mutex;
|
||||
use transaction::{Action, Transaction};
|
||||
|
||||
use v1::{PersonalClient, Personal, Metadata};
|
||||
use v1::helpers::nonce;
|
||||
|
@ -21,10 +21,10 @@ use bytes::ToPretty;
|
||||
|
||||
use ethcore::account_provider::AccountProvider;
|
||||
use ethcore::client::TestBlockChainClient;
|
||||
use ethcore::transaction::{Transaction, Action, SignedTransaction};
|
||||
use parity_reactor::EventLoop;
|
||||
use parking_lot::Mutex;
|
||||
use rlp::encode;
|
||||
use transaction::{Transaction, Action, SignedTransaction};
|
||||
|
||||
use serde_json;
|
||||
use jsonrpc_core::IoHandler;
|
||||
|
@ -32,13 +32,13 @@ use v1::tests::mocked::parity;
|
||||
|
||||
use ethereum_types::{U256, Address};
|
||||
use bytes::ToPretty;
|
||||
use ethkey::Secret;
|
||||
use ethcore::account_provider::AccountProvider;
|
||||
use ethcore::client::TestBlockChainClient;
|
||||
use ethcore::transaction::{Transaction, Action, SignedTransaction};
|
||||
use ethkey::Secret;
|
||||
use ethstore::ethkey::{Generator, Random};
|
||||
use serde_json;
|
||||
use parking_lot::Mutex;
|
||||
use serde_json;
|
||||
use transaction::{Transaction, Action, SignedTransaction};
|
||||
|
||||
use parity_reactor::Remote;
|
||||
|
||||
|
@ -18,7 +18,7 @@ use serde::{Serialize, Serializer};
|
||||
use serde::ser::SerializeStruct;
|
||||
use ethcore::miner;
|
||||
use ethcore::{contract_address, CreateContractAddress};
|
||||
use ethcore::transaction::{LocalizedTransaction, Action, PendingTransaction, SignedTransaction};
|
||||
use transaction::{LocalizedTransaction, Action, PendingTransaction, SignedTransaction};
|
||||
use v1::helpers::errors;
|
||||
use v1::types::{Bytes, H160, H256, U256, H512, U64, TransactionCondition};
|
||||
|
||||
|
@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use ethcore;
|
||||
use transaction;
|
||||
|
||||
/// Represents condition on minimum block number or block timestamp.
|
||||
#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)]
|
||||
@ -28,27 +28,26 @@ pub enum TransactionCondition {
|
||||
Timestamp(u64),
|
||||
}
|
||||
|
||||
impl Into<ethcore::transaction::Condition> for TransactionCondition {
|
||||
fn into(self) -> ethcore::transaction::Condition {
|
||||
impl Into<transaction::Condition> for TransactionCondition {
|
||||
fn into(self) -> transaction::Condition {
|
||||
match self {
|
||||
TransactionCondition::Number(n) => ethcore::transaction::Condition::Number(n),
|
||||
TransactionCondition::Timestamp(n) => ethcore::transaction::Condition::Timestamp(n),
|
||||
TransactionCondition::Number(n) => transaction::Condition::Number(n),
|
||||
TransactionCondition::Timestamp(n) => transaction::Condition::Timestamp(n),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ethcore::transaction::Condition> for TransactionCondition {
|
||||
fn from(condition: ethcore::transaction::Condition) -> Self {
|
||||
impl From<transaction::Condition> for TransactionCondition {
|
||||
fn from(condition: transaction::Condition) -> Self {
|
||||
match condition {
|
||||
ethcore::transaction::Condition::Number(n) => TransactionCondition::Number(n),
|
||||
ethcore::transaction::Condition::Timestamp(n) => TransactionCondition::Timestamp(n),
|
||||
transaction::Condition::Number(n) => TransactionCondition::Number(n),
|
||||
transaction::Condition::Timestamp(n) => TransactionCondition::Timestamp(n),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use ethcore;
|
||||
use super::*;
|
||||
use serde_json;
|
||||
|
||||
@ -61,8 +60,8 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn condition_into() {
|
||||
assert_eq!(ethcore::transaction::Condition::Number(100), TransactionCondition::Number(100).into());
|
||||
assert_eq!(ethcore::transaction::Condition::Timestamp(100), TransactionCondition::Timestamp(100).into());
|
||||
assert_eq!(transaction::Condition::Number(100), TransactionCondition::Number(100).into());
|
||||
assert_eq!(transaction::Condition::Timestamp(100), TransactionCondition::Timestamp(100).into());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,8 @@ authors = ["Parity Technologies <admin@parity.io>"]
|
||||
ethcore-bytes = { path = "../util/bytes" }
|
||||
ethcore-network = { path = "../util/network" }
|
||||
ethcore-io = { path = "../util/io" }
|
||||
ethcore-light = { path = "../ethcore/light"}
|
||||
ethcore-light = { path = "../ethcore/light" }
|
||||
ethcore-transaction = { path = "../ethcore/transaction" }
|
||||
ethcore = { path = "../ethcore" }
|
||||
ethereum-types = "0.1"
|
||||
plain_hasher = { path = "../util/plain_hasher" }
|
||||
|
@ -440,7 +440,7 @@ impl ChainNotify for EthSync {
|
||||
struct TxRelay(Arc<BlockChainClient>);
|
||||
|
||||
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());
|
||||
self.0.queue_transactions(relay.iter().map(|tx| ::rlp::encode(tx).into_vec()).collect(), ctx.peer())
|
||||
}
|
||||
|
@ -102,7 +102,7 @@ use ethcore::header::{BlockNumber, Header as BlockHeader};
|
||||
use ethcore::client::{BlockChainClient, BlockStatus, BlockId, BlockChainInfo, BlockImportError, BlockQueueInfo};
|
||||
use ethcore::error::*;
|
||||
use ethcore::snapshot::{ManifestData, RestorationStatus};
|
||||
use ethcore::transaction::PendingTransaction;
|
||||
use transaction::PendingTransaction;
|
||||
use sync_io::SyncIo;
|
||||
use time;
|
||||
use super::SyncConfig;
|
||||
@ -2233,8 +2233,8 @@ mod tests {
|
||||
use super::{PeerInfo, PeerAsking};
|
||||
use ethcore::header::*;
|
||||
use ethcore::client::{BlockChainClient, EachBlockWith, TestBlockChainClient};
|
||||
use ethcore::transaction::UnverifiedTransaction;
|
||||
use ethcore::miner::MinerService;
|
||||
use transaction::UnverifiedTransaction;
|
||||
|
||||
fn get_dummy_block(order: u32, parent_hash: H256) -> Bytes {
|
||||
let mut header = Header::new();
|
||||
|
@ -24,6 +24,7 @@
|
||||
extern crate ethcore_network as network;
|
||||
extern crate ethcore_bytes as bytes;
|
||||
extern crate ethcore_io as io;
|
||||
extern crate ethcore_transaction as transaction;
|
||||
extern crate ethcore;
|
||||
extern crate ethereum_types;
|
||||
extern crate env_logger;
|
||||
|
@ -22,9 +22,9 @@ use ethcore::client::{BlockChainClient, Client};
|
||||
use ethcore::service::ClientIoMessage;
|
||||
use ethcore::spec::Spec;
|
||||
use ethcore::miner::MinerService;
|
||||
use ethcore::transaction::*;
|
||||
use ethcore::account_provider::AccountProvider;
|
||||
use ethkey::{KeyPair, Secret};
|
||||
use transaction::{Action, PendingTransaction, Transaction};
|
||||
use super::helpers::*;
|
||||
use SyncConfig;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user