Skip to content

Commit

Permalink
Merge pull request bitcoin#3111 from codablock/pr_backports_v15_v16_3
Browse files Browse the repository at this point in the history
Backport same PRs as done in bitcoin#11447
  • Loading branch information
UdjinM6 committed Sep 27, 2019
2 parents ed82988 + 4770830 commit 3712f8d
Show file tree
Hide file tree
Showing 26 changed files with 254 additions and 134 deletions.
1 change: 1 addition & 0 deletions COPYING
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
The MIT License (MIT)

Copyright (c) 2009-2019 The Bitcoin Core developers
Copyright (c) 2009-2019 Bitcoin Developers
Copyright (c) 2014-2019 The Dash Core developers

Permission is hereby granted, free of charge, to any person obtaining a copy
Expand Down
27 changes: 21 additions & 6 deletions doc/build-cross.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,17 +46,32 @@ $ sudo apt-get install nsis wine-stable wine64 bc
For Windows 64bit, install :
```bash
$ sudo apt-get install g++-mingw-w64-x86-64
$ # Required to enable C++ threading libraries (e.g. std::thread)
$ sudo update-alternatives --set x86_64-w64-mingw32-g++ /usr/bin/x86_64-w64-mingw32-g++-posix
$ sudo update-alternatives --set x86_64-w64-mingw32-gcc /usr/bin/x86_64-w64-mingw32-gcc-posix
```

