Merge pull request #968 from ethcore/tx-tracing

Additional logging for transactions
This commit is contained in:
Arkadiy Paronyan 2016-04-18 10:41:30 +02:00
commit 5b8ca74d65
6 changed files with 65 additions and 17 deletions

1
Cargo.lock generated
View File

@ -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)",

View File

@ -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<T>(&self, transactions: Vec<SignedTransaction>, fetch_account: T) -> Vec<Result<(), Error>>
fn import_transactions<T>(&self, transactions: Vec<SignedTransaction>, fetch_account: T) ->
Vec<Result<TransactionImportResult, Error>>
where T: Fn(&Address) -> AccountDetails;
/// Imports own (node owner) transaction to queue.
fn import_own_transaction<T>(&self, transaction: SignedTransaction, fetch_account: T) ->
Result<TransactionImportResult, Error>
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,

View File

@ -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,35 @@ impl MinerService for Miner {
*self.gas_floor_target.read().unwrap()
}
fn import_transactions<T>(&self, transactions: Vec<SignedTransaction>, fetch_account: T) -> Vec<Result<(), Error>>
fn import_transactions<T>(&self, transactions: Vec<SignedTransaction>, fetch_account: T) ->
Vec<Result<TransactionImportResult, Error>>
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<T>(&self, transaction: SignedTransaction, fetch_account: T) ->
Result<TransactionImportResult, Error>
where T: Fn(&Address) -> AccountDetails {
let hash = transaction.hash();
trace!(target: "own_tx", "Importing transaction: {:?}", transaction);
let mut transaction_queue = self.transaction_queue.lock().unwrap();
let import = transaction_queue.add(transaction, &fetch_account);
match import {
Ok(ref res) => {
trace!(target: "own_tx", "Imported transaction to {:?} (hash: {:?})", res, hash);
trace!(target: "own_tx", "Status: {:?}", self.status());
},
Err(ref e) => {
trace!(target: "own_tx", "Failed to import transaction {:?} (hash: {:?})", e, hash);
trace!(target: "own_tx", "Status: {:?}", self.status());
},
}
import
}
fn pending_transactions_hashes(&self) -> Vec<H256> {
let transaction_queue = self.transaction_queue.lock().unwrap();
transaction_queue.pending_hashes()

View File

@ -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<T>(&mut self, txs: Vec<SignedTransaction>, fetch_account: T) -> Vec<Result<(), Error>>
pub fn add_all<T>(&mut self, txs: Vec<SignedTransaction>, fetch_account: T) -> Vec<Result<TransactionImportResult, Error>>
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<T>(&mut self, tx: SignedTransaction, fetch_account: &T) -> Result<(), Error>
pub fn add<T>(&mut self, tx: SignedTransaction, fetch_account: &T) -> Result<TransactionImportResult, Error>
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<TransactionImportResult, TransactionError> {
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`).

View File

@ -186,7 +186,7 @@ impl<C, S, A, M, EM> EthClient<C, S, A, M, EM>
let client = take_weak!(self.client);
let miner = take_weak!(self.miner);
miner.import_transactions(vec![signed_transaction], |a: &Address| {
miner.import_own_transaction(signed_transaction, |a: &Address| {
AccountDetails {
nonce: client.nonce(&a),
balance: client.balance(&a),
@ -194,10 +194,8 @@ impl<C, S, A, M, EM> EthClient<C, S, A, M, EM>
})
};
match import.into_iter().collect::<Result<Vec<_>, _>>() {
Ok(_) => {
to_value(&hash)
}
match import {
Ok(_) => to_value(&hash),
Err(e) => {
warn!("Error sending transaction: {:?}", e);
to_value(&H256::zero())

View File

@ -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<T>(&self, transactions: Vec<SignedTransaction>, _fetch_account: T) -> Vec<Result<(), Error>>
fn import_transactions<T>(&self, transactions: Vec<SignedTransaction>, _fetch_account: T) ->
Vec<Result<TransactionImportResult, Error>>
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<T>(&self, transaction: SignedTransaction, _fetch_account: T) ->
Result<TransactionImportResult, Error>
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<H256> {
vec![]