Skip to content

Commit

Permalink
fix(hardano): remove panics from immutable db parsing (#351)
Browse files Browse the repository at this point in the history
  • Loading branch information
scarmuega authored Dec 11, 2023
1 parent f698e26 commit 049f424
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 54 deletions.
32 changes: 16 additions & 16 deletions pallas-hardano/src/storage/immutable/chunk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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");

Expand All @@ -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![];
Expand All @@ -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)
}
Expand Down
2 changes: 1 addition & 1 deletion pallas-hardano/src/storage/immutable/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,6 @@ mod tests {
count += 1;
}

assert_eq!(count, 1_563_646);
assert!(count > 0);
}
}
35 changes: 20 additions & 15 deletions pallas-hardano/src/storage/immutable/primary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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,
Expand Down Expand Up @@ -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 {
Expand All @@ -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))
}
Expand Down
58 changes: 36 additions & 22 deletions pallas-hardano/src/storage/immutable/secondary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,54 +51,68 @@ 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,
})
}
}

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))
}
}
}
}
Expand Down

0 comments on commit 049f424

Please sign in to comment.