27 #include <boost/endian/buffers.hpp>
29 namespace graphene {
namespace chain {
37 boost::endian::little_uint64_buf_t
block_pos;
44 namespace graphene {
namespace chain {
49 _block_num_to_pos.exceptions(std::ios_base::failbit | std::ios_base::badbit);
50 _blocks.exceptions(std::ios_base::failbit | std::ios_base::badbit);
52 _index_filename = dbdir /
"index";
55 _block_num_to_pos.open( _index_filename.
generic_string().c_str(), std::fstream::binary | std::fstream::in | std::fstream::out | std::fstream::trunc);
56 _blocks.open( (dbdir/
"blocks").generic_string().c_str(), std::fstream::binary | std::fstream::in | std::fstream::out | std::fstream::trunc);
60 _block_num_to_pos.open( _index_filename.
generic_string().c_str(), std::fstream::binary | std::fstream::in | std::fstream::out );
61 _blocks.open( (dbdir/
"blocks").generic_string().c_str(), std::fstream::binary | std::fstream::in | std::fstream::out );
67 return _blocks.is_open();
73 _block_num_to_pos.close();
79 _block_num_to_pos.flush();
88 elog(
"id argument of block_database::store() was not initialized for block ${id}", (
"id",
id) );
92 _blocks.seekp( 0, _blocks.end );
97 _blocks.write( vec.data(), vec.size() );
98 _block_num_to_pos.write( (
char*)&e,
sizeof(e) );
105 _block_num_to_pos.seekg( 0, _block_num_to_pos.end );
106 if ( _block_num_to_pos.tellg() <= index_pos )
107 FC_THROW_EXCEPTION(fc::key_not_found_exception,
"Block ${id} not contained in block database", (
"id",
id));
109 _block_num_to_pos.seekg( index_pos );
110 _block_num_to_pos.read( (
char*)&e,
sizeof(e) );
116 _block_num_to_pos.write( (
char*)&e,
sizeof(e) );
127 _block_num_to_pos.seekg( 0, _block_num_to_pos.end );
128 if ( _block_num_to_pos.tellg() < int64_t(index_pos +
sizeof(e)) )
130 _block_num_to_pos.seekg( index_pos );
131 _block_num_to_pos.read( (
char*)&e,
sizeof(e) );
138 assert( block_num != 0 );
140 int64_t index_pos =
sizeof(e) * int64_t(block_num);
141 _block_num_to_pos.seekg( 0, _block_num_to_pos.end );
142 if ( _block_num_to_pos.tellg() <= index_pos )
143 FC_THROW_EXCEPTION(fc::key_not_found_exception,
"Block number ${block_num} not contained in block database", (
"block_num", block_num));
145 _block_num_to_pos.seekg( index_pos );
146 _block_num_to_pos.read( (
char*)&e,
sizeof(e) );
158 _block_num_to_pos.seekg( 0, _block_num_to_pos.end );
159 if ( _block_num_to_pos.tellg() <= index_pos )
162 _block_num_to_pos.seekg( index_pos );
163 _block_num_to_pos.read( (
char*)&e,
sizeof(e) );
170 _blocks.read( data.data(), e.
block_size.value() );
171 auto result = fc::raw::unpack<signed_block>(data);
178 catch (
const std::exception&)
189 int64_t index_pos =
sizeof(e) * int64_t(block_num);
190 _block_num_to_pos.seekg( 0, _block_num_to_pos.end );
191 if ( _block_num_to_pos.tellg() <= index_pos )
194 _block_num_to_pos.seekg( index_pos, _block_num_to_pos.beg );
195 _block_num_to_pos.read( (
char*)&e,
sizeof(e) );
199 _blocks.read( data.data(), e.
block_size.value() );
200 auto result = fc::raw::unpack<signed_block>(data);
207 catch (
const std::exception&)
218 _block_num_to_pos.seekg( 0, _block_num_to_pos.end );
219 std::streampos pos = _block_num_to_pos.tellg();
225 _blocks.seekg( 0, _block_num_to_pos.end );
226 const std::streampos blocks_size = _blocks.tellg();
230 _block_num_to_pos.seekg( pos );
231 _block_num_to_pos.read( (
char*)&e,
sizeof(e) );
232 if( _block_num_to_pos.gcount() ==
sizeof(e) && e.
block_size.value() > 0
238 _blocks.read( data.data(), e.
block_size.value() );
239 if( _blocks.gcount() ==
long(e.
block_size.value()) )
241 const signed_block block = fc::raw::unpack<signed_block>(data);
249 catch (
const std::exception&)
258 catch (
const std::exception&)
261 return optional<index_entry>();
274 if( entry.
valid() )
return entry->block_id;
280 return (
size_t)_blocks.tellg();
285 _blocks.seekg( 0, _blocks.end );
286 return (
size_t)_blocks.tellg();