Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

diagnose, rpc: fix compilation with boost 1.87 #2786

Merged
merged 8 commits into from
Jan 12, 2025
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
6 changes: 3 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ env:
jobs:
test-linux:
name: ${{ matrix.name }}
runs-on: ubuntu-20.04
runs-on: ubuntu-24.04
strategy:
matrix:
include:
- name: ARM [GOAL install] [buster]
- name: ARM [GOAL install] [bullseye]
script-id: arm
- name: Win32
script-id: win32
Expand All @@ -21,7 +21,7 @@ jobs:
script-id: linux_i386
- name: x86_64 Linux [GOAL install] [GUI] [focal] [no depends]
script-id: native
- name: x86_64 Linux [GOAL install] [GUI] [bionic] [no depends]
- name: x86_64 Linux [GOAL install] [GUI] [noble] [no depends]
script-id: native_old
- name: x86_64 Linux [ASan] [LSan] [UBSan] [integer] [jammy] [no depends]
script-id: native_asan
Expand Down
5 changes: 1 addition & 4 deletions .github/workflows/cmake-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ jobs:
- name: Install dependencies
run: brew install --overwrite
${{matrix.deps}}
boost@1.85
boost
ccache
libzip
ninja
Expand All @@ -168,7 +168,6 @@ jobs:
-DCMAKE_C_COMPILER_LAUNCHER=ccache
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache
${{matrix.options}}
-DBOOST_ROOT=$(brew --prefix [email protected])
-DENABLE_TESTS=ON
- name: Restore cache
uses: actions/cache/restore@v4
Expand Down Expand Up @@ -196,8 +195,6 @@ jobs:
retention-days: 7

test-msys2:
# MSYS2 is rolling release, only latest Boost is available.
if: false
runs-on: windows-latest
defaults:
run:
Expand Down
8 changes: 7 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,13 @@ if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.30)
# Allow to find old Boost (pre 1.70) with new CMake (3.30 and later).
cmake_policy(SET CMP0167 OLD)
endif()
find_package(Boost ${BOOST_MINIMUM_VERSION}...<1.87.0 COMPONENTS ${BOOST_COMPONENTS} REQUIRED)
find_package(Boost ${BOOST_MINIMUM_VERSION} REQUIRED)
if(Boost_VERSION VERSION_LESS 1.70.0)
find_package(Boost ${BOOST_MINIMUM_VERSION} COMPONENTS ${BOOST_COMPONENTS} REQUIRED)
else()
# Better upstream-provided CMake config is available.
find_package(Boost ${BOOST_MINIMUM_VERSION} COMPONENTS ${BOOST_COMPONENTS} CONFIG REQUIRED)
endif()

if(BUNDLED_OPENSSL)
hunter_add_package(OpenSSL)
Expand Down
2 changes: 1 addition & 1 deletion cd/00_setup_env.sh
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export HOST=${HOST:-$("$BASE_ROOT_DIR/depends/config.guess")}
# Whether to prefer BusyBox over GNU utilities
export USE_BUSY_BOX=${USE_BUSY_BOX:-false}
export CONTAINER_NAME=${CONTAINER_NAME:-ci_unnamed}
export DOCKER_NAME_TAG=${DOCKER_NAME_TAG:-ubuntu:18.04}
export DOCKER_NAME_TAG=${DOCKER_NAME_TAG:-ubuntu:20.04}
# See man 7 debconf
export DEBIAN_FRONTEND=noninteractive
export CCACHE_SIZE=${CCACHE_SIZE:-300M}
Expand Down
2 changes: 1 addition & 1 deletion ci/test/00_setup_env.sh
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export RUN_SECURITY_TESTS=${RUN_SECURITY_TESTS:-false}
export TEST_RUNNER_ENV=${TEST_RUNNER_ENV:-}
export RUN_FUZZ_TESTS=${RUN_FUZZ_TESTS:-false}
export CONTAINER_NAME=${CONTAINER_NAME:-ci_unnamed}
export DOCKER_NAME_TAG=${DOCKER_NAME_TAG:-ubuntu:18.04}
export DOCKER_NAME_TAG=${DOCKER_NAME_TAG:-ubuntu:20.04}
# Randomize test order.
# See https://www.boost.org/doc/libs/1_71_0/libs/test/doc/html/boost_test/utf_reference/rt_param_reference/random.html
export BOOST_TEST_RANDOM=${BOOST_TEST_RANDOM:-1}
Expand Down
2 changes: 1 addition & 1 deletion ci/test/00_setup_env_arm.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ if [ -n "$QEMU_USER_CMD" ]; then
fi
export CONTAINER_NAME=ci_arm_linux
# Use debian to avoid 404 apt errors when cross compiling
export DOCKER_NAME_TAG="debian:buster"
export DOCKER_NAME_TAG="debian:bullseye"
export USE_BUSY_BOX=true
export RUN_UNIT_TESTS=true
export RUN_FUNCTIONAL_TESTS=false
Expand Down
2 changes: 1 addition & 1 deletion ci/test/00_setup_env_native_old.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
export LC_ALL=C.UTF-8

