feat(contract): add helper to query events w/ metadata (block num + tx hash) (#33)
* feat(contract): add helper to query events w/ metadata (block num + tx hash)
This commit is contained in:
parent
833ca33f60
commit
7a17e54fbd
|
@ -4,13 +4,14 @@ use ethers_providers::{FilterStream, JsonRpcClient, Provider};
|
|||
|
||||
use ethers_core::{
|
||||
abi::{Detokenize, Event as AbiEvent, RawLog},
|
||||
types::{BlockNumber, Filter, Log, ValueOrArray, H256},
|
||||
types::{BlockNumber, Filter, Log, TxHash, ValueOrArray, H256, U64},
|
||||
};
|
||||
|
||||
use futures::stream::{Stream, StreamExt};
|
||||
use std::{collections::HashMap, marker::PhantomData};
|
||||
use std::marker::PhantomData;
|
||||
|
||||
/// Helper for managing the event filter before querying or streaming its logs
|
||||
#[derive(Debug)]
|
||||
#[must_use = "event filters do nothing unless you `query` or `stream` them"]
|
||||
pub struct Event<'a: 'b, 'b, P, D> {
|
||||
/// The event filter's state
|
||||
|
@ -93,16 +94,16 @@ where
|
|||
Ok(events)
|
||||
}
|
||||
|
||||
/// Queries the blockchain for the selected filter and returns a hashmap of
|
||||
/// txhash -> logs
|
||||
pub async fn query_with_hashes(&self) -> Result<HashMap<H256, D>, ContractError> {
|
||||
/// Queries the blockchain for the selected filter and returns a vector of logs
|
||||
/// along with their metadata
|
||||
pub async fn query_with_meta(&self) -> Result<Vec<(D, LogMeta)>, ContractError> {
|
||||
let logs = self.provider.get_logs(&self.filter).await?;
|
||||
let events = logs
|
||||
.into_iter()
|
||||
.map(|log| {
|
||||
let tx_hash = log.transaction_hash.expect("should have tx hash");
|
||||
let meta = LogMeta::from(&log);
|
||||
let event = self.parse_log(log)?;
|
||||
Ok((tx_hash, event))
|
||||
Ok((event, meta))
|
||||
})
|
||||
.collect::<Result<_, ContractError>>()?;
|
||||
Ok(events)
|
||||
|
@ -125,3 +126,22 @@ where
|
|||
Ok(D::from_tokens(tokens)?)
|
||||
}
|
||||
}
|
||||
|
||||
/// Metadata inside a log
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct LogMeta {
|
||||
/// The block in which the log was emitted
|
||||
pub block_number: U64,
|
||||
|
||||
/// The transaction hash in which the log was emitted
|
||||
pub transaction_hash: TxHash,
|
||||
}
|
||||
|
||||
impl From<&Log> for LogMeta {
|
||||
fn from(src: &Log) -> Self {
|
||||
LogMeta {
|
||||
block_number: src.block_number.expect("should have a block number"),
|
||||
transaction_hash: src.transaction_hash.expect("should have a tx hash"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ use crate::{Contract, ContractError};
|
|||
|
||||
use ethers_core::{
|
||||
abi::{Abi, Tokenize},
|
||||
types::{Bytes, TransactionRequest},
|
||||
types::{BlockNumber, Bytes, TransactionRequest},
|
||||
};
|
||||
use ethers_providers::JsonRpcClient;
|
||||
use ethers_signers::{Client, Signer};
|
||||
|
@ -15,6 +15,7 @@ pub struct Deployer<'a, P, S> {
|
|||
abi: Abi,
|
||||
client: &'a Client<P, S>,
|
||||
confs: usize,
|
||||
block: BlockNumber,
|
||||
}
|
||||
|
||||
impl<'a, P, S> Deployer<'a, P, S>
|
||||
|
@ -28,11 +29,19 @@ where
|
|||
self
|
||||
}
|
||||
|
||||
pub fn block<T: Into<BlockNumber>>(mut self, block: T) -> Self {
|
||||
self.block = block.into();
|
||||
self
|
||||
}
|
||||
|
||||
/// Broadcasts the contract deployment transaction and after waiting for it to
|
||||
/// be sufficiently confirmed (default: 1), it returns a [`Contract`](crate::Contract)
|
||||
/// struct at the deployed contract's address.
|
||||
pub async fn send(self) -> Result<Contract<'a, P, S>, ContractError> {
|
||||
let pending_tx = self.client.send_transaction(self.tx, None).await?;
|
||||
let pending_tx = self
|
||||
.client
|
||||
.send_transaction(self.tx, Some(self.block))
|
||||
.await?;
|
||||
|
||||
let receipt = pending_tx.confirmations(self.confs).await?;
|
||||
|
||||
|
@ -159,6 +168,7 @@ where
|
|||
abi: self.abi,
|
||||
tx,
|
||||
confs: 1,
|
||||
block: BlockNumber::Latest,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -176,6 +176,7 @@ mod celo_tests {
|
|||
use ethers::{
|
||||
providers::{Http, Provider},
|
||||
signers::Wallet,
|
||||
types::BlockNumber,
|
||||
};
|
||||
use std::convert::TryFrom;
|
||||
|
||||
|
@ -195,7 +196,7 @@ mod celo_tests {
|
|||
|
||||
let factory = ContractFactory::new(abi, bytecode, &client);
|
||||
let deployer = factory.deploy("initial value".to_string()).unwrap();
|
||||
let contract = deployer.send().await.unwrap();
|
||||
let contract = deployer.block(BlockNumber::Pending).send().await.unwrap();
|
||||
|
||||
let value: String = contract
|
||||
.method("getValue", ())
|
||||
|
|
Loading…
Reference in New Issue