diff options
-rw-r--r-- | bitcoin-qt.pro | 2 | ||||
-rw-r--r-- | contrib/gitian-descriptors/README | 65 | ||||
-rwxr-xr-x | contrib/macdeploy/macdeployqtplus | 5 | ||||
-rw-r--r-- | doc/Tor.txt | 4 | ||||
-rw-r--r-- | doc/coding.txt | 2 | ||||
-rw-r--r-- | doc/release-notes.txt | 25 | ||||
-rw-r--r-- | doc/release-process.txt | 10 | ||||
-rw-r--r-- | share/setup.nsi | 2 | ||||
-rw-r--r-- | src/alert.cpp | 239 | ||||
-rw-r--r-- | src/alert.h | 102 | ||||
-rw-r--r-- | src/init.cpp | 3 | ||||
-rw-r--r-- | src/main.cpp | 92 | ||||
-rw-r--r-- | src/main.h | 206 | ||||
-rw-r--r-- | src/makefile.linux-mingw | 1 | ||||
-rw-r--r-- | src/makefile.mingw | 1 | ||||
-rw-r--r-- | src/makefile.osx | 1 | ||||
-rw-r--r-- | src/makefile.unix | 1 | ||||
-rw-r--r-- | src/net.cpp | 5 | ||||
-rw-r--r-- | src/qt/clientmodel.cpp | 1 | ||||
-rw-r--r-- | src/version.h | 2 | ||||
-rw-r--r-- | src/wallet.cpp | 2 |
21 files changed, 450 insertions, 321 deletions
diff --git a/bitcoin-qt.pro b/bitcoin-qt.pro index 7c122dee34..1d2b1dbdc3 100644 --- a/bitcoin-qt.pro +++ b/bitcoin-qt.pro @@ -119,6 +119,7 @@ HEADERS += src/qt/bitcoingui.h \ src/qt/aboutdialog.h \ src/qt/editaddressdialog.h \ src/qt/bitcoinaddressvalidator.h \ + src/alert.h \ src/addrman.h \ src/base58.h \ src/bignum.h \ @@ -189,6 +190,7 @@ SOURCES += src/qt/bitcoin.cpp src/qt/bitcoingui.cpp \ src/qt/aboutdialog.cpp \ src/qt/editaddressdialog.cpp \ src/qt/bitcoinaddressvalidator.cpp \ + src/alert.cpp \ src/version.cpp \ src/sync.cpp \ src/util.cpp \ diff --git a/contrib/gitian-descriptors/README b/contrib/gitian-descriptors/README index a2d902e210..66a0509ac6 100644 --- a/contrib/gitian-descriptors/README +++ b/contrib/gitian-descriptors/README @@ -1,31 +1,86 @@ -Gavin's notes on getting gitian builds up and running: +Gavin's notes on getting gitian builds up and running using KVM: + +These instructions distilled from: + https://help.ubuntu.com/community/KVM/Installation +... see there for complete details. You need the right hardware: you need a 64-bit-capable CPU with hardware virtualization support (Intel VT-x or AMD-V). Not all modern CPUs support hardware virtualization. You probably need to enable hardware virtualization in your machine's BIOS. You need to be running a recent version of 64-bit-Ubuntu, and you need to install several prerequisites: - sudo apt-get install apache2 git apt-cacher-ng python-vm-builder qemu-kvm + sudo apt-get install ruby apache2 git apt-cacher-ng python-vm-builder qemu-kvm Sanity checks: sudo service apt-cacher-ng status # Should return apt-cacher-ng is running ls -l /dev/kvm # Should show a /dev/kvm device + Once you've got the right hardware and software: git clone git://github.com/bitcoin/bitcoin.git git clone git://github.com/devrandom/gitian-builder.git mkdir gitian-builder/inputs - wget 'http://miniupnp.tuxfamily.org/files/download.php?file=miniupnpc-1.6.tar.gz' -O gitian-builder/inputs/miniupnpc-1.6.tar.gz + cd gitian-builder/inputs + # Inputs for Linux and Win32: + wget -O miniupnpc-1.6.tar.gz 'http://miniupnp.tuxfamily.org/files/download.php?file=miniupnpc-1.6.tar.gz' + wget 'http://fukuchi.org/works/qrencode/qrencode-3.2.0.tar.bz2' + # Inputs for Win32: (Linux has packages for these) + wget 'https://downloads.sourceforge.net/project/boost/boost/1.50.0/boost_1_50_0.tar.bz2' + wget 'http://www.openssl.org/source/openssl-1.0.1b.tar.gz' + wget 'http://download.oracle.com/berkeley-db/db-4.8.30.NC.tar.gz' + wget 'https://downloads.sourceforge.net/project/libpng/zlib/1.2.6/zlib-1.2.6.tar.gz' + wget 'https://downloads.sourceforge.net/project/libpng/libpng15/older-releases/1.5.9/libpng-1.5.9.tar.gz' + wget 'ftp://ftp.trolltech.com/qt/source/qt-everywhere-opensource-src-4.7.4.tar.gz' + cd ../.. cd gitian-builder bin/make-base-vm --arch i386 bin/make-base-vm --arch amd64 cd .. - # To build + # Build Linux release: cd bitcoin git pull cd ../gitian-builder git pull - ./bin/gbuild --commit bitcoin=HEAD ../bitcoin/contrib/gitian.yml + ./bin/gbuild --commit bitcoin=HEAD ../bitcoin/contrib/gitian-descriptors/gitian.yml + + # Build Win32 dependencies: (only needs to be done once, or when dependency versions change) + ./bin/gbuild --commit bitcoin=HEAD ../bitcoin/contrib/gitian-descriptors/boost-win32.yml + ./bin/gbuild --commit bitcoin=HEAD ../bitcoin/contrib/gitian-descriptors/deps-win32.yml + ./bin/gbuild --commit bitcoin=HEAD ../bitcoin/contrib/gitian-descriptors/qt-win32.yml + + # Build Win32 release: + ./bin/gbuild --commit bitcoin=HEAD ../bitcoin/contrib/gitian-descriptors/gitian-win32.yml + +--------------------- + +gitian-builder now also supports building using LXC. See + https://help.ubuntu.com/12.04/serverguide/lxc.html +... for how to get LXC up and running under Ubuntu. + +If your main machine is a 64-bit Mac or PC with a few gigabytes of memory +and at least 10 gigabytes of free disk space, you can gitian-build using +LXC running inside a virtual machine. + +Here's a description of Gavin's setup on OSX 10.6: + +1. Download and install VirtualBox from https://www.virtualbox.org/ + +2. Download the 64-bit Ubuntu Desktop 12.04 LTS .iso CD image from + http://www.ubuntu.com/ + +3. Run VirtualBox and create a new virtual machine, using the + Ubuntu .iso (see the VirtualBox documentation for details). + Create it with at least 2 gigabytes of memory and a disk + that is at least 20 gigabytes big. + +4. Inside the running Ubuntu desktop, install: + sudo apt-get install debootstrap lxc ruby apache2 git apt-cacher-ng python-vm-builder + +5. Still inside Ubuntu, tell gitian-builder to use LXC, then follow the "Once you've got the right + hardware and software" instructions above: + export USE_LXC=1 + git clone git://github.com/bitcoin/bitcoin.git + ... etc diff --git a/contrib/macdeploy/macdeployqtplus b/contrib/macdeploy/macdeployqtplus index e159f9bbc3..16daa59b08 100755 --- a/contrib/macdeploy/macdeployqtplus +++ b/contrib/macdeploy/macdeployqtplus @@ -169,6 +169,9 @@ class DeploymentInfo(object): elif os.path.exists(os.path.join(parentDir, "share", "qt4", "translations")): # MacPorts layout, e.g. "/opt/local/share/qt4" self.qtPath = os.path.join(parentDir, "share", "qt4") + elif os.path.exists(os.path.join(os.path.dirname(parentDir), "share", "qt4", "translations")): + # Newer Macports layout + self.qtPath = os.path.join(os.path.dirname(parentDir), "share", "qt4") if self.qtPath is not None: pluginPath = os.path.join(self.qtPath, "plugins") @@ -725,7 +728,7 @@ if config.dmg is not None: disk.close() if bg_path is not None: subprocess.call(["SetFile", "-a", "V", bg_path]) - disk.update(registering_applications=False) +# disk.update(registering_applications=False) sleep(2) disk.eject() diff --git a/doc/Tor.txt b/doc/Tor.txt index e088d87105..f515f96f49 100644 --- a/doc/Tor.txt +++ b/doc/Tor.txt @@ -28,10 +28,6 @@ outgoing connections be anonimized, but more is possible. need to set this if it's the same as -proxy. You can use -notor to explicitly disable access to hidden service. --dnsseed DNS seeds are not resolved directly when a SOCKS5 proxy server is - set. Rather, a short-lived proxy connection to the dns seed - hostname is attempted, and peer addresses are requested. - -listen When using -proxy, listening is disabled by default. If you want to run a hidden service (see next section), you'll need to enable it explicitly. diff --git a/doc/coding.txt b/doc/coding.txt index b3c812a486..0813105e73 100644 --- a/doc/coding.txt +++ b/doc/coding.txt @@ -44,7 +44,7 @@ bn CBigNum Locking/mutex usage notes
The code is multi-threaded, and uses mutexes and the
-CRITICAL_BLOCK/TRY_CRITICAL_BLOCK macros to protect data structures.
+LOCK/TRY_LOCK macros to protect data structures.
Deadlocks due to inconsistent lock ordering (thread 1 locks cs_main
and then cs_wallet, while thread 2 locks them in the opposite order:
diff --git a/doc/release-notes.txt b/doc/release-notes.txt index babc56ff81..1fe385bd9e 100644 --- a/doc/release-notes.txt +++ b/doc/release-notes.txt @@ -1,4 +1,3 @@ - (note: this is a temporary file, to be added-to by anybody, and deleted at release time) @@ -6,7 +5,25 @@ Building this from $ git shortlog --no-merges v0.6.3.. +How to Upgrade +-------------- +If you are running an older version, shut it down. Wait +until it has completely shut down (which might take a few minutes for older +versions), then run the installer (on Windows) or just copy over +/Applications/Bitcoin-Qt (on Mac) or bitcoind/bitcoin-qt (on Linux). + +If you were running on Linux with a version that might have been compiled +with a different version of Berkeley DB (for example, if you were using an +Ubuntu PPA version), then run the old version again with the -detachdb +argument and shut it down; if you do not, then the new version will not +be able to read the database files and will exit with an error. + +Incompatible Changes +-------------------- +* Replaced the 'getmemorypool' RPC command with 'getblocktemplate/submitblock' + and 'getrawmempool' commands. +* Remove deprecated RPC 'getblocknumber' Bitcoin Improvement Proposals implemented ----------------------------------------- @@ -24,7 +41,8 @@ Core bitcoin handling and blockchain database * Database: better validation of on-disk stored data * Database: minor optimizations and reliability improvements * -loadblock=FILE will import an external block file -* Additional DoS prevention measures +* Additional DoS (denial-of-service) prevention measures +* New blockchain checkpoint at block 193,000 JSON-RPC API @@ -44,7 +62,6 @@ JSON-RPC API non-wallet TXs now. * Remove deprecated RPC 'getblocknumber' * Remove superceded RPC 'getmemorypool' (see BIP 22, above) -* New blockchain checkpoint at block 193,000 * listtransactions output now displays "smart" times for transactions, and 'blocktime' and 'timereceived' fields were added @@ -52,7 +69,7 @@ JSON-RPC API P2P networking -------------- * IPv6 support -* Tor hidden service support +* Tor hidden service support (see doc/Tor.txt) * Attempts to fix "stuck blockchain download" problems * Replace BDB database "addr.dat" with internally-managed "peers.dat" file containing peer address data. diff --git a/doc/release-process.txt b/doc/release-process.txt index 59488a7bfe..b31b0ab541 100644 --- a/doc/release-process.txt +++ b/doc/release-process.txt @@ -21,7 +21,7 @@ export VERSION=0.5.1 cd ./gitian-builder - * Fetch and build inputs: + * Fetch and build inputs: (first time, or when dependency versions change) mkdir -p inputs; cd inputs/ wget 'http://miniupnp.free.fr/files/download.php?file=miniupnpc-1.6.tar.gz' -O miniupnpc-1.6.tar.gz wget 'http://www.openssl.org/source/openssl-1.0.1b.tar.gz' @@ -29,15 +29,15 @@ wget 'http://zlib.net/zlib-1.2.6.tar.gz' wget 'ftp://ftp.simplesystems.org/pub/libpng/png/src/libpng-1.5.9.tar.gz' wget 'http://fukuchi.org/works/qrencode/qrencode-3.2.0.tar.bz2' - wget 'http://downloads.sourceforge.net/project/boost/boost/1.47.0/boost_1_47_0.tar.bz2' + wget 'http://downloads.sourceforge.net/project/boost/boost/1.50.0/boost_1_50_0.tar.bz2' wget 'http://download.qt.nokia.com/qt/source/qt-everywhere-opensource-src-4.7.4.tar.gz' cd .. ./bin/gbuild ../bitcoin/contrib/gitian-descriptors/boost-win32.yml - cp build/out/boost-win32-1.47.0-gitian.zip inputs/ + mv build/out/boost-win32-1.50.0-gitian2.zip inputs/ ./bin/gbuild ../bitcoin/contrib/gitian-descriptors/qt-win32.yml - cp build/out/qt-win32-4.7.4-gitian.zip inputs/ + mv build/out/qt-win32-4.7.4-gitian.zip inputs/ ./bin/gbuild ../bitcoin/contrib/gitian-descriptors/deps-win32.yml - cp build/out/bitcoin-deps-0.0.3.zip inputs/ + mv build/out/bitcoin-deps-0.0.3.zip inputs/ * Build bitcoind and bitcoin-qt on Linux32, Linux64, and Win32: ./bin/gbuild --commit bitcoin=v${VERSION} ../bitcoin/contrib/gitian-descriptors/gitian.yml diff --git a/share/setup.nsi b/share/setup.nsi index 4feab69b38..d46e1e68ae 100644 --- a/share/setup.nsi +++ b/share/setup.nsi @@ -51,7 +51,7 @@ CRCCheck on XPStyle on
BrandingText " "
ShowInstDetails show
-VIProductVersion 0.7.0.0
+VIProductVersion 0.7.0.2
VIAddVersionKey ProductName Bitcoin
VIAddVersionKey ProductVersion "${VERSION}"
VIAddVersionKey CompanyName "${COMPANY}"
diff --git a/src/alert.cpp b/src/alert.cpp new file mode 100644 index 0000000000..48920629e2 --- /dev/null +++ b/src/alert.cpp @@ -0,0 +1,239 @@ +// +// Alert system +// + +#include <boost/foreach.hpp> +#include <map> + +#include "alert.h" +#include "key.h" +#include "net.h" +#include "sync.h" +#include "ui_interface.h" + +using namespace std; + +map<uint256, CAlert> mapAlerts; +CCriticalSection cs_mapAlerts; + +static const char* pszMainKey = "04fc9702847840aaf195de8442ebecedf5b095cdbb9bc716bda9110971b28a49e0ead8564ff0db22209e0374782c093bb899692d524e9d6a6956e7c5ecbcd68284"; +static const char* pszTestKey = "04302390343f91cc401d56d68b123028bf52e5fca1939df127f63c6467cdf9c8e2c14b61104cf817d0b780da337893ecc4aaff1309e536162dabbdb45200ca2b0a"; + +void CUnsignedAlert::SetNull() +{ + nVersion = 1; + nRelayUntil = 0; + nExpiration = 0; + nID = 0; + nCancel = 0; + setCancel.clear(); + nMinVer = 0; + nMaxVer = 0; + setSubVer.clear(); + nPriority = 0; + + strComment.clear(); + strStatusBar.clear(); + strReserved.clear(); +} + +std::string CUnsignedAlert::ToString() const +{ + std::string strSetCancel; + BOOST_FOREACH(int n, setCancel) + strSetCancel += strprintf("%d ", n); + std::string strSetSubVer; + BOOST_FOREACH(std::string str, setSubVer) + strSetSubVer += "\"" + str + "\" "; + return strprintf( + "CAlert(\n" + " nVersion = %d\n" + " nRelayUntil = %"PRI64d"\n" + " nExpiration = %"PRI64d"\n" + " nID = %d\n" + " nCancel = %d\n" + " setCancel = %s\n" + " nMinVer = %d\n" + " nMaxVer = %d\n" + " setSubVer = %s\n" + " nPriority = %d\n" + " strComment = \"%s\"\n" + " strStatusBar = \"%s\"\n" + ")\n", + nVersion, + nRelayUntil, + nExpiration, + nID, + nCancel, + strSetCancel.c_str(), + nMinVer, + nMaxVer, + strSetSubVer.c_str(), + nPriority, + strComment.c_str(), + strStatusBar.c_str()); +} + +void CUnsignedAlert::print() const +{ + printf("%s", ToString().c_str()); +} + +void CAlert::SetNull() +{ + CUnsignedAlert::SetNull(); + vchMsg.clear(); + vchSig.clear(); +} + +bool CAlert::IsNull() const +{ + return (nExpiration == 0); +} + +uint256 CAlert::GetHash() const +{ + return Hash(this->vchMsg.begin(), this->vchMsg.end()); +} + +bool CAlert::IsInEffect() const +{ + return (GetAdjustedTime() < nExpiration); +} + +bool CAlert::Cancels(const CAlert& alert) const +{ + if (!IsInEffect()) + return false; // this was a no-op before 31403 + return (alert.nID <= nCancel || setCancel.count(alert.nID)); +} + +bool CAlert::AppliesTo(int nVersion, std::string strSubVerIn) const +{ + // TODO: rework for client-version-embedded-in-strSubVer ? + return (IsInEffect() && + nMinVer <= nVersion && nVersion <= nMaxVer && + (setSubVer.empty() || setSubVer.count(strSubVerIn))); +} + +bool CAlert::AppliesToMe() const +{ + return AppliesTo(PROTOCOL_VERSION, FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector<std::string>())); +} + +bool CAlert::RelayTo(CNode* pnode) const +{ + if (!IsInEffect()) + return false; + // returns true if wasn't already contained in the set + if (pnode->setKnown.insert(GetHash()).second) + { + if (AppliesTo(pnode->nVersion, pnode->strSubVer) || + AppliesToMe() || + GetAdjustedTime() < nRelayUntil) + { + pnode->PushMessage("alert", *this); + return true; + } + } + return false; +} + +bool CAlert::CheckSignature() const +{ + CKey key; + if (!key.SetPubKey(ParseHex(fTestNet ? pszTestKey : pszMainKey))) + return error("CAlert::CheckSignature() : SetPubKey failed"); + if (!key.Verify(Hash(vchMsg.begin(), vchMsg.end()), vchSig)) + return error("CAlert::CheckSignature() : verify signature failed"); + + // Now unserialize the data + CDataStream sMsg(vchMsg, SER_NETWORK, PROTOCOL_VERSION); + sMsg >> *(CUnsignedAlert*)this; + return true; +} + +CAlert CAlert::getAlertByHash(const uint256 &hash) +{ + CAlert retval; + { + LOCK(cs_mapAlerts); + map<uint256, CAlert>::iterator mi = mapAlerts.find(hash); + if(mi != mapAlerts.end()) + retval = mi->second; + } + return retval; +} + +bool CAlert::ProcessAlert() +{ + if (!CheckSignature()) + return false; + if (!IsInEffect()) + return false; + + // alert.nID=max is reserved for if the alert key is + // compromised. It must have a pre-defined message, + // must never expire, must apply to all versions, + // and must cancel all previous + // alerts or it will be ignored (so an attacker can't + // send an "everything is OK, don't panic" version that + // cannot be overridden): + int maxInt = std::numeric_limits<int>::max(); + if (nID == maxInt) + { + if (!( + nExpiration == maxInt && + nCancel == (maxInt-1) && + nMinVer == 0 && + nMaxVer == maxInt && + setSubVer.empty() && + nPriority == maxInt && + strStatusBar == "URGENT: Alert key compromised, upgrade required" + )) + return false; + } + + { + LOCK(cs_mapAlerts); + // Cancel previous alerts + for (map<uint256, CAlert>::iterator mi = mapAlerts.begin(); mi != mapAlerts.end();) + { + const CAlert& alert = (*mi).second; + if (Cancels(alert)) + { + printf("cancelling alert %d\n", alert.nID); + uiInterface.NotifyAlertChanged((*mi).first, CT_DELETED); + mapAlerts.erase(mi++); + } + else if (!alert.IsInEffect()) + { + printf("expiring alert %d\n", alert.nID); + uiInterface.NotifyAlertChanged((*mi).first, CT_DELETED); + mapAlerts.erase(mi++); + } + else + mi++; + } + + // Check if this alert has been cancelled + BOOST_FOREACH(PAIRTYPE(const uint256, CAlert)& item, mapAlerts) + { + const CAlert& alert = item.second; + if (alert.Cancels(*this)) + { + printf("alert already cancelled by %d\n", alert.nID); + return false; + } + } + + // Add to mapAlerts + mapAlerts.insert(make_pair(GetHash(), *this)); + // Notify UI if it applies to me + if(AppliesToMe()) + uiInterface.NotifyAlertChanged(GetHash(), CT_NEW); + } + + printf("accepted alert %d, AppliesToMe()=%d\n", nID, AppliesToMe()); + return true; +} diff --git a/src/alert.h b/src/alert.h new file mode 100644 index 0000000000..7949c76972 --- /dev/null +++ b/src/alert.h @@ -0,0 +1,102 @@ +// Copyright (c) 2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 The Bitcoin developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef _BITCOINALERT_H_ +#define _BITCOINALERT_H_ 1 + +#include <set> +#include <string> + +#include "uint256.h" +#include "util.h" + +class CNode; + +/** Alerts are for notifying old versions if they become too obsolete and + * need to upgrade. The message is displayed in the status bar. + * Alert messages are broadcast as a vector of signed data. Unserializing may + * not read the entire buffer if the alert is for a newer version, but older + * versions can still relay the original data. + */ +class CUnsignedAlert +{ +public: + int nVersion; + int64 nRelayUntil; // when newer nodes stop relaying to newer nodes + int64 nExpiration; + int nID; + int nCancel; + std::set<int> setCancel; + int nMinVer; // lowest version inclusive + int nMaxVer; // highest version inclusive + std::set<std::string> setSubVer; // empty matches all + int nPriority; + + // Actions + std::string strComment; + std::string strStatusBar; + std::string strReserved; + + IMPLEMENT_SERIALIZE + ( + READWRITE(this->nVersion); + nVersion = this->nVersion; + READWRITE(nRelayUntil); + READWRITE(nExpiration); + READWRITE(nID); + READWRITE(nCancel); + READWRITE(setCancel); + READWRITE(nMinVer); + READWRITE(nMaxVer); + READWRITE(setSubVer); + READWRITE(nPriority); + + READWRITE(strComment); + READWRITE(strStatusBar); + READWRITE(strReserved); + ) + + void SetNull(); + + std::string ToString() const; + void print() const; +}; + +/** An alert is a combination of a serialized CUnsignedAlert and a signature. */ +class CAlert : public CUnsignedAlert +{ +public: + std::vector<unsigned char> vchMsg; + std::vector<unsigned char> vchSig; + + CAlert() + { + SetNull(); + } + + IMPLEMENT_SERIALIZE + ( + READWRITE(vchMsg); + READWRITE(vchSig); + ) + + void SetNull(); + bool IsNull() const; + uint256 GetHash() const; + bool IsInEffect() const; + bool Cancels(const CAlert& alert) const; + bool AppliesTo(int nVersion, std::string strSubVerIn) const; + bool AppliesToMe() const; + bool RelayTo(CNode* pnode) const; + bool CheckSignature() const; + bool ProcessAlert(); + + /* + * Get copy of (active) alert object by hash. Returns a null alert if it is not found. + */ + static CAlert getAlertByHash(const uint256 &hash); +}; + +#endif diff --git a/src/init.cpp b/src/init.cpp index 859e20b2bf..dc425da644 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -225,7 +225,7 @@ std::string HelpMessage() " -datadir=<dir> " + _("Specify data directory") + "\n" + " -dbcache=<n> " + _("Set database cache size in megabytes (default: 25)") + "\n" + " -dblogsize=<n> " + _("Set database disk log size in megabytes (default: 100)") + "\n" + - " -timeout=<n> " + _("Specify connection timeout in milliseconds (default: 5000))") + "\n" + + " -timeout=<n> " + _("Specify connection timeout in milliseconds (default: 5000)") + "\n" + " -proxy=<ip:port> " + _("Connect through socks proxy") + "\n" + " -socks=<n> " + _("Select the version of socks proxy to use (4-5, default: 5)") + "\n" + " -tor=<ip:port> " + _("Use proxy to reach tor hidden services (default: same as -proxy)") + "\n" @@ -469,7 +469,6 @@ bool AppInit2() printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"); printf("Bitcoin version %s (%s)\n", FormatFullVersion().c_str(), CLIENT_DATE.c_str()); printf("Using OpenSSL version %s\n", SSLeay_version(SSLEAY_VERSION)); - printf("Startup time: %s\n", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str()); if (!fLogTimestamps) printf("Startup time: %s\n", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str()); printf("Default data directory %s\n", GetDefaultDataDir().string().c_str()); diff --git a/src/main.cpp b/src/main.cpp index 9e2ebb932e..302292ee29 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3,6 +3,7 @@ // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include "alert.h" #include "checkpoints.h" #include "db.h" #include "net.h" @@ -1993,7 +1994,7 @@ bool CheckDiskSpace(uint64 nAdditionalBytes) static filesystem::path BlockFilePath(unsigned int nFile) { - string strBlockFn = strprintf("blk%04d.dat", nFile); + string strBlockFn = strprintf("blk%04u.dat", nFile); return GetDataDir() / strBlockFn; } @@ -2262,8 +2263,8 @@ bool LoadExternalBlockFile(FILE* fileIn) // CAlert // -map<uint256, CAlert> mapAlerts; -CCriticalSection cs_mapAlerts; +extern map<uint256, CAlert> mapAlerts; +extern CCriticalSection cs_mapAlerts; string GetWarnings(string strFor) { @@ -2309,91 +2310,6 @@ string GetWarnings(string strFor) return "error"; } -CAlert CAlert::getAlertByHash(const uint256 &hash) -{ - CAlert retval; - { - LOCK(cs_mapAlerts); - map<uint256, CAlert>::iterator mi = mapAlerts.find(hash); - if(mi != mapAlerts.end()) - retval = mi->second; - } - return retval; -} - -bool CAlert::ProcessAlert() -{ - if (!CheckSignature()) - return false; - if (!IsInEffect()) - return false; - - // alert.nID=max is reserved for if the alert key is - // compromised. It must have a pre-defined message, - // must never expire, must apply to all versions, - // and must cancel all previous - // alerts or it will be ignored (so an attacker can't - // send an "everything is OK, don't panic" version that - // cannot be overridden): - int maxInt = std::numeric_limits<int>::max(); - if (nID == maxInt) - { - if (!( - nExpiration == maxInt && - nCancel == (maxInt-1) && - nMinVer == 0 && - nMaxVer == maxInt && - setSubVer.empty() && - nPriority == maxInt && - strStatusBar == "URGENT: Alert key compromised, upgrade required" - )) - return false; - } - - { - LOCK(cs_mapAlerts); - // Cancel previous alerts - for (map<uint256, CAlert>::iterator mi = mapAlerts.begin(); mi != mapAlerts.end();) - { - const CAlert& alert = (*mi).second; - if (Cancels(alert)) - { - printf("cancelling alert %d\n", alert.nID); - uiInterface.NotifyAlertChanged((*mi).first, CT_DELETED); - mapAlerts.erase(mi++); - } - else if (!alert.IsInEffect()) - { - printf("expiring alert %d\n", alert.nID); - uiInterface.NotifyAlertChanged((*mi).first, CT_DELETED); - mapAlerts.erase(mi++); - } - else - mi++; - } - - // Check if this alert has been cancelled - BOOST_FOREACH(PAIRTYPE(const uint256, CAlert)& item, mapAlerts) - { - const CAlert& alert = item.second; - if (alert.Cancels(*this)) - { - printf("alert already cancelled by %d\n", alert.nID); - return false; - } - } - - // Add to mapAlerts - mapAlerts.insert(make_pair(GetHash(), *this)); - // Notify UI if it applies to me - if(AppliesToMe()) - uiInterface.NotifyAlertChanged(GetHash(), CT_NEW); - } - - printf("accepted alert %d, AppliesToMe()=%d\n", nID, AppliesToMe()); - return true; -} - diff --git a/src/main.h b/src/main.h index b8057a295e..e61cbdd46b 100644 --- a/src/main.h +++ b/src/main.h @@ -1397,212 +1397,6 @@ public: - -/** Alerts are for notifying old versions if they become too obsolete and - * need to upgrade. The message is displayed in the status bar. - * Alert messages are broadcast as a vector of signed data. Unserializing may - * not read the entire buffer if the alert is for a newer version, but older - * versions can still relay the original data. - */ -class CUnsignedAlert -{ -public: - int nVersion; - int64 nRelayUntil; // when newer nodes stop relaying to newer nodes - int64 nExpiration; - int nID; - int nCancel; - std::set<int> setCancel; - int nMinVer; // lowest version inclusive - int nMaxVer; // highest version inclusive - std::set<std::string> setSubVer; // empty matches all - int nPriority; - - // Actions - std::string strComment; - std::string strStatusBar; - std::string strReserved; - - IMPLEMENT_SERIALIZE - ( - READWRITE(this->nVersion); - nVersion = this->nVersion; - READWRITE(nRelayUntil); - READWRITE(nExpiration); - READWRITE(nID); - READWRITE(nCancel); - READWRITE(setCancel); - READWRITE(nMinVer); - READWRITE(nMaxVer); - READWRITE(setSubVer); - READWRITE(nPriority); - - READWRITE(strComment); - READWRITE(strStatusBar); - READWRITE(strReserved); - ) - - void SetNull() - { - nVersion = 1; - nRelayUntil = 0; - nExpiration = 0; - nID = 0; - nCancel = 0; - setCancel.clear(); - nMinVer = 0; - nMaxVer = 0; - setSubVer.clear(); - nPriority = 0; - - strComment.clear(); - strStatusBar.clear(); - strReserved.clear(); - } - - std::string ToString() const - { - std::string strSetCancel; - BOOST_FOREACH(int n, setCancel) - strSetCancel += strprintf("%d ", n); - std::string strSetSubVer; - BOOST_FOREACH(std::string str, setSubVer) - strSetSubVer += "\"" + str + "\" "; - return strprintf( - "CAlert(\n" - " nVersion = %d\n" - " nRelayUntil = %"PRI64d"\n" - " nExpiration = %"PRI64d"\n" - " nID = %d\n" - " nCancel = %d\n" - " setCancel = %s\n" - " nMinVer = %d\n" - " nMaxVer = %d\n" - " setSubVer = %s\n" - " nPriority = %d\n" - " strComment = \"%s\"\n" - " strStatusBar = \"%s\"\n" - ")\n", - nVersion, - nRelayUntil, - nExpiration, - nID, - nCancel, - strSetCancel.c_str(), - nMinVer, - nMaxVer, - strSetSubVer.c_str(), - nPriority, - strComment.c_str(), - strStatusBar.c_str()); - } - - void print() const - { - printf("%s", ToString().c_str()); - } -}; - -/** An alert is a combination of a serialized CUnsignedAlert and a signature. */ -class CAlert : public CUnsignedAlert -{ -public: - std::vector<unsigned char> vchMsg; - std::vector<unsigned char> vchSig; - - CAlert() - { - SetNull(); - } - - IMPLEMENT_SERIALIZE - ( - READWRITE(vchMsg); - READWRITE(vchSig); - ) - - void SetNull() - { - CUnsignedAlert::SetNull(); - vchMsg.clear(); - vchSig.clear(); - } - - bool IsNull() const - { - return (nExpiration == 0); - } - - uint256 GetHash() const - { - return Hash(this->vchMsg.begin(), this->vchMsg.end()); - } - - bool IsInEffect() const - { - return (GetAdjustedTime() < nExpiration); - } - - bool Cancels(const CAlert& alert) const - { - if (!IsInEffect()) - return false; // this was a no-op before 31403 - return (alert.nID <= nCancel || setCancel.count(alert.nID)); - } - - bool AppliesTo(int nVersion, std::string strSubVerIn) const - { - // TODO: rework for client-version-embedded-in-strSubVer ? - return (IsInEffect() && - nMinVer <= nVersion && nVersion <= nMaxVer && - (setSubVer.empty() || setSubVer.count(strSubVerIn))); - } - - bool AppliesToMe() const - { - return AppliesTo(PROTOCOL_VERSION, FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector<std::string>())); - } - - bool RelayTo(CNode* pnode) const - { - if (!IsInEffect()) - return false; - // returns true if wasn't already contained in the set - if (pnode->setKnown.insert(GetHash()).second) - { - if (AppliesTo(pnode->nVersion, pnode->strSubVer) || - AppliesToMe() || - GetAdjustedTime() < nRelayUntil) - { - pnode->PushMessage("alert", *this); - return true; - } - } - return false; - } - - bool CheckSignature() - { - CKey key; - if (!key.SetPubKey(ParseHex("04fc9702847840aaf195de8442ebecedf5b095cdbb9bc716bda9110971b28a49e0ead8564ff0db22209e0374782c093bb899692d524e9d6a6956e7c5ecbcd68284"))) - return error("CAlert::CheckSignature() : SetPubKey failed"); - if (!key.Verify(Hash(vchMsg.begin(), vchMsg.end()), vchSig)) - return error("CAlert::CheckSignature() : verify signature failed"); - - // Now unserialize the data - CDataStream sMsg(vchMsg, SER_NETWORK, PROTOCOL_VERSION); - sMsg >> *(CUnsignedAlert*)this; - return true; - } - - bool ProcessAlert(); - - /* - * Get copy of (active) alert object by hash. Returns a null alert if it is not found. - */ - static CAlert getAlertByHash(const uint256 &hash); -}; - class CTxMemPool { public: diff --git a/src/makefile.linux-mingw b/src/makefile.linux-mingw index 828ddfe588..4ba0cf06f0 100644 --- a/src/makefile.linux-mingw +++ b/src/makefile.linux-mingw @@ -56,6 +56,7 @@ LIBS += -l mingwthrd -l kernel32 -l user32 -l gdi32 -l comdlg32 -l winspool -l w HEADERS = $(wildcard *.h) OBJS= \ + obj/alert.o \ obj/version.o \ obj/checkpoints.o \ obj/netbase.o \ diff --git a/src/makefile.mingw b/src/makefile.mingw index 5d46797766..55c5b7e387 100644 --- a/src/makefile.mingw +++ b/src/makefile.mingw @@ -52,6 +52,7 @@ LIBS += -l kernel32 -l user32 -l gdi32 -l comdlg32 -l winspool -l winmm -l shell HEADERS = $(wildcard *.h) OBJS= \ + obj/alert.o \ obj/version.o \ obj/checkpoints.o \ obj/netbase.o \ diff --git a/src/makefile.osx b/src/makefile.osx index de829b9eb1..2666caa918 100644 --- a/src/makefile.osx +++ b/src/makefile.osx @@ -70,6 +70,7 @@ CFLAGS += -Wall -Wextra -Wformat -Wformat-security -Wno-unused-parameter \ $(DEBUGFLAGS) $(DEFS) $(INCLUDEPATHS) OBJS= \ + obj/alert.o \ obj/version.o \ obj/checkpoints.o \ obj/netbase.o \ diff --git a/src/makefile.unix b/src/makefile.unix index ac42743d8e..37a1917973 100644 --- a/src/makefile.unix +++ b/src/makefile.unix @@ -101,6 +101,7 @@ xCXXFLAGS=-O2 -pthread -Wall -Wextra -Wformat -Wformat-security -Wno-unused-para xLDFLAGS=$(LDHARDENING) $(LDFLAGS) OBJS= \ + obj/alert.o \ obj/version.o \ obj/checkpoints.o \ obj/netbase.o \ diff --git a/src/net.cpp b/src/net.cpp index 2c6efff63c..c0693306af 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -827,8 +827,9 @@ void ThreadSocketHandler2(void* parg) if (hSocket == INVALID_SOCKET) { - if (WSAGetLastError() != WSAEWOULDBLOCK) - printf("socket error accept failed: %d\n", WSAGetLastError()); + int nErr = WSAGetLastError(); + if (nErr != WSAEWOULDBLOCK) + printf("socket error accept failed: %d\n", nErr); } else if (nInbound >= GetArg("-maxconnections", 125) - MAX_OUTBOUND_CONNECTIONS) { diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp index 43bce6f289..b820d16abf 100644 --- a/src/qt/clientmodel.cpp +++ b/src/qt/clientmodel.cpp @@ -4,6 +4,7 @@ #include "addresstablemodel.h" #include "transactiontablemodel.h" +#include "alert.h" #include "main.h" #include "ui_interface.h" diff --git a/src/version.h b/src/version.h index a26c9e42ef..f731c4570a 100644 --- a/src/version.h +++ b/src/version.h @@ -14,7 +14,7 @@ #define CLIENT_VERSION_MAJOR 0 #define CLIENT_VERSION_MINOR 7 #define CLIENT_VERSION_REVISION 0 -#define CLIENT_VERSION_BUILD 0 +#define CLIENT_VERSION_BUILD 2 static const int CLIENT_VERSION = 1000000 * CLIENT_VERSION_MAJOR diff --git a/src/wallet.cpp b/src/wallet.cpp index 2f312d809e..f88a0e1413 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -1367,7 +1367,7 @@ string CWallet::SendMoneyToDestination(const CTxDestination& address, int64 nVal int CWallet::LoadWallet(bool& fFirstRunRet) { if (!fFileBacked) - return false; + return DB_LOAD_OK; fFirstRunRet = false; int nLoadWalletRet = CWalletDB(strWalletFile,"cr+").LoadWallet(this); if (nLoadWalletRet == DB_NEED_REWRITE) |