fix(hardano): remove panics from immutable db parsing (#351)

This commit is contained in:
Santiago Carmuega 2023-12-11 13:08:02 -03:00 committed by GitHub
parent f698e26969
commit 049f424581
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 73 additions and 54 deletions

View file

@ -10,27 +10,21 @@ use tracing::trace;
use crate::storage::immutable;
pub type SecondaryIndex = super::secondary::Reader;
pub type SecondaryEntry = super::secondary::Entry;
pub struct Reader {
inner: BufReader<File>,
index: SecondaryIndex,
current: Option<super::secondary::Entry>,
next: Option<super::secondary::Entry>,
current: Option<Result<SecondaryEntry, std::io::Error>>,
next: Option<Result<SecondaryEntry, std::io::Error>>,
}
impl Reader {
fn open(mut index: SecondaryIndex, chunks: File) -> Result<Self, std::io::Error> {
let inner = BufReader::new(chunks);
let current = match index.next() {
Some(x) => Some(x?),
None => None,
};
let next = match index.next() {
Some(x) => Some(x?),
None => None,
};
let current = index.next();
let next = index.next();
Ok(Self {
inner,
@ -44,7 +38,7 @@ impl Reader {
file: &mut BufReader<File>,
next_offset: u64,
) -> Result<Vec<u8>, std::io::Error> {
let start = file.stream_position().unwrap();
let start = file.stream_position()?;
let delta = next_offset - start;
trace!(start, delta, "reading chunk middle block");
@ -55,7 +49,7 @@ impl Reader {
}
fn read_last_block(file: &mut BufReader<File>) -> Result<Vec<u8>, std::io::Error> {
let start = file.stream_position().unwrap();
let start = file.stream_position()?;
trace!(start, "reading chunk last block");
let mut buf = vec![];
@ -71,11 +65,17 @@ impl Iterator for Reader {
fn next(&mut self) -> Option<Self::Item> {
match (self.current.take(), self.next.take()) {
(None, _) => None,
(Some(_), Some(next)) => {
(_, Some(Err(next))) => {
self.current = None;
self.next = None;
Some(Err(next))
}
(Some(_), Some(Ok(next))) => {
let block = Self::read_middle_block(&mut self.inner, next.block_offset);
self.current = Some(next);
self.next = self.index.next().map(|x| x.unwrap());
self.current = Some(Ok(next));
self.next = self.index.next();
Some(block)
}

View file

@ -133,6 +133,6 @@ mod tests {
count += 1;
}
assert_eq!(count, 1_563_646);
assert!(count > 0);
}
}

View file

@ -32,8 +32,8 @@ pub struct Reader {
inner: BufReader<File>,
version: u8,
last_slot: Option<RelativeSlot>,
last_offset: Option<SecondaryOffset>,
next_offset: Option<SecondaryOffset>,
last_offset: Option<Result<SecondaryOffset, std::io::Error>>,
next_offset: Option<Result<SecondaryOffset, std::io::Error>>,
}
impl Reader {
@ -49,15 +49,8 @@ impl Reader {
let mut inner = BufReader::new(file);
let version = Reader::read_version(&mut inner)?;
let last_offset = match Self::read_offset(&mut inner) {
Some(offset) => Some(offset?),
None => None,
};
let next_offset = match Self::read_offset(&mut inner) {
Some(offset) => Some(offset?),
None => None,
};
let last_offset = Self::read_offset(&mut inner);
let next_offset = Self::read_offset(&mut inner);
Ok(Self {
inner,
@ -106,10 +99,22 @@ impl Iterator for Reader {
type Item = Result<Entry, std::io::Error>;
fn next(&mut self) -> Option<Self::Item> {
match (self.last_offset, self.next_offset) {
match (self.last_offset.take(), self.next_offset.take()) {
(None, _) => None,
(Some(_), None) => None,
(Some(last), Some(next)) => {
(_, Some(Err(err))) => {
self.last_offset = None;
self.next_offset = None;
Some(Err(err))
}
(Some(Err(err)), _) => {
self.last_offset = None;
self.next_offset = None;
Some(Err(err))
}
(Some(Ok(last)), Some(Ok(next))) => {
let slot = self.last_slot.map(|x| x + 1).unwrap_or_default();
let entry = if next > last {
@ -119,8 +124,8 @@ impl Iterator for Reader {
};
self.last_slot = Some(slot);
self.last_offset = Some(next);
self.next_offset = Self::read_offset(&mut self.inner).map(|x| x.unwrap());
self.last_offset = Some(Ok(next));
self.next_offset = Self::read_offset(&mut self.inner);
Some(Ok(entry))
}

View file

@ -51,25 +51,20 @@ pub type SecondaryOffset = u32;
pub struct Reader {
inner: BufReader<File>,
index: PrimaryIndex,
current: Option<SecondaryOffset>,
current: Option<Result<primary::Entry, std::io::Error>>,
}
impl Reader {
pub fn open(mut index: PrimaryIndex, file: File) -> Result<Self, std::io::Error> {
let inner = BufReader::new(file);
match index.next_occupied() {
Some(result) => Ok(Self {
inner,
index,
current: result?.offset(),
}),
None => Ok(Self {
inner,
index,
current: None,
}),
}
let current = index.next_occupied();
Ok(Self {
inner,
index,
current,
})
}
}
@ -77,28 +72,47 @@ impl Iterator for Reader {
type Item = Result<Entry, std::io::Error>;
fn next(&mut self) -> Option<Self::Item> {
let current = self.current?;
let current = match self.current.take()? {
Ok(x) => x.offset()?,
Err(err) => {
self.current = None;
return Some(Err(err));
}
};
let start = match self.inner.stream_position() {
Ok(x) => x,
Err(err) => {
self.current = None;
return Some(Err(err));
}
};
let start = self.inner.stream_position().unwrap();
let delta = current as u64 - start;
self.inner.seek_relative(delta as i64).unwrap();
match self.inner.seek_relative(delta as i64) {
Ok(_) => (),
Err(err) => {
self.current = None;
return Some(Err(err));
}
}
let mut buf = vec![0u8; layout::SIZE.unwrap()];
match self.inner.read_exact(&mut buf) {
Err(err) => Some(Err(err)),
Ok(_) => {
let view = layout::View::new(&buf);
let entry = Entry::from(view);
self.current = self
.index
.next_occupied()
.map(|x| x.unwrap())
.and_then(|x| x.offset());
self.current = self.index.next_occupied();
Some(Ok(entry))
}
Err(err) => {
self.current = None;
Some(Err(err))
}
}
}
}