jsonrpc eth_getCode method

This commit is contained in:
debris 2016-02-08 10:58:08 +01:00
parent 4116bdd8fd
commit 3adfebdc20
7 changed files with 127 additions and 2 deletions

View File

@ -86,6 +86,9 @@ pub trait BlockChainClient : Sync + Send {
/// Get block total difficulty. /// Get block total difficulty.
fn block_total_difficulty(&self, hash: &H256) -> Option<U256>; fn block_total_difficulty(&self, hash: &H256) -> Option<U256>;
/// Get address code.
fn code(&self, address: &Address) -> Option<Bytes>;
/// Get raw block header data by block number. /// Get raw block header data by block number.
fn block_header_at(&self, n: BlockNumber) -> Option<Bytes>; fn block_header_at(&self, n: BlockNumber) -> Option<Bytes>;
@ -357,6 +360,10 @@ impl BlockChainClient for Client {
self.chain.read().unwrap().block_details(hash).map(|d| d.total_difficulty) self.chain.read().unwrap().block_details(hash).map(|d| d.total_difficulty)
} }
fn code(&self, address: &Address) -> Option<Bytes> {
self.state().code(address)
}
fn block_header_at(&self, n: BlockNumber) -> Option<Bytes> { fn block_header_at(&self, n: BlockNumber) -> Option<Bytes> {
self.chain.read().unwrap().block_hash(n).and_then(|h| self.block_header(&h)) self.chain.read().unwrap().block_hash(n).and_then(|h| self.block_header(&h))
} }

View File

@ -18,4 +18,4 @@ ethcore = { path = "../ethcore" }
ethsync = { path = "../sync" } ethsync = { path = "../sync" }
clippy = "0.0.37" clippy = "0.0.37"
target_info = "0.1.0" target_info = "0.1.0"
rustc-serialize = "0.3"

View File

@ -20,6 +20,7 @@
#![plugin(serde_macros)] #![plugin(serde_macros)]
#![plugin(clippy)] #![plugin(clippy)]
extern crate rustc_serialize;
extern crate target_info; extern crate target_info;
extern crate serde; extern crate serde;
extern crate serde_json; extern crate serde_json;

View File

@ -23,7 +23,7 @@ use util::sha3::*;
use ethcore::client::*; use ethcore::client::*;
use ethcore::views::*; use ethcore::views::*;
use v1::traits::{Eth, EthFilter}; use v1::traits::{Eth, EthFilter};
use v1::types::{Block, SyncStatus}; use v1::types::{Block, BlockNumber, Bytes, SyncStatus};
/// Eth rpc implementation. /// Eth rpc implementation.
pub struct EthClient { pub struct EthClient {
@ -115,6 +115,14 @@ impl Eth for EthClient {
} }
} }
// TODO: do not ignore block number param
fn code_at(&self, params: Params) -> Result<Value, Error> {
match from_params::<(Address, BlockNumber)>(params) {
Ok((address, _block_number)) => to_value(&Bytes::new(self.client.code(&address).unwrap_or_else(|| vec![]))),
Err(err) => Err(err)
}
}
fn block(&self, params: Params) -> Result<Value, Error> { fn block(&self, params: Params) -> Result<Value, Error> {
match from_params::<(H256, bool)>(params) { match from_params::<(H256, bool)>(params) {
Ok((hash, _include_txs)) => match (self.client.block_header(&hash), self.client.block_total_difficulty(&hash)) { Ok((hash, _include_txs)) => match (self.client.block_header(&hash), self.client.block_total_difficulty(&hash)) {

View File

@ -0,0 +1,68 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
use serde::{Deserialize, Deserializer, Error};
use serde::de::Visitor;
/// Represents rpc api block number param.
#[derive(Debug, PartialEq)]
pub enum BlockNumber {
Num(u64),
Latest,
Earliest,
Pending
}
impl Deserialize for BlockNumber {
fn deserialize<D>(deserializer: &mut D) -> Result<BlockNumber, D::Error>
where D: Deserializer {
deserializer.visit(BlockNumberVisitor)
}
}
struct BlockNumberVisitor;
impl Visitor for BlockNumberVisitor {
type Value = BlockNumber;
fn visit_str<E>(&mut self, value: &str) -> Result<Self::Value, E> where E: Error {
match value {
"latest" => Ok(BlockNumber::Latest),
"earliest" => Ok(BlockNumber::Earliest),
"pending" => Ok(BlockNumber::Pending),
_ if value.starts_with("0x") => u64::from_str_radix(&value[2..], 16).map(BlockNumber::Num).map_err(|_| Error::syntax("invalid block number")),
_ => value.parse::<u64>().map(BlockNumber::Num).map_err(|_| Error::syntax("invalid block number"))
}
}
fn visit_string<E>(&mut self, value: String) -> Result<Self::Value, E> where E: Error {
self.visit_str(value.as_ref())
}
}
#[cfg(test)]
mod tests {
use super::*;
use serde_json;
#[test]
fn block_number_deserialization() {
let s = r#"["0xa", "10", "latest", "earliest", "pending"]"#;
let deserialized: Vec<BlockNumber> = serde_json::from_str(s).unwrap();
assert_eq!(deserialized, vec![BlockNumber::Num(10), BlockNumber::Num(10), BlockNumber::Latest, BlockNumber::Earliest, BlockNumber::Pending])
}
}

37
rpc/src/v1/types/bytes.rs Normal file
View File

@ -0,0 +1,37 @@
use rustc_serialize::hex::ToHex;
use serde::{Serialize, Serializer};
/// Wrapper structure around vector of bytes.
pub struct Bytes(Vec<u8>);
impl Bytes {
/// Simple constructor.
pub fn new(bytes: Vec<u8>) -> Bytes {
Bytes(bytes)
}
}
impl Serialize for Bytes {
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer {
let mut serialized = "0x".to_owned();
serialized.push_str(self.0.to_hex().as_ref());
serializer.visit_str(serialized.as_ref())
}
}
#[cfg(test)]
mod tests {
use super::*;
use serde_json;
use rustc_serialize::hex::FromHex;
#[test]
fn test_bytes_serialize() {
let bytes = Bytes("0123456789abcdef".from_hex().unwrap());
let serialized = serde_json::to_string(&bytes).unwrap();
assert_eq!(serialized, r#""0x0123456789abcdef""#);
}
}

View File

@ -15,7 +15,11 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
mod block; mod block;
mod block_number;
mod bytes;
mod sync; mod sync;
pub use self::block::Block; pub use self::block::Block;
pub use self::block_number::BlockNumber;
pub use self::bytes::Bytes;
pub use self::sync::SyncStatus; pub use self::sync::SyncStatus;