diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index bf1ae7f05..4f17901b7 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -22,7 +22,7 @@ use util::*; use util::panics::*; use views::BlockView; use error::{Error, ImportError, ExecutionError, BlockError, ImportResult}; -use header::{BlockNumber, Header}; +use header::{BlockNumber}; use state::State; use spec::Spec; use engine::Engine; @@ -585,9 +585,9 @@ impl BlockChainClient for Client { self.transaction_address(id).and_then(|address| self.chain.transaction(&address)) } - fn uncle(&self, id: UncleID) -> Option
{ - let index = id.1; - self.block(id.0).and_then(|block| BlockView::new(&block).uncle_at(index)) + fn uncle(&self, id: UncleID) -> Option { + let index = id.position; + self.block(id.block).and_then(|block| BlockView::new(&block).uncle_rlp_at(index)) } fn transaction_receipt(&self, id: TransactionID) -> Option { diff --git a/ethcore/src/client/mod.rs b/ethcore/src/client/mod.rs index 7f3c3bb3a..27a1d3265 100644 --- a/ethcore/src/client/mod.rs +++ b/ethcore/src/client/mod.rs @@ -38,7 +38,7 @@ use util::Itertools; use blockchain::TreeRoute; use block_queue::BlockQueueInfo; use block::{OpenBlock, SealedBlock}; -use header::{BlockNumber, Header}; +use header::{BlockNumber}; use transaction::{LocalizedTransaction, SignedTransaction}; use log_entry::LocalizedLogEntry; use filter::Filter; @@ -126,7 +126,7 @@ pub trait BlockChainClient : Sync + Send { fn transaction(&self, id: TransactionID) -> Option; /// Get uncle with given id. - fn uncle(&self, id: UncleID) -> Option
; + fn uncle(&self, id: UncleID) -> Option; /// Get transaction receipt with given hash. fn transaction_receipt(&self, id: TransactionID) -> Option; diff --git a/ethcore/src/client/test_client.rs b/ethcore/src/client/test_client.rs index f51f978de..be90d9b67 100644 --- a/ethcore/src/client/test_client.rs +++ b/ethcore/src/client/test_client.rs @@ -244,7 +244,7 @@ impl MiningBlockChainClient for TestBlockChainClient { fn prepare_open_block(&self, _author: Address, _gas_range_target: (U256, U256), _extra_data: Bytes) -> OpenBlock { unimplemented!(); } - + fn vm_factory(&self) -> &EvmFactory { unimplemented!(); } @@ -298,7 +298,7 @@ impl BlockChainClient for TestBlockChainClient { unimplemented!(); } - fn uncle(&self, _id: UncleID) -> Option { + fn uncle(&self, _id: UncleID) -> Option { unimplemented!(); } diff --git a/ethcore/src/types/ids.rs b/ethcore/src/types/ids.rs index 0a492735c..99dadc4ea 100644 --- a/ethcore/src/types/ids.rs +++ b/ethcore/src/types/ids.rs @@ -55,10 +55,10 @@ pub struct TraceId { } /// Uniquely identifies Uncle. -#[derive(Debug)] -pub struct UncleID ( +#[derive(Debug, Binary)] +pub struct UncleID { /// Block id. - pub BlockID, + pub block: BlockID, /// Position in block. - pub usize -); + pub position: usize +} diff --git a/ethcore/src/views/block.rs b/ethcore/src/views/block.rs index 82b8fb805..42fd52a20 100644 --- a/ethcore/src/views/block.rs +++ b/ethcore/src/views/block.rs @@ -139,6 +139,11 @@ impl<'a> BlockView<'a> { pub fn uncle_at(&self, index: usize) -> Option
{ self.rlp.at(2).iter().nth(index).map(|rlp| rlp.as_val()) } + + /// Return nth uncle rlp. + pub fn uncle_rlp_at(&self, index: usize) -> Option { + self.rlp.at(2).iter().nth(index).map(|rlp| rlp.as_raw().to_vec()) + } } impl<'a> Hashable for BlockView<'a> { diff --git a/rpc/src/v1/impls/eth.rs b/rpc/src/v1/impls/eth.rs index 8bfc661e3..f2325de93 100644 --- a/rpc/src/v1/impls/eth.rs +++ b/rpc/src/v1/impls/eth.rs @@ -41,6 +41,7 @@ use v1::traits::Eth; use v1::types::{Block, BlockTransactions, BlockNumber, Bytes, SyncStatus, SyncInfo, Transaction, CallRequest, OptionalValue, Index, Filter, Log, Receipt}; use v1::impls::{default_gas_price, dispatch_transaction, error_codes}; use serde; +use ethcore::header::Header as BlockHeader; /// Eth rpc implementation. pub struct EthClient where @@ -126,33 +127,38 @@ impl EthClient where fn uncle(&self, id: UncleID) -> Result { let client = take_weak!(self.client); - match client.uncle(id).and_then(|u| client.block_total_difficulty(BlockID::Hash(u.parent_hash().clone())).map(|diff| (diff, u))) { - Some((parent_difficulty, uncle)) => { - let block = Block { - hash: OptionalValue::Value(uncle.hash()), - parent_hash: uncle.parent_hash, - uncles_hash: uncle.uncles_hash, - author: uncle.author, - miner: uncle.author, - state_root: uncle.state_root, - transactions_root: uncle.transactions_root, - number: OptionalValue::Value(U256::from(uncle.number)), - gas_used: uncle.gas_used, - gas_limit: uncle.gas_limit, - logs_bloom: uncle.log_bloom, - timestamp: U256::from(uncle.timestamp), - difficulty: uncle.difficulty, - total_difficulty: uncle.difficulty + parent_difficulty, - receipts_root: uncle.receipts_root, - extra_data: Bytes::new(uncle.extra_data), - seal_fields: uncle.seal.into_iter().map(|f| decode(&f)).map(Bytes::new).collect(), - uncles: vec![], - transactions: BlockTransactions::Hashes(vec![]), - }; - to_value(&block) - }, - None => Ok(Value::Null) - } + + let uncle: BlockHeader = match client.uncle(id) { + Some(rlp) => decode(&rlp), + None => { return Ok(Value::Null); } + }; + let parent_difficulty = match client.block_total_difficulty(BlockID::Hash(uncle.parent_hash().clone())) { + Some(difficulty) => difficulty, + None => { return Ok(Value::Null); } + }; + + let block = Block { + hash: OptionalValue::Value(uncle.hash()), + parent_hash: uncle.parent_hash, + uncles_hash: uncle.uncles_hash, + author: uncle.author, + miner: uncle.author, + state_root: uncle.state_root, + transactions_root: uncle.transactions_root, + number: OptionalValue::Value(U256::from(uncle.number)), + gas_used: uncle.gas_used, + gas_limit: uncle.gas_limit, + logs_bloom: uncle.log_bloom, + timestamp: U256::from(uncle.timestamp), + difficulty: uncle.difficulty, + total_difficulty: uncle.difficulty + parent_difficulty, + receipts_root: uncle.receipts_root, + extra_data: Bytes::new(uncle.extra_data), + seal_fields: uncle.seal.into_iter().map(|f| decode(&f)).map(Bytes::new).collect(), + uncles: vec![], + transactions: BlockTransactions::Hashes(vec![]), + }; + to_value(&block) } fn sign_call(&self, request: CallRequest) -> Result { @@ -435,12 +441,12 @@ impl Eth for EthClient where fn uncle_by_block_hash_and_index(&self, params: Params) -> Result { from_params::<(H256, Index)>(params) - .and_then(|(hash, index)| self.uncle(UncleID(BlockID::Hash(hash), index.value()))) + .and_then(|(hash, index)| self.uncle(UncleID { block: BlockID::Hash(hash), position: index.value() })) } fn uncle_by_block_number_and_index(&self, params: Params) -> Result { from_params::<(BlockNumber, Index)>(params) - .and_then(|(number, index)| self.uncle(UncleID(number.into(), index.value()))) + .and_then(|(number, index)| self.uncle(UncleID { block: number.into(), position: index.value() })) } fn compilers(&self, params: Params) -> Result {