export CONTAINER_NAME=ci_native_old
export DOCKER_NAME_TAG=ubuntu:18.04
export DOCKER_NAME_TAG=ubuntu:20.04
export PACKAGES="gcc-8 g++-8 libqt5gui5 libqt5core5a qtbase5-dev libqt5dbus5 qttools5-dev qttools5-dev-tools libssl-dev libevent-dev bsdmainutils libboost-system-dev libboost-filesystem-dev libboost-iostreams-dev libboost-test-dev libboost-thread-dev libminiupnpc-dev libqrencode-dev libzip-dev zlib1g zlib1g-dev libcurl4-openssl-dev"
export RUN_UNIT_TESTS=true
# export RUN_FUNCTIONAL_TESTS=false
Expand Down
20 changes: 10 additions & 10 deletions src/rpc/protocol.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,18 +143,18 @@ class SSLIOStreamDevice : public boost::iostreams::device<boost::iostreams::bidi
bool connect(const std::string& server, const std::string& port)
{
boost::asio::ip::tcp::resolver resolver(GetIOService(stream));
boost::asio::ip::tcp::resolver::query query(server.c_str(), port.c_str());
boost::asio::ip::tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
boost::asio::ip::tcp::resolver::iterator end;
boost::system::error_code error = boost::asio::error::host_not_found;
while (error && endpoint_iterator != end)
{
boost::system::error_code error;

for (const auto& res : resolver.resolve(server, port)) {
stream.lowest_layer().close();
stream.lowest_layer().connect(*endpoint_iterator++, error);
stream.lowest_layer().connect(res, error);

if (!error) {
return true;
}
}
if (error)
return false;
return true;

return false;
}

private:
Expand Down
16 changes: 10 additions & 6 deletions src/rpc/server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -500,15 +500,19 @@ bool ClientAllowed(const boost::asio::ip::address& address)
{
// Make sure that IPv4-compatible and IPv4-mapped IPv6 addresses are treated as IPv4 addresses
if (address.is_v6()
&& (address.to_v6().is_v4_compatible()
|| address.to_v6().is_v4_mapped()))
return ClientAllowed(address.to_v6().to_v4());
&& (address.to_v6() <= boost::asio::ip::make_address_v6("::ffff:ffff")
|| address.to_v6().is_v4_mapped())) {
auto address6 = address.to_v6();
auto bytes = address6.to_bytes();

return ClientAllowed(boost::asio::ip::address_v4({bytes[12], bytes[13], bytes[14], bytes[15]}));
}

if (address == asio::ip::address_v4::loopback()
|| address == asio::ip::address_v6::loopback()
|| (address.is_v4()
// Check whether IPv4 addresses match 127.0.0.0/8 (loopback subnet)
&& (address.to_v4().to_ulong() & 0xff000000) == 0x7f000000))
&& (address.to_v4().to_bytes()[0] == 127)))
return true;

const string strAddress = address.to_string();
Expand Down Expand Up @@ -661,7 +665,7 @@ void StartRPCThreads()
acceptor->set_option(boost::asio::ip::v6_only(loopback), v6_only_error);

acceptor->bind(endpoint);
acceptor->listen(socket_base::max_connections);
acceptor->listen(socket_base::max_listen_connections);

RPCListen(acceptor, *rpc_ssl_context, fUseSSL);

Expand All @@ -684,7 +688,7 @@ void StartRPCThreads()
acceptor->open(endpoint.protocol());
acceptor->set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));
acceptor->bind(endpoint);
acceptor->listen(socket_base::max_connections);
acceptor->listen(socket_base::max_listen_connections);

