Skip to content

Commit

Permalink
Revert get_bypass() technique, hardwired bypass start.
Browse files Browse the repository at this point in the history
  • Loading branch information
evoskuil committed Jun 4, 2024
1 parent 546817b commit 037b9a5
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 101 deletions.
4 changes: 0 additions & 4 deletions include/bitcoin/node/chase.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,6 @@ enum class chase
/// 'block_in_31800'.
bypass,

/// Request for initial bypass notification (channel_t).
/// Issued by 'block_in_31800' and handled by 'organize'.
get_bypass,

/// Late-stage Invalidity.
/// -----------------------------------------------------------------------

Expand Down
3 changes: 0 additions & 3 deletions include/bitcoin/node/chasers/chaser_organize.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,9 +159,6 @@ class chaser_organize
// Bypass methods.
// ------------------------------------------------------------------------

// Send chase::bypass to new channel.
bool do_get_bypass(object_t channel) const NOEXCEPT;

// The current bypass height.
size_t bypass_height() const NOEXCEPT;

Expand Down
12 changes: 0 additions & 12 deletions include/bitcoin/node/impl/chasers/chaser_organize.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -123,11 +123,6 @@ bool CLASS::handle_event(const code&, chase event_, event_value value) NOEXCEPT
POST(do_disorganize, possible_narrow_cast<header_t>(value));
break;
}
case chase::get_bypass:
{
POST(do_get_bypass, possible_narrow_cast<object_t>(value));
break;
}
case chase::stop:
{
return false;
Expand Down Expand Up @@ -643,13 +638,6 @@ size_t CLASS::bypass_height() const NOEXCEPT
return std::max(active_milestone_height_, top_checkpoint_height_);
}

TEMPLATE
bool CLASS::do_get_bypass(object_t channel) const NOEXCEPT
{
notify_bypass(system::possible_narrow_cast<object_key>(channel));
return true;
}

TEMPLATE
bool CLASS::initialize_bypass() NOEXCEPT
{
Expand Down
11 changes: 4 additions & 7 deletions include/bitcoin/node/protocols/protocol_block_in_31800.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#ifndef LIBBITCOIN_NODE_PROTOCOLS_PROTOCOL_BLOCK_IN_31800_HPP
#define LIBBITCOIN_NODE_PROTOCOLS_PROTOCOL_BLOCK_IN_31800_HPP

#include <atomic>
#include <bitcoin/network.hpp>
#include <bitcoin/node/chasers/chasers.hpp>
#include <bitcoin/node/define.hpp>
Expand Down Expand Up @@ -60,8 +61,8 @@ class BCN_API protocol_block_in_31800

/// Manage work.
bool is_idle() const NOEXCEPT override;
virtual void do_purge(channel_t) NOEXCEPT;
virtual void do_split(channel_t) NOEXCEPT;
virtual void do_purge(channel_t) NOEXCEPT;
virtual void do_report(count_t count) NOEXCEPT;
virtual void do_bypass(height_t height) NOEXCEPT;
virtual void do_get_downloads(count_t count) NOEXCEPT;
Expand All @@ -73,11 +74,7 @@ class BCN_API protocol_block_in_31800
private:
using type_id = network::messages::inventory::type_id;

bool is_bypass_set() const NOEXCEPT;
void set_bypass(size_t bypass) NOEXCEPT;
void set_first_bypass(size_t bypass) NOEXCEPT;
bool is_under_bypass(size_t height) const NOEXCEPT;

code check(const system::chain::block& block,
const system::chain::context& ctx, bool bypass) const NOEXCEPT;

Expand All @@ -90,13 +87,13 @@ class BCN_API protocol_block_in_31800
void handle_get_hashes(const code& ec, const map_ptr& map) NOEXCEPT;
void do_handle_complete(const code& ec) NOEXCEPT;

// This is thread safe.
// These are thread safe.
const network::messages::inventory::type_id block_type_;
std::atomic_bool skip_{};

// These are protected by strand.
map_ptr map_;
size_t bypass_{ max_size_t };
std::chrono::steady_clock::time_point point_{};
};

} // namespace node
Expand Down
128 changes: 53 additions & 75 deletions src/protocols/protocol_block_in_31800.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <bitcoin/node/protocols/protocol_block_in_31800.hpp>

#include <algorithm>
#include <atomic>
#include <bitcoin/database.hpp>
#include <bitcoin/network.hpp>
#include <bitcoin/node/chasers/chasers.hpp>
Expand Down Expand Up @@ -46,12 +47,12 @@ void protocol_block_in_31800::start() NOEXCEPT
if (started())
return;

// protocol::start() call is deferred.
subscribe_events(
BIND(handle_event, _1, _2, _3),
// Events subscription is asynchronous, events may be missed.
subscribe_events(BIND(handle_event, _1, _2, _3),
BIND(handle_complete, _1, _2));

point_ = steady_clock::now();
SUBSCRIBE_CHANNEL(block, handle_receive_block, _1, _2);
protocol::start();
}

// protected
Expand All @@ -76,11 +77,13 @@ void protocol_block_in_31800::do_handle_complete(const code& ec) NOEXCEPT
return;
}

SUBSCRIBE_CHANNEL(block, handle_receive_block, _1, _2);

// TODO: get organizer key from full_node.
notify_one(object_key{ 1 }, error::success, chase::get_bypass,
possible_narrow_cast<object_t>(events_key()));
// Start performance timing and download cycles if candidates are current.
// This prevents a startup delay in which the node waits on a header.
if (is_current())
{
start_performance();
get_hashes(BIND(handle_get_hashes, _1, _2));
}
}

