cardano_net/
blockfetch.rs

1use super::channel::Channel;
2use super::packet::ProtocolError;
3use cardano_sdk::protocol::{BlockFetch, BlockFetchKind, Point, SerializedBlock};
4
5/// Block Fetcher Stream like (Async Iterator) object
6///
7/// call `next()` to get the next received block
8pub struct BlockFetcher<'b> {
9    channel: &'b mut Channel<BlockFetch>,
10    done: bool,
11}
12
13impl<'b> BlockFetcher<'b> {
14    /// Get the next received block if still have some, otherwise return None,
15    /// or a protocol error if something unexpected happen.
16    pub async fn next(&mut self) -> Result<Option<SerializedBlock>, ProtocolError> {
17        if self.done {
18            return Ok(None);
19        }
20        match self.channel.rx().await? {
21            BlockFetch::Block(b) => Ok(Some(b)),
22            BlockFetch::BatchDone => {
23                self.done = true;
24                Ok(None)
25            }
26            bf => Err(ProtocolError::UnexpectedVariant(
27                "block fetch (block|done)".to_string(),
28                format!("{:?}", BlockFetchKind::from(bf)),
29            )),
30        }
31    }
32
33    /// Return if the block fetcher is done
34    pub fn done(self) -> bool {
35        self.done
36    }
37}
38
39impl Channel<BlockFetch> {
40    /// Perform the BlockFetch `RequestRange` sub protocol with the opposite side
41    ///
42    /// Return a BlockFetcher which is a
43    pub async fn request_range<'b>(
44        &'b mut self,
45        from: Point,
46        to: Point,
47    ) -> Result<Option<BlockFetcher<'b>>, ProtocolError> {
48        self.tx(false, BlockFetch::RequestRange { from, to })
49            .await?;
50        match self.rx().await? {
51            BlockFetch::StartBatch => Ok(Some(BlockFetcher {
52                channel: self,
53                done: false,
54            })),
55            BlockFetch::NoBlocks => {
56                Ok(None)
57            }
58            bf => Err(ProtocolError::UnexpectedVariant(
59                "block fetch".to_string(),
60                format!("{:?}", BlockFetchKind::from(bf)),
61            )),
62        }
63    }
64}