Skip to content

Commit

Permalink
Merge pull request #2786 from div72/boost-1.87
Browse files Browse the repository at this point in the history
diagnose, rpc: fix compilation with boost 1.87
  • Loading branch information
jamescowens authored Jan 12, 2025
2 parents 9a62b1d + bd44d1e commit c9f3674
Show file tree
Hide file tree
Showing 11 changed files with 57 additions and 137 deletions.
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

0 comments on commit c9f3674

Please sign in to comment.