42 namespace graphene {
namespace chain {
47 initialize_evaluators();
57 auto last_block = _block_id_to_block.
last();
59 elog(
"!no last block" );
65 ilog(
"reindexing blockchain" );
67 const auto last_block_num = last_block->block_num();
83 std::queue< std::tuple< size_t, signed_block, fc::future< void > > > blocks;
85 uint32_t i = next_block_num;
86 while( next_block_num <= last_block_num || !blocks.empty() )
88 if( next_block_num <= last_block_num && blocks.size() < 20 )
95 if( block->timestamp >= (last_block->timestamp - gpo.parameters.maximum_time_until_expiration) )
97 blocks.emplace( processed_block_size, std::move(*block),
fc::future<void>() );
102 wlog(
"Reindexing terminated due to gap: Block ${i} does not exist!", (
"i", i) );
103 uint32_t dropped_count = 0;
112 _block_id_to_block.
remove( *last_id );
115 wlog(
"Dropped ${n} blocks from after the gap", (
"n", dropped_count) );
116 next_block_num = last_block_num + 1;
121 std::get<2>(blocks.front()).wait();
122 const signed_block& block = std::get<1>(blocks.front());
126 std::stringstream bysize;
127 std::stringstream bynum;
128 size_t current_pos = std::get<0>(blocks.front());
129 if( current_pos > total_block_size )
130 total_block_size = current_pos;
131 bysize << std::fixed << std::setprecision(5) << (100 * double(current_pos) / total_block_size);
132 bynum << std::fixed << std::setprecision(5) << (100 * double(i) / last_block_num);
134 " [by size: ${size}% ${processed} of ${total}] [by num: ${num}% ${i} of ${last}]",
135 (
"size", bysize.str())
136 (
"processed", current_pos)
137 (
"total", total_block_size)
140 (
"last", last_block_num)
143 if( i == undo_point )
145 ilog(
"Writing object database to disk at block ${i}, please DO NOT kill the program", (
"i", i) );
147 ilog(
"Done writing object database to disk" );
162 ilog(
"Done reindexing, elapsed time: ${t} sec", (
"t",
double((end-start).count())/1000000.0 ) );
167 ilog(
"Wiping database", (
"include_blocks", include_blocks));
179 const std::string& db_version)
183 bool wipe_object_db =
false;
185 wipe_object_db =
true;
188 std::string version_string;
190 wipe_object_db = ( version_string != db_version );
192 if( wipe_object_db ) {
193 ilog(
"Wiping object_database due to missing or wrong version");
195 std::ofstream version_file( (data_dir /
"db_version").generic_string().c_str(),
196 std::ios::out | std::ios::binary | std::ios::trunc );
197 version_file.write( db_version.c_str(), db_version.size() );
198 version_file.close();
203 _block_id_to_block.
open(data_dir /
"database" /
"block_num_to_block");
205 if( !
find(global_property_id_type()) )
206 init_genesis(genesis_loader());
209 _p_core_asset_obj = &
get( asset_id_type() );
210 _p_core_dynamic_data_obj = &
get( asset_dynamic_data_id_type() );
211 _p_global_prop_obj = &
get( global_property_id_type() );
212 _p_chain_property_obj = &
get( chain_property_id_type() );
213 _p_dyn_global_prop_obj = &
get( dynamic_global_property_id_type() );
214 _p_witness_schedule_obj = &
get( witness_schedule_id_type() );
218 if( last_block.
valid() )
221 "last block ID does not match current chain state",
222 (
"last_block->id", last_block)(
"head_block_id",
head_block_num()) );
245 ilog(
"Rewinding from ${head} to ${cutoff}", (
"head",
head_block_num())(
"cutoff",cutoff) );
250 _fork_db.
remove(popped_block_id);
255 wlog(
"Database close unexpected exception: ${e}", (
"e", e) );
264 ilog(
"Writing object database to disk at block ${i}, please DO NOT kill the program", (
"i",
head_block_num()) );
266 ilog(
"Done writing object database to disk" );
270 if( _block_id_to_block.
is_open() )
271 _block_id_to_block.
close();