Skip to content

Commit

Permalink
Merge pull request #651 from evoskuil/master
Browse files Browse the repository at this point in the history
Fix confirmation chaser.
  • Loading branch information
evoskuil authored Jun 23, 2024
2 parents 8133c84 + ccd7f19 commit cb6cc29
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 72 deletions.
111 changes: 60 additions & 51 deletions src/chasers/chaser_confirm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,18 +107,26 @@ void chaser_confirm::do_validated(height_t height) NOEXCEPT
uint256_t work{};
header_links fork{};

// Scan down from height to first confirmed, accumulate links and sum work.
if (!get_fork_work(work, fork, height))
{
fault(error::get_fork_work);
return;
}

if (!get_is_strong(strong, work, height))
// No longer a candidate fork (heights are not candidates).
if (fork.empty())
return;

// fork_point is the highest common block.
const auto fork_point = height - fork.size();
if (!get_is_strong(strong, work, fork_point))
{
fault(error::get_is_strong);
return;
}

// Not yet a strong fork (confirmed branch has at least as much work).
if (!strong)
return;

Expand All @@ -127,7 +135,6 @@ void chaser_confirm::do_validated(height_t height) NOEXCEPT

auto& query = archive();
const auto top = query.get_top_confirmed();
const auto fork_point = height - fork.size();
if (top < fork_point)
{
fault(error::invalid_fork_point);
Expand Down Expand Up @@ -222,51 +229,51 @@ void chaser_confirm::do_validated(height_t height) NOEXCEPT
fault(error::set_confirmed);
return;
}

continue;
}

ec = query.block_confirmable(link);
if (ec == database::error::integrity)
{
fault(error::node_confirm);
return;
}

if (ec)
else
{
if (!query.set_block_unconfirmable(link))
ec = query.block_confirmable(link);
if (ec == database::error::integrity)
{
fault(error::set_block_unconfirmable);
fault(error::node_confirm);
return;
}

LOGR("Unconfirmable block [" << index << "] " << ec.message());
notify(ec, chase::unconfirmable, link);
fire(events::block_unconfirmable, index);

if (!roll_back(popped, link, fork_point, index))
if (ec)
{
fault(error::node_roll_back);
}
if (!query.set_block_unconfirmable(link))
{
fault(error::set_block_unconfirmable);
return;
}

return;
}
LOGR("Unconfirmable block [" << index << "] " << ec.message());
notify(ec, chase::unconfirmable, link);
fire(events::block_unconfirmable, index);

// TODO: compute fees from validation records.
if (!query.set_block_confirmable(link, uint64_t{}))
{
fault(error::block_confirmable);
return;
}
if (!roll_back(popped, link, fork_point, index))
{
fault(error::node_roll_back);
}

notify(error::success, chase::confirmable, index);
fire(events::block_confirmed, index);
return;
}

if (!set_organized(link, index))
{
fault(error::set_confirmed);
return;
// TODO: compute fees from validation records.
if (!query.set_block_confirmable(link, uint64_t{}))
{
fault(error::block_confirmable);
return;
}

notify(error::success, chase::confirmable, index);
fire(events::block_confirmed, index);

if (!set_organized(link, index))
{
fault(error::set_confirmed);
return;
}
}

LOGV("Block confirmed and organized: " << index);
Expand Down Expand Up @@ -637,31 +644,33 @@ bool chaser_confirm::roll_back(const header_links& popped,
return true;
}

bool chaser_confirm::get_fork_work(uint256_t& fork_work,
header_links& fork, height_t fork_top) const NOEXCEPT
bool chaser_confirm::get_fork_work(uint256_t& fork_work, header_links& fork,
height_t fork_top) const NOEXCEPT
{
const auto& query = archive();
header_link link{};
fork_work = zero;
fork.clear();

// Walk down candidate index from fork_top to fork point (first confirmed).
for (auto link = query.to_candidate(fork_top);
!query.is_confirmed_block(link);
// Walk down candidates from fork_top to fork point (highest common).
for (link = query.to_candidate(fork_top);
!link.is_terminal() && !query.is_confirmed_block(link);
link = query.to_candidate(--fork_top))
{
// Terminal candidate from validated link implies candidate regression.
// This is ok, just means that the fork is no longer a candidate.
if (link.is_terminal())
{
fork_work = zero;
return true;
}

uint32_t bits{};
if (!query.get_bits(bits, link))
return false;

fork_work += chain::header::proof(bits);
fork.push_back(link);
fork_work += system::chain::header::proof(bits);
}

// Terminal candidate from validated link implies candidate regression.
// This is ok, it just means that the fork is no longer a candidate.
if (link.is_terminal())
{
fork_work = zero;
fork.clear();
}

return true;
Expand All @@ -682,7 +691,7 @@ bool chaser_confirm::get_is_strong(bool& strong, const uint256_t& fork_work,
return false;

// Not strong when confirmed_work equals or exceeds fork_work.
confirmed_work += system::chain::header::proof(bits);
confirmed_work += chain::header::proof(bits);
if (confirmed_work >= fork_work)
{
strong = false;
Expand Down
42 changes: 21 additions & 21 deletions src/chasers/chaser_validate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -177,30 +177,30 @@ void chaser_validate::do_bump(height_t) NOEXCEPT
// Don't confirm until validations are current.
if (is_current(link))
notify(ec, chase::valid, height);

continue;
}

////// TODO: the quantity of work must be throttled.
////// This will very rapidly pump all outstanding work into asio queue.
////if (!enqueue_block(link))
////{
//// fault(error::node_validate);
//// return;
////}
if (!query.set_block_valid(link))
else
{
fault(error::set_block_valid);
return;
}

// Retain last height in validation sequence, update neutrino.
update_position(height);
////fire(events::block_validated, height);
////// TODO: the quantity of work must be throttled.
////// Will very rapidly pump outstanding work in asio queue.
////if (!enqueue_block(link))
////{
//// fault(error::node_validate);
//// return;
////}
if (!query.set_block_valid(link))
{
fault(error::set_block_valid);
return;
}

// Retain last height in validation sequence, update neutrino.
update_position(height);
////fire(events::block_validated, height);

// Don't confirm until validations are current.
if (is_current(link))
notify(ec, chase::valid, height);
// Don't confirm until validations are current.
if (is_current(link))
notify(ec, chase::valid, height);
}
}
}

Expand Down

0 comments on commit cb6cc29

Please sign in to comment.