diff --git a/examples/bench.rs b/examples/bench.rs index 5ae100a2..406d7e78 100644 --- a/examples/bench.rs +++ b/examples/bench.rs @@ -18,7 +18,7 @@ async fn main() -> web3::Result { fn bench(id: &str, transport: T, max: usize) where - T::Out: Send + Unpin + 'static, + T::Out: Send + 'static, { use futures::FutureExt; diff --git a/src/api/accounts.rs b/src/api/accounts.rs index d98eccd4..c0efa86e 100644 --- a/src/api/accounts.rs +++ b/src/api/accounts.rs @@ -16,7 +16,6 @@ use rlp::RlpStream; use secp256k1::key::ONE_KEY; use secp256k1::{Message, PublicKey, Secp256k1, SecretKey}; use std::convert::TryInto; -use std::marker::Unpin; use std::mem; use std::ops::Deref; use std::pin::Pin; @@ -49,10 +48,7 @@ impl Accounts { } /// Signs an Ethereum transaction with a given private key. - pub fn sign_transaction(&self, tx: TransactionParameters, key: &SecretKey) -> SignTransactionFuture - where - T::Out: Unpin, - { + pub fn sign_transaction(&self, tx: TransactionParameters, key: &SecretKey) -> SignTransactionFuture { SignTransactionFuture::new(self, tx, key) } @@ -179,19 +175,13 @@ type TxParams = Join3, MaybeReady, MaybeReady -where - T::Out: Unpin, -{ +pub struct SignTransactionFuture { tx: TransactionParameters, key: ZeroizeSecretKey, inner: TxParams, } -impl SignTransactionFuture -where - T::Out: Unpin, -{ +impl SignTransactionFuture { /// Creates a new SignTransactionFuture with accounts and transaction data. pub fn new(accounts: &Accounts, tx: TransactionParameters, key: &SecretKey) -> SignTransactionFuture { macro_rules! maybe { @@ -218,10 +208,7 @@ where } } -impl Future for SignTransactionFuture -where - T::Out: Unpin, -{ +impl Future for SignTransactionFuture { type Output = error::Result; fn poll(mut self: Pin<&mut Self>, ctx: &mut Context) -> Poll { @@ -243,10 +230,7 @@ where } } -impl Drop for SignTransactionFuture -where - T::Out: Unpin, -{ +impl Drop for SignTransactionFuture { fn drop(&mut self) { self.key.zeroize(); } diff --git a/src/api/eth_filter.rs b/src/api/eth_filter.rs index 4fca4a31..bae06af0 100644 --- a/src/api/eth_filter.rs +++ b/src/api/eth_filter.rs @@ -67,10 +67,7 @@ enum FilterStreamState { NextItem(vec::IntoIter), } -impl Stream for FilterStream -where - T::Out: Unpin, -{ +impl Stream for FilterStream { type Item = error::Result; fn poll_next(mut self: Pin<&mut Self>, ctx: &mut Context) -> Poll> { @@ -232,7 +229,6 @@ pub struct CreateFilter { impl Future for CreateFilter where T: Transport, - T::Out: Unpin, I: Unpin, { type Output = error::Result>; diff --git a/src/api/eth_subscribe.rs b/src/api/eth_subscribe.rs index 8e6c95d8..b99e30df 100644 --- a/src/api/eth_subscribe.rs +++ b/src/api/eth_subscribe.rs @@ -81,7 +81,6 @@ impl SubscriptionStream { impl Stream for SubscriptionStream where T: DuplexTransport, - T::Out: Unpin, T::NotificationStream: Unpin, I: serde::de::DeserializeOwned + Unpin, { @@ -122,7 +121,6 @@ impl Future for SubscriptionResult where T: DuplexTransport, I: serde::de::DeserializeOwned + Unpin, - T::Out: Unpin, { type Output = error::Result>; diff --git a/src/confirm.rs b/src/confirm.rs index 34124c04..321df3bf 100644 --- a/src/confirm.rs +++ b/src/confirm.rs @@ -54,7 +54,6 @@ where impl Future for WaitForConfirmations where T: Transport, - T::Out: Unpin, V: ConfirmationCheck + Unpin, F: Future>> + Unpin, { @@ -126,7 +125,6 @@ impl Confirmations { impl Future for Confirmations where T: Transport, - T::Out: Unpin, V: ConfirmationCheck + Unpin, F: Future>> + Unpin, { @@ -176,10 +174,7 @@ struct TransactionReceiptBlockNumber { future: CallFuture, T::Out>, } -impl Future for TransactionReceiptBlockNumber -where - T::Out: Unpin, -{ +impl Future for TransactionReceiptBlockNumber { type Output = error::Result>; fn poll(mut self: Pin<&mut Self>, ctx: &mut Context) -> Poll { @@ -199,10 +194,7 @@ impl TransactionReceiptBlockNumberCheck { } } -impl ConfirmationCheck for TransactionReceiptBlockNumberCheck -where - T::Out: Unpin, -{ +impl ConfirmationCheck for TransactionReceiptBlockNumberCheck { type Check = TransactionReceiptBlockNumber; fn check(&self) -> Self::Check { @@ -259,10 +251,7 @@ impl SendTransactionWithConfirmation { } } -impl Future for SendTransactionWithConfirmation -where - T::Out: Unpin, -{ +impl Future for SendTransactionWithConfirmation { type Output = error::Result; fn poll(mut self: Pin<&mut Self>, ctx: &mut Context) -> Poll { diff --git a/src/contract/deploy.rs b/src/contract/deploy.rs index 66cd9e7d..1bb4e7c1 100644 --- a/src/contract/deploy.rs +++ b/src/contract/deploy.rs @@ -55,7 +55,6 @@ impl Builder { where P: Tokenize, V: AsRef, - T::Out: Unpin, { let transport = self.eth.transport().clone(); let poll_interval = self.poll_interval; @@ -81,7 +80,6 @@ impl Builder { where P: Tokenize, V: AsRef, - T::Out: Unpin, { let transport = self.eth.transport().clone(); let poll_interval = self.poll_interval; @@ -176,7 +174,6 @@ impl Future for PendingContract where F: Future> + Unpin, T: Transport, - T::Out: Unpin, { type Output = Result, Error>; diff --git a/src/contract/mod.rs b/src/contract/mod.rs index a6ddcdd0..209ea109 100644 --- a/src/contract/mod.rs +++ b/src/contract/mod.rs @@ -1,16 +1,17 @@ //! Ethereum Contract Interface -use ethabi; - use crate::api::{Accounts, Eth, Namespace}; use crate::confirm; use crate::contract::tokens::{Detokenize, Tokenize}; use crate::types::{ - Address, BlockId, Bytes, CallRequest, TransactionCondition, TransactionParameters, TransactionReceipt, - TransactionRequest, H256, U256, + Address, BlockId, Bytes, CallRequest, FilterBuilder, TransactionCondition, TransactionParameters, + TransactionReceipt, TransactionRequest, H256, U256, }; use crate::Transport; -use futures::future::Either; +use futures::{ + future::{self, Either}, + Future, FutureExt, TryFutureExt, +}; use secp256k1::key::SecretKey; use std::{collections::HashMap, hash::Hash, time}; @@ -159,12 +160,7 @@ impl Contract { options: Options, confirmations: usize, key: &'a SecretKey, - ) -> impl futures::Future> + 'a - where - T::Out: Unpin, - { - use futures::TryFutureExt; - + ) -> impl Future> + 'a { let poll_interval = time::Duration::from_secs(1); self.abi @@ -200,7 +196,7 @@ impl Contract { // TODO [ToDr] SendTransactionWithConfirmation should support custom error type (so that we can return // `contract::Error` instead of more generic `Error`. let err = crate::error::Error::Decoder(format!("{:?}", e)); - Either::Right(futures::future::ready(Err(err))) + Either::Right(future::ready(Err(err))) }) } @@ -311,6 +307,65 @@ impl Contract { }) .unwrap_or_else(Into::into) } + + /// Find events matching the topics. + pub fn events( + &self, + event: &str, + topic0: A, + topic1: B, + topic2: C, + ) -> impl Future>> + where + A: Tokenize, + B: Tokenize, + C: Tokenize, + R: Detokenize, + { + fn to_topic(x: A) -> ethabi::Topic { + let tokens = x.into_tokens(); + if tokens.is_empty() { + ethabi::Topic::Any + } else { + tokens.into() + } + } + + let res = self.abi.event(event).and_then(|ev| { + let filter = ev.filter(ethabi::RawTopicFilter { + topic0: to_topic(topic0), + topic1: to_topic(topic1), + topic2: to_topic(topic2), + })?; + Ok((ev.clone(), filter)) + }); + let (ev, filter) = match res { + Ok(x) => x, + Err(e) => return Either::Left(future::ready(Err(e.into()))), + }; + + Either::Right( + self.eth + .logs(FilterBuilder::default().topic_filter(filter).build()) + .map_err(Into::into) + .map(move |logs| { + logs.and_then(|logs| { + logs.into_iter() + .map(move |l| { + let log = ev.parse_log(ethabi::RawLog { + topics: l.topics, + data: l.data.0, + })?; + + Ok(R::from_tokens( + log.params.into_iter().map(|x| x.value).collect::>(), + )?) + }) + .collect::>>() + }) + }), + ) + } } #[cfg(test)] diff --git a/src/lib.rs b/src/lib.rs index 003398fd..b7de709a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -41,7 +41,7 @@ pub type RequestId = usize; /// Transport implementation pub trait Transport: std::fmt::Debug + Clone + Unpin { /// The type of future this transport returns when a call is made. - type Out: futures::Future>; + type Out: futures::Future> + Unpin; /// Prepare serializable RPC call for given method with parameters. fn prepare(&self, method: &str, params: Vec) -> (RequestId, rpc::Call); diff --git a/src/types/traces.rs b/src/types/traces.rs index edbbf06c..f0da17fa 100644 --- a/src/types/traces.rs +++ b/src/types/traces.rs @@ -1,8 +1,8 @@ //! Types for the Parity Ad-Hoc Trace API -use std::collections::BTreeMap; use crate::types::{Action, ActionType, Bytes, Res, H160, H256, U256}; use serde::{Deserialize, Serialize}; +use std::collections::BTreeMap; #[derive(Debug, Clone, Serialize)] /// Description of the type of trace to make