Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crates/evm-helpers/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ futures.workspace = true
futures-util.workspace = true
once_cell.workspace = true
tokio.workspace = true
tracing.workspace = true
29 changes: 11 additions & 18 deletions crates/evm-helpers/src/contracts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,8 +164,8 @@ pub trait EnclaveWrite {
}

/// Generic type to represent different provider types
pub trait ProviderType: Send {
type Provider: Provider + Send + Sync + 'static;
pub trait ProviderType: Clone + Send + Sync + 'static {
type Provider: Provider + Clone + Send + Sync + 'static;
}

/// Marker type for read-only provider
Expand All @@ -190,6 +190,15 @@ pub struct EnclaveContract<T: ProviderType> {
_marker: PhantomData<T>,
}

impl<R: ProviderType> EnclaveContract<R> {
pub fn address(&self) -> &Address {
&self.contract_address
}
pub fn get_provider(&self) -> Arc<R::Provider> {
self.provider.clone()
}
}

impl EnclaveContract<ReadWrite> {
pub async fn new(
http_rpc_url: &str,
Expand All @@ -198,14 +207,6 @@ impl EnclaveContract<ReadWrite> {
) -> Result<EnclaveContract<ReadWrite>> {
EnclaveContractFactory::create_write(http_rpc_url, contract_address, private_key).await
}

pub fn get_provider(&self) -> Arc<EnclaveWriteProvider> {
self.provider.clone()
}

pub fn address(&self) -> &Address {
&self.contract_address
}
}

impl EnclaveContract<ReadOnly> {
Expand All @@ -215,14 +216,6 @@ impl EnclaveContract<ReadOnly> {
) -> Result<EnclaveContract<ReadOnly>> {
EnclaveContractFactory::create_read(http_rpc_url, contract_address).await
}

pub fn get_provider(&self) -> Arc<EnclaveReadOnlyProvider> {
self.provider.clone()
}

pub fn address(&self) -> &Address {
&self.contract_address
}
}

/// Type alias for read-only provider
Expand Down
21 changes: 11 additions & 10 deletions crates/evm-helpers/src/listener.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ use eyre::Result;
use futures::stream::StreamExt;
use futures_util::future::FutureExt;
use std::{collections::HashMap, future::Future, pin::Pin, sync::Arc};
use tokio::{sync::RwLock, task::JoinHandle};
use tokio::sync::RwLock;
use tracing::info;

type EventHandler =
Box<dyn Fn(&Log) -> Pin<Box<dyn Future<Output = Result<()>> + Send>> + Send + Sync>;
Expand All @@ -36,7 +37,7 @@ impl EventListener {
}
}

pub async fn add_event_handler<E, F, Fut>(&mut self, handler: F)
pub async fn add_event_handler<E, F, Fut>(&self, handler: F)
where
E: SolEvent + Send + Clone + 'static,
F: Fn(E) -> Fut + Send + Sync + 'static,
Expand All @@ -63,7 +64,7 @@ impl EventListener {
.push(wrapped_handler);
}

async fn listen(&self) -> Result<()> {
pub async fn listen(&self) -> Result<()> {
let mut stream = self
.provider
.subscribe_logs(&self.filter)
Expand All @@ -89,14 +90,14 @@ impl EventListener {
Ok(())
}

pub fn start(&self) -> JoinHandle<Result<()>> {
let this = self.clone();
tokio::spawn(async move { this.listen().await })
}

pub async fn create_contract_listener(ws_url: &str, contract_address: &str) -> Result<Self> {
/// Create a contract listener that will listen to events from all addresses.
pub async fn create_contract_listener(ws_url: &str, addresses: &[&str]) -> Result<Self> {
let provider = Arc::new(ProviderBuilder::new().connect(ws_url).await?);
let address = contract_address.parse::<Address>()?;

let address = addresses
.iter()
.map(|a| a.parse::<Address>().map_err(|e| eyre::eyre!("{e}")))
.collect::<Result<Vec<_>>>()?;
let filter = Filter::new()
.address(address)
.from_block(BlockNumberOrTag::Latest);
Expand Down
35 changes: 22 additions & 13 deletions crates/evm-helpers/tests/integration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@ use alloy::sol;
use e3_evm_helpers::listener::EventListener;
use eyre::Result;
use helpers::setup_logs_contract;
use std::time::{Duration, SystemTime, UNIX_EPOCH};
use std::{
sync::Arc,
time::{Duration, SystemTime, UNIX_EPOCH},
};
use tokio::time::sleep;

sol!(
Expand All @@ -25,11 +28,13 @@ async fn test_event_listener() -> Result<()> {
let (tx, mut rx) = tokio::sync::mpsc::channel::<String>(10);
let (tx_addr, mut rx_addr) = tokio::sync::mpsc::channel::<String>(10);

let mut event_listener = EventListener::create_contract_listener(
&anvil.ws_endpoint(),
&contract.address().to_string(),
)
.await?;
let event_listener = Arc::new(
EventListener::create_contract_listener(
&anvil.ws_endpoint(),
&[&contract.address().to_string()],
)
.await?,
);

event_listener
.add_event_handler(move |event: EmitLogs::ValueChanged| {
Expand All @@ -51,7 +56,8 @@ async fn test_event_listener() -> Result<()> {
})
.await;

event_listener.start();
let spawn_event_listener = event_listener.clone();
let _ = tokio::spawn(async move { spawn_event_listener.listen().await });

contract
.setValue("hello".to_string())
Expand Down Expand Up @@ -104,11 +110,13 @@ async fn test_overlapping_listener_handlers() -> Result<()> {
let (contract, _, _, anvil) = setup_logs_contract().await?;
let (tx, mut rx) = tokio::sync::mpsc::channel::<String>(10);

let mut event_listener = EventListener::create_contract_listener(
&anvil.ws_endpoint(),
&contract.address().to_string(),
)
.await?;
let event_listener = Arc::new(
EventListener::create_contract_listener(
&anvil.ws_endpoint(),
&[&contract.address().to_string()],
)
.await?,
);

let tx1 = tx.clone();
event_listener
Expand Down Expand Up @@ -140,7 +148,8 @@ async fn test_overlapping_listener_handlers() -> Result<()> {
})
.await;

event_listener.start();
let spawn_event_listener = event_listener.clone();
let _ = tokio::spawn(async move { spawn_event_listener.listen().await });

// Events should be returned roughly in this order:
// 0ms : one
Expand Down
1 change: 1 addition & 0 deletions crates/indexer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@ eyre.workspace = true
serde.workspace = true
thiserror.workspace = true
tokio.workspace = true
tracing.workspace = true
Loading
Loading