diff options
94 files changed, 1281 insertions, 1143 deletions
diff --git a/.travis.yml b/.travis.yml index 7580adf5c4..54799362a2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -27,7 +27,7 @@ matrix: - compiler: "true 1" env: HOST=arm-linux-gnueabihf PACKAGES="g++-arm-linux-gnueabihf" DEP_OPTS="NO_QT=1" GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat" - compiler: "true 2" - env: HOST=x86_64-unknown-linux-gnu DEP_OPTS="NO_QT=1 NO_WALLET=1 NO_UPNP=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat" + env: HOST=x86_64-unknown-linux-gnu DEP_OPTS="NO_QT=1 NO_WALLET=1 NO_UPNP=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat CPPFLAGS=-DDEBUG_LOCKORDER" - compiler: "true 3" env: HOST=x86_64-unknown-linux-gnu RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat" - compiler: "true 4" @@ -58,6 +58,6 @@ script: - cd bitcoin-$HOST - ./configure --cache-file=../config.cache $BITCOIN_CONFIG_ALL $BITCOIN_CONFIG || ( cat config.log && false) - make $MAKEJOBS $GOAL || ( echo "Build failure. Verbose build follows." && make $GOAL V=1 ; false ) - - if [ "$RUN_TESTS" = "true" ]; then make check; fi + - if [ "$RUN_TESTS" = "true" ]; then travis_retry make check; fi after_script: - if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then (echo "Upload goes here. Something like: scp -r $BASE_OUTDIR server" || echo "upload failed"); fi diff --git a/depends/config.site.in b/depends/config.site.in index 4012f5a8d1..1df04eec3f 100644 --- a/depends/config.site.in +++ b/depends/config.site.in @@ -52,7 +52,7 @@ export PATH=$prefix/native/bin:$PATH export PKG_CONFIG="`which pkg-config` --static" export PKG_CONFIG_LIBDIR=$prefix/lib/pkgconfig export PKG_CONFIG_PATH=$prefix/share/pkgconfig -export CPPFLAGS=-I$prefix/include/ +export CPPFLAGS="-I$prefix/include/ $CPPFLAGS" export CC="@CC@" export CXX="@CXX@" diff --git a/doc/build-osx.md b/doc/build-osx.md index ade9eb466b..5eeda5b08e 100644 --- a/doc/build-osx.md +++ b/doc/build-osx.md @@ -26,44 +26,14 @@ There's also an assumption that you already have `git` installed. If not, it's the path of least resistance to install [Github for Mac](https://mac.github.com/) (OS X 10.7+) or [Git for OS X](https://code.google.com/p/git-osx-installer/). It is also -available via Homebrew or MacPorts. +available via Homebrew. -You will also need to install [Homebrew](http://brew.sh) -or [MacPorts](https://www.macports.org/) in order to install library -dependencies. It's largely a religious decision which to choose, however, Homebrew -is now used for building release versions. +You will also need to install [Homebrew](http://brew.sh) in order to install library +dependencies. The installation of the actual dependencies is covered in the Instructions sections below. -Instructions: MacPorts ----------------------- - -### Install dependencies - - sudo port install boost db48@+no_java openssl miniupnpc autoconf pkgconfig automake libtool - -Optional: install Qt4 - - sudo port install qt4-mac qrencode protobuf-cpp - -### Building `bitcoind` - -1. Clone the github tree to get the source code and go into the directory. - - git clone git@github.com:bitcoin/bitcoin.git bitcoin - cd bitcoin - -2. Build bitcoind (and Bitcoin-Qt, if configured): - - ./autogen.sh - ./configure - make - -3. It is a good idea to build and run the unit tests, too: - - make check - Instructions: Homebrew ---------------------- @@ -126,18 +96,6 @@ All dependencies should be compiled with these flags: -arch x86_64 -isysroot $(xcode-select --print-path)/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.6.sdk -For MacPorts, that means editing your macports.conf and setting -`macosx_deployment_target` and `build_arch`: - - macosx_deployment_target=10.6 - build_arch=x86_64 - -... and then uninstalling and re-installing, or simply rebuilding, all ports. - -As of December 2012, the `boost` port does not obey `macosx_deployment_target`. -Download `https://gavinandresen-bitcoin.s3.amazonaws.com/boost_macports_fix.zip` -for a fix. - Once dependencies are compiled, see release-process.md for how the Bitcoin-Qt.app bundle is packaged and signed to create the .dmg disk image that is distributed. diff --git a/doc/release-process.md b/doc/release-process.md index c5ead4199b..8934be66c4 100644 --- a/doc/release-process.md +++ b/doc/release-process.md @@ -64,7 +64,7 @@ Release Process wget 'http://www.opensource.apple.com/tarballs/cctools/cctools-809.tar.gz' wget 'http://www.opensource.apple.com/tarballs/dyld/dyld-195.5.tar.gz' wget 'http://www.opensource.apple.com/tarballs/ld64/ld64-127.2.tar.gz' - wget 'http://cdrkit.org/releases/cdrkit-1.1.11.tar.gz' + wget 'http://pkgs.fedoraproject.org/repo/pkgs/cdrkit/cdrkit-1.1.11.tar.gz/efe08e2f3ca478486037b053acd512e9/cdrkit-1.1.11.tar.gz' wget 'https://github.com/theuni/libdmg-hfsplus/archive/libdmg-hfsplus-v0.1.tar.gz' wget 'http://llvm.org/releases/3.2/clang+llvm-3.2-x86-linux-ubuntu-12.04.tar.gz' -O clang-llvm-3.2-x86-linux-ubuntu-12.04.tar.gz wget 'https://raw.githubusercontent.com/theuni/osx-cross-depends/master/patches/cdrtools/genisoimage.diff' -O cdrkit-deterministic.patch diff --git a/src/addrman.cpp b/src/addrman.cpp index 68948ac7ff..7b674a66e7 100644 --- a/src/addrman.cpp +++ b/src/addrman.cpp @@ -9,7 +9,7 @@ using namespace std; -int CAddrInfo::GetTriedBucket(const std::vector<unsigned char> &nKey) const +int CAddrInfo::GetTriedBucket(const std::vector<unsigned char>& nKey) const { CDataStream ss1(SER_GETHASH, 0); std::vector<unsigned char> vchKey = GetKey(); @@ -23,7 +23,7 @@ int CAddrInfo::GetTriedBucket(const std::vector<unsigned char> &nKey) const return hash2 % ADDRMAN_TRIED_BUCKET_COUNT; } -int CAddrInfo::GetNewBucket(const std::vector<unsigned char> &nKey, const CNetAddr& src) const +int CAddrInfo::GetNewBucket(const std::vector<unsigned char>& nKey, const CNetAddr& src) const { CDataStream ss1(SER_GETHASH, 0); std::vector<unsigned char> vchGroupKey = GetGroup(); @@ -39,19 +39,19 @@ int CAddrInfo::GetNewBucket(const std::vector<unsigned char> &nKey, const CNetAd bool CAddrInfo::IsTerrible(int64_t nNow) const { - if (nLastTry && nLastTry >= nNow-60) // never remove things tried the last minute + if (nLastTry && nLastTry >= nNow - 60) // never remove things tried the last minute return false; - if (nTime > nNow + 10*60) // came in a flying DeLorean + if (nTime > nNow + 10 * 60) // came in a flying DeLorean return true; - if (nTime==0 || nNow-nTime > ADDRMAN_HORIZON_DAYS*24*60*60) // not seen in recent history + if (nTime == 0 || nNow - nTime > ADDRMAN_HORIZON_DAYS * 24 * 60 * 60) // not seen in recent history return true; - if (nLastSuccess==0 && nAttempts>=ADDRMAN_RETRIES) // tried N times and never a success + if (nLastSuccess == 0 && nAttempts >= ADDRMAN_RETRIES) // tried N times and never a success return true; - if (nNow-nLastSuccess > ADDRMAN_MIN_FAIL_DAYS*24*60*60 && nAttempts>=ADDRMAN_MAX_FAILURES) // N successive failures in the last week + if (nNow - nLastSuccess > ADDRMAN_MIN_FAIL_DAYS * 24 * 60 * 60 && nAttempts >= ADDRMAN_MAX_FAILURES) // N successive failures in the last week return true; return false; @@ -64,23 +64,25 @@ double CAddrInfo::GetChance(int64_t nNow) const int64_t nSinceLastSeen = nNow - nTime; int64_t nSinceLastTry = nNow - nLastTry; - if (nSinceLastSeen < 0) nSinceLastSeen = 0; - if (nSinceLastTry < 0) nSinceLastTry = 0; + if (nSinceLastSeen < 0) + nSinceLastSeen = 0; + if (nSinceLastTry < 0) + nSinceLastTry = 0; fChance *= 600.0 / (600.0 + nSinceLastSeen); // deprioritize very recent attempts away - if (nSinceLastTry < 60*10) + if (nSinceLastTry < 60 * 10) fChance *= 0.01; // deprioritize 50% after each failed attempt - for (int n=0; n<nAttempts; n++) + for (int n = 0; n < nAttempts; n++) fChance /= 1.5; return fChance; } -CAddrInfo* CAddrMan::Find(const CNetAddr& addr, int *pnId) +CAddrInfo* CAddrMan::Find(const CNetAddr& addr, int* pnId) { std::map<CNetAddr, int>::iterator it = mapAddr.find(addr); if (it == mapAddr.end()) @@ -93,7 +95,7 @@ CAddrInfo* CAddrMan::Find(const CNetAddr& addr, int *pnId) return NULL; } -CAddrInfo* CAddrMan::Create(const CAddress &addr, const CNetAddr &addrSource, int *pnId) +CAddrInfo* CAddrMan::Create(const CAddress& addr, const CNetAddr& addrSource, int* pnId) { int nId = nIdCount++; mapInfo[nId] = CAddrInfo(addr, addrSource); @@ -127,22 +129,21 @@ void CAddrMan::SwapRandom(unsigned int nRndPos1, unsigned int nRndPos2) int CAddrMan::SelectTried(int nKBucket) { - std::vector<int> &vTried = vvTried[nKBucket]; + std::vector<int>& vTried = vvTried[nKBucket]; // random shuffle the first few elements (using the entire list) // find the least recently tried among them int64_t nOldest = -1; int nOldestPos = -1; - for (unsigned int i = 0; i < ADDRMAN_TRIED_ENTRIES_INSPECT_ON_EVICT && i < vTried.size(); i++) - { + for (unsigned int i = 0; i < ADDRMAN_TRIED_ENTRIES_INSPECT_ON_EVICT && i < vTried.size(); i++) { int nPos = GetRandInt(vTried.size() - i) + i; int nTemp = vTried[nPos]; vTried[nPos] = vTried[i]; vTried[i] = nTemp; assert(nOldest == -1 || mapInfo.count(nTemp) == 1); if (nOldest == -1 || mapInfo[nTemp].nLastSuccess < mapInfo[nOldest].nLastSuccess) { - nOldest = nTemp; - nOldestPos = nPos; + nOldest = nTemp; + nOldestPos = nPos; } } @@ -152,18 +153,15 @@ int CAddrMan::SelectTried(int nKBucket) int CAddrMan::ShrinkNew(int nUBucket) { assert(nUBucket >= 0 && (unsigned int)nUBucket < vvNew.size()); - std::set<int> &vNew = vvNew[nUBucket]; + std::set<int>& vNew = vvNew[nUBucket]; // first look for deletable items - for (std::set<int>::iterator it = vNew.begin(); it != vNew.end(); it++) - { + for (std::set<int>::iterator it = vNew.begin(); it != vNew.end(); it++) { assert(mapInfo.count(*it)); - CAddrInfo &info = mapInfo[*it]; - if (info.IsTerrible()) - { - if (--info.nRefCount == 0) - { - SwapRandom(info.nRandomPos, vRandom.size()-1); + CAddrInfo& info = mapInfo[*it]; + if (info.IsTerrible()) { + if (--info.nRefCount == 0) { + SwapRandom(info.nRandomPos, vRandom.size() - 1); vRandom.pop_back(); mapAddr.erase(info); mapInfo.erase(*it); @@ -178,10 +176,8 @@ int CAddrMan::ShrinkNew(int nUBucket) int n[4] = {GetRandInt(vNew.size()), GetRandInt(vNew.size()), GetRandInt(vNew.size()), GetRandInt(vNew.size())}; int nI = 0; int nOldest = -1; - for (std::set<int>::iterator it = vNew.begin(); it != vNew.end(); it++) - { - if (nI == n[0] || nI == n[1] || nI == n[2] || nI == n[3]) - { + for (std::set<int>::iterator it = vNew.begin(); it != vNew.end(); it++) { + if (nI == n[0] || nI == n[1] || nI == n[2] || nI == n[3]) { assert(nOldest == -1 || mapInfo.count(*it) == 1); if (nOldest == -1 || mapInfo[*it].nTime < mapInfo[nOldest].nTime) nOldest = *it; @@ -189,10 +185,9 @@ int CAddrMan::ShrinkNew(int nUBucket) nI++; } assert(mapInfo.count(nOldest) == 1); - CAddrInfo &info = mapInfo[nOldest]; - if (--info.nRefCount == 0) - { - SwapRandom(info.nRandomPos, vRandom.size()-1); + CAddrInfo& info = mapInfo[nOldest]; + if (--info.nRefCount == 0) { + SwapRandom(info.nRandomPos, vRandom.size() - 1); vRandom.pop_back(); mapAddr.erase(info); mapInfo.erase(nOldest); @@ -208,8 +203,7 @@ void CAddrMan::MakeTried(CAddrInfo& info, int nId, int nOrigin) assert(vvNew[nOrigin].count(nId) == 1); // remove the entry from all new buckets - for (std::vector<std::set<int> >::iterator it = vvNew.begin(); it != vvNew.end(); it++) - { + for (std::vector<std::set<int> >::iterator it = vvNew.begin(); it != vvNew.end(); it++) { if ((*it).erase(nId)) info.nRefCount--; } @@ -219,11 +213,10 @@ void CAddrMan::MakeTried(CAddrInfo& info, int nId, int nOrigin) // what tried bucket to move the entry to int nKBucket = info.GetTriedBucket(nKey); - std::vector<int> &vTried = vvTried[nKBucket]; + std::vector<int>& vTried = vvTried[nKBucket]; // first check whether there is place to just add it - if (vTried.size() < ADDRMAN_TRIED_BUCKET_SIZE) - { + if (vTried.size() < ADDRMAN_TRIED_BUCKET_SIZE) { vTried.push_back(nId); nTried++; info.fInTried = true; @@ -236,7 +229,7 @@ void CAddrMan::MakeTried(CAddrInfo& info, int nId, int nOrigin) // find which new bucket it belongs to assert(mapInfo.count(vTried[nPos]) == 1); int nUBucket = mapInfo[vTried[nPos]].GetNewBucket(nKey); - std::set<int> &vNew = vvNew[nUBucket]; + std::set<int>& vNew = vvNew[nUBucket]; // remove the to-be-replaced tried entry from the tried set CAddrInfo& infoOld = mapInfo[vTried[nPos]]; @@ -245,8 +238,7 @@ void CAddrMan::MakeTried(CAddrInfo& info, int nId, int nOrigin) // do not update nTried, as we are going to move something else there immediately // check whether there is place in that one, - if (vNew.size() < ADDRMAN_NEW_BUCKET_SIZE) - { + if (vNew.size() < ADDRMAN_NEW_BUCKET_SIZE) { // if so, move it back there vNew.insert(vTried[nPos]); } else { @@ -261,16 +253,16 @@ void CAddrMan::MakeTried(CAddrInfo& info, int nId, int nOrigin) return; } -void CAddrMan::Good_(const CService &addr, int64_t nTime) +void CAddrMan::Good_(const CService& addr, int64_t nTime) { int nId; - CAddrInfo *pinfo = Find(addr, &nId); + CAddrInfo* pinfo = Find(addr, &nId); // if not found, bail out if (!pinfo) return; - CAddrInfo &info = *pinfo; + CAddrInfo& info = *pinfo; // check whether we are talking about the exact same CService (including same port) if (info != addr) @@ -289,12 +281,10 @@ void CAddrMan::Good_(const CService &addr, int64_t nTime) // find a bucket it is in now int nRnd = GetRandInt(vvNew.size()); int nUBucket = -1; - for (unsigned int n = 0; n < vvNew.size(); n++) - { - int nB = (n+nRnd) % vvNew.size(); - std::set<int> &vNew = vvNew[nB]; - if (vNew.count(nId)) - { + for (unsigned int n = 0; n < vvNew.size(); n++) { + int nB = (n + nRnd) % vvNew.size(); + std::set<int>& vNew = vvNew[nB]; + if (vNew.count(nId)) { nUBucket = nB; break; } @@ -302,7 +292,8 @@ void CAddrMan::Good_(const CService &addr, int64_t nTime) // if no bucket is found, something bad happened; // TODO: maybe re-add the node, but for now, just bail out - if (nUBucket == -1) return; + if (nUBucket == -1) + return; LogPrint("addrman", "Moving %s to tried\n", addr.ToString()); @@ -310,17 +301,16 @@ void CAddrMan::Good_(const CService &addr, int64_t nTime) MakeTried(info, nId, nUBucket); } -bool CAddrMan::Add_(const CAddress &addr, const CNetAddr& source, int64_t nTimePenalty) +bool CAddrMan::Add_(const CAddress& addr, const CNetAddr& source, int64_t nTimePenalty) { if (!addr.IsRoutable()) return false; bool fNew = false; int nId; - CAddrInfo *pinfo = Find(addr, &nId); + CAddrInfo* pinfo = Find(addr, &nId); - if (pinfo) - { + if (pinfo) { // periodically update nTime bool fCurrentlyOnline = (GetAdjustedTime() - addr.nTime < 24 * 60 * 60); int64_t nUpdateInterval = (fCurrentlyOnline ? 60 * 60 : 24 * 60 * 60); @@ -344,7 +334,7 @@ bool CAddrMan::Add_(const CAddress &addr, const CNetAddr& source, int64_t nTimeP // stochastic test: previous nRefCount == N: 2^N times harder to increase it int nFactor = 1; - for (int n=0; n<pinfo->nRefCount; n++) + for (int n = 0; n < pinfo->nRefCount; n++) nFactor *= 2; if (nFactor > 1 && (GetRandInt(nFactor) != 0)) return false; @@ -356,9 +346,8 @@ bool CAddrMan::Add_(const CAddress &addr, const CNetAddr& source, int64_t nTimeP } int nUBucket = pinfo->GetNewBucket(nKey, source); - std::set<int> &vNew = vvNew[nUBucket]; - if (!vNew.count(nId)) - { + std::set<int>& vNew = vvNew[nUBucket]; + if (!vNew.count(nId)) { pinfo->nRefCount++; if (vNew.size() == ADDRMAN_NEW_BUCKET_SIZE) ShrinkNew(nUBucket); @@ -367,15 +356,15 @@ bool CAddrMan::Add_(const CAddress &addr, const CNetAddr& source, int64_t nTimeP return fNew; } -void CAddrMan::Attempt_(const CService &addr, int64_t nTime) +void CAddrMan::Attempt_(const CService& addr, int64_t nTime) { - CAddrInfo *pinfo = Find(addr); + CAddrInfo* pinfo = Find(addr); // if not found, bail out if (!pinfo) return; - CAddrInfo &info = *pinfo; + CAddrInfo& info = *pinfo; // check whether we are talking about the exact same CService (including same port) if (info != addr) @@ -393,37 +382,36 @@ CAddress CAddrMan::Select_(int nUnkBias) double nCorTried = sqrt(nTried) * (100.0 - nUnkBias); double nCorNew = sqrt(nNew) * nUnkBias; - if ((nCorTried + nCorNew)*GetRandInt(1<<30)/(1<<30) < nCorTried) - { + if ((nCorTried + nCorNew) * GetRandInt(1 << 30) / (1 << 30) < nCorTried) { // use a tried node double fChanceFactor = 1.0; - while(1) - { + while (1) { int nKBucket = GetRandInt(vvTried.size()); - std::vector<int> &vTried = vvTried[nKBucket]; - if (vTried.size() == 0) continue; + std::vector<int>& vTried = vvTried[nKBucket]; + if (vTried.size() == 0) + continue; int nPos = GetRandInt(vTried.size()); assert(mapInfo.count(vTried[nPos]) == 1); - CAddrInfo &info = mapInfo[vTried[nPos]]; - if (GetRandInt(1<<30) < fChanceFactor*info.GetChance()*(1<<30)) + CAddrInfo& info = mapInfo[vTried[nPos]]; + if (GetRandInt(1 << 30) < fChanceFactor * info.GetChance() * (1 << 30)) return info; fChanceFactor *= 1.2; } } else { // use a new node double fChanceFactor = 1.0; - while(1) - { + while (1) { int nUBucket = GetRandInt(vvNew.size()); - std::set<int> &vNew = vvNew[nUBucket]; - if (vNew.size() == 0) continue; + std::set<int>& vNew = vvNew[nUBucket]; + if (vNew.size() == 0) + continue; int nPos = GetRandInt(vNew.size()); std::set<int>::iterator it = vNew.begin(); while (nPos--) it++; assert(mapInfo.count(*it) == 1); - CAddrInfo &info = mapInfo[*it]; - if (GetRandInt(1<<30) < fChanceFactor*info.GetChance()*(1<<30)) + CAddrInfo& info = mapInfo[*it]; + if (GetRandInt(1 << 30) < fChanceFactor * info.GetChance() * (1 << 30)) return info; fChanceFactor *= 1.2; } @@ -436,69 +424,76 @@ int CAddrMan::Check_() std::set<int> setTried; std::map<int, int> mapNew; - if (vRandom.size() != nTried + nNew) return -7; + if (vRandom.size() != nTried + nNew) + return -7; - for (std::map<int, CAddrInfo>::iterator it = mapInfo.begin(); it != mapInfo.end(); it++) - { + for (std::map<int, CAddrInfo>::iterator it = mapInfo.begin(); it != mapInfo.end(); it++) { int n = (*it).first; - CAddrInfo &info = (*it).second; - if (info.fInTried) - { - - if (!info.nLastSuccess) return -1; - if (info.nRefCount) return -2; + CAddrInfo& info = (*it).second; + if (info.fInTried) { + if (!info.nLastSuccess) + return -1; + if (info.nRefCount) + return -2; setTried.insert(n); } else { - if (info.nRefCount < 0 || info.nRefCount > ADDRMAN_NEW_BUCKETS_PER_ADDRESS) return -3; - if (!info.nRefCount) return -4; + if (info.nRefCount < 0 || info.nRefCount > ADDRMAN_NEW_BUCKETS_PER_ADDRESS) + return -3; + if (!info.nRefCount) + return -4; mapNew[n] = info.nRefCount; } - if (mapAddr[info] != n) return -5; - if (info.nRandomPos<0 || info.nRandomPos>=vRandom.size() || vRandom[info.nRandomPos] != n) return -14; - if (info.nLastTry < 0) return -6; - if (info.nLastSuccess < 0) return -8; + if (mapAddr[info] != n) + return -5; + if (info.nRandomPos < 0 || info.nRandomPos >= vRandom.size() || vRandom[info.nRandomPos] != n) + return -14; + if (info.nLastTry < 0) + return -6; + if (info.nLastSuccess < 0) + return -8; } - if (setTried.size() != nTried) return -9; - if (mapNew.size() != nNew) return -10; + if (setTried.size() != nTried) + return -9; + if (mapNew.size() != nNew) + return -10; - for (int n=0; n<vvTried.size(); n++) - { - std::vector<int> &vTried = vvTried[n]; - for (std::vector<int>::iterator it = vTried.begin(); it != vTried.end(); it++) - { - if (!setTried.count(*it)) return -11; + for (int n = 0; n < vvTried.size(); n++) { + std::vector<int>& vTried = vvTried[n]; + for (std::vector<int>::iterator it = vTried.begin(); it != vTried.end(); it++) { + if (!setTried.count(*it)) + return -11; setTried.erase(*it); } } - for (int n=0; n<vvNew.size(); n++) - { - std::set<int> &vNew = vvNew[n]; - for (std::set<int>::iterator it = vNew.begin(); it != vNew.end(); it++) - { - if (!mapNew.count(*it)) return -12; + for (int n = 0; n < vvNew.size(); n++) { + std::set<int>& vNew = vvNew[n]; + for (std::set<int>::iterator it = vNew.begin(); it != vNew.end(); it++) { + if (!mapNew.count(*it)) + return -12; if (--mapNew[*it] == 0) mapNew.erase(*it); } } - if (setTried.size()) return -13; - if (mapNew.size()) return -15; + if (setTried.size()) + return -13; + if (mapNew.size()) + return -15; return 0; } #endif -void CAddrMan::GetAddr_(std::vector<CAddress> &vAddr) +void CAddrMan::GetAddr_(std::vector<CAddress>& vAddr) { unsigned int nNodes = ADDRMAN_GETADDR_MAX_PCT * vRandom.size() / 100; if (nNodes > ADDRMAN_GETADDR_MAX) nNodes = ADDRMAN_GETADDR_MAX; // gather a list of random nodes, skipping those of low quality - for (unsigned int n = 0; n < vRandom.size(); n++) - { + for (unsigned int n = 0; n < vRandom.size(); n++) { if (vAddr.size() >= nNodes) break; @@ -512,15 +507,15 @@ void CAddrMan::GetAddr_(std::vector<CAddress> &vAddr) } } -void CAddrMan::Connected_(const CService &addr, int64_t nTime) +void CAddrMan::Connected_(const CService& addr, int64_t nTime) { - CAddrInfo *pinfo = Find(addr); + CAddrInfo* pinfo = Find(addr); // if not found, bail out if (!pinfo) return; - CAddrInfo &info = *pinfo; + CAddrInfo& info = *pinfo; // check whether we are talking about the exact same CService (including same port) if (info != addr) diff --git a/src/allocators.cpp b/src/allocators.cpp index 8ecd7206cd..dfe26f1b1e 100644 --- a/src/allocators.cpp +++ b/src/allocators.cpp @@ -37,13 +37,13 @@ static inline size_t GetSystemPageSize() page_size = sSysInfo.dwPageSize; #elif defined(PAGESIZE) // defined in limits.h page_size = PAGESIZE; -#else // assume some POSIX OS +#else // assume some POSIX OS page_size = sysconf(_SC_PAGESIZE); #endif return page_size; } -bool MemoryPageLocker::Lock(const void *addr, size_t len) +bool MemoryPageLocker::Lock(const void* addr, size_t len) { #ifdef WIN32 return VirtualLock(const_cast<void*>(addr), len) != 0; @@ -52,7 +52,7 @@ bool MemoryPageLocker::Lock(const void *addr, size_t len) #endif } -bool MemoryPageLocker::Unlock(const void *addr, size_t len) +bool MemoryPageLocker::Unlock(const void* addr, size_t len) { #ifdef WIN32 return VirtualUnlock(const_cast<void*>(addr), len) != 0; @@ -64,4 +64,3 @@ bool MemoryPageLocker::Unlock(const void *addr, size_t len) LockedPageManager::LockedPageManager() : LockedPageManagerBase<MemoryPageLocker>(GetSystemPageSize()) { } - diff --git a/src/allocators.h b/src/allocators.h index 65a7d08987..6b69e7ae69 100644 --- a/src/allocators.h +++ b/src/allocators.h @@ -26,14 +26,14 @@ * small objects that span up to a few pages, mostly smaller than a page. To support large allocations, * something like an interval tree would be the preferred data structure. */ -template <class Locker> class LockedPageManagerBase +template <class Locker> +class LockedPageManagerBase { public: - LockedPageManagerBase(size_t page_size): - page_size(page_size) + LockedPageManagerBase(size_t page_size) : page_size(page_size) { // Determine bitmask for extracting page from address - assert(!(page_size & (page_size-1))); // size must be power of two + assert(!(page_size & (page_size - 1))); // size must be power of two page_mask = ~(page_size - 1); } @@ -44,22 +44,21 @@ public: // For all pages in affected range, increase lock count - void LockRange(void *p, size_t size) + void LockRange(void* p, size_t size) { boost::mutex::scoped_lock lock(mutex); - if(!size) return; + if (!size) + return; const size_t base_addr = reinterpret_cast<size_t>(p); const size_t start_page = base_addr & page_mask; const size_t end_page = (base_addr + size - 1) & page_mask; - for(size_t page = start_page; page <= end_page; page += page_size) - { + for (size_t page = start_page; page <= end_page; page += page_size) { Histogram::iterator it = histogram.find(page); - if(it == histogram.end()) // Newly locked page + if (it == histogram.end()) // Newly locked page { locker.Lock(reinterpret_cast<void*>(page), page_size); histogram.insert(std::make_pair(page, 1)); - } - else // Page was already locked; increase counter + } else // Page was already locked; increase counter { it->second += 1; } @@ -67,20 +66,20 @@ public: } // For all pages in affected range, decrease lock count - void UnlockRange(void *p, size_t size) + void UnlockRange(void* p, size_t size) { boost::mutex::scoped_lock lock(mutex); - if(!size) return; + if (!size) + return; const size_t base_addr = reinterpret_cast<size_t>(p); const size_t start_page = base_addr & page_mask; const size_t end_page = (base_addr + size - 1) & page_mask; - for(size_t page = start_page; page <= end_page; page += page_size) - { + for (size_t page = start_page; page <= end_page; page += page_size) { Histogram::iterator it = histogram.find(page); assert(it != histogram.end()); // Cannot unlock an area that was not locked // Decrease counter for page, when it is zero, the page will be unlocked it->second -= 1; - if(it->second == 0) // Nothing on the page anymore that keeps it locked + if (it->second == 0) // Nothing on the page anymore that keeps it locked { // Unlock page and remove the count from histogram locker.Unlock(reinterpret_cast<void*>(page), page_size); @@ -101,7 +100,7 @@ private: boost::mutex mutex; size_t page_size, page_mask; // map of page base address to lock count - typedef std::map<size_t,int> Histogram; + typedef std::map<size_t, int> Histogram; Histogram histogram; }; @@ -116,11 +115,11 @@ public: /** Lock memory pages. * addr and len must be a multiple of the system page size */ - bool Lock(const void *addr, size_t len); + bool Lock(const void* addr, size_t len); /** Unlock memory pages. * addr and len must be a multiple of the system page size */ - bool Unlock(const void *addr, size_t len); + bool Unlock(const void* addr, size_t len); }; /** @@ -134,10 +133,10 @@ public: * secure_allocator are created. So instead of having LockedPageManager also be * static-initialized, it is created on demand. */ -class LockedPageManager: public LockedPageManagerBase<MemoryPageLocker> +class LockedPageManager : public LockedPageManagerBase<MemoryPageLocker> { public: - static LockedPageManager& Instance() + static LockedPageManager& Instance() { boost::call_once(LockedPageManager::CreateInstance, LockedPageManager::init_flag); return *LockedPageManager::_instance; @@ -165,11 +164,15 @@ private: // Functions for directly locking/unlocking memory objects. // Intended for non-dynamically allocated structures. // -template<typename T> void LockObject(const T &t) { +template <typename T> +void LockObject(const T& t) +{ LockedPageManager::Instance().LockRange((void*)(&t), sizeof(T)); } -template<typename T> void UnlockObject(const T &t) { +template <typename T> +void UnlockObject(const T& t) +{ OPENSSL_cleanse((void*)(&t), sizeof(T)); LockedPageManager::Instance().UnlockRange((void*)(&t), sizeof(T)); } @@ -178,13 +181,12 @@ template<typename T> void UnlockObject(const T &t) { // Allocator that locks its contents from being paged // out of memory and clears its contents before deletion. // -template<typename T> -struct secure_allocator : public std::allocator<T> -{ +template <typename T> +struct secure_allocator : public std::allocator<T> { // MSVC8 default copy constructor is broken typedef std::allocator<T> base; typedef typename base::size_type size_type; - typedef typename base::difference_type difference_type; + typedef typename base::difference_type difference_type; typedef typename base::pointer pointer; typedef typename base::const_pointer const_pointer; typedef typename base::reference reference; @@ -193,14 +195,18 @@ struct secure_allocator : public std::allocator<T> secure_allocator() throw() {} secure_allocator(const secure_allocator& a) throw() : base(a) {} template <typename U> - secure_allocator(const secure_allocator<U>& a) throw() : base(a) {} + secure_allocator(const secure_allocator<U>& a) throw() : base(a) + { + } ~secure_allocator() throw() {} - template<typename _Other> struct rebind - { typedef secure_allocator<_Other> other; }; + template <typename _Other> + struct rebind { + typedef secure_allocator<_Other> other; + }; - T* allocate(std::size_t n, const void *hint = 0) + T* allocate(std::size_t n, const void* hint = 0) { - T *p; + T* p; p = std::allocator<T>::allocate(n, hint); if (p != NULL) LockedPageManager::Instance().LockRange(p, sizeof(T) * n); @@ -209,8 +215,7 @@ struct secure_allocator : public std::allocator<T> void deallocate(T* p, std::size_t n) { - if (p != NULL) - { + if (p != NULL) { OPENSSL_cleanse(p, sizeof(T) * n); LockedPageManager::Instance().UnlockRange(p, sizeof(T) * n); } @@ -222,13 +227,12 @@ struct secure_allocator : public std::allocator<T> // // Allocator that clears its contents before deletion. // -template<typename T> -struct zero_after_free_allocator : public std::allocator<T> -{ +template <typename T> +struct zero_after_free_allocator : public std::allocator<T> { // MSVC8 default copy constructor is broken typedef std::allocator<T> base; typedef typename base::size_type size_type; - typedef typename base::difference_type difference_type; + typedef typename base::difference_type difference_type; typedef typename base::pointer pointer; typedef typename base::const_pointer const_pointer; typedef typename base::reference reference; @@ -237,10 +241,14 @@ struct zero_after_free_allocator : public std::allocator<T> zero_after_free_allocator() throw() {} zero_after_free_allocator(const zero_after_free_allocator& a) throw() : base(a) {} template <typename U> - zero_after_free_allocator(const zero_after_free_allocator<U>& a) throw() : base(a) {} + zero_after_free_allocator(const zero_after_free_allocator<U>& a) throw() : base(a) + { + } ~zero_after_free_allocator() throw() {} - template<typename _Other> struct rebind - { typedef zero_after_free_allocator<_Other> other; }; + template <typename _Other> + struct rebind { + typedef zero_after_free_allocator<_Other> other; + }; void deallocate(T* p, std::size_t n) { diff --git a/src/base58.cpp b/src/base58.cpp index 76f0404a18..9750f0a161 100644 --- a/src/base58.cpp +++ b/src/base58.cpp @@ -18,7 +18,8 @@ /* All alphanumeric characters except for "0", "I", "O", and "l" */ static const char* pszBase58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; -bool DecodeBase58(const char *psz, std::vector<unsigned char>& vch) { +bool DecodeBase58(const char* psz, std::vector<unsigned char>& vch) +{ // Skip leading spaces. while (*psz && isspace(*psz)) psz++; @@ -33,7 +34,7 @@ bool DecodeBase58(const char *psz, std::vector<unsigned char>& vch) { // Process the characters. while (*psz && !isspace(*psz)) { // Decode base58 character - const char *ch = strchr(pszBase58, *psz); + const char* ch = strchr(pszBase58, *psz); if (ch == NULL) return false; // Apply "b256 = b256 * 58 + ch". @@ -59,11 +60,12 @@ bool DecodeBase58(const char *psz, std::vector<unsigned char>& vch) { vch.reserve(zeroes + (b256.end() - it)); vch.assign(zeroes, 0x00); while (it != b256.end()) - vch.push_back(*(it++)); + vch.push_back(*(it++)); return true; } -std::string EncodeBase58(const unsigned char* pbegin, const unsigned char* pend) { +std::string EncodeBase58(const unsigned char* pbegin, const unsigned char* pend) +{ // Skip & count leading zeroes. int zeroes = 0; while (pbegin != pend && *pbegin == 0) { @@ -97,15 +99,18 @@ std::string EncodeBase58(const unsigned char* pbegin, const unsigned char* pend) return str; } -std::string EncodeBase58(const std::vector<unsigned char>& vch) { +std::string EncodeBase58(const std::vector<unsigned char>& vch) +{ return EncodeBase58(&vch[0], &vch[0] + vch.size()); } -bool DecodeBase58(const std::string& str, std::vector<unsigned char>& vchRet) { +bool DecodeBase58(const std::string& str, std::vector<unsigned char>& vchRet) +{ return DecodeBase58(str.c_str(), vchRet); } -std::string EncodeBase58Check(const std::vector<unsigned char>& vchIn) { +std::string EncodeBase58Check(const std::vector<unsigned char>& vchIn) +{ // add 4-byte hash check to the end std::vector<unsigned char> vch(vchIn); uint256 hash = Hash(vch.begin(), vch.end()); @@ -113,45 +118,49 @@ std::string EncodeBase58Check(const std::vector<unsigned char>& vchIn) { return EncodeBase58(vch); } -bool DecodeBase58Check(const char* psz, std::vector<unsigned char>& vchRet) { +bool DecodeBase58Check(const char* psz, std::vector<unsigned char>& vchRet) +{ if (!DecodeBase58(psz, vchRet) || - (vchRet.size() < 4)) - { + (vchRet.size() < 4)) { vchRet.clear(); return false; } // re-calculate the checksum, insure it matches the included 4-byte checksum - uint256 hash = Hash(vchRet.begin(), vchRet.end()-4); - if (memcmp(&hash, &vchRet.end()[-4], 4) != 0) - { + uint256 hash = Hash(vchRet.begin(), vchRet.end() - 4); + if (memcmp(&hash, &vchRet.end()[-4], 4) != 0) { vchRet.clear(); return false; } - vchRet.resize(vchRet.size()-4); + vchRet.resize(vchRet.size() - 4); return true; } -bool DecodeBase58Check(const std::string& str, std::vector<unsigned char>& vchRet) { +bool DecodeBase58Check(const std::string& str, std::vector<unsigned char>& vchRet) +{ return DecodeBase58Check(str.c_str(), vchRet); } -CBase58Data::CBase58Data() { +CBase58Data::CBase58Data() +{ vchVersion.clear(); vchData.clear(); } -void CBase58Data::SetData(const std::vector<unsigned char> &vchVersionIn, const void* pdata, size_t nSize) { +void CBase58Data::SetData(const std::vector<unsigned char>& vchVersionIn, const void* pdata, size_t nSize) +{ vchVersion = vchVersionIn; vchData.resize(nSize); if (!vchData.empty()) memcpy(&vchData[0], pdata, nSize); } -void CBase58Data::SetData(const std::vector<unsigned char> &vchVersionIn, const unsigned char *pbegin, const unsigned char *pend) { +void CBase58Data::SetData(const std::vector<unsigned char>& vchVersionIn, const unsigned char* pbegin, const unsigned char* pend) +{ SetData(vchVersionIn, (void*)pbegin, pend - pbegin); } -bool CBase58Data::SetString(const char* psz, unsigned int nVersionBytes) { +bool CBase58Data::SetString(const char* psz, unsigned int nVersionBytes) +{ std::vector<unsigned char> vchTemp; bool rc58 = DecodeBase58Check(psz, vchTemp); if ((!rc58) || (vchTemp.size() < nVersionBytes)) { @@ -167,65 +176,80 @@ bool CBase58Data::SetString(const char* psz, unsigned int nVersionBytes) { return true; } -bool CBase58Data::SetString(const std::string& str) { +bool CBase58Data::SetString(const std::string& str) +{ return SetString(str.c_str()); } -std::string CBase58Data::ToString() const { +std::string CBase58Data::ToString() const +{ std::vector<unsigned char> vch = vchVersion; vch.insert(vch.end(), vchData.begin(), vchData.end()); return EncodeBase58Check(vch); } -int CBase58Data::CompareTo(const CBase58Data& b58) const { - if (vchVersion < b58.vchVersion) return -1; - if (vchVersion > b58.vchVersion) return 1; - if (vchData < b58.vchData) return -1; - if (vchData > b58.vchData) return 1; +int CBase58Data::CompareTo(const CBase58Data& b58) const +{ + if (vchVersion < b58.vchVersion) + return -1; + if (vchVersion > b58.vchVersion) + return 1; + if (vchData < b58.vchData) + return -1; + if (vchData > b58.vchData) + return 1; return 0; } -namespace { +namespace +{ +class CBitcoinAddressVisitor : public boost::static_visitor<bool> +{ +private: + CBitcoinAddress* addr; - class CBitcoinAddressVisitor : public boost::static_visitor<bool> { - private: - CBitcoinAddress *addr; - public: - CBitcoinAddressVisitor(CBitcoinAddress *addrIn) : addr(addrIn) { } +public: + CBitcoinAddressVisitor(CBitcoinAddress* addrIn) : addr(addrIn) {} - bool operator()(const CKeyID &id) const { return addr->Set(id); } - bool operator()(const CScriptID &id) const { return addr->Set(id); } - bool operator()(const CNoDestination &no) const { return false; } - }; + bool operator()(const CKeyID& id) const { return addr->Set(id); } + bool operator()(const CScriptID& id) const { return addr->Set(id); } + bool operator()(const CNoDestination& no) const { return false; } +}; } // anon namespace -bool CBitcoinAddress::Set(const CKeyID &id) { +bool CBitcoinAddress::Set(const CKeyID& id) +{ SetData(Params().Base58Prefix(CChainParams::PUBKEY_ADDRESS), &id, 20); return true; } -bool CBitcoinAddress::Set(const CScriptID &id) { +bool CBitcoinAddress::Set(const CScriptID& id) +{ SetData(Params().Base58Prefix(CChainParams::SCRIPT_ADDRESS), &id, 20); return true; } -bool CBitcoinAddress::Set(const CTxDestination &dest) { +bool CBitcoinAddress::Set(const CTxDestination& dest) +{ return boost::apply_visitor(CBitcoinAddressVisitor(this), dest); } -bool CBitcoinAddress::IsValid() const { +bool CBitcoinAddress::IsValid() const +{ return IsValid(Params()); } -bool CBitcoinAddress::IsValid(const CChainParams ¶ms) const { +bool CBitcoinAddress::IsValid(const CChainParams& params) const +{ bool fCorrectSize = vchData.size() == 20; bool fKnownVersion = vchVersion == params.Base58Prefix(CChainParams::PUBKEY_ADDRESS) || vchVersion == params.Base58Prefix(CChainParams::SCRIPT_ADDRESS); return fCorrectSize && fKnownVersion; } -CTxDestination CBitcoinAddress::Get() const { +CTxDestination CBitcoinAddress::Get() const +{ if (!IsValid()) return CNoDestination(); uint160 id; @@ -238,7 +262,8 @@ CTxDestination CBitcoinAddress::Get() const { return CNoDestination(); } -bool CBitcoinAddress::GetKeyID(CKeyID &keyID) const { +bool CBitcoinAddress::GetKeyID(CKeyID& keyID) const +{ if (!IsValid() || vchVersion != Params().Base58Prefix(CChainParams::PUBKEY_ADDRESS)) return false; uint160 id; @@ -247,33 +272,39 @@ bool CBitcoinAddress::GetKeyID(CKeyID &keyID) const { return true; } -bool CBitcoinAddress::IsScript() const { +bool CBitcoinAddress::IsScript() const +{ return IsValid() && vchVersion == Params().Base58Prefix(CChainParams::SCRIPT_ADDRESS); } -void CBitcoinSecret::SetKey(const CKey& vchSecret) { +void CBitcoinSecret::SetKey(const CKey& vchSecret) +{ assert(vchSecret.IsValid()); SetData(Params().Base58Prefix(CChainParams::SECRET_KEY), vchSecret.begin(), vchSecret.size()); if (vchSecret.IsCompressed()) vchData.push_back(1); } -CKey CBitcoinSecret::GetKey() { +CKey CBitcoinSecret::GetKey() +{ CKey ret; ret.Set(&vchData[0], &vchData[32], vchData.size() > 32 && vchData[32] == 1); return ret; } -bool CBitcoinSecret::IsValid() const { +bool CBitcoinSecret::IsValid() const +{ bool fExpectedFormat = vchData.size() == 32 || (vchData.size() == 33 && vchData[32] == 1); bool fCorrectVersion = vchVersion == Params().Base58Prefix(CChainParams::SECRET_KEY); return fExpectedFormat && fCorrectVersion; } -bool CBitcoinSecret::SetString(const char* pszSecret) { +bool CBitcoinSecret::SetString(const char* pszSecret) +{ return CBase58Data::SetString(pszSecret) && IsValid(); } -bool CBitcoinSecret::SetString(const std::string& strSecret) { +bool CBitcoinSecret::SetString(const std::string& strSecret) +{ return SetString(strSecret.c_str()); } diff --git a/src/base58.h b/src/base58.h index 15bf710f5e..c5e230c72e 100644 --- a/src/base58.h +++ b/src/base58.h @@ -17,6 +17,7 @@ #include "chainparams.h" #include "key.h" #include "script/script.h" +#include "script/standard.h" #include <string> #include <vector> diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp index 354d6ba41d..b6e7a6c540 100644 --- a/src/bitcoin-tx.cpp +++ b/src/bitcoin-tx.cpp @@ -224,9 +224,8 @@ static void MutateTxAddOutAddr(CMutableTransaction& tx, const string& strInput) if (!addr.IsValid()) throw runtime_error("invalid TX output address"); - // build standard output script via SetDestination() - CScript scriptPubKey; - scriptPubKey.SetDestination(addr.Get()); + // build standard output script via GetScriptForDestination() + CScript scriptPubKey = GetScriptForDestination(addr.Get()); // construct TxOut, append to transaction output list CTxOut txout(value, scriptPubKey); @@ -436,7 +435,7 @@ static void MutateTxSign(CMutableTransaction& tx, const string& flagStr) BOOST_FOREACH(const CTransaction& txv, txVariants) { txin.scriptSig = CombineSignatures(prevPubKey, mergedTx, i, txin.scriptSig, txv.vin[i].scriptSig); } - if (!VerifyScript(txin.scriptSig, prevPubKey, mergedTx, i, STANDARD_SCRIPT_VERIFY_FLAGS, 0)) + if (!VerifyScript(txin.scriptSig, prevPubKey, mergedTx, i, STANDARD_SCRIPT_VERIFY_FLAGS)) fComplete = false; } diff --git a/src/bitcoind.cpp b/src/bitcoind.cpp index 5be8708979..0737b5a83d 100644 --- a/src/bitcoind.cpp +++ b/src/bitcoind.cpp @@ -129,7 +129,6 @@ bool AppInit(int argc, char* argv[]) } if (pid > 0) // Parent process, pid is child process id { - CreatePidFile(GetPidFile(), pid); return true; } // Child process falls through to rest of initialization diff --git a/src/chainparamsbase.cpp b/src/chainparamsbase.cpp index d1e19871c3..98bb5b855f 100644 --- a/src/chainparamsbase.cpp +++ b/src/chainparamsbase.cpp @@ -17,9 +17,11 @@ using namespace boost::assign; // Main network // -class CBaseMainParams : public CBaseChainParams { +class CBaseMainParams : public CBaseChainParams +{ public: - CBaseMainParams() { + CBaseMainParams() + { networkID = CBaseChainParams::MAIN; nRPCPort = 8332; } @@ -29,9 +31,11 @@ static CBaseMainParams mainParams; // // Testnet (v3) // -class CBaseTestNetParams : public CBaseMainParams { +class CBaseTestNetParams : public CBaseMainParams +{ public: - CBaseTestNetParams() { + CBaseTestNetParams() + { networkID = CBaseChainParams::TESTNET; nRPCPort = 18332; strDataDir = "testnet3"; @@ -42,40 +46,45 @@ static CBaseTestNetParams testNetParams; // // Regression test // -class CBaseRegTestParams : public CBaseTestNetParams { +class CBaseRegTestParams : public CBaseTestNetParams +{ public: - CBaseRegTestParams() { + CBaseRegTestParams() + { networkID = CBaseChainParams::REGTEST; strDataDir = "regtest"; } }; static CBaseRegTestParams regTestParams; -static CBaseChainParams *pCurrentBaseParams = 0; +static CBaseChainParams* pCurrentBaseParams = 0; -const CBaseChainParams &BaseParams() { +const CBaseChainParams& BaseParams() +{ assert(pCurrentBaseParams); return *pCurrentBaseParams; } -void SelectBaseParams(CBaseChainParams::Network network) { +void SelectBaseParams(CBaseChainParams::Network network) +{ switch (network) { - case CBaseChainParams::MAIN: - pCurrentBaseParams = &mainParams; - break; - case CBaseChainParams::TESTNET: - pCurrentBaseParams = &testNetParams; - break; - case CBaseChainParams::REGTEST: - pCurrentBaseParams = ®TestParams; - break; - default: - assert(false && "Unimplemented network"); - return; + case CBaseChainParams::MAIN: + pCurrentBaseParams = &mainParams; + break; + case CBaseChainParams::TESTNET: + pCurrentBaseParams = &testNetParams; + break; + case CBaseChainParams::REGTEST: + pCurrentBaseParams = ®TestParams; + break; + default: + assert(false && "Unimplemented network"); + return; } } -bool SelectBaseParamsFromCommandLine() { +bool SelectBaseParamsFromCommandLine() +{ bool fRegTest = GetBoolArg("-regtest", false); bool fTestNet = GetBoolArg("-testnet", false); @@ -93,6 +102,7 @@ bool SelectBaseParamsFromCommandLine() { return true; } -bool AreBaseParamsConfigured() { +bool AreBaseParamsConfigured() +{ return pCurrentBaseParams != NULL; } diff --git a/src/chainparamsbase.h b/src/chainparamsbase.h index 743c8c541a..c054f03f17 100644 --- a/src/chainparamsbase.h +++ b/src/chainparamsbase.h @@ -26,6 +26,7 @@ public: const std::string& DataDir() const { return strDataDir; } int RPCPort() const { return nRPCPort; } Network NetworkID() const { return networkID; } + protected: CBaseChainParams() {} @@ -38,7 +39,7 @@ protected: * Return the currently selected parameters. This won't change after app startup * outside of the unit tests. */ -const CBaseChainParams &BaseParams(); +const CBaseChainParams& BaseParams(); /** Sets the params returned by Params() to those for the given network. */ void SelectBaseParams(CBaseChainParams::Network network); diff --git a/src/checkpoints.h b/src/checkpoints.h index 6d3f2d4935..fca046559a 100644 --- a/src/checkpoints.h +++ b/src/checkpoints.h @@ -13,20 +13,20 @@ class uint256; /** Block-chain checkpoints are compiled-in sanity checks. * They are updated every release or three. */ -namespace Checkpoints { +namespace Checkpoints +{ +// Returns true if block passes checkpoint checks +bool CheckBlock(int nHeight, const uint256& hash); - // Returns true if block passes checkpoint checks - bool CheckBlock(int nHeight, const uint256& hash); +// Return conservative estimate of total number of blocks, 0 if unknown +int GetTotalBlocksEstimate(); - // Return conservative estimate of total number of blocks, 0 if unknown - int GetTotalBlocksEstimate(); +// Returns last CBlockIndex* in mapBlockIndex that is a checkpoint +CBlockIndex* GetLastCheckpoint(); - // Returns last CBlockIndex* in mapBlockIndex that is a checkpoint - CBlockIndex* GetLastCheckpoint(); +double GuessVerificationProgress(CBlockIndex* pindex, bool fSigchecks = true); - double GuessVerificationProgress(CBlockIndex *pindex, bool fSigchecks = true); - - extern bool fEnabled; +extern bool fEnabled; } //namespace Checkpoints diff --git a/src/checkqueue.h b/src/checkqueue.h index c2c7d8ca24..b2a713e646 100644 --- a/src/checkqueue.h +++ b/src/checkqueue.h @@ -13,7 +13,8 @@ #include <boost/thread/locks.hpp> #include <boost/thread/mutex.hpp> -template<typename T> class CCheckQueueControl; +template <typename T> +class CCheckQueueControl; /** Queue for verifications that have to be performed. * The verifications are represented by a type T, which must provide an @@ -24,7 +25,9 @@ template<typename T> class CCheckQueueControl; * the master is done adding work, it temporarily joins the worker pool * as an N'th worker, until all jobs are done. */ -template<typename T> class CCheckQueue { +template <typename T> +class CCheckQueue +{ private: // Mutex to protect the inner state boost::mutex mutex; @@ -60,8 +63,9 @@ private: unsigned int nBatchSize; // Internal function that does bulk of the verification work. - bool Loop(bool fMaster = false) { - boost::condition_variable &cond = fMaster ? condMaster : condWorker; + bool Loop(bool fMaster = false) + { + boost::condition_variable& cond = fMaster ? condMaster : condWorker; std::vector<T> vChecks; vChecks.reserve(nBatchSize); unsigned int nNow = 0; @@ -103,41 +107,43 @@ private: nNow = std::max(1U, std::min(nBatchSize, (unsigned int)queue.size() / (nTotal + nIdle + 1))); vChecks.resize(nNow); for (unsigned int i = 0; i < nNow; i++) { - // We want the lock on the mutex to be as short as possible, so swap jobs from the global - // queue to the local batch vector instead of copying. - vChecks[i].swap(queue.back()); - queue.pop_back(); + // We want the lock on the mutex to be as short as possible, so swap jobs from the global + // queue to the local batch vector instead of copying. + vChecks[i].swap(queue.back()); + queue.pop_back(); } // Check whether we need to do work at all fOk = fAllOk; } // execute work - BOOST_FOREACH(T &check, vChecks) + BOOST_FOREACH (T& check, vChecks) if (fOk) fOk = check(); vChecks.clear(); - } while(true); + } while (true); } public: // Create a new check queue - CCheckQueue(unsigned int nBatchSizeIn) : - nIdle(0), nTotal(0), fAllOk(true), nTodo(0), fQuit(false), nBatchSize(nBatchSizeIn) {} + CCheckQueue(unsigned int nBatchSizeIn) : nIdle(0), nTotal(0), fAllOk(true), nTodo(0), fQuit(false), nBatchSize(nBatchSizeIn) {} // Worker thread - void Thread() { + void Thread() + { Loop(); } // Wait until execution finishes, and return whether all evaluations where succesful. - bool Wait() { + bool Wait() + { return Loop(true); } // Add a batch of checks to the queue - void Add(std::vector<T> &vChecks) { + void Add(std::vector<T>& vChecks) + { boost::unique_lock<boost::mutex> lock(mutex); - BOOST_FOREACH(T &check, vChecks) { + BOOST_FOREACH (T& check, vChecks) { queue.push_back(T()); check.swap(queue.back()); } @@ -148,7 +154,8 @@ public: condWorker.notify_all(); } - ~CCheckQueue() { + ~CCheckQueue() + { } friend class CCheckQueueControl<T>; @@ -157,13 +164,16 @@ public: /** RAII-style controller object for a CCheckQueue that guarantees the passed * queue is finished before continuing. */ -template<typename T> class CCheckQueueControl { +template <typename T> +class CCheckQueueControl +{ private: - CCheckQueue<T> *pqueue; + CCheckQueue<T>* pqueue; bool fDone; public: - CCheckQueueControl(CCheckQueue<T> *pqueueIn) : pqueue(pqueueIn), fDone(false) { + CCheckQueueControl(CCheckQueue<T>* pqueueIn) : pqueue(pqueueIn), fDone(false) + { // passed queue is supposed to be unused, or NULL if (pqueue != NULL) { assert(pqueue->nTotal == pqueue->nIdle); @@ -172,7 +182,8 @@ public: } } - bool Wait() { + bool Wait() + { if (pqueue == NULL) return true; bool fRet = pqueue->Wait(); @@ -180,12 +191,14 @@ public: return fRet; } - void Add(std::vector<T> &vChecks) { + void Add(std::vector<T>& vChecks) + { if (pqueue != NULL) pqueue->Add(vChecks); } - ~CCheckQueueControl() { + ~CCheckQueueControl() + { if (!fDone) Wait(); } diff --git a/src/clientversion.h b/src/clientversion.h index 5634516ca4..cd7ceb78f0 100644 --- a/src/clientversion.h +++ b/src/clientversion.h @@ -13,13 +13,13 @@ // // These need to be macros, as version.cpp's and bitcoin*-res.rc's voodoo requires it -#define CLIENT_VERSION_MAJOR 0 -#define CLIENT_VERSION_MINOR 9 -#define CLIENT_VERSION_REVISION 99 -#define CLIENT_VERSION_BUILD 0 +#define CLIENT_VERSION_MAJOR 0 +#define CLIENT_VERSION_MINOR 9 +#define CLIENT_VERSION_REVISION 99 +#define CLIENT_VERSION_BUILD 0 // Set to true for release, false for prerelease or test build -#define CLIENT_VERSION_IS_RELEASE false +#define CLIENT_VERSION_IS_RELEASE false // Copyright year (2009-this) // Todo: update this when changing our copyright comments in the source @@ -33,6 +33,6 @@ #define DO_STRINGIZE(X) #X // Copyright string used in Windows .rc files -#define COPYRIGHT_STR "2009-" STRINGIZE(COPYRIGHT_YEAR) " The Bitcoin Core Developers" +#define COPYRIGHT_STR "2009-" STRINGIZE(COPYRIGHT_YEAR) " The Bitcoin Core Developers" #endif // CLIENTVERSION_H diff --git a/src/coincontrol.h b/src/coincontrol.h index 97c30c2713..033092c019 100644 --- a/src/coincontrol.h +++ b/src/coincontrol.h @@ -57,7 +57,6 @@ public: private: std::set<COutPoint> setSelected; - }; #endif // COINCONTROL_H diff --git a/src/core.cpp b/src/core.cpp index 491e4fa68b..e52327ba8e 100644 --- a/src/core.cpp +++ b/src/core.cpp @@ -226,6 +226,13 @@ uint256 CBlockHeader::GetHash() const uint256 CBlock::BuildMerkleTree() const { + // WARNING! If you're reading this because you're learning about crypto + // and/or designing a new system that will use merkle trees, keep in mind + // that the following merkle tree algorithm has a serious flaw related to + // duplicate txids, resulting in a vulnerability. (CVE-2012-2459) Bitcoin + // has since worked around the flaw, but for new applications you should + // use something different; don't just copy-and-paste this code without + // understanding the problem first. vMerkleTree.clear(); BOOST_FOREACH(const CTransaction& tx, vtx) vMerkleTree.push_back(tx.GetHash()); diff --git a/src/db.cpp b/src/db.cpp index edbff6fd49..12650e459f 100644 --- a/src/db.cpp +++ b/src/db.cpp @@ -30,7 +30,6 @@ using namespace boost; unsigned int nWalletDBUpdated; - // // CDB // @@ -94,15 +93,15 @@ bool CDBEnv::Open(const boost::filesystem::path& pathIn) dbenv.set_flags(DB_TXN_WRITE_NOSYNC, 1); dbenv.log_set_config(DB_LOG_AUTO_REMOVE, 1); int ret = dbenv.open(path.string().c_str(), - DB_CREATE | - DB_INIT_LOCK | - DB_INIT_LOG | - DB_INIT_MPOOL | - DB_INIT_TXN | - DB_THREAD | - DB_RECOVER | - nEnvFlags, - S_IRUSR | S_IWUSR); + DB_CREATE | + DB_INIT_LOCK | + DB_INIT_LOG | + DB_INIT_MPOOL | + DB_INIT_TXN | + DB_THREAD | + DB_RECOVER | + nEnvFlags, + S_IRUSR | S_IWUSR); if (ret != 0) return error("CDBEnv::Open : Error %d opening database environment: %s\n", ret, DbEnv::strerror(ret)); @@ -121,21 +120,21 @@ void CDBEnv::MakeMock() LogPrint("db", "CDBEnv::MakeMock\n"); dbenv.set_cachesize(1, 0, 1); - dbenv.set_lg_bsize(10485760*4); + dbenv.set_lg_bsize(10485760 * 4); dbenv.set_lg_max(10485760); dbenv.set_lk_max_locks(10000); dbenv.set_lk_max_objects(10000); dbenv.set_flags(DB_AUTO_COMMIT, 1); dbenv.log_set_config(DB_LOG_IN_MEMORY, 1); int ret = dbenv.open(NULL, - DB_CREATE | - DB_INIT_LOCK | - DB_INIT_LOG | - DB_INIT_MPOOL | - DB_INIT_TXN | - DB_THREAD | - DB_PRIVATE, - S_IRUSR | S_IWUSR); + DB_CREATE | + DB_INIT_LOCK | + DB_INIT_LOG | + DB_INIT_MPOOL | + DB_INIT_TXN | + DB_THREAD | + DB_PRIVATE, + S_IRUSR | S_IWUSR); if (ret > 0) throw runtime_error(strprintf("CDBEnv::MakeMock : Error %d opening database environment.", ret)); @@ -160,30 +159,27 @@ CDBEnv::VerifyResult CDBEnv::Verify(std::string strFile, bool (*recoverFunc)(CDB return (fRecovered ? RECOVER_OK : RECOVER_FAIL); } -bool CDBEnv::Salvage(std::string strFile, bool fAggressive, - std::vector<CDBEnv::KeyValPair >& vResult) +bool CDBEnv::Salvage(std::string strFile, bool fAggressive, std::vector<CDBEnv::KeyValPair>& vResult) { LOCK(cs_db); assert(mapFileUseCount.count(strFile) == 0); u_int32_t flags = DB_SALVAGE; - if (fAggressive) flags |= DB_AGGRESSIVE; + if (fAggressive) + flags |= DB_AGGRESSIVE; stringstream strDump; Db db(&dbenv, 0); int result = db.verify(strFile.c_str(), NULL, &strDump, flags); - if (result == DB_VERIFY_BAD) - { + if (result == DB_VERIFY_BAD) { LogPrintf("CDBEnv::Salvage : Database salvage found errors, all data may not be recoverable.\n"); - if (!fAggressive) - { + if (!fAggressive) { LogPrintf("CDBEnv::Salvage : Rerun with aggressive mode to ignore errors and continue.\n"); return false; } } - if (result != 0 && result != DB_VERIFY_BAD) - { + if (result != 0 && result != DB_VERIFY_BAD) { LogPrintf("CDBEnv::Salvage : Database salvage failed with result %d.\n", result); return false; } @@ -201,13 +197,11 @@ bool CDBEnv::Salvage(std::string strFile, bool fAggressive, getline(strDump, strLine); // Skip past header std::string keyHex, valueHex; - while (!strDump.eof() && keyHex != "DATA=END") - { + while (!strDump.eof() && keyHex != "DATA=END") { getline(strDump, keyHex); - if (keyHex != "DATA_END") - { + if (keyHex != "DATA_END") { getline(strDump, valueHex); - vResult.push_back(make_pair(ParseHex(keyHex),ParseHex(valueHex))); + vResult.push_back(make_pair(ParseHex(keyHex), ParseHex(valueHex))); } } @@ -215,7 +209,7 @@ bool CDBEnv::Salvage(std::string strFile, bool fAggressive, } -void CDBEnv::CheckpointLSN(std::string strFile) +void CDBEnv::CheckpointLSN(const std::string& strFile) { dbenv.txn_checkpoint(0, 0, 0); if (fMockDb) @@ -224,12 +218,11 @@ void CDBEnv::CheckpointLSN(std::string strFile) } -CDB::CDB(const char *pszFile, const char* pszMode) : - pdb(NULL), activeTxn(NULL) +CDB::CDB(const std::string& strFilename, const char* pszMode) : pdb(NULL), activeTxn(NULL) { int ret; fReadOnly = (!strchr(pszMode, '+') && !strchr(pszMode, 'w')); - if (pszFile == NULL) + if (strFilename.empty()) return; bool fCreate = strchr(pszMode, 'c') != NULL; @@ -242,40 +235,36 @@ CDB::CDB(const char *pszFile, const char* pszMode) : if (!bitdb.Open(GetDataDir())) throw runtime_error("CDB : Failed to open database environment."); - strFile = pszFile; + strFile = strFilename; ++bitdb.mapFileUseCount[strFile]; pdb = bitdb.mapDb[strFile]; - if (pdb == NULL) - { + if (pdb == NULL) { pdb = new Db(&bitdb.dbenv, 0); bool fMockDb = bitdb.IsMock(); - if (fMockDb) - { - DbMpoolFile*mpf = pdb->get_mpf(); + if (fMockDb) { + DbMpoolFile* mpf = pdb->get_mpf(); ret = mpf->set_flags(DB_MPOOL_NOFILE, 1); if (ret != 0) - throw runtime_error(strprintf("CDB : Failed to configure for no temp file backing for database %s", pszFile)); + throw runtime_error(strprintf("CDB : Failed to configure for no temp file backing for database %s", strFile)); } - ret = pdb->open(NULL, // Txn pointer - fMockDb ? NULL : pszFile, // Filename - fMockDb ? pszFile : "main", // Logical db name - DB_BTREE, // Database type - nFlags, // Flags + ret = pdb->open(NULL, // Txn pointer + fMockDb ? NULL : strFile.c_str(), // Filename + fMockDb ? strFile.c_str() : "main", // Logical db name + DB_BTREE, // Database type + nFlags, // Flags 0); - if (ret != 0) - { + if (ret != 0) { delete pdb; pdb = NULL; --bitdb.mapFileUseCount[strFile]; strFile = ""; - throw runtime_error(strprintf("CDB : Error %d, can't open database %s", ret, pszFile)); + throw runtime_error(strprintf("CDB : Error %d, can't open database %s", ret, strFile)); } - if (fCreate && !Exists(string("version"))) - { + if (fCreate && !Exists(string("version"))) { bool fTmp = fReadOnly; fReadOnly = false; WriteVersion(CLIENT_VERSION); @@ -297,7 +286,7 @@ void CDB::Flush() if (fReadOnly) nMinutes = 1; - bitdb.dbenv.txn_checkpoint(nMinutes ? GetArg("-dblogsize", 100)*1024 : 0, nMinutes, 0); + bitdb.dbenv.txn_checkpoint(nMinutes ? GetArg("-dblogsize", 100) * 1024 : 0, nMinutes, 0); } void CDB::Close() @@ -321,8 +310,7 @@ void CDBEnv::CloseDb(const string& strFile) { { LOCK(cs_db); - if (mapDb[strFile] != NULL) - { + if (mapDb[strFile] != NULL) { // Close the database handle Db* pdb = mapDb[strFile]; pdb->close(0); @@ -343,12 +331,10 @@ bool CDBEnv::RemoveDb(const string& strFile) bool CDB::Rewrite(const string& strFile, const char* pszSkip) { - while (true) - { + while (true) { { LOCK(bitdb.cs_db); - if (!bitdb.mapFileUseCount.count(strFile) || bitdb.mapFileUseCount[strFile] == 0) - { + if (!bitdb.mapFileUseCount.count(strFile) || bitdb.mapFileUseCount[strFile] == 0) { // Flush log data to the dat file bitdb.CloseDb(strFile); bitdb.CheckpointLSN(strFile); @@ -361,32 +347,27 @@ bool CDB::Rewrite(const string& strFile, const char* pszSkip) CDB db(strFile.c_str(), "r"); Db* pdbCopy = new Db(&bitdb.dbenv, 0); - int ret = pdbCopy->open(NULL, // Txn pointer - strFileRes.c_str(), // Filename - "main", // Logical db name - DB_BTREE, // Database type - DB_CREATE, // Flags + int ret = pdbCopy->open(NULL, // Txn pointer + strFileRes.c_str(), // Filename + "main", // Logical db name + DB_BTREE, // Database type + DB_CREATE, // Flags 0); - if (ret > 0) - { + if (ret > 0) { LogPrintf("CDB::Rewrite : Can't create database file %s\n", strFileRes); fSuccess = false; } Dbc* pcursor = db.GetCursor(); if (pcursor) - while (fSuccess) - { + while (fSuccess) { CDataStream ssKey(SER_DISK, CLIENT_VERSION); CDataStream ssValue(SER_DISK, CLIENT_VERSION); int ret = db.ReadAtCursor(pcursor, ssKey, ssValue, DB_NEXT); - if (ret == DB_NOTFOUND) - { + if (ret == DB_NOTFOUND) { pcursor->close(); break; - } - else if (ret != 0) - { + } else if (ret != 0) { pcursor->close(); fSuccess = false; break; @@ -394,8 +375,7 @@ bool CDB::Rewrite(const string& strFile, const char* pszSkip) if (pszSkip && strncmp(&ssKey[0], pszSkip, std::min(ssKey.size(), strlen(pszSkip))) == 0) continue; - if (strncmp(&ssKey[0], "\x07version", 8) == 0) - { + if (strncmp(&ssKey[0], "\x07version", 8) == 0) { // Update version: ssValue.clear(); ssValue << CLIENT_VERSION; @@ -406,8 +386,7 @@ bool CDB::Rewrite(const string& strFile, const char* pszSkip) if (ret2 > 0) fSuccess = false; } - if (fSuccess) - { + if (fSuccess) { db.Close(); bitdb.CloseDb(strFile); if (pdbCopy->close(0)) @@ -415,8 +394,7 @@ bool CDB::Rewrite(const string& strFile, const char* pszSkip) delete pdbCopy; } } - if (fSuccess) - { + if (fSuccess) { Db dbA(&bitdb.dbenv, 0); if (dbA.remove(strFile.c_str(), NULL, 0)) fSuccess = false; @@ -445,13 +423,11 @@ void CDBEnv::Flush(bool fShutdown) { LOCK(cs_db); map<string, int>::iterator mi = mapFileUseCount.begin(); - while (mi != mapFileUseCount.end()) - { + while (mi != mapFileUseCount.end()) { string strFile = (*mi).first; int nRefCount = (*mi).second; LogPrint("db", "CDBEnv::Flush : Flushing %s (refcount = %d)...\n", strFile, nRefCount); - if (nRefCount == 0) - { + if (nRefCount == 0) { // Move log data to the dat file CloseDb(strFile); LogPrint("db", "CDBEnv::Flush : %s checkpoint\n", strFile); @@ -461,16 +437,13 @@ void CDBEnv::Flush(bool fShutdown) dbenv.lsn_reset(strFile.c_str(), 0); LogPrint("db", "CDBEnv::Flush : %s closed\n", strFile); mapFileUseCount.erase(mi++); - } - else + } else mi++; } LogPrint("db", "CDBEnv::Flush : Flush(%s)%s took %15dms\n", fShutdown ? "true" : "false", fDbEnvInit ? "" : " database not started", GetTimeMillis() - nStart); - if (fShutdown) - { + if (fShutdown) { char** listp; - if (mapFileUseCount.empty()) - { + if (mapFileUseCount.empty()) { dbenv.log_archive(&listp, DB_ARCH_REMOVE); Close(); if (!fMockDb) @@ -479,4 +452,3 @@ void CDBEnv::Flush(bool fShutdown) } } } - @@ -54,7 +54,9 @@ public: * This must be called BEFORE strFile is opened. * Returns true if strFile is OK. */ - enum VerifyResult { VERIFY_OK, RECOVER_OK, RECOVER_FAIL }; + enum VerifyResult { VERIFY_OK, + RECOVER_OK, + RECOVER_FAIL }; VerifyResult Verify(std::string strFile, bool (*recoverFunc)(CDBEnv& dbenv, std::string strFile)); /* * Salvage data from a file that Verify says is bad. @@ -66,15 +68,15 @@ public: typedef std::pair<std::vector<unsigned char>, std::vector<unsigned char> > KeyValPair; bool Salvage(std::string strFile, bool fAggressive, std::vector<KeyValPair>& vResult); - bool Open(const boost::filesystem::path &path); + bool Open(const boost::filesystem::path& path); void Close(); void Flush(bool fShutdown); - void CheckpointLSN(std::string strFile); + void CheckpointLSN(const std::string& strFile); void CloseDb(const std::string& strFile); bool RemoveDb(const std::string& strFile); - DbTxn *TxnBegin(int flags=DB_TXN_WRITE_NOSYNC) + DbTxn* TxnBegin(int flags = DB_TXN_WRITE_NOSYNC) { DbTxn* ptxn = NULL; int ret = dbenv.txn_begin(NULL, &ptxn, flags); @@ -93,20 +95,22 @@ class CDB protected: Db* pdb; std::string strFile; - DbTxn *activeTxn; + DbTxn* activeTxn; bool fReadOnly; - explicit CDB(const char* pszFile, const char* pszMode="r+"); + explicit CDB(const std::string& strFilename, const char* pszMode = "r+"); ~CDB() { Close(); } + public: void Flush(); void Close(); + private: CDB(const CDB&); void operator=(const CDB&); protected: - template<typename K, typename T> + template <typename K, typename T> bool Read(const K& key, T& value) { if (!pdb) @@ -130,8 +134,7 @@ protected: try { CDataStream ssValue((char*)datValue.get_data(), (char*)datValue.get_data() + datValue.get_size(), SER_DISK, CLIENT_VERSION); ssValue >> value; - } - catch (const std::exception &) { + } catch (const std::exception&) { return false; } @@ -141,8 +144,8 @@ protected: return (ret == 0); } - template<typename K, typename T> - bool Write(const K& key, const T& value, bool fOverwrite=true) + template <typename K, typename T> + bool Write(const K& key, const T& value, bool fOverwrite = true) { if (!pdb) return false; @@ -170,7 +173,7 @@ protected: return (ret == 0); } - template<typename K> + template <typename K> bool Erase(const K& key) { if (!pdb) @@ -192,7 +195,7 @@ protected: return (ret == 0 || ret == DB_NOTFOUND); } - template<typename K> + template <typename K> bool Exists(const K& key) { if (!pdb) @@ -223,18 +226,16 @@ protected: return pcursor; } - int ReadAtCursor(Dbc* pcursor, CDataStream& ssKey, CDataStream& ssValue, unsigned int fFlags=DB_NEXT) + int ReadAtCursor(Dbc* pcursor, CDataStream& ssKey, CDataStream& ssValue, unsigned int fFlags = DB_NEXT) { // Read at cursor Dbt datKey; - if (fFlags == DB_SET || fFlags == DB_SET_RANGE || fFlags == DB_GET_BOTH || fFlags == DB_GET_BOTH_RANGE) - { + if (fFlags == DB_SET || fFlags == DB_SET_RANGE || fFlags == DB_GET_BOTH || fFlags == DB_GET_BOTH_RANGE) { datKey.set_data(&ssKey[0]); datKey.set_size(ssKey.size()); } Dbt datValue; - if (fFlags == DB_GET_BOTH || fFlags == DB_GET_BOTH_RANGE) - { + if (fFlags == DB_GET_BOTH || fFlags == DB_GET_BOTH_RANGE) { datValue.set_data(&ssValue[0]); datValue.set_size(ssValue.size()); } diff --git a/src/hash.cpp b/src/hash.cpp index bddd8abf38..4ce4da4c30 100644 --- a/src/hash.cpp +++ b/src/hash.cpp @@ -1,6 +1,6 @@ #include "hash.h" -inline uint32_t ROTL32 ( uint32_t x, int8_t r ) +inline uint32_t ROTL32(uint32_t x, int8_t r) { return (x << r) | (x >> (32 - r)); } @@ -16,33 +16,37 @@ unsigned int MurmurHash3(unsigned int nHashSeed, const std::vector<unsigned char //---------- // body - const uint32_t * blocks = (const uint32_t *)(&vDataToHash[0] + nblocks*4); + const uint32_t* blocks = (const uint32_t*)(&vDataToHash[0] + nblocks * 4); - for(int i = -nblocks; i; i++) - { + for (int i = -nblocks; i; i++) { uint32_t k1 = blocks[i]; k1 *= c1; - k1 = ROTL32(k1,15); + k1 = ROTL32(k1, 15); k1 *= c2; h1 ^= k1; - h1 = ROTL32(h1,13); - h1 = h1*5+0xe6546b64; + h1 = ROTL32(h1, 13); + h1 = h1 * 5 + 0xe6546b64; } //---------- // tail - const uint8_t * tail = (const uint8_t*)(&vDataToHash[0] + nblocks*4); + const uint8_t* tail = (const uint8_t*)(&vDataToHash[0] + nblocks * 4); uint32_t k1 = 0; - switch(vDataToHash.size() & 3) - { - case 3: k1 ^= tail[2] << 16; - case 2: k1 ^= tail[1] << 8; - case 1: k1 ^= tail[0]; - k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1; + switch (vDataToHash.size() & 3) { + case 3: + k1 ^= tail[2] << 16; + case 2: + k1 ^= tail[1] << 8; + case 1: + k1 ^= tail[0]; + k1 *= c1; + k1 = ROTL32(k1, 15); + k1 *= c2; + h1 ^= k1; }; //---------- diff --git a/src/init.cpp b/src/init.cpp index 67f53e044c..7299bd0f4a 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -160,7 +160,9 @@ void Shutdown() if (pwalletMain) bitdb.Flush(true); #endif +#ifndef WIN32 boost::filesystem::remove(GetPidFile()); +#endif UnregisterAllWallets(); #ifdef ENABLE_WALLET if (pwalletMain) @@ -228,7 +230,9 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += " -maxorphanblocks=<n> " + strprintf(_("Keep at most <n> unconnectable blocks in memory (default: %u)"), DEFAULT_MAX_ORPHAN_BLOCKS) + "\n"; strUsage += " -maxorphantx=<n> " + strprintf(_("Keep at most <n> unconnectable transactions in memory (default: %u)"), DEFAULT_MAX_ORPHAN_TRANSACTIONS) + "\n"; strUsage += " -par=<n> " + strprintf(_("Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)"), -(int)boost::thread::hardware_concurrency(), MAX_SCRIPTCHECK_THREADS, DEFAULT_SCRIPTCHECK_THREADS) + "\n"; +#ifndef WIN32 strUsage += " -pid=<file> " + _("Specify pid file (default: bitcoind.pid)") + "\n"; +#endif strUsage += " -reindex " + _("Rebuild block chain index from current blk000??.dat files") + " " + _("on startup") + "\n"; #if !defined(WIN32) strUsage += " -sysperms " + _("Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)") + "\n"; @@ -714,7 +718,9 @@ bool AppInit2(boost::thread_group& threadGroup) static boost::interprocess::file_lock lock(pathLockFile.string().c_str()); if (!lock.try_lock()) return InitError(strprintf(_("Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running."), strDataDir)); - +#ifndef WIN32 + CreatePidFile(GetPidFile(), getpid()); +#endif if (GetBoolArg("-shrinkdebugfile", !fDebug)) ShrinkDebugFile(); LogPrintf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"); diff --git a/src/init.h b/src/init.h index cf1d1e7e39..aaf8c07e6e 100644 --- a/src/init.h +++ b/src/init.h @@ -10,8 +10,9 @@ class CWallet; -namespace boost { - class thread_group; +namespace boost +{ +class thread_group; } // namespace boost extern CWallet* pwalletMain; @@ -22,8 +23,7 @@ void Shutdown(); bool AppInit2(boost::thread_group& threadGroup); /* The help message mode determines what help message to show */ -enum HelpMessageMode -{ +enum HelpMessageMode { HMM_BITCOIND, HMM_BITCOIN_QT }; @@ -26,27 +26,29 @@ class CKeyID : public uint160 { public: - CKeyID() : uint160(0) { } - CKeyID(const uint160 &in) : uint160(in) { } + CKeyID() : uint160(0) {} + CKeyID(const uint160& in) : uint160(in) {} }; /** A reference to a CScript: the Hash160 of its serialization (see script.h) */ class CScriptID : public uint160 { public: - CScriptID() : uint160(0) { } - CScriptID(const uint160 &in) : uint160(in) { } + CScriptID() : uint160(0) {} + CScriptID(const uint160& in) : uint160(in) {} }; /** An encapsulated public key. */ -class CPubKey { +class CPubKey +{ private: // Just store the serialized data. // Its length can very cheaply be computed from the first byte. unsigned char vch[65]; // Compute the length of a pubkey with a given first byte. - unsigned int static GetLen(unsigned char chHeader) { + unsigned int static GetLen(unsigned char chHeader) + { if (chHeader == 2 || chHeader == 3) return 33; if (chHeader == 4 || chHeader == 6 || chHeader == 7) @@ -55,66 +57,79 @@ private: } // Set this key data to be invalid - void Invalidate() { + void Invalidate() + { vch[0] = 0xFF; } public: // Construct an invalid public key. - CPubKey() { + CPubKey() + { Invalidate(); } // Initialize a public key using begin/end iterators to byte data. - template<typename T> - void Set(const T pbegin, const T pend) { + template <typename T> + void Set(const T pbegin, const T pend) + { int len = pend == pbegin ? 0 : GetLen(pbegin[0]); - if (len && len == (pend-pbegin)) + if (len && len == (pend - pbegin)) memcpy(vch, (unsigned char*)&pbegin[0], len); else Invalidate(); } // Construct a public key using begin/end iterators to byte data. - template<typename T> - CPubKey(const T pbegin, const T pend) { + template <typename T> + CPubKey(const T pbegin, const T pend) + { Set(pbegin, pend); } // Construct a public key from a byte vector. - CPubKey(const std::vector<unsigned char> &vch) { + CPubKey(const std::vector<unsigned char>& vch) + { Set(vch.begin(), vch.end()); } // Simple read-only vector-like interface to the pubkey data. unsigned int size() const { return GetLen(vch[0]); } - const unsigned char *begin() const { return vch; } - const unsigned char *end() const { return vch+size(); } - const unsigned char &operator[](unsigned int pos) const { return vch[pos]; } + const unsigned char* begin() const { return vch; } + const unsigned char* end() const { return vch + size(); } + const unsigned char& operator[](unsigned int pos) const { return vch[pos]; } // Comparator implementation. - friend bool operator==(const CPubKey &a, const CPubKey &b) { + friend bool operator==(const CPubKey& a, const CPubKey& b) + { return a.vch[0] == b.vch[0] && memcmp(a.vch, b.vch, a.size()) == 0; } - friend bool operator!=(const CPubKey &a, const CPubKey &b) { + friend bool operator!=(const CPubKey& a, const CPubKey& b) + { return !(a == b); } - friend bool operator<(const CPubKey &a, const CPubKey &b) { + friend bool operator<(const CPubKey& a, const CPubKey& b) + { return a.vch[0] < b.vch[0] || (a.vch[0] == b.vch[0] && memcmp(a.vch, b.vch, a.size()) < 0); } // Implement serialization, as if this was a byte vector. - unsigned int GetSerializeSize(int nType, int nVersion) const { + unsigned int GetSerializeSize(int nType, int nVersion) const + { return size() + 1; } - template<typename Stream> void Serialize(Stream &s, int nType, int nVersion) const { + template <typename Stream> + void Serialize(Stream& s, int nType, int nVersion) const + { unsigned int len = size(); ::WriteCompactSize(s, len); s.write((char*)vch, len); } - template<typename Stream> void Unserialize(Stream &s, int nType, int nVersion) { + template <typename Stream> + void Unserialize(Stream& s, int nType, int nVersion) + { unsigned int len = ::ReadCompactSize(s); if (len <= 65) { s.read((char*)vch, len); @@ -128,19 +143,22 @@ public: } // Get the KeyID of this public key (hash of its serialization) - CKeyID GetID() const { - return CKeyID(Hash160(vch, vch+size())); + CKeyID GetID() const + { + return CKeyID(Hash160(vch, vch + size())); } // Get the 256-bit hash of this public key. - uint256 GetHash() const { - return Hash(vch, vch+size()); + uint256 GetHash() const + { + return Hash(vch, vch + size()); } // Check syntactic correctness. // // Note that this is consensus critical as CheckSig() calls it! - bool IsValid() const { + bool IsValid() const + { return size() > 0; } @@ -148,16 +166,17 @@ public: bool IsFullyValid() const; // Check whether this is a compressed public key. - bool IsCompressed() const { + bool IsCompressed() const + { return size() == 33; } // Verify a DER signature (~72 bytes). // If this public key is not fully valid, the return value will be false. - bool Verify(const uint256 &hash, const std::vector<unsigned char>& vchSig) const; + bool Verify(const uint256& hash, const std::vector<unsigned char>& vchSig) const; // Recover a public key from a compact signature. - bool RecoverCompact(const uint256 &hash, const std::vector<unsigned char>& vchSig); + bool RecoverCompact(const uint256& hash, const std::vector<unsigned char>& vchSig); // Turn this public key into an uncompressed public key. bool Decompress(); @@ -172,7 +191,8 @@ public: typedef std::vector<unsigned char, secure_allocator<unsigned char> > CPrivKey; /** An encapsulated private key. */ -class CKey { +class CKey +{ private: // Whether this private key is valid. We check for correctness when modifying the key // data, so fValid should always correspond to the actual state. @@ -185,33 +205,38 @@ private: unsigned char vch[32]; // Check whether the 32-byte array pointed to be vch is valid keydata. - bool static Check(const unsigned char *vch); -public: + bool static Check(const unsigned char* vch); +public: // Construct an invalid private key. - CKey() : fValid(false), fCompressed(false) { + CKey() : fValid(false), fCompressed(false) + { LockObject(vch); } // Copy constructor. This is necessary because of memlocking. - CKey(const CKey &secret) : fValid(secret.fValid), fCompressed(secret.fCompressed) { + CKey(const CKey& secret) : fValid(secret.fValid), fCompressed(secret.fCompressed) + { LockObject(vch); memcpy(vch, secret.vch, sizeof(vch)); } // Destructor (again necessary because of memlocking). - ~CKey() { + ~CKey() + { UnlockObject(vch); } - friend bool operator==(const CKey &a, const CKey &b) { + friend bool operator==(const CKey& a, const CKey& b) + { return a.fCompressed == b.fCompressed && a.size() == b.size() && memcmp(&a.vch[0], &b.vch[0], a.size()) == 0; } // Initialize using begin and end iterators to byte data. - template<typename T> - void Set(const T pbegin, const T pend, bool fCompressedIn) { + template <typename T> + void Set(const T pbegin, const T pend, bool fCompressedIn) + { if (pend - pbegin != 32) { fValid = false; return; @@ -227,8 +252,8 @@ public: // Simple read-only vector-like interface. unsigned int size() const { return (fValid ? 32 : 0); } - const unsigned char *begin() const { return vch; } - const unsigned char *end() const { return vch + size(); } + const unsigned char* begin() const { return vch; } + const unsigned char* end() const { return vch + size(); } // Check whether this private key is valid. bool IsValid() const { return fValid; } @@ -237,7 +262,7 @@ public: bool IsCompressed() const { return fCompressed; } // Initialize from a CPrivKey (serialized OpenSSL private key data). - bool SetPrivKey(const CPrivKey &vchPrivKey, bool fCompressed); + bool SetPrivKey(const CPrivKey& vchPrivKey, bool fCompressed); // Generate a new private key using a cryptographic PRNG. void MakeNewKey(bool fCompressed); @@ -251,23 +276,23 @@ public: CPubKey GetPubKey() const; // Create a DER-serialized signature. - bool Sign(const uint256 &hash, std::vector<unsigned char>& vchSig) const; + bool Sign(const uint256& hash, std::vector<unsigned char>& vchSig) const; // Create a compact signature (65 bytes), which allows reconstructing the used public key. // The format is one header byte, followed by two times 32 bytes for the serialized r and s values. // The header byte: 0x1B = first key with even y, 0x1C = first key with odd y, // 0x1D = second key with even y, 0x1E = second key with odd y, // add 0x04 for compressed keys. - bool SignCompact(const uint256 &hash, std::vector<unsigned char>& vchSig) const; + bool SignCompact(const uint256& hash, std::vector<unsigned char>& vchSig) const; // Derive BIP32 child key. bool Derive(CKey& keyChild, unsigned char ccChild[32], unsigned int nChild, const unsigned char cc[32]) const; // Load private key and check that public key matches. - bool Load(CPrivKey &privkey, CPubKey &vchPubKey, bool fSkipCheck); + bool Load(CPrivKey& privkey, CPubKey& vchPubKey, bool fSkipCheck); // Check whether an element of a signature (r or s) is valid. - static bool CheckSignatureElement(const unsigned char *vch, int len, bool half); + static bool CheckSignatureElement(const unsigned char* vch, int len, bool half); }; struct CExtPubKey { @@ -277,14 +302,15 @@ struct CExtPubKey { unsigned char vchChainCode[32]; CPubKey pubkey; - friend bool operator==(const CExtPubKey &a, const CExtPubKey &b) { + friend bool operator==(const CExtPubKey& a, const CExtPubKey& b) + { return a.nDepth == b.nDepth && memcmp(&a.vchFingerprint[0], &b.vchFingerprint[0], 4) == 0 && a.nChild == b.nChild && memcmp(&a.vchChainCode[0], &b.vchChainCode[0], 32) == 0 && a.pubkey == b.pubkey; } void Encode(unsigned char code[74]) const; void Decode(const unsigned char code[74]); - bool Derive(CExtPubKey &out, unsigned int nChild) const; + bool Derive(CExtPubKey& out, unsigned int nChild) const; }; struct CExtKey { @@ -294,16 +320,17 @@ struct CExtKey { unsigned char vchChainCode[32]; CKey key; - friend bool operator==(const CExtKey &a, const CExtKey &b) { + friend bool operator==(const CExtKey& a, const CExtKey& b) + { return a.nDepth == b.nDepth && memcmp(&a.vchFingerprint[0], &b.vchFingerprint[0], 4) == 0 && a.nChild == b.nChild && memcmp(&a.vchChainCode[0], &b.vchChainCode[0], 32) == 0 && a.key == b.key; } void Encode(unsigned char code[74]) const; void Decode(const unsigned char code[74]); - bool Derive(CExtKey &out, unsigned int nChild) const; + bool Derive(CExtKey& out, unsigned int nChild) const; CExtPubKey Neuter() const; - void SetMaster(const unsigned char *seed, unsigned int nSeedLen); + void SetMaster(const unsigned char* seed, unsigned int nSeedLen); }; /** Check that required EC support is available at runtime */ diff --git a/src/leveldbwrapper.cpp b/src/leveldbwrapper.cpp index 9e849696a8..8ce3e7b470 100644 --- a/src/leveldbwrapper.cpp +++ b/src/leveldbwrapper.cpp @@ -12,7 +12,8 @@ #include <leveldb/filter_policy.h> #include <memenv.h> -void HandleError(const leveldb::Status &status) throw(leveldb_error) { +void HandleError(const leveldb::Status& status) throw(leveldb_error) +{ if (status.ok()) return; LogPrintf("%s\n", status.ToString()); @@ -25,7 +26,8 @@ void HandleError(const leveldb::Status &status) throw(leveldb_error) { throw leveldb_error("Unknown database error"); } -static leveldb::Options GetOptions(size_t nCacheSize) { +static leveldb::Options GetOptions(size_t nCacheSize) +{ leveldb::Options options; options.block_cache = leveldb::NewLRUCache(nCacheSize / 2); options.write_buffer_size = nCacheSize / 4; // up to two write buffers may be held in memory simultaneously @@ -40,7 +42,8 @@ static leveldb::Options GetOptions(size_t nCacheSize) { return options; } -CLevelDBWrapper::CLevelDBWrapper(const boost::filesystem::path &path, size_t nCacheSize, bool fMemory, bool fWipe) { +CLevelDBWrapper::CLevelDBWrapper(const boost::filesystem::path& path, size_t nCacheSize, bool fMemory, bool fWipe) +{ penv = NULL; readoptions.verify_checksums = true; iteroptions.verify_checksums = true; @@ -64,7 +67,8 @@ CLevelDBWrapper::CLevelDBWrapper(const boost::filesystem::path &path, size_t nCa LogPrintf("Opened LevelDB successfully\n"); } -CLevelDBWrapper::~CLevelDBWrapper() { +CLevelDBWrapper::~CLevelDBWrapper() +{ delete pdb; pdb = NULL; delete options.filter_policy; @@ -75,7 +79,8 @@ CLevelDBWrapper::~CLevelDBWrapper() { options.env = NULL; } -bool CLevelDBWrapper::WriteBatch(CLevelDBBatch &batch, bool fSync) throw(leveldb_error) { +bool CLevelDBWrapper::WriteBatch(CLevelDBBatch& batch, bool fSync) throw(leveldb_error) +{ leveldb::Status status = pdb->Write(fSync ? syncoptions : writeoptions, &batch.batch); HandleError(status); return true; diff --git a/src/leveldbwrapper.h b/src/leveldbwrapper.h index 29bc71f99d..da5ba61c7b 100644 --- a/src/leveldbwrapper.h +++ b/src/leveldbwrapper.h @@ -17,10 +17,10 @@ class leveldb_error : public std::runtime_error { public: - leveldb_error(const std::string &msg) : std::runtime_error(msg) {} + leveldb_error(const std::string& msg) : std::runtime_error(msg) {} }; -void HandleError(const leveldb::Status &status) throw(leveldb_error); +void HandleError(const leveldb::Status& status) throw(leveldb_error); // Batch of changes queued to be written to a CLevelDBWrapper class CLevelDBBatch @@ -31,7 +31,9 @@ private: leveldb::WriteBatch batch; public: - template<typename K, typename V> void Write(const K& key, const V& value) { + template <typename K, typename V> + void Write(const K& key, const V& value) + { CDataStream ssKey(SER_DISK, CLIENT_VERSION); ssKey.reserve(ssKey.GetSerializeSize(key)); ssKey << key; @@ -45,7 +47,9 @@ public: batch.Put(slKey, slValue); } - template<typename K> void Erase(const K& key) { + template <typename K> + void Erase(const K& key) + { CDataStream ssKey(SER_DISK, CLIENT_VERSION); ssKey.reserve(ssKey.GetSerializeSize(key)); ssKey << key; @@ -59,7 +63,7 @@ class CLevelDBWrapper { private: // custom environment this database is using (may be NULL in case of default environment) - leveldb::Env *penv; + leveldb::Env* penv; // database options used leveldb::Options options; @@ -77,13 +81,15 @@ private: leveldb::WriteOptions syncoptions; // the database itself - leveldb::DB *pdb; + leveldb::DB* pdb; public: - CLevelDBWrapper(const boost::filesystem::path &path, size_t nCacheSize, bool fMemory = false, bool fWipe = false); + CLevelDBWrapper(const boost::filesystem::path& path, size_t nCacheSize, bool fMemory = false, bool fWipe = false); ~CLevelDBWrapper(); - template<typename K, typename V> bool Read(const K& key, V& value) const throw(leveldb_error) { + template <typename K, typename V> + bool Read(const K& key, V& value) const throw(leveldb_error) + { CDataStream ssKey(SER_DISK, CLIENT_VERSION); ssKey.reserve(ssKey.GetSerializeSize(key)); ssKey << key; @@ -100,19 +106,23 @@ public: try { CDataStream ssValue(strValue.data(), strValue.data() + strValue.size(), SER_DISK, CLIENT_VERSION); ssValue >> value; - } catch(const std::exception &) { + } catch (const std::exception&) { return false; } return true; } - template<typename K, typename V> bool Write(const K& key, const V& value, bool fSync = false) throw(leveldb_error) { + template <typename K, typename V> + bool Write(const K& key, const V& value, bool fSync = false) throw(leveldb_error) + { CLevelDBBatch batch; batch.Write(key, value); return WriteBatch(batch, fSync); } - template<typename K> bool Exists(const K& key) const throw(leveldb_error) { + template <typename K> + bool Exists(const K& key) const throw(leveldb_error) + { CDataStream ssKey(SER_DISK, CLIENT_VERSION); ssKey.reserve(ssKey.GetSerializeSize(key)); ssKey << key; @@ -129,26 +139,31 @@ public: return true; } - template<typename K> bool Erase(const K& key, bool fSync = false) throw(leveldb_error) { + template <typename K> + bool Erase(const K& key, bool fSync = false) throw(leveldb_error) + { CLevelDBBatch batch; batch.Erase(key); return WriteBatch(batch, fSync); } - bool WriteBatch(CLevelDBBatch &batch, bool fSync = false) throw(leveldb_error); + bool WriteBatch(CLevelDBBatch& batch, bool fSync = false) throw(leveldb_error); // not available for LevelDB; provide for compatibility with BDB - bool Flush() { + bool Flush() + { return true; } - bool Sync() throw(leveldb_error) { + bool Sync() throw(leveldb_error) + { CLevelDBBatch batch; return WriteBatch(batch, true); } // not exactly clean encapsulation, but it's easiest for now - leveldb::Iterator *NewIterator() { + leveldb::Iterator* NewIterator() + { return pdb->NewIterator(iteroptions); } }; diff --git a/src/limitedmap.h b/src/limitedmap.h index 58593688af..4bc8d9e5aa 100644 --- a/src/limitedmap.h +++ b/src/limitedmap.h @@ -9,7 +9,8 @@ #include <map> /** STL-like map container that only keeps the N elements with the highest value. */ -template <typename K, typename V> class limitedmap +template <typename K, typename V> +class limitedmap { public: typedef K key_type; @@ -36,10 +37,8 @@ public: void insert(const value_type& x) { std::pair<iterator, bool> ret = map.insert(x); - if (ret.second) - { - if (nMaxSize && map.size() == nMaxSize) - { + if (ret.second) { + if (nMaxSize && map.size() == nMaxSize) { map.erase(rmap.begin()->second); rmap.erase(rmap.begin()); } @@ -54,8 +53,7 @@ public: return; std::pair<rmap_iterator, rmap_iterator> itPair = rmap.equal_range(itTarget->second); for (rmap_iterator it = itPair.first; it != itPair.second; ++it) - if (it->second == itTarget) - { + if (it->second == itTarget) { rmap.erase(it); map.erase(itTarget); return; @@ -72,8 +70,7 @@ public: return; std::pair<rmap_iterator, rmap_iterator> itPair = rmap.equal_range(itTarget->second); for (rmap_iterator it = itPair.first; it != itPair.second; ++it) - if (it->second == itTarget) - { + if (it->second == itTarget) { rmap.erase(it); itTarget->second = v; rmap.insert(make_pair(v, itTarget)); @@ -88,8 +85,7 @@ public: size_type max_size(size_type s) { if (s) - while (map.size() > s) - { + while (map.size() > s) { map.erase(rmap.begin()->second); rmap.erase(rmap.begin()); } diff --git a/src/main.cpp b/src/main.cpp index 3c19407b95..15c3916a6f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -697,7 +697,7 @@ bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs) // IsStandard() will have already returned false // and this method isn't called. vector<vector<unsigned char> > stack; - if (!EvalScript(stack, tx.vin[i].scriptSig, tx, i, false, 0)) + if (!EvalScript(stack, tx.vin[i].scriptSig, tx, i, false)) return false; if (whichType == TX_SCRIPTHASH) @@ -1351,12 +1351,13 @@ void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCach bool ret; // mark inputs spent if (!tx.IsCoinBase()) { - BOOST_FOREACH(const CTxIn &txin, tx.vin) { + txundo.vprevout.reserve(tx.vin.size()); + for (unsigned int i = 0; i < tx.vin.size(); i++) { + const CTxIn &txin = tx.vin[i]; CCoins &coins = inputs.GetCoins(txin.prevout.hash); - CTxInUndo undo; - ret = coins.Spend(txin.prevout, undo); + txundo.vprevout.push_back(CTxInUndo()); + ret = coins.Spend(txin.prevout, txundo.vprevout.back()); assert(ret); - txundo.vprevout.push_back(undo); } } @@ -1367,16 +1368,11 @@ void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCach bool CScriptCheck::operator()() const { const CScript &scriptSig = ptxTo->vin[nIn].scriptSig; - if (!VerifyScript(scriptSig, scriptPubKey, *ptxTo, nIn, nFlags, nHashType)) + if (!VerifyScript(scriptSig, scriptPubKey, *ptxTo, nIn, nFlags)) return error("CScriptCheck() : %s VerifySignature failed", ptxTo->GetHash().ToString()); return true; } -bool VerifySignature(const CCoins& txFrom, const CTransaction& txTo, unsigned int nIn, unsigned int flags, int nHashType) -{ - return CScriptCheck(txFrom, txTo, nIn, flags, nHashType)(); -} - bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsViewCache &inputs, bool fScriptChecks, unsigned int flags, std::vector<CScriptCheck> *pvChecks) { if (!tx.IsCoinBase()) @@ -1445,7 +1441,7 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsVi assert(coins); // Verify signature - CScriptCheck check(*coins, tx, i, flags, 0); + CScriptCheck check(*coins, tx, i, flags); if (pvChecks) { pvChecks->push_back(CScriptCheck()); check.swap(pvChecks->back()); @@ -1458,7 +1454,7 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsVi // avoid splitting the network between upgraded and // non-upgraded nodes. CScriptCheck check(*coins, tx, i, - flags & ~STANDARD_NOT_MANDATORY_VERIFY_FLAGS, 0); + flags & ~STANDARD_NOT_MANDATORY_VERIFY_FLAGS); if (check()) return state.Invalid(false, REJECT_NONSTANDARD, "non-mandatory-script-verify-flag"); } @@ -1668,6 +1664,7 @@ bool ConnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, C CDiskTxPos pos(pindex->GetBlockPos(), GetSizeOfCompactSize(block.vtx.size())); std::vector<std::pair<uint256, CDiskTxPos> > vPos; vPos.reserve(block.vtx.size()); + blockundo.vtxundo.reserve(block.vtx.size() - 1); for (unsigned int i = 0; i < block.vtx.size(); i++) { const CTransaction &tx = block.vtx[i]; @@ -1703,10 +1700,11 @@ bool ConnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, C control.Add(vChecks); } - CTxUndo txundo; - UpdateCoins(tx, state, view, txundo, pindex->nHeight); - if (!tx.IsCoinBase()) - blockundo.vtxundo.push_back(txundo); + CTxUndo undoDummy; + if (i > 0) { + blockundo.vtxundo.push_back(CTxUndo()); + } + UpdateCoins(tx, state, view, i == 0 ? undoDummy : blockundo.vtxundo.back(), pindex->nHeight); vPos.push_back(std::make_pair(tx.GetHash(), pos)); pos.nTxOffset += ::GetSerializeSize(tx, SER_DISK, CLIENT_VERSION); @@ -4111,21 +4109,25 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, else if (strCommand == "reject") { - if (fDebug) - { - string strMsg; unsigned char ccode; string strReason; - vRecv >> LIMITED_STRING(strMsg, CMessageHeader::COMMAND_SIZE) >> ccode >> LIMITED_STRING(strReason, 111); + if (fDebug) { + try { + string strMsg; unsigned char ccode; string strReason; + vRecv >> LIMITED_STRING(strMsg, CMessageHeader::COMMAND_SIZE) >> ccode >> LIMITED_STRING(strReason, 111); - ostringstream ss; - ss << strMsg << " code " << itostr(ccode) << ": " << strReason; + ostringstream ss; + ss << strMsg << " code " << itostr(ccode) << ": " << strReason; - if (strMsg == "block" || strMsg == "tx") - { - uint256 hash; - vRecv >> hash; - ss << ": hash " << hash.ToString(); + if (strMsg == "block" || strMsg == "tx") + { + uint256 hash; + vRecv >> hash; + ss << ": hash " << hash.ToString(); + } + LogPrint("net", "Reject %s\n", SanitizeString(ss.str())); + } catch (std::ios_base::failure& e) { + // Avoid feedback loops by preventing reject messages from triggering a new reject message. + LogPrint("net", "Unparseable reject message received\n"); } - LogPrint("net", "Reject %s\n", SanitizeString(ss.str())); } } diff --git a/src/main.h b/src/main.h index f83db59849..5acc551793 100644 --- a/src/main.h +++ b/src/main.h @@ -176,8 +176,6 @@ int64_t GetBlockValue(int nHeight, int64_t nFees); /** Create a new block index entry for a given block hash */ CBlockIndex * InsertBlockIndex(uint256 hash); -/** Verify a signature */ -bool VerifySignature(const CCoins& txFrom, const CTransaction& txTo, unsigned int nIn, unsigned int flags, int nHashType); /** Abort with a message */ bool AbortNode(const std::string &msg); /** Get statistics from node state */ @@ -344,13 +342,12 @@ private: const CTransaction *ptxTo; unsigned int nIn; unsigned int nFlags; - int nHashType; public: - CScriptCheck(): ptxTo(0), nIn(0), nFlags(0), nHashType(0) {} - CScriptCheck(const CCoins& txFromIn, const CTransaction& txToIn, unsigned int nInIn, unsigned int nFlagsIn, int nHashTypeIn) : + CScriptCheck(): ptxTo(0), nIn(0), nFlags(0) {} + CScriptCheck(const CCoins& txFromIn, const CTransaction& txToIn, unsigned int nInIn, unsigned int nFlagsIn) : scriptPubKey(txFromIn.vout[txToIn.vin[nInIn].prevout.n].scriptPubKey), - ptxTo(&txToIn), nIn(nInIn), nFlags(nFlagsIn), nHashType(nHashTypeIn) { } + ptxTo(&txToIn), nIn(nInIn), nFlags(nFlagsIn) { } bool operator()() const; @@ -359,7 +356,6 @@ public: std::swap(ptxTo, check.ptxTo); std::swap(nIn, check.nIn); std::swap(nFlags, check.nFlags); - std::swap(nHashType, check.nHashType); } }; diff --git a/src/mruset.h b/src/mruset.h index b9f325d874..1691875f57 100644 --- a/src/mruset.h +++ b/src/mruset.h @@ -10,7 +10,8 @@ #include <utility> /** STL-like set container that only keeps the most recent N elements. */ -template <typename T> class mruset +template <typename T> +class mruset { public: typedef T key_type; @@ -32,17 +33,19 @@ public: bool empty() const { return set.empty(); } iterator find(const key_type& k) const { return set.find(k); } size_type count(const key_type& k) const { return set.count(k); } - void clear() { set.clear(); queue.clear(); } + void clear() + { + set.clear(); + queue.clear(); + } bool inline friend operator==(const mruset<T>& a, const mruset<T>& b) { return a.set == b.set; } bool inline friend operator==(const mruset<T>& a, const std::set<T>& b) { return a.set == b; } bool inline friend operator<(const mruset<T>& a, const mruset<T>& b) { return a.set < b.set; } std::pair<iterator, bool> insert(const key_type& x) { std::pair<iterator, bool> ret = set.insert(x); - if (ret.second) - { - if (nMaxSize && queue.size() == nMaxSize) - { + if (ret.second) { + if (nMaxSize && queue.size() == nMaxSize) { set.erase(queue.front()); queue.pop_front(); } @@ -54,8 +57,7 @@ public: size_type max_size(size_type s) { if (s) - while (queue.size() > s) - { + while (queue.size() > s) { set.erase(queue.front()); queue.pop_front(); } diff --git a/src/noui.cpp b/src/noui.cpp index 8b00fd4057..f786a20db5 100644 --- a/src/noui.cpp +++ b/src/noui.cpp @@ -35,7 +35,7 @@ static bool noui_ThreadSafeMessageBox(const std::string& message, const std::str return false; } -static void noui_InitMessage(const std::string &message) +static void noui_InitMessage(const std::string& message) { LogPrintf("init message: %s\n", message); } diff --git a/src/protocol.h b/src/protocol.h index 82d29e66de..b73041a9fd 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -4,7 +4,7 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef __cplusplus -# error This header can only be compiled as C++. +#error This header can only be compiled as C++. #endif #ifndef __INCLUDED_PROTOCOL_H__ @@ -28,43 +28,43 @@ */ class CMessageHeader { - public: - CMessageHeader(); - CMessageHeader(const char* pszCommand, unsigned int nMessageSizeIn); +public: + CMessageHeader(); + CMessageHeader(const char* pszCommand, unsigned int nMessageSizeIn); - std::string GetCommand() const; - bool IsValid() const; + std::string GetCommand() const; + bool IsValid() const; - ADD_SERIALIZE_METHODS; + ADD_SERIALIZE_METHODS; - template <typename Stream, typename Operation> - inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { - READWRITE(FLATDATA(pchMessageStart)); - READWRITE(FLATDATA(pchCommand)); - READWRITE(nMessageSize); - READWRITE(nChecksum); - } + template <typename Stream, typename Operation> + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) + { + READWRITE(FLATDATA(pchMessageStart)); + READWRITE(FLATDATA(pchCommand)); + READWRITE(nMessageSize); + READWRITE(nChecksum); + } // TODO: make private (improves encapsulation) - public: - enum { - COMMAND_SIZE=12, - MESSAGE_SIZE_SIZE=sizeof(int), - CHECKSUM_SIZE=sizeof(int), - - MESSAGE_SIZE_OFFSET=MESSAGE_START_SIZE+COMMAND_SIZE, - CHECKSUM_OFFSET=MESSAGE_SIZE_OFFSET+MESSAGE_SIZE_SIZE, - HEADER_SIZE=MESSAGE_START_SIZE+COMMAND_SIZE+MESSAGE_SIZE_SIZE+CHECKSUM_SIZE - }; - char pchMessageStart[MESSAGE_START_SIZE]; - char pchCommand[COMMAND_SIZE]; - unsigned int nMessageSize; - unsigned int nChecksum; +public: + enum { + COMMAND_SIZE = 12, + MESSAGE_SIZE_SIZE = sizeof(int), + CHECKSUM_SIZE = sizeof(int), + + MESSAGE_SIZE_OFFSET = MESSAGE_START_SIZE + COMMAND_SIZE, + CHECKSUM_OFFSET = MESSAGE_SIZE_OFFSET + MESSAGE_SIZE_SIZE, + HEADER_SIZE = MESSAGE_START_SIZE + COMMAND_SIZE + MESSAGE_SIZE_SIZE + CHECKSUM_SIZE + }; + char pchMessageStart[MESSAGE_START_SIZE]; + char pchCommand[COMMAND_SIZE]; + unsigned int nMessageSize; + unsigned int nChecksum; }; /** nServices flags */ -enum -{ +enum { NODE_NETWORK = (1 << 0), // Bits 24-31 are reserved for temporary experiments. Just pick a bit that @@ -79,68 +79,69 @@ enum /** A CService with information about it as peer */ class CAddress : public CService { - public: - CAddress(); - explicit CAddress(CService ipIn, uint64_t nServicesIn=NODE_NETWORK); - - void Init(); - - ADD_SERIALIZE_METHODS; - - template <typename Stream, typename Operation> - inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { - if (ser_action.ForRead()) - Init(); - if (nType & SER_DISK) - READWRITE(nVersion); - if ((nType & SER_DISK) || - (nVersion >= CADDR_TIME_VERSION && !(nType & SER_GETHASH))) - READWRITE(nTime); - READWRITE(nServices); - READWRITE(*(CService*)this); - } +public: + CAddress(); + explicit CAddress(CService ipIn, uint64_t nServicesIn = NODE_NETWORK); + + void Init(); + + ADD_SERIALIZE_METHODS; + + template <typename Stream, typename Operation> + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) + { + if (ser_action.ForRead()) + Init(); + if (nType & SER_DISK) + READWRITE(nVersion); + if ((nType & SER_DISK) || + (nVersion >= CADDR_TIME_VERSION && !(nType & SER_GETHASH))) + READWRITE(nTime); + READWRITE(nServices); + READWRITE(*(CService*)this); + } // TODO: make private (improves encapsulation) - public: - uint64_t nServices; +public: + uint64_t nServices; - // disk and network only - unsigned int nTime; + // disk and network only + unsigned int nTime; - // memory only - int64_t nLastTry; + // memory only + int64_t nLastTry; }; /** inv message data */ class CInv { - public: - CInv(); - CInv(int typeIn, const uint256& hashIn); - CInv(const std::string& strType, const uint256& hashIn); +public: + CInv(); + CInv(int typeIn, const uint256& hashIn); + CInv(const std::string& strType, const uint256& hashIn); - ADD_SERIALIZE_METHODS; + ADD_SERIALIZE_METHODS; - template <typename Stream, typename Operation> - inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { - READWRITE(type); - READWRITE(hash); - } + template <typename Stream, typename Operation> + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) + { + READWRITE(type); + READWRITE(hash); + } - friend bool operator<(const CInv& a, const CInv& b); + friend bool operator<(const CInv& a, const CInv& b); - bool IsKnownType() const; - const char* GetCommand() const; - std::string ToString() const; + bool IsKnownType() const; + const char* GetCommand() const; + std::string ToString() const; // TODO: make private (improves encapsulation) - public: - int type; - uint256 hash; +public: + int type; + uint256 hash; }; -enum -{ +enum { MSG_TX = 1, MSG_BLOCK, // Nodes may always request a MSG_FILTERED_BLOCK in a getdata, however, diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index 6cc6b99ceb..bd686041c1 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -16,6 +16,7 @@ #include "splashscreen.h" #include "utilitydialog.h" #include "winshutdownmonitor.h" + #ifdef ENABLE_WALLET #include "paymentserver.h" #include "walletmodel.h" @@ -26,6 +27,7 @@ #include "rpcserver.h" #include "ui_interface.h" #include "util.h" + #ifdef ENABLE_WALLET #include "wallet.h" #endif @@ -34,15 +36,16 @@ #include <boost/filesystem/operations.hpp> #include <boost/thread.hpp> + #include <QApplication> #include <QDebug> #include <QLibraryInfo> #include <QLocale> #include <QMessageBox> #include <QSettings> +#include <QThread> #include <QTimer> #include <QTranslator> -#include <QThread> #if defined(QT_STATICPLUGIN) #include <QtPlugin> @@ -338,7 +341,9 @@ void BitcoinApplication::createWindow(bool isaTestNet) void BitcoinApplication::createSplashScreen(bool isaTestNet) { - SplashScreen *splash = new SplashScreen(QPixmap(), 0, isaTestNet); + SplashScreen *splash = new SplashScreen(0, isaTestNet); + // We don't hold a direct pointer to the splash screen after creation, so use + // Qt::WA_DeleteOnClose to make sure that the window will be deleted eventually. splash->setAttribute(Qt::WA_DeleteOnClose); splash->show(); connect(this, SIGNAL(splashFinished(QWidget*)), splash, SLOT(slotFinish(QWidget*))); @@ -423,8 +428,6 @@ void BitcoinApplication::initializeResult(int retval) } #endif - emit splashFinished(window); - // If -min option passed, start window minimized. if(GetBoolArg("-min", false)) { @@ -434,6 +437,8 @@ void BitcoinApplication::initializeResult(int retval) { window->show(); } + emit splashFinished(window); + #ifdef ENABLE_WALLET // Now that initialization/startup is done, process any command-line // bitcoin: URIs or payment requests: diff --git a/src/qt/bitcoinamountfield.h b/src/qt/bitcoinamountfield.h index c713f5d687..84795a7e7a 100644 --- a/src/qt/bitcoinamountfield.h +++ b/src/qt/bitcoinamountfield.h @@ -7,12 +7,12 @@ #include <QWidget> +class AmountSpinBox; + QT_BEGIN_NAMESPACE class QValueComboBox; QT_END_NAMESPACE -class AmountSpinBox; - /** Widget for entering bitcoin amounts. */ class BitcoinAmountField: public QWidget diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 790301a1eb..dd5192982e 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -14,6 +14,7 @@ #include "optionsmodel.h" #include "rpcconsole.h" #include "utilitydialog.h" + #ifdef ENABLE_WALLET #include "walletframe.h" #include "walletmodel.h" @@ -24,8 +25,8 @@ #endif #include "init.h" -#include "util.h" #include "ui_interface.h" +#include "util.h" #include <iostream> @@ -50,8 +51,8 @@ #include <QVBoxLayout> #if QT_VERSION < 0x050000 -#include <QUrl> #include <QTextDocument> +#include <QUrl> #else #include <QUrlQuery> #endif diff --git a/src/qt/coincontroldialog.h b/src/qt/coincontroldialog.h index 4f7422642f..a6f239a898 100644 --- a/src/qt/coincontroldialog.h +++ b/src/qt/coincontroldialog.h @@ -14,13 +14,15 @@ #include <QString> #include <QTreeWidgetItem> -namespace Ui { - class CoinControlDialog; -} class WalletModel; + class CCoinControl; class CTxMemPool; +namespace Ui { + class CoinControlDialog; +} + class CoinControlDialog : public QDialog { Q_OBJECT diff --git a/src/qt/guiconstants.h b/src/qt/guiconstants.h index 5ae4bc833d..4c8a67b663 100644 --- a/src/qt/guiconstants.h +++ b/src/qt/guiconstants.h @@ -23,6 +23,12 @@ static const int STATUSBAR_ICONSIZE = 16; #define COLOR_NEGATIVE QColor(255, 0, 0) /* Transaction list -- bare address (without label) */ #define COLOR_BAREADDRESS QColor(140, 140, 140) +/* Transaction list -- TX status decoration - open until date */ +#define COLOR_TX_STATUS_OPENUNTILDATE QColor(64, 64, 255) +/* Transaction list -- TX status decoration - offline */ +#define COLOR_TX_STATUS_OFFLINE QColor(192, 192, 192) +/* Transaction list -- TX status decoration - default color */ +#define COLOR_BLACK QColor(0, 0, 0) /* Tooltips longer than this (in characters) are converted into rich text, so that they can be word-wrapped. diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index 304177ee11..fc22871a6b 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -13,6 +13,8 @@ #include "init.h" #include "main.h" #include "protocol.h" +#include "script/script.h" +#include "script/standard.h" #include "util.h" #ifdef WIN32 @@ -222,7 +224,7 @@ QString formatBitcoinURI(const SendCoinsRecipient &info) bool isDust(const QString& address, qint64 amount) { CTxDestination dest = CBitcoinAddress(address.toStdString()).Get(); - CScript script; script.SetDestination(dest); + CScript script = GetScriptForDestination(dest); CTxOut txOut(amount, script); return txOut.IsDust(::minRelayTxFee); } diff --git a/src/qt/intro.h b/src/qt/intro.h index 295a75562f..e3e396d369 100644 --- a/src/qt/intro.h +++ b/src/qt/intro.h @@ -12,7 +12,7 @@ class FreespaceChecker; namespace Ui { -class Intro; + class Intro; } /** Introduction screen (pre-GUI startup). diff --git a/src/qt/openuridialog.h b/src/qt/openuridialog.h index 28da7d6d9d..67a5f167d1 100644 --- a/src/qt/openuridialog.h +++ b/src/qt/openuridialog.h @@ -8,7 +8,7 @@ #include <QDialog> namespace Ui { -class OpenURIDialog; + class OpenURIDialog; } class OpenURIDialog : public QDialog diff --git a/src/qt/optionsdialog.cpp b/src/qt/optionsdialog.cpp index c775a7f8d6..279467129f 100644 --- a/src/qt/optionsdialog.cpp +++ b/src/qt/optionsdialog.cpp @@ -17,11 +17,13 @@ #include "main.h" // for MAX_SCRIPTCHECK_THREADS #include "netbase.h" #include "txdb.h" // for -dbcache defaults + #ifdef ENABLE_WALLET #include "wallet.h" // for CWallet::minTxFee #endif #include <boost/thread.hpp> + #include <QDir> #include <QIntValidator> #include <QLocale> diff --git a/src/qt/optionsmodel.cpp b/src/qt/optionsmodel.cpp index 99928ebe4d..bd747faeb6 100644 --- a/src/qt/optionsmodel.cpp +++ b/src/qt/optionsmodel.cpp @@ -15,6 +15,7 @@ #include "main.h" #include "net.h" #include "txdb.h" // for -dbcache defaults + #ifdef ENABLE_WALLET #include "wallet.h" #include "walletdb.h" diff --git a/src/qt/paymentrequestplus.cpp b/src/qt/paymentrequestplus.cpp index acce42e203..7b7de49831 100644 --- a/src/qt/paymentrequestplus.cpp +++ b/src/qt/paymentrequestplus.cpp @@ -13,6 +13,7 @@ #include <openssl/x509.h> #include <openssl/x509_vfy.h> + #include <QDateTime> #include <QDebug> #include <QSslCertificate> diff --git a/src/qt/paymentserver.cpp b/src/qt/paymentserver.cpp index 219a685faf..cc4478f39f 100644 --- a/src/qt/paymentserver.cpp +++ b/src/qt/paymentserver.cpp @@ -609,7 +609,7 @@ void PaymentServer::fetchPaymentACK(CWallet* wallet, SendCoinsRecipient recipien std::string strAccount = account.toStdString(); set<CTxDestination> refundAddresses = wallet->GetAccountAddresses(strAccount); if (!refundAddresses.empty()) { - CScript s; s.SetDestination(*refundAddresses.begin()); + CScript s = GetScriptForDestination(*refundAddresses.begin()); payments::Output* refund_to = payment.add_refund_to(); refund_to->set_script(&s[0], s.size()); } @@ -620,7 +620,7 @@ void PaymentServer::fetchPaymentACK(CWallet* wallet, SendCoinsRecipient recipien CKeyID keyID = newKey.GetID(); wallet->SetAddressBook(keyID, strAccount, "refund"); - CScript s; s.SetDestination(keyID); + CScript s = GetScriptForDestination(keyID); payments::Output* refund_to = payment.add_refund_to(); refund_to->set_script(&s[0], s.size()); } diff --git a/src/qt/receivecoinsdialog.h b/src/qt/receivecoinsdialog.h index 663cb157a4..7a7e38e25e 100644 --- a/src/qt/receivecoinsdialog.h +++ b/src/qt/receivecoinsdialog.h @@ -5,6 +5,8 @@ #ifndef RECEIVECOINSDIALOG_H #define RECEIVECOINSDIALOG_H +#include "guiutil.h" + #include <QDialog> #include <QHeaderView> #include <QItemSelection> @@ -13,13 +15,12 @@ #include <QPoint> #include <QVariant> -#include "guiutil.h" +class OptionsModel; +class WalletModel; namespace Ui { class ReceiveCoinsDialog; } -class OptionsModel; -class WalletModel; QT_BEGIN_NAMESPACE class QModelIndex; diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index 11089b2497..8129353d4b 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -16,10 +16,12 @@ #include "util.h" #include "json/json_spirit_value.h" + +#include <openssl/crypto.h> + #ifdef ENABLE_WALLET #include <db_cxx.h> #endif -#include <openssl/crypto.h> #include <QKeyEvent> #include <QScrollBar> diff --git a/src/qt/rpcconsole.h b/src/qt/rpcconsole.h index 64bb5c29b3..1ffff92758 100644 --- a/src/qt/rpcconsole.h +++ b/src/qt/rpcconsole.h @@ -14,14 +14,14 @@ class ClientModel; -QT_BEGIN_NAMESPACE -class QItemSelection; -QT_END_NAMESPACE - namespace Ui { class RPCConsole; } +QT_BEGIN_NAMESPACE +class QItemSelection; +QT_END_NAMESPACE + /** Local Bitcoin RPC console. */ class RPCConsole: public QDialog { diff --git a/src/qt/sendcoinsdialog.h b/src/qt/sendcoinsdialog.h index 6cdf4a00c8..a090fa42d5 100644 --- a/src/qt/sendcoinsdialog.h +++ b/src/qt/sendcoinsdialog.h @@ -14,14 +14,14 @@ class OptionsModel; class SendCoinsEntry; class SendCoinsRecipient; -QT_BEGIN_NAMESPACE -class QUrl; -QT_END_NAMESPACE - namespace Ui { class SendCoinsDialog; } +QT_BEGIN_NAMESPACE +class QUrl; +QT_END_NAMESPACE + /** Dialog for sending bitcoins */ class SendCoinsDialog : public QDialog { diff --git a/src/qt/splashscreen.cpp b/src/qt/splashscreen.cpp index 5dd110b36a..673e984691 100644 --- a/src/qt/splashscreen.cpp +++ b/src/qt/splashscreen.cpp @@ -4,22 +4,25 @@ #include "splashscreen.h" -#include "version.h" #include "clientversion.h" #include "init.h" #include "ui_interface.h" #include "util.h" +#include "version.h" + #ifdef ENABLE_WALLET #include "wallet.h" #endif #include <QApplication> +#include <QCloseEvent> +#include <QDesktopWidget> #include <QPainter> -SplashScreen::SplashScreen(const QPixmap &pixmap, Qt::WindowFlags f, bool isTestNet) : - QSplashScreen(pixmap, f) +SplashScreen::SplashScreen(Qt::WindowFlags f, bool isTestNet) : + QWidget(0, f), curAlignment(0) { - setAutoFillBackground(true); + //setAutoFillBackground(true); // set reference point, paddings int paddingRight = 50; @@ -38,15 +41,14 @@ SplashScreen::SplashScreen(const QPixmap &pixmap, Qt::WindowFlags f, bool isTest QString font = "Arial"; // load the bitmap for writing some text over it - QPixmap newPixmap; if(isTestNet) { - newPixmap = QPixmap(":/images/splash_testnet"); + pixmap = QPixmap(":/images/splash_testnet"); } else { - newPixmap = QPixmap(":/images/splash"); + pixmap = QPixmap(":/images/splash"); } - QPainter pixPaint(&newPixmap); + QPainter pixPaint(&pixmap); pixPaint.setPen(QColor(100,100,100)); // check font size and drawing with @@ -61,7 +63,7 @@ SplashScreen::SplashScreen(const QPixmap &pixmap, Qt::WindowFlags f, bool isTest pixPaint.setFont(QFont(font, 33*fontFactor)); fm = pixPaint.fontMetrics(); titleTextWidth = fm.width(titleText); - pixPaint.drawText(newPixmap.width()-titleTextWidth-paddingRight,paddingTop,titleText); + pixPaint.drawText(pixmap.width()-titleTextWidth-paddingRight,paddingTop,titleText); pixPaint.setFont(QFont(font, 15*fontFactor)); @@ -72,11 +74,11 @@ SplashScreen::SplashScreen(const QPixmap &pixmap, Qt::WindowFlags f, bool isTest pixPaint.setFont(QFont(font, 10*fontFactor)); titleVersionVSpace -= 5; } - pixPaint.drawText(newPixmap.width()-titleTextWidth-paddingRight+2,paddingTop+titleVersionVSpace,versionText); + pixPaint.drawText(pixmap.width()-titleTextWidth-paddingRight+2,paddingTop+titleVersionVSpace,versionText); // draw copyright stuff pixPaint.setFont(QFont(font, 10*fontFactor)); - pixPaint.drawText(newPixmap.width()-titleTextWidth-paddingRight,paddingTop+titleCopyrightVSpace,copyrightText); + pixPaint.drawText(pixmap.width()-titleTextWidth-paddingRight,paddingTop+titleCopyrightVSpace,copyrightText); // draw testnet string if testnet is on if(isTestNet) { @@ -85,12 +87,22 @@ SplashScreen::SplashScreen(const QPixmap &pixmap, Qt::WindowFlags f, bool isTest pixPaint.setFont(boldFont); fm = pixPaint.fontMetrics(); int testnetAddTextWidth = fm.width(testnetAddText); - pixPaint.drawText(newPixmap.width()-testnetAddTextWidth-10,15,testnetAddText); + pixPaint.drawText(pixmap.width()-testnetAddTextWidth-10,15,testnetAddText); } pixPaint.end(); - this->setPixmap(newPixmap); + // Set window title + if(isTestNet) + setWindowTitle(titleText + " " + testnetAddText); + else + setWindowTitle(titleText); + + // Resize window and move to center of desktop, disallow resizing + QRect r(QPoint(), pixmap.size()); + resize(r.size()); + setFixedSize(r.size()); + move(QApplication::desktop()->screenGeometry().center() - r.center()); subscribeToCoreSignals(); } @@ -102,7 +114,7 @@ SplashScreen::~SplashScreen() void SplashScreen::slotFinish(QWidget *mainWin) { - finish(mainWin); + hide(); } static void InitMessage(SplashScreen *splash, const std::string &message) @@ -146,3 +158,26 @@ void SplashScreen::unsubscribeFromCoreSignals() pwalletMain->ShowProgress.disconnect(boost::bind(ShowProgress, this, _1, _2)); #endif } + +void SplashScreen::showMessage(const QString &message, int alignment, const QColor &color) +{ + curMessage = message; + curAlignment = alignment; + curColor = color; + update(); +} + +void SplashScreen::paintEvent(QPaintEvent *event) +{ + QPainter painter(this); + painter.drawPixmap(0, 0, pixmap); + QRect r = rect().adjusted(5, 5, -5, -5); + painter.setPen(curColor); + painter.drawText(r, curAlignment, curMessage); +} + +void SplashScreen::closeEvent(QCloseEvent *event) +{ + event->ignore(); +} + diff --git a/src/qt/splashscreen.h b/src/qt/splashscreen.h index d79038d81d..89c21e6457 100644 --- a/src/qt/splashscreen.h +++ b/src/qt/splashscreen.h @@ -7,25 +7,41 @@ #include <QSplashScreen> -/** class for the splashscreen with information of the running client +/** Class for the splashscreen with information of the running client. + * + * @note this is intentionally not a QSplashScreen. Bitcoin Core initialization + * can take a long time, and in that case a progress window that cannot be + * moved around and minimized has turned out to be frustrating to the user. */ -class SplashScreen : public QSplashScreen +class SplashScreen : public QWidget { Q_OBJECT public: - explicit SplashScreen(const QPixmap &pixmap, Qt::WindowFlags f, bool isTestNet); + explicit SplashScreen(Qt::WindowFlags f, bool isTestNet); ~SplashScreen(); +protected: + void paintEvent(QPaintEvent *event); + void closeEvent(QCloseEvent *event); + public slots: /** Slot to call finish() method as it's not defined as slot */ void slotFinish(QWidget *mainWin); + /** Show message and progress */ + void showMessage(const QString &message, int alignment, const QColor &color); + private: /** Connect core signals to splash screen */ void subscribeToCoreSignals(); /** Disconnect core signals to splash screen */ void unsubscribeFromCoreSignals(); + + QPixmap pixmap; + QString curMessage; + QColor curColor; + int curAlignment; }; #endif // SPLASHSCREEN_H diff --git a/src/qt/transactiondesc.cpp b/src/qt/transactiondesc.cpp index 727b8dc66d..4923718341 100644 --- a/src/qt/transactiondesc.cpp +++ b/src/qt/transactiondesc.cpp @@ -6,13 +6,13 @@ #include "bitcoinunits.h" #include "guiutil.h" +#include "paymentserver.h" +#include "transactionrecord.h" #include "base58.h" #include "db.h" #include "main.h" -#include "paymentserver.h" #include "script/script.h" -#include "transactionrecord.h" #include "timedata.h" #include "ui_interface.h" #include "util.h" diff --git a/src/qt/transactiontablemodel.cpp b/src/qt/transactiontablemodel.cpp index 734c7afc4e..2b869b4ea5 100644 --- a/src/qt/transactiontablemodel.cpp +++ b/src/qt/transactiontablemodel.cpp @@ -209,10 +209,7 @@ public: } return rec; } - else - { - return 0; - } + return 0; } QString describe(TransactionRecord *rec, int unit) @@ -225,7 +222,7 @@ public: return TransactionDesc::toHTML(wallet, mi->second, rec, unit); } } - return QString(""); + return QString(); } }; @@ -330,10 +327,7 @@ QString TransactionTableModel::formatTxDate(const TransactionRecord *wtx) const { return GUIUtil::dateTimeStr(wtx->time); } - else - { - return QString(); - } + return QString(); } /* Look up address in address book, if found return label (address) @@ -345,11 +339,11 @@ QString TransactionTableModel::lookupAddress(const std::string &address, bool to QString description; if(!label.isEmpty()) { - description += label + QString(" "); + description += label; } if(label.isEmpty() || tooltip) { - description += QString("(") + QString::fromStdString(address) + QString(")"); + description += QString(" (") + QString::fromStdString(address) + QString(")"); } return description; } @@ -389,7 +383,6 @@ QVariant TransactionTableModel::txAddressDecoration(const TransactionRecord *wtx default: return QIcon(":/icons/tx_inout"); } - return QVariant(); } QString TransactionTableModel::formatTxToAddress(const TransactionRecord *wtx, bool tooltip) const @@ -456,9 +449,9 @@ QVariant TransactionTableModel::txStatusDecoration(const TransactionRecord *wtx) { case TransactionStatus::OpenUntilBlock: case TransactionStatus::OpenUntilDate: - return QColor(64,64,255); + return COLOR_TX_STATUS_OPENUNTILDATE; case TransactionStatus::Offline: - return QColor(192,192,192); + return COLOR_TX_STATUS_OFFLINE; case TransactionStatus::Unconfirmed: return QIcon(":/icons/transaction_0"); case TransactionStatus::Confirming: @@ -482,8 +475,9 @@ QVariant TransactionTableModel::txStatusDecoration(const TransactionRecord *wtx) case TransactionStatus::MaturesWarning: case TransactionStatus::NotAccepted: return QIcon(":/icons/transaction_0"); + default: + return COLOR_BLACK; } - return QColor(0,0,0); } QVariant TransactionTableModel::txWatchonlyDecoration(const TransactionRecord *wtx) const @@ -646,10 +640,7 @@ QModelIndex TransactionTableModel::index(int row, int column, const QModelIndex { return createIndex(row, column, priv->index(row)); } - else - { - return QModelIndex(); - } + return QModelIndex(); } void TransactionTableModel::updateDisplayUnit() diff --git a/src/qt/utilitydialog.cpp b/src/qt/utilitydialog.cpp index 7df9d1bc2d..84f88dff5a 100644 --- a/src/qt/utilitydialog.cpp +++ b/src/qt/utilitydialog.cpp @@ -15,6 +15,7 @@ #include <stdio.h> +#include <QCloseEvent> #include <QLabel> #include <QRegExp> #include <QVBoxLayout> @@ -106,18 +107,26 @@ void HelpMessageDialog::on_okButton_accepted() /** "Shutdown" window */ +ShutdownWindow::ShutdownWindow(QWidget *parent, Qt::WindowFlags f): + QWidget(parent, f) +{ + QVBoxLayout *layout = new QVBoxLayout(); + layout->addWidget(new QLabel( + tr("Bitcoin Core is shutting down...") + "<br /><br />" + + tr("Do not shut down the computer until this window disappears."))); + setLayout(layout); +} + void ShutdownWindow::showShutdownWindow(BitcoinGUI *window) { if (!window) return; // Show a simple window indicating shutdown status - QWidget *shutdownWindow = new QWidget(); - QVBoxLayout *layout = new QVBoxLayout(); - layout->addWidget(new QLabel( - tr("Bitcoin Core is shutting down...") + "<br /><br />" + - tr("Do not shut down the computer until this window disappears."))); - shutdownWindow->setLayout(layout); + QWidget *shutdownWindow = new ShutdownWindow(); + // We don't hold a direct pointer to the shutdown window after creation, so use + // Qt::WA_DeleteOnClose to make sure that the window will be deleted eventually. + shutdownWindow->setAttribute(Qt::WA_DeleteOnClose); shutdownWindow->setWindowTitle(window->windowTitle()); // Center shutdown window at where main window was @@ -125,3 +134,8 @@ void ShutdownWindow::showShutdownWindow(BitcoinGUI *window) shutdownWindow->move(global.x() - shutdownWindow->width() / 2, global.y() - shutdownWindow->height() / 2); shutdownWindow->show(); } + +void ShutdownWindow::closeEvent(QCloseEvent *event) +{ + event->ignore(); +} diff --git a/src/qt/utilitydialog.h b/src/qt/utilitydialog.h index 154bb70b8b..ae5045cca9 100644 --- a/src/qt/utilitydialog.h +++ b/src/qt/utilitydialog.h @@ -37,12 +37,16 @@ private slots: /** "Shutdown" window */ -class ShutdownWindow : public QObject +class ShutdownWindow : public QWidget { Q_OBJECT public: + ShutdownWindow(QWidget *parent=0, Qt::WindowFlags f=0); static void showShutdownWindow(BitcoinGUI *window); + +protected: + void closeEvent(QCloseEvent *event); }; #endif // UTILITYDIALOG_H diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index 8d2c2e96d8..ed90914ba7 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -241,8 +241,7 @@ WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransact setAddress.insert(rcp.address); ++nAddresses; - CScript scriptPubKey; - scriptPubKey.SetDestination(CBitcoinAddress(rcp.address.toStdString()).Get()); + CScript scriptPubKey = GetScriptForDestination(CBitcoinAddress(rcp.address.toStdString()).Get()); vecSend.push_back(std::pair<CScript, int64_t>(scriptPubKey, rcp.amount)); total += rcp.amount; diff --git a/src/random.cpp b/src/random.cpp index fb5258a442..998e7dfb08 100644 --- a/src/random.cpp +++ b/src/random.cpp @@ -8,8 +8,8 @@ #ifdef WIN32 #include "compat.h" // for Windows API #endif -#include "serialize.h" // for begin_ptr(vec) -#include "util.h" // for LogPrint() +#include "serialize.h" // for begin_ptr(vec) +#include "util.h" // for LogPrint() #include "utilstrencodings.h" // for GetTime() #include <limits> @@ -56,28 +56,25 @@ void RandAddSeedPerfmon() #ifdef WIN32 // Don't need this on Linux, OpenSSL automatically uses /dev/urandom // Seed with the entire set of perfmon data - std::vector <unsigned char> vData(250000,0); + std::vector<unsigned char> vData(250000, 0); long ret = 0; unsigned long nSize = 0; const size_t nMaxSize = 10000000; // Bail out at more than 10MB of performance data - while (true) - { + while (true) { nSize = vData.size(); ret = RegQueryValueExA(HKEY_PERFORMANCE_DATA, "Global", NULL, NULL, begin_ptr(vData), &nSize); if (ret != ERROR_MORE_DATA || vData.size() >= nMaxSize) break; - vData.resize(std::max((vData.size()*3)/2, nMaxSize)); // Grow size of buffer exponentially + vData.resize(std::max((vData.size() * 3) / 2, nMaxSize)); // Grow size of buffer exponentially } RegCloseKey(HKEY_PERFORMANCE_DATA); - if (ret == ERROR_SUCCESS) - { - RAND_add(begin_ptr(vData), nSize, nSize/100.0); + if (ret == ERROR_SUCCESS) { + RAND_add(begin_ptr(vData), nSize, nSize / 100.0); OPENSSL_cleanse(begin_ptr(vData), nSize); LogPrint("rand", "%s: %lu bytes\n", __func__, nSize); } else { static bool warned = false; // Warn only once - if (!warned) - { + if (!warned) { LogPrintf("%s: Warning: RegQueryValueExA(HKEY_PERFORMANCE_DATA) failed with code %i\n", __func__, ret); warned = true; } @@ -85,7 +82,7 @@ void RandAddSeedPerfmon() #endif } -bool GetRandBytes(unsigned char *buf, int num) +bool GetRandBytes(unsigned char* buf, int num) { if (RAND_bytes(buf, num) != 1) { LogPrintf("%s: OpenSSL RAND_bytes() failed with error: %s\n", __func__, ERR_error_string(ERR_get_error(), NULL)); @@ -126,18 +123,17 @@ uint32_t insecure_rand_Rw = 11; void seed_insecure_rand(bool fDeterministic) { // The seed values have some unlikely fixed points which we avoid. - if(fDeterministic) - { + if (fDeterministic) { insecure_rand_Rz = insecure_rand_Rw = 11; } else { uint32_t tmp; do { GetRandBytes((unsigned char*)&tmp, 4); - } while(tmp == 0 || tmp == 0x9068ffffU); + } while (tmp == 0 || tmp == 0x9068ffffU); insecure_rand_Rz = tmp; do { GetRandBytes((unsigned char*)&tmp, 4); - } while(tmp == 0 || tmp == 0x464fffffU); + } while (tmp == 0 || tmp == 0x464fffffU); insecure_rand_Rw = tmp; } } diff --git a/src/random.h b/src/random.h index a599b08478..161ebe8986 100644 --- a/src/random.h +++ b/src/random.h @@ -19,7 +19,7 @@ void RandAddSeedPerfmon(); /** * Functions to gather random data via the OpenSSL PRNG */ -bool GetRandBytes(unsigned char *buf, int num); +bool GetRandBytes(unsigned char* buf, int num); uint64_t GetRand(uint64_t nMax); int GetRandInt(int nMax); uint256 GetRandHash(); diff --git a/src/rpcclient.cpp b/src/rpcclient.cpp index 81797248b4..a9c491cede 100644 --- a/src/rpcclient.cpp +++ b/src/rpcclient.cpp @@ -8,7 +8,6 @@ #include "rpcprotocol.h" #include "util.h" #include "ui_interface.h" -#include "chainparams.h" // for Params().RPCPort() #include <set> #include <stdint.h> @@ -67,6 +66,7 @@ static const CRPCConvertParam vRPCConvertParams[] = { "listunspent", 1 }, { "listunspent", 2 }, { "getblock", 1 }, + { "gettransaction", 1 }, { "getrawtransaction", 1 }, { "createrawtransaction", 0 }, { "createrawtransaction", 1 }, diff --git a/src/rpcclient.h b/src/rpcclient.h index 1233ea3875..307aa2aab8 100644 --- a/src/rpcclient.h +++ b/src/rpcclient.h @@ -10,6 +10,6 @@ #include "json/json_spirit_utils.h" #include "json/json_spirit_writer_template.h" -json_spirit::Array RPCConvertValues(const std::string &strMethod, const std::vector<std::string> &strParams); +json_spirit::Array RPCConvertValues(const std::string& strMethod, const std::vector<std::string>& strParams); #endif // _BITCOINRPC_CLIENT_H_ diff --git a/src/rpcdump.cpp b/src/rpcdump.cpp index dc73161bf1..1ac7024550 100644 --- a/src/rpcdump.cpp +++ b/src/rpcdump.cpp @@ -6,6 +6,8 @@ #include "rpcserver.h" #include "init.h" #include "main.h" +#include "script/script.h" +#include "script/standard.h" #include "sync.h" #include "util.h" #include "utiltime.h" @@ -161,7 +163,7 @@ Value importaddress(const Array& params, bool fHelp) CBitcoinAddress address(params[0].get_str()); if (address.IsValid()) { - script.SetDestination(address.Get()); + script = GetScriptForDestination(address.Get()); } else if (IsHex(params[0].get_str())) { std::vector<unsigned char> data(ParseHex(params[0].get_str())); script = CScript(data.begin(), data.end()); diff --git a/src/rpcmisc.cpp b/src/rpcmisc.cpp index 917c840536..dd45eefd58 100644 --- a/src/rpcmisc.cpp +++ b/src/rpcmisc.cpp @@ -250,8 +250,7 @@ CScript _createmultisig_redeemScript(const Array& params) throw runtime_error(" Invalid public key: "+ks); } } - CScript result; - result.SetMultisig(nRequired, pubkeys); + CScript result = GetScriptForMultisig(nRequired, pubkeys); if (result.size() > MAX_SCRIPT_ELEMENT_SIZE) throw runtime_error( diff --git a/src/rpcnet.cpp b/src/rpcnet.cpp index 4afbe442ee..95f42eb47f 100644 --- a/src/rpcnet.cpp +++ b/src/rpcnet.cpp @@ -95,8 +95,8 @@ Value getpeerinfo(const Array& params, bool fHelp) " \"subver\": \"/Satoshi:0.8.5/\", (string) The string version\n" " \"inbound\": true|false, (boolean) Inbound (true) or Outbound (false)\n" " \"startingheight\": n, (numeric) The starting height (block) of the peer\n" - " \"banscore\": n, (numeric) The ban score (stats.nMisbehavior)\n" - " \"syncnode\" : true|false (booleamn) if sync node\n" + " \"banscore\": n, (numeric) The ban score\n" + " \"syncnode\": true|false (boolean) if sync node\n" " }\n" " ,...\n" "]\n" diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp index 1828a5dc7d..dbb0966ae2 100644 --- a/src/rpcrawtransaction.cpp +++ b/src/rpcrawtransaction.cpp @@ -366,8 +366,7 @@ Value createrawtransaction(const Array& params, bool fHelp) throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ")+s.name_); setAddress.insert(address); - CScript scriptPubKey; - scriptPubKey.SetDestination(address.Get()); + CScript scriptPubKey = GetScriptForDestination(address.Get()); int64_t nAmount = AmountFromValue(s.value_); CTxOut out(nAmount, scriptPubKey); @@ -688,7 +687,7 @@ Value signrawtransaction(const Array& params, bool fHelp) BOOST_FOREACH(const CMutableTransaction& txv, txVariants) { txin.scriptSig = CombineSignatures(prevPubKey, mergedTx, i, txin.scriptSig, txv.vin[i].scriptSig); } - if (!VerifyScript(txin.scriptSig, prevPubKey, mergedTx, i, STANDARD_SCRIPT_VERIFY_FLAGS, 0)) + if (!VerifyScript(txin.scriptSig, prevPubKey, mergedTx, i, STANDARD_SCRIPT_VERIFY_FLAGS)) fComplete = false; } diff --git a/src/rpcwallet.cpp b/src/rpcwallet.cpp index 997b861e59..35637362a4 100644 --- a/src/rpcwallet.cpp +++ b/src/rpcwallet.cpp @@ -124,8 +124,7 @@ CBitcoinAddress GetAccountAddress(string strAccount, bool bForceNew=false) // Check if the current key has been used if (account.vchPubKey.IsValid()) { - CScript scriptPubKey; - scriptPubKey.SetDestination(account.vchPubKey.GetID()); + CScript scriptPubKey = GetScriptForDestination(account.vchPubKey.GetID()); for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end() && account.vchPubKey.IsValid(); ++it) @@ -472,10 +471,9 @@ Value getreceivedbyaddress(const Array& params, bool fHelp) // Bitcoin address CBitcoinAddress address = CBitcoinAddress(params[0].get_str()); - CScript scriptPubKey; if (!address.IsValid()) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address"); - scriptPubKey.SetDestination(address.Get()); + CScript scriptPubKey = GetScriptForDestination(address.Get()); if (!IsMine(*pwalletMain,scriptPubKey)) return (double)0.0; @@ -849,8 +847,7 @@ Value sendmany(const Array& params, bool fHelp) throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ")+s.name_); setAddress.insert(address); - CScript scriptPubKey; - scriptPubKey.SetDestination(address.Get()); + CScript scriptPubKey = GetScriptForDestination(address.Get()); int64_t nAmount = AmountFromValue(s.value_); totalAmount += nAmount; @@ -1490,7 +1487,7 @@ Value gettransaction(const Array& params, bool fHelp) { if (fHelp || params.size() < 1 || params.size() > 2) throw runtime_error( - "gettransaction \"txid\"\n" + "gettransaction \"txid\" ( includeWatchonly )\n" "\nGet detailed information about in-wallet transaction <txid>\n" "\nArguments:\n" "1. \"txid\" (string, required) The transaction id\n" @@ -1520,6 +1517,7 @@ Value gettransaction(const Array& params, bool fHelp) "\nExamples:\n" + HelpExampleCli("gettransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"") + + HelpExampleCli("gettransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\" true") + HelpExampleRpc("gettransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"") ); diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index 471edf1c98..fd3e4f1ff7 100644 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -132,7 +132,7 @@ bool IsCanonicalSignature(const valtype &vchSig, unsigned int flags) { return true; } -bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, const CTransaction& txTo, unsigned int nIn, unsigned int flags, int nHashType) +bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, const CTransaction& txTo, unsigned int nIn, unsigned int flags) { CScript::const_iterator pc = script.begin(); CScript::const_iterator pend = script.end(); @@ -675,7 +675,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co scriptCode.FindAndDelete(CScript(vchSig)); bool fSuccess = IsCanonicalSignature(vchSig, flags) && IsCanonicalPubKey(vchPubKey, flags) && - CheckSig(vchSig, vchPubKey, scriptCode, txTo, nIn, nHashType, flags); + CheckSig(vchSig, vchPubKey, scriptCode, txTo, nIn, flags); popstack(stack); popstack(stack); @@ -736,7 +736,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co // Check signature bool fOk = IsCanonicalSignature(vchSig, flags) && IsCanonicalPubKey(vchPubKey, flags) && - CheckSig(vchSig, vchPubKey, scriptCode, txTo, nIn, nHashType, flags); + CheckSig(vchSig, vchPubKey, scriptCode, txTo, nIn, flags); if (fOk) { isig++; @@ -975,7 +975,7 @@ public: } }; -bool CheckSig(vector<unsigned char> vchSig, const vector<unsigned char> &vchPubKey, const CScript &scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType, int flags) +bool CheckSig(vector<unsigned char> vchSig, const vector<unsigned char>& vchPubKey, const CScript& scriptCode, const CTransaction& txTo, unsigned int nIn, int flags) { static CSignatureCache signatureCache; @@ -986,10 +986,7 @@ bool CheckSig(vector<unsigned char> vchSig, const vector<unsigned char> &vchPubK // Hash type is one byte tacked on to the end of the signature if (vchSig.empty()) return false; - if (nHashType == 0) - nHashType = vchSig.back(); - else if (nHashType != vchSig.back()) - return false; + int nHashType = vchSig.back(); vchSig.pop_back(); uint256 sighash = SignatureHash(scriptCode, txTo, nIn, nHashType); @@ -1006,15 +1003,14 @@ bool CheckSig(vector<unsigned char> vchSig, const vector<unsigned char> &vchPubK return true; } -bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn, - unsigned int flags, int nHashType) +bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn, unsigned int flags) { vector<vector<unsigned char> > stack, stackCopy; - if (!EvalScript(stack, scriptSig, txTo, nIn, flags, nHashType)) + if (!EvalScript(stack, scriptSig, txTo, nIn, flags)) return false; if (flags & SCRIPT_VERIFY_P2SH) stackCopy = stack; - if (!EvalScript(stack, scriptPubKey, txTo, nIn, flags, nHashType)) + if (!EvalScript(stack, scriptPubKey, txTo, nIn, flags)) return false; if (stack.empty()) return false; @@ -1037,7 +1033,7 @@ bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, const C CScript pubKey2(pubKeySerialized.begin(), pubKeySerialized.end()); popstack(stackCopy); - if (!EvalScript(stackCopy, pubKey2, txTo, nIn, flags, nHashType)) + if (!EvalScript(stackCopy, pubKey2, txTo, nIn, flags)) return false; if (stackCopy.empty()) return false; diff --git a/src/script/interpreter.h b/src/script/interpreter.h index 6fbcd92a3d..adca2142ac 100644 --- a/src/script/interpreter.h +++ b/src/script/interpreter.h @@ -38,8 +38,8 @@ bool IsCanonicalPubKey(const std::vector<unsigned char> &vchPubKey, unsigned int bool IsCanonicalSignature(const std::vector<unsigned char> &vchSig, unsigned int flags); uint256 SignatureHash(const CScript &scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType); -bool CheckSig(std::vector<unsigned char> vchSig, const std::vector<unsigned char> &vchPubKey, const CScript &scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType, int flags); -bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript& script, const CTransaction& txTo, unsigned int nIn, unsigned int flags, int nHashType); -bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn, unsigned int flags, int nHashType); +bool CheckSig(std::vector<unsigned char> vchSig, const std::vector<unsigned char> &vchPubKey, const CScript &scriptCode, const CTransaction& txTo, unsigned int nIn, int flags); +bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript& script, const CTransaction& txTo, unsigned int nIn, unsigned int flags); +bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn, unsigned int flags); #endif // H_BITCOIN_SCRIPT_INTERPRETER diff --git a/src/script/script.cpp b/src/script/script.cpp index 3c9f38dc8b..a5126e7cc2 100644 --- a/src/script/script.cpp +++ b/src/script/script.cpp @@ -253,43 +253,3 @@ bool CScript::HasCanonicalPushes() const } return true; } - -class CScriptVisitor : public boost::static_visitor<bool> -{ -private: - CScript *script; -public: - CScriptVisitor(CScript *scriptin) { script = scriptin; } - - bool operator()(const CNoDestination &dest) const { - script->clear(); - return false; - } - - bool operator()(const CKeyID &keyID) const { - script->clear(); - *script << OP_DUP << OP_HASH160 << keyID << OP_EQUALVERIFY << OP_CHECKSIG; - return true; - } - - bool operator()(const CScriptID &scriptID) const { - script->clear(); - *script << OP_HASH160 << scriptID << OP_EQUAL; - return true; - } -}; - -void CScript::SetDestination(const CTxDestination& dest) -{ - boost::apply_visitor(CScriptVisitor(this), dest); -} - -void CScript::SetMultisig(int nRequired, const std::vector<CPubKey>& keys) -{ - this->clear(); - - *this << EncodeOP_N(nRequired); - BOOST_FOREACH(const CPubKey& key, keys) - *this << key; - *this << EncodeOP_N(keys.size()) << OP_CHECKMULTISIG; -} diff --git a/src/script/script.h b/src/script/script.h index 2336cafd67..4c9ac74b78 100644 --- a/src/script/script.h +++ b/src/script/script.h @@ -320,20 +320,6 @@ inline std::string ValueString(const std::vector<unsigned char>& vch) return HexStr(vch); } -class CNoDestination { -public: - friend bool operator==(const CNoDestination &a, const CNoDestination &b) { return true; } - friend bool operator<(const CNoDestination &a, const CNoDestination &b) { return true; } -}; - -/** A txout script template with a specific destination. It is either: - * * CNoDestination: no destination set - * * CKeyID: TX_PUBKEYHASH destination - * * CScriptID: TX_SCRIPTHASH destination - * A CTxDestination is the internal data type encoded in a CBitcoinAddress - */ -typedef boost::variant<CNoDestination, CKeyID, CScriptID> CTxDestination; - /** Serialized script, used inside transaction inputs and outputs */ class CScript : public std::vector<unsigned char> { @@ -354,9 +340,7 @@ public: CScript() { } CScript(const CScript& b) : std::vector<unsigned char>(b.begin(), b.end()) { } CScript(const_iterator pbegin, const_iterator pend) : std::vector<unsigned char>(pbegin, pend) { } -#ifndef _MSC_VER CScript(const unsigned char* pbegin, const unsigned char* pend) : std::vector<unsigned char>(pbegin, pend) { } -#endif CScript& operator+=(const CScript& b) { @@ -604,9 +588,6 @@ public: return (size() > 0 && *begin() == OP_RETURN); } - void SetDestination(const CTxDestination& address); - void SetMultisig(int nRequired, const std::vector<CPubKey>& keys); - std::string ToString() const { std::string str; diff --git a/src/script/sign.cpp b/src/script/sign.cpp index db9513db9f..8abd8d221d 100644 --- a/src/script/sign.cpp +++ b/src/script/sign.cpp @@ -123,7 +123,7 @@ bool SignSignature(const CKeyStore &keystore, const CScript& fromPubKey, CMutabl } // Test solution - return VerifyScript(txin.scriptSig, fromPubKey, txTo, nIn, STANDARD_SCRIPT_VERIFY_FLAGS, 0); + return VerifyScript(txin.scriptSig, fromPubKey, txTo, nIn, STANDARD_SCRIPT_VERIFY_FLAGS); } bool SignSignature(const CKeyStore &keystore, const CTransaction& txFrom, CMutableTransaction& txTo, unsigned int nIn, int nHashType) @@ -174,7 +174,7 @@ static CScript CombineMultisig(CScript scriptPubKey, const CMutableTransaction& if (sigs.count(pubkey)) continue; // Already got a sig for this pubkey - if (CheckSig(sig, pubkey, scriptPubKey, txTo, nIn, 0, 0)) + if (CheckSig(sig, pubkey, scriptPubKey, txTo, nIn, 0)) { sigs[pubkey] = sig; break; @@ -252,9 +252,9 @@ CScript CombineSignatures(CScript scriptPubKey, const CTransaction& txTo, unsign Solver(scriptPubKey, txType, vSolutions); vector<valtype> stack1; - EvalScript(stack1, scriptSig1, CTransaction(), 0, SCRIPT_VERIFY_STRICTENC, 0); + EvalScript(stack1, scriptSig1, CTransaction(), 0, SCRIPT_VERIFY_STRICTENC); vector<valtype> stack2; - EvalScript(stack2, scriptSig2, CTransaction(), 0, SCRIPT_VERIFY_STRICTENC, 0); + EvalScript(stack2, scriptSig2, CTransaction(), 0, SCRIPT_VERIFY_STRICTENC); return CombineSignatures(scriptPubKey, txTo, nIn, txType, vSolutions, stack1, stack2); } diff --git a/src/script/standard.cpp b/src/script/standard.cpp index bda4b8b0ae..407baf621d 100644 --- a/src/script/standard.cpp +++ b/src/script/standard.cpp @@ -252,3 +252,50 @@ bool ExtractDestinations(const CScript& scriptPubKey, txnouttype& typeRet, vecto return true; } + +namespace +{ +class CScriptVisitor : public boost::static_visitor<bool> +{ +private: + CScript *script; +public: + CScriptVisitor(CScript *scriptin) { script = scriptin; } + + bool operator()(const CNoDestination &dest) const { + script->clear(); + return false; + } + + bool operator()(const CKeyID &keyID) const { + script->clear(); + *script << OP_DUP << OP_HASH160 << keyID << OP_EQUALVERIFY << OP_CHECKSIG; + return true; + } + + bool operator()(const CScriptID &scriptID) const { + script->clear(); + *script << OP_HASH160 << scriptID << OP_EQUAL; + return true; + } +}; +} + +CScript GetScriptForDestination(const CTxDestination& dest) +{ + CScript script; + + boost::apply_visitor(CScriptVisitor(&script), dest); + return script; +} + +CScript GetScriptForMultisig(int nRequired, const std::vector<CPubKey>& keys) +{ + CScript script; + + script << CScript::EncodeOP_N(nRequired); + BOOST_FOREACH(const CPubKey& key, keys) + script << key; + script << CScript::EncodeOP_N(keys.size()) << OP_CHECKMULTISIG; + return script; +} diff --git a/src/script/standard.h b/src/script/standard.h index 6c17a9394e..ead79b82a2 100644 --- a/src/script/standard.h +++ b/src/script/standard.h @@ -45,6 +45,20 @@ enum txnouttype TX_NULL_DATA, }; +class CNoDestination { +public: + friend bool operator==(const CNoDestination &a, const CNoDestination &b) { return true; } + friend bool operator<(const CNoDestination &a, const CNoDestination &b) { return true; } +}; + +/** A txout script template with a specific destination. It is either: + * * CNoDestination: no destination set + * * CKeyID: TX_PUBKEYHASH destination + * * CScriptID: TX_SCRIPTHASH destination + * A CTxDestination is the internal data type encoded in a CBitcoinAddress + */ +typedef boost::variant<CNoDestination, CKeyID, CScriptID> CTxDestination; + const char* GetTxnOutputType(txnouttype t); bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, std::vector<std::vector<unsigned char> >& vSolutionsRet); @@ -53,4 +67,7 @@ bool IsStandard(const CScript& scriptPubKey, txnouttype& whichType); bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet); bool ExtractDestinations(const CScript& scriptPubKey, txnouttype& typeRet, std::vector<CTxDestination>& addressRet, int& nRequiredRet); +CScript GetScriptForDestination(const CTxDestination& dest); +CScript GetScriptForMultisig(int nRequired, const std::vector<CPubKey>& keys); + #endif // H_BITCOIN_SCRIPT_STANDARD diff --git a/src/sync.cpp b/src/sync.cpp index d424f7bc95..ef35c9d646 100644 --- a/src/sync.cpp +++ b/src/sync.cpp @@ -32,8 +32,7 @@ void PrintLockContention(const char* pszName, const char* pszFile, int nLine) // Complain if any thread tries to lock in a different order. // -struct CLockLocation -{ +struct CLockLocation { CLockLocation(const char* pszName, const char* pszFile, int nLine) { mutexName = pszName; @@ -43,7 +42,7 @@ struct CLockLocation std::string ToString() const { - return mutexName+" "+sourceFile+":"+itostr(sourceLine); + return mutexName + " " + sourceFile + ":" + itostr(sourceLine); } std::string MutexName() const { return mutexName; } @@ -54,7 +53,7 @@ private: int sourceLine; }; -typedef std::vector< std::pair<void*, CLockLocation> > LockStack; +typedef std::vector<std::pair<void*, CLockLocation> > LockStack; static boost::mutex dd_mutex; static std::map<std::pair<void*, void*>, LockStack> lockorders; @@ -65,17 +64,19 @@ static void potential_deadlock_detected(const std::pair<void*, void*>& mismatch, { LogPrintf("POTENTIAL DEADLOCK DETECTED\n"); LogPrintf("Previous lock order was:\n"); - BOOST_FOREACH(const PAIRTYPE(void*, CLockLocation)& i, s2) - { - if (i.first == mismatch.first) LogPrintf(" (1)"); - if (i.first == mismatch.second) LogPrintf(" (2)"); + BOOST_FOREACH (const PAIRTYPE(void*, CLockLocation) & i, s2) { + if (i.first == mismatch.first) + LogPrintf(" (1)"); + if (i.first == mismatch.second) + LogPrintf(" (2)"); LogPrintf(" %s\n", i.second.ToString()); } LogPrintf("Current lock order is:\n"); - BOOST_FOREACH(const PAIRTYPE(void*, CLockLocation)& i, s1) - { - if (i.first == mismatch.first) LogPrintf(" (1)"); - if (i.first == mismatch.second) LogPrintf(" (2)"); + BOOST_FOREACH (const PAIRTYPE(void*, CLockLocation) & i, s1) { + if (i.first == mismatch.first) + LogPrintf(" (1)"); + if (i.first == mismatch.second) + LogPrintf(" (2)"); LogPrintf(" %s\n", i.second.ToString()); } } @@ -91,8 +92,9 @@ static void push_lock(void* c, const CLockLocation& locklocation, bool fTry) (*lockstack).push_back(std::make_pair(c, locklocation)); if (!fTry) { - BOOST_FOREACH(const PAIRTYPE(void*, CLockLocation)& i, (*lockstack)) { - if (i.first == c) break; + BOOST_FOREACH (const PAIRTYPE(void*, CLockLocation) & i, (*lockstack)) { + if (i.first == c) + break; std::pair<void*, void*> p1 = std::make_pair(i.first, c); if (lockorders.count(p1)) @@ -100,8 +102,7 @@ static void push_lock(void* c, const CLockLocation& locklocation, bool fTry) lockorders[p1] = (*lockstack); std::pair<void*, void*> p2 = std::make_pair(c, i.first); - if (lockorders.count(p2)) - { + if (lockorders.count(p2)) { potential_deadlock_detected(p1, lockorders[p2], lockorders[p1]); break; } @@ -112,8 +113,7 @@ static void push_lock(void* c, const CLockLocation& locklocation, bool fTry) static void pop_lock() { - if (fDebug) - { + if (fDebug) { const CLockLocation& locklocation = (*lockstack).rbegin()->second; LogPrint("lock", "Unlocked: %s\n", locklocation.ToString()); } @@ -135,17 +135,17 @@ void LeaveCritical() std::string LocksHeld() { std::string result; - BOOST_FOREACH(const PAIRTYPE(void*, CLockLocation)&i, *lockstack) + BOOST_FOREACH (const PAIRTYPE(void*, CLockLocation) & i, *lockstack) result += i.second.ToString() + std::string("\n"); return result; } -void AssertLockHeldInternal(const char *pszName, const char* pszFile, int nLine, void *cs) +void AssertLockHeldInternal(const char* pszName, const char* pszFile, int nLine, void* cs) { - BOOST_FOREACH(const PAIRTYPE(void*, CLockLocation)&i, *lockstack) - if (i.first == cs) return; - fprintf(stderr, "Assertion failed: lock %s not held in %s:%i; locks held:\n%s", - pszName, pszFile, nLine, LocksHeld().c_str()); + BOOST_FOREACH (const PAIRTYPE(void*, CLockLocation) & i, *lockstack) + if (i.first == cs) + return; + fprintf(stderr, "Assertion failed: lock %s not held in %s:%i; locks held:\n%s", pszName, pszFile, nLine, LocksHeld().c_str()); abort(); } diff --git a/src/sync.h b/src/sync.h index 4b81b4bd32..cd0aa7b20e 100644 --- a/src/sync.h +++ b/src/sync.h @@ -48,7 +48,6 @@ LEAVE_CRITICAL_SECTION(mutex); // no RAII */ - /////////////////////////////// // // // THE ACTUAL IMPLEMENTATION // @@ -63,17 +62,17 @@ class LOCKABLE AnnotatedMixin : public PARENT public: void lock() EXCLUSIVE_LOCK_FUNCTION() { - PARENT::lock(); + PARENT::lock(); } void unlock() UNLOCK_FUNCTION() { - PARENT::unlock(); + PARENT::unlock(); } bool try_lock() EXCLUSIVE_TRYLOCK_FUNCTION(true) { - return PARENT::try_lock(); + return PARENT::try_lock(); } }; @@ -91,11 +90,13 @@ typedef boost::condition_variable CConditionVariable; void EnterCritical(const char* pszName, const char* pszFile, int nLine, void* cs, bool fTry = false); void LeaveCritical(); std::string LocksHeld(); -void AssertLockHeldInternal(const char* pszName, const char* pszFile, int nLine, void *cs); +void AssertLockHeldInternal(const char* pszName, const char* pszFile, int nLine, void* cs); #else -void static inline EnterCritical(const char* pszName, const char* pszFile, int nLine, void* cs, bool fTry = false) {} +void static inline EnterCritical(const char* pszName, const char* pszFile, int nLine, void* cs, bool fTry = false) +{ +} void static inline LeaveCritical() {} -void static inline AssertLockHeldInternal(const char* pszName, const char* pszFile, int nLine, void *cs) {} +void static inline AssertLockHeldInternal(const char* pszName, const char* pszFile, int nLine, void* cs) {} #endif #define AssertLockHeld(cs) AssertLockHeldInternal(#cs, __FILE__, __LINE__, &cs) @@ -104,7 +105,7 @@ void PrintLockContention(const char* pszName, const char* pszFile, int nLine); #endif /** Wrapper around boost::unique_lock<Mutex> */ -template<typename Mutex> +template <typename Mutex> class CMutexLock { private: @@ -114,11 +115,10 @@ private: { EnterCritical(pszName, pszFile, nLine, (void*)(lock.mutex())); #ifdef DEBUG_LOCKCONTENTION - if (!lock.try_lock()) - { + if (!lock.try_lock()) { PrintLockContention(pszName, pszFile, nLine); #endif - lock.lock(); + lock.lock(); #ifdef DEBUG_LOCKCONTENTION } #endif @@ -157,19 +157,19 @@ public: typedef CMutexLock<CCriticalSection> CCriticalBlock; #define LOCK(cs) CCriticalBlock criticalblock(cs, #cs, __FILE__, __LINE__) -#define LOCK2(cs1,cs2) CCriticalBlock criticalblock1(cs1, #cs1, __FILE__, __LINE__),criticalblock2(cs2, #cs2, __FILE__, __LINE__) -#define TRY_LOCK(cs,name) CCriticalBlock name(cs, #cs, __FILE__, __LINE__, true) +#define LOCK2(cs1, cs2) CCriticalBlock criticalblock1(cs1, #cs1, __FILE__, __LINE__), criticalblock2(cs2, #cs2, __FILE__, __LINE__) +#define TRY_LOCK(cs, name) CCriticalBlock name(cs, #cs, __FILE__, __LINE__, true) -#define ENTER_CRITICAL_SECTION(cs) \ - { \ +#define ENTER_CRITICAL_SECTION(cs) \ + { \ EnterCritical(#cs, __FILE__, __LINE__, (void*)(&cs)); \ - (cs).lock(); \ + (cs).lock(); \ } #define LEAVE_CRITICAL_SECTION(cs) \ - { \ - (cs).unlock(); \ - LeaveCritical(); \ + { \ + (cs).unlock(); \ + LeaveCritical(); \ } class CSemaphore @@ -182,7 +182,8 @@ private: public: CSemaphore(int init) : value(init) {} - void wait() { + void wait() + { boost::unique_lock<boost::mutex> lock(mutex); while (value < 1) { condition.wait(lock); @@ -190,7 +191,8 @@ public: value--; } - bool try_wait() { + bool try_wait() + { boost::unique_lock<boost::mutex> lock(mutex); if (value < 1) return false; @@ -198,7 +200,8 @@ public: return true; } - void post() { + void post() + { { boost::unique_lock<boost::mutex> lock(mutex); value++; @@ -211,31 +214,35 @@ public: class CSemaphoreGrant { private: - CSemaphore *sem; + CSemaphore* sem; bool fHaveGrant; public: - void Acquire() { + void Acquire() + { if (fHaveGrant) return; sem->wait(); fHaveGrant = true; } - void Release() { + void Release() + { if (!fHaveGrant) return; sem->post(); fHaveGrant = false; } - bool TryAcquire() { + bool TryAcquire() + { if (!fHaveGrant && sem->try_wait()) fHaveGrant = true; return fHaveGrant; } - void MoveTo(CSemaphoreGrant &grant) { + void MoveTo(CSemaphoreGrant& grant) + { grant.Release(); grant.sem = sem; grant.fHaveGrant = fHaveGrant; @@ -245,18 +252,21 @@ public: CSemaphoreGrant() : sem(NULL), fHaveGrant(false) {} - CSemaphoreGrant(CSemaphore &sema, bool fTry = false) : sem(&sema), fHaveGrant(false) { + CSemaphoreGrant(CSemaphore& sema, bool fTry = false) : sem(&sema), fHaveGrant(false) + { if (fTry) TryAcquire(); else Acquire(); } - ~CSemaphoreGrant() { + ~CSemaphoreGrant() + { Release(); } - operator bool() { + operator bool() + { return fHaveGrant; } }; diff --git a/src/test/DoS_tests.cpp b/src/test/DoS_tests.cpp index e019674816..7bec12b665 100644 --- a/src/test/DoS_tests.cpp +++ b/src/test/DoS_tests.cpp @@ -27,7 +27,11 @@ extern bool AddOrphanTx(const CTransaction& tx, NodeId peer); extern void EraseOrphansFor(NodeId peer); extern unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans); -extern std::map<uint256, CTransaction> mapOrphanTransactions; +struct COrphanTx { + CTransaction tx; + NodeId fromPeer; +}; +extern std::map<uint256, COrphanTx> mapOrphanTransactions; extern std::map<uint256, std::set<uint256> > mapOrphanTransactionsByPrev; CService ip(uint32_t i) @@ -149,11 +153,11 @@ BOOST_AUTO_TEST_CASE(DoS_checknbits) CTransaction RandomOrphan() { - std::map<uint256, CTransaction>::iterator it; + std::map<uint256, COrphanTx>::iterator it; it = mapOrphanTransactions.lower_bound(GetRandHash()); if (it == mapOrphanTransactions.end()) it = mapOrphanTransactions.begin(); - return it->second; + return it->second.tx; } BOOST_AUTO_TEST_CASE(DoS_mapOrphans) @@ -173,7 +177,7 @@ BOOST_AUTO_TEST_CASE(DoS_mapOrphans) tx.vin[0].scriptSig << OP_1; tx.vout.resize(1); tx.vout[0].nValue = 1*CENT; - tx.vout[0].scriptPubKey.SetDestination(key.GetPubKey().GetID()); + tx.vout[0].scriptPubKey = GetScriptForDestination(key.GetPubKey().GetID()); AddOrphanTx(tx, i); } @@ -189,7 +193,7 @@ BOOST_AUTO_TEST_CASE(DoS_mapOrphans) tx.vin[0].prevout.hash = txPrev.GetHash(); tx.vout.resize(1); tx.vout[0].nValue = 1*CENT; - tx.vout[0].scriptPubKey.SetDestination(key.GetPubKey().GetID()); + tx.vout[0].scriptPubKey = GetScriptForDestination(key.GetPubKey().GetID()); SignSignature(keystore, txPrev, tx, 0); AddOrphanTx(tx, i); @@ -203,7 +207,7 @@ BOOST_AUTO_TEST_CASE(DoS_mapOrphans) CMutableTransaction tx; tx.vout.resize(1); tx.vout[0].nValue = 1*CENT; - tx.vout[0].scriptPubKey.SetDestination(key.GetPubKey().GetID()); + tx.vout[0].scriptPubKey = GetScriptForDestination(key.GetPubKey().GetID()); tx.vin.resize(500); for (unsigned int j = 0; j < tx.vin.size(); j++) { diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp index 47977cf295..9e4669eba9 100644 --- a/src/test/miner_tests.cpp +++ b/src/test/miner_tests.cpp @@ -170,7 +170,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) tx.vin[0].scriptSig = CScript() << OP_1; tx.vout[0].nValue = 4900000000LL; script = CScript() << OP_0; - tx.vout[0].scriptPubKey.SetDestination(script.GetID()); + tx.vout[0].scriptPubKey = GetScriptForDestination(script.GetID()); hash = tx.GetHash(); mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11)); tx.vin[0].prevout.hash = hash; diff --git a/src/test/multisig_tests.cpp b/src/test/multisig_tests.cpp index 91dfa39505..cb37740068 100644 --- a/src/test/multisig_tests.cpp +++ b/src/test/multisig_tests.cpp @@ -82,19 +82,19 @@ BOOST_AUTO_TEST_CASE(multisig_verify) keys.clear(); keys += key[0],key[1]; // magic operator+= from boost.assign s = sign_multisig(a_and_b, keys, txTo[0], 0); - BOOST_CHECK(VerifyScript(s, a_and_b, txTo[0], 0, flags, 0)); + BOOST_CHECK(VerifyScript(s, a_and_b, txTo[0], 0, flags)); for (int i = 0; i < 4; i++) { keys.clear(); keys += key[i]; s = sign_multisig(a_and_b, keys, txTo[0], 0); - BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, txTo[0], 0, flags, 0), strprintf("a&b 1: %d", i)); + BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, txTo[0], 0, flags), strprintf("a&b 1: %d", i)); keys.clear(); keys += key[1],key[i]; s = sign_multisig(a_and_b, keys, txTo[0], 0); - BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, txTo[0], 0, flags, 0), strprintf("a&b 2: %d", i)); + BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, txTo[0], 0, flags), strprintf("a&b 2: %d", i)); } // Test a OR b: @@ -104,16 +104,16 @@ BOOST_AUTO_TEST_CASE(multisig_verify) keys += key[i]; s = sign_multisig(a_or_b, keys, txTo[1], 0); if (i == 0 || i == 1) - BOOST_CHECK_MESSAGE(VerifyScript(s, a_or_b, txTo[1], 0, flags, 0), strprintf("a|b: %d", i)); + BOOST_CHECK_MESSAGE(VerifyScript(s, a_or_b, txTo[1], 0, flags), strprintf("a|b: %d", i)); else - BOOST_CHECK_MESSAGE(!VerifyScript(s, a_or_b, txTo[1], 0, flags, 0), strprintf("a|b: %d", i)); + BOOST_CHECK_MESSAGE(!VerifyScript(s, a_or_b, txTo[1], 0, flags), strprintf("a|b: %d", i)); } s.clear(); s << OP_0 << OP_0; - BOOST_CHECK(!VerifyScript(s, a_or_b, txTo[1], 0, flags, 0)); + BOOST_CHECK(!VerifyScript(s, a_or_b, txTo[1], 0, flags)); s.clear(); s << OP_0 << OP_1; - BOOST_CHECK(!VerifyScript(s, a_or_b, txTo[1], 0, flags, 0)); + BOOST_CHECK(!VerifyScript(s, a_or_b, txTo[1], 0, flags)); for (int i = 0; i < 4; i++) @@ -123,9 +123,9 @@ BOOST_AUTO_TEST_CASE(multisig_verify) keys += key[i],key[j]; s = sign_multisig(escrow, keys, txTo[2], 0); if (i < j && i < 3 && j < 3) - BOOST_CHECK_MESSAGE(VerifyScript(s, escrow, txTo[2], 0, flags, 0), strprintf("escrow 1: %d %d", i, j)); + BOOST_CHECK_MESSAGE(VerifyScript(s, escrow, txTo[2], 0, flags), strprintf("escrow 1: %d %d", i, j)); else - BOOST_CHECK_MESSAGE(!VerifyScript(s, escrow, txTo[2], 0, flags, 0), strprintf("escrow 2: %d %d", i, j)); + BOOST_CHECK_MESSAGE(!VerifyScript(s, escrow, txTo[2], 0, flags), strprintf("escrow 2: %d %d", i, j)); } } diff --git a/src/test/script_P2SH_tests.cpp b/src/test/script_P2SH_tests.cpp index f99002017f..e6cf00c2d0 100644 --- a/src/test/script_P2SH_tests.cpp +++ b/src/test/script_P2SH_tests.cpp @@ -42,7 +42,7 @@ Verify(const CScript& scriptSig, const CScript& scriptPubKey, bool fStrict) txTo.vin[0].scriptSig = scriptSig; txTo.vout[0].nValue = 1; - return VerifyScript(scriptSig, scriptPubKey, txTo, 0, fStrict ? SCRIPT_VERIFY_P2SH : SCRIPT_VERIFY_NONE, 0); + return VerifyScript(scriptSig, scriptPubKey, txTo, 0, fStrict ? SCRIPT_VERIFY_P2SH : SCRIPT_VERIFY_NONE); } @@ -68,14 +68,14 @@ BOOST_AUTO_TEST_CASE(sign) // different keys, straight/P2SH, pubkey/pubkeyhash CScript standardScripts[4]; standardScripts[0] << key[0].GetPubKey() << OP_CHECKSIG; - standardScripts[1].SetDestination(key[1].GetPubKey().GetID()); + standardScripts[1] = GetScriptForDestination(key[1].GetPubKey().GetID()); standardScripts[2] << key[1].GetPubKey() << OP_CHECKSIG; - standardScripts[3].SetDestination(key[2].GetPubKey().GetID()); + standardScripts[3] = GetScriptForDestination(key[2].GetPubKey().GetID()); CScript evalScripts[4]; for (int i = 0; i < 4; i++) { keystore.AddCScript(standardScripts[i]); - evalScripts[i].SetDestination(standardScripts[i].GetID()); + evalScripts[i] = GetScriptForDestination(standardScripts[i].GetID()); } CMutableTransaction txFrom; // Funding transaction: @@ -113,7 +113,7 @@ BOOST_AUTO_TEST_CASE(sign) { CScript sigSave = txTo[i].vin[0].scriptSig; txTo[i].vin[0].scriptSig = txTo[j].vin[0].scriptSig; - bool sigOK = VerifySignature(CCoins(txFrom, 0), txTo[i], 0, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC, 0); + bool sigOK = CScriptCheck(CCoins(txFrom, 0), txTo[i], 0, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC)(); if (i == j) BOOST_CHECK_MESSAGE(sigOK, strprintf("VerifySignature %d %d", i, j)); else @@ -129,8 +129,7 @@ BOOST_AUTO_TEST_CASE(norecurse) CScript invalidAsScript; invalidAsScript << OP_INVALIDOPCODE << OP_INVALIDOPCODE; - CScript p2sh; - p2sh.SetDestination(invalidAsScript.GetID()); + CScript p2sh = GetScriptForDestination(invalidAsScript.GetID()); CScript scriptSig; scriptSig << Serialize(invalidAsScript); @@ -140,8 +139,7 @@ BOOST_AUTO_TEST_CASE(norecurse) // Try to recur, and verification should succeed because // the inner HASH160 <> EQUAL should only check the hash: - CScript p2sh2; - p2sh2.SetDestination(p2sh.GetID()); + CScript p2sh2 = GetScriptForDestination(p2sh.GetID()); CScript scriptSig2; scriptSig2 << Serialize(invalidAsScript) << Serialize(p2sh); @@ -163,15 +161,15 @@ BOOST_AUTO_TEST_CASE(set) } CScript inner[4]; - inner[0].SetDestination(key[0].GetPubKey().GetID()); - inner[1].SetMultisig(2, std::vector<CPubKey>(keys.begin(), keys.begin()+2)); - inner[2].SetMultisig(1, std::vector<CPubKey>(keys.begin(), keys.begin()+2)); - inner[3].SetMultisig(2, std::vector<CPubKey>(keys.begin(), keys.begin()+3)); + inner[0] = GetScriptForDestination(key[0].GetPubKey().GetID()); + inner[1] = GetScriptForMultisig(2, std::vector<CPubKey>(keys.begin(), keys.begin()+2)); + inner[2] = GetScriptForMultisig(1, std::vector<CPubKey>(keys.begin(), keys.begin()+2)); + inner[3] = GetScriptForMultisig(2, std::vector<CPubKey>(keys.begin(), keys.begin()+3)); CScript outer[4]; for (int i = 0; i < 4; i++) { - outer[i].SetDestination(inner[i].GetID()); + outer[i] = GetScriptForDestination(inner[i].GetID()); keystore.AddCScript(inner[i]); } @@ -244,8 +242,7 @@ BOOST_AUTO_TEST_CASE(switchover) CScript scriptSig; scriptSig << Serialize(notValid); - CScript fund; - fund.SetDestination(notValid.GetID()); + CScript fund = GetScriptForDestination(notValid.GetID()); // Validation should succeed under old rules (hash is correct): @@ -274,11 +271,11 @@ BOOST_AUTO_TEST_CASE(AreInputsStandard) txFrom.vout.resize(7); // First three are standard: - CScript pay1; pay1.SetDestination(key[0].GetPubKey().GetID()); + CScript pay1 = GetScriptForDestination(key[0].GetPubKey().GetID()); keystore.AddCScript(pay1); - CScript pay1of3; pay1of3.SetMultisig(1, keys); + CScript pay1of3 = GetScriptForMultisig(1, keys); - txFrom.vout[0].scriptPubKey.SetDestination(pay1.GetID()); // P2SH (OP_CHECKSIG) + txFrom.vout[0].scriptPubKey = GetScriptForDestination(pay1.GetID()); // P2SH (OP_CHECKSIG) txFrom.vout[0].nValue = 1000; txFrom.vout[1].scriptPubKey = pay1; // ordinary OP_CHECKSIG txFrom.vout[1].nValue = 2000; @@ -293,7 +290,7 @@ BOOST_AUTO_TEST_CASE(AreInputsStandard) oneAndTwo << OP_2 << key[3].GetPubKey() << key[4].GetPubKey() << key[5].GetPubKey(); oneAndTwo << OP_3 << OP_CHECKMULTISIG; keystore.AddCScript(oneAndTwo); - txFrom.vout[3].scriptPubKey.SetDestination(oneAndTwo.GetID()); + txFrom.vout[3].scriptPubKey = GetScriptForDestination(oneAndTwo.GetID()); txFrom.vout[3].nValue = 4000; // vout[4] is max sigops: @@ -302,17 +299,17 @@ BOOST_AUTO_TEST_CASE(AreInputsStandard) fifteenSigops << key[i%3].GetPubKey(); fifteenSigops << OP_15 << OP_CHECKMULTISIG; keystore.AddCScript(fifteenSigops); - txFrom.vout[4].scriptPubKey.SetDestination(fifteenSigops.GetID()); + txFrom.vout[4].scriptPubKey = GetScriptForDestination(fifteenSigops.GetID()); txFrom.vout[4].nValue = 5000; // vout[5/6] are non-standard because they exceed MAX_P2SH_SIGOPS CScript sixteenSigops; sixteenSigops << OP_16 << OP_CHECKMULTISIG; keystore.AddCScript(sixteenSigops); - txFrom.vout[5].scriptPubKey.SetDestination(fifteenSigops.GetID()); + txFrom.vout[5].scriptPubKey = GetScriptForDestination(fifteenSigops.GetID()); txFrom.vout[5].nValue = 5000; CScript twentySigops; twentySigops << OP_CHECKMULTISIG; keystore.AddCScript(twentySigops); - txFrom.vout[6].scriptPubKey.SetDestination(twentySigops.GetID()); + txFrom.vout[6].scriptPubKey = GetScriptForDestination(twentySigops.GetID()); txFrom.vout[6].nValue = 6000; @@ -320,7 +317,7 @@ BOOST_AUTO_TEST_CASE(AreInputsStandard) CMutableTransaction txTo; txTo.vout.resize(1); - txTo.vout[0].scriptPubKey.SetDestination(key[1].GetPubKey().GetID()); + txTo.vout[0].scriptPubKey = GetScriptForDestination(key[1].GetPubKey().GetID()); txTo.vin.resize(5); for (int i = 0; i < 5; i++) @@ -352,7 +349,7 @@ BOOST_AUTO_TEST_CASE(AreInputsStandard) CMutableTransaction txToNonStd1; txToNonStd1.vout.resize(1); - txToNonStd1.vout[0].scriptPubKey.SetDestination(key[1].GetPubKey().GetID()); + txToNonStd1.vout[0].scriptPubKey = GetScriptForDestination(key[1].GetPubKey().GetID()); txToNonStd1.vout[0].nValue = 1000; txToNonStd1.vin.resize(1); txToNonStd1.vin[0].prevout.n = 5; @@ -364,7 +361,7 @@ BOOST_AUTO_TEST_CASE(AreInputsStandard) CMutableTransaction txToNonStd2; txToNonStd2.vout.resize(1); - txToNonStd2.vout[0].scriptPubKey.SetDestination(key[1].GetPubKey().GetID()); + txToNonStd2.vout[0].scriptPubKey = GetScriptForDestination(key[1].GetPubKey().GetID()); txToNonStd2.vout[0].nValue = 1000; txToNonStd2.vin.resize(1); txToNonStd2.vin[0].prevout.n = 6; diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index bc610778c4..cb543a0cf1 100644 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -77,7 +77,7 @@ BOOST_AUTO_TEST_CASE(script_valid) unsigned int scriptflags = ParseScriptFlags(test[2].get_str()); CTransaction tx; - BOOST_CHECK_MESSAGE(VerifyScript(scriptSig, scriptPubKey, tx, 0, scriptflags, SIGHASH_NONE), strTest); + BOOST_CHECK_MESSAGE(VerifyScript(scriptSig, scriptPubKey, tx, 0, scriptflags), strTest); } } @@ -102,7 +102,7 @@ BOOST_AUTO_TEST_CASE(script_invalid) unsigned int scriptflags = ParseScriptFlags(test[2].get_str()); CTransaction tx; - BOOST_CHECK_MESSAGE(!VerifyScript(scriptSig, scriptPubKey, tx, 0, scriptflags, SIGHASH_NONE), strTest); + BOOST_CHECK_MESSAGE(!VerifyScript(scriptSig, scriptPubKey, tx, 0, scriptflags), strTest); } } @@ -116,18 +116,18 @@ BOOST_AUTO_TEST_CASE(script_PushData) static const unsigned char pushdata4[] = { OP_PUSHDATA4, 1, 0, 0, 0, 0x5a }; vector<vector<unsigned char> > directStack; - BOOST_CHECK(EvalScript(directStack, CScript(&direct[0], &direct[sizeof(direct)]), CTransaction(), 0, true, 0)); + BOOST_CHECK(EvalScript(directStack, CScript(&direct[0], &direct[sizeof(direct)]), CTransaction(), 0, true)); vector<vector<unsigned char> > pushdata1Stack; - BOOST_CHECK(EvalScript(pushdata1Stack, CScript(&pushdata1[0], &pushdata1[sizeof(pushdata1)]), CTransaction(), 0, true, 0)); + BOOST_CHECK(EvalScript(pushdata1Stack, CScript(&pushdata1[0], &pushdata1[sizeof(pushdata1)]), CTransaction(), 0, true)); BOOST_CHECK(pushdata1Stack == directStack); vector<vector<unsigned char> > pushdata2Stack; - BOOST_CHECK(EvalScript(pushdata2Stack, CScript(&pushdata2[0], &pushdata2[sizeof(pushdata2)]), CTransaction(), 0, true, 0)); + BOOST_CHECK(EvalScript(pushdata2Stack, CScript(&pushdata2[0], &pushdata2[sizeof(pushdata2)]), CTransaction(), 0, true)); BOOST_CHECK(pushdata2Stack == directStack); vector<vector<unsigned char> > pushdata4Stack; - BOOST_CHECK(EvalScript(pushdata4Stack, CScript(&pushdata4[0], &pushdata4[sizeof(pushdata4)]), CTransaction(), 0, true, 0)); + BOOST_CHECK(EvalScript(pushdata4Stack, CScript(&pushdata4[0], &pushdata4[sizeof(pushdata4)]), CTransaction(), 0, true)); BOOST_CHECK(pushdata4Stack == directStack); } @@ -185,15 +185,15 @@ BOOST_AUTO_TEST_CASE(script_CHECKMULTISIG12) txTo12.vout[0].nValue = 1; CScript goodsig1 = sign_multisig(scriptPubKey12, key1, txTo12); - BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey12, txTo12, 0, flags, 0)); + BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey12, txTo12, 0, flags)); txTo12.vout[0].nValue = 2; - BOOST_CHECK(!VerifyScript(goodsig1, scriptPubKey12, txTo12, 0, flags, 0)); + BOOST_CHECK(!VerifyScript(goodsig1, scriptPubKey12, txTo12, 0, flags)); CScript goodsig2 = sign_multisig(scriptPubKey12, key2, txTo12); - BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey12, txTo12, 0, flags, 0)); + BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey12, txTo12, 0, flags)); CScript badsig1 = sign_multisig(scriptPubKey12, key3, txTo12); - BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey12, txTo12, 0, flags, 0)); + BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey12, txTo12, 0, flags)); } BOOST_AUTO_TEST_CASE(script_CHECKMULTISIG23) @@ -221,46 +221,46 @@ BOOST_AUTO_TEST_CASE(script_CHECKMULTISIG23) std::vector<CKey> keys; keys.push_back(key1); keys.push_back(key2); CScript goodsig1 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey23, txTo23, 0, flags, 0)); + BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey23, txTo23, 0, flags)); keys.clear(); keys.push_back(key1); keys.push_back(key3); CScript goodsig2 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey23, txTo23, 0, flags, 0)); + BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey23, txTo23, 0, flags)); keys.clear(); keys.push_back(key2); keys.push_back(key3); CScript goodsig3 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(VerifyScript(goodsig3, scriptPubKey23, txTo23, 0, flags, 0)); + BOOST_CHECK(VerifyScript(goodsig3, scriptPubKey23, txTo23, 0, flags)); keys.clear(); keys.push_back(key2); keys.push_back(key2); // Can't re-use sig CScript badsig1 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey23, txTo23, 0, flags, 0)); + BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey23, txTo23, 0, flags)); keys.clear(); keys.push_back(key2); keys.push_back(key1); // sigs must be in correct order CScript badsig2 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(!VerifyScript(badsig2, scriptPubKey23, txTo23, 0, flags, 0)); + BOOST_CHECK(!VerifyScript(badsig2, scriptPubKey23, txTo23, 0, flags)); keys.clear(); keys.push_back(key3); keys.push_back(key2); // sigs must be in correct order CScript badsig3 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(!VerifyScript(badsig3, scriptPubKey23, txTo23, 0, flags, 0)); + BOOST_CHECK(!VerifyScript(badsig3, scriptPubKey23, txTo23, 0, flags)); keys.clear(); keys.push_back(key4); keys.push_back(key2); // sigs must match pubkeys CScript badsig4 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(!VerifyScript(badsig4, scriptPubKey23, txTo23, 0, flags, 0)); + BOOST_CHECK(!VerifyScript(badsig4, scriptPubKey23, txTo23, 0, flags)); keys.clear(); keys.push_back(key1); keys.push_back(key4); // sigs must match pubkeys CScript badsig5 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(!VerifyScript(badsig5, scriptPubKey23, txTo23, 0, flags, 0)); + BOOST_CHECK(!VerifyScript(badsig5, scriptPubKey23, txTo23, 0, flags)); keys.clear(); // Must have signatures CScript badsig6 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(!VerifyScript(badsig6, scriptPubKey23, txTo23, 0, flags, 0)); + BOOST_CHECK(!VerifyScript(badsig6, scriptPubKey23, txTo23, 0, flags)); } BOOST_AUTO_TEST_CASE(script_combineSigs) @@ -280,7 +280,7 @@ BOOST_AUTO_TEST_CASE(script_combineSigs) CMutableTransaction txFrom; txFrom.vout.resize(1); - txFrom.vout[0].scriptPubKey.SetDestination(keys[0].GetPubKey().GetID()); + txFrom.vout[0].scriptPubKey = GetScriptForDestination(keys[0].GetPubKey().GetID()); CScript& scriptPubKey = txFrom.vout[0].scriptPubKey; CMutableTransaction txTo; txTo.vin.resize(1); @@ -309,7 +309,7 @@ BOOST_AUTO_TEST_CASE(script_combineSigs) // P2SH, single-signature case: CScript pkSingle; pkSingle << keys[0].GetPubKey() << OP_CHECKSIG; keystore.AddCScript(pkSingle); - scriptPubKey.SetDestination(pkSingle.GetID()); + scriptPubKey = GetScriptForDestination(pkSingle.GetID()); SignSignature(keystore, txFrom, txTo, 0); combined = CombineSignatures(scriptPubKey, txTo, 0, scriptSig, empty); BOOST_CHECK(combined == scriptSig); @@ -327,7 +327,7 @@ BOOST_AUTO_TEST_CASE(script_combineSigs) BOOST_CHECK(combined == scriptSig); // Hardest case: Multisig 2-of-3 - scriptPubKey.SetMultisig(2, pubkeys); + scriptPubKey = GetScriptForMultisig(2, pubkeys); keystore.AddCScript(scriptPubKey); SignSignature(keystore, txFrom, txTo, 0); combined = CombineSignatures(scriptPubKey, txTo, 0, scriptSig, empty); diff --git a/src/test/sigopcount_tests.cpp b/src/test/sigopcount_tests.cpp index 2d10c356ac..62a6cd63d6 100644 --- a/src/test/sigopcount_tests.cpp +++ b/src/test/sigopcount_tests.cpp @@ -4,6 +4,7 @@ #include "key.h" #include "script/script.h" +#include "script/standard.h" #include "uint256.h" #include <vector> @@ -37,8 +38,7 @@ BOOST_AUTO_TEST_CASE(GetSigOpCount) BOOST_CHECK_EQUAL(s1.GetSigOpCount(true), 3U); BOOST_CHECK_EQUAL(s1.GetSigOpCount(false), 21U); - CScript p2sh; - p2sh.SetDestination(s1.GetID()); + CScript p2sh = GetScriptForDestination(s1.GetID()); CScript scriptSig; scriptSig << OP_0 << Serialize(s1); BOOST_CHECK_EQUAL(p2sh.GetSigOpCount(scriptSig), 3U); @@ -50,12 +50,11 @@ BOOST_AUTO_TEST_CASE(GetSigOpCount) k.MakeNewKey(true); keys.push_back(k.GetPubKey()); } - CScript s2; - s2.SetMultisig(1, keys); + CScript s2 = GetScriptForMultisig(1, keys); BOOST_CHECK_EQUAL(s2.GetSigOpCount(true), 3U); BOOST_CHECK_EQUAL(s2.GetSigOpCount(false), 20U); - p2sh.SetDestination(s2.GetID()); + p2sh = GetScriptForDestination(s2.GetID()); BOOST_CHECK_EQUAL(p2sh.GetSigOpCount(true), 0U); BOOST_CHECK_EQUAL(p2sh.GetSigOpCount(false), 0U); CScript scriptSig2; diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp index 21377395cf..41d8ee9f19 100644 --- a/src/test/transaction_tests.cpp +++ b/src/test/transaction_tests.cpp @@ -121,7 +121,7 @@ BOOST_AUTO_TEST_CASE(tx_valid) unsigned int verify_flags = ParseScriptFlags(test[2].get_str()); BOOST_CHECK_MESSAGE(VerifyScript(tx.vin[i].scriptSig, mapprevOutScriptPubKeys[tx.vin[i].prevout], - tx, i, verify_flags, 0), + tx, i, verify_flags), strTest); } } @@ -194,7 +194,7 @@ BOOST_AUTO_TEST_CASE(tx_invalid) unsigned int verify_flags = ParseScriptFlags(test[2].get_str()); fValid = VerifyScript(tx.vin[i].scriptSig, mapprevOutScriptPubKeys[tx.vin[i].prevout], - tx, i, verify_flags, 0); + tx, i, verify_flags); } BOOST_CHECK_MESSAGE(!fValid, strTest); @@ -248,9 +248,9 @@ SetupDummyInputs(CBasicKeyStore& keystoreRet, CCoinsView & coinsRet) dummyTransactions[1].vout.resize(2); dummyTransactions[1].vout[0].nValue = 21*CENT; - dummyTransactions[1].vout[0].scriptPubKey.SetDestination(key[2].GetPubKey().GetID()); + dummyTransactions[1].vout[0].scriptPubKey = GetScriptForDestination(key[2].GetPubKey().GetID()); dummyTransactions[1].vout[1].nValue = 22*CENT; - dummyTransactions[1].vout[1].scriptPubKey.SetDestination(key[3].GetPubKey().GetID()); + dummyTransactions[1].vout[1].scriptPubKey = GetScriptForDestination(key[3].GetPubKey().GetID()); coinsRet.SetCoins(dummyTransactions[1].GetHash(), CCoins(dummyTransactions[1], 0)); return dummyTransactions; @@ -307,7 +307,7 @@ BOOST_AUTO_TEST_CASE(test_IsStandard) t.vout[0].nValue = 90*CENT; CKey key; key.MakeNewKey(true); - t.vout[0].scriptPubKey.SetDestination(key.GetPubKey().GetID()); + t.vout[0].scriptPubKey = GetScriptForDestination(key.GetPubKey().GetID()); string reason; BOOST_CHECK(IsStandardTx(t, reason)); diff --git a/src/threadsafety.h b/src/threadsafety.h index 9ee39372e1..7515d050e7 100644 --- a/src/threadsafety.h +++ b/src/threadsafety.h @@ -13,24 +13,24 @@ // See http://clang.llvm.org/docs/LanguageExtensions.html#threadsafety // for documentation. The clang compiler can do advanced static analysis // of locking when given the -Wthread-safety option. -#define LOCKABLE __attribute__ ((lockable)) -#define SCOPED_LOCKABLE __attribute__ ((scoped_lockable)) -#define GUARDED_BY(x) __attribute__ ((guarded_by(x))) -#define GUARDED_VAR __attribute__ ((guarded_var)) -#define PT_GUARDED_BY(x) __attribute__ ((pt_guarded_by(x))) -#define PT_GUARDED_VAR __attribute__ ((pt_guarded_var)) -#define ACQUIRED_AFTER(...) __attribute__ ((acquired_after(__VA_ARGS__))) -#define ACQUIRED_BEFORE(...) __attribute__ ((acquired_before(__VA_ARGS__))) -#define EXCLUSIVE_LOCK_FUNCTION(...) __attribute__ ((exclusive_lock_function(__VA_ARGS__))) -#define SHARED_LOCK_FUNCTION(...) __attribute__ ((shared_lock_function(__VA_ARGS__))) -#define EXCLUSIVE_TRYLOCK_FUNCTION(...) __attribute__ ((exclusive_trylock_function(__VA_ARGS__))) -#define SHARED_TRYLOCK_FUNCTION(...) __attribute__ ((shared_trylock_function(__VA_ARGS__))) -#define UNLOCK_FUNCTION(...) __attribute__ ((unlock_function(__VA_ARGS__))) -#define LOCK_RETURNED(x) __attribute__ ((lock_returned(x))) -#define LOCKS_EXCLUDED(...) __attribute__ ((locks_excluded(__VA_ARGS__))) -#define EXCLUSIVE_LOCKS_REQUIRED(...) __attribute__ ((exclusive_locks_required(__VA_ARGS__))) -#define SHARED_LOCKS_REQUIRED(...) __attribute__ ((shared_locks_required(__VA_ARGS__))) -#define NO_THREAD_SAFETY_ANALYSIS __attribute__ ((no_thread_safety_analysis)) +#define LOCKABLE __attribute__((lockable)) +#define SCOPED_LOCKABLE __attribute__((scoped_lockable)) +#define GUARDED_BY(x) __attribute__((guarded_by(x))) +#define GUARDED_VAR __attribute__((guarded_var)) +#define PT_GUARDED_BY(x) __attribute__((pt_guarded_by(x))) +#define PT_GUARDED_VAR __attribute__((pt_guarded_var)) +#define ACQUIRED_AFTER(...) __attribute__((acquired_after(__VA_ARGS__))) +#define ACQUIRED_BEFORE(...) __attribute__((acquired_before(__VA_ARGS__))) +#define EXCLUSIVE_LOCK_FUNCTION(...) __attribute__((exclusive_lock_function(__VA_ARGS__))) +#define SHARED_LOCK_FUNCTION(...) __attribute__((shared_lock_function(__VA_ARGS__))) +#define EXCLUSIVE_TRYLOCK_FUNCTION(...) __attribute__((exclusive_trylock_function(__VA_ARGS__))) +#define SHARED_TRYLOCK_FUNCTION(...) __attribute__((shared_trylock_function(__VA_ARGS__))) +#define UNLOCK_FUNCTION(...) __attribute__((unlock_function(__VA_ARGS__))) +#define LOCK_RETURNED(x) __attribute__((lock_returned(x))) +#define LOCKS_EXCLUDED(...) __attribute__((locks_excluded(__VA_ARGS__))) +#define EXCLUSIVE_LOCKS_REQUIRED(...) __attribute__((exclusive_locks_required(__VA_ARGS__))) +#define SHARED_LOCKS_REQUIRED(...) __attribute__((shared_locks_required(__VA_ARGS__))) +#define NO_THREAD_SAFETY_ANALYSIS __attribute__((no_thread_safety_analysis)) #else #define LOCKABLE #define SCOPED_LOCKABLE @@ -50,6 +50,6 @@ #define EXCLUSIVE_LOCKS_REQUIRED(...) #define SHARED_LOCKS_REQUIRED(...) #define NO_THREAD_SAFETY_ANALYSIS -#endif // __GNUC__ +#endif // __GNUC__ -#endif // BITCOIN_THREADSAFETY_H +#endif // BITCOIN_THREADSAFETY_H diff --git a/src/timedata.h b/src/timedata.h index 155f6872da..2c20f4efd5 100644 --- a/src/timedata.h +++ b/src/timedata.h @@ -15,15 +15,16 @@ class CNetAddr; /** Median filter over a stream of values. * Returns the median of the last N numbers */ -template <typename T> class CMedianFilter +template <typename T> +class CMedianFilter { private: std::vector<T> vValues; std::vector<T> vSorted; unsigned int nSize; + public: - CMedianFilter(unsigned int size, T initial_value): - nSize(size) + CMedianFilter(unsigned int size, T initial_value) : nSize(size) { vValues.reserve(size); vValues.push_back(initial_value); @@ -32,8 +33,7 @@ public: void input(T value) { - if(vValues.size() == nSize) - { + if (vValues.size() == nSize) { vValues.erase(vValues.begin()); } vValues.push_back(value); @@ -46,14 +46,13 @@ public: T median() const { int size = vSorted.size(); - assert(size>0); - if(size & 1) // Odd number of elements + assert(size > 0); + if (size & 1) // Odd number of elements { - return vSorted[size/2]; - } - else // Even number of elements + return vSorted[size / 2]; + } else // Even number of elements { - return (vSorted[size/2-1] + vSorted[size/2]) / 2; + return (vSorted[size / 2 - 1] + vSorted[size / 2]) / 2; } } @@ -62,7 +61,7 @@ public: return vValues.size(); } - std::vector<T> sorted () const + std::vector<T> sorted() const { return vSorted; } diff --git a/src/txmempool.cpp b/src/txmempool.cpp index 404cca2373..52d07bf6a0 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -13,7 +13,7 @@ using namespace std; CTxMemPoolEntry::CTxMemPoolEntry(): - nFee(0), nTxSize(0), nTime(0), dPriority(0.0) + nFee(0), nTxSize(0), nModSize(0), nTime(0), dPriority(0.0) { nHeight = MEMPOOL_HEIGHT; } diff --git a/src/uint256.cpp b/src/uint256.cpp index feda0ca5a9..79406f2475 100644 --- a/src/uint256.cpp +++ b/src/uint256.cpp @@ -10,13 +10,13 @@ #include <stdio.h> #include <string.h> -template<unsigned int BITS> +template <unsigned int BITS> base_uint<BITS>::base_uint(const std::string& str) { SetHex(str); } -template<unsigned int BITS> +template <unsigned int BITS> base_uint<BITS>::base_uint(const std::vector<unsigned char>& vch) { if (vch.size() != sizeof(pn)) @@ -24,7 +24,7 @@ base_uint<BITS>::base_uint(const std::vector<unsigned char>& vch) memcpy(pn, &vch[0], sizeof(pn)); } -template<unsigned int BITS> +template <unsigned int BITS> base_uint<BITS>& base_uint<BITS>::operator<<=(unsigned int shift) { base_uint<BITS> a(*this); @@ -33,15 +33,15 @@ base_uint<BITS>& base_uint<BITS>::operator<<=(unsigned int shift) int k = shift / 32; shift = shift % 32; for (int i = 0; i < WIDTH; i++) { - if (i+k+1 < WIDTH && shift != 0) - pn[i+k+1] |= (a.pn[i] >> (32-shift)); - if (i+k < WIDTH) - pn[i+k] |= (a.pn[i] << shift); + if (i + k + 1 < WIDTH && shift != 0) + pn[i + k + 1] |= (a.pn[i] >> (32 - shift)); + if (i + k < WIDTH) + pn[i + k] |= (a.pn[i] << shift); } return *this; } -template<unsigned int BITS> +template <unsigned int BITS> base_uint<BITS>& base_uint<BITS>::operator>>=(unsigned int shift) { base_uint<BITS> a(*this); @@ -50,15 +50,15 @@ base_uint<BITS>& base_uint<BITS>::operator>>=(unsigned int shift) int k = shift / 32; shift = shift % 32; for (int i = 0; i < WIDTH; i++) { - if (i-k-1 >= 0 && shift != 0) - pn[i-k-1] |= (a.pn[i] << (32-shift)); - if (i-k >= 0) - pn[i-k] |= (a.pn[i] >> shift); + if (i - k - 1 >= 0 && shift != 0) + pn[i - k - 1] |= (a.pn[i] << (32 - shift)); + if (i - k >= 0) + pn[i - k] |= (a.pn[i] >> shift); } return *this; } -template<unsigned int BITS> +template <unsigned int BITS> base_uint<BITS>& base_uint<BITS>::operator*=(uint32_t b32) { uint64_t carry = 0; @@ -70,7 +70,7 @@ base_uint<BITS>& base_uint<BITS>::operator*=(uint32_t b32) return *this; } -template<unsigned int BITS> +template <unsigned int BITS> base_uint<BITS>& base_uint<BITS>::operator*=(const base_uint& b) { base_uint<BITS> a = *this; @@ -86,12 +86,12 @@ base_uint<BITS>& base_uint<BITS>::operator*=(const base_uint& b) return *this; } -template<unsigned int BITS> +template <unsigned int BITS> base_uint<BITS>& base_uint<BITS>::operator/=(const base_uint& b) { - base_uint<BITS> div = b; // make a copy, so we can shift. + base_uint<BITS> div = b; // make a copy, so we can shift. base_uint<BITS> num = *this; // make a copy, so we can subtract. - *this = 0; // the quotient. + *this = 0; // the quotient. int num_bits = num.bits(); int div_bits = div.bits(); if (div_bits == 0) @@ -112,9 +112,10 @@ base_uint<BITS>& base_uint<BITS>::operator/=(const base_uint& b) return *this; } -template<unsigned int BITS> -int base_uint<BITS>::CompareTo(const base_uint<BITS>& b) const { - for (int i = WIDTH-1; i >= 0; i--) { +template <unsigned int BITS> +int base_uint<BITS>::CompareTo(const base_uint<BITS>& b) const +{ + for (int i = WIDTH - 1; i >= 0; i--) { if (pn[i] < b.pn[i]) return -1; if (pn[i] > b.pn[i]) @@ -123,9 +124,10 @@ int base_uint<BITS>::CompareTo(const base_uint<BITS>& b) const { return 0; } -template<unsigned int BITS> -bool base_uint<BITS>::EqualTo(uint64_t b) const { - for (int i = WIDTH-1; i >= 2; i--) { +template <unsigned int BITS> +bool base_uint<BITS>::EqualTo(uint64_t b) const +{ + for (int i = WIDTH - 1; i >= 2; i--) { if (pn[i]) return false; } @@ -136,7 +138,7 @@ bool base_uint<BITS>::EqualTo(uint64_t b) const { return true; } -template<unsigned int BITS> +template <unsigned int BITS> double base_uint<BITS>::getdouble() const { double ret = 0.0; @@ -148,19 +150,19 @@ double base_uint<BITS>::getdouble() const return ret; } -template<unsigned int BITS> +template <unsigned int BITS> std::string base_uint<BITS>::GetHex() const { - char psz[sizeof(pn)*2 + 1]; + char psz[sizeof(pn) * 2 + 1]; for (unsigned int i = 0; i < sizeof(pn); i++) - sprintf(psz + i*2, "%02x", ((unsigned char*)pn)[sizeof(pn) - i - 1]); - return std::string(psz, psz + sizeof(pn)*2); + sprintf(psz + i * 2, "%02x", ((unsigned char*)pn)[sizeof(pn) - i - 1]); + return std::string(psz, psz + sizeof(pn) * 2); } -template<unsigned int BITS> +template <unsigned int BITS> void base_uint<BITS>::SetHex(const char* psz) { - memset(pn,0,sizeof(pn)); + memset(pn, 0, sizeof(pn)); // skip leading spaces while (isspace(*psz)) @@ -186,28 +188,28 @@ void base_uint<BITS>::SetHex(const char* psz) } } -template<unsigned int BITS> +template <unsigned int BITS> void base_uint<BITS>::SetHex(const std::string& str) { SetHex(str.c_str()); } -template<unsigned int BITS> +template <unsigned int BITS> std::string base_uint<BITS>::ToString() const { return (GetHex()); } -template<unsigned int BITS> +template <unsigned int BITS> unsigned int base_uint<BITS>::bits() const { - for (int pos = WIDTH-1; pos >= 0; pos--) { + for (int pos = WIDTH - 1; pos >= 0; pos--) { if (pn[pos]) { for (int bits = 31; bits > 0; bits--) { - if (pn[pos] & 1<<bits) - return 32*pos + bits + 1; + if (pn[pos] & 1 << bits) + return 32 * pos + bits + 1; } - return 32*pos + 1; + return 32 * pos + 1; } } return 0; @@ -249,16 +251,16 @@ template unsigned int base_uint<256>::bits() const; // This implementation directly uses shifts instead of going // through an intermediate MPI representation. -uint256& uint256::SetCompact(uint32_t nCompact, bool *pfNegative, bool *pfOverflow) +uint256& uint256::SetCompact(uint32_t nCompact, bool* pfNegative, bool* pfOverflow) { int nSize = nCompact >> 24; uint32_t nWord = nCompact & 0x007fffff; if (nSize <= 3) { - nWord >>= 8*(3-nSize); + nWord >>= 8 * (3 - nSize); *this = nWord; } else { *this = nWord; - *this <<= 8*(nSize-3); + *this <<= 8 * (nSize - 3); } if (pfNegative) *pfNegative = nWord != 0 && (nCompact & 0x00800000) != 0; @@ -274,9 +276,9 @@ uint32_t uint256::GetCompact(bool fNegative) const int nSize = (bits() + 7) / 8; uint32_t nCompact = 0; if (nSize <= 3) { - nCompact = GetLow64() << 8*(3-nSize); + nCompact = GetLow64() << 8 * (3 - nSize); } else { - uint256 bn = *this >> 8*(nSize-3); + uint256 bn = *this >> 8 * (nSize - 3); nCompact = bn.GetLow64(); } // The 0x00800000 bit denotes the sign. @@ -295,27 +297,46 @@ uint32_t uint256::GetCompact(bool fNegative) const static void inline HashMix(uint32_t& a, uint32_t& b, uint32_t& c) { // Taken from lookup3, by Bob Jenkins. - a -= c; a ^= ((c << 4) | (c >> 28)); c += b; - b -= a; b ^= ((a << 6) | (a >> 26)); a += c; - c -= b; c ^= ((b << 8) | (b >> 24)); b += a; - a -= c; a ^= ((c << 16) | (c >> 16)); c += b; - b -= a; b ^= ((a << 19) | (a >> 13)); a += c; - c -= b; c ^= ((b << 4) | (b >> 28)); b += a; + a -= c; + a ^= ((c << 4) | (c >> 28)); + c += b; + b -= a; + b ^= ((a << 6) | (a >> 26)); + a += c; + c -= b; + c ^= ((b << 8) | (b >> 24)); + b += a; + a -= c; + a ^= ((c << 16) | (c >> 16)); + c += b; + b -= a; + b ^= ((a << 19) | (a >> 13)); + a += c; + c -= b; + c ^= ((b << 4) | (b >> 28)); + b += a; } static void inline HashFinal(uint32_t& a, uint32_t& b, uint32_t& c) { // Taken from lookup3, by Bob Jenkins. - c ^= b; c -= ((b << 14) | (b >> 18)); - a ^= c; a -= ((c << 11) | (c >> 21)); - b ^= a; b -= ((a << 25) | (a >> 7)); - c ^= b; c -= ((b << 16) | (b >> 16)); - a ^= c; a -= ((c << 4) | (c >> 28)); - b ^= a; b -= ((a << 14) | (a >> 18)); - c ^= b; c -= ((b << 24) | (b >> 8)); + c ^= b; + c -= ((b << 14) | (b >> 18)); + a ^= c; + a -= ((c << 11) | (c >> 21)); + b ^= a; + b -= ((a << 25) | (a >> 7)); + c ^= b; + c -= ((b << 16) | (b >> 16)); + a ^= c; + a -= ((c << 4) | (c >> 28)); + b ^= a; + b -= ((a << 14) | (a >> 18)); + c ^= b; + c -= ((b << 24) | (b >> 8)); } -uint64_t uint256::GetHash(const uint256 &salt) const +uint64_t uint256::GetHash(const uint256& salt) const { uint32_t a, b, c; a = b = c = 0xdeadbeef + (WIDTH << 2); diff --git a/src/util.cpp b/src/util.cpp index 0ac0f70a79..f387fce8c7 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -472,6 +472,7 @@ void ReadConfigFile(map<string, string>& mapSettingsRet, ClearDatadirCache(); } +#ifndef WIN32 boost::filesystem::path GetPidFile() { boost::filesystem::path pathPidFile(GetArg("-pid", "bitcoind.pid")); @@ -479,7 +480,6 @@ boost::filesystem::path GetPidFile() return pathPidFile; } -#ifndef WIN32 void CreatePidFile(const boost::filesystem::path &path, pid_t pid) { FILE* file = fopen(path.string().c_str(), "w"); diff --git a/src/util.h b/src/util.h index e72c99adc7..4b2415278b 100644 --- a/src/util.h +++ b/src/util.h @@ -93,8 +93,8 @@ bool TryCreateDirectory(const boost::filesystem::path& p); boost::filesystem::path GetDefaultDataDir(); const boost::filesystem::path &GetDataDir(bool fNetSpecific = true); boost::filesystem::path GetConfigFile(); -boost::filesystem::path GetPidFile(); #ifndef WIN32 +boost::filesystem::path GetPidFile(); void CreatePidFile(const boost::filesystem::path &path, pid_t pid); #endif void ReadConfigFile(std::map<std::string, std::string>& mapSettingsRet, std::map<std::string, std::vector<std::string> >& mapMultiSettingsRet); diff --git a/src/utilstrencodings.cpp b/src/utilstrencodings.cpp index 6837e4e267..2cec3023b5 100644 --- a/src/utilstrencodings.cpp +++ b/src/utilstrencodings.cpp @@ -224,7 +224,7 @@ vector<unsigned char> DecodeBase64(const char* p, bool* pfInvalid) string DecodeBase64(const string& str) { vector<unsigned char> vchRet = DecodeBase64(str.c_str()); - return string((const char*)&vchRet[0], vchRet.size()); + return (vchRet.size() == 0) ? string() : string((const char*)&vchRet[0], vchRet.size()); } string EncodeBase32(const unsigned char* pch, size_t len) @@ -411,7 +411,7 @@ vector<unsigned char> DecodeBase32(const char* p, bool* pfInvalid) string DecodeBase32(const string& str) { vector<unsigned char> vchRet = DecodeBase32(str.c_str()); - return string((const char*)&vchRet[0], vchRet.size()); + return (vchRet.size() == 0) ? string() : string((const char*)&vchRet[0], vchRet.size()); } bool ParseInt32(const std::string& str, int32_t *out) diff --git a/src/version.cpp b/src/version.cpp index e441cc463f..95632fdab7 100644 --- a/src/version.cpp +++ b/src/version.cpp @@ -16,7 +16,7 @@ const std::string CLIENT_NAME("Satoshi"); // Client version number -#define CLIENT_VERSION_SUFFIX "" +#define CLIENT_VERSION_SUFFIX "" // The following part of the code determines the CLIENT_BUILD variable. @@ -35,40 +35,40 @@ const std::string CLIENT_NAME("Satoshi"); // First, include build.h if requested #ifdef HAVE_BUILD_INFO -# include "build.h" +#include "build.h" #endif // git will put "#define GIT_ARCHIVE 1" on the next line inside archives. $Format:%n#define GIT_ARCHIVE 1$ #ifdef GIT_ARCHIVE -# define GIT_COMMIT_ID "$Format:%h$" -# define GIT_COMMIT_DATE "$Format:%cD$" +#define GIT_COMMIT_ID "$Format:%h$" +#define GIT_COMMIT_DATE "$Format:%cD$" #endif -#define BUILD_DESC_WITH_SUFFIX(maj,min,rev,build,suffix) \ +#define BUILD_DESC_WITH_SUFFIX(maj, min, rev, build, suffix) \ "v" DO_STRINGIZE(maj) "." DO_STRINGIZE(min) "." DO_STRINGIZE(rev) "." DO_STRINGIZE(build) "-" DO_STRINGIZE(suffix) -#define BUILD_DESC_FROM_COMMIT(maj,min,rev,build,commit) \ +#define BUILD_DESC_FROM_COMMIT(maj, min, rev, build, commit) \ "v" DO_STRINGIZE(maj) "." DO_STRINGIZE(min) "." DO_STRINGIZE(rev) "." DO_STRINGIZE(build) "-g" commit -#define BUILD_DESC_FROM_UNKNOWN(maj,min,rev,build) \ +#define BUILD_DESC_FROM_UNKNOWN(maj, min, rev, build) \ "v" DO_STRINGIZE(maj) "." DO_STRINGIZE(min) "." DO_STRINGIZE(rev) "." DO_STRINGIZE(build) "-unk" #ifndef BUILD_DESC -# ifdef BUILD_SUFFIX -# define BUILD_DESC BUILD_DESC_WITH_SUFFIX(CLIENT_VERSION_MAJOR, CLIENT_VERSION_MINOR, CLIENT_VERSION_REVISION, CLIENT_VERSION_BUILD, BUILD_SUFFIX) -# elif defined(GIT_COMMIT_ID) -# define BUILD_DESC BUILD_DESC_FROM_COMMIT(CLIENT_VERSION_MAJOR, CLIENT_VERSION_MINOR, CLIENT_VERSION_REVISION, CLIENT_VERSION_BUILD, GIT_COMMIT_ID) -# else -# define BUILD_DESC BUILD_DESC_FROM_UNKNOWN(CLIENT_VERSION_MAJOR, CLIENT_VERSION_MINOR, CLIENT_VERSION_REVISION, CLIENT_VERSION_BUILD) -# endif +#ifdef BUILD_SUFFIX +#define BUILD_DESC BUILD_DESC_WITH_SUFFIX(CLIENT_VERSION_MAJOR, CLIENT_VERSION_MINOR, CLIENT_VERSION_REVISION, CLIENT_VERSION_BUILD, BUILD_SUFFIX) +#elif defined(GIT_COMMIT_ID) +#define BUILD_DESC BUILD_DESC_FROM_COMMIT(CLIENT_VERSION_MAJOR, CLIENT_VERSION_MINOR, CLIENT_VERSION_REVISION, CLIENT_VERSION_BUILD, GIT_COMMIT_ID) +#else +#define BUILD_DESC BUILD_DESC_FROM_UNKNOWN(CLIENT_VERSION_MAJOR, CLIENT_VERSION_MINOR, CLIENT_VERSION_REVISION, CLIENT_VERSION_BUILD) +#endif #endif #ifndef BUILD_DATE -# ifdef GIT_COMMIT_DATE -# define BUILD_DATE GIT_COMMIT_DATE -# else -# define BUILD_DATE __DATE__ ", " __TIME__ -# endif +#ifdef GIT_COMMIT_DATE +#define BUILD_DATE GIT_COMMIT_DATE +#else +#define BUILD_DATE __DATE__ ", " __TIME__ +#endif #endif const std::string CLIENT_BUILD(BUILD_DESC CLIENT_VERSION_SUFFIX); @@ -76,10 +76,10 @@ const std::string CLIENT_DATE(BUILD_DATE); static std::string FormatVersion(int nVersion) { - if (nVersion%100 == 0) - return strprintf("%d.%d.%d", nVersion/1000000, (nVersion/10000)%100, (nVersion/100)%100); + if (nVersion % 100 == 0) + return strprintf("%d.%d.%d", nVersion / 1000000, (nVersion / 10000) % 100, (nVersion / 100) % 100); else - return strprintf("%d.%d.%d.%d", nVersion/1000000, (nVersion/10000)%100, (nVersion/100)%100, nVersion%100); + return strprintf("%d.%d.%d.%d", nVersion / 1000000, (nVersion / 10000) % 100, (nVersion / 100) % 100, nVersion % 100); } std::string FormatFullVersion() diff --git a/src/wallet.cpp b/src/wallet.cpp index 611fb8bbcd..e69f59aacd 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -646,7 +646,7 @@ bool CWallet::AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pbl CWalletTx wtx(this,tx); // Get merkle branch if transaction was found in a block if (pblock) - wtx.SetMerkleBranch(pblock); + wtx.SetMerkleBranch(*pblock); return AddToWallet(wtx); } } @@ -1385,7 +1385,7 @@ bool CWallet::CreateTransaction(const vector<pair<CScript, int64_t> >& vecSend, // coin control: send change to custom address if (coinControl && !boost::get<CNoDestination>(&coinControl->destChange)) - scriptChange.SetDestination(coinControl->destChange); + scriptChange = GetScriptForDestination(coinControl->destChange); // no coin control: send change to newly generated address else @@ -1403,7 +1403,7 @@ bool CWallet::CreateTransaction(const vector<pair<CScript, int64_t> >& vecSend, ret = reservekey.GetReservedKey(vchPubKey); assert(ret); // should never fail, as we just unlocked - scriptChange.SetDestination(vchPubKey.GetID()); + scriptChange = GetScriptForDestination(vchPubKey.GetID()); } CTxOut newTxOut(nChange, scriptChange); @@ -1556,8 +1556,7 @@ string CWallet::SendMoney(const CTxDestination &address, int64_t nValue, CWallet } // Parse Bitcoin address - CScript scriptPubKey; - scriptPubKey.SetDestination(address); + CScript scriptPubKey = GetScriptForDestination(address); // Create and send the transaction CReserveKey reservekey(this); @@ -2230,48 +2229,34 @@ CWalletKey::CWalletKey(int64_t nExpires) nTimeExpires = nExpires; } -int CMerkleTx::SetMerkleBranch(const CBlock* pblock) +int CMerkleTx::SetMerkleBranch(const CBlock& block) { AssertLockHeld(cs_main); CBlock blockTmp; - if (pblock == NULL) { - CCoins coins; - if (pcoinsTip->GetCoins(GetHash(), coins)) { - CBlockIndex *pindex = chainActive[coins.nHeight]; - if (pindex) { - if (!ReadBlockFromDisk(blockTmp, pindex)) - return 0; - pblock = &blockTmp; - } - } - } - - if (pblock) { - // Update the tx's hashBlock - hashBlock = pblock->GetHash(); - - // Locate the transaction - for (nIndex = 0; nIndex < (int)pblock->vtx.size(); nIndex++) - if (pblock->vtx[nIndex] == *(CTransaction*)this) - break; - if (nIndex == (int)pblock->vtx.size()) - { - vMerkleBranch.clear(); - nIndex = -1; - LogPrintf("ERROR: SetMerkleBranch() : couldn't find tx in block\n"); - return 0; - } + // Update the tx's hashBlock + hashBlock = block.GetHash(); - // Fill in merkle branch - vMerkleBranch = pblock->GetMerkleBranch(nIndex); + // Locate the transaction + for (nIndex = 0; nIndex < (int)block.vtx.size(); nIndex++) + if (block.vtx[nIndex] == *(CTransaction*)this) + break; + if (nIndex == (int)block.vtx.size()) + { + vMerkleBranch.clear(); + nIndex = -1; + LogPrintf("ERROR: SetMerkleBranch() : couldn't find tx in block\n"); + return 0; } + // Fill in merkle branch + vMerkleBranch = block.GetMerkleBranch(nIndex); + // Is the tx in a block that's in the main chain BlockMap::iterator mi = mapBlockIndex.find(hashBlock); if (mi == mapBlockIndex.end()) return 0; - CBlockIndex* pindex = (*mi).second; + const CBlockIndex* pindex = (*mi).second; if (!pindex || !chainActive.Contains(pindex)) return 0; diff --git a/src/wallet.h b/src/wallet.h index 3461446b8b..fde87a8a2f 100644 --- a/src/wallet.h +++ b/src/wallet.h @@ -504,7 +504,7 @@ public: READWRITE(nIndex); } - int SetMerkleBranch(const CBlock* pblock=NULL); + int SetMerkleBranch(const CBlock& block); // Return depth of transaction in blockchain: // -1 : not in blockchain, and not in memory pool (conflicted transaction) diff --git a/src/wallet_ismine.cpp b/src/wallet_ismine.cpp index a3c221d3ab..07149ebd0b 100644 --- a/src/wallet_ismine.cpp +++ b/src/wallet_ismine.cpp @@ -29,8 +29,7 @@ unsigned int HaveKeys(const vector<valtype>& pubkeys, const CKeyStore& keystore) isminetype IsMine(const CKeyStore &keystore, const CTxDestination& dest) { - CScript script; - script.SetDestination(dest); + CScript script = GetScriptForDestination(dest); return IsMine(keystore, script); } diff --git a/src/wallet_ismine.h b/src/wallet_ismine.h index 29e13a94a6..f326b86815 100644 --- a/src/wallet_ismine.h +++ b/src/wallet_ismine.h @@ -7,9 +7,10 @@ #define H_BITCOIN_WALLET_ISMINE #include "key.h" -#include "script/script.h" +#include "script/standard.h" class CKeyStore; +class CScript; /** IsMine() return codes */ enum isminetype diff --git a/src/walletdb.cpp b/src/walletdb.cpp index 03161250db..a84f44db01 100644 --- a/src/walletdb.cpp +++ b/src/walletdb.cpp @@ -242,9 +242,7 @@ void CWalletDB::ListAccountCreditDebit(const string& strAccount, list<CAccountin pcursor->close(); } - -DBErrors -CWalletDB::ReorderTransactions(CWallet* pwallet) +DBErrors CWalletDB::ReorderTransactions(CWallet* pwallet) { LOCK(pwallet->cs_wallet); // Old wallets didn't have any defined order for transactions diff --git a/src/walletdb.h b/src/walletdb.h index ce63bb0b97..2c5b608f3d 100644 --- a/src/walletdb.h +++ b/src/walletdb.h @@ -75,13 +75,10 @@ public: class CWalletDB : public CDB { public: - CWalletDB(std::string strFilename, const char* pszMode="r+") : CDB(strFilename.c_str(), pszMode) + CWalletDB(const std::string& strFilename, const char* pszMode = "r+") : CDB(strFilename, pszMode) { } -private: - CWalletDB(const CWalletDB&); - void operator=(const CWalletDB&); -public: + bool WriteName(const std::string& strAddress, const std::string& strName); bool EraseName(const std::string& strAddress); @@ -119,19 +116,23 @@ public: bool WriteDestData(const std::string &address, const std::string &key, const std::string &value); /// Erase destination data tuple from wallet database bool EraseDestData(const std::string &address, const std::string &key); -private: - bool WriteAccountingEntry(const uint64_t nAccEntryNum, const CAccountingEntry& acentry); -public: + bool WriteAccountingEntry(const CAccountingEntry& acentry); int64_t GetAccountCreditDebit(const std::string& strAccount); void ListAccountCreditDebit(const std::string& strAccount, std::list<CAccountingEntry>& acentries); - DBErrors ReorderTransactions(CWallet*); + DBErrors ReorderTransactions(CWallet* pwallet); DBErrors LoadWallet(CWallet* pwallet); DBErrors FindWalletTx(CWallet* pwallet, std::vector<uint256>& vTxHash, std::vector<CWalletTx>& vWtx); DBErrors ZapWalletTx(CWallet* pwallet, std::vector<CWalletTx>& vWtx); static bool Recover(CDBEnv& dbenv, std::string filename, bool fOnlyKeys); static bool Recover(CDBEnv& dbenv, std::string filename); + +private: + CWalletDB(const CWalletDB&); + void operator=(const CWalletDB&); + + bool WriteAccountingEntry(const uint64_t nAccEntryNum, const CAccountingEntry& acentry); }; bool BackupWallet(const CWallet& wallet, const std::string& strDest); |