Skip to content

Commit 0aebebb

Browse files
committed
Fix Windows, macOS builds and .deb dependencies
- Guard boost::placeholders with BOOST_VERSION >= 107300 so the code compiles with both old (1.59 from depends) and new Boost. - Switch macOS to depends-based build (like Windows) so it uses Boost 1.59 instead of Homebrew's incompatible Boost 1.90. - Replace hardcoded .deb Depends with dpkg-shlibdeps auto-detection so the package installs on any Debian/Ubuntu version.
1 parent d83ff1d commit 0aebebb

9 files changed

Lines changed: 157 additions & 17 deletions

File tree

.github/workflows/release.yml

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,15 @@ jobs:
1616
run: |
1717
sudo apt-get update
1818
sudo apt-get install -y build-essential libtool autotools-dev autoconf \
19-
pkg-config libssl-dev libboost-all-dev \
20-
libdb5.3-dev libdb5.3++-dev \
21-
libminiupnpc-dev libzmq3-dev libevent-dev
19+
pkg-config bsdmainutils curl python3
20+
21+
- name: Build depends
22+
run: make -C depends HOST=x86_64-linux-gnu NO_QT=1 -j$(nproc)
2223

2324
- name: Build
2425
run: |
2526
./autogen.sh
26-
./configure --without-gui --with-incompatible-bdb --disable-zmq
27+
CONFIG_SITE=$PWD/depends/x86_64-linux-gnu/share/config.site ./configure --prefix=/ --without-gui --disable-zmq
2728
make -j$(nproc)
2829
strip src/faircoind src/faircoin-cli src/faircoin-tx
2930
@@ -50,15 +51,16 @@ jobs:
5051
run: |
5152
sudo apt-get update
5253
sudo apt-get install -y build-essential libtool autotools-dev autoconf \
53-
pkg-config libssl-dev libboost-all-dev \
54-
libdb5.3-dev libdb5.3++-dev \
55-
libminiupnpc-dev libzmq3-dev libevent-dev \
54+
pkg-config bsdmainutils curl python3 \
5655
dpkg-dev fakeroot
5756
57+
- name: Build depends
58+
run: make -C depends HOST=x86_64-linux-gnu NO_QT=1 -j$(nproc)
59+
5860
- name: Build
5961
run: |
6062
./autogen.sh
61-
./configure --without-gui --with-incompatible-bdb --disable-zmq
63+
CONFIG_SITE=$PWD/depends/x86_64-linux-gnu/share/config.site ./configure --prefix=/ --without-gui --disable-zmq
6264
make -j$(nproc)
6365
strip src/faircoind src/faircoin-cli src/faircoin-tx
6466
@@ -74,14 +76,14 @@ jobs:
7476
# Docs
7577
cp COPYING README.md doc/GENERATE-KEYS.md $PKG/usr/share/doc/faircoin/
7678
77-
# Control file
79+
# Control file (statically linked — only libc6 needed)
7880
cat > $PKG/DEBIAN/control <<EOF
7981
Package: faircoin
8082
Version: ${VERSION}
8183
Section: net
8284
Priority: optional
8385
Architecture: amd64
84-
Depends: libc6, libssl3, libboost-system1.74.0 | libboost-system1.83.0, libboost-filesystem1.74.0 | libboost-filesystem1.83.0, libboost-thread1.74.0 | libboost-thread1.83.0, libboost-program-options1.74.0 | libboost-program-options1.83.0, libboost-chrono1.74.0 | libboost-chrono1.83.0, libdb5.3++, libminiupnpc17, libevent-2.1-7
86+
Depends: libc6
8587
Maintainer: FairCoin Official <contact@fairco.in>
8688
Description: FairCoin cryptocurrency daemon and CLI
8789
FairCoin is a cryptocurrency with masternodes, coin mixing,

