alloy icon indicating copy to clipboard operation
alloy copied to clipboard

Added nicer API for Provider mocking

Open PlamenHristov opened this issue 6 months ago • 0 comments

Motivation

I want to able to mock the Provider for Subscription<T> in an easier way like so

...
#[derive(Clone)]
pub struct MockProvider<P, T, N>
{
    inner: Arc<P>,
    from_block: u64,
    to_block: u64,
    _phantom: PhantomData<(T, N)>,
}

...

#[async_trait::async_trait]
impl<P: Provider<T, N> + 'static, T: Transport + Clone, N: Network> Provider<T, N> for MockProvider<P, T, N> {
    fn root(&self) -> &RootProvider<T, N> {
        self.inner.root()
    }
    async fn subscribe_blocks(&self) -> TransportResult<Subscription<Block>> {
        let (tx, rx) = broadcast::channel(100);
        let from_block = self.from_block;
        let to_block = self.to_block;
        let inner = self.inner.clone();

        tokio::spawn(async move {
            for block_number in from_block..=to_block {
                if let Some(block) = inner
                    .get_block_by_number(BlockNumberOrTag::Number(block_number), false)
                    .await
                    .ok()
                {
                    let serialized_block = RawValue::from_string(serde_json::to_string(&block).unwrap()).unwrap();
                    if tx.send(serialized_block).is_err() {
                        break;
                    }
                }
            }
        });

        Ok(rx.into())
    }
}

Solution

impl<T> From<broadcast::Receiver<Box<RawValue>>> for Subscription<T> {
    fn from(rx: broadcast::Receiver<Box<RawValue>>) -> Self {
        Self { inner: RawSubscription { rx, local_id: B256::ZERO }, _pd: std::marker::PhantomData }
    }
}

PR Checklist

  • [ ] Added Tests
  • [ ] Added Documentation
  • [ ] Breaking changes

PlamenHristov avatar Aug 17 '24 13:08 PlamenHristov