If you're building on Ubuntu 17.04 or later, run these two commands, selecting the 'posix' variant for both,
to work around issues with mingw-w64. See issue [8732](https://github.com/bitcoin/bitcoin/issues/8732) for more information.
This also fixes linker issues related to std::thread and other threading related standard C++ libraries.
```
sudo update-alternatives --config x86_64-w64-mingw32-g++
sudo update-alternatives --config x86_64-w64-mingw32-gcc
```

For Windows 32bit, install:
```bash
$ sudo apt-get install g++-mingw-w64-i686
$ # Required to enable C++ threading libraries (e.g. std::thread)
$ sudo update-alternatives --set i686-w64-mingw32-gcc /usr/bin/i686-w64-mingw32-gcc-posix
$ sudo update-alternatives --set i686-w64-mingw32-g++ /usr/bin/i686-w64-mingw32-g++-posix
```

If you're building on Ubuntu 17.04 or later, run these two commands, selecting the 'posix' variant for both,
to fix linker issues related to std::thread and other threading related standard C++ libraries.
```
sudo update-alternatives --config x86_64-w64-mingw32-g++
sudo update-alternatives --config x86_64-w64-mingw32-gcc
```

Before building for Windows 32bit or 64bit, run

```
$ PATH=$(echo "$PATH" | sed -e 's/:\/mnt.*//g') # strip out problematic Windows %PATH% imported var
```

When building the dependencies, as described in [build-generic](build-generic.md), use
Expand Down
7 changes: 4 additions & 3 deletions doc/build-windows.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ WINDOWS BUILD NOTES
Below are some notes on how to build Dash Core for Windows.

Most developers use cross-compilation from Ubuntu to build executables for
Windows. This is also used to build the release binaries.
Windows. Cross-compilation is also used to build the release binaries.

Currently only building on Ubuntu Trusty 14.04 is supported.
Other versions are unsupported or known to be broken (e.g. Ubuntu Xenial 16.04).
Currently only building on Ubuntu Trusty 14.04 or Ubuntu Zesty 17.04 or later is supported.
Building on Ubuntu Xenial 16.04 is known to be broken, see extensive discussion in issue [8732](https://github.com/bitcoin/bitcoin/issues/8732).
While it may be possible to do so with work arounds, it's potentially dangerous and not recommended.

While there are potentially a number of ways to build on Windows (for example using msys / mingw-w64),
using the Windows Subsystem For Linux is the most straightforward. If you are building with
Expand Down
1 change: 1 addition & 0 deletions doc/files.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,4 @@
* wallet.dat: personal wallet (BDB) with keys and transactions
* .cookie: session RPC authentication cookie (written at start when cookie authentication is used, deleted on shutdown)
* onion_private_key: cached Tor hidden service private key for `-listenonion`
* guisettings.ini.bak: backup of former GUI settings after `-resetguisettings` is used
125 changes: 89 additions & 36 deletions src/netbase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,48 @@ struct timeval MillisToTimeval(int64_t nTimeout)
return timeout;
}

/** SOCKS version */
enum SOCKSVersion: uint8_t {
SOCKS4 = 0x04,
SOCKS5 = 0x05
};

/** Values defined for METHOD in RFC1928 */
enum SOCKS5Method: uint8_t {
NOAUTH = 0x00, //! No authentication required
GSSAPI = 0x01, //! GSSAPI
USER_PASS = 0x02, //! Username/password
NO_ACCEPTABLE = 0xff, //! No acceptable methods
};

/** Values defined for CMD in RFC1928 */
enum SOCKS5Command: uint8_t {
CONNECT = 0x01,
BIND = 0x02,
UDP_ASSOCIATE = 0x03
};

/** Values defined for REP in RFC1928 */
enum SOCKS5Reply: uint8_t {
SUCCEEDED = 0x00, //! Succeeded
GENFAILURE = 0x01, //! General failure
NOTALLOWED = 0x02, //! Connection not allowed by ruleset
NETUNREACHABLE = 0x03, //! Network unreachable
HOSTUNREACHABLE = 0x04, //! Network unreachable
CONNREFUSED = 0x05, //! Connection refused
TTLEXPIRED = 0x06, //! TTL expired
CMDUNSUPPORTED = 0x07, //! Command not supported
ATYPEUNSUPPORTED = 0x08, //! Address type not supported
};

/** Values defined for ATYPE in RFC1928 */
enum SOCKS5Atyp: uint8_t {
IPV4 = 0x01,
DOMAINNAME = 0x03,
IPV6 = 0x04,
};

/** Status codes that can be returned by InterruptibleRecv */
enum class IntrRecvError {
OK,
Timeout,
Expand All @@ -203,15 +245,15 @@ enum class IntrRecvError {
*
* @note This function requires that hSocket is in non-blocking mode.
*/
static IntrRecvError InterruptibleRecv(char* data, size_t len, int timeout, const SOCKET& hSocket)
static IntrRecvError InterruptibleRecv(uint8_t* data, size_t len, int timeout, const SOCKET& hSocket)
{
int64_t curTime = GetTimeMillis();
int64_t endTime = curTime + timeout;
// Maximum time to wait in one select call. It will take up until this time (in millis)
// to break off in case of an interruption.
const int64_t maxWait = 1000;
while (len > 0 && curTime < endTime) {
ssize_t ret = recv(hSocket, data, len, 0); // Optimistically try the recv first
ssize_t ret = recv(hSocket, (char*)data, len, 0); // Optimistically try the recv first
if (ret > 0) {
len -= ret;
data += ret;
Expand Down Expand Up @@ -242,24 +284,35 @@ static IntrRecvError InterruptibleRecv(char* data, size_t len, int timeout, cons
return len == 0 ? IntrRecvError::OK : IntrRecvError::Timeout;
}

/** Credentials for proxy authentication */
struct ProxyCredentials
{
std::string username;
std::string password;
};

std::string Socks5ErrorString(int err)
/** Convert SOCKS5 reply to a an error message */
std::string Socks5ErrorString(uint8_t err)
{
switch(err) {
case 0x01: return "general failure";
case 0x02: return "connection not allowed";
case 0x03: return "network unreachable";
case 0x04: return "host unreachable";
case 0x05: return "connection refused";
case 0x06: return "TTL expired";
case 0x07: return "protocol error";
case 0x08: return "address type not supported";
default: return "unknown";
case SOCKS5Reply::GENFAILURE:
return "general failure";
case SOCKS5Reply::NOTALLOWED:
return "connection not allowed";
case SOCKS5Reply::NETUNREACHABLE:
return "network unreachable";
case SOCKS5Reply::HOSTUNREACHABLE:
return "host unreachable";
case SOCKS5Reply::CONNREFUSED:
return "connection refused";
case SOCKS5Reply::TTLEXPIRED:
return "TTL expired";
case SOCKS5Reply::CMDUNSUPPORTED:
return "protocol error";
case SOCKS5Reply::ATYPEUNSUPPORTED:
return "address type not supported";
default:
return "unknown";
}
}

Expand All @@ -274,34 +327,34 @@ static bool Socks5(const std::string& strDest, int port, const ProxyCredentials
}
// Accepted authentication methods
std::vector<uint8_t> vSocks5Init;
vSocks5Init.push_back(0x05);
vSocks5Init.push_back(SOCKSVersion::SOCKS5);
if (auth) {
vSocks5Init.push_back(0x02); // # METHODS
vSocks5Init.push_back(0x00); // X'00' NO AUTHENTICATION REQUIRED
vSocks5Init.push_back(0x02); // X'02' USERNAME/PASSWORD (RFC1929)
vSocks5Init.push_back(0x02); // Number of methods
vSocks5Init.push_back(SOCKS5Method::NOAUTH);
vSocks5Init.push_back(SOCKS5Method::USER_PASS);
} else {
vSocks5Init.push_back(0x01); // # METHODS
vSocks5Init.push_back(0x00); // X'00' NO AUTHENTICATION REQUIRED
vSocks5Init.push_back(0x01); // Number of methods
vSocks5Init.push_back(SOCKS5Method::NOAUTH);
}
ssize_t ret = send(hSocket, (const char*)vSocks5Init.data(), vSocks5Init.size(), MSG_NOSIGNAL);
if (ret != (ssize_t)vSocks5Init.size()) {
CloseSocket(hSocket);
return error("Error sending to proxy");
}
char pchRet1[2];
uint8_t pchRet1[2];
if ((recvr = InterruptibleRecv(pchRet1, 2, SOCKS5_RECV_TIMEOUT, hSocket)) != IntrRecvError::OK) {
CloseSocket(hSocket);
LogPrintf("Socks5() connect to %s:%d failed: InterruptibleRecv() timeout or other failure\n", strDest, port);
return false;
}
if (pchRet1[0] != 0x05) {
if (pchRet1[0] != SOCKSVersion::SOCKS5) {
CloseSocket(hSocket);
return error("Proxy failed to initialize");
}
if (pchRet1[1] == 0x02 && auth) {
if (pchRet1[1] == SOCKS5Method::USER_PASS && auth) {
// Perform username/password authentication (as described in RFC1929)
std::vector<uint8_t> vAuth;
vAuth.push_back(0x01);
vAuth.push_back(0x01); // Current (and only) version of user/pass subnegotiation
if (auth->username.size() > 255 || auth->password.size() > 255)
return error("Proxy username or password too long");
vAuth.push_back(auth->username.size());
Expand All @@ -314,7 +367,7 @@ static bool Socks5(const std::string& strDest, int port, const ProxyCredentials
return error("Error sending authentication to proxy");
}
LogPrint(BCLog::PROXY, "SOCKS5 sending proxy authentication %s:%s\n", auth->username, auth->password);
char pchRetA[2];
uint8_t pchRetA[2];
if ((recvr = InterruptibleRecv(pchRetA, 2, SOCKS5_RECV_TIMEOUT, hSocket)) != IntrRecvError::OK) {
CloseSocket(hSocket);
return error("Error reading proxy authentication response");
Expand All @@ -323,17 +376,17 @@ static bool Socks5(const std::string& strDest, int port, const ProxyCredentials
CloseSocket(hSocket);
return error("Proxy authentication unsuccessful");
}
} else if (pchRet1[1] == 0x00) {
} else if (pchRet1[1] == SOCKS5Method::NOAUTH) {
// Perform no authentication
} else {
CloseSocket(hSocket);
return error("Proxy requested wrong authentication method %02x", pchRet1[1]);
}
std::vector<uint8_t> vSocks5;
vSocks5.push_back(0x05); // VER protocol version
vSocks5.push_back(0x01); // CMD CONNECT
vSocks5.push_back(0x00); // RSV Reserved
vSocks5.push_back(0x03); // ATYP DOMAINNAME
vSocks5.push_back(SOCKSVersion::SOCKS5); // VER protocol version
vSocks5.push_back(SOCKS5Command::CONNECT); // CMD CONNECT
vSocks5.push_back(0x00); // RSV Reserved must be 0
vSocks5.push_back(SOCKS5Atyp::DOMAINNAME); // ATYP DOMAINNAME
vSocks5.push_back(strDest.size()); // Length<=255 is checked at beginning of function
vSocks5.insert(vSocks5.end(), strDest.begin(), strDest.end());
vSocks5.push_back((port >> 8) & 0xFF);
Expand All @@ -343,7 +396,7 @@ static bool Socks5(const std::string& strDest, int port, const ProxyCredentials
CloseSocket(hSocket);
return error("Error sending to proxy");
}
char pchRet2[4];
uint8_t pchRet2[4];
if ((recvr = InterruptibleRecv(pchRet2, 4, SOCKS5_RECV_TIMEOUT, hSocket)) != IntrRecvError::OK) {
CloseSocket(hSocket);
if (recvr == IntrRecvError::Timeout) {
Expand All @@ -355,26 +408,26 @@ static bool Socks5(const std::string& strDest, int port, const ProxyCredentials
return error("Error while reading proxy response");
}
}
if (pchRet2[0] != 0x05) {
if (pchRet2[0] != SOCKSVersion::SOCKS5) {
CloseSocket(hSocket);
return error("Proxy failed to accept request");
}
if (pchRet2[1] != 0x00) {
if (pchRet2[1] != SOCKS5Reply::SUCCEEDED) {
// Failures to connect to a peer that are not proxy errors
CloseSocket(hSocket);
LogPrintf("Socks5() connect to %s:%d failed: %s\n", strDest, port, Socks5ErrorString(pchRet2[1]));
return false;
}
if (pchRet2[2] != 0x00) {
if (pchRet2[2] != 0x00) { // Reserved field must be 0
CloseSocket(hSocket);
return error("Error: malformed proxy response");
}
char pchRet3[256];
uint8_t pchRet3[256];
switch (pchRet2[3])
{
case 0x01: recvr = InterruptibleRecv(pchRet3, 4, SOCKS5_RECV_TIMEOUT, hSocket); break;
case 0x04: recvr = InterruptibleRecv(pchRet3, 16, SOCKS5_RECV_TIMEOUT, hSocket); break;
case 0x03:
case SOCKS5Atyp::IPV4: recvr = InterruptibleRecv(pchRet3, 4, SOCKS5_RECV_TIMEOUT, hSocket); break;
case SOCKS5Atyp::IPV6: recvr = InterruptibleRecv(pchRet3, 16, SOCKS5_RECV_TIMEOUT, hSocket); break;
case SOCKS5Atyp::DOMAINNAME:
{
recvr = InterruptibleRecv(pchRet3, 1, SOCKS5_RECV_TIMEOUT, hSocket);
if (recvr != IntrRecvError::OK) {
Expand Down
9 changes: 7 additions & 2 deletions src/qt/bitcoingui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,11 @@ BitcoinGUI::BitcoinGUI(const PlatformStyle *_platformStyle, const NetworkStyle *
/* Open CSS when configured */
this->setStyleSheet(GUIUtil::loadStyleSheet());

GUIUtil::restoreWindowGeometry("nWindow", QSize(850, 550), this);
QSettings settings;
if (!restoreGeometry(settings.value("MainWindowGeometry").toByteArray())) {
// Restore failed (perhaps missing setting), center the window
move(QApplication::desktop()->availableGeometry().center() - frameGeometry().center());
}

QString windowTitle = tr(PACKAGE_NAME) + " - ";
#ifdef ENABLE_WALLET
Expand Down Expand Up @@ -278,7 +282,8 @@ BitcoinGUI::~BitcoinGUI()
// Unsubscribe from notifications from core
unsubscribeFromCoreSignals();

GUIUtil::saveWindowGeometry("nWindow", this);
QSettings settings;
settings.setValue("MainWindowGeometry", saveGeometry());
if(trayIcon) // Hide tray icon, as deleting will let it linger until quit (on Ubuntu)
trayIcon->hide();
#ifdef Q_OS_MAC
Expand Down
26 changes: 0 additions & 26 deletions src/qt/guiutil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -867,32 +867,6 @@ void migrateQtSettings()
}
}

void saveWindowGeometry(const QString& strSetting, QWidget *parent)
{
QSettings settings;
settings.setValue(strSetting + "Pos", parent->pos());
settings.setValue(strSetting + "Size", parent->size());
}

void restoreWindowGeometry(const QString& strSetting, const QSize& defaultSize, QWidget *parent)
{
QSettings settings;
QPoint pos = settings.value(strSetting + "Pos").toPoint();
QSize size = settings.value(strSetting + "Size", defaultSize).toSize();

parent->resize(size);
parent->move(pos);

if ((!pos.x() && !pos.y()) || (QApplication::desktop()->screenNumber(parent) == -1))
{
QRect screen = QApplication::desktop()->screenGeometry();
QPoint defaultPos = screen.center() -
QPoint(defaultSize.width() / 2, defaultSize.height() / 2);
parent->resize(defaultSize);
parent->move(defaultPos);
}
}

// Return name of current UI-theme or default theme if no theme was found
QString getThemeName()
{
Expand Down
5 changes: 0 additions & 5 deletions src/qt/guiutil.h
Original file line number Diff line number Diff line change
Expand Up @@ -185,11 +185,6 @@ namespace GUIUtil
/** Modify Qt network specific settings on migration */
void migrateQtSettings();

/** Save window size and position */
void saveWindowGeometry(const QString& strSetting, QWidget *parent);
/** Restore window size and position */
void restoreWindowGeometry(const QString& strSetting, const QSize &defaultSizeIn, QWidget *parent);

/** Load global CSS theme */
QString loadStyleSheet();

Expand Down
8 changes: 4 additions & 4 deletions src/qt/masternodelist.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -177,10 +177,10 @@ void MasternodeList::updateDIP3List()
mnList.ForEachMN(false, [&](const CDeterministicMNCPtr& dmn) {
if (walletModel && ui->checkBoxMyMasternodesOnly->isChecked()) {
bool fMyMasternode = setOutpts.count(dmn->collateralOutpoint) ||
walletModel->havePrivKey(dmn->pdmnState->keyIDOwner) ||
walletModel->havePrivKey(dmn->pdmnState->keyIDVoting) ||
walletModel->havePrivKey(dmn->pdmnState->scriptPayout) ||
walletModel->havePrivKey(dmn->pdmnState->scriptOperatorPayout);
walletModel->IsSpendable(dmn->pdmnState->keyIDOwner) ||
walletModel->IsSpendable(dmn->pdmnState->keyIDVoting) ||
walletModel->IsSpendable(dmn->pdmnState->scriptPayout) ||
walletModel->IsSpendable(dmn->pdmnState->scriptOperatorPayout);
if (!fMyMasternode) return;
}
// populate list
Expand Down
Loading

0 comments on commit 3712f8d

Please sign in to comment.