// If this is invoked before do_handle_complete then it will unsubscribe.
Expand All @@ -89,6 +92,7 @@ void protocol_block_in_31800::stopping(const code& ec) NOEXCEPT
BC_ASSERT(stranded());
restore(map_);
map_ = chaser_check::empty_map();
skip_.store(true, std::memory_order_relaxed);
stop_performance();
unsubscribe_events();
protocol::stopping(ec);
Expand All @@ -104,46 +108,7 @@ void protocol_block_in_31800::do_bypass(height_t height) NOEXCEPT
if (stopped())
return;

if (!started())
{
set_first_bypass(height);
return;
}

set_bypass(height);
}

bool protocol_block_in_31800::is_bypass_set() const NOEXCEPT
{
BC_ASSERT(stranded());
return bypass_ != max_size_t;
}

void protocol_block_in_31800::set_bypass(size_t bypass) NOEXCEPT
{
BC_ASSERT(stranded());
bypass_ = bypass;
}

void protocol_block_in_31800::set_first_bypass(size_t bypass) NOEXCEPT
{
BC_ASSERT(stranded());

// Don't start downloads until bypass is set.
set_bypass(bypass);
protocol::start();

using namespace std::chrono;
const auto delay = (steady_clock::now() - point_);
LOGA("Delay: " << duration_cast<milliseconds>(delay).count());

// Start performance timing and download cycles if candidates are current.
// This prevents a startup delay in which the node waits on a header.
if (is_current())
{
start_performance();
get_hashes(BIND(handle_get_hashes, _1, _2));
}
bypass_ = height;
}

bool protocol_block_in_31800::is_under_bypass(size_t height) const NOEXCEPT
Expand All @@ -165,23 +130,32 @@ bool protocol_block_in_31800::handle_event(const code&, chase event_,
{
case chase::split:
{
// chase::split is posted by notify_one() using subscription key.
// 'value' is the channel that requested a split to obtain work.
POST(do_split, channel_t{});
// If this channel has divisible work, split it and stop.
// This is posted by notify_one to the slowest reporting channel.
// This is initiated by 'value' channel notifying chase::starved.
if (!skip_.load(std::memory_order_relaxed))
{
skip_.store(true, std::memory_order_relaxed);
POST(do_split, channel_t{});
}
break;
}
case chase::stall:
{
// If this channel has divisible work, split it and stop.
// There are no channels reporting work, either stalled or done.
// This is initiated by any channel notifying chase::starved.
POST(do_split, channel_t{});
// There are no channels reporting work, so either stalled or done.
// This is initiated by 'value' channel notifying chase::starved.
if (!skip_.load(std::memory_order_relaxed))
{
skip_.store(true, std::memory_order_relaxed);
POST(do_split, channel_t{});
}
break;
}
case chase::purge:
{
// If have work clear it and stop.
// This is initiated by chase::regressed/disorganized.
// If this channel has work clear it and stop.
// Sent by check chaser, initiated by chase::regressed/disorganized.
POST(do_purge, channel_t{});
break;
}
Expand Down Expand Up @@ -223,7 +197,7 @@ void protocol_block_in_31800::do_get_downloads(count_t) NOEXCEPT
{
BC_ASSERT(stranded());

if (stopped() || !started())
if (stopped())
return;

if (is_idle())
Expand All @@ -233,26 +207,10 @@ void protocol_block_in_31800::do_get_downloads(count_t) NOEXCEPT
get_hashes(BIND(handle_get_hashes, _1, _2));
}
}

void protocol_block_in_31800::do_purge(channel_t) NOEXCEPT
{
BC_ASSERT(stranded());

if (!map_->empty())
{
LOGV("Purge work (" << map_->size() << ") from [" << authority() << "].");
map_->clear();
stop(error::sacrificed_channel);
}
}

void protocol_block_in_31800::do_split(channel_t) NOEXCEPT
{
BC_ASSERT(stranded());

if (stopped())
return;

if (map_->empty())
return;

Expand All @@ -263,6 +221,18 @@ void protocol_block_in_31800::do_split(channel_t) NOEXCEPT
stop(error::sacrificed_channel);
}

void protocol_block_in_31800::do_purge(channel_t) NOEXCEPT
{
BC_ASSERT(stranded());

if (map_->empty())
return;

LOGV("Purge work (" << map_->size() << ") from [" << authority() << "].");
map_->clear();
stop(error::sacrificed_channel);
}

void protocol_block_in_31800::do_report(count_t sequence) NOEXCEPT
{
BC_ASSERT(stranded());
Expand Down Expand Up @@ -362,7 +332,7 @@ bool protocol_block_in_31800::handle_receive_block(const code& ec,

// Transaction/witness commitments are required under checkpoint.
// This ensures that the block/header hash represents expected txs.
const auto bypass = /*is_under_bypass(ctx.height) &&*/ !malleable64;
const auto bypass = is_under_bypass(ctx.height) && !malleable64;

// Performs full check if block is mally64 (mally32 caught either way).
if (const auto code = check(*block_ptr, ctx, bypass))
Expand Down Expand Up @@ -453,6 +423,10 @@ bool protocol_block_in_31800::handle_receive_block(const code& ec,

count(message->cached_size);
map_->erase(it);

if (map_->size() <= one)
skip_.store(true, std::memory_order_relaxed);

if (is_idle())
get_hashes(BIND(handle_get_hashes, _1, _2));

Expand Down Expand Up @@ -518,12 +492,16 @@ void protocol_block_in_31800::handle_get_hashes(const code& ec,
return;
}

if (map->size() <= one)
skip_.store(true, std::memory_order_relaxed);

if (map->empty())
{
notify(error::success, chase::starved, events_key());
return;
}

skip_.store(false, std::memory_order_relaxed);
POST(send_get_data, map);
}

Expand Down

0 comments on commit 037b9a5

Please sign in to comment.