jsonrpc eth_getCode method
This commit is contained in:
parent
4116bdd8fd
commit
3adfebdc20
@ -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))
|
||||||
}
|
}
|
||||||
|
@ -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"
|
||||||
|
@ -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;
|
||||||
|
@ -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)) {
|
||||||
|
68
rpc/src/v1/types/block_number.rs
Normal file
68
rpc/src/v1/types/block_number.rs
Normal 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
37
rpc/src/v1/types/bytes.rs
Normal 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""#);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user