From 04082d15149db9b5c9d85d7d540c63ea151e6056 Mon Sep 17 00:00:00 2001 From: debris Date: Sun, 20 Mar 2016 18:44:57 +0100 Subject: [PATCH] client implementation of transaction receipt --- ethcore/src/client/client.rs | 40 +++++++++++++++++++++++++++---- ethcore/src/client/mod.rs | 4 ++-- ethcore/src/client/test_client.rs | 4 ++-- ethcore/src/log_entry.rs | 3 ++- rpc/src/v1/impls/eth.rs | 11 +++++---- 5 files changed, 49 insertions(+), 13 deletions(-) diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index 551a714ba..9737fc982 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -39,7 +39,7 @@ use blockchain::{BlockChain, BlockProvider, TreeRoute, ImportRoute}; use client::{BlockId, TransactionId, ClientConfig, BlockChainClient}; use env_info::EnvInfo; use executive::{Executive, Executed}; -use receipt::Receipt; +use receipt::LocalizedReceipt; pub use blockchain::CacheSize as BlockChainCacheSize; /// General block status @@ -548,8 +548,40 @@ impl BlockChainClient for Client where V: Verifier { self.transaction_address(id).and_then(|address| self.chain.transaction(&address)) } - fn transaction_receipt(&self, id: TransactionId) -> Option { - self.transaction_address(id).and_then(|address| self.chain.transaction_receipt(&address)) + fn transaction_receipt(&self, id: TransactionId) -> Option { + self.transaction_address(id).and_then(|address| { + let t = self.chain.block(&address.block_hash) + .and_then(|block| BlockView::new(&block).localized_transaction_at(address.index)); + + match (t, self.chain.transaction_receipt(&address)) { + (Some(tx), Some(receipt)) => { + let block_hash = tx.block_hash.clone(); + let block_number = tx.block_number.clone(); + let transaction_hash = tx.hash(); + let transaction_index = tx.transaction_index; + Some(LocalizedReceipt { + transaction_hash: tx.hash(), + transaction_index: tx.transaction_index, + block_hash: tx.block_hash, + block_number: tx.block_number, + // TODO: to fix this, query all previous transaction receipts and retrieve their gas usage + cumulative_gas_used: receipt.gas_used, + gas_used: receipt.gas_used, + // TODO: to fix this, store created contract address in db + contract_address: None, + logs: receipt.logs.into_iter().enumerate().map(|(i, log)| LocalizedLogEntry { + entry: log, + block_hash: block_hash.clone(), + block_number: block_number, + transaction_hash: transaction_hash.clone(), + transaction_index: transaction_index, + log_index: i + }).collect() + }) + }, + _ => None + } + }) } fn tree_route(&self, from: &H256, to: &H256) -> Option { @@ -634,7 +666,7 @@ impl BlockChainClient for Client where V: Verifier { .map(|(i, log)| LocalizedLogEntry { entry: log, block_hash: hash.clone(), - block_number: number as usize, + block_number: number, transaction_hash: hashes.get(index).cloned().unwrap_or_else(H256::new), transaction_index: index, log_index: log_index + i diff --git a/ethcore/src/client/mod.rs b/ethcore/src/client/mod.rs index 420fcf75e..74b05652f 100644 --- a/ethcore/src/client/mod.rs +++ b/ethcore/src/client/mod.rs @@ -39,7 +39,7 @@ use transaction::{LocalizedTransaction, SignedTransaction}; use log_entry::LocalizedLogEntry; use filter::Filter; use error::{ImportResult, Error}; -use receipt::Receipt; +use receipt::LocalizedReceipt; /// Blockchain database client. Owns and manages a blockchain and a block queue. pub trait BlockChainClient : Sync + Send { @@ -78,7 +78,7 @@ pub trait BlockChainClient : Sync + Send { fn transaction(&self, id: TransactionId) -> Option; /// Get transaction receipt with given hash. - fn transaction_receipt(&self, id: TransactionId) -> Option; + fn transaction_receipt(&self, id: TransactionId) -> Option; /// Get a tree route between `from` and `to`. /// See `BlockChain::tree_route`. diff --git a/ethcore/src/client/test_client.rs b/ethcore/src/client/test_client.rs index 4dcf16c83..27e4eefe8 100644 --- a/ethcore/src/client/test_client.rs +++ b/ethcore/src/client/test_client.rs @@ -23,7 +23,7 @@ use client::{BlockChainClient, BlockChainInfo, BlockStatus, BlockId, Transaction use header::{Header as BlockHeader, BlockNumber}; use filter::Filter; use log_entry::LocalizedLogEntry; -use receipt::Receipt; +use receipt::{Receipt, LocalizedReceipt}; use extras::BlockReceipts; use error::{ImportResult}; @@ -224,7 +224,7 @@ impl BlockChainClient for TestBlockChainClient { unimplemented!(); } - fn transaction_receipt(&self, _id: TransactionId) -> Option { + fn transaction_receipt(&self, _id: TransactionId) -> Option { unimplemented!(); } diff --git a/ethcore/src/log_entry.rs b/ethcore/src/log_entry.rs index 63d09b4f0..cf74a6df9 100644 --- a/ethcore/src/log_entry.rs +++ b/ethcore/src/log_entry.rs @@ -18,6 +18,7 @@ use util::*; use basic_types::LogBloom; +use header::BlockNumber; /// A record of execution for a `LOG` operation. #[derive(Default, Debug, Clone, PartialEq, Eq)] @@ -84,7 +85,7 @@ pub struct LocalizedLogEntry { /// Block in which this log was created. pub block_hash: H256, /// Block number. - pub block_number: usize, + pub block_number: BlockNumber, /// Hash of transaction in which this log was created. pub transaction_hash: H256, /// Index of transaction within block. diff --git a/rpc/src/v1/impls/eth.rs b/rpc/src/v1/impls/eth.rs index 950cdb783..d7ee478bf 100644 --- a/rpc/src/v1/impls/eth.rs +++ b/rpc/src/v1/impls/eth.rs @@ -31,7 +31,7 @@ use ethcore::ethereum::Ethash; use ethcore::ethereum::denominations::shannon; use ethcore::transaction::Transaction as EthTransaction; use v1::traits::{Eth, EthFilter}; -use v1::types::{Block, BlockTransactions, BlockNumber, Bytes, SyncStatus, SyncInfo, Transaction, TransactionRequest, OptionalValue, Index, Filter, Log}; +use v1::types::{Block, BlockTransactions, BlockNumber, Bytes, SyncStatus, SyncInfo, Transaction, TransactionRequest, OptionalValue, Index, Filter, Log, Receipt}; use v1::helpers::{PollFilter, PollManager, ExternalMinerService, ExternalMiner}; use util::keys::store::AccountProvider; @@ -294,9 +294,12 @@ impl Eth for EthClient } fn transaction_receipt(&self, params: Params) -> Result { - unimplemented!(); - //from_params::<(H256,)>(params) - //.and_then(|(hash,)| self.transaction_receipt(TransactionId::Hash(hash))) + from_params::<(H256,)>(params) + .and_then(|(hash,)| { + let client = take_weak!(self.client); + let receipt = client.transaction_receipt(TransactionId::Hash(hash)); + to_value(&receipt.map(Receipt::from)) + }) } fn uncle_by_block_hash_and_index(&self, params: Params) -> Result {