Use impl Future in the light client RPC helpers (#8628)

This commit is contained in:
Pierre Krieger 2018-05-24 04:39:52 +02:00 committed by Marek Kotewicz
parent db9397890e
commit 6563576ae9
3 changed files with 36 additions and 37 deletions

View File

@ -25,7 +25,7 @@ use ethcore::ids::BlockId;
use ethcore::filter::Filter as EthcoreFilter; use ethcore::filter::Filter as EthcoreFilter;
use ethcore::receipt::Receipt; use ethcore::receipt::Receipt;
use jsonrpc_core::{BoxFuture, Result}; use jsonrpc_core::{Result, Error};
use jsonrpc_core::futures::{future, Future}; use jsonrpc_core::futures::{future, Future};
use jsonrpc_core::futures::future::Either; use jsonrpc_core::futures::future::Either;
use jsonrpc_macros::Trailing; use jsonrpc_macros::Trailing;
@ -139,58 +139,57 @@ impl LightFetch {
} }
/// Get a block header from the on demand service or client, or error. /// Get a block header from the on demand service or client, or error.
pub fn header(&self, id: BlockId) -> BoxFuture<encoded::Header> { pub fn header(&self, id: BlockId) -> impl Future<Item = encoded::Header, Error = Error> + Send {
let mut reqs = Vec::new(); let mut reqs = Vec::new();
let header_ref = match self.make_header_requests(id, &mut reqs) { let header_ref = match self.make_header_requests(id, &mut reqs) {
Ok(r) => r, Ok(r) => r,
Err(e) => return Box::new(future::err(e)), Err(e) => return Either::A(future::err(e)),
}; };
Either::B(self.send_requests(reqs, |res|
self.send_requests(reqs, |res|
extract_header(&res, header_ref) extract_header(&res, header_ref)
.expect("these responses correspond to requests that header_ref belongs to \ .expect("these responses correspond to requests that header_ref belongs to \
therefore it will not fail; qed") therefore it will not fail; qed")
) ))
} }
/// Helper for getting contract code at a given block. /// Helper for getting contract code at a given block.
pub fn code(&self, address: Address, id: BlockId) -> BoxFuture<Vec<u8>> { pub fn code(&self, address: Address, id: BlockId) -> impl Future<Item = Vec<u8>, Error = Error> + Send {
let mut reqs = Vec::new(); let mut reqs = Vec::new();
let header_ref = match self.make_header_requests(id, &mut reqs) { let header_ref = match self.make_header_requests(id, &mut reqs) {
Ok(r) => r, Ok(r) => r,
Err(e) => return Box::new(future::err(e)), Err(e) => return Either::A(future::err(e)),
}; };
reqs.push(request::Account { header: header_ref.clone(), address: address }.into()); reqs.push(request::Account { header: header_ref.clone(), address: address }.into());
let account_idx = reqs.len() - 1; let account_idx = reqs.len() - 1;
reqs.push(request::Code { header: header_ref, code_hash: Field::back_ref(account_idx, 0) }.into()); reqs.push(request::Code { header: header_ref, code_hash: Field::back_ref(account_idx, 0) }.into());
self.send_requests(reqs, |mut res| match res.pop() { Either::B(self.send_requests(reqs, |mut res| match res.pop() {
Some(OnDemandResponse::Code(code)) => code, Some(OnDemandResponse::Code(code)) => code,
_ => panic!("responses correspond directly with requests in amount and type; qed"), _ => panic!("responses correspond directly with requests in amount and type; qed"),
}) }))
} }
/// Helper for getting account info at a given block. /// Helper for getting account info at a given block.
/// `None` indicates the account doesn't exist at the given block. /// `None` indicates the account doesn't exist at the given block.
pub fn account(&self, address: Address, id: BlockId) -> BoxFuture<Option<BasicAccount>> { pub fn account(&self, address: Address, id: BlockId) -> impl Future<Item = Option<BasicAccount>, Error = Error> + Send {
let mut reqs = Vec::new(); let mut reqs = Vec::new();
let header_ref = match self.make_header_requests(id, &mut reqs) { let header_ref = match self.make_header_requests(id, &mut reqs) {
Ok(r) => r, Ok(r) => r,
Err(e) => return Box::new(future::err(e)), Err(e) => return Either::A(future::err(e)),
}; };
reqs.push(request::Account { header: header_ref, address: address }.into()); reqs.push(request::Account { header: header_ref, address: address }.into());
self.send_requests(reqs, |mut res|match res.pop() { Either::B(self.send_requests(reqs, |mut res|match res.pop() {
Some(OnDemandResponse::Account(acc)) => acc, Some(OnDemandResponse::Account(acc)) => acc,
_ => panic!("responses correspond directly with requests in amount and type; qed"), _ => panic!("responses correspond directly with requests in amount and type; qed"),
}) }))
} }
/// Helper for getting proved execution. /// Helper for getting proved execution.
pub fn proved_execution(&self, req: CallRequest, num: Trailing<BlockNumber>) -> BoxFuture<ExecutionResult> { pub fn proved_execution(&self, req: CallRequest, num: Trailing<BlockNumber>) -> impl Future<Item = ExecutionResult, Error = Error> + Send {
const DEFAULT_GAS_PRICE: u64 = 21_000; const DEFAULT_GAS_PRICE: u64 = 21_000;
// starting gas when gas not provided. // starting gas when gas not provided.
const START_GAS: u64 = 50_000; const START_GAS: u64 = 50_000;
@ -280,39 +279,39 @@ impl LightFetch {
} }
/// Get a block itself. Fails on unknown block ID. /// Get a block itself. Fails on unknown block ID.
pub fn block(&self, id: BlockId) -> BoxFuture<encoded::Block> { pub fn block(&self, id: BlockId) -> impl Future<Item = encoded::Block, Error = Error> + Send {
let mut reqs = Vec::new(); let mut reqs = Vec::new();
let header_ref = match self.make_header_requests(id, &mut reqs) { let header_ref = match self.make_header_requests(id, &mut reqs) {
Ok(r) => r, Ok(r) => r,
Err(e) => return Box::new(future::err(e)), Err(e) => return Either::A(future::err(e)),
}; };
reqs.push(request::Body(header_ref).into()); reqs.push(request::Body(header_ref).into());
self.send_requests(reqs, |mut res| match res.pop() { Either::B(self.send_requests(reqs, |mut res| match res.pop() {
Some(OnDemandResponse::Body(b)) => b, Some(OnDemandResponse::Body(b)) => b,
_ => panic!("responses correspond directly with requests in amount and type; qed"), _ => panic!("responses correspond directly with requests in amount and type; qed"),
}) }))
} }
/// Get the block receipts. Fails on unknown block ID. /// Get the block receipts. Fails on unknown block ID.
pub fn receipts(&self, id: BlockId) -> BoxFuture<Vec<Receipt>> { pub fn receipts(&self, id: BlockId) -> impl Future<Item = Vec<Receipt>, Error = Error> + Send {
let mut reqs = Vec::new(); let mut reqs = Vec::new();
let header_ref = match self.make_header_requests(id, &mut reqs) { let header_ref = match self.make_header_requests(id, &mut reqs) {
Ok(r) => r, Ok(r) => r,
Err(e) => return Box::new(future::err(e)), Err(e) => return Either::A(future::err(e)),
}; };
reqs.push(request::BlockReceipts(header_ref).into()); reqs.push(request::BlockReceipts(header_ref).into());
self.send_requests(reqs, |mut res| match res.pop() { Either::B(self.send_requests(reqs, |mut res| match res.pop() {
Some(OnDemandResponse::Receipts(b)) => b, Some(OnDemandResponse::Receipts(b)) => b,
_ => panic!("responses correspond directly with requests in amount and type; qed"), _ => panic!("responses correspond directly with requests in amount and type; qed"),
}) }))
} }
/// Get transaction logs /// Get transaction logs
pub fn logs(&self, filter: EthcoreFilter) -> BoxFuture<Vec<Log>> { pub fn logs(&self, filter: EthcoreFilter) -> impl Future<Item = Vec<Log>, Error = Error> + Send {
use std::collections::BTreeMap; use std::collections::BTreeMap;
use jsonrpc_core::futures::stream::{self, Stream}; use jsonrpc_core::futures::stream::{self, Stream};
@ -326,9 +325,9 @@ impl LightFetch {
}; };
match (block_number(filter.to_block), block_number(filter.from_block)) { match (block_number(filter.to_block), block_number(filter.from_block)) {
(Some(to), Some(from)) if to < from => return Box::new(future::ok(Vec::new())), (Some(to), Some(from)) if to < from => return Either::A(future::ok(Vec::new())),
(Some(_), Some(_)) => {}, (Some(_), Some(_)) => {},
_ => return Box::new(future::err(errors::unknown_block())), _ => return Either::A(future::err(errors::unknown_block())),
} }
let maybe_future = self.sync.with_context(move |ctx| { let maybe_future = self.sync.with_context(move |ctx| {
@ -362,15 +361,15 @@ impl LightFetch {
}); });
match maybe_future { match maybe_future {
Some(fut) => Box::new(fut), Some(fut) => Either::B(Either::A(fut)),
None => Box::new(future::err(errors::network_disabled())), None => Either::B(Either::B(future::err(errors::network_disabled()))),
} }
} }
// Get a transaction by hash. also returns the index in the block. // Get a transaction by hash. also returns the index in the block.
// Only returns transactions in the canonical chain. // Only returns transactions in the canonical chain.
pub fn transaction_by_hash(&self, tx_hash: H256, eip86_transition: u64) pub fn transaction_by_hash(&self, tx_hash: H256, eip86_transition: u64)
-> BoxFuture<Option<(Transaction, usize)>> -> impl Future<Item = Option<(Transaction, usize)>, Error = Error> + Send
{ {
let params = (self.sync.clone(), self.on_demand.clone()); let params = (self.sync.clone(), self.on_demand.clone());
let fetcher: Self = self.clone(); let fetcher: Self = self.clone();
@ -426,7 +425,7 @@ impl LightFetch {
})) }))
} }
fn send_requests<T, F>(&self, reqs: Vec<OnDemandRequest>, parse_response: F) -> BoxFuture<T> where fn send_requests<T, F>(&self, reqs: Vec<OnDemandRequest>, parse_response: F) -> impl Future<Item = T, Error = Error> + Send where
F: FnOnce(Vec<OnDemandResponse>) -> T + Send + 'static, F: FnOnce(Vec<OnDemandResponse>) -> T + Send + 'static,
T: Send + 'static, T: Send + 'static,
{ {
@ -439,7 +438,7 @@ impl LightFetch {
match maybe_future { match maybe_future {
Some(recv) => recv, Some(recv) => recv,
None => Box::new(future::err(errors::network_disabled())) None => Box::new(future::err(errors::network_disabled())) as Box<Future<Item = _, Error = _> + Send>
} }
} }
} }
@ -457,7 +456,7 @@ struct ExecuteParams {
// has a peer execute the transaction with given params. If `gas_known` is false, // has a peer execute the transaction with given params. If `gas_known` is false,
// this will double the gas on each `OutOfGas` error. // this will double the gas on each `OutOfGas` error.
fn execute_tx(gas_known: bool, params: ExecuteParams) -> BoxFuture<ExecutionResult> { fn execute_tx(gas_known: bool, params: ExecuteParams) -> impl Future<Item = ExecutionResult, Error = Error> + Send {
if !gas_known { if !gas_known {
Box::new(future::loop_fn(params, |mut params| { Box::new(future::loop_fn(params, |mut params| {
execute_tx(true, params.clone()).and_then(move |res| { execute_tx(true, params.clone()).and_then(move |res| {
@ -480,7 +479,7 @@ fn execute_tx(gas_known: bool, params: ExecuteParams) -> BoxFuture<ExecutionResu
failed => Ok(future::Loop::Break(failed)), failed => Ok(future::Loop::Break(failed)),
} }
}) })
})) })) as Box<Future<Item = _, Error = _> + Send>
} else { } else {
trace!(target: "light_fetch", "Placing execution request for {} gas in on_demand", trace!(target: "light_fetch", "Placing execution request for {} gas in on_demand",
params.tx.gas); params.tx.gas);
@ -501,8 +500,8 @@ fn execute_tx(gas_known: bool, params: ExecuteParams) -> BoxFuture<ExecutionResu
}); });
match proved_future { match proved_future {
Some(fut) => Box::new(fut), Some(fut) => Box::new(fut) as Box<Future<Item = _, Error = _> + Send>,
None => Box::new(future::err(errors::network_disabled())), None => Box::new(future::err(errors::network_disabled())) as Box<Future<Item = _, Error = _> + Send>,
} }
} }
} }

View File

@ -199,7 +199,7 @@ impl LightClient for LightFetch {
} }
fn logs(&self, filter: EthFilter) -> BoxFuture<Vec<Log>> { fn logs(&self, filter: EthFilter) -> BoxFuture<Vec<Log>> {
LightFetch::logs(self, filter) Box::new(LightFetch::logs(self, filter)) as BoxFuture<_>
} }
} }

View File

@ -538,7 +538,7 @@ impl<T: LightChainClient + 'static> Filterable for EthClient<T> {
} }
fn logs(&self, filter: EthcoreFilter) -> BoxFuture<Vec<Log>> { fn logs(&self, filter: EthcoreFilter) -> BoxFuture<Vec<Log>> {
self.fetcher().logs(filter) Box::new(self.fetcher().logs(filter)) as BoxFuture<_>
} }
fn pending_logs(&self, _block_number: u64, _filter: &EthcoreFilter) -> Vec<Log> { fn pending_logs(&self, _block_number: u64, _filter: &EthcoreFilter) -> Vec<Log> {