11use std:: {
22 collections:: BTreeMap ,
3- io:: { self , Read , Write } ,
3+ fs:: File ,
4+ io:: { self , Read , Seek , SeekFrom , Write } ,
45} ;
56
6- type BlockHash = [ u8 ; 32 ] ;
77type BlockHeight = u32 ;
8+ type FilePos = u64 ;
89
910pub fn write_compact_size < W : Write > ( value : u64 , writer : & mut W ) -> Result < ( ) , io:: Error > {
1011 match value {
@@ -45,43 +46,46 @@ pub fn read_compact_size<R: Read>(reader: &mut R) -> Result<u64, io::Error> {
4546
4647#[ derive( Debug ) ]
4748pub struct Hints {
48- map : BTreeMap < BlockHeight , Vec < u64 > > ,
49- assume_valid : BlockHash ,
49+ map : BTreeMap < BlockHeight , FilePos > ,
50+ file : File ,
5051 stop_height : BlockHeight ,
5152}
5253
5354impl Hints {
5455 // # Panics
5556 //
5657 // Panics when expected data is not present, or the hintfile overflows the maximum blockheight
57- pub fn from_file < R : Read > ( reader : & mut R ) -> Self {
58+ pub fn from_file ( mut file : File ) -> Self {
5859 let mut map = BTreeMap :: new ( ) ;
59- let mut height = 1 ;
60+ let mut magic = [ 0 ; 4 ] ;
61+ file. read_exact ( & mut magic) . unwrap ( ) ;
62+ assert_eq ! ( magic, [ 0x55 , 0x54 , 0x58 , 0x4f ] ) ;
63+ let mut ver = [ 0 ; 1 ] ;
64+ file. read_exact ( & mut ver) . unwrap ( ) ;
65+ if u8:: from_le_bytes ( ver) != 0x00 {
66+ panic ! ( "Unsupported file version." ) ;
67+ }
6068 let mut stop_height = [ 0 ; 4 ] ;
61- reader. read_exact ( & mut stop_height) . expect ( "empty file" ) ;
62- let mut assume_valid = [ 0 ; 32 ] ;
63- reader. read_exact ( & mut assume_valid) . expect ( "empty file" ) ;
64- while let Ok ( count) = read_compact_size ( reader) {
65- // panics on 32 bit machines
66- let mut offsets = Vec :: with_capacity ( count as usize ) ;
67- for _ in 0 ..count {
68- offsets. push ( read_compact_size ( reader) . expect ( "unexpected end of hintfile" ) ) ;
69- }
70- map. insert ( height, offsets) ;
71- height += 1 ;
69+ file. read_exact ( & mut stop_height) . expect ( "empty file" ) ;
70+ let stop_height = BlockHeight :: from_le_bytes ( stop_height) ;
71+ for _ in 1 ..=stop_height {
72+ let mut height = [ 0 ; 4 ] ;
73+ file. read_exact ( & mut height)
74+ . expect ( "expected kv pair does not exist." ) ;
75+ let height = BlockHeight :: from_le_bytes ( height) ;
76+ let mut file_pos = [ 0 ; 8 ] ;
77+ file. read_exact ( & mut file_pos)
78+ . expect ( "expected kv pair does not exist." ) ;
79+ let file_pos = FilePos :: from_le_bytes ( file_pos) ;
80+ map. insert ( height, file_pos) ;
7281 }
7382 Self {
7483 map,
75- assume_valid ,
76- stop_height : BlockHeight :: from_le_bytes ( stop_height ) ,
84+ file ,
85+ stop_height,
7786 }
7887 }
7988
80- /// Get the last hash encoded in the hintfile.
81- pub fn stop_hash ( & self ) -> BlockHash {
82- self . assume_valid
83- }
84-
8589 /// Get the stop height of the hint file.
8690 pub fn stop_height ( & self ) -> BlockHeight {
8791 self . stop_height
@@ -91,15 +95,20 @@ impl Hints {
9195 ///
9296 /// If there are no offset present at that height, aka an overflow, or the entry has already
9397 /// been fetched.
94- pub fn get_indexes ( & self , height : BlockHeight ) -> Vec < u64 > {
95- let offsets = self
98+ pub fn get_indexes ( & mut self , height : BlockHeight ) -> Vec < u64 > {
99+ let file_pos = self
96100 . map
97101 . get ( & height)
98102 . cloned ( )
99103 . expect ( "block height overflow" ) ;
100- let mut indexes = Vec :: with_capacity ( offsets. len ( ) ) ;
104+ self . file
105+ . seek ( SeekFrom :: Start ( file_pos) )
106+ . expect ( "missing file position." ) ;
107+ let num_unspents = read_compact_size ( & mut self . file ) . expect ( "unexpected missing hints." ) ;
108+ let mut indexes = Vec :: new ( ) ;
101109 let mut prev = 0 ;
102- for offset in offsets {
110+ for _ in 0 ..num_unspents {
111+ let offset = read_compact_size ( & mut self . file ) . expect ( "unexpected missing hints." ) ;
103112 let next = prev + offset;
104113 indexes. push ( next) ;
105114 prev = next;
0 commit comments