Skip to content

Commit

Permalink
Support eth_call by block hash (#345)
Browse files Browse the repository at this point in the history
  • Loading branch information
leoyvens committed May 14, 2020
1 parent fe520ce commit dc5cdc0
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 10 deletions.
4 changes: 2 additions & 2 deletions src/api/eth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ impl<T: Transport> Eth<T> {
}

/// Call a constant method of contract without changing the state of the blockchain.
pub fn call(&self, req: CallRequest, block: Option<BlockNumber>) -> CallFuture<Bytes, T::Out> {
pub fn call(&self, req: CallRequest, block: Option<BlockId>) -> CallFuture<Bytes, T::Out> {
let req = helpers::serialize(&req);
let block = helpers::serialize(&block.unwrap_or(BlockNumber::Latest));
let block = helpers::serialize(&block.unwrap_or(BlockNumber::Latest.into()));

CallFuture::new(self.transport.execute("eth_call", vec![req, block]))
}
Expand Down
44 changes: 39 additions & 5 deletions src/contract/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use ethabi;
use crate::api::{Eth, Namespace};
use crate::confirm;
use crate::contract::tokens::{Detokenize, Tokenize};
use crate::types::{Address, BlockNumber, Bytes, CallRequest, TransactionCondition, TransactionRequest, H256, U256};
use crate::types::{Address, BlockId, Bytes, CallRequest, TransactionCondition, TransactionRequest, H256, U256};
use crate::Transport;
use std::{collections::HashMap, hash::Hash, time};

Expand Down Expand Up @@ -222,7 +222,7 @@ impl<T: Transport> Contract<T> {
where
R: Detokenize,
A: Into<Option<Address>>,
B: Into<Option<BlockNumber>>,
B: Into<Option<BlockId>>,
P: Tokenize,
{
self.abi
Expand Down Expand Up @@ -256,7 +256,7 @@ mod tests {
use crate::api::{self, Namespace};
use crate::helpers::tests::TestTransport;
use crate::rpc;
use crate::types::{Address, BlockNumber, H256, U256};
use crate::types::{Address, BlockId, BlockNumber, H256, U256};
use crate::Transport;
use futures::Future;

Expand All @@ -276,7 +276,13 @@ mod tests {

// when
token
.query("name", (), None, Options::default(), BlockNumber::Number(1.into()))
.query(
"name",
(),
None,
Options::default(),
BlockId::Number(BlockNumber::Number(1.into())),
)
.wait()
.unwrap()
};
Expand All @@ -293,6 +299,34 @@ mod tests {
assert_eq!(result, "Hello World!".to_owned());
}

#[test]
fn should_call_constant_function_by_hash() {
// given
let mut transport = TestTransport::default();
transport.set_response(rpc::Value::String("0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000c48656c6c6f20576f726c64210000000000000000000000000000000000000000".into()));

let result: String = {
let token = contract(&transport);

// when
token
.query("name", (), None, Options::default(), BlockId::Hash(H256::default()))
.wait()
.unwrap()
};

// then
transport.assert_request(
"eth_call",
&[
"{\"data\":\"0x06fdde03\",\"to\":\"0x0000000000000000000000000000000000000001\"}".into(),
"{\"blockHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\"}".into(),
],
);
transport.assert_no_more_requests();
assert_eq!(result, "Hello World!".to_owned());
}

#[test]
fn should_query_with_params() {
// given
Expand All @@ -311,7 +345,7 @@ mod tests {
Options::with(|options| {
options.gas_price = Some(10_000_000.into());
}),
BlockNumber::Latest,
BlockId::Number(BlockNumber::Latest),
)
.wait()
.unwrap()
Expand Down
10 changes: 7 additions & 3 deletions src/types/block.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::types::{Bytes, H160, H2048, H256, H64, U256, U64};
use serde::{Deserialize, Serialize, Serializer};
use serde::{ser::SerializeStruct, Deserialize, Serialize, Serializer};

/// The block header type returned from RPC calls.
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
Expand Down Expand Up @@ -144,7 +144,7 @@ impl Serialize for BlockNumber {
}

/// Block Identifier
#[derive(Clone, Debug, PartialEq)]
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum BlockId {
/// By Hash
Hash(H256),
Expand All @@ -158,7 +158,11 @@ impl Serialize for BlockId {
S: Serializer,
{
match *self {
BlockId::Hash(ref x) => serializer.serialize_str(&format!("0x{}", x)),
BlockId::Hash(ref x) => {
let mut s = serializer.serialize_struct("BlockIdEip1898", 1)?;
s.serialize_field("blockHash", &format!("{:?}", x))?;
s.end()
}
BlockId::Number(ref num) => num.serialize(serializer),
}
}
Expand Down

0 comments on commit dc5cdc0

Please sign in to comment.