RPCListen(acceptor, *rpc_ssl_context, fUseSSL);

Expand Down
91 changes: 14 additions & 77 deletions src/wallet/diagnose.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ bool Diagnose::m_hasPoolProjects = false;
bool Diagnose::m_configured_for_investor_mode = false;
std::unordered_map<Diagnose::TestNames, Diagnose*> Diagnose::m_name_to_test_map;
CCriticalSection Diagnose::cs_diagnostictests;
boost::asio::io_service Diagnose::s_ioService;
boost::asio::io_context Diagnose::s_ioService;

/**
* The function check the time is correct on your PC. It checks the skew in the clock.
Expand Down Expand Up @@ -102,102 +102,39 @@ void VerifyClock::timerHandle(
void VerifyClock::connectToNTPHost()
{
m_startedTesting = true;
boost::asio::ip::udp::resolver resolver(s_ioService);

try {
FastRandomContext rng;

std::string ntp_host = m_ntp_hosts[rng.randrange(m_ntp_hosts.size())];

#if BOOST_VERSION > 106501
// results_type is only in boost 1.66 and above.
boost::asio::ip::udp::resolver::results_type receiver_endpoint;
boost::asio::ip::udp::resolver resolver(s_ioService);
auto resolved = resolver.resolve(boost::asio::ip::udp::v4(), ntp_host, "ntp");

receiver_endpoint = resolver.resolve(boost::asio::ip::udp::v4(), ntp_host, "ntp");
if (m_udpSocket.is_open())
m_udpSocket.close();
m_udpSocket.open(boost::asio::ip::udp::v4());
boost::asio::connect(m_udpSocket, resolved);

if (receiver_endpoint == boost::asio::ip::udp::resolver::iterator()) {
// If can not connect to server, then finish the test with a warning.
clkReportResults(0, true);
} else {
if (m_udpSocket.is_open())
m_udpSocket.close();
m_udpSocket.open(boost::asio::ip::udp::v4());

// Let's put the send here to reduce the complexity of this. No need for the send to be async.
size_t bytes_transferred = 0;

try {
bytes_transferred = m_udpSocket.send_to(boost::asio::buffer(m_sendBuf), *receiver_endpoint);
} catch (boost::system::error_code& e) {
clkReportResults(0, true);
}

if (bytes_transferred != 48) {
clkReportResults(0, true);
} else {
m_udpSocket.async_receive_from(
boost::asio::buffer(m_recvBuf),
m_sender_endpoint,
boost::bind(&VerifyClock::sockRecvHandle, this,
boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
}
}
size_t bytes_transferred = m_udpSocket.send(boost::asio::buffer(m_sendBuf));

#else
boost::asio::ip::udp::resolver::query query(
boost::asio::ip::udp::v4(),
ntp_host,
"ntp");

boost::asio::ip::udp::resolver::iterator endpoint_iterator = resolver.resolve(query);

if (endpoint_iterator == boost::asio::ip::udp::resolver::iterator()) {
// If can not connect to server, then finish the test with a warning.
if (bytes_transferred != 48) {
clkReportResults(0, true);
} else {
if (m_udpSocket.is_open())
m_udpSocket.close();
m_udpSocket.open(boost::asio::ip::udp::v4());

// Let's put the send here to reduce the complexity of this. No need for the send to be async.
size_t bytes_transferred = 0;

try {
bytes_transferred = m_udpSocket.send_to(boost::asio::buffer(m_sendBuf), *endpoint_iterator);
} catch (boost::system::error_code& e) {
clkReportResults(0, true);
}

if (bytes_transferred != 48) {
clkReportResults(0, true);
} else {
boost::asio::ip::udp::endpoint sender_endpoint;

m_udpSocket.async_receive_from(
boost::asio::buffer(m_recvBuf),
sender_endpoint,
boost::bind(&VerifyClock::sockRecvHandle, this,
boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
}
m_udpSocket.async_receive(
boost::asio::buffer(m_recvBuf),
boost::bind(&VerifyClock::sockRecvHandle, this,
boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
}
#endif
} catch (...) {
clkReportResults(0, true);
}
}

void VerifyTCPPort::handle_connect(const boost::system::error_code& err,
boost::asio::ip::tcp::resolver::iterator endpoint_iterator)
void VerifyTCPPort::handle_connect(const boost::system::error_code& err)
{
if (!err) {
this->TCPFinished();
} else if (endpoint_iterator != boost::asio::ip::tcp::resolver::iterator()) {
// The connection failed. Try the next endpoint in the list.
m_tcpSocket.close();
boost::asio::ip::tcp::endpoint endpoint = *endpoint_iterator;
m_tcpSocket.async_connect(endpoint,
boost::bind(&VerifyTCPPort::handle_connect, this,
boost::asio::placeholders::error, ++endpoint_iterator));
} else {
m_tcpSocket.close();
m_results = WARNING;
Expand Down
40 changes: 8 additions & 32 deletions src/wallet/diagnose.h
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ class Diagnose
static CCriticalSection cs_diagnostictests; //!< used to protect the critical sections, for multithreading
TestNames m_test_name; //!< This must be defined for derived classes. Each derived class must declare the name of the test and add to the TestNames enum
static std::unordered_map<Diagnose::TestNames, Diagnose*> m_name_to_test_map; //!< a map to save the test and a pointer to it. Some tests are related and need to access the results of each other.
static boost::asio::io_service s_ioService;
static boost::asio::io_context s_ioService;
};

/**
Expand Down Expand Up @@ -349,7 +349,6 @@ class VerifyClock : public Diagnose
boost::array<unsigned char, 48> m_sendBuf = {0x1b, 0, 0, 0, 0, 0, 0, 0, 0};
boost::array<unsigned char, 1024> m_recvBuf;
bool m_startedTesting = false;
boost::asio::ip::udp::endpoint m_sender_endpoint; // This has to be here to guarantee it is available for the callback

void clkReportResults(const int64_t& time_offset, const bool& timeout_during_check = false);
void sockRecvHandle(const boost::system::error_code& error, std::size_t bytes_transferred);
Expand Down Expand Up @@ -381,7 +380,7 @@ class VerifyClock : public Diagnose

connectToNTPHost();

s_ioService.reset();
s_ioService.restart();
s_ioService.run();
}
}
Expand Down Expand Up @@ -637,8 +636,7 @@ class VerifyTCPPort : public Diagnose
{
private:
boost::asio::ip::tcp::socket m_tcpSocket;
void handle_connect(const boost::system::error_code& err,
boost::asio::ip::tcp::resolver::iterator endpoint_iterator);
void handle_connect(const boost::system::error_code& err);

void TCPFinished();

Expand All @@ -649,7 +647,7 @@ class VerifyTCPPort : public Diagnose
~VerifyTCPPort() {}
void runCheck()
{
s_ioService.reset();
s_ioService.restart();

m_results_string_arg.clear();
m_results_tip_arg.clear();
Expand All @@ -662,34 +660,12 @@ class VerifyTCPPort : public Diagnose
}

boost::asio::ip::tcp::resolver resolver(s_ioService);
#if BOOST_VERSION > 106501
auto endpoint_iterator = resolver.resolve("portquiz.net", "http");
#else
boost::asio::ip::tcp::resolver::query query(
"portquiz.net",
"http");
auto endpoint_iterator = resolver.resolve(query);
#endif

if (endpoint_iterator == boost::asio::ip::tcp::resolver::iterator()) {
m_tcpSocket.close();
m_results = WARNING;
m_results_tip = _("Outbound communication to TCP port %1 appears to be blocked.");
std::string ss = ToString(GetListenPort());
m_results_string_arg.push_back(ss);
} else {
// Attempt a connection to the first endpoint in the list. Each endpoint
// will be tried until we successfully establish a connection.
boost::asio::ip::tcp::endpoint endpoint = *endpoint_iterator;
if (m_tcpSocket.is_open())
m_tcpSocket.close();
auto resolved = resolver.resolve("portquiz.net", "http");

m_tcpSocket.async_connect(endpoint,
boost::bind(&VerifyTCPPort::handle_connect, this,
boost::asio::placeholders::error, (++endpoint_iterator)));
// FIXME(div72): This whole portion was/is a BLOCKING asynchronous segment, what the hell.
boost::asio::async_connect(m_tcpSocket, resolved, boost::bind(&VerifyTCPPort::handle_connect, this, boost::asio::placeholders::error));

s_ioService.run();
}
s_ioService.run();
}
};

Expand Down
Loading