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 Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,10 @@ include_bitcoin_node_impl_chasersdir = ${includedir}/bitcoin/node/impl/chasers
include_bitcoin_node_impl_chasers_HEADERS = \
include/bitcoin/node/impl/chasers/chaser_organize.ipp

include_bitcoin_node_impl_sessionsdir = ${includedir}/bitcoin/node/impl/sessions
include_bitcoin_node_impl_sessions_HEADERS = \
include/bitcoin/node/impl/sessions/session_peer.ipp

include_bitcoin_node_messagesdir = ${includedir}/bitcoin/node/messages
include_bitcoin_node_messages_HEADERS = \
include/bitcoin/node/messages/block.hpp \
Expand Down
1 change: 1 addition & 0 deletions builds/msvc/vs2022/libbitcoin-node/libbitcoin-node.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@
</ItemGroup>
<ItemGroup>
<None Include="..\..\..\..\include\bitcoin\node\impl\chasers\chaser_organize.ipp" />
<None Include="..\..\..\..\include\bitcoin\node\impl\sessions\session_peer.ipp" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@
<Filter Include="include\bitcoin\node\impl\chasers">
<UniqueIdentifier>{5FFB5F52-0772-4404-0000-00000000000F}</UniqueIdentifier>
</Filter>
<Filter Include="include\bitcoin\node\impl\sessions">
<UniqueIdentifier>{5FFB5F52-0772-4404-0000-000000000001}</UniqueIdentifier>
</Filter>
<Filter Include="include\bitcoin\node\messages">
<UniqueIdentifier>{5FFB5F52-0772-4404-0000-00000000000C}</UniqueIdentifier>
</Filter>
Expand All @@ -38,7 +41,7 @@
<UniqueIdentifier>{5FFB5F52-0772-4404-0000-00000000000E}</UniqueIdentifier>
</Filter>
<Filter Include="resource">
<UniqueIdentifier>{5FFB5F52-0772-4404-0000-000000000001}</UniqueIdentifier>
<UniqueIdentifier>{5FFB5F52-0772-4404-0000-000000000002}</UniqueIdentifier>
</Filter>
<Filter Include="src">
<UniqueIdentifier>{5FFB5F52-0772-4404-0000-000000000000}</UniqueIdentifier>
Expand Down Expand Up @@ -337,6 +340,9 @@
<None Include="..\..\..\..\include\bitcoin\node\impl\chasers\chaser_organize.ipp">
<Filter>include\bitcoin\node\impl\chasers</Filter>
</None>
<None Include="..\..\..\..\include\bitcoin\node\impl\sessions\session_peer.ipp">
<Filter>include\bitcoin\node\impl\sessions</Filter>
</None>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
Expand Down
166 changes: 166 additions & 0 deletions include/bitcoin/node/impl/sessions/session_peer.ipp
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
/**
* Copyright (c) 2011-2026 libbitcoin developers (see AUTHORS)
*
* This file is part of libbitcoin.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef LIBBITCOIN_NODE_SESSIONS_SESSION_PEER_IPP
#define LIBBITCOIN_NODE_SESSIONS_SESSION_PEER_IPP

namespace libbitcoin {
namespace node {

// this-> is required for dependent base access in CRTP.

TEMPLATE
inline CLASS::channel_ptr CLASS::create_channel(
const socket_ptr& socket) NOEXCEPT
{
BC_ASSERT(this->stranded());

const auto channel = system::emplace_shared<channel_t>(
this->get_memory(), this->log, socket, this->create_key(),
this->node_config(), this->options());

return std::static_pointer_cast<network::channel>(channel);
}

TEMPLATE
inline void CLASS::attach_handshake(const channel_ptr& channel,
network::result_handler&& handler) NOEXCEPT
{
BC_ASSERT(channel->stranded());
BC_ASSERT(channel->paused());

// Set the current top for version protocol, before handshake.
const auto top = this->archive().get_top_confirmed();
const auto peer = std::dynamic_pointer_cast<channel_t>(channel);
peer->set_start_height(top);

// Attach and execute appropriate version protocol.
NetworkSession::attach_handshake(channel, std::move(handler));
}

TEMPLATE
inline void CLASS::attach_protocols(const channel_ptr& channel) NOEXCEPT
{
BC_ASSERT(channel->stranded());
BC_ASSERT(channel->paused());

using namespace system;
using namespace network;
using namespace network::messages::peer;
using base = session_peer<NetworkSession>;

const auto self = this->template shared_from_base<base>();
const auto relay = this->network_settings().enable_relay;
const auto delay = this->node_settings().delay_inbound;
const auto headers = this->node_settings().headers_first;
const auto node_network = to_bool(bit_and<uint64_t>
(
this->network_settings().services_maximum,
service::node_network
));
const auto node_client_filters = to_bool(bit_and<uint64_t>
(
this->network_settings().services_maximum,
service::node_client_filters
));

// Attach appropriate alert, reject, ping, and/or address protocols.
NetworkSession::attach_protocols(channel);

// Channel suspensions.
channel->attach<protocol_observer>(self)->start();

// Ready to relay blocks or block filters.
const auto blocks_out = !delay || this->is_recent();

///////////////////////////////////////////////////////////////////////
// bip152: "Upon receipt of a `sendcmpct` message with the first and
// second integers set to 1, the node SHOULD announce new blocks by
// sending a cmpctblock message." IOW at 70014 bip152 is optional.
// This allows the node to support bip157 without supporting bip152.
///////////////////////////////////////////////////////////////////////

const auto peer = std::dynamic_pointer_cast<channel_t>(channel);

// Node must advertise node_client_filters or no out filters.
if (node_client_filters && blocks_out &&
peer->is_negotiated(level::bip157))
channel->attach<protocol_filter_out_70015>(self)->start();

// Node must advertise node_network or no in|out blocks|txs.
if (!node_network)
return;

// Ready to relay transactions.
const auto txs_in_out = relay && peer->is_negotiated(level::bip37) &&
(!delay || is_current(true));

// Peer advertises chain (blocks in).
if (peer->is_peer_service(service::node_network))
{
if (headers && peer->is_negotiated(level::bip130))
{
channel->attach<protocol_header_in_70012>(self)->start();
channel->attach<protocol_block_in_31800>(self)->start();

}
else if (headers && peer->is_negotiated(level::headers_protocol))
{
channel->attach<protocol_header_in_31800>(self)->start();
channel->attach<protocol_block_in_31800>(self)->start();
}
else
{
// Very hard to find < 31800 peer to connect with.
// Blocks-first synchronization (not base of block_in_31800).
channel->attach<protocol_block_in_106>(self)->start();
}
}

// Blocks are ready (blocks out).
if (blocks_out)
{
if (headers && peer->is_negotiated(level::bip130))
{
channel->attach<protocol_header_out_70012>(self)->start();
channel->attach<protocol_block_out_70012>(self)->start();
}
else if (headers && peer->is_negotiated(level::headers_protocol))
{
channel->attach<protocol_header_out_31800>(self)->start();
channel->attach<protocol_block_out_106>(self)->start();
}
else
{
channel->attach<protocol_block_out_106>(self)->start();
}
}

// Relay is configured, active, and txs are ready (txs in/out).
if (txs_in_out)
{
if (peer->peer_version()->relay)
channel->attach<protocol_transaction_out_106>(self)->start();
}
}

} // namespace node
} // namespace libbitcoin

#endif
2 changes: 1 addition & 1 deletion include/bitcoin/node/protocols/protocol_performer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class BCN_API protocol_performer
: node::protocol_peer(session, channel),
deviation_(session->node_settings().allowed_deviation > 0.0),
enabled_(enabled && to_bool(session->node_settings().sample_period_seconds)),
performance_timer_(std::make_shared<network::deadline>(session->log,
performance_timer_(system::emplace_shared<network::deadline>(session->log,
channel->strand(), session->node_settings().sample_period())),
network::tracker<protocol_performer>(session->log)
{
Expand Down
145 changes: 15 additions & 130 deletions include/bitcoin/node/sessions/session_peer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,141 +54,26 @@ class session_peer
using socket_ptr = network::socket::ptr;
using channel_ptr = network::channel::ptr;

// this-> is required for dependent base access in CRTP.

channel_ptr create_channel(const socket_ptr& socket) NOEXCEPT override
{
BC_ASSERT(this->stranded());

const auto channel = std::make_shared<channel_t>(
this->get_memory(), this->log, socket, this->create_key(),
this->node_config(), this->options());

return std::static_pointer_cast<network::channel>(channel);
}

void attach_handshake(const channel_ptr& channel,
network::result_handler&& handler) NOEXCEPT override
{
BC_ASSERT(channel->stranded());
BC_ASSERT(channel->paused());

// Set the current top for version protocol, before handshake.
const auto top = this->archive().get_top_confirmed();
const auto peer = std::dynamic_pointer_cast<channel_t>(channel);
peer->set_start_height(top);

// Attach and execute appropriate version protocol.
NetworkSession::attach_handshake(channel, std::move(handler));
}

void attach_protocols(const channel_ptr& channel) NOEXCEPT override
{
BC_ASSERT(channel->stranded());
BC_ASSERT(channel->paused());

using namespace system;
using namespace network;
using namespace network::messages::peer;
using base = session_peer<NetworkSession>;

const auto self = this->template shared_from_base<base>();
const auto relay = this->network_settings().enable_relay;
const auto delay = this->node_settings().delay_inbound;
const auto headers = this->node_settings().headers_first;
const auto node_network = to_bool(bit_and<uint64_t>
(
this->network_settings().services_maximum,
service::node_network
));
const auto node_client_filters = to_bool(bit_and<uint64_t>
(
this->network_settings().services_maximum,
service::node_client_filters
));

// Attach appropriate alert, reject, ping, and/or address protocols.
NetworkSession::attach_protocols(channel);

// Channel suspensions.
channel->attach<protocol_observer>(self)->start();

// Ready to relay blocks or block filters.
const auto blocks_out = !delay || this->is_recent();

///////////////////////////////////////////////////////////////////////
// bip152: "Upon receipt of a `sendcmpct` message with the first and
// second integers set to 1, the node SHOULD announce new blocks by
// sending a cmpctblock message." IOW at 70014 bip152 is optional.
// This allows the node to support bip157 without supporting bip152.
///////////////////////////////////////////////////////////////////////

const auto peer = std::dynamic_pointer_cast<channel_t>(channel);

// Node must advertise node_client_filters or no out filters.
if (node_client_filters && blocks_out &&
peer->is_negotiated(level::bip157))
channel->attach<protocol_filter_out_70015>(self)->start();

// Node must advertise node_network or no in|out blocks|txs.
if (!node_network)
return;
inline channel_ptr create_channel(
const socket_ptr& socket) NOEXCEPT override;
inline void attach_handshake(const channel_ptr& channel,
network::result_handler&& handler) NOEXCEPT override;
inline void attach_protocols(const channel_ptr& channel) NOEXCEPT override;
};

// Ready to relay transactions.
const auto txs_in_out = relay && peer->is_negotiated(level::bip37) &&
(!delay || is_current(true));
} // namespace node
} // namespace libbitcoin

// Peer advertises chain (blocks in).
if (peer->is_peer_service(service::node_network))
{
if (headers && peer->is_negotiated(level::bip130))
{
channel->attach<protocol_header_in_70012>(self)->start();
channel->attach<protocol_block_in_31800>(self)->start();
#define TEMPLATE template <typename NetworkSession>
#define CLASS session_peer<NetworkSession>

}
else if (headers && peer->is_negotiated(level::headers_protocol))
{
channel->attach<protocol_header_in_31800>(self)->start();
channel->attach<protocol_block_in_31800>(self)->start();
}
else
{
// Very hard to find < 31800 peer to connect with.
// Blocks-first synchronization (not base of block_in_31800).
channel->attach<protocol_block_in_106>(self)->start();
}
}
////BC_PUSH_WARNING(NO_THROW_IN_NOEXCEPT)

// Blocks are ready (blocks out).
if (blocks_out)
{
if (headers && peer->is_negotiated(level::bip130))
{
channel->attach<protocol_header_out_70012>(self)->start();
channel->attach<protocol_block_out_70012>(self)->start();
}
else if (headers && peer->is_negotiated(level::headers_protocol))
{
channel->attach<protocol_header_out_31800>(self)->start();
channel->attach<protocol_block_out_106>(self)->start();
}
else
{
channel->attach<protocol_block_out_106>(self)->start();
}
}
#include <bitcoin/node/impl/sessions/session_peer.ipp>

// Relay is configured, active, and txs are ready (txs in/out).
if (txs_in_out)
{
if (peer->peer_version()->relay)
channel->attach<protocol_transaction_out_106>(self)->start();
}
}
};
////BC_POP_WARNING()

} // namespace node
} // namespace libbitcoin
#undef CLASS
#undef TEMPLATE

#endif