@@ -1826,8 +1826,9 @@ struct controller_impl {
1826
1826
// loading from snapshot without a block log so fork_db can't be considered valid
1827
1827
fork_db_reset_root_to_chain_head ();
1828
1828
} else if ( !except_ptr && !check_shutdown () && !irreversible_mode () && forkdb.head ()) {
1829
- // applies all blocks up to forkdb head from forkdb
1830
- maybe_apply_blocks (forked_callback_t {}, trx_meta_cache_lookup{});
1829
+ // applies all blocks up to forkdb head from forkdb, shouldn't return incomplete, but if it does loop until complete
1830
+ while (maybe_apply_blocks (forked_callback_t {}, trx_meta_cache_lookup{}) == controller::apply_blocks_result::incomplete)
1831
+ ;
1831
1832
auto head = forkdb.head ();
1832
1833
ilog ( " reversible blocks replayed to ${bn} : ${id}" , (" bn" , head->block_num ())(" id" , head->id ()) );
1833
1834
}
@@ -2008,7 +2009,9 @@ struct controller_impl {
2008
2009
// See comment below about pause-at-block for why `|| conf.num_configured_p2p_peers > 0`
2009
2010
if (chain_head_is_root || conf.num_configured_p2p_peers > 0 ) {
2010
2011
ilog (" applying branch from fork database ending with block: ${id}" , (" id" , pending_head->id ()));
2011
- maybe_apply_blocks (forked_callback_t {}, trx_meta_cache_lookup{});
2012
+ // applies all blocks up to forkdb head from forkdb, shouldn't return incomplete, but if it does loop until complete
2013
+ while (maybe_apply_blocks (forked_callback_t {}, trx_meta_cache_lookup{}) == controller::apply_blocks_result::incomplete)
2014
+ ;
2012
2015
}
2013
2016
}
2014
2017
} else {
@@ -4296,23 +4299,25 @@ struct controller_impl {
4296
4299
} FC_LOG_AND_RETHROW ( )
4297
4300
}
4298
4301
4299
- void apply_blocks (const forked_callback_t & cb, const trx_meta_cache_lookup& trx_lookup) {
4302
+ controller::apply_blocks_result apply_blocks (const forked_callback_t & cb, const trx_meta_cache_lookup& trx_lookup) {
4300
4303
try {
4301
4304
if ( !irreversible_mode () ) {
4302
- maybe_apply_blocks ( cb, trx_lookup );
4303
- } else {
4304
- log_irreversible ();
4305
- transition_to_savanna_if_needed ();
4305
+ return maybe_apply_blocks ( cb, trx_lookup );
4306
4306
}
4307
+
4308
+ log_irreversible ();
4309
+ transition_to_savanna_if_needed ();
4310
+ return controller::apply_blocks_result::complete;
4307
4311
} FC_LOG_AND_RETHROW ( )
4308
4312
}
4309
4313
4310
- void maybe_apply_blocks ( const forked_callback_t & forked_cb, const trx_meta_cache_lookup& trx_lookup )
4314
+ controller::apply_blocks_result maybe_apply_blocks ( const forked_callback_t & forked_cb, const trx_meta_cache_lookup& trx_lookup )
4311
4315
{
4316
+ controller::apply_blocks_result result = controller::apply_blocks_result::complete;
4312
4317
auto do_apply_blocks = [&](auto & forkdb) {
4313
4318
auto new_head = forkdb.head (); // use best head
4314
4319
if (!new_head)
4315
- return ; // nothing to do, forkdb at root
4320
+ return ;// nothing to do, forkdb at root
4316
4321
auto [new_head_branch, old_head_branch] = forkdb.fetch_branch_from ( new_head->id (), chain_head.id () );
4317
4322
4318
4323
bool switch_fork = !old_head_branch.empty ();
@@ -4358,9 +4363,17 @@ struct controller_impl {
4358
4363
try {
4359
4364
bool applied = apply_block ( bsp, bsp->is_valid () ? controller::block_status::validated
4360
4365
: controller::block_status::complete, trx_lookup );
4361
- if (!switch_fork && (!applied || check_shutdown ())) {
4362
- shutdown ();
4363
- break ;
4366
+ if (!switch_fork) { // always complete a switch fork
4367
+ if (!applied || check_shutdown ()) {
4368
+ shutdown ();
4369
+ break ; // result should be complete since we are shutting down
4370
+ }
4371
+ // Break every ~500ms to allow other tasks (e.g. get_info, SHiP) opportunity to run. User expected
4372
+ // to call apply_blocks again if this returns incomplete.
4373
+ if (!replaying && fc::time_point::now () - start > fc::milliseconds (500 )) {
4374
+ result = controller::apply_blocks_result::incomplete;
4375
+ break ;
4376
+ }
4364
4377
}
4365
4378
} catch ( const std::bad_alloc& ) {
4366
4379
throw ;
@@ -4417,6 +4430,8 @@ struct controller_impl {
4417
4430
};
4418
4431
4419
4432
fork_db.apply <void >(do_apply_blocks);
4433
+
4434
+ return result;
4420
4435
}
4421
4436
4422
4437
deque<transaction_metadata_ptr> abort_block () {
@@ -5179,9 +5194,9 @@ void controller::set_async_aggregation(async_t val) {
5179
5194
my->async_aggregation = val;
5180
5195
}
5181
5196
5182
- void controller::apply_blocks (const forked_callback_t & cb, const trx_meta_cache_lookup& trx_lookup) {
5197
+ controller::apply_blocks_result controller::apply_blocks (const forked_callback_t & cb, const trx_meta_cache_lookup& trx_lookup) {
5183
5198
validate_db_available_size ();
5184
- my->apply_blocks (cb, trx_lookup);
5199
+ return my->apply_blocks (cb, trx_lookup);
5185
5200
}
5186
5201
5187
5202
0 commit comments