diff options
-rw-r--r-- | contrib/README.md | 44 | ||||
-rw-r--r-- | src/Makefile.am | 1 | ||||
-rw-r--r-- | src/base58.cpp | 91 | ||||
-rw-r--r-- | src/base58.h | 144 | ||||
-rw-r--r-- | src/net.cpp | 6 | ||||
-rw-r--r-- | src/netbase.cpp | 9 | ||||
-rw-r--r-- | src/wallet.cpp | 1 | ||||
-rw-r--r-- | src/walletdb.cpp | 4 |
8 files changed, 161 insertions, 139 deletions
diff --git a/contrib/README.md b/contrib/README.md index cd0dd3b023..92d0a343db 100644 --- a/contrib/README.md +++ b/contrib/README.md @@ -1,22 +1,36 @@ -Python Tools +Wallet Tools --------------------- ### [BitRPC](/contrib/bitrpc) ### Allows for sending of all standard Bitcoin commands via RPC rather than as command line args. +### [SpendFrom](/contrib/spendfrom) ### + +Use the raw transactions API to send coins received on a particular +address (or addresses). + +Repository Tools +--------------------- + +### [Developer tools](/contrib/devtools) ### +Specific tools for developers working on this repository. +Contains the script `github-merge.sh` for merging github pull requests securely and signing them using GPG. + +### [Linearize](/contrib/linearize) ### +Construct a linear, no-fork, best version of the blockchain. + ### [PyMiner](/contrib/pyminer) ### This is a 'getwork' CPU mining client for Bitcoin. It is pure-python, and therefore very, very slow. The purpose is to provide a reference implementation of a miner, for study. -### [SpendFrom](/contrib/spendfrom) ### +### [Qos](/contrib/qos) ### -Use the raw transactions API to send coins received on a particular -address (or addresses). +A Linux bash script that will set up tc to limit the outgoing bandwidth for connections to the Bitcoin network. This means one can have an always-on bitcoind instance running, and another local bitcoind/bitcoin-qt instance which connects to this node and receives blocks from it. -### WalletTools -Removed. Please see [/contrib/bitrpc](/contrib/bitrpc). +### [Seeds](/contrib/seeds) ### +Utility to generate the pnSeed[] array that is compiled into the client. -Repository Tools +Build Tools and Keys --------------------- ### [Debian](/contrib/debian) ### @@ -29,18 +43,11 @@ Gavin's notes on getting gitian builds up and running using KVM. ### [Gitian-downloader](/contrib/gitian-downloader) Various PGP files of core developers. -### [Linearize](/contrib/linearize) ### -Construct a linear, no-fork, best version of the blockchain. - ### [MacDeploy](/contrib/macdeploy) ### Scripts and notes for Mac builds. -### [Qos](/contrib/qos) ### - -A Linux bash script that will set up tc to limit the outgoing bandwidth for connections to the Bitcoin network. This means one can have an always-on bitcoind instance running, and another local bitcoind/bitcoin-qt instance which connects to this node and receives blocks from it. - -### [Seeds](/contrib/seeds) ### -Utility to generate the pnSeed[] array that is compiled into the client. +Test and Verify Tools +--------------------- ### [TestGen](/contrib/testgen) ### Utilities to generate test vectors for the data-driven Bitcoin tests. @@ -51,8 +58,3 @@ tests each pull and when master is tested using jenkins. ### [Verify SF Binaries](/contrib/verifysfbinaries) ### This script attempts to download and verify the signature file SHA256SUMS.asc from SourceForge. - -### [Developer tools](/contrib/devtools) ### -Specific tools for developers working on this repository. -Contains the script `github-merge.sh` for merging github pull requests securely and signing them using GPG. - diff --git a/src/Makefile.am b/src/Makefile.am index c725c4f1c2..b037ac2c98 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -121,6 +121,7 @@ libbitcoin_wallet_a_SOURCES = \ $(BITCOIN_CORE_H) libbitcoin_common_a_SOURCES = \ + base58.cpp \ allocators.cpp \ chainparams.cpp \ core.cpp \ diff --git a/src/base58.cpp b/src/base58.cpp new file mode 100644 index 0000000000..0b08ee3d06 --- /dev/null +++ b/src/base58.cpp @@ -0,0 +1,91 @@ +// Copyright (c) 2014 The Bitcoin developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include <assert.h> +#include <stdint.h> +#include <string.h> +#include <vector> +#include <string> + +/* 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) { + // Skip leading spaces. + while (*psz && isspace(*psz)) + psz++; + // Skip and count leading '1's. + int zeroes = 0; + while (*psz == '1') { + zeroes++; + psz++; + } + // Allocate enough space in big-endian base256 representation. + std::vector<unsigned char> b256(strlen(psz) * 733 / 1000 + 1); // log(58) / log(256), rounded up. + // Process the characters. + while (*psz && !isspace(*psz)) { + // Decode base58 character + const char *ch = strchr(pszBase58, *psz); + if (ch == NULL) + return false; + // Apply "b256 = b256 * 58 + ch". + int carry = ch - pszBase58; + for (std::vector<unsigned char>::reverse_iterator it = b256.rbegin(); it != b256.rend(); it++) { + carry += 58 * (*it); + *it = carry % 256; + carry /= 256; + } + assert(carry == 0); + psz++; + } + // Skip trailing spaces. + while (isspace(*psz)) + psz++; + if (*psz != 0) + return false; + // Skip leading zeroes in b256. + std::vector<unsigned char>::iterator it = b256.begin(); + while (it != b256.end() && *it == 0) + it++; + // Copy result into output vector. + vch.reserve(zeroes + (b256.end() - it)); + vch.assign(zeroes, 0x00); + while (it != b256.end()) + vch.push_back(*(it++)); + return true; +} + +std::string EncodeBase58(const unsigned char* pbegin, const unsigned char* pend) { + // Skip & count leading zeroes. + int zeroes = 0; + while (pbegin != pend && *pbegin == 0) { + pbegin++; + zeroes++; + } + // Allocate enough space in big-endian base58 representation. + std::vector<unsigned char> b58((pend - pbegin) * 138 / 100 + 1); // log(256) / log(58), rounded up. + // Process the bytes. + while (pbegin != pend) { + int carry = *pbegin; + // Apply "b58 = b58 * 256 + ch". + for (std::vector<unsigned char>::reverse_iterator it = b58.rbegin(); it != b58.rend(); it++) { + carry += 256 * (*it); + *it = carry % 58; + carry /= 58; + } + assert(carry == 0); + pbegin++; + } + // Skip leading zeroes in base58 result. + std::vector<unsigned char>::iterator it = b58.begin(); + while (it != b58.end() && *it == 0) + it++; + // Translate the result into a string. + std::string str; + str.reserve(zeroes + (b58.end() - it)); + str.assign(zeroes, '1'); + while (it != b58.end()) + str += pszBase58[*(it++)]; + return str; +} diff --git a/src/base58.h b/src/base58.h index ebe5376825..4fb436c5ed 100644 --- a/src/base58.h +++ b/src/base58.h @@ -14,7 +14,6 @@ #ifndef BITCOIN_BASE58_H #define BITCOIN_BASE58_H -#include "bignum.h" #include "chainparams.h" #include "hash.h" #include "key.h" @@ -27,114 +26,39 @@ #include <boost/variant/apply_visitor.hpp> #include <boost/variant/static_visitor.hpp> -static const char* pszBase58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; - -// Encode a byte sequence as a base58-encoded string -inline std::string EncodeBase58(const unsigned char* pbegin, const unsigned char* pend) -{ - CAutoBN_CTX pctx; - CBigNum bn58 = 58; - CBigNum bn0 = 0; - - // Convert big endian data to little endian - // Extra zero at the end make sure bignum will interpret as a positive number - std::vector<unsigned char> vchTmp(pend-pbegin+1, 0); - reverse_copy(pbegin, pend, vchTmp.begin()); - - // Convert little endian data to bignum - CBigNum bn; - bn.setvch(vchTmp); - - // Convert bignum to std::string - std::string str; - // Expected size increase from base58 conversion is approximately 137% - // use 138% to be safe - str.reserve((pend - pbegin) * 138 / 100 + 1); - CBigNum dv; - CBigNum rem; - while (bn > bn0) - { - if (!BN_div(&dv, &rem, &bn, &bn58, pctx)) - throw bignum_error("EncodeBase58 : BN_div failed"); - bn = dv; - unsigned int c = rem.getulong(); - str += pszBase58[c]; - } - - // Leading zeroes encoded as base58 zeros - for (const unsigned char* p = pbegin; p < pend && *p == 0; p++) - str += pszBase58[0]; - - // Convert little endian std::string to big endian - reverse(str.begin(), str.end()); - return str; -} +/** + * Encode a byte sequence as a base58-encoded string. + * pbegin and pend cannot be NULL, unless both are. + */ +std::string EncodeBase58(const unsigned char* pbegin, const unsigned char* pend); -// Encode a byte vector as a base58-encoded string +/** + * Encode a byte vector as a base58-encoded string + */ inline std::string EncodeBase58(const std::vector<unsigned char>& vch) { return EncodeBase58(&vch[0], &vch[0] + vch.size()); } -// Decode a base58-encoded string psz into byte vector vchRet -// returns true if decoding is successful -inline bool DecodeBase58(const char* psz, std::vector<unsigned char>& vchRet) -{ - CAutoBN_CTX pctx; - vchRet.clear(); - CBigNum bn58 = 58; - CBigNum bn = 0; - CBigNum bnChar; - while (isspace(*psz)) - psz++; - - // Convert big endian string to bignum - for (const char* p = psz; *p; p++) - { - const char* p1 = strchr(pszBase58, *p); - if (p1 == NULL) - { - while (isspace(*p)) - p++; - if (*p != '\0') - return false; - break; - } - bnChar.setulong(p1 - pszBase58); - if (!BN_mul(&bn, &bn, &bn58, pctx)) - throw bignum_error("DecodeBase58 : BN_mul failed"); - bn += bnChar; - } - - // Get bignum as little endian data - std::vector<unsigned char> vchTmp = bn.getvch(); - - // Trim off sign byte if present - if (vchTmp.size() >= 2 && vchTmp.end()[-1] == 0 && vchTmp.end()[-2] >= 0x80) - vchTmp.erase(vchTmp.end()-1); - - // Restore leading zeros - int nLeadingZeros = 0; - for (const char* p = psz; *p == pszBase58[0]; p++) - nLeadingZeros++; - vchRet.assign(nLeadingZeros + vchTmp.size(), 0); - - // Convert little endian data to big endian - reverse_copy(vchTmp.begin(), vchTmp.end(), vchRet.end() - vchTmp.size()); - return true; -} +/** + * Decode a base58-encoded string (psz) into a byte vector (vchRet). + * return true if decoding is successful. + * psz cannot be NULL. + */ +bool DecodeBase58(const char* psz, std::vector<unsigned char>& vchRet); -// Decode a base58-encoded string str into byte vector vchRet -// returns true if decoding is successful +/** + * Decode a base58-encoded string (str) into a byte vector (vchRet). + * return true if decoding is successful. + */ inline bool DecodeBase58(const std::string& str, std::vector<unsigned char>& vchRet) { return DecodeBase58(str.c_str(), vchRet); } - - - -// Encode a byte vector to a base58-encoded string, including checksum +/** + * Encode a byte vector into a base58-encoded string, including checksum + */ inline std::string EncodeBase58Check(const std::vector<unsigned char>& vchIn) { // add 4-byte hash check to the end @@ -144,8 +68,10 @@ inline std::string EncodeBase58Check(const std::vector<unsigned char>& vchIn) return EncodeBase58(vch); } -// Decode a base58-encoded string psz that includes a checksum, into byte vector vchRet -// returns true if decoding is successful +/** + * Decode a base58-encoded string (psz) that includes a checksum into a byte + * vector (vchRet), return true if decoding is successful + */ inline bool DecodeBase58Check(const char* psz, std::vector<unsigned char>& vchRet) { if (!DecodeBase58(psz, vchRet)) @@ -155,6 +81,7 @@ inline bool DecodeBase58Check(const char* psz, std::vector<unsigned char>& vchRe 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) { @@ -165,18 +92,18 @@ inline bool DecodeBase58Check(const char* psz, std::vector<unsigned char>& vchRe return true; } -// Decode a base58-encoded string str that includes a checksum, into byte vector vchRet -// returns true if decoding is successful +/** + * Decode a base58-encoded string (str) that includes a checksum into a byte + * vector (vchRet), return true if decoding is successful + */ inline bool DecodeBase58Check(const std::string& str, std::vector<unsigned char>& vchRet) { return DecodeBase58Check(str.c_str(), vchRet); } - - - - -/** Base class for all base58-encoded data */ +/** + * Base class for all base58-encoded data + */ class CBase58Data { protected: @@ -347,7 +274,9 @@ bool inline CBitcoinAddressVisitor::operator()(const CKeyID &id) const { bool inline CBitcoinAddressVisitor::operator()(const CScriptID &id) const { return addr->Set(id); } bool inline CBitcoinAddressVisitor::operator()(const CNoDestination &id) const { return false; } -/** A base58-encoded secret key */ +/** + * A base58-encoded secret key + */ class CBitcoinSecret : public CBase58Data { public: @@ -393,7 +322,6 @@ public: } }; - template<typename K, int Size, CChainParams::Base58Type Type> class CBitcoinExtKeyBase : public CBase58Data { public: diff --git a/src/net.cpp b/src/net.cpp index 657a39bcff..a0208c9605 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -946,11 +946,7 @@ void ThreadSocketHandler() } else if (nInbound >= nMaxConnections - MAX_OUTBOUND_CONNECTIONS) { - { - LOCK(cs_setservAddNodeAddresses); - if (!setservAddNodeAddresses.count(addr)) - closesocket(hSocket); - } + closesocket(hSocket); } else if (CNode::IsBanned(addr)) { diff --git a/src/netbase.cpp b/src/netbase.cpp index d5b75d6afd..2b300e5dd3 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -293,8 +293,10 @@ bool static Socks5(string strDest, int port, SOCKET& hSocket) case 0x03: { ret = recv(hSocket, pchRet3, 1, 0) != 1; - if (ret) + if (ret) { + closesocket(hSocket); return error("Error reading from proxy"); + } int nRecv = pchRet3[0]; ret = recv(hSocket, pchRet3, nRecv, 0) != nRecv; break; @@ -501,6 +503,7 @@ bool ConnectSocket(const CService &addrDest, SOCKET& hSocketRet, int nTimeout) return false; break; default: + closesocket(hSocket); return false; } @@ -532,7 +535,9 @@ bool ConnectSocketByName(CService &addr, SOCKET& hSocketRet, const char *pszDest switch(nameproxy.second) { default: - case 4: return false; + case 4: + closesocket(hSocket); + return false; case 5: if (!Socks5(strDest, port, hSocket)) return false; diff --git a/src/wallet.cpp b/src/wallet.cpp index 6b0c604a34..7cf2361096 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -471,6 +471,7 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet) if (fFromLoadWallet) { mapWallet[hash] = wtxIn; + mapWallet[hash].BindWallet(this); AddToSpends(hash); } else diff --git a/src/walletdb.cpp b/src/walletdb.cpp index b57ea0b518..359a1cef61 100644 --- a/src/walletdb.cpp +++ b/src/walletdb.cpp @@ -352,9 +352,7 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, CWalletTx wtx; ssValue >> wtx; CValidationState state; - if (CheckTransaction(wtx, state) && (wtx.GetHash() == hash) && state.IsValid()) - wtx.BindWallet(pwallet); - else + if (!(CheckTransaction(wtx, state) && (wtx.GetHash() == hash) && state.IsValid())) return false; // Undo serialize changes in 31600 |