use brk_error::{Error, Result};
use brk_types::Block;
use crate::State;
pub struct BlockIterator(State);
impl BlockIterator {
pub fn new(state: State) -> Self {
Self(state)
}
}
impl Iterator for BlockIterator {
type Item = Result<Block>;
fn next(&mut self) -> Option<Self::Item> {
match &mut self.0 {
State::Rpc {
client,
heights,
prev_hash,
} => {
let height = heights.next()?;
let hash = match client.get_block_hash(height) {
Ok(h) => h,
Err(e) => return Some(Err(e)),
};
let block = match client.get_block(&hash) {
Ok(b) => b,
Err(e) => return Some(Err(e)),
};
if prev_hash
.as_ref()
.is_some_and(|prev| block.header.prev_blockhash != prev.into())
{
return Some(Err(Error::Internal(
"rpc iterator: chain continuity broken (likely reorg mid-iteration)",
)));
}
prev_hash.replace(hash);
Some(Ok(Block::from((height, hash, block))))
}
State::Reader { receiver } => match receiver.recv().ok()? {
Ok(b) => Some(Ok(Block::from(b))),
Err(e) => Some(Err(e)),
},
}
}
}