@@ -45,14 +45,15 @@ void block_database::open( const fc::path& dbdir )
4545 _block_num_to_pos.exceptions (std::ios_base::failbit | std::ios_base::badbit);
4646 _blocks.exceptions (std::ios_base::failbit | std::ios_base::badbit);
4747
48- if ( !fc::exists ( dbdir/" index" ) )
48+ _index_filename = dbdir / " index" ;
49+ if ( !fc::exists ( _index_filename ) )
4950 {
50- _block_num_to_pos.open ( (dbdir/ " index " ) .generic_string ().c_str (), std::fstream::binary | std::fstream::in | std::fstream::out | std::fstream::trunc);
51+ _block_num_to_pos.open ( _index_filename .generic_string ().c_str (), std::fstream::binary | std::fstream::in | std::fstream::out | std::fstream::trunc);
5152 _blocks.open ( (dbdir/" blocks" ).generic_string ().c_str (), std::fstream::binary | std::fstream::in | std::fstream::out | std::fstream::trunc);
5253 }
5354 else
5455 {
55- _block_num_to_pos.open ( (dbdir/ " index " ) .generic_string ().c_str (), std::fstream::binary | std::fstream::in | std::fstream::out );
56+ _block_num_to_pos.open ( _index_filename .generic_string ().c_str (), std::fstream::binary | std::fstream::in | std::fstream::out );
5657 _blocks.open ( (dbdir/" blocks" ).generic_string ().c_str (), std::fstream::binary | std::fstream::in | std::fstream::out );
5758 }
5859} FC_CAPTURE_AND_RETHROW ( (dbdir) ) }
@@ -121,7 +122,7 @@ bool block_database::contains( const block_id_type& id )const
121122 index_entry e;
122123 auto index_pos = sizeof (e)*block_header::num_from_id (id);
123124 _block_num_to_pos.seekg ( 0 , _block_num_to_pos.end );
124- if ( _block_num_to_pos.tellg () <= index_pos )
125+ if ( _block_num_to_pos.tellg () < index_pos + sizeof (e) )
125126 return false ;
126127 _block_num_to_pos.seekg ( index_pos );
127128 _block_num_to_pos.read ( (char *)&e, sizeof (e) );
@@ -206,77 +207,69 @@ optional<signed_block> block_database::fetch_by_number( uint32_t block_num )cons
206207 return optional<signed_block>();
207208}
208209
209- optional<signed_block> block_database::last ()const
210- {
210+ optional<index_entry> block_database::last_index_entry ()const {
211211 try
212212 {
213213 index_entry e;
214+
214215 _block_num_to_pos.seekg ( 0 , _block_num_to_pos.end );
216+ std::streampos pos = _block_num_to_pos.tellg ();
217+ if ( pos < sizeof (index_entry) )
218+ return optional<index_entry>();
215219
216- if ( _block_num_to_pos.tellp () < sizeof (index_entry) )
217- return optional<signed_block>();
220+ pos -= pos % sizeof (index_entry);
218221
219- _block_num_to_pos.seekg ( -sizeof (index_entry), _block_num_to_pos.end );
220- _block_num_to_pos.read ( (char *)&e, sizeof (e) );
221- uint64_t pos = _block_num_to_pos.tellg ();
222- while ( e.block_size == 0 && pos > 0 )
222+ _blocks.seekg ( 0 , _block_num_to_pos.end );
223+ const std::streampos blocks_size = _blocks.tellg ();
224+ while ( pos > 0 )
223225 {
224226 pos -= sizeof (index_entry);
225227 _block_num_to_pos.seekg ( pos );
226228 _block_num_to_pos.read ( (char *)&e, sizeof (e) );
229+ if ( _block_num_to_pos.gcount () == sizeof (e) && e.block_size > 0
230+ && e.block_pos + e.block_size <= blocks_size )
231+ try
232+ {
233+ vector<char > data ( e.block_size );
234+ _blocks.seekg ( e.block_pos );
235+ _blocks.read ( data.data (), e.block_size );
236+ if ( _blocks.gcount () == e.block_size )
237+ {
238+ const signed_block block = fc::raw::unpack<signed_block>(data);
239+ if ( block.id () == e.block_id )
240+ return e;
241+ }
242+ }
243+ catch (const fc::exception&)
244+ {
245+ }
246+ catch (const std::exception&)
247+ {
248+ }
249+ fc::resize_file ( _index_filename, pos );
227250 }
228-
229- if ( e.block_size == 0 )
230- return optional<signed_block>();
231-
232- vector<char > data ( e.block_size );
233- _blocks.seekg ( e.block_pos );
234- _blocks.read ( data.data (), e.block_size );
235- auto result = fc::raw::unpack<signed_block>(data);
236- return result;
237251 }
238252 catch (const fc::exception&)
239253 {
240254 }
241255 catch (const std::exception&)
242256 {
243257 }
258+ return optional<index_entry>();
259+ }
260+
261+ optional<signed_block> block_database::last ()const
262+ {
263+ optional<index_entry> entry = last_index_entry ();
264+ if ( entry.valid () ) return fetch_by_number ( block_header::num_from_id (entry->block_id ) );
244265 return optional<signed_block>();
245266}
246267
247268optional<block_id_type> block_database::last_id ()const
248269{
249- try
250- {
251- index_entry e;
252- _block_num_to_pos.seekg ( 0 , _block_num_to_pos.end );
253-
254- if ( _block_num_to_pos.tellp () < sizeof (index_entry) )
255- return optional<block_id_type>();
256-
257- _block_num_to_pos.seekg ( -sizeof (index_entry), _block_num_to_pos.end );
258- _block_num_to_pos.read ( (char *)&e, sizeof (e) );
259- uint64_t pos = _block_num_to_pos.tellg ();
260- while ( e.block_size == 0 && pos > 0 )
261- {
262- pos -= sizeof (index_entry);
263- _block_num_to_pos.seekg ( pos );
264- _block_num_to_pos.read ( (char *)&e, sizeof (e) );
265- }
266-
267- if ( e.block_size == 0 )
268- return optional<block_id_type>();
269-
270- return e.block_id ;
271- }
272- catch (const fc::exception&)
273- {
274- }
275- catch (const std::exception&)
276- {
277- }
270+ optional<index_entry> entry = last_index_entry ();
271+ if ( entry.valid () ) return entry->block_id ;
278272 return optional<block_id_type>();
279273}
280274
281-
282275} }
0 commit comments