diff --git a/Cargo.lock b/Cargo.lock index aecd84a2d..39aed230f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -274,7 +274,6 @@ name = "ethcore-ipc-codegen" version = "1.1.0" dependencies = [ "aster 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "ethcore-ipc 1.1.0", "quasi 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "quasi_codegen 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "syntex 0.31.0 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/miner/src/lib.rs b/miner/src/lib.rs index 9ba2cdc1c..1b080f30c 100644 --- a/miner/src/lib.rs +++ b/miner/src/lib.rs @@ -101,7 +101,13 @@ pub trait MinerService : Send + Sync { fn set_gas_floor_target(&self, target: U256); /// Imports transactions to transaction queue. - fn import_transactions(&self, transactions: Vec, fetch_account: T) -> Vec> + fn import_transactions(&self, transactions: Vec, fetch_account: T) -> + Vec> + where T: Fn(&Address) -> AccountDetails; + + /// Imports own (node owner) transaction to queue. + fn import_own_transaction(&self, transaction: SignedTransaction, fetch_account: T) -> + Result where T: Fn(&Address) -> AccountDetails; /// Returns hashes of transactions currently in pending @@ -139,7 +145,17 @@ pub trait MinerService : Send + Sync { fn sensible_gas_limit(&self) -> U256 { x!(21000) } } +/// Represents the result of importing transaction. +#[derive(Debug)] +pub enum TransactionImportResult { + /// Transaction was imported to current queue. + Current, + /// Transaction was imported to future queue. + Future +} + /// Mining status +#[derive(Debug)] pub struct MinerStatus { /// Number of transactions in queue with state `pending` (ready to be included in block) pub transactions_in_pending_queue: usize, diff --git a/miner/src/miner.rs b/miner/src/miner.rs index af89a7345..29055713d 100644 --- a/miner/src/miner.rs +++ b/miner/src/miner.rs @@ -23,7 +23,7 @@ use ethcore::client::{BlockChainClient, BlockId}; use ethcore::block::{ClosedBlock, IsBlock}; use ethcore::error::*; use ethcore::transaction::SignedTransaction; -use super::{MinerService, MinerStatus, TransactionQueue, AccountDetails}; +use super::{MinerService, MinerStatus, TransactionQueue, AccountDetails, TransactionImportResult}; /// Keeps track of transactions using priority queue and holds currently mined block. pub struct Miner { @@ -220,12 +220,20 @@ impl MinerService for Miner { *self.gas_floor_target.read().unwrap() } - fn import_transactions(&self, transactions: Vec, fetch_account: T) -> Vec> + fn import_transactions(&self, transactions: Vec, fetch_account: T) -> + Vec> where T: Fn(&Address) -> AccountDetails { let mut transaction_queue = self.transaction_queue.lock().unwrap(); transaction_queue.add_all(transactions, fetch_account) } + fn import_own_transaction(&self, transaction: SignedTransaction, fetch_account: T) -> + Result + where T: Fn(&Address) -> AccountDetails { + let mut transaction_queue = self.transaction_queue.lock().unwrap(); + transaction_queue.add(transaction, &fetch_account) + } + fn pending_transactions_hashes(&self) -> Vec { let transaction_queue = self.transaction_queue.lock().unwrap(); transaction_queue.pending_hashes() diff --git a/miner/src/transaction_queue.rs b/miner/src/transaction_queue.rs index 95f2056b5..bd017fd69 100644 --- a/miner/src/transaction_queue.rs +++ b/miner/src/transaction_queue.rs @@ -92,6 +92,7 @@ use util::hash::{Address, H256}; use util::table::*; use ethcore::transaction::*; use ethcore::error::{Error, TransactionError}; +use super::TransactionImportResult; #[derive(Clone, Debug)] @@ -346,7 +347,7 @@ impl TransactionQueue { } /// Adds all signed transactions to queue to be verified and imported - pub fn add_all(&mut self, txs: Vec, fetch_account: T) -> Vec> + pub fn add_all(&mut self, txs: Vec, fetch_account: T) -> Vec> where T: Fn(&Address) -> AccountDetails { txs.into_iter() @@ -355,7 +356,7 @@ impl TransactionQueue { } /// Add signed transaction to queue to be verified and imported - pub fn add(&mut self, tx: SignedTransaction, fetch_account: &T) -> Result<(), Error> + pub fn add(&mut self, tx: SignedTransaction, fetch_account: &T) -> Result where T: Fn(&Address) -> AccountDetails { trace!(target: "miner", "Importing: {:?}", tx.hash()); @@ -568,7 +569,7 @@ 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<(), TransactionError> { + fn import_tx(&mut self, tx: VerifiedTransaction, state_nonce: U256) -> Result { if self.by_hash.get(&tx.hash()).is_some() { // Transaction is already imported. @@ -590,7 +591,7 @@ impl TransactionQueue { // We have a gap - put to future Self::replace_transaction(tx, next_nonce, &mut self.future, &mut self.by_hash); self.future.enforce_limit(&mut self.by_hash); - return Ok(()); + return Ok(TransactionImportResult::Future); } else if nonce < state_nonce { // Droping transaction trace!(target: "miner", "Dropping old transaction: {:?} (nonce: {} < {})", tx.hash(), nonce, next_nonce); @@ -615,7 +616,7 @@ impl TransactionQueue { self.current.enforce_limit(&mut self.by_hash); trace!(target: "miner", "status: {:?}", self.status()); - Ok(()) + Ok(TransactionImportResult::Current) } /// Replaces transaction in given set (could be `future` or `current`). diff --git a/rpc/src/v1/impls/eth.rs b/rpc/src/v1/impls/eth.rs index 5a7f93e17..26cf3ef4d 100644 --- a/rpc/src/v1/impls/eth.rs +++ b/rpc/src/v1/impls/eth.rs @@ -182,24 +182,30 @@ impl EthClient fn dispatch_transaction(&self, signed_transaction: SignedTransaction) -> Result { let hash = signed_transaction.hash(); - let import = { + let (import, status) = { let client = take_weak!(self.client); let miner = take_weak!(self.miner); - miner.import_transactions(vec![signed_transaction], |a: &Address| { + let import = miner.import_own_transaction(signed_transaction, |a: &Address| { AccountDetails { nonce: client.nonce(&a), balance: client.balance(&a), } - }) + }); + let status_after = miner.status(); + (import, status_after) }; - match import.into_iter().collect::, _>>() { - Ok(_) => { + match import { + Ok(res) => { + trace!(target: "tx", "Imported transaction to {:?} (hash: {:?})", res, hash); + trace!(target: "tx", "Status: {:?}", status); to_value(&hash) } Err(e) => { warn!("Error sending transaction: {:?}", e); + trace!(target: "tx", "Failed to import transaction {:?} (hash: {:?})", e, hash); + trace!(target: "tx", "Status: {:?}", status); to_value(&H256::zero()) } } diff --git a/rpc/src/v1/tests/helpers/miner_service.rs b/rpc/src/v1/tests/helpers/miner_service.rs index b2e546b2b..927b8ed50 100644 --- a/rpc/src/v1/tests/helpers/miner_service.rs +++ b/rpc/src/v1/tests/helpers/miner_service.rs @@ -22,7 +22,7 @@ use ethcore::error::Error; use ethcore::client::BlockChainClient; use ethcore::block::ClosedBlock; use ethcore::transaction::SignedTransaction; -use ethminer::{MinerService, MinerStatus, AccountDetails}; +use ethminer::{MinerService, MinerStatus, AccountDetails, TransactionImportResult}; /// Test miner service. pub struct TestMinerService { @@ -101,17 +101,28 @@ impl MinerService for TestMinerService { } /// Imports transactions to transaction queue. - fn import_transactions(&self, transactions: Vec, _fetch_account: T) -> Vec> + fn import_transactions(&self, transactions: Vec, _fetch_account: T) -> + Vec> where T: Fn(&Address) -> AccountDetails { // lets assume that all txs are valid self.imported_transactions.lock().unwrap().extend_from_slice(&transactions); transactions .iter() - .map(|_| Ok(())) + .map(|_| Ok(TransactionImportResult::Current)) .collect() } + /// Imports transactions to transaction queue. + fn import_own_transaction(&self, transaction: SignedTransaction, _fetch_account: T) -> + Result + where T: Fn(&Address) -> AccountDetails { + // lets assume that all txs are valid + self.imported_transactions.lock().unwrap().push(transaction); + + Ok(TransactionImportResult::Current) + } + /// Returns hashes of transactions currently in pending fn pending_transactions_hashes(&self) -> Vec { vec![]