diff --git a/rpc/src/impls/eth.rs b/rpc/src/impls/eth.rs index 54372ab3a..f0ad73c57 100644 --- a/rpc/src/impls/eth.rs +++ b/rpc/src/impls/eth.rs @@ -1,10 +1,12 @@ use std::sync::Arc; -use serde_json; use jsonrpc_core::*; use util::hash::*; +use util::uint::*; +use util::sha3::*; use ethcore::client::*; +use ethcore::views::*; use traits::{Eth, EthFilter}; -use types::{Block, as_value, from_value}; +use types::{Block, to_value, from_value}; pub struct EthClient { client: Arc, @@ -28,7 +30,7 @@ impl Eth for EthClient { fn author(&self, params: Params) -> Result { match params { - Params::None => Ok(as_value(&Address::new())), + Params::None => Ok(to_value(&Address::new())), _ => Err(Error::invalid_params()) } } @@ -67,9 +69,34 @@ impl Eth for EthClient { fn block(&self, params: Params) -> Result { if let Params::Array(ref arr) = params { - if let [ref h, Value::Bool(ref include_transactions)] = arr as &[Value] { + if let [ref h, Value::Bool(ref _include_txs)] = arr as &[Value] { if let Ok(hash) = from_value::(h.clone()) { - return Ok(as_value(&Block::default())) + return match (self.client.block_header(&hash), self.client.block_details(&hash)) { + (Some(bytes), Some(details)) => { + let view = HeaderView::new(&bytes); + let block = Block { + hash: view.sha3(), + parent_hash: view.parent_hash(), + uncles_hash: view.uncles_hash(), + author: view.author(), + miner: view.author(), + state_root: view.state_root(), + transactions_root: view.transactions_root(), + receipts_root: view.receipts_root(), + number: U256::from(view.number()), + gas_used: view.gas_used(), + gas_limit: view.gas_limit(), + logs_bloom: view.log_bloom(), + timestamp: U256::from(view.timestamp()), + difficulty: view.difficulty(), + total_difficulty: details.total_difficulty, + uncles: vec![], + transactions: vec![] + }; + Ok(to_value(&block)) + }, + _ => Ok(Value::Null), + } } } } @@ -99,6 +126,6 @@ impl EthFilter for EthFilterClient { } fn filter_changes(&self, _: Params) -> Result { - Ok(Value::Array(vec![as_value(&self.client.chain_info().best_block_hash)])) + Ok(Value::Array(vec![to_value(&self.client.chain_info().best_block_hash)])) } } diff --git a/rpc/src/impls/web3.rs b/rpc/src/impls/web3.rs index 58e7858eb..50eb9c6f5 100644 --- a/rpc/src/impls/web3.rs +++ b/rpc/src/impls/web3.rs @@ -10,7 +10,8 @@ impl Web3Client { impl Web3 for Web3Client { fn client_version(&self, params: Params) -> Result { match params { - Params::None => Ok(Value::String("parity/0.1.0/-/rust1.7-nightly".to_string())), + //Params::None => Ok(Value::String("parity/0.1.0/-/rust1.7-nightly".to_owned())), + Params::None => Ok(Value::String("surprise/0.1.0/surprise/surprise".to_owned())), _ => Err(Error::invalid_params()) } } diff --git a/rpc/src/types/block.rs b/rpc/src/types/block.rs index 7b23e2e0c..ac1e673a5 100644 --- a/rpc/src/types/block.rs +++ b/rpc/src/types/block.rs @@ -1,33 +1,38 @@ use util::hash::*; use util::uint::*; -#[derive(Default, Serialize)] +#[derive(Default, Debug, Serialize)] pub struct Block { - hash: H256, + pub hash: H256, #[serde(rename="parentHash")] - parent_hash: H256, + pub parent_hash: H256, #[serde(rename="sha3Uncles")] - uncles_hash: H256, - author: Address, + pub uncles_hash: H256, + pub author: Address, // TODO: get rid of this one - miner: Address, + pub miner: Address, #[serde(rename="stateRoot")] - state_root: H256, + pub state_root: H256, #[serde(rename="transactionsRoot")] - transactions_root: H256, + pub transactions_root: H256, #[serde(rename="receiptsRoot")] - receipts_root: H256, - number: u64, + pub receipts_root: H256, + pub number: U256, #[serde(rename="gasUsed")] - gas_used: U256, + pub gas_used: U256, #[serde(rename="gasLimit")] - gas_limit: U256, + pub gas_limit: U256, // TODO: figure out how to properly serialize bytes //#[serde(rename="extraData")] //extra_data: Vec, #[serde(rename="logsBloom")] - logs_bloom: H2048, - timestamp: u64 + pub logs_bloom: H2048, + pub timestamp: U256, + pub difficulty: U256, + #[serde(rename="totalDifficulty")] + pub total_difficulty: U256, + pub uncles: Vec, + pub transactions: Vec } #[test] diff --git a/rpc/src/types/mod.rs b/rpc/src/types/mod.rs index a2f1da63e..0b7d97916 100644 --- a/rpc/src/types/mod.rs +++ b/rpc/src/types/mod.rs @@ -3,7 +3,7 @@ use serde_json::value::{Value, Serializer, Deserializer}; mod block; -pub fn as_value(s: &S) -> Value where S: Serialize { +pub fn to_value(s: &S) -> Value where S: Serialize { let mut serializer = Serializer::new(); // should never panic! s.serialize(&mut serializer).unwrap(); diff --git a/src/client.rs b/src/client.rs index 2e9029709..e8d8fc8f2 100644 --- a/src/client.rs +++ b/src/client.rs @@ -11,6 +11,7 @@ use service::NetSyncMessage; use env_info::LastHashes; use verification::*; use block::*; +use extras::BlockDetails; /// General block status #[derive(Debug)] @@ -64,6 +65,9 @@ pub trait BlockChainClient : Sync + Send { /// Get block status by block header hash. fn block_status(&self, hash: &H256) -> BlockStatus; + /// Get familial details concerning a block. + fn block_details(&self, hash: &H256) -> Option; + /// Get raw block header data by block number. fn block_header_at(&self, n: BlockNumber) -> Option; @@ -299,6 +303,10 @@ impl BlockChainClient for Client { fn block_status(&self, hash: &H256) -> BlockStatus { if self.chain.read().unwrap().is_known(&hash) { BlockStatus::InChain } else { BlockStatus::Unknown } } + + fn block_details(&self, hash: &H256) -> Option { + self.chain.read().unwrap().block_details(hash) + } fn block_header_at(&self, n: BlockNumber) -> Option { self.chain.read().unwrap().block_hash(n).and_then(|h| self.block_header(&h)) diff --git a/src/externalities.rs b/src/externalities.rs index f9a79c3c0..8b16cc72b 100644 --- a/src/externalities.rs +++ b/src/externalities.rs @@ -19,8 +19,7 @@ pub enum OutputPolicy<'a> { pub struct OriginInfo { address: Address, origin: Address, - gas_price: U256, - value: U256 + gas_price: U256 } impl OriginInfo { @@ -29,11 +28,7 @@ impl OriginInfo { OriginInfo { address: params.address.clone(), origin: params.origin.clone(), - gas_price: params.gas_price.clone(), - value: match params.value { - ActionValue::Transfer(val) => val, - ActionValue::Apparent(val) => val, - } + gas_price: params.gas_price.clone() } } } @@ -116,7 +111,7 @@ impl<'a> Ext for Externalities<'a> { origin: self.origin_info.origin.clone(), gas: *gas, gas_price: self.origin_info.gas_price.clone(), - value: ActionValue::Transfer(value.clone()), + value: value.clone(), code: Some(code.to_vec()), data: None, }; @@ -136,29 +131,24 @@ impl<'a> Ext for Externalities<'a> { fn call(&mut self, gas: &U256, - sender_address: &Address, - receive_address: &Address, - value: Option, + address: &Address, + value: &U256, data: &[u8], code_address: &Address, output: &mut [u8]) -> MessageCallResult { - let mut params = ActionParams { - sender: sender_address.clone(), - address: receive_address.clone(), - value: ActionValue::Apparent(self.origin_info.value.clone()), + let params = ActionParams { code_address: code_address.clone(), + address: address.clone(), + sender: self.origin_info.address.clone(), origin: self.origin_info.origin.clone(), gas: *gas, gas_price: self.origin_info.gas_price.clone(), + value: value.clone(), code: self.state.code(code_address), data: Some(data.to_vec()), }; - if let Some(value) = value { - params.value = ActionValue::Transfer(value); - } - let mut ex = Executive::from_parent(self.state, self.env_info, self.engine, self.depth); match ex.call(params, self.substate, BytesRef::Fixed(output)) { @@ -168,10 +158,9 @@ impl<'a> Ext for Externalities<'a> { } fn extcode(&self, address: &Address) -> Bytes { - self.state.code(address).unwrap_or_else(|| vec![]) + self.state.code(address).unwrap_or(vec![]) } - #[allow(match_ref_pats)] fn ret(&mut self, gas: &U256, data: &[u8]) -> Result { match &mut self.output { &mut OutputPolicy::Return(BytesRef::Fixed(ref mut slice)) => unsafe {