From 6a77235bedd40e532e7959f92f7da1e5cccfd0fe Mon Sep 17 00:00:00 2001 From: rustaceanrob Date: Wed, 13 Aug 2025 16:48:46 +0100 Subject: [PATCH] Add a shallow `.hints` file parser --- hintfile/src/lib.rs | 42 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/hintfile/src/lib.rs b/hintfile/src/lib.rs index fefd188..92451ea 100644 --- a/hintfile/src/lib.rs +++ b/hintfile/src/lib.rs @@ -1,4 +1,9 @@ -use std::io::{self, Read, Write}; +use std::{ + collections::BTreeMap, + io::{self, Read, Write}, +}; + +use bitcoin::{BlockHeight, BlockHeightInterval}; pub fn write_compact_size(value: u64, writer: &mut W) -> Result<(), io::Error> { match value { @@ -37,6 +42,41 @@ pub fn read_compact_size(reader: &mut R) -> Result { } } +#[derive(Debug)] +pub struct Hints { + map: BTreeMap>, +} + +impl Hints { + // # Panics + // + // Panics when expected data is not present, or the hintfile overflows the maximum blockheight + pub fn from_file(reader: &mut R) -> Self { + let mut map = BTreeMap::new(); + let mut height = BlockHeight::from_u32(1); + while let Ok(count) = read_compact_size(reader) { + // panics on 32 bit machines + let mut offsets = Vec::with_capacity(count as usize); + for _ in 0..count { + offsets.push(read_compact_size(reader).expect("unexpected end of hintfile")); + } + map.insert(height, offsets); + height = height + .checked_add(BlockHeightInterval::from_u32(1)) + .expect("hintfile absurdly large.") + } + Self { map } + } + + /// # Panics + /// + /// If there are no offset present at that height, aka an overflow, or the entry has already + /// been fetched. + pub fn take_block_offsets(&mut self, height: BlockHeight) -> Vec { + self.map.remove(&height).expect("block height overflow") + } +} + #[cfg(test)] mod tests { use crate::{read_compact_size, write_compact_size};