diff --git a/Makefile.am b/Makefile.am
index 943eb918a..6dc738bdc 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -71,7 +71,8 @@ src_libbitcoin_node_la_SOURCES = \
src/sessions/session.cpp \
src/sessions/session_inbound.cpp \
src/sessions/session_manual.cpp \
- src/sessions/session_outbound.cpp
+ src/sessions/session_outbound.cpp \
+ src/sessions/session_tcp.cpp
# local: test/libbitcoin-node-test
#------------------------------------------------------------------------------
@@ -200,6 +201,7 @@ include_bitcoin_node_sessions_HEADERS = \
include/bitcoin/node/sessions/session_inbound.hpp \
include/bitcoin/node/sessions/session_manual.hpp \
include/bitcoin/node/sessions/session_outbound.hpp \
+ include/bitcoin/node/sessions/session_tcp.hpp \
include/bitcoin/node/sessions/sessions.hpp
# files => ${bash_completiondir}
diff --git a/builds/cmake/CMakeLists.txt b/builds/cmake/CMakeLists.txt
index 0915effc5..215ccec4d 100644
--- a/builds/cmake/CMakeLists.txt
+++ b/builds/cmake/CMakeLists.txt
@@ -283,7 +283,8 @@ add_library( ${CANONICAL_LIB_NAME}
"../../src/sessions/session.cpp"
"../../src/sessions/session_inbound.cpp"
"../../src/sessions/session_manual.cpp"
- "../../src/sessions/session_outbound.cpp" )
+ "../../src/sessions/session_outbound.cpp"
+ "../../src/sessions/session_tcp.cpp" )
# ${CANONICAL_LIB_NAME} project specific include directory normalization for build.
#------------------------------------------------------------------------------
diff --git a/builds/msvc/vs2022/libbitcoin-node/libbitcoin-node.vcxproj b/builds/msvc/vs2022/libbitcoin-node/libbitcoin-node.vcxproj
index 70940f6e0..b0d09e10c 100644
--- a/builds/msvc/vs2022/libbitcoin-node/libbitcoin-node.vcxproj
+++ b/builds/msvc/vs2022/libbitcoin-node/libbitcoin-node.vcxproj
@@ -157,6 +157,7 @@
+
@@ -204,6 +205,7 @@
+
diff --git a/builds/msvc/vs2022/libbitcoin-node/libbitcoin-node.vcxproj.filters b/builds/msvc/vs2022/libbitcoin-node/libbitcoin-node.vcxproj.filters
index 5b350838e..2f73303a8 100644
--- a/builds/msvc/vs2022/libbitcoin-node/libbitcoin-node.vcxproj.filters
+++ b/builds/msvc/vs2022/libbitcoin-node/libbitcoin-node.vcxproj.filters
@@ -156,6 +156,9 @@
src\sessions
+
+ src\sessions
+
src
@@ -293,6 +296,9 @@
include\bitcoin\node\sessions
+
+ include\bitcoin\node\sessions
+
include\bitcoin\node\sessions
diff --git a/include/bitcoin/node.hpp b/include/bitcoin/node.hpp
index 64146c496..c95f9dc9a 100644
--- a/include/bitcoin/node.hpp
+++ b/include/bitcoin/node.hpp
@@ -61,6 +61,7 @@
#include
#include
#include
+#include
#include
#endif
diff --git a/include/bitcoin/node/full_node.hpp b/include/bitcoin/node/full_node.hpp
index 90fc5833c..438326b0b 100644
--- a/include/bitcoin/node/full_node.hpp
+++ b/include/bitcoin/node/full_node.hpp
@@ -25,8 +25,7 @@
#include
#include
#include
-////#include
-////#include
+#include
namespace libbitcoin {
namespace node {
@@ -45,6 +44,7 @@ class BCN_API full_node
using store = node::store;
using query = node::query;
using memory_controller = block_memory;
+ using result_handler = network::result_handler;
typedef std::shared_ptr ptr;
/// Constructors.
@@ -59,10 +59,10 @@ class BCN_API full_node
/// -----------------------------------------------------------------------
/// Start the node (seed and manual services).
- void start(network::result_handler&& handler) NOEXCEPT override;
+ void start(result_handler&& handler) NOEXCEPT override;
/// Run the node (inbound/outbound services and blockchain chasers).
- void run(network::result_handler&& handler) NOEXCEPT override;
+ void run(result_handler&& handler) NOEXCEPT override;
/// Close the node.
void close() NOEXCEPT override;
@@ -81,7 +81,7 @@ class BCN_API full_node
/// Manage download queue.
virtual void get_hashes(map_handler&& handler) NOEXCEPT;
virtual void put_hashes(const map_ptr& map,
- network::result_handler&& handler) NOEXCEPT;
+ result_handler&& handler) NOEXCEPT;
/// Events.
/// -----------------------------------------------------------------------
@@ -149,7 +149,7 @@ class BCN_API full_node
/// Handle performance, base returns false (implied terminate).
virtual void performance(object_key channel, uint64_t speed,
- network::result_handler&& handler) NOEXCEPT;
+ result_handler&& handler) NOEXCEPT;
/// Get the memory resource.
virtual network::memory& get_memory() NOEXCEPT;
@@ -160,14 +160,17 @@ class BCN_API full_node
network::session_manual::ptr attach_manual_session() NOEXCEPT override;
network::session_inbound::ptr attach_inbound_session() NOEXCEPT override;
network::session_outbound::ptr attach_outbound_session() NOEXCEPT override;
+ virtual session_explore::ptr attach_explore_session() NOEXCEPT;
/// Virtual handlers.
/// -----------------------------------------------------------------------
- void do_start(const network::result_handler& handler) NOEXCEPT override;
- void do_run(const network::result_handler& handler) NOEXCEPT override;
+ void do_start(const result_handler& handler) NOEXCEPT override;
+ void do_run(const result_handler& handler) NOEXCEPT override;
void do_close() NOEXCEPT override;
private:
+ void start_explore(const code& ec, const result_handler& handler) NOEXCEPT;
+
void do_subscribe_events(const event_notifier& handler,
const event_completer& complete) NOEXCEPT;
void do_notify(const code& ec, chase event_, event_value value) NOEXCEPT;
diff --git a/include/bitcoin/node/protocols/protocol.hpp b/include/bitcoin/node/protocols/protocol.hpp
index 95e4b010f..1110bfbda 100644
--- a/include/bitcoin/node/protocols/protocol.hpp
+++ b/include/bitcoin/node/protocols/protocol.hpp
@@ -29,6 +29,11 @@
namespace libbitcoin {
namespace node {
+///////////////////////////////////////////////////////////////////////////////
+// TODO: ... -> node::protocol_tcp -> node::protocol -> network::protocol. //
+// TODO: ... -> node::protocol_peer -> node::protocol -> network::protocol. //
+///////////////////////////////////////////////////////////////////////////////
+
/// Abstract base for node protocols, thread safe.
class BCN_API protocol
: public network::protocol_peer
diff --git a/include/bitcoin/node/sessions/attach.hpp b/include/bitcoin/node/sessions/attach.hpp
index a85f0aab6..da23f4bff 100644
--- a/include/bitcoin/node/sessions/attach.hpp
+++ b/include/bitcoin/node/sessions/attach.hpp
@@ -20,6 +20,7 @@
#define LIBBITCOIN_NODE_SESSIONS_ATTACH_HPP
#include
+#include
#include
#include
#include
@@ -30,7 +31,7 @@ namespace node {
class full_node;
-/// Session base class template for protocol attachment.
+/// Session base class template for network session attachment.
/// node::session does not derive from network::session (siblings).
/// This avoids the diamond inheritance problem between network/node.
/// Protocol contructors are templatized on Session, obtaining session.
@@ -39,8 +40,10 @@ class attach
: public Session, public node::session
{
public:
- attach(full_node& node, uint64_t identifier) NOEXCEPT
- : Session(node, identifier), session(node)
+ template
+ attach(full_node& node, uint64_t identifier, Args&&... args) NOEXCEPT
+ : Session(node, identifier, std::forward(args)...),
+ node::session(node)
{
}
@@ -56,21 +59,22 @@ class attach
Session::attach_handshake(channel, std::move(handler));
}
- void attach_protocols(const network::channel::ptr& channel) NOEXCEPT override
+ void attach_protocols(
+ const network::channel::ptr& channel) NOEXCEPT override
{
using namespace system;
using namespace network::messages::peer;
- const auto relay = config().network.enable_relay;
- const auto delay = config().node.delay_inbound;
- const auto headers = config().node.headers_first;
+ const auto relay = this->config().network.enable_relay;
+ const auto delay = this->config().node.delay_inbound;
+ const auto headers = this->config().node.headers_first;
const auto node_network = to_bool(bit_and
(
- config().network.services_maximum,
+ this->config().network.services_maximum,
network::messages::peer::service::node_network
));
const auto node_client_filters = to_bool(bit_and
(
- config().network.services_maximum,
+ this->config().network.services_maximum,
network::messages::peer::service::node_client_filters
));
@@ -158,12 +162,12 @@ class attach
}
}
- network::channel::ptr create_channel(const network::socket::ptr& socket) NOEXCEPT override
+ network::channel::ptr create_channel(
+ const network::socket::ptr& socket) NOEXCEPT override
{
return std::static_pointer_cast(
- std::make_shared(node::session::get_memory(),
- network::session::log, socket, node::session::config(),
- network::session::create_key()));
+ std::make_shared(this->get_memory(), this->log,
+ socket, this->config(), this->create_key()));
}
};
diff --git a/include/bitcoin/node/sessions/session_tcp.hpp b/include/bitcoin/node/sessions/session_tcp.hpp
new file mode 100644
index 000000000..4e0dcc58e
--- /dev/null
+++ b/include/bitcoin/node/sessions/session_tcp.hpp
@@ -0,0 +1,57 @@
+/**
+ * Copyright (c) 2011-2025 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 .
+ */
+#ifndef LIBBITCOIN_NODE_SESSIONS_SESSION_TCP_HPP
+#define LIBBITCOIN_NODE_SESSIONS_SESSION_TCP_HPP
+
+#include
+#include
+#include
+
+namespace libbitcoin {
+namespace node {
+
+class full_node;
+
+class session_tcp
+ : public network::session_tcp, public node::session
+{
+public:
+ typedef std::shared_ptr ptr;
+ using options_t = network::session_tcp::options_t;
+
+ session_tcp(full_node& node, uint64_t identifier,
+ const options_t& options) NOEXCEPT;
+
+protected:
+ inline bool enabled() const NOEXCEPT override;
+};
+
+// TODO: move all sessions up from network.
+////using session_web = network::session_server;
+using session_explore = network::session_server;
+////using session_websocket = network::session_server;
+////using session_bitcoind = network::session_server;
+////using session_electrum = network::session_server;
+////using session_stratum_v1 = network::session_server;
+////using session_stratum_v2 = network::session_server;
+
+} // namespace node
+} // namespace libbitcoin
+
+#endif
diff --git a/include/bitcoin/node/sessions/sessions.hpp b/include/bitcoin/node/sessions/sessions.hpp
index 931852b52..dec55b118 100644
--- a/include/bitcoin/node/sessions/sessions.hpp
+++ b/include/bitcoin/node/sessions/sessions.hpp
@@ -24,5 +24,6 @@
#include
#include
#include
+#include
#endif
diff --git a/src/full_node.cpp b/src/full_node.cpp
index c1756d8a5..12515520a 100644
--- a/src/full_node.cpp
+++ b/src/full_node.cpp
@@ -23,8 +23,7 @@
#include
#include
#include
-////#include
-////#include
+#include
namespace libbitcoin {
namespace node {
@@ -32,6 +31,7 @@ namespace node {
using namespace system;
using namespace database;
using namespace network;
+using namespace std::placeholders;
BC_PUSH_WARNING(NO_THROW_IN_NOEXCEPT)
@@ -117,7 +117,28 @@ void full_node::do_run(const result_handler& handler) NOEXCEPT
// This will kick off lagging validations even if not current.
do_notify(error::success, chase::start, height_t{});
- net::do_run(handler);
+ // Start services after network is running.
+ net::do_run(std::bind(&full_node::start_explore, this, _1, handler));
+}
+
+void full_node::start_explore(const code& ec,
+ const result_handler& handler) NOEXCEPT
+{
+ BC_ASSERT_MSG(stranded(), "strand");
+
+ if (ec)
+ {
+ handler(ec);
+ return;
+ }
+
+ if (!config().network.explore.enabled())
+ {
+ handler(ec);
+ return;
+ }
+
+ attach_explore_session()->start(move_copy(handler));
}
void full_node::close() NOEXCEPT
@@ -433,6 +454,11 @@ network::session_outbound::ptr full_node::attach_outbound_session() NOEXCEPT
return attach(*this);
}
+session_explore::ptr full_node::attach_explore_session() NOEXCEPT
+{
+ return net::attach(*this, config_.network.explore);
+}
+
BC_POP_WARNING()
} // namespace node
diff --git a/src/sessions/session_tcp.cpp b/src/sessions/session_tcp.cpp
new file mode 100644
index 000000000..842a92120
--- /dev/null
+++ b/src/sessions/session_tcp.cpp
@@ -0,0 +1,41 @@
+/**
+ * Copyright (c) 2011-2025 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 .
+ */
+#include
+
+#include
+
+namespace libbitcoin {
+namespace node {
+
+session_tcp::session_tcp(full_node& node, uint64_t identifier,
+ const options_t& options) NOEXCEPT
+ : network::session_tcp(node, identifier, options),
+ node::session(node)
+{
+}
+
+// Inbound connection attempts are dropped unless confirmed chain is current.
+// Used instead of suspension because suspension has independent start/stop.
+bool session_tcp::enabled() const NOEXCEPT
+{
+ return !config().node.delay_inbound || is_recent();
+}
+
+} // namespace node
+} // namespace libbitcoin