diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index a269ae9fe..b37defc9b 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -578,17 +578,6 @@ jobs:
platform: "x64"
version: "vs2022"
tests: "*"
- - image: windows-2025-vs2026
- configuration: "StaticRelease"
- platform: "x64"
- version: "vs2026"
- tests: "*"
-
- - image: windows-2025-vs2026
- configuration: "StaticDebug"
- platform: "x64"
- version: "vs2026"
- tests: "*"
runs-on: ${{ matrix.image }}
diff --git a/Makefile.am b/Makefile.am
index ecf96dd63..1bbe3d5f1 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -45,7 +45,6 @@ src_libbitcoin_network_la_SOURCES = \
src/channels/channel.cpp \
src/channels/channel_http.cpp \
src/channels/channel_peer.cpp \
- src/channels/channel_ws.cpp \
src/config/address.cpp \
src/config/authority.cpp \
src/config/endpoint.cpp \
@@ -222,7 +221,6 @@ test_libbitcoin_network_test_SOURCES = \
test/channels/channel_http.cpp \
test/channels/channel_peer.cpp \
test/channels/channel_rpc.cpp \
- test/channels/channel_ws.cpp \
test/config/address.cpp \
test/config/authority.cpp \
test/config/endpoint.cpp \
@@ -513,7 +511,6 @@ include_bitcoin_network_channels_HEADERS = \
include/bitcoin/network/channels/channel_http.hpp \
include/bitcoin/network/channels/channel_peer.hpp \
include/bitcoin/network/channels/channel_rpc.hpp \
- include/bitcoin/network/channels/channel_ws.hpp \
include/bitcoin/network/channels/channels.hpp
include_bitcoin_network_configdir = ${includedir}/bitcoin/network/config
@@ -693,7 +690,6 @@ include_bitcoin_network_protocols_HEADERS = \
include/bitcoin/network/protocols/protocol_version_70001.hpp \
include/bitcoin/network/protocols/protocol_version_70002.hpp \
include/bitcoin/network/protocols/protocol_version_70016.hpp \
- include/bitcoin/network/protocols/protocol_ws.hpp \
include/bitcoin/network/protocols/protocols.hpp
include_bitcoin_network_sessionsdir = ${includedir}/bitcoin/network/sessions
diff --git a/builds/msvc/vs2022/libbitcoin-network-test/libbitcoin-network-test.vcxproj b/builds/msvc/vs2022/libbitcoin-network-test/libbitcoin-network-test.vcxproj
index 3be694f54..6fd2bc26d 100644
--- a/builds/msvc/vs2022/libbitcoin-network-test/libbitcoin-network-test.vcxproj
+++ b/builds/msvc/vs2022/libbitcoin-network-test/libbitcoin-network-test.vcxproj
@@ -134,7 +134,6 @@
-
$(IntDir)test_config_address.obj
diff --git a/builds/msvc/vs2022/libbitcoin-network-test/libbitcoin-network-test.vcxproj.filters b/builds/msvc/vs2022/libbitcoin-network-test/libbitcoin-network-test.vcxproj.filters
index 264dbeca4..1d5ff0a3c 100644
--- a/builds/msvc/vs2022/libbitcoin-network-test/libbitcoin-network-test.vcxproj.filters
+++ b/builds/msvc/vs2022/libbitcoin-network-test/libbitcoin-network-test.vcxproj.filters
@@ -153,9 +153,6 @@
src\channels
-
- src\channels
-
src\config
diff --git a/builds/msvc/vs2022/libbitcoin-network/libbitcoin-network.vcxproj b/builds/msvc/vs2022/libbitcoin-network/libbitcoin-network.vcxproj
index f8f5c2729..f1eeba864 100644
--- a/builds/msvc/vs2022/libbitcoin-network/libbitcoin-network.vcxproj
+++ b/builds/msvc/vs2022/libbitcoin-network/libbitcoin-network.vcxproj
@@ -128,7 +128,6 @@
-
$(IntDir)src_config_address.obj
@@ -312,7 +311,6 @@
-
@@ -427,7 +425,6 @@
-
diff --git a/builds/msvc/vs2022/libbitcoin-network/libbitcoin-network.vcxproj.filters b/builds/msvc/vs2022/libbitcoin-network/libbitcoin-network.vcxproj.filters
index 341431d97..b428ac415 100644
--- a/builds/msvc/vs2022/libbitcoin-network/libbitcoin-network.vcxproj.filters
+++ b/builds/msvc/vs2022/libbitcoin-network/libbitcoin-network.vcxproj.filters
@@ -189,9 +189,6 @@
src\channels
-
- src\channels
-
src\config
@@ -701,9 +698,6 @@
include\bitcoin\network\channels
-
- include\bitcoin\network\channels
-
include\bitcoin\network\channels
@@ -1046,9 +1040,6 @@
include\bitcoin\network\protocols
-
- include\bitcoin\network\protocols
-
include\bitcoin\network\protocols
diff --git a/include/bitcoin/network.hpp b/include/bitcoin/network.hpp
index ce81ce1a5..9773e2e38 100644
--- a/include/bitcoin/network.hpp
+++ b/include/bitcoin/network.hpp
@@ -45,7 +45,6 @@
#include
#include
#include
-#include
#include
#include
#include
@@ -154,7 +153,6 @@
#include
#include
#include
-#include
#include
#include
#include
diff --git a/include/bitcoin/network/channels/channel_rpc.hpp b/include/bitcoin/network/channels/channel_rpc.hpp
index a97ee278c..a7f55724e 100644
--- a/include/bitcoin/network/channels/channel_rpc.hpp
+++ b/include/bitcoin/network/channels/channel_rpc.hpp
@@ -26,39 +26,19 @@
#include
#include
+// TODO: This template can be re-based on channel_http giving it the ability to
+// TODO: support RPC over both tcp and http/ws. In that case the settings type
+// TODO: can be templatized and reader/writer configured at compile. Without an
+// TODO: http reader the socket cannot be upgraded to ws and thus operates as a
+// TODO: simple TCP socket, and TLS remains possible with all protocols. Http
+// TODO: methods are dispatched from channel to base protocol and re-dispatched
+// TODO: to subscribers. TCP/WS are dispatched to protocol as a custom method.
+// TODO: this allows the base protocol to differentiate these as non-http for
+// TODO: selection of the proper response path. As http is half duplex, notify
+// TODO: is only provided to a TCP or upgraded (WS) socket.
+
namespace libbitcoin {
namespace network {
-
-// TODO: Interface argument provides templated dispatch for rpc protocols.
-// TODO: transport independent sender methods in each are duck typed for rpc protocol.
-// TODO: network::channel_trpc : network::channel
-// TODO: network::channel_wrpc : network::channel_ws
-// : network::channel_http
-// : network::channel
-//
-// TODO: reused channel state unique to electrum/bitcoind.
-// TODO: server::channel_electrum_base
-// TODO: server::channel_bitcoind_base
-//
-// TODO: aliases.
-// TODO: server::channel_electrum_tcp : channel_electrum_base, network::channel_trpc
-// TODO: server::channel_electrum_web : channel_electrum_base, network::channel_wrpc
-// TODO: server::channel_bitcoind_tcp : channel_bitcoind_base, network::channel_trpc
-// TODO: server::channel_bitcoind_web : channel_bitcoind_base, network::channel_wrpc
-//
-// TODO: base sender methods for passthrough to channel senders.
-// TODO: these could be implemented in the two protocols to reduce compile time.
-// TODO: network::protocol_rpc : network::protocol
-//
-// TODO: reused protocol logic unique to electrum/bitcoind.
-// TODO: server::protocol_electrum : network::protocol_rpc
-// TODO: server::protocol_bitcoind : network::protocol_rpc
-//
-// TODO: aliases.
-// TODO: server::protocol_electrum_tcp : network::protocol_electrum
-// TODO: server::protocol_electrum_web : network::protocol_electrum
-// TODO: server::protocol_bitcoind_tcp : network::protocol_bitcoind
-// TODO: server::protocol_bitcoind_web : network::protocol_bitcoind
/// Read rpc-request and send rpc-response, dispatch to Interface.
template
diff --git a/include/bitcoin/network/channels/channel_ws.hpp b/include/bitcoin/network/channels/channel_ws.hpp
deleted file mode 100644
index 30d315099..000000000
--- a/include/bitcoin/network/channels/channel_ws.hpp
+++ /dev/null
@@ -1,71 +0,0 @@
-/**
- * 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 .
- */
-#ifndef LIBBITCOIN_NETWORK_CHANNELS_CHANNEL_WS_HPP
-#define LIBBITCOIN_NETWORK_CHANNELS_CHANNEL_WS_HPP
-
-#include
-#include
-#include
-#include
-#include
-#include
-
-namespace libbitcoin {
-namespace network {
-
-/// Abstract base websocket tcp/ip channel, on base http channel.
-class BCT_API channel_ws
- : public channel_http
-{
-public:
- typedef std::shared_ptr ptr;
- using options_t = settings_t::websocket_server;
-
-protected:
- inline channel_ws(const logger& log, const socket::ptr& socket,
- uint64_t identifier, const settings_t& settings,
- const options_t& options) NOEXCEPT
- : channel_http(log, socket, identifier, settings, options)
- {
- }
-
- /// Reads are never buffered, restart the reader.
- void receive() NOEXCEPT override;
-
- /// Pre-upgrade http read.
- void handle_receive(const code& ec, size_t bytes,
- const http::request_cptr& request) NOEXCEPT override;
-
- /// Post-upgrade websocket read.
- virtual void handle_receive_ws(const code& ec, size_t bytes) NOEXCEPT;
-
- /// Dispatch websocket buffer via derived handlers (override to handle).
- /// Override to handle dispatch, must invoke receive() on complete.
- virtual void dispatch_ws(const http::flat_buffer& buffer,
- size_t bytes) NOEXCEPT;
-
-private:
- // This is protected by strand.
- bool upgraded_{ false };
-};
-
-} // namespace network
-} // namespace libbitcoin
-
-#endif
diff --git a/include/bitcoin/network/channels/channels.hpp b/include/bitcoin/network/channels/channels.hpp
index 9cfdf2b5d..e73bf5deb 100644
--- a/include/bitcoin/network/channels/channels.hpp
+++ b/include/bitcoin/network/channels/channels.hpp
@@ -23,6 +23,5 @@
#include
#include
#include
-#include
#endif
diff --git a/include/bitcoin/network/net/proxy.hpp b/include/bitcoin/network/net/proxy.hpp
index 004b612a4..0fbd56db5 100644
--- a/include/bitcoin/network/net/proxy.hpp
+++ b/include/bitcoin/network/net/proxy.hpp
@@ -132,10 +132,10 @@ class BCT_API proxy
/// Binary or text mode applies to websockets (no-op for tcp).
/// Write the provided buffer to socket, handler posted to socket strand.
- virtual void write(const asio::const_buffer& in,
- count_handler&& handler, bool binary) NOEXCEPT;
+ virtual void write(const asio::const_buffer& in, bool binary,
+ count_handler&& handler) NOEXCEPT;
- /// P2P (generic, fixed size).
+ /// P2P (generic, fixed size, WS: always binary).
/// -----------------------------------------------------------------------
/// Read fixed-size TCP message from the remote endpoint into buffer.
diff --git a/include/bitcoin/network/net/socket.hpp b/include/bitcoin/network/net/socket.hpp
index ed75b1f8f..72c3f854e 100644
--- a/include/bitcoin/network/net/socket.hpp
+++ b/include/bitcoin/network/net/socket.hpp
@@ -120,8 +120,8 @@ class BCT_API socket
/// Binary or text mode applies to websockets (no-op for tcp).
/// Write the provided buffer to socket, handler posted to socket strand.
- virtual void raw_write(const asio::const_buffer& in,
- count_handler&& handler, bool binary=true) NOEXCEPT;
+ virtual void raw_write(const asio::const_buffer& in, bool binary,
+ count_handler&& handler) NOEXCEPT;
/// P2P (generic, fixed size).
/// -----------------------------------------------------------------------
diff --git a/include/bitcoin/network/protocols/protocol_ws.hpp b/include/bitcoin/network/protocols/protocol_ws.hpp
deleted file mode 100644
index cde800a6f..000000000
--- a/include/bitcoin/network/protocols/protocol_ws.hpp
+++ /dev/null
@@ -1,49 +0,0 @@
-/**
- * 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 .
- */
-#ifndef LIBBITCOIN_NETWORK_PROTOCOL_WS_HPP
-#define LIBBITCOIN_NETWORK_PROTOCOL_WS_HPP
-
-#include
-#include
-#include
-#include
-
-namespace libbitcoin {
-namespace network {
-
-class BCT_API protocol_ws
- : public protocol_http
-{
-public:
- typedef std::shared_ptr ptr;
- using channel_t = channel_ws;
- using options_t = channel_t::options_t;
-
-protected:
- inline protocol_ws(const session::ptr& session,
- const channel::ptr& channel, const options_t& options) NOEXCEPT
- : protocol_http(session, channel, options)
- {
- }
-};
-
-} // namespace network
-} // namespace libbitcoin
-
-#endif
diff --git a/include/bitcoin/network/protocols/protocols.hpp b/include/bitcoin/network/protocols/protocols.hpp
index 688b0d153..070119a37 100644
--- a/include/bitcoin/network/protocols/protocols.hpp
+++ b/include/bitcoin/network/protocols/protocols.hpp
@@ -38,6 +38,5 @@
// server
#include
#include
-#include
#endif
diff --git a/src/channels/channel_ws.cpp b/src/channels/channel_ws.cpp
deleted file mode 100644
index 066fd4327..000000000
--- a/src/channels/channel_ws.cpp
+++ /dev/null
@@ -1,123 +0,0 @@
-/**
- * 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 .
- */
-#include
-
-#include
-#include
-#include
-
-namespace libbitcoin {
-namespace network {
-
-#define CLASS channel_ws
-
-using namespace system;
-using namespace network::http;
-using namespace std::placeholders;
-
-BC_PUSH_WARNING(NO_THROW_IN_NOEXCEPT)
-
-// public/virtual
-// ----------------------------------------------------------------------------
-
-void channel_ws::receive() NOEXCEPT
-{
- BC_ASSERT(stranded());
-
- if (stopped() || paused() || !upgraded_)
- {
- channel_http::receive();
- return;
- }
-
- read(request_buffer(),
- std::bind(&channel_ws::handle_receive_ws,
- shared_from_base(), _1, _2));
-}
-
-// upgraded
-// ----------------------------------------------------------------------------
-
-void channel_ws::handle_receive_ws(const code& ec, size_t bytes) NOEXCEPT
-{
- BC_ASSERT(stranded());
-
- if (stopped())
- {
- LOGQ("Websocket read abort [" << endpoint() << "]");
- return;
- }
-
- if (ec)
- {
- // Don't log common conditions.
- if (ec != error::peer_disconnect && ec != error::operation_canceled)
- {
- LOGF("Websocket read failure [" << endpoint() << "] "
- << ec.message());
- }
-
- stop(ec);
- return;
- }
-
- dispatch_ws(request_buffer(), bytes);
-}
-
-void channel_ws::dispatch_ws(const http::flat_buffer&,
- size_t LOG_ONLY(bytes)) NOEXCEPT
-{
- LOGA("Websocket read of " << bytes << " bytes [" << endpoint() << "]");
-
- // TODO: dispatch and restart upon completion.
-
- // Restart reader.
- receive();
-}
-
-// pre-upgrade
-// ----------------------------------------------------------------------------
-
-void channel_ws::handle_receive(const code& ec, size_t bytes,
- const http::request_cptr& request) NOEXCEPT
-{
- BC_ASSERT(stranded());
-
- if (upgraded_)
- {
- LOGF("Http request in websocket state [" << endpoint() << "]");
- stop(network::error::operation_failed);
- return;
- }
-
- if (ec != error::upgraded)
- {
- channel_http::handle_receive(ec, bytes, request);
- return;
- }
-
- upgraded_ = true;
- LOGA("Websocket upgraded [" << endpoint() << "]");
- receive();
-}
-
-BC_POP_WARNING()
-
-} // namespace network
-} // namespace libbitcoin
diff --git a/src/net/deadline.cpp b/src/net/deadline.cpp
index c886a04fa..6b3c428f7 100644
--- a/src/net/deadline.cpp
+++ b/src/net/deadline.cpp
@@ -39,12 +39,12 @@ deadline::deadline(const logger& log, asio::strand& strand,
timer_(strand),
tracker(log)
{
- timer_.expires_after(timeout);
+ // Timer is disarmed (epoch) at construct.
}
deadline::~deadline() NOEXCEPT
{
- BC_ASSERT_MSG(timer_.expiry() == epoch, "");
+ BC_ASSERT(timer_.expiry() == epoch);
}
// Start/stop must not be called concurrently.
diff --git a/src/net/proxy_actions.cpp b/src/net/proxy_actions.cpp
index 291c608b1..bd9403888 100644
--- a/src/net/proxy_actions.cpp
+++ b/src/net/proxy_actions.cpp
@@ -52,8 +52,8 @@ void proxy::read(http::flat_buffer& out, count_handler&& handler) NOEXCEPT
socket_->raw_read(out, std::move(handler));
}
-void proxy::write(const asio::const_buffer& in, count_handler&& handler,
- bool binary) NOEXCEPT
+void proxy::write(const asio::const_buffer& in, bool binary,
+ count_handler&& handler) NOEXCEPT
{
writer call = std::bind(&proxy::do_raw_write,
shared_from_this(), in, binary, std::move(handler));
@@ -67,9 +67,9 @@ void proxy::write(const asio::const_buffer& in, count_handler&& handler,
void proxy::do_raw_write(const asio::const_buffer& payload, bool binary,
const count_handler& handler) NOEXCEPT
{
- socket_->raw_write({ payload.data(), payload.size() },
+ socket_->raw_write({ payload.data(), payload.size() }, binary,
std::bind(&proxy::handle_write,
- shared_from_this(), _1, _2, handler), binary);
+ shared_from_this(), _1, _2, handler));
}
// P2P (generic, fixed size).
diff --git a/src/net/socket_p2p.cpp b/src/net/socket_p2p.cpp
index 442b7b817..4a4412100 100644
--- a/src/net/socket_p2p.cpp
+++ b/src/net/socket_p2p.cpp
@@ -54,7 +54,7 @@ void socket::do_p2p_read(const asio::mutable_buffer& out,
void socket::p2p_write(const asio::const_buffer& in,
count_handler&& handler) NOEXCEPT
{
- raw_write(in, std::move(handler), true);
+ raw_write(in, true, std::move(handler));
}
BC_POP_WARNING()
diff --git a/src/net/socket_raw.cpp b/src/net/socket_raw.cpp
index ffe859fbb..59145e936 100644
--- a/src/net/socket_raw.cpp
+++ b/src/net/socket_raw.cpp
@@ -32,6 +32,9 @@ BC_PUSH_WARNING(NO_THROW_IN_NOEXCEPT)
// RAW (read).
// ----------------------------------------------------------------------------
+// The flat_buffer must have sufficient capacity already allocated before the
+// RAW read is initiated. If the incoming WebSocket message exceeds the current
+// capacity, the read will fail or truncate.
void socket::raw_read(http::flat_buffer& out,
count_handler&& handler) NOEXCEPT
{
@@ -51,8 +54,10 @@ void socket::do_raw_read(ref out,
// RAW (write).
// ----------------------------------------------------------------------------
-void socket::raw_write(const asio::const_buffer& in,
- count_handler&& handler, bool binary) NOEXCEPT
+// The const_buffer is fully allocated before write, so this is currently
+// identical to p2p write.
+void socket::raw_write(const asio::const_buffer& in, bool binary,
+ count_handler&& handler) NOEXCEPT
{
boost::asio::dispatch(strand_,
std::bind(&socket::do_raw_write,
diff --git a/src/net/socket_rpc.cpp b/src/net/socket_rpc.cpp
index 7ad6f5122..564a92108 100644
--- a/src/net/socket_rpc.cpp
+++ b/src/net/socket_rpc.cpp
@@ -148,7 +148,7 @@ void socket::do_rpc_write(boost_code ec, size_t total,
BC_ASSERT(buffer.has_value());
- async_write(buffer.value().first, true,
+ async_write(buffer.value().first, false,
std::bind(&socket::handle_rpc_write,
shared_from_this(), _1, _2, total, out, handler));
}
@@ -210,7 +210,7 @@ void socket::do_rpc_notify(boost_code ec, size_t total,
BC_ASSERT(buffer.has_value());
- async_write(buffer.value().first, true,
+ async_write(buffer.value().first, false,
std::bind(&socket::handle_rpc_notify,
shared_from_this(), _1, _2, total, out, handler));
}
diff --git a/test/channels/channel_ws.cpp b/test/channels/channel_ws.cpp
deleted file mode 100644
index 6d7c3eb62..000000000
--- a/test/channels/channel_ws.cpp
+++ /dev/null
@@ -1,28 +0,0 @@
-/**
- * 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 .
- */
-#include "../test.hpp"
-
-BOOST_AUTO_TEST_SUITE(channel_ws_tests)
-
-BOOST_AUTO_TEST_CASE(channel_ws_tests)
-{
- BOOST_REQUIRE(true);
-}
-
-BOOST_AUTO_TEST_SUITE_END()