From 6814e8cc938142c2d362401ede73b98e32ae4c93 Mon Sep 17 00:00:00 2001 From: ryardley Date: Tue, 25 Nov 2025 20:11:11 +0000 Subject: [PATCH 01/33] add threshold queue --- crates/evm-helpers/src/threshold_queue.rs | 126 ++++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 crates/evm-helpers/src/threshold_queue.rs diff --git a/crates/evm-helpers/src/threshold_queue.rs b/crates/evm-helpers/src/threshold_queue.rs new file mode 100644 index 0000000000..91225a8b76 --- /dev/null +++ b/crates/evm-helpers/src/threshold_queue.rs @@ -0,0 +1,126 @@ +// SPDX-License-Identifier: LGPL-3.0-only +// +// This file is provided WITHOUT ANY WARRANTY; +// without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. + +use std::{ + cmp::Reverse, + collections::BinaryHeap, + sync::{Arc, RwLock}, +}; + +#[derive(Clone)] +/// An implementation of a ThresholdQueue. This enables releasing elements from a collection when +/// the given timestamp is reached or a given count has reached a certain threshold. +pub struct ThresholdQueue { + inner: Arc>>>, +} + +/// An item that can be added to a threshold queue +pub trait ThresholdItem: Ord { + type Item; + fn within_threshold(&self, threshold: u64) -> bool; + fn item(&self) -> Self::Item; +} + +impl ThresholdQueue +where + T: ThresholdItem, +{ + /// Create a new ThresholdQueue + pub fn new() -> Self { + Self { + inner: Arc::new(RwLock::new(BinaryHeap::new())), + } + } + + /// Push an item onto the queue + pub fn push(&self, item: T) { + self.inner + .write() + .expect("Poisoned write in ThresholdQueue") + .push(Reverse(item)); + } + + /// Keep taking items off the queue until `item.within_threshold(threshold)` returns false + pub fn take_until_including(&self, threshold: u64) -> Vec { + let mut found = Vec::new(); + let mut inner = self + .inner + .write() + .expect("Poisoned write in ThresholdQueue"); + + while let Some(Reverse(item)) = inner.peek() { + if item.within_threshold(threshold) { + if let Some(Reverse(item)) = inner.pop() { + found.push(item.item()); + } + } else { + break; + } + } + + found + } +} + +#[cfg(test)] +mod tests { + use super::{ThresholdItem, ThresholdQueue}; + + struct ThreshItem { + val: u64, + rank: u64, + } + + impl Eq for ThreshItem {} + + impl PartialEq for ThreshItem { + fn eq(&self, other: &Self) -> bool { + self.rank == other.rank + } + } + + impl PartialOrd for ThreshItem { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } + } + + impl Ord for ThreshItem { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + self.rank.cmp(&other.rank) + } + } + + impl ThresholdItem for ThreshItem { + type Item = u64; + fn item(&self) -> Self::Item { + self.val + } + + fn within_threshold(&self, threshold: u64) -> bool { + self.rank <= threshold + } + } + + #[test] + fn test_collection_is_ordered() { + let queue = ThresholdQueue::new(); + queue.push(ThreshItem { val: 111, rank: 25 }); + queue.push(ThreshItem { + val: 666, + rank: 100, + }); + queue.push(ThreshItem { val: 444, rank: 70 }); + queue.push(ThreshItem { val: 222, rank: 26 }); + let items = queue.take_until_including(70); + + assert_eq!(items, vec![111, 222, 444]); + + let items = queue.take_until_including(101); + + assert_eq!(items, vec![666]); + } +} From 80734fd1fcbe2dcbbc976cb6cf8f07e9fb852515 Mon Sep 17 00:00:00 2001 From: ryardley Date: Tue, 25 Nov 2025 20:19:02 +0000 Subject: [PATCH 02/33] add callback queue --- crates/evm-helpers/src/lib.rs | 1 + crates/evm-helpers/src/threshold_queue.rs | 4 + crates/indexer/src/callback_queue.rs | 181 ++++++++++++++++++++++ crates/indexer/src/lib.rs | 1 + 4 files changed, 187 insertions(+) create mode 100644 crates/indexer/src/callback_queue.rs diff --git a/crates/evm-helpers/src/lib.rs b/crates/evm-helpers/src/lib.rs index da02ad0519..7c343cc998 100644 --- a/crates/evm-helpers/src/lib.rs +++ b/crates/evm-helpers/src/lib.rs @@ -7,3 +7,4 @@ pub mod contracts; pub mod events; pub mod listener; +pub mod threshold_queue; diff --git a/crates/evm-helpers/src/threshold_queue.rs b/crates/evm-helpers/src/threshold_queue.rs index 91225a8b76..f93a4bffe9 100644 --- a/crates/evm-helpers/src/threshold_queue.rs +++ b/crates/evm-helpers/src/threshold_queue.rs @@ -20,7 +20,11 @@ pub struct ThresholdQueue { /// An item that can be added to a threshold queue pub trait ThresholdItem: Ord { type Item; + + /// Defines what it means to be withing the threshold eg self.myprop <= threshold fn within_threshold(&self, threshold: u64) -> bool; + + /// Access the inner item this wraps fn item(&self) -> Self::Item; } diff --git a/crates/indexer/src/callback_queue.rs b/crates/indexer/src/callback_queue.rs new file mode 100644 index 0000000000..f818b122e3 --- /dev/null +++ b/crates/indexer/src/callback_queue.rs @@ -0,0 +1,181 @@ +// SPDX-License-Identifier: LGPL-3.0-only +// +// This file is provided WITHOUT ANY WARRANTY; +// without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. + +use e3_evm_helpers::threshold_queue::{ThresholdItem, ThresholdQueue}; +use eyre::Result; +use std::{future::Future, pin::Pin, sync::Arc}; +use tracing::info; + +/// Callback for CallbackQueue +type Callback = Arc Pin> + Send>> + Send + Sync>; + +#[derive(Clone)] +/// A callback that has an execute time associated with it +pub struct TimedCallback { + time: u64, + callback: Callback, +} + +impl ThresholdItem for TimedCallback { + type Item = Callback; + + fn item(&self) -> Self::Item { + self.callback.clone() + } + + fn within_threshold(&self, threshold: u64) -> bool { + self.time <= threshold + } +} + +// We need to ensure Ord is satisfied to use this in the threshold queue +impl Eq for TimedCallback {} + +impl PartialEq for TimedCallback { + fn eq(&self, other: &Self) -> bool { + self.time == other.time + } +} + +impl PartialOrd for TimedCallback { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl Ord for TimedCallback { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + self.time.cmp(&other.time) + } +} + +#[derive(Clone)] +/// A queue of callbacks that can be executed when a given timestamp has been passed. This is a +/// specialization of a ThresholdQueue. +pub struct CallbackQueue { + inner: ThresholdQueue, +} + +impl CallbackQueue { + /// Create a new queue + pub fn new() -> Self { + Self { + inner: ThresholdQueue::new(), + } + } + + /// Push a callback to the queue to be executed at or before the given time. + pub fn push(&mut self, time: u64, callback: F) + where + F: Fn() -> Fut + Send + Sync + 'static, + Fut: Future> + Send + 'static, + { + info!("ADDING CALLBACK TO time={}", time); + self.inner.push(TimedCallback { + time, + callback: Arc::new(move || Box::pin(callback())), + }) + } + + /// Execute all pending callbacks up to and including the given time + pub async fn execute_until_including(&self, time: u64) -> Result<()> { + info!("execute_until_including..."); + let handlers = self.inner.take_until_including(time); + info!("found {} handlers", handlers.len()); + for callback in handlers { + callback().await?; + } + Ok(()) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use std::sync::{Arc, Mutex}; + + #[tokio::test] + async fn test_single_callback_executes() { + let mut queue = CallbackQueue::new(); + let called = Arc::new(Mutex::new(false)); + let called_clone = called.clone(); + + queue.push(100, move || { + let called = called_clone.clone(); + async move { + *called.lock().unwrap() = true; + Ok(()) + } + }); + + queue.execute_until_including(100).await.unwrap(); + assert!(*called.lock().unwrap()); + } + + #[tokio::test] + async fn test_callback_not_executed_before_threshold() { + let mut queue = CallbackQueue::new(); + let called = Arc::new(Mutex::new(false)); + let called_clone = called.clone(); + + queue.push(100, move || { + let called = called_clone.clone(); + async move { + *called.lock().unwrap() = true; + Ok(()) + } + }); + + queue.execute_until_including(50).await.unwrap(); + assert!(!*called.lock().unwrap()); + } + + #[tokio::test] + async fn test_multiple_callbacks_execute() { + let mut queue = CallbackQueue::new(); + let counter = Arc::new(Mutex::new(0)); + + let c1 = counter.clone(); + queue.push(50, move || { + let c = c1.clone(); + async move { + *c.lock().unwrap() += 1; + Ok(()) + } + }); + + let c2 = counter.clone(); + queue.push(100, move || { + let c = c2.clone(); + async move { + *c.lock().unwrap() += 1; + Ok(()) + } + }); + + let c3 = counter.clone(); + queue.push(150, move || { + let c = c3.clone(); + async move { + *c.lock().unwrap() += 1; + Ok(()) + } + }); + + queue.execute_until_including(100).await.unwrap(); + assert_eq!(*counter.lock().unwrap(), 2); + } + + #[tokio::test] + async fn test_error_propagation() { + let mut queue = CallbackQueue::new(); + + queue.push(100, || async { Err(eyre::eyre!("test error")) }); + + let result = queue.execute_until_including(100).await; + assert!(result.is_err()); + } +} diff --git a/crates/indexer/src/lib.rs b/crates/indexer/src/lib.rs index b42c0bff8c..1a377cd1ac 100644 --- a/crates/indexer/src/lib.rs +++ b/crates/indexer/src/lib.rs @@ -4,6 +4,7 @@ // without even the implied warranty of MERCHANTABILITY // or FITNESS FOR A PARTICULAR PURPOSE. +mod callback_queue; mod indexer; pub mod models; mod repo; From 771075d0585b5a9df641ec1f39e9c871c158c13c Mon Sep 17 00:00:00 2001 From: ryardley Date: Tue, 25 Nov 2025 20:57:31 +0000 Subject: [PATCH 03/33] add blocklistener that does not do much --- crates/evm-helpers/src/block_listener.rs | 58 ++++++++++++++++ .../src/{listener.rs => event_listener.rs} | 7 +- crates/evm-helpers/src/lib.rs | 3 +- crates/indexer/src/indexer.rs | 67 ++++++++++++------- 4 files changed, 109 insertions(+), 26 deletions(-) create mode 100644 crates/evm-helpers/src/block_listener.rs rename crates/evm-helpers/src/{listener.rs => event_listener.rs} (95%) diff --git a/crates/evm-helpers/src/block_listener.rs b/crates/evm-helpers/src/block_listener.rs new file mode 100644 index 0000000000..0e75c58ea7 --- /dev/null +++ b/crates/evm-helpers/src/block_listener.rs @@ -0,0 +1,58 @@ +// SPDX-License-Identifier: LGPL-3.0-only +// +// This file is provided WITHOUT ANY WARRANTY; +// without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. + +use alloy::{consensus::Header, network::Ethereum, providers::Provider}; +use eyre::Result; +use futures::stream::StreamExt; +use std::{future::Future, pin::Pin, sync::Arc}; +use tokio::sync::RwLock; +use tracing::info; + +type BlockHandler = + Box Pin> + Send>> + Send + Sync>; + +#[derive(Clone)] +pub struct BlockListener { + provider: Arc>, + block_handlers: Arc>>, +} + +impl BlockListener { + pub fn new(provider: Arc>) -> Self { + Self { + provider, + block_handlers: Arc::new(RwLock::new(Vec::new())), + } + } + + pub async fn add_block_handler(&self, handler: F) + where + F: Fn(&Header) -> Fut + Send + Sync + 'static, + Fut: Future> + Send + 'static, + { + info!("add_block_handler"); + self.block_handlers + .write() + .await + .push(Box::new(move |h: &Header| Box::pin(handler(h)))); + } + + pub async fn listen(&self) -> Result<()> { + let mut stream = self.provider.subscribe_blocks().await?.into_stream(); + while let Some(block) = stream.next().await { + let handlers = self.block_handlers.read().await; + for handler in handlers.iter() { + let fut = handler(&block); + tokio::spawn(async move { + if let Err(e) = fut.await { + eprintln!("Error processing block: {:?}", e); + } + }); + } + } + Ok(()) + } +} diff --git a/crates/evm-helpers/src/listener.rs b/crates/evm-helpers/src/event_listener.rs similarity index 95% rename from crates/evm-helpers/src/listener.rs rename to crates/evm-helpers/src/event_listener.rs index 76e2d97d9e..7c67c420bb 100644 --- a/crates/evm-helpers/src/listener.rs +++ b/crates/evm-helpers/src/event_listener.rs @@ -16,14 +16,13 @@ use futures::stream::StreamExt; use futures_util::future::FutureExt; use std::{collections::HashMap, future::Future, pin::Pin, sync::Arc}; use tokio::sync::RwLock; -use tracing::info; type EventHandler = Box Pin> + Send>> + Send + Sync>; #[derive(Clone)] pub struct EventListener { - provider: Arc>, + provider: Arc>, // should this be Ethereum? filter: Filter, handlers: Arc>>>, } @@ -90,6 +89,10 @@ impl EventListener { Ok(()) } + pub fn provider(&self) -> Arc> { + self.provider.clone() + } + /// Create a contract listener that will listen to events from all addresses. pub async fn create_contract_listener(ws_url: &str, addresses: &[&str]) -> Result { let provider = Arc::new(ProviderBuilder::new().connect(ws_url).await?); diff --git a/crates/evm-helpers/src/lib.rs b/crates/evm-helpers/src/lib.rs index 7c343cc998..9af64694c9 100644 --- a/crates/evm-helpers/src/lib.rs +++ b/crates/evm-helpers/src/lib.rs @@ -4,7 +4,8 @@ // without even the implied warranty of MERCHANTABILITY // or FITNESS FOR A PARTICULAR PURPOSE. +pub mod block_listener; pub mod contracts; +pub mod event_listener; pub mod events; -pub mod listener; pub mod threshold_queue; diff --git a/crates/indexer/src/indexer.rs b/crates/indexer/src/indexer.rs index e17b755133..73c7ae7543 100644 --- a/crates/indexer/src/indexer.rs +++ b/crates/indexer/src/indexer.rs @@ -13,11 +13,12 @@ use alloy::providers::Provider; use alloy::sol_types::SolEvent; use async_trait::async_trait; use e3_evm_helpers::{ + block_listener::BlockListener, contracts::{ EnclaveContract, EnclaveContractFactory, EnclaveRead, ProviderType, ReadOnly, ReadWrite, }, + event_listener::EventListener, events::{CiphertextOutputPublished, E3Activated, PlaintextOutputPublished}, - listener::EventListener, }; use eyre::eyre; use eyre::Result; @@ -26,7 +27,7 @@ use std::future::Future; use std::{collections::HashMap, sync::Arc}; use thiserror::Error; use tokio::sync::RwLock; -use tracing::info; +use tracing::{error, info, warn}; type E3Id = u64; @@ -157,7 +158,8 @@ impl Drop for EnclaveIndexer { pub struct IndexerContext { store: SharedStore, - listener: EventListener, + event_listener: EventListener, + block_listener: BlockListener, contract: EnclaveContract, contract_address: String, chain_id: u64, @@ -168,9 +170,14 @@ impl IndexerContext { self.store.clone() } - pub fn listener(&self) -> EventListener { - self.listener.clone() + pub fn event_listener(&self) -> EventListener { + self.event_listener.clone() } + + pub fn block_listener(&self) -> BlockListener { + self.block_listener.clone() + } + pub fn contract(&self) -> EnclaveContract { self.contract.clone() } @@ -185,12 +192,12 @@ impl IndexerContext { impl EnclaveIndexer { pub async fn new_with_in_mem_store( - listener: EventListener, + event_listener: EventListener, contract: EnclaveContract, ) -> Result> { let store = InMemoryStore::new(); - EnclaveIndexer::new(listener, contract, store).await + EnclaveIndexer::new(event_listener, contract, store).await } } @@ -199,9 +206,10 @@ impl EnclaveIndexer { /// /// Note: `addresses[0]` must be the enclave contract address. pub async fn from_endpoint_address_in_mem(ws_url: &str, addresses: &[&str]) -> Result { - let listener = EventListener::create_contract_listener(ws_url, addresses).await?; + let event_listener = EventListener::create_contract_listener(ws_url, addresses).await?; let contract = EnclaveContractFactory::create_read(ws_url, addresses[0]).await?; - EnclaveIndexer::::new_with_in_mem_store(listener, contract).await + EnclaveIndexer::::new_with_in_mem_store(event_listener, contract) + .await } /// Creates an `EnclaveIndexer` with a provided in-memory store. @@ -212,9 +220,9 @@ impl EnclaveIndexer { addresses: &[&str], store: InMemoryStore, ) -> Result { - let listener = EventListener::create_contract_listener(ws_url, addresses).await?; + let event_listener = EventListener::create_contract_listener(ws_url, addresses).await?; let contract = EnclaveContractFactory::create_read(ws_url, addresses[0]).await?; - EnclaveIndexer::new(listener, contract, store).await + EnclaveIndexer::new(event_listener, contract, store).await } } @@ -229,8 +237,9 @@ impl EnclaveIndexer { let Some(contract_address) = addresses.first() else { return Err(eyre::eyre!("No addresses provided")); }; + let event_listener = EventListener::create_contract_listener(ws_url, addresses).await?; EnclaveIndexer::new( - EventListener::create_contract_listener(ws_url, addresses).await?, + event_listener, EnclaveContractFactory::create_write(ws_url, contract_address, private_key).await?, store, ) @@ -240,17 +249,19 @@ impl EnclaveIndexer { impl EnclaveIndexer { pub async fn new( - listener: EventListener, + event_listener: EventListener, contract: EnclaveContract, store: S, ) -> Result { let chain_id = contract.provider.get_chain_id().await?; let contract_address = contract.address().to_string(); + let block_listener = BlockListener::new(event_listener.provider()); let mut instance = Self { ctx: Arc::new(IndexerContext { store: SharedStore::new(Arc::new(RwLock::new(store))), contract, - listener, + event_listener, + block_listener, contract_address, chain_id, }), @@ -274,7 +285,7 @@ impl EnclaveIndexer { let ctx_weak = Arc::downgrade(&ctx); self.ctx - .listener + .event_listener .add_event_handler(move |e: E| { let handler = Arc::clone(&handler); let ctx_weak = ctx_weak.clone(); @@ -285,7 +296,7 @@ impl EnclaveIndexer { if let Some(ctx) = ctx_weak.upgrade() { handler(e, ctx).await } else { - println!("Context was dropped!"); + warn!("Context was dropped!"); Ok(()) } } @@ -349,7 +360,7 @@ impl EnclaveIndexer { async fn register_ciphertext_output_published(&mut self) -> Result<()> { self.add_event_handler(move |e: CiphertextOutputPublished, ctx| async move { let store = ctx.store(); - println!( + info!( "CiphertextOutputPublished: e3_id={}, output=0x{}...", e.e3Id, hex::encode(&e.ciphertextOutput[..8.min(e.ciphertextOutput.len())]) @@ -369,7 +380,7 @@ impl EnclaveIndexer { async fn register_plaintext_output_published(&mut self) -> Result<()> { self.add_event_handler(move |e: PlaintextOutputPublished, ctx| async move { let store = ctx.store(); - println!( + info!( "PlaintextOutputPublished: e3_id={}, output=0x{}...", e.e3Id, hex::encode(&e.plaintextOutput[..8.min(e.plaintextOutput.len())]) @@ -396,7 +407,21 @@ impl EnclaveIndexer { pub async fn listen(&self) -> Result<()> { info!("Starting EnclaveIndexer listening..."); - self.ctx.listener.listen().await + tokio::select! { + res = self.ctx.event_listener.listen() => { + match res { + Ok(_) => warn!("EventListener curiously halted naturally."), + Err(e) => error!("EventListener halted with an error: {e}") + } + } + res = self.ctx.block_listener.listen() => { + match res { + Ok(_) => warn!("BlockListener curiously halted naturally."), + Err(e) => error!("BlockListener halted with an error: {e}") + } + } + } + Ok(()) } pub async fn get_e3(&self, e3_id: u64) -> Result { @@ -404,10 +429,6 @@ impl EnclaveIndexer { Ok(e3) } - pub fn get_listener(&self) -> EventListener { - self.ctx.listener.clone() - } - pub fn get_store(&self) -> SharedStore { self.ctx.store.clone() } From e035e94afc52c7a588264bcdb11a3f8a918b862b Mon Sep 17 00:00:00 2001 From: ryardley Date: Tue, 25 Nov 2025 22:05:04 +0000 Subject: [PATCH 04/33] add block listener test --- crates/evm-helpers/src/block_listener.rs | 4 +- crates/evm-helpers/tests/integration.rs | 53 +++++++++++++++++++++++- crates/indexer/tests/integration.rs | 2 +- 3 files changed, 54 insertions(+), 5 deletions(-) diff --git a/crates/evm-helpers/src/block_listener.rs b/crates/evm-helpers/src/block_listener.rs index 0e75c58ea7..ec7af25ad3 100644 --- a/crates/evm-helpers/src/block_listener.rs +++ b/crates/evm-helpers/src/block_listener.rs @@ -4,7 +4,7 @@ // without even the implied warranty of MERCHANTABILITY // or FITNESS FOR A PARTICULAR PURPOSE. -use alloy::{consensus::Header, network::Ethereum, providers::Provider}; +use alloy::{network::Ethereum, providers::Provider, rpc::types::Header}; use eyre::Result; use futures::stream::StreamExt; use std::{future::Future, pin::Pin, sync::Arc}; @@ -28,7 +28,7 @@ impl BlockListener { } } - pub async fn add_block_handler(&self, handler: F) + pub async fn add_block_handler(&self, handler: F) where F: Fn(&Header) -> Fut + Send + Sync + 'static, Fut: Future> + Send + 'static, diff --git a/crates/evm-helpers/tests/integration.rs b/crates/evm-helpers/tests/integration.rs index 34077de664..f9bac54c4f 100644 --- a/crates/evm-helpers/tests/integration.rs +++ b/crates/evm-helpers/tests/integration.rs @@ -5,14 +5,19 @@ // or FITNESS FOR A PARTICULAR PURPOSE. mod helpers; -use alloy::sol; -use e3_evm_helpers::listener::EventListener; +use alloy::consensus::BlockHeader; +use alloy::providers::ext::AnvilApi; +use alloy::{node_bindings::Anvil, providers::ProviderBuilder, sol}; +use e3_evm_helpers::block_listener; +use e3_evm_helpers::{block_listener::BlockListener, event_listener::EventListener}; use eyre::Result; use helpers::setup_logs_contract; use std::{ sync::Arc, time::{Duration, SystemTime, UNIX_EPOCH}, }; +use tokio::sync::Mutex; + use tokio::time::sleep; sol!( @@ -202,3 +207,47 @@ async fn test_overlapping_listener_handlers() -> Result<()> { Ok(()) } + +#[tokio::test] +async fn test_block_listener() -> Result<()> { + let anvil = Anvil::new().try_spawn()?; + let provider = Arc::new(ProviderBuilder::new().connect(&anvil.ws_endpoint()).await?); + let block_listener = Arc::new(BlockListener::new(provider.clone())); + let events: Arc>> = Arc::new(Mutex::new(vec![])); + let events_handler = events.clone(); + + // Save each block number to a vector. + block_listener + .add_block_handler(move |block| { + let events = events_handler.clone(); + let blockheight = block.number(); + async move { + let mut events = events.lock().await; + events.push(blockheight); + Ok(()) + } + }) + .await; + + // Start up a listener + let listen_handle = tokio::spawn(async move { + let _ = block_listener.listen().await; + }); + + // Give the listener time to start + sleep(Duration::from_millis(100)).await; + + // Mine a few blocks + provider.anvil_mine(Some(5), None).await?; + + // Wait for the block to be processed + sleep(Duration::from_secs(1)).await; + + // Cancel the listener + listen_handle.abort(); + + let guard = events.lock().await; + assert_eq!(*guard, vec![1, 2, 3, 4, 5]); + + Ok(()) +} diff --git a/crates/indexer/tests/integration.rs b/crates/indexer/tests/integration.rs index dc63325587..451ec3fe01 100644 --- a/crates/indexer/tests/integration.rs +++ b/crates/indexer/tests/integration.rs @@ -186,7 +186,7 @@ async fn test_indexer() -> Result<()> { mod test_memory_leak { - use e3_evm_helpers::{contracts::EnclaveContractFactory, listener::EventListener}; + use e3_evm_helpers::{contracts::EnclaveContractFactory, event_listener::EventListener}; use super::*; use std::sync::atomic::{AtomicUsize, Ordering}; From b1de7049ad7f50f42337c6792b0fa35b4c273f7e Mon Sep 17 00:00:00 2001 From: ryardley Date: Tue, 25 Nov 2025 22:18:41 +0000 Subject: [PATCH 05/33] loop restart --- crates/indexer/src/indexer.rs | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/crates/indexer/src/indexer.rs b/crates/indexer/src/indexer.rs index 73c7ae7543..1551a281d1 100644 --- a/crates/indexer/src/indexer.rs +++ b/crates/indexer/src/indexer.rs @@ -23,10 +23,10 @@ use e3_evm_helpers::{ use eyre::eyre; use eyre::Result; use serde::{de::DeserializeOwned, Serialize}; -use std::future::Future; use std::{collections::HashMap, sync::Arc}; +use std::{future::Future, time::Duration}; use thiserror::Error; -use tokio::sync::RwLock; +use tokio::{sync::RwLock, time::sleep}; use tracing::{error, info, warn}; type E3Id = u64; @@ -407,21 +407,28 @@ impl EnclaveIndexer { pub async fn listen(&self) -> Result<()> { info!("Starting EnclaveIndexer listening..."); - tokio::select! { - res = self.ctx.event_listener.listen() => { - match res { - Ok(_) => warn!("EventListener curiously halted naturally."), - Err(e) => error!("EventListener halted with an error: {e}") + loop { + let res = tokio::select! { + res = self.ctx.event_listener.listen() => { + match &res { + Ok(_) => warn!("EventListener curiously halted naturally."), + Err(e) => error!("EventListener halted with an error: {e}") + }; + res } - } - res = self.ctx.block_listener.listen() => { - match res { - Ok(_) => warn!("BlockListener curiously halted naturally."), - Err(e) => error!("BlockListener halted with an error: {e}") + res = self.ctx.block_listener.listen() => { + match &res { + Ok(_) => warn!("BlockListener curiously halted naturally."), + Err(e) => error!("BlockListener halted with an error: {e}") + }; + res } - } + }; + + let secs = res.map(|_| 1).unwrap_or(5); + warn!("Restarting listeners in {}s...", secs); + sleep(Duration::from_secs(secs)).await } - Ok(()) } pub async fn get_e3(&self, e3_id: u64) -> Result { From fb31b0d0b55cb81cc88dcadc9ac8946b5225c6ef Mon Sep 17 00:00:00 2001 From: ryardley Date: Wed, 26 Nov 2025 01:15:55 +0000 Subject: [PATCH 06/33] listen for blocks and add do_later to context --- crates/indexer/src/callback_queue.rs | 2 +- crates/indexer/src/indexer.rs | 41 ++++++++++++++++++++++++++-- 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/crates/indexer/src/callback_queue.rs b/crates/indexer/src/callback_queue.rs index f818b122e3..4a5694a152 100644 --- a/crates/indexer/src/callback_queue.rs +++ b/crates/indexer/src/callback_queue.rs @@ -68,7 +68,7 @@ impl CallbackQueue { } /// Push a callback to the queue to be executed at or before the given time. - pub fn push(&mut self, time: u64, callback: F) + pub fn push(&self, time: u64, callback: F) where F: Fn() -> Fut + Send + Sync + 'static, Fut: Future> + Send + 'static, diff --git a/crates/indexer/src/indexer.rs b/crates/indexer/src/indexer.rs index 1551a281d1..30a6dfff14 100644 --- a/crates/indexer/src/indexer.rs +++ b/crates/indexer/src/indexer.rs @@ -4,9 +4,10 @@ // without even the implied warranty of MERCHANTABILITY // or FITNESS FOR A PARTICULAR PURPOSE. -use crate::E3Repository; - use super::{models::E3, DataStore}; +use crate::callback_queue::CallbackQueue; +use crate::E3Repository; +use alloy::consensus::BlockHeader; use alloy::hex; use alloy::primitives::Uint; use alloy::providers::Provider; @@ -163,6 +164,7 @@ pub struct IndexerContext { contract: EnclaveContract, contract_address: String, chain_id: u64, + callbacks: CallbackQueue, } impl IndexerContext { @@ -188,6 +190,21 @@ impl IndexerContext { pub fn chain_id(&self) -> u64 { self.chain_id } + + pub async fn do_later(self: &Arc, timestamp: u64, callback: F) + where + F: Fn(Arc) -> Fut + Send + Sync + 'static, + Fut: Future> + Send + 'static, + { + let callback = Arc::new(callback); + let ctx = Arc::clone(self); + self.callbacks.push(timestamp, move || { + info!("Running callback: time={}", timestamp); + let callback = Arc::clone(&callback); + let ctx = Arc::clone(&ctx); + callback(ctx) + }) + } } impl EnclaveIndexer { @@ -264,6 +281,7 @@ impl EnclaveIndexer { block_listener, contract_address, chain_id, + callbacks: CallbackQueue::new(), }), }; instance.setup_listeners().await?; @@ -396,11 +414,30 @@ impl EnclaveIndexer { Ok(()) } + async fn register_blocktime_callback_handler(&mut self) -> Result<()> { + let callbacks = self.ctx.callbacks.clone(); + self.ctx + .block_listener + .add_block_handler(move |block| { + let timestamp = block.timestamp(); + let blockheight = block.number(); + let callbacks = callbacks.clone(); + async move { + info!("ON BLOCK: {}:{}", blockheight, timestamp); + callbacks.execute_until_including(timestamp).await?; + Ok(()) + } + }) + .await; + Ok(()) + } + async fn setup_listeners(&mut self) -> Result<()> { info!("Setting up listeners for EnclaveIndexer..."); self.register_e3_activated().await?; self.register_ciphertext_output_published().await?; self.register_plaintext_output_published().await?; + self.register_blocktime_callback_handler().await?; info!("Listeners have been setup!"); Ok(()) } From b4dde8335353272b7f3025d75d89901469280697 Mon Sep 17 00:00:00 2001 From: ryardley Date: Wed, 26 Nov 2025 01:41:32 +0000 Subject: [PATCH 07/33] add test for memory in do_later --- crates/indexer/src/indexer.rs | 13 +++++-- crates/indexer/tests/integration.rs | 57 ++++++++++++++++++++++++++--- 2 files changed, 61 insertions(+), 9 deletions(-) diff --git a/crates/indexer/src/indexer.rs b/crates/indexer/src/indexer.rs index 30a6dfff14..b02cb67648 100644 --- a/crates/indexer/src/indexer.rs +++ b/crates/indexer/src/indexer.rs @@ -191,9 +191,13 @@ impl IndexerContext { self.chain_id } - pub async fn do_later(self: &Arc, timestamp: u64, callback: F) + /// Schedule a callback to execute as or after a block with the given timestamp is processed. + /// + /// Useful for handling deadlines or expirations. The callback receives the scheduled + /// timestamp and a reference to the indexer context. + pub fn do_later(self: &Arc, timestamp: u64, callback: F) where - F: Fn(Arc) -> Fut + Send + Sync + 'static, + F: Fn(u64, Arc) -> Fut + Send + Sync + 'static, Fut: Future> + Send + 'static, { let callback = Arc::new(callback); @@ -202,7 +206,10 @@ impl IndexerContext { info!("Running callback: time={}", timestamp); let callback = Arc::clone(&callback); let ctx = Arc::clone(&ctx); - callback(ctx) + async move { + callback(timestamp, ctx).await?; + Ok(()) + } }) } } diff --git a/crates/indexer/tests/integration.rs b/crates/indexer/tests/integration.rs index 451ec3fe01..ebf31046d2 100644 --- a/crates/indexer/tests/integration.rs +++ b/crates/indexer/tests/integration.rs @@ -223,14 +223,13 @@ mod test_memory_leak { EnclaveIndexer::::new_with_in_mem_store(listener, contract).await } + sol! { + #[derive(Debug)] + event TestEvent(); + } + #[tokio::test] async fn test_memory_leak() -> Result<()> { - sol! { - #[derive(Debug)] - event TestEvent(); - - } - DROP_COUNT.store(0, Ordering::SeqCst); CREATE_COUNT.store(0, Ordering::SeqCst); @@ -269,4 +268,50 @@ mod test_memory_leak { Ok(()) } + + #[tokio::test] + async fn test_do_later_memory_leak() -> Result<()> { + DROP_COUNT.store(0, Ordering::SeqCst); + CREATE_COUNT.store(0, Ordering::SeqCst); + + { + let indexer = create_indexer().await?; + let detector = LeakDetector::new(); + + // Schedule a callback far in the future that will never execute + indexer + .add_event_handler(move |_e: TestEvent, ctx| { + let detector = detector.clone(); + async move { + ctx.do_later(u64::MAX, { + move |_timestamp, _ctx| { + let _captured = detector.clone(); + async move { + println!("This should never run"); + Ok(()) + } + } + }); + + Ok(()) + } + }) + .await; + } + + tokio::time::sleep(tokio::time::Duration::from_millis(100)).await; + + let created = CREATE_COUNT.load(Ordering::SeqCst); + let dropped = DROP_COUNT.load(Ordering::SeqCst); + + println!("Created: {}, Dropped: {}", created, dropped); + + assert_eq!( + created, dropped, + "Memory leak detected in do_later! Created {} objects but only dropped {}", + created, dropped + ); + + Ok(()) + } } From 54706fa70dccb45aa09ffb7448fbf55279373f86 Mon Sep 17 00:00:00 2001 From: ryardley Date: Wed, 26 Nov 2025 02:10:20 +0000 Subject: [PATCH 08/33] use do_later to wait for blocktime --- examples/CRISP/server/src/server/indexer.rs | 126 ++++++++++---------- 1 file changed, 62 insertions(+), 64 deletions(-) diff --git a/examples/CRISP/server/src/server/indexer.rs b/examples/CRISP/server/src/server/indexer.rs index f7f15d9a95..4da948904b 100644 --- a/examples/CRISP/server/src/server/indexer.rs +++ b/examples/CRISP/server/src/server/indexer.rs @@ -199,70 +199,11 @@ pub async fn register_e3_activated( .set_current_round(CurrentRound { id: e3_id }) .await?; - // Calculate expiration time to sleep until - let now = get_current_timestamp_rpc().await?; - info!("[e3_id={}] Current time before sleep: {}", e3_id, now); - let wait_duration = if expiration > now { - let secs = expiration - now; - info!( - "[e3_id={}] Need to wait {} seconds until expiration", - e3_id, secs - ); - Duration::from_secs(secs) - } else { - info!("[e3_id={}] Expired E3", e3_id); - Duration::ZERO - }; - if !wait_duration.is_zero() { - sleep(wait_duration).await; - } - let e3: e3_sdk::indexer::models::E3 = repo.get_e3().await?; - repo.update_status("Expired").await?; - - if repo.get_vote_count().await? > 0 { - info!("[e3_id={}] Starting computation for E3", e3_id); - repo.update_status("Computing").await?; - - let votes = repo.get_ciphertext_inputs().await?; - - let (id, status) = run_compute( - e3_id, - e3.e3_params, - votes, - format!("{}/state/add-result", CONFIG.enclave_server_url), - ) - .await - .map_err(|e| eyre::eyre!("Error sending run compute request: {e}"))?; - - if id != e3_id { - return Err(eyre::eyre!( - "Computation request returned unexpected E3 ID: expected {}, got {}", - e3_id, - id - ) - .into()); - } - - if status != "processing" { - return Err(eyre::eyre!( - "Computation request failed with status: {}", - status - ) - .into()); - } - - info!("[e3_id={}] Request Computation for E3", e3_id); - - repo.update_status("PublishingCiphertext").await?; - } else { - info!( - "[e3_id={}] E3 has no votes to decrypt. Setting status to Finished.", - e3_id - ); - repo.update_status("Finished").await?; - } - info!("[e3_id={}] E3 request handled successfully.", e3_id); - + info!("[e3_id={}] Registering hook for {}", e3_id, expiration); + ctx.do_later(expiration, move |_, ctx| { + info!("Running...."); + handle_e3_input_deadline_expiration(e3_id, ctx.store()) + }); Ok(()) } }) @@ -270,6 +211,58 @@ pub async fn register_e3_activated( Ok(indexer) } +async fn handle_e3_input_deadline_expiration( + e3_id: u64, + store: SharedStore, +) -> eyre::Result<()> { + let mut repo = CrispE3Repository::new(store.clone(), e3_id); + let e3: e3_sdk::indexer::models::E3 = repo.get_e3().await?; + + repo.update_status("Expired").await?; + + if repo.get_vote_count().await? > 0 { + info!("[e3_id={}] Starting computation for E3", e3_id); + repo.update_status("Computing").await?; + + let votes = repo.get_ciphertext_inputs().await?; + + let (id, status) = run_compute( + e3_id, + e3.e3_params, + votes, + format!("{}/state/add-result", CONFIG.enclave_server_url), + ) + .await + .map_err(|e| eyre::eyre!("Error sending run compute request: {e}"))?; + + if id != e3_id { + return Err(eyre::eyre!( + "Computation request returned unexpected E3 ID: expected {}, got {}", + e3_id, + id + ) + .into()); + } + + if status != "processing" { + return Err(eyre::eyre!("Computation request failed with status: {}", status).into()); + } + + info!("[e3_id={}] Request Computation for E3", e3_id); + + repo.update_status("PublishingCiphertext").await?; + } else { + info!( + "[e3_id={}] E3 has no votes to decrypt. Setting status to Finished.", + e3_id + ); + repo.update_status("Finished").await?; + } + info!("[e3_id={}] E3 request handled successfully.", e3_id); + + Ok(()) +} + pub async fn register_ciphertext_output_published( indexer: EnclaveIndexer, ) -> Result> { @@ -357,6 +350,9 @@ pub async fn register_committee_published( let now = get_current_timestamp_rpc().await?; info!("[e3_id={}] Current time: {}", event.e3Id, now); + ////////////////////////////////////////////////////// + // XXX: FIX ME + // Calculate wait duration let wait_duration = if start_time > now { let secs = start_time - now; @@ -376,6 +372,8 @@ pub async fn register_committee_published( sleep(wait_duration).await; } + /////////////////////////////////////////////////////// + // If not activated activate let tx = contract.activate(event.e3Id, event.publicKey).await?; info!( From 3a608e54e573161c2500588b629119a01aed7dcb Mon Sep 17 00:00:00 2001 From: ryardley Date: Wed, 26 Nov 2025 02:32:00 +0000 Subject: [PATCH 09/33] update hardhat config --- examples/CRISP/packages/crisp-contracts/hardhat.config.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/examples/CRISP/packages/crisp-contracts/hardhat.config.ts b/examples/CRISP/packages/crisp-contracts/hardhat.config.ts index f66e4fc52f..1cc1bee9f8 100644 --- a/examples/CRISP/packages/crisp-contracts/hardhat.config.ts +++ b/examples/CRISP/packages/crisp-contracts/hardhat.config.ts @@ -72,6 +72,10 @@ const config: HardhatUserConfig = { chainId: chainIds.hardhat, type: 'edr-simulated', chainType: 'l1', + mining: { + auto: true, + interval: 1000, // mine a block every 1 second + }, }, ganache: { accounts: { From 389a611484ba0a55745d1a1f60dd4ae888487531 Mon Sep 17 00:00:00 2001 From: ryardley Date: Wed, 26 Nov 2025 03:07:10 +0000 Subject: [PATCH 10/33] update hardhat config --- .../packages/crisp-contracts/hardhat.config.ts | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/examples/CRISP/packages/crisp-contracts/hardhat.config.ts b/examples/CRISP/packages/crisp-contracts/hardhat.config.ts index 1cc1bee9f8..95e09d2361 100644 --- a/examples/CRISP/packages/crisp-contracts/hardhat.config.ts +++ b/examples/CRISP/packages/crisp-contracts/hardhat.config.ts @@ -69,13 +69,14 @@ const config: HardhatUserConfig = { accounts: { mnemonic, }, + url: 'http://localhost:8545', chainId: chainIds.hardhat, - type: 'edr-simulated', - chainType: 'l1', - mining: { - auto: true, - interval: 1000, // mine a block every 1 second - }, + type: 'http', + // chainType: 'l1', + // mining: { + // auto: true, + // interval: 1000, // mine a block every 1 second + // }, }, ganache: { accounts: { From b46202a4fdcee1466cf9971c7205acf6989a1c58 Mon Sep 17 00:00:00 2001 From: ryardley Date: Wed, 26 Nov 2025 03:48:51 +0000 Subject: [PATCH 11/33] enable polling mode --- crates/evm-helpers/src/contracts.rs | 8 ++++---- crates/evm-helpers/src/event_listener.rs | 4 ++-- crates/indexer/src/indexer.rs | 18 +++++++++--------- examples/CRISP/server/.env.example | 3 ++- examples/CRISP/server/src/config.rs | 1 + examples/CRISP/server/src/server/indexer.rs | 4 ++-- examples/CRISP/server/src/server/mod.rs | 8 +++++++- 7 files changed, 27 insertions(+), 19 deletions(-) diff --git a/crates/evm-helpers/src/contracts.rs b/crates/evm-helpers/src/contracts.rs index 2fae264586..82926e8088 100644 --- a/crates/evm-helpers/src/contracts.rs +++ b/crates/evm-helpers/src/contracts.rs @@ -250,7 +250,7 @@ pub struct EnclaveContractFactory; impl EnclaveContractFactory { /// Create a write-capable contract pub async fn create_write( - http_rpc_url: &str, + rpc_url: &str, contract_address: &str, private_key: &str, ) -> Result> { @@ -261,7 +261,7 @@ impl EnclaveContractFactory { let wallet = EthereumWallet::from(signer); let provider = ProviderBuilder::new() .wallet(wallet) - .connect(http_rpc_url) + .connect(rpc_url) .await?; Ok(EnclaveContract:: { @@ -274,12 +274,12 @@ impl EnclaveContractFactory { /// Create a read-only contract pub async fn create_read( - http_rpc_url: &str, + rpc_url: &str, contract_address: &str, ) -> Result> { let contract_address = contract_address.parse()?; - let provider = ProviderBuilder::new().connect(http_rpc_url).await?; + let provider = ProviderBuilder::new().connect(rpc_url).await?; Ok(EnclaveContract:: { provider: Arc::new(provider), diff --git a/crates/evm-helpers/src/event_listener.rs b/crates/evm-helpers/src/event_listener.rs index 7c67c420bb..1ac553f49a 100644 --- a/crates/evm-helpers/src/event_listener.rs +++ b/crates/evm-helpers/src/event_listener.rs @@ -94,8 +94,8 @@ impl EventListener { } /// Create a contract listener that will listen to events from all addresses. - pub async fn create_contract_listener(ws_url: &str, addresses: &[&str]) -> Result { - let provider = Arc::new(ProviderBuilder::new().connect(ws_url).await?); + pub async fn create_contract_listener(rpc_url: &str, addresses: &[&str]) -> Result { + let provider = Arc::new(ProviderBuilder::new().connect(rpc_url).await?); let address = addresses .iter() diff --git a/crates/indexer/src/indexer.rs b/crates/indexer/src/indexer.rs index b02cb67648..155823c962 100644 --- a/crates/indexer/src/indexer.rs +++ b/crates/indexer/src/indexer.rs @@ -229,9 +229,9 @@ impl EnclaveIndexer { /// Creates an `EnclaveIndexer` with an in-memory store. /// /// Note: `addresses[0]` must be the enclave contract address. - pub async fn from_endpoint_address_in_mem(ws_url: &str, addresses: &[&str]) -> Result { - let event_listener = EventListener::create_contract_listener(ws_url, addresses).await?; - let contract = EnclaveContractFactory::create_read(ws_url, addresses[0]).await?; + pub async fn from_endpoint_address_in_mem(rpc_url: &str, addresses: &[&str]) -> Result { + let event_listener = EventListener::create_contract_listener(rpc_url, addresses).await?; + let contract = EnclaveContractFactory::create_read(rpc_url, addresses[0]).await?; EnclaveIndexer::::new_with_in_mem_store(event_listener, contract) .await } @@ -240,12 +240,12 @@ impl EnclaveIndexer { /// /// Note: `addresses[0]` must be the enclave contract address. pub async fn from_endpoint_address( - ws_url: &str, + rpc_url: &str, addresses: &[&str], store: InMemoryStore, ) -> Result { - let event_listener = EventListener::create_contract_listener(ws_url, addresses).await?; - let contract = EnclaveContractFactory::create_read(ws_url, addresses[0]).await?; + let event_listener = EventListener::create_contract_listener(rpc_url, addresses).await?; + let contract = EnclaveContractFactory::create_read(rpc_url, addresses[0]).await?; EnclaveIndexer::new(event_listener, contract, store).await } } @@ -253,7 +253,7 @@ impl EnclaveIndexer { impl EnclaveIndexer { /// Creates a new EnclaveIndexer with a writeable contract. pub async fn new_with_write_contract( - ws_url: &str, + rpc_url: &str, addresses: &[&str], // First address must be contract_address store: S, private_key: &str, @@ -261,10 +261,10 @@ impl EnclaveIndexer { let Some(contract_address) = addresses.first() else { return Err(eyre::eyre!("No addresses provided")); }; - let event_listener = EventListener::create_contract_listener(ws_url, addresses).await?; + let event_listener = EventListener::create_contract_listener(rpc_url, addresses).await?; EnclaveIndexer::new( event_listener, - EnclaveContractFactory::create_write(ws_url, contract_address, private_key).await?, + EnclaveContractFactory::create_write(rpc_url, contract_address, private_key).await?, store, ) .await diff --git a/examples/CRISP/server/.env.example b/examples/CRISP/server/.env.example index 78ff8b0759..4816b2d0c7 100644 --- a/examples/CRISP/server/.env.example +++ b/examples/CRISP/server/.env.example @@ -2,9 +2,10 @@ PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 ENCLAVE_SERVER_URL=http://0.0.0.0:4000 HTTP_RPC_URL=http://127.0.0.1:8545 -PROGRAM_SERVER_URL=http://127.0.0.1:13151 WS_RPC_URL=ws://127.0.0.1:8545 +PROGRAM_SERVER_URL=http://127.0.0.1:13151 CHAIN_ID=31337 +RPC_POLLING=1 # Etherscan API key ETHERSCAN_API_KEY="" diff --git a/examples/CRISP/server/src/config.rs b/examples/CRISP/server/src/config.rs index 446cba6d51..b8d2148c6a 100644 --- a/examples/CRISP/server/src/config.rs +++ b/examples/CRISP/server/src/config.rs @@ -16,6 +16,7 @@ pub struct Config { pub private_key: String, pub http_rpc_url: String, pub ws_rpc_url: String, + pub rpc_polling: bool, pub enclave_address: String, pub e3_program_address: String, pub ciphernode_registry_address: String, diff --git a/examples/CRISP/server/src/server/indexer.rs b/examples/CRISP/server/src/server/indexer.rs index 4da948904b..dced87c311 100644 --- a/examples/CRISP/server/src/server/indexer.rs +++ b/examples/CRISP/server/src/server/indexer.rs @@ -423,7 +423,7 @@ pub async fn register_input_published( } pub async fn start_indexer( - ws_url: &str, + url: &str, contract_address: &str, registry_address: &str, crisp_address: &str, @@ -432,7 +432,7 @@ pub async fn start_indexer( ) -> Result<()> { info!("CRISP: Creating indexer..."); let crisp_indexer = EnclaveIndexer::new_with_write_contract( - ws_url, + url, &[contract_address, registry_address, crisp_address], store, private_key, diff --git a/examples/CRISP/server/src/server/mod.rs b/examples/CRISP/server/src/server/mod.rs index 992d577bd3..477bee2580 100644 --- a/examples/CRISP/server/src/server/mod.rs +++ b/examples/CRISP/server/src/server/mod.rs @@ -39,8 +39,14 @@ pub async fn start() -> Result<(), Box> { tokio::spawn({ let db = db.clone(); async move { + let url = if CONFIG.rpc_polling { + &CONFIG.http_rpc_url + } else { + &CONFIG.ws_rpc_url + }; + if let Err(e) = start_indexer( - &CONFIG.ws_rpc_url, + url, &CONFIG.enclave_address, &CONFIG.ciphernode_registry_address, &CONFIG.e3_program_address, From 85eaf7f866bf3a1d0c751b277efe011619f2f79b Mon Sep 17 00:00:00 2001 From: ryardley Date: Wed, 26 Nov 2025 03:50:21 +0000 Subject: [PATCH 12/33] revert to hh sim mode --- .../packages/crisp-contracts/hardhat.config.ts | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/examples/CRISP/packages/crisp-contracts/hardhat.config.ts b/examples/CRISP/packages/crisp-contracts/hardhat.config.ts index 95e09d2361..1cc1bee9f8 100644 --- a/examples/CRISP/packages/crisp-contracts/hardhat.config.ts +++ b/examples/CRISP/packages/crisp-contracts/hardhat.config.ts @@ -69,14 +69,13 @@ const config: HardhatUserConfig = { accounts: { mnemonic, }, - url: 'http://localhost:8545', chainId: chainIds.hardhat, - type: 'http', - // chainType: 'l1', - // mining: { - // auto: true, - // interval: 1000, // mine a block every 1 second - // }, + type: 'edr-simulated', + chainType: 'l1', + mining: { + auto: true, + interval: 1000, // mine a block every 1 second + }, }, ganache: { accounts: { From 5375c0335cccfc248e5c16305fc49715398c4b52 Mon Sep 17 00:00:00 2001 From: ryardley Date: Wed, 26 Nov 2025 04:12:49 +0000 Subject: [PATCH 13/33] use annvil --- examples/CRISP/scripts/dev.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/CRISP/scripts/dev.sh b/examples/CRISP/scripts/dev.sh index ea5e5d2ec3..458e336605 100755 --- a/examples/CRISP/scripts/dev.sh +++ b/examples/CRISP/scripts/dev.sh @@ -33,8 +33,8 @@ echo "DEV SCRIPT STARTING..." pnpm concurrently \ -ks first \ - --names "HARDHAT,DEPLOY" \ + --names "ANVIL,DEPLOY" \ --prefix-colors "blue,green" \ - "cd packages/crisp-contracts && pnpm hardhat node" \ + "cd packages/crisp-contracts && anvil --block-time 1" \ "./scripts/crisp_deploy.sh && ./scripts/dev_services.sh" From 24a95b289c2d8e120f1eedd064c74d633fb1e08b Mon Sep 17 00:00:00 2001 From: ryardley Date: Wed, 26 Nov 2025 04:14:28 +0000 Subject: [PATCH 14/33] use anvil --- examples/CRISP/server/.env.example | 1 - examples/CRISP/server/src/config.rs | 1 - examples/CRISP/server/src/server/mod.rs | 8 +------- 3 files changed, 1 insertion(+), 9 deletions(-) diff --git a/examples/CRISP/server/.env.example b/examples/CRISP/server/.env.example index 4816b2d0c7..405ed6ae4d 100644 --- a/examples/CRISP/server/.env.example +++ b/examples/CRISP/server/.env.example @@ -5,7 +5,6 @@ HTTP_RPC_URL=http://127.0.0.1:8545 WS_RPC_URL=ws://127.0.0.1:8545 PROGRAM_SERVER_URL=http://127.0.0.1:13151 CHAIN_ID=31337 -RPC_POLLING=1 # Etherscan API key ETHERSCAN_API_KEY="" diff --git a/examples/CRISP/server/src/config.rs b/examples/CRISP/server/src/config.rs index b8d2148c6a..446cba6d51 100644 --- a/examples/CRISP/server/src/config.rs +++ b/examples/CRISP/server/src/config.rs @@ -16,7 +16,6 @@ pub struct Config { pub private_key: String, pub http_rpc_url: String, pub ws_rpc_url: String, - pub rpc_polling: bool, pub enclave_address: String, pub e3_program_address: String, pub ciphernode_registry_address: String, diff --git a/examples/CRISP/server/src/server/mod.rs b/examples/CRISP/server/src/server/mod.rs index 477bee2580..992d577bd3 100644 --- a/examples/CRISP/server/src/server/mod.rs +++ b/examples/CRISP/server/src/server/mod.rs @@ -39,14 +39,8 @@ pub async fn start() -> Result<(), Box> { tokio::spawn({ let db = db.clone(); async move { - let url = if CONFIG.rpc_polling { - &CONFIG.http_rpc_url - } else { - &CONFIG.ws_rpc_url - }; - if let Err(e) = start_indexer( - url, + &CONFIG.ws_rpc_url, &CONFIG.enclave_address, &CONFIG.ciphernode_registry_address, &CONFIG.e3_program_address, From 571834343f220f800130ba75c18a7737ea0ae4f9 Mon Sep 17 00:00:00 2001 From: ryardley Date: Wed, 26 Nov 2025 04:31:38 +0000 Subject: [PATCH 15/33] update contracty things --- examples/CRISP/enclave.config.yaml | 32 ++++--- .../crisp-contracts/deployed_contracts.json | 86 +++++++++---------- 2 files changed, 58 insertions(+), 60 deletions(-) diff --git a/examples/CRISP/enclave.config.yaml b/examples/CRISP/enclave.config.yaml index 92bb4b9d16..20cc61c95c 100644 --- a/examples/CRISP/enclave.config.yaml +++ b/examples/CRISP/enclave.config.yaml @@ -3,20 +3,20 @@ chains: rpc_url: ws://localhost:8545 contracts: e3_program: - address: "0xc5a5C42992dECbae36851359345FE25997F5C42d" + address: '0xc5a5C42992dECbae36851359345FE25997F5C42d' deploy_block: 1 enclave: - address: "0xA51c1fc2f0D1a1b8494Ed1FE312d7C3a78Ed91C0" - deploy_block: 13 + address: '0xB7f8BC63BbcaD18155201308C8f3540b07f84F5e' + deploy_block: 14 ciphernode_registry: - address: "0x610178dA211FEF7D417bC0e6FeD39F05609AD788" - deploy_block: 11 + address: '0x8A791620dd6260079BF849Dc5567aDC3F2FdC318' + deploy_block: 12 bonding_registry: - address: "0x2279B7A0a67DB372996a5FaB50D91eAA73d2eBe6" - deploy_block: 8 + address: '0xa513E6E4b8f2a923D98304ec87F64353C4D5C853' + deploy_block: 9 fee_token: - address: "0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0" - deploy_block: 4 + address: '0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512' + deploy_block: 5 program: dev: true # risc0: @@ -27,38 +27,36 @@ program: # pinata_jwt: "PINATA_JWT" # For uploading programs # program_url: "https://gateway.pinata.cloud/ipfs/QmNMRAB7DW43JSmENfzGmD96G6sqaeBBNfTVrrq5WQae3D" # Pre-uploaded program # onchain: true # true = onchain requests, false = offchain - nodes: cn1: - address: "0x70997970C51812dc3A010C7d01b50e0d17dc79C8" + address: '0x70997970C51812dc3A010C7d01b50e0d17dc79C8' quic_port: 9201 autonetkey: true autopassword: true cn2: - address: "0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC" + address: '0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC' quic_port: 9202 autonetkey: true autopassword: true cn3: - address: "0x90F79bf6EB2c4f870365E785982E1f101E93b906" + address: '0x90F79bf6EB2c4f870365E785982E1f101E93b906' quic_port: 9203 autonetkey: true autopassword: true cn4: - address: "0x15d34AAf54267DB7D7c367839AAf71A00a2C6A65" + address: '0x15d34AAf54267DB7D7c367839AAf71A00a2C6A65' quic_port: 9204 autonetkey: true autopassword: true cn5: - address: "0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc" + address: '0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc' quic_port: 9205 autonetkey: true autopassword: true ag: - address: "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" + address: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266' quic_port: 9206 autonetkey: true autopassword: true role: type: aggregator - diff --git a/examples/CRISP/packages/crisp-contracts/deployed_contracts.json b/examples/CRISP/packages/crisp-contracts/deployed_contracts.json index 3c2f539839..6c1b79f4f9 100644 --- a/examples/CRISP/packages/crisp-contracts/deployed_contracts.json +++ b/examples/CRISP/packages/crisp-contracts/deployed_contracts.json @@ -119,38 +119,38 @@ "constructorArgs": { "initialSupply": "1000000" }, - "blockNumber": 4, - "address": "0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0" + "blockNumber": 5, + "address": "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512" }, "EnclaveToken": { "constructorArgs": { "owner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" }, - "blockNumber": 5, - "address": "0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9" + "blockNumber": 6, + "address": "0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0" }, "EnclaveTicketToken": { "constructorArgs": { - "baseToken": "0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0", + "baseToken": "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512", "registry": "0x0000000000000000000000000000000000000001", "owner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" }, - "blockNumber": 7, - "address": "0x5FC8d32690cc91D4c39d9d3abcBD16989F875707" + "blockNumber": 8, + "address": "0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9" }, "SlashingManager": { "constructorArgs": { "admin": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", "bondingRegistry": "0x0000000000000000000000000000000000000001" }, - "blockNumber": 8, - "address": "0x0165878A594ca255338adfa4d48449f69242Eb8F" + "blockNumber": 9, + "address": "0x5FC8d32690cc91D4c39d9d3abcBD16989F875707" }, "BondingRegistry": { "constructorArgs": { "owner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "ticketToken": "0x5FC8d32690cc91D4c39d9d3abcBD16989F875707", - "licenseToken": "0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9", + "ticketToken": "0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9", + "licenseToken": "0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0", "registry": "0x0000000000000000000000000000000000000001", "slashedFundsTreasury": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", "ticketPrice": "10000000", @@ -159,14 +159,14 @@ "exitDelay": "604800" }, "proxyRecords": { - "initData": "0x7333fa82000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb922660000000000000000000000005fc8d32690cc91d4c39d9d3abcbd16989f875707000000000000000000000000cf7ed3acca5a467e9e704c703e8d87f634fb0fc90000000000000000000000000000000000000000000000000000000000000001000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb9226600000000000000000000000000000000000000000000000000000000009896800000000000000000000000000000000000000000000000056bc75e2d6310000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000093a80", + "initData": "0x7333fa82000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266000000000000000000000000dc64a140aa3e981100a9beca4e685f962f0cf6c90000000000000000000000009fe46736679d2d9a65f0992f2272de9f3c7fa6e00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb9226600000000000000000000000000000000000000000000000000000000009896800000000000000000000000000000000000000000000000056bc75e2d6310000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000093a80", "initialOwner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "proxyAddress": "0x2279B7A0a67DB372996a5FaB50D91eAA73d2eBe6", - "proxyAdminAddress": "0x94099942864EA81cCF197E9D71ac53310b1468D8", - "implementationAddress": "0xa513E6E4b8f2a923D98304ec87F64353C4D5C853" + "proxyAddress": "0xa513E6E4b8f2a923D98304ec87F64353C4D5C853", + "proxyAdminAddress": "0x9bd03768a7DCc129555dE410FF8E85528A4F88b5", + "implementationAddress": "0x0165878A594ca255338adfa4d48449f69242Eb8F" }, - "blockNumber": 8, - "address": "0x2279B7A0a67DB372996a5FaB50D91eAA73d2eBe6" + "blockNumber": 9, + "address": "0xa513E6E4b8f2a923D98304ec87F64353C4D5C853" }, "CiphernodeRegistryOwnable": { "constructorArgs": { @@ -177,58 +177,58 @@ "proxyRecords": { "initData": "0x1794bb3c000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb922660000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000a", "initialOwner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "proxyAddress": "0x610178dA211FEF7D417bC0e6FeD39F05609AD788", - "proxyAdminAddress": "0x6F1216D1BFe15c98520CA1434FC1d9D57AC95321", - "implementationAddress": "0x8A791620dd6260079BF849Dc5567aDC3F2FdC318" + "proxyAddress": "0x8A791620dd6260079BF849Dc5567aDC3F2FdC318", + "proxyAdminAddress": "0x8aCd85898458400f7Db866d53FCFF6f0D49741FF", + "implementationAddress": "0x2279B7A0a67DB372996a5FaB50D91eAA73d2eBe6" }, - "blockNumber": 11, - "address": "0x610178dA211FEF7D417bC0e6FeD39F05609AD788" + "blockNumber": 12, + "address": "0x8A791620dd6260079BF849Dc5567aDC3F2FdC318" }, "Enclave": { "constructorArgs": { "owner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "registry": "0x610178dA211FEF7D417bC0e6FeD39F05609AD788", - "bondingRegistry": "0x2279B7A0a67DB372996a5FaB50D91eAA73d2eBe6", - "feeToken": "0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0", + "registry": "0x8A791620dd6260079BF849Dc5567aDC3F2FdC318", + "bondingRegistry": "0xa513E6E4b8f2a923D98304ec87F64353C4D5C853", + "feeToken": "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512", "maxDuration": "2592000", "params": [ "0x000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000fc00100000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000003fffffff000001" ] }, "proxyRecords": { - "initData": "0xefe0308b000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266000000000000000000000000610178da211fef7d417bc0e6fed39f05609ad7880000000000000000000000002279b7a0a67db372996a5fab50d91eaa73d2ebe60000000000000000000000009fe46736679d2d9a65f0992f2272de9f3c7fa6e00000000000000000000000000000000000000000000000000000000000278d0000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000fc00100000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000003fffffff000001", + "initData": "0xefe0308b000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb922660000000000000000000000008a791620dd6260079bf849dc5567adc3f2fdc318000000000000000000000000a513e6e4b8f2a923d98304ec87f64353c4d5c853000000000000000000000000e7f1725e7734ce288f8367e1bb143e90bb3f05120000000000000000000000000000000000000000000000000000000000278d0000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000fc00100000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000003fffffff000001", "initialOwner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "proxyAddress": "0xA51c1fc2f0D1a1b8494Ed1FE312d7C3a78Ed91C0", - "proxyAdminAddress": "0x1F708C24a0D3A740cD47cC0444E9480899f3dA7D", - "implementationAddress": "0xB7f8BC63BbcaD18155201308C8f3540b07f84F5e" + "proxyAddress": "0xB7f8BC63BbcaD18155201308C8f3540b07f84F5e", + "proxyAdminAddress": "0x8dAF17A20c9DBA35f005b6324F493785D239719d", + "implementationAddress": "0x610178dA211FEF7D417bC0e6FeD39F05609AD788" }, - "blockNumber": 13, - "address": "0xA51c1fc2f0D1a1b8494Ed1FE312d7C3a78Ed91C0" + "blockNumber": 14, + "address": "0xB7f8BC63BbcaD18155201308C8f3540b07f84F5e" }, "MockComputeProvider": { - "blockNumber": 23, - "address": "0x59b670e9fA9D0A427751Af201D676719a970857b" + "blockNumber": 16, + "address": "0xc6e7DF5E7b4f2A278906862b61205850344D4e7d" }, "MockDecryptionVerifier": { - "blockNumber": 24, - "address": "0x4ed7c70F96B99c776995fB64377f0d4aB3B0e1C1" + "blockNumber": 17, + "address": "0x59b670e9fA9D0A427751Af201D676719a970857b" }, "MockE3Program": { - "blockNumber": 25, - "address": "0x322813Fd9A801c5507c9de605d63CEA4f2CE6c44" + "blockNumber": 18, + "address": "0x4ed7c70F96B99c776995fB64377f0d4aB3B0e1C1" }, "MockRISC0Verifier": { - "address": "0x7a2088a1bFc9d81c55368AE168C2C02570cB814F" + "address": "0x4A679253410272dd5232B3Ff7cF5dbB88f295319" }, "HonkVerifier": { - "address": "0xc5a5C42992dECbae36851359345FE25997F5C42d" + "address": "0x09635F643e140090A9A8Dcd712eD6285858ceBef" }, "CRISPProgram": { - "address": "0x67d269191c92Caf3cD7723F116c85e6E9bf55933", + "address": "0xc5a5C42992dECbae36851359345FE25997F5C42d", "constructorArgs": { - "enclave": "0xA51c1fc2f0D1a1b8494Ed1FE312d7C3a78Ed91C0", - "verifierAddress": "0x7a2088a1bFc9d81c55368AE168C2C02570cB814F", - "honkVerifierAddress": "0xc5a5C42992dECbae36851359345FE25997F5C42d", + "enclave": "0xB7f8BC63BbcaD18155201308C8f3540b07f84F5e", + "verifierAddress": "0x4A679253410272dd5232B3Ff7cF5dbB88f295319", + "honkVerifierAddress": "0x09635F643e140090A9A8Dcd712eD6285858ceBef", "imageId": "0x23734b77b0f76e85623a88d7a82f24c34c94834f2501964ea123b7a2027013a2" } } From 2e505131b3102353f2839c9ce8a843e546165995 Mon Sep 17 00:00:00 2001 From: ryardley Date: Wed, 26 Nov 2025 04:53:03 +0000 Subject: [PATCH 16/33] update env --- examples/CRISP/server/.env.example | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/CRISP/server/.env.example b/examples/CRISP/server/.env.example index 405ed6ae4d..19b356592b 100644 --- a/examples/CRISP/server/.env.example +++ b/examples/CRISP/server/.env.example @@ -13,10 +13,10 @@ ETHERSCAN_API_KEY="" CRON_API_KEY=1234567890 # Based on Default Hardhat Deployments (Only for testing) -ENCLAVE_ADDRESS="0xA51c1fc2f0D1a1b8494Ed1FE312d7C3a78Ed91C0" -CIPHERNODE_REGISTRY_ADDRESS="0x610178dA211FEF7D417bC0e6FeD39F05609AD788" -E3_PROGRAM_ADDRESS="0x67d269191c92Caf3cD7723F116c85e6E9bf55933" # CRISPProgram Contract Address -FEE_TOKEN_ADDRESS="0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0" +ENCLAVE_ADDRESS="0xB7f8BC63BbcaD18155201308C8f3540b07f84F5e" +CIPHERNODE_REGISTRY_ADDRESS="0x8A791620dd6260079BF849Dc5567aDC3F2FdC318" +E3_PROGRAM_ADDRESS="0xc5a5C42992dECbae36851359345FE25997F5C42d" # CRISPProgram Contract Address +FEE_TOKEN_ADDRESS="0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512" # E3 Config E3_WINDOW_SIZE=40 From ec87b85500ce7d065b46084b932305f66100dc7e Mon Sep 17 00:00:00 2001 From: ryardley Date: Wed, 26 Nov 2025 05:14:35 +0000 Subject: [PATCH 17/33] avoid goto(/) issue --- examples/CRISP/test/crisp.spec.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/CRISP/test/crisp.spec.ts b/examples/CRISP/test/crisp.spec.ts index 1d0faa287f..601c278787 100644 --- a/examples/CRISP/test/crisp.spec.ts +++ b/examples/CRISP/test/crisp.spec.ts @@ -84,7 +84,8 @@ test('CRISP smoke test', async ({ context, page, metamaskPage, extensionId }) => const e3id = await runCliInit() log(`Got e3 id: ${e3id}`) - await page.goto('/') + await page.goto('/', { waitUntil: 'domcontentloaded' }) + await page.waitForLoadState('load') log(`ensureHomePageLoaded...`) await ensureHomePageLoaded(page) From d3ba77b766e31c2522eef9763ad5912ea71725c2 Mon Sep 17 00:00:00 2001 From: ryardley Date: Wed, 26 Nov 2025 05:27:17 +0000 Subject: [PATCH 18/33] update indexer to avoid waiting and use blocktime --- examples/CRISP/server/src/server/indexer.rs | 49 +++++++++------------ 1 file changed, 20 insertions(+), 29 deletions(-) diff --git a/examples/CRISP/server/src/server/indexer.rs b/examples/CRISP/server/src/server/indexer.rs index dced87c311..b43f28a217 100644 --- a/examples/CRISP/server/src/server/indexer.rs +++ b/examples/CRISP/server/src/server/indexer.rs @@ -15,6 +15,7 @@ use crate::server::{ use alloy::providers::{Provider, ProviderBuilder}; use alloy::sol_types::{sol_data, SolType}; use alloy_primitives::{Address, U256}; +use e3_sdk::indexer::IndexerContext; use e3_sdk::{ bfv_helpers::decode_bytes_to_vec_u64, evm_helpers::{ @@ -31,6 +32,7 @@ use eyre::Context; use log::info; use num_bigint::BigUint; use std::error::Error; +use std::sync::Arc; use std::time::Duration; use tokio::time::sleep; @@ -350,36 +352,12 @@ pub async fn register_committee_published( let now = get_current_timestamp_rpc().await?; info!("[e3_id={}] Current time: {}", event.e3Id, now); - ////////////////////////////////////////////////////// - // XXX: FIX ME - - // Calculate wait duration - let wait_duration = if start_time > now { - let secs = start_time - now; - info!( - "[e3_id={}] Need to wait {} seconds until activation", - event.e3Id, secs - ); - Duration::from_secs(secs) - } else { - info!("[e3_id={}] Activating E3", event.e3Id); - Duration::ZERO - }; - info!("[e3_id={}] Wait duration: {:?}", event.e3Id, wait_duration); - - // Sleep until start time - if !wait_duration.is_zero() { - sleep(wait_duration).await; - } - - /////////////////////////////////////////////////////// + let later_event = event.clone(); + ctx.do_later(start_time, move |_, ctx| { + let event = later_event.clone(); + handle_committee_time_expired(event, ctx) + }); - // If not activated activate - let tx = contract.activate(event.e3Id, event.publicKey).await?; - info!( - "[e3_id={}] E3 activated with tx: {:?}", - event.e3Id, tx.transaction_hash - ); Ok(()) } }) @@ -387,6 +365,19 @@ pub async fn register_committee_published( Ok(indexer) } +async fn handle_committee_time_expired( + event: CommitteePublished, + ctx: Arc>, +) -> eyre::Result<()> { + // If not activated activate + let tx = ctx.contract().activate(event.e3Id, event.publicKey).await?; + info!( + "[e3_id={}] E3 activated with tx: {:?}", + event.e3Id, tx.transaction_hash + ); + Ok(()) +} + pub async fn get_current_timestamp_rpc() -> eyre::Result { let provider = ProviderBuilder::new().connect(&CONFIG.http_rpc_url).await?; let block = provider From ff4fa0b3de6fb3a5782c536040ed7e1476675d84 Mon Sep 17 00:00:00 2001 From: ryardley Date: Wed, 26 Nov 2025 05:28:34 +0000 Subject: [PATCH 19/33] remove sleep --- examples/CRISP/server/src/server/indexer.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/examples/CRISP/server/src/server/indexer.rs b/examples/CRISP/server/src/server/indexer.rs index b43f28a217..5bb546d182 100644 --- a/examples/CRISP/server/src/server/indexer.rs +++ b/examples/CRISP/server/src/server/indexer.rs @@ -33,8 +33,6 @@ use log::info; use num_bigint::BigUint; use std::error::Error; use std::sync::Arc; -use std::time::Duration; -use tokio::time::sleep; type Result = std::result::Result>; From 015df26ecec4f5030cb361eca6d98d876dcd2726 Mon Sep 17 00:00:00 2001 From: ryardley Date: Wed, 26 Nov 2025 13:42:58 +0000 Subject: [PATCH 20/33] remove comment --- crates/evm-helpers/src/event_listener.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/evm-helpers/src/event_listener.rs b/crates/evm-helpers/src/event_listener.rs index 1ac553f49a..738d77451c 100644 --- a/crates/evm-helpers/src/event_listener.rs +++ b/crates/evm-helpers/src/event_listener.rs @@ -22,7 +22,7 @@ type EventHandler = #[derive(Clone)] pub struct EventListener { - provider: Arc>, // should this be Ethereum? + provider: Arc>, filter: Filter, handlers: Arc>>>, } From 7909eceedb2ac31e8255e60638e33e6a6e6c7f1e Mon Sep 17 00:00:00 2001 From: ryardley Date: Wed, 26 Nov 2025 13:46:39 +0000 Subject: [PATCH 21/33] remove redundent settings --- examples/CRISP/packages/crisp-contracts/hardhat.config.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/examples/CRISP/packages/crisp-contracts/hardhat.config.ts b/examples/CRISP/packages/crisp-contracts/hardhat.config.ts index 1cc1bee9f8..f66e4fc52f 100644 --- a/examples/CRISP/packages/crisp-contracts/hardhat.config.ts +++ b/examples/CRISP/packages/crisp-contracts/hardhat.config.ts @@ -72,10 +72,6 @@ const config: HardhatUserConfig = { chainId: chainIds.hardhat, type: 'edr-simulated', chainType: 'l1', - mining: { - auto: true, - interval: 1000, // mine a block every 1 second - }, }, ganache: { accounts: { From 16a861ef09195efcb87721cf43db061e74c1a3bd Mon Sep 17 00:00:00 2001 From: ryardley Date: Wed, 26 Nov 2025 13:47:33 +0000 Subject: [PATCH 22/33] revert accidental ordering --- examples/CRISP/server/.env.example | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/CRISP/server/.env.example b/examples/CRISP/server/.env.example index 19b356592b..2395eff366 100644 --- a/examples/CRISP/server/.env.example +++ b/examples/CRISP/server/.env.example @@ -2,8 +2,8 @@ PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 ENCLAVE_SERVER_URL=http://0.0.0.0:4000 HTTP_RPC_URL=http://127.0.0.1:8545 -WS_RPC_URL=ws://127.0.0.1:8545 PROGRAM_SERVER_URL=http://127.0.0.1:13151 +WS_RPC_URL=ws://127.0.0.1:8545 CHAIN_ID=31337 # Etherscan API key From 35107ada7851d951f574991fef167c9211ea7fb8 Mon Sep 17 00:00:00 2001 From: ryardley Date: Wed, 26 Nov 2025 13:52:10 +0000 Subject: [PATCH 23/33] remove line to get in size limit --- examples/CRISP/server/src/server/indexer.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/CRISP/server/src/server/indexer.rs b/examples/CRISP/server/src/server/indexer.rs index 5bb546d182..aeaa446576 100644 --- a/examples/CRISP/server/src/server/indexer.rs +++ b/examples/CRISP/server/src/server/indexer.rs @@ -201,7 +201,6 @@ pub async fn register_e3_activated( info!("[e3_id={}] Registering hook for {}", e3_id, expiration); ctx.do_later(expiration, move |_, ctx| { - info!("Running...."); handle_e3_input_deadline_expiration(e3_id, ctx.store()) }); Ok(()) From 83354feb06db5a211c61c8af1e54c16435a6040c Mon Sep 17 00:00:00 2001 From: ryardley Date: Wed, 26 Nov 2025 19:04:44 +0000 Subject: [PATCH 24/33] use localhost network specifically --- examples/CRISP/scripts/dev.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/CRISP/scripts/dev.sh b/examples/CRISP/scripts/dev.sh index 458e336605..ac8c721139 100755 --- a/examples/CRISP/scripts/dev.sh +++ b/examples/CRISP/scripts/dev.sh @@ -35,6 +35,6 @@ pnpm concurrently \ -ks first \ --names "ANVIL,DEPLOY" \ --prefix-colors "blue,green" \ - "cd packages/crisp-contracts && anvil --block-time 1" \ + "cd packages/crisp-contracts && pnpm hardhat --network localhost" \ "./scripts/crisp_deploy.sh && ./scripts/dev_services.sh" From 7ba2a971feb2f7e51e20a46453a08048fd8fdc46 Mon Sep 17 00:00:00 2001 From: ryardley Date: Wed, 26 Nov 2025 19:06:13 +0000 Subject: [PATCH 25/33] set hardhat config --- examples/CRISP/packages/crisp-contracts/hardhat.config.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/examples/CRISP/packages/crisp-contracts/hardhat.config.ts b/examples/CRISP/packages/crisp-contracts/hardhat.config.ts index f66e4fc52f..d5b2ff01ed 100644 --- a/examples/CRISP/packages/crisp-contracts/hardhat.config.ts +++ b/examples/CRISP/packages/crisp-contracts/hardhat.config.ts @@ -72,6 +72,10 @@ const config: HardhatUserConfig = { chainId: chainIds.hardhat, type: 'edr-simulated', chainType: 'l1', + mining: { + auto: false, + interval: 1000, + }, }, ganache: { accounts: { From 7d478637c81a2637a1ce288d5c3c0e95ee1a5cbd Mon Sep 17 00:00:00 2001 From: ryardley Date: Wed, 26 Nov 2025 19:11:27 +0000 Subject: [PATCH 26/33] revert contract changes --- examples/CRISP/enclave.config.yaml | 32 +++---- .../crisp-contracts/deployed_contracts.json | 86 +++++++++---------- 2 files changed, 60 insertions(+), 58 deletions(-) diff --git a/examples/CRISP/enclave.config.yaml b/examples/CRISP/enclave.config.yaml index 20cc61c95c..92bb4b9d16 100644 --- a/examples/CRISP/enclave.config.yaml +++ b/examples/CRISP/enclave.config.yaml @@ -3,20 +3,20 @@ chains: rpc_url: ws://localhost:8545 contracts: e3_program: - address: '0xc5a5C42992dECbae36851359345FE25997F5C42d' + address: "0xc5a5C42992dECbae36851359345FE25997F5C42d" deploy_block: 1 enclave: - address: '0xB7f8BC63BbcaD18155201308C8f3540b07f84F5e' - deploy_block: 14 + address: "0xA51c1fc2f0D1a1b8494Ed1FE312d7C3a78Ed91C0" + deploy_block: 13 ciphernode_registry: - address: '0x8A791620dd6260079BF849Dc5567aDC3F2FdC318' - deploy_block: 12 + address: "0x610178dA211FEF7D417bC0e6FeD39F05609AD788" + deploy_block: 11 bonding_registry: - address: '0xa513E6E4b8f2a923D98304ec87F64353C4D5C853' - deploy_block: 9 + address: "0x2279B7A0a67DB372996a5FaB50D91eAA73d2eBe6" + deploy_block: 8 fee_token: - address: '0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512' - deploy_block: 5 + address: "0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0" + deploy_block: 4 program: dev: true # risc0: @@ -27,36 +27,38 @@ program: # pinata_jwt: "PINATA_JWT" # For uploading programs # program_url: "https://gateway.pinata.cloud/ipfs/QmNMRAB7DW43JSmENfzGmD96G6sqaeBBNfTVrrq5WQae3D" # Pre-uploaded program # onchain: true # true = onchain requests, false = offchain + nodes: cn1: - address: '0x70997970C51812dc3A010C7d01b50e0d17dc79C8' + address: "0x70997970C51812dc3A010C7d01b50e0d17dc79C8" quic_port: 9201 autonetkey: true autopassword: true cn2: - address: '0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC' + address: "0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC" quic_port: 9202 autonetkey: true autopassword: true cn3: - address: '0x90F79bf6EB2c4f870365E785982E1f101E93b906' + address: "0x90F79bf6EB2c4f870365E785982E1f101E93b906" quic_port: 9203 autonetkey: true autopassword: true cn4: - address: '0x15d34AAf54267DB7D7c367839AAf71A00a2C6A65' + address: "0x15d34AAf54267DB7D7c367839AAf71A00a2C6A65" quic_port: 9204 autonetkey: true autopassword: true cn5: - address: '0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc' + address: "0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc" quic_port: 9205 autonetkey: true autopassword: true ag: - address: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266' + address: "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" quic_port: 9206 autonetkey: true autopassword: true role: type: aggregator + diff --git a/examples/CRISP/packages/crisp-contracts/deployed_contracts.json b/examples/CRISP/packages/crisp-contracts/deployed_contracts.json index 6c1b79f4f9..3c2f539839 100644 --- a/examples/CRISP/packages/crisp-contracts/deployed_contracts.json +++ b/examples/CRISP/packages/crisp-contracts/deployed_contracts.json @@ -119,38 +119,38 @@ "constructorArgs": { "initialSupply": "1000000" }, - "blockNumber": 5, - "address": "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512" + "blockNumber": 4, + "address": "0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0" }, "EnclaveToken": { "constructorArgs": { "owner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" }, - "blockNumber": 6, - "address": "0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0" + "blockNumber": 5, + "address": "0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9" }, "EnclaveTicketToken": { "constructorArgs": { - "baseToken": "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512", + "baseToken": "0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0", "registry": "0x0000000000000000000000000000000000000001", "owner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" }, - "blockNumber": 8, - "address": "0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9" + "blockNumber": 7, + "address": "0x5FC8d32690cc91D4c39d9d3abcBD16989F875707" }, "SlashingManager": { "constructorArgs": { "admin": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", "bondingRegistry": "0x0000000000000000000000000000000000000001" }, - "blockNumber": 9, - "address": "0x5FC8d32690cc91D4c39d9d3abcBD16989F875707" + "blockNumber": 8, + "address": "0x0165878A594ca255338adfa4d48449f69242Eb8F" }, "BondingRegistry": { "constructorArgs": { "owner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "ticketToken": "0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9", - "licenseToken": "0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0", + "ticketToken": "0x5FC8d32690cc91D4c39d9d3abcBD16989F875707", + "licenseToken": "0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9", "registry": "0x0000000000000000000000000000000000000001", "slashedFundsTreasury": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", "ticketPrice": "10000000", @@ -159,14 +159,14 @@ "exitDelay": "604800" }, "proxyRecords": { - "initData": "0x7333fa82000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266000000000000000000000000dc64a140aa3e981100a9beca4e685f962f0cf6c90000000000000000000000009fe46736679d2d9a65f0992f2272de9f3c7fa6e00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb9226600000000000000000000000000000000000000000000000000000000009896800000000000000000000000000000000000000000000000056bc75e2d6310000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000093a80", + "initData": "0x7333fa82000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb922660000000000000000000000005fc8d32690cc91d4c39d9d3abcbd16989f875707000000000000000000000000cf7ed3acca5a467e9e704c703e8d87f634fb0fc90000000000000000000000000000000000000000000000000000000000000001000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb9226600000000000000000000000000000000000000000000000000000000009896800000000000000000000000000000000000000000000000056bc75e2d6310000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000093a80", "initialOwner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "proxyAddress": "0xa513E6E4b8f2a923D98304ec87F64353C4D5C853", - "proxyAdminAddress": "0x9bd03768a7DCc129555dE410FF8E85528A4F88b5", - "implementationAddress": "0x0165878A594ca255338adfa4d48449f69242Eb8F" + "proxyAddress": "0x2279B7A0a67DB372996a5FaB50D91eAA73d2eBe6", + "proxyAdminAddress": "0x94099942864EA81cCF197E9D71ac53310b1468D8", + "implementationAddress": "0xa513E6E4b8f2a923D98304ec87F64353C4D5C853" }, - "blockNumber": 9, - "address": "0xa513E6E4b8f2a923D98304ec87F64353C4D5C853" + "blockNumber": 8, + "address": "0x2279B7A0a67DB372996a5FaB50D91eAA73d2eBe6" }, "CiphernodeRegistryOwnable": { "constructorArgs": { @@ -177,58 +177,58 @@ "proxyRecords": { "initData": "0x1794bb3c000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb922660000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000a", "initialOwner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "proxyAddress": "0x8A791620dd6260079BF849Dc5567aDC3F2FdC318", - "proxyAdminAddress": "0x8aCd85898458400f7Db866d53FCFF6f0D49741FF", - "implementationAddress": "0x2279B7A0a67DB372996a5FaB50D91eAA73d2eBe6" + "proxyAddress": "0x610178dA211FEF7D417bC0e6FeD39F05609AD788", + "proxyAdminAddress": "0x6F1216D1BFe15c98520CA1434FC1d9D57AC95321", + "implementationAddress": "0x8A791620dd6260079BF849Dc5567aDC3F2FdC318" }, - "blockNumber": 12, - "address": "0x8A791620dd6260079BF849Dc5567aDC3F2FdC318" + "blockNumber": 11, + "address": "0x610178dA211FEF7D417bC0e6FeD39F05609AD788" }, "Enclave": { "constructorArgs": { "owner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "registry": "0x8A791620dd6260079BF849Dc5567aDC3F2FdC318", - "bondingRegistry": "0xa513E6E4b8f2a923D98304ec87F64353C4D5C853", - "feeToken": "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512", + "registry": "0x610178dA211FEF7D417bC0e6FeD39F05609AD788", + "bondingRegistry": "0x2279B7A0a67DB372996a5FaB50D91eAA73d2eBe6", + "feeToken": "0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0", "maxDuration": "2592000", "params": [ "0x000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000fc00100000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000003fffffff000001" ] }, "proxyRecords": { - "initData": "0xefe0308b000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb922660000000000000000000000008a791620dd6260079bf849dc5567adc3f2fdc318000000000000000000000000a513e6e4b8f2a923d98304ec87f64353c4d5c853000000000000000000000000e7f1725e7734ce288f8367e1bb143e90bb3f05120000000000000000000000000000000000000000000000000000000000278d0000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000fc00100000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000003fffffff000001", + "initData": "0xefe0308b000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266000000000000000000000000610178da211fef7d417bc0e6fed39f05609ad7880000000000000000000000002279b7a0a67db372996a5fab50d91eaa73d2ebe60000000000000000000000009fe46736679d2d9a65f0992f2272de9f3c7fa6e00000000000000000000000000000000000000000000000000000000000278d0000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000fc00100000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000003fffffff000001", "initialOwner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "proxyAddress": "0xB7f8BC63BbcaD18155201308C8f3540b07f84F5e", - "proxyAdminAddress": "0x8dAF17A20c9DBA35f005b6324F493785D239719d", - "implementationAddress": "0x610178dA211FEF7D417bC0e6FeD39F05609AD788" + "proxyAddress": "0xA51c1fc2f0D1a1b8494Ed1FE312d7C3a78Ed91C0", + "proxyAdminAddress": "0x1F708C24a0D3A740cD47cC0444E9480899f3dA7D", + "implementationAddress": "0xB7f8BC63BbcaD18155201308C8f3540b07f84F5e" }, - "blockNumber": 14, - "address": "0xB7f8BC63BbcaD18155201308C8f3540b07f84F5e" + "blockNumber": 13, + "address": "0xA51c1fc2f0D1a1b8494Ed1FE312d7C3a78Ed91C0" }, "MockComputeProvider": { - "blockNumber": 16, - "address": "0xc6e7DF5E7b4f2A278906862b61205850344D4e7d" + "blockNumber": 23, + "address": "0x59b670e9fA9D0A427751Af201D676719a970857b" }, "MockDecryptionVerifier": { - "blockNumber": 17, - "address": "0x59b670e9fA9D0A427751Af201D676719a970857b" + "blockNumber": 24, + "address": "0x4ed7c70F96B99c776995fB64377f0d4aB3B0e1C1" }, "MockE3Program": { - "blockNumber": 18, - "address": "0x4ed7c70F96B99c776995fB64377f0d4aB3B0e1C1" + "blockNumber": 25, + "address": "0x322813Fd9A801c5507c9de605d63CEA4f2CE6c44" }, "MockRISC0Verifier": { - "address": "0x4A679253410272dd5232B3Ff7cF5dbB88f295319" + "address": "0x7a2088a1bFc9d81c55368AE168C2C02570cB814F" }, "HonkVerifier": { - "address": "0x09635F643e140090A9A8Dcd712eD6285858ceBef" + "address": "0xc5a5C42992dECbae36851359345FE25997F5C42d" }, "CRISPProgram": { - "address": "0xc5a5C42992dECbae36851359345FE25997F5C42d", + "address": "0x67d269191c92Caf3cD7723F116c85e6E9bf55933", "constructorArgs": { - "enclave": "0xB7f8BC63BbcaD18155201308C8f3540b07f84F5e", - "verifierAddress": "0x4A679253410272dd5232B3Ff7cF5dbB88f295319", - "honkVerifierAddress": "0x09635F643e140090A9A8Dcd712eD6285858ceBef", + "enclave": "0xA51c1fc2f0D1a1b8494Ed1FE312d7C3a78Ed91C0", + "verifierAddress": "0x7a2088a1bFc9d81c55368AE168C2C02570cB814F", + "honkVerifierAddress": "0xc5a5C42992dECbae36851359345FE25997F5C42d", "imageId": "0x23734b77b0f76e85623a88d7a82f24c34c94834f2501964ea123b7a2027013a2" } } From 2cc4e0b5c0270d2da3cfedc7f71aa2851a9a1cd4 Mon Sep 17 00:00:00 2001 From: ryardley Date: Wed, 26 Nov 2025 19:12:33 +0000 Subject: [PATCH 27/33] revert contract changes --- examples/CRISP/server/.env.example | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/CRISP/server/.env.example b/examples/CRISP/server/.env.example index 2395eff366..78ff8b0759 100644 --- a/examples/CRISP/server/.env.example +++ b/examples/CRISP/server/.env.example @@ -13,10 +13,10 @@ ETHERSCAN_API_KEY="" CRON_API_KEY=1234567890 # Based on Default Hardhat Deployments (Only for testing) -ENCLAVE_ADDRESS="0xB7f8BC63BbcaD18155201308C8f3540b07f84F5e" -CIPHERNODE_REGISTRY_ADDRESS="0x8A791620dd6260079BF849Dc5567aDC3F2FdC318" -E3_PROGRAM_ADDRESS="0xc5a5C42992dECbae36851359345FE25997F5C42d" # CRISPProgram Contract Address -FEE_TOKEN_ADDRESS="0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512" +ENCLAVE_ADDRESS="0xA51c1fc2f0D1a1b8494Ed1FE312d7C3a78Ed91C0" +CIPHERNODE_REGISTRY_ADDRESS="0x610178dA211FEF7D417bC0e6FeD39F05609AD788" +E3_PROGRAM_ADDRESS="0x67d269191c92Caf3cD7723F116c85e6E9bf55933" # CRISPProgram Contract Address +FEE_TOKEN_ADDRESS="0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0" # E3 Config E3_WINDOW_SIZE=40 From f3032541c8debe2a40b3db2ed835b37671bf50b9 Mon Sep 17 00:00:00 2001 From: ryardley Date: Wed, 26 Nov 2025 19:13:42 +0000 Subject: [PATCH 28/33] fix bad command --- examples/CRISP/scripts/dev.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/CRISP/scripts/dev.sh b/examples/CRISP/scripts/dev.sh index ac8c721139..910cda1362 100755 --- a/examples/CRISP/scripts/dev.sh +++ b/examples/CRISP/scripts/dev.sh @@ -35,6 +35,6 @@ pnpm concurrently \ -ks first \ --names "ANVIL,DEPLOY" \ --prefix-colors "blue,green" \ - "cd packages/crisp-contracts && pnpm hardhat --network localhost" \ + "cd packages/crisp-contracts && pnpm hardhat node --network localhost" \ "./scripts/crisp_deploy.sh && ./scripts/dev_services.sh" From 1dac4a3f3526003d184b1ddafe359b543681310c Mon Sep 17 00:00:00 2001 From: ryardley Date: Wed, 26 Nov 2025 19:14:24 +0000 Subject: [PATCH 29/33] fix bad command --- examples/CRISP/scripts/dev.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/CRISP/scripts/dev.sh b/examples/CRISP/scripts/dev.sh index 910cda1362..c18a062cdf 100755 --- a/examples/CRISP/scripts/dev.sh +++ b/examples/CRISP/scripts/dev.sh @@ -33,7 +33,7 @@ echo "DEV SCRIPT STARTING..." pnpm concurrently \ -ks first \ - --names "ANVIL,DEPLOY" \ + --names "HARDHAT,DEPLOY" \ --prefix-colors "blue,green" \ "cd packages/crisp-contracts && pnpm hardhat node --network localhost" \ "./scripts/crisp_deploy.sh && ./scripts/dev_services.sh" From 8ea5e9e9f3ec59010646b0049a51d7851b587e61 Mon Sep 17 00:00:00 2001 From: ryardley Date: Wed, 26 Nov 2025 21:58:23 +0000 Subject: [PATCH 30/33] revert use default --- examples/CRISP/packages/crisp-contracts/hardhat.config.ts | 2 +- examples/CRISP/scripts/dev.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/CRISP/packages/crisp-contracts/hardhat.config.ts b/examples/CRISP/packages/crisp-contracts/hardhat.config.ts index d5b2ff01ed..9403e1575f 100644 --- a/examples/CRISP/packages/crisp-contracts/hardhat.config.ts +++ b/examples/CRISP/packages/crisp-contracts/hardhat.config.ts @@ -65,7 +65,7 @@ const config: HardhatUserConfig = { plugins: [hardhatTypechainPlugin, hardhatEthersChaiMatchers, hardhatNetworkHelpers, hardhatToolboxMochaEthersPlugin, hardhatVerify], tasks: [cleanDeploymentsTask, ciphernodeAdd, ciphernodeAdminAdd, ciphernodeMintTokens], networks: { - localhost: { + default: { accounts: { mnemonic, }, diff --git a/examples/CRISP/scripts/dev.sh b/examples/CRISP/scripts/dev.sh index c18a062cdf..ea5e5d2ec3 100755 --- a/examples/CRISP/scripts/dev.sh +++ b/examples/CRISP/scripts/dev.sh @@ -35,6 +35,6 @@ pnpm concurrently \ -ks first \ --names "HARDHAT,DEPLOY" \ --prefix-colors "blue,green" \ - "cd packages/crisp-contracts && pnpm hardhat node --network localhost" \ + "cd packages/crisp-contracts && pnpm hardhat node" \ "./scripts/crisp_deploy.sh && ./scripts/dev_services.sh" From 706b61a73f170d05462a1b6cfa887555fde2ec35 Mon Sep 17 00:00:00 2001 From: ryardley Date: Wed, 26 Nov 2025 22:12:22 +0000 Subject: [PATCH 31/33] add explicit localhost network --- .../crisp-contracts/deployed_contracts.json | 123 ------------------ .../crisp-contracts/hardhat.config.ts | 9 ++ 2 files changed, 9 insertions(+), 123 deletions(-) diff --git a/examples/CRISP/packages/crisp-contracts/deployed_contracts.json b/examples/CRISP/packages/crisp-contracts/deployed_contracts.json index 3c2f539839..0b5a15cb3e 100644 --- a/examples/CRISP/packages/crisp-contracts/deployed_contracts.json +++ b/examples/CRISP/packages/crisp-contracts/deployed_contracts.json @@ -109,128 +109,5 @@ "MockRISC0Verifier": { "address": "0xa85233C63b9Ee964Add6F2cffe00Fd84eb32338f" } - }, - "localhost": { - "PoseidonT3": { - "blockNumber": 3, - "address": "0x3333333C0A88F9BE4fd23ed0536F9B6c427e3B93" - }, - "MockUSDC": { - "constructorArgs": { - "initialSupply": "1000000" - }, - "blockNumber": 4, - "address": "0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0" - }, - "EnclaveToken": { - "constructorArgs": { - "owner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" - }, - "blockNumber": 5, - "address": "0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9" - }, - "EnclaveTicketToken": { - "constructorArgs": { - "baseToken": "0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0", - "registry": "0x0000000000000000000000000000000000000001", - "owner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" - }, - "blockNumber": 7, - "address": "0x5FC8d32690cc91D4c39d9d3abcBD16989F875707" - }, - "SlashingManager": { - "constructorArgs": { - "admin": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "bondingRegistry": "0x0000000000000000000000000000000000000001" - }, - "blockNumber": 8, - "address": "0x0165878A594ca255338adfa4d48449f69242Eb8F" - }, - "BondingRegistry": { - "constructorArgs": { - "owner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "ticketToken": "0x5FC8d32690cc91D4c39d9d3abcBD16989F875707", - "licenseToken": "0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9", - "registry": "0x0000000000000000000000000000000000000001", - "slashedFundsTreasury": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "ticketPrice": "10000000", - "licenseRequiredBond": "100000000000000000000", - "minTicketBalance": "1", - "exitDelay": "604800" - }, - "proxyRecords": { - "initData": "0x7333fa82000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb922660000000000000000000000005fc8d32690cc91d4c39d9d3abcbd16989f875707000000000000000000000000cf7ed3acca5a467e9e704c703e8d87f634fb0fc90000000000000000000000000000000000000000000000000000000000000001000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb9226600000000000000000000000000000000000000000000000000000000009896800000000000000000000000000000000000000000000000056bc75e2d6310000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000093a80", - "initialOwner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "proxyAddress": "0x2279B7A0a67DB372996a5FaB50D91eAA73d2eBe6", - "proxyAdminAddress": "0x94099942864EA81cCF197E9D71ac53310b1468D8", - "implementationAddress": "0xa513E6E4b8f2a923D98304ec87F64353C4D5C853" - }, - "blockNumber": 8, - "address": "0x2279B7A0a67DB372996a5FaB50D91eAA73d2eBe6" - }, - "CiphernodeRegistryOwnable": { - "constructorArgs": { - "owner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "enclaveAddress": "0x0000000000000000000000000000000000000001", - "submissionWindow": "10" - }, - "proxyRecords": { - "initData": "0x1794bb3c000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb922660000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000a", - "initialOwner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "proxyAddress": "0x610178dA211FEF7D417bC0e6FeD39F05609AD788", - "proxyAdminAddress": "0x6F1216D1BFe15c98520CA1434FC1d9D57AC95321", - "implementationAddress": "0x8A791620dd6260079BF849Dc5567aDC3F2FdC318" - }, - "blockNumber": 11, - "address": "0x610178dA211FEF7D417bC0e6FeD39F05609AD788" - }, - "Enclave": { - "constructorArgs": { - "owner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "registry": "0x610178dA211FEF7D417bC0e6FeD39F05609AD788", - "bondingRegistry": "0x2279B7A0a67DB372996a5FaB50D91eAA73d2eBe6", - "feeToken": "0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0", - "maxDuration": "2592000", - "params": [ - "0x000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000fc00100000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000003fffffff000001" - ] - }, - "proxyRecords": { - "initData": "0xefe0308b000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266000000000000000000000000610178da211fef7d417bc0e6fed39f05609ad7880000000000000000000000002279b7a0a67db372996a5fab50d91eaa73d2ebe60000000000000000000000009fe46736679d2d9a65f0992f2272de9f3c7fa6e00000000000000000000000000000000000000000000000000000000000278d0000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000fc00100000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000003fffffff000001", - "initialOwner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "proxyAddress": "0xA51c1fc2f0D1a1b8494Ed1FE312d7C3a78Ed91C0", - "proxyAdminAddress": "0x1F708C24a0D3A740cD47cC0444E9480899f3dA7D", - "implementationAddress": "0xB7f8BC63BbcaD18155201308C8f3540b07f84F5e" - }, - "blockNumber": 13, - "address": "0xA51c1fc2f0D1a1b8494Ed1FE312d7C3a78Ed91C0" - }, - "MockComputeProvider": { - "blockNumber": 23, - "address": "0x59b670e9fA9D0A427751Af201D676719a970857b" - }, - "MockDecryptionVerifier": { - "blockNumber": 24, - "address": "0x4ed7c70F96B99c776995fB64377f0d4aB3B0e1C1" - }, - "MockE3Program": { - "blockNumber": 25, - "address": "0x322813Fd9A801c5507c9de605d63CEA4f2CE6c44" - }, - "MockRISC0Verifier": { - "address": "0x7a2088a1bFc9d81c55368AE168C2C02570cB814F" - }, - "HonkVerifier": { - "address": "0xc5a5C42992dECbae36851359345FE25997F5C42d" - }, - "CRISPProgram": { - "address": "0x67d269191c92Caf3cD7723F116c85e6E9bf55933", - "constructorArgs": { - "enclave": "0xA51c1fc2f0D1a1b8494Ed1FE312d7C3a78Ed91C0", - "verifierAddress": "0x7a2088a1bFc9d81c55368AE168C2C02570cB814F", - "honkVerifierAddress": "0xc5a5C42992dECbae36851359345FE25997F5C42d", - "imageId": "0x23734b77b0f76e85623a88d7a82f24c34c94834f2501964ea123b7a2027013a2" - } - } } } \ No newline at end of file diff --git a/examples/CRISP/packages/crisp-contracts/hardhat.config.ts b/examples/CRISP/packages/crisp-contracts/hardhat.config.ts index 9403e1575f..7c6af6c1d1 100644 --- a/examples/CRISP/packages/crisp-contracts/hardhat.config.ts +++ b/examples/CRISP/packages/crisp-contracts/hardhat.config.ts @@ -77,6 +77,15 @@ const config: HardhatUserConfig = { interval: 1000, }, }, + localhost: { + accounts: { + mnemonic, + }, + chainId: chainIds.hardhat, + type: 'http', + url: 'http://localhost:8545', + timeout: 60000, + }, ganache: { accounts: { mnemonic, From 5ae8a14bf78dcd01c8b4e594053f1f100efc30c0 Mon Sep 17 00:00:00 2001 From: ryardley Date: Thu, 27 Nov 2025 02:55:49 +0000 Subject: [PATCH 32/33] make auto true in order to get deploy scripts working --- examples/CRISP/packages/crisp-contracts/hardhat.config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/CRISP/packages/crisp-contracts/hardhat.config.ts b/examples/CRISP/packages/crisp-contracts/hardhat.config.ts index 7c6af6c1d1..f2ae3a7493 100644 --- a/examples/CRISP/packages/crisp-contracts/hardhat.config.ts +++ b/examples/CRISP/packages/crisp-contracts/hardhat.config.ts @@ -73,7 +73,7 @@ const config: HardhatUserConfig = { type: 'edr-simulated', chainType: 'l1', mining: { - auto: false, + auto: true, interval: 1000, }, }, From 08d8a60ea488e1007a2ad26e9306fafafc0553ce Mon Sep 17 00:00:00 2001 From: ryardley Date: Thu, 27 Nov 2025 03:23:53 +0000 Subject: [PATCH 33/33] remove space --- crates/evm-helpers/tests/integration.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/crates/evm-helpers/tests/integration.rs b/crates/evm-helpers/tests/integration.rs index f9bac54c4f..48a15de85a 100644 --- a/crates/evm-helpers/tests/integration.rs +++ b/crates/evm-helpers/tests/integration.rs @@ -17,7 +17,6 @@ use std::{ time::{Duration, SystemTime, UNIX_EPOCH}, }; use tokio::sync::Mutex; - use tokio::time::sleep; sol!(