Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions include/bitcoin/node/chasers/chaser_organize.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ class chaser_organize
virtual void organize(const typename Block::cptr& block,
organize_handler&& handler) NOEXCEPT;

/// Reorganize to the branch of an archived block of at least equal work.
virtual void prioritize(const system::hash_digest& hash,
organize_handler&& handler) NOEXCEPT;

protected:
using header_link = database::header_link;
using chain_state = system::chain::chain_state;
Expand Down Expand Up @@ -89,13 +93,17 @@ class chaser_organize
virtual bool handle_chase(const code&, chase event_,
event_value value) NOEXCEPT;

/// Organize a discovered Block.
virtual void do_organize(typename Block::cptr block,
/// Organize a discovered Block, prioritized accepts a tied branch.
virtual void do_organize(typename Block::cptr block, bool prioritized,
const organize_handler& handler) NOEXCEPT;

/// Reorganize following Block unconfirmability.
virtual void do_disorganize(header_t header) NOEXCEPT;

/// Reorganize to the branch of the given block.
virtual void do_prioritize(const system::hash_digest& hash,
const organize_handler& handler) NOEXCEPT;

/// Properties
/// -----------------------------------------------------------------------

Expand Down
4 changes: 4 additions & 0 deletions include/bitcoin/node/full_node.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ class BCN_API full_node
virtual void organize(const system::chain::block::cptr& block,
organize_handler&& handler) NOEXCEPT;

/// Reorganize to the branch of an archived block of at least equal work.
virtual void prioritize(const system::hash_digest& hash,
organize_handler&& handler) NOEXCEPT;

/// Manage download queue.
virtual void get_hashes(map_handler&& handler) NOEXCEPT;
virtual void put_hashes(const map_ptr& map,
Expand Down
50 changes: 46 additions & 4 deletions include/bitcoin/node/impl/chasers/chaser_organize.ipp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/**
/**
* Copyright (c) 2011-2026 libbitcoin developers
*
* This file is part of libbitcoin.
Expand Down Expand Up @@ -73,7 +73,17 @@ void CLASS::organize(const typename Block::cptr& block,
if (closed())
return;

POST(do_organize, block, std::move(handler));
POST(do_organize, block, false, std::move(handler));
}

TEMPLATE
void CLASS::prioritize(const system::hash_digest& hash,
organize_handler&& handler) NOEXCEPT
{
if (closed())
return;

POST(do_prioritize, hash, std::move(handler));
}

// Methods
Expand Down Expand Up @@ -113,7 +123,7 @@ bool CLASS::handle_chase(const code&, chase event_, event_value value) NOEXCEPT
}

TEMPLATE
void CLASS::do_organize(typename Block::cptr block,
void CLASS::do_organize(typename Block::cptr block, bool prioritized,
const organize_handler& handler) NOEXCEPT
{
BC_ASSERT(stranded());
Expand Down Expand Up @@ -217,7 +227,7 @@ void CLASS::do_organize(typename Block::cptr block,
bool strong{};
const auto branch_size = tree_branch.size() + store_branch.size();
const auto branch_point = height - add1(branch_size);
if (!query.get_strong_branch(strong, work, branch_point))
if (!query.get_strong_branch(strong, work, branch_point, prioritized))
{
handler(fault(error::organize3), height);
return;
Expand Down Expand Up @@ -333,6 +343,38 @@ void CLASS::do_organize(typename Block::cptr block,
handler(error::success, height);
}

// bitcoind's preciousblock, a manual tie break between equal work branches.
// The preference is not retained, as the reorganized branch then wins ties.
TEMPLATE
void CLASS::do_prioritize(const system::hash_digest& hash,
const organize_handler& handler) NOEXCEPT
{
BC_ASSERT(stranded());

if (closed())
return;

// Only the top of a cached branch can tie the candidate top.
if (std::any_of(tree_.begin(), tree_.end(), [&](const auto& item) NOEXCEPT
{
return get_header(*item.second).previous_block_hash() == hash;
}))
{
handler(error::success, {});
return;
}

// A tied branch is cached, extract it for reevaluation as prioritized.
auto handle = tree_.extract(hash);
if (!handle)
{
handler(database::error::not_found, {});
return;
}

do_organize(handle.mapped(), true, handler);
}

TEMPLATE
void CLASS::do_disorganize(header_t link) NOEXCEPT
{
Expand Down
4 changes: 4 additions & 0 deletions include/bitcoin/node/protocols/protocol.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,10 @@ class BCN_API protocol
virtual void organize(const system::chain::block::cptr& block,
organize_handler&& handler) NOEXCEPT;

/// Reorganize to the branch of an archived block of at least equal work.
virtual void prioritize(const system::hash_digest& hash,
organize_handler&& handler) NOEXCEPT;

/// Events subscription.
/// -----------------------------------------------------------------------

Expand Down
4 changes: 4 additions & 0 deletions include/bitcoin/node/sessions/session.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ class BCN_API session
virtual void organize(const system::chain::block::cptr& block,
organize_handler&& handler) NOEXCEPT;

/// Reorganize to the branch of an archived block of at least equal work.
virtual void prioritize(const system::hash_digest& hash,
organize_handler&& handler) NOEXCEPT;

/// Manage download queue.
virtual void get_hashes(map_handler&& handler) NOEXCEPT;
virtual void put_hashes(const map_ptr& map,
Expand Down
3 changes: 2 additions & 1 deletion src/chasers/chaser_confirm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -164,8 +164,9 @@ void chaser_confirm::do_bumped(height_t) NOEXCEPT
}

// Compares candidate branch work to confirmed (above fork point).
// A tie is accepted because only prioritization creates one.
bool strong{};
if (!query.get_strong_fork(strong, work, fork_point))
if (!query.get_strong_fork(strong, work, fork_point, true))
{
fault(error::confirm3);
return;
Expand Down
9 changes: 9 additions & 0 deletions src/full_node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,15 @@ void full_node::organize(const system::chain::block::cptr& block,
chaser_block_.organize(block, std::move(handler));
}

void full_node::prioritize(const system::hash_digest& hash,
organize_handler&& handler) NOEXCEPT
{
if (config_.node.headers_first)
chaser_header_.prioritize(hash, std::move(handler));
else
chaser_block_.prioritize(hash, std::move(handler));
}

void full_node::get_hashes(map_handler&& handler) NOEXCEPT
{
chaser_check_.get_hashes(std::move(handler));
Expand Down
6 changes: 6 additions & 0 deletions src/protocols/protocol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,12 @@ void protocol::organize(const system::chain::block::cptr& block,
session_->organize(block, std::move(handler));
}

void protocol::prioritize(const system::hash_digest& hash,
organize_handler&& handler) NOEXCEPT
{
session_->prioritize(hash, std::move(handler));
}

void protocol::subscribe_chase(event_notifier&& handler) NOEXCEPT
{
// This is a shared instance multiply-derived from network::protocol.
Expand Down
6 changes: 6 additions & 0 deletions src/sessions/session.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,12 @@ void session::organize(const block::cptr& block,
node_.organize(block, std::move(handler));
}

void session::prioritize(const hash_digest& hash,
organize_handler&& handler) NOEXCEPT
{
node_.prioritize(hash, std::move(handler));
}

void session::get_hashes(map_handler&& handler) NOEXCEPT
{
node_.get_hashes(std::move(handler));
Expand Down
Loading