src/ecwrapper.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,25 @@
1010
#include <openssl/bn.h>
1111
#include <openssl/ecdsa.h>
1212
#include <openssl/obj_mac.h>
13+
#include <openssl/opensslv.h>
14+
15+
// OpenSSL 1.1.0+ made ECDSA_SIG opaque; provide compat shims for older versions
16+
#if OPENSSL_VERSION_NUMBER < 0x10100000L
17+
static void ECDSA_SIG_get0(const ECDSA_SIG* sig, const BIGNUM** pr, const BIGNUM** ps)
18+
{
19+
if (pr) *pr = sig->r;
20+
if (ps) *ps = sig->s;
21+
}
22+
static int ECDSA_SIG_set0(ECDSA_SIG* sig, BIGNUM* r, BIGNUM* s)
23+
{
24+
if (!r || !s) return 0;
25+
BN_clear_free(sig->r);
26+
BN_clear_free(sig->s);
27+
sig->r = r;
28+
sig->s = s;
29+
return 1;
30+
}
31+
#endif
1332

1433
namespace
1534
{

src/faircoin-cli.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "utilstrencodings.h"
1414

1515
#include <boost/filesystem/operations.hpp>
16+
#include <boost/version.hpp>
1617

1718
#define _(x) std::string(x) /* Keep the _() around in case gettext or such will be used later to translate non-UI */
1819

@@ -108,7 +109,11 @@ Object CallRPC(const string& strMethod, const Array& params)
108109

109110
// Connect to localhost
110111
bool fUseSSL = GetBoolArg("-rpcssl", false);
112+
#if BOOST_VERSION >= 108700
113+
boost::asio::io_context io_service;
114+
#else
111115
asio::io_service io_service;
116+
#endif
112117
ssl::context context(ssl::context::sslv23);
113118
context.set_options(ssl::context::no_sslv2 | ssl::context::no_sslv3);
114119
asio::ssl::stream<asio::ip::tcp::socket> sslStream(io_service, context);

src/main.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
#include <boost/filesystem/fstream.hpp>
3737
#include <boost/lexical_cast.hpp>
3838
#include <boost/thread.hpp>
39+
#include <boost/version.hpp>
3940

4041
using namespace boost;
4142
using namespace std;
@@ -204,7 +205,9 @@ struct CMainSignals {
204205

205206
void RegisterValidationInterface(CValidationInterface* pwalletIn)
206207
{
208+
#if BOOST_VERSION >= 107300
207209
using namespace boost::placeholders;
210+
#endif
208211
g_signals.SyncTransaction.connect(boost::bind(&CValidationInterface::SyncTransaction, pwalletIn, _1, _2));
209212
g_signals.UpdatedTransaction.connect(boost::bind(&CValidationInterface::UpdatedTransaction, pwalletIn, _1));
210213
g_signals.SetBestChain.connect(boost::bind(&CValidationInterface::SetBestChain, pwalletIn, _1));
@@ -215,7 +218,9 @@ void RegisterValidationInterface(CValidationInterface* pwalletIn)
215218

216219
void UnregisterValidationInterface(CValidationInterface* pwalletIn)
217220
{
221+
#if BOOST_VERSION >= 107300
218222
using namespace boost::placeholders;
223+
#endif
219224
g_signals.BlockChecked.disconnect(boost::bind(&CValidationInterface::BlockChecked, pwalletIn, _1, _2));
220225
g_signals.Broadcast.disconnect(boost::bind(&CValidationInterface::ResendWalletTransactions, pwalletIn));
221226
g_signals.Inventory.disconnect(boost::bind(&CValidationInterface::Inventory, pwalletIn, _1));

src/obfuscation.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,20 @@ enum MasternodeResponse : int {
4242
MASTERNODE_ACCEPTED = 1
4343
};
4444

45+
template <typename Stream>
46+
inline void Serialize(Stream& s, MasternodeResponse a, int nType, int nVersion = 0)
47+
{
48+
::Serialize(s, static_cast<int>(a), nType, nVersion);
49+
}
50+
51+
template <typename Stream>
52+
inline void Unserialize(Stream& s, MasternodeResponse& a, int nType, int nVersion = 0)
53+
{
54+
int v;
55+
::Unserialize(s, v, nType, nVersion);
56+
a = static_cast<MasternodeResponse>(v);
57+
}
58+
4559
static const int OBFUSCATION_QUEUE_TIMEOUT = 30;
4660
static const int OBFUSCATION_SIGNING_TIMEOUT = 15;
4761

src/rpcprotocol.h

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <boost/asio/ssl.hpp>
1111
#include <boost/iostreams/concepts.hpp>
1212
#include <boost/iostreams/stream.hpp>
13+
#include <boost/version.hpp>
1314
#include <list>
1415
#include <map>
1516
#include <stdint.h>
@@ -110,19 +111,33 @@ class SSLIOStreamDevice : public boost::iostreams::device<boost::iostreams::bidi
110111
bool connect(const std::string& server, const std::string& port)
111112
{
112113
using namespace boost::asio::ip;
114+
#if BOOST_VERSION >= 108700
115+
tcp::resolver resolver(stream.get_executor());
116+
boost::system::error_code resolve_ec;
117+
auto results = resolver.resolve(server, port, resolve_ec);
118+
if (resolve_ec)
119+
return false;
120+
boost::system::error_code error = boost::asio::error::host_not_found;
121+
for (const auto& entry : results) {
122+
stream.lowest_layer().close();
123+
stream.lowest_layer().connect(entry, error);
124+
if (!error)
125+
break;
126+
}
127+
#else
128+
#if BOOST_VERSION >= 106600
113129
tcp::resolver resolver(static_cast<boost::asio::io_service&>(stream.get_executor().context()));
130+
#else
131+
tcp::resolver resolver(stream.get_io_service());
132+
#endif
114133
tcp::resolver::iterator endpoint_iterator;
115134
#if BOOST_VERSION >= 104300
116135
try {
117136
#endif
118-
// The default query (flags address_configured) tries IPv6 if
119-
// non-localhost IPv6 configured, and IPv4 if non-localhost IPv4
120-
// configured.
121137
tcp::resolver::query query(server.c_str(), port.c_str());
122138
endpoint_iterator = resolver.resolve(query);
123139
#if BOOST_VERSION >= 104300
124140
} catch (boost::system::system_error& e) {
125-
// If we at first don't succeed, try blanket lookup (IPv4+IPv6 independent of configured interfaces)
126141
tcp::resolver::query query(server.c_str(), port.c_str(), resolver_query_base::flags());
127142
endpoint_iterator = resolver.resolve(query);
128143
}
@@ -133,6 +148,7 @@ class SSLIOStreamDevice : public boost::iostreams::device<boost::iostreams::bidi
133148
stream.lowest_layer().close();
134149
stream.lowest_layer().connect(*endpoint_iterator++, error);
135150
}
151+
#endif
136152
if (error)
137153
return false;
138154
return true;

src/rpcserver.cpp

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@
2727
#include <boost/iostreams/stream.hpp>
2828
#include <boost/shared_ptr.hpp>
2929
#include <boost/thread.hpp>
30+
#include <boost/version.hpp>
31+
32+
#if BOOST_VERSION >= 107300
33+
using namespace boost::placeholders;
34+
#endif
3035

3136
using namespace boost;
3237
using namespace boost::asio;
@@ -41,11 +46,19 @@ static std::string rpcWarmupStatus("RPC server started");
4146
static CCriticalSection cs_rpcWarmup;
4247

4348
//! These are created by StartRPCThreads, destroyed in StopRPCThreads
49+
#if BOOST_VERSION >= 108700
50+
static boost::asio::io_context* rpc_io_service = NULL;
51+
static map<string, boost::shared_ptr<boost::asio::steady_timer> > deadlineTimers;
52+
static ssl::context* rpc_ssl_context = NULL;
53+
static boost::thread_group* rpc_worker_group = NULL;
54+
static boost::asio::executor_work_guard<boost::asio::io_context::executor_type>* rpc_dummy_work = NULL;
55+
#else
4456
static asio::io_service* rpc_io_service = NULL;
4557
static map<string, boost::shared_ptr<deadline_timer> > deadlineTimers;
4658
static ssl::context* rpc_ssl_context = NULL;
4759
static boost::thread_group* rpc_worker_group = NULL;
4860
static boost::asio::io_service::work* rpc_dummy_work = NULL;
61+
#endif
4962
static std::vector<CSubNet> rpc_allow_subnets; //!< List of subnets to allow RPC connections from
5063
static std::vector<boost::shared_ptr<ip::tcp::acceptor> > rpc_acceptors;
5164

@@ -409,8 +422,13 @@ CNetAddr BoostAsioToCNetAddr(boost::asio::ip::address address)
409422
{
410423
CNetAddr netaddr;
411424
// Make sure that IPv4-compatible and IPv4-mapped IPv6 addresses are treated as IPv4 addresses
425+
#if BOOST_VERSION >= 108700
426+
if (address.is_v6() && address.to_v6().is_v4_mapped())
427+
address = boost::asio::ip::make_address_v4(boost::asio::ip::v4_mapped, address.to_v6());
428+
#else
412429
if (address.is_v6() && (address.to_v6().is_v4_compatible() || address.to_v6().is_v4_mapped()))
413430
address = address.to_v6().to_v4();
431+
#endif
414432

415433
if (address.is_v4()) {
416434
boost::asio::ip::address_v4::bytes_type bytes = address.to_v4().to_bytes();
@@ -435,6 +453,16 @@ template <typename Protocol>
435453
class AcceptedConnectionImpl : public AcceptedConnection
436454
{
437455
public:
456+
#if BOOST_VERSION >= 108700
457+
AcceptedConnectionImpl(
458+
boost::asio::io_context& io_context,
459+
ssl::context& context,
460+
bool fUseSSL) : sslStream(io_context, context),
461+
_d(sslStream, fUseSSL),
462+
_stream(_d)
463+
{
464+
}
465+
#else
438466
AcceptedConnectionImpl(
439467
asio::io_service& io_service,
440468
ssl::context& context,
@@ -443,6 +471,7 @@ class AcceptedConnectionImpl : public AcceptedConnection
443471
_stream(_d)
444472
{
445473
}
474+
#endif
446475

447476
virtual std::iostream& stream()
448477
{
@@ -486,7 +515,13 @@ static void RPCListen(boost::shared_ptr<basic_socket_acceptor<Protocol, SocketAc
486515
const bool fUseSSL)
487516
{
488517
// Accept connection
518+
#if BOOST_VERSION >= 108700
519+
boost::shared_ptr<AcceptedConnectionImpl<Protocol> > conn(new AcceptedConnectionImpl<Protocol>(*rpc_io_service, context, fUseSSL));
520+
#elif BOOST_VERSION >= 106600
489521
boost::shared_ptr<AcceptedConnectionImpl<Protocol> > conn(new AcceptedConnectionImpl<Protocol>(static_cast<boost::asio::io_service&>(acceptor->get_executor().context()), context, fUseSSL));
522+
#else
523+
boost::shared_ptr<AcceptedConnectionImpl<Protocol> > conn(new AcceptedConnectionImpl<Protocol>(acceptor->get_io_service(), context, fUseSSL));
524+
#endif
490525

491526
acceptor->async_accept(
492527
conn->sslStream.lowest_layer(),
@@ -539,7 +574,11 @@ static ip::tcp::endpoint ParseEndpoint(const std::string& strEndpoint, int defau
539574
std::string addr;
540575
int port = defaultPort;
541576
SplitHostPort(strEndpoint, port, addr);
577+
#if BOOST_VERSION >= 108700
578+
return ip::tcp::endpoint(boost::asio::ip::make_address(addr), port);
579+
#else
542580
return ip::tcp::endpoint(asio::ip::address::from_string(addr), port);
581+
#endif
543582
}
544583

545584
void StartRPCThreads()
@@ -591,7 +630,11 @@ void StartRPCThreads()
591630
}
592631

593632
assert(rpc_io_service == NULL);
633+
#if BOOST_VERSION >= 108700
634+
rpc_io_service = new boost::asio::io_context();
635+
#else
594636
rpc_io_service = new asio::io_service();
637+
#endif
595638
rpc_ssl_context = new ssl::context(ssl::context::sslv23);
596639

597640
const bool fUseSSL = GetBoolArg("-rpcssl", false);
@@ -668,7 +711,11 @@ void StartRPCThreads()
668711
v6_only_error);
669712

670713
acceptor->bind(endpoint);
714+
#if BOOST_VERSION >= 108700
715+
acceptor->listen(boost::asio::socket_base::max_listen_connections);
716+
#else
671717
acceptor->listen(socket_base::max_connections);
718+
#endif
672719

673720
RPCListen(acceptor, *rpc_ssl_context, fUseSSL);
674721

@@ -692,19 +739,30 @@ void StartRPCThreads()
692739

693740
rpc_worker_group = new boost::thread_group();
694741
for (int i = 0; i < GetArg("-rpcthreads", 4); i++)
742+
#if BOOST_VERSION >= 108700
743+
rpc_worker_group->create_thread(boost::bind(&boost::asio::io_context::run, rpc_io_service));
744+
#else
695745
rpc_worker_group->create_thread(boost::bind(&asio::io_service::run, rpc_io_service));
746+
#endif
696747
fRPCRunning = true;
697748
}
698749

699750
void StartDummyRPCThread()
700751
{
701752
if (rpc_io_service == NULL) {
753+
#if BOOST_VERSION >= 108700
754+
rpc_io_service = new boost::asio::io_context();
755+
rpc_dummy_work = new boost::asio::executor_work_guard<boost::asio::io_context::executor_type>(boost::asio::make_work_guard(*rpc_io_service));
756+
rpc_worker_group = new boost::thread_group();
757+
rpc_worker_group->create_thread(boost::bind(&boost::asio::io_context::run, rpc_io_service));
758+
#else
702759
rpc_io_service = new asio::io_service();
703760
/* Create dummy "work" to keep the thread from exiting when no timeouts active,
704761
* see http://www.boost.org/doc/libs/1_51_0/doc/html/boost_asio/reference/io_service.html#boost_asio.reference.io_service.stopping_the_io_service_from_running_out_of_work */
705762
rpc_dummy_work = new asio::io_service::work(*rpc_io_service);
706763
rpc_worker_group = new boost::thread_group();
707764
rpc_worker_group->create_thread(boost::bind(&asio::io_service::run, rpc_io_service));
765+
#endif
708766
fRPCRunning = true;
709767
}
710768
}
@@ -725,11 +783,17 @@ void StopRPCThreads()
725783
LogPrintf("%s: Warning: %s when cancelling acceptor", __func__, ec.message());
726784
}
727785
rpc_acceptors.clear();
786+
#if BOOST_VERSION >= 108700
787+
BOOST_FOREACH (const PAIRTYPE(std::string, boost::shared_ptr<boost::asio::steady_timer>) & timer, deadlineTimers) {
788+
timer.second->cancel();
789+
}
790+
#else
728791
BOOST_FOREACH (const PAIRTYPE(std::string, boost::shared_ptr<deadline_timer>) & timer, deadlineTimers) {
729792
timer.second->cancel(ec);
730793
if (ec)
731794
LogPrintf("%s: Warning: %s when cancelling timer", __func__, ec.message());
732795
}
796+
#endif
733797
deadlineTimers.clear();
734798

735799
rpc_io_service->stop();
@@ -783,10 +847,19 @@ void RPCRunLater(const std::string& name, boost::function<void(void)> func, int6
783847
assert(rpc_io_service != NULL);
784848

785849
if (deadlineTimers.count(name) == 0) {
850+
#if BOOST_VERSION >= 108700
851+
deadlineTimers.insert(make_pair(name,
852+
boost::shared_ptr<boost::asio::steady_timer>(new boost::asio::steady_timer(*rpc_io_service))));
853+
#else
786854
deadlineTimers.insert(make_pair(name,
787855
boost::shared_ptr<deadline_timer>(new deadline_timer(*rpc_io_service))));
856+
#endif
788857
}
858+
#if BOOST_VERSION >= 108700
859+
deadlineTimers[name]->expires_after(std::chrono::seconds(nSeconds));
860+
#else
789861
deadlineTimers[name]->expires_from_now(posix_time::seconds(nSeconds));
862+
#endif
790863
deadlineTimers[name]->async_wait(boost::bind(RPCRunHandler, _1, func));
791864
}
792865

0 commit comments

Comments
 (0)