Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
76776fb
Merge #11017: [wallet] Close DB on error.
jonasschnelli Aug 15, 2017
9a5b798
Merge #10957: Avoid returning a BIP9Stats object with uninitialized v…
Aug 16, 2017
6ec77c0
Merge #11131: rpc: Write authcookie atomically
laanwj Aug 28, 2017
a88e000
Merge #11247: qt: Use IsMine to validate custom change address
Sep 5, 2017
cbf59ef
Implement WalletModel::IsSpendable for CScript
codablock Sep 24, 2019
654c78f
Merge #11267: rpc: update cli for estimate*fee argument rename
Sep 12, 2017
61c5fb9
Merge #11015: [Qt] Add delay before filtering transactions
jonasschnelli Sep 26, 2017
b6e7a4b
Merge #11335: Replace save|restoreWindowGeometry with Qt functions
laanwj Sep 25, 2017
3b0df34
Merge #11318: Put back inadvertently removed copyright notices
laanwj Sep 28, 2017
6ab6809
Merge #11338: qt: Backup former GUI settings on `-resetguisettings`
laanwj Sep 23, 2017
1d3ac9a
Merge #11440: Fix validationinterface build on super old boost/clang
laanwj Oct 4, 2017
9e3cb75
Merge #9937: rpc: Prevent `dumpwallet` from overwriting files
laanwj Oct 4, 2017
08513bf
Merge #11437: [Docs] Update Windows build instructions for using WSL …
laanwj Oct 5, 2017
1313ee3
Merge #11397: net: Improve and document SOCKS code
jonasschnelli Sep 28, 2017
f8f55c2
Merge #11465: rpc: Update named args documentation for importprivkey
Oct 9, 2017
f616989
Merge #11483: Fix importmulti bug when importing an already imported key
Oct 17, 2017
1c65e08
Fix "os" import in wallet-dump.py
codablock Sep 25, 2019
4770830
Drop accidently added lines in release-notes.md
codablock Sep 26, 2019
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
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