@@ -159,19 +159,18 @@ void chaser_confirm::do_bumped(height_t height) NOEXCEPT
159159 if (closed ())
160160 return ;
161161
162- // Scan from candidate height to first confirmed, return links and work.
162+ // If empty height is not on a candidate fork (may have been reorganized).
163+ auto fork = get_fork (height);
164+ if (fork.empty ())
165+ return ;
166+
163167 uint256_t work{};
164- header_links fork{};
165- if (!get_fork_work (work, fork, height))
168+ if (!get_fork_work (work, fork))
166169 {
167170 fault (error::confirm1);
168171 return ;
169172 }
170173
171- // No longer a candidate fork (may have been reorganized).
172- if (fork.empty ())
173- return ;
174-
175174 bool strong{};
176175 const auto fork_point = height - fork.size ();
177176 if (!get_is_strong (strong, work, fork_point))
@@ -426,34 +425,47 @@ bool chaser_confirm::roll_back(const header_links& popped, size_t fork_point,
426425// ----------------------------------------------------------------------------
427426// These are subject to intervening/concurrent candidate chain reorganization.
428427
429- bool chaser_confirm::get_fork_work ( uint256_t & fork_work, header_links& fork,
428+ chaser_confirm::header_links chaser_confirm::get_fork (
430429 height_t fork_top) const NOEXCEPT
431430{
432431 BC_ASSERT (stranded ());
433432 const auto & query = archive ();
434433 header_link link{};
434+ header_links out{};
435435
436436 // Prevents organizer from popping candidates (does not block push).
437437 get_reorganization_lock ();
438438
439439 // Walk down candidates from fork_top to fork point (highest common).
440- for (link = query.to_candidate (fork_top); !link.is_terminal () &&
441- !query.is_confirmed_block (link); link = query.to_candidate (--fork_top))
440+ for (link = query.to_candidate (fork_top);
441+ !link.is_terminal () && !query.is_confirmed_block (link);
442+ link = query.to_candidate (--fork_top))
442443 {
443- uint32_t bits{};
444- if (!query.get_bits (bits, link))
445- return false ;
446-
447- fork_work += chain::header::proof (bits);
448- fork.push_back (link);
444+ out.push_back (link);
449445 }
450446
451447 // Terminal candidate from previously valid height implies regression.
452448 // This is ok, it just means that the fork is no longer a candidate.
453449 if (link.is_terminal ())
450+ out.clear ();
451+
452+ return out;
453+ }
454+
455+ bool chaser_confirm::get_fork_work (uint256_t & fork_work,
456+ const header_links& fork) const NOEXCEPT
457+ {
458+ BC_ASSERT (stranded ());
459+ const auto & query = archive ();
460+
461+ // Walk down candidates from fork_top to fork point (highest common).
462+ for (const auto & link: fork)
454463 {
455- fork_work = zero;
456- fork.clear ();
464+ uint32_t bits{};
465+ if (!query.get_bits (bits, link))
466+ return false ;
467+
468+ fork_work += chain::header::proof (bits);
457469 }
458470
459471 return true ;
0 commit comments