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
3 changes: 3 additions & 0 deletions include/bitcoin/node/protocols/protocol_block_in_31800.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ class BCN_API protocol_block_in_31800
session->system_settings().top_checkpoint().height()),
block_type_(session->network_settings().witness_node() ?
type_id::witness_block : type_id::block),
node_pruned_(session->network_settings().pruned_node()),
map_(chaser_check::empty_map()),
network::tracker<protocol_block_in_31800>(session->log)
{
Expand Down Expand Up @@ -84,13 +85,15 @@ class BCN_API protocol_block_in_31800

void restore(const map_ptr& map) NOEXCEPT;
bool is_under_checkpoint(size_t height) const NOEXCEPT;
type_id to_block_type(const database::association& item) const NOEXCEPT;
void handle_put_hashes(const code& ec, size_t count) NOEXCEPT;
void handle_get_hashes(const code& ec, const map_ptr& map,
const job::ptr& job) NOEXCEPT;

// These are thread safe.
const size_t top_checkpoint_height_;
const type_id block_type_;
const bool node_pruned_;

// These are protected by strand.
map_ptr map_;
Expand Down
6 changes: 6 additions & 0 deletions include/bitcoin/node/protocols/protocol_block_out_106.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ class BCN_API protocol_block_out_106
protocol_block_out_106(const auto& session,
const network::channel::ptr& channel) NOEXCEPT
: node::protocol_peer(session, channel),
top_checkpoint_height_(
session->system_settings().top_checkpoint().height()),
node_pruned_(session->network_settings().pruned_node()),
node_witness_(session->network_settings().witness_node()),
allow_overlapped_(session->node_settings().allow_overlapped),
network::tracker<protocol_block_out_106>(session->log)
Expand Down Expand Up @@ -73,10 +76,13 @@ class BCN_API protocol_block_out_106
using inventory_item = network::messages::peer::inventory_item;
using inventory_items = network::messages::peer::inventory_items;

bool is_under_checkpoint(const database::header_link& link) NOEXCEPT;
inventory create_inventory(const get_blocks& locator) const NOEXCEPT;
void merge_inventory(const inventory_items& items) NOEXCEPT;

// These are thread safe.
const size_t top_checkpoint_height_;
const bool node_pruned_;
const bool node_witness_;
const bool allow_overlapped_;

Expand Down
39 changes: 29 additions & 10 deletions src/protocols/protocol_block_in_31800.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ get_data protocol_block_in_31800::create_get_data(
// bip144: get_data uses witness type_id but inv does not.
std::for_each(map.pos_begin(), map.pos_end(), [&](const auto& item) NOEXCEPT
{
data.items.emplace_back(block_type_, item.hash);
data.items.emplace_back(to_block_type(item), item.hash);
});

return data;
Expand All @@ -277,8 +277,6 @@ bool protocol_block_in_31800::handle_receive_block(const code& ec,
const auto& block = message->block;
const auto hash = block.hash();
const auto it = map_->find(hash);
auto& query = archive();

if (it == map_->end())
{
// Allow unrequested block, not counted toward performance.
Expand All @@ -287,15 +285,21 @@ bool protocol_block_in_31800::handle_receive_block(const code& ec,
return true;
}

auto& query = archive();
const auto link = it->link;
const auto height = it->context.height;
const auto checked = is_under_checkpoint(height);
const auto bypass = checked || query.is_milestone(link);
if (bypass && node_pruned_ && block.is_segregated())
{
LOGR("Unexpected witness from [" << opposite() << "].");
stop(system::error::unexpected_witness);
return false;
}

// Identify block.
// ........................................................................

const auto checked = is_under_checkpoint(height);
const auto bypass = checked || query.is_milestone(link);

// Tx commitments and malleation are checked under bypass. Invalidity is
// only stored when a strong header has been stored, later to be found out
// as invalid and not malleable. Stored invalidity prevents repeat
Expand Down Expand Up @@ -363,11 +367,16 @@ bool protocol_block_in_31800::handle_receive_block(const code& ec,
// While check could be called here, it's more optimal to defer to validate, as
// requiring only identity here allows the use of the simplified block_view.
code protocol_block_in_31800::identify(const chain::block_view& block,
const chain::context& ctx, bool) const NOEXCEPT
const chain::context& ctx, bool bypass) const NOEXCEPT
{
code ec{};
if (const auto ec = block.identify())
return ec;

// Bypass witness commitment check for stripped blocks.
if (bypass && node_pruned_)
return error::success;

if (((ec = block.identify())) || ((ec = block.identify(ctx))))
if (const auto ec = block.identify(ctx))
return ec;

return error::success;
Expand Down Expand Up @@ -420,14 +429,24 @@ void protocol_block_in_31800::handle_get_hashes(const code& ec,
POST(send_get_data, map, job);
}

// checkpoint
// utility
// ----------------------------------------------------------------------------

bool protocol_block_in_31800::is_under_checkpoint(size_t height) const NOEXCEPT
{
return height <= top_checkpoint_height_;
}

type_id protocol_block_in_31800::to_block_type(
const association& item) const NOEXCEPT
{
const auto stripped = node_pruned_ &&
(is_under_checkpoint(item.context.height) ||
archive().is_milestone(item.link));

return stripped ? type_id::block : block_type_;
}

BC_POP_WARNING()
BC_POP_WARNING()
BC_POP_WARNING()
Expand Down
34 changes: 32 additions & 2 deletions src/protocols/protocol_block_out_106.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,15 @@ using namespace network;
using namespace std::chrono;
using namespace std::placeholders;

BC_PUSH_WARNING(NO_THROW_IN_NOEXCEPT)
BC_PUSH_WARNING(SMART_PTR_NOT_NEEDED)
BC_PUSH_WARNING(NO_VALUE_OR_CONST_REF_SHARED_PTR)

// This protocol provides witness support despite 106 being much older than
// bip144. This is because protocols are splot on the version negotiated in the
// p2p handshake. Witness is enabled via a service bit. Protocols should also
// be factored based on relevant service bits but that is not yet implemented.

// start/stop
// ----------------------------------------------------------------------------

Expand Down Expand Up @@ -202,17 +208,27 @@ void protocol_block_out_106::send_block(const code& ec) NOEXCEPT
if (backlog_.empty()) return;
const auto& item = backlog_.front();
const auto witness = item.is_witness_type();
if (!node_witness_ && witness)
if (witness && !node_witness_)
{
LOGR("Unsupported witness get_data from [" << opposite() << "].");
stop(network::error::protocol_violation);
return;
}

const auto& query = archive();
const auto start = logger::now();
const auto link = query.to_header(item.hash);
if (witness && node_witness_ && node_pruned_ &&
(is_under_checkpoint(link) || query.is_milestone(link)))
{
LOGR("Request of witness for stripped block "
<< encode_hash(item.hash) << " from [" << opposite() << "].");

// The peer should not be asking for this block with witness.
stop(system::error::not_found);
return;
}

const auto start = logger::now();
node::messages::block out{ query.get_wire_block(link, witness), witness };
if (out.block_data.empty())
{
Expand Down Expand Up @@ -255,6 +271,20 @@ protocol_block_out_106::inventory protocol_block_out_106::create_inventory(
);
}

bool protocol_block_out_106::is_under_checkpoint(
const database::header_link& link) NOEXCEPT
{
const auto height = archive().get_height(link);
if (height.is_terminal())
{
fault(database::error::integrity);
return false;
}

return height <= top_checkpoint_height_;
}

BC_POP_WARNING()
BC_POP_WARNING()
BC_POP_WARNING()

Expand Down
Loading