Skip to content

Commit

Permalink
Merge pull request #737 from evoskuil/master
Browse files Browse the repository at this point in the history
Complete validation off-strand, making backlog counter atomic.
  • Loading branch information
evoskuil authored Feb 17, 2025
2 parents 0160386 + edf6cbf commit 573cdd1
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 32 deletions.
4 changes: 2 additions & 2 deletions include/bitcoin/node/chasers/chaser_check.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,13 @@ class BCN_API chaser_check

virtual void do_bump(height_t height) NOEXCEPT;
virtual void do_checked(height_t height) NOEXCEPT;
virtual void do_advanced(height_t height) NOEXCEPT;
virtual void do_headers(height_t branch_point) NOEXCEPT;
virtual void do_regressed(height_t branch_point) NOEXCEPT;
virtual void do_handle_purged(const code& ec) NOEXCEPT;
virtual void do_get_hashes(const map_handler& handler) NOEXCEPT;
virtual void do_put_hashes(const map_ptr& map,
const network::result_handler& handler) NOEXCEPT;
virtual void do_confirmable(height_t height) NOEXCEPT;

private:
typedef std::deque<map_ptr> maps;
Expand All @@ -89,7 +89,7 @@ class BCN_API chaser_check
// These are protected by strand.
size_t inventory_{};
size_t requested_{};
size_t confirmed_{};
size_t advanced_{};
job::ptr job_{};
maps maps_{};
};
Expand Down
7 changes: 3 additions & 4 deletions include/bitcoin/node/chasers/chaser_validate.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#ifndef LIBBITCOIN_NODE_CHASERS_CHASER_VALIDATE_HPP
#define LIBBITCOIN_NODE_CHASERS_CHASER_VALIDATE_HPP

#include <atomic>
#include <bitcoin/database.hpp>
#include <bitcoin/network.hpp>
#include <bitcoin/node/chasers/chaser.hpp>
Expand Down Expand Up @@ -59,8 +60,6 @@ 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, bool bypassed) NOEXCEPT;
virtual void complete_block(const code& ec,
const database::header_link& link, size_t height, bool bypassed) NOEXCEPT;

Expand All @@ -74,11 +73,11 @@ class BCN_API chaser_validate
return backlog_ < maximum_backlog_;
}

// These are protected by strand.
size_t backlog_{};
// This is protected by strand.
network::threadpool threadpool_;

// These are thread safe.
std::atomic<size_t> backlog_{};
network::asio::strand independent_strand_;
const uint32_t subsidy_interval_;
const uint64_t initial_subsidy_;
Expand Down
14 changes: 7 additions & 7 deletions src/chasers/chaser_check.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,10 +129,11 @@ bool chaser_check::handle_event(const code&, chase event_,
POST(do_headers, std::get<height_t>(value));
break;
}
case chase::confirmable:
////case chase::confirmable:
case chase::valid:
{
BC_ASSERT(std::holds_alternative<height_t>(value));
POST(do_confirmable, std::get<height_t>(value));
POST(do_advanced, std::get<height_t>(value));
break;
}
case chase::stop:
Expand Down Expand Up @@ -205,15 +206,15 @@ void chaser_check::do_regressed(height_t branch_point) NOEXCEPT
// track downloaded in order (to move download window)
// ----------------------------------------------------------------------------

void chaser_check::do_confirmable(height_t height) NOEXCEPT
void chaser_check::do_advanced(height_t height) NOEXCEPT
{
BC_ASSERT(stranded());

// Confirmations are ordered and notification order is guaranteed.
confirmed_ = height;
advanced_ = height;

// The full set of requested hashes has been confirmed.
if (confirmed_ == requested_)
if (advanced_ == requested_)
do_headers(height);
}

Expand Down Expand Up @@ -345,8 +346,7 @@ size_t chaser_check::set_unassociated() NOEXCEPT
return {};

// Defer new work issuance until gaps filled and confirmation caught up.
if (position() < requested_ ||
confirmed_ < requested_)
if (position() < requested_ || advanced_ < requested_)
return {};

// Inventory size gets set only once.
Expand Down
30 changes: 11 additions & 19 deletions src/chasers/chaser_validate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
*/
#include <bitcoin/node/chasers/chaser_validate.hpp>

#include <atomic>
#include <bitcoin/system.hpp>
#include <bitcoin/node/chasers/chaser.hpp>
#include <bitcoin/node/define.hpp>
Expand Down Expand Up @@ -171,6 +172,7 @@ void chaser_validate::do_bump(height_t) NOEXCEPT
return;
}

// block_unknown allowed here (debug reset).
const auto bypass =
(ec == database::error::block_valid) ||
(ec == database::error::block_confirmable) ||
Expand All @@ -182,7 +184,7 @@ void chaser_validate::do_bump(height_t) NOEXCEPT
}
else
{
++backlog_;
backlog_.fetch_add(one, std::memory_order_relaxed);
PARALLEL(validate_block, link, bypass);
}

Expand Down Expand Up @@ -225,8 +227,10 @@ void chaser_validate::validate_block(const header_link& link,
ec = error::validate5;
}

backlog_.fetch_sub(one, std::memory_order_relaxed);

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

code chaser_validate::populate(bool bypass, const chain::block& block,
Expand Down Expand Up @@ -267,30 +271,19 @@ code chaser_validate::validate(bool bypass, const chain::block& block,
if ((ec = block.connect(ctx)))
return ec;

if (!query.set_prevouts(link, block))
return error::validate8;
if ((ec = query.set_prevouts(link, block)))
return ec;

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

return ec;
}

// 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, bool bypassed) NOEXCEPT
{
BC_ASSERT(stranded());

--backlog_;
complete_block(ec, link, height, bypassed);
}

// Completes off strand.
void chaser_validate::complete_block(const code& ec, const header_link& link,
size_t height, bool bypassed) NOEXCEPT
{
BC_ASSERT(stranded());

if (ec)
{
if (node::error::error_category::contains(ec))
Expand All @@ -307,7 +300,6 @@ void chaser_validate::complete_block(const code& ec, const header_link& link,
// Stop the network in case of an unexpected invalidity (debugging).
// This is considered a bug, not an invalid block arrival (for now).
////fault(ec);

return;
}

Expand All @@ -320,7 +312,7 @@ void chaser_validate::complete_block(const code& ec, const header_link& link,
}

// Prevent stall by posting internal event, avoid hitting external handlers.
if (is_zero(backlog_))
if (is_zero(backlog_.load(std::memory_order_relaxed)))
handle_event(ec, chase::bump, height_t{});
}

Expand Down

0 comments on commit 573cdd1

Please sign in to comment.