-
Notifications
You must be signed in to change notification settings - Fork 22
feat: connect crisp to blockchain time [skip-line-limit] #1052
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
33 commits
Select commit
Hold shift + click to select a range
6814e8c
add threshold queue
80734fd
add callback queue
771075d
add blocklistener that does not do much
e035e94
add block listener test
b1de704
loop restart
fb31b0d
listen for blocks and add do_later to context
b4dde83
add test for memory in do_later
54706fa
use do_later to wait for blocktime
3a608e5
update hardhat config
389a611
update hardhat config
b46202a
enable polling mode
85eaf7f
revert to hh sim mode
5375c03
use annvil
24a95b2
use anvil
5718343
update contracty things
2e50513
update env
ec87b85
avoid goto(/) issue
d3ba77b
update indexer to avoid waiting and use blocktime
ff4fa0b
remove sleep
015df26
remove comment
7909ece
remove redundent settings
16a861e
revert accidental ordering
35107ad
remove line to get in size limit
83354fe
use localhost network specifically
7ba2a97
set hardhat config
7d47863
revert contract changes
2cc4e0b
revert contract changes
f303254
fix bad command
1dac4a3
fix bad command
8ea5e9e
revert use default
706b61a
add explicit localhost network
5ae8a14
make auto true in order to get deploy scripts working
08d8a60
remove space
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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::{network::Ethereum, providers::Provider, rpc::types::Header}; | ||
| 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<dyn Fn(&Header) -> Pin<Box<dyn Future<Output = Result<()>> + Send>> + Send + Sync>; | ||
|
|
||
| #[derive(Clone)] | ||
| pub struct BlockListener { | ||
| provider: Arc<dyn Provider<Ethereum>>, | ||
| block_handlers: Arc<RwLock<Vec<BlockHandler>>>, | ||
| } | ||
|
|
||
| impl BlockListener { | ||
| pub fn new(provider: Arc<dyn Provider<Ethereum>>) -> Self { | ||
| Self { | ||
| provider, | ||
| block_handlers: Arc::new(RwLock::new(Vec::new())), | ||
| } | ||
| } | ||
|
|
||
| pub async fn add_block_handler<F, Fut>(&self, handler: F) | ||
| where | ||
| F: Fn(&Header) -> Fut + Send + Sync + 'static, | ||
| Fut: Future<Output = Result<()>> + 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(()) | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,130 @@ | ||
| // 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<T> { | ||
| inner: Arc<RwLock<BinaryHeap<Reverse<T>>>>, | ||
| } | ||
|
|
||
| /// 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; | ||
| } | ||
|
|
||
| impl<T, U> ThresholdQueue<T> | ||
| where | ||
| T: ThresholdItem<Item = U>, | ||
| { | ||
| /// 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<T::Item> { | ||
| 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<std::cmp::Ordering> { | ||
| 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]); | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.