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
4 changes: 4 additions & 0 deletions include/bitcoin/node/protocols/protocol_header_in_70014.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class BCN_API protocol_header_in_70014
void start() NOEXCEPT override;

protected:
using send_compact = network::messages::peer::send_compact;
using compact_transactions = network::messages::peer::compact_transactions;
using compact_block = network::messages::peer::compact_block;
using short_id_t = system::chain::short_id::integer;
Expand All @@ -68,6 +69,8 @@ class BCN_API protocol_header_in_70014
/// Invoked when initial headers sync is complete.
void complete() NOEXCEPT override;

virtual bool handle_receive_send_compact(const code& ec,
const send_compact::cptr& message) NOEXCEPT;
virtual bool handle_receive_compact_block(const code& ec,
const compact_block::cptr& message) NOEXCEPT;
virtual bool handle_receive_compact_transactions(const code& ec,
Expand All @@ -88,6 +91,7 @@ class BCN_API protocol_header_in_70014
bool to_hashes(system::hashes& txids, system::hashes& wtxids,
const fill& block) NOEXCEPT;

void upgrade() NOEXCEPT;
void request() NOEXCEPT;
void identify() NOEXCEPT;
bool resolve(const database::header_link& link) NOEXCEPT;
Expand Down
4 changes: 0 additions & 4 deletions include/bitcoin/node/protocols/protocol_header_out_70014.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,6 @@ class BCN_API protocol_header_out_70014

virtual bool handle_receive_send_compact(const code& ec,
const network::messages::peer::send_compact::cptr& message) NOEXCEPT;

private:
// This is protected by strand.
bool high_bandwidth_{};
};

} // namespace node
Expand Down
38 changes: 30 additions & 8 deletions src/protocols/protocol_header_in_70014.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,29 +45,51 @@ void protocol_header_in_70014::start() NOEXCEPT
if (started())
return;

SUBSCRIBE_CHANNEL(send_compact, handle_receive_send_compact, _1, _2);
SUBSCRIBE_CHANNEL(compact_block, handle_receive_compact_block, _1, _2);
SUBSCRIBE_CHANNEL(compact_transactions,
handle_receive_compact_transactions, _1, _2);

protocol_header_in_70012::start();
}

// Compact block announcements are requested once current (high bandwidth).
void protocol_header_in_70014::complete() NOEXCEPT
{
BC_ASSERT(stranded());
upgrade();
protocol_header_in_70012::complete();
}

// Inbound (sendcmpct).
// ----------------------------------------------------------------------------

bool protocol_header_in_70014::handle_receive_send_compact(const code& ec,
const send_compact::cptr&) NOEXCEPT
{
BC_ASSERT(stranded());

if (stopped(ec))
return false;

upgrade();
return true;
}

// High bandwidth is requested of a peer that signaled compact blocks, once the
// chain is current, whichever comes last.
void protocol_header_in_70014::upgrade() NOEXCEPT
{
BC_ASSERT(stranded());

// TODO: this is hardwired in handshake.
constexpr auto version = send_compact::compact_version_2;

if (!compact_ && is_current_chain(true))
{
compact_ = true;
SEND((send_compact{ true, version }), handle_send, _1);
LOGP("Subscribed to compact blocks at [" << opposite() << "].");
}
if (compact_ || !accepts_compact_blocks() || !is_current_chain(true))
return;

protocol_header_in_70012::complete();
compact_ = true;
SEND((send_compact{ true, version }), handle_send, _1);
LOGP("Subscribed to compact blocks at [" << opposite() << "].");
}

// Inbound (cmpctblock).
Expand Down
15 changes: 5 additions & 10 deletions src/protocols/protocol_header_out_70014.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ bool protocol_header_out_70014::do_announce(header_t link) NOEXCEPT
if (stopped())
return false;

if (high_bandwidth_)
if (wants_compact_blocks())
{
// Don't announce to peer that announced to us.
const auto hash = archive().get_header_key(link);
Expand Down Expand Up @@ -88,15 +88,10 @@ bool protocol_header_out_70014::handle_receive_send_compact(const code& ec,
if (stopped(ec))
return false;

// Only version 2 is supported, the peer may change bandwidth mode.
if (message->compact_version == send_compact::compact_version_2)
{
high_bandwidth_ = message->high_bandwidth;
if (high_bandwidth_)
announce();
}

// TODO: drop peer on non-negotiated version.
// The signal is recorded on the channel by the version protocol.
if ((message->compact_version == send_compact::compact_version_2) &&
message->high_bandwidth)
announce();

return true;
}
Expand Down
32 changes: 31 additions & 1 deletion test/functional/p2p_compact.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,11 @@ BOOST_AUTO_TEST_CASE(functional_p2p_compact__handshake__verack__send_compact_low
BOOST_REQUIRE_EQUAL(message->compact_version, send_compact::compact_version_2);
}

// Headers completion when current requests compact block announcement.
// Headers completion when current requests announcement of a signaled peer.
BOOST_AUTO_TEST_CASE(functional_p2p_compact__headers__complete__send_compact_high_bandwidth)
{
BOOST_REQUIRE(handshake(full_node));
send(send_compact{ false, send_compact::compact_version_2 }, node_version->value);

receive(get_headers::command);
send(headers{}, node_version->value);
Expand All @@ -68,6 +69,35 @@ BOOST_AUTO_TEST_CASE(functional_p2p_compact__headers__complete__send_compact_hig
BOOST_REQUIRE_EQUAL(message->compact_version, send_compact::compact_version_2);
}

// A peer that has not signaled compact blocks is not asked to announce.
BOOST_AUTO_TEST_CASE(functional_p2p_compact__headers__complete_unsignaled__no_high_bandwidth)
{
BOOST_REQUIRE(handshake(full_node));
receive(send_compact::command);

receive(get_headers::command);
send(headers{}, node_version->value);
send(ping{ 42 }, node_version->value);

BOOST_REQUIRE(!received(send_compact::command, pong::command));
}

// A peer signaling after headers completion is then asked to announce.
BOOST_AUTO_TEST_CASE(functional_p2p_compact__send_compact__after_complete__send_compact_high_bandwidth)
{
BOOST_REQUIRE(handshake(full_node));
receive(send_compact::command);

receive(get_headers::command);
send(headers{}, node_version->value);
send(send_compact{ false, send_compact::compact_version_2 }, node_version->value);

const auto message = send_compact::deserialize(node_version->value, receive(send_compact::command));
BOOST_REQUIRE(message);
BOOST_REQUIRE(message->high_bandwidth);
BOOST_REQUIRE_EQUAL(message->compact_version, send_compact::compact_version_2);
}

// cmpctblock (out)
// ----------------------------------------------------------------------------

Expand Down
Loading