Skip to content

Commit

Permalink
Merge pull request #714 from evoskuil/master
Browse files Browse the repository at this point in the history
Confirmation and validation updates.
  • Loading branch information
evoskuil authored Jan 22, 2025
2 parents 66a7516 + 2250d80 commit 470a474
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 114 deletions.
10 changes: 9 additions & 1 deletion console/executor_test_reader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ using namespace system;
using namespace std::chrono;
using namespace std::placeholders;

// arbitrary testing (const).
void executor::read_test(bool dump) const
{
using namespace database;
Expand Down Expand Up @@ -273,7 +274,14 @@ void executor::read_test(bool dump) const

#if defined(UNDEFINED)

// arbitrary testing (const).
void executor::read_test(bool) const
{
database::header_link link{ 350'017_u32 };
const auto ec = query_.block_confirmable(link);
logger(format("block_confirmable [%1%] at height [%2%].") % ec.message() %
query_.get_height(link));
}

void executor::read_test(bool dump) const
{
logger("Wire size computation.");
Expand Down
5 changes: 0 additions & 5 deletions include/bitcoin/node/chasers/chaser_confirm.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,6 @@ class BCN_API chaser_confirm
database::header_link link{};
};

void reset_position(size_t confirmed_height) NOEXCEPT;
bool update_neutrino(const database::header_link& link) NOEXCEPT;

bool set_organized(const database::header_link& link,
height_t height) NOEXCEPT;
bool reset_organized(const database::header_link& link,
Expand All @@ -89,8 +86,6 @@ class BCN_API chaser_confirm

// These are protected by strand.
bool mature_{};
bool filters_{};
neutrino_header neutrino_{};
network::threadpool threadpool_;

// These are thread safe.
Expand Down
2 changes: 2 additions & 0 deletions include/bitcoin/node/chasers/chaser_validate.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ class BCN_API chaser_validate
const system::chain::context& ctx) NOEXCEPT;
virtual code populate(bool bypass, const system::chain::block& block,
const system::chain::context& ctx) NOEXCEPT;
virtual void tracked_complete_block(const code& ec,
const database::header_link& link, size_t height) NOEXCEPT;
virtual void complete_block(const code& ec,
const database::header_link& link, size_t height) NOEXCEPT;

Expand Down
120 changes: 34 additions & 86 deletions src/chasers/chaser_confirm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,7 @@ chaser_confirm::chaser_confirm(full_node& node) NOEXCEPT
code chaser_confirm::start() NOEXCEPT
{
const auto& query = archive();
filters_ = query.neutrino_enabled();
reset_position(query.get_fork());
set_position(query.get_fork());
SUBSCRIBE_EVENTS(handle_event, _1, _2, _3);
return error::success;
}
Expand Down Expand Up @@ -163,7 +162,7 @@ void chaser_confirm::do_regressed(height_t branch_point) NOEXCEPT
}
}

reset_position(branch_point);
set_position(branch_point);
}

// Candidate block validated at given height, if next then confirm/advance.
Expand All @@ -189,108 +188,93 @@ void chaser_confirm::do_bump(height_t) NOEXCEPT
const auto link = query.to_candidate(height);
auto ec = query.get_block_state(link);

// Don't report bypassed block is confirmable until associated.
if (ec == database::error::unassociated)
{
// Wait until the gap is filled.
return;

if (is_under_checkpoint(height) || query.is_milestone(link))
}
else if (is_under_checkpoint(height) || query.is_milestone(link))
{
notify(error::success, chase::confirmable, height);
fire(events::confirm_bypassed, height);
LOGV("Block confirmation bypassed: " << height);
////return;
// Fall through (report confirmed).
}
else if (ec == database::error::unvalidated)
{
// Wait until this block is validated.
return;
}
else if (ec == database::error::block_valid)
{
if (!query.set_strong(link))
{
fault(error::confirm2);
return;
}

//////////////////////////////////////////
// Confirmation query.
// This will pull from new prevouts table.
//////////////////////////////////////////
if ((ec = query.block_confirmable(link)))
{
if (ec == database::error::integrity)
{
fault(error::confirm3);
fault(error::confirm2);
return;
}

if (!query.set_block_unconfirmable(link))
{
fault(error::confirm4);
return;
}

if (!query.set_unstrong(link))
{
fault(error::confirm5);
fault(error::confirm3);
return;
}

// Blocks between link and fork point will be set_unstrong
// by header reorganization, picked up by do_regressed.
notify(ec, chase::unconfirmable, link);
fire(events::block_unconfirmable, height);
LOGR("Unconfirmable block [" << height << "] "
<< ec.message());
LOGR("Unconfirmable block [" << height << "] " << ec.message());
return;
}

if (!query.set_block_confirmable(link))
{
fault(error::confirm6);
fault(error::confirm4);
return;
}

if (!set_organized(link, height))
if (!query.set_strong(link))
{
fault(error::confirm7);
fault(error::confirm5);
return;
}

notify(error::success, chase::confirmable, height);
fire(events::block_confirmed, height);
LOGV("Block confirmed: " << height);
////return;
}
else if (ec == database::error::block_confirmable)
{
if (!query.set_strong(link))
{
fault(error::confirm8);
fault(error::confirm6);
return;
}

notify(error::success, chase::confirmable, height);
fire(events::confirm_bypassed, height);
LOGV("Block previously confirmable: " << height);
////return;
}
else
{
// With or without an error code, shouldn't be here.
// database::error::unassociated [wait state ]
// database::error::unvalidated [wait state ]
// database::error::block_valid [canonical state ]
// database::error::block_confirmable [resurrected state]
// database::error::block_unconfirmable [shouldn't be here]
// database::error::unknown_state [shouldn't be here]
// database::error::unassociated [shouldn't be here]
// database::error::unvalidated [shouldn't be here]
fault(error::confirm9);
fault(error::confirm7);
return;
}

if (!query.set_filter_head(link))
{
fault(error::confirm8);
return;
}

if (!update_neutrino(link))
if (!set_organized(link, height))
{
fault(error::confirm10);
fault(error::confirm9);
return;
}

set_position(height);

notify(error::success, chase::confirmable, height);
fire(events::block_confirmed, height);
////LOGV("Block confirmed: " << height);
}
}

Expand Down Expand Up @@ -624,42 +608,6 @@ bool chaser_confirm::get_is_strong(bool& strong, const uint256_t& fork_work,
return true;
}

// neutrino
// ----------------------------------------------------------------------------

bool chaser_confirm::update_neutrino(const header_link& link) NOEXCEPT
{
// neutrino_.link is only used for this assertion, should compile away.
BC_ASSERT(archive().get_height(link) ==
add1(archive().get_height(neutrino_.link)));

if (!filters_)
return true;

data_chunk filter{};
auto& query = archive();
if (!query.get_filter_body(filter, link))
return false;

neutrino_.link = link;
neutrino_.head = neutrino::compute_filter_header(neutrino_.head, filter);
return query.set_filter_head(link, neutrino_.head);
}

// Expects confirmed height.
// Use for startup and regression, to read current filter header from store.
void chaser_confirm::reset_position(size_t confirmed_height) NOEXCEPT
{
set_position(confirmed_height);

if (filters_)
{
const auto& query = archive();
neutrino_.link = query.to_confirmed(confirmed_height);
query.get_filter_head(neutrino_.head, neutrino_.link);
}
}

// Strand.
// ----------------------------------------------------------------------------

Expand Down
49 changes: 27 additions & 22 deletions src/chasers/chaser_validate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -173,21 +173,17 @@ void chaser_validate::do_bump(height_t) NOEXCEPT
const auto link = query.to_candidate(height);
const auto ec = query.get_block_state(link);

// Wait until the gap is filled at a current height (or next top).
if (ec == database::error::unassociated)
{
// Wait until the gap is filled.
return;

// The size of the job is not relevant to the backlog cost.
++backlog_;

if (ec == database::error::block_unconfirmable)
}
else if (ec == database::error::block_unconfirmable)
{
complete_block(ec, link, height);
return;
}

set_position(height);

const auto bypass =
(ec == database::error::block_valid) ||
(ec == database::error::block_confirmable) ||
Expand All @@ -196,10 +192,14 @@ void chaser_validate::do_bump(height_t) NOEXCEPT
if (bypass && !filter_)
{
complete_block(error::success, link, height);
continue;
}
else
{
++backlog_;
PARALLEL(validate_block, link, bypass);
}

PARALLEL(validate_block, link, bypass);
set_position(height);
}
}

Expand Down Expand Up @@ -237,13 +237,9 @@ void chaser_validate::validate_block(const header_link& link,
{
ec = error::validate5;
}
else
{
fire(events::block_validated, ctx.height);
}

// Return to strand to handle result.
POST(complete_block, ec, link, ctx.height);
POST(tracked_complete_block, ec, link, ctx.height);
}

code chaser_validate::populate(bool bypass, const system::chain::block& block,
Expand Down Expand Up @@ -285,22 +281,29 @@ code chaser_validate::validate(bool bypass, const system::chain::block& block,
if ((ec = block.connect(ctx)))
return ec;

if (!query.set_block_valid(link, block.fees()))
if (!query.set_prevouts(link, block))
return error::validate6;

if (!query.set_prevouts(link, block))
if (!query.set_block_valid(link, block.fees()))
return error::validate7;

return ec;
}

void chaser_validate::complete_block(const code& ec, const header_link& link,
size_t height) NOEXCEPT
// The size of the job is not relevant to the backlog cost.
void chaser_validate::tracked_complete_block(const code& ec,
const header_link& link, size_t height) NOEXCEPT
{
BC_ASSERT(stranded());

// The size of the job is not relevant to the backlog cost.
--backlog_;
complete_block(ec, link, height);
}

void chaser_validate::complete_block(const code& ec, const header_link& link,
size_t height) NOEXCEPT
{
BC_ASSERT(stranded());

if (ec)
{
Expand All @@ -317,13 +320,15 @@ void chaser_validate::complete_block(const code& ec, const header_link& link,
return;
}

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

notify(ec, chase::valid, possible_wide_cast<height_t>(height));
fire(events::block_validated, height);
////LOGV("Block validated: " << height);

// Prevent stall by posting internal event, avoid hitting external handlers.
if (is_zero(backlog_))
Expand Down

0 comments on commit 470a474

Please sign